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