mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 11:37:44 +00:00
checksum: avoid to recompute Regexps
This commit is contained in:
parent
ed15ca1d26
commit
65ddccbeb6
3 changed files with 28 additions and 14 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -3573,6 +3573,7 @@ dependencies = [
|
||||||
"glob",
|
"glob",
|
||||||
"hex",
|
"hex",
|
||||||
"itertools",
|
"itertools",
|
||||||
|
"lazy_static",
|
||||||
"libc",
|
"libc",
|
||||||
"md-5",
|
"md-5",
|
||||||
"memchr",
|
"memchr",
|
||||||
|
|
|
@ -25,6 +25,7 @@ dns-lookup = { workspace = true, optional = true }
|
||||||
dunce = { version = "1.0.4", optional = true }
|
dunce = { version = "1.0.4", optional = true }
|
||||||
wild = "2.2.1"
|
wild = "2.2.1"
|
||||||
glob = { workspace = true }
|
glob = { workspace = true }
|
||||||
|
lazy_static = "1.4.0"
|
||||||
# * optional
|
# * optional
|
||||||
itertools = { workspace = true, optional = true }
|
itertools = { workspace = true, optional = true }
|
||||||
thiserror = { workspace = true, optional = true }
|
thiserror = { workspace = true, optional = true }
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
// spell-checker:ignore anotherfile invalidchecksum regexes JWZG FFFD xffname prefixfilename
|
// spell-checker:ignore anotherfile invalidchecksum regexes JWZG FFFD xffname prefixfilename
|
||||||
|
|
||||||
use data_encoding::BASE64;
|
use data_encoding::BASE64;
|
||||||
|
use lazy_static::lazy_static;
|
||||||
use os_display::Quotable;
|
use os_display::Quotable;
|
||||||
use regex::bytes::{Match, Regex};
|
use regex::bytes::{Match, Regex};
|
||||||
use std::{
|
use std::{
|
||||||
|
@ -428,6 +429,13 @@ const DOUBLE_SPACE_REGEX: &str = r"^(?P<checksum>[a-fA-F0-9]+)\s{2}(?P<filename>
|
||||||
// In this case, we ignore the *
|
// In this case, we ignore the *
|
||||||
const SINGLE_SPACE_REGEX: &str = r"^(?P<checksum>[a-fA-F0-9]+)\s(?P<filename>\*?(?-u:.*))$";
|
const SINGLE_SPACE_REGEX: &str = r"^(?P<checksum>[a-fA-F0-9]+)\s(?P<filename>\*?(?-u:.*))$";
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
static ref R_ALGO_BASED: Regex = Regex::new(ALGO_BASED_REGEX).unwrap();
|
||||||
|
static ref R_DOUBLE_SPACE: Regex = Regex::new(DOUBLE_SPACE_REGEX).unwrap();
|
||||||
|
static ref R_SINGLE_SPACE: Regex = Regex::new(SINGLE_SPACE_REGEX).unwrap();
|
||||||
|
static ref R_ALGO_BASED_BASE_64: Regex = Regex::new(ALGO_BASED_REGEX_BASE64).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
/// Hold the data extracted from a checksum line.
|
/// Hold the data extracted from a checksum line.
|
||||||
struct LineInfo {
|
struct LineInfo {
|
||||||
algo_name: Option<String>,
|
algo_name: Option<String>,
|
||||||
|
@ -435,28 +443,32 @@ struct LineInfo {
|
||||||
checksum: String,
|
checksum: String,
|
||||||
filename: Vec<u8>,
|
filename: Vec<u8>,
|
||||||
|
|
||||||
regex: Regex,
|
regex: &'static Regex,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LineInfo {
|
impl LineInfo {
|
||||||
fn parse(s: impl AsRef<OsStr>, cached_regex: &mut Option<Regex>) -> Option<Self> {
|
fn parse(s: impl AsRef<OsStr>, cached_regex: &mut Option<&'static Regex>) -> Option<Self> {
|
||||||
let regexes = [
|
let regexes: &[(&'static Regex, bool)] = &[
|
||||||
(Regex::new(ALGO_BASED_REGEX).unwrap(), true),
|
(&R_ALGO_BASED, true),
|
||||||
(Regex::new(DOUBLE_SPACE_REGEX).unwrap(), false),
|
(&R_DOUBLE_SPACE, false),
|
||||||
(Regex::new(SINGLE_SPACE_REGEX).unwrap(), false),
|
(&R_SINGLE_SPACE, false),
|
||||||
(Regex::new(ALGO_BASED_REGEX_BASE64).unwrap(), false),
|
(&R_ALGO_BASED_BASE_64, true),
|
||||||
];
|
];
|
||||||
|
|
||||||
let line_bytes = os_str_as_bytes(s.as_ref()).expect("UTF-8 decoding failed");
|
let line_bytes = os_str_as_bytes(s.as_ref()).expect("UTF-8 decoding failed");
|
||||||
|
|
||||||
for (regex, algo_based) in ®exes {
|
for (regex, algo_based) in regexes {
|
||||||
if !regex.is_match(line_bytes) {
|
if !regex.is_match(line_bytes) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut r = regex.clone();
|
let mut r = *regex;
|
||||||
if !algo_based && cached_regex.is_some() {
|
if !algo_based {
|
||||||
r = cached_regex.clone().unwrap();
|
if cached_regex.is_some() {
|
||||||
|
r = cached_regex.unwrap();
|
||||||
|
} else {
|
||||||
|
*cached_regex = Some(r);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(caps) = r.captures(line_bytes) {
|
if let Some(caps) = r.captures(line_bytes) {
|
||||||
|
@ -470,7 +482,7 @@ impl LineInfo {
|
||||||
.map(|m| match_to_string(m).parse::<usize>().unwrap()),
|
.map(|m| match_to_string(m).parse::<usize>().unwrap()),
|
||||||
checksum: caps.name("checksum").map(match_to_string).unwrap(),
|
checksum: caps.name("checksum").map(match_to_string).unwrap(),
|
||||||
filename: caps.name("filename").map(|m| m.as_bytes().into()).unwrap(),
|
filename: caps.name("filename").map(|m| m.as_bytes().into()).unwrap(),
|
||||||
regex: r.clone(),
|
regex: r,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -638,7 +650,7 @@ fn process_checksum_line(
|
||||||
cli_algo_name: Option<&str>,
|
cli_algo_name: Option<&str>,
|
||||||
cli_algo_length: Option<usize>,
|
cli_algo_length: Option<usize>,
|
||||||
opts: ChecksumOptions,
|
opts: ChecksumOptions,
|
||||||
cached_regex: &mut Option<Regex>,
|
cached_regex: &mut Option<&'static Regex>,
|
||||||
) -> Result<(), LineCheckError> {
|
) -> Result<(), LineCheckError> {
|
||||||
let line_bytes = os_str_as_bytes(line)?;
|
let line_bytes = os_str_as_bytes(line)?;
|
||||||
|
|
||||||
|
@ -652,7 +664,7 @@ fn process_checksum_line(
|
||||||
// its cannot be changed (can't have single and double space regexes
|
// its cannot be changed (can't have single and double space regexes
|
||||||
// used in the same file).
|
// used in the same file).
|
||||||
if cached_regex.is_none() && !line_info.is_algo_based() {
|
if cached_regex.is_none() && !line_info.is_algo_based() {
|
||||||
let _ = cached_regex.insert(line_info.regex.clone());
|
let _ = cached_regex.insert(line_info.regex);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut filename_to_check = line_info.filename.as_slice();
|
let mut filename_to_check = line_info.filename.as_slice();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue