Deleted Added
full compact
expr.c (92921) expr.c (95060)
1/* $OpenBSD: expr.c,v 1.12 2002/02/16 21:27:48 millert Exp $ */
2/* $NetBSD: expr.c,v 1.7 1995/09/28 05:37:31 tls Exp $ */
3
1/*
2 * Copyright (c) 1989, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Ozan Yigit at York University.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 18 unchanged lines hidden (view full) ---

27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
4/*
5 * Copyright (c) 1989, 1993
6 * The Regents of the University of California. All rights reserved.
7 *
8 * This code is derived from software contributed to Berkeley by
9 * Ozan Yigit at York University.
10 *
11 * Redistribution and use in source and binary forms, with or without

--- 18 unchanged lines hidden (view full) ---

30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 * SUCH DAMAGE.
35 *
36 * $FreeBSD: head/usr.bin/m4/expr.c 92921 2002-03-22 01:33:25Z imp $
37 */
38
38 */
39
39#ifndef lint
40static char sccsid[] = "@(#)expr.c 8.1 (Berkeley) 6/6/93";
41#endif /* not lint */
42
43#include <sys/cdefs.h>
40#include <sys/cdefs.h>
41__SCCSID("@(#)expr.c 8.2 (Berkeley) 4/29/95");
42__RCSID_SOURCE("$OpenBSD: expr.c,v 1.12 2002/02/16 21:27:48 millert Exp $");
43__FBSDID("$FreeBSD: head/usr.bin/m4/expr.c 95060 2002-04-19 17:26:21Z jmallett $");
44
45#include <sys/types.h>
46#include <ctype.h>
47#include <err.h>
48#include <stddef.h>
44#include <stdio.h>
49#include <stdio.h>
50#include "mdef.h"
51#include "extern.h"
45
46/*
47 * expression evaluator: performs a standard recursive
48 * descent parse to evaluate any expression permissible
49 * within the following grammar:
50 *
51 * expr : query EOS
52 * query : lor

--- 29 unchanged lines hidden (view full) ---

82 * This expression evaluator is lifted from a public-domain
83 * C Pre-Processor included with the DECUS C Compiler distribution.
84 * It is hacked somewhat to be suitable for m4.
85 *
86 * Originally by: Mike Lutz
87 * Bob Harper
88 */
89
52
53/*
54 * expression evaluator: performs a standard recursive
55 * descent parse to evaluate any expression permissible
56 * within the following grammar:
57 *
58 * expr : query EOS
59 * query : lor

--- 29 unchanged lines hidden (view full) ---

89 * This expression evaluator is lifted from a public-domain
90 * C Pre-Processor included with the DECUS C Compiler distribution.
91 * It is hacked somewhat to be suitable for m4.
92 *
93 * Originally by: Mike Lutz
94 * Bob Harper
95 */
96
90#define TRUE 1
91#define FALSE 0
92#define EOS (char) 0
93#define EQL 0
94#define NEQ 1
95#define LSS 2
96#define LEQ 3
97#define GTR 4
98#define GEQ 5
99#define OCTAL 8
100#define DECIMAL 10
97#define EQL 0
98#define NEQ 1
99#define LSS 2
100#define LEQ 3
101#define GTR 4
102#define GEQ 5
103#define OCTAL 8
104#define DECIMAL 10
105#define HEX 16
101
106
102static char *nxtch; /* Parser scan pointer */
107static const char *nxtch; /* Parser scan pointer */
108static const char *where;
103
104static int query(void);
105static int lor(void);
106static int land(void);
107static int not(void);
108static int eqrel(void);
109static int shift(void);
110static int primary(void);
111static int term(void);
112static int exp(void);
113static int unary(void);
114static int factor(void);
115static int constant(void);
116static int num(void);
117static int geteqrel(void);
118static int skipws(void);
109
110static int query(void);
111static int lor(void);
112static int land(void);
113static int not(void);
114static int eqrel(void);
115static int shift(void);
116static int primary(void);
117static int term(void);
118static int exp(void);
119static int unary(void);
120static int factor(void);
121static int constant(void);
122static int num(void);
123static int geteqrel(void);
124static int skipws(void);
119static void experr(char *);
125static void experr(const char *);
120
121/*
122 * For longjmp
123 */
124#include <setjmp.h>
125static jmp_buf expjump;
126
127/*
128 * macros:
129 * ungetch - Put back the last character examined.
130 * getch - return the next character from expr string.
131 */
132#define ungetch() nxtch--
133#define getch() *nxtch++
134
135int
136expr(expbuf)
126
127/*
128 * For longjmp
129 */
130#include <setjmp.h>
131static jmp_buf expjump;
132
133/*
134 * macros:
135 * ungetch - Put back the last character examined.
136 * getch - return the next character from expr string.
137 */
138#define ungetch() nxtch--
139#define getch() *nxtch++
140
141int
142expr(expbuf)
137char *expbuf;
143 const char *expbuf;
138{
144{
139 register int rval;
145 int rval;
140
141 nxtch = expbuf;
146
147 nxtch = expbuf;
148 where = expbuf;
142 if (setjmp(expjump) != 0)
143 return FALSE;
144
145 rval = query();
146 if (skipws() == EOS)
147 return rval;
148
149 printf("m4: ill-formed expression.\n");
150 return FALSE;
151}
152
153/*
154 * query : lor | lor '?' query ':' query
155 */
156static int
157query()
158{
149 if (setjmp(expjump) != 0)
150 return FALSE;
151
152 rval = query();
153 if (skipws() == EOS)
154 return rval;
155
156 printf("m4: ill-formed expression.\n");
157 return FALSE;
158}
159
160/*
161 * query : lor | lor '?' query ':' query
162 */
163static int
164query()
165{
159 register int bool, true_val, false_val;
166 int bool, true_val, false_val;
160
161 bool = lor();
162 if (skipws() != '?') {
163 ungetch();
164 return bool;
165 }
166
167 true_val = query();

--- 5 unchanged lines hidden (view full) ---

173}
174
175/*
176 * lor : land { '||' land }
177 */
178static int
179lor()
180{
167
168 bool = lor();
169 if (skipws() != '?') {
170 ungetch();
171 return bool;
172 }
173
174 true_val = query();

--- 5 unchanged lines hidden (view full) ---

180}
181
182/*
183 * lor : land { '||' land }
184 */
185static int
186lor()
187{
181 register int c, vl, vr;
188 int c, vl, vr;
182
183 vl = land();
184 while ((c = skipws()) == '|') {
185 if (getch() != '|')
186 ungetch();
187 vr = land();
188 vl = vl || vr;
189 }
190
191 ungetch();
192 return vl;
193}
194
195/*
196 * land : not { '&&' not }
197 */
198static int
199land()
200{
189
190 vl = land();
191 while ((c = skipws()) == '|') {
192 if (getch() != '|')
193 ungetch();
194 vr = land();
195 vl = vl || vr;
196 }
197
198 ungetch();
199 return vl;
200}
201
202/*
203 * land : not { '&&' not }
204 */
205static int
206land()
207{
201 register int c, vl, vr;
208 int c, vl, vr;
202
203 vl = not();
204 while ((c = skipws()) == '&') {
205 if (getch() != '&')
206 ungetch();
207 vr = not();
208 vl = vl && vr;
209 }
210
211 ungetch();
212 return vl;
213}
214
215/*
216 * not : eqrel | '!' not
217 */
218static int
219not()
220{
209
210 vl = not();
211 while ((c = skipws()) == '&') {
212 if (getch() != '&')
213 ungetch();
214 vr = not();
215 vl = vl && vr;
216 }
217
218 ungetch();
219 return vl;
220}
221
222/*
223 * not : eqrel | '!' not
224 */
225static int
226not()
227{
221 register int val, c;
228 int val, c;
222
223 if ((c = skipws()) == '!' && getch() != '=') {
224 ungetch();
225 val = not();
226 return !val;
227 }
228
229 if (c == '!')
230 ungetch();
231 ungetch();
232 return eqrel();
233}
234
235/*
236 * eqrel : shift { eqrelop shift }
237 */
238static int
239eqrel()
240{
229
230 if ((c = skipws()) == '!' && getch() != '=') {
231 ungetch();
232 val = not();
233 return !val;
234 }
235
236 if (c == '!')
237 ungetch();
238 ungetch();
239 return eqrel();
240}
241
242/*
243 * eqrel : shift { eqrelop shift }
244 */
245static int
246eqrel()
247{
241 register int vl, vr, eqrel;
248 int vl, vr, eqrel;
242
243 vl = shift();
244 while ((eqrel = geteqrel()) != -1) {
245 vr = shift();
246
247 switch (eqrel) {
248
249 case EQL:

--- 21 unchanged lines hidden (view full) ---

271}
272
273/*
274 * shift : primary { shop primary }
275 */
276static int
277shift()
278{
249
250 vl = shift();
251 while ((eqrel = geteqrel()) != -1) {
252 vr = shift();
253
254 switch (eqrel) {
255
256 case EQL:

--- 21 unchanged lines hidden (view full) ---

278}
279
280/*
281 * shift : primary { shop primary }
282 */
283static int
284shift()
285{
279 register int vl, vr, c;
286 int vl, vr, c;
280
281 vl = primary();
282 while (((c = skipws()) == '<' || c == '>') && getch() == c) {
283 vr = primary();
284
285 if (c == '<')
286 vl <<= vr;
287 else

--- 7 unchanged lines hidden (view full) ---

295}
296
297/*
298 * primary : term { addop term }
299 */
300static int
301primary()
302{
287
288 vl = primary();
289 while (((c = skipws()) == '<' || c == '>') && getch() == c) {
290 vr = primary();
291
292 if (c == '<')
293 vl <<= vr;
294 else

--- 7 unchanged lines hidden (view full) ---

302}
303
304/*
305 * primary : term { addop term }
306 */
307static int
308primary()
309{
303 register int c, vl, vr;
310 int c, vl, vr;
304
305 vl = term();
306 while ((c = skipws()) == '+' || c == '-') {
307 vr = term();
308
309 if (c == '+')
310 vl += vr;
311 else

--- 5 unchanged lines hidden (view full) ---

317}
318
319/*
320 * <term> := <exp> { <mulop> <exp> }
321 */
322static int
323term()
324{
311
312 vl = term();
313 while ((c = skipws()) == '+' || c == '-') {
314 vr = term();
315
316 if (c == '+')
317 vl += vr;
318 else

--- 5 unchanged lines hidden (view full) ---

324}
325
326/*
327 * <term> := <exp> { <mulop> <exp> }
328 */
329static int
330term()
331{
325 register int c, vl, vr;
332 int c, vl, vr;
326
327 vl = exp();
328 while ((c = skipws()) == '*' || c == '/' || c == '%') {
329 vr = exp();
330
331 switch (c) {
332 case '*':
333 vl *= vr;
334 break;
335 case '/':
333
334 vl = exp();
335 while ((c = skipws()) == '*' || c == '/' || c == '%') {
336 vr = exp();
337
338 switch (c) {
339 case '*':
340 vl *= vr;
341 break;
342 case '/':
336 vl /= vr;
343 if (vr == 0)
344 errx(1, "division by zero in eval.");
345 else
346 vl /= vr;
337 break;
338 case '%':
347 break;
348 case '%':
339 vl %= vr;
349 if (vr == 0)
350 errx(1, "modulo zero in eval.");
351 else
352 vl %= vr;
340 break;
341 }
342 }
343 ungetch();
344 return vl;
345}
346
347/*
348 * <term> := <unary> { <expop> <unary> }
349 */
350static int
351exp()
352{
353 break;
354 }
355 }
356 ungetch();
357 return vl;
358}
359
360/*
361 * <term> := <unary> { <expop> <unary> }
362 */
363static int
364exp()
365{
353 register c, vl, vr, n;
366 int c, vl, vr, n;
354
355 vl = unary();
356 switch (c = skipws()) {
357
358 case '*':
359 if (getch() != '*') {
360 ungetch();
361 break;

--- 12 unchanged lines hidden (view full) ---

374}
375
376/*
377 * unary : factor | unop unary
378 */
379static int
380unary()
381{
367
368 vl = unary();
369 switch (c = skipws()) {
370
371 case '*':
372 if (getch() != '*') {
373 ungetch();
374 break;

--- 12 unchanged lines hidden (view full) ---

387}
388
389/*
390 * unary : factor | unop unary
391 */
392static int
393unary()
394{
382 register int val, c;
395 int val, c;
383
384 if ((c = skipws()) == '+' || c == '-' || c == '~') {
385 val = unary();
386
387 switch (c) {
388 case '+':
389 return val;
390 case '-':

--- 8 unchanged lines hidden (view full) ---

399}
400
401/*
402 * factor : constant | '(' query ')'
403 */
404static int
405factor()
406{
396
397 if ((c = skipws()) == '+' || c == '-' || c == '~') {
398 val = unary();
399
400 switch (c) {
401 case '+':
402 return val;
403 case '-':

--- 8 unchanged lines hidden (view full) ---

412}
413
414/*
415 * factor : constant | '(' query ')'
416 */
417static int
418factor()
419{
407 register int val;
420 int val;
408
409 if (skipws() == '(') {
410 val = query();
411 if (skipws() != ')')
412 experr("bad factor");
413 return val;
414 }
415
416 ungetch();
417 return constant();
418}
419
420/*
421 * constant: num | 'char'
422 * Note: constant() handles multi-byte constants
423 */
424static int
425constant()
426{
421
422 if (skipws() == '(') {
423 val = query();
424 if (skipws() != ')')
425 experr("bad factor");
426 return val;
427 }
428
429 ungetch();
430 return constant();
431}
432
433/*
434 * constant: num | 'char'
435 * Note: constant() handles multi-byte constants
436 */
437static int
438constant()
439{
427 register int i;
428 register int value;
429 register char c;
440 int i;
441 int value;
442 int c;
430 int v[sizeof(int)];
431
432 if (skipws() != '\'') {
433 ungetch();
434 return num();
435 }
436 for (i = 0; i < sizeof(int); i++) {
437 if ((c = getch()) == '\'') {

--- 42 unchanged lines hidden (view full) ---

480}
481
482/*
483 * num : digit | num digit
484 */
485static int
486num()
487{
443 int v[sizeof(int)];
444
445 if (skipws() != '\'') {
446 ungetch();
447 return num();
448 }
449 for (i = 0; i < sizeof(int); i++) {
450 if ((c = getch()) == '\'') {

--- 42 unchanged lines hidden (view full) ---

493}
494
495/*
496 * num : digit | num digit
497 */
498static int
499num()
500{
488 register int rval, c, base;
501 int rval, c, base;
489 int ndig;
490
502 int ndig;
503
491 base = ((c = skipws()) == '0') ? OCTAL : DECIMAL;
492 rval = 0;
493 ndig = 0;
504 rval = 0;
505 ndig = 0;
494 while (c >= '0' && c <= (base == OCTAL ? '7' : '9')) {
495 rval *= base;
496 rval += (c - '0');
506 c = skipws();
507 if (c == '0') {
508 c = skipws();
509 if (c == 'x' || c == 'X') {
510 base = HEX;
511 c = skipws();
512 } else {
513 base = OCTAL;
514 ndig++;
515 }
516 } else
517 base = DECIMAL;
518 for(;;) {
519 switch(c) {
520 case '8': case '9':
521 if (base == OCTAL)
522 goto bad_digit;
523 /*FALLTHRU*/
524 case '0': case '1': case '2': case '3':
525 case '4': case '5': case '6': case '7':
526 rval *= base;
527 rval += c - '0';
528 break;
529 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
530 c = tolower(c);
531 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
532 if (base == HEX) {
533 rval *= base;
534 rval += c - 'a' + 10;
535 break;
536 }
537 /*FALLTHRU*/
538 default:
539 goto bad_digit;
540 }
497 c = getch();
498 ndig++;
499 }
541 c = getch();
542 ndig++;
543 }
544bad_digit:
500 ungetch();
545 ungetch();
501
546
502 if (ndig == 0)
503 experr("bad constant");
547 if (ndig == 0)
548 experr("bad constant");
504
549
505 return rval;
550 return rval;
506
507}
508
509/*
510 * eqrel : '=' | '==' | '!=' | '<' | '>' | '<=' | '>='
511 */
512static int
513geteqrel()
514{
551}
552
553/*
554 * eqrel : '=' | '==' | '!=' | '<' | '>' | '<=' | '>='
555 */
556static int
557geteqrel()
558{
515 register int c1, c2;
559 int c1, c2;
516
517 c1 = skipws();
518 c2 = getch();
519
520 switch (c1) {
521
522 case '=':
523 if (c2 != '=')

--- 27 unchanged lines hidden (view full) ---

551}
552
553/*
554 * Skip over any white space and return terminating char.
555 */
556static int
557skipws()
558{
560
561 c1 = skipws();
562 c2 = getch();
563
564 switch (c1) {
565
566 case '=':
567 if (c2 != '=')

--- 27 unchanged lines hidden (view full) ---

595}
596
597/*
598 * Skip over any white space and return terminating char.
599 */
600static int
601skipws()
602{
559 register char c;
603 int c;
560
561 while ((c = getch()) <= ' ' && c > EOS)
562 ;
563 return c;
564}
565
566/*
604
605 while ((c = getch()) <= ' ' && c > EOS)
606 ;
607 return c;
608}
609
610/*
567 * resets environment to eval(), prints an error
611 * resets environment to eval(), prints an error
568 * and forces eval to return FALSE.
569 */
570static void
571experr(msg)
612 * and forces eval to return FALSE.
613 */
614static void
615experr(msg)
572char *msg;
616 const char *msg;
573{
617{
574 printf("m4: %s in expr.\n", msg);
618 printf("m4: %s in expr %s.\n", msg, where);
575 longjmp(expjump, -1);
576}
619 longjmp(expjump, -1);
620}