From 34c1b99256befce0205e8d95aa6ededd811cb7f8 Mon Sep 17 00:00:00 2001 From: Sag0Sag0 <Sag0Sag0@users.noreply.github.com> Date: Sun, 18 Mar 2018 09:34:24 +1100 Subject: [PATCH] Add builtin type (#713) * Add builtin type * Add most of mmsticks changes * made get_command_info() return a Cow<'a, str> --- src/lib/builtins/command_info.rs | 86 ++++++++++++++++++++++++++++++++ src/lib/builtins/mod.rs | 40 ++++----------- 2 files changed, 97 insertions(+), 29 deletions(-) create mode 100644 src/lib/builtins/command_info.rs diff --git a/src/lib/builtins/command_info.rs b/src/lib/builtins/command_info.rs new file mode 100644 index 00000000..f18699cb --- /dev/null +++ b/src/lib/builtins/command_info.rs @@ -0,0 +1,86 @@ +use sys; +use shell::Shell; +use shell::status::*; +use builtins::man_pages::*; + +use std::env; +use std::path::Path; +use std::borrow::Cow; + +pub(crate) fn which(args: &[&str], shell: &mut Shell) -> Result<i32, ()> { + if check_help(args, MAN_WHICH) { + return Ok(SUCCESS) + } + + if args.len() == 1 { + eprintln!("which: Expected at least 1 args, got only 0"); + return Err(()) + } + + let mut result = SUCCESS; + for &command in &args[1..] { + if let Ok(c_type) = get_command_info(command, shell) { + match c_type.as_ref() { + "alias" => { + let alias = shell.variables.aliases.get(command).unwrap(); + println!("{}: alias to {}", command, alias); + }, + "function" => println!("{}: function", command), + "builtin" => println!("{}: built-in shell command", command), + _path => println!("{}", _path) + } + } else { + result = FAILURE; + } + } + Ok(result) +} + +pub(crate) fn find_type(args: &[&str], shell: &mut Shell) -> Result<i32, ()> { + // Type does not accept help flags, aka "--help". + if args.len() == 1 { + eprintln!("type: Expected at least 1 args, got only 0"); + return Err(()) + } + + let mut result = FAILURE; + for &command in &args[1..] { + if let Ok(c_type) = get_command_info(command, shell) { + match c_type.as_ref() { + "alias" => { + let alias = shell.variables.aliases.get(command).unwrap(); + println!("{} is aliased to `{}`", command, alias); + }, + // TODO Make it print the function. + "function" => println!("{} is a function", command), + "builtin" => println!("{} is a shell builtin", command), + _path => println!("{} is {}", command, _path) + } + result = SUCCESS; + } else { + eprintln!("type: {}: not found", command); + } + } + Ok(result) +} + +pub(crate) fn get_command_info<'a>(command: &str, shell: &mut Shell) -> Result<Cow<'a, str>, ()> { + if shell.variables.aliases.get(command).is_some() { + return Ok("alias".into()) + } else if shell.functions.contains_key(command) { + return Ok("function".into()) + } else if shell.builtins.contains_key(command) { + return Ok("builtin".into()) + } else { + for path in env::var("PATH") + .unwrap_or("/bin".to_string()) + .split(sys::PATH_SEPARATOR) + { + let executable = Path::new(path).join(command); + if executable.is_file() { + return Ok(executable.display().to_string().into()) + } + } + } + Err(()) +} \ No newline at end of file diff --git a/src/lib/builtins/mod.rs b/src/lib/builtins/mod.rs index c3cef783..eb39feef 100644 --- a/src/lib/builtins/mod.rs +++ b/src/lib/builtins/mod.rs @@ -4,6 +4,7 @@ pub mod functions; pub mod calc; pub mod random; +mod command_info; mod conditionals; mod job_control; mod man_pages; @@ -16,6 +17,7 @@ mod exec; mod ion; mod is; +use self::command_info::*; use self::conditionals::{contains, ends_with, starts_with}; use self::echo::echo; use self::exec::exec; @@ -33,7 +35,6 @@ use types::Array; use std::env; use std::error::Error; use std::io::{self, Write}; -use std::path::Path; use parser::Terminator; use parser::pipelines::{PipeItem, Pipeline}; @@ -110,6 +111,7 @@ pub const BUILTINS: &'static BuiltinMap = &map!( "suspend" => builtin_suspend : "Suspends the shell with a SIGTSTOP signal", "test" => builtin_test : "Performs tests on files and text", "true" => builtin_true : "Do nothing, successfully", + "type" => builtin_type : "indicates how a command would be interpreted", "unalias" => builtin_unalias : "Delete an alias", "wait" => builtin_wait : "Waits until all running background processes have completed", "which" => builtin_which : "Shows the full path of commands" @@ -606,37 +608,17 @@ fn builtin_exists(args: &[&str], shell: &mut Shell) -> i32 { } fn builtin_which(args: &[&str], shell: &mut Shell) -> i32 { - if check_help(args, MAN_WHICH) { - return SUCCESS; + match which(args, shell) { + Ok(result) => result, + Err(()) => FAILURE } +} - let mut result = SUCCESS; - 'outer: for &command in &args[1..] { - if let Some(alias) = shell.variables.aliases.get(command) { - println!("{}: alias to {}", command, alias); - continue; - } else if shell.functions.contains_key(command) { - println!("{}: function", command); - continue; - } else if shell.builtins.contains_key(command) { - println!("{}: built-in shell command", command); - continue; - } else { - for path in env::var("PATH") - .unwrap_or("/bin".to_string()) - .split(sys::PATH_SEPARATOR) - { - let executable = Path::new(path).join(command); - if executable.is_file() { - println!("{}", executable.display()); - continue 'outer; - } - } - result = FAILURE; - println!("{} not found", command); - } +fn builtin_type(args: &[&str], shell: &mut Shell) -> i32 { + match find_type(args, shell) { + Ok(result) => result, + Err(()) => FAILURE } - result } fn builtin_isatty(args: &[&str], _: &mut Shell) -> i32 { -- GitLab