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