Blame intl/plural-exp.c

Packit Service a721b1
/* Expression parsing for plural form selection.
Packit Service a721b1
   Copyright (C) 2000-2001, 2003, 2005-2007 Free Software Foundation, Inc.
Packit Service a721b1
   Written by Ulrich Drepper <drepper@cygnus.com>, 2000.
Packit Service a721b1
Packit Service a721b1
   This program is free software; you can redistribute it and/or modify it
Packit Service a721b1
   under the terms of the GNU Library General Public License as published
Packit Service a721b1
   by the Free Software Foundation; either version 2, or (at your option)
Packit Service a721b1
   any later version.
Packit Service a721b1
Packit Service a721b1
   This program is distributed in the hope that it will be useful,
Packit Service a721b1
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service a721b1
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service a721b1
   Library General Public License for more details.
Packit Service a721b1
Packit Service a721b1
   You should have received a copy of the GNU Library General Public
Packit Service a721b1
   License along with this program; if not, write to the Free Software
Packit Service a721b1
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
Packit Service a721b1
   USA.  */
Packit Service a721b1
Packit Service a721b1
#ifdef HAVE_CONFIG_H
Packit Service a721b1
# include <config.h>
Packit Service a721b1
#endif
Packit Service a721b1
Packit Service a721b1
#include <ctype.h>
Packit Service a721b1
#include <stdlib.h>
Packit Service a721b1
#include <string.h>
Packit Service a721b1
Packit Service a721b1
#include "plural-exp.h"
Packit Service a721b1
Packit Service a721b1
#if (defined __GNUC__ && !(__APPLE_CC__ > 1) && !defined __cplusplus) \
Packit Service a721b1
    || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L)
Packit Service a721b1
Packit Service a721b1
/* These structs are the constant expression for the germanic plural
Packit Service a721b1
   form determination.  It represents the expression  "n != 1".  */
Packit Service a721b1
static const struct expression plvar =
Packit Service a721b1
{
Packit Service a721b1
  .nargs = 0,
Packit Service a721b1
  .operation = var,
Packit Service a721b1
};
Packit Service a721b1
static const struct expression plone =
Packit Service a721b1
{
Packit Service a721b1
  .nargs = 0,
Packit Service a721b1
  .operation = num,
Packit Service a721b1
  .val =
Packit Service a721b1
  {
Packit Service a721b1
    .num = 1
Packit Service a721b1
  }
Packit Service a721b1
};
Packit Service a721b1
struct expression GERMANIC_PLURAL =
Packit Service a721b1
{
Packit Service a721b1
  .nargs = 2,
Packit Service a721b1
  .operation = not_equal,
Packit Service a721b1
  .val =
Packit Service a721b1
  {
Packit Service a721b1
    .args =
Packit Service a721b1
    {
Packit Service a721b1
      [0] = (struct expression *) &plvar,
Packit Service a721b1
      [1] = (struct expression *) &plone
Packit Service a721b1
    }
Packit Service a721b1
  }
Packit Service a721b1
};
Packit Service a721b1
Packit Service a721b1
# define INIT_GERMANIC_PLURAL()
Packit Service a721b1
Packit Service a721b1
#else
Packit Service a721b1
Packit Service a721b1
/* For compilers without support for ISO C 99 struct/union initializers:
Packit Service a721b1
   Initialization at run-time.  */
Packit Service a721b1
Packit Service a721b1
static struct expression plvar;
Packit Service a721b1
static struct expression plone;
Packit Service a721b1
struct expression GERMANIC_PLURAL;
Packit Service a721b1
Packit Service a721b1
static void
Packit Service a721b1
init_germanic_plural ()
Packit Service a721b1
{
Packit Service a721b1
  if (plone.val.num == 0)
Packit Service a721b1
    {
Packit Service a721b1
      plvar.nargs = 0;
Packit Service a721b1
      plvar.operation = var;
Packit Service a721b1
Packit Service a721b1
      plone.nargs = 0;
Packit Service a721b1
      plone.operation = num;
Packit Service a721b1
      plone.val.num = 1;
Packit Service a721b1
Packit Service a721b1
      GERMANIC_PLURAL.nargs = 2;
Packit Service a721b1
      GERMANIC_PLURAL.operation = not_equal;
Packit Service a721b1
      GERMANIC_PLURAL.val.args[0] = &plvar;
Packit Service a721b1
      GERMANIC_PLURAL.val.args[1] = &plone;
Packit Service a721b1
    }
Packit Service a721b1
}
Packit Service a721b1
Packit Service a721b1
# define INIT_GERMANIC_PLURAL() init_germanic_plural ()
Packit Service a721b1
Packit Service a721b1
#endif
Packit Service a721b1
Packit Service a721b1
void
Packit Service a721b1
internal_function
Packit Service a721b1
EXTRACT_PLURAL_EXPRESSION (const char *nullentry,
Packit Service a721b1
			   const struct expression **pluralp,
Packit Service a721b1
			   unsigned long int *npluralsp)
Packit Service a721b1
{
Packit Service a721b1
  if (nullentry != NULL)
Packit Service a721b1
    {
Packit Service a721b1
      const char *plural;
Packit Service a721b1
      const char *nplurals;
Packit Service a721b1
Packit Service a721b1
      plural = strstr (nullentry, "plural=");
Packit Service a721b1
      nplurals = strstr (nullentry, "nplurals=");
Packit Service a721b1
      if (plural == NULL || nplurals == NULL)
Packit Service a721b1
	goto no_plural;
Packit Service a721b1
      else
Packit Service a721b1
	{
Packit Service a721b1
	  char *endp;
Packit Service a721b1
	  unsigned long int n;
Packit Service a721b1
	  struct parse_args args;
Packit Service a721b1
Packit Service a721b1
	  /* First get the number.  */
Packit Service a721b1
	  nplurals += 9;
Packit Service a721b1
	  while (*nplurals != '\0' && isspace ((unsigned char) *nplurals))
Packit Service a721b1
	    ++nplurals;
Packit Service a721b1
	  if (!(*nplurals >= '0' && *nplurals <= '9'))
Packit Service a721b1
	    goto no_plural;
Packit Service a721b1
#if defined HAVE_STRTOUL || defined _LIBC
Packit Service a721b1
	  n = strtoul (nplurals, &endp, 10);
Packit Service a721b1
#else
Packit Service a721b1
	  for (endp = nplurals, n = 0; *endp >= '0' && *endp <= '9'; endp++)
Packit Service a721b1
	    n = n * 10 + (*endp - '0');
Packit Service a721b1
#endif
Packit Service a721b1
	  if (nplurals == endp)
Packit Service a721b1
	    goto no_plural;
Packit Service a721b1
	  *npluralsp = n;
Packit Service a721b1
Packit Service a721b1
	  /* Due to the restrictions bison imposes onto the interface of the
Packit Service a721b1
	     scanner function we have to put the input string and the result
Packit Service a721b1
	     passed up from the parser into the same structure which address
Packit Service a721b1
	     is passed down to the parser.  */
Packit Service a721b1
	  plural += 7;
Packit Service a721b1
	  args.cp = plural;
Packit Service a721b1
	  if (PLURAL_PARSE (&args) != 0)
Packit Service a721b1
	    goto no_plural;
Packit Service a721b1
	  *pluralp = args.res;
Packit Service a721b1
	}
Packit Service a721b1
    }
Packit Service a721b1
  else
Packit Service a721b1
    {
Packit Service a721b1
      /* By default we are using the Germanic form: singular form only
Packit Service a721b1
         for `one', the plural form otherwise.  Yes, this is also what
Packit Service a721b1
         English is using since English is a Germanic language.  */
Packit Service a721b1
    no_plural:
Packit Service a721b1
      INIT_GERMANIC_PLURAL ();
Packit Service a721b1
      *pluralp = &GERMANIC_PLURAL;
Packit Service a721b1
      *npluralsp = 2;
Packit Service a721b1
    }
Packit Service a721b1
}