Phase 5: Ausführung und Output implementieren und archivieren
This commit is contained in:
@@ -1668,44 +1668,23 @@ fn bi_lpos(
|
||||
Ok(Some(Value::Int(spalte as i16 + 1)))
|
||||
}
|
||||
|
||||
/// Gemeinsamer Kern von `SHELL` als Anweisung und als Funktion.
|
||||
fn shell_ausfuehren(befehl: &str) -> Result<i32, RuntimeError> {
|
||||
let mut cmd = if cfg!(windows) {
|
||||
let mut c = std::process::Command::new("cmd");
|
||||
c.args(["/C", befehl]);
|
||||
c
|
||||
} else {
|
||||
let mut c = std::process::Command::new("sh");
|
||||
c.args(["-c", befehl]);
|
||||
c
|
||||
};
|
||||
cmd.status()
|
||||
.map(|s| s.code().unwrap_or(0))
|
||||
.map_err(|_| RuntimeError(53))
|
||||
}
|
||||
|
||||
fn bi_shell_stmt(
|
||||
_: &mut RtState,
|
||||
_: &mut dyn Host,
|
||||
host: &mut dyn Host,
|
||||
a: &mut [Value],
|
||||
) -> Result<Option<Value>, RuntimeError> {
|
||||
let befehl = match a.first() {
|
||||
Some(Value::Str(s)) => s.to_string(),
|
||||
_ => String::new(),
|
||||
let command = match a.first() {
|
||||
Some(Value::Str(s)) => s.as_ref(),
|
||||
_ => "",
|
||||
};
|
||||
if befehl.is_empty() {
|
||||
return Ok(None);
|
||||
}
|
||||
shell_ausfuehren(&befehl).map(|_| None)
|
||||
host.shell(command).map(|_| None)
|
||||
}
|
||||
|
||||
fn bi_shell_fn(
|
||||
_: &mut RtState,
|
||||
_: &mut dyn Host,
|
||||
host: &mut dyn Host,
|
||||
a: &mut [Value],
|
||||
) -> Result<Option<Value>, RuntimeError> {
|
||||
let code = shell_ausfuehren(&arg_str(a, 0)?)?;
|
||||
Ok(Some(Value::Lng(code)))
|
||||
host.shell(&arg_str(a, 0)?).map(|code| code.map(Value::Lng))
|
||||
}
|
||||
|
||||
/// `MKI$`/`MKL$`/`MKS$`/`MKD$`/`MKC$` — Zahl in ihre Bytedarstellung.
|
||||
|
||||
@@ -158,6 +158,15 @@ pub mod taste {
|
||||
}
|
||||
|
||||
pub trait Host {
|
||||
/// None means the frontend has scheduled a terminal handoff; retry the
|
||||
/// same request after it supplies the child result.
|
||||
fn shell(&mut self, command: &str) -> Result<Option<i32>, crate::errors::RuntimeError> {
|
||||
shell_command(command)
|
||||
.status()
|
||||
.map(|s| Some(s.code().unwrap_or(0)))
|
||||
.map_err(|_| crate::errors::RuntimeError(53))
|
||||
}
|
||||
|
||||
/// Aktuellen Bildschirmzustand anzeigen.
|
||||
fn present(&mut self, screen: &TextScreen);
|
||||
|
||||
@@ -388,3 +397,12 @@ mod tests {
|
||||
assert_eq!(h.next_event(false), None);
|
||||
}
|
||||
}
|
||||
|
||||
/// Shared child command, inheriting the foreground terminal and stdio.
|
||||
pub fn shell_command(command: &str) -> std::process::Command {
|
||||
let mut child = std::process::Command::new(if cfg!(windows) { "cmd" } else { "sh" });
|
||||
if !command.is_empty() {
|
||||
child.args([if cfg!(windows) { "/C" } else { "-c" }, command]);
|
||||
}
|
||||
child
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user