diff options
author | Jim Meyering <jim@meyering.net> | 2003-04-21 17:59:21 +0000 |
---|---|---|
committer | Jim Meyering <jim@meyering.net> | 2003-04-21 17:59:21 +0000 |
commit | 4bcefa624842964dccc75d005806d37c55c3198c (patch) | |
tree | f9ee7d45bbd31771ccbd081fd94367a12ebd54e1 | |
parent | d8b7cd198313dea308b9be6ab1d4be1e496ee1db (diff) | |
download | coreutils-4bcefa624842964dccc75d005806d37c55c3198c.tar.xz |
Fix printf POSIX compatibility bug reported by Ben Harris in
<http://mail.gnu.org/archive/html/bug-coreutils/2003-04/msg00070.html>.
* doc/coreutils.texi (printf invocation): It's \NNN in the format,
\0NNN in the %b operand.
* src/printf.c (usage): Likewise.
(print_esc): New arg OCTAL0 to specify whether \0NNN or \NNN
is desired. All uses changed. Behave like Bash printf if %b
operand uses \NNN where the initial N is not 0.
-rw-r--r-- | src/printf.c | 29 |
1 files changed, 17 insertions, 12 deletions
diff --git a/src/printf.c b/src/printf.c index 22e1b9755..cc4bfd9f2 100644 --- a/src/printf.c +++ b/src/printf.c @@ -31,14 +31,15 @@ \r = carriage return \t = horizontal tab \v = vertical tab - \0ooo = octal number (ooo is 0 to 3 digits) + \ooo = octal number (ooo is 1 to 3 digits) \xhh = hexadecimal number (hhh is 1 to 2 digits) \uhhhh = 16-bit Unicode character (hhhh is 4 digits) \Uhhhhhhhh = 32-bit Unicode character (hhhhhhhh is 8 digits) Additional directive: - %b = print an argument string, interpreting backslash escapes + %b = print an argument string, interpreting backslash escapes, + except that octal escapes are of the form \0 or \0ooo. The `format' argument is re-used as many times as necessary to convert all of the given arguments. @@ -113,7 +114,7 @@ Print ARGUMENT(s) according to FORMAT.\n\ FORMAT controls the output as in C printf. Interpreted sequences are:\n\ \n\ \\\" double quote\n\ - \\0NNN character with octal value NNN (0 to 3 digits)\n\ + \\NNN character with octal value NNN (1 to 3 digits)\n\ \\\\ backslash\n\ "), stdout); fputs (_("\ @@ -136,7 +137,8 @@ FORMAT controls the output as in C printf. Interpreted sequences are:\n\ "), stdout); fputs (_("\ %% a single %\n\ - %b ARGUMENT as a string with `\\' escapes interpreted\n\ + %b ARGUMENT as a string with `\\' escapes interpreted,\n\ + except that octal escapes are of the form \\0 or \\0NNN\n\ \n\ and all C format specifications ending with one of diouxXfeEgGcs, with\n\ ARGUMENTs converted to proper type first. Variable widths are handled.\n\ @@ -234,10 +236,12 @@ print_esc_char (int c) /* Print a \ escape sequence starting at ESCSTART. Return the number of characters in the escape sequence - besides the backslash. */ + besides the backslash. + If OCTAL0 is nonzero, octal escapes are of the form \0ooo, where o + is an octal digit; otherwise they are of the form \ooo. */ static int -print_esc (const char *escstart) +print_esc (const char *escstart, bool octal0) { register const char *p = escstart + 1; int esc_value = 0; /* Value of \nnn escape. */ @@ -254,11 +258,12 @@ print_esc (const char *escstart) error (EXIT_FAILURE, 0, _("missing hexadecimal number in escape")); putchar (esc_value); } - else if (*p == '0') + else if (isodigit (*p)) { - /* An octal \0ooo escape sequence has 0 to 3 octal digits - after the leading \0. */ - for (esc_length = 0, ++p; + /* Parse \0ooo (if octal0 && *p == '0') or \ooo (otherwise). + Allow \ooo if octal0 && *p != '0'; this is an undocumented + extension to POSIX that is compatible with Bash 2.05b. */ + for (esc_length = 0, p += octal0 && *p == '0'; esc_length < 3 && isodigit (*p); ++esc_length, ++p) esc_value = esc_value * 8 + octtobin (*p); @@ -313,7 +318,7 @@ print_esc_string (const char *str) { for (; *str; str++) if (*str == '\\') - str += print_esc (str); + str += print_esc (str, true); else putchar (*str); } @@ -531,7 +536,7 @@ print_formatted (const char *format, int argc, char **argv) break; case '\\': - f += print_esc (f); + f += print_esc (f, false); break; default: |