Merge from vendor branch BINUTILS:
[dragonfly.git] / contrib / gcc / cexp.y
1 /* Parse C expressions for CCCP.
2    Copyright (C) 1987, 92, 94-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  Adapted from expread.y of GDB by Paul Rubin, July 1986.  */
24
25 /* Parse a C expression from text in a string  */
26    
27 %{
28 #include "config.h"
29
30 #include "system.h"
31 #include "intl.h"
32 #include <setjmp.h>
33 /* #define YYDEBUG 1 */
34
35 #ifdef MULTIBYTE_CHARS
36 #include "mbchar.h"
37 #include <locale.h>
38 #endif /* MULTIBYTE_CHARS */
39
40 typedef unsigned char U_CHAR;
41
42 /* This is used for communicating lists of keywords with cccp.c.  */
43 struct arglist {
44   struct arglist *next;
45   U_CHAR *name;
46   int length;
47   int argno;
48 };
49
50 HOST_WIDEST_INT parse_c_expression PROTO((char *, int));
51
52 static int yylex PROTO((void));
53 static void yyerror PVPROTO((const char *, ...))
54   ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
55 static HOST_WIDEST_INT expression_value;
56 #ifdef TEST_EXP_READER
57 static int expression_signedp;
58 #endif
59
60 static jmp_buf parse_return_error;
61
62 /* Nonzero means count most punctuation as part of a name.  */
63 static int keyword_parsing = 0;
64
65 /* Nonzero means do not evaluate this expression.
66    This is a count, since unevaluated expressions can nest.  */
67 static int skip_evaluation;
68
69 /* Nonzero means warn if undefined identifiers are evaluated.  */
70 static int warn_undef;
71
72 /* some external tables of character types */
73 extern unsigned char is_idstart[], is_idchar[], is_space[];
74
75 /* Flag for -pedantic.  */
76 extern int pedantic;
77
78 /* Flag for -traditional.  */
79 extern int traditional;
80
81 /* Flag for -lang-c89.  */
82 extern int c89;
83
84 #ifndef CHAR_TYPE_SIZE
85 #define CHAR_TYPE_SIZE BITS_PER_UNIT
86 #endif
87
88 #ifndef INT_TYPE_SIZE
89 #define INT_TYPE_SIZE BITS_PER_WORD
90 #endif
91
92 #ifndef LONG_TYPE_SIZE
93 #define LONG_TYPE_SIZE BITS_PER_WORD
94 #endif
95
96 #ifndef WCHAR_TYPE_SIZE
97 #define WCHAR_TYPE_SIZE INT_TYPE_SIZE
98 #endif
99
100 #ifndef MAX_CHAR_TYPE_SIZE
101 #define MAX_CHAR_TYPE_SIZE CHAR_TYPE_SIZE
102 #endif
103
104 #ifndef MAX_INT_TYPE_SIZE
105 #define MAX_INT_TYPE_SIZE INT_TYPE_SIZE
106 #endif
107
108 #ifndef MAX_LONG_TYPE_SIZE
109 #define MAX_LONG_TYPE_SIZE LONG_TYPE_SIZE
110 #endif
111
112 #ifndef MAX_WCHAR_TYPE_SIZE
113 #define MAX_WCHAR_TYPE_SIZE WCHAR_TYPE_SIZE
114 #endif
115
116 #define MAX_CHAR_TYPE_MASK (MAX_CHAR_TYPE_SIZE < HOST_BITS_PER_WIDEST_INT \
117                             ? (~ (~ (HOST_WIDEST_INT) 0 << MAX_CHAR_TYPE_SIZE)) \
118                             : ~ (HOST_WIDEST_INT) 0)
119
120 #define MAX_WCHAR_TYPE_MASK (MAX_WCHAR_TYPE_SIZE < HOST_BITS_PER_WIDEST_INT \
121                              ? ~ (~ (HOST_WIDEST_INT) 0 << MAX_WCHAR_TYPE_SIZE) \
122                              : ~ (HOST_WIDEST_INT) 0)
123
124 /* Suppose A1 + B1 = SUM1, using 2's complement arithmetic ignoring overflow.
125    Suppose A, B and SUM have the same respective signs as A1, B1, and SUM1.
126    Suppose SIGNEDP is negative if the result is signed, zero if unsigned.
127    Then this yields nonzero if overflow occurred during the addition.
128    Overflow occurs if A and B have the same sign, but A and SUM differ in sign,
129    and SIGNEDP is negative.
130    Use `^' to test whether signs differ, and `< 0' to isolate the sign.  */
131 #define overflow_sum_sign(a, b, sum, signedp) \
132         ((~((a) ^ (b)) & ((a) ^ (sum)) & (signedp)) < 0)
133
134 struct constant;
135
136 HOST_WIDEST_INT parse_escape PROTO((char **, HOST_WIDEST_INT));
137 int check_assertion PROTO((U_CHAR *, int, int, struct arglist *));
138 struct hashnode *lookup PROTO((U_CHAR *, int, int));
139 void error PVPROTO((const char *, ...)) ATTRIBUTE_PRINTF_1;
140 void verror PROTO((const char *, va_list));
141 void pedwarn PVPROTO((const char *, ...)) ATTRIBUTE_PRINTF_1;
142 void warning PVPROTO((const char *, ...)) ATTRIBUTE_PRINTF_1;
143
144 static int parse_number PROTO((int));
145 static HOST_WIDEST_INT left_shift PROTO((struct constant *, unsigned HOST_WIDEST_INT));
146 static HOST_WIDEST_INT right_shift PROTO((struct constant *, unsigned HOST_WIDEST_INT));
147 static void integer_overflow PROTO((void));
148
149 /* `signedp' values */
150 #define SIGNED (~0)
151 #define UNSIGNED 0
152 %}
153
154 %union {
155   struct constant {HOST_WIDEST_INT value; int signedp;} integer;
156   struct name {U_CHAR *address; int length;} name;
157   struct arglist *keywords;
158 }
159
160 %type <integer> exp exp1 start
161 %type <keywords> keywords
162 %token <integer> INT CHAR
163 %token <name> NAME
164 %token <integer> ERROR
165
166 %right '?' ':'
167 %left ','
168 %left OR
169 %left AND
170 %left '|'
171 %left '^'
172 %left '&'
173 %left EQUAL NOTEQUAL
174 %left '<' '>' LEQ GEQ
175 %left LSH RSH
176 %left '+' '-'
177 %left '*' '/' '%'
178 %right UNARY
179
180 /* %expect 40 */
181 \f
182 %%
183
184 start   :       exp1
185                 {
186                   expression_value = $1.value;
187 #ifdef TEST_EXP_READER
188                   expression_signedp = $1.signedp;
189 #endif
190                 }
191         ;
192
193 /* Expressions, including the comma operator.  */
194 exp1    :       exp
195         |       exp1 ',' exp
196                         { if (pedantic)
197                             pedwarn ("comma operator in operand of `#if'");
198                           $$ = $3; }
199         ;
200
201 /* Expressions, not including the comma operator.  */
202 exp     :       '-' exp    %prec UNARY
203                         { $$.value = - $2.value;
204                           $$.signedp = $2.signedp;
205                           if (($$.value & $2.value & $$.signedp) < 0)
206                             integer_overflow (); }
207         |       '!' exp    %prec UNARY
208                         { $$.value = ! $2.value;
209                           $$.signedp = SIGNED; }
210         |       '+' exp    %prec UNARY
211                         { $$ = $2; }
212         |       '~' exp    %prec UNARY
213                         { $$.value = ~ $2.value;
214                           $$.signedp = $2.signedp; }
215         |       '#' NAME
216                         { $$.value = check_assertion ($2.address, $2.length,
217                                                       0, NULL_PTR);
218                           $$.signedp = SIGNED; }
219         |       '#' NAME
220                         { keyword_parsing = 1; }
221                 '(' keywords ')'
222                         { $$.value = check_assertion ($2.address, $2.length,
223                                                       1, $5);
224                           keyword_parsing = 0;
225                           $$.signedp = SIGNED; }
226         |       '(' exp1 ')'
227                         { $$ = $2; }
228         ;
229
230 /* Binary operators in order of decreasing precedence.  */
231 exp     :       exp '*' exp
232                         { $$.signedp = $1.signedp & $3.signedp;
233                           if ($$.signedp)
234                             {
235                               $$.value = $1.value * $3.value;
236                               if ($1.value
237                                   && ($$.value / $1.value != $3.value
238                                       || ($$.value & $1.value & $3.value) < 0))
239                                 integer_overflow ();
240                             }
241                           else
242                             $$.value = ((unsigned HOST_WIDEST_INT) $1.value
243                                         * $3.value); }
244         |       exp '/' exp
245                         { if ($3.value == 0)
246                             {
247                               if (!skip_evaluation)
248                                 error ("division by zero in #if");
249                               $3.value = 1;
250                             }
251                           $$.signedp = $1.signedp & $3.signedp;
252                           if ($$.signedp)
253                             {
254                               $$.value = $1.value / $3.value;
255                               if (($$.value & $1.value & $3.value) < 0)
256                                 integer_overflow ();
257                             }
258                           else
259                             $$.value = ((unsigned HOST_WIDEST_INT) $1.value
260                                         / $3.value); }
261         |       exp '%' exp
262                         { if ($3.value == 0)
263                             {
264                               if (!skip_evaluation)
265                                 error ("division by zero in #if");
266                               $3.value = 1;
267                             }
268                           $$.signedp = $1.signedp & $3.signedp;
269                           if ($$.signedp)
270                             $$.value = $1.value % $3.value;
271                           else
272                             $$.value = ((unsigned HOST_WIDEST_INT) $1.value
273                                         % $3.value); }
274         |       exp '+' exp
275                         { $$.value = $1.value + $3.value;
276                           $$.signedp = $1.signedp & $3.signedp;
277                           if (overflow_sum_sign ($1.value, $3.value,
278                                                  $$.value, $$.signedp))
279                             integer_overflow (); }
280         |       exp '-' exp
281                         { $$.value = $1.value - $3.value;
282                           $$.signedp = $1.signedp & $3.signedp;
283                           if (overflow_sum_sign ($$.value, $3.value,
284                                                  $1.value, $$.signedp))
285                             integer_overflow (); }
286         |       exp LSH exp
287                         { $$.signedp = $1.signedp;
288                           if (($3.value & $3.signedp) < 0)
289                             $$.value = right_shift (&$1, -$3.value);
290                           else
291                             $$.value = left_shift (&$1, $3.value); }
292         |       exp RSH exp
293                         { $$.signedp = $1.signedp;
294                           if (($3.value & $3.signedp) < 0)
295                             $$.value = left_shift (&$1, -$3.value);
296                           else
297                             $$.value = right_shift (&$1, $3.value); }
298         |       exp EQUAL exp
299                         { $$.value = ($1.value == $3.value);
300                           $$.signedp = SIGNED; }
301         |       exp NOTEQUAL exp
302                         { $$.value = ($1.value != $3.value);
303                           $$.signedp = SIGNED; }
304         |       exp LEQ exp
305                         { $$.signedp = SIGNED;
306                           if ($1.signedp & $3.signedp)
307                             $$.value = $1.value <= $3.value;
308                           else
309                             $$.value = ((unsigned HOST_WIDEST_INT) $1.value
310                                         <= $3.value); }
311         |       exp GEQ exp
312                         { $$.signedp = SIGNED;
313                           if ($1.signedp & $3.signedp)
314                             $$.value = $1.value >= $3.value;
315                           else
316                             $$.value = ((unsigned HOST_WIDEST_INT) $1.value
317                                         >= $3.value); }
318         |       exp '<' exp
319                         { $$.signedp = SIGNED;
320                           if ($1.signedp & $3.signedp)
321                             $$.value = $1.value < $3.value;
322                           else
323                             $$.value = ((unsigned HOST_WIDEST_INT) $1.value
324                                         < $3.value); }
325         |       exp '>' exp
326                         { $$.signedp = SIGNED;
327                           if ($1.signedp & $3.signedp)
328                             $$.value = $1.value > $3.value;
329                           else
330                             $$.value = ((unsigned HOST_WIDEST_INT) $1.value
331                                         > $3.value); }
332         |       exp '&' exp
333                         { $$.value = $1.value & $3.value;
334                           $$.signedp = $1.signedp & $3.signedp; }
335         |       exp '^' exp
336                         { $$.value = $1.value ^ $3.value;
337                           $$.signedp = $1.signedp & $3.signedp; }
338         |       exp '|' exp
339                         { $$.value = $1.value | $3.value;
340                           $$.signedp = $1.signedp & $3.signedp; }
341         |       exp AND
342                         { skip_evaluation += !$1.value; }
343                 exp
344                         { skip_evaluation -= !$1.value;
345                           $$.value = ($1.value && $4.value);
346                           $$.signedp = SIGNED; }
347         |       exp OR
348                         { skip_evaluation += !!$1.value; }
349                 exp
350                         { skip_evaluation -= !!$1.value;
351                           $$.value = ($1.value || $4.value);
352                           $$.signedp = SIGNED; }
353         |       exp '?'
354                         { skip_evaluation += !$1.value; }
355                 exp ':'
356                         { skip_evaluation += !!$1.value - !$1.value; }
357                 exp
358                         { skip_evaluation -= !!$1.value;
359                           $$.value = $1.value ? $4.value : $7.value;
360                           $$.signedp = $4.signedp & $7.signedp; }
361         |       INT
362                         { $$ = yylval.integer; }
363         |       CHAR
364                         { $$ = yylval.integer; }
365         |       NAME
366                         { if (warn_undef && !skip_evaluation)
367                             warning ("`%.*s' is not defined",
368                                      $1.length, $1.address);
369                           $$.value = 0;
370                           $$.signedp = SIGNED; }
371         ;
372
373 keywords :
374                         { $$ = 0; } 
375         |       '(' keywords ')' keywords
376                         { struct arglist *temp;
377                           $$ = (struct arglist *) xmalloc (sizeof (struct arglist));
378                           $$->next = $2;
379                           $$->name = (U_CHAR *) "(";
380                           $$->length = 1;
381                           temp = $$;
382                           while (temp != 0 && temp->next != 0)
383                             temp = temp->next;
384                           temp->next = (struct arglist *) xmalloc (sizeof (struct arglist));
385                           temp->next->next = $4;
386                           temp->next->name = (U_CHAR *) ")";
387                           temp->next->length = 1; }
388         |       NAME keywords
389                         { $$ = (struct arglist *) xmalloc (sizeof (struct arglist));
390                           $$->name = $1.address;
391                           $$->length = $1.length;
392                           $$->next = $2; } 
393         ;
394 %%
395 \f
396 /* During parsing of a C expression, the pointer to the next character
397    is in this variable.  */
398
399 static char *lexptr;
400
401 /* Take care of parsing a number (anything that starts with a digit).
402    Set yylval and return the token type; update lexptr.
403    LEN is the number of characters in it.  */
404
405 /* maybe needs to actually deal with floating point numbers */
406
407 static int
408 parse_number (olen)
409      int olen;
410 {
411   register char *p = lexptr;
412   register int c;
413   register unsigned HOST_WIDEST_INT n = 0, nd, max_over_base;
414   register int base = 10;
415   register int len = olen;
416   register int overflow = 0;
417   register int digit, largest_digit = 0;
418   int spec_long = 0;
419
420   yylval.integer.signedp = SIGNED;
421
422   if (*p == '0') {
423     base = 8;
424     if (len >= 3 && (p[1] == 'x' || p[1] == 'X')) {
425       p += 2;
426       base = 16;
427       len -= 2;
428     }
429   }
430
431   max_over_base = (unsigned HOST_WIDEST_INT) -1 / base;
432
433   for (; len > 0; len--) {
434     c = *p++;
435
436     if (c >= '0' && c <= '9')
437       digit = c - '0';
438     else if (base == 16 && c >= 'a' && c <= 'f')
439       digit = c - 'a' + 10;
440     else if (base == 16 && c >= 'A' && c <= 'F')
441       digit = c - 'A' + 10;
442     else {
443       /* `l' means long, and `u' means unsigned.  */
444       while (1) {
445         if (c == 'l' || c == 'L')
446           {
447             if (!pedantic < spec_long)
448               yyerror ("too many `l's in integer constant");
449             spec_long++;
450           }
451         else if (c == 'u' || c == 'U')
452           {
453             if (! yylval.integer.signedp)
454               yyerror ("two `u's in integer constant");
455             yylval.integer.signedp = UNSIGNED;
456           }
457         else {
458           if (c == '.' || c == 'e' || c == 'E' || c == 'p' || c == 'P')
459             yyerror ("Floating point numbers not allowed in #if expressions");
460           else
461             yyerror ("missing white space after number `%.*s'",
462                      (int) (p - lexptr - 1), lexptr);
463         }
464
465         if (--len == 0)
466           break;
467         c = *p++;
468       }
469       /* Don't look for any more digits after the suffixes.  */
470       break;
471     }
472     if (largest_digit < digit)
473       largest_digit = digit;
474     nd = n * base + digit;
475     overflow |= (max_over_base < n) | (nd < n);
476     n = nd;
477   }
478
479   if (base <= largest_digit)
480     pedwarn ("integer constant contains digits beyond the radix");
481
482   if (overflow)
483     pedwarn ("integer constant out of range");
484
485   /* If too big to be signed, consider it unsigned.  */
486   if (((HOST_WIDEST_INT) n & yylval.integer.signedp) < 0)
487     {
488       if (base == 10)
489         warning ("integer constant is so large that it is unsigned");
490       yylval.integer.signedp = UNSIGNED;
491     }
492
493   lexptr = p;
494   yylval.integer.value = n;
495   return INT;
496 }
497
498 struct token {
499   const char *operator;
500   int token;
501 };
502
503 static struct token tokentab2[] = {
504   {"&&", AND},
505   {"||", OR},
506   {"<<", LSH},
507   {">>", RSH},
508   {"==", EQUAL},
509   {"!=", NOTEQUAL},
510   {"<=", LEQ},
511   {">=", GEQ},
512   {"++", ERROR},
513   {"--", ERROR},
514   {NULL, ERROR}
515 };
516
517 /* Read one token, getting characters through lexptr.  */
518
519 static int
520 yylex ()
521 {
522   register int c;
523   register int namelen;
524   register unsigned char *tokstart;
525   register struct token *toktab;
526   int wide_flag;
527   HOST_WIDEST_INT mask;
528
529  retry:
530
531   tokstart = (unsigned char *) lexptr;
532   c = *tokstart;
533   /* See if it is a special token of length 2.  */
534   if (! keyword_parsing)
535     for (toktab = tokentab2; toktab->operator != NULL; toktab++)
536       if (c == *toktab->operator && tokstart[1] == toktab->operator[1]) {
537         lexptr += 2;
538         if (toktab->token == ERROR)
539           yyerror ("`%s' not allowed in operand of `#if'", toktab->operator);
540         return toktab->token;
541       }
542
543   switch (c) {
544   case '\n':
545     return 0;
546     
547   case ' ':
548   case '\t':
549   case '\r':
550     lexptr++;
551     goto retry;
552     
553   case 'L':
554     /* Capital L may start a wide-string or wide-character constant.  */
555     if (lexptr[1] == '\'')
556       {
557         lexptr++;
558         wide_flag = 1;
559         mask = MAX_WCHAR_TYPE_MASK;
560         goto char_constant;
561       }
562     if (lexptr[1] == '"')
563       {
564         lexptr++;
565         wide_flag = 1;
566         mask = MAX_WCHAR_TYPE_MASK;
567         goto string_constant;
568       }
569     break;
570
571   case '\'':
572     wide_flag = 0;
573     mask = MAX_CHAR_TYPE_MASK;
574   char_constant:
575     lexptr++;
576     if (keyword_parsing) {
577       char *start_ptr = lexptr - 1;
578       while (1) {
579         c = *lexptr++;
580         if (c == '\\')
581           c = parse_escape (&lexptr, mask);
582         else if (c == '\'')
583           break;
584       }
585       yylval.name.address = tokstart;
586       yylval.name.length = lexptr - start_ptr;
587       return NAME;
588     }
589
590     /* This code for reading a character constant
591        handles multicharacter constants and wide characters.
592        It is mostly copied from c-lex.c.  */
593     {
594       register HOST_WIDEST_INT result = 0;
595       register int num_chars = 0;
596       int chars_seen = 0;
597       unsigned width = MAX_CHAR_TYPE_SIZE;
598       int max_chars;
599 #ifdef MULTIBYTE_CHARS
600       int longest_char = local_mb_cur_max ();
601       char *token_buffer = (char *) alloca (longest_char);
602       (void) local_mbtowc (NULL_PTR, NULL_PTR, 0);
603 #endif
604
605       max_chars = MAX_LONG_TYPE_SIZE / width;
606       if (wide_flag)
607         width = MAX_WCHAR_TYPE_SIZE;
608
609       while (1)
610         {
611           c = *lexptr++;
612
613           if (c == '\'' || c == EOF)
614             break;
615
616           ++chars_seen;
617           if (c == '\\')
618             {
619               c = parse_escape (&lexptr, mask);
620             }
621           else
622             {
623 #ifdef MULTIBYTE_CHARS
624               wchar_t wc;
625               int i;
626               int char_len = -1;
627               for (i = 1; i <= longest_char; ++i)
628                 {
629                   token_buffer[i - 1] = c;
630                   char_len = local_mbtowc (& wc, token_buffer, i);
631                   if (char_len != -1)
632                     break;
633                   c = *lexptr++;
634                 }
635               if (char_len > 1)
636                 {
637                   /* mbtowc sometimes needs an extra char before accepting */
638                   if (char_len < i)
639                     lexptr--;
640                   if (! wide_flag)
641                     {
642                       /* Merge character into result; ignore excess chars.  */
643                       for (i = 1; i <= char_len; ++i)
644                         {
645                           if (i > max_chars)
646                             break;
647                           if (width < HOST_BITS_PER_INT)
648                             result = (result << width)
649                               | (token_buffer[i - 1]
650                                  & ((1 << width) - 1));
651                           else
652                             result = token_buffer[i - 1];
653                         }
654                       num_chars += char_len;
655                       continue;
656                     }
657                 }
658               else
659                 {
660                   if (char_len == -1)
661                     warning ("Ignoring invalid multibyte character");
662                 }
663               if (wide_flag)
664                 c = wc;
665 #endif /* ! MULTIBYTE_CHARS */
666             }
667
668           if (wide_flag)
669             {
670               if (chars_seen == 1) /* only keep the first one */
671                 result = c;
672               continue;
673             }
674
675           /* Merge character into result; ignore excess chars.  */
676           num_chars++;
677           if (num_chars <= max_chars)
678             {
679               if (width < HOST_BITS_PER_INT)
680                 result = (result << width) | (c & ((1 << width) - 1));
681               else
682                 result = c;
683             }
684         }
685
686       if (c != '\'')
687         error ("malformatted character constant");
688       else if (chars_seen == 0)
689         error ("empty character constant");
690       else if (num_chars > max_chars)
691         {
692           num_chars = max_chars;
693           error ("character constant too long");
694         }
695       else if (chars_seen != 1 && ! traditional)
696         warning ("multi-character character constant");
697
698       /* If char type is signed, sign-extend the constant.  */
699       if (! wide_flag)
700         {
701           int num_bits = num_chars * width;
702           if (num_bits == 0)
703             /* We already got an error; avoid invalid shift.  */
704             yylval.integer.value = 0;
705           else if (lookup ((U_CHAR *) "__CHAR_UNSIGNED__",
706                       sizeof ("__CHAR_UNSIGNED__") - 1, -1)
707               || ((result >> (num_bits - 1)) & 1) == 0)
708             yylval.integer.value
709               = result & (~ (unsigned HOST_WIDEST_INT) 0
710                           >> (HOST_BITS_PER_WIDEST_INT - num_bits));
711           else
712             yylval.integer.value
713               = result | ~(~ (unsigned HOST_WIDEST_INT) 0
714                            >> (HOST_BITS_PER_WIDEST_INT - num_bits));
715         }
716       else
717         {
718           yylval.integer.value = result;
719         }
720     }
721
722     /* This is always a signed type.  */
723     yylval.integer.signedp = SIGNED;
724     
725     return CHAR;
726
727     /* some of these chars are invalid in constant expressions;
728        maybe do something about them later */
729   case '/':
730   case '+':
731   case '-':
732   case '*':
733   case '%':
734   case '|':
735   case '&':
736   case '^':
737   case '~':
738   case '!':
739   case '@':
740   case '<':
741   case '>':
742   case '[':
743   case ']':
744   case '.':
745   case '?':
746   case ':':
747   case '=':
748   case '{':
749   case '}':
750   case ',':
751   case '#':
752     if (keyword_parsing)
753       break;
754   case '(':
755   case ')':
756     lexptr++;
757     return c;
758
759   case '"':
760     mask = MAX_CHAR_TYPE_MASK;
761   string_constant:
762     if (keyword_parsing) {
763       char *start_ptr = lexptr;
764       lexptr++;
765       while (1) {
766         c = *lexptr++;
767         if (c == '\\')
768           c = parse_escape (&lexptr, mask);
769         else if (c == '"')
770           break;
771       }
772       yylval.name.address = tokstart;
773       yylval.name.length = lexptr - start_ptr;
774       return NAME;
775     }
776     yyerror ("string constants not allowed in #if expressions");
777     return ERROR;
778   }
779
780   if (c >= '0' && c <= '9' && !keyword_parsing) {
781     /* It's a number */
782     for (namelen = 1; ; namelen++) {
783       int d = tokstart[namelen];
784       if (! ((is_idchar[d] || d == '.')
785              || ((d == '-' || d == '+')
786                  && (c == 'e' || c == 'E'
787                      || ((c == 'p' || c == 'P') && ! c89))
788                  && ! traditional)))
789         break;
790       c = d;
791     }
792     return parse_number (namelen);
793   }
794
795   /* It is a name.  See how long it is.  */
796
797   if (keyword_parsing) {
798     for (namelen = 0;; namelen++) {
799       if (is_space[tokstart[namelen]])
800         break;
801       if (tokstart[namelen] == '(' || tokstart[namelen] == ')')
802         break;
803       if (tokstart[namelen] == '"' || tokstart[namelen] == '\'')
804         break;
805     }
806   } else {
807     if (!is_idstart[c]) {
808       yyerror ("Invalid token in expression");
809       return ERROR;
810     }
811
812     for (namelen = 0; is_idchar[tokstart[namelen]]; namelen++)
813       ;
814   }
815   
816   lexptr += namelen;
817   yylval.name.address = tokstart;
818   yylval.name.length = namelen;
819   return NAME;
820 }
821
822
823 /* Parse a C escape sequence.  STRING_PTR points to a variable
824    containing a pointer to the string to parse.  That pointer
825    is updated past the characters we use.  The value of the
826    escape sequence is returned.
827
828    RESULT_MASK is used to mask out the result;
829    an error is reported if bits are lost thereby.
830
831    A negative value means the sequence \ newline was seen,
832    which is supposed to be equivalent to nothing at all.
833
834    If \ is followed by a null character, we return a negative
835    value and leave the string pointer pointing at the null character.
836
837    If \ is followed by 000, we return 0 and leave the string pointer
838    after the zeros.  A value of 0 does not mean end of string.  */
839
840 HOST_WIDEST_INT
841 parse_escape (string_ptr, result_mask)
842      char **string_ptr;
843      HOST_WIDEST_INT result_mask;
844 {
845   register int c = *(*string_ptr)++;
846   switch (c)
847     {
848     case 'a':
849       return TARGET_BELL;
850     case 'b':
851       return TARGET_BS;
852     case 'e':
853     case 'E':
854       if (pedantic)
855         pedwarn ("non-ANSI-standard escape sequence, `\\%c'", c);
856       return 033;
857     case 'f':
858       return TARGET_FF;
859     case 'n':
860       return TARGET_NEWLINE;
861     case 'r':
862       return TARGET_CR;
863     case 't':
864       return TARGET_TAB;
865     case 'v':
866       return TARGET_VT;
867     case '\n':
868       return -2;
869     case 0:
870       (*string_ptr)--;
871       return 0;
872       
873     case '0':
874     case '1':
875     case '2':
876     case '3':
877     case '4':
878     case '5':
879     case '6':
880     case '7':
881       {
882         register HOST_WIDEST_INT i = c - '0';
883         register int count = 0;
884         while (++count < 3)
885           {
886             c = *(*string_ptr)++;
887             if (c >= '0' && c <= '7')
888               i = (i << 3) + c - '0';
889             else
890               {
891                 (*string_ptr)--;
892                 break;
893               }
894           }
895         if (i != (i & result_mask))
896           {
897             i &= result_mask;
898             pedwarn ("octal escape sequence out of range");
899           }
900         return i;
901       }
902     case 'x':
903       {
904         register unsigned HOST_WIDEST_INT i = 0, overflow = 0;
905         register int digits_found = 0, digit;
906         for (;;)
907           {
908             c = *(*string_ptr)++;
909             if (c >= '0' && c <= '9')
910               digit = c - '0';
911             else if (c >= 'a' && c <= 'f')
912               digit = c - 'a' + 10;
913             else if (c >= 'A' && c <= 'F')
914               digit = c - 'A' + 10;
915             else
916               {
917                 (*string_ptr)--;
918                 break;
919               }
920             overflow |= i ^ (i << 4 >> 4);
921             i = (i << 4) + digit;
922             digits_found = 1;
923           }
924         if (!digits_found)
925           yyerror ("\\x used with no following hex digits");
926         if (overflow | (i != (i & result_mask)))
927           {
928             i &= result_mask;
929             pedwarn ("hex escape sequence out of range");
930           }
931         return i;
932       }
933     default:
934       return c;
935     }
936 }
937
938 static void
939 integer_overflow ()
940 {
941   if (!skip_evaluation && pedantic)
942     pedwarn ("integer overflow in preprocessor expression");
943 }
944
945 static HOST_WIDEST_INT
946 left_shift (a, b)
947      struct constant *a;
948      unsigned HOST_WIDEST_INT b;
949 {
950    /* It's unclear from the C standard whether shifts can overflow.
951       The following code ignores overflow; perhaps a C standard
952       interpretation ruling is needed.  */
953   if (b >= HOST_BITS_PER_WIDEST_INT)
954     return 0;
955   else
956     return (unsigned HOST_WIDEST_INT) a->value << b;
957 }
958
959 static HOST_WIDEST_INT
960 right_shift (a, b)
961      struct constant *a;
962      unsigned HOST_WIDEST_INT b;
963 {
964   if (b >= HOST_BITS_PER_WIDEST_INT)
965     return a->signedp ? a->value >> (HOST_BITS_PER_WIDEST_INT - 1) : 0;
966   else if (a->signedp)
967     return a->value >> b;
968   else
969     return (unsigned HOST_WIDEST_INT) a->value >> b;
970 }
971 \f
972 /* This page contains the entry point to this file.  */
973
974 /* Parse STRING as an expression, and complain if this fails
975    to use up all of the contents of STRING.
976    STRING may contain '\0' bytes; it is terminated by the first '\n'
977    outside a string constant, so that we can diagnose '\0' properly.
978    If WARN_UNDEFINED is nonzero, warn if undefined identifiers are evaluated.
979    We do not support C comments.  They should be removed before
980    this function is called.  */
981
982 HOST_WIDEST_INT
983 parse_c_expression (string, warn_undefined)
984      char *string;
985      int warn_undefined;
986 {
987   lexptr = string;
988   warn_undef = warn_undefined;
989
990   /* if there is some sort of scanning error, just return 0 and assume
991      the parsing routine has printed an error message somewhere.
992      there is surely a better thing to do than this.     */
993   if (setjmp (parse_return_error))
994     return 0;
995
996   if (yyparse () != 0)
997     abort ();
998
999   if (*lexptr != '\n')
1000     error ("Junk after end of expression.");
1001
1002   return expression_value;      /* set by yyparse () */
1003 }
1004
1005 static void
1006 yyerror VPROTO ((const char * msgid, ...))
1007 {
1008 #ifndef ANSI_PROTOTYPES
1009   const char * msgid;
1010 #endif
1011   va_list args;
1012
1013   VA_START (args, msgid);
1014
1015 #ifndef ANSI_PROTOTYPES
1016   msgid = va_arg (args, const char *);
1017 #endif
1018
1019   verror (msgid, args);
1020   va_end (args);
1021   skip_evaluation = 0;
1022   longjmp (parse_return_error, 1);
1023 }
1024
1025 \f
1026 #ifdef TEST_EXP_READER
1027
1028 #if YYDEBUG
1029 extern int yydebug;
1030 #endif
1031
1032 int pedantic;
1033 int traditional;
1034 int c89;
1035
1036 int main PROTO((int, char **));
1037 static void initialize_random_junk PROTO((void));
1038 static void print_unsigned_host_widest_int PROTO((unsigned HOST_WIDEST_INT));
1039
1040 /* Main program for testing purposes.  */
1041 int
1042 main (argc, argv)
1043      int argc;
1044      char **argv;
1045 {
1046   int n, c;
1047   char buf[1024];
1048   unsigned HOST_WIDEST_INT u;
1049
1050   pedantic = 1 < argc;
1051   traditional = 2 < argc;
1052   c89 = 3 < argc;
1053 #if YYDEBUG
1054   yydebug = 4 < argc;
1055 #endif
1056   initialize_random_junk ();
1057
1058   for (;;) {
1059     printf ("enter expression: ");
1060     n = 0;
1061     while ((buf[n] = c = getchar ()) != '\n' && c != EOF)
1062       n++;
1063     if (c == EOF)
1064       break;
1065     parse_c_expression (buf, 1);
1066     printf ("parser returned ");
1067     u = (unsigned HOST_WIDEST_INT) expression_value;
1068     if (expression_value < 0 && expression_signedp) {
1069       u = -u;
1070       printf ("-");
1071     }
1072     if (u == 0)
1073       printf ("0");
1074     else
1075       print_unsigned_host_widest_int (u);
1076     if (! expression_signedp)
1077       printf("u");
1078     printf ("\n");
1079   }
1080
1081   return 0;
1082 }
1083
1084 static void
1085 print_unsigned_host_widest_int (u)
1086      unsigned HOST_WIDEST_INT u;
1087 {
1088   if (u) {
1089     print_unsigned_host_widest_int (u / 10);
1090     putchar ('0' + (int) (u % 10));
1091   }
1092 }
1093
1094 /* table to tell if char can be part of a C identifier. */
1095 unsigned char is_idchar[256];
1096 /* table to tell if char can be first char of a c identifier. */
1097 unsigned char is_idstart[256];
1098 /* table to tell if c is horizontal or vertical space.  */
1099 unsigned char is_space[256];
1100
1101 /*
1102  * initialize random junk in the hash table and maybe other places
1103  */
1104 static void
1105 initialize_random_junk ()
1106 {
1107   register int i;
1108
1109   /*
1110    * Set up is_idchar and is_idstart tables.  These should be
1111    * faster than saying (is_alpha (c) || c == '_'), etc.
1112    * Must do set up these things before calling any routines tthat
1113    * refer to them.
1114    */
1115   for (i = 'a'; i <= 'z'; i++) {
1116     ++is_idchar[i - 'a' + 'A'];
1117     ++is_idchar[i];
1118     ++is_idstart[i - 'a' + 'A'];
1119     ++is_idstart[i];
1120   }
1121   for (i = '0'; i <= '9'; i++)
1122     ++is_idchar[i];
1123   ++is_idchar['_'];
1124   ++is_idstart['_'];
1125   ++is_idchar['$'];
1126   ++is_idstart['$'];
1127
1128   ++is_space[' '];
1129   ++is_space['\t'];
1130   ++is_space['\v'];
1131   ++is_space['\f'];
1132   ++is_space['\n'];
1133   ++is_space['\r'];
1134 }
1135
1136 void
1137 error VPROTO ((char * msgid, ...))
1138 {
1139 #ifndef ANSI_PROTOTYPES
1140   char * msgid;
1141 #endif
1142   va_list args;
1143
1144   VA_START (args, msgid);
1145
1146 #ifndef ANSI_PROTOTYPES
1147   msgid = va_arg (args, char *);
1148 #endif
1149
1150   fprintf (stderr, "error: ");
1151   vfprintf (stderr, _(msgid), args);
1152   fprintf (stderr, "\n");
1153   va_end (args);
1154 }
1155
1156 void
1157 pedwarn VPROTO ((char * msgid, ...))
1158 {
1159 #ifndef ANSI_PROTOTYPES
1160   char * msgid;
1161 #endif
1162   va_list args;
1163
1164   VA_START (args, msgid);
1165
1166 #ifndef ANSI_PROTOTYPES
1167   msgid = va_arg (args, char *);
1168 #endif
1169
1170   fprintf (stderr, "pedwarn: ");
1171   vfprintf (stderr, _(msgid), args);
1172   fprintf (stderr, "\n");
1173   va_end (args);
1174 }
1175
1176 void
1177 warning VPROTO ((char * msgid, ...))
1178 {
1179 #ifndef ANSI_PROTOTYPES
1180   char * msgid;
1181 #endif
1182   va_list args;
1183
1184   VA_START (args, msgid);
1185
1186 #ifndef ANSI_PROTOTYPES
1187   msgid = va_arg (args, char *);
1188 #endif
1189
1190   fprintf (stderr, "warning: ");
1191   vfprintf (stderr, _(msgid), args);
1192   fprintf (stderr, "\n");
1193   va_end (args);
1194 }
1195
1196
1197 int
1198 check_assertion (name, sym_length, tokens_specified, tokens)
1199      U_CHAR *name;
1200      int sym_length;
1201      int tokens_specified;
1202      struct arglist *tokens;
1203 {
1204   return 0;
1205 }
1206
1207 struct hashnode *
1208 lookup (name, len, hash)
1209      U_CHAR *name;
1210      int len;
1211      int hash;
1212 {
1213   return (DEFAULT_SIGNED_CHAR) ? 0 : ((struct hashnode *) -1);
1214 }
1215
1216 PTR
1217 xmalloc (size)
1218   size_t size;
1219 {
1220   return (PTR) malloc (size);
1221 }
1222 #endif