diff options
author | Bruno Haible <bruno@clisp.org> | 2001-12-10 12:53:51 +0000 |
---|---|---|
committer | Bruno Haible <bruno@clisp.org> | 2009-06-21 23:36:24 +0200 |
commit | ac6e10bb4c917df3ea0cbcb55b0ebc7bf96aa62e (patch) | |
tree | 6cf4eeec74d4ecba6969cea0021d964e3559ae39 /src | |
parent | 602faaa029ed0df037ba5b4f56689853c89077a8 (diff) | |
download | external_gettext-ac6e10bb4c917df3ea0cbcb55b0ebc7bf96aa62e.zip external_gettext-ac6e10bb4c917df3ea0cbcb55b0ebc7bf96aa62e.tar.gz external_gettext-ac6e10bb4c917df3ea0cbcb55b0ebc7bf96aa62e.tar.bz2 |
msgmerge now marks a message fuzzy if it adds a c-format bit and the message
does not yet correctly pass the format check.
Diffstat (limited to 'src')
-rw-r--r-- | src/ChangeLog | 16 | ||||
-rw-r--r-- | src/format-c.c | 30 | ||||
-rw-r--r-- | src/format-java.c | 45 | ||||
-rw-r--r-- | src/format-lisp.c | 17 | ||||
-rw-r--r-- | src/format-pascal.c | 45 | ||||
-rw-r--r-- | src/format-python.c | 91 | ||||
-rw-r--r-- | src/format-ycp.c | 23 | ||||
-rw-r--r-- | src/format.h | 6 | ||||
-rw-r--r-- | src/message.c | 55 | ||||
-rw-r--r-- | src/msgfmt.c | 3 |
10 files changed, 233 insertions, 98 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 898b363..3678339 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,19 @@ +2001-12-06 Bruno Haible <bruno@clisp.org> + + * format.h (struct formatstring_parser): Add 'noisy' argument to + 'check' field. + * format-c.c (format_check): Add 'noisy' argument. + * format-java.c (format_check): Likewise. + * format-lisp.c (format_check): Likewise. + * format-pascal.c (format_check): Likewise. + * format-python.c (format_check): Likewise. + * format-ycp.c (format_check): Likewise. + * msgfmt.c (check_pair): Pass noisy=true. + * message.c: Include format.h. + (msgfmt_check_pair_fails): New function. + (message_merge): Set fuzzy flag when adding a -format specifier that + needs the translator's attention. + 2001-12-10 Bruno Haible <bruno@clisp.org> * x-java.l (tailcmp): If s1 ends with s2, it must be either equal to diff --git a/src/format-c.c b/src/format-c.c index 926a192..5abf9a6 100644 --- a/src/format-c.c +++ b/src/format-c.c @@ -141,7 +141,8 @@ static void *format_parse PARAMS ((const char *format)); static void format_free PARAMS ((void *descr)); static int format_get_number_of_directives PARAMS ((void *descr)); static bool format_check PARAMS ((const lex_pos_ty *pos, - void *msgid_descr, void *msgstr_descr)); + void *msgid_descr, void *msgstr_descr, + bool noisy)); static int @@ -560,10 +561,11 @@ format_get_number_of_directives (descr) } static bool -format_check (pos, msgid_descr, msgstr_descr) +format_check (pos, msgid_descr, msgstr_descr, noisy) const lex_pos_ty *pos; void *msgid_descr; void *msgstr_descr; + bool noisy; { struct spec *spec1 = (struct spec *) msgid_descr; struct spec *spec2 = (struct spec *) msgstr_descr; @@ -573,21 +575,27 @@ format_check (pos, msgid_descr, msgstr_descr) /* Check the argument types are the same. */ if (spec1->unnumbered_arg_count != spec2->unnumbered_arg_count) { - error_with_progname = false; - error_at_line (0, 0, pos->file_name, pos->line_number, - _("number of format specifications in 'msgid' and 'msgstr' does not match")); - error_with_progname = true; + if (noisy) + { + error_with_progname = false; + error_at_line (0, 0, pos->file_name, pos->line_number, + _("number of format specifications in 'msgid' and 'msgstr' does not match")); + error_with_progname = true; + } err = true; } else for (i = 0; i < spec1->unnumbered_arg_count; i++) if (spec1->unnumbered[i].type != spec2->unnumbered[i].type) { - error_with_progname = false; - error_at_line (0, 0, pos->file_name, pos->line_number, - _("format specifications in 'msgid' and 'msgstr' for argument %u are not the same"), - i + 1); - error_with_progname = true; + if (noisy) + { + error_with_progname = false; + error_at_line (0, 0, pos->file_name, pos->line_number, + _("format specifications in 'msgid' and 'msgstr' for argument %u are not the same"), + i + 1); + error_with_progname = true; + } err = true; } diff --git a/src/format-java.c b/src/format-java.c index 6dd9984..feaf66a 100644 --- a/src/format-java.c +++ b/src/format-java.c @@ -139,7 +139,8 @@ static void *format_parse PARAMS ((const char *format)); static void format_free PARAMS ((void *descr)); static int format_get_number_of_directives PARAMS ((void *descr)); static bool format_check PARAMS ((const lex_pos_ty *pos, - void *msgid_descr, void *msgstr_descr)); + void *msgid_descr, void *msgstr_descr, + bool noisy)); /* Quote handling: @@ -621,10 +622,11 @@ format_get_number_of_directives (descr) } static bool -format_check (pos, msgid_descr, msgstr_descr) +format_check (pos, msgid_descr, msgstr_descr, noisy) const lex_pos_ty *pos; void *msgid_descr; void *msgstr_descr; + bool noisy; { struct spec *spec1 = (struct spec *) msgid_descr; struct spec *spec2 = (struct spec *) msgstr_descr; @@ -647,21 +649,27 @@ format_check (pos, msgid_descr, msgstr_descr) if (cmp > 0) { - error_with_progname = false; - error_at_line (0, 0, pos->file_name, pos->line_number, - _("a format specification for argument {%u} doesn't exist in 'msgid'"), - spec2->numbered[i].number); - error_with_progname = true; + if (noisy) + { + error_with_progname = false; + error_at_line (0, 0, pos->file_name, pos->line_number, + _("a format specification for argument {%u} doesn't exist in 'msgid'"), + spec2->numbered[i].number); + error_with_progname = true; + } err = true; break; } else if (cmp < 0) { - error_with_progname = false; - error_at_line (0, 0, pos->file_name, pos->line_number, - _("a format specification for argument {%u} doesn't exist in 'msgstr'"), - spec1->numbered[i].number); - error_with_progname = true; + if (noisy) + { + error_with_progname = false; + error_at_line (0, 0, pos->file_name, pos->line_number, + _("a format specification for argument {%u} doesn't exist in 'msgstr'"), + spec1->numbered[i].number); + error_with_progname = true; + } err = true; break; } @@ -671,11 +679,14 @@ format_check (pos, msgid_descr, msgstr_descr) for (i = 0; i < spec2->numbered_arg_count; i++) if (spec1->numbered[i].type != spec2->numbered[i].type) { - error_with_progname = false; - error_at_line (0, 0, pos->file_name, pos->line_number, - _("format specifications in 'msgid' and 'msgstr' for argument {%u} are not the same"), - spec2->numbered[i].number); - error_with_progname = true; + if (noisy) + { + error_with_progname = false; + error_at_line (0, 0, pos->file_name, pos->line_number, + _("format specifications in 'msgid' and 'msgstr' for argument {%u} are not the same"), + spec2->numbered[i].number); + error_with_progname = true; + } err = true; break; } diff --git a/src/format-lisp.c b/src/format-lisp.c index e2c4df9..26d7595 100644 --- a/src/format-lisp.c +++ b/src/format-lisp.c @@ -229,7 +229,8 @@ static void *format_parse PARAMS ((const char *format)); static void format_free PARAMS ((void *descr)); static int format_get_number_of_directives PARAMS ((void *descr)); static bool format_check PARAMS ((const lex_pos_ty *pos, - void *msgid_descr, void *msgstr_descr)); + void *msgid_descr, void *msgstr_descr, + bool noisy)); /* ======================= Verify a format_arg_list ======================= */ @@ -3355,10 +3356,11 @@ format_get_number_of_directives (descr) } static bool -format_check (pos, msgid_descr, msgstr_descr) +format_check (pos, msgid_descr, msgstr_descr, noisy) const lex_pos_ty *pos; void *msgid_descr; void *msgstr_descr; + bool noisy; { struct spec *spec1 = (struct spec *) msgid_descr; struct spec *spec2 = (struct spec *) msgstr_descr; @@ -3366,10 +3368,13 @@ format_check (pos, msgid_descr, msgstr_descr) if (!equal_list (spec1->list, spec2->list)) { - error_with_progname = false; - error_at_line (0, 0, pos->file_name, pos->line_number, - _("format specifications in 'msgid' and 'msgstr' are not equivalent")); - error_with_progname = true; + if (noisy) + { + error_with_progname = false; + error_at_line (0, 0, pos->file_name, pos->line_number, + _("format specifications in 'msgid' and 'msgstr' are not equivalent")); + error_with_progname = true; + } err = true; } diff --git a/src/format-pascal.c b/src/format-pascal.c index 38243d1..de06431 100644 --- a/src/format-pascal.c +++ b/src/format-pascal.c @@ -101,7 +101,8 @@ static void *format_parse PARAMS ((const char *format)); static void format_free PARAMS ((void *descr)); static int format_get_number_of_directives PARAMS ((void *descr)); static bool format_check PARAMS ((const lex_pos_ty *pos, - void *msgid_descr, void *msgstr_descr)); + void *msgid_descr, void *msgstr_descr, + bool noisy)); static int @@ -365,10 +366,11 @@ format_get_number_of_directives (descr) } static bool -format_check (pos, msgid_descr, msgstr_descr) +format_check (pos, msgid_descr, msgstr_descr, noisy) const lex_pos_ty *pos; void *msgid_descr; void *msgstr_descr; + bool noisy; { struct spec *spec1 = (struct spec *) msgid_descr; struct spec *spec2 = (struct spec *) msgstr_descr; @@ -391,21 +393,27 @@ format_check (pos, msgid_descr, msgstr_descr) if (cmp > 0) { - error_with_progname = false; - error_at_line (0, 0, pos->file_name, pos->line_number, - _("a format specification for argument {%u} doesn't exist in 'msgid'"), - spec2->numbered[i].number); - error_with_progname = true; + if (noisy) + { + error_with_progname = false; + error_at_line (0, 0, pos->file_name, pos->line_number, + _("a format specification for argument {%u} doesn't exist in 'msgid'"), + spec2->numbered[i].number); + error_with_progname = true; + } err = true; break; } else if (cmp < 0) { - error_with_progname = false; - error_at_line (0, 0, pos->file_name, pos->line_number, - _("a format specification for argument {%u} doesn't exist in 'msgstr'"), - spec1->numbered[i].number); - error_with_progname = true; + if (noisy) + { + error_with_progname = false; + error_at_line (0, 0, pos->file_name, pos->line_number, + _("a format specification for argument {%u} doesn't exist in 'msgstr'"), + spec1->numbered[i].number); + error_with_progname = true; + } err = true; break; } @@ -415,11 +423,14 @@ format_check (pos, msgid_descr, msgstr_descr) for (i = 0; i < spec2->numbered_arg_count; i++) if (spec1->numbered[i].type != spec2->numbered[i].type) { - error_with_progname = false; - error_at_line (0, 0, pos->file_name, pos->line_number, - _("format specifications in 'msgid' and 'msgstr' for argument {%u} are not the same"), - spec2->numbered[i].number); - error_with_progname = true; + if (noisy) + { + error_with_progname = false; + error_at_line (0, 0, pos->file_name, pos->line_number, + _("format specifications in 'msgid' and 'msgstr' for argument {%u} are not the same"), + spec2->numbered[i].number); + error_with_progname = true; + } err = true; break; } diff --git a/src/format-python.c b/src/format-python.c index 09bcb7e..ab47d10 100644 --- a/src/format-python.c +++ b/src/format-python.c @@ -109,7 +109,8 @@ static void *format_parse PARAMS ((const char *format)); static void format_free PARAMS ((void *descr)); static int format_get_number_of_directives PARAMS ((void *descr)); static bool format_check PARAMS ((const lex_pos_ty *pos, - void *msgid_descr, void *msgstr_descr)); + void *msgid_descr, void *msgstr_descr, + bool noisy)); static int @@ -375,10 +376,11 @@ format_get_number_of_directives (descr) } static bool -format_check (pos, msgid_descr, msgstr_descr) +format_check (pos, msgid_descr, msgstr_descr, noisy) const lex_pos_ty *pos; void *msgid_descr; void *msgstr_descr; + bool noisy; { struct spec *spec1 = (struct spec *) msgid_descr; struct spec *spec2 = (struct spec *) msgstr_descr; @@ -386,18 +388,24 @@ format_check (pos, msgid_descr, msgstr_descr) if (spec1->named_arg_count > 0 && spec2->unnamed_arg_count > 0) { - error_with_progname = false; - error_at_line (0, 0, pos->file_name, pos->line_number, - _("format specifications in 'msgid' expect a mapping, those in 'msgstr' expect a tuple")); - error_with_progname = true; + if (noisy) + { + error_with_progname = false; + error_at_line (0, 0, pos->file_name, pos->line_number, + _("format specifications in 'msgid' expect a mapping, those in 'msgstr' expect a tuple")); + error_with_progname = true; + } err = true; } else if (spec1->unnamed_arg_count > 0 && spec2->named_arg_count > 0) { - error_with_progname = false; - error_at_line (0, 0, pos->file_name, pos->line_number, - _("format specifications in 'msgid' expect a tuple, those in 'msgstr' expect a mapping")); - error_with_progname = true; + if (noisy) + { + error_with_progname = false; + error_at_line (0, 0, pos->file_name, pos->line_number, + _("format specifications in 'msgid' expect a tuple, those in 'msgstr' expect a mapping")); + error_with_progname = true; + } err = true; } else @@ -417,21 +425,27 @@ format_check (pos, msgid_descr, msgstr_descr) if (cmp > 0) { - error_with_progname = false; - error_at_line (0, 0, pos->file_name, pos->line_number, - _("a format specification for argument '%s' doesn't exist in 'msgid'"), - spec2->named[i].name); - error_with_progname = true; + if (noisy) + { + error_with_progname = false; + error_at_line (0, 0, pos->file_name, pos->line_number, + _("a format specification for argument '%s' doesn't exist in 'msgid'"), + spec2->named[i].name); + error_with_progname = true; + } err = true; break; } else if (cmp < 0) { - error_with_progname = false; - error_at_line (0, 0, pos->file_name, pos->line_number, - _("a format specification for argument '%s' doesn't exist in 'msgstr'"), - spec1->named[i].name); - error_with_progname = true; + if (noisy) + { + error_with_progname = false; + error_at_line (0, 0, pos->file_name, pos->line_number, + _("a format specification for argument '%s' doesn't exist in 'msgstr'"), + spec1->named[i].name); + error_with_progname = true; + } err = true; break; } @@ -441,11 +455,14 @@ format_check (pos, msgid_descr, msgstr_descr) for (i = 0; i < spec2->named_arg_count; i++) if (spec1->named[i].type != spec2->named[i].type) { - error_with_progname = false; - error_at_line (0, 0, pos->file_name, pos->line_number, - _("format specifications in 'msgid' and 'msgstr' for argument '%s' are not the same"), - spec2->named[i].name); - error_with_progname = true; + if (noisy) + { + error_with_progname = false; + error_at_line (0, 0, pos->file_name, pos->line_number, + _("format specifications in 'msgid' and 'msgstr' for argument '%s' are not the same"), + spec2->named[i].name); + error_with_progname = true; + } err = true; break; } @@ -458,21 +475,27 @@ format_check (pos, msgid_descr, msgstr_descr) /* Check the argument types are the same. */ if (spec1->unnamed_arg_count != spec2->unnamed_arg_count) { - error_with_progname = false; - error_at_line (0, 0, pos->file_name, pos->line_number, - _("number of format specifications in 'msgid' and 'msgstr' does not match")); - error_with_progname = true; + if (noisy) + { + error_with_progname = false; + error_at_line (0, 0, pos->file_name, pos->line_number, + _("number of format specifications in 'msgid' and 'msgstr' does not match")); + error_with_progname = true; + } err = true; } else for (i = 0; i < spec1->unnamed_arg_count; i++) if (spec1->unnamed[i].type != spec2->unnamed[i].type) { - error_with_progname = false; - error_at_line (0, 0, pos->file_name, pos->line_number, - _("format specifications in 'msgid' and 'msgstr' for argument %u are not the same"), - i + 1); - error_with_progname = true; + if (noisy) + { + error_with_progname = false; + error_at_line (0, 0, pos->file_name, pos->line_number, + _("format specifications in 'msgid' and 'msgstr' for argument %u are not the same"), + i + 1); + error_with_progname = true; + } err = true; } } diff --git a/src/format-ycp.c b/src/format-ycp.c index dd4b708..dbd9e6a 100644 --- a/src/format-ycp.c +++ b/src/format-ycp.c @@ -52,7 +52,8 @@ static void *format_parse PARAMS ((const char *format)); static void format_free PARAMS ((void *descr)); static int format_get_number_of_directives PARAMS ((void *descr)); static bool format_check PARAMS ((const lex_pos_ty *pos, - void *msgid_descr, void *msgstr_descr)); + void *msgid_descr, void *msgstr_descr, + bool noisy)); static void * @@ -114,10 +115,11 @@ format_get_number_of_directives (descr) } static bool -format_check (pos, msgid_descr, msgstr_descr) +format_check (pos, msgid_descr, msgstr_descr, noisy) const lex_pos_ty *pos; void *msgid_descr; void *msgstr_descr; + bool noisy; { struct spec *spec1 = (struct spec *) msgid_descr; struct spec *spec2 = (struct spec *) msgstr_descr; @@ -131,13 +133,16 @@ format_check (pos, msgid_descr, msgstr_descr) if (arg_used1 != arg_used2) { - error_with_progname = false; - error_at_line (0, 0, pos->file_name, pos->line_number, - arg_used1 - ? _("a format specification for argument %u doesn't exist in 'msgstr'") - : _("a format specification for argument %u doesn't exist in 'msgid'"), - i + 1); - error_with_progname = true; + if (noisy) + { + error_with_progname = false; + error_at_line (0, 0, pos->file_name, pos->line_number, + arg_used1 + ? _("a format specification for argument %u doesn't exist in 'msgstr'") + : _("a format specification for argument %u doesn't exist in 'msgid'"), + i + 1); + error_with_progname = true; + } err = true; break; } diff --git a/src/format.h b/src/format.h index 58e730e..cb925ff 100644 --- a/src/format.h +++ b/src/format.h @@ -19,6 +19,8 @@ #ifndef _FORMAT_H #define _FORMAT_H +#include <stdbool.h> + #include "pos.h" /* Get lex_pos_ty. */ #include "message.h" /* Get NFORMATS. */ @@ -44,8 +46,8 @@ struct formatstring_parser error_with_progname = false; error_at_line (0, 0, pos->file_name, pos->line_number, ...); error_with_progname = true; - and return true. Otherwise return false. */ - bool (*check) PARAMS ((const lex_pos_ty *pos, void *msgid_descr, void *msgstr_descr)); + (but only if noisy=true) and return true. Otherwise return false. */ + bool (*check) PARAMS ((const lex_pos_ty *pos, void *msgid_descr, void *msgstr_descr, bool noisy)); }; /* Format string parsers, each defined in its own file. */ diff --git a/src/message.c b/src/message.c index 0f19e20..2b6c39c 100644 --- a/src/message.c +++ b/src/message.c @@ -29,6 +29,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "fstrcmp.h" #include "hash.h" +#include "format.h" #include "xmalloc.h" #include "strstr.h" #include "system.h" @@ -36,6 +37,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* Prototypes for local functions. Needed to ensure compiler checking of function argument counts despite of K&R C function definition syntax. */ +static bool msgfmt_check_pair_fails PARAMS ((const lex_pos_ty *pos, + const char *msgid, + const char *msgstr, size_t i)); static message_ty *message_list_search_fuzzy_inner PARAMS (( message_list_ty *mlp, const char *msgid, double *best_weight_p)); @@ -208,6 +212,37 @@ message_copy (mp) } +static bool +msgfmt_check_pair_fails (pos, msgid, msgstr, i) + const lex_pos_ty *pos; + const char *msgid; + const char *msgstr; + size_t i; +{ + bool failure; + struct formatstring_parser *parser = formatstring_parsers[i]; + void *msgid_descr = parser->parse (msgid); + + if (msgid_descr != NULL) + { + void *msgstr_descr = parser->parse (msgstr); + + if (msgstr_descr != NULL) + { + failure = parser->check (pos, msgid_descr, msgstr_descr, false); + parser->free (msgstr_descr); + } + else + failure = true; + + parser->free (msgid_descr); + } + else + failure = false; + + return failure; +} + message_ty * message_merge (def, ref) message_ty *def; @@ -407,8 +442,26 @@ message_merge (def, ref) from the reference message (such as format/no-format), others come from the definition file (fuzzy or not). */ result->is_fuzzy = def->is_fuzzy; + for (i = 0; i < NFORMATS; i++) - result->is_format[i] = ref->is_format[i]; + { + result->is_format[i] = ref->is_format[i]; + + /* If the reference message is marked as being a format specifier, + but the definition message is not, we check if the resulting + message would pass "msgfmt -c". If yes, then all is fine. If + not, we add a fuzzy marker, because + 1. the message needs the translator's attention, + 2. msgmerge must not transform a PO file which passes "msgfmt -c" + into a PO file which doesn't. */ + if (!result->is_fuzzy + && ref->msgid_plural == NULL + && possible_format_p (ref->is_format[i]) + && !possible_format_p (def->is_format[i]) + && msgfmt_check_pair_fails (&def->pos, ref->msgid, msgstr, i)) + result->is_fuzzy = true; + } + result->do_wrap = ref->do_wrap; /* Take the file position comments from the reference file, as they diff --git a/src/msgfmt.c b/src/msgfmt.c index 811f525..01794a2 100644 --- a/src/msgfmt.c +++ b/src/msgfmt.c @@ -1075,7 +1075,8 @@ check_pair (msgid, msgid_pos, msgid_plural, msgstr, msgstr_len, msgstr_pos, if (msgstr_descr != NULL) { - if (parser->check (msgid_pos, msgid_descr, msgstr_descr)) + if (parser->check (msgid_pos, msgid_descr, msgstr_descr, + true)) exit_status = EXIT_FAILURE; parser->free (msgstr_descr); |