Skip to content

Commit

Permalink
printf: support for extract chars
Browse files Browse the repository at this point in the history
Should fix tests/printf/printf-mb.sh
  • Loading branch information
sylvestre committed Jan 1, 2025
1 parent 3528b27 commit a79d0d8
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 7 deletions.
21 changes: 15 additions & 6 deletions src/uucore/src/lib/features/format/argument.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ impl<'a, T: Iterator<Item = &'a FormatArgument>> ArgumentIter<'a> for T {
_ => b'\0',
}
}

fn get_u64(&mut self) -> u64 {
let Some(next) = self.next() else {
return 0;
Expand All @@ -57,13 +58,21 @@ impl<'a, T: Iterator<Item = &'a FormatArgument>> ArgumentIter<'a> for T {
FormatArgument::UnsignedInt(n) => *n,
FormatArgument::Unparsed(s) => {
// Check if the string is a character literal enclosed in quotes
if s.starts_with(['"', '\'']) && s.len() > 2 {
// Extract the content between the quotes safely
let chars: Vec<char> =
s.trim_matches(|c| c == '"' || c == '\'').chars().collect();
if chars.len() == 1 {
return chars[0] as u64; // Return the Unicode code point
if s.starts_with(['"', '\'']) {
// Extract the content between the quotes safely using chars
let mut chars = s.trim_matches(|c| c == '"' || c == '\'').chars();
if let Some(first_char) = chars.next() {
if chars.clone().count() > 0 {
// Emit a warning if there are additional characters
let remaining: String = chars.collect();
show_warning!(
"{}: character(s) following character constant have been ignored",
remaining
);
}
return first_char as u64; // Use only the first character
}
return 0; // Empty quotes
}
extract_value(ParsedNumber::parse_u64(s), s)
}
Expand Down
17 changes: 16 additions & 1 deletion tests/by-util/test_printf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -869,12 +869,27 @@ fn float_switch_switch_decimal_scientific() {

#[test]
fn mb_input() {
for format in ["\"á", "\'á"] {
for format in ["\"á", "\'á", "'\u{e1}"] {
new_ucmd!()
.args(&["%04x\n", format])
.succeeds()
.stdout_only("00e1\n");
}

let cases = vec![
("\"á=", "="),
("\'á-", "-"),
("\'á=-==", "=-=="),
("'\u{e1}++", "++"),
];

for (format, expected) in cases {
new_ucmd!()
.args(&["%04x\n", format])
.succeeds()
.stdout_is("00e1\n")
.stderr_is(format!("printf: warning: {expected}: character(s) following character constant have been ignored\n"));
}
}

#[test]
Expand Down

0 comments on commit a79d0d8

Please sign in to comment.