diff options
author | Aqua-sama <aqua@iserlohn-fortress.net> | 2020-10-17 17:55:44 +0300 |
---|---|---|
committer | Aqua-sama <aqua@iserlohn-fortress.net> | 2020-10-17 19:22:59 +0300 |
commit | 3cce88f681029385ac3e80a9990346f9272f15e1 (patch) | |
tree | 885e3b994134857f54831761bd1c6cbda25d5772 /src/parser | |
parent | Add ! builtin to display the last status (diff) | |
download | rshell-3cce88f681029385ac3e80a9990346f9272f15e1.tar.xz |
Add new tokenizer
Diffstat (limited to 'src/parser')
-rw-r--r-- | src/parser/command.rs | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/src/parser/command.rs b/src/parser/command.rs new file mode 100644 index 0000000..496614f --- /dev/null +++ b/src/parser/command.rs @@ -0,0 +1,91 @@ +use std::io::{Error, ErrorKind}; +use std::path::{Path, PathBuf}; + +#[derive(Debug)] +pub enum Redirect { + Std, + FileOverwrite(String), + FileAppend(String), +} + +#[derive(Debug, PartialEq)] +pub enum RunOn { + Always, + ExitSuccess, + ExitFailure, +} + +pub enum RunResult { + Command(std::process::ExitStatus), + Builtin, +} + +#[derive(Debug)] +pub struct CommandInfo { + pub args: Vec<String>, + pub stdout: Redirect, + pub when: RunOn, +} + +impl CommandInfo { + pub fn new() -> CommandInfo { + CommandInfo { + args: Vec::new(), + stdout: Redirect::Std, + when: RunOn::Always, + } + } + + pub fn run( + &self, + home: &PathBuf, + cwd: &mut PathBuf, + status: &Option<std::process::ExitStatus>, + ) -> Result<RunResult, Error> { + match self.args[0].as_str() { + "!" => { + println!("{:?}", status); + Ok(RunResult::Builtin) + } + "cd" => match cd(&self.args[1..], home) { + Ok(p) => { + *cwd = p; + Ok(RunResult::Builtin) + } + Err(e) => Err(e), + }, + "exit" => { + std::process::exit(0); + } + _ => { + let mut child = std::process::Command::new(&self.args[0]) + .args(&self.args[1..]) + .spawn()?; + Ok(RunResult::Command(child.wait().unwrap())) + } + } + } +} + +fn cd(args: &[String], home: &PathBuf) -> Result<PathBuf, Error> { + if args.len() > 1 { + return Err(Error::new( + ErrorKind::InvalidInput, + "Too many arguments passed to cd", + )); + } + + if args.len() == 0 { + return Ok(home.to_path_buf()); + } + + let root = match std::fs::canonicalize(Path::new(args[0].as_str())) { + Ok(p) => p, + Err(_) => Path::new("/").to_path_buf(), + }; + + match std::env::set_current_dir(&root) { + Ok(_) => Ok(root.to_path_buf()), + Err(e) => Err(e), + } +} |