summaryrefslogtreecommitdiffstats
path: root/src/builtins.rs
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2022-01-03 04:59:12 -0500
committerJesse Luehrs <doy@tozt.net>2022-01-03 04:59:12 -0500
commit120ab82f07fbae69482c68f9f526860ce28e7a9a (patch)
treeb89d5ce49738bd73ea495f36f5b7431ce12edb08 /src/builtins.rs
parent936d5fa20ea275d1a573d030aca0bd5e8cf2bf92 (diff)
downloadnbsh-120ab82f07fbae69482c68f9f526860ce28e7a9a.tar.gz
nbsh-120ab82f07fbae69482c68f9f526860ce28e7a9a.zip
add echo builtin for testing
Diffstat (limited to 'src/builtins.rs')
-rw-r--r--src/builtins.rs46
1 files changed, 46 insertions, 0 deletions
diff --git a/src/builtins.rs b/src/builtins.rs
index 8ff1222..638496b 100644
--- a/src/builtins.rs
+++ b/src/builtins.rs
@@ -161,6 +161,7 @@ static BUILTINS: once_cell::sync::Lazy<
> = once_cell::sync::Lazy::new(|| {
let mut builtins = std::collections::HashMap::new();
builtins.insert("cd", &cd as Builtin);
+ builtins.insert("echo", &echo);
builtins.insert("and", &and);
builtins.insert("or", &or);
builtins.insert("command", &command);
@@ -303,6 +304,51 @@ fn cd(
})
}
+// clippy can't tell that the type is necessary
+#[allow(clippy::unnecessary_wraps)]
+// mostly just for testing and ensuring that builtins work, i'll likely remove
+// this later, since the binary seems totally fine
+fn echo(
+ exe: &crate::parse::Exe,
+ env: &crate::command::Env,
+ io: Io,
+) -> anyhow::Result<Child> {
+ async fn async_echo(
+ exe: &crate::parse::Exe,
+ _env: &crate::command::Env,
+ io: Io,
+ ) -> std::process::ExitStatus {
+ macro_rules! write_stdout {
+ ($bytes:expr) => {
+ if let Err(e) = io.write_stdout($bytes).await {
+ io.write_stderr(format!("echo: {}", e).as_bytes())
+ .await
+ .unwrap();
+ return async_std::process::ExitStatus::from_raw(1 << 8);
+ }
+ };
+ }
+ let count = exe.args().count();
+ for (i, arg) in exe.args().enumerate() {
+ write_stdout!(arg.as_bytes());
+ if i == count - 1 {
+ write_stdout!(b"\n");
+ } else {
+ write_stdout!(b" ");
+ }
+ }
+
+ async_std::process::ExitStatus::from_raw(0)
+ }
+
+ let exe = exe.clone();
+ let env = env.clone();
+ Ok(Child {
+ fut: Box::pin(async move { async_echo(&exe, &env, io).await }),
+ wrapped_child: None,
+ })
+}
+
fn and(
exe: &crate::parse::Exe,
env: &crate::command::Env,