mirror of
https://https.git.savannah.gnu.org/git/gettext.git
synced 2026-01-26 15:39:11 +00:00
Add support for Shell printf format strings, part 3.
* gettext-tools/src/format-invalid.h (INVALID_FLAG_FOR): New macro. * gettext-tools/src/format-java-printf.c (INVALID_FLAG_FOR): Remove macro. * gettext-tools/src/format-sh-printf.c (format_parse): Reject format strings with invalid flag+specifier combinations. * gettext-tools/tests/format-sh-printf-1: Add more test cases. * gettext-tools/doc/gettext.texi (sh-format): Mention the ' flag.
This commit is contained in:
parent
c6373812d7
commit
2fdcb6546c
@ -10266,6 +10266,9 @@ but without the obsolescent @code{b} conversion specifier.
|
||||
Extensions by the GNU coreutils @samp{printf} command
|
||||
(@url{https://www.gnu.org/software/coreutils/manual/html_node/printf-invocation.html})
|
||||
are not supported:
|
||||
use of the @samp{'} flag in the
|
||||
@code{%i}, @code{%d}, @code{%u}, @code{%f}, @code{%F}, @code{%g}, @code{%G}
|
||||
directives;
|
||||
use of @samp{*} or @samp{*@var{m}$} as width or precision;
|
||||
use of size specifiers @code{h}, @code{l}, @code{j}, @code{z}, @code{t} (ignored);
|
||||
and the escape sequences @code{\c},
|
||||
|
||||
@ -39,5 +39,8 @@
|
||||
? xasprintf (_("In the directive number %u, the character '%c' is not a valid conversion specifier."), directive_number, conv_char) \
|
||||
: xasprintf (_("The character that terminates the directive number %u is not a valid conversion specifier."), directive_number))
|
||||
|
||||
#define INVALID_FLAG_FOR(directive_number,flag_char,conv_char) \
|
||||
xasprintf (_("In the directive number %u, the flag '%c' is invalid for the conversion '%c'."), directive_number, flag_char, conv_char)
|
||||
|
||||
#define INVALID_INCOMPATIBLE_ARG_TYPES(arg_number) \
|
||||
xasprintf (_("The string refers to argument number %u in incompatible ways."), arg_number)
|
||||
|
||||
@ -131,9 +131,6 @@ numbered_arg_compare (const void *p1, const void *p2)
|
||||
#define INVALID_LAST_ARG(directive_number) \
|
||||
xasprintf (_("In the directive number %u, the reference to the argument of the previous directive is invalid."), directive_number)
|
||||
|
||||
#define INVALID_FLAG_FOR(directive_number,flag_char,conv_char) \
|
||||
xasprintf (_("In the directive number %u, the flag '%c' is invalid for the conversion '%c'."), directive_number, flag_char, conv_char)
|
||||
|
||||
#define INVALID_WIDTH_FOR(directive_number,conv_char) \
|
||||
xasprintf (_("In the directive number %u, a width is invalid for the conversion '%c'."), directive_number, conv_char)
|
||||
|
||||
|
||||
@ -65,6 +65,9 @@
|
||||
- 'u', 'o', 'x', 'X', that need an unsigned integer argument,
|
||||
- [optional in POSIX, but supported here:] 'e', 'E', 'f', 'F', 'g', 'G',
|
||||
'a', 'A', that need a floating-point argument.
|
||||
Some flag+specifier combinations are invalid:
|
||||
- The '#' flag with the specifiers 'c', 's', 'i', 'd', 'u'.
|
||||
- The '0' flag with the specifiers 'c', 's'.
|
||||
Additionally there is the directive '%%', which takes no argument.
|
||||
Numbered ('%m$' or '*m$') and unnumbered argument specifications cannot
|
||||
be used in the same string.
|
||||
@ -172,11 +175,17 @@ format_parse (const char *format, bool translated, char *fdi,
|
||||
}
|
||||
|
||||
/* Parse flags. */
|
||||
bool have_hash_flag = false;
|
||||
bool have_zero_flag = false;
|
||||
while (*format == ' ' || *format == '+' || *format == '-'
|
||||
|| *format == '#' || *format == '0')
|
||||
{
|
||||
if (*format == ' ')
|
||||
likely_intentional = false;
|
||||
if (*format == '#')
|
||||
have_hash_flag = true;
|
||||
if (*format == '0')
|
||||
have_zero_flag = true;
|
||||
format++;
|
||||
}
|
||||
|
||||
@ -228,6 +237,23 @@ format_parse (const char *format, bool translated, char *fdi,
|
||||
goto bad_format;
|
||||
}
|
||||
|
||||
if (have_hash_flag
|
||||
&& (*format == 'c' || *format == 's'
|
||||
|| *format == 'i' || *format == 'd' || *format == 'u'))
|
||||
{
|
||||
*invalid_reason =
|
||||
INVALID_FLAG_FOR (spec.directives, '#', *format);
|
||||
FDI_SET (format, FMTDIR_ERROR);
|
||||
goto bad_format;
|
||||
}
|
||||
if (have_zero_flag && (*format == 'c' || *format == 's'))
|
||||
{
|
||||
*invalid_reason =
|
||||
INVALID_FLAG_FOR (spec.directives, '0', *format);
|
||||
FDI_SET (format, FMTDIR_ERROR);
|
||||
goto bad_format;
|
||||
}
|
||||
|
||||
if (number)
|
||||
{
|
||||
/* Numbered argument. */
|
||||
|
||||
@ -103,6 +103,28 @@ LC_ALL=C sed -e "$escape_backslashes" <<\EOF > f-sp-1.data
|
||||
"abc%3$*2$.*1$g"
|
||||
# Invalid: zero
|
||||
"abc%2$*0$.*1$g"
|
||||
# Invalid: flag not valid
|
||||
"abc%'d"
|
||||
# Invalid: flag not valid
|
||||
"abc%'u"
|
||||
# Invalid: flag not valid
|
||||
"abc%'f"
|
||||
# Invalid: flag not valid
|
||||
"abc%'g"
|
||||
# Invalid: flag not valid for specifier
|
||||
"abc%#c"
|
||||
# Invalid: flag not valid for specifier
|
||||
"abc%#s"
|
||||
# Invalid: flag not valid for specifier
|
||||
"abc%#i"
|
||||
# Invalid: flag not valid for specifier
|
||||
"abc%#d"
|
||||
# Invalid: flag not valid for specifier
|
||||
"abc%#u"
|
||||
# Invalid: flag not valid for specifier
|
||||
"abc%0c"
|
||||
# Invalid: flag not valid for specifier
|
||||
"abc%0s"
|
||||
# Valid: escape sequence
|
||||
"abc%%def\\"
|
||||
# Valid: escape sequence
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user