Repository navigation
find: support precision and the + space # 0 flags in -printf - #918
jayhemnani9910 wants to merge 3 commits into
Conversation
There was a problem hiding this comment.
Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota.
An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing. Review the Copilot code review billing settings.
|
Commit 3a17aed has test result changes: bfs testsuite: |
Merging this PR will not alter performance1 warning
Comparing |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #918 +/- ##
==========================================
+ Coverage 92.62% 92.76% +0.14%
==========================================
Files 37 37
Lines 7808 8005 +197
Branches 392 402 +10
==========================================
+ Hits 7232 7426 +194
- Misses 435 437 +2
- Partials 141 142 +1 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
| // safe to unwrap: .front() already succeeded above. | ||
| self.advance_one().unwrap(); | ||
| } | ||
| // GNU find only takes `0` after the other flags. |
There was a problem hiding this comment.
could you please add a test for %0-5d staying unrecognized?
There was a problem hiding this comment.
Added in 95392e5. It also showed that we printed %-5d there: the literal kept only the directive letter. An unrecognized directive now prints its whole text, as GNU find does (%0-5d, %5z and %+.2z stay as written).
| let width = self.parse_format_width()?; | ||
| let precision = if self.front()? == '.' { | ||
| self.advance_one()?; | ||
| Some(self.parse_format_width()?.unwrap_or(0)) |
There was a problem hiding this comment.
a big precision will fail with "Format width too large", ok with that?
There was a problem hiding this comment.
Not ok, GNU takes it: %.70000f prints the name. The precision no longer has the u16 limit (95392e5). For names it only cuts, and for numbers the zeros are added with repeat instead of a format width. The width keeps its limit.
| FormatDirective::Sparseness => return content, | ||
| _ => { | ||
| return match precision { | ||
| Some(precision) => content.chars().take(precision).collect::<String>().into(), |
There was a problem hiding this comment.
GNU cuts bytes here, not chars, no?
does %.2f on a non-ascii name match?
There was a problem hiding this comment.
Right, it did not match: GNU cuts bytes, even inside a character, and pads the width in bytes too. On é_ab, %.3f|%5.2f|%-5.1f| gives é_| é|\xc3 |. Both are byte-based now (95392e5), and the output is written as bytes. A test checks those three.
| } | ||
|
|
||
| #[test] | ||
| fn test_printf_precision_and_flags() { |
There was a problem hiding this comment.
please add the %m cases too (%#m, %05m, %#.0m), and %.0d on depth 0
the octal branch isn't tested at all
There was a problem hiding this comment.
Added in 95392e5: %#m|%05m|%#.0m|%#5m|%#05m|%.0m| on modes 644, 000 and 4755, and %.0d|%.1d|%#d| at depth 0 (|0|0|). All the expected outputs come from GNU find 4.10.0. The branch is also rebased on main, which now prints %m with the special bits and no zero padding.
3a17aed to
95392e5
Compare
There was a problem hiding this comment.
Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota.
An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing. Review the Copilot code review billing settings.
|
Commit 95392e5 has test result changes: bfs testsuite: |
| digits.clear(); | ||
| } | ||
| if let Some(precision) = precision { | ||
| let zeros = precision.saturating_sub(digits.len()); |
There was a problem hiding this comment.
with the u16 limit gone, %.9999999999d will try to allocate ~10GB here, no?
maybe cap the precision for %d/%m (GNU fails above INT_MAX)
There was a problem hiding this comment.
Yes, it would. Fixed in 97e39e5: a precision above INT_MAX now prints nothing for that directive, the rest of the format still prints, and find exits 1 with 'standard output': Value too large for defined data type, as GNU find 4.10 does. This applies to every directive, as in GNU, and a precision too large for usize is treated the same way instead of failing to parse. One difference: we report it once, like other stdout errors, where GNU repeats it for each file. New test find_printf_precision_too_large.
There was a problem hiding this comment.
Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota.
An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing. Review the Copilot code review billing settings.
|
Commit 97e39e5 has test result changes: bfs testsuite: |
-printfonly understands-and a width. A precision or any other flag makes the whole directive print literally with a warning:GNU treats
%dand%mas integers (C%dand%o): precision is the minimum number of digits,+and space add a sign to%d,#gives%ma leading 0, and0pads with zeros when there is no precision and no-. Every other directive is a string: precision cuts it, in bytes (%.3p,%.3Tc,%.1i), and+, space,#and0change nothing. As in GNU,0is only taken after the other flags (%0-5dstays an unrecognized directive, printed as written). The width is counted in bytes too, as in GNU.%Sis left as it is (#842 changes its format).The parser now records the flags and a precision on each directive, and
apply_precision_and_flagsapplies them to the formatted value before the width.New tests
test_parse_precision_and_flags,test_printf_precision_and_flags, and four more for a big precision and depth 0, unrecognized directives, a non-ASCII name, and%mon modes 644, 000 and 4755.cargo testpasses, clippy and fmt clean. Every directive with eight flag and precision mixes (200 formats,%Sleft out) prints the same as GNU find 4.10.0 over a directory, files, a symlink and a name with a space.