chiark / gitweb /
Imported Upstream version 1.0.0
[e16] / epp / cppexp.c
1
2 /* Parse C expressions for CCCP.
3  * Copyright (C) 1987, 1992, 1994, 1995 Free Software Foundation.
4  * 
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License as published by the
7  * Free Software Foundation; either version 2, or (at your option) any
8  * later version.
9  * 
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  * 
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, 675 Mass Ave, Cambridge, MA 02139, 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 #include "cpphash.h"
30
31 #ifdef __EMX__
32 #include <strings.h>
33 #endif
34
35 #ifdef MULTIBYTE_CHARS
36 #include <locale.h>
37 #endif
38
39 #include <stdlib.h>
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    unsigned 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 #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 #define ERROR 299
106 #define OROR 300
107 #define ANDAND 301
108 #define EQUAL 302
109 #define NOTEQUAL 303
110 #define LEQ 304
111 #define GEQ 305
112 #define LSH 306
113 #define RSH 307
114 #define NAME 308
115 #define INT 309
116 #define CHAR 310
117
118 #define LEFT_OPERAND_REQUIRED 1
119 #define RIGHT_OPERAND_REQUIRED 2
120 #define HAVE_VALUE 4
121 /* SKIP_OPERAND is set for '&&' '||' '?' and ':' when the
122  * following operand should be short-circuited instead of evaluated. */
123 #define SKIP_OPERAND 8
124 /*#define UNSIGNEDP 16 */
125
126 struct operation {
127    short               op;
128    char                rprio;   /* Priority of op (relative to it right operand). */
129    char                flags;
130    char                unsignedp;       /* true if value should be treated as unsigned */
131    HOST_WIDE_INT       value;   /* The value logically "right" of op. */
132 };
133
134 /* Take care of parsing a number (anything that starts with a digit).
135  * LEN is the number of characters in it.  */
136
137 /* maybe needs to actually deal with floating point numbers */
138
139 static void
140 parse_number(struct operation *op, cpp_reader * pfile, const char *start,
141              int olen)
142 {
143    const char         *p = start;
144    int                 c;
145    unsigned long       n = 0, nd, ULONG_MAX_over_base;
146    int                 base = 10;
147    int                 len = olen;
148    int                 overflow = 0;
149    int                 digit, largest_digit = 0;
150    int                 spec_long = 0;
151
152    op->unsignedp = 0;
153
154    for (c = 0; c < len; c++)
155       if (p[c] == '.')
156         {
157            /* It's a float since it contains a point.  */
158            cpp_error(pfile,
159                      "floating point numbers not allowed in #if expressions");
160            op->op = ERROR;
161            return;
162         }
163    if (len >= 3 && (!strncmp(p, "0x", 2) || !strncmp(p, "0X", 2)))
164      {
165         p += 2;
166         base = 16;
167         len -= 2;
168      }
169    else if (*p == '0')
170       base = 8;
171
172    /* Some buggy compilers (e.g. MPW C) seem to need both casts. */
173    ULONG_MAX_over_base = ((unsigned long)-1) / ((unsigned long)base);
174
175    for (; len > 0; len--)
176      {
177         c = *p++;
178
179         if (c >= '0' && c <= '9')
180            digit = c - '0';
181         else if (base == 16 && c >= 'a' && c <= 'f')
182            digit = c - 'a' + 10;
183         else if (base == 16 && c >= 'A' && c <= 'F')
184            digit = c - 'A' + 10;
185         else
186           {
187              /* `l' means long, and `u' means unsigned.  */
188              while (1)
189                {
190                   if (c == 'l' || c == 'L')
191                     {
192                        if (spec_long)
193                           cpp_error(pfile, "two `l's in integer constant");
194                        spec_long = 1;
195                     }
196                   else if (c == 'u' || c == 'U')
197                     {
198                        if (op->unsignedp)
199                           cpp_error(pfile, "two `u's in integer constant");
200                        op->unsignedp = 1;
201                     }
202                   else
203                      break;
204
205                   if (--len == 0)
206                      break;
207                   c = *p++;
208                }
209              /* Don't look for any more digits after the suffixes.  */
210              break;
211           }
212         if (largest_digit < digit)
213            largest_digit = digit;
214         nd = n * base + digit;
215         overflow |= (ULONG_MAX_over_base < n) | (nd < n);
216         n = nd;
217      }
218
219    if (len != 0)
220      {
221         cpp_error(pfile, "Invalid number in #if expression");
222         op->op = ERROR;
223         return;
224      }
225    if (base <= largest_digit)
226       cpp_warning(pfile, "integer constant contains digits beyond the radix");
227
228    if (overflow)
229       cpp_warning(pfile, "integer constant out of range");
230
231    /* If too big to be signed, consider it unsigned.  */
232    if ((long)n < 0 && !op->unsignedp)
233      {
234         if (base == 10)
235            cpp_warning(pfile,
236                        "integer constant is so large that it is unsigned");
237         op->unsignedp = 1;
238      }
239    op->value = n;
240    op->op = INT;
241 }
242
243 struct token {
244    const char         *oper;
245    int                 token;
246 };
247
248 static struct token tokentab2[] = {
249    {"&&", ANDAND},
250    {"||", OROR},
251    {"<<", LSH},
252    {">>", RSH},
253    {"==", EQUAL},
254    {"!=", NOTEQUAL},
255    {"<=", LEQ},
256    {">=", GEQ},
257    {"++", ERROR},
258    {"--", ERROR},
259    {NULL, ERROR}
260 };
261
262 /* Read one token. */
263
264 static void
265 cpp_lex(struct operation *op, cpp_reader * pfile)
266 {
267    int                 c;
268    struct token       *toktab;
269    enum cpp_token      token;
270    unsigned char      *tok_start, *tok_end;
271    int                 old_written;
272
273    op->value = 0;
274    op->unsignedp = 0;
275
276  retry:
277
278    old_written = CPP_WRITTEN(pfile);
279    cpp_skip_hspace(pfile);
280    c = CPP_BUF_PEEK(CPP_BUFFER(pfile));
281    if (c == '#')
282      {
283         parse_number(op, pfile, cpp_read_check_assertion(pfile) ? "1" : "0", 1);
284         return;
285      }
286
287    if (c == '\n')
288      {
289         op->op = 0;
290         return;
291      }
292    token = cpp_get_token(pfile);
293    tok_start = pfile->token_buffer + old_written;
294    tok_end = CPP_PWRITTEN(pfile);
295    pfile->limit = tok_start;
296    switch (token)
297      {
298      case CPP_EOF:              /* Should not happen ... */
299         op->op = 0;
300         break;
301
302      case CPP_VSPACE:
303      case CPP_POP:
304         if (CPP_BUFFER(pfile)->fname != NULL)
305           {
306              op->op = 0;
307              break;
308           }
309         goto retry;
310
311      case CPP_HSPACE:
312      case CPP_COMMENT:
313         goto retry;
314
315      case CPP_NUMBER:
316         parse_number(op, pfile, (char *)tok_start, tok_end - tok_start);
317         break;
318
319      case CPP_STRING:
320         cpp_error(pfile, "string constants not allowed in #if expressions");
321         op->op = ERROR;
322         break;
323
324      case CPP_CHAR:
325         /* This code for reading a character constant
326          * handles multicharacter constants and wide characters.
327          * It is mostly copied from c-lex.c.  */
328         {
329            int                 result = 0;
330            int                 num_chars = 0;
331            unsigned            width = MAX_CHAR_TYPE_SIZE;
332            int                 wide_flag = 0;
333            int                 max_chars;
334            char               *ptr = (char *)tok_start;
335
336 #ifdef MULTIBYTE_CHARS
337            char                token_buffer[MAX_LONG_TYPE_SIZE /
338                                             MAX_CHAR_TYPE_SIZE + MB_CUR_MAX];
339
340 #else
341            char                token_buffer[MAX_LONG_TYPE_SIZE /
342                                             MAX_CHAR_TYPE_SIZE + 1];
343
344 #endif
345
346            if (*ptr == 'L')
347              {
348                 ptr++;
349                 wide_flag = 1;
350                 width = MAX_WCHAR_TYPE_SIZE;
351 #ifdef MULTIBYTE_CHARS
352                 max_chars = MB_CUR_MAX;
353 #else
354                 max_chars = 1;
355 #endif
356              }
357            else
358               max_chars = MAX_LONG_TYPE_SIZE / width;
359
360            while (1)
361              {
362                 if (ptr >= (char *)CPP_PWRITTEN(pfile) || (c = *ptr++) == '\'')
363                    break;
364
365                 if (c == '\\')
366                   {
367                      c = cpp_parse_escape(pfile, &ptr);
368                      if (width < HOST_BITS_PER_INT
369                          && (unsigned)c >= (unsigned)(1 << width))
370                         cpp_pedwarn(pfile,
371                                     "escape sequence out of range for character");
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("__CHAR_UNSIGNED__",
406                                sizeof("__CHAR_UNSIGNED__") - 1, -1)
407                     || ((result >> (num_bits - 1)) & 1) == 0)
408                    op->value =
409                       result & ((unsigned long)~0 >>
410                                 (HOST_BITS_PER_LONG - num_bits));
411                 else
412                    op->value =
413                       result | ~((unsigned long)~0 >>
414                                  (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
428                      (void)mbtowc(NULL_PTR, NULL_PTR, 0);
429                      if (mbtowc(&wc, token_buffer, num_chars) == num_chars)
430                         result = wc;
431                      else
432                         cpp_warning(pfile,
433                                     "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         break;
444
445      case CPP_NAME:
446         parse_number(op, pfile, "0", 0);
447         break;
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->oper != NULL; toktab++)
454                 if (tok_start[0] == toktab->oper[0]
455                     && tok_start[1] == toktab->oper[1])
456                    break;
457              if (toktab->token == ERROR)
458                {
459                   char               *buf = (char *)malloc(40);
460
461                   memset(buf, 0, 40);
462
463                   sprintf(buf, "`%s' not allowed in operand of `#if'",
464                           tok_start);
465                   cpp_error(pfile, buf);
466                   free(buf);
467                }
468              op->op = toktab->token;
469              break;
470           }
471         /* fall through */
472      default:
473         op->op = *tok_start;
474         break;
475      }
476 }
477
478 /* Parse a C escape sequence.  STRING_PTR points to a variable
479  * containing a pointer to the string to parse.  That pointer
480  * is updated past the characters we use.  The value of the
481  * escape sequence is returned.
482  * 
483  * A negative value means the sequence \ newline was seen,
484  * which is supposed to be equivalent to nothing at all.
485  * 
486  * If \ is followed by a null character, we return a negative
487  * value and leave the string pointer pointing at the null character.
488  * 
489  * If \ is followed by 000, we return 0 and leave the string pointer
490  * after the zeros.  A value of 0 does not mean end of string.  */
491
492 int
493 cpp_parse_escape(cpp_reader * pfile, char **string_ptr)
494 {
495    int                 c = *(*string_ptr)++;
496
497    switch (c)
498      {
499      case 'a':
500         return TARGET_BELL;
501      case 'b':
502         return TARGET_BS;
503      case 'e':
504      case 'E':
505         if (CPP_PEDANTIC(pfile))
506            cpp_pedwarn(pfile, "non-ANSI-standard escape sequence, `\\%c'", c);
507         return 033;
508      case 'f':
509         return TARGET_FF;
510      case 'n':
511         return TARGET_NEWLINE;
512      case 'r':
513         return TARGET_CR;
514      case 't':
515         return TARGET_TAB;
516      case 'v':
517         return TARGET_VT;
518      case '\n':
519         return -2;
520      case 0:
521         (*string_ptr)--;
522         return 0;
523
524      case '0':
525      case '1':
526      case '2':
527      case '3':
528      case '4':
529      case '5':
530      case '6':
531      case '7':
532         {
533            int                 i = c - '0';
534            int                 count = 0;
535
536            while (++count < 3)
537              {
538                 c = *(*string_ptr)++;
539                 if (c >= '0' && c <= '7')
540                    i = (i << 3) + c - '0';
541                 else
542                   {
543                      (*string_ptr)--;
544                      break;
545                   }
546              }
547            if ((i & ~((1 << MAX_CHAR_TYPE_SIZE) - 1)) != 0)
548              {
549                 i &= (1 << MAX_CHAR_TYPE_SIZE) - 1;
550                 cpp_warning(pfile,
551                             "octal character constant does not fit in a byte");
552              }
553            return i;
554         }
555      case 'x':
556         {
557            unsigned            i = 0, overflow = 0, digits_found = 0, digit;
558
559            for (;;)
560              {
561                 c = *(*string_ptr)++;
562                 if (c >= '0' && c <= '9')
563                    digit = c - '0';
564                 else if (c >= 'a' && c <= 'f')
565                    digit = c - 'a' + 10;
566                 else if (c >= 'A' && c <= 'F')
567                    digit = c - 'A' + 10;
568                 else
569                   {
570                      (*string_ptr)--;
571                      break;
572                   }
573                 overflow |= i ^ (i << 4 >> 4);
574                 i = (i << 4) + digit;
575                 digits_found = 1;
576              }
577            if (!digits_found)
578               cpp_error(pfile, "\\x used with no following hex digits");
579            if (overflow | (i & ~((1 << BITS_PER_UNIT) - 1)))
580              {
581                 i &= (1 << BITS_PER_UNIT) - 1;
582                 cpp_warning(pfile,
583                             "hex character constant does not fit in a byte");
584              }
585            return i;
586         }
587      default:
588         return c;
589      }
590 }
591
592 static void
593 integer_overflow(cpp_reader * pfile)
594 {
595    if (CPP_PEDANTIC(pfile))
596       cpp_pedwarn(pfile, "integer overflow in preprocessor expression");
597 }
598
599 static long
600 left_shift(cpp_reader * pfile, long a, int unsignedp, 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
614         if (l >> b != a)
615            integer_overflow(pfile);
616         return l;
617      }
618 }
619
620 static long
621 right_shift(cpp_reader * pfile, long a, int unsignedp, unsigned long b)
622 {
623    pfile = NULL;
624    if (b >= HOST_BITS_PER_LONG)
625      {
626         return unsignedp ? 0 : a >> (HOST_BITS_PER_LONG - 1);
627      }
628    else if (unsignedp)
629      {
630         return (unsigned long)a >> b;
631      }
632    else
633      {
634         return a >> b;
635      }
636 }
637
638 /* These priorities are all even, so we can handle associatively. */
639 #define PAREN_INNER_PRIO 0
640 #define COMMA_PRIO 4
641 #define COND_PRIO (COMMA_PRIO+2)
642 #define OROR_PRIO (COND_PRIO+2)
643 #define ANDAND_PRIO (OROR_PRIO+2)
644 #define OR_PRIO (ANDAND_PRIO+2)
645 #define XOR_PRIO (OR_PRIO+2)
646 #define AND_PRIO (XOR_PRIO+2)
647 #define EQUAL_PRIO (AND_PRIO+2)
648 #define LESS_PRIO (EQUAL_PRIO+2)
649 #define SHIFT_PRIO (LESS_PRIO+2)
650 #define PLUS_PRIO (SHIFT_PRIO+2)
651 #define MUL_PRIO (PLUS_PRIO+2)
652 #define UNARY_PRIO (MUL_PRIO+2)
653 #define PAREN_OUTER_PRIO (UNARY_PRIO+2)
654
655 #define COMPARE(OP) \
656   top->unsignedp = 0;\
657   top->value = (unsigned1 || unsigned2) ? (unsigned long) v1 OP (unsigned long) v2 : (v1 OP v2)
658
659 /* Parse and evaluate a C expression, reading from PFILE.
660  * Returns the value of the expression.  */
661
662 HOST_WIDE_INT
663 cpp_parse_expr(cpp_reader * pfile)
664 {
665    /* The implementation is an operator precedence parser,
666     * i.e. a bottom-up parser, using a stack for not-yet-reduced tokens.
667     * 
668     * The stack base is 'stack', and the current stack pointer is 'top'.
669     * There is a stack element for each operator (only),
670     * and the most recently pushed operator is 'top->op'.
671     * An operand (value) is stored in the 'value' field of the stack
672     * element of the operator that precedes it.
673     * In that case the 'flags' field has the HAVE_VALUE flag set.  */
674
675 #define INIT_STACK_SIZE 20
676    struct operation    init_stack[INIT_STACK_SIZE];
677    struct operation   *stack = init_stack;
678    struct operation   *limit = stack + INIT_STACK_SIZE;
679    struct operation   *top = stack;
680    int                 lprio = 0, rprio = 0;
681    int                 skip_evaluation = 0;
682
683    top->rprio = 0;
684    top->flags = 0;
685    for (;;)
686      {
687         struct operation    op;
688         char                flags = 0;
689
690         /* Read a token */
691         cpp_lex(&op, pfile);
692
693         /* See if the token is an operand, in which case go to set_value.
694          * If the token is an operator, figure out its left and right
695          * priorities, and then goto maybe_reduce. */
696
697         switch (op.op)
698           {
699           case NAME:
700              top->value = 0, top->unsignedp = 0;
701              goto set_value;
702           case INT:
703           case CHAR:
704              top->value = op.value;
705              top->unsignedp = op.unsignedp;
706              goto set_value;
707           case 0:
708              lprio = 0;
709              goto maybe_reduce;
710           case '+':
711           case '-':
712              /* Is this correct if unary ? FIXME */
713              flags = RIGHT_OPERAND_REQUIRED;
714              lprio = PLUS_PRIO;
715              rprio = lprio + 1;
716              goto maybe_reduce;
717           case '!':
718           case '~':
719              flags = RIGHT_OPERAND_REQUIRED;
720              rprio = UNARY_PRIO;
721              lprio = rprio + 1;
722              goto maybe_reduce;
723           case '*':
724           case '/':
725           case '%':
726              lprio = MUL_PRIO;
727              goto binop;
728           case '<':
729           case '>':
730           case LEQ:
731           case GEQ:
732              lprio = LESS_PRIO;
733              goto binop;
734           case EQUAL:
735           case NOTEQUAL:
736              lprio = EQUAL_PRIO;
737              goto binop;
738           case LSH:
739           case RSH:
740              lprio = SHIFT_PRIO;
741              goto binop;
742           case '&':
743              lprio = AND_PRIO;
744              goto binop;
745           case '^':
746              lprio = XOR_PRIO;
747              goto binop;
748           case '|':
749              lprio = OR_PRIO;
750              goto binop;
751           case ANDAND:
752              lprio = ANDAND_PRIO;
753              goto binop;
754           case OROR:
755              lprio = OROR_PRIO;
756              goto binop;
757           case ',':
758              lprio = COMMA_PRIO;
759              goto binop;
760           case '(':
761              lprio = PAREN_OUTER_PRIO;
762              rprio = PAREN_INNER_PRIO;
763              goto maybe_reduce;
764           case ')':
765              lprio = PAREN_INNER_PRIO;
766              rprio = PAREN_OUTER_PRIO;
767              goto maybe_reduce;
768           case ':':
769              lprio = COND_PRIO;
770              rprio = COND_PRIO;
771              goto maybe_reduce;
772           case '?':
773              lprio = COND_PRIO + 1;
774              rprio = COND_PRIO;
775              goto maybe_reduce;
776            binop:
777              flags = LEFT_OPERAND_REQUIRED | RIGHT_OPERAND_REQUIRED;
778              rprio = lprio + 1;
779              goto maybe_reduce;
780           default:
781              cpp_error(pfile, "invalid character in #if");
782              goto syntax_error;
783           }
784
785       set_value:
786         /* Push a value onto the stack. */
787         if (top->flags & HAVE_VALUE)
788           {
789              cpp_error(pfile, "syntax error in #if");
790              goto syntax_error;
791           }
792         top->flags |= HAVE_VALUE;
793         continue;
794
795       maybe_reduce:
796         /* Push an operator, and check if we can reduce now. */
797         while (top->rprio > lprio)
798           {
799              long                v1 = top[-1].value, v2 = top[0].value;
800              int                 unsigned1 = top[-1].unsignedp, unsigned2 =
801                 top[0].unsignedp;
802
803              top--;
804              if ((top[1].flags & LEFT_OPERAND_REQUIRED)
805                  && !(top[0].flags & HAVE_VALUE))
806                {
807                   cpp_error(pfile, "syntax error - missing left operand");
808                   goto syntax_error;
809                }
810              if ((top[1].flags & RIGHT_OPERAND_REQUIRED)
811                  && !(top[1].flags & HAVE_VALUE))
812                {
813                   cpp_error(pfile, "syntax error - missing right operand");
814                   goto syntax_error;
815                }
816              /* top[0].value = (top[1].op)(v1, v2); */
817              switch (top[1].op)
818                {
819                case '+':
820                   if (!(top->flags & HAVE_VALUE))
821                     {           /* Unary '+' */
822                        top->value = v2;
823                        top->unsignedp = unsigned2;
824                        top->flags |= HAVE_VALUE;
825                     }
826                   else
827                     {
828                        top->value = v1 + v2;
829                        top->unsignedp = unsigned1 || unsigned2;
830                        if (!top->unsignedp && !skip_evaluation
831                            && !possible_sum_sign(v1, v2, top->value))
832                           integer_overflow(pfile);
833                     }
834                   break;
835                case '-':
836                   if (skip_evaluation); /* do nothing */
837                   else if (!(top->flags & HAVE_VALUE))
838                     {           /* Unary '-' */
839                        top->value = -v2;
840                        if ((top->value & v2) < 0 && !unsigned2)
841                           integer_overflow(pfile);
842                        top->unsignedp = unsigned2;
843                        top->flags |= HAVE_VALUE;
844                     }
845                   else
846                     {           /* Binary '-' */
847                        top->value = v1 - v2;
848                        top->unsignedp = unsigned1 || unsigned2;
849                        if (!top->unsignedp
850                            && !possible_sum_sign(top->value, v2, v1))
851                           integer_overflow(pfile);
852                     }
853                   break;
854                case '*':
855                   top->unsignedp = unsigned1 || unsigned2;
856                   if (top->unsignedp)
857                      top->value = (unsigned long)v1 *v2;
858
859                   else if (!skip_evaluation)
860                     {
861                        top->value = v1 * v2;
862                        if (v1
863                            && (top->value / v1 != v2
864                                || (top->value & v1 & v2) < 0))
865                           integer_overflow(pfile);
866                     }
867                   break;
868                case '/':
869                   if (skip_evaluation)
870                      break;
871                   if (v2 == 0)
872                     {
873                        cpp_error(pfile, "division by zero in #if");
874                        v2 = 1;
875                     }
876                   top->unsignedp = unsigned1 || unsigned2;
877                   if (top->unsignedp)
878                      top->value = (unsigned long)v1 / v2;
879                   else
880                     {
881                        top->value = v1 / v2;
882                        if ((top->value & v1 & v2) < 0)
883                           integer_overflow(pfile);
884                     }
885                   break;
886                case '%':
887                   if (skip_evaluation)
888                      break;
889                   if (v2 == 0)
890                     {
891                        cpp_error(pfile, "division by zero in #if");
892                        v2 = 1;
893                     }
894                   top->unsignedp = unsigned1 || unsigned2;
895                   if (top->unsignedp)
896                      top->value = (unsigned long)v1 % v2;
897                   else
898                      top->value = v1 % v2;
899                   break;
900                case '!':
901                   if (top->flags & HAVE_VALUE)
902                     {
903                        cpp_error(pfile, "syntax error");
904                        goto syntax_error;
905                     }
906                   top->value = !v2;
907                   top->unsignedp = 0;
908                   top->flags |= HAVE_VALUE;
909                   break;
910                case '~':
911                   if (top->flags & HAVE_VALUE)
912                     {
913                        cpp_error(pfile, "syntax error");
914                        goto syntax_error;
915                     }
916                   top->value = ~v2;
917                   top->unsignedp = unsigned2;
918                   top->flags |= HAVE_VALUE;
919                   break;
920                case '<':
921                   COMPARE(<);
922                   break;
923                case '>':
924                   COMPARE(>);
925                   break;
926                case LEQ:
927                   COMPARE(<=);
928                   break;
929                case GEQ:
930                   COMPARE(>=);
931                   break;
932                case EQUAL:
933                   top->value = (v1 == v2);
934                   top->unsignedp = 0;
935                   break;
936                case NOTEQUAL:
937                   top->value = (v1 != v2);
938                   top->unsignedp = 0;
939                   break;
940                case LSH:
941                   if (skip_evaluation)
942                      break;
943                   top->unsignedp = unsigned1;
944                   if (v2 < 0 && !unsigned2)
945                      top->value = right_shift(pfile, v1, unsigned1, -v2);
946                   else
947                      top->value = left_shift(pfile, v1, unsigned1, v2);
948                   break;
949                case RSH:
950                   if (skip_evaluation)
951                      break;
952                   top->unsignedp = unsigned1;
953                   if (v2 < 0 && !unsigned2)
954                      top->value = left_shift(pfile, v1, unsigned1, -v2);
955                   else
956                      top->value = right_shift(pfile, v1, unsigned1, v2);
957                   break;
958 #define LOGICAL(OP) \
959               top->value = v1 OP v2;\
960               top->unsignedp = unsigned1 || unsigned2;
961                case '&':
962                   LOGICAL(&);
963                   break;
964                case '^':
965                   LOGICAL(^);
966                   break;
967                case '|':
968                   LOGICAL(|);
969                   break;
970                case ANDAND:
971                   top->value = v1 && v2;
972                   top->unsignedp = 0;
973                   if (!v1)
974                      skip_evaluation--;
975                   break;
976                case OROR:
977                   top->value = v1 || v2;
978                   top->unsignedp = 0;
979                   if (v1)
980                      skip_evaluation--;
981                   break;
982                case ',':
983                   if (CPP_PEDANTIC(pfile))
984                      cpp_pedwarn(pfile, "comma operator in operand of `#if'");
985                   top->value = v2;
986                   top->unsignedp = unsigned2;
987                   break;
988                case '(':
989                case '?':
990                   cpp_error(pfile, "syntax error in #if");
991                   goto syntax_error;
992                case ':':
993                   if (top[0].op != '?')
994                     {
995                        cpp_error(pfile,
996                                  "syntax error ':' without preceding '?'");
997                        goto syntax_error;
998                     }
999                   else if (!(top[1].flags & HAVE_VALUE)
1000                            || !(top[-1].flags & HAVE_VALUE)
1001                            || !(top[0].flags & HAVE_VALUE))
1002                     {
1003                        cpp_error(pfile, "bad syntax for ?: operator");
1004                        goto syntax_error;
1005                     }
1006                   else
1007                     {
1008                        top--;
1009                        if (top->value)
1010                           skip_evaluation--;
1011                        top->value = top->value ? v1 : v2;
1012                        top->unsignedp = unsigned1 || unsigned2;
1013                     }
1014                   break;
1015                case ')':
1016                   if ((top[1].flags & HAVE_VALUE)
1017                       || !(top[0].flags & HAVE_VALUE)
1018                       || top[0].op != '(' || (top[-1].flags & HAVE_VALUE))
1019                     {
1020                        cpp_error(pfile, "mismatched parentheses in #if");
1021                        goto syntax_error;
1022                     }
1023                   else
1024                     {
1025                        top--;
1026                        top->value = v1;
1027                        top->unsignedp = unsigned1;
1028                        top->flags |= HAVE_VALUE;
1029                     }
1030                   break;
1031                default:
1032                   fprintf(stderr,
1033                           top[1].op >= ' ' && top[1].op <= '~'
1034                           ? "unimplemented operator '%c'\n"
1035                           : "unimplemented operator '\\%03o'\n", top[1].op);
1036                }
1037           }
1038         if (op.op == 0)
1039           {
1040              if (top != stack)
1041                 cpp_error(pfile, "internal error in #if expression");
1042              if (stack != init_stack)
1043                 free(stack);
1044              return top->value;
1045           }
1046         top++;
1047
1048         /* Check for and handle stack overflow. */
1049         if (top == limit)
1050           {
1051              struct operation   *new_stack;
1052              int                 old_size = (char *)limit - (char *)stack;
1053              int                 new_size = 2 * old_size;
1054
1055              if (stack != init_stack)
1056                 new_stack = (struct operation *)xrealloc(stack, new_size);
1057              else
1058                {
1059                   new_stack = (struct operation *)xmalloc(new_size);
1060                   memcpy((char *)new_stack, (char *)stack, old_size);
1061                }
1062              stack = new_stack;
1063              top = (struct operation *)((char *)new_stack + old_size);
1064              limit = (struct operation *)((char *)new_stack + new_size);
1065           }
1066         top->flags = flags;
1067         top->rprio = rprio;
1068         top->op = op.op;
1069         if ((op.op == OROR && top[-1].value)
1070             || (op.op == ANDAND && !top[-1].value)
1071             || (op.op == '?' && !top[-1].value))
1072           {
1073              skip_evaluation++;
1074           }
1075         else if (op.op == ':')
1076           {
1077              if (top[-2].value) /* Was condition true? */
1078                 skip_evaluation++;
1079              else
1080                 skip_evaluation--;
1081           }
1082      }
1083  syntax_error:
1084    if (stack != init_stack)
1085       free(stack);
1086    skip_rest_of_line(pfile);
1087    return 0;
1088 }