From 4bcefa624842964dccc75d005806d37c55c3198c Mon Sep 17 00:00:00 2001 From: Jim Meyering Date: Mon, 21 Apr 2003 17:59:21 +0000 Subject: Fix printf POSIX compatibility bug reported by Ben Harris in . * 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. --- src/printf.c | 29 +++++++++++++++++------------ 1 file 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: -- cgit v1.2.3-54-g00ecf