diff --git a/src/lib/builtins/helpers.rs b/src/lib/builtins/helpers.rs index 22cdd38c35cec3d00115e328f7072c9931d18965..f50fdd94016de4cf4633bcbd3ab2bf7c11e0d596 100644 --- a/src/lib/builtins/helpers.rs +++ b/src/lib/builtins/helpers.rs @@ -5,9 +5,11 @@ pub struct Status(i32); impl Status { pub const COULD_NOT_EXEC: Self = Status(126); + pub const FALSE: Self = Status(1); pub const NO_SUCH_COMMAND: Self = Status(127); pub const SUCCESS: Self = Status(0); pub const TERMINATED: Self = Status(143); + pub const TRUE: Self = Status(0); pub fn from_signal(signal: i32) -> Self { Status(128 + signal) } diff --git a/src/lib/builtins/mod.rs b/src/lib/builtins/mod.rs index 0e1c8280c52aec5e3ee9eda0938679ffc5350f91..25c872a892e7d2276e96eff99d48fe6cb6aed6f8 100644 --- a/src/lib/builtins/mod.rs +++ b/src/lib/builtins/mod.rs @@ -29,7 +29,7 @@ pub use self::{ source::builtin_source, status::builtin_status, test::test, - variables::{alias, drop_alias, drop_array, drop_variable}, + variables::{builtin_alias, builtin_unalias, drop_array, drop_variable}, }; use crate as ion_shell; use crate::{ @@ -383,7 +383,7 @@ pub fn dirs(args: &[types::Str], shell: &mut Shell<'_>) -> Status { (false, false) => |(_, x)| x.to_string_lossy(), }; - let mut iter = shell.dir_stack().dirs().enumerate().map(mapper); + let mut iter = shell.dir_stack().dirs(); if let Some(arg) = num_arg { let num = match parse_numeric_arg(arg.as_ref()) { @@ -393,7 +393,7 @@ pub fn dirs(args: &[types::Str], shell: &mut Shell<'_>) -> Status { } _ => return Status::error(format!("ion: dirs: {}: invalid argument", arg)), }; - match iter.nth(num) { + match iter.nth(num).map(|x| mapper((num, x))) { Some(x) => { println!("{}", x); Status::SUCCESS @@ -401,7 +401,7 @@ pub fn dirs(args: &[types::Str], shell: &mut Shell<'_>) -> Status { None => Status::error(""), } } else { - println!("{}", iter.join(if multiline { "\n" } else { " " })); + println!("{}", iter.enumerate().map(mapper).format(if multiline { "\n" } else { " " })); Status::SUCCESS } } @@ -478,7 +478,7 @@ pub fn pushd(args: &[types::Str], shell: &mut Shell<'_>) -> Status { .dir_stack() .dirs() .map(|dir| dir.to_str().unwrap_or("ion: no directory found")) - .join(" ") + .format(" ") ); Status::SUCCESS } @@ -545,7 +545,7 @@ pub fn popd(args: &[types::Str], shell: &mut Shell<'_>) -> Status { .dir_stack() .dirs() .map(|dir| dir.to_str().unwrap_or("ion: no directory found")) - .join(" ") + .format(" ") ); Status::SUCCESS } else { @@ -553,15 +553,6 @@ pub fn popd(args: &[types::Str], shell: &mut Shell<'_>) -> Status { } } -pub fn builtin_alias(args: &[types::Str], shell: &mut Shell<'_>) -> Status { - let args_str = args[1..].join(" "); - alias(shell.variables_mut(), &args_str) -} - -pub fn builtin_unalias(args: &[types::Str], shell: &mut Shell<'_>) -> Status { - drop_alias(shell.variables_mut(), args) -} - // TODO There is a man page for fn however the -h and --help flags are not // checked for. pub fn builtin_fn(_: &[types::Str], shell: &mut Shell<'_>) -> Status { @@ -592,7 +583,7 @@ pub fn read(args: &[types::Str], shell: &mut Shell<'_>) -> Status { Ok(buffer) => { shell.variables_mut().set(arg.as_ref(), buffer.trim()); } - Err(_) => return Status::error(""), + Err(_) => return Status::FALSE, } } } else { @@ -651,8 +642,8 @@ pub fn builtin_test(args: &[types::Str], _: &mut Shell<'_>) -> Status { // Do not use `check_help` for the `test` builtin. The // `test` builtin contains a "-h" option. match test(args) { - Ok(true) => Status::SUCCESS, - Ok(false) => Status::error(""), + Ok(true) => Status::TRUE, + Ok(false) => Status::FALSE, Err(why) => Status::error(why), } } @@ -707,7 +698,7 @@ SYNOPSIS DESCRIPTION Sets the exit status to 1." )] -pub fn false_(args: &[types::Str], _: &mut Shell<'_>) -> Status { Status::error("") } +pub fn false_(args: &[types::Str], _: &mut Shell<'_>) -> Status { Status::FALSE } // TODO create a manpage pub fn builtin_wait(_: &[types::Str], shell: &mut Shell<'_>) -> Status { @@ -785,7 +776,7 @@ pub fn builtin_help(args: &[types::Str], shell: &mut Shell<'_>) -> Status { println!("Command helper not found [run 'help']..."); } } else { - println!("{}", shell.builtins().keys().join("")); + println!("{}", shell.builtins().keys().format("")); } Status::SUCCESS } @@ -820,9 +811,9 @@ pub fn matches(args: &[types::Str], _: &mut Shell<'_>) -> Status { }; if re.is_match(input) { - Status::SUCCESS + Status::TRUE } else { - Status::error("") + Status::FALSE } } @@ -884,8 +875,8 @@ AUTHOR )] pub fn exists(args: &[types::Str], shell: &mut Shell<'_>) -> Status { match exists(args, shell) { - Ok(true) => Status::SUCCESS, - Ok(false) => Status::error(""), + Ok(true) => Status::TRUE, + Ok(false) => Status::FALSE, Err(why) => Status::error(why), } } @@ -910,9 +901,9 @@ pub fn isatty(args: &[types::Str], _: &mut Shell<'_>) -> Status { match pid { Ok(r) => { if sys::isatty(r) { - Status::SUCCESS + Status::TRUE } else { - Status::error("") + Status::FALSE } } Err(_) => Status::error("ion: isatty given bad number"), diff --git a/src/lib/builtins/variables.rs b/src/lib/builtins/variables.rs index fd38efeb2fef276e8c9aadc66e5c53957a634a1a..82fa484b4ff10a0ad62389c891d6f58b0a7d35d2 100644 --- a/src/lib/builtins/variables.rs +++ b/src/lib/builtins/variables.rs @@ -3,7 +3,7 @@ use std::io::{self, Write}; use super::Status; -use crate::{shell::variables::Variables, types}; +use crate::{shell::variables::Variables, types, Shell}; fn print_list(vars: &Variables<'_>) { let stdout = io::stdout(); @@ -63,15 +63,15 @@ fn parse_alias(args: &str) -> Binding { /// The `alias` command will define an alias for another command, and thus may be used as a /// command itself. -pub fn alias(vars: &mut Variables<'_>, args: &str) -> Status { - match parse_alias(args) { +pub fn builtin_alias(args: &[types::Str], shell: &mut Shell<'_>) -> Status { + match parse_alias(&args[1..].join(" ")) { Binding::InvalidKey(key) => { return Status::error(format!("ion: alias name, '{}', is invalid", key)); } Binding::KeyValue(key, value) => { - vars.set(&key, types::Alias(value)); + shell.variables_mut().set(&key, types::Alias(value)); } - Binding::ListEntries => print_list(&vars), + Binding::ListEntries => print_list(&shell.variables()), Binding::KeyOnly(key) => { return Status::error(format!("ion: please provide value for alias '{}'", key)); } @@ -80,13 +80,13 @@ pub fn alias(vars: &mut Variables<'_>, args: &str) -> Status { } /// Dropping an alias will erase it from the shell. -pub fn drop_alias<S: AsRef<str>>(vars: &mut Variables<'_>, args: &[S]) -> Status { +pub fn builtin_unalias(args: &[types::Str], shell: &mut Shell<'_>) -> Status { if args.len() <= 1 { return Status::error("ion: you must specify an alias name".to_string()); } for alias in args.iter().skip(1) { - if vars.remove(alias.as_ref()).is_none() { - return Status::error(format!("ion: undefined alias: {}", alias.as_ref())); + if shell.variables_mut().remove(alias.as_ref()).is_none() { + return Status::error(format!("ion: undefined alias: {}", alias)); } } Status::SUCCESS