diff --git a/src/lib/builtins/exec.rs b/src/lib/builtins/exec.rs index 6aceb2815d1b21849f6cb7c00d2c63808d64b56a..4837dcde68ae966200d160584c99d306e8595b10 100644 --- a/src/lib/builtins/exec.rs +++ b/src/lib/builtins/exec.rs @@ -8,13 +8,11 @@ use std::error::Error; /// Executes the givent commmand. pub fn exec(shell: &mut Shell, args: &[small::String]) -> Result<(), small::String> { - const CLEAR_ENV: u8 = 1; - - let mut flags = 0u8; + let mut clear_env = false; let mut idx = 0; for arg in args.iter() { match &**arg { - "-c" => flags |= CLEAR_ENV, + "-c" => clear_env = true, _ if check_help(args, MAN_EXEC) => { return Ok(()); } @@ -27,7 +25,7 @@ pub fn exec(shell: &mut Shell, args: &[small::String]) -> Result<(), small::Stri Some(argument) => { let args = if args.len() > idx + 1 { &args[idx + 1..] } else { &[] }; shell.prep_for_exit(); - Err(execve(argument, args, (flags & CLEAR_ENV) == 1).description().into()) + Err(execve(argument, args, clear_env).description().into()) } None => Err("no command provided".into()), } diff --git a/src/lib/parser/statement/parse.rs b/src/lib/parser/statement/parse.rs index 5fc25d0b9e242b574714997d6fd60f6807c5bd92..17379be1c42ecdf026208bfea87cfdb953587f5a 100644 --- a/src/lib/parser/statement/parse.rs +++ b/src/lib/parser/statement/parse.rs @@ -7,7 +7,7 @@ use crate::{ builtins::BuiltinMap, lexers::{assignment_lexer, ArgumentSplitter}, shell::{ - flow_control::{Case, ElseIf, ExportAction, LocalAction, Statement}, + flow_control::{Case, ElseIf, ExportAction, IfMode, LocalAction, Statement}, status::FAILURE, }, }; @@ -83,7 +83,7 @@ pub fn parse<'a>(code: &str, builtins: &BuiltinMap<'a>) -> Statement<'a> { success: Vec::new(), else_if: Vec::new(), failure: Vec::new(), - mode: 0, + mode: IfMode::Success, }, "else" => Statement::Else, _ if cmd.starts_with("else") => { @@ -279,7 +279,7 @@ mod tests { success: vec![], else_if: vec![], failure: vec![], - mode: 0, + mode: IfMode::Success, }; assert_eq!(correct_parse, parsed_if); diff --git a/src/lib/shell/assignments.rs b/src/lib/shell/assignments.rs index 6b5dba35614a475de05cd6b7313497c0b27a190c..cb9b9fcca20e4115ebfedfa1a7bca50468588489 100644 --- a/src/lib/shell/assignments.rs +++ b/src/lib/shell/assignments.rs @@ -183,7 +183,7 @@ impl<'b> Shell<'b> { } } -// This should logically be a method over iterator, but Value is only accessible in the main repo +// This should logically be a method over operator, but Value is only accessible in the main repo // TODO: too much allocations occur over here. We need to expand variables before they get // parsed fn apply<'b>(op: Operator, lhs: &Value<'b>, rhs: Value<'b>) -> Result<Value<'b>, OpError> { diff --git a/src/lib/shell/flow_control.rs b/src/lib/shell/flow_control.rs index 98280149cec6e64fbe98e6978731f870da34074f..b275c96e7947e39131a787e0062798af307b99a0 100644 --- a/src/lib/shell/flow_control.rs +++ b/src/lib/shell/flow_control.rs @@ -62,6 +62,13 @@ pub enum ExportAction { Assign(String, Operator, String), } +#[derive(Debug, PartialEq, Clone, Copy, Hash)] +pub enum IfMode { + Success, + ElseIf, + Else, +} + // TODO: Enable statements and expressions to contain &str values. #[derive(Debug, PartialEq, Clone)] pub enum Statement<'a> { @@ -73,7 +80,7 @@ pub enum Statement<'a> { success: Block<'a>, else_if: Vec<ElseIf<'a>>, failure: Block<'a>, - mode: u8, // {0 = success, 1 = else_if, 2 = failure} + mode: IfMode, }, ElseIf(ElseIf<'a>), Function { @@ -206,44 +213,42 @@ pub fn insert_statement<'a>( } } Statement::And(_) | Statement::Or(_) if !block.is_empty() => { - let mut pushed = true; - match block.last_mut().unwrap() { + let pushed = match block.last_mut().unwrap() { Statement::If { ref mut expression, ref mode, ref success, ref mut else_if, .. - } => match *mode { - 0 if success.is_empty() => { + } => match mode { + IfMode::Success if success.is_empty() => { // Insert into If expression if there's no previous statement. expression.push(statement.clone()); + true } - 1 => { + IfMode::ElseIf => { // Try to insert into last ElseIf expression if there's no previous // statement. - if let Some(eif) = else_if.last_mut() { - if eif.success.is_empty() { - eif.expression.push(statement.clone()); - } else { - pushed = false; - } + let eif = else_if.last_mut().expect("Missmatch in 'If' mode!"); + if eif.success.is_empty() { + eif.expression.push(statement.clone()); + true } else { - // should not be reached... - unreachable!("Missmatch in 'If' mode!") + false } } - _ => pushed = false, + _ => false, }, Statement::While { ref mut expression, ref statements } => { if statements.is_empty() { expression.push(statement.clone()); + true } else { - pushed = false; + false } } - _ => pushed = false, - } + _ => false, + }; if !pushed { insert_into_block(block, statement)?; } @@ -306,25 +311,24 @@ fn insert_into_block<'a>( ref mut success, ref mut else_if, ref mut failure, ref mut mode, .. } => match statement { Statement::ElseIf(eif) => { - if *mode > 1 { + if *mode == IfMode::Else { return Err("ion: error: ElseIf { .. } found after Else"); } else { - *mode = 1; + *mode = IfMode::ElseIf; else_if.push(eif); } } Statement::Else => { - if *mode == 2 { + if *mode == IfMode::Else { return Err("ion: error: Else block already exists"); } else { - *mode = 2; + *mode = IfMode::Else; } } - _ => match *mode { - 0 => success.push(statement), - 1 => else_if.last_mut().unwrap().success.push(statement), - 2 => failure.push(statement), - _ => unreachable!(), + _ => match mode { + IfMode::Success => success.push(statement), + IfMode::ElseIf => else_if.last_mut().unwrap().success.push(statement), + IfMode::Else => failure.push(statement), }, }, _ => unreachable!("Not block-like statement pushed to stack!"), @@ -430,7 +434,7 @@ mod tests { success: Vec::new(), else_if: Vec::new(), failure: Vec::new(), - mode: 0, + mode: IfMode::Success, } } fn new_case() -> Statement<'static> { diff --git a/src/lib/shell/pipe_exec/foreground.rs b/src/lib/shell/pipe_exec/foreground.rs index ab4506fb4918bdaeb69520bf4b50a3be7983810a..463eec4717e5e24486fef726f4868a84af733d49 100644 --- a/src/lib/shell/pipe_exec/foreground.rs +++ b/src/lib/shell/pipe_exec/foreground.rs @@ -29,9 +29,9 @@ impl ForegroundSignals { pub fn was_processed(&self) -> Option<BackgroundResult> { let reply = self.reply.load(Ordering::SeqCst) as u8; self.reply.store(0, Ordering::SeqCst); - if reply & ERRORED != 0 { + if reply == ERRORED { Some(BackgroundResult::Errored) - } else if reply & REPLIED != 0 { + } else if reply == REPLIED { Some(BackgroundResult::Status(self.status.load(Ordering::SeqCst) as u8)) } else { None