tr: align [:upper:]/[:lower:] the way GNU does, and say so - #14400
tr: align [:upper:]/[:lower:] the way GNU does, and say so#14400Socialpranker wants to merge 2 commits into
Conversation
Three related gaps in the SET1/SET2 class rules: - Any class in SET1 counted as a match for an 'upper'/'lower' in SET2, so 'tr [:alpha:] [:upper:]' fell through to the length check and 'tr [:digit:] [:upper:]' was accepted and translated nothing. Only an 'upper'/'lower' can line up with one. - Both class checks ran with -d, where SET2 is the squeeze set and lines up with nothing: 'tr -ds [:alpha:] [:upper:]' failed instead of deleting. - The diagnostic named the rule instead of the fault; GNU calls it a misaligned construct. Also the second line of the -ds missing-operand message, which GNU spells 'when both deleting and squeezing repeats'.
|
GNU testsuite comparison: |
| tr-error-empty-set2-when-not-truncating = quand on ne tronque pas set1, string2 doit être non-vide | ||
| tr-error-class-except-lower-upper-in-set2 = lors de la traduction, les seules classes de caractères qui peuvent apparaître dans set2 sont 'upper' et 'lower' | ||
| tr-error-class-in-set2-not-matched = lors de la traduction, chaque 'upper'/'lower' dans set2 doit être associé à un 'upper'/'lower' à la même position dans set1 | ||
| tr-error-class-in-set2-not-matched = construction [:upper:] et/ou [:lower:] mal alignée |
There was a problem hiding this comment.
does this match the french translation of gnu in meaning ? Could you post it here ?
There was a problem hiding this comment.
GNU's official translation (translationproject.org fr.po):
msgid "misaligned [:upper:] and/or [:lower:] construct"
msgstr "les structures [:upper:] ou [:lower:] sont mal alignées"
Our fr string was close in meaning but not the official wording. Updated fr-FR.ftl to match GNU's translation exactly, in 828738d.
…er/lower GNU's translationproject.org fr.po translates 'misaligned [:upper:] and/or [:lower:] construct' as 'les structures [:upper:] ou [:lower:] sont mal alignées'; match that wording instead of the ad hoc phrasing.
|
GNU's official translation (translationproject.org fr.po): Our previous fr string was close in meaning but not the official wording. Updated fr-FR.ftl to match GNU's translation exactly, in 828738d. |
anastygnome
left a comment
There was a problem hiding this comment.
You must NOT copy code from GNU for licencing reasons.
Just to be in the clear
Replace
sont mal alignées
By
ne sont pas alignées correctement
Three related gaps in how SET1/SET2 character classes are validated, found
by diffing against GNU:
The fix
upper/lowerin SET2. Only anupper/lowercan be one — anythingelse leaves the mapping undefined, which is why GNU rejects it. With
[:alpha:]/[:upper:]the bogus match let the input fall through tothe length check and produce the wrong message; with
[:digit:]/[:upper:]it produced no error at all.-d, SET2 is thesqueeze set and lines up with nothing, so both are now gated on
translating.
tr-error-class-in-set2-not-matchedrestated the rule where GNU namesthe fault:
misaligned [:upper:] and/or [:lower:] construct.Plus the second line of the
-dsmissing-operand message, which GNUspells
Two strings must be given when both deleting and squeezing repeats.The
when translating with string1 longer than string2message is notremoved — GNU has it too, for
tr '[:upper:][:lower:]' '[:lower:]', and anew test pins that it still fires there.
How the GNU behavior was established
By running the installed GNU coreutils 9.11 binary (Homebrew,
gtr) as ablack box over 14 SET1/SET2 pairs: classes aligned and misaligned, a class
in SET2 against a literal, a non-
upper/lowerclass in SET1, SET1longer than SET2, and each of those again under
-d,-s,-dsand-dcs. Exit status and stderr diffed against uutils. I did not read GNUcoreutils source.
Testing
tests/by-util/test_tr.rs:test_misaligned_upper_lower_construct(five pairs, exact message and exit status 1),
test_misaligned_construct_not_checked_when_deleting, andtest_set1_longer_than_set2_ending_in_classguarding the message thatmust stay. One existing assertion updated for the new
-dswording.Mutation-checked: reverting
operation.rsalone fails two of them,reverting the
.ftlalone fails two.cargo test --features tr --test tests test_tr: 253 passed, 0 failed(250/0 before).
cargo clippy -p uu_tr --all-targets -- -D warnings: clean.cargo fmt --check: clean.trinvocationsin my harness: mismatches 2 -> 0.
French translations updated to match.
Disclosure
Prepared with AI assistance (Claude Opus 5, via Claude Code), per the AI
policy in CONTRIBUTING.md. Every GNU behavior quoted above came from
running the installed binary, not from reading GPL source. All testing was
run locally.