Skip to content

Commit 92b8359

Browse files
committed
feat: Implement $* parameters; make $# respect function arguments
1 parent 79979db commit 92b8359

File tree

4 files changed

+38
-2
lines changed

4 files changed

+38
-2
lines changed

src/exec.rs

+24-2
Original file line numberDiff line numberDiff line change
@@ -1013,12 +1013,34 @@ impl ShellContext {
10131013
.skip(1)
10141014
.cloned()
10151015
.collect(),
1016-
Parameter::Pound => vec![format!("{}", config.positional_args.len() - 1)],
1016+
Parameter::Star => match self.function_args.last() {
1017+
Some(args) => args,
1018+
None => &config.positional_args,
1019+
}
1020+
.iter()
1021+
.skip(1)
1022+
.map(|word| {
1023+
crate::parser::parse_word(word)
1024+
.map_err(|e| {
1025+
ProcessExit::ExecError(CommandExecError::BadStarPositional { err: e })
1026+
})
1027+
.and_then(|word| self.evaluate_tl_word(&word, config))
1028+
})
1029+
.flatten_ok()
1030+
.collect::<Result<Vec<_>, _>>()?,
1031+
Parameter::Pound => vec![format!(
1032+
"{}",
1033+
match self.function_args.last() {
1034+
Some(args) => args,
1035+
None => &config.positional_args,
1036+
}
1037+
.len()
1038+
- 1
1039+
)],
10171040
Parameter::Dollar => vec![format!("{}", std::process::id())],
10181041
Parameter::Question => vec![format!("{}", self.exit_code)],
10191042
Parameter::Bang => vec![format!("{}", self.pid)],
10201043

1021-
Parameter::Star => todo!(), // Like @ but runs evaluate_word on each word
10221044
Parameter::Dash => todo!(), // Options of current run invocation. Perhaps could be useful?
10231045
})
10241046
}

src/out.rs

+3
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,9 @@ pub fn process_finish(output_stream: &StandardStream, status: &ProcessExit) {
378378
fn exec_error(error: &CommandExecError) -> String {
379379
match error {
380380
CommandExecError::CommandFailed { err } => format!("{}", err),
381+
CommandExecError::BadStarPositional { err } => {
382+
format!("Could not parse positional parameter: {}", err)
383+
} //TODO: Which parameter in particular?
381384
CommandExecError::InvalidGlob { glob, err } => {
382385
format!("Invalid glob pattern: {}: {}", glob, err)
383386
}

src/parser/mod.rs

+8
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ pub mod token;
1616
use ast::AtomicTopLevelCommand;
1717
use lexer::Lexer;
1818

19+
use self::ast::ComplexWord;
20+
1921
#[derive(Debug, Clone)]
2022
pub struct RunscriptSource {
2123
pub path: PathBuf,
@@ -67,6 +69,12 @@ pub fn parse_command(command: &str) -> Result<AtomicTopLevelCommand, ParseError>
6769
parser.complete_command().map(Option::unwrap)
6870
}
6971

72+
pub fn parse_word(word: &str) -> Result<ComplexWord, ParseError> {
73+
let lexer = Lexer::new(word.chars());
74+
let mut parser = Parser::<_>::new(lexer);
75+
parser.word().map(Option::unwrap)
76+
}
77+
7078
pub fn parse_runscript(source: RunscriptSource) -> Result<Runscript, RunscriptParseError> {
7179
let line_indices = source
7280
.source

src/process.rs

+3
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,11 @@ use std::str::Utf8Error;
55

66
use glob::PatternError;
77

8+
use crate::parser::parse::ParseError;
9+
810
#[derive(Debug)]
911
pub enum CommandExecError {
12+
BadStarPositional { err: ParseError },
1013
InvalidGlob { glob: String, err: PatternError },
1114
NoGlobMatches { glob: String },
1215
CommandFailed { err: std::io::Error },

0 commit comments

Comments
 (0)