numfmt: implement the last changes#11411
Conversation
Merging this PR will improve performance by 23.64%
Performance Changes
Comparing Footnotes
|
339ca87 to
524c1b1
Compare
|
and it passed! |
32deeba to
840c848
Compare
|
@cakebaker i can split it into several if you want |
|
GNU testsuite comparison: |
|
GNU testsuite comparison: |
@sylvestre yes, please. |
|
@cakebaker started: |
|
GNU testsuite comparison: |
src/uu/numfmt/src/format.rs
Outdated
| if valid_part == "." { | ||
| return Some(translate!("numfmt-error-invalid-suffix", "input" => s.quote())); | ||
| } | ||
|
|
||
| if valid_part.ends_with('.') { | ||
| return Some(translate!("numfmt-error-invalid-number", "input" => s.quote())); | ||
| } |
There was a problem hiding this comment.
The name valid_part is a bit unlucky as its content can be invalid ;-)
src/uu/numfmt/src/format.rs
Outdated
| let rest = &s[valid_part.len()..]; | ||
| if let Some(after_sep) = rest.strip_prefix(unit_separator) { | ||
| // Check if the next char is a valid suffix letter | ||
| let mut chars = after_sep.chars(); | ||
| let has_suffix = chars | ||
| .next() | ||
| .is_some_and(|c| RawSuffix::try_from(&c).is_ok()); | ||
| if has_suffix { | ||
| let suffix_char_len = 1; | ||
| let with_i = | ||
| chars.next() == Some('i') && [Unit::Auto, Unit::Iec(true)].contains(&unit); | ||
| let suffix_len = if with_i { | ||
| suffix_char_len + 1 | ||
| } else { | ||
| suffix_char_len | ||
| }; | ||
| valid_part.len() + unit_separator.len() + suffix_len | ||
| } else { |
There was a problem hiding this comment.
I would move this stuff into its own function to get rid of the nesting and all the else { valid_part.len() }. Something like:
fn some_great_function_name(
s: &str,
valid_part: &str,
unit: Unit,
unit_separator: &str,
) -> Option<usize> {
let after_sep = s.get(valid_part.len()..)?.strip_prefix(unit_separator)?;
let mut chars = after_sep.chars();
let first_char = chars.next()?;
RawSuffix::try_from(&first_char).ok()?;
let is_iec = chars.next() == Some('i') && matches!(unit, Unit::Auto | Unit::Iec(true));
let suffix_len = 1 + usize::from(is_iec);
Some(valid_part.len() + unit_separator.len() + suffix_len)
}And then use it like:
let valid_end =
if !unit_separator.is_empty() && valid_part == find_numeric_beginning(s).unwrap_or("") {
some_great_function_name(s, valid_part, unit, &unit_separator).unwrap_or(valid_part.len())
} else {
valid_part.len()
};| Some('+' | '-') => { | ||
| Some(translate!("numfmt-error-invalid-number", "input" => s.quote())) | ||
| } |
There was a problem hiding this comment.
Is this intentional? GNU numfmt shows an "invalid suffix" error in such cases:
$ numfmt 123-
numfmt: invalid suffix in input: ‘123-’
$ numfmt 123+
numfmt: invalid suffix in input: ‘123+’
|
GNU testsuite comparison: |
Skip GNU numfmt.pl tests not yet supported: unit-sep-22-fail, grp-1,
grp-2, delim-7, field-1, field-range-err-{1-4,6-13}, strtod-6,
strtod-6.1, leading-4, debug-2, devdebug-{1-7,9-11}, help-1,
fmt-err-9, fmt-err-11, fmt-15, ign-err-5, ign-err-m2.2, ign-err-m3.1.
Also unconditionally refresh binary symlinks to avoid stale builds.
…alidation Fixes GNU numfmt.pl tests: grp-1, grp-2, debug-2, fmt-err-9, fmt-err-11.
Buffer formatted output so that --invalid=fail does not duplicate lines on error, and --invalid=abort streams directly for partial output. Fixes GNU numfmt.pl test: field-3. Re-enables the full numfmt.pl test suite by removing the skip list added earlier in the stack.
Build the grouped string in a single forward pass using chunk iteration instead of reversing, inserting separators, then reversing again. This avoids an extra String allocation and collection.
Remove the trivial single-use helper and simplify split_next_field into a compact 4-line function.
The two match arms for length 1 and length 2 had identical RawSuffix::try_from checks. Unify into a single check after a boolean guard.
Flatten the nested block scope by moving the output trait object and format dispatch to the same level, reducing indentation.
Use the existing print_warning helper for the grouping-no-effect message instead of a one-off writeln with util_name(). Use hardcoded "numfmt:" prefix for the failed-to-convert message to match the other debug warnings. Remove now-unused util_name import.
…o format_and_write
GNU test: numfmt.pl fmt-15
GNU test: numfmt.pl unit-sep-22-fail
GNU test: numfmt.pl devdebug-*, help-1, field-1, field-range-err-*
… and apply_grouping
…ix +/- error message
|
GNU testsuite comparison: |
|
merging for the next release |
should fix gnu/tests/numfmt/numfmt.pl