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