aboutsummaryrefslogtreecommitdiff
path: root/src/makefile
diff options
context:
space:
mode:
Diffstat (limited to 'src/makefile')
-rw-r--r--src/makefile/functions.rs36
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::*;