Skip to content

Commit 8f4c286

Browse files
sylvestrejtracey
authored andcommitted
printf: support for extract chars
Should fix tests/printf/printf-mb.sh
1 parent 2cd2e6e commit 8f4c286

File tree

2 files changed

+31
-7
lines changed

2 files changed

+31
-7
lines changed

src/uucore/src/lib/features/format/argument.rs

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ impl<'a, T: Iterator<Item = &'a FormatArgument>> ArgumentIter<'a> for T {
4949
_ => b'\0',
5050
}
5151
}
52+
5253
fn get_u64(&mut self) -> u64 {
5354
let Some(next) = self.next() else {
5455
return 0;
@@ -57,13 +58,21 @@ impl<'a, T: Iterator<Item = &'a FormatArgument>> ArgumentIter<'a> for T {
5758
FormatArgument::UnsignedInt(n) => *n,
5859
FormatArgument::Unparsed(s) => {
5960
// Check if the string is a character literal enclosed in quotes
60-
if s.starts_with(['"', '\'']) && s.len() > 2 {
61-
// Extract the content between the quotes safely
62-
let chars: Vec<char> =
63-
s.trim_matches(|c| c == '"' || c == '\'').chars().collect();
64-
if chars.len() == 1 {
65-
return chars[0] as u64; // Return the Unicode code point
61+
if s.starts_with(['"', '\'']) {
62+
// Extract the content between the quotes safely using chars
63+
let mut chars = s.trim_matches(|c| c == '"' || c == '\'').chars();
64+
if let Some(first_char) = chars.next() {
65+
if chars.clone().count() > 0 {
66+
// Emit a warning if there are additional characters
67+
let remaining: String = chars.collect();
68+
show_warning!(
69+
"{}: character(s) following character constant have been ignored",
70+
remaining
71+
);
72+
}
73+
return first_char as u64; // Use only the first character
6674
}
75+
return 0; // Empty quotes
6776
}
6877
extract_value(ParsedNumber::parse_u64(s), s)
6978
}

tests/by-util/test_printf.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -869,12 +869,27 @@ fn float_switch_switch_decimal_scientific() {
869869

870870
#[test]
871871
fn mb_input() {
872-
for format in ["\"á", "\'á"] {
872+
for format in ["\"á", "\'á", "'\u{e1}"] {
873873
new_ucmd!()
874874
.args(&["%04x\n", format])
875875
.succeeds()
876876
.stdout_only("00e1\n");
877877
}
878+
879+
let cases = vec![
880+
("\"á=", "="),
881+
("\'á-", "-"),
882+
("\'á=-==", "=-=="),
883+
("'\u{e1}++", "++"),
884+
];
885+
886+
for (format, expected) in cases {
887+
new_ucmd!()
888+
.args(&["%04x\n", format])
889+
.succeeds()
890+
.stdout_is("00e1\n")
891+
.stderr_is(format!("printf: warning: {expected}: character(s) following character constant have been ignored\n"));
892+
}
878893
}
879894

880895
#[test]

0 commit comments

Comments
 (0)