diff options
-rw-r--r-- | src/makefile/functions.rs | 36 |
1 files changed, 35 insertions, 1 deletions
diff --git a/src/makefile/functions.rs b/src/makefile/functions.rs index a61a0cf..8df1892 100644 --- a/src/makefile/functions.rs +++ b/src/makefile/functions.rs @@ -62,7 +62,10 @@ pub fn expand_call(name: &str, args: &[TokenString], macros: &MacroSet) -> Resul } // shell - "shell" => todo!(), + "shell" => { + assert_eq!(args.len(), 1); + shell::shell(macros, &args[0]) + } // fallback _ => bail!("function not implemented: {}", name), @@ -274,6 +277,37 @@ mod origin { } } +mod shell { + use super::*; + + use std::env; + use std::process::{Command, Stdio}; + + pub fn shell(macros: &MacroSet, command: &TokenString) -> Result<String> { + // TODO bring this in from command_line + let command = macros.expand(command)?; + let (program, args) = if cfg!(windows) { + let cmd = env::var("COMSPEC").unwrap_or_else(|_| "cmd.exe".into()); + let args = vec!["/c", &command]; + (cmd, args) + } else { + let sh = env::var("SHELL").unwrap_or_else(|_| "/bin/sh".into()); + let args = vec!["-e", "-c", &command]; + (sh, args) + }; + let result = Command::new(program) + .args(args) + .stderr(Stdio::inherit()) + .output()?; + let status = result.status; + // TODO set .SHELLSTATUS + Ok(String::from_utf8(result.stdout)? + .replace("\r\n", "\n") + .trim_end_matches("\n") + .replace("\n", " ")) + } +} + #[cfg(test)] mod test { use super::*; |