summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBruno Haible <bruno@clisp.org>2001-12-10 12:53:51 +0000
committerBruno Haible <bruno@clisp.org>2009-06-21 23:36:24 +0200
commitac6e10bb4c917df3ea0cbcb55b0ebc7bf96aa62e (patch)
tree6cf4eeec74d4ecba6969cea0021d964e3559ae39 /src
parent602faaa029ed0df037ba5b4f56689853c89077a8 (diff)
downloadexternal_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/ChangeLog16
-rw-r--r--src/format-c.c30
-rw-r--r--src/format-java.c45
-rw-r--r--src/format-lisp.c17
-rw-r--r--src/format-pascal.c45
-rw-r--r--src/format-python.c91
-rw-r--r--src/format-ycp.c23
-rw-r--r--src/format.h6
-rw-r--r--src/message.c55
-rw-r--r--src/msgfmt.c3
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);