]> git.ipfire.org Git - thirdparty/gettext.git/commitdiff
Improved handling of missing plural-form entry in header.
authorBruno Haible <bruno@clisp.org>
Tue, 5 Feb 2002 13:03:26 +0000 (13:03 +0000)
committerBruno Haible <bruno@clisp.org>
Sun, 21 Jun 2009 23:16:05 +0000 (01:16 +0200)
src/ChangeLog
src/Makefile.am
src/msgfmt.c
src/msginit.c
src/plural-table.c [new file with mode: 0644]
src/plural-table.h [new file with mode: 0644]

index 1a2007fb5dffabba9bc9de1c7e4857d07b3536e5..2b3560438eaa73e18dcf9df03136d7650aa304ba 100644 (file)
@@ -1,3 +1,14 @@
+2002-02-03  Bruno Haible  <bruno@clisp.org>
+
+       * plural-table.h: New file.
+       * plural-table.c: New file.
+       * msginit.c: Include plural-table.h.
+       (plural_forms): Use plural_table.
+       * msgfmt.c: Include plural-table.h.
+       (check_plural): Print a recommendation about the right plural formula.
+       * Makefile.am (noinst_HEADERS): Add plural-table.h.
+       (libgettextsrc_la_SOURCES): Add plural-table.c.
+
 2002-02-03  Bruno Haible  <bruno@clisp.org>
 
        * xgettext.c (finalize_header): New function.
index 1e4983295c5ccdad2470620af30452fa6b6fd1d0..c012b780d5fd2edb20639aade7696dc9bee9776b 100644 (file)
@@ -31,8 +31,8 @@ noinst_HEADERS = pos.h message.h po-gram.h po-hash.h po-charset.h po-lex.h \
 po.h open-po.h read-po.h str-list.h write-po.h dir-list.h file-list.h \
 po-gram-gen.h po-hash-gen.h msgl-charset.h msgl-equal.h msgl-iconv.h \
 msgl-ascii.h msgl-cat.h msgl-english.h msgfmt.h msgunfmt.h read-mo.h \
-write-mo.h read-java.h write-java.h po-time.h format.h xgettext.h x-c.h \
-x-po.h x-lisp.h x-elisp.h x-librep.h x-java.h x-ycp.h x-rst.h
+write-mo.h read-java.h write-java.h po-time.h plural-table.h format.h \
+xgettext.h x-c.h x-po.h x-lisp.h x-elisp.h x-librep.h x-java.h x-ycp.h x-rst.h
 
 EXTRA_DIST = FILES project-id \
 gnu/gettext/DumpResource.java gnu/gettext/GetURL.java
@@ -73,7 +73,7 @@ format-python.c format-pascal.c format-ycp.c
 libgettextsrc_la_SOURCES = \
 $(COMMON_SOURCE) read-po.c write-po.c msgl-ascii.c msgl-iconv.c msgl-equal.c \
 msgl-cat.c msgl-english.c file-list.c msgl-charset.c po-time.c plural.c \
-$(FORMAT_SOURCE)
+plural-table.c $(FORMAT_SOURCE)
 
 # Source dependencies.
 gettext_SOURCES = gettext.c
index 523ffb85d0bfc857b54b12937d78aedd51135744..9f880325fe2c170dc2e7ebfdede56c4354fa4a99 100644 (file)
@@ -38,6 +38,7 @@
 #include "format.h"
 #include "xmalloc.h"
 #include "plural-exp.h"
+#include "plural-table.h"
 #include "strstr.h"
 #include "stpcpy.h"
 #include "exit.h"
@@ -831,6 +832,7 @@ check_plural (mlp)
       const char *nullentry;
       const char *plural;
       const char *nplurals;
+      bool try_to_help = false;
 
       nullentry = header->msgstr;
 
@@ -845,6 +847,7 @@ check_plural (mlp)
          error_at_line (0, 0, header->pos.file_name, header->pos.line_number,
                         _("...but header entry lacks a \"plural=EXPRESSION\" attribute"));
          error_with_progname = true;
+         try_to_help = true;
          exit_status = EXIT_FAILURE;
        }
       if (nplurals == NULL && has_plural != NULL)
@@ -856,6 +859,7 @@ check_plural (mlp)
          error_at_line (0, 0, header->pos.file_name, header->pos.line_number,
                         _("...but header entry lacks a \"nplurals=INTEGER\" attribute"));
          error_with_progname = true;
+         try_to_help = true;
          exit_status = EXIT_FAILURE;
        }
       if (plural != NULL && nplurals != NULL)
@@ -880,6 +884,7 @@ check_plural (mlp)
                             header->pos.file_name, header->pos.line_number,
                             _("invalid nplurals value"));
              error_with_progname = true;
+             try_to_help = true;
              exit_status = EXIT_FAILURE;
            }
 
@@ -893,6 +898,7 @@ check_plural (mlp)
                             header->pos.file_name, header->pos.line_number,
                             _("invalid plural expression"));
              error_with_progname = true;
+             try_to_help = true;
              exit_status = EXIT_FAILURE;
            }
          plural_expr = args.res;
@@ -939,6 +945,32 @@ check_plural (mlp)
                 max_nplurals = n = min_nplurals.  */
            }
        }
+      /* Try to help the translator by looking up the right plural formula
+        for her.  */
+      if (try_to_help)
+       {
+         const char *language;
+
+         language = strstr (nullentry, "Language-Team: ");
+         if (language != NULL)
+           {
+             language += 15;
+             for (j = 0; j < plural_table_size; j++)
+               if (strncmp (language,
+                            plural_table[j].language,
+                            strlen (plural_table[j].language)) == 0)
+                 {
+                   char *recommended =
+                     xasprintf ("Plural-Forms: %s\\n", plural_table[j].value);
+                   fprintf (stderr,
+                            _("Try using the following, valid for %s:\n"),
+                            plural_table[j].language);
+                   fprintf (stderr, "\"%s\"\n", recommended);
+                   free (recommended);
+                   break;
+                 }
+           }
+       }
     }
   else if (has_plural != NULL)
     {
index 61dcfb6df55b281561240764a0ba06823e6da278..33fed5177e120d9d675a25f2646edf25a87f06cf 100644 (file)
@@ -74,6 +74,7 @@
 #include "write-po.h"
 #include "po-charset.h"
 #include "po-time.h"
+#include "plural-table.h"
 #include "xmalloc.h"
 #include "exit.h"
 #include "pathname.h"
@@ -1219,53 +1220,17 @@ content_transfer_encoding ()
 static const char *
 plural_forms ()
 {
-  /* Formulas taken from the documentation, node "Plural forms".  */
-  static struct { const char *lang; const char *value; } table[] =
-    {
-      { "hu", "nplurals=1; plural=0;" },
-      { "ja", "nplurals=1; plural=0;" },
-      { "ko", "nplurals=1; plural=0;" },
-      { "tr", "nplurals=1; plural=0;" },
-      { "da", "nplurals=2; plural=(n != 1);" },
-      { "nl", "nplurals=2; plural=(n != 1);" },
-      { "en", "nplurals=2; plural=(n != 1);" },
-      { "de", "nplurals=2; plural=(n != 1);" },
-      { "nb", "nplurals=2; plural=(n != 1);" },
-      { "no", "nplurals=2; plural=(n != 1);" },
-      { "nn", "nplurals=2; plural=(n != 1);" },
-      { "sv", "nplurals=2; plural=(n != 1);" },
-      { "et", "nplurals=2; plural=(n != 1);" },
-      { "fi", "nplurals=2; plural=(n != 1);" },
-      { "el", "nplurals=2; plural=(n != 1);" },
-      { "he", "nplurals=2; plural=(n != 1);" },
-      { "it", "nplurals=2; plural=(n != 1);" },
-      { "pt", "nplurals=2; plural=(n != 1);" },
-      { "es", "nplurals=2; plural=(n != 1);" },
-      { "eo", "nplurals=2; plural=(n != 1);" },
-      { "fr", "nplurals=2; plural=(n > 1);" },
-      { "pt_BR", "nplurals=2; plural=(n > 1);" },
-      { "lv", "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);" },
-      { "ga", "nplurals=3; plural=n==1 ? 0 : n==2 ? 1 : 2;" },
-      { "lt", "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2);" },
-      { "hr", "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" },
-      { "cs", "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" },
-      { "ru", "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" },
-      { "sk", "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" },
-      { "uk", "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" },
-      { "pl", "nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" },
-      { "sl", "nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);" }
-    };
   size_t i;
 
   /* Search for a formula depending on the catalogname.  */
-  for (i = 0; i < SIZEOF (table); i++)
-    if (strcmp (table[i].lang, catalogname) == 0)
-      return table[i].value;
+  for (i = 0; i < plural_table_size; i++)
+    if (strcmp (plural_table[i].lang, catalogname) == 0)
+      return plural_table[i].value;
 
   /* Search for a formula depending on the language only.  */
-  for (i = 0; i < SIZEOF (table); i++)
-    if (strcmp (table[i].lang, language) == 0)
-      return table[i].value;
+  for (i = 0; i < plural_table_size; i++)
+    if (strcmp (plural_table[i].lang, language) == 0)
+      return plural_table[i].value;
 
   return NULL;
 }
diff --git a/src/plural-table.c b/src/plural-table.c
new file mode 100644 (file)
index 0000000..5bed4e3
--- /dev/null
@@ -0,0 +1,62 @@
+/* Table of known plural form expressions.
+   Copyright (C) 2001-2002 Free Software Foundation, Inc.
+   Written by Bruno Haible <haible@clisp.cons.org>, 2002.
+
+   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
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   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.  */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+/* Specification.  */
+#include "plural-table.h"
+
+/* Formulas taken from the documentation, node "Plural forms".  */
+struct plural_table_entry plural_table[] =
+  {
+    { "hu", "Hungarian",         "nplurals=1; plural=0;" },
+    { "ja", "Japanese",          "nplurals=1; plural=0;" },
+    { "ko", "Korean",            "nplurals=1; plural=0;" },
+    { "tr", "Turkish",           "nplurals=1; plural=0;" },
+    { "da", "Danish",            "nplurals=2; plural=(n != 1);" },
+    { "nl", "Dutch",             "nplurals=2; plural=(n != 1);" },
+    { "en", "English",           "nplurals=2; plural=(n != 1);" },
+    { "de", "German",            "nplurals=2; plural=(n != 1);" },
+    { "nb", "Norwegian Bokmal",  "nplurals=2; plural=(n != 1);" },
+    { "no", "Norwegian",         "nplurals=2; plural=(n != 1);" },
+    { "nn", "Norwegian Nynorsk", "nplurals=2; plural=(n != 1);" },
+    { "sv", "Swedish",           "nplurals=2; plural=(n != 1);" },
+    { "et", "Estonian",          "nplurals=2; plural=(n != 1);" },
+    { "fi", "Finnish",           "nplurals=2; plural=(n != 1);" },
+    { "el", "Greek",             "nplurals=2; plural=(n != 1);" },
+    { "he", "Hebrew",            "nplurals=2; plural=(n != 1);" },
+    { "it", "Italian",           "nplurals=2; plural=(n != 1);" },
+    { "pt", "Portuguese",        "nplurals=2; plural=(n != 1);" },
+    { "es", "Spanish",           "nplurals=2; plural=(n != 1);" },
+    { "eo", "Esperanto",         "nplurals=2; plural=(n != 1);" },
+    { "fr", "French",            "nplurals=2; plural=(n > 1);" },
+    { "pt_BR", "Brazilian",      "nplurals=2; plural=(n > 1);" },
+    { "lv", "Latvian",           "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);" },
+    { "ga", "Irish",             "nplurals=3; plural=n==1 ? 0 : n==2 ? 1 : 2;" },
+    { "lt", "Lithuanian",        "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2);" },
+    { "hr", "Croatian",          "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" },
+    { "cs", "Czech",             "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" },
+    { "ru", "Russian",           "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" },
+    { "sk", "Slovak",            "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" },
+    { "uk", "Ukrainian",         "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" },
+    { "pl", "Polish",            "nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" },
+    { "sl", "Slovenian",         "nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);" }
+  };
+const size_t plural_table_size = sizeof (plural_table) / sizeof (plural_table[0]);
diff --git a/src/plural-table.h b/src/plural-table.h
new file mode 100644 (file)
index 0000000..ae7a7a8
--- /dev/null
@@ -0,0 +1,34 @@
+/* Table of known plural form expressions.
+   Copyright (C) 2001-2002 Free Software Foundation, Inc.
+   Written by Bruno Haible <haible@clisp.cons.org>, 2002.
+
+   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
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   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 _PLURAL_TABLE_H
+#define _PLURAL_TABLE_H
+
+#include <stddef.h>
+
+struct plural_table_entry
+{
+  const char *lang;
+  const char *language;
+  const char *value;
+};
+
+extern struct plural_table_entry plural_table[];
+extern const size_t plural_table_size;
+
+#endif /* _PLURAL_TABLE_H */