diff --git a/src/main.rs b/src/main.rs index cf06c951a..694279f88 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,7 +5,7 @@ extern crate alloc; use bootloader::{entry_point, BootInfo}; use core::panic::PanicInfo; -use moros::{sys, usr, debug, print, println, hlt_loop}; +use moros::{sys, usr, print, println, debug, hlt_loop}; entry_point!(main); diff --git a/src/usr/shell.rs b/src/usr/shell.rs index d3cdb99cb..90e43d3be 100644 --- a/src/usr/shell.rs +++ b/src/usr/shell.rs @@ -155,11 +155,11 @@ pub fn split_args(cmd: &str) -> Vec { n = j; // Discard comments break; } else if c == ' ' && !is_quote { - if i != j { + if i != j && !cmd[i..j].trim().is_empty() { if args.is_empty() { - args.push(cmd[i..j].to_string()) + args.push(cmd[i..j].to_string()) // program name } else { - args.extend(glob(&cmd[i..j])) + args.extend(glob(&cmd[i..j])) // program args } } i = j + 1; @@ -178,12 +178,12 @@ pub fn split_args(cmd: &str) -> Vec { args.push(cmd[i..n].to_string()); } else if args.is_empty() { args.push(cmd[i..n].to_string()); - } else { + } else if !cmd[i..n].trim().is_empty() { args.extend(glob(&cmd[i..n])) } } - if n == 0 || cmd.ends_with(' ') { + if n == 0 { args.push("".to_string()); } @@ -203,8 +203,9 @@ fn tilde_expansion(arg: &str) -> String { fn variables_expansion(cmd: &str, config: &mut Config) -> String { let mut cmd = cmd.to_string(); - // Special case for `?` which is not alphanum (\w) + // Special cases for none alphanum (\w) variables cmd = cmd.replace("$?", "$status"); + cmd = cmd.replace("$*", "$1 $2 $3 $4 $5 $6 $7 $8 $9"); // Replace alphanum `$key` with its value in the environment or an empty string let re = Regex::new("\\$\\w+"); @@ -482,6 +483,7 @@ fn exec_with_config(cmd: &str, config: &mut Config) -> Result<(), ExitCode> { "user" => usr::user::main(&args), "vga" => usr::vga::main(&args), "write" => usr::write::main(&args), + "panic" => panic!("{}", args[1..].join(" ")), _ => { let mut path = fs::realpath(args[0]); if path.len() > 1 { @@ -627,6 +629,27 @@ fn test_shell() { sys::fs::dismount(); } +#[test_case] +fn test_split_args() { + use alloc::vec; + assert_eq!(split_args(""), vec![""]); + assert_eq!(split_args("print"), vec!["print"]); + assert_eq!(split_args("print "), vec!["print"]); + assert_eq!(split_args("print "), vec!["print"]); + assert_eq!(split_args("print # comment"), vec!["print"]); + assert_eq!(split_args("print foo"), vec!["print", "foo"]); + assert_eq!(split_args("print foo "), vec!["print", "foo"]); + assert_eq!(split_args("print foo "), vec!["print", "foo"]); + assert_eq!(split_args("print foo # comment"), vec!["print", "foo"]); + assert_eq!(split_args("print foo bar"), vec!["print", "foo", "bar"]); + assert_eq!(split_args("print foo bar"), vec!["print", "foo", "bar"]); + assert_eq!(split_args("print foo bar"), vec!["print", "foo", "bar"]); + assert_eq!(split_args("print foo \"bar\""), vec!["print", "foo", "bar"]); + assert_eq!(split_args("print foo \"\""), vec!["print", "foo", ""]); + assert_eq!(split_args("print foo \"bar\" "), vec!["print", "foo", "bar"]); + assert_eq!(split_args("print foo \"\" "), vec!["print", "foo", ""]); +} + #[test_case] fn test_glob_to_regex() { assert_eq!(glob_to_regex("hello.txt"), "^hello\\.txt$"); diff --git a/src/usr/user.rs b/src/usr/user.rs index 60cecf7a5..145b794f1 100644 --- a/src/usr/user.rs +++ b/src/usr/user.rs @@ -76,8 +76,9 @@ pub fn login(username: &str) -> Result<(), ExitCode> { let home = format!("/usr/{}", username); sys::process::set_user(username); - sys::process::set_env("HOME", &home); sys::process::set_dir(&home); + sys::process::set_env("USER", &username); + sys::process::set_env("HOME", &home); // TODO: load shell Ok(())