|
|
1.1 root 1: /* Parse C expressions for CCCP.
2: Copyright (C) 1987, 1992, 1994, 1995 Free Software Foundation.
3:
4: This program is free software; you can redistribute it and/or modify it
5: under the terms of the GNU General Public License as published by the
6: Free Software Foundation; either version 2, or (at your option) any
7: later version.
8:
9: This program is distributed in the hope that it will be useful,
10: but WITHOUT ANY WARRANTY; without even the implied warranty of
11: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12: GNU General Public License for more details.
13:
14: You should have received a copy of the GNU General Public License
15: along with this program; if not, write to the Free Software
16: Foundation, 59 Temple Place - Suite 330,
17: Boston, MA 02111-1307, USA.
18:
19: In other words, you are welcome to use, share and improve this program.
20: You are forbidden to forbid anyone else to use, share and improve
21: what you give them. Help stamp out software-hoarding!
22:
23: Written by Per Bothner 1994. */
24:
25: /* Parse a C expression from text in a string */
26:
27: #include "config.h"
28: #include "cpplib.h"
29:
30: extern char *xmalloc PARAMS ((unsigned));
31: extern char *xrealloc PARAMS ((char *, unsigned));
32:
33: #ifdef MULTIBYTE_CHARS
34: #include <stdlib.h>
35: #include <locale.h>
36: #endif
37:
38: #include <stdio.h>
39:
40: /* This is used for communicating lists of keywords with cccp.c. */
41: struct arglist {
42: struct arglist *next;
43: U_CHAR *name;
44: int length;
45: int argno;
46: };
47:
48: /* Define a generic NULL if one hasn't already been defined. */
49:
50: #ifndef NULL
51: #define NULL 0
52: #endif
53:
54: #ifndef GENERIC_PTR
55: #if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__)
56: #define GENERIC_PTR void *
57: #else
58: #define GENERIC_PTR char *
59: #endif
60: #endif
61:
62: #ifndef NULL_PTR
63: #define NULL_PTR ((GENERIC_PTR)0)
64: #endif
65:
66: extern char *xmalloc ();
67:
68: #ifndef CHAR_TYPE_SIZE
69: #define CHAR_TYPE_SIZE BITS_PER_UNIT
70: #endif
71:
72: #ifndef INT_TYPE_SIZE
73: #define INT_TYPE_SIZE BITS_PER_WORD
74: #endif
75:
76: #ifndef LONG_TYPE_SIZE
77: #define LONG_TYPE_SIZE BITS_PER_WORD
78: #endif
79:
80: #ifndef WCHAR_TYPE_SIZE
81: #define WCHAR_TYPE_SIZE INT_TYPE_SIZE
82: #endif
83:
84: #ifndef MAX_CHAR_TYPE_SIZE
85: #define MAX_CHAR_TYPE_SIZE CHAR_TYPE_SIZE
86: #endif
87:
88: #ifndef MAX_INT_TYPE_SIZE
89: #define MAX_INT_TYPE_SIZE INT_TYPE_SIZE
90: #endif
91:
92: #ifndef MAX_LONG_TYPE_SIZE
93: #define MAX_LONG_TYPE_SIZE LONG_TYPE_SIZE
94: #endif
95:
96: #ifndef MAX_WCHAR_TYPE_SIZE
97: #define MAX_WCHAR_TYPE_SIZE WCHAR_TYPE_SIZE
98: #endif
99:
100: /* Yield nonzero if adding two numbers with A's and B's signs can yield a
101: number with SUM's sign, where A, B, and SUM are all C integers. */
102: #define possible_sum_sign(a, b, sum) ((((a) ^ (b)) | ~ ((a) ^ (sum))) < 0)
103:
104: static void integer_overflow ();
105: static long left_shift ();
106: static long right_shift ();
107:
108: #define ERROR 299
109: #define OROR 300
110: #define ANDAND 301
111: #define EQUAL 302
112: #define NOTEQUAL 303
113: #define LEQ 304
114: #define GEQ 305
115: #define LSH 306
116: #define RSH 307
117: #define NAME 308
118: #define INT 309
119: #define CHAR 310
120:
121: #define LEFT_OPERAND_REQUIRED 1
122: #define RIGHT_OPERAND_REQUIRED 2
123: #define HAVE_VALUE 4
124: /*#define UNSIGNEDP 8*/
125:
126: #ifndef HOST_BITS_PER_WIDE_INT
127:
128: #if HOST_BITS_PER_LONG > HOST_BITS_PER_INT
129: #define HOST_BITS_PER_WIDE_INT HOST_BITS_PER_LONG
130: #define HOST_WIDE_INT long
131: #else
132: #define HOST_BITS_PER_WIDE_INT HOST_BITS_PER_INT
133: #define HOST_WIDE_INT int
134: #endif
135:
136: #endif
137:
138: struct operation {
139: short op;
140: char rprio; /* Priority of op (relative to it right operand). */
141: char flags;
142: char unsignedp; /* true if value should be treated as unsigned */
143: HOST_WIDE_INT value; /* The value logically "right" of op. */
144: };
145:
146: /* Take care of parsing a number (anything that starts with a digit).
147: LEN is the number of characters in it. */
148:
149: /* maybe needs to actually deal with floating point numbers */
150:
151: struct operation
152: parse_number (pfile, start, olen)
153: cpp_reader *pfile;
154: char *start;
155: int olen;
156: {
157: struct operation op;
158: register char *p = start;
159: register int c;
160: register unsigned long n = 0, nd, ULONG_MAX_over_base;
161: register int base = 10;
162: register int len = olen;
163: register int overflow = 0;
164: register int digit, largest_digit = 0;
165: int spec_long = 0;
166:
167: op.unsignedp = 0;
168:
169: for (c = 0; c < len; c++)
170: if (p[c] == '.') {
171: /* It's a float since it contains a point. */
172: cpp_error (pfile,
173: "floating point numbers not allowed in #if expressions");
174: op.op = ERROR;
175: return op;
176: }
177:
178: if (len >= 3 && (!strncmp (p, "0x", 2) || !strncmp (p, "0X", 2))) {
179: p += 2;
180: base = 16;
181: len -= 2;
182: }
183: else if (*p == '0')
184: base = 8;
185:
186: /* Some buggy compilers (e.g. MPW C) seem to need both casts. */
187: ULONG_MAX_over_base = ((unsigned long) -1) / ((unsigned long) base);
188:
189: for (; len > 0; len--) {
190: c = *p++;
191:
192: if (c >= '0' && c <= '9')
193: digit = c - '0';
194: else if (base == 16 && c >= 'a' && c <= 'f')
195: digit = c - 'a' + 10;
196: else if (base == 16 && c >= 'A' && c <= 'F')
197: digit = c - 'A' + 10;
198: else {
199: /* `l' means long, and `u' means unsigned. */
200: while (1) {
201: if (c == 'l' || c == 'L')
202: {
203: if (spec_long)
204: cpp_error (pfile, "two `l's in integer constant");
205: spec_long = 1;
206: }
207: else if (c == 'u' || c == 'U')
208: {
209: if (op.unsignedp)
210: cpp_error (pfile, "two `u's in integer constant");
211: op.unsignedp = 1;
212: }
213: else
214: break;
215:
216: if (--len == 0)
217: break;
218: c = *p++;
219: }
220: /* Don't look for any more digits after the suffixes. */
221: break;
222: }
223: if (largest_digit < digit)
224: largest_digit = digit;
225: nd = n * base + digit;
226: overflow |= ULONG_MAX_over_base < n | nd < n;
227: n = nd;
228: }
229:
230: if (len != 0)
231: {
232: cpp_error (pfile, "Invalid number in #if expression");
233: op.op = ERROR;
234: return op;
235: }
236:
237: if (base <= largest_digit)
238: cpp_warning (pfile, "integer constant contains digits beyond the radix");
239:
240: if (overflow)
241: cpp_warning (pfile, "integer constant out of range");
242:
243: /* If too big to be signed, consider it unsigned. */
244: if ((long) n < 0 && ! op.unsignedp)
245: {
246: if (base == 10)
247: cpp_warning (pfile, "integer constant is so large that it is unsigned");
248: op.unsignedp = 1;
249: }
250:
251: op.value = n;
252: op.op = INT;
253: return op;
254: }
255:
256: struct token {
257: char *operator;
258: int token;
259: };
260:
261: static struct token tokentab2[] = {
262: {"&&", ANDAND},
263: {"||", OROR},
264: {"<<", LSH},
265: {">>", RSH},
266: {"==", EQUAL},
267: {"!=", NOTEQUAL},
268: {"<=", LEQ},
269: {">=", GEQ},
270: {"++", ERROR},
271: {"--", ERROR},
272: {NULL, ERROR}
273: };
274:
275: /* Read one token. */
276:
277: struct operation
278: cpp_lex (pfile)
279: cpp_reader *pfile;
280: {
281: register int c;
282: register int namelen;
283: register struct token *toktab;
284: enum cpp_token token;
285: struct operation op;
286: U_CHAR *tok_start, *tok_end;
287: int old_written;
288:
289: retry:
290:
291: old_written = CPP_WRITTEN (pfile);
292: cpp_skip_hspace (pfile);
293: c = CPP_BUF_PEEK (CPP_BUFFER (pfile));
294: if (c == '#')
295: return parse_number (pfile,
296: cpp_read_check_assertion (pfile) ? "1" : "0", 1);
297:
298: if (c == '\n')
299: {
300: op.op = 0;
301: return op;
302: }
303:
304: token = cpp_get_token (pfile);
305: tok_start = pfile->token_buffer + old_written;
306: tok_end = CPP_PWRITTEN (pfile);
307: pfile->limit = tok_start;
308: switch (token)
309: {
310: case CPP_EOF: /* Should not happen ... */
311: op.op = 0;
312: return op;
313: case CPP_VSPACE:
314: case CPP_POP:
315: if (CPP_BUFFER (pfile)->fname != NULL)
316: {
317: op.op = 0;
318: return op;
319: }
320: goto retry;
321: case CPP_HSPACE: case CPP_COMMENT:
322: goto retry;
323: case CPP_NUMBER:
324: return parse_number (pfile, tok_start, tok_end - tok_start);
325: case CPP_STRING:
326: cpp_error (pfile, "string constants not allowed in #if expressions");
327: op.op = ERROR;
328: return op;
329: case CPP_CHAR:
330: /* This code for reading a character constant
331: handles multicharacter constants and wide characters.
332: It is mostly copied from c-lex.c. */
333: {
334: register int result = 0;
335: register num_chars = 0;
336: unsigned width = MAX_CHAR_TYPE_SIZE;
337: int wide_flag = 0;
338: int max_chars;
339: U_CHAR *ptr = tok_start;
340: #ifdef MULTIBYTE_CHARS
341: char token_buffer[MAX_LONG_TYPE_SIZE/MAX_CHAR_TYPE_SIZE + MB_CUR_MAX];
342: #else
343: char token_buffer[MAX_LONG_TYPE_SIZE/MAX_CHAR_TYPE_SIZE + 1];
344: #endif
345:
346: if (*ptr == 'L')
347: {
348: ptr++;
349: wide_flag = 1;
350: width = MAX_WCHAR_TYPE_SIZE;
351: #ifdef MULTIBYTE_CHARS
352: max_chars = MB_CUR_MAX;
353: #else
354: max_chars = 1;
355: #endif
356: }
357: else
358: max_chars = MAX_LONG_TYPE_SIZE / width;
359:
360: ++ptr;
361: while (ptr < tok_end && ((c = *ptr++) != '\''))
362: {
363: if (c == '\\')
364: {
365: c = cpp_parse_escape (pfile, &ptr);
366: if (width < HOST_BITS_PER_INT
367: && (unsigned) c >= (1 << width))
368: cpp_pedwarn (pfile,
369: "escape sequence out of range for character");
370: }
371:
372: num_chars++;
373:
374: /* Merge character into result; ignore excess chars. */
375: if (num_chars < max_chars + 1)
376: {
377: if (width < HOST_BITS_PER_INT)
378: result = (result << width) | (c & ((1 << width) - 1));
379: else
380: result = c;
381: token_buffer[num_chars - 1] = c;
382: }
383: }
384:
385: token_buffer[num_chars] = 0;
386:
387: if (c != '\'')
388: cpp_error (pfile, "malformatted character constant");
389: else if (num_chars == 0)
390: cpp_error (pfile, "empty character constant");
391: else if (num_chars > max_chars)
392: {
393: num_chars = max_chars;
394: cpp_error (pfile, "character constant too long");
395: }
396: else if (num_chars != 1 && ! CPP_TRADITIONAL (pfile))
397: cpp_warning (pfile, "multi-character character constant");
398:
399: /* If char type is signed, sign-extend the constant. */
400: if (! wide_flag)
401: {
402: int num_bits = num_chars * width;
403:
404: if (cpp_lookup (pfile, "__CHAR_UNSIGNED__",
405: sizeof ("__CHAR_UNSIGNED__")-1, -1)
406: || ((result >> (num_bits - 1)) & 1) == 0)
407: op.value
408: = result & ((unsigned long) ~0 >> (HOST_BITS_PER_LONG - num_bits));
409: else
410: op.value
411: = result | ~((unsigned long) ~0 >> (HOST_BITS_PER_LONG - num_bits));
412: }
413: else
414: {
415: #ifdef MULTIBYTE_CHARS
416: /* Set the initial shift state and convert the next sequence. */
417: result = 0;
418: /* In all locales L'\0' is zero and mbtowc will return zero,
419: so don't use it. */
420: if (num_chars > 1
421: || (num_chars == 1 && token_buffer[0] != '\0'))
422: {
423: wchar_t wc;
424: (void) mbtowc (NULL_PTR, NULL_PTR, 0);
425: if (mbtowc (& wc, token_buffer, num_chars) == num_chars)
426: result = wc;
427: else
428: cpp_warning (pfile,"Ignoring invalid multibyte character");
429: }
430: #endif
431: op.value = result;
432: }
433: }
434:
435: /* This is always a signed type. */
436: op.unsignedp = 0;
437: op.op = CHAR;
438:
439: return op;
440:
441: case CPP_NAME:
442: return parse_number (pfile, "0", 0);
443:
444: case CPP_OTHER:
445: /* See if it is a special token of length 2. */
446: if (tok_start + 2 == tok_end)
447: {
448: for (toktab = tokentab2; toktab->operator != NULL; toktab++)
449: if (tok_start[0] == toktab->operator[0]
450: && tok_start[1] == toktab->operator[1])
451: break;
452: if (toktab->token == ERROR)
453: {
454: char *buf = (char *) alloca (40);
455: sprintf (buf, "`%s' not allowed in operand of `#if'", tok_start);
456: cpp_error (pfile, buf);
457: }
458: op.op = toktab->token;
459: return op;
460: }
461: /* fall through */
462: default:
463: op.op = *tok_start;
464: return op;
465: }
466: }
467:
468:
469: /* Parse a C escape sequence. STRING_PTR points to a variable
470: containing a pointer to the string to parse. That pointer
471: is updated past the characters we use. The value of the
472: escape sequence is returned.
473:
474: A negative value means the sequence \ newline was seen,
475: which is supposed to be equivalent to nothing at all.
476:
477: If \ is followed by a null character, we return a negative
478: value and leave the string pointer pointing at the null character.
479:
480: If \ is followed by 000, we return 0 and leave the string pointer
481: after the zeros. A value of 0 does not mean end of string. */
482:
483: int
484: cpp_parse_escape (pfile, string_ptr)
485: cpp_reader *pfile;
486: char **string_ptr;
487: {
488: register int c = *(*string_ptr)++;
489: switch (c)
490: {
491: case 'a':
492: return TARGET_BELL;
493: case 'b':
494: return TARGET_BS;
495: case 'e':
496: case 'E':
497: if (CPP_PEDANTIC (pfile))
498: cpp_pedwarn (pfile, "non-ANSI-standard escape sequence, `\\%c'", c);
499: return 033;
500: case 'f':
501: return TARGET_FF;
502: case 'n':
503: return TARGET_NEWLINE;
504: case 'r':
505: return TARGET_CR;
506: case 't':
507: return TARGET_TAB;
508: case 'v':
509: return TARGET_VT;
510: case '\n':
511: return -2;
512: case 0:
513: (*string_ptr)--;
514: return 0;
515:
516: case '0':
517: case '1':
518: case '2':
519: case '3':
520: case '4':
521: case '5':
522: case '6':
523: case '7':
524: {
525: register int i = c - '0';
526: register int count = 0;
527: while (++count < 3)
528: {
529: c = *(*string_ptr)++;
530: if (c >= '0' && c <= '7')
531: i = (i << 3) + c - '0';
532: else
533: {
534: (*string_ptr)--;
535: break;
536: }
537: }
538: if ((i & ~((1 << MAX_CHAR_TYPE_SIZE) - 1)) != 0)
539: {
540: i &= (1 << MAX_CHAR_TYPE_SIZE) - 1;
541: cpp_warning (pfile,
542: "octal character constant does not fit in a byte");
543: }
544: return i;
545: }
546: case 'x':
547: {
548: register unsigned i = 0, overflow = 0, digits_found = 0, digit;
549: for (;;)
550: {
551: c = *(*string_ptr)++;
552: if (c >= '0' && c <= '9')
553: digit = c - '0';
554: else if (c >= 'a' && c <= 'f')
555: digit = c - 'a' + 10;
556: else if (c >= 'A' && c <= 'F')
557: digit = c - 'A' + 10;
558: else
559: {
560: (*string_ptr)--;
561: break;
562: }
563: overflow |= i ^ (i << 4 >> 4);
564: i = (i << 4) + digit;
565: digits_found = 1;
566: }
567: if (!digits_found)
568: cpp_error (pfile, "\\x used with no following hex digits");
569: if (overflow | (i & ~((1 << BITS_PER_UNIT) - 1)))
570: {
571: i &= (1 << BITS_PER_UNIT) - 1;
572: cpp_warning (pfile,
573: "hex character constant does not fit in a byte");
574: }
575: return i;
576: }
577: default:
578: return c;
579: }
580: }
581:
582: static void
583: integer_overflow (pfile)
584: cpp_reader *pfile;
585: {
586: if (CPP_PEDANTIC (pfile))
587: cpp_pedwarn (pfile, "integer overflow in preprocessor expression");
588: }
589:
590: static long
591: left_shift (pfile, a, unsignedp, b)
592: cpp_reader *pfile;
593: long a;
594: int unsignedp;
595: unsigned long b;
596: {
597: if (b >= HOST_BITS_PER_LONG)
598: {
599: if (! unsignedp && a != 0)
600: integer_overflow (pfile);
601: return 0;
602: }
603: else if (unsignedp)
604: return (unsigned long) a << b;
605: else
606: {
607: long l = a << b;
608: if (l >> b != a)
609: integer_overflow (pfile);
610: return l;
611: }
612: }
613:
614: static long
615: right_shift (pfile, a, unsignedp, b)
616: cpp_reader *pfile;
617: long a;
618: int unsignedp;
619: unsigned long b;
620: {
621: if (b >= HOST_BITS_PER_LONG)
622: return unsignedp ? 0 : a >> (HOST_BITS_PER_LONG - 1);
623: else if (unsignedp)
624: return (unsigned long) a >> b;
625: else
626: return a >> b;
627: }
628:
629: /* These priorities are all even, so we can handle associatively. */
630: #define PAREN_INNER_PRIO 0
631: #define COMMA_PRIO 4
632: #define COND_PRIO (COMMA_PRIO+2)
633: #define OROR_PRIO (COND_PRIO+2)
634: #define ANDAND_PRIO (OROR_PRIO+2)
635: #define OR_PRIO (ANDAND_PRIO+2)
636: #define XOR_PRIO (OR_PRIO+2)
637: #define AND_PRIO (XOR_PRIO+2)
638: #define EQUAL_PRIO (AND_PRIO+2)
639: #define LESS_PRIO (EQUAL_PRIO+2)
640: #define SHIFT_PRIO (LESS_PRIO+2)
641: #define PLUS_PRIO (SHIFT_PRIO+2)
642: #define MUL_PRIO (PLUS_PRIO+2)
643: #define UNARY_PRIO (MUL_PRIO+2)
644: #define PAREN_OUTER_PRIO (UNARY_PRIO+2)
645:
646: #define COMPARE(OP) \
647: top->unsignedp = 0;\
648: top->value = (unsigned1 || unsigned2) ? (unsigned long) v1 OP v2 : (v1 OP v2)
649:
650: /* Parse and evaluate a C expression, reading from PFILE.
651: Returns the value of the expression. */
652:
653: HOST_WIDE_INT
654: cpp_parse_expr (pfile)
655: cpp_reader *pfile;
656: {
657: /* The implementation is an operator precedence parser,
658: i.e. a bottom-up parser, using a stack for not-yet-reduced tokens.
659:
660: The stack base is 'stack', and the current stack pointer is 'top'.
661: There is a stack element for each operator (only),
662: and the most recently pushed operator is 'top->op'.
663: An operand (value) is stored in the 'value' field of the stack
664: element of the operator that precedes it.
665: In that case the 'flags' field has the HAVE_VALUE flag set. */
666:
667: #define INIT_STACK_SIZE 20
668: struct operation init_stack[INIT_STACK_SIZE];
669: struct operation *stack = init_stack;
670: struct operation *limit = stack + INIT_STACK_SIZE;
671: register struct operation *top = stack;
672: int lprio, rprio;
673:
674: top->rprio = 0;
675: top->flags = 0;
676: for (;;)
677: {
678: struct operation op;
679: char flags = 0;
680:
681: /* Read a token */
682: op = cpp_lex (pfile);
683:
684: /* See if the token is an operand, in which case go to set_value.
685: If the token is an operator, figure out its left and right
686: priorities, and then goto maybe_reduce. */
687:
688: switch (op.op)
689: {
690: case NAME:
691: top->value = 0, top->unsignedp = 0;
692: goto set_value;
693: case INT: case CHAR:
694: top->value = op.value;
695: top->unsignedp = op.unsignedp;
696: goto set_value;
697: case 0:
698: lprio = 0; goto maybe_reduce;
699: case '+': case '-':
700: /* Is this correct if unary ? FIXME */
701: flags = RIGHT_OPERAND_REQUIRED;
702: lprio = PLUS_PRIO; rprio = lprio + 1; goto maybe_reduce;
703: case '!': case '~':
704: flags = RIGHT_OPERAND_REQUIRED;
705: rprio = UNARY_PRIO; lprio = rprio + 1; goto maybe_reduce;
706: case '*': case '/': case '%':
707: lprio = MUL_PRIO; goto binop;
708: case '<': case '>': case LEQ: case GEQ:
709: lprio = LESS_PRIO; goto binop;
710: case EQUAL: case NOTEQUAL:
711: lprio = EQUAL_PRIO; goto binop;
712: case LSH: case RSH:
713: lprio = SHIFT_PRIO; goto binop;
714: case '&': lprio = AND_PRIO; goto binop;
715: case '^': lprio = XOR_PRIO; goto binop;
716: case '|': lprio = OR_PRIO; goto binop;
717: case ANDAND: lprio = ANDAND_PRIO; goto binop;
718: case OROR: lprio = OROR_PRIO; goto binop;
719: case ',':
720: lprio = COMMA_PRIO; goto binop;
721: case '(':
722: lprio = PAREN_OUTER_PRIO; rprio = PAREN_INNER_PRIO;
723: goto maybe_reduce;
724: case ')':
725: lprio = PAREN_INNER_PRIO; rprio = PAREN_OUTER_PRIO;
726: goto maybe_reduce;
727: case ':':
728: lprio = COND_PRIO; rprio = COND_PRIO;
729: goto maybe_reduce;
730: case '?':
731: lprio = COND_PRIO + 1; rprio = COND_PRIO;
732: goto maybe_reduce;
733: binop:
734: flags = LEFT_OPERAND_REQUIRED|RIGHT_OPERAND_REQUIRED;
735: rprio = lprio + 1;
736: goto maybe_reduce;
737: default:
738: cpp_error (pfile, "invalid character in #if");
739: goto syntax_error;
740: }
741:
742: set_value:
743: /* Push a value onto the stack. */
744: if (top->flags & HAVE_VALUE)
745: {
746: cpp_error (pfile, "syntax error in #if");
747: goto syntax_error;
748: }
749: top->flags |= HAVE_VALUE;
750: continue;
751:
752: maybe_reduce:
753: /* Push an operator, and check if we can reduce now. */
754: while (top->rprio > lprio)
755: {
756: long v1 = top[-1].value, v2 = top[0].value;
757: int unsigned1 = top[-1].unsignedp, unsigned2 = top[0].unsignedp;
758: top--;
759: if ((top[1].flags & LEFT_OPERAND_REQUIRED)
760: && ! (top[0].flags & HAVE_VALUE))
761: {
762: cpp_error (pfile, "syntax error - missing left operand");
763: goto syntax_error;
764: }
765: if ((top[1].flags & RIGHT_OPERAND_REQUIRED)
766: && ! (top[1].flags & HAVE_VALUE))
767: {
768: cpp_error (pfile, "syntax error - missing right operand");
769: goto syntax_error;
770: }
771: /* top[0].value = (top[1].op)(v1, v2);*/
772: switch (top[1].op)
773: {
774: case '+':
775: if (!(top->flags & HAVE_VALUE))
776: { /* Unary '+' */
777: top->value = v2;
778: top->unsignedp = unsigned2;
779: top->flags |= HAVE_VALUE;
780: }
781: else
782: {
783: top->value = v1 + v2;
784: top->unsignedp = unsigned1 || unsigned2;
785: if (! top->unsignedp
786: && ! possible_sum_sign (v1, v2, top->value))
787: integer_overflow (pfile);
788: }
789: break;
790: case '-':
791: if (!(top->flags & HAVE_VALUE))
792: { /* Unary '-' */
793: top->value = - v2;
794: if ((top->value & v2) < 0 && ! unsigned2)
795: integer_overflow (pfile);
796: top->unsignedp = unsigned2;
797: top->flags |= HAVE_VALUE;
798: }
799: else
800: { /* Binary '-' */
801: top->value = v1 - v2;
802: top->unsignedp = unsigned1 || unsigned2;
803: if (! top->unsignedp
804: && ! possible_sum_sign (top->value, v2, v1))
805: integer_overflow (pfile);
806: }
807: break;
808: case '*':
809: top->unsignedp = unsigned1 || unsigned2;
810: if (top->unsignedp)
811: top->value = (unsigned long) v1 * v2;
812: else
813: {
814: top->value = v1 * v2;
815: if (v1
816: && (top->value / v1 != v2
817: || (top->value & v1 & v2) < 0))
818: integer_overflow (pfile);
819: }
820: break;
821: case '/':
822: if (v2 == 0)
823: {
824: cpp_error (pfile, "division by zero in #if");
825: v2 = 1;
826: }
827: top->unsignedp = unsigned1 || unsigned2;
828: if (top->unsignedp)
829: top->value = (unsigned long) v1 / v2;
830: else
831: {
832: top->value = v1 / v2;
833: if ((top->value & v1 & v2) < 0)
834: integer_overflow (pfile);
835: }
836: break;
837: case '%':
838: if (v2 == 0)
839: {
840: cpp_error (pfile, "division by zero in #if");
841: v2 = 1;
842: }
843: top->unsignedp = unsigned1 || unsigned2;
844: if (top->unsignedp)
845: top->value = (unsigned long) v1 % v2;
846: else
847: top->value = v1 % v2;
848: break;
849: case '!':
850: if (top->flags & HAVE_VALUE)
851: {
852: cpp_error (pfile, "syntax error");
853: goto syntax_error;
854: }
855: top->value = ! v2;
856: top->unsignedp = 0;
857: top->flags |= HAVE_VALUE;
858: break;
859: case '~':
860: if (top->flags & HAVE_VALUE)
861: {
862: cpp_error (pfile, "syntax error");
863: goto syntax_error;
864: }
865: top->value = ~ v2;
866: top->unsignedp = unsigned2;
867: top->flags |= HAVE_VALUE;
868: break;
869: case '<': COMPARE(<); break;
870: case '>': COMPARE(>); break;
871: case LEQ: COMPARE(<=); break;
872: case GEQ: COMPARE(>=); break;
873: case EQUAL:
874: top->value = (v1 == v2);
875: top->unsignedp = 0;
876: break;
877: case NOTEQUAL:
878: top->value = (v1 != v2);
879: top->unsignedp = 0;
880: break;
881: case LSH:
882: top->unsignedp = unsigned1;
883: if (v2 < 0 && ! unsigned2)
884: top->value = right_shift (pfile, v1, unsigned1, -v2);
885: else
886: top->value = left_shift (pfile, v1, unsigned1, v2);
887: break;
888: case RSH:
889: top->unsignedp = unsigned1;
890: if (v2 < 0 && ! unsigned2)
891: top->value = left_shift (pfile, v1, unsigned1, -v2);
892: else
893: top->value = right_shift (pfile, v1, unsigned1, v2);
894: break;
895: #define LOGICAL(OP) \
896: top->value = v1 OP v2;\
897: top->unsignedp = unsigned1 || unsigned2;
898: case '&': LOGICAL(&); break;
899: case '^': LOGICAL(^); break;
900: case '|': LOGICAL(|); break;
901: case ANDAND:
902: top->value = v1 && v2; top->unsignedp = 0; break;
903: case OROR:
904: top->value = v1 || v2; top->unsignedp = 0; break;
905: case ',':
906: if (CPP_PEDANTIC (pfile))
907: cpp_pedwarn (pfile, "comma operator in operand of `#if'");
908: top->value = v2;
909: top->unsignedp = unsigned2;
910: break;
911: case '(': case '?':
912: cpp_error (pfile, "syntax error in #if");
913: goto syntax_error;
914: case ':':
915: if (top[0].op != '?')
916: {
917: cpp_error (pfile,
918: "syntax error ':' without preceding '?'");
919: goto syntax_error;
920: }
921: else if (! (top[1].flags & HAVE_VALUE)
922: || !(top[-1].flags & HAVE_VALUE)
923: || !(top[0].flags & HAVE_VALUE))
924: {
925: cpp_error (pfile, "bad syntax for ?: operator");
926: goto syntax_error;
927: }
928: else
929: {
930: top--;
931: top->value = top->value ? v1 : v2;
932: top->unsignedp = unsigned1 || unsigned2;
933: }
934: break;
935: case ')':
936: if ((top[1].flags & HAVE_VALUE)
937: || ! (top[0].flags & HAVE_VALUE)
938: || top[0].op != '('
939: || (top[-1].flags & HAVE_VALUE))
940: {
941: cpp_error (pfile, "mismatched parentheses in #if");
942: goto syntax_error;
943: }
944: else
945: {
946: top--;
947: top->value = v1;
948: top->unsignedp = unsigned1;
949: top->flags |= HAVE_VALUE;
950: }
951: break;
952: default:
953: fprintf (stderr,
954: top[1].op >= ' ' && top[1].op <= '~'
955: ? "unimplemented operator '%c'\n"
956: : "unimplemented operator '\\%03o'\n",
957: top[1].op);
958: }
959: }
960: if (op.op == 0)
961: {
962: if (top != stack)
963: cpp_error (pfile, "internal error in #if expression");
964: if (stack != init_stack)
965: free (stack);
966: return top->value;
967: }
968: top++;
969:
970: /* Check for and handle stack overflow. */
971: if (top == limit)
972: {
973: struct operation *new_stack;
974: int old_size = (char*)limit - (char*)stack;
975: int new_size = 2 * old_size;
976: if (stack != init_stack)
977: new_stack = (struct operation*) xrealloc (stack, new_size);
978: else
979: {
980: new_stack = (struct operation*) xmalloc (new_size);
981: bcopy ((char *) stack, (char *) new_stack, old_size);
982: }
983: stack = new_stack;
984: top = (struct operation*)((char*) new_stack + old_size);
985: limit = (struct operation*)((char*) new_stack + new_size);
986: }
987:
988: top->flags = flags;
989: top->rprio = rprio;
990: top->op = op.op;
991: }
992: syntax_error:
993: if (stack != init_stack)
994: free (stack);
995: skip_rest_of_line (pfile);
996: return 0;
997: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.