1*63eb84d1Schristos /* Expression parsing and evaluation for plural form selection.
2*63eb84d1Schristos    Copyright (C) 2000-2003, 2005 Free Software Foundation, Inc.
3*63eb84d1Schristos    Written by Ulrich Drepper <drepper@cygnus.com>, 2000.
4*63eb84d1Schristos 
5*63eb84d1Schristos    This program is free software; you can redistribute it and/or modify it
6*63eb84d1Schristos    under the terms of the GNU Library General Public License as published
7*63eb84d1Schristos    by the Free Software Foundation; either version 2, or (at your option)
8*63eb84d1Schristos    any later version.
9*63eb84d1Schristos 
10*63eb84d1Schristos    This program is distributed in the hope that it will be useful,
11*63eb84d1Schristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
12*63eb84d1Schristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13*63eb84d1Schristos    Library General Public License for more details.
14*63eb84d1Schristos 
15*63eb84d1Schristos    You should have received a copy of the GNU Library General Public
16*63eb84d1Schristos    License along with this program; if not, write to the Free Software
17*63eb84d1Schristos    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
18*63eb84d1Schristos    USA.  */
19*63eb84d1Schristos 
20*63eb84d1Schristos #ifndef _PLURAL_EXP_H
21*63eb84d1Schristos #define _PLURAL_EXP_H
22*63eb84d1Schristos 
23*63eb84d1Schristos #ifndef internal_function
24*63eb84d1Schristos # define internal_function
25*63eb84d1Schristos #endif
26*63eb84d1Schristos 
27*63eb84d1Schristos #ifndef attribute_hidden
28*63eb84d1Schristos # define attribute_hidden
29*63eb84d1Schristos #endif
30*63eb84d1Schristos 
31*63eb84d1Schristos 
32*63eb84d1Schristos /* This is the representation of the expressions to determine the
33*63eb84d1Schristos    plural form.  */
34*63eb84d1Schristos struct expression
35*63eb84d1Schristos {
36*63eb84d1Schristos   int nargs;			/* Number of arguments.  */
37*63eb84d1Schristos   enum operator
38*63eb84d1Schristos   {
39*63eb84d1Schristos     /* Without arguments:  */
40*63eb84d1Schristos     var,			/* The variable "n".  */
41*63eb84d1Schristos     num,			/* Decimal number.  */
42*63eb84d1Schristos     /* Unary operators:  */
43*63eb84d1Schristos     lnot,			/* Logical NOT.  */
44*63eb84d1Schristos     /* Binary operators:  */
45*63eb84d1Schristos     mult,			/* Multiplication.  */
46*63eb84d1Schristos     divide,			/* Division.  */
47*63eb84d1Schristos     module,			/* Modulo operation.  */
48*63eb84d1Schristos     plus,			/* Addition.  */
49*63eb84d1Schristos     minus,			/* Subtraction.  */
50*63eb84d1Schristos     less_than,			/* Comparison.  */
51*63eb84d1Schristos     greater_than,		/* Comparison.  */
52*63eb84d1Schristos     less_or_equal,		/* Comparison.  */
53*63eb84d1Schristos     greater_or_equal,		/* Comparison.  */
54*63eb84d1Schristos     equal,			/* Comparison for equality.  */
55*63eb84d1Schristos     not_equal,			/* Comparison for inequality.  */
56*63eb84d1Schristos     land,			/* Logical AND.  */
57*63eb84d1Schristos     lor,			/* Logical OR.  */
58*63eb84d1Schristos     /* Ternary operators:  */
59*63eb84d1Schristos     qmop			/* Question mark operator.  */
60*63eb84d1Schristos   } operation;
61*63eb84d1Schristos   union
62*63eb84d1Schristos   {
63*63eb84d1Schristos     unsigned long int num;	/* Number value for `num'.  */
64*63eb84d1Schristos     struct expression *args[3];	/* Up to three arguments.  */
65*63eb84d1Schristos   } val;
66*63eb84d1Schristos };
67*63eb84d1Schristos 
68*63eb84d1Schristos /* This is the data structure to pass information to the parser and get
69*63eb84d1Schristos    the result in a thread-safe way.  */
70*63eb84d1Schristos struct parse_args
71*63eb84d1Schristos {
72*63eb84d1Schristos   const char *cp;
73*63eb84d1Schristos   struct expression *res;
74*63eb84d1Schristos };
75*63eb84d1Schristos 
76*63eb84d1Schristos 
77*63eb84d1Schristos /* Names for the libintl functions are a problem.  This source code is used
78*63eb84d1Schristos    1. in the GNU C Library library,
79*63eb84d1Schristos    2. in the GNU libintl library,
80*63eb84d1Schristos    3. in the GNU gettext tools.
81*63eb84d1Schristos    The function names in each situation must be different, to allow for
82*63eb84d1Schristos    binary incompatible changes in 'struct expression'.  Furthermore,
83*63eb84d1Schristos    1. in the GNU C Library library, the names have a __ prefix,
84*63eb84d1Schristos    2.+3. in the GNU libintl library and in the GNU gettext tools, the names
85*63eb84d1Schristos          must follow ANSI C and not start with __.
86*63eb84d1Schristos    So we have to distinguish the three cases.  */
87*63eb84d1Schristos #ifdef _LIBC
88*63eb84d1Schristos # define FREE_EXPRESSION __gettext_free_exp
89*63eb84d1Schristos # define PLURAL_PARSE __gettextparse
90*63eb84d1Schristos # define GERMANIC_PLURAL __gettext_germanic_plural
91*63eb84d1Schristos # define EXTRACT_PLURAL_EXPRESSION __gettext_extract_plural
92*63eb84d1Schristos #elif defined (IN_LIBINTL)
93*63eb84d1Schristos # define FREE_EXPRESSION libintl_gettext_free_exp
94*63eb84d1Schristos # define PLURAL_PARSE libintl_gettextparse
95*63eb84d1Schristos # define GERMANIC_PLURAL libintl_gettext_germanic_plural
96*63eb84d1Schristos # define EXTRACT_PLURAL_EXPRESSION libintl_gettext_extract_plural
97*63eb84d1Schristos #else
98*63eb84d1Schristos # define FREE_EXPRESSION free_plural_expression
99*63eb84d1Schristos # define PLURAL_PARSE parse_plural_expression
100*63eb84d1Schristos # define GERMANIC_PLURAL germanic_plural
101*63eb84d1Schristos # define EXTRACT_PLURAL_EXPRESSION extract_plural_expression
102*63eb84d1Schristos #endif
103*63eb84d1Schristos 
104*63eb84d1Schristos extern void FREE_EXPRESSION (struct expression *exp)
105*63eb84d1Schristos      internal_function;
106*63eb84d1Schristos extern int PLURAL_PARSE (void *arg);
107*63eb84d1Schristos extern struct expression GERMANIC_PLURAL attribute_hidden;
108*63eb84d1Schristos extern void EXTRACT_PLURAL_EXPRESSION (const char *nullentry,
109*63eb84d1Schristos 				       struct expression **pluralp,
110*63eb84d1Schristos 				       unsigned long int *npluralsp)
111*63eb84d1Schristos      internal_function;
112*63eb84d1Schristos 
113*63eb84d1Schristos #if !defined (_LIBC) && !defined (IN_LIBINTL) && !defined (IN_LIBGLOCALE)
114*63eb84d1Schristos extern unsigned long int plural_eval (struct expression *pexp,
115*63eb84d1Schristos 				      unsigned long int n);
116*63eb84d1Schristos #endif
117*63eb84d1Schristos 
118*63eb84d1Schristos #endif /* _PLURAL_EXP_H */
119