Blame intl/eval-plural.h

Packit 6c4009
/* Plural expression evaluation.
Packit 6c4009
   Copyright (C) 2000-2018 Free Software Foundation, Inc.
Packit 6c4009
Packit 6c4009
   This program is free software: you can redistribute it and/or modify
Packit 6c4009
   it under the terms of the GNU Lesser General Public License as published by
Packit 6c4009
   the Free Software Foundation; either version 2.1 of the License, or
Packit 6c4009
   (at your option) any later version.
Packit 6c4009
Packit 6c4009
   This program is distributed in the hope that it will be useful,
Packit 6c4009
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 6c4009
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit 6c4009
   GNU Lesser General Public License for more details.
Packit 6c4009
Packit 6c4009
   You should have received a copy of the GNU Lesser General Public License
Packit 6c4009
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
Packit 6c4009
Packit 6c4009
#ifndef STATIC
Packit 6c4009
#define STATIC static
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
/* Evaluate the plural expression and return an index value.  */
Packit 6c4009
STATIC
Packit 6c4009
unsigned long int
Packit 6c4009
plural_eval (const struct expression *pexp, unsigned long int n)
Packit 6c4009
{
Packit 6c4009
  switch (pexp->nargs)
Packit 6c4009
    {
Packit 6c4009
    case 0:
Packit 6c4009
      switch (pexp->operation)
Packit 6c4009
	{
Packit 6c4009
	case var:
Packit 6c4009
	  return n;
Packit 6c4009
	case num:
Packit 6c4009
	  return pexp->val.num;
Packit 6c4009
	default:
Packit 6c4009
	  break;
Packit 6c4009
	}
Packit 6c4009
      /* NOTREACHED */
Packit 6c4009
      break;
Packit 6c4009
    case 1:
Packit 6c4009
      {
Packit 6c4009
	/* pexp->operation must be lnot.  */
Packit 6c4009
	unsigned long int arg = plural_eval (pexp->val.args[0], n);
Packit 6c4009
	return ! arg;
Packit 6c4009
      }
Packit 6c4009
    case 2:
Packit 6c4009
      {
Packit 6c4009
	unsigned long int leftarg = plural_eval (pexp->val.args[0], n);
Packit 6c4009
	if (pexp->operation == lor)
Packit 6c4009
	  return leftarg || plural_eval (pexp->val.args[1], n);
Packit 6c4009
	else if (pexp->operation == land)
Packit 6c4009
	  return leftarg && plural_eval (pexp->val.args[1], n);
Packit 6c4009
	else
Packit 6c4009
	  {
Packit 6c4009
	    unsigned long int rightarg = plural_eval (pexp->val.args[1], n);
Packit 6c4009
Packit 6c4009
	    switch (pexp->operation)
Packit 6c4009
	      {
Packit 6c4009
	      case mult:
Packit 6c4009
		return leftarg * rightarg;
Packit 6c4009
	      case divide:
Packit 6c4009
#if !INTDIV0_RAISES_SIGFPE
Packit 6c4009
		if (rightarg == 0)
Packit 6c4009
		  raise (SIGFPE);
Packit 6c4009
#endif
Packit 6c4009
		return leftarg / rightarg;
Packit 6c4009
	      case module:
Packit 6c4009
#if !INTDIV0_RAISES_SIGFPE
Packit 6c4009
		if (rightarg == 0)
Packit 6c4009
		  raise (SIGFPE);
Packit 6c4009
#endif
Packit 6c4009
		return leftarg % rightarg;
Packit 6c4009
	      case plus:
Packit 6c4009
		return leftarg + rightarg;
Packit 6c4009
	      case minus:
Packit 6c4009
		return leftarg - rightarg;
Packit 6c4009
	      case less_than:
Packit 6c4009
		return leftarg < rightarg;
Packit 6c4009
	      case greater_than:
Packit 6c4009
		return leftarg > rightarg;
Packit 6c4009
	      case less_or_equal:
Packit 6c4009
		return leftarg <= rightarg;
Packit 6c4009
	      case greater_or_equal:
Packit 6c4009
		return leftarg >= rightarg;
Packit 6c4009
	      case equal:
Packit 6c4009
		return leftarg == rightarg;
Packit 6c4009
	      case not_equal:
Packit 6c4009
		return leftarg != rightarg;
Packit 6c4009
	      default:
Packit 6c4009
		break;
Packit 6c4009
	      }
Packit 6c4009
	  }
Packit 6c4009
	/* NOTREACHED */
Packit 6c4009
	break;
Packit 6c4009
      }
Packit 6c4009
    case 3:
Packit 6c4009
      {
Packit 6c4009
	/* pexp->operation must be qmop.  */
Packit 6c4009
	unsigned long int boolarg = plural_eval (pexp->val.args[0], n);
Packit 6c4009
	return plural_eval (pexp->val.args[boolarg ? 1 : 2], n);
Packit 6c4009
      }
Packit 6c4009
    }
Packit 6c4009
  /* NOTREACHED */
Packit 6c4009
  return 0;
Packit 6c4009
}