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