mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-27 11:07:44 +00:00
Merge pull request #7352 from RenjiSann/expr-no-clap
expr: Get rid of clap for performance reasons
This commit is contained in:
commit
9c0ff86caa
2 changed files with 33 additions and 20 deletions
|
@ -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
|
||||
.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();
|
||||
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(())
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
||||
|
@ -427,13 +427,13 @@ 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 }
|
||||
}
|
||||
|
||||
|
@ -441,19 +441,19 @@ impl<'a> Parser<'a> {
|
|||
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)
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue