Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 22 additions & 9 deletions src/uu/expr/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,16 +94,29 @@ pub fn uu_app() -> Command {
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
// For expr utility we do not want getopts.
// The following usage should work without escaping hyphens: `expr -15 = 1 + 2 \* \( 3 - -4 \)`
let matches = uu_app().try_get_matches_from(args)?;
let token_strings: Vec<&str> = matches
.get_many::<String>(options::EXPRESSION)
.map(|v| v.into_iter().map(|s| s.as_ref()).collect::<Vec<_>>())
.unwrap_or_default();
let args: Vec<String> = args
Comment thread
RenjiSann marked this conversation as resolved.
Outdated
.skip(1) // Skip binary name
.map(|a| a.to_string_lossy().to_string())
.collect();

let res: String = AstNode::parse(&token_strings)?.eval()?.eval_as_string();
println!("{res}");
if !is_truthy(&res.into()) {
return Err(1.into());
if args.len() == 1 && args[0] == "--help" {
let _ = uu_app().print_help();
} else if args.len() == 1 && args[0] == "--version" {
println!("{} {}", uucore::util_name(), crate_version!())
} else {
// The first argument may be "--" and should be be ignored.
let args = if !args.is_empty() && args[0] == "--" {
&args[1..]
} else {
&args
};

let res: String = AstNode::parse(args)?.eval()?.eval_as_string();
println!("{res}");
if !is_truthy(&res.into()) {
return Err(1.into());
}
}

Ok(())
}
22 changes: 11 additions & 11 deletions src/uu/expr/src/syntax_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ pub enum AstNode {
}

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

Expand Down Expand Up @@ -427,33 +427,33 @@ impl AstNode {
}
}

struct Parser<'a> {
input: &'a [&'a str],
struct Parser<'a, S: AsRef<str>> {
input: &'a [S],
index: usize,
}

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

fn next(&mut self) -> ExprResult<&'a str> {
let next = self.input.get(self.index);
if let Some(next) = next {
self.index += 1;
Ok(next)
Ok(next.as_ref())
} else {
// The indexing won't panic, because we know that the input size
// is greater than zero.
Err(ExprError::MissingArgument(
self.input[self.index - 1].into(),
self.input[self.index - 1].as_ref().into(),
))
}
}

fn accept<T>(&mut self, f: impl Fn(&str) -> Option<T>) -> Option<T> {
let next = self.input.get(self.index)?;
let tok = f(next);
let tok = f(next.as_ref());
if let Some(tok) = tok {
self.index += 1;
Some(tok)
Expand All @@ -468,7 +468,7 @@ impl<'a> Parser<'a> {
}
let res = self.parse_expression()?;
if let Some(arg) = self.input.get(self.index) {
return Err(ExprError::UnexpectedArgument(arg.to_string()));
return Err(ExprError::UnexpectedArgument(arg.as_ref().into()));
}
Ok(res)
}
Expand Down Expand Up @@ -556,12 +556,12 @@ impl<'a> Parser<'a> {
// at `self.index - 1`. So this indexing won't panic.
Ok(_) => {
return Err(ExprError::ExpectedClosingBraceInsteadOf(
self.input[self.index - 1].into(),
self.input[self.index - 1].as_ref().into(),
));
}
Err(ExprError::MissingArgument(_)) => {
return Err(ExprError::ExpectedClosingBraceAfter(
self.input[self.index - 1].into(),
self.input[self.index - 1].as_ref().into(),
));
}
Err(e) => return Err(e),
Expand Down