]> git.ipfire.org Git - thirdparty/gettext.git/commitdiff
Better support of PO files that contain multiple domains.
authorBruno Haible <bruno@clisp.org>
Mon, 11 Jun 2001 20:01:56 +0000 (20:01 +0000)
committerBruno Haible <bruno@clisp.org>
Mon, 11 Jun 2001 20:01:56 +0000 (20:01 +0000)
29 files changed:
src/ChangeLog
src/dir-list.h
src/gettext.c
src/message.c
src/message.h
src/msgcmp.c
src/msgcomm.c
src/msgfmt.c
src/msgmerge.c
src/msgunfmt.c
src/ngettext.c
src/open-po.h
src/po-gram.h
src/po-hash.h
src/po-lex.c
src/po-lex.h
src/po.c
src/po.h
src/pos.h
src/read-po.c
src/read-po.h
src/str-list.h
src/write-po.c
src/write-po.h
src/xget-lex.c
src/xget-lex.h
src/xgettext.c
tests/ChangeLog
tests/Makefile.am

index acd84c226ad6f5a83ef8e2669e33f0a2ccd77b8e..0c5bc2dfeeaefbf96e60e76cbc0d841ce16e847e 100644 (file)
@@ -1,3 +1,110 @@
+2001-06-10  Bruno Haible  <haible@clisp.cons.org>
+
+       * message.h (struct message_variant_ty): Remove type.
+       (struct message_ty): Remove variant_count, variant fields. Add
+       msgstr, msgstr_len, pos fields.
+       (message_alloc): Add msgstr, msgstr_len, pp arguments.
+       (message_variant_search, message_variant_append): Remove declarations.
+       (msgdomain_ty): New type.
+       (msgdomain_alloc, msgdomain_free): New declarations.
+       (msgdomain_list_ty): New type.
+       (msgdomain_list_alloc, msgdomain_list_free, msgdomain_list_append,
+       msgdomain_list_append_list, msgdomain_list_sublist,
+       msgdomain_list_search, msgdomain_list_search_fuzzy): New declarations.
+       * message.c (message_alloc): Add msgstr, msgstr_len, pp arguments.
+       (message_free): Update.
+       (message_variant_search): Remove function.
+       (message_variant_append): Remove function.
+       (message_copy): Update.
+       (message_merge): Update.
+       (message_list_alloc): Use NULL, not 0.
+       (message_list_search): Likewise.
+       (message_list_search_fuzzy_inner): Update.
+       (message_list_list_alloc): Use NULL, not 0.
+       (message_list_list_search): Likewise.
+       (message_list_list_free): Comment out.
+       (msgdomain_alloc, msgdomain_free, msgdomain_list_alloc,
+       msgdomain_list_append, msgdomain_list_sublist): New functions.
+       * read-po.h (read_po_file): Change return type to
+       'msgdomain_list_ty *'.
+       * read-po.c (readall_class_ty): Remove field domain_list, add field
+       mdlp.
+       (readall_constructor): Update.
+       (readall_destructor): Likewise.
+       (readall_directive_message): Likewise.
+       (readall_parse_debrief): Remove function.
+       (readall_methods): Use NULL instead of readall_parse_debrief.
+       (read_po_file): Change return type to 'msgdomain_list_ty *'.
+       * write-po.h (message_list_print, message_list_sort_by_msgid,
+       message_list_sort_by_filepos): Remove declarations.
+       (msgdomain_list_print, msgdomain_list_sort_by_msgid,
+       msgdomain_list_sort_by_filepos): New declarations.
+       * write-po.c (message_print): Remove domain argument. Update. Assume
+       'first' is true.
+       (message_print_obsolete): Likewise.
+       (msgdomain_list_print): Renamed from message_list_print. Change type
+       of first argument.
+       (msgdomain_list_sort_by_msgid): Renamed from
+       message_list_sort_by_msgid. Change type of argument.
+       (msgdomain_list_sort_by_filepos): Renamed from
+       message_list_sort_by_filepos. Change type of argument.
+       * msgcmp.c (compare_class_ty): Remove field domain_list, add field
+       mdlp.
+       (multi_domain_mode): New variable.
+       (long_options): Add --multi-domain.
+       (main): Accept -m/--multi-domain.
+       (usage): Explain --multi-domain.
+       (match_domain): New function, extracted from 'compare'.
+       (compare): Update. Handle multi_domain_mode. Change argument types to
+       'const char *'.
+       (compare_constructor): Update.
+       (compare_destructor): Likewise.
+       (compare_directive_message): Likewise.
+       (compare_parse_debrief): Remove function.
+       (compare_methods): Use NULL instead of compare_parse_debrief.
+       (grammar): Change argument type to 'const char *' and return type to
+       'msgdomain_list_ty *'.
+       * msgcomm.c (main): Update.
+       (extract_directive_message): Update.
+       * msgmerge.c (multi_domain_mode): New variable.
+       (long_options): Add --multi-domain.
+       (struct statistics): New type.
+       (main): Accept -m/--multi-domain. Update.
+       (usage): Explain --multi-domain.
+       (compendium): Update.
+       (match_domain): New function, extracted from 'merge'.
+       (merge): Update. Handle multi_domain_mode.
+       * msgunfmt.c (main): Update.
+       (read_mo_file): Update.
+       * xgettext.c (main): Update.
+       (exclude_directive_message): Update.
+       (remember_a_message): Likewise.
+       (remember_a_message_plural): Likewise.
+       (scan_c_file): Change argument type to 'msgdomain_list_ty *'.
+       (extract_directive_message): Update.
+       (read_po_file): Change argument type to 'msgdomain_list_ty *'.
+       (construct_header): Update.
+
+       * dir-list.h: Don't use reserved identifiers in prototypes.
+       * gettext.c: Likewise.
+       * message.c: Likewise.
+       * msgcmp.c: Likewise.
+       * msgcomm.c: Likewise.
+       * msgfmt.c: Likewise.
+       * msgunfmt.c: Likewise.
+       * ngettext.c: Likewise.
+       * open-po.h: Likewise.
+       * po-hash.h: Likewise.
+       * po-lex.h: Likewise.
+       * po-lex.c: Likewise.
+       * po.h: Likewise.
+       * po.c: Likewise.
+       * str-list.h: Likewise.
+       * write-po.c: Likewise.
+       * xget-lex.h: Likewise.
+       * xget-lex.c: Likewise.
+       * xgettext.c: Likewise.
+
 2001-06-10  Bruno Haible  <haible@clisp.cons.org>
 
        * message.h (message_list_prepend): New declaration.
index d3378c2c91ace79e3b3815cb22ff5a8c30fc82f7..ffa68f0dedd8e026fac74dd18ffc0856da9915fe 100644 (file)
@@ -1,5 +1,5 @@
 /* GNU gettext - internationalization aids
-   Copyright (C) 1996, 1998, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1996, 1998, 2000, 2001 Free Software Foundation, Inc.
 
    This file was written by Peter Miller <millerp@canb.auug.org.au>
 
@@ -17,17 +17,17 @@ You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
-#ifndef SRC_DIR_LIST_H
-#define SRC_DIR_LIST_H
+#ifndef _DIR_LIST_H
+#define _DIR_LIST_H
 
 /* Management of the list of directories where PO files are searched.
    It is an ordered list, without duplicates.  The default value of the
    list consists of the single directory ".".  */
 
 /* Append a directory to the end of the list of directories.  */
-extern void dir_list_append PARAMS ((const char *__directory));
+extern void dir_list_append PARAMS ((const char *directory));
 
 /* Return the nth directory, or NULL of n is out of range.  */
-extern const char *dir_list_nth PARAMS ((int __n));
+extern const char *dir_list_nth PARAMS ((int n));
 
-#endif /* SRC_DIR_LIST_H */
+#endif /* _DIR_LIST_H */
index 9a8cbb2d824c7ae8670dae57c7fc1913ad6c28b4..ef992533a7914727f36990f5b58bfd45111fd9bd 100644 (file)
@@ -64,13 +64,14 @@ static const struct option long_options[] =
   { NULL, 0, NULL, 0 }
 };
 
-/* Prototypes for local functions.  */
-static void usage PARAMS ((int __status))
+/* Prototypes for local functions.  Needed to ensure compiler checking of
+   function argument counts despite of K&R C function definition syntax.  */
+static void usage PARAMS ((int status))
 #if defined __GNUC__ && ((__GNUC__ == 2 && __GNUC_MINOR__ >= 5) || __GNUC__ > 2)
      __attribute__ ((noreturn))
 #endif
 ;
-static const char *expand_escape PARAMS ((const char *__str));
+static const char *expand_escape PARAMS ((const char *str));
 
 int
 main (argc, argv)
index 40b754dd59cb732faea75e8a932cede630772d8e..e2cd57c1dafc9bedbbf3c299fd70d4b47485d500 100644 (file)
@@ -29,10 +29,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #include "system.h"
 
 
-/* Prototypes for local functions.  */
+/* Prototypes for local functions.  Needed to ensure compiler checking of
+   function argument counts despite of K&R C function definition syntax.  */
 static message_ty *message_list_search_fuzzy_inner PARAMS ((
-       message_list_ty *__mlp, const char *__msgid, double *__best_weight_p));
-
+       message_list_ty *mlp, const char *msgid, double *best_weight_p));
 
 
 enum is_c_format
@@ -72,26 +72,30 @@ parse_c_width_description_string (s)
 
 
 message_ty *
-message_alloc (msgid, msgid_plural)
+message_alloc (msgid, msgid_plural, msgstr, msgstr_len, pp)
      const char *msgid;
      const char *msgid_plural;
+     const char *msgstr;
+     size_t msgstr_len;
+     const lex_pos_ty *pp;
 {
   message_ty *mp;
 
   mp = xmalloc (sizeof (message_ty));
   mp->msgid = msgid;
   mp->msgid_plural = (msgid_plural != NULL ? xstrdup (msgid_plural) : NULL);
+  mp->msgstr = msgstr;
+  mp->msgstr_len = msgstr_len;
+  mp->pos = *pp;
   mp->comment = NULL;
   mp->comment_dot = NULL;
   mp->filepos_count = 0;
   mp->filepos = NULL;
-  mp->variant_count = 0;
-  mp->variant = NULL;
-  mp->used = 0;
-  mp->obsolete = 0;
   mp->is_fuzzy = 0;
   mp->is_c_format = undecided;
   mp->do_wrap = undecided;
+  mp->used = 0;
+  mp->obsolete = 0;
   return mp;
 }
 
@@ -102,17 +106,14 @@ message_free (mp)
 {
   size_t j;
 
+  free ((char *) mp->msgid);
+  if (mp->msgid_plural != NULL)
+    free ((char *) mp->msgid_plural);
+  free ((char *) mp->msgstr);
   if (mp->comment != NULL)
     string_list_free (mp->comment);
   if (mp->comment_dot != NULL)
     string_list_free (mp->comment_dot);
-  free ((char *) mp->msgid);
-  if (mp->msgid_plural != NULL)
-    free ((char *) mp->msgid_plural);
-  for (j = 0; j < mp->variant_count; ++j)
-    free ((char *) mp->variant[j].msgstr);
-  if (mp->variant != NULL)
-    free (mp->variant);
   for (j = 0; j < mp->filepos_count; ++j)
     free ((char *) mp->filepos[j].file_name);
   if (mp->filepos != NULL)
@@ -121,45 +122,6 @@ message_free (mp)
 }
 
 
-message_variant_ty *
-message_variant_search (mp, domain)
-     message_ty *mp;
-     const char *domain;
-{
-  size_t j;
-  message_variant_ty *mvp;
-
-  for (j = 0; j < mp->variant_count; ++j)
-    {
-      mvp = &mp->variant[j];
-      if (0 == strcmp (domain, mvp->domain))
-       return mvp;
-    }
-  return 0;
-}
-
-
-void
-message_variant_append (mp, domain, msgstr, msgstr_len, pp)
-     message_ty *mp;
-     const char *domain;
-     const char *msgstr;
-     size_t msgstr_len;
-     const lex_pos_ty *pp;
-{
-  size_t nbytes;
-  message_variant_ty *mvp;
-
-  nbytes = (mp->variant_count + 1) * sizeof (mp->variant[0]);
-  mp->variant = xrealloc (mp->variant, nbytes);
-  mvp = &mp->variant[mp->variant_count++];
-  mvp->domain = domain;
-  mvp->msgstr = msgstr;
-  mvp->msgstr_len = msgstr_len;
-  mvp->pos = *pp;
-}
-
-
 void
 message_comment_append (mp, s)
      message_ty *mp;
@@ -182,6 +144,58 @@ message_comment_dot_append (mp, s)
 }
 
 
+void
+message_comment_filepos (mp, name, line)
+     message_ty *mp;
+     const char *name;
+     size_t line;
+{
+  size_t nbytes;
+  lex_pos_ty *pp;
+  int min, max;
+  int j;
+
+  /* See if we have this position already.  They are kept in sorted
+     order, so use a binary chop.  */
+  /* FIXME: use bsearch */
+  min = 0;
+  max = (int) mp->filepos_count - 1;
+  while (min <= max)
+    {
+      int mid;
+      int cmp;
+
+      mid = (min + max) / 2;
+      pp = &mp->filepos[mid];
+      cmp = strcmp (pp->file_name, name);
+      if (cmp == 0)
+       cmp = (int) pp->line_number - line;
+      if (cmp == 0)
+       return;
+      if (cmp < 0)
+       min = mid + 1;
+      else
+       max = mid - 1;
+    }
+
+  /* Extend the list so that we can add an position to it.  */
+  nbytes = (mp->filepos_count + 1) * sizeof (mp->filepos[0]);
+  mp->filepos = xrealloc (mp->filepos, nbytes);
+
+  /* Shuffle the rest of the list up one, so that we can insert the
+     position at 'min'.  */
+  /* FIXME: use memmove */
+  for (j = mp->filepos_count; j > min; --j)
+    mp->filepos[j] = mp->filepos[j - 1];
+  mp->filepos_count++;
+
+  /* Insert the postion into the empty slot.  */
+  pp = &mp->filepos[min];
+  pp->file_name = xstrdup (name);
+  pp->line_number = line;
+}
+
+
 message_ty *
 message_copy (mp)
      message_ty *mp;
@@ -189,14 +203,9 @@ message_copy (mp)
   message_ty *result;
   size_t j;
 
-  result = message_alloc (xstrdup (mp->msgid), mp->msgid_plural);
+  result = message_alloc (xstrdup (mp->msgid), mp->msgid_plural,
+                         mp->msgstr, mp->msgstr_len, &mp->pos);
 
-  for (j = 0; j < mp->variant_count; ++j)
-    {
-      message_variant_ty *mvp = &mp->variant[j];
-      message_variant_append (result, mvp->domain, mvp->msgstr, mvp->msgstr_len,
-                             &mvp->pos);
-    }
   if (mp->comment)
     {
       for (j = 0; j < mp->comment->nitems; ++j)
@@ -224,186 +233,183 @@ message_merge (def, ref)
      message_ty *def;
      message_ty *ref;
 {
+  const char *msgstr;
+  size_t msgstr_len;
   message_ty *result;
-  const char *pot_date_ptr = NULL;
-  size_t pot_date_len = 0;
   size_t j;
 
   /* Take the msgid from the reference.  When fuzzy matches are made,
      the definition will not be unique, but the reference will be -
-     usually because it has a typo.  */
-  result = message_alloc (xstrdup (ref->msgid), ref->msgid_plural);
+     usually because it has only been slightly changed.  */
 
-  /* If msgid is the header entry (i.e., "") we find the
-     POT-Creation-Date line in the reference.  */
+  /* Take the msgstr from the definition.  The msgstr of the reference
+     is usually empty, as it was generated by xgettext.  If we currently
+     process the header entry we have to merge the msgstr by using the
+     POT-Creation-Date field from the reference.  */
   if (ref->msgid[0] == '\0')
     {
-      pot_date_ptr = strstr (ref->variant[0].msgstr, "POT-Creation-Date:");
-      if (pot_date_ptr != NULL)
-       {
-         const char *endp;
-
-         pot_date_ptr += sizeof ("POT-Creation-Date:") - 1;
-
-         endp = strchr (pot_date_ptr, '\n');
-         if (endp == NULL)
-           {
-             char *extended;
-             endp = strchr (pot_date_ptr, '\0');
-             pot_date_len = (endp - pot_date_ptr) + 1;
-             extended = (char *) alloca (pot_date_len + 1);
-             stpcpy (stpcpy (extended, pot_date_ptr), "\n");
-             pot_date_ptr = extended;
-           }
-         else
-           pot_date_len = (endp - pot_date_ptr) + 1;
-
-         if (pot_date_len == 0)
-           pot_date_ptr = NULL;
-       }
-    }
-
-  /* Take the variant list from the definition.  The msgstr of the
-     refences will be empty, as they were generated by xgettext.  If
-     we currently process the header entry we have to merge the msgstr
-     by using the POT-Creation-Date field from the .pot file.  */
-  for (j = 0; j < def->variant_count; ++j)
-    {
-      message_variant_ty *mvp = &def->variant[j];
-
-      if (ref->msgid[0] == '\0')
-       {
-         /* Oh, oh.  The header entry and we have something to fill in.  */
-         static const struct
-         {
-           const char *name;
-           size_t len;
-         } known_fields[] =
-         {
-           { "Project-Id-Version:", sizeof ("Project-Id-Version:") - 1 },
+      /* Oh, oh.  The header entry and we have something to fill in.  */
+      static const struct
+      {
+       const char *name;
+       size_t len;
+      } known_fields[] =
+      {
+       { "Project-Id-Version:", sizeof ("Project-Id-Version:") - 1 },
 #define PROJECT_ID     0
-           { "POT-Creation-Date:", sizeof ("POT-Creation-Date:") - 1 },
+       { "POT-Creation-Date:", sizeof ("POT-Creation-Date:") - 1 },
 #define POT_CREATION   1
-           { "PO-Revision-Date:", sizeof ("PO-Revision-Date:") - 1 },
+       { "PO-Revision-Date:", sizeof ("PO-Revision-Date:") - 1 },
 #define PO_REVISION    2
-           { "Last-Translator:", sizeof ("Last-Translator:") - 1 },
+       { "Last-Translator:", sizeof ("Last-Translator:") - 1 },
 #define LAST_TRANSLATOR        3
-           { "Language-Team:", sizeof ("Language-Team:") - 1 },
+       { "Language-Team:", sizeof ("Language-Team:") - 1 },
 #define LANGUAGE_TEAM  4
-           { "MIME-Version:", sizeof ("MIME-Version:") - 1 },
+       { "MIME-Version:", sizeof ("MIME-Version:") - 1 },
 #define MIME_VERSION   5
-           { "Content-Type:", sizeof ("Content-Type:") - 1 },
+       { "Content-Type:", sizeof ("Content-Type:") - 1 },
 #define CONTENT_TYPE   6
-           { "Content-Transfer-Encoding:",
-             sizeof ("Content-Transfer-Encoding:") - 1 }
+       { "Content-Transfer-Encoding:",
+         sizeof ("Content-Transfer-Encoding:") - 1 }
 #define CONTENT_TRANSFER 7
-         };
+      };
 #define UNKNOWN        8
-         struct
-         {
-           const char *string;
-           size_t len;
-         } header_fields[UNKNOWN + 1];
-         const char *cp;
-         char *newp;
-         size_t len, cnt;
-
-         /* Clear all fields.  */
-         memset (header_fields, '\0', sizeof (header_fields));
-
-         cp = mvp->msgstr;
-         while (*cp != '\0')
+      struct
+      {
+       const char *string;
+       size_t len;
+      } header_fields[UNKNOWN + 1];
+      const char *cp;
+      char *newp;
+      size_t len, cnt;
+
+      /* Clear all fields.  */
+      memset (header_fields, '\0', sizeof (header_fields));
+
+      cp = def->msgstr;
+      while (*cp != '\0')
+       {
+         const char *endp = strchr (cp, '\n');
+         int terminated = endp != NULL;
+
+         if (!terminated)
+           {
+             /* Add a trailing newline.  */
+             char *copy;
+             endp = strchr (cp, '\0');
+
+             len = endp - cp + 1;
+
+             copy = (char *) alloca (len + 1);
+             stpcpy (stpcpy (copy, cp), "\n");
+             cp = copy;
+           }
+         else
            {
-             const char *endp = strchr (cp, '\n');
-             int terminated = endp != NULL;
-
-             if (!terminated)
-               {
-                 char *copy;
-                 endp = strchr (cp, '\0');
-
-                 len = endp - cp + 1;
-
-                 copy = (char *) alloca (len + 1);
-                 stpcpy (stpcpy (copy, cp), "\n");
-                 cp = copy;
-               }
-             else
-               {
-                 len = (endp - cp) + 1;
-                 ++endp;
-               }
-
-             /* Compare with any of the known fields.  */
-             for (cnt = 0;
-                  cnt < sizeof (known_fields) / sizeof (known_fields[0]);
-                  ++cnt)
-               if (strncasecmp (cp, known_fields[cnt].name,
-                                known_fields[cnt].len) == 0)
-                 break;
-
-             if (cnt < sizeof (known_fields) / sizeof (known_fields[0]))
-               {
-                 header_fields[cnt].string = &cp[known_fields[cnt].len];
-                 header_fields[cnt].len = len - known_fields[cnt].len;
-               }
-             else
-               {
-                 /* It's an unknown field.  Append content to what is
-                    already known.  */
-                 char *extended = (char *) alloca (header_fields[UNKNOWN].len
-                                                   + len + 1);
-                 memcpy (extended, header_fields[UNKNOWN].string,
-                         header_fields[UNKNOWN].len);
-                 memcpy (&extended[header_fields[UNKNOWN].len], cp, len);
-                 extended[header_fields[UNKNOWN].len + len] = '\0';
-                 header_fields[UNKNOWN].string = extended;
-                 header_fields[UNKNOWN].len += len;
-               }
-
-             cp = endp;
+             len = (endp - cp) + 1;
+             ++endp;
            }
 
-         if (pot_date_ptr != NULL)
+         /* Compare with any of the known fields.  */
+         for (cnt = 0;
+              cnt < sizeof (known_fields) / sizeof (known_fields[0]);
+              ++cnt)
+           if (strncasecmp (cp, known_fields[cnt].name, known_fields[cnt].len)
+               == 0)
+             break;
+
+         if (cnt < sizeof (known_fields) / sizeof (known_fields[0]))
            {
-             header_fields[POT_CREATION].string = pot_date_ptr;
-             header_fields[POT_CREATION].len = pot_date_len;
+             header_fields[cnt].string = &cp[known_fields[cnt].len];
+             header_fields[cnt].len = len - known_fields[cnt].len;
            }
+         else
+           {
+             /* It's an unknown field.  Append content to what is already
+                known.  */
+             char *extended =
+               (char *) alloca (header_fields[UNKNOWN].len + len + 1);
+             memcpy (extended, header_fields[UNKNOWN].string,
+                     header_fields[UNKNOWN].len);
+             memcpy (&extended[header_fields[UNKNOWN].len], cp, len);
+             extended[header_fields[UNKNOWN].len + len] = '\0';
+             header_fields[UNKNOWN].string = extended;
+             header_fields[UNKNOWN].len += len;
+           }
+
+         cp = endp;
+       }
+
+      {
+       const char *pot_date_ptr;
+
+       pot_date_ptr = strstr (ref->msgstr, "POT-Creation-Date:");
+       if (pot_date_ptr != NULL)
+         {
+           size_t pot_date_len;
+           const char *endp;
+
+           pot_date_ptr += sizeof ("POT-Creation-Date:") - 1;
+
+           endp = strchr (pot_date_ptr, '\n');
+           if (endp == NULL)
+             {
+               /* Add a trailing newline.  */
+               char *extended;
+               endp = strchr (pot_date_ptr, '\0');
+               pot_date_len = (endp - pot_date_ptr) + 1;
+               extended = (char *) alloca (pot_date_len + 1);
+               stpcpy (stpcpy (extended, pot_date_ptr), "\n");
+               pot_date_ptr = extended;
+             }
+           else
+             pot_date_len = (endp - pot_date_ptr) + 1;
+
+           header_fields[POT_CREATION].string = pot_date_ptr;
+           header_fields[POT_CREATION].len = pot_date_len;
+         }
+      }
 
-         /* Concatenate all the various fields.  */
-         len = 0;
-         for (cnt = 0; cnt < UNKNOWN; ++cnt)
-           if (header_fields[cnt].string != NULL)
-             len += known_fields[cnt].len + header_fields[cnt].len;
-         len += header_fields[UNKNOWN].len;
+      /* Concatenate all the various fields.  */
+      len = 0;
+      for (cnt = 0; cnt < UNKNOWN; ++cnt)
+       if (header_fields[cnt].string != NULL)
+         len += known_fields[cnt].len + header_fields[cnt].len;
+      len += header_fields[UNKNOWN].len;
 
-         cp = newp = (char *) xmalloc (len + 1);
-         newp[len] = '\0';
+      cp = newp = (char *) xmalloc (len + 1);
+      newp[len] = '\0';
 
 #define IF_FILLED(idx)                                                       \
-         if (header_fields[idx].string)                                      \
-           newp = stpncpy (stpcpy (newp, known_fields[idx].name),            \
-                           header_fields[idx].string, header_fields[idx].len)
-
-         IF_FILLED (PROJECT_ID);
-         IF_FILLED (POT_CREATION);
-         IF_FILLED (PO_REVISION);
-         IF_FILLED (LAST_TRANSLATOR);
-         IF_FILLED (LANGUAGE_TEAM);
-         IF_FILLED (MIME_VERSION);
-         IF_FILLED (CONTENT_TYPE);
-         IF_FILLED (CONTENT_TRANSFER);
-         if (header_fields[UNKNOWN].string != NULL)
-           stpcpy (newp, header_fields[UNKNOWN].string);
-
-         message_variant_append (result, mvp->domain, cp, strlen (cp) + 1,
-                                 &mvp->pos);
-       }
-      else
-       message_variant_append (result, mvp->domain, mvp->msgstr,
-                               mvp->msgstr_len, &mvp->pos);
+      if (header_fields[idx].string)                                         \
+       newp = stpncpy (stpcpy (newp, known_fields[idx].name),                \
+                       header_fields[idx].string, header_fields[idx].len)
+
+      IF_FILLED (PROJECT_ID);
+      IF_FILLED (POT_CREATION);
+      IF_FILLED (PO_REVISION);
+      IF_FILLED (LAST_TRANSLATOR);
+      IF_FILLED (LANGUAGE_TEAM);
+      IF_FILLED (MIME_VERSION);
+      IF_FILLED (CONTENT_TYPE);
+      IF_FILLED (CONTENT_TRANSFER);
+      if (header_fields[UNKNOWN].string != NULL)
+       stpcpy (newp, header_fields[UNKNOWN].string);
+
+#undef IF_FILLED
+
+      msgstr = cp;
+      msgstr_len = strlen (cp) + 1;
+    }
+  else
+    {
+      msgstr = def->msgstr;
+      msgstr_len = def->msgstr_len;
     }
 
+  result = message_alloc (xstrdup (ref->msgid), ref->msgid_plural,
+                         msgstr, msgstr_len, &def->pos);
+
   /* Take the comments from the definition file.  There will be none at
      all in the reference file, as it was generated by xgettext.  */
   if (def->comment)
@@ -438,58 +444,6 @@ message_merge (def, ref)
 }
 
 
-void
-message_comment_filepos (mp, name, line)
-     message_ty *mp;
-     const char *name;
-     size_t line;
-{
-  size_t nbytes;
-  lex_pos_ty *pp;
-  int min, max;
-  int j;
-
-  /* See if we have this position already.  They are kept in sorted
-     order, so use a binary chop.  */
-  /* FIXME: use bsearch */
-  min = 0;
-  max = (int) mp->filepos_count - 1;
-  while (min <= max)
-    {
-      int mid;
-      int cmp;
-
-      mid = (min + max) / 2;
-      pp = &mp->filepos[mid];
-      cmp = strcmp (pp->file_name, name);
-      if (cmp == 0)
-       cmp = (int) pp->line_number - line;
-      if (cmp == 0)
-       return;
-      if (cmp < 0)
-       min = mid + 1;
-      else
-       max = mid - 1;
-    }
-
-  /* Extend the list so that we can add an position to it.  */
-  nbytes = (mp->filepos_count + 1) * sizeof (mp->filepos[0]);
-  mp->filepos = xrealloc (mp->filepos, nbytes);
-
-  /* Shuffle the rest of the list up one, so that we can insert the
-     position at ``min''.  */
-  /* FIXME: use memmove */
-  for (j = mp->filepos_count; j > min; --j)
-    mp->filepos[j] = mp->filepos[j - 1];
-  mp->filepos_count++;
-
-  /* Insert the postion into the empty slot.  */
-  pp = &mp->filepos[min];
-  pp->file_name = xstrdup (name);
-  pp->line_number = line;
-}
-
-
 message_list_ty *
 message_list_alloc ()
 {
@@ -498,11 +452,25 @@ message_list_alloc ()
   mlp = xmalloc (sizeof (message_list_ty));
   mlp->nitems = 0;
   mlp->nitems_max = 0;
-  mlp->item = 0;
+  mlp->item = NULL;
   return mlp;
 }
 
 
+void
+message_list_free (mlp)
+     message_list_ty *mlp;
+{
+  size_t j;
+
+  for (j = 0; j < mlp->nitems; ++j)
+    message_free (mlp->item[j]);
+  if (mlp->item)
+    free (mlp->item);
+  free (mlp);
+}
+
+
 void
 message_list_append (mlp, mp)
      message_list_ty *mlp;
@@ -520,6 +488,28 @@ message_list_append (mlp, mp)
 }
 
 
+void
+message_list_prepend (mlp, mp)
+     message_list_ty *mlp;
+     message_ty *mp;
+{
+  size_t j;
+
+  if (mlp->nitems >= mlp->nitems_max)
+    {
+      size_t nbytes;
+
+      mlp->nitems_max = mlp->nitems_max * 2 + 4;
+      nbytes = mlp->nitems_max * sizeof (message_ty *);
+      mlp->item = xrealloc (mlp->item, nbytes);
+    }
+  for (j = mlp->nitems; j > 0; j--)
+    mlp->item[j] = mlp->item[j - 1];
+  mlp->item[0] = mp;
+  mlp->nitems++;
+}
+
+
 void
 message_list_delete_nth (mlp, n)
      message_list_ty *mlp;
@@ -548,10 +538,10 @@ message_list_search (mlp, msgid)
       message_ty *mp;
 
       mp = mlp->item[j];
-      if (0 == strcmp (msgid, mp->msgid))
+      if (strcmp (msgid, mp->msgid) == 0)
        return mp;
     }
-  return 0;
+  return NULL;
 }
 
 
@@ -567,23 +557,18 @@ message_list_search_fuzzy_inner (mlp, msgid, best_weight_p)
   best_mp = NULL;
   for (j = 0; j < mlp->nitems; ++j)
     {
-      size_t k;
-      double weight;
       message_ty *mp;
 
       mp = mlp->item[j];
 
-      for (k = 0; k < mp->variant_count; ++k)
-       if (mp->variant[k].msgstr != NULL && mp->variant[k].msgstr[0] != '\0')
-         break;
-      if (k >= mp->variant_count)
-       continue;
-
-      weight = fstrcmp (msgid, mp->msgid);
-      if (weight > *best_weight_p)
+      if (mp->msgstr != NULL && mp->msgstr[0] != '\0')
        {
-         *best_weight_p = weight;
-         best_mp = mp;
+         double weight = fstrcmp (msgid, mp->msgid);
+         if (weight > *best_weight_p)
+           {
+             *best_weight_p = weight;
+             best_mp = mp;
+           }
        }
     }
   return best_mp;
@@ -602,20 +587,6 @@ message_list_search_fuzzy (mlp, msgid)
 }
 
 
-void
-message_list_free (mlp)
-     message_list_ty *mlp;
-{
-  size_t j;
-
-  for (j = 0; j < mlp->nitems; ++j)
-    message_free (mlp->item[j]);
-  if (mlp->item)
-    free (mlp->item);
-  free (mlp);
-}
-
-
 message_list_list_ty *
 message_list_list_alloc ()
 {
@@ -624,11 +595,27 @@ message_list_list_alloc ()
   mllp = xmalloc (sizeof (message_list_list_ty));
   mllp->nitems = 0;
   mllp->nitems_max = 0;
-  mllp->item = 0;
+  mllp->item = NULL;
   return mllp;
 }
 
 
+#if 0 /* unused */
+void
+message_list_list_free (mllp)
+     message_list_list_ty *mllp;
+{
+  size_t j;
+
+  for (j = 0; j < mllp->nitems; ++j)
+    message_list_free (mllp->item[j]);
+  if (mllp->item)
+    free (mllp->item);
+  free (mllp);
+}
+#endif
+
+
 void
 message_list_list_append (mllp, mlp)
      message_list_list_ty *mllp;
@@ -675,7 +662,7 @@ message_list_list_search (mllp, msgid)
       if (mp)
         return mp;
     }
-  return 0;
+  return NULL;
 }
 
 
@@ -704,15 +691,159 @@ message_list_list_search_fuzzy (mllp, msgid)
 }
 
 
+msgdomain_ty*
+msgdomain_alloc (domain)
+     const char *domain;
+{
+  msgdomain_ty * mdp;
+
+  mdp = xmalloc (sizeof (msgdomain_ty));
+  mdp->domain = domain;
+  mdp->messages = message_list_alloc ();
+  return mdp;
+}
+
+
 void
-message_list_list_free (mllp)
-     message_list_list_ty *mllp;
+msgdomain_free (mdp)
+     msgdomain_ty *mdp;
+{
+  message_list_free (mdp->messages);
+  free (mdp);
+}
+
+
+msgdomain_list_ty *
+msgdomain_list_alloc ()
+{
+  msgdomain_list_ty *mdlp;
+
+  mdlp = xmalloc (sizeof (msgdomain_list_ty));
+  /* Put the default domain first, so that when we output it,
+     we can omit the 'domain' directive.  */
+  mdlp->nitems = 1;
+  mdlp->nitems_max = 1;
+  mdlp->item = xmalloc (mdlp->nitems_max * sizeof (msgdomain_ty *));
+  mdlp->item[0] = msgdomain_alloc (MESSAGE_DOMAIN_DEFAULT);
+  return mdlp;
+}
+
+
+#if 0 /* unused */
+void
+msgdomain_list_free (mdlp)
+     msgdomain_list_ty *mdlp;
 {
   size_t j;
 
-  for (j = 0; j < mllp->nitems; ++j)
-    message_list_free (mllp->item[j]);
-  if (mllp->item)
-    free (mllp->item);
-  free (mllp);
+  for (j = 0; j < mdlp->nitems; ++j)
+    msgdomain_free (mdlp->item[j]);
+  if (mdlp->item)
+    free (mdlp->item);
+  free (mdlp);
+}
+#endif
+
+
+void
+msgdomain_list_append (mdlp, mdp)
+     msgdomain_list_ty *mdlp;
+     msgdomain_ty *mdp;
+{
+  if (mdlp->nitems >= mdlp->nitems_max)
+    {
+      size_t nbytes;
+
+      mdlp->nitems_max = mdlp->nitems_max * 2 + 4;
+      nbytes = mdlp->nitems_max * sizeof (msgdomain_ty *);
+      mdlp->item = xrealloc (mdlp->item, nbytes);
+    }
+  mdlp->item[mdlp->nitems++] = mdp;
+}
+
+
+#if 0 /* unused */
+void
+msgdomain_list_append_list (mdlp, mdlp2)
+     msgdomain_list_ty *mdlp;
+     msgdomain_list_ty *mdlp2;
+{
+  size_t j;
+
+  for (j = 0; j < mdlp2->nitems; ++j)
+    msgdomain_list_append (mdlp, mdlp2->item[j]);
+}
+#endif
+
+
+message_list_ty *
+msgdomain_list_sublist (mdlp, domain, create)
+     msgdomain_list_ty *mdlp;
+     const char *domain;
+     int create;
+{
+  size_t j;
+
+  for (j = 0; j < mdlp->nitems; j++)
+    if (strcmp (mdlp->item[j]->domain, domain) == 0)
+      return mdlp->item[j]->messages;
+
+  if (create)
+    {
+      msgdomain_ty *mdp = msgdomain_alloc (domain);
+      msgdomain_list_append (mdlp, mdp);
+      return mdp->messages;
+    }
+  else
+    return NULL;
 }
+
+
+#if 0 /* unused */
+message_ty *
+msgdomain_list_search (mdlp, msgid)
+     msgdomain_list_ty *mdlp;
+     const char *msgid;
+{
+  size_t j;
+
+  for (j = 0; j < mdlp->nitems; ++j)
+    {
+      msgdomain_ty *mdp;
+      message_ty *mp;
+
+      mdp = mdlp->item[j];
+      mp = message_list_search (mdp->messages, msgid);
+      if (mp)
+        return mp;
+    }
+  return NULL;
+}
+#endif
+
+
+#if 0 /* unused */
+message_ty *
+msgdomain_list_search_fuzzy (mdlp, msgid)
+     msgdomain_list_ty *mdlp;
+     const char *msgid;
+{
+  size_t j;
+  double best_weight;
+  message_ty *best_mp;
+
+  best_weight = 0.6;
+  best_mp = NULL;
+  for (j = 0; j < mdlp->nitems; ++j)
+    {
+      msgdomain_ty *mdp;
+      message_ty *mp;
+
+      mdp = mdlp->item[j];
+      mp = message_list_search_fuzzy_inner (mdp->messages, msgid, &best_weight);
+      if (mp)
+       best_mp = mp;
+    }
+  return best_mp;
+}
+#endif
index 2cc355f0f0feebbe0cd160be92fca121aa65a786..c591df2171662c3492767204afab74fef16bd0e4 100644 (file)
@@ -24,7 +24,7 @@
 #include "pos.h"
 
 /* According to Sun's Uniforum proposal the default message domain is
-   named `messages'.  */
+   named 'messages'.  */
 #define MESSAGE_DOMAIN_DEFAULT "messages"
 
 
@@ -40,7 +40,8 @@ enum is_c_format
 
 extern enum is_c_format
        parse_c_format_description_string PARAMS ((const char *s));
-extern int possible_c_format_p PARAMS ((enum is_c_format));
+extern int
+       possible_c_format_p PARAMS ((enum is_c_format));
 
 
 /* Is current msgid wrappable?  */
@@ -55,23 +56,27 @@ enum is_wrap
 #define is_wrap is_c_format
 #endif
 
-extern enum is_wrap parse_c_width_description_string PARAMS ((const char *s));
+extern enum is_wrap
+       parse_c_width_description_string PARAMS ((const char *s));
 
 
-typedef struct message_variant_ty message_variant_ty;
-struct message_variant_ty
+typedef struct message_ty message_ty;
+struct message_ty
 {
-  const char *domain;
+  /* The msgid string.  */
+  const char *msgid;
 
-  lex_pos_ty pos;
+  /* The msgid's plural, if present.  */
+  const char *msgid_plural;
 
+  /* The msgstr strings.  */
   const char *msgstr;
+  /* The number of bytes in msgstr, including the terminating NUL.  */
   size_t msgstr_len;
-};
 
-typedef struct message_ty message_ty;
-struct message_ty
-{
+  /* Position in the source PO file.  */
+  lex_pos_ty pos;
+
   /* Plain comments (#) appearing before the message.  */
   string_list_ty *comment;
 
@@ -91,18 +96,8 @@ struct message_ty
   /* Do we want the string to be wrapped in the emitted PO file?  */
   enum is_wrap do_wrap;
 
-  /* The msgid string.  */
-  const char *msgid;
-
-  /* The msgid's plural, if present.  */
-  const char *msgid_plural;
-
-  /* The msgstr strings, one for each observed domain in the file.  */
-  size_t variant_count;
-  message_variant_ty *variant;
-
-  /* Used for checking that messages have been used, in the msgcmp and
-     msgmerge programs.  */
+  /* Used for checking that messages have been used, in the msgcmp,
+     msgmerge and msgcomm programs.  */
   int used;
 
   /* If set the message is obsolete and while writing out it should be
@@ -110,20 +105,24 @@ struct message_ty
   int obsolete;
 };
 
-message_ty *message_alloc PARAMS ((const char *msgid,
-                                  const char *msgid_plural));
-void message_free PARAMS ((message_ty *));
-
-message_variant_ty *message_variant_search PARAMS ((message_ty *mp,
-                                                   const char *domain));
-void message_variant_append PARAMS ((message_ty *mp, const char *domain,
-                                    const char *msgstr, size_t msgstr_len,
-                                    const lex_pos_ty *pp));
-void message_comment_append PARAMS ((message_ty *, const char *));
-void message_comment_dot_append PARAMS ((message_ty *, const char *));
-message_ty *message_copy PARAMS ((message_ty *));
-message_ty *message_merge PARAMS ((message_ty *def, message_ty *ref));
-void message_comment_filepos PARAMS ((message_ty *, const char *, size_t));
+extern message_ty *
+       message_alloc PARAMS ((const char *msgid, const char *msgid_plural,
+                             const char *msgstr, size_t msgstr_len,
+                             const lex_pos_ty *pp));
+extern void
+       message_free PARAMS ((message_ty *mp));
+extern void
+       message_comment_append PARAMS ((message_ty *mp, const char *comment));
+extern void
+       message_comment_dot_append PARAMS ((message_ty *mp,
+                                          const char *comment));
+extern void
+       message_comment_filepos PARAMS ((message_ty *mp,
+                                       const char *name, size_t line));
+extern message_ty *
+       message_copy PARAMS ((message_ty *mp));
+extern message_ty *
+       message_merge PARAMS ((message_ty *def, message_ty *ref));
 
 
 typedef struct message_list_ty message_list_ty;
@@ -134,14 +133,21 @@ struct message_list_ty
   size_t nitems_max;
 };
 
-message_list_ty *message_list_alloc PARAMS ((void));
-void message_list_free PARAMS ((message_list_ty *));
-void message_list_append PARAMS ((message_list_ty *, message_ty *));
-void message_list_prepend PARAMS ((message_list_ty *, message_ty *));
-void message_list_delete_nth PARAMS ((message_list_ty *, size_t));
-message_ty *message_list_search PARAMS ((message_list_ty *, const char *));
-message_ty *message_list_search_fuzzy PARAMS ((message_list_ty *,
-                                              const char *));
+extern message_list_ty *
+       message_list_alloc PARAMS ((void));
+extern void
+       message_list_free PARAMS ((message_list_ty *mlp));
+extern void
+       message_list_append PARAMS ((message_list_ty *mlp, message_ty *mp));
+extern void
+       message_list_prepend PARAMS ((message_list_ty *mlp, message_ty *mp));
+extern void
+       message_list_delete_nth PARAMS ((message_list_ty *mlp, size_t n));
+extern message_ty *
+       message_list_search PARAMS ((message_list_ty *mlp, const char *msgid));
+extern message_ty *
+       message_list_search_fuzzy PARAMS ((message_list_ty *mlp,
+                                         const char *msgid));
 
 
 typedef struct message_list_list_ty message_list_list_ty;
@@ -152,15 +158,64 @@ struct message_list_list_ty
   size_t nitems_max;
 };
 
-message_list_list_ty *message_list_list_alloc PARAMS ((void));
-void message_list_list_free PARAMS ((message_list_list_ty *));
-void message_list_list_append PARAMS ((message_list_list_ty *,
-                                      message_list_ty *));
-void message_list_list_append_list PARAMS ((message_list_list_ty *,
-                                           message_list_list_ty *));
-message_ty *message_list_list_search PARAMS ((message_list_list_ty *,
-                                             const char *));
-message_ty *message_list_list_search_fuzzy PARAMS ((message_list_list_ty *,
-                                                   const char *));
+extern message_list_list_ty *
+       message_list_list_alloc PARAMS ((void));
+extern void
+       message_list_list_free PARAMS ((message_list_list_ty *mllp));
+extern void
+       message_list_list_append PARAMS ((message_list_list_ty *mllp,
+                                        message_list_ty *mlp));
+extern void
+       message_list_list_append_list PARAMS ((message_list_list_ty *mllp,
+                                             message_list_list_ty *mllp2));
+extern message_ty *
+       message_list_list_search PARAMS ((message_list_list_ty *mllp,
+                                        const char *msgid));
+extern message_ty *
+       message_list_list_search_fuzzy PARAMS ((message_list_list_ty *mllp,
+                                              const char *msgid));
+
+
+typedef struct msgdomain_ty msgdomain_ty;
+struct msgdomain_ty
+{
+  const char *domain;
+  message_list_ty *messages;
+};
+
+extern msgdomain_ty *
+       msgdomain_alloc PARAMS ((const char *domain));
+extern void
+       msgdomain_free PARAMS ((msgdomain_ty *mdp));
+
+
+typedef struct msgdomain_list_ty msgdomain_list_ty;
+struct msgdomain_list_ty
+{
+  msgdomain_ty **item;
+  size_t nitems;
+  size_t nitems_max;
+};
+
+extern msgdomain_list_ty *
+       msgdomain_list_alloc PARAMS ((void));
+extern void
+       msgdomain_list_free PARAMS ((msgdomain_list_ty *mdlp));
+extern void
+       msgdomain_list_append PARAMS ((msgdomain_list_ty *mdlp,
+                                     msgdomain_ty *mdp));
+extern void
+       msgdomain_list_append_list PARAMS ((msgdomain_list_ty *mdlp,
+                                          msgdomain_list_ty *mdlp2));
+extern message_list_ty *
+       msgdomain_list_sublist PARAMS ((msgdomain_list_ty *mdlp,
+                                      const char *domain, int create));
+extern message_ty *
+       msgdomain_list_search PARAMS ((msgdomain_list_ty *mdlp,
+                                     const char *msgid));
+extern message_ty *
+       msgdomain_list_search_fuzzy PARAMS ((msgdomain_list_ty *mdlp,
+                                           const char *msgid));
+
 
 #endif /* message.h */
index 7c9f029c13aa259ebd9462aa6810bbd0f377c624..1efebb6ba690eabc8000dd4e8498df566a8bcb9b 100644 (file)
 #define _(str) gettext (str)
 
 
-/* This structure defines a derived class of the po_ty class.  (See
-   po.h for an explanation.)  */
-typedef struct compare_class_ty compare_class_ty;
-struct compare_class_ty
-{
-  /* inherited instance variables, etc */
-  PO_BASE_TY
-
-  /* Name of domain we are currently examining.  */
-  const char *domain;
-
-  /* List of domains already appeared in the current file.  */
-  string_list_ty *domain_list;
-
-  /* List of messages already appeared in the current file.  */
-  message_list_ty *mlp;
-};
+/* Apply the .pot file to each of the domains in the PO file.  */
+static int multi_domain_mode;
 
 /* Long options.  */
 static const struct option long_options[] =
 {
   { "directory", required_argument, NULL, 'D' },
   { "help", no_argument, NULL, 'h' },
+  { "multi-domain", no_argument, NULL, 'm' },
   { "version", no_argument, NULL, 'V' },
   { NULL, 0, NULL, 0 }
 };
 
 
-/* Prototypes for local functions.  */
-static void usage PARAMS ((int __status));
-static void compare PARAMS ((char *, char *));
-static message_list_ty *grammar PARAMS ((char *__filename));
-static void compare_constructor PARAMS ((po_ty *__that));
-static void compare_destructor PARAMS ((po_ty *__that));
-static void compare_directive_domain PARAMS ((po_ty *__that, char *__name));
-static void compare_directive_message PARAMS ((po_ty *__that, char *__msgid,
+/* Prototypes for local functions.  Needed to ensure compiler checking of
+   function argument counts despite of K&R C function definition syntax.  */
+static void usage PARAMS ((int status));
+static void match_domain PARAMS ((const char *fn1, const char *fn2,
+                                 message_list_ty *defmlp,
+                                 message_list_ty *refmlp, int *nerrors));
+static void compare PARAMS ((const char *, const char *));
+static msgdomain_list_ty *grammar PARAMS ((const char *filename));
+static void compare_constructor PARAMS ((po_ty *that));
+static void compare_destructor PARAMS ((po_ty *that));
+static void compare_directive_domain PARAMS ((po_ty *that, char *name));
+static void compare_directive_message PARAMS ((po_ty *that, char *msgid,
                                               lex_pos_ty *msgid_pos,
-                                              char *__msgid_plural,
-                                              char *__msgstr,
-                                              size_t __msgstr_len,
-                                              lex_pos_ty *__msgstr_pos,
-                                              int __obsolete));
-static void compare_parse_debrief PARAMS ((po_ty *__that));
+                                              char *msgid_plural,
+                                              char *msgstr, size_t msgstr_len,
+                                              lex_pos_ty *msgstr_pos,
+                                              int obsolete));
 
 
 int
@@ -106,7 +94,7 @@ main (argc, argv)
 
   do_help = 0;
   do_version = 0;
-  while ((optchar = getopt_long (argc, argv, "D:hV", long_options, NULL))
+  while ((optchar = getopt_long (argc, argv, "D:hmV", long_options, NULL))
         != EOF)
     switch (optchar)
       {
@@ -121,6 +109,10 @@ main (argc, argv)
        do_help = 1;
        break;
 
+      case 'm':
+       multi_domain_mode = 1;
+       break;
+
       case 'V':
        do_version = 1;
        break;
@@ -206,6 +198,12 @@ Input file location:\n\
       printf ("\n");
       /* xgettext: no-wrap */
       printf (_("\
+Operation modifiers:\n\
+  -m, --multi-domain          apply ref.pot to each of the domains in def.po\n\
+"));
+      printf ("\n");
+      /* xgettext: no-wrap */
+      printf (_("\
 Informative output:\n\
   -h, --help                  display this help and exit\n\
   -V, --version               output version information and exit\n\
@@ -218,71 +216,117 @@ Informative output:\n\
 }
 
 
+static void
+match_domain (fn1, fn2, defmlp, refmlp, nerrors)
+     const char *fn1;
+     const char *fn2;
+     message_list_ty *defmlp;
+     message_list_ty *refmlp;
+     int *nerrors;
+{
+  size_t j;
+
+  for (j = 0; j < refmlp->nitems; j++)
+    {
+      message_ty *refmsg;
+      message_ty *defmsg;
+
+      refmsg = refmlp->item[j];
+
+      /* See if it is in the other file.  */
+      defmsg = message_list_search (defmlp, refmsg->msgid);
+      if (defmsg)
+       defmsg->used = 1;
+      else
+       {
+         /* If the message was not defined at all, try to find a very
+            similar message, it could be a typo, or the suggestion may
+            help.  */
+         (*nerrors)++;
+         defmsg = message_list_search_fuzzy (defmlp, refmsg->msgid);
+         if (defmsg)
+           {
+             po_gram_error_at_line (&refmsg->pos, _("\
+this message is used but not defined..."));
+             po_gram_error_at_line (&defmsg->pos, _("\
+...but this definition is similar"));
+             defmsg->used = 1;
+           }
+         else
+           po_gram_error_at_line (&refmsg->pos, _("\
+this message is used but not defined in %s"), fn1);
+       }
+    }
+}
+
+
 static void
 compare (fn1, fn2)
-     char *fn1;
-     char *fn2;
+     const char *fn1;
+     const char *fn2;
 {
-  message_list_ty *list1;
-  message_list_ty *list2;
+  msgdomain_list_ty *def;
+  msgdomain_list_ty *ref;
   int nerrors;
-  message_ty *mp1;
   size_t j, k;
+  message_list_ty *empty_list;
 
   /* This is the master file, created by a human.  */
-  list1 = grammar (fn1);
+  def = grammar (fn1);
 
   /* This is the generated file, created by groping the sources with
      the xgettext program.  */
-  list2 = grammar (fn2);
+  ref = grammar (fn2);
+
+  empty_list = message_list_alloc ();
 
   /* Every entry in the xgettext generated file must be matched by a
      (single) entry in the human created file.  */
   nerrors = 0;
-  for (j = 0; j < list2->nitems; ++j)
-    {
-      message_ty *mp2;
+  if (!multi_domain_mode)
+    for (k = 0; k < ref->nitems; k++)
+      {
+       const char *domain = ref->item[k]->domain;
+       message_list_ty *refmlp = ref->item[k]->messages;
+       message_list_ty *defmlp;
 
-      mp2 = list2->item[j];
+       defmlp = msgdomain_list_sublist (def, domain, 0);
+       if (defmlp == NULL)
+         defmlp = empty_list;
 
-      /* See if it is in the other file.  */
-      mp1 = message_list_search (list1, mp2->msgid);
-      if (mp1)
-       {
-         mp1->used = 1;
-         continue;
-       }
+       match_domain (fn1, fn2, defmlp, refmlp, &nerrors);
+      }
+  else
+    {
+      /* Apply the references messages in the default domain to each of
+        the definition domains.  */
+      message_list_ty *refmlp = ref->item[0]->messages;
 
-      /* If the message was not defined at all, try to find a very
-        similar message, it could be a typo, or the suggestion may
-        help.  */
-      ++nerrors;
-      mp1 = message_list_search_fuzzy (list1, mp2->msgid);
-      if (mp1)
+      for (k = 0; k < def->nitems; k++)
        {
-         po_gram_error_at_line (&mp2->variant[0].pos, _("\
-this message is used but not defined..."));
-         po_gram_error_at_line (&mp1->variant[0].pos, _("\
-...but this definition is similar"));
-         mp1->used = 1;
-       }
-      else
-       {
-         po_gram_error_at_line (&mp2->variant[0].pos, _("\
-this message is used but not defined in %s"), fn1);
+         message_list_ty *defmlp = def->item[k]->messages;
+
+         /* Ignore the default message domain if it has no messages.  */
+         if (k > 0 || defmlp->nitems > 0)
+           match_domain (fn1, fn2, defmlp, refmlp, &nerrors);
        }
     }
 
-  /* Look for messages in the human generated file, which are not
-     present in the xgettext generated file, indicating messages which
-     are not used in the program.  */
-  for (k = 0; k < list1->nitems; ++k)
+  /* Look for messages in the definition file, which are not present
+     in the reference file, indicating messages which defined but not
+     used in the program.  */
+  for (k = 0; k < def->nitems; ++k)
     {
-      mp1 = list1->item[k];
-      if (mp1->used)
-       continue;
-      po_gram_error_at_line (&mp1->variant[0].pos,
-                          _("warning: this message is not used"));
+      message_list_ty *defmlp = def->item[k]->messages;
+
+      for (j = 0; j < defmlp->nitems; j++)
+       {
+         message_ty *defmsg = defmlp->item[j];
+
+         if (!defmsg->used)
+           po_gram_error_at_line (&defmsg->pos,
+                                  _("warning: this message is not used"));
+       }
     }
 
   /* Exit with status 1 on any error.  */
@@ -295,15 +339,33 @@ this message is used but not defined in %s"), fn1);
 
 /* Local functions.  */
 
+/* This structure defines a derived class of the po_ty class.  (See
+   po.h for an explanation.)  */
+typedef struct compare_class_ty compare_class_ty;
+struct compare_class_ty
+{
+  /* inherited instance variables, etc */
+  PO_BASE_TY
+
+  /* List of messages already appeared in the current file.  */
+  msgdomain_list_ty *mdlp;
+
+  /* Name of domain we are currently examining.  */
+  char *domain;
+
+  /* List of messages belonging to the current domain.  */
+  message_list_ty *mlp;
+};
+
 static void
 compare_constructor (that)
      po_ty *that;
 {
   compare_class_ty *this = (compare_class_ty *) that;
 
-  this->mlp = message_list_alloc ();
+  this->mdlp = msgdomain_list_alloc ();
   this->domain = MESSAGE_DOMAIN_DEFAULT;
-  this->domain_list = string_list_alloc ();
+  this->mlp = msgdomain_list_sublist (this->mdlp, this->domain, 1);
 }
 
 
@@ -313,8 +375,8 @@ compare_destructor (that)
 {
   compare_class_ty *this = (compare_class_ty *) that;
 
-  string_list_free (this->domain_list);
-  /* Do not free this->mlp!  */
+  (void) this;
+  /* Do not free this->mdlp and this->mlp.  */
 }
 
 
@@ -343,69 +405,24 @@ compare_directive_message (that, msgid, msgid_pos, msgid_plural,
 {
   compare_class_ty *this = (compare_class_ty *) that;
   message_ty *mp;
-  message_variant_ty *mvp;
 
-  /* Remember the domain names for later.  */
-  string_list_append_unique (this->domain_list, this->domain);
+  /* Select the appropriate sublist of this->mdlp.  */
+  this->mlp = msgdomain_list_sublist (this->mdlp, this->domain, 1);
 
   /* See if this message ID has been seen before.  */
   mp = message_list_search (this->mlp, msgid);
   if (mp)
-    free (msgid);
-  else
-    {
-      mp = message_alloc (msgid, msgid_plural);
-      message_list_append (this->mlp, mp);
-    }
-
-  /* See if this domain has been seen for this message ID.  */
-  mvp = message_variant_search (mp, this->domain);
-  if (mvp)
     {
       po_gram_error_at_line (msgid_pos, _("duplicate message definition"));
-      po_gram_error_at_line (&mvp->pos, _("\
+      po_gram_error_at_line (&mp->pos, _("\
 ...this is the location of the first definition"));
       free (msgstr);
+      free (msgid);
     }
   else
-    message_variant_append (mp, this->domain, msgstr, msgstr_len, msgstr_pos);
-}
-
-
-static void
-compare_parse_debrief (that)
-     po_ty *that;
-{
-  compare_class_ty *this = (compare_class_ty *) that;
-  message_list_ty *mlp = this->mlp;
-  size_t j;
-
-  /* For each domain in the used-domain-list, make sure each message
-     defines a msgstr in that domain.  */
-  for (j = 0; j < this->domain_list->nitems; ++j)
     {
-      const char *domain_name;
-      size_t k;
-
-      domain_name = this->domain_list->item[j];
-      for (k = 0; k < mlp->nitems; ++k)
-       {
-         const message_ty *mp;
-         size_t m;
-
-         mp = mlp->item[k];
-         for (m = 0; m < mp->variant_count; ++m)
-           {
-             message_variant_ty *mvp;
-
-             mvp = &mp->variant[m];
-             if (strcmp (domain_name, mvp->domain) == 0)
-               break;
-           }
-         if (m >= mp->variant_count)
-           po_gram_error_at_line (&mp->variant[0].pos, _("\
-this message has no definition in the \"%s\" domain"), domain_name);
-       }
+      mp = message_alloc (msgid, msgid_plural, msgstr, msgstr_len, msgstr_pos);
+      message_list_append (this->mlp, mp);
     }
 }
 
@@ -424,7 +441,7 @@ static po_method_ty compare_methods =
   compare_directive_domain,
   compare_directive_message,
   NULL, /* parse_brief */
-  compare_parse_debrief,
+  NULL, /* parse_debrief */
   NULL, /* comment */
   NULL, /* comment_dot */
   NULL, /* comment_filepos */
@@ -432,16 +449,16 @@ static po_method_ty compare_methods =
 };
 
 
-static message_list_ty *
+static msgdomain_list_ty *
 grammar (filename)
-     char *filename;
+     const char *filename;
 {
   po_ty *pop;
-  message_list_ty *mlp;
+  msgdomain_list_ty *mdlp;
 
   pop = po_alloc (&compare_methods);
   po_scan (pop, filename);
-  mlp = ((compare_class_ty *)pop)->mlp;
+  mdlp = ((compare_class_ty *)pop)->mdlp;
   po_free (pop);
-  return mlp;
+  return mdlp;
 }
index 8e61b3b4c58a015090ca63cce73d9a676eb2ea7e..33c3434e84c47bc15a70622022b362ac6c8e0ed6 100644 (file)
@@ -98,30 +98,30 @@ static const struct option long_options[] =
 };
 
 
-/* Prototypes for local functions.  */
+/* Prototypes for local functions.  Needed to ensure compiler checking of
+   function argument counts despite of K&R C function definition syntax.  */
 static void usage PARAMS ((int status))
 #if defined __GNUC__ && ((__GNUC__ == 2 && __GNUC_MINOR__ > 4) || __GNUC__ > 2)
        __attribute__ ((noreturn))
 #endif
 ;
-static string_list_ty *read_name_from_file PARAMS ((const char *__file_name));
-static void extract_constructor PARAMS ((po_ty *__that));
-static void extract_directive_domain PARAMS ((po_ty *__that, char *__name));
-static void extract_directive_message PARAMS ((po_ty *__that, char *__msgid,
-                                              lex_pos_ty *__msgid_pos,
-                                              char *__msgid_plural,
-                                              char *__msgstr,
-                                              size_t __msgstr_len,
-                                              lex_pos_ty *__msgstr_pos,
+static string_list_ty *read_name_from_file PARAMS ((const char *file_name));
+static void extract_constructor PARAMS ((po_ty *that));
+static void extract_directive_domain PARAMS ((po_ty *that, char *name));
+static void extract_directive_message PARAMS ((po_ty *that, char *msgid,
+                                              lex_pos_ty *msgid_pos,
+                                              char *msgid_plural,
+                                              char *msgstr, size_t msgstr_len,
+                                              lex_pos_ty *msgstr_pos,
                                               int obsolete));
-static void extract_parse_brief PARAMS ((po_ty *__that));
-static void extract_comment PARAMS ((po_ty *__that, const char *__s));
-static void extract_comment_dot PARAMS ((po_ty *__that, const char *__s));
-static void extract_comment_filepos PARAMS ((po_ty *__that, const char *__name,
-                                            int __line));
+static void extract_parse_brief PARAMS ((po_ty *that));
+static void extract_comment PARAMS ((po_ty *that, const char *s));
+static void extract_comment_dot PARAMS ((po_ty *that, const char *s));
+static void extract_comment_filepos PARAMS ((po_ty *that, const char *name,
+                                            int line));
 static void extract_comment_special PARAMS ((po_ty *that, const char *s));
-static void read_po_file PARAMS ((const char *__file_name,
-                                 message_list_ty *__mlp));
+static void read_po_file PARAMS ((const char *file_name,
+                                 message_list_ty *mlp));
 
 
 int
@@ -134,6 +134,7 @@ main (argc, argv)
   int do_help = 0;
   int do_version = 0;
   message_list_ty *mlp;
+  msgdomain_list_ty *result;
   int sort_by_msgid = 0;
   int sort_by_filepos = 0;
   const char *file_name;
@@ -331,7 +332,8 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
            more_than, less_than);
 
   /* Allocate a message list to remember all the messages.  */
-  mlp = message_list_alloc ();
+  result = msgdomain_list_alloc ();
+  mlp = result->item[0]->messages;
 
   /* Process all input files.  */
   for (cnt = 0; cnt < file_list->nitems; ++cnt)
@@ -353,12 +355,12 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
 
   /* Sorting the list of messages.  */
   if (sort_by_filepos)
-    message_list_sort_by_filepos (mlp);
+    msgdomain_list_sort_by_filepos (result);
   else if (sort_by_msgid)
-    message_list_sort_by_msgid (mlp);
+    msgdomain_list_sort_by_msgid (result);
 
   /* Write the PO file.  */
-  message_list_print (mlp, file_name, force_po, 0);
+  msgdomain_list_print (result, file_name, force_po, 0);
 
   exit (EXIT_SUCCESS);
 }
@@ -578,7 +580,6 @@ extract_directive_message (that, msgid, msgid_pos, msgid_plural,
 {
   extract_class_ty *this = (extract_class_ty *)that;
   message_ty *mp;
-  message_variant_ty *mvp;
   size_t j;
 
   /* If the msgid is the empty string, and we are omiting headers, throw
@@ -606,10 +607,13 @@ extract_directive_message (that, msgid, msgid_pos, msgid_plural,
   /* See if this message ID has been seen before.  */
   mp = message_list_search (this->mlp, msgid);
   if (mp)
-    free (msgid);
+    {
+      free (msgid);
+      free (msgstr);
+    }
   else
     {
-      mp = message_alloc (msgid, msgid_plural);
+      mp = message_alloc (msgid, msgid_plural, msgstr, msgstr_len, msgstr_pos);
       message_list_append (this->mlp, mp);
     }
 
@@ -660,14 +664,6 @@ extract_directive_message (that, msgid, msgid_pos, msgid_plural,
   this->is_fuzzy = 0;
   this->is_c_format = undecided;
   this->do_wrap = undecided;
-
-  /* See if this domain has been seen for this message ID.  */
-  mvp = message_variant_search (mp, MESSAGE_DOMAIN_DEFAULT);
-  if (mvp != NULL)
-    free (msgstr);
-  else
-    message_variant_append (mp, MESSAGE_DOMAIN_DEFAULT, msgstr, msgstr_len,
-                           msgstr_pos);
 }
 
 
index 69951f43ff46b996ffac4a6f580130abf0ff08c1..e44bf4165ad8de1cfa816bcae3e27f733d805273 100644 (file)
@@ -162,22 +162,22 @@ static const struct option long_options[] =
 # endif        /* GNU CC2  */
 #endif /* roundup  */
 
-/* Prototypes for local functions.  */
+/* Prototypes for local functions.  Needed to ensure compiler checking of
+   function argument counts despite of K&R C function definition syntax.  */
 static void usage PARAMS ((int status))
 #if defined __GNUC__ && ((__GNUC__ == 2 && __GNUC_MINOR__ >= 5) || __GNUC__ > 2)
        __attribute__ ((noreturn))
 #endif
 ;
-static void grammar PARAMS ((char *__filename));
-static void format_constructor PARAMS ((po_ty *__that));
-static void format_directive_domain PARAMS ((po_ty *__pop, char *__name));
-static void format_directive_message PARAMS ((po_ty *__pop, char *__msgid,
-                                             lex_pos_ty *__msgid_pos,
-                                             char *__msgid_plural,
-                                             char *__msgstr,
-                                             size_t __msgstr_len,
-                                             lex_pos_ty *__msgstr_pos,
-                                             int __obsolete));
+static void grammar PARAMS ((char *filename));
+static void format_constructor PARAMS ((po_ty *that));
+static void format_directive_domain PARAMS ((po_ty *pop, char *name));
+static void format_directive_message PARAMS ((po_ty *pop, char *msgid,
+                                             lex_pos_ty *msgid_pos,
+                                             char *msgid_plural,
+                                             char *msgstr, size_t msgstr_len,
+                                             lex_pos_ty *msgstr_pos,
+                                             int obsolete));
 static void format_comment_special PARAMS ((po_ty *pop, const char *s));
 static void format_debrief PARAMS ((po_ty *));
 static struct msg_domain *new_domain PARAMS ((const char *name,
index 77dd4000c37ff15b8a76aa76222d164642015835..58a1d94277e9341eb27ce8dc782f19e3ceead052 100644 (file)
@@ -48,7 +48,10 @@ static int verbosity_level;
 /* Force output of PO file even if empty.  */
 static int force_po;
 
-/* list of user-specified compendiums.  */
+/* Apply the .pot file to each of the domains in the PO file.  */
+static int multi_domain_mode;
+
+/* List of user-specified compendiums.  */
 static message_list_list_ty *compendiums;
 
 /* Long options.  */
@@ -61,6 +64,7 @@ static const struct option long_options[] =
   { "force-po", no_argument, &force_po, 1 },
   { "help", no_argument, NULL, 'h' },
   { "indent", no_argument, NULL, 'i' },
+  { "multi-domain", no_argument, NULL, 'm' },
   { "no-escape", no_argument, NULL, 'e' },
   { "no-location", no_argument, &line_comment, 0 },
   { "output-file", required_argument, NULL, 'o' },
@@ -76,10 +80,25 @@ static const struct option long_options[] =
 };
 
 
-/* Prototypes for local functions.  */
-static void usage PARAMS ((int __status));
-static message_list_ty *merge PARAMS ((const char *__fn1, const char *__fn2));
-static void compendium PARAMS ((const char *__filename));
+struct statistics
+{
+  size_t merged;
+  size_t fuzzied;
+  size_t missing;
+  size_t obsolete;
+};
+
+
+/* Prototypes for local functions.  Needed to ensure compiler checking of
+   function argument counts despite of K&R C function definition syntax.  */
+static void usage PARAMS ((int status));
+static msgdomain_list_ty *merge PARAMS ((const char *fn1, const char *fn2));
+static void compendium PARAMS ((const char *filename));
+static void match_domain PARAMS ((const char *fn1, const char *fn2,
+                                 message_list_list_ty *definitions,
+                                 message_list_ty *refmlp,
+                                 message_list_ty *resultmlp,
+                                 struct statistics *stats, int *processed));
 
 
 int
@@ -91,7 +110,7 @@ main (argc, argv)
   int do_help;
   int do_version;
   char *output_file;
-  message_list_ty *result;
+  msgdomain_list_ty *result;
   int sort_by_filepos = 0;
   int sort_by_msgid = 0;
 
@@ -117,7 +136,7 @@ main (argc, argv)
   output_file = NULL;
 
   while ((opt
-         = getopt_long (argc, argv, "C:D:eEFhio:qsvVw:", long_options, NULL))
+         = getopt_long (argc, argv, "C:D:eEFhimo:qsvVw:", long_options, NULL))
         != EOF)
     switch (opt)
       {
@@ -152,6 +171,10 @@ main (argc, argv)
        message_print_style_indent ();
        break;
 
+      case 'm':
+       multi_domain_mode = 1;
+       break;
+
       case 'o':
        output_file = optarg;
        break;
@@ -230,30 +253,17 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
 
   /* Sort the results.  */
   if (sort_by_filepos)
-    message_list_sort_by_filepos (result);
+    msgdomain_list_sort_by_filepos (result);
   else if (sort_by_msgid)
-    message_list_sort_by_msgid (result);
+    msgdomain_list_sort_by_msgid (result);
 
   /* Write the merged message list out.  */
-  message_list_print (result, output_file, force_po, 0);
+  msgdomain_list_print (result, output_file, force_po, 0);
 
   exit (EXIT_SUCCESS);
 }
 
 
-static void
-compendium (filename)
-    const char *filename;
-{
-  message_list_ty *mlp;
-
-  mlp = read_po_file (filename);
-  if (!compendiums)
-    compendiums = message_list_list_alloc ();
-  message_list_list_append (compendiums, mlp);
-}
-
-
 /* Display usage information and exit.  */
 static void
 usage (status)
@@ -303,6 +313,12 @@ Output file location:\n\
   -o, --output-file=FILE      write output to specified file\n\
 The results are written to standard output if no output file is specified\n\
 or if it is -.\n\
+"));
+      printf ("\n");
+      /* xgettext: no-wrap */
+      printf (_("\
+Operation modifiers:\n\
+  -m, --multi-domain          apply ref.pot to each of the domains in def.po\n\
 "));
       printf ("\n");
       /* xgettext: no-wrap */
@@ -337,59 +353,46 @@ Informative output:\n\
 }
 
 
-#define DOT_FREQUENCE 10
-
-static message_list_ty *
-merge (fn1, fn2)
-     const char *fn1;                  /* definitions */
-     const char *fn2;                  /* references */
+static void
+compendium (filename)
+    const char *filename;
 {
-  message_list_ty *def;
-  message_list_ty *ref;
-  message_ty *defmsg;
-  size_t j, k;
-  size_t merged, fuzzied, missing, obsolete;
-  message_list_ty *result;
-  message_list_list_ty *definitions;
+  msgdomain_list_ty *mdlp;
+  size_t k;
 
-  merged = fuzzied = missing = obsolete = 0;
-
-  /* This is the definitions file, created by a human.  */
-  def = read_po_file (fn1);
-
-  /* Glue the definition file and the compendiums together, to define
-     the set of places to look for message definitions.  */
-  definitions = message_list_list_alloc ();
-  message_list_list_append (definitions, def);
-  if (compendiums)
-    message_list_list_append_list (definitions, compendiums);
+  mdlp = read_po_file (filename);
+  if (!compendiums)
+    compendiums = message_list_list_alloc ();
+  for (k = 0; k < mdlp->nitems; k++)
+    message_list_list_append (compendiums, mdlp->item[k]->messages);
+}
 
-  /* This is the references file, created by groping the sources with
-     the xgettext program.  */
-  ref = read_po_file (fn2);
-  /* Add a dummy header entry, if the references file contains none.  */
-  if (message_list_search (ref, "") == NULL)
-    {
-      static lex_pos_ty pos = { __FILE__, __LINE__ };
-      message_ty *refmsg = message_alloc ("", NULL);
 
-      message_variant_append (refmsg, MESSAGE_DOMAIN_DEFAULT, "", 1, &pos);
-      message_list_prepend (ref, refmsg);
-    }
+#define DOT_FREQUENCE 10
 
-  result = message_list_alloc ();
+static void
+match_domain (fn1, fn2, definitions, refmlp, resultmlp, stats, processed)
+     const char *fn1;
+     const char *fn2;
+     message_list_list_ty *definitions;
+     message_list_ty *refmlp;
+     message_list_ty *resultmlp;
+     struct statistics *stats;
+     int *processed;
+{
+  size_t j;
 
-  /* Every reference must be matched with its definition. */
-  for (j = 0; j < ref->nitems; ++j)
+  for (j = 0; j < refmlp->nitems; j++, (*processed)++)
     {
       message_ty *refmsg;
+      message_ty *defmsg;
 
       /* Because merging can take a while we print something to signal
         we are not dead.  */
-      if (!quiet && verbosity_level <= 1 && j % DOT_FREQUENCE == 0)
+      if (!quiet && verbosity_level <= 1 && *processed % DOT_FREQUENCE == 0)
        fputc ('.', stderr);
 
-      refmsg = ref->item[j];
+      refmsg = refmlp->item[j];
 
       /* See if it is in the other file.  */
       defmsg = message_list_list_search (definitions, refmsg->msgid);
@@ -401,65 +404,147 @@ merge (fn1, fn2)
             this merged entry to the output message list.  */
          message_ty *mp = message_merge (defmsg, refmsg);
 
-         message_list_append (result, mp);
+         message_list_append (resultmlp, mp);
 
          /* Remember that this message has been used, when we scan
             later to see if anything was omitted.  */
          defmsg->used = 1;
-         ++merged;
-         continue;
+         stats->merged++;
        }
-
-      /* Special treatment for the header entry.  */
-      if (refmsg->msgid[0] == '\0')
-       continue;
-
-      /* If the message was not defined at all, try to find a very
-        similar message, it could be a typo, or the suggestion may
-        help.  */
-      defmsg = message_list_list_search_fuzzy (definitions, refmsg->msgid);
-      if (defmsg)
+      else if (refmsg->msgid[0] != '\0')
        {
-         message_ty *mp;
-
-         if (verbosity_level > 1)
+         /* If the message was not defined at all, try to find a very
+            similar message, it could be a typo, or the suggestion may
+            help.  */
+         defmsg = message_list_list_search_fuzzy (definitions, refmsg->msgid);
+         if (defmsg)
            {
-             po_gram_error_at_line (&refmsg->variant[0].pos, _("\
+             message_ty *mp;
+
+             if (verbosity_level > 1)
+               {
+                 po_gram_error_at_line (&refmsg->pos, _("\
 this message is used but not defined..."));
-             po_gram_error_at_line (&defmsg->variant[0].pos, _("\
+                 po_gram_error_at_line (&defmsg->pos, _("\
 ...but this definition is similar"));
-           }
+               }
 
-         /* Merge the reference with the definition: take the #. and
-            #: comments from the reference, take the # comments from
-            the definition, take the msgstr from the definition.  Add
-            this merged entry to the output message list.  */
-         mp = message_merge (defmsg, refmsg);
+             /* Merge the reference with the definition: take the #. and
+                #: comments from the reference, take the # comments from
+                the definition, take the msgstr from the definition.  Add
+                this merged entry to the output message list.  */
+             mp = message_merge (defmsg, refmsg);
 
-         mp->is_fuzzy = 1;
+             mp->is_fuzzy = 1;
 
-         message_list_append (result, mp);
+             message_list_append (resultmlp, mp);
 
-         /* Remember that this message has been used, when we scan
-            later to see if anything was omitted.  */
-         defmsg->used = 1;
-         ++fuzzied;
-         if (!quiet && verbosity_level <= 1)
-           /* Always print a dot if we handled a fuzzy match.  */
-           fputc ('.', stderr);
+             /* Remember that this message has been used, when we scan
+                later to see if anything was omitted.  */
+             defmsg->used = 1;
+             stats->fuzzied++;
+             if (!quiet && verbosity_level <= 1)
+               /* Always print a dot if we handled a fuzzy match.  */
+               fputc ('.', stderr);
+           }
+         else
+           {
+             message_ty *mp;
+
+             if (verbosity_level > 1)
+               po_gram_error_at_line (&refmsg->pos, _("\
+this message is used but not defined in %s"), fn1);
+
+             mp = message_copy (refmsg);
+
+             message_list_append (resultmlp, mp);
+             stats->missing++;
+           }
        }
-      else
+    }
+}
+
+static msgdomain_list_ty *
+merge (fn1, fn2)
+     const char *fn1;                  /* definitions */
+     const char *fn2;                  /* references */
+{
+  msgdomain_list_ty *def;
+  msgdomain_list_ty *ref;
+  size_t j, k;
+  size_t processed;
+  struct statistics stats;
+  msgdomain_list_ty *result;
+  message_list_list_ty *definitions;
+  message_list_ty *empty_list;
+
+  stats.merged = stats.fuzzied = stats.missing = stats.obsolete = 0;
+
+  /* This is the definitions file, created by a human.  */
+  def = read_po_file (fn1);
+
+  /* Create the set of places to look for message definitions: a list
+     whose first element will be definitions for the current domain, and
+     whose other elements come from the compendiums.  */
+  definitions = message_list_list_alloc ();
+  message_list_list_append (definitions, NULL);
+  if (compendiums)
+    message_list_list_append_list (definitions, compendiums);
+  empty_list = message_list_alloc ();
+
+  /* This is the references file, created by groping the sources with
+     the xgettext program.  */
+  ref = read_po_file (fn2);
+  /* Add a dummy header entry, if the references file contains none.  */
+  for (k = 0; k < ref->nitems; k++)
+    if (message_list_search (ref->item[k]->messages, "") == NULL)
+      {
+       static lex_pos_ty pos = { __FILE__, __LINE__ };
+       message_ty *refheader = message_alloc ("", NULL, "", 1, &pos);
+
+       message_list_prepend (ref->item[k]->messages, refheader);
+      }
+
+  result = msgdomain_list_alloc ();
+  processed = 0;
+
+  /* Every reference must be matched with its definition. */
+  if (!multi_domain_mode)
+    for (k = 0; k < ref->nitems; k++)
+      {
+       const char *domain = ref->item[k]->domain;
+       message_list_ty *refmlp = ref->item[k]->messages;
+       message_list_ty *resultmlp = msgdomain_list_sublist (result, domain, 1);
+
+       definitions->item[0] = msgdomain_list_sublist (def, domain, 0);
+       if (definitions->item[0] == NULL)
+         definitions->item[0] = empty_list;
+
+       match_domain (fn1, fn2, definitions, refmlp, resultmlp,
+                     &stats, &processed);
+      }
+  else
+    {
+      /* Apply the references messages in the default domain to each of
+        the definition domains.  */
+      message_list_ty *refmlp = ref->item[0]->messages;
+
+      for (k = 0; k < def->nitems; k++)
        {
-         message_ty *mp;
+         const char *domain = def->item[k]->domain;
+         message_list_ty *defmlp = def->item[k]->messages;
 
-         if (verbosity_level > 1)
-             po_gram_error_at_line (&refmsg->variant[0].pos, _("\
-this message is used but not defined in %s"), fn1);
+         /* Ignore the default message domain if it has no messages.  */
+         if (k > 0 || defmlp->nitems > 0)
+           {
+             message_list_ty *resultmlp =
+               msgdomain_list_sublist (result, domain, 1);
 
-         mp = message_copy (refmsg);
+             definitions->item[0] = defmlp;
 
-         message_list_append (result, mp);
-         ++missing;
+             match_domain (fn1, fn2, definitions, refmlp, resultmlp,
+                           &stats, &processed);
+           }
        }
     }
 
@@ -468,16 +553,24 @@ this message is used but not defined in %s"), fn1);
      used in the program.  Don't scan the compendium(s).  */
   for (k = 0; k < def->nitems; ++k)
     {
-      defmsg = def->item[k];
-      if (defmsg->used)
-       continue;
+      const char *domain = def->item[k]->domain;
+      message_list_ty *defmlp = def->item[k]->messages;
 
-      /* Remember the old translation although it is not used anymore.
-        But we mark it as obsolete.  */
-      defmsg->obsolete = 1;
+      for (j = 0; j < defmlp->nitems; j++)
+       {
+         message_ty *defmsg = defmlp->item[j];
 
-      message_list_append (result, defmsg);
-      ++obsolete;
+         if (!defmsg->used)
+           {
+             /* Remember the old translation although it is not used anymore.
+                But we mark it as obsolete.  */
+             defmsg->obsolete = 1;
+
+             message_list_append (msgdomain_list_sublist (result, domain, 1),
+                                  defmsg);
+             stats.obsolete++;
+           }
+       }
     }
 
   /* Report some statistics.  */
@@ -487,7 +580,8 @@ Read %ld old + %ld reference, \
 merged %ld, fuzzied %ld, missing %ld, obsolete %ld.\n"),
             !quiet && verbosity_level <= 1 ? "\n" : "",
             (long) def->nitems, (long) ref->nitems,
-            (long) merged, (long) fuzzied, (long) missing, (long) obsolete);
+            (long) stats.merged, (long) stats.fuzzied, (long) stats.missing,
+            (long) stats.obsolete);
   else if (!quiet)
     fputs (_(" done.\n"), stderr);
 
index 46a1cfb156a6a3ed76cd914a450d3e2cab94f05a..860aeef288a87cd987475c86ec290b7e7276063b 100644 (file)
@@ -74,14 +74,15 @@ static const struct option long_options[] =
 static enum { MO_LITTLE_ENDIAN, MO_BIG_ENDIAN } endian;
 
 
-/* Prototypes for local functions.  */
-static void usage PARAMS ((int __status));
-static nls_uint32 read32 PARAMS ((FILE *__fp, const char *__fn));
-static void seek32 PARAMS ((FILE *__fp, const char *__fn, long __offset));
-static char *string32 PARAMS ((FILE *__fp, const char *__fn, long __offset,
+/* Prototypes for local functions.  Needed to ensure compiler checking of
+   function argument counts despite of K&R C function definition syntax.  */
+static void usage PARAMS ((int status));
+static nls_uint32 read32 PARAMS ((FILE *fp, const char *fn));
+static void seek32 PARAMS ((FILE *fp, const char *fn, long offset));
+static char *string32 PARAMS ((FILE *fp, const char *fn, long offset,
                               size_t *lengthp));
-static message_list_ty *read_mo_file PARAMS ((message_list_ty *__mlp,
-                                             const char *__fn));
+static message_list_ty *read_mo_file PARAMS ((message_list_ty *mlp,
+                                             const char *fn));
 
 
 int
@@ -93,7 +94,8 @@ main (argc, argv)
   int do_help = 0;
   int do_version = 0;
   const char *output_file = "-";
-  message_list_ty *mlp = NULL;
+  message_list_ty *mlp;
+  msgdomain_list_ty *result;
   int sort_by_msgid = 0;
 
   /* Set program name for messages.  */
@@ -184,18 +186,24 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
 
   /* Read the given .mo file. */
   if (optind < argc)
-    do
-      mlp = read_mo_file (mlp, argv[optind]);
-    while (++optind < argc);
+    {
+      mlp = NULL;
+      do
+       mlp = read_mo_file (mlp, argv[optind]);
+      while (++optind < argc);
+    }
   else
     mlp = read_mo_file (NULL, "-");
 
+  result = msgdomain_list_alloc ();
+  result->item[0]->messages = mlp;
+
   /* Sorting the list of messages.  */
   if (sort_by_msgid)
-    message_list_sort_by_msgid (mlp);
+    msgdomain_list_sort_by_msgid (result);
 
   /* Write the resulting message list to the given .po file.  */
-  message_list_print (mlp, output_file, force_po, 0);
+  msgdomain_list_print (result, output_file, force_po, 0);
 
   /* No problems.  */
   exit (EXIT_SUCCESS);
@@ -434,9 +442,8 @@ read_mo_file (mlp, fn)
       mp = message_alloc (msgid,
                          (strlen (msgid) + 1 < msgid_len
                           ? msgid + strlen (msgid) + 1
-                          : NULL));
-      message_variant_append (mp, MESSAGE_DOMAIN_DEFAULT, msgstr, msgstr_len,
-                             &pos);
+                          : NULL),
+                         msgstr, msgstr_len, &pos);
       message_list_append (mlp, mp);
     }
 
index e08a162f59fdbd3c340df579b31f45a38cace32f..a3524a25f5fb6f74bbc6dc81159bd816f6aa6e4a 100644 (file)
@@ -49,13 +49,14 @@ static const struct option long_options[] =
   { NULL, 0, NULL, 0 }
 };
 
-/* Prototypes for local functions.  */
-static void usage PARAMS ((int __status))
+/* Prototypes for local functions.  Needed to ensure compiler checking of
+   function argument counts despite of K&R C function definition syntax.  */
+static void usage PARAMS ((int status))
 #if defined __GNUC__ && ((__GNUC__ == 2 && __GNUC_MINOR__ >= 5) || __GNUC__ > 2)
      __attribute__ ((noreturn))
 #endif
 ;
-static const char *expand_escape PARAMS ((const char *__str));
+static const char *expand_escape PARAMS ((const char *str));
 
 int
 main (argc, argv)
index 0bf9cb34b6e91ac11cd3f4300519db03813303d0..5fd358f1feda211436a484df3f0f245f296de2d2 100644 (file)
@@ -1,5 +1,5 @@
 /* Opening PO files.
-   Copyright (C) 1995, 1996, 1997, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1995, 1996, 1997, 2000, 2001 Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    along with this program; if not, write to the Free Software Foundation,
    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
-#ifndef SRC_OPEN_PO_H
-#define SRC_OPEN_PO_H
+#ifndef _OPEN_PO_H
+#define _OPEN_PO_H
 
 /* Open the input file with the name INPUT_NAME.  The ending .po is added
    if necessary.  If INPUT_NAME is not an absolute file name and the file is
    not found, the list of directories in "dir-list.h" is searched.  The
    file's pathname is returned in *FILE_NAME, for error message purposes.  */
-extern FILE *open_po_file PARAMS ((const char *__input_name,
-                                  char **__file_name));
+extern FILE *open_po_file PARAMS ((const char *input_name, char **file_name));
 
-#endif
+#endif /* _OPEN_PO_H */
index 11c62226752a405e2de480f4372b7f06c24c47e1..9c5b3491ce4527704bdb0541383093dde82cdd6f 100644 (file)
@@ -23,6 +23,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 /* Include some fundamental headers.  */
 #include <sys/types.h>
 
-int po_gram_parse PARAMS ((void));
+extern int po_gram_parse PARAMS ((void));
 
 #endif
index 051ff0387557c46ae3cb8cde2132432b3b7442e2..c1e90293da2b926c92a0e22ed246ffbee4c71c1b 100644 (file)
@@ -1,5 +1,5 @@
 /* GNU gettext - internationalization aids
-   Copyright (C) 1995, 1996, 1998 Free Software Foundation, Inc.
+   Copyright (C) 1995, 1996, 1998, 2001 Free Software Foundation, Inc.
 
    This file was written by Peter Miller <millerp@canb.auug.org.au>
 
@@ -17,9 +17,9 @@ You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
-#ifndef SRC_PO_HASH_H
-#define SRC_PO_HASH_H
+#ifndef _PO_HASH_H
+#define _PO_HASH_H
 
-int po_hash PARAMS ((const char *__string));
+extern int po_hash PARAMS ((const char *string));
 
-#endif
+#endif /* _PO_HASH_H */
index 0ad49d8c6ef7c9dec00753127e66ad1f8fabf66e..f94e81b74cd809106b119d4fee60edf3ee290958 100644 (file)
@@ -66,10 +66,11 @@ static int pass_comments = 0;
 int pass_obsolete_entries = 0;
 
 
-/* Prototypes for local functions.  */
+/* Prototypes for local functions.  Needed to ensure compiler checking of
+   function argument counts despite of K&R C function definition syntax.  */
 static int lex_getc PARAMS ((void));
-static void lex_ungetc PARAMS ((int __ch));
-static int keyword_p PARAMS ((const char *__s));
+static void lex_ungetc PARAMS ((int ch));
+static int keyword_p PARAMS ((const char *s));
 static int control_sequence PARAMS ((void));
 
 
index 0ade9e408a42bbf850dd652f12e2cab544bef35c..03332ce17ebc4881a8cc3d160a1da79228d09905 100644 (file)
@@ -42,7 +42,7 @@ extern int pass_obsolete_entries;
 
 
 /* Open the PO file FNAME and prepare its lexical analysis.  */
-extern void lex_open PARAMS ((const char *__fname));
+extern void lex_open PARAMS ((const char *fname));
 
 /* Terminate lexical analysis and close the current PO file.  */
 extern void lex_close PARAMS ((void));
@@ -52,11 +52,11 @@ extern void lex_close PARAMS ((void));
 extern int po_gram_lex PARAMS ((void));
 
 /* po_gram_lex() can return comments as COMMENT.  Switch this on or off.  */
-extern void po_lex_pass_comments PARAMS ((int __flag));
+extern void po_lex_pass_comments PARAMS ((int flag));
 
 /* po_gram_lex() can return obsolete entries as if they were normal entries.
    Switch this on or off.  */
-extern void po_lex_pass_obsolete_entries PARAMS ((int __flag));
+extern void po_lex_pass_obsolete_entries PARAMS ((int flag));
 
 
 /* ISO C 99 is smart enough to allow optimizations like this.  */
@@ -128,9 +128,9 @@ extern void po_lex_pass_obsolete_entries PARAMS ((int __flag));
   } while (0)
 
 #else
-extern void po_gram_error PARAMS ((const char *__fmt, ...));
-extern void po_gram_error_at_line PARAMS ((const lex_pos_ty *__pos,
-                                          const char *__fmt, ...));
+extern void po_gram_error PARAMS ((const char *fmt, ...));
+extern void po_gram_error_at_line PARAMS ((const lex_pos_ty *pos,
+                                          const char *fmt, ...));
 #endif
 
 
index e9ccb33da416becae6ad4660984553b85164df42..e148f25cb1a7a47a8fae281c64285da2ae148760 100644 (file)
--- a/src/po.c
+++ b/src/po.c
@@ -29,22 +29,23 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #include "po-hash.h"
 #include "system.h"
 
-/* Prototypes for local functions.  */
-static void po_parse_brief PARAMS ((po_ty *__pop));
-static void po_parse_debrief PARAMS ((po_ty *__pop));
+/* Prototypes for local functions.  Needed to ensure compiler checking of
+   function argument counts despite of K&R C function definition syntax.  */
+static void po_parse_brief PARAMS ((po_ty *pop));
+static void po_parse_debrief PARAMS ((po_ty *pop));
 
 /* Methods used indirectly by po_scan.  */
-static void po_directive_domain PARAMS ((po_ty *__pop, char *__name));
-static void po_directive_message PARAMS ((po_ty *__pop, char *__msgid,
-                                         lex_pos_ty *__msgid_pos,
-                                         char *__msgid_plural,
-                                         char *__msgstr, size_t __msgstr_len,
-                                         lex_pos_ty *__msgstr_pos,
-                                         int __obsolete));
-static void po_comment PARAMS ((po_ty *__pop, const char *__s));
-static void po_comment_dot PARAMS ((po_ty *__pop, const char *__s));
-static void po_comment_filepos PARAMS ((po_ty *__pop, const char *__name,
-                                       int __line));
+static void po_directive_domain PARAMS ((po_ty *pop, char *name));
+static void po_directive_message PARAMS ((po_ty *pop, char *msgid,
+                                         lex_pos_ty *msgid_pos,
+                                         char *msgid_plural,
+                                         char *msgstr, size_t msgstr_len,
+                                         lex_pos_ty *msgstr_pos,
+                                         int obsolete));
+static void po_comment PARAMS ((po_ty *pop, const char *s));
+static void po_comment_dot PARAMS ((po_ty *pop, const char *s));
+static void po_comment_filepos PARAMS ((po_ty *pop, const char *name,
+                                       int line));
 static void po_comment_special PARAMS ((po_ty *pop, const char *s));
 
 /* Local variables.  */
index 069296dc50e963ca51f1777bea50364864f9232f..9a97ba5ffc5f6450ab4f79317d7f4e2025880d16 100644 (file)
--- a/src/po.h
+++ b/src/po.h
@@ -17,8 +17,8 @@ You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
-#ifndef SRC_PO_H
-#define SRC_PO_H
+#ifndef _PO_H
+#define _PO_H
 
 #include "po-lex.h"
 
@@ -46,54 +46,54 @@ struct po_method_ty
   size_t size;
 
   /* what to do immediately after the instance is malloc()ed */
-  void (*constructor) PARAMS ((struct po_ty *__pop));
+  void (*constructor) PARAMS ((struct po_ty *pop));
 
   /* what to do immediately before the instance is free()ed */
-  void (*destructor) PARAMS ((struct po_ty *__pop));
+  void (*destructor) PARAMS ((struct po_ty *pop));
 
   /* what to do with a domain directive */
-  void (*directive_domain) PARAMS ((struct po_ty *__pop, char *__name));
+  void (*directive_domain) PARAMS ((struct po_ty *pop, char *name));
 
   /* what to do with a message directive */
-  void (*directive_message) PARAMS ((struct po_ty *__pop,
-                                    char *__msgid, lex_pos_ty *__msgid_pos,
-                                    char *__msgid_plural,
-                                    char *__msgstr, size_t __msgstr_len,
-                                    lex_pos_ty *__msgstr_pos,
-                                    int __obsolete));
+  void (*directive_message) PARAMS ((struct po_ty *pop,
+                                    char *msgid, lex_pos_ty *msgid_pos,
+                                    char *msgid_plural,
+                                    char *msgstr, size_t msgstr_len,
+                                    lex_pos_ty *msgstr_pos,
+                                    int obsolete));
 
   /* This method is invoked before the parse, but after the file is
      opened by the lexer.  */
-  void (*parse_brief) PARAMS ((struct po_ty *__pop));
+  void (*parse_brief) PARAMS ((struct po_ty *pop));
 
   /* This method is invoked after the parse, but before the file is
      closed by the lexer.  The intention is to make consistency checks
      against the file here, and emit the errors through the lex_error*
      functions.  */
-  void (*parse_debrief) PARAMS ((struct po_ty *__pop));
+  void (*parse_debrief) PARAMS ((struct po_ty *pop));
 
   /* What to do with a plain-vanilla comment - the expectation is that
      they will be accumulated, and added to the next message
      definition seen.  Or completely ignored.  */
-  void (*comment) PARAMS ((struct po_ty *__pop, const char *__s));
+  void (*comment) PARAMS ((struct po_ty *pop, const char *s));
 
   /* What to do with a comment that starts with a dot (i.e.  extracted
      by xgettext) - the expectation is that they will be accumulated,
      and added to the next message definition seen.  Or completely
      ignored.  */
-  void (*comment_dot) PARAMS ((struct po_ty *__pop, const char *__s));
+  void (*comment_dot) PARAMS ((struct po_ty *pop, const char *s));
 
   /* What to do with a file position seen in a comment (i.e. a message
      location comment extracted by xgettext) - the expectation is that
      they will be accumulated, and added to the next message
      definition seen.  Or completely ignored.  */
-  void (*comment_filepos) PARAMS ((struct po_ty *__pop, const char *__s,
-                                  int __line));
+  void (*comment_filepos) PARAMS ((struct po_ty *pop, const char *s,
+                                  int line));
 
   /* What to do with a comment that starts with a `!' - this is a
      special comment.  One of the possible uses is to indicate a
      inexact translation.  */
-  void (*comment_special) PARAMS ((struct po_ty *__pop, const char *__s));
+  void (*comment_special) PARAMS ((struct po_ty *pop, const char *s));
 };
 
 
@@ -118,27 +118,26 @@ struct po_ty
 
 /* Allocate a fresh po_ty (or derived class) instance and call its
    constructor.  */
-extern po_ty *po_alloc PARAMS ((po_method_ty *__jtable));
+extern po_ty *po_alloc PARAMS ((po_method_ty *jtable));
 
 /* Read a PO file, and dispatch to the various po_method_ty methods.  */
-extern void po_scan PARAMS ((po_ty *__pop, const char *__filename));
+extern void po_scan PARAMS ((po_ty *pop, const char *filename));
 
 /* Call the destructor and deallocate a po_ty (or derived class)
    instance.  */
-extern void po_free PARAMS ((po_ty *__pop));
+extern void po_free PARAMS ((po_ty *pop));
 
 
 /* Callbacks used by po-gram.y or po-hash.y or po-lex.c, indirectly
    from po_scan.  */
-extern void po_callback_domain PARAMS ((char *__name));
-extern void po_callback_message PARAMS ((char *__msgid,
-                                        lex_pos_ty *__msgid_pos,
-                                        char *__msgid_plural,
-                                        char *__msgstr, size_t __msgstr_len,
-                                        lex_pos_ty *__msgstr_pos,
-                                        int __obsolete));
-extern void po_callback_comment PARAMS ((const char *__s));
-extern void po_callback_comment_dot PARAMS ((const char *__s));
-extern void po_callback_comment_filepos PARAMS ((const char *__s, int __line));
-
-#endif
+extern void po_callback_domain PARAMS ((char *name));
+extern void po_callback_message PARAMS ((char *msgid, lex_pos_ty *msgid_pos,
+                                        char *msgid_plural,
+                                        char *msgstr, size_t msgstr_len,
+                                        lex_pos_ty *msgstr_pos,
+                                        int obsolete));
+extern void po_callback_comment PARAMS ((const char *s));
+extern void po_callback_comment_dot PARAMS ((const char *s));
+extern void po_callback_comment_filepos PARAMS ((const char *s, int line));
+
+#endif /* _PO_H */
index 5626cbcc7930cafe40cd53f24ec108442d093e11..bd33d4f057b223b2bfe280c0fd972d347e1e792d 100644 (file)
--- a/src/pos.h
+++ b/src/pos.h
@@ -1,5 +1,5 @@
 /* Source file positions.
-   Copyright (C) 1995, 1996, 1997, 1998, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1995-1998, 2000-2001 Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -15,8 +15,8 @@
    along with this program; if not, write to the Free Software Foundation,
    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
-#ifndef SRC_POS_H
-#define SRC_POS_H
+#ifndef _POS_H
+#define _POS_H
 
 /* Position of a message within a source file.
    Used for error reporting purposes.  */
@@ -27,4 +27,4 @@ struct lex_pos_ty
   size_t line_number;
 };
 
-#endif
+#endif /* _POS_H */
index 7c502494a3da6974d1fca762dbe2928c69a8ec99..4ccd08393e22d027b3fe562542f7dd3bcb8d2fff 100644 (file)
@@ -44,13 +44,13 @@ struct readall_class_ty
   /* inherited instance variables, etc.  */
   PO_BASE_TY
 
+  /* List of messages already appeared in the current file.  */
+  msgdomain_list_ty *mdlp;
+
   /* Name of domain we are currently examining.  */
   char *domain;
 
-  /* List of domains already appeared in the current file.  */
-  string_list_ty *domain_list;
-
-  /* List of messages already appeared in the current file.  */
+  /* List of messages belonging to the current domain.  */
   message_list_ty *mlp;
 
   /* Accumulate comments for next message directive.  */
@@ -68,7 +68,8 @@ struct readall_class_ty
 };
 
 
-/* Prototypes for local functions.  */
+/* Prototypes for local functions.  Needed to ensure compiler checking of
+   function argument counts despite of K&R C function definition syntax.  */
 static void readall_constructor PARAMS ((po_ty *that));
 static void readall_destructor PARAMS ((po_ty *that));
 static void readall_directive_domain PARAMS ((po_ty *that, char *name));
@@ -79,7 +80,6 @@ static void readall_directive_message PARAMS ((po_ty *that, char *msgid,
                                               lex_pos_ty *msgstr_pos,
                                               int obsolete));
 static void readall_parse_brief PARAMS ((po_ty *that));
-static void readall_parse_debrief PARAMS ((po_ty *that));
 static void readall_comment PARAMS ((po_ty *that, const char *s));
 static void readall_comment_dot PARAMS ((po_ty *that, const char *s));
 static void readall_comment_special PARAMS ((po_ty *that, const char *s));
@@ -93,9 +93,9 @@ readall_constructor (that)
 {
   readall_class_ty *this = (readall_class_ty *) that;
 
-  this->mlp = message_list_alloc ();
+  this->mdlp = msgdomain_list_alloc ();
   this->domain = MESSAGE_DOMAIN_DEFAULT;
-  this->domain_list = string_list_alloc ();
+  this->mlp = msgdomain_list_sublist (this->mdlp, this->domain, 1);
   this->comment = NULL;
   this->comment_dot = NULL;
   this->filepos_count = 0;
@@ -113,8 +113,7 @@ readall_destructor (that)
   readall_class_ty *this = (readall_class_ty *) that;
   size_t j;
 
-  string_list_free (this->domain_list);
-  /* Do not free this->mlp.  */
+  /* Do not free this->mdlp and this->mlp.  */
   if (this->comment != NULL)
     string_list_free (this->comment);
   if (this->comment_dot != NULL)
@@ -173,23 +172,24 @@ readall_directive_message (that, msgid, msgid_pos, msgid_plural,
 {
   readall_class_ty *this = (readall_class_ty *) that;
   message_ty *mp;
-  message_variant_ty *mvp;
   size_t j;
 
-  /* Remember the domain names for later.  */
-  string_list_append_unique (this->domain_list, this->domain);
+  /* Select the appropriate sublist of this->mdlp.  */
+  this->mlp = msgdomain_list_sublist (this->mdlp, this->domain, 1);
 
   /* See if this message ID has been seen before.  */
   mp = message_list_search (this->mlp, msgid);
   if (mp)
     {
+      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 (msgstr);
       free (msgid);
-      if (!obsolete)
-       mp->obsolete = 0;
     }
   else
     {
-      mp = message_alloc (msgid, msgid_plural);
+      mp = message_alloc (msgid, msgid_plural, msgstr, msgstr_len, msgstr_pos);
       message_list_append (this->mlp, mp);
       mp->obsolete = obsolete;
     }
@@ -229,18 +229,6 @@ readall_directive_message (that, msgid, msgid_pos, msgid_plural,
   this->is_fuzzy = 0;
   this->is_c_format = undecided;
   this->do_wrap = undecided;
-
-  /* See if this domain has been seen for this message ID.  */
-  mvp = message_variant_search (mp, this->domain);
-  if (mvp)
-    {
-      po_gram_error_at_line (msgid_pos, _("duplicate message definition"));
-      po_gram_error_at_line (&mvp->pos, _("\
-...this is the location of the first definition"));
-      free (msgstr);
-    }
-  else
-    message_variant_append (mp, this->domain, msgstr, msgstr_len, msgstr_pos);
 }
 
 
@@ -252,44 +240,6 @@ readall_parse_brief (that)
 }
 
 
-static void
-readall_parse_debrief (that)
-     po_ty *that;
-{
-  readall_class_ty *this = (readall_class_ty *) that;
-  message_list_ty *mlp = this->mlp;
-  size_t j;
-
-  /* For each domain in the used-domain-list, make sure each message
-     defines a msgstr in that domain.  */
-  for (j = 0; j < this->domain_list->nitems; ++j)
-    {
-      const char *domain_name;
-      size_t k;
-
-      domain_name = this->domain_list->item[j];
-      for (k = 0; k < mlp->nitems; ++k)
-       {
-         const message_ty *mp;
-         size_t m;
-
-         mp = mlp->item[k];
-         for (m = 0; m < mp->variant_count; ++m)
-           {
-             message_variant_ty *mvp;
-
-             mvp = &mp->variant[m];
-             if (strcmp (domain_name, mvp->domain) == 0)
-               break;
-           }
-         if (m >= mp->variant_count)
-           po_gram_error_at_line (&mp->variant[0].pos, _("\
-this message has no definition in the \"%s\" domain"), domain_name);
-       }
-    }
-}
-
-
 static void
 readall_comment (that, s)
      po_ty *that;
@@ -365,7 +315,7 @@ static po_method_ty readall_methods =
   readall_directive_domain,
   readall_directive_message,
   readall_parse_brief,
-  readall_parse_debrief,
+  NULL, /* parse_debrief */
   readall_comment,
   readall_comment_dot,
   readall_comment_filepos,
@@ -373,17 +323,17 @@ static po_method_ty readall_methods =
 };
 
 
-message_list_ty *
+msgdomain_list_ty *
 read_po_file (filename)
      const char *filename;
 {
   po_ty *pop;
-  message_list_ty *mlp;
+  msgdomain_list_ty *mdlp;
 
   pop = po_alloc (&readall_methods);
   po_lex_pass_obsolete_entries (1);
   po_scan (pop, filename);
-  mlp = ((readall_class_ty *) pop)->mlp;
+  mdlp = ((readall_class_ty *) pop)->mdlp;
   po_free (pop);
-  return mlp;
+  return mdlp;
 }
index 69e25d626897fedfde0c0b7e7d7f5e29b1d1aa96..4346750fb3bcb1a1727350e77f7fa4609f95c24c 100644 (file)
@@ -29,6 +29,6 @@ extern int line_comment;
    if necessary.  If INPUT_NAME is not an absolute file name and the file is
    not found, the list of directories in "dir-list.h" is searched.  Returns
    a list of messages.  */
-extern message_list_ty *read_po_file PARAMS ((const char *input_name));
+extern msgdomain_list_ty *read_po_file PARAMS ((const char *input_name));
 
 #endif /* _READ_PO_H */
index 4a60b0fe20a43ff5ea2b3ba59d04097b9249ceb1..e31a62429c25ac92ba2d4693df2ef0bc4dae1d06 100644 (file)
@@ -17,8 +17,8 @@ You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
-#ifndef SRC_STR_LIST_H
-#define SRC_STR_LIST_H 1
+#ifndef _STR_LIST_H
+#define _STR_LIST_H 1
 
 /* Get size_t and NULL.  */
 #include <stddef.h>
@@ -34,40 +34,39 @@ struct string_list_ty
 };
 
 /* Initialize an empty list of strings.  */
-extern void string_list_init PARAMS ((string_list_ty *__slp));
+extern void string_list_init PARAMS ((string_list_ty *slp));
 
 /* Return a fresh, empty list of strings.  */
 extern string_list_ty *string_list_alloc PARAMS ((void));
 
 /* Append a single string to the end of a list of strings.  */
-extern void string_list_append PARAMS ((string_list_ty *__slp,
-                                       const char *__s));
+extern void string_list_append PARAMS ((string_list_ty *slp, const char *s));
 
 /* Append a single string to the end of a list of strings, unless it is
    already contained in the list.  */
-extern void string_list_append_unique PARAMS ((string_list_ty *__slp,
-                                              const char *__s));
+extern void string_list_append_unique PARAMS ((string_list_ty *slp,
+                                              const char *s));
 
 /* Destroy a list of strings.  */
-extern void string_list_destroy PARAMS ((string_list_ty *__slp));
+extern void string_list_destroy PARAMS ((string_list_ty *slp));
 
 /* Free a list of strings.  */
-extern void string_list_free PARAMS ((string_list_ty *__slp));
+extern void string_list_free PARAMS ((string_list_ty *slp));
 
 /* Return a freshly allocated string obtained by concatenating all the
    strings in the list.  */
-extern char *string_list_concat PARAMS ((const string_list_ty *__slp));
+extern char *string_list_concat PARAMS ((const string_list_ty *slp));
 
 /* Return a freshly allocated string obtained by concatenating all the
    strings in the list, and destroy the list.  */
-extern char *string_list_concat_destroy PARAMS ((string_list_ty *__slp));
+extern char *string_list_concat_destroy PARAMS ((string_list_ty *slp));
 
 /* Return a freshly allocated string obtained by concatenating all the
    strings in the list, separated by spaces.  */
-extern char *string_list_join PARAMS ((const string_list_ty *__slp));
+extern char *string_list_join PARAMS ((const string_list_ty *slp));
 
 /* Return 1 if s is contained in the list of strings, 0 otherwise.  */
-extern int string_list_member PARAMS ((const string_list_ty *__slp,
-                                      const char *__s));
+extern int string_list_member PARAMS ((const string_list_ty *slp,
+                                      const char *s));
 
-#endif
+#endif /* _STR_LIST_H */
index 1479b361b268b4453e63ab9fbade3d986affce4a..89f10fdc1fd6d202e44a3c9fd58bbe2a6c197bc5 100644 (file)
@@ -46,24 +46,24 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #define _(str) gettext (str)
 
 
-/* Prototypes for local functions.  */
+/* Prototypes for local functions.  Needed to ensure compiler checking of
+   function argument counts despite of K&R C function definition syntax.  */
 static const char *make_c_format_description_string PARAMS ((enum is_c_format,
                                                             int debug));
+static int significant_c_format_p PARAMS ((enum is_c_format is_c_format));
 static const char *make_c_width_description_string PARAMS ((enum is_c_format));
-static int significant_c_format_p PARAMS ((enum is_c_format __is_c_format));
-static void wrap PARAMS ((FILE *__fp, const char *__line_prefix,
-                         const char *__name, const char *__value,
-                         enum is_wrap do_wrap, const char *__charset));
-static void print_blank_line PARAMS ((FILE *__fp));
-static void message_print PARAMS ((const message_ty *__mp, FILE *__fp,
-                                  const char *__domain, const char *__charset,
-                                  int blank_line, int __debug));
-static void message_print_obsolete PARAMS ((const message_ty *__mp, FILE *__fp,
-                                           const char *__domain,
-                                           const char *__charset,
+static void wrap PARAMS ((FILE *fp, const char *line_prefix, const char *name,
+                         const char *value, enum is_wrap do_wrap,
+                         const char *charset));
+static void print_blank_line PARAMS ((FILE *fp));
+static void message_print PARAMS ((const message_ty *mp, FILE *fp,
+                                  const char *charset, int blank_line,
+                                  int debug));
+static void message_print_obsolete PARAMS ((const message_ty *mp, FILE *fp,
+                                           const char *charset,
                                            int blank_line));
-static int msgid_cmp PARAMS ((const void *__va, const void *__vb));
-static int filepos_cmp PARAMS ((const void *__va, const void *__vb));
+static int msgid_cmp PARAMS ((const void *va, const void *vb));
+static int filepos_cmp PARAMS ((const void *va, const void *vb));
 
 
 /* This variable controls the page width when printing messages.
@@ -516,33 +516,15 @@ print_blank_line (fp)
 
 
 static void
-message_print (mp, fp, domain, charset, blank_line, debug)
+message_print (mp, fp, charset, blank_line, debug)
      const message_ty *mp;
      FILE *fp;
-     const char *domain;
      const char *charset;
      int blank_line;
      int debug;
 {
-  message_variant_ty *mvp;
-  int first;
   size_t j;
 
-  /* Find the relevant message variant.  If there isn't one, remember
-     this using a NULL pointer.  */
-  mvp = NULL;
-  first = 0;
-
-  for (j = 0; j < mp->variant_count; ++j)
-    {
-      if (strcmp (domain, mp->variant[j].domain) == 0)
-       {
-         mvp = &mp->variant[j];
-         first = (j == 0);
-         break;
-       }
-    }
-
   /* Separate messages with a blank line.  Uniforum doesn't like blank
      lines, so use an empty comment (unless there already is one).  */
   if (blank_line && (!uniforum
@@ -551,55 +533,48 @@ message_print (mp, fp, domain, charset, blank_line, debug)
                     || mp->comment->item[0][0] != '\0'))
     print_blank_line (fp);
 
-  /* The first variant of a message will have the comments attached to
-     it.  We can't attach them to all variants in case we are read in
-     again, multiplying the number of comment lines.  Usually there is
-     only one variant.  */
-  if (first)
-    {
-      if (mp->comment != NULL)
-       for (j = 0; j < mp->comment->nitems; ++j)
-         {
-           const char *s = mp->comment->item[j];
-           do
-             {
-               const char *e;
-               putc ('#', fp);
-               if (*s != '\0' && *s != ' ')
-                 putc (' ', fp);
-               e = strchr (s, '\n');
-               if (e == NULL)
-                 {
-                   fputs (s, fp);
-                   s = NULL;
-                 }
-               else
-                 {
-                   fwrite (s, 1, e - s, fp);
-                   s = e + 1;
-                 }
-               putc ('\n', fp);
-             }
-           while (s != NULL);
-         }
-
-      if (mp->comment_dot != NULL)
-       for (j = 0; j < mp->comment_dot->nitems; ++j)
+  /* Print translator comment if available.  */
+  if (mp->comment != NULL)
+    for (j = 0; j < mp->comment->nitems; ++j)
+      {
+       const char *s = mp->comment->item[j];
+       do
          {
-           const char *s = mp->comment_dot->item[j];
+           const char *e;
            putc ('#', fp);
-           putc ('.', fp);
            if (*s != '\0' && *s != ' ')
              putc (' ', fp);
-           fputs (s, fp);
+           e = strchr (s, '\n');
+           if (e == NULL)
+             {
+               fputs (s, fp);
+               s = NULL;
+             }
+           else
+             {
+               fwrite (s, 1, e - s, fp);
+               s = e + 1;
+             }
            putc ('\n', fp);
          }
-    }
+       while (s != NULL);
+      }
 
-  /* Print the file position comments for every domain.  This will
-     help a human who is trying to navigate the sources.  There is no
-     problem of getting repeat positions, because duplicates are
-     checked for.  */
+  if (mp->comment_dot != NULL)
+    for (j = 0; j < mp->comment_dot->nitems; ++j)
+      {
+       const char *s = mp->comment_dot->item[j];
+       putc ('#', fp);
+       putc ('.', fp);
+       if (*s != '\0' && *s != ' ')
+         putc (' ', fp);
+       fputs (s, fp);
+       putc ('\n', fp);
+      }
+
+  /* Print the file position comments.  This will help a human who is
+     trying to navigate the sources.  There is no problem of getting
+     repeated positions, because duplicates are checked for.  */
   if (mp->filepos_count != 0)
     {
       if (uniforum)
@@ -646,9 +621,9 @@ message_print (mp, fp, domain, charset, blank_line, debug)
     }
 
   /* Print flag information in special comment.  */
-  if (first && ((mp->is_fuzzy && mvp != NULL && mvp->msgstr[0] != '\0')
-               || significant_c_format_p (mp->is_c_format)
-               || mp->do_wrap == no))
+  if ((mp->is_fuzzy && mp->msgstr[0] != '\0')
+      || significant_c_format_p (mp->is_c_format)
+      || mp->do_wrap == no)
     {
       int first_flag = 1;
 
@@ -658,7 +633,7 @@ message_print (mp, fp, domain, charset, blank_line, debug)
       /* We don't print the fuzzy flag if the msgstr is empty.  This
         might be introduced by the user but we want to normalize the
         output.  */
-      if (mp->is_fuzzy && mvp != NULL && mvp->msgstr[0] != '\0')
+      if (mp->is_fuzzy && mp->msgstr[0] != '\0')
        {
          fputs (" fuzzy", fp);
          first_flag = 0;
@@ -694,62 +669,35 @@ message_print (mp, fp, domain, charset, blank_line, debug)
     wrap (fp, NULL, "msgid_plural", mp->msgid_plural, mp->do_wrap, charset);
 
   if (mp->msgid_plural == NULL)
-    wrap (fp, NULL, "msgstr", mvp ? mvp->msgstr : "", mp->do_wrap, charset);
+    wrap (fp, NULL, "msgstr", mp->msgstr, mp->do_wrap, charset);
   else
     {
       char prefix_buf[20];
       unsigned int i;
+      const char *p;
 
-      if (mvp)
-       {
-         const char *p;
-
-         for (p = mvp->msgstr, i = 0;
-              p < mvp->msgstr + mvp->msgstr_len;
-              p += strlen (p) + 1, i++)
-           {
-             sprintf (prefix_buf, "msgstr[%u]", i);
-             wrap (fp, NULL, prefix_buf, p, mp->do_wrap, charset);
-           }
-       }
-      else
+      for (p = mp->msgstr, i = 0;
+          p < mp->msgstr + mp->msgstr_len;
+          p += strlen (p) + 1, i++)
        {
-         for (i = 0; i < 2; i++)
-           {
-             sprintf (prefix_buf, "msgstr[%u]", i);
-             wrap (fp, NULL, prefix_buf, "", mp->do_wrap, charset);
-           }
+         sprintf (prefix_buf, "msgstr[%u]", i);
+         wrap (fp, NULL, prefix_buf, p, mp->do_wrap, charset);
        }
     }
 }
 
 
 static void
-message_print_obsolete (mp, fp, domain, charset, blank_line)
+message_print_obsolete (mp, fp, charset, blank_line)
      const message_ty *mp;
      FILE *fp;
-     const char *domain;
      const char *charset;
      int blank_line;
 {
-  message_variant_ty *mvp;
   size_t j;
 
-  /* Find the relevant message variant.  If there isn't one, remember
-     this using a NULL pointer.  */
-  mvp = NULL;
-
-  for (j = 0; j < mp->variant_count; ++j)
-    {
-      if (strcmp (domain, mp->variant[j].domain) == 0)
-       {
-         mvp = &mp->variant[j];
-         break;
-       }
-    }
-
-  /* If no msgstr is found or it is the empty string we print nothing.  */
-  if (mvp == NULL || mvp->msgstr[0] == '\0')
+  /* If msgstr is the empty string we print nothing.  */
+  if (mp->msgstr[0] == '\0')
     return;
 
   /* Separate messages with a blank line.  Uniforum doesn't like blank
@@ -808,15 +756,15 @@ message_print_obsolete (mp, fp, domain, charset, blank_line)
     wrap (fp, "#~ ", "msgid_plural", mp->msgid_plural, mp->do_wrap, charset);
 
   if (mp->msgid_plural == NULL)
-    wrap (fp, "#~ ", "msgstr", mvp->msgstr, mp->do_wrap, charset);
+    wrap (fp, "#~ ", "msgstr", mp->msgstr, mp->do_wrap, charset);
   else
     {
       char prefix_buf[20];
       unsigned int i;
       const char *p;
 
-      for (p = mvp->msgstr, i = 0;
-          p < mvp->msgstr + mvp->msgstr_len;
+      for (p = mp->msgstr, i = 0;
+          p < mp->msgstr + mp->msgstr_len;
           p += strlen (p) + 1, i++)
        {
          sprintf (prefix_buf, "msgstr[%u]", i);
@@ -827,31 +775,36 @@ message_print_obsolete (mp, fp, domain, charset, blank_line)
 
 
 void
-message_list_print (mlp, filename, force, debug)
-     message_list_ty *mlp;
+msgdomain_list_print (mdlp, filename, force, debug)
+     msgdomain_list_ty *mdlp;
      const char *filename;
      int force;
      int debug;
 {
   FILE *fp;
-  size_t i, j, k;
-  string_list_ty *dl;
+  size_t j, k;
   int blank_line;
 
-  /* We will not write anything if we have no message or only the
-     header entry.  */
-  if (force == 0
-      && (mlp->nitems == 0
-         || (mlp->nitems == 1 && *mlp->item[0]->msgid == '\0')))
-    return;
-
-  /* Build the list of domains.  */
-  dl = string_list_alloc ();
-  for (j = 0; j < mlp->nitems; ++j)
+  /* We will not write anything if, for every domain, we have no message
+     or only the header entry.  */
+  if (!force)
     {
-      message_ty *mp = mlp->item[j];
-      for (k = 0; k < mp->variant_count; ++k)
-       string_list_append_unique (dl, mp->variant[k].domain);
+      int found_nonempty = 0;
+
+      for (k = 0; k < mdlp->nitems; k++)
+       {
+         message_list_ty *mlp = mdlp->item[k]->messages;
+
+         if (!(mlp->nitems == 0
+               || (mlp->nitems == 1 && mlp->item[0]->msgid[0] == '\0')))
+           {
+             found_nonempty = 1;
+             break;
+           }
+       }
+
+      if (!found_nonempty)
+       return;
     }
 
   /* Open the output file.  */
@@ -872,33 +825,31 @@ message_list_print (mlp, filename, force, debug)
 
   /* Write out the messages for each domain.  */
   blank_line = 0;
-  for (k = 0; k < dl->nitems; ++k)
+  for (k = 0; k < mdlp->nitems; k++)
     {
+      message_list_ty *mlp;
       const char *header;
       char *charset;
 
-      /* If there is only one domain, and that domain is the default,
-        don't bother emitting the domain name, because it is the
-        default.  */
-      if (dl->nitems != 1 || strcmp (dl->item[0], MESSAGE_DOMAIN_DEFAULT) != 0)
+      /* If the first domain is the default, don't bother emitting
+        the domain name, because it is the default.  */
+      if (!(k == 0
+           && strcmp (mdlp->item[k]->domain, MESSAGE_DOMAIN_DEFAULT) == 0))
        {
          if (blank_line)
            print_blank_line (fp);
-         fprintf (fp, "domain \"%s\"\n", dl->item[k]);
+         fprintf (fp, "domain \"%s\"\n", mdlp->item[k]->domain);
          blank_line = 1;
        }
 
+      mlp = mdlp->item[k]->messages;
+
       /* Search the header entry.  */
       header = NULL;
       for (j = 0; j < mlp->nitems; ++j)
-       if (*mlp->item[j]->msgid == '\0' && mlp->item[j]->obsolete == 0)
+       if (mlp->item[j]->msgid[0] == '\0' && mlp->item[j]->obsolete == 0)
          {
-           for (i = 0; i < mlp->item[j]->variant_count; i++)
-             if (strcmp (dl->item[k], mlp->item[j]->variant[i].domain) == 0)
-               {
-                 header = mlp->item[j]->variant[i].msgstr;
-                 break;
-               }
+           header = mlp->item[j]->msgstr;
            break;
          }
 
@@ -924,8 +875,7 @@ message_list_print (mlp, filename, force, debug)
       for (j = 0; j < mlp->nitems; ++j)
        if (mlp->item[j]->obsolete == 0)
          {
-           message_print (mlp->item[j], fp, dl->item[k], charset,
-                          blank_line, debug);
+           message_print (mlp->item[j], fp, charset, blank_line, debug);
            blank_line = 1;
          }
 
@@ -933,12 +883,10 @@ message_list_print (mlp, filename, force, debug)
       for (j = 0; j < mlp->nitems; ++j)
        if (mlp->item[j]->obsolete != 0)
          {
-           message_print_obsolete (mlp->item[j], fp, dl->item[k], charset,
-                                   blank_line);
+           message_print_obsolete (mlp->item[j], fp, charset, blank_line);
            blank_line = 1;
          }
     }
-  string_list_free (dl);
 
   /* Make sure nothing went wrong.  */
   if (fflush (fp))
@@ -963,10 +911,18 @@ msgid_cmp (va, vb)
 
 
 void
-message_list_sort_by_msgid (mlp)
-     message_list_ty *mlp;
+msgdomain_list_sort_by_msgid (mdlp)
+     msgdomain_list_ty *mdlp;
 {
-  qsort (mlp->item, mlp->nitems, sizeof (mlp->item[0]), msgid_cmp);
+  size_t k;
+
+  for (k = 0; k < mdlp->nitems; k++)
+    {
+      message_list_ty *mlp = mdlp->item[k]->messages;
+
+      if (mlp->nitems > 0)
+       qsort (mlp->item, mlp->nitems, sizeof (mlp->item[0]), msgid_cmp);
+    }
 }
 
 
@@ -1007,8 +963,16 @@ filepos_cmp (va, vb)
 
 
 void
-message_list_sort_by_filepos (mlp)
-    message_list_ty *mlp;
+msgdomain_list_sort_by_filepos (mdlp)
+    msgdomain_list_ty *mdlp;
 {
-  qsort (mlp->item, mlp->nitems, sizeof (mlp->item[0]), filepos_cmp);
+  size_t k;
+
+  for (k = 0; k < mdlp->nitems; k++)
+    {
+      message_list_ty *mlp = mdlp->item[k]->messages;
+
+      if (mlp->nitems > 0)
+       qsort (mlp->item, mlp->nitems, sizeof (mlp->item[0]), filepos_cmp);
+    }
 }
index e71f107b97897a7364bf3fdf56c46758e30efcdb..1523c44100036438a7e890197c99ab24b446b2db 100644 (file)
 
 #include "message.h"
 
-extern void message_page_width_set PARAMS ((size_t width));
-
-extern void message_print_style_indent PARAMS ((void));
-extern void message_print_style_uniforum PARAMS ((void));
-extern void message_print_style_escape PARAMS ((int));
-
-extern void message_list_print PARAMS ((message_list_ty *, const char *, int, int));
-extern void message_list_sort_by_msgid PARAMS ((message_list_ty *));
-extern void message_list_sort_by_filepos PARAMS ((message_list_ty *));
+extern void
+       message_page_width_set PARAMS ((size_t width));
+
+extern void
+       message_print_style_indent PARAMS ((void));
+extern void
+       message_print_style_uniforum PARAMS ((void));
+extern void
+       message_print_style_escape PARAMS ((int flag));
+
+extern void
+       msgdomain_list_print PARAMS ((msgdomain_list_ty *mdlp,
+                                    const char *filename,
+                                    int force, int debug));
+extern void
+       msgdomain_list_sort_by_msgid PARAMS ((msgdomain_list_ty *mdlp));
+extern void
+       msgdomain_list_sort_by_filepos PARAMS ((msgdomain_list_ty *mdlp));
 
 #endif /* _WRITE_PO_H */
index 08b31581869e3b5529df91aed4214e64d668b968..c69e23027351ac8ce8b1c8a853be54ab6d11fc65 100644 (file)
@@ -118,23 +118,24 @@ static int last_non_comment_line = -1;
 static int newline_count = 0;
 
 
-/* Prototypes for local functions.  */
+/* Prototypes for local functions.  Needed to ensure compiler checking of
+   function argument counts despite of K&R C function definition syntax.  */
 static int phase1_getc PARAMS ((void));
-static void phase1_ungetc PARAMS ((int __c));
+static void phase1_ungetc PARAMS ((int c));
 static int phase2_getc PARAMS ((void));
-static void phase2_ungetc PARAMS ((int __c));
+static void phase2_ungetc PARAMS ((int c));
 static int phase3_getc PARAMS ((void));
-static void phase3_ungetc PARAMS ((int __c));
+static void phase3_ungetc PARAMS ((int c));
 static int phase4_getc PARAMS ((void));
-static void phase4_ungetc PARAMS ((int __c));
+static void phase4_ungetc PARAMS ((int c));
 static int phase7_getc PARAMS ((void));
-static void phase7_ungetc PARAMS ((int __c));
-static void phase5_get PARAMS ((token_ty *__tp));
-static void phase5_unget PARAMS ((token_ty *__tp));
-static void phaseX_get PARAMS ((token_ty *__tp));
-static void phase6_get PARAMS ((token_ty *__tp));
-static void phase6_unget PARAMS ((token_ty *__tp));
-static void phase8_get PARAMS ((token_ty *__tp));
+static void phase7_ungetc PARAMS ((int c));
+static void phase5_get PARAMS ((token_ty *tp));
+static void phase5_unget PARAMS ((token_ty *tp));
+static void phaseX_get PARAMS ((token_ty *tp));
+static void phase6_get PARAMS ((token_ty *tp));
+static void phase6_unget PARAMS ((token_ty *tp));
+static void phase8_get PARAMS ((token_ty *tp));
 
 
 
index 660ebb70a6bca1b8aa62fc3a61c1a2fbf5532c87..1fe4edd8cc6786b0b674d7e19442e856c12450c9 100644 (file)
@@ -17,8 +17,8 @@ You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
-#ifndef SRC_XGET_LEX_H
-#define SRC_XGET_LEX_H
+#ifndef _XGET_LEX_H
+#define _XGET_LEX_H
 
 enum xgettext_token_type_ty
 {
@@ -52,14 +52,14 @@ struct xgettext_token_ty
 };
 
 
-void xgettext_lex_open PARAMS ((const char *__file_name));
+void xgettext_lex_open PARAMS ((const char *file_name));
 void xgettext_lex_close PARAMS ((void));
-void xgettext_lex PARAMS ((xgettext_token_ty *__tp));
-const char *xgettext_lex_comment PARAMS ((size_t __n));
+void xgettext_lex PARAMS ((xgettext_token_ty *tp));
+const char *xgettext_lex_comment PARAMS ((size_t n));
 void xgettext_lex_comment_reset PARAMS ((void));
 /* void xgettext_lex_filepos PARAMS ((char **, int *)); FIXME needed?  */
-void xgettext_lex_keyword PARAMS ((const char *__name));
+void xgettext_lex_keyword PARAMS ((const char *name));
 int xgettext_any_keywords PARAMS ((void));
 void xgettext_lex_trigraphs PARAMS ((void));
 
-#endif
+#endif /* _XGET_LEX_H */
index e3e9b1db660ae85bee1e9b09dd6597a9e3dd0b02..b5d6b52fbd56274d895f597f83a63e87f37bcd90 100644 (file)
@@ -141,53 +141,52 @@ static const struct option long_options[] =
 };
 
 
-/* Prototypes for local functions.  */
+/* Prototypes for local functions.  Needed to ensure compiler checking of
+   function argument counts despite of K&R C function definition syntax.  */
 static void usage PARAMS ((int status))
 #if defined __GNUC__ && ((__GNUC__ == 2 && __GNUC_MINOR__ > 4) || __GNUC__ > 2)
        __attribute__ ((noreturn))
 #endif
 ;
-static string_list_ty *read_name_from_file PARAMS ((const char *__file_name));
-static void exclude_directive_domain PARAMS ((po_ty *__pop, char *__name));
-static void exclude_directive_message PARAMS ((po_ty *__pop, char *__msgid,
-                                              lex_pos_ty *__msgid_pos,
-                                              char *__msgid_plural,
-                                              char *__msgstr,
-                                              size_t __msgstr_len,
-                                              lex_pos_ty *__msgstr_pos,
-                                              int __obsolete));
-static void read_exclusion_file PARAMS ((char *__file_name));
-static message_ty *remember_a_message PARAMS ((message_list_ty *__mlp,
-                                              xgettext_token_ty *__tp));
-static void remember_a_message_plural PARAMS ((message_ty *__mp,
-                                              xgettext_token_ty *__tp));
-static void scan_c_file PARAMS ((const char *__file_name,
-                                message_list_ty *__mlp));
-static void extract_constructor PARAMS ((po_ty *__that));
-static void extract_directive_domain PARAMS ((po_ty *__that, char *__name));
-static void extract_directive_message PARAMS ((po_ty *__that, char *__msgid,
-                                              lex_pos_ty *__msgid_pos,
-                                              char *__msgid_plural,
-                                              char *__msgstr,
-                                              size_t __msgstr_len,
-                                              lex_pos_ty *__msgstr_pos,
-                                              int __obsolete));
-static void extract_parse_brief PARAMS ((po_ty *__that));
-static void extract_comment PARAMS ((po_ty *__that, const char *__s));
-static void extract_comment_dot PARAMS ((po_ty *__that, const char *__s));
-static void extract_comment_filepos PARAMS ((po_ty *__that, const char *__name,
-                                            int __line));
+static string_list_ty *read_name_from_file PARAMS ((const char *file_name));
+static void exclude_directive_domain PARAMS ((po_ty *pop, char *name));
+static void exclude_directive_message PARAMS ((po_ty *pop, char *msgid,
+                                              lex_pos_ty *msgid_pos,
+                                              char *msgid_plural,
+                                              char *msgstr, size_t msgstr_len,
+                                              lex_pos_ty *msgstr_pos,
+                                              int obsolete));
+static void read_exclusion_file PARAMS ((char *file_name));
+static message_ty *remember_a_message PARAMS ((message_list_ty *mlp,
+                                              xgettext_token_ty *tp));
+static void remember_a_message_plural PARAMS ((message_ty *mp,
+                                              xgettext_token_ty *tp));
+static void scan_c_file PARAMS ((const char *file_name,
+                                msgdomain_list_ty *mdlp));
+static void extract_constructor PARAMS ((po_ty *that));
+static void extract_directive_domain PARAMS ((po_ty *that, char *name));
+static void extract_directive_message PARAMS ((po_ty *that, char *msgid,
+                                              lex_pos_ty *msgid_pos,
+                                              char *msgid_plural,
+                                              char *msgstr, size_t msgstr_len,
+                                              lex_pos_ty *msgstr_pos,
+                                              int obsolete));
+static void extract_parse_brief PARAMS ((po_ty *that));
+static void extract_comment PARAMS ((po_ty *that, const char *s));
+static void extract_comment_dot PARAMS ((po_ty *that, const char *s));
+static void extract_comment_filepos PARAMS ((po_ty *that, const char *name,
+                                            int line));
 static void extract_comment_special PARAMS ((po_ty *that, const char *s));
-static void read_po_file PARAMS ((const char *__file_name,
-                                 message_list_ty *__mlp));
-static long difftm PARAMS ((const struct tm *__a, const struct tm *__b));
+static void read_po_file PARAMS ((const char *file_name,
+                                 msgdomain_list_ty *mdlp));
+static long difftm PARAMS ((const struct tm *a, const struct tm *b));
 static message_ty *construct_header PARAMS ((void));
-static enum is_c_format test_whether_c_format PARAMS ((const char *__s));
+static enum is_c_format test_whether_c_format PARAMS ((const char *s));
 
 
 /* The scanners must all be functions returning void and taking one
    string argument and a message list argument.  */
-typedef void (*scanner_fp) PARAMS ((const char *, message_list_ty *));
+typedef void (*scanner_fp) PARAMS ((const char *, msgdomain_list_ty *));
 
 static const char *extension_to_language PARAMS ((const char *));
 static scanner_fp language_to_scanner PARAMS ((const char *));
@@ -202,7 +201,7 @@ main (argc, argv)
   int optchar;
   int do_help = 0;
   int do_version = 0;
-  message_list_ty *mlp;
+  msgdomain_list_ty *mdlp;
   int join_existing = 0;
   int sort_by_msgid = 0;
   int sort_by_filepos = 0;
@@ -439,16 +438,16 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
     string_list_append_unique (file_list, argv[cnt]);
 
   /* Allocate a message list to remember all the messages.  */
-  mlp = message_list_alloc ();
+  mdlp = msgdomain_list_alloc ();
 
   /* Generate a header, so that we know how and when this PO file was
      created.  */
   if (!omit_header)
-    message_list_append (mlp, construct_header ());
+    message_list_append (mdlp->item[0]->messages, construct_header ());
 
   /* Read in the old messages, so that we can add to them.  */
   if (join_existing)
-    read_po_file (file_name, mlp);
+    read_po_file (file_name, mdlp);
 
   /* Process all input files.  */
   for (cnt = 0; cnt < file_list->nitems; ++cnt)
@@ -479,27 +478,27 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
             function from the language.  */
          language = extension_to_language (extension);
          if (language == NULL)
-         {
-           error (0, 0, _("\
+           {
+             error (0, 0, _("\
 warning: file `%s' extension `%s' is unknown; will try C"), fname, extension);
-           language = "C";
-         }
+             language = "C";
+           }
          scan_file = language_to_scanner (language);
        }
 
       /* Scan the file.  */
-      scan_file (fname, mlp);
+      scan_file (fname, mdlp);
     }
   string_list_free (file_list);
 
   /* Sorting the list of messages.  */
   if (sort_by_filepos)
-    message_list_sort_by_filepos (mlp);
+    msgdomain_list_sort_by_filepos (mdlp);
   else if (sort_by_msgid)
-    message_list_sort_by_msgid (mlp);
+    msgdomain_list_sort_by_msgid (mdlp);
 
   /* Write the PO file.  */
-  message_list_print (mlp, file_name, force_po, do_debug);
+  msgdomain_list_print (mdlp, file_name, force_po, do_debug);
 
   exit (EXIT_SUCCESS);
 }
@@ -700,7 +699,7 @@ exclude_directive_message (pop, msgid, msgid_pos, msgid_plural,
     free (msgid);
   else
     {
-      mp = message_alloc (msgid, msgid_plural);
+      mp = message_alloc (msgid, msgid_plural, "", 1, msgstr_pos);
       /* Do not free msgid.  */
       message_list_append (exclude, mp);
     }
@@ -780,11 +779,6 @@ remember_a_message (mlp, tp)
     {
       static lex_pos_ty pos = { __FILE__, __LINE__ };
 
-      /* Allocate a new message and append the message to the list.  */
-      mp = message_alloc (msgid, NULL);
-      /* Do not free msgid.  */
-      message_list_append (mlp, mp);
-
       /* Construct the msgstr from the prefix and suffix, otherwise use the
         empty string.  */
       if (msgstr_prefix)
@@ -797,8 +791,11 @@ remember_a_message (mlp, tp)
        }
       else
        msgstr = "";
-      message_variant_append (mp, MESSAGE_DOMAIN_DEFAULT, msgstr,
-                             strlen (msgstr) + 1, &pos);
+
+      /* Allocate a new message and append the message to the list.  */
+      mp = message_alloc (msgid, NULL, msgstr, strlen (msgstr) + 1, &pos);
+      /* Do not free msgid.  */
+      message_list_append (mlp, mp);
     }
 
   /* Ask the lexer for the comments it has seen.  Only do this for the
@@ -858,7 +855,6 @@ remember_a_message_plural (mp, tp)
      xgettext_token_ty *tp;
 {
   char *msgid_plural;
-  message_variant_ty *mvp;
   char *msgstr1;
   size_t msgstr1_len;
   char *msgstr;
@@ -873,26 +869,22 @@ remember_a_message_plural (mp, tp)
       /* Construct the first plural form from the prefix and suffix,
         otherwise use the empty string.  The translator will have to
         provide additional plural forms.  */
-      mvp = message_variant_search (mp, MESSAGE_DOMAIN_DEFAULT);
-      if (mvp != NULL)
+      if (msgstr_prefix)
        {
-         if (msgstr_prefix)
-           {
-             msgstr1 = (char *) xmalloc (strlen (msgstr_prefix)
-                                         + strlen (msgid_plural)
-                                         + strlen (msgstr_suffix) + 1);
-             stpcpy (stpcpy (stpcpy (msgstr1, msgstr_prefix), msgid_plural),
-                     msgstr_suffix);
-           }
-         else
-           msgstr1 = "";
-         msgstr1_len = strlen (msgstr1) + 1;
-         msgstr = (char *) xmalloc (mvp->msgstr_len + msgstr1_len);
-         memcpy (msgstr, mvp->msgstr, mvp->msgstr_len);
-         memcpy (msgstr + mvp->msgstr_len, msgstr1, msgstr1_len);
-         mvp->msgstr = msgstr;
-         mvp->msgstr_len = mvp->msgstr_len + msgstr1_len;
+         msgstr1 = (char *) xmalloc (strlen (msgstr_prefix)
+                                     + strlen (msgid_plural)
+                                     + strlen (msgstr_suffix) + 1);
+         stpcpy (stpcpy (stpcpy (msgstr1, msgstr_prefix), msgid_plural),
+                 msgstr_suffix);
        }
+      else
+       msgstr1 = "";
+      msgstr1_len = strlen (msgstr1) + 1;
+      msgstr = (char *) xmalloc (mp->msgstr_len + msgstr1_len);
+      memcpy (msgstr, mp->msgstr, mp->msgstr_len);
+      memcpy (msgstr + mp->msgstr_len, msgstr1, msgstr1_len);
+      mp->msgstr = msgstr;
+      mp->msgstr_len = mp->msgstr_len + msgstr1_len;
     }
   else
     free (msgid_plural);
@@ -900,10 +892,11 @@ remember_a_message_plural (mp, tp)
 
 
 static void
-scan_c_file (filename, mlp)
+scan_c_file (filename, mdlp)
      const char *filename;
-     message_list_ty *mlp;
+     msgdomain_list_ty *mdlp;
 {
+  message_list_ty *mlp = mdlp->item[0]->messages;
   int state;
   int commas_to_skip = 0;      /* defined only when in states 1 and 2 */
   int plural_commas = 0;       /* defined only when in states 1 and 2 */
@@ -1115,7 +1108,6 @@ extract_directive_message (that, msgid, msgid_pos, msgid_plural,
 {
   extract_class_ty *this = (extract_class_ty *)that;
   message_ty *mp;
-  message_variant_ty *mvp;
   size_t j;
 
   /* See whether we shall exclude this message.  */
@@ -1148,10 +1140,20 @@ extract_directive_message (that, msgid, msgid_pos, msgid_plural,
   /* See if this message ID has been seen before.  */
   mp = message_list_search (this->mlp, msgid);
   if (mp)
-    free (msgid);
+    {
+      if (msgstr_len != mp->msgstr_len
+         || memcmp (msgstr, mp->msgstr, msgstr_len) != 0)
+       {
+         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 (msgid);
+      free (msgstr);
+    }
   else
     {
-      mp = message_alloc (msgid, msgid_plural);
+      mp = message_alloc (msgid, msgid_plural, msgstr, msgstr_len, msgstr_pos);
       message_list_append (this->mlp, mp);
     }
 
@@ -1189,21 +1191,6 @@ extract_directive_message (that, msgid, msgid_pos, msgid_plural,
   this->is_fuzzy = 0;
   this->is_c_format = undecided;
   this->do_wrap = undecided;
-
-  /* See if this domain has been seen for this message ID.  */
-  mvp = message_variant_search (mp, MESSAGE_DOMAIN_DEFAULT);
-  if (mvp != NULL
-      && (msgstr_len != mvp->msgstr_len
-         || memcmp (msgstr, mvp->msgstr, msgstr_len) != 0))
-    {
-      po_gram_error_at_line (msgid_pos, _("duplicate message definition"));
-      po_gram_error_at_line (&mvp->pos, _("\
-...this is the location of the first definition"));
-      free (msgstr);
-    }
-  else
-    message_variant_append (mp, MESSAGE_DOMAIN_DEFAULT, msgstr, msgstr_len,
-                           msgstr_pos);
 }
 
 
@@ -1302,12 +1289,12 @@ static po_method_ty extract_methods =
 /* Read the contents of the specified .po file into a message list.  */
 
 static void
-read_po_file (file_name, mlp)
+read_po_file (file_name, mdlp)
      const char *file_name;
-     message_list_ty *mlp;
+     msgdomain_list_ty *mdlp;
 {
   po_ty *pop = po_alloc (&extract_methods);
-  ((extract_class_ty *) pop)->mlp = mlp;
+  ((extract_class_ty *) pop)->mlp = mdlp->item[0]->messages;
   po_scan (pop, file_name);
   po_free (pop);
 }
@@ -1351,20 +1338,6 @@ construct_header ()
   char tz_sign;
   long tz_min;
 
-  mp = message_alloc ("", NULL);
-
-  if (foreign_user)
-    message_comment_append (mp, "\
-SOME DESCRIPTIVE TITLE.\n\
-FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.\n");
-  else
-    message_comment_append (mp, "\
-SOME DESCRIPTIVE TITLE.\n\
-Copyright (C) YEAR Free Software Foundation, Inc.\n\
-FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.\n");
-
-  mp->is_fuzzy = 1;
-
   time (&now);
   local_time = *localtime (&now);
   tz_sign = '+';
@@ -1394,8 +1367,19 @@ Content-Transfer-Encoding: 8bit\n",
   if (msgstr == NULL)
     error (EXIT_FAILURE, errno, _("while preparing output"));
 
-  message_variant_append (mp, MESSAGE_DOMAIN_DEFAULT, msgstr,
-                         strlen (msgstr) + 1, &pos);
+  mp = message_alloc ("", NULL, msgstr, strlen (msgstr) + 1, &pos);
+
+  if (foreign_user)
+    message_comment_append (mp, "\
+SOME DESCRIPTIVE TITLE.\n\
+FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.\n");
+  else
+    message_comment_append (mp, "\
+SOME DESCRIPTIVE TITLE.\n\
+Copyright (C) YEAR Free Software Foundation, Inc.\n\
+FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.\n");
+
+  mp->is_fuzzy = 1;
 
   return mp;
 }
index 546d4248aebc67d410db69d038fca268b4de3578..965621be7a59b5f7408175d2d944f93c9f662697 100644 (file)
@@ -1,3 +1,9 @@
+2001-06-10  Bruno Haible  <haible@clisp.cons.org>
+
+       * msgmerge-10: New file.
+       * msgmerge-11: New file.
+       * Makefile.am (TESTS): Add them.
+
 2001-06-10  Bruno Haible  <haible@clisp.cons.org>
 
        * msgfmt-5: New file.
index 0d777b5cbf4974196a8c1470325efe40ec8fe6f8..147064674351796d7e884091221b3c32cd320d11 100644 (file)
@@ -26,7 +26,7 @@ TESTS = gettext-1 gettext-2 \
        msgcomm-14 msgcomm-15 msgcomm-16 \
        msgfmt-1 msgfmt-2 msgfmt-3 msgfmt-4 msgfmt-5 \
        msgmerge-1 msgmerge-2 msgmerge-3 msgmerge-4 msgmerge-5 msgmerge-6 \
-       msgmerge-7 msgmerge-8 msgmerge-9 \
+       msgmerge-7 msgmerge-8 msgmerge-9 msgmerge-10 msgmerge-11 \
        msgunfmt-1 \
        xgettext-1 xgettext-2 xgettext-3 xgettext-4 xgettext-5 xgettext-6 \
        xgettext-7 xgettext-8 xgettext-9 \