diff options
Diffstat (limited to 'src/macro_processor')
| -rw-r--r-- | src/macro_processor/macro_processor.rs | 123 | 
1 files changed, 118 insertions, 5 deletions
diff --git a/src/macro_processor/macro_processor.rs b/src/macro_processor/macro_processor.rs index 2e8675f..b36783b 100644 --- a/src/macro_processor/macro_processor.rs +++ b/src/macro_processor/macro_processor.rs @@ -38,6 +38,12 @@ fn smp_builtin_define(      args: &mut [String],  ) -> Result<String, SMPError> {      if args.len() < 1 { +        smp.warnings +            .push(MacroProcessorWarning::from_macro_invocation( +                macro_name, +                args, +                format!("Wrong number of arguments, expected at least 1"), +            ));          return Ok(macro_name.to_string());      }      let arg0 = smp.process_input(&args[0])?; @@ -57,6 +63,12 @@ fn smp_builtin_ifdef(      args: &mut [String],  ) -> Result<String, SMPError> {      if args.len() < 2 { +        smp.warnings +            .push(MacroProcessorWarning::from_macro_invocation( +                macro_name, +                args, +                format!("Wrong number of arguments, expected at least 2"), +            ));          return Ok(macro_name.to_string());      }      // We need to expand the first argument here as well, but we need to make the parser @@ -77,6 +89,12 @@ fn smp_builtin_ifndef(      args: &mut [String],  ) -> Result<String, SMPError> {      if args.len() < 2 { +        smp.warnings +            .push(MacroProcessorWarning::from_macro_invocation( +                macro_name, +                args, +                format!("Wrong number of arguments, expected at least 2"), +            ));          return Ok(macro_name.to_string());      }      // We need to expand the first argument here as well, but we need to make the parser @@ -97,6 +115,12 @@ fn smp_builtin_ifeq(      args: &mut [String],  ) -> Result<String, SMPError> {      if args.len() < 3 { +        smp.warnings +            .push(MacroProcessorWarning::from_macro_invocation( +                macro_name, +                args, +                format!("Wrong number of arguments, expected at least 3"), +            ));          return Ok(macro_name.to_string());      }      let arg0 = smp.process_input(&args[0])?; @@ -117,6 +141,12 @@ fn smp_builtin_ifneq(      args: &mut [String],  ) -> Result<String, SMPError> {      if args.len() < 3 { +        smp.warnings +            .push(MacroProcessorWarning::from_macro_invocation( +                macro_name, +                args, +                format!("Wrong number of arguments, expected at least 3"), +            ));          return Ok(macro_name.to_string());      }      let arg0 = smp.process_input(&args[0])?; @@ -137,6 +167,12 @@ fn smp_builtin_include(      args: &mut [String],  ) -> Result<String, SMPError> {      if args.len() < 1 { +        smp.warnings +            .push(MacroProcessorWarning::from_macro_invocation( +                macro_name, +                args, +                format!("Wrong number of arguments, expected at least 1"), +            ));          return Ok(macro_name.to_string());      }      let arg0 = smp.process_input(&args[0])?; @@ -151,6 +187,12 @@ fn smp_builtin_include_verbatim(      args: &mut [String],  ) -> Result<String, SMPError> {      if args.len() < 1 { +        smp.warnings +            .push(MacroProcessorWarning::from_macro_invocation( +                macro_name, +                args, +                format!("Wrong number of arguments, expected at least 1"), +            ));          return Ok(macro_name.to_string());      }      let arg0 = smp.process_input(&args[0])?; @@ -164,6 +206,12 @@ fn smp_builtin_shell(      args: &mut [String],  ) -> Result<String, SMPError> {      if args.len() < 1 { +        smp.warnings +            .push(MacroProcessorWarning::from_macro_invocation( +                macro_name, +                args, +                format!("Wrong number of arguments, expected at least 1"), +            ));          return Ok(macro_name.to_string());      }      let arg0 = smp.process_input(&args[0])?; @@ -171,7 +219,15 @@ fn smp_builtin_shell(      match res {          Ok(output) => String::from_utf8(output.stdout)              .map_err(|e| SMPError::ShellCommandError(1, Box::new(e))), -        Err(_) => Ok(String::new()), +        Err(e) => { +            smp.warnings +                .push(MacroProcessorWarning::from_macro_invocation( +                    macro_name, +                    args, +                    format!("Error running shell command ({})", e), +                )); +            Ok(String::new()) +        }      }  } @@ -182,6 +238,12 @@ fn smp_builtin_expr(      args: &mut [String],  ) -> Result<String, SMPError> {      if args.len() < 1 { +        smp.warnings +            .push(MacroProcessorWarning::from_macro_invocation( +                macro_name, +                args, +                format!("Wrong number of arguments, expected at least 1"), +            ));          return Ok(macro_name.to_string());      } @@ -189,11 +251,20 @@ fn smp_builtin_expr(          *arg = smp.process_input(&arg)?;      } -    let res = Command::new("expr").args(args).output(); +    let args = args.to_vec(); +    let res = Command::new("expr").args(args.clone()).output();      match res {          Ok(output) => String::from_utf8(output.stdout)              .map_err(|e| SMPError::ShellCommandError(1, Box::new(e))), -        Err(_) => Ok(String::new()), +        Err(e) => { +            smp.warnings +                .push(MacroProcessorWarning::from_macro_invocation( +                    macro_name, +                    &args, +                    format!("Error running shell command ({})", e), +                )); +            Ok(String::new()) +        }      }  } @@ -225,11 +296,27 @@ fn smp_builtin_format_time(      args: &mut [String],  ) -> Result<String, SMPError> {      if args.len() < 2 { +        smp.warnings +            .push(MacroProcessorWarning::from_macro_invocation( +                macro_name, +                args, +                format!("Wrong number of arguments, expected at least 2"), +            ));          return Ok(macro_name.to_string());      }      let timestamp = smp.process_input(&args[1])?; -    let dt = chrono::DateTime::parse_from_rfc3339(×tamp) -        .map_err(|_| SMPError::UnknownError(87, None))?; +    let dt = match chrono::DateTime::parse_from_rfc3339(×tamp) { +        Ok(dt) => dt, +        Err(e) => { +            smp.warnings +                .push(MacroProcessorWarning::from_macro_invocation( +                    macro_name, +                    args, +                    format!("Could not parse datetime {} ({})", timestamp, e), +                )); +            return Ok(timestamp); +        } +    };      Ok(format!("{}", dt.format(&args[0])))  } @@ -258,6 +345,29 @@ enum ParserState {      DNL,  } +#[derive(Clone, Debug)] +pub struct MacroProcessorWarning { +    pub description: String, +} + +impl MacroProcessorWarning { +    pub fn new(description: String) -> Self { +        MacroProcessorWarning { description } +    } + +    pub fn from_macro_invocation(macro_name: &str, args: &[String], description: String) -> Self { +        let mut desc = format!("{}(", macro_name); +        for (i, arg) in args.iter().enumerate() { +            desc.push_str(arg); +            if i < (args.len() - 1) { +                desc.push(','); +            } +        } +        desc.push_str(&format!(") -> {}", description)); +        MacroProcessorWarning { description: desc } +    } +} +  /// Defines a MacroProcessor object, with it's associated state  /// the state mostly includes the defined macros  #[derive(Clone)] @@ -266,6 +376,8 @@ pub struct MacroProcessor {      pub macros: HashMap<String, MacroType>,      /// All macro invocations that has happened      pub macro_invocations: Vec<(String, Vec<String>)>, +    /// Emitted warnings +    pub warnings: Vec<MacroProcessorWarning>,  }  impl MacroProcessor { @@ -273,6 +385,7 @@ impl MacroProcessor {          let mut smp = Self {              macros: HashMap::new(),              macro_invocations: Vec::new(), +            warnings: Vec::new(),          };          smp.define_builtins();          smp  | 
