Back to index

cell-binutils  2.17cvs20070401
plural-exp.c
Go to the documentation of this file.
00001 /* Expression parsing for plural form selection.
00002    Copyright (C) 2000, 2001 Free Software Foundation, Inc.
00003    Written by Ulrich Drepper <drepper@cygnus.com>, 2000.
00004 
00005    This program is free software; you can redistribute it and/or modify it
00006    under the terms of the GNU Library General Public License as published
00007    by the Free Software Foundation; either version 2, or (at your option)
00008    any later version.
00009 
00010    This program is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Library General Public License for more details.
00014 
00015    You should have received a copy of the GNU Library General Public
00016    License along with this program; if not, write to the Free Software
00017    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301,
00018    USA.  */
00019 
00020 #ifdef HAVE_CONFIG_H
00021 # include <config.h>
00022 #endif
00023 
00024 #include <ctype.h>
00025 #include <stdlib.h>
00026 #include <string.h>
00027 
00028 #include "plural-exp.h"
00029 
00030 #if (defined __GNUC__ && !defined __APPLE_CC__) \
00031     || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L)
00032 
00033 /* These structs are the constant expression for the germanic plural
00034    form determination.  It represents the expression  "n != 1".  */
00035 static const struct expression plvar =
00036 {
00037   .nargs = 0,
00038   .operation = var,
00039 };
00040 static const struct expression plone =
00041 {
00042   .nargs = 0,
00043   .operation = num,
00044   .val =
00045   {
00046     .num = 1
00047   }
00048 };
00049 struct expression GERMANIC_PLURAL =
00050 {
00051   .nargs = 2,
00052   .operation = not_equal,
00053   .val =
00054   {
00055     .args =
00056     {
00057       [0] = (struct expression *) &plvar,
00058       [1] = (struct expression *) &plone
00059     }
00060   }
00061 };
00062 
00063 # define INIT_GERMANIC_PLURAL()
00064 
00065 #else
00066 
00067 /* For compilers without support for ISO C 99 struct/union initializers:
00068    Initialization at run-time.  */
00069 
00070 static struct expression plvar;
00071 static struct expression plone;
00072 struct expression GERMANIC_PLURAL;
00073 
00074 static void
00075 init_germanic_plural ()
00076 {
00077   if (plone.val.num == 0)
00078     {
00079       plvar.nargs = 0;
00080       plvar.operation = var;
00081 
00082       plone.nargs = 0;
00083       plone.operation = num;
00084       plone.val.num = 1;
00085 
00086       GERMANIC_PLURAL.nargs = 2;
00087       GERMANIC_PLURAL.operation = not_equal;
00088       GERMANIC_PLURAL.val.args[0] = &plvar;
00089       GERMANIC_PLURAL.val.args[1] = &plone;
00090     }
00091 }
00092 
00093 # define INIT_GERMANIC_PLURAL() init_germanic_plural ()
00094 
00095 #endif
00096 
00097 void
00098 internal_function
00099 EXTRACT_PLURAL_EXPRESSION (nullentry, pluralp, npluralsp)
00100      const char *nullentry;
00101      struct expression **pluralp;
00102      unsigned long int *npluralsp;
00103 {
00104   if (nullentry != NULL)
00105     {
00106       const char *plural;
00107       const char *nplurals;
00108 
00109       plural = strstr (nullentry, "plural=");
00110       nplurals = strstr (nullentry, "nplurals=");
00111       if (plural == NULL || nplurals == NULL)
00112        goto no_plural;
00113       else
00114        {
00115          char *endp;
00116          unsigned long int n;
00117          struct parse_args args;
00118 
00119          /* First get the number.  */
00120          nplurals += 9;
00121          while (*nplurals != '\0' && isspace ((unsigned char) *nplurals))
00122            ++nplurals;
00123          if (!(*nplurals >= '0' && *nplurals <= '9'))
00124            goto no_plural;
00125 #if defined HAVE_STRTOUL || defined _LIBC
00126          n = strtoul (nplurals, &endp, 10);
00127 #else
00128          for (endp = nplurals, n = 0; *endp >= '0' && *endp <= '9'; endp++)
00129            n = n * 10 + (*endp - '0');
00130 #endif
00131          if (nplurals == endp)
00132            goto no_plural;
00133          *npluralsp = n;
00134 
00135          /* Due to the restrictions bison imposes onto the interface of the
00136             scanner function we have to put the input string and the result
00137             passed up from the parser into the same structure which address
00138             is passed down to the parser.  */
00139          plural += 7;
00140          args.cp = plural;
00141          if (PLURAL_PARSE (&args) != 0)
00142            goto no_plural;
00143          *pluralp = args.res;
00144        }
00145     }
00146   else
00147     {
00148       /* By default we are using the Germanic form: singular form only
00149          for `one', the plural form otherwise.  Yes, this is also what
00150          English is using since English is a Germanic language.  */
00151     no_plural:
00152       INIT_GERMANIC_PLURAL ();
00153       *pluralp = &GERMANIC_PLURAL;
00154       *npluralsp = 2;
00155     }
00156 }