mirror of
https://github.com/uutils/coreutils
synced 2024-10-06 16:09:08 +00:00
expr: implement regular expressions
This commit is contained in:
parent
eb75085595
commit
9abc3208d3
473
Cargo.lock
generated
473
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -171,7 +171,7 @@ To do
|
|||
* [x] echo
|
||||
* [x] env
|
||||
* [x] expand
|
||||
* [ ] expr (almost done, no regular expressions)
|
||||
* [x] expr
|
||||
* [x] factor
|
||||
* [x] false
|
||||
* [x] fmt
|
||||
|
|
|
@ -8,8 +8,8 @@ name = "uu_date"
|
|||
path = "date.rs"
|
||||
|
||||
[dependencies]
|
||||
chrono = "*"
|
||||
clap = "*"
|
||||
chrono = "0.4"
|
||||
clap = "2.25"
|
||||
uucore = { path="../uucore" }
|
||||
|
||||
[[bin]]
|
||||
|
|
|
@ -15,7 +15,7 @@ extern crate clap;
|
|||
extern crate uucore;
|
||||
|
||||
use chrono::{DateTime, FixedOffset, Offset, Local};
|
||||
use chrono::offset::utc::UTC;
|
||||
use chrono::offset::Utc;
|
||||
use std::fs::File;
|
||||
use std::io::{BufRead, BufReader};
|
||||
use std::path::PathBuf;
|
||||
|
@ -123,7 +123,7 @@ pub fn uumain(args: Vec<String>) -> i32 {
|
|||
// Get the current time, either in the local time zone or UTC.
|
||||
let now: DateTime<FixedOffset> = match settings.utc {
|
||||
true => {
|
||||
let now = UTC::now();
|
||||
let now = Utc::now();
|
||||
now.with_timezone(&now.offset().fix())
|
||||
}
|
||||
false => {
|
||||
|
|
|
@ -9,6 +9,7 @@ path = "expr.rs"
|
|||
|
||||
[dependencies]
|
||||
libc = "*"
|
||||
onig = "1.1"
|
||||
uucore = { path="../uucore" }
|
||||
|
||||
[[bin]]
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#[macro_use]
|
||||
extern crate uucore;
|
||||
extern crate onig;
|
||||
|
||||
mod tokens;
|
||||
mod syntax_tree;
|
||||
|
@ -95,9 +96,9 @@ separates increasing precedence groups. EXPRESSION may be:
|
|||
ARG1 / ARG2 arithmetic quotient of ARG1 divided by ARG2
|
||||
ARG1 % ARG2 arithmetic remainder of ARG1 divided by ARG2
|
||||
|
||||
STRING : REGEXP [NOT IMPLEMENTED] anchored pattern match of REGEXP in STRING
|
||||
STRING : REGEXP anchored pattern match of REGEXP in STRING
|
||||
|
||||
match STRING REGEXP [NOT IMPLEMENTED] same as STRING : REGEXP
|
||||
match STRING REGEXP same as STRING : REGEXP
|
||||
substr STRING POS LENGTH substring of STRING, POS counted from 1
|
||||
index STRING CHARS index in STRING where any CHARS is found, or 0
|
||||
length STRING length of STRING
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
//!
|
||||
|
||||
use tokens::{Token};
|
||||
use onig::{Regex, Syntax, REGEX_OPTION_NONE};
|
||||
|
||||
type TokenStack = Vec<(usize, Token)>;
|
||||
pub type OperandsList = Vec< Box<ASTNode> >;
|
||||
|
@ -105,6 +106,7 @@ impl ASTNode {
|
|||
),
|
||||
"|" => infix_operator_or(&operand_values),
|
||||
"&" => infix_operator_and(&operand_values),
|
||||
":" | "match" => operator_match(&operand_values),
|
||||
"length" => prefix_operator_length( &operand_values ),
|
||||
"index" => prefix_operator_index( &operand_values ),
|
||||
"substr" => prefix_operator_substr( &operand_values ),
|
||||
|
@ -350,6 +352,25 @@ fn infix_operator_and( values: &Vec<String> ) -> Result<String, String> {
|
|||
}
|
||||
}
|
||||
|
||||
fn operator_match(values: &Vec<String>) -> Result<String, String> {
|
||||
assert!(values.len() == 2);
|
||||
let re = match Regex::with_options(&values[1], REGEX_OPTION_NONE, Syntax::grep()) {
|
||||
Ok(m) => m,
|
||||
Err(err) => return Err(err.description().to_string())
|
||||
};
|
||||
if re.captures_len() > 0 {
|
||||
Ok(match re.captures(&values[0]) {
|
||||
Some(captures) => captures.at(1).unwrap().to_string(),
|
||||
None => "".to_string()
|
||||
})
|
||||
} else {
|
||||
Ok(match re.find(&values[0]) {
|
||||
Some((start, end)) => (end - start).to_string(),
|
||||
None => "0".to_string()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn prefix_operator_length( values: &Vec<String> ) -> Result<String, String> {
|
||||
assert!( values.len() == 1 );
|
||||
Ok( values[0].len().to_string() )
|
||||
|
|
|
@ -295,12 +295,12 @@ fn hashsum(algoname: &str, mut digest: Box<Digest>, files: Vec<String>, binary:
|
|||
for (i, line) in buffer.lines().enumerate() {
|
||||
let line = safe_unwrap!(line);
|
||||
let (ck_filename, sum, binary_check) = match gnu_re.captures(&line) {
|
||||
Some(caps) => (caps.name("fileName").unwrap(),
|
||||
caps.name("digest").unwrap().to_ascii_lowercase(),
|
||||
caps.name("binary").unwrap() == "*"),
|
||||
Some(caps) => (caps.name("fileName").unwrap().as_str(),
|
||||
caps.name("digest").unwrap().as_str().to_ascii_lowercase(),
|
||||
caps.name("binary").unwrap().as_str() == "*"),
|
||||
None => match bsd_re.captures(&line) {
|
||||
Some(caps) => (caps.name("fileName").unwrap(),
|
||||
caps.name("digest").unwrap().to_ascii_lowercase(),
|
||||
Some(caps) => (caps.name("fileName").unwrap().as_str(),
|
||||
caps.name("digest").unwrap().as_str().to_ascii_lowercase(),
|
||||
true),
|
||||
None => {
|
||||
bad_format += 1;
|
||||
|
|
|
@ -8,12 +8,12 @@ name = "uu_ptx"
|
|||
path = "ptx.rs"
|
||||
|
||||
[dependencies]
|
||||
getopts = "*"
|
||||
libc = "*"
|
||||
aho-corasick = "*"
|
||||
memchr = "*"
|
||||
regex-syntax = "*"
|
||||
regex = "*"
|
||||
getopts = "0.2"
|
||||
libc = "0.2"
|
||||
aho-corasick = "0.6"
|
||||
memchr = "1.0"
|
||||
regex-syntax = "0.4"
|
||||
regex = "0.2"
|
||||
uucore = { path="../uucore" }
|
||||
|
||||
[[bin]]
|
||||
|
|
|
@ -237,11 +237,12 @@ fn create_word_set(config: &Config, filter: &WordFilter,
|
|||
for line in &lines.0 {
|
||||
// if -r, exclude reference from word set
|
||||
let (ref_beg, ref_end) = match ref_reg.find(line) {
|
||||
Some(x) => x,
|
||||
Some(x) => (x.start(), x.end()),
|
||||
None => (0,0)
|
||||
};
|
||||
// match words with given regex
|
||||
for (beg, end) in reg.find_iter(line) {
|
||||
for mat in reg.find_iter(line) {
|
||||
let (beg, end) = (mat.start(), mat.end());
|
||||
if config.input_ref && ((beg, end) == (ref_beg, ref_end)) {
|
||||
continue;
|
||||
}
|
||||
|
@ -279,7 +280,7 @@ fn get_reference(config: &Config, word_ref: &WordRef, line: &str) ->
|
|||
} else if config.input_ref {
|
||||
let reg = Regex::new(&config.context_regex).unwrap();
|
||||
let (beg, end) = match reg.find(line) {
|
||||
Some(x) => x,
|
||||
Some(x) => (x.start(), x.end()),
|
||||
None => (0,0)
|
||||
};
|
||||
format!("{}", &line[beg .. end])
|
||||
|
|
Loading…
Reference in a new issue