(linenum→info "unix/slp.c:2238")

glibc/2.7/intl/plural-exp.c

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