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