diff options
author | Bruno Haible <bruno@clisp.org> | 2005-05-23 10:45:50 +0000 |
---|---|---|
committer | Bruno Haible <bruno@clisp.org> | 2009-06-23 12:12:35 +0200 |
commit | e0192e1277a4e0b7124241f2cf816fdeaf4d7599 (patch) | |
tree | 9532beef2004e223564bae7fee2a32de0d2ed696 | |
parent | 8c40a8c465fb47ac0bc7579a10d4e54a38c69aa5 (diff) | |
download | external_gettext-e0192e1277a4e0b7124241f2cf816fdeaf4d7599.zip external_gettext-e0192e1277a4e0b7124241f2cf816fdeaf4d7599.tar.gz external_gettext-e0192e1277a4e0b7124241f2cf816fdeaf4d7599.tar.bz2 |
Update gcc-internal-format for GCC 4.0.
-rw-r--r-- | NEWS | 4 | ||||
-rw-r--r-- | gettext-tools/src/ChangeLog | 12 | ||||
-rw-r--r-- | gettext-tools/src/format-gcc-internal.c | 155 | ||||
-rw-r--r-- | gettext-tools/tests/ChangeLog | 6 | ||||
-rwxr-xr-x | gettext-tools/tests/format-gcc-internal-1 | 24 | ||||
-rwxr-xr-x | gettext-tools/tests/format-gcc-internal-2 | 86 |
6 files changed, 254 insertions, 33 deletions
@@ -1,3 +1,7 @@ +Version 0.14.5 - May 2005 + +* Updated the meaning of 'gcc-internal-format' to match GCC 4.0. + Version 0.14.4 - April 2005 * The gettext autoconf macros will now work with the forthcoming g++ 4.0. diff --git a/gettext-tools/src/ChangeLog b/gettext-tools/src/ChangeLog index 66c3998..84eb2aa 100644 --- a/gettext-tools/src/ChangeLog +++ b/gettext-tools/src/ChangeLog @@ -1,3 +1,15 @@ +2005-05-21 Bruno Haible <bruno@clisp.org> + + * format-gcc-internal.c: Update for GCC 4.0. + (FAT_POINTER, FAT_SIZE_LONGLONG, FAT_SIZE_WIDE, FAT_SIZE_MASK): New + enum items. + (FAT_*): Update. + (struct spec): Add uses_err_no field. + (format_parse): Initialize uses_err_no field. Handle %q flag. Handle + 'll', 'w' size specifiers. Handle %<, %>, %', %m, %p, %J directives. + (format_check): Also check that the use of err_no is the same. + Based on a patch by Jakub Jelinek <jakub@redhat.com>. + 2005-05-05 Bruno Haible <bruno@clisp.org> * Makefile.am (msgfmt_SOURCES): Add hash-string.c. diff --git a/gettext-tools/src/format-gcc-internal.c b/gettext-tools/src/format-gcc-internal.c index c274bd9..7d3be08 100644 --- a/gettext-tools/src/format-gcc-internal.c +++ b/gettext-tools/src/format-gcc-internal.c @@ -1,5 +1,5 @@ /* GCC internal format strings. - Copyright (C) 2003-2004 Free Software Foundation, Inc. + Copyright (C) 2003-2005 Free Software Foundation, Inc. Written by Bruno Haible <bruno@clisp.org>, 2003. This program is free software; you can redistribute it and/or modify @@ -33,41 +33,55 @@ #define _(str) gettext (str) /* GCC internal format strings consist of language frontend independent - format directives, implemented in gcc-3.3/gcc/diagnostic.c (function - output_format), plus some frontend dependent extensions: - - for the C/ObjC frontend in gcc-3.3/gcc/c-objc-common.c - - for the C++ frontend in gcc-3.3/gcc/cp/error.c + format directives, implemented in gcc-4.0.0/gcc/pretty-print.c (function + pp_base_format_text), plus some frontend dependent extensions: + - for the C/ObjC frontend + in gcc-4.0.0/gcc/c-objc-common.c (function c_tree_printer) + - for the C++ frontend + in gcc-4.0.0/gcc/cp/error.c (function cp_printer) Taking these together, GCC internal format strings are specified as follows. + A directive - starts with '%', - - is optionally followed by a size specifier 'l', + - is optionally followed by 'q', + - is optionally followed by a size specifier 'l', 'll' or 'w', - is optionally followed by '+' (only the specifiers of gcc/cp/error.c), - is optionally followed by '#' (only the specifiers of gcc/cp/error.c), - is finished by a specifier - - '%', that needs no argument, + - '%', '<', '>', "'", that need no argument, + - 'm', that needs no argument but looks at an err_no variable, - 'c', that needs a character argument, - 's', that needs a string argument, - - 'i', 'd', that need a signed integer argument, - - 'o', 'u', 'x', that need an unsigned integer argument, + - 'i', 'd', that need a signed integer argument of the specified size, + - 'o', 'u', 'x', that need an unsigned integer argument of the specified + size, - '.*s', that needs a signed integer argument and a string argument, + - 'p', that needs a 'void *' argument, - 'H', that needs a 'location_t *' argument, - [see gcc/diagnostic.c] + [see gcc/pretty-print.c] - 'D', that needs a general declaration argument, - 'F', that needs a function declaration argument, - 'T', that needs a type argument, + - 'E', that needs an expression argument, [see gcc/c-objc-common.c and gcc/cp/error.c] - 'A', that needs a function argument list argument, - 'C', that needs a tree code argument, - - 'E', that needs an expression argument, - 'L', that needs a language argument, - 'O', that needs a binary operator argument, - 'P', that needs a function parameter argument, - 'Q', that needs an assignment operator argument, - 'V', that needs a const/volatile qualifier argument. [see gcc/cp/error.c] + + Furthermore, some extra directives can occur only at the beginning of a + format string. Such a directive + - starts with '%', + - is finished by a specifier + - 'J', that needs a general declaration argument. + [see gcc/pretty-print.c (function pp_base_prepare_to_format)] */ enum format_arg_type @@ -77,22 +91,27 @@ enum format_arg_type FAT_INTEGER = 1, FAT_CHAR = 2, FAT_STRING = 3, - FAT_LOCATION = 4, - FAT_TREE = 5, - FAT_TREE_CODE = 6, - FAT_LANGUAGES = 7, + FAT_POINTER = 4, + FAT_LOCATION = 5, + FAT_TREE = 6, + FAT_TREE_CODE = 7, + FAT_LANGUAGES = 8, /* Flags */ - FAT_UNSIGNED = 1 << 3, - FAT_SIZE_LONG = 1 << 4, - FAT_TREE_DECL = 1 << 5, - FAT_TREE_FUNCDECL = 2 << 5, - FAT_TREE_TYPE = 3 << 5, - FAT_TREE_ARGUMENT = 4 << 5, - FAT_TREE_EXPRESSION = 5 << 5, - FAT_TREE_CV = 6 << 5, - FAT_TREE_CODE_BINOP = 1 << 8, - FAT_TREE_CODE_ASSOP = 2 << 8, - FAT_FUNCPARAM = 1 << 10 + FAT_UNSIGNED = 1 << 4, + FAT_SIZE_LONG = 1 << 5, + FAT_SIZE_LONGLONG = 2 << 5, + FAT_SIZE_WIDE = 3 << 5, + FAT_TREE_DECL = 1 << 7, + FAT_TREE_FUNCDECL = 2 << 7, + FAT_TREE_TYPE = 3 << 7, + FAT_TREE_ARGUMENT = 4 << 7, + FAT_TREE_EXPRESSION = 5 << 7, + FAT_TREE_CV = 6 << 7, + FAT_TREE_CODE_BINOP = 1 << 10, + FAT_TREE_CODE_ASSOP = 2 << 10, + FAT_FUNCPARAM = 1 << 12, + /* Bitmasks */ + FAT_SIZE_MASK = (FAT_SIZE_LONG | FAT_SIZE_LONGLONG | FAT_SIZE_WIDE) }; struct unnumbered_arg @@ -106,19 +125,24 @@ struct spec unsigned int unnumbered_arg_count; unsigned int allocated; struct unnumbered_arg *unnumbered; + bool uses_err_no; }; static void * format_parse (const char *format, bool translated, char **invalid_reason) { + const char *format_start; struct spec spec; struct spec *result; + format_start = format; + spec.directives = 0; spec.unnumbered_arg_count = 0; spec.allocated = 0; spec.unnumbered = NULL; + spec.uses_err_no = false; for (; *format != '\0';) if (*format++ == '%') @@ -128,15 +152,33 @@ format_parse (const char *format, bool translated, char **invalid_reason) spec.directives++; + if (*format == 'q') + format++; + /* Parse size. */ size = 0; if (*format == 'l') { format++; size = FAT_SIZE_LONG; + if (*format == 'l') + { + format++; + size = FAT_SIZE_LONGLONG; + } + } + else if (*format == 'w') + { + format++; + size = FAT_SIZE_WIDE; } - if (*format != '%') + if (*format == '%' || *format == '<' || *format == '>' + || *format == '\'') + ; + else if (*format == 'm') + spec.uses_err_no = true; + else { enum format_arg_type type; @@ -159,8 +201,23 @@ format_parse (const char *format, bool translated, char **invalid_reason) spec.unnumbered_arg_count++; type = FAT_STRING; } + else if (*format == 'p') + type = FAT_POINTER; else if (*format == 'H') type = FAT_LOCATION; + else if (*format == 'J') + { + if (format - format_start == 1) + type = FAT_TREE | FAT_TREE_DECL; + else + { + *invalid_reason = + (format[-1] == '%' + ? xasprintf (_("The %%J directive is only allowed at the beginning of the string.")) + : xasprintf (_("The %%J directive does not support flags."))); + goto bad_format; + } + } else { if (*format == '+') @@ -173,12 +230,12 @@ format_parse (const char *format, bool translated, char **invalid_reason) type = FAT_TREE | FAT_TREE_FUNCDECL; else if (*format == 'T') type = FAT_TREE | FAT_TREE_TYPE; + else if (*format == 'E') + type = FAT_TREE | FAT_TREE_EXPRESSION; else if (*format == 'A') type = FAT_TREE | FAT_TREE_ARGUMENT; else if (*format == 'C') type = FAT_TREE_CODE; - else if (*format == 'E') - type = FAT_TREE | FAT_TREE_EXPRESSION; else if (*format == 'L') type = FAT_LANGUAGES; else if (*format == 'O') @@ -276,6 +333,21 @@ format_check (void *msgid_descr, void *msgstr_descr, bool equality, err = true; } + /* Check that the use of err_no is the same. */ + if (spec1->uses_err_no != spec2->uses_err_no) + { + if (error_logger) + { + if (spec1->uses_err_no) + error_logger (_("'msgid' uses %%m but '%s' doesn't"), + pretty_msgstr); + else + error_logger (_("'msgid' does not use %%m but '%s' uses %%m"), + pretty_msgstr); + } + err = true; + } + return err; } @@ -316,9 +388,23 @@ format_print (void *descr) printf (" "); if (spec->unnumbered[i].type & FAT_UNSIGNED) printf ("[unsigned]"); - if (spec->unnumbered[i].type & FAT_SIZE_LONG) - printf ("[long]"); - switch (spec->unnumbered[i].type & ~(FAT_UNSIGNED | FAT_SIZE_LONG)) + switch (spec->unnumbered[i].type & FAT_SIZE_MASK) + { + case 0: + break; + case FAT_SIZE_LONG: + printf ("[long]"); + break; + case FAT_SIZE_LONGLONG: + printf ("[long long]"); + break; + case FAT_SIZE_WIDE: + printf ("[host-wide]"); + break; + default: + abort (); + } + switch (spec->unnumbered[i].type & ~(FAT_UNSIGNED | FAT_SIZE_MASK)) { case FAT_INTEGER: printf ("i"); @@ -332,6 +418,9 @@ format_print (void *descr) case FAT_STRING: printf ("s"); break; + case FAT_POINTER: + printf ("p"); + break; case FAT_LOCATION: printf ("H"); break; @@ -370,6 +459,8 @@ format_print (void *descr) } } printf (")"); + if (spec->uses_err_no) + printf (" ERR_NO"); } int diff --git a/gettext-tools/tests/ChangeLog b/gettext-tools/tests/ChangeLog index 6e71892..ebe53fc 100644 --- a/gettext-tools/tests/ChangeLog +++ b/gettext-tools/tests/ChangeLog @@ -1,5 +1,11 @@ 2005-05-21 Bruno Haible <bruno@clisp.org> + * format-gcc-internal-1: Add tests for GCC-4.0 directives %<, %>, %', + %m, %p, %J and size specifiers. + * format-gcc-internal-2: Likewise. + +2005-05-21 Bruno Haible <bruno@clisp.org> + * format-c-2: Test also the type incompatibility due to size. 2005-05-01 Bruno Haible <bruno@clisp.org> diff --git a/gettext-tools/tests/format-gcc-internal-1 b/gettext-tools/tests/format-gcc-internal-1 index e47626e..a64074c 100755 --- a/gettext-tools/tests/format-gcc-internal-1 +++ b/gettext-tools/tests/format-gcc-internal-1 @@ -9,6 +9,14 @@ tmpfiles="$tmpfiles f-gi-1.data" cat <<\EOF > f-gi-1.data # Valid: no argument "abc%%" +# Valid: no argument +"abc%<" +# Valid: no argument +"abc%>" +# Valid: no argument +"abc%'" +# Valid: no argument +"abc%m" # Valid: one character argument "abc%c" # Valid: one string argument @@ -26,8 +34,16 @@ cat <<\EOF > f-gi-1.data # Valid: one integer and one string argument "abc%.*s" # Valid: one pointer argument +"abc%p" +# Valid: one pointer argument "abc%H" # Valid: one pointer argument +"%J" +# Invalid: %J not at start +"abc%J" +# Invalid: %J with flags +"%qJ" +# Valid: one pointer argument "abc%D" # Valid: one pointer argument "abc%F" @@ -50,9 +66,17 @@ cat <<\EOF > f-gi-1.data # Valid: one pointer argument "abc%V" # Valid: one argument with flags +"abc%qdef" +# Valid: one argument with flags "abc%+#Ag" # Valid: one argument with size specifier "abc%li" +# Valid: one argument with size specifier +"abc%lli" +# Invalid: one argument with invalid size specifier +"abc%llli" +# Valid: one argument with size specifier +"abc%wi" # Invalid: unterminated "abc%" # Invalid: unknown format specifier diff --git a/gettext-tools/tests/format-gcc-internal-2 b/gettext-tools/tests/format-gcc-internal-2 index a4b7d5d..bf0a2d2 100755 --- a/gettext-tools/tests/format-gcc-internal-2 +++ b/gettext-tools/tests/format-gcc-internal-2 @@ -1,6 +1,6 @@ #! /bin/sh -# Test checking of C format strings. +# Test checking of GCC internal format strings. tmpfiles="" trap 'rm -fr $tmpfiles' 1 2 3 15 @@ -10,12 +10,30 @@ cat <<\EOF > f-gi-2.data # Valid: %% doesn't count msgid "abc%%def" msgstr "xyz" +# Valid: %< doesn't count +msgid "abc%<def" +msgstr "xyz" +# Valid: %> doesn't count +msgid "abc%>def" +msgstr "xyz" +# Valid: %' doesn't count +msgid "abc%'def" +msgstr "xyz" +# Invalid: %m consumes err_no +msgid "abc%mdef" +msgstr "xyz" +# Invalid: %m consumes err_no +msgid "abc" +msgstr "xyz%muvw" # Invalid: invalid msgstr msgid "abc%%def" msgstr "xyz%" # Valid: same arguments msgid "abc%s%Hdef" msgstr "xyz%s%H" +# Valid: same arguments, with different flags +msgid "abc%s%Hdef" +msgstr "xyz%qs%qH" # Valid: same arguments, with different widths msgid "abc%.*sdef" msgstr "xyz%i%s" @@ -45,6 +63,9 @@ msgid "abc%c" msgstr "xyz%u" # Invalid: type incompatibility msgid "abc%c" +msgstr "xyz%p" +# Invalid: type incompatibility +msgid "abc%c" msgstr "xyz%H" # Invalid: type incompatibility msgid "abc%c" @@ -87,6 +108,9 @@ msgid "abc%s" msgstr "xyz%u" # Invalid: type incompatibility msgid "abc%s" +msgstr "xyz%p" +# Invalid: type incompatibility +msgid "abc%s" msgstr "xyz%H" # Invalid: type incompatibility msgid "abc%s" @@ -126,6 +150,9 @@ msgid "abc%i" msgstr "xyz%u" # Invalid: type incompatibility msgid "abc%i" +msgstr "xyz%p" +# Invalid: type incompatibility +msgid "abc%i" msgstr "xyz%H" # Invalid: type incompatibility msgid "abc%i" @@ -162,6 +189,9 @@ msgid "abc%i" msgstr "xyz%V" # Invalid: type incompatibility msgid "abc%u" +msgstr "xyz%p" +# Invalid: type incompatibility +msgid "abc%u" msgstr "xyz%H" # Invalid: type incompatibility msgid "abc%u" @@ -197,6 +227,42 @@ msgstr "xyz%Q" msgid "abc%u" msgstr "xyz%V" # Invalid: type incompatibility +msgid "abc%p" +msgstr "xyz%H" +# Invalid: type incompatibility +msgid "abc%p" +msgstr "xyz%D" +# Invalid: type incompatibility +msgid "abc%p" +msgstr "xyz%F" +# Invalid: type incompatibility +msgid "abc%p" +msgstr "xyz%T" +# Invalid: type incompatibility +msgid "abc%p" +msgstr "xyz%A" +# Invalid: type incompatibility +msgid "abc%p" +msgstr "xyz%C" +# Invalid: type incompatibility +msgid "abc%p" +msgstr "xyz%E" +# Invalid: type incompatibility +msgid "abc%p" +msgstr "xyz%L" +# Invalid: type incompatibility +msgid "abc%p" +msgstr "xyz%O" +# Invalid: type incompatibility +msgid "abc%p" +msgstr "xyz%P" +# Invalid: type incompatibility +msgid "abc%p" +msgstr "xyz%Q" +# Invalid: type incompatibility +msgid "abc%p" +msgstr "xyz%V" +# Invalid: type incompatibility msgid "abc%H" msgstr "xyz%D" # Invalid: type incompatibility @@ -394,6 +460,24 @@ msgstr "xyz%V" # Invalid: type incompatibility msgid "abc%Q" msgstr "xyz%V" +# Invalid: type incompatibility due to size +msgid "abc%i" +msgstr "xyz%li" +# Invalid: type incompatibility due to size +msgid "abc%i" +msgstr "xyz%lli" +# Invalid: type incompatibility due to size +msgid "abc%i" +msgstr "xyz%wi" +# Invalid: type incompatibility due to size +msgid "abc%li" +msgstr "xyz%lli" +# Invalid: type incompatibility due to size +msgid "abc%li" +msgstr "xyz%wi" +# Invalid: type incompatibility due to size +msgid "abc%lli" +msgstr "xyz%wi" # Invalid: type incompatibility for width msgid "abc%.*s" msgstr "xyz%u%s" |