| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108 | /* Plural expression evaluation.   Copyright (C) 2000-2003, 2007 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.  */STATICunsigned long intinternal_functionplural_eval (const 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;}
 |