Home | History | Annotate | Line # | Download | only in intl
      1  1.1  christos /*	$NetBSD: plural-exp.c,v 1.1.1.1 2016/01/10 21:36:18 christos Exp $	*/
      2  1.1  christos 
      3  1.1  christos /* Expression parsing for plural form selection.
      4  1.1  christos    Copyright (C) 2000, 2001 Free Software Foundation, Inc.
      5  1.1  christos    Written by Ulrich Drepper <drepper (at) cygnus.com>, 2000.
      6  1.1  christos 
      7  1.1  christos    This program is free software; you can redistribute it and/or modify it
      8  1.1  christos    under the terms of the GNU Library General Public License as published
      9  1.1  christos    by the Free Software Foundation; either version 2, or (at your option)
     10  1.1  christos    any later version.
     11  1.1  christos 
     12  1.1  christos    This program is distributed in the hope that it will be useful,
     13  1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14  1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     15  1.1  christos    Library General Public License for more details.
     16  1.1  christos 
     17  1.1  christos    You should have received a copy of the GNU Library General Public
     18  1.1  christos    License along with this program; if not, write to the Free Software
     19  1.1  christos    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
     20  1.1  christos    USA.  */
     21  1.1  christos 
     22  1.1  christos #ifdef HAVE_CONFIG_H
     23  1.1  christos # include <config.h>
     24  1.1  christos #endif
     25  1.1  christos 
     26  1.1  christos #include <ctype.h>
     27  1.1  christos #include <stdlib.h>
     28  1.1  christos #include <string.h>
     29  1.1  christos 
     30  1.1  christos #include "plural-exp.h"
     31  1.1  christos 
     32  1.1  christos #if (defined __GNUC__ && !defined __APPLE_CC__) \
     33  1.1  christos     || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L)
     34  1.1  christos 
     35  1.1  christos /* These structs are the constant expression for the germanic plural
     36  1.1  christos    form determination.  It represents the expression  "n != 1".  */
     37  1.1  christos static const struct expression plvar =
     38  1.1  christos {
     39  1.1  christos   .nargs = 0,
     40  1.1  christos   .operation = var,
     41  1.1  christos };
     42  1.1  christos static const struct expression plone =
     43  1.1  christos {
     44  1.1  christos   .nargs = 0,
     45  1.1  christos   .operation = num,
     46  1.1  christos   .val =
     47  1.1  christos   {
     48  1.1  christos     .num = 1
     49  1.1  christos   }
     50  1.1  christos };
     51  1.1  christos struct expression GERMANIC_PLURAL =
     52  1.1  christos {
     53  1.1  christos   .nargs = 2,
     54  1.1  christos   .operation = not_equal,
     55  1.1  christos   .val =
     56  1.1  christos   {
     57  1.1  christos     .args =
     58  1.1  christos     {
     59  1.1  christos       [0] = (struct expression *) &plvar,
     60  1.1  christos       [1] = (struct expression *) &plone
     61  1.1  christos     }
     62  1.1  christos   }
     63  1.1  christos };
     64  1.1  christos 
     65  1.1  christos # define INIT_GERMANIC_PLURAL()
     66  1.1  christos 
     67  1.1  christos #else
     68  1.1  christos 
     69  1.1  christos /* For compilers without support for ISO C 99 struct/union initializers:
     70  1.1  christos    Initialization at run-time.  */
     71  1.1  christos 
     72  1.1  christos static struct expression plvar;
     73  1.1  christos static struct expression plone;
     74  1.1  christos struct expression GERMANIC_PLURAL;
     75  1.1  christos 
     76  1.1  christos static void
     77  1.1  christos init_germanic_plural ()
     78  1.1  christos {
     79  1.1  christos   if (plone.val.num == 0)
     80  1.1  christos     {
     81  1.1  christos       plvar.nargs = 0;
     82  1.1  christos       plvar.operation = var;
     83  1.1  christos 
     84  1.1  christos       plone.nargs = 0;
     85  1.1  christos       plone.operation = num;
     86  1.1  christos       plone.val.num = 1;
     87  1.1  christos 
     88  1.1  christos       GERMANIC_PLURAL.nargs = 2;
     89  1.1  christos       GERMANIC_PLURAL.operation = not_equal;
     90  1.1  christos       GERMANIC_PLURAL.val.args[0] = &plvar;
     91  1.1  christos       GERMANIC_PLURAL.val.args[1] = &plone;
     92  1.1  christos     }
     93  1.1  christos }
     94  1.1  christos 
     95  1.1  christos # define INIT_GERMANIC_PLURAL() init_germanic_plural ()
     96  1.1  christos 
     97  1.1  christos #endif
     98  1.1  christos 
     99  1.1  christos void
    100  1.1  christos internal_function
    101  1.1  christos EXTRACT_PLURAL_EXPRESSION (nullentry, pluralp, npluralsp)
    102  1.1  christos      const char *nullentry;
    103  1.1  christos      struct expression **pluralp;
    104  1.1  christos      unsigned long int *npluralsp;
    105  1.1  christos {
    106  1.1  christos   if (nullentry != NULL)
    107  1.1  christos     {
    108  1.1  christos       const char *plural;
    109  1.1  christos       const char *nplurals;
    110  1.1  christos 
    111  1.1  christos       plural = strstr (nullentry, "plural=");
    112  1.1  christos       nplurals = strstr (nullentry, "nplurals=");
    113  1.1  christos       if (plural == NULL || nplurals == NULL)
    114  1.1  christos 	goto no_plural;
    115  1.1  christos       else
    116  1.1  christos 	{
    117  1.1  christos 	  char *endp;
    118  1.1  christos 	  unsigned long int n;
    119  1.1  christos 	  struct parse_args args;
    120  1.1  christos 
    121  1.1  christos 	  /* First get the number.  */
    122  1.1  christos 	  nplurals += 9;
    123  1.1  christos 	  while (*nplurals != '\0' && isspace ((unsigned char) *nplurals))
    124  1.1  christos 	    ++nplurals;
    125  1.1  christos 	  if (!(*nplurals >= '0' && *nplurals <= '9'))
    126  1.1  christos 	    goto no_plural;
    127  1.1  christos #if defined HAVE_STRTOUL || defined _LIBC
    128  1.1  christos 	  n = strtoul (nplurals, &endp, 10);
    129  1.1  christos #else
    130  1.1  christos 	  for (endp = nplurals, n = 0; *endp >= '0' && *endp <= '9'; endp++)
    131  1.1  christos 	    n = n * 10 + (*endp - '0');
    132  1.1  christos #endif
    133  1.1  christos 	  if (nplurals == endp)
    134  1.1  christos 	    goto no_plural;
    135  1.1  christos 	  *npluralsp = n;
    136  1.1  christos 
    137  1.1  christos 	  /* Due to the restrictions bison imposes onto the interface of the
    138  1.1  christos 	     scanner function we have to put the input string and the result
    139  1.1  christos 	     passed up from the parser into the same structure which address
    140  1.1  christos 	     is passed down to the parser.  */
    141  1.1  christos 	  plural += 7;
    142  1.1  christos 	  args.cp = plural;
    143  1.1  christos 	  if (PLURAL_PARSE (&args) != 0)
    144  1.1  christos 	    goto no_plural;
    145  1.1  christos 	  *pluralp = args.res;
    146  1.1  christos 	}
    147  1.1  christos     }
    148  1.1  christos   else
    149  1.1  christos     {
    150  1.1  christos       /* By default we are using the Germanic form: singular form only
    151  1.1  christos          for `one', the plural form otherwise.  Yes, this is also what
    152  1.1  christos          English is using since English is a Germanic language.  */
    153  1.1  christos     no_plural:
    154  1.1  christos       INIT_GERMANIC_PLURAL ();
    155  1.1  christos       *pluralp = &GERMANIC_PLURAL;
    156  1.1  christos       *npluralsp = 2;
    157  1.1  christos     }
    158  1.1  christos }
    159