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