From 4a88b5c888da073407431cf435527ce69b032e3a Mon Sep 17 00:00:00 2001 From: Aqua-sama Date: Tue, 24 Nov 2020 23:28:03 +0200 Subject: Refactoring Add doc/rc.pdf --- src/parser/command.rs | 204 -------------------------------------------------- 1 file changed, 204 deletions(-) delete mode 100644 src/parser/command.rs (limited to 'src/parser') diff --git a/src/parser/command.rs b/src/parser/command.rs deleted file mode 100644 index 4dea8a6..0000000 --- a/src/parser/command.rs +++ /dev/null @@ -1,204 +0,0 @@ -use std::io::{Error, ErrorKind}; -use std::path::{Path, PathBuf}; -use std::process::{Command, ExitStatus}; - -// > overwrite -// >> append -// | pipe - -#[derive(Debug)] -enum Redirect { - Std, - FileOverwrite(String), - FileAppend(String), -} - -#[derive(Debug, PartialEq, Copy, Clone)] -pub(in crate::parser) enum RunOn { - Always, - ExitSuccess, - ExitFailure, -} - -impl RunOn { - pub(in crate::parser) fn can_run(&self, status: &Option) -> bool { - if *self == RunOn::Always { - return true; - } - match status { - Some(s) => { - (*self == RunOn::ExitSuccess && s.success()) - || (*self == RunOn::ExitFailure && !s.success()) - } - None => true, - } - } -} - -pub(in crate::parser) enum RunResult { - Command(ExitStatus), - Builtin, -} - -#[derive(Debug)] -pub struct CommandInfo { - args: Vec, - stdout: Redirect, - pub(in crate::parser) when: RunOn, -} - -impl CommandInfo { - pub(in crate::parser) fn new(line: &str, when: RunOn) -> CommandInfo { - let (args, stdout) = tokenize(line); - CommandInfo { args, stdout, when } - } - - pub(in crate::parser) fn run( - &self, - home: &PathBuf, - status: &Option, - ) -> Result { - match self.args[0].as_str() { - "!" => { - println!("{:?}", status); - Ok(RunResult::Builtin) - } - "cd" => cd(&self.args[1..], home), - "exit" => { - std::process::exit(0); - } - "set" => set(&self.args[1..]), - "unset" => unset(&self.args[1..]), - _ => { - let mut child = Command::new(&self.args[0]).args(&self.args[1..]).spawn()?; - Ok(RunResult::Command(child.wait().unwrap())) - } - } - } -} - -enum TokenType { - Argument, - StdoutFileOverwrite, - StdoutFileAppend, -} - -fn tokenize(line: &str) -> (Vec, Redirect) { - let mut args: Vec = Vec::new(); - let mut stdout = Redirect::Std; - - let mut iter = line.chars().peekable(); - let mut token = String::new(); - let mut token_type = TokenType::Argument; - let mut quote = false; - - while let Some(i) = iter.next() { - match i { - ' ' => { - if quote { - token.push(' '); - } - } - '\'' => match iter.peek() { - Some(&'\'') | Some(&'>') | Some(&'&') => { - token.push(iter.next().unwrap()); - } - _ => { - quote = !quote; - } - }, - '>' => { - if iter.peek() == Some(&'>') { - token_type = TokenType::StdoutFileAppend; - iter.next(); - } else { - token_type = TokenType::StdoutFileOverwrite; - } - } - _ => { - token.push(i); - } - } - - if !token.is_empty() && ((iter.peek() == Some(&' ') && !quote) || iter.peek() == None) { - match token_type { - TokenType::Argument => args.push(token), - TokenType::StdoutFileOverwrite => stdout = Redirect::FileOverwrite(token), - TokenType::StdoutFileAppend => stdout = Redirect::FileAppend(token), - } - token = String::new(); - } - } - - (args, stdout) -} -/* -#[test] -fn test_tokenizer() { - { - let ls = tokenize("ls -l"); - assert_eq!(ls.args, vec!("ls", "-l")); - let string = tokenize("ls -l 'something else'"); - assert_eq!(string.args, vec!("ls", "-l", "something else")); - let escape = tokenize("ls -l 'junction jan''s'"); - assert_eq!(escape.args, vec!("ls", "-l", "junction jan\'s")); - } - { - let o = tokenize("&& ls"); - assert_eq!(o.args, vec!("ls")); - assert_eq!(o.when, RunOn::ExitSuccess); - let f = tokenize("|| ls"); - assert_eq!(f.args, vec!("ls")); - assert_eq!(f.when, RunOn::ExitFailure); - } - println!("{:?}", tokenize("ls -l something'>")); - println!("{:?}", tokenize("ls -l something'>'>")); - println!("{:?}", tokenize("ls -l something >output")); - println!("{:?}", tokenize("ls -l something > output")); - println!("{:?}", tokenize("ls -l something >'junction jan''s'")); - println!("{:?}", tokenize("ls -l something >>output")); - println!("{:?}", tokenize("ls -l something >> output")); - println!("{:?}", tokenize("ls -l something >>'junction jan''s'")); -} -*/ -fn cd(args: &[String], home: &PathBuf) -> Result { - if args.len() > 1 { - return Err(Error::new( - ErrorKind::InvalidInput, - "Too many arguments passed to cd", - )); - } - - let root = if args.len() == 0 { - home.to_path_buf() - } else { - std::fs::canonicalize(Path::new(args[0].as_str()))? - }; - - match std::env::set_current_dir(&root) { - Ok(_) => Ok(RunResult::Builtin), - Err(e) => Err(e), - } -} - -fn set(args: &[String]) -> Result { - if args.len() != 2 { - return Err(Error::new( - ErrorKind::InvalidInput, - format!("set requires 2 arguments, got {}", args.len()), - )); - } - std::env::set_var(&args[0], &args[1]); - Ok(RunResult::Builtin) -} - -fn unset(args: &[String]) -> Result { - if args.len() != 1 { - return Err(Error::new( - ErrorKind::InvalidInput, - format!("unset requires 1 argument, got {}", args.len()), - )); - } - std::env::remove_var(&args[0]); - Ok(RunResult::Builtin) -} -- cgit v1.2.1