implemented for loops

This commit is contained in:
2025-04-20 05:16:50 -04:00
parent d741854f5f
commit 11353b2d69
27 changed files with 360 additions and 174 deletions

View File

@@ -30,7 +30,7 @@ pub fn alias(node: Node, io_stack: &mut IoStack, job: &mut JobBldr) -> ShResult<
ShErr::full(
ShErrKind::SyntaxErr,
"alias: Expected an assignment in alias args",
span.into()
span
)
)
};
@@ -41,3 +41,45 @@ pub fn alias(node: Node, io_stack: &mut IoStack, job: &mut JobBldr) -> ShResult<
state::set_status(0);
Ok(())
}
pub fn unalias(node: Node, io_stack: &mut IoStack, job: &mut JobBldr) -> ShResult<()> {
let NdRule::Command { assignments: _, argv } = node.class else {
unreachable!()
};
let (argv, io_frame) = setup_builtin(argv, job, Some((io_stack, node.redirs)))?;
if argv.is_empty() {
// Display the environment variables
let mut alias_output = read_logic(|l| {
l.aliases()
.iter()
.map(|ent| format!("{} = \"{}\"", ent.0, ent.1))
.collect::<Vec<_>>()
});
alias_output.sort(); // Sort them alphabetically
let mut alias_output = alias_output.join("\n"); // Join them with newlines
alias_output.push('\n'); // Push a final newline
let stdout = borrow_fd(STDOUT_FILENO);
write(stdout, alias_output.as_bytes())?; // Write it
} else {
for (arg,span) in argv {
flog!(DEBUG, arg);
if read_logic(|l| l.get_alias(&arg)).is_none() {
return Err(
ShErr::full(
ShErrKind::SyntaxErr,
format!("unalias: alias '{arg}' not found"),
span
)
)
};
write_logic(|l| l.remove_alias(&arg))
}
}
io_frame.unwrap().restore()?;
state::set_status(0);
Ok(())
}

View File

@@ -95,7 +95,7 @@ fn parse_job_id(arg: &str, blame: Span) -> ShResult<usize> {
ShErr::full(
ShErrKind::InternalErr,
"Found a job but no table id in parse_job_id()",
blame.into()
blame
)
)
}
@@ -121,7 +121,7 @@ fn parse_job_id(arg: &str, blame: Span) -> ShResult<usize> {
ShErr::full(
ShErrKind::InternalErr,
"Found a job but no table id in parse_job_id()",
blame.into()
blame
)
)
}
@@ -130,7 +130,7 @@ fn parse_job_id(arg: &str, blame: Span) -> ShResult<usize> {
ShErr::full(
ShErrKind::SyntaxErr,
format!("Invalid fd arg: {}", arg),
blame.into()
blame
)
)
}
@@ -151,12 +151,12 @@ pub fn jobs(node: Node, io_stack: &mut IoStack, job: &mut JobBldr) -> ShResult<(
ShErr::full(
ShErrKind::SyntaxErr,
"Invalid flag in jobs call",
span.into()
span
)
)
}
chars.next();
while let Some(ch) = chars.next() {
for ch in chars {
let flag = match ch {
'l' => JobCmdFlags::LONG,
'p' => JobCmdFlags::PIDS,
@@ -167,7 +167,7 @@ pub fn jobs(node: Node, io_stack: &mut IoStack, job: &mut JobBldr) -> ShResult<(
ShErr::full(
ShErrKind::SyntaxErr,
"Invalid flag in jobs call",
span.into()
span
)
)

View File

@@ -14,7 +14,7 @@ pub mod flowctl;
pub mod zoltraak;
pub mod shopt;
pub const BUILTINS: [&str;16] = [
pub const BUILTINS: [&str;17] = [
"echo",
"cd",
"export",
@@ -25,6 +25,7 @@ pub const BUILTINS: [&str;16] = [
"fg",
"bg",
"alias",
"unalias",
"return",
"break",
"continue",
@@ -55,11 +56,12 @@ pub const BUILTINS: [&str;16] = [
/// * If redirections are given to this function, the caller must call `IoFrame.restore()` on the returned `IoFrame`
/// * If redirections are given, the second field of the resulting tuple will *always* be `Some()`
/// * If no redirections are given, the second field will *always* be `None`
type SetupReturns = ShResult<(Vec<(String,Span)>, Option<IoFrame>)>;
pub fn setup_builtin(
argv: Vec<Tk>,
job: &mut JobBldr,
io_mode: Option<(&mut IoStack,Vec<Redir>)>,
) -> ShResult<(Vec<(String,Span)>, Option<IoFrame>)> {
) -> SetupReturns {
let mut argv: Vec<(String,Span)> = prepare_argv(argv)?;
let child_pgid = if let Some(pgid) = job.pgid() {

View File

@@ -16,7 +16,7 @@ pub fn shift(node: Node, job: &mut JobBldr) -> ShResult<()> {
ShErr::full(
ShErrKind::ExecFail,
"Expected a number in shift args",
span.into()
span
)
)
};

View File

@@ -16,7 +16,7 @@ pub fn source(node: Node, job: &mut JobBldr) -> ShResult<()> {
ShErr::full(
ShErrKind::ExecFail,
"source: File not found",
span.into()
span
)
);
}
@@ -25,7 +25,7 @@ pub fn source(node: Node, job: &mut JobBldr) -> ShResult<()> {
ShErr::full(
ShErrKind::ExecFail,
"source: Given path is not a file",
span.into()
span
)
);
}

View File

@@ -4,7 +4,7 @@ use crate::{getopt::{get_opts_from_tokens, Opt, OptSet}, jobs::JobBldr, libsh::e
use super::setup_builtin;
pub const ZOLTRAAK_OPTS: LazyLock<OptSet> = LazyLock::new(|| {
pub static ZOLTRAAK_OPTS: LazyLock<OptSet> = LazyLock::new(|| {
[
Opt::Long("dry-run".into()),
Opt::Long("confirm".into()),
@@ -90,7 +90,7 @@ pub fn zoltraak(node: Node, io_stack: &mut IoStack, job: &mut JobBldr) -> ShResu
}
if let Err(e) = annihilate(&arg, flags).blame(span) {
io_frame.restore()?;
return Err(e.into());
return Err(e);
}
}