summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Meyering <jim@meyering.net>2003-04-21 17:59:21 +0000
committerJim Meyering <jim@meyering.net>2003-04-21 17:59:21 +0000
commit4bcefa624842964dccc75d005806d37c55c3198c (patch)
treef9ee7d45bbd31771ccbd081fd94367a12ebd54e1
parentd8b7cd198313dea308b9be6ab1d4be1e496ee1db (diff)
downloadcoreutils-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.c29
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: