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