Skip to content

Commit 2aa196b

Browse files
RenjiSannsylvestre
authored andcommitted
expr: Do not parse arguments using clap
1 parent 2805dc7 commit 2aa196b

File tree

2 files changed

+33
-20
lines changed

2 files changed

+33
-20
lines changed

src/uu/expr/src/expr.rs

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -94,16 +94,29 @@ pub fn uu_app() -> Command {
9494
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
9595
// For expr utility we do not want getopts.
9696
// The following usage should work without escaping hyphens: `expr -15 = 1 + 2 \* \( 3 - -4 \)`
97-
let matches = uu_app().try_get_matches_from(args)?;
98-
let token_strings: Vec<&str> = matches
99-
.get_many::<String>(options::EXPRESSION)
100-
.map(|v| v.into_iter().map(|s| s.as_ref()).collect::<Vec<_>>())
101-
.unwrap_or_default();
97+
let args: Vec<String> = args
98+
.skip(1) // Skip binary name
99+
.map(|a| a.to_string_lossy().to_string())
100+
.collect();
102101

103-
let res: String = AstNode::parse(&token_strings)?.eval()?.eval_as_string();
104-
println!("{res}");
105-
if !is_truthy(&res.into()) {
106-
return Err(1.into());
102+
if args.len() == 1 && args[0] == "--help" {
103+
let _ = uu_app().print_help();
104+
} else if args.len() == 1 && args[0] == "--version" {
105+
println!("{} {}", uucore::util_name(), crate_version!())
106+
} else {
107+
// The first argument may be "--" and should be be ignored.
108+
let args = if !args.is_empty() && args[0] == "--" {
109+
&args[1..]
110+
} else {
111+
&args
112+
};
113+
114+
let res: String = AstNode::parse(args)?.eval()?.eval_as_string();
115+
println!("{res}");
116+
if !is_truthy(&res.into()) {
117+
return Err(1.into());
118+
}
107119
}
120+
108121
Ok(())
109122
}

src/uu/expr/src/syntax_tree.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,7 @@ pub enum AstNode {
365365
}
366366

367367
impl AstNode {
368-
pub fn parse(input: &[&str]) -> ExprResult<Self> {
368+
pub fn parse(input: &[impl AsRef<str>]) -> ExprResult<Self> {
369369
Parser::new(input).parse()
370370
}
371371

@@ -427,33 +427,33 @@ impl AstNode {
427427
}
428428
}
429429

430-
struct Parser<'a> {
431-
input: &'a [&'a str],
430+
struct Parser<'a, S: AsRef<str>> {
431+
input: &'a [S],
432432
index: usize,
433433
}
434434

435-
impl<'a> Parser<'a> {
436-
fn new(input: &'a [&'a str]) -> Self {
435+
impl<'a, S: AsRef<str>> Parser<'a, S> {
436+
fn new(input: &'a [S]) -> Self {
437437
Self { input, index: 0 }
438438
}
439439

440440
fn next(&mut self) -> ExprResult<&'a str> {
441441
let next = self.input.get(self.index);
442442
if let Some(next) = next {
443443
self.index += 1;
444-
Ok(next)
444+
Ok(next.as_ref())
445445
} else {
446446
// The indexing won't panic, because we know that the input size
447447
// is greater than zero.
448448
Err(ExprError::MissingArgument(
449-
self.input[self.index - 1].into(),
449+
self.input[self.index - 1].as_ref().into(),
450450
))
451451
}
452452
}
453453

454454
fn accept<T>(&mut self, f: impl Fn(&str) -> Option<T>) -> Option<T> {
455455
let next = self.input.get(self.index)?;
456-
let tok = f(next);
456+
let tok = f(next.as_ref());
457457
if let Some(tok) = tok {
458458
self.index += 1;
459459
Some(tok)
@@ -468,7 +468,7 @@ impl<'a> Parser<'a> {
468468
}
469469
let res = self.parse_expression()?;
470470
if let Some(arg) = self.input.get(self.index) {
471-
return Err(ExprError::UnexpectedArgument(arg.to_string()));
471+
return Err(ExprError::UnexpectedArgument(arg.as_ref().into()));
472472
}
473473
Ok(res)
474474
}
@@ -556,12 +556,12 @@ impl<'a> Parser<'a> {
556556
// at `self.index - 1`. So this indexing won't panic.
557557
Ok(_) => {
558558
return Err(ExprError::ExpectedClosingBraceInsteadOf(
559-
self.input[self.index - 1].into(),
559+
self.input[self.index - 1].as_ref().into(),
560560
));
561561
}
562562
Err(ExprError::MissingArgument(_)) => {
563563
return Err(ExprError::ExpectedClosingBraceAfter(
564-
self.input[self.index - 1].into(),
564+
self.input[self.index - 1].as_ref().into(),
565565
));
566566
}
567567
Err(e) => return Err(e),

0 commit comments

Comments
 (0)