diff --git a/manual/src/ch11-00-builtins.md b/manual/src/ch11-00-builtins.md index 261b7f51827168dffc24b57f696b7577a2f68d0b..c62b4bceb096d9f6574ea8e1d98b81c101a6080e 100644 --- a/manual/src/ch11-00-builtins.md +++ b/manual/src/ch11-00-builtins.md @@ -1,4 +1,5 @@ # Builtin Commands +<<<<<<< HEAD ## alias ``` alias NAME=DEFINITION @@ -249,3 +250,20 @@ Waits until all running background processes have completed which COMMAND ``` Shows the full path of commands +======= +## random +###Synopsis +``` +random +random SEED +random START END +random START STEP END +random choice [ITEMS...] +``` + +###Description + +RANDOM generates a pseudo-random integer from a uniform distribution. The range (inclusive) is dependent on the arguments passed. No arguments indicate a range of [0; 32767]. If one argument is specified, the internal engine will be seeded with the argument for future invocations of RANDOM and no output will be produced. Two arguments indicate a range of [START; END]. Three arguments indicate a range of [START; END] with a spacing of STEP between possible outputs. RANDOM choice will select one random item from the succeeding arguments. + +NOTE: Due to limitations int the rand crate, seeding is not yet implemented +>>>>>>> 1ecdec5... Added more functunality to random and added docs for random diff --git a/src/builtins/mod.rs b/src/builtins/mod.rs index 98d119d52cef992075f5cbec4fa8624e3585dc48..9d0512a32a24d723e77a831920e9ef85e251bed2 100644 --- a/src/builtins/mod.rs +++ b/src/builtins/mod.rs @@ -257,8 +257,8 @@ fn builtin_calc(args: &[&str], _: &mut Shell) -> i32 { } } -fn builtin_random(_: &[&str], _: &mut Shell) -> i32 { - match random::random() { +fn builtin_random(args: &[&str], _: &mut Shell) -> i32 { + match random::random(&args[1..]) { Ok(()) => SUCCESS, Err(why) => { let stderr = io::stderr(); diff --git a/src/builtins/random.rs b/src/builtins/random.rs index 72990163cfd90a80cc24a96bdd76eef756a66a42..862b9ad9ea2a32a5db3c23d9ec3b8d819457c1c7 100644 --- a/src/builtins/random.rs +++ b/src/builtins/random.rs @@ -1,11 +1,82 @@ extern crate rand; use self::rand::Rng; -use std::io::{self, Write,Error}; +use std::io::{self, Write}; -pub(crate) fn random() -> Result<(), Error> { +#[allow(unused_must_use)] +fn rand_list(args: &[&str]) -> Result<(), String> { let stdout = io::stdout(); let mut stdout = stdout.lock(); - let rand_num = rand::thread_rng().next_u64(); - writeln!(stdout, "{}", rand_num)?; + let mut output = Vec::new(); + let arg1 = match args[0].parse::<usize>() { + Ok(v) => v, + Err(_) => return Err(String::from("Invalid argument for random")), + }; + while output.len() < arg1 { + let rand_num = rand::thread_rng().gen_range(1, args.len()); + output.push(args[rand_num]); + output.dedup(); + } + for out in output { + write!(stdout, "{} ", out); + + } + writeln!(stdout); + Ok(()) +} +#[allow(unused_must_use)] +pub(crate) fn random(args: &[&str]) -> Result<(), String> { + let stdout = io::stdout(); + let mut stdout = stdout.lock(); + match args.len() { + 0 => { + let rand_num = rand::thread_rng().gen_range(0, 32767); + writeln!(stdout, "{}", rand_num); + } + 1 => { + writeln!(stdout, "Ion Shell does not currently support changing the seed"); + } + 2 => { + let arg1 = match args[0].parse::<u64>() { + Ok(v) => v, + Err(_) => return Err(String::from("Invalid argument for random")), + }; + let arg2 = match args[1].parse::<u64>() { + Ok(v) => v, + Err(_) => return Err(String::from("Invalid argument for random")), + }; + if arg2 <= arg1 { + return Err(String::from("END must be greater than START")); + } + let rand_num = rand::thread_rng().gen_range(arg1, arg2); + writeln!(stdout, "{}", rand_num); + } + 3 => { + let arg1 = match args[0].parse::<u64>() { + Ok(v) => v, + Err(_) => return Err(String::from("Invalid argument for random")), + }; + let arg2 = match args[1].parse::<u64>() { + Ok(v) => v, + Err(_) => return rand_list(args), + }; + match args[2].parse::<u64>() { + Ok(v) => { + if arg2 <= arg1 { + return Err(String::from("END must be greater than START")); + } + let mut end = v / arg2 + 1; + if arg1 / arg2 >= end { + end += 1; + } + let rand_num = rand::thread_rng().gen_range(arg1 / arg2, end); + writeln!(stdout, "{}", rand_num * arg2); + } + Err(_) => return rand_list(args), + }; + + } + _ => return rand_list(args), + } + Ok(()) }