xref: /netbsd-src/external/gpl2/texinfo/dist/intl/eval-plural.h (revision 29619d2afe564e54d657b83e5a3ae89584f83720)
1*29619d2aSchristos /*	$NetBSD: eval-plural.h,v 1.1.1.1 2016/01/14 00:11:27 christos Exp $	*/
2*29619d2aSchristos 
3*29619d2aSchristos /* Plural expression evaluation.
4*29619d2aSchristos    Copyright (C) 2000-2003 Free Software Foundation, Inc.
5*29619d2aSchristos 
6*29619d2aSchristos    This program is free software; you can redistribute it and/or modify it
7*29619d2aSchristos    under the terms of the GNU Library General Public License as published
8*29619d2aSchristos    by the Free Software Foundation; either version 2, or (at your option)
9*29619d2aSchristos    any later version.
10*29619d2aSchristos 
11*29619d2aSchristos    This program is distributed in the hope that it will be useful,
12*29619d2aSchristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
13*29619d2aSchristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14*29619d2aSchristos    Library General Public License for more details.
15*29619d2aSchristos 
16*29619d2aSchristos    You should have received a copy of the GNU Library General Public
17*29619d2aSchristos    License along with this program; if not, write to the Free Software
18*29619d2aSchristos    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
19*29619d2aSchristos    USA.  */
20*29619d2aSchristos 
21*29619d2aSchristos #ifndef STATIC
22*29619d2aSchristos #define STATIC static
23*29619d2aSchristos #endif
24*29619d2aSchristos 
25*29619d2aSchristos /* Evaluate the plural expression and return an index value.  */
26*29619d2aSchristos STATIC
27*29619d2aSchristos unsigned long int
28*29619d2aSchristos internal_function
plural_eval(struct expression * pexp,unsigned long int n)29*29619d2aSchristos plural_eval (struct expression *pexp, unsigned long int n)
30*29619d2aSchristos {
31*29619d2aSchristos   switch (pexp->nargs)
32*29619d2aSchristos     {
33*29619d2aSchristos     case 0:
34*29619d2aSchristos       switch (pexp->operation)
35*29619d2aSchristos 	{
36*29619d2aSchristos 	case var:
37*29619d2aSchristos 	  return n;
38*29619d2aSchristos 	case num:
39*29619d2aSchristos 	  return pexp->val.num;
40*29619d2aSchristos 	default:
41*29619d2aSchristos 	  break;
42*29619d2aSchristos 	}
43*29619d2aSchristos       /* NOTREACHED */
44*29619d2aSchristos       break;
45*29619d2aSchristos     case 1:
46*29619d2aSchristos       {
47*29619d2aSchristos 	/* pexp->operation must be lnot.  */
48*29619d2aSchristos 	unsigned long int arg = plural_eval (pexp->val.args[0], n);
49*29619d2aSchristos 	return ! arg;
50*29619d2aSchristos       }
51*29619d2aSchristos     case 2:
52*29619d2aSchristos       {
53*29619d2aSchristos 	unsigned long int leftarg = plural_eval (pexp->val.args[0], n);
54*29619d2aSchristos 	if (pexp->operation == lor)
55*29619d2aSchristos 	  return leftarg || plural_eval (pexp->val.args[1], n);
56*29619d2aSchristos 	else if (pexp->operation == land)
57*29619d2aSchristos 	  return leftarg && plural_eval (pexp->val.args[1], n);
58*29619d2aSchristos 	else
59*29619d2aSchristos 	  {
60*29619d2aSchristos 	    unsigned long int rightarg = plural_eval (pexp->val.args[1], n);
61*29619d2aSchristos 
62*29619d2aSchristos 	    switch (pexp->operation)
63*29619d2aSchristos 	      {
64*29619d2aSchristos 	      case mult:
65*29619d2aSchristos 		return leftarg * rightarg;
66*29619d2aSchristos 	      case divide:
67*29619d2aSchristos #if !INTDIV0_RAISES_SIGFPE
68*29619d2aSchristos 		if (rightarg == 0)
69*29619d2aSchristos 		  raise (SIGFPE);
70*29619d2aSchristos #endif
71*29619d2aSchristos 		return leftarg / rightarg;
72*29619d2aSchristos 	      case module:
73*29619d2aSchristos #if !INTDIV0_RAISES_SIGFPE
74*29619d2aSchristos 		if (rightarg == 0)
75*29619d2aSchristos 		  raise (SIGFPE);
76*29619d2aSchristos #endif
77*29619d2aSchristos 		return leftarg % rightarg;
78*29619d2aSchristos 	      case plus:
79*29619d2aSchristos 		return leftarg + rightarg;
80*29619d2aSchristos 	      case minus:
81*29619d2aSchristos 		return leftarg - rightarg;
82*29619d2aSchristos 	      case less_than:
83*29619d2aSchristos 		return leftarg < rightarg;
84*29619d2aSchristos 	      case greater_than:
85*29619d2aSchristos 		return leftarg > rightarg;
86*29619d2aSchristos 	      case less_or_equal:
87*29619d2aSchristos 		return leftarg <= rightarg;
88*29619d2aSchristos 	      case greater_or_equal:
89*29619d2aSchristos 		return leftarg >= rightarg;
90*29619d2aSchristos 	      case equal:
91*29619d2aSchristos 		return leftarg == rightarg;
92*29619d2aSchristos 	      case not_equal:
93*29619d2aSchristos 		return leftarg != rightarg;
94*29619d2aSchristos 	      default:
95*29619d2aSchristos 		break;
96*29619d2aSchristos 	      }
97*29619d2aSchristos 	  }
98*29619d2aSchristos 	/* NOTREACHED */
99*29619d2aSchristos 	break;
100*29619d2aSchristos       }
101*29619d2aSchristos     case 3:
102*29619d2aSchristos       {
103*29619d2aSchristos 	/* pexp->operation must be qmop.  */
104*29619d2aSchristos 	unsigned long int boolarg = plural_eval (pexp->val.args[0], n);
105*29619d2aSchristos 	return plural_eval (pexp->val.args[boolarg ? 1 : 2], n);
106*29619d2aSchristos       }
107*29619d2aSchristos     }
108*29619d2aSchristos   /* NOTREACHED */
109*29619d2aSchristos   return 0;
110*29619d2aSchristos }
111