fixed empty arguments being filtered out during word splitting
This commit is contained in:
@@ -94,9 +94,7 @@ impl Expander {
|
||||
_ => cur_word.push(ch),
|
||||
}
|
||||
}
|
||||
if !cur_word.is_empty() {
|
||||
words.push(cur_word);
|
||||
}
|
||||
words.push(cur_word);
|
||||
words
|
||||
}
|
||||
}
|
||||
@@ -754,7 +752,7 @@ pub fn expand_proc_sub(raw: &str, is_input: bool) -> ShResult<String> {
|
||||
let mut io_stack = IoStack::new();
|
||||
io_stack.push_frame(io_frame);
|
||||
|
||||
if let Err(e) = exec_input(raw.to_string(), Some(io_stack)) {
|
||||
if let Err(e) = exec_input(raw.to_string(), Some(io_stack), false) {
|
||||
eprintln!("{e}");
|
||||
exit(1);
|
||||
}
|
||||
@@ -787,7 +785,7 @@ pub fn expand_cmd_sub(raw: &str) -> ShResult<String> {
|
||||
match unsafe { fork()? } {
|
||||
ForkResult::Child => {
|
||||
io_stack.push_frame(cmd_sub_io_frame);
|
||||
if let Err(e) = exec_input(raw.to_string(), Some(io_stack)) {
|
||||
if let Err(e) = exec_input(raw.to_string(), Some(io_stack), false) {
|
||||
eprintln!("{e}");
|
||||
unsafe { libc::_exit(1) };
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ fn run_script<P: AsRef<Path>>(path: P, args: Vec<String>) -> ShResult<()> {
|
||||
write_vars(|v| v.cur_scope_mut().bpush_arg(arg))
|
||||
}
|
||||
|
||||
exec_input(input, None)
|
||||
exec_input(input, None, false)
|
||||
}
|
||||
|
||||
fn fern_interactive() -> ShResult<()> {
|
||||
@@ -187,7 +187,7 @@ fn fern_interactive() -> ShResult<()> {
|
||||
match readline.process_input() {
|
||||
Ok(ReadlineEvent::Line(input)) => {
|
||||
write_meta(|m| m.start_timer());
|
||||
if let Err(e) = exec_input(input, None) {
|
||||
if let Err(e) = exec_input(input, None, true) {
|
||||
match e.kind() {
|
||||
ShErrKind::CleanExit(code) => {
|
||||
QUIT_CODE.store(*code, Ordering::SeqCst);
|
||||
|
||||
@@ -116,7 +116,7 @@ impl ExecArgs {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn exec_input(input: String, io_stack: Option<IoStack>) -> ShResult<()> {
|
||||
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));
|
||||
@@ -127,7 +127,7 @@ pub fn exec_input(input: String, io_stack: Option<IoStack>) -> ShResult<()> {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let mut dispatcher = Dispatcher::new(parser.extract_nodes());
|
||||
let mut dispatcher = Dispatcher::new(parser.extract_nodes(), interactive);
|
||||
if let Some(mut stack) = io_stack {
|
||||
dispatcher.io_stack.extend(stack.drain(..));
|
||||
}
|
||||
@@ -136,15 +136,17 @@ pub fn exec_input(input: String, io_stack: Option<IoStack>) -> ShResult<()> {
|
||||
|
||||
pub struct Dispatcher {
|
||||
nodes: VecDeque<Node>,
|
||||
interactive: bool,
|
||||
pub io_stack: IoStack,
|
||||
pub job_stack: JobStack,
|
||||
}
|
||||
|
||||
impl Dispatcher {
|
||||
pub fn new(nodes: Vec<Node>) -> Self {
|
||||
pub fn new(nodes: Vec<Node>, interactive: bool) -> Self {
|
||||
let nodes = VecDeque::from(nodes);
|
||||
Self {
|
||||
nodes,
|
||||
interactive,
|
||||
io_stack: IoStack::new(),
|
||||
job_stack: JobStack::new(),
|
||||
}
|
||||
@@ -265,7 +267,7 @@ impl Dispatcher {
|
||||
let subsh_body = subsh.0.to_string();
|
||||
let _guard = ScopeGuard::shared_scope();
|
||||
|
||||
exec_input(subsh_body, None)?;
|
||||
exec_input(subsh_body, None, self.interactive)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -607,6 +609,10 @@ impl Dispatcher {
|
||||
self.io_stack.append_to_frame(cmd.redirs);
|
||||
|
||||
let exec_args = ExecArgs::new(argv)?;
|
||||
if self.interactive {
|
||||
log::info!("expanded argv: {:?}", exec_args.argv.iter().map(|s| s.to_str().unwrap()).collect::<Vec<_>>());
|
||||
}
|
||||
|
||||
let io_frame = self.io_stack.pop_frame();
|
||||
run_fork(
|
||||
io_frame,
|
||||
|
||||
@@ -802,6 +802,6 @@ pub fn source_file(path: PathBuf) -> ShResult<()> {
|
||||
|
||||
let mut buf = String::new();
|
||||
file.read_to_string(&mut buf)?;
|
||||
exec_input(buf, None)?;
|
||||
exec_input(buf, None, false)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user