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