fixed the $0 parameter not being populated correctly
This commit is contained in:
@@ -20,6 +20,10 @@ use super::{
|
||||
ParsedSrc, Redir, RedirType,
|
||||
};
|
||||
|
||||
thread_local! {
|
||||
static RECURSE_DEPTH: std::cell::Cell<usize> = const { std::cell::Cell::new(0) };
|
||||
}
|
||||
|
||||
pub struct ScopeGuard;
|
||||
|
||||
|
||||
@@ -105,7 +109,12 @@ impl ExecArgs {
|
||||
pub fn exec_input(input: String, io_stack: Option<IoStack>, interactive: bool) -> ShResult<()> {
|
||||
let log_tab = read_logic(|l| l.clone());
|
||||
let input = expand_aliases(input, HashSet::new(), &log_tab);
|
||||
let mut parser = ParsedSrc::new(Arc::new(input));
|
||||
let lex_flags = if interactive {
|
||||
super::lex::LexFlags::INTERACTIVE
|
||||
} else {
|
||||
super::lex::LexFlags::empty()
|
||||
};
|
||||
let mut parser = ParsedSrc::new(Arc::new(input)).with_lex_flags(lex_flags);
|
||||
if let Err(errors) = parser.parse_src() {
|
||||
for error in errors {
|
||||
eprintln!("{error}");
|
||||
@@ -170,6 +179,10 @@ impl Dispatcher {
|
||||
self.exec_builtin(node)
|
||||
} else if is_subsh(node.get_command().cloned()) {
|
||||
self.exec_subsh(node)
|
||||
} else if crate::state::read_shopts(|s| s.core.autocd) && Path::new(cmd.span.as_str()).is_dir() {
|
||||
let dir = cmd.span.as_str().to_string();
|
||||
let stack = IoStack { stack: self.io_stack.clone() };
|
||||
exec_input(format!("cd {dir}"), Some(stack), self.interactive)
|
||||
} else {
|
||||
self.exec_cmd(node)
|
||||
}
|
||||
@@ -266,6 +279,21 @@ impl Dispatcher {
|
||||
unreachable!()
|
||||
};
|
||||
|
||||
let max_depth = crate::state::read_shopts(|s| s.core.max_recurse_depth);
|
||||
let depth = RECURSE_DEPTH.with(|d| {
|
||||
let cur = d.get();
|
||||
d.set(cur + 1);
|
||||
cur + 1
|
||||
});
|
||||
if depth > max_depth {
|
||||
RECURSE_DEPTH.with(|d| d.set(d.get() - 1));
|
||||
return Err(ShErr::full(
|
||||
ShErrKind::InternalErr,
|
||||
format!("maximum recursion depth ({max_depth}) exceeded"),
|
||||
blame,
|
||||
));
|
||||
}
|
||||
|
||||
let env_vars = self.set_assignments(assignments, AssignBehavior::Export)?;
|
||||
let _var_guard = VarCtxGuard::new(env_vars.into_iter().collect());
|
||||
|
||||
@@ -273,27 +301,30 @@ impl Dispatcher {
|
||||
|
||||
let func_name = argv.remove(0).span.as_str().to_string();
|
||||
let argv = prepare_argv(argv)?;
|
||||
if let Some(func) = read_logic(|l| l.get_func(&func_name)) {
|
||||
let result = if let Some(func) = read_logic(|l| l.get_func(&func_name)) {
|
||||
let _guard = ScopeGuard::exclusive_scope(Some(argv));
|
||||
|
||||
if let Err(e) = self.exec_brc_grp((*func).clone()) {
|
||||
match e.kind() {
|
||||
ShErrKind::FuncReturn(code) => {
|
||||
state::set_status(*code);
|
||||
return Ok(());
|
||||
Ok(())
|
||||
}
|
||||
_ => return Err(e),
|
||||
_ => Err(e),
|
||||
}
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Ok(())
|
||||
} else {
|
||||
Err(ShErr::full(
|
||||
ShErrKind::InternalErr,
|
||||
format!("Failed to find function '{}'", func_name),
|
||||
blame,
|
||||
))
|
||||
}
|
||||
};
|
||||
|
||||
RECURSE_DEPTH.with(|d| d.set(d.get() - 1));
|
||||
result
|
||||
}
|
||||
fn exec_brc_grp(&mut self, brc_grp: Node) -> ShResult<()> {
|
||||
let NdRule::BraceGrp { body } = brc_grp.class else {
|
||||
|
||||
@@ -156,10 +156,10 @@ pub struct LexStream {
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct LexFlags: u32 {
|
||||
/// Return comment tokens
|
||||
const LEX_COMMENTS = 0b000000001;
|
||||
/// The lexer is operating in interactive mode
|
||||
const INTERACTIVE = 0b000000001;
|
||||
/// Allow unfinished input
|
||||
const LEX_UNFINISHED = 0b000000010;
|
||||
/// The next string-type token is a command name
|
||||
@@ -740,7 +740,7 @@ impl Iterator for LexStream {
|
||||
}
|
||||
self.get_token(ch_idx..self.cursor, TkRule::Sep)
|
||||
}
|
||||
'#' => {
|
||||
'#' if !self.flags.contains(LexFlags::INTERACTIVE) || crate::state::read_shopts(|s| s.core.interactive_comments) => {
|
||||
let ch_idx = self.cursor;
|
||||
self.cursor += 1;
|
||||
|
||||
|
||||
@@ -44,6 +44,7 @@ macro_rules! try_match {
|
||||
pub struct ParsedSrc {
|
||||
pub src: Arc<String>,
|
||||
pub ast: Ast,
|
||||
pub lex_flags: LexFlags,
|
||||
}
|
||||
|
||||
impl ParsedSrc {
|
||||
@@ -51,11 +52,16 @@ impl ParsedSrc {
|
||||
Self {
|
||||
src,
|
||||
ast: Ast::new(vec![]),
|
||||
lex_flags: LexFlags::empty(),
|
||||
}
|
||||
}
|
||||
pub fn with_lex_flags(mut self, flags: LexFlags) -> Self {
|
||||
self.lex_flags = flags;
|
||||
self
|
||||
}
|
||||
pub fn parse_src(&mut self) -> Result<(), Vec<ShErr>> {
|
||||
let mut tokens = vec![];
|
||||
for lex_result in LexStream::new(self.src.clone(), LexFlags::empty()) {
|
||||
for lex_result in LexStream::new(self.src.clone(), self.lex_flags) {
|
||||
match lex_result {
|
||||
Ok(token) => tokens.push(token),
|
||||
Err(error) => return Err(vec![error]),
|
||||
|
||||
Reference in New Issue
Block a user