cexp.y 28.3 KB
Newer Older
Charles Hannum committed
1
/* Parse C expressions for CCCP.
2
   Copyright (C) 1987, 92, 94-98, 1999 Free Software Foundation.
Charles Hannum committed
3 4 5 6 7 8 9 10 11 12 13 14 15

This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Richard Kenner committed
16 17
Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
Charles Hannum committed
18 19 20 21 22

 In other words, you are welcome to use, share and improve this program.
 You are forbidden to forbid anyone else to use, share and improve
 what you give them.   Help stamp out software-hoarding!

Richard Stallman committed
23
 Adapted from expread.y of GDB by Paul Rubin, July 1986.  */
Charles Hannum committed
24 25 26 27 28

/* Parse a C expression from text in a string  */
   
%{
#include "config.h"
29

30
#include "system.h"
31
#include "intl.h"
32 33
#include <setjmp.h>
/* #define YYDEBUG 1 */
Jeff Law committed
34

Charles Hannum committed
35
#ifdef MULTIBYTE_CHARS
36
#include "mbchar.h"
Charles Hannum committed
37
#include <locale.h>
38
#endif /* MULTIBYTE_CHARS */
39

Charles Hannum committed
40 41 42 43 44 45 46 47 48 49
typedef unsigned char U_CHAR;

/* This is used for communicating lists of keywords with cccp.c.  */
struct arglist {
  struct arglist *next;
  U_CHAR *name;
  int length;
  int argno;
};

50
HOST_WIDEST_INT parse_c_expression PROTO((char *, int));
51 52

static int yylex PROTO((void));
53 54
static void yyerror PVPROTO((const char *, ...))
  ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
55
static HOST_WIDEST_INT expression_value;
Jeff Law committed
56 57 58
#ifdef TEST_EXP_READER
static int expression_signedp;
#endif
Charles Hannum committed
59 60 61 62 63 64

static jmp_buf parse_return_error;

/* Nonzero means count most punctuation as part of a name.  */
static int keyword_parsing = 0;

65 66 67 68
/* Nonzero means do not evaluate this expression.
   This is a count, since unevaluated expressions can nest.  */
static int skip_evaluation;

Jeff Law committed
69 70 71
/* Nonzero means warn if undefined identifiers are evaluated.  */
static int warn_undef;

Charles Hannum committed
72
/* some external tables of character types */
73
extern unsigned char is_idstart[], is_idchar[], is_space[];
Charles Hannum committed
74 75 76 77 78 79 80

/* Flag for -pedantic.  */
extern int pedantic;

/* Flag for -traditional.  */
extern int traditional;

81 82 83
/* Flag for -lang-c89.  */
extern int c89;

Charles Hannum committed
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
#ifndef CHAR_TYPE_SIZE
#define CHAR_TYPE_SIZE BITS_PER_UNIT
#endif

#ifndef INT_TYPE_SIZE
#define INT_TYPE_SIZE BITS_PER_WORD
#endif

#ifndef LONG_TYPE_SIZE
#define LONG_TYPE_SIZE BITS_PER_WORD
#endif

#ifndef WCHAR_TYPE_SIZE
#define WCHAR_TYPE_SIZE INT_TYPE_SIZE
#endif
99

100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
#ifndef MAX_CHAR_TYPE_SIZE
#define MAX_CHAR_TYPE_SIZE CHAR_TYPE_SIZE
#endif

#ifndef MAX_INT_TYPE_SIZE
#define MAX_INT_TYPE_SIZE INT_TYPE_SIZE
#endif

#ifndef MAX_LONG_TYPE_SIZE
#define MAX_LONG_TYPE_SIZE LONG_TYPE_SIZE
#endif

#ifndef MAX_WCHAR_TYPE_SIZE
#define MAX_WCHAR_TYPE_SIZE WCHAR_TYPE_SIZE
#endif

116 117 118
#define MAX_CHAR_TYPE_MASK (MAX_CHAR_TYPE_SIZE < HOST_BITS_PER_WIDEST_INT \
			    ? (~ (~ (HOST_WIDEST_INT) 0 << MAX_CHAR_TYPE_SIZE)) \
			    : ~ (HOST_WIDEST_INT) 0)
119

120 121 122
#define MAX_WCHAR_TYPE_MASK (MAX_WCHAR_TYPE_SIZE < HOST_BITS_PER_WIDEST_INT \
			     ? ~ (~ (HOST_WIDEST_INT) 0 << MAX_WCHAR_TYPE_SIZE) \
			     : ~ (HOST_WIDEST_INT) 0)
123

124 125 126 127 128 129 130 131 132 133 134 135
/* Suppose A1 + B1 = SUM1, using 2's complement arithmetic ignoring overflow.
   Suppose A, B and SUM have the same respective signs as A1, B1, and SUM1.
   Suppose SIGNEDP is negative if the result is signed, zero if unsigned.
   Then this yields nonzero if overflow occurred during the addition.
   Overflow occurs if A and B have the same sign, but A and SUM differ in sign,
   and SIGNEDP is negative.
   Use `^' to test whether signs differ, and `< 0' to isolate the sign.  */
#define overflow_sum_sign(a, b, sum, signedp) \
	((~((a) ^ (b)) & ((a) ^ (sum)) & (signedp)) < 0)

struct constant;

136
HOST_WIDEST_INT parse_escape PROTO((char **, HOST_WIDEST_INT));
137 138
int check_assertion PROTO((U_CHAR *, int, int, struct arglist *));
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 142
void pedwarn PVPROTO((const char *, ...)) ATTRIBUTE_PRINTF_1;
void warning PVPROTO((const char *, ...)) ATTRIBUTE_PRINTF_1;
143 144

static int parse_number PROTO((int));
145 146
static HOST_WIDEST_INT left_shift PROTO((struct constant *, unsigned HOST_WIDEST_INT));
static HOST_WIDEST_INT right_shift PROTO((struct constant *, unsigned HOST_WIDEST_INT));
147 148 149 150 151
static void integer_overflow PROTO((void));

/* `signedp' values */
#define SIGNED (~0)
#define UNSIGNED 0
Charles Hannum committed
152 153 154
%}

%union {
155
  struct constant {HOST_WIDEST_INT value; int signedp;} integer;
Charles Hannum committed
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184
  struct name {U_CHAR *address; int length;} name;
  struct arglist *keywords;
}

%type <integer> exp exp1 start
%type <keywords> keywords
%token <integer> INT CHAR
%token <name> NAME
%token <integer> ERROR

%right '?' ':'
%left ','
%left OR
%left AND
%left '|'
%left '^'
%left '&'
%left EQUAL NOTEQUAL
%left '<' '>' LEQ GEQ
%left LSH RSH
%left '+' '-'
%left '*' '/' '%'
%right UNARY

/* %expect 40 */

%%

start   :	exp1
Jeff Law committed
185 186 187 188 189 190
		{
		  expression_value = $1.value;
#ifdef TEST_EXP_READER
		  expression_signedp = $1.signedp;
#endif
		}
Charles Hannum committed
191 192 193 194 195 196 197 198 199 200 201 202 203
	;

/* Expressions, including the comma operator.  */
exp1	:	exp
	|	exp1 ',' exp
			{ if (pedantic)
			    pedwarn ("comma operator in operand of `#if'");
			  $$ = $3; }
	;

/* Expressions, not including the comma operator.  */
exp	:	'-' exp    %prec UNARY
			{ $$.value = - $2.value;
204 205 206
			  $$.signedp = $2.signedp;
			  if (($$.value & $2.value & $$.signedp) < 0)
			    integer_overflow (); }
Charles Hannum committed
207 208
	|	'!' exp    %prec UNARY
			{ $$.value = ! $2.value;
209
			  $$.signedp = SIGNED; }
Charles Hannum committed
210 211 212 213
	|	'+' exp    %prec UNARY
			{ $$ = $2; }
	|	'~' exp    %prec UNARY
			{ $$.value = ~ $2.value;
214
			  $$.signedp = $2.signedp; }
Charles Hannum committed
215 216 217
	|	'#' NAME
  			{ $$.value = check_assertion ($2.address, $2.length,
						      0, NULL_PTR);
218
			  $$.signedp = SIGNED; }
Charles Hannum committed
219 220 221 222 223 224
	|	'#' NAME
			{ keyword_parsing = 1; }
		'(' keywords ')'
  			{ $$.value = check_assertion ($2.address, $2.length,
						      1, $5);
			  keyword_parsing = 0;
225
			  $$.signedp = SIGNED; }
Charles Hannum committed
226 227 228 229 230 231
	|	'(' exp1 ')'
			{ $$ = $2; }
	;

/* Binary operators in order of decreasing precedence.  */
exp	:	exp '*' exp
232 233
			{ $$.signedp = $1.signedp & $3.signedp;
			  if ($$.signedp)
234 235 236 237 238 239
			    {
			      $$.value = $1.value * $3.value;
			      if ($1.value
				  && ($$.value / $1.value != $3.value
				      || ($$.value & $1.value & $3.value) < 0))
				integer_overflow ();
240 241
			    }
			  else
242
			    $$.value = ((unsigned HOST_WIDEST_INT) $1.value
243
					* $3.value); }
Charles Hannum committed
244 245 246
	|	exp '/' exp
			{ if ($3.value == 0)
			    {
247 248
			      if (!skip_evaluation)
				error ("division by zero in #if");
Charles Hannum committed
249 250
			      $3.value = 1;
			    }
251 252
			  $$.signedp = $1.signedp & $3.signedp;
			  if ($$.signedp)
253 254 255 256
			    {
			      $$.value = $1.value / $3.value;
			      if (($$.value & $1.value & $3.value) < 0)
				integer_overflow ();
257 258
			    }
			  else
259
			    $$.value = ((unsigned HOST_WIDEST_INT) $1.value
260
					/ $3.value); }
Charles Hannum committed
261 262 263
	|	exp '%' exp
			{ if ($3.value == 0)
			    {
264 265
			      if (!skip_evaluation)
				error ("division by zero in #if");
Charles Hannum committed
266 267
			      $3.value = 1;
			    }
268 269 270
			  $$.signedp = $1.signedp & $3.signedp;
			  if ($$.signedp)
			    $$.value = $1.value % $3.value;
Charles Hannum committed
271
			  else
272
			    $$.value = ((unsigned HOST_WIDEST_INT) $1.value
273
					% $3.value); }
Charles Hannum committed
274 275
	|	exp '+' exp
			{ $$.value = $1.value + $3.value;
276 277 278
			  $$.signedp = $1.signedp & $3.signedp;
			  if (overflow_sum_sign ($1.value, $3.value,
						 $$.value, $$.signedp))
279
			    integer_overflow (); }
Charles Hannum committed
280 281
	|	exp '-' exp
			{ $$.value = $1.value - $3.value;
282 283 284
			  $$.signedp = $1.signedp & $3.signedp;
			  if (overflow_sum_sign ($$.value, $3.value,
						 $1.value, $$.signedp))
285
			    integer_overflow (); }
Charles Hannum committed
286
	|	exp LSH exp
287 288
			{ $$.signedp = $1.signedp;
			  if (($3.value & $3.signedp) < 0)
289
			    $$.value = right_shift (&$1, -$3.value);
Charles Hannum committed
290
			  else
291
			    $$.value = left_shift (&$1, $3.value); }
Charles Hannum committed
292
	|	exp RSH exp
293 294
			{ $$.signedp = $1.signedp;
			  if (($3.value & $3.signedp) < 0)
295
			    $$.value = left_shift (&$1, -$3.value);
Charles Hannum committed
296
			  else
297
			    $$.value = right_shift (&$1, $3.value); }
Charles Hannum committed
298 299
	|	exp EQUAL exp
			{ $$.value = ($1.value == $3.value);
300
			  $$.signedp = SIGNED; }
Charles Hannum committed
301 302
	|	exp NOTEQUAL exp
			{ $$.value = ($1.value != $3.value);
303
			  $$.signedp = SIGNED; }
Charles Hannum committed
304
	|	exp LEQ exp
305 306 307
			{ $$.signedp = SIGNED;
			  if ($1.signedp & $3.signedp)
			    $$.value = $1.value <= $3.value;
Charles Hannum committed
308
			  else
309
			    $$.value = ((unsigned HOST_WIDEST_INT) $1.value
310
					<= $3.value); }
Charles Hannum committed
311
	|	exp GEQ exp
312 313 314
			{ $$.signedp = SIGNED;
			  if ($1.signedp & $3.signedp)
			    $$.value = $1.value >= $3.value;
Charles Hannum committed
315
			  else
316
			    $$.value = ((unsigned HOST_WIDEST_INT) $1.value
317
					>= $3.value); }
Charles Hannum committed
318
	|	exp '<' exp
319 320 321
			{ $$.signedp = SIGNED;
			  if ($1.signedp & $3.signedp)
			    $$.value = $1.value < $3.value;
Charles Hannum committed
322
			  else
323
			    $$.value = ((unsigned HOST_WIDEST_INT) $1.value
324
					< $3.value); }
Charles Hannum committed
325
	|	exp '>' exp
326 327 328
			{ $$.signedp = SIGNED;
			  if ($1.signedp & $3.signedp)
			    $$.value = $1.value > $3.value;
Charles Hannum committed
329
			  else
330
			    $$.value = ((unsigned HOST_WIDEST_INT) $1.value
331
					> $3.value); }
Charles Hannum committed
332 333
	|	exp '&' exp
			{ $$.value = $1.value & $3.value;
334
			  $$.signedp = $1.signedp & $3.signedp; }
Charles Hannum committed
335 336
	|	exp '^' exp
			{ $$.value = $1.value ^ $3.value;
337
			  $$.signedp = $1.signedp & $3.signedp; }
Charles Hannum committed
338 339
	|	exp '|' exp
			{ $$.value = $1.value | $3.value;
340
			  $$.signedp = $1.signedp & $3.signedp; }
341 342 343 344 345
	|	exp AND
			{ skip_evaluation += !$1.value; }
		exp
			{ skip_evaluation -= !$1.value;
			  $$.value = ($1.value && $4.value);
346
			  $$.signedp = SIGNED; }
347 348 349 350 351
	|	exp OR
			{ skip_evaluation += !!$1.value; }
		exp
			{ skip_evaluation -= !!$1.value;
			  $$.value = ($1.value || $4.value);
352
			  $$.signedp = SIGNED; }
353 354 355 356 357 358 359
	|	exp '?'
			{ skip_evaluation += !$1.value; }
	        exp ':'
			{ skip_evaluation += !!$1.value - !$1.value; }
		exp
			{ skip_evaluation -= !!$1.value;
			  $$.value = $1.value ? $4.value : $7.value;
360
			  $$.signedp = $4.signedp & $7.signedp; }
Charles Hannum committed
361 362 363 364 365
	|	INT
			{ $$ = yylval.integer; }
	|	CHAR
			{ $$ = yylval.integer; }
	|	NAME
366 367 368 369
			{ if (warn_undef && !skip_evaluation)
			    warning ("`%.*s' is not defined",
				     $1.length, $1.address);
			  $$.value = 0;
370
			  $$.signedp = SIGNED; }
Charles Hannum committed
371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406
	;

keywords :
			{ $$ = 0; } 
	|	'(' keywords ')' keywords
			{ struct arglist *temp;
			  $$ = (struct arglist *) xmalloc (sizeof (struct arglist));
			  $$->next = $2;
			  $$->name = (U_CHAR *) "(";
			  $$->length = 1;
			  temp = $$;
			  while (temp != 0 && temp->next != 0)
			    temp = temp->next;
			  temp->next = (struct arglist *) xmalloc (sizeof (struct arglist));
			  temp->next->next = $4;
			  temp->next->name = (U_CHAR *) ")";
			  temp->next->length = 1; }
	|	NAME keywords
			{ $$ = (struct arglist *) xmalloc (sizeof (struct arglist));
			  $$->name = $1.address;
			  $$->length = $1.length;
			  $$->next = $2; } 
	;
%%

/* During parsing of a C expression, the pointer to the next character
   is in this variable.  */

static char *lexptr;

/* Take care of parsing a number (anything that starts with a digit).
   Set yylval and return the token type; update lexptr.
   LEN is the number of characters in it.  */

/* maybe needs to actually deal with floating point numbers */

407
static int
Charles Hannum committed
408 409 410 411 412
parse_number (olen)
     int olen;
{
  register char *p = lexptr;
  register int c;
413
  register unsigned HOST_WIDEST_INT n = 0, nd, max_over_base;
Charles Hannum committed
414 415
  register int base = 10;
  register int len = olen;
416
  register int overflow = 0;
417
  register int digit, largest_digit = 0;
418
  int spec_long = 0;
Charles Hannum committed
419

420
  yylval.integer.signedp = SIGNED;
Charles Hannum committed
421

422
  if (*p == '0') {
Charles Hannum committed
423
    base = 8;
424 425 426 427 428 429
    if (len >= 3 && (p[1] == 'x' || p[1] == 'X')) {
      p += 2;
      base = 16;
      len -= 2;
    }
  }
Charles Hannum committed
430

431
  max_over_base = (unsigned HOST_WIDEST_INT) -1 / base;
432 433

  for (; len > 0; len--) {
Charles Hannum committed
434
    c = *p++;
435 436 437 438 439 440 441 442

    if (c >= '0' && c <= '9')
      digit = c - '0';
    else if (base == 16 && c >= 'a' && c <= 'f')
      digit = c - 'a' + 10;
    else if (base == 16 && c >= 'A' && c <= 'F')
      digit = c - 'A' + 10;
    else {
Charles Hannum committed
443 444 445
      /* `l' means long, and `u' means unsigned.  */
      while (1) {
	if (c == 'l' || c == 'L')
446
	  {
447 448 449
	    if (!pedantic < spec_long)
	      yyerror ("too many `l's in integer constant");
	    spec_long++;
450
	  }
Charles Hannum committed
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 461
	  else
	    yyerror ("missing white space after number `%.*s'",
462 463
		     (int) (p - lexptr - 1), lexptr);
	}
Charles Hannum committed
464

465
	if (--len == 0)
Charles Hannum committed
466 467 468 469 470 471
	  break;
	c = *p++;
      }
      /* Don't look for any more digits after the suffixes.  */
      break;
    }
472 473 474
    if (largest_digit < digit)
      largest_digit = digit;
    nd = n * base + digit;
475
    overflow |= (max_over_base < n) | (nd < n);
476
    n = nd;
Charles Hannum committed
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

Charles Hannum committed
485
  /* If too big to be signed, consider it unsigned.  */
486
  if (((HOST_WIDEST_INT) n & yylval.integer.signedp) < 0)
487 488 489
    {
      if (base == 10)
	warning ("integer constant is so large that it is unsigned");
490
      yylval.integer.signedp = UNSIGNED;
491
    }
Charles Hannum committed
492 493 494 495 496 497 498

  lexptr = p;
  yylval.integer.value = n;
  return INT;
}

struct token {
499
  const char *operator;
Charles Hannum committed
500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518
  int token;
};

static struct token tokentab2[] = {
  {"&&", AND},
  {"||", OR},
  {"<<", LSH},
  {">>", RSH},
  {"==", EQUAL},
  {"!=", NOTEQUAL},
  {"<=", LEQ},
  {">=", GEQ},
  {"++", ERROR},
  {"--", ERROR},
  {NULL, ERROR}
};

/* Read one token, getting characters through lexptr.  */

519
static int
Charles Hannum committed
520 521 522 523
yylex ()
{
  register int c;
  register int namelen;
524
  register unsigned char *tokstart;
Charles Hannum committed
525 526
  register struct token *toktab;
  int wide_flag;
527
  HOST_WIDEST_INT mask;
Charles Hannum committed
528 529 530

 retry:

531
  tokstart = (unsigned char *) lexptr;
Charles Hannum committed
532 533 534 535 536 537 538
  c = *tokstart;
  /* See if it is a special token of length 2.  */
  if (! keyword_parsing)
    for (toktab = tokentab2; toktab->operator != NULL; toktab++)
      if (c == *toktab->operator && tokstart[1] == toktab->operator[1]) {
	lexptr += 2;
	if (toktab->token == ERROR)
539
	  yyerror ("`%s' not allowed in operand of `#if'", toktab->operator);
Charles Hannum committed
540 541 542 543
	return toktab->token;
      }

  switch (c) {
544
  case '\n':
Charles Hannum committed
545 546 547 548 549 550 551 552 553 554 555 556 557 558
    return 0;
    
  case ' ':
  case '\t':
  case '\r':
    lexptr++;
    goto retry;
    
  case 'L':
    /* Capital L may start a wide-string or wide-character constant.  */
    if (lexptr[1] == '\'')
      {
	lexptr++;
	wide_flag = 1;
559
	mask = MAX_WCHAR_TYPE_MASK;
Charles Hannum committed
560 561 562 563 564 565
	goto char_constant;
      }
    if (lexptr[1] == '"')
      {
	lexptr++;
	wide_flag = 1;
566
	mask = MAX_WCHAR_TYPE_MASK;
Charles Hannum committed
567 568 569 570 571 572
	goto string_constant;
      }
    break;

  case '\'':
    wide_flag = 0;
573
    mask = MAX_CHAR_TYPE_MASK;
Charles Hannum committed
574 575 576 577 578 579 580
  char_constant:
    lexptr++;
    if (keyword_parsing) {
      char *start_ptr = lexptr - 1;
      while (1) {
	c = *lexptr++;
	if (c == '\\')
581
	  c = parse_escape (&lexptr, mask);
Charles Hannum committed
582 583 584
	else if (c == '\'')
	  break;
      }
585
      yylval.name.address = tokstart;
Charles Hannum committed
586 587 588 589 590 591 592 593
      yylval.name.length = lexptr - start_ptr;
      return NAME;
    }

    /* This code for reading a character constant
       handles multicharacter constants and wide characters.
       It is mostly copied from c-lex.c.  */
    {
594
      register HOST_WIDEST_INT result = 0;
Jeff Law committed
595
      register int num_chars = 0;
596
      int chars_seen = 0;
597
      unsigned width = MAX_CHAR_TYPE_SIZE;
Charles Hannum committed
598 599
      int max_chars;
#ifdef MULTIBYTE_CHARS
600 601 602
      int longest_char = local_mb_cur_max ();
      char *token_buffer = (char *) alloca (longest_char);
      (void) local_mbtowc (NULL_PTR, NULL_PTR, 0);
Charles Hannum committed
603 604
#endif

605 606 607
      max_chars = MAX_LONG_TYPE_SIZE / width;
      if (wide_flag)
	width = MAX_WCHAR_TYPE_SIZE;
Charles Hannum committed
608 609 610 611 612 613 614 615

      while (1)
	{
	  c = *lexptr++;

	  if (c == '\'' || c == EOF)
	    break;

616
	  ++chars_seen;
Charles Hannum committed
617 618
	  if (c == '\\')
	    {
619
	      c = parse_escape (&lexptr, mask);
Charles Hannum committed
620
	    }
621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666
	  else
	    {
#ifdef MULTIBYTE_CHARS
	      wchar_t wc;
	      int i;
	      int char_len = -1;
	      for (i = 1; i <= longest_char; ++i)
		{
		  token_buffer[i - 1] = c;
		  char_len = local_mbtowc (& wc, token_buffer, i);
		  if (char_len != -1)
		    break;
		  c = *lexptr++;
		}
	      if (char_len > 1)
		{
		  /* mbtowc sometimes needs an extra char before accepting */
		  if (char_len < i)
		    lexptr--;
		  if (! wide_flag)
		    {
		      /* Merge character into result; ignore excess chars.  */
		      for (i = 1; i <= char_len; ++i)
			{
			  if (i > max_chars)
			    break;
			  if (width < HOST_BITS_PER_INT)
			    result = (result << width)
			      | (token_buffer[i - 1]
				 & ((1 << width) - 1));
			  else
			    result = token_buffer[i - 1];
			}
		      num_chars += char_len;
		      continue;
		    }
		}
	      else
		{
		  if (char_len == -1)
		    warning ("Ignoring invalid multibyte character");
		}
	      if (wide_flag)
		c = wc;
#endif /* ! MULTIBYTE_CHARS */
	    }
Charles Hannum committed
667

668 669 670 671 672 673
	  if (wide_flag)
	    {
	      if (chars_seen == 1) /* only keep the first one */
		result = c;
	      continue;
	    }
Charles Hannum committed
674 675

	  /* Merge character into result; ignore excess chars.  */
676
	  num_chars++;
677
	  if (num_chars <= max_chars)
Charles Hannum committed
678
	    {
679 680
	      if (width < HOST_BITS_PER_INT)
		result = (result << width) | (c & ((1 << width) - 1));
Charles Hannum committed
681 682 683 684 685 686 687
	      else
		result = c;
	    }
	}

      if (c != '\'')
	error ("malformatted character constant");
688
      else if (chars_seen == 0)
Charles Hannum committed
689 690 691 692 693 694
	error ("empty character constant");
      else if (num_chars > max_chars)
	{
	  num_chars = max_chars;
	  error ("character constant too long");
	}
695
      else if (chars_seen != 1 && ! traditional)
Charles Hannum committed
696 697 698 699 700 701
	warning ("multi-character character constant");

      /* If char type is signed, sign-extend the constant.  */
      if (! wide_flag)
	{
	  int num_bits = num_chars * width;
702 703 704 705
	  if (num_bits == 0)
	    /* We already got an error; avoid invalid shift.  */
	    yylval.integer.value = 0;
	  else if (lookup ((U_CHAR *) "__CHAR_UNSIGNED__",
706
		      sizeof ("__CHAR_UNSIGNED__") - 1, -1)
Charles Hannum committed
707 708
	      || ((result >> (num_bits - 1)) & 1) == 0)
	    yylval.integer.value
709 710
	      = result & (~ (unsigned HOST_WIDEST_INT) 0
			  >> (HOST_BITS_PER_WIDEST_INT - num_bits));
Charles Hannum committed
711 712
	  else
	    yylval.integer.value
713 714
	      = result | ~(~ (unsigned HOST_WIDEST_INT) 0
			   >> (HOST_BITS_PER_WIDEST_INT - num_bits));
Charles Hannum committed
715 716 717 718 719 720 721 722
	}
      else
	{
	  yylval.integer.value = result;
	}
    }

    /* This is always a signed type.  */
723
    yylval.integer.signedp = SIGNED;
Charles Hannum committed
724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759
    
    return CHAR;

    /* some of these chars are invalid in constant expressions;
       maybe do something about them later */
  case '/':
  case '+':
  case '-':
  case '*':
  case '%':
  case '|':
  case '&':
  case '^':
  case '~':
  case '!':
  case '@':
  case '<':
  case '>':
  case '[':
  case ']':
  case '.':
  case '?':
  case ':':
  case '=':
  case '{':
  case '}':
  case ',':
  case '#':
    if (keyword_parsing)
      break;
  case '(':
  case ')':
    lexptr++;
    return c;

  case '"':
760
    mask = MAX_CHAR_TYPE_MASK;
Charles Hannum committed
761 762 763 764 765 766 767
  string_constant:
    if (keyword_parsing) {
      char *start_ptr = lexptr;
      lexptr++;
      while (1) {
	c = *lexptr++;
	if (c == '\\')
768
	  c = parse_escape (&lexptr, mask);
Charles Hannum committed
769 770 771
	else if (c == '"')
	  break;
      }
772
      yylval.name.address = tokstart;
Charles Hannum committed
773 774 775 776 777 778 779 780 781
      yylval.name.length = lexptr - start_ptr;
      return NAME;
    }
    yyerror ("string constants not allowed in #if expressions");
    return ERROR;
  }

  if (c >= '0' && c <= '9' && !keyword_parsing) {
    /* It's a number */
782 783 784
    for (namelen = 1; ; namelen++) {
      int d = tokstart[namelen];
      if (! ((is_idchar[d] || d == '.')
785 786 787
	     || ((d == '-' || d == '+')
		 && (c == 'e' || c == 'E'
		     || ((c == 'p' || c == 'P') && ! c89))
788 789 790 791
		 && ! traditional)))
	break;
      c = d;
    }
Charles Hannum committed
792 793 794 795 796 797 798
    return parse_number (namelen);
  }

  /* It is a name.  See how long it is.  */

  if (keyword_parsing) {
    for (namelen = 0;; namelen++) {
799
      if (is_space[tokstart[namelen]])
Charles Hannum committed
800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816
	break;
      if (tokstart[namelen] == '(' || tokstart[namelen] == ')')
	break;
      if (tokstart[namelen] == '"' || tokstart[namelen] == '\'')
	break;
    }
  } else {
    if (!is_idstart[c]) {
      yyerror ("Invalid token in expression");
      return ERROR;
    }

    for (namelen = 0; is_idchar[tokstart[namelen]]; namelen++)
      ;
  }
  
  lexptr += namelen;
817
  yylval.name.address = tokstart;
Charles Hannum committed
818 819 820 821 822 823 824 825 826 827
  yylval.name.length = namelen;
  return NAME;
}


/* Parse a C escape sequence.  STRING_PTR points to a variable
   containing a pointer to the string to parse.  That pointer
   is updated past the characters we use.  The value of the
   escape sequence is returned.

828 829 830
   RESULT_MASK is used to mask out the result;
   an error is reported if bits are lost thereby.

Charles Hannum committed
831 832 833 834 835 836 837 838 839
   A negative value means the sequence \ newline was seen,
   which is supposed to be equivalent to nothing at all.

   If \ is followed by a null character, we return a negative
   value and leave the string pointer pointing at the null character.

   If \ is followed by 000, we return 0 and leave the string pointer
   after the zeros.  A value of 0 does not mean end of string.  */

840
HOST_WIDEST_INT
841
parse_escape (string_ptr, result_mask)
Charles Hannum committed
842
     char **string_ptr;
843
     HOST_WIDEST_INT result_mask;
Charles Hannum committed
844 845 846 847 848 849 850 851 852
{
  register int c = *(*string_ptr)++;
  switch (c)
    {
    case 'a':
      return TARGET_BELL;
    case 'b':
      return TARGET_BS;
    case 'e':
853 854 855
    case 'E':
      if (pedantic)
	pedwarn ("non-ANSI-standard escape sequence, `\\%c'", c);
Charles Hannum committed
856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881
      return 033;
    case 'f':
      return TARGET_FF;
    case 'n':
      return TARGET_NEWLINE;
    case 'r':
      return TARGET_CR;
    case 't':
      return TARGET_TAB;
    case 'v':
      return TARGET_VT;
    case '\n':
      return -2;
    case 0:
      (*string_ptr)--;
      return 0;
      
    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
      {
882
	register HOST_WIDEST_INT i = c - '0';
Charles Hannum committed
883 884 885 886 887 888 889 890 891 892 893 894
	register int count = 0;
	while (++count < 3)
	  {
	    c = *(*string_ptr)++;
	    if (c >= '0' && c <= '7')
	      i = (i << 3) + c - '0';
	    else
	      {
		(*string_ptr)--;
		break;
	      }
	  }
895
	if (i != (i & result_mask))
Charles Hannum committed
896
	  {
897 898
	    i &= result_mask;
	    pedwarn ("octal escape sequence out of range");
Charles Hannum committed
899 900 901 902 903
	  }
	return i;
      }
    case 'x':
      {
904
	register unsigned HOST_WIDEST_INT i = 0, overflow = 0;
905
	register int digits_found = 0, digit;
Charles Hannum committed
906 907 908 909
	for (;;)
	  {
	    c = *(*string_ptr)++;
	    if (c >= '0' && c <= '9')
910
	      digit = c - '0';
Charles Hannum committed
911
	    else if (c >= 'a' && c <= 'f')
912
	      digit = c - 'a' + 10;
Charles Hannum committed
913
	    else if (c >= 'A' && c <= 'F')
914
	      digit = c - 'A' + 10;
Charles Hannum committed
915 916 917 918 919
	    else
	      {
		(*string_ptr)--;
		break;
	      }
920 921 922
	    overflow |= i ^ (i << 4 >> 4);
	    i = (i << 4) + digit;
	    digits_found = 1;
Charles Hannum committed
923
	  }
924 925
	if (!digits_found)
	  yyerror ("\\x used with no following hex digits");
926
	if (overflow | (i != (i & result_mask)))
Charles Hannum committed
927
	  {
928 929
	    i &= result_mask;
	    pedwarn ("hex escape sequence out of range");
Charles Hannum committed
930 931 932 933 934 935 936 937
	  }
	return i;
      }
    default:
      return c;
    }
}

938
static void
939 940
integer_overflow ()
{
941
  if (!skip_evaluation && pedantic)
942
    pedwarn ("integer overflow in preprocessor expression");
943 944
}

945
static HOST_WIDEST_INT
946 947
left_shift (a, b)
     struct constant *a;
948
     unsigned HOST_WIDEST_INT b;
949
{
950 951 952
   /* It's unclear from the C standard whether shifts can overflow.
      The following code ignores overflow; perhaps a C standard
      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 961
right_shift (a, b)
     struct constant *a;
962
     unsigned HOST_WIDEST_INT b;
963
{
964 965
  if (b >= HOST_BITS_PER_WIDEST_INT)
    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
}
Charles Hannum committed
971 972 973 974

/* This page contains the entry point to this file.  */

/* Parse STRING as an expression, and complain if this fails
Jeff Law committed
975 976 977 978 979
   to use up all of the contents of STRING.
   STRING may contain '\0' bytes; it is terminated by the first '\n'
   outside a string constant, so that we can diagnose '\0' properly.
   If WARN_UNDEFINED is nonzero, warn if undefined identifiers are evaluated.
   We do not support C comments.  They should be removed before
Charles Hannum committed
980 981
   this function is called.  */

982
HOST_WIDEST_INT
Jeff Law committed
983
parse_c_expression (string, warn_undefined)
Charles Hannum committed
984
     char *string;
Jeff Law committed
985
     int warn_undefined;
Charles Hannum committed
986 987
{
  lexptr = string;
Jeff Law committed
988
  warn_undef = warn_undefined;
Charles Hannum committed
989 990 991 992 993 994 995

  /* if there is some sort of scanning error, just return 0 and assume
     the parsing routine has printed an error message somewhere.
     there is surely a better thing to do than this.     */
  if (setjmp (parse_return_error))
    return 0;

996 997 998
  if (yyparse () != 0)
    abort ();

999
  if (*lexptr != '\n')
Charles Hannum committed
1000 1001 1002 1003
    error ("Junk after end of expression.");

  return expression_value;	/* set by yyparse () */
}
1004 1005

static void
1006
yyerror VPROTO ((const char * msgid, ...))
1007 1008
{
#ifndef ANSI_PROTOTYPES
1009
  const char * msgid;
1010 1011 1012 1013 1014 1015
#endif
  va_list args;

  VA_START (args, msgid);

#ifndef ANSI_PROTOTYPES
1016
  msgid = va_arg (args, const char *);
1017 1018
#endif

1019
  verror (msgid, args);
1020 1021 1022 1023 1024
  va_end (args);
  skip_evaluation = 0;
  longjmp (parse_return_error, 1);
}

Charles Hannum committed
1025 1026

#ifdef TEST_EXP_READER
1027 1028

#if YYDEBUG
Charles Hannum committed
1029
extern int yydebug;
1030 1031 1032 1033
#endif

int pedantic;
int traditional;
1034
int c89;
1035 1036 1037

int main PROTO((int, char **));
static void initialize_random_junk PROTO((void));
1038
static void print_unsigned_host_widest_int PROTO((unsigned HOST_WIDEST_INT));
Charles Hannum committed
1039 1040 1041

/* Main program for testing purposes.  */
int
1042 1043 1044
main (argc, argv)
     int argc;
     char **argv;
Charles Hannum committed
1045 1046 1047
{
  int n, c;
  char buf[1024];
1048
  unsigned HOST_WIDEST_INT u;
Charles Hannum committed
1049

1050 1051
  pedantic = 1 < argc;
  traditional = 2 < argc;
1052
  c89 = 3 < argc;
1053
#if YYDEBUG
1054
  yydebug = 4 < argc;
1055
#endif
Charles Hannum committed
1056 1057 1058 1059 1060
  initialize_random_junk ();

  for (;;) {
    printf ("enter expression: ");
    n = 0;
1061
    while ((buf[n] = c = getchar ()) != '\n' && c != EOF)
Charles Hannum committed
1062
      n++;
1063
    if (c == EOF)
Charles Hannum committed
1064
      break;
Jeff Law committed
1065 1066
    parse_c_expression (buf, 1);
    printf ("parser returned ");
1067
    u = (unsigned HOST_WIDEST_INT) expression_value;
Jeff Law committed
1068 1069 1070 1071 1072 1073 1074
    if (expression_value < 0 && expression_signedp) {
      u = -u;
      printf ("-");
    }
    if (u == 0)
      printf ("0");
    else
1075
      print_unsigned_host_widest_int (u);
Jeff Law committed
1076 1077 1078
    if (! expression_signedp)
      printf("u");
    printf ("\n");
Charles Hannum committed
1079 1080 1081 1082 1083
  }

  return 0;
}

Jeff Law committed
1084
static void
1085 1086
print_unsigned_host_widest_int (u)
     unsigned HOST_WIDEST_INT u;
Jeff Law committed
1087 1088
{
  if (u) {
1089
    print_unsigned_host_widest_int (u / 10);
Jeff Law committed
1090 1091 1092 1093
    putchar ('0' + (int) (u % 10));
  }
}

Charles Hannum committed
1094 1095 1096 1097
/* table to tell if char can be part of a C identifier. */
unsigned char is_idchar[256];
/* table to tell if char can be first char of a c identifier. */
unsigned char is_idstart[256];
1098 1099
/* table to tell if c is horizontal or vertical space.  */
unsigned char is_space[256];
Charles Hannum committed
1100 1101 1102 1103

/*
 * initialize random junk in the hash table and maybe other places
 */
1104
static void
Charles Hannum committed
1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127
initialize_random_junk ()
{
  register int i;

  /*
   * Set up is_idchar and is_idstart tables.  These should be
   * faster than saying (is_alpha (c) || c == '_'), etc.
   * Must do set up these things before calling any routines tthat
   * refer to them.
   */
  for (i = 'a'; i <= 'z'; i++) {
    ++is_idchar[i - 'a' + 'A'];
    ++is_idchar[i];
    ++is_idstart[i - 'a' + 'A'];
    ++is_idstart[i];
  }
  for (i = '0'; i <= '9'; i++)
    ++is_idchar[i];
  ++is_idchar['_'];
  ++is_idstart['_'];
  ++is_idchar['$'];
  ++is_idstart['$'];

1128 1129 1130 1131 1132 1133
  ++is_space[' '];
  ++is_space['\t'];
  ++is_space['\v'];
  ++is_space['\f'];
  ++is_space['\n'];
  ++is_space['\r'];
Charles Hannum committed
1134 1135
}

1136
void
1137
error VPROTO ((char * msgid, ...))
Charles Hannum committed
1138
{
1139
#ifndef ANSI_PROTOTYPES
1140
  char * msgid;
1141
#endif
1142 1143
  va_list args;

1144 1145
  VA_START (args, msgid);

1146
#ifndef ANSI_PROTOTYPES
1147
  msgid = va_arg (args, char *);
1148
#endif
1149

1150
  fprintf (stderr, "error: ");
1151
  vfprintf (stderr, _(msgid), args);
1152 1153
  fprintf (stderr, "\n");
  va_end (args);
Charles Hannum committed
1154 1155
}

1156
void
1157
pedwarn VPROTO ((char * msgid, ...))
1158
{
1159
#ifndef ANSI_PROTOTYPES
1160
  char * msgid;
1161
#endif
1162 1163
  va_list args;

1164 1165
  VA_START (args, msgid);

1166
#ifndef ANSI_PROTOTYPES
1167
  msgid = va_arg (args, char *);
1168
#endif
1169

1170
  fprintf (stderr, "pedwarn: ");
1171
  vfprintf (stderr, _(msgid), args);
1172 1173 1174 1175 1176
  fprintf (stderr, "\n");
  va_end (args);
}

void
1177
warning VPROTO ((char * msgid, ...))
Charles Hannum committed
1178
{
1179
#ifndef ANSI_PROTOTYPES
1180
  char * msgid;
1181
#endif
1182 1183
  va_list args;

1184 1185
  VA_START (args, msgid);

1186
#ifndef ANSI_PROTOTYPES
1187
  msgid = va_arg (args, char *);
1188
#endif
1189

1190
  fprintf (stderr, "warning: ");
1191
  vfprintf (stderr, _(msgid), args);
1192 1193 1194 1195
  fprintf (stderr, "\n");
  va_end (args);
}

1196

1197 1198 1199 1200 1201 1202 1203 1204
int
check_assertion (name, sym_length, tokens_specified, tokens)
     U_CHAR *name;
     int sym_length;
     int tokens_specified;
     struct arglist *tokens;
{
  return 0;
Charles Hannum committed
1205 1206 1207 1208
}

struct hashnode *
lookup (name, len, hash)
1209
     U_CHAR *name;
Charles Hannum committed
1210 1211 1212 1213 1214
     int len;
     int hash;
{
  return (DEFAULT_SIGNED_CHAR) ? 0 : ((struct hashnode *) -1);
}
1215

1216
PTR
1217
xmalloc (size)
1218
  size_t size;
1219
{
1220
  return (PTR) malloc (size);
1221
}
Charles Hannum committed
1222
#endif