summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBruno Haible <bruno@clisp.org>2005-05-23 10:45:50 +0000
committerBruno Haible <bruno@clisp.org>2009-06-23 12:12:35 +0200
commite0192e1277a4e0b7124241f2cf816fdeaf4d7599 (patch)
tree9532beef2004e223564bae7fee2a32de0d2ed696
parent8c40a8c465fb47ac0bc7579a10d4e54a38c69aa5 (diff)
downloadexternal_gettext-e0192e1277a4e0b7124241f2cf816fdeaf4d7599.zip
external_gettext-e0192e1277a4e0b7124241f2cf816fdeaf4d7599.tar.gz
external_gettext-e0192e1277a4e0b7124241f2cf816fdeaf4d7599.tar.bz2
Update gcc-internal-format for GCC 4.0.
-rw-r--r--NEWS4
-rw-r--r--gettext-tools/src/ChangeLog12
-rw-r--r--gettext-tools/src/format-gcc-internal.c155
-rw-r--r--gettext-tools/tests/ChangeLog6
-rwxr-xr-xgettext-tools/tests/format-gcc-internal-124
-rwxr-xr-xgettext-tools/tests/format-gcc-internal-286
6 files changed, 254 insertions, 33 deletions
diff --git a/NEWS b/NEWS
index 2602c22..55d881e 100644
--- a/NEWS
+++ b/NEWS
@@ -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"