]> git.ipfire.org Git - thirdparty/gettext.git/commitdiff
Separate the plural expression parser, so it can be used by msgfmt.
authorBruno Haible <bruno@clisp.org>
Tue, 11 Sep 2001 12:20:09 +0000 (12:20 +0000)
committerBruno Haible <bruno@clisp.org>
Tue, 11 Sep 2001 12:20:09 +0000 (12:20 +0000)
intl/ChangeLog
intl/Makefile.in
intl/dcigettext.c
intl/gettextP.h
intl/loadmsgcat.c
intl/plural-exp.c [new file with mode: 0644]
intl/plural-exp.h [new file with mode: 0644]
intl/plural.y

index 05f318421aacf62ad402a222d1f930e2c99f9986..97a3ff2e35ef19b8d0f92341bfe45de8e363350d 100644 (file)
@@ -1,3 +1,24 @@
+2001-09-02  Bruno Haible  <haible@clisp.cons.org>
+
+       * plural-exp.h: New file, extracted from gettextP.h.
+       * plural-exp.c: New file, extracted from loadmsgcat.c.
+       * gettextP.h (struct expression, struct parse_args,
+       __gettext_free_exp, __gettextparse): Move to plural-exp.h.
+       * loadmsgcat.c: Include plural-exp.h.
+       (PLURAL_PARSE): Move macro to plural-exp.h.
+       (plvar, plone, germanic_plural, INIT_GERMANIC_PLURAL): Move to
+       plural-exp.c.
+       (_nl_load_domain): Move plural handling code to plural-exp.c. Call
+       EXTRACT_PLURAL_EXPRESSION.
+       * dcigettext.c: Include plural-exp.h.
+       * plural.y: Include plural-exp.h, not gettextP.h.
+       (FREE_EXPRESSION): Move macro to plural-exp.h.
+       * Makefile.in (DEFS): Define IN_LIBINTL.
+       (COMHDRS): Add plural-exp.h.
+       (COMSRCS): Add plural-exp.c.
+       (OBJECTS): Add plural-exp.$lo.
+       Update dependencies.
+
 2001-09-01  Bruno Haible  <haible@clisp.cons.org>
 
        * *.h, *.c, *.y, Makefile.in: Change copyright notice from GPL to LGPL.
index 71350d1522892779fb8b34c66ec0d027aed9c785..0dc41aa42c8a077826645254dbfb440dbc18ac95 100644 (file)
@@ -52,7 +52,7 @@ YACC = @INTLBISON@ -y -d
 YFLAGS = --name-prefix=__gettext
 
 DEFS = -DLOCALEDIR=\"$(localedir)\" -DLOCALE_ALIAS_PATH=\"$(aliaspath)\" \
--DLIBDIR=\"$(libdir)\" @DEFS@
+-DLIBDIR=\"$(libdir)\" -DIN_LIBINTL @DEFS@
 CPPFLAGS = @CPPFLAGS@
 CFLAGS = @CFLAGS@
 LDFLAGS = @LDFLAGS@
@@ -60,16 +60,16 @@ LDFLAGS = @LDFLAGS@
 COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(XCFLAGS)
 
 HEADERS = $(COMHDRS) libgnuintl.h libgettext.h loadinfo.h
-COMHDRS = gettext.h gettextP.h hash-string.h
+COMHDRS = gettext.h gettextP.h hash-string.h plural-exp.h
 SOURCES = $(COMSRCS) intl-compat.c
 COMSRCS = bindtextdom.c dcgettext.c dgettext.c gettext.c \
 finddomain.c loadmsgcat.c localealias.c textdomain.c l10nflist.c \
 explodename.c dcigettext.c dcngettext.c dngettext.c ngettext.c plural.y \
-localcharset.c
+plural-exp.c localcharset.c
 OBJECTS = @INTLOBJS@ bindtextdom.$lo dcgettext.$lo dgettext.$lo gettext.$lo \
 finddomain.$lo loadmsgcat.$lo localealias.$lo textdomain.$lo l10nflist.$lo \
 explodename.$lo dcigettext.$lo dcngettext.$lo dngettext.$lo ngettext.$lo \
-plural.$lo localcharset.$lo
+plural.$lo plural-exp.$lo localcharset.$lo
 GETTOBJS = intl-compat.$lo
 DISTFILES.common = COPYING.LIB-2 COPYING.LIB-2.1 Makefile.in \
 config.charset locale.alias ref-add.sin ref-del.sin $(HEADERS) $(SOURCES)
@@ -254,8 +254,10 @@ uninstall:
 info dvi:
 
 $(OBJECTS): ../config.h libgnuintl.h
-bindtextdom.$lo finddomain.$lo loadmsgcat.$lo: gettextP.h gettext.h loadinfo.h
-dcgettext.$lo: gettextP.h gettext.h hash-string.h loadinfo.h
+bindtextdom.$lo dcgettext.$lo dcigettext.$lo dcngettext.$lo dgettext.$lo dngettext.$lo finddomain.$lo gettext.$lo intl-compat.$lo loadmsgcat.$lo localealias.$lo ngettext.$lo textdomain.$lo: gettextP.h gettext.h loadinfo.h
+dcigettext.$lo: hash-string.h
+explodename.$lo l10nflist.$lo: loadinfo.h
+dcigettext.$lo loadmsgcat.$lo plural.$lo plural-exp.$lo: plural-exp.h
 
 tags: TAGS
 
index 6acde195ff6adfeba7c21f599360d0abe6346367..5bae74c73b325bc3d20bdc6b02fb75bf0d7f7124 100644 (file)
@@ -75,6 +75,7 @@ extern int errno;
 #endif
 
 #include "gettextP.h"
+#include "plural-exp.h"
 #ifdef _LIBC
 # include <libintl.h>
 #else
index 43de1cd47d15187b8517e260e0252d8e334a14e2..a04196cea9877eefd0178aab7122f3ad54b24bcc 100644 (file)
@@ -72,51 +72,6 @@ SWAP (i)
 #endif
 
 
-/* This is the representation of the expressions to determine the
-   plural form.  */
-struct expression
-{
-  int nargs;                   /* Number of arguments.  */
-  enum operator
-  {
-    /* Without arguments:  */
-    var,                       /* The variable "n".  */
-    num,                       /* Decimal number.  */
-    /* Unary operators:  */
-    lnot,                      /* Logical NOT.  */
-    /* Binary operators:  */
-    mult,                      /* Multiplication.  */
-    divide,                    /* Division.  */
-    module,                    /* Module operation.  */
-    plus,                      /* Addition.  */
-    minus,                     /* Subtraction.  */
-    less_than,                 /* Comparison.  */
-    greater_than,              /* Comparison.  */
-    less_or_equal,             /* Comparison.  */
-    greater_or_equal,          /* Comparison.  */
-    equal,                     /* Comparision for equality.  */
-    not_equal,                 /* Comparision for inequality.  */
-    land,                      /* Logical AND.  */
-    lor,                       /* Logical OR.  */
-    /* Ternary operators:  */
-    qmop                       /* Question mark operator.  */
-  } operation;
-  union
-  {
-    unsigned long int num;     /* Number value for `num'.  */
-    struct expression *args[3];        /* Up to three arguments.  */
-  } val;
-};
-
-/* This is the data structure to pass information to the parser and get
-   the result in a thread-safe way.  */
-struct parse_args
-{
-  const char *cp;
-  struct expression *res;
-};
-
-
 /* The representation of an opened message catalog.  */
 struct loaded_domain
 {
@@ -237,16 +192,6 @@ extern char *bind_textdomain_codeset__ PARAMS ((const char *__domainname,
                                                const char *__codeset));
 #endif
 
-#ifdef _LIBC
-extern void __gettext_free_exp PARAMS ((struct expression *exp))
-     internal_function;
-extern int __gettextparse PARAMS ((void *arg));
-#else
-extern void gettext_free_exp__ PARAMS ((struct expression *exp))
-     internal_function;
-extern int gettextparse__ PARAMS ((void *arg));
-#endif
-
 /* @@ begin of epilog @@ */
 
 #endif /* gettextP.h  */
index a06134a1d3a30af7439ed24c1210972014d47eb7..98f9f2b11b83b6f9cdbf2582998d76f835b1d8d1 100644 (file)
@@ -73,6 +73,7 @@ char *alloca ();
 
 #include "gettext.h"
 #include "gettextP.h"
+#include "plural-exp.h"
 
 #ifdef _LIBC
 # include "../locale/localeinfo.h"
@@ -91,16 +92,6 @@ char *alloca ();
 # define munmap __munmap
 #endif
 
-/* Names for the libintl functions are a problem.  They must not clash
-   with existing names and they should follow ANSI C.  But this source
-   code is also used in GNU C Library where the names have a __
-   prefix.  So we have to make a difference here.  */
-#ifdef _LIBC
-# define PLURAL_PARSE __gettextparse
-#else
-# define PLURAL_PARSE gettextparse__
-#endif
-
 /* For those losing systems which don't have `alloca' we have to add
    some additional code emulating it.  */
 #ifdef HAVE_ALLOCA
@@ -132,73 +123,6 @@ char *alloca ();
    cached by one of GCC's features.  */
 int _nl_msg_cat_cntr;
 
-#if (defined __GNUC__ && !defined __APPLE_CC__) \
-    || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L)
-
-/* These structs are the constant expression for the germanic plural
-   form determination.  It represents the expression  "n != 1".  */
-static const struct expression plvar =
-{
-  .nargs = 0,
-  .operation = var,
-};
-static const struct expression plone =
-{
-  .nargs = 0,
-  .operation = num,
-  .val =
-  {
-    .num = 1
-  }
-};
-static struct expression germanic_plural =
-{
-  .nargs = 2,
-  .operation = not_equal,
-  .val =
-  {
-    .args =
-    {
-      [0] = (struct expression *) &plvar,
-      [1] = (struct expression *) &plone
-    }
-  }
-};
-
-# define INIT_GERMANIC_PLURAL()
-
-#else
-
-/* For compilers without support for ISO C 99 struct/union initializers:
-   Initialization at run-time.  */
-
-static struct expression plvar;
-static struct expression plone;
-static struct expression germanic_plural;
-
-static void
-init_germanic_plural ()
-{
-  if (plone.val.num == 0)
-    {
-      plvar.nargs = 0;
-      plvar.operation = var;
-
-      plone.nargs = 0;
-      plone.operation = num;
-      plone.val.num = 1;
-
-      germanic_plural.nargs = 2;
-      germanic_plural.operation = not_equal;
-      germanic_plural.val.args[0] = &plvar;
-      germanic_plural.val.args[1] = &plone;
-    }
-}
-
-# define INIT_GERMANIC_PLURAL() init_germanic_plural ()
-
-#endif
-
 
 /* Initialize the codeset dependent parts of an opened message catalog.
    Return the header entry.  */
@@ -491,56 +415,7 @@ _nl_load_domain (domain_file, domainbinding)
   nullentry = _nl_init_domain_conv (domain_file, domain, domainbinding);
 
   /* Also look for a plural specification.  */
-  if (nullentry != NULL)
-    {
-      const char *plural;
-      const char *nplurals;
-
-      plural = strstr (nullentry, "plural=");
-      nplurals = strstr (nullentry, "nplurals=");
-      if (plural == NULL || nplurals == NULL)
-       goto no_plural;
-      else
-       {
-         /* First get the number.  */
-         char *endp;
-         unsigned long int n;
-         struct parse_args args;
-
-         nplurals += 9;
-         while (*nplurals != '\0' && isspace ((unsigned char) *nplurals))
-           ++nplurals;
-#if defined HAVE_STRTOUL || defined _LIBC
-         n = strtoul (nplurals, &endp, 10);
-#else
-         for (endp = nplurals, n = 0; *endp >= '0' && *endp <= '9'; endp++)
-           n = n * 10 + (*endp - '0');
-#endif
-         domain->nplurals = n;
-         if (nplurals == endp)
-           goto no_plural;
-
-         /* Due to the restrictions bison imposes onto the interface of the
-            scanner function we have to put the input string and the result
-            passed up from the parser into the same structure which address
-            is passed down to the parser.  */
-         plural += 7;
-         args.cp = plural;
-         if (PLURAL_PARSE (&args) != 0)
-           goto no_plural;
-         domain->plural = args.res;
-       }
-    }
-  else
-    {
-      /* By default we are using the Germanic form: singular form only
-         for `one', the plural form otherwise.  Yes, this is also what
-         English is using since English is a Germanic language.  */
-    no_plural:
-      INIT_GERMANIC_PLURAL ();
-      domain->plural = &germanic_plural;
-      domain->nplurals = 2;
-    }
+  EXTRACT_PLURAL_EXPRESSION (nullentry, &domain->plural, &domain->nplurals);
 }
 
 
diff --git a/intl/plural-exp.c b/intl/plural-exp.c
new file mode 100644 (file)
index 0000000..bd8c22c
--- /dev/null
@@ -0,0 +1,154 @@
+/* Expression parsing for plural form selection.
+   Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+   Written by Ulrich Drepper <drepper@cygnus.com>, 2000.
+
+   This program is free software; you can redistribute it and/or modify it
+   under the terms of the GNU Library 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library 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
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "plural-exp.h"
+
+#if (defined __GNUC__ && !defined __APPLE_CC__) \
+    || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L)
+
+/* These structs are the constant expression for the germanic plural
+   form determination.  It represents the expression  "n != 1".  */
+static const struct expression plvar =
+{
+  .nargs = 0,
+  .operation = var,
+};
+static const struct expression plone =
+{
+  .nargs = 0,
+  .operation = num,
+  .val =
+  {
+    .num = 1
+  }
+};
+static struct expression germanic_plural =
+{
+  .nargs = 2,
+  .operation = not_equal,
+  .val =
+  {
+    .args =
+    {
+      [0] = (struct expression *) &plvar,
+      [1] = (struct expression *) &plone
+    }
+  }
+};
+
+# define INIT_GERMANIC_PLURAL()
+
+#else
+
+/* For compilers without support for ISO C 99 struct/union initializers:
+   Initialization at run-time.  */
+
+static struct expression plvar;
+static struct expression plone;
+static struct expression germanic_plural;
+
+static void
+init_germanic_plural ()
+{
+  if (plone.val.num == 0)
+    {
+      plvar.nargs = 0;
+      plvar.operation = var;
+
+      plone.nargs = 0;
+      plone.operation = num;
+      plone.val.num = 1;
+
+      germanic_plural.nargs = 2;
+      germanic_plural.operation = not_equal;
+      germanic_plural.val.args[0] = &plvar;
+      germanic_plural.val.args[1] = &plone;
+    }
+}
+
+# define INIT_GERMANIC_PLURAL() init_germanic_plural ()
+
+#endif
+
+void
+internal_function
+EXTRACT_PLURAL_EXPRESSION (nullentry, pluralp, npluralsp)
+     const char *nullentry;
+     struct expression **pluralp;
+     unsigned long int *npluralsp;
+{
+  if (nullentry != NULL)
+    {
+      const char *plural;
+      const char *nplurals;
+
+      plural = strstr (nullentry, "plural=");
+      nplurals = strstr (nullentry, "nplurals=");
+      if (plural == NULL || nplurals == NULL)
+       goto no_plural;
+      else
+       {
+         /* First get the number.  */
+         char *endp;
+         unsigned long int n;
+         struct parse_args args;
+
+         nplurals += 9;
+         while (*nplurals != '\0' && isspace ((unsigned char) *nplurals))
+           ++nplurals;
+#if defined HAVE_STRTOUL || defined _LIBC
+         n = strtoul (nplurals, &endp, 10);
+#else
+         for (endp = nplurals, n = 0; *endp >= '0' && *endp <= '9'; endp++)
+           n = n * 10 + (*endp - '0');
+#endif
+         if (nplurals == endp)
+           goto no_plural;
+         *npluralsp = n;
+
+         /* Due to the restrictions bison imposes onto the interface of the
+            scanner function we have to put the input string and the result
+            passed up from the parser into the same structure which address
+            is passed down to the parser.  */
+         plural += 7;
+         args.cp = plural;
+         if (PLURAL_PARSE (&args) != 0)
+           goto no_plural;
+         *pluralp = args.res;
+       }
+    }
+  else
+    {
+      /* By default we are using the Germanic form: singular form only
+         for `one', the plural form otherwise.  Yes, this is also what
+         English is using since English is a Germanic language.  */
+    no_plural:
+      INIT_GERMANIC_PLURAL ();
+      *pluralp = &germanic_plural;
+      *npluralsp = 2;
+    }
+}
diff --git a/intl/plural-exp.h b/intl/plural-exp.h
new file mode 100644 (file)
index 0000000..3b668d8
--- /dev/null
@@ -0,0 +1,112 @@
+/* Expression parsing for plural form selection.
+   Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+   Written by Ulrich Drepper <drepper@cygnus.com>, 2000.
+
+   This program is free software; you can redistribute it and/or modify it
+   under the terms of the GNU Library 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library 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_EXP_H
+#define _PLURAL_EXP_H
+
+#ifndef PARAMS
+# if __STDC__
+#  define PARAMS(args) args
+# else
+#  define PARAMS(args) ()
+# endif
+#endif
+
+#ifndef internal_function
+# define internal_function
+#endif
+
+
+/* This is the representation of the expressions to determine the
+   plural form.  */
+struct expression
+{
+  int nargs;                   /* Number of arguments.  */
+  enum operator
+  {
+    /* Without arguments:  */
+    var,                       /* The variable "n".  */
+    num,                       /* Decimal number.  */
+    /* Unary operators:  */
+    lnot,                      /* Logical NOT.  */
+    /* Binary operators:  */
+    mult,                      /* Multiplication.  */
+    divide,                    /* Division.  */
+    module,                    /* Modulo operation.  */
+    plus,                      /* Addition.  */
+    minus,                     /* Subtraction.  */
+    less_than,                 /* Comparison.  */
+    greater_than,              /* Comparison.  */
+    less_or_equal,             /* Comparison.  */
+    greater_or_equal,          /* Comparison.  */
+    equal,                     /* Comparison for equality.  */
+    not_equal,                 /* Comparison for inequality.  */
+    land,                      /* Logical AND.  */
+    lor,                       /* Logical OR.  */
+    /* Ternary operators:  */
+    qmop                       /* Question mark operator.  */
+  } operation;
+  union
+  {
+    unsigned long int num;     /* Number value for `num'.  */
+    struct expression *args[3];        /* Up to three arguments.  */
+  } val;
+};
+
+/* This is the data structure to pass information to the parser and get
+   the result in a thread-safe way.  */
+struct parse_args
+{
+  const char *cp;
+  struct expression *res;
+};
+
+
+/* Names for the libintl functions are a problem.  This source code is used
+   1. in the GNU C Library library,
+   2. in the GNU libintl library,
+   3. in the GNU gettext tools.
+   The function names in each situation must be different, to allow for
+   binary incompatible changes in 'struct expression'.  Furthermore,
+   1. in the GNU C Library library, the names have a __ prefix,
+   2.+3. in the GNU libintl library and in the GNU gettext tools, the names
+         must follow ANSI C and not start with __.
+   So we have to distinguish the three cases.  */
+#ifdef _LIBC
+# define FREE_EXPRESSION __gettext_free_exp
+# define PLURAL_PARSE __gettextparse
+# define EXTRACT_PLURAL_EXPRESSION __gettext_extract_plural
+#elif defined (IN_LIBINTL)
+# define FREE_EXPRESSION gettext_free_exp__
+# define PLURAL_PARSE gettextparse__
+# define EXTRACT_PLURAL_EXPRESSION gettext_extract_plural__
+#else
+# define FREE_EXPRESSION free_plural_expression
+# define PLURAL_PARSE parse_plural_expression
+# define EXTRACT_PLURAL_EXPRESSION extract_plural_expression
+#endif
+extern void FREE_EXPRESSION PARAMS ((struct expression *exp))
+     internal_function;
+extern int PLURAL_PARSE PARAMS ((void *arg));
+extern void EXTRACT_PLURAL_EXPRESSION PARAMS ((const char *nullentry,
+                                              struct expression **pluralp,
+                                              unsigned long int *npluralsp))
+     internal_function;
+
+#endif /* _PLURAL_EXP_H */
index be049a6d4ec99aad67810bdd965106b5c2e7bea7..43f520ee586e61c7f6c0c5cd6c8496dfdf07fa86 100644 (file)
 #endif
 
 #include <stdlib.h>
-#include "gettextP.h"
-
-/* Names for the libintl functions are a problem.  They must not clash
-   with existing names and they should follow ANSI C.  But this source
-   code is also used in GNU C Library where the names have a __
-   prefix.  So we have to make a difference here.  */
-#ifdef _LIBC
-# define FREE_EXPRESSION __gettext_free_exp
-#else
-# define FREE_EXPRESSION gettext_free_exp__
-# define __gettextparse gettextparse__
+#include "plural-exp.h"
+
+/* The main function generated by the parser is called __gettextparse,
+   but we want it to be called PLURAL_PARSE.  */
+#ifndef _LIBC
+# define __gettextparse PLURAL_PARSE
 #endif
 
 #define YYLEX_PARAM    &((struct parse_args *) arg)->cp