mirror of
https://git.savannah.gnu.org/git/coreutils.git
synced 2025-09-10 07:59:52 +02:00
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.
This commit is contained in:
29
src/printf.c
29
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:
|
||||
|
||||
Reference in New Issue
Block a user