* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
* This code is derived from software contributed to Berkeley by
* Ozan Yigit at York University.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
static char sccsid
[] = "@(#)expr.c 8.2 (Berkeley) 4/29/95";
* expression evaluator: performs a standard recursive
* descent parse to evaluate any expression permissible
* within the following grammar:
* | lor "?" query ":" query
* lor : land { "||" land }
* land : not { "&&" not }
* eqrel : shift { eqrelop shift }
* shift : primary { shop primary }
* primary : term { addop term }
* term : exp { mulop exp }
* exp : unary { expop unary }
* This expression evaluator is lifted from a public-domain
* C Pre-Processor included with the DECUS C Compiler distribution.
* It is hacked somewhat to be suitable for m4.
* Originally by: Mike Lutz
static char *nxtch
; /* Parser scan pointer */
static int query
__P((void));
static int lor
__P((void));
static int land
__P((void));
static int not __P((void));
static int eqrel
__P((void));
static int shift
__P((void));
static int primary
__P((void));
static int term
__P((void));
static int exp
__P((void));
static int unary
__P((void));
static int factor
__P((void));
static int constant
__P((void));
static int num
__P((void));
static int geteqrel
__P((void));
static int skipws
__P((void));
static void experr
__P((char *));
* ungetch - Put back the last character examined.
* getch - return the next character from expr string.
#define ungetch() nxtch--
if (setjmp(expjump
) != 0)
printf("m4: ill-formed expression.\n");
* query : lor | lor '?' query ':' query
register int bool, true_val
, false_val
;
return bool ? true_val
: false_val
;
* lor : land { '||' land }
while ((c
= skipws()) == '|') {
* land : not { '&&' not }
while ((c
= skipws()) == '&') {
if ((c
= skipws()) == '!' && getch() != '=') {
* eqrel : shift { eqrelop shift }
register int vl
, vr
, eqrel
;
while ((eqrel
= geteqrel()) != -1) {
* shift : primary { shop primary }
while (((c
= skipws()) == '<' || c
== '>') && getch() == c
) {
if (c
== '<' || c
== '>')
* primary : term { addop term }
while ((c
= skipws()) == '+' || c
== '-') {
* <term> := <exp> { <mulop> <exp> }
while ((c
= skipws()) == '*' || c
== '/' || c
== '%') {
* <term> := <unary> { <expop> <unary> }
* unary : factor | unop unary
if ((c
= skipws()) == '+' || c
== '-' || c
== '~') {
* factor : constant | '(' query ')'
* Note: constant() handles multi-byte constants
for (i
= 0; i
< sizeof(int); i
++) {
if ((c
= getch()) == '\'') {
if (i
== 0 || getch() != '\'')
experr("illegal character constant");
for (value
= 0; --i
>= 0;) {
* num : digit | num digit
register int rval
, c
, base
;
base
= ((c
= skipws()) == '0') ? OCTAL
: DECIMAL
;
while (c
>= '0' && c
<= (base
== OCTAL
? '7' : '9')) {
* eqrel : '=' | '==' | '!=' | '<' | '>' | '<=' | '>='
* Skip over any white space and return terminating char.
while ((c
= getch()) <= ' ' && c
> EOS
)
* resets environment to eval(), prints an error
* and forces eval to return FALSE.
printf("m4: %s in expr.\n", msg
);