summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBruno Haible <bruno@clisp.org>2001-11-22 21:02:15 +0000
committerBruno Haible <bruno@clisp.org>2009-06-21 23:23:45 +0200
commit5db2c4c33e71dd7e989afebfe41b8c6062d89b00 (patch)
tree7fd3e7ddb1f27d502148ed773a24e7444da834e4
parent892f7216d88a64eb545b0f7c88bc3c806f9b0e14 (diff)
downloadexternal_gettext-5db2c4c33e71dd7e989afebfe41b8c6062d89b00.zip
external_gettext-5db2c4c33e71dd7e989afebfe41b8c6062d89b00.tar.gz
external_gettext-5db2c4c33e71dd7e989afebfe41b8c6062d89b00.tar.bz2
Change duplicate checking of msgfmt to match the duplicate checking of
msgmerge and other tools.
-rw-r--r--src/ChangeLog12
-rw-r--r--src/msgfmt.c266
-rw-r--r--src/read-po.c4
3 files changed, 160 insertions, 122 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 0f6cef8..8f72f0f 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,17 @@
2001-11-17 Bruno Haible <haible@clisp.cons.org>
+ * msgfmt.c (is_nonobsolete): New function.
+ (main): Remove obsolete messages after reading all input files.
+ (check_header_entry): New function, extracted from
+ format_directive_message.
+ (format_directive_message): Perform duplicate checking also on
+ obsolete, untranslated and fuzzy messages, like msgmerge and the
+ other tools do. Put also obsolete, untranslated and fuzzy messages
+ on the result list, but mark them obsolete.
+ (read_po_file): Call po_lex_pass_obsolete_entries.
+
+2001-11-17 Bruno Haible <haible@clisp.cons.org>
+
* po.c (po_callback_message): Ignore obsolete header entries, for
consistency with msgdomain_list_print(), compare_po_locale_charsets(),
iconv_message_list(), catenate_msgdomain_list().
diff --git a/src/msgfmt.c b/src/msgfmt.c
index 18a530a..e900180 100644
--- a/src/msgfmt.c
+++ b/src/msgfmt.c
@@ -173,6 +173,7 @@ static void usage PARAMS ((int status))
static const char *add_mo_suffix PARAMS ((const char *));
static struct msg_domain *new_domain PARAMS ((const char *name,
const char *file_name));
+static bool is_nonobsolete PARAMS ((const message_ty *mp));
#if HAVE_SIGINFO
static void sigfpe_handler PARAMS ((int sig, siginfo_t *sip, void *scp));
#else
@@ -189,6 +190,7 @@ static void check_pair PARAMS ((const char *msgid, const lex_pos_ty *msgid_pos,
const char *msgstr, size_t msgstr_len,
const lex_pos_ty *msgstr_pos,
enum is_format is_format[NFORMATS]));
+static void check_header_entry PARAMS ((const char *msgstr_string));
static void format_constructor PARAMS ((po_ty *that));
static void format_debrief PARAMS ((po_ty *));
static void format_directive_domain PARAMS ((po_ty *pop, char *name));
@@ -411,6 +413,11 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
++optind;
}
+ /* Remove obsolete messages. They were only needed for duplicate
+ checking. */
+ for (domain = domain_list; domain != NULL; domain = domain->next)
+ message_list_remove_if_not (domain->mlp, is_nonobsolete);
+
/* Check the plural expression is present if needed and has valid syntax. */
if (check_header)
for (domain = domain_list; domain != NULL; domain = domain->next)
@@ -603,6 +610,14 @@ new_domain (name, file_name)
}
+static bool
+is_nonobsolete (mp)
+ const message_ty *mp;
+{
+ return !mp->obsolete;
+}
+
+
static sigjmp_buf sigfpe_exit;
#if HAVE_SIGINFO
@@ -1120,6 +1135,59 @@ check_pair (msgid, msgid_pos, msgid_plural, msgstr, msgstr_len, msgstr_pos,
}
+/* Perform miscellaneous checks on a header entry. */
+static void
+check_header_entry (msgstr_string)
+ const char *msgstr_string;
+{
+ static const char *required_fields[] =
+ {
+ "Project-Id-Version", "PO-Revision-Date", "Last-Translator",
+ "Language-Team", "MIME-Version", "Content-Type",
+ "Content-Transfer-Encoding"
+ };
+ static const char *default_values[] =
+ {
+ "PACKAGE VERSION", "YEAR-MO-DA", "FULL NAME", "LANGUAGE", NULL,
+ "text/plain; charset=CHARSET", "ENCODING"
+ };
+ const size_t nfields = SIZEOF (required_fields);
+ int initial = -1;
+ int cnt;
+
+ for (cnt = 0; cnt < nfields; ++cnt)
+ {
+ char *endp = strstr (msgstr_string, required_fields[cnt]);
+
+ if (endp == NULL)
+ error (0, 0, _("headerfield `%s' missing in header"),
+ required_fields[cnt]);
+ else if (endp != msgstr_string && endp[-1] != '\n')
+ error (0, 0, _("header field `%s' should start at beginning of line"),
+ required_fields[cnt]);
+ else if (default_values[cnt] != NULL
+ && strncmp (default_values[cnt],
+ endp + strlen (required_fields[cnt]) + 2,
+ strlen (default_values[cnt])) == 0)
+ {
+ if (initial != -1)
+ {
+ error (0, 0, _("\
+some header fields still have the initial default value"));
+ initial = -1;
+ break;
+ }
+ else
+ initial = cnt;
+ }
+ }
+
+ if (initial != -1)
+ error (0, 0, _("field `%s' still has initial default value"),
+ required_fields[initial]);
+}
+
+
/* The rest of the file is similar to read-po.c. The differences are:
- Comments are not stored, they are discarded right away.
- The header entry check is performed on-the-fly.
@@ -1218,144 +1286,97 @@ format_directive_message (that, msgid_string, msgid_pos, msgid_plural,
bool obsolete;
{
msgfmt_class_ty *this = (msgfmt_class_ty *) that;
- message_ty *entry;
- message_ty *other_entry;
+ message_ty *mp;
size_t i;
- /* Don't emit untranslated entries. Also don't emit fuzzy entries, unless
- --use-fuzzy was specified. But ignore fuzziness of the header entry. */
- if (msgstr_string[0] == '\0'
- || (!include_all && this->is_fuzzy && msgid_string[0] != '\0'))
- {
- if (check_compatibility)
- {
- error_with_progname = false;
- error_at_line (0, 0, msgstr_pos->file_name, msgstr_pos->line_number,
- (msgstr_string[0] == '\0'
- ? _("empty `msgstr' entry ignored")
- : _("fuzzy `msgstr' entry ignored")));
- error_with_progname = true;
- }
+ /* Check whether already a domain is specified. If not, use default
+ domain. */
+ if (current_domain == NULL)
+ current_domain = new_domain (MESSAGE_DOMAIN_DEFAULT,
+ add_mo_suffix (MESSAGE_DOMAIN_DEFAULT));
- /* Increment counter for fuzzy/untranslated messages. */
- if (msgstr_string[0] == '\0')
- ++msgs_untranslated;
- else
- ++msgs_fuzzy;
+ /* Duplicate checking. */
+ mp = message_list_search (current_domain->mlp, msgid_string);
+ if (mp)
+ {
+ /* We give a fatal error about this, regardless whether the
+ translations are equal or different. This is for consistency
+ with msgmerge, msgcat and others. The user can use the
+ msguniq program to get rid of duplicates. */
+ po_gram_error_at_line (msgid_pos, _("duplicate message definition"));
+ po_gram_error_at_line (&mp->pos, _("\
+...this is the location of the first definition"));
- /* Free strings allocated in po-gram.y. */
+ /* We don't need the just constructed entries' parameter string
+ (allocated in po-gram.y). */
+ free (msgid_string);
free (msgstr_string);
}
else
{
- /* Test for header entry. */
- if (msgid_string[0] == '\0')
+ /* Construct message to add to the list.
+ Non-obsolete messages will be output.
+ Obsolete message go into the list only for duplicate checking. */
+ mp = message_alloc (NULL, NULL, msgstr_string, msgstr_len, msgstr_pos);
+ mp->msgid = msgid_string;
+ mp->msgid_plural = msgid_plural;
+ mp->obsolete = obsolete;
+
+ if (!obsolete)
{
- this->has_header_entry = true;
-
- /* Do some more tests on test contents of the header entry. */
- if (check_header)
+ /* Don't emit untranslated entries.
+ Also don't emit fuzzy entries, unless --use-fuzzy was specified.
+ But ignore fuzziness of the header entry. */
+ if (msgstr_string[0] == '\0'
+ || (!include_all && this->is_fuzzy && msgid_string[0] != '\0'))
{
- static const char *required_fields[] =
- {
- "Project-Id-Version", "PO-Revision-Date",
- "Last-Translator", "Language-Team", "MIME-Version",
- "Content-Type", "Content-Transfer-Encoding"
- };
- static const char *default_values[] =
- {
- "PACKAGE VERSION", "YEAR-MO-DA", "FULL NAME", "LANGUAGE",
- NULL, "text/plain; charset=CHARSET", "ENCODING"
- };
- const size_t nfields = SIZEOF (required_fields);
- int initial = -1;
- int cnt;
-
- for (cnt = 0; cnt < nfields; ++cnt)
+ if (check_compatibility)
{
- char *endp = strstr (msgstr_string, required_fields[cnt]);
-
- if (endp == NULL)
- error (0, 0, _("headerfield `%s' missing in header"),
- required_fields[cnt]);
- else if (endp != msgstr_string && endp[-1] != '\n')
- error (0, 0, _("\
-header field `%s' should start at beginning of line"),
- required_fields[cnt]);
- else if (default_values[cnt] != NULL
- && strncmp (default_values[cnt],
- endp + strlen (required_fields[cnt]) + 2,
- strlen (default_values[cnt])) == 0)
- {
- if (initial != -1)
- {
- error (0, 0, _("\
-some header fields still have the initial default value"));
- initial = -1;
- break;
- }
- else
- initial = cnt;
- }
+ error_with_progname = false;
+ error_at_line (0, 0, msgstr_pos->file_name,
+ msgstr_pos->line_number,
+ (msgstr_string[0] == '\0'
+ ? _("empty `msgstr' entry ignored")
+ : _("fuzzy `msgstr' entry ignored")));
+ error_with_progname = true;
}
- if (initial != -1)
- error (0, 0, _("field `%s' still has initial default value"),
- required_fields[initial]);
+ /* Increment counter for fuzzy/untranslated messages. */
+ if (msgstr_string[0] == '\0')
+ ++msgs_untranslated;
+ else
+ ++msgs_fuzzy;
+
+ mp->obsolete = true;
}
- }
- else
- /* We don't count the header entry in the statistic so place the
- counter incrementation here. */
- if (this->is_fuzzy)
- ++msgs_fuzzy;
- else
- ++msgs_translated;
-
- /* We found a valid pair of msgid/msgstr.
- Construct struct to describe msgstr definition. */
- entry = message_alloc (NULL, NULL, NULL, 0, msgstr_pos);
- entry->msgid = msgid_string;
- entry->msgid_plural = msgid_plural;
- entry->msgstr = msgstr_string;
- entry->msgstr_len = msgstr_len;
-
- /* Do some more checks on both strings. */
- check_pair (msgid_string, msgid_pos, msgid_plural,
- msgstr_string, msgstr_len, msgstr_pos,
- this->is_format);
-
- /* Check whether already a domain is specified. If not use default
- domain. */
- if (current_domain == NULL)
- current_domain = new_domain (MESSAGE_DOMAIN_DEFAULT,
- add_mo_suffix (MESSAGE_DOMAIN_DEFAULT));
-
- /* We insert the ID/string pair into the list and hashing table.
- But we have to take care for duplicates. */
- other_entry = message_list_search (current_domain->mlp, msgid_string);
- if (other_entry != NULL)
- {
- /* We don't need the just constructed entry. */
- free (entry);
-
- /* We give a fatal error about this, regardless whether the
- translations are equal or different. This is for consistency
- with msgmerge, msgcat and others. The user can use the
- msguniq program to get rid of duplicates. */
- po_gram_error_at_line (msgid_pos, _("\
-duplicate message definition"));
- po_gram_error_at_line (&other_entry->pos, _("\
-...this is the location of the first definition"));
+ else
+ {
+ /* Test for header entry. */
+ if (msgid_string[0] == '\0')
+ {
+ this->has_header_entry = true;
- /* We don't need the just constructed entries'
- parameter string (allocated in po-gram.y). */
- free (msgid_string);
- free (msgstr_string);
+ /* Do some more tests on the contents of the header
+ entry. */
+ if (check_header)
+ check_header_entry (msgstr_string);
+ }
+ else
+ /* We don't count the header entry in the statistic so place
+ the counter incrementation here. */
+ if (this->is_fuzzy)
+ ++msgs_fuzzy;
+ else
+ ++msgs_translated;
+
+ /* Do some more checks on both strings. */
+ check_pair (msgid_string, msgid_pos, msgid_plural,
+ msgstr_string, msgstr_len, msgstr_pos,
+ this->is_format);
+ }
}
- else
- message_list_append (current_domain->mlp, entry);
- }
+ message_list_append (current_domain->mlp, mp);
+ }
/* Prepare for next message. */
this->is_fuzzy = false;
@@ -1423,6 +1444,7 @@ read_po_file (filename)
po_ty *pop;
pop = po_alloc (&format_methods);
+ po_lex_pass_obsolete_entries (true);
po_scan_file (pop, filename);
po_free (pop);
}
diff --git a/src/read-po.c b/src/read-po.c
index b5a2702..c38fa0b 100644
--- a/src/read-po.c
+++ b/src/read-po.c
@@ -95,6 +95,7 @@ static void readall_comment_filepos PARAMS ((po_ty *that, const char *name,
size_t line));
+/* Prepare for first message. */
static void
readall_constructor (that)
po_ty *that;
@@ -135,6 +136,7 @@ readall_destructor (that)
}
+/* Process 'domain' directive from .po file. */
static void
readall_directive_domain (that, name)
po_ty *that;
@@ -168,6 +170,7 @@ readall_directive_domain (that, name)
}
+/* Process 'msgid'/'msgstr' pair from .po file. */
static void
readall_directive_message (that, msgid, msgid_pos, msgid_plural,
msgstr, msgstr_len, msgstr_pos, obsolete)
@@ -283,6 +286,7 @@ readall_comment_dot (that, s)
}
+/* Test for '#, fuzzy' comments and warn. */
static void
readall_comment_special (that, s)
po_ty *that;