1 /* Parse C expressions for CCCP.
2 Copyright (C) 1987, 1992, 1994, 1995, 1996, 1997 Free Software Foundation.
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
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.
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.
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!
23 Adapted from expread.y of GDB by Paul Rubin, July 1986. */
25 /* Parse a C expression from text in a string */
30 /* #define YYDEBUG 1 */
32 /* The following symbols should be autoconfigured:
35 In the mean time, we'll get by with approximations based
36 on existing GCC configuration symbols. */
39 # ifndef HAVE_STDLIB_H
40 # define HAVE_STDLIB_H 1
43 # define STDC_HEADERS 1
45 #endif /* defined (POSIX) */
51 #if HAVE_STDLIB_H || defined (MULTIBYTE_CHARS)
55 #ifdef MULTIBYTE_CHARS
61 typedef
unsigned char U_CHAR
;
63 /* This is used for communicating lists of keywords with cccp.c. */
71 /* Define a generic NULL if one hasn't already been defined. */
78 #if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__)
79 #define GENERIC_PTR void *
81 #define GENERIC_PTR char *
86 #define NULL_PTR ((GENERIC_PTR) 0)
89 /* Find the largest host integer type and set its size and type.
90 Don't blindly use `long'; on some crazy hosts it is shorter than `int'. */
92 #ifndef HOST_BITS_PER_WIDE_INT
94 #if HOST_BITS_PER_LONG > HOST_BITS_PER_INT
95 #define HOST_BITS_PER_WIDE_INT HOST_BITS_PER_LONG
96 #define HOST_WIDE_INT long
98 #define HOST_BITS_PER_WIDE_INT HOST_BITS_PER_INT
99 #define HOST_WIDE_INT int
104 #if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7)
105 # define __attribute__(x)
109 # if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__)
110 # define PROTO(ARGS) ARGS
112 # define PROTO(ARGS) ()
116 #if defined (__STDC__) && defined (HAVE_VPRINTF)
118 # define VA_START(va_list, var) va_start (va_list, var)
119 # define PRINTF_ALIST(msg) char *msg, ...
120 # define PRINTF_DCL(msg)
121 # define PRINTF_PROTO(ARGS, m, n) PROTO (ARGS) __attribute__ ((format (__printf__, m, n)))
123 # include <varargs.h>
124 # define VA_START(va_list, var) va_start (va_list)
125 # define PRINTF_ALIST(msg) msg, va_alist
126 # define PRINTF_DCL(msg) char *msg; va_dcl
127 # define PRINTF_PROTO(ARGS, m, n) () __attribute__ ((format (__printf__, m, n)))
128 # define vfprintf(file, msg, args) \
130 char *a0
= va_arg
(args
, char *); \
131 char *a1
= va_arg
(args
, char *); \
132 char *a2
= va_arg
(args
, char *); \
133 char *a3
= va_arg
(args
, char *); \
134 fprintf
(file
, msg
, a0
, a1
, a2
, a3
); \
138 #define PRINTF_PROTO_1(ARGS) PRINTF_PROTO(ARGS, 1, 2)
140 HOST_WIDE_INT parse_c_expression PROTO
((char *));
142 static int yylex PROTO
((void));
143 static void yyerror PROTO
((char *)) __attribute__
((noreturn
));
144 static HOST_WIDE_INT expression_value
;
146 static jmp_buf parse_return_error
;
148 /* Nonzero means count most punctuation as part of a name. */
149 static int keyword_parsing
= 0;
151 /* Nonzero means do not evaluate this expression.
152 This is a count, since unevaluated expressions can nest. */
153 static int skip_evaluation
;
155 /* some external tables of character types */
156 extern
unsigned char is_idstart
[], is_idchar
[], is_space
[];
158 /* Flag for -pedantic. */
161 /* Flag for -traditional. */
162 extern
int traditional
;
164 /* Flag for -lang-c89. */
167 /* Flag for -Wundef. */
168 extern
int warn_undef
;
170 #ifndef CHAR_TYPE_SIZE
171 #define CHAR_TYPE_SIZE BITS_PER_UNIT
174 #ifndef INT_TYPE_SIZE
175 #define INT_TYPE_SIZE BITS_PER_WORD
178 #ifndef LONG_TYPE_SIZE
179 #define LONG_TYPE_SIZE BITS_PER_WORD
182 #ifndef WCHAR_TYPE_SIZE
183 #define WCHAR_TYPE_SIZE INT_TYPE_SIZE
186 #ifndef MAX_CHAR_TYPE_SIZE
187 #define MAX_CHAR_TYPE_SIZE CHAR_TYPE_SIZE
190 #ifndef MAX_INT_TYPE_SIZE
191 #define MAX_INT_TYPE_SIZE INT_TYPE_SIZE
194 #ifndef MAX_LONG_TYPE_SIZE
195 #define MAX_LONG_TYPE_SIZE LONG_TYPE_SIZE
198 #ifndef MAX_WCHAR_TYPE_SIZE
199 #define MAX_WCHAR_TYPE_SIZE WCHAR_TYPE_SIZE
202 #if MAX_CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT
203 #define MAX_CHAR_TYPE_MASK (~ (~ (HOST_WIDE_INT) 0 << MAX_CHAR_TYPE_SIZE))
205 #define MAX_CHAR_TYPE_MASK (~ (HOST_WIDE_INT) 0)
208 #if MAX_WCHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT
209 #define MAX_WCHAR_TYPE_MASK (~ (~ (HOST_WIDE_INT) 0 << MAX_WCHAR_TYPE_SIZE))
211 #define MAX_WCHAR_TYPE_MASK (~ (HOST_WIDE_INT) 0)
214 /* Suppose A1 + B1 = SUM1, using 2's complement arithmetic ignoring overflow.
215 Suppose A, B and SUM have the same respective signs as A1, B1, and SUM1.
216 Suppose SIGNEDP is negative if the result is signed, zero if unsigned.
217 Then this yields nonzero if overflow occurred during the addition.
218 Overflow occurs if A and B have the same sign, but A and SUM differ in sign,
219 and SIGNEDP is negative.
220 Use `^' to test whether signs differ, and `< 0' to isolate the sign. */
221 #define overflow_sum_sign(a, b, sum, signedp) \
222 ((~
((a
) ^
(b
)) & ((a
) ^
(sum
)) & (signedp
)) < 0)
226 GENERIC_PTR xmalloc PROTO
((size_t));
227 HOST_WIDE_INT parse_escape PROTO
((char **, HOST_WIDE_INT
));
228 int check_assertion PROTO
((U_CHAR
*, int, int, struct arglist
*));
229 struct hashnode
*lookup PROTO
((U_CHAR
*, int, int));
230 void error PRINTF_PROTO_1
((char *, ...
));
231 void pedwarn PRINTF_PROTO_1
((char *, ...
));
232 void warning PRINTF_PROTO_1
((char *, ...
));
234 static int parse_number PROTO
((int));
235 static HOST_WIDE_INT left_shift PROTO
((struct constant
*, unsigned HOST_WIDE_INT
));
236 static HOST_WIDE_INT right_shift PROTO
((struct constant
*, unsigned HOST_WIDE_INT
));
237 static void integer_overflow PROTO
((void));
239 /* `signedp' values */
245 struct constant
{HOST_WIDE_INT value
; int signedp
;} integer
;
246 struct name
{U_CHAR
*address
; int length
;} name
;
247 struct arglist
*keywords
;
250 %type
<integer
> exp exp1 start
251 %type
<keywords
> keywords
252 %token
<integer
> INT CHAR
254 %token
<integer
> ERROR
264 %left
'<' '>' LEQ GEQ
275 { expression_value
= $1.value
; }
278 /* Expressions, including the comma operator. */
282 pedwarn
("comma operator in operand of `#if'");
286 /* Expressions, not including the comma operator. */
287 exp
: '-' exp %prec UNARY
288 { $$.value
= - $2.value
;
289 $$.signedp
= $2.signedp
;
290 if
(($$.value
& $2.value
& $$.signedp
) < 0)
291 integer_overflow
(); }
292 |
'!' exp %prec UNARY
293 { $$.value
= ! $2.value
;
294 $$.signedp
= SIGNED
; }
295 |
'+' exp %prec UNARY
297 |
'~' exp %prec UNARY
298 { $$.value
= ~
$2.value
;
299 $$.signedp
= $2.signedp
; }
301 { $$.value
= check_assertion
($2.address
, $2.length
,
303 $$.signedp
= SIGNED
; }
305 { keyword_parsing
= 1; }
307 { $$.value
= check_assertion
($2.address
, $2.length
,
310 $$.signedp
= SIGNED
; }
315 /* Binary operators in order of decreasing precedence. */
317 { $$.signedp
= $1.signedp
& $3.signedp
;
320 $$.value
= $1.value
* $3.value
;
322 && ($$.value
/ $1.value
!= $3.value
323 ||
($$.value
& $1.value
& $3.value
) < 0))
327 $$.value
= ((unsigned HOST_WIDE_INT
) $1.value
332 if
(!skip_evaluation
)
333 error ("division by zero in #if");
336 $$.signedp
= $1.signedp
& $3.signedp
;
339 $$.value
= $1.value
/ $3.value
;
340 if
(($$.value
& $1.value
& $3.value
) < 0)
344 $$.value
= ((unsigned HOST_WIDE_INT
) $1.value
349 if
(!skip_evaluation
)
350 error ("division by zero in #if");
353 $$.signedp
= $1.signedp
& $3.signedp
;
355 $$.value
= $1.value %
$3.value
;
357 $$.value
= ((unsigned HOST_WIDE_INT
) $1.value
360 { $$.value
= $1.value
+ $3.value
;
361 $$.signedp
= $1.signedp
& $3.signedp
;
362 if
(overflow_sum_sign
($1.value
, $3.value
,
363 $$.value
, $$.signedp
))
364 integer_overflow
(); }
366 { $$.value
= $1.value
- $3.value
;
367 $$.signedp
= $1.signedp
& $3.signedp
;
368 if
(overflow_sum_sign
($$.value
, $3.value
,
369 $1.value
, $$.signedp
))
370 integer_overflow
(); }
372 { $$.signedp
= $1.signedp
;
373 if
(($3.value
& $3.signedp
) < 0)
374 $$.value
= right_shift
(&$1, -$3.value
);
376 $$.value
= left_shift
(&$1, $3.value
); }
378 { $$.signedp
= $1.signedp
;
379 if
(($3.value
& $3.signedp
) < 0)
380 $$.value
= left_shift
(&$1, -$3.value
);
382 $$.value
= right_shift
(&$1, $3.value
); }
384 { $$.value
= ($1.value
== $3.value
);
385 $$.signedp
= SIGNED
; }
387 { $$.value
= ($1.value
!= $3.value
);
388 $$.signedp
= SIGNED
; }
390 { $$.signedp
= SIGNED
;
391 if
($1.signedp
& $3.signedp
)
392 $$.value
= $1.value
<= $3.value
;
394 $$.value
= ((unsigned HOST_WIDE_INT
) $1.value
397 { $$.signedp
= SIGNED
;
398 if
($1.signedp
& $3.signedp
)
399 $$.value
= $1.value
>= $3.value
;
401 $$.value
= ((unsigned HOST_WIDE_INT
) $1.value
404 { $$.signedp
= SIGNED
;
405 if
($1.signedp
& $3.signedp
)
406 $$.value
= $1.value
< $3.value
;
408 $$.value
= ((unsigned HOST_WIDE_INT
) $1.value
411 { $$.signedp
= SIGNED
;
412 if
($1.signedp
& $3.signedp
)
413 $$.value
= $1.value
> $3.value
;
415 $$.value
= ((unsigned HOST_WIDE_INT
) $1.value
418 { $$.value
= $1.value
& $3.value
;
419 $$.signedp
= $1.signedp
& $3.signedp
; }
421 { $$.value
= $1.value ^
$3.value
;
422 $$.signedp
= $1.signedp
& $3.signedp
; }
424 { $$.value
= $1.value |
$3.value
;
425 $$.signedp
= $1.signedp
& $3.signedp
; }
427 { skip_evaluation
+= !$1.value
; }
429 { skip_evaluation
-= !$1.value
;
430 $$.value
= ($1.value
&& $4.value
);
431 $$.signedp
= SIGNED
; }
433 { skip_evaluation
+= !!$1.value
; }
435 { skip_evaluation
-= !!$1.value
;
436 $$.value
= ($1.value ||
$4.value
);
437 $$.signedp
= SIGNED
; }
439 { skip_evaluation
+= !$1.value
; }
441 { skip_evaluation
+= !!$1.value
- !$1.value
; }
443 { skip_evaluation
-= !!$1.value
;
444 $$.value
= $1.value ?
$4.value
: $7.value
;
445 $$.signedp
= $4.signedp
& $7.signedp
; }
447 { $$
= yylval.integer
; }
449 { $$
= yylval.integer
; }
451 { if
(warn_undef
&& !skip_evaluation
)
452 warning
("`%.*s' is not defined",
453 $1.length
, $1.address
);
455 $$.signedp
= SIGNED
; }
460 |
'(' keywords
')' keywords
461 { struct arglist
*temp
;
462 $$
= (struct arglist
*) xmalloc
(sizeof
(struct arglist
));
464 $$
->name
= (U_CHAR
*) "(";
467 while
(temp
!= 0 && temp
->next
!= 0)
469 temp
->next
= (struct arglist
*) xmalloc
(sizeof
(struct arglist
));
470 temp
->next
->next
= $4;
471 temp
->next
->name
= (U_CHAR
*) ")";
472 temp
->next
->length
= 1; }
474 { $$
= (struct arglist
*) xmalloc
(sizeof
(struct arglist
));
475 $$
->name
= $1.address
;
476 $$
->length
= $1.length
;
481 /* During parsing of a C expression, the pointer to the next character
482 is in this variable. */
486 /* Take care of parsing a number (anything that starts with a digit).
487 Set yylval and return the token type; update lexptr.
488 LEN is the number of characters in it. */
490 /* maybe needs to actually deal with floating point numbers */
496 register
char *p
= lexptr
;
498 register
unsigned HOST_WIDE_INT n
= 0, nd
, max_over_base
;
499 register
int base
= 10;
500 register
int len
= olen
;
501 register
int overflow
= 0;
502 register
int digit
, largest_digit
= 0;
505 yylval.integer.signedp
= SIGNED
;
509 if
(len
>= 3 && (p
[1] == 'x' || p
[1] == 'X')) {
516 max_over_base
= (unsigned HOST_WIDE_INT
) -1 / base
;
518 for
(; len
> 0; len
--) {
521 if
(c
>= '0' && c
<= '9')
523 else if
(base
== 16 && c
>= 'a' && c
<= 'f')
524 digit
= c
- 'a' + 10;
525 else if
(base
== 16 && c
>= 'A' && c
<= 'F')
526 digit
= c
- 'A' + 10;
528 /* `l' means long, and `u' means unsigned. */
530 if
(c
== 'l' || c
== 'L')
532 if
(!pedantic
< spec_long
)
533 yyerror ("too many `l's in integer constant");
536 else if
(c
== 'u' || c
== 'U')
538 if
(! yylval.integer.signedp
)
539 yyerror ("two `u's in integer constant");
540 yylval.integer.signedp
= UNSIGNED
;
543 if
(c
== '.' || c
== 'e' || c
== 'E' || c
== 'p' || c
== 'P')
544 yyerror ("Floating point numbers not allowed in #if expressions");
546 char *buf
= (char *) alloca
(p
- lexptr
+ 40);
547 sprintf
(buf
, "missing white space after number `%.*s'",
548 (int) (p
- lexptr
- 1), lexptr
);
557 /* Don't look for any more digits after the suffixes. */
560 if
(largest_digit
< digit
)
561 largest_digit
= digit
;
562 nd
= n
* base
+ digit
;
563 overflow |
= (max_over_base
< n
) |
(nd
< n
);
567 if
(base
<= largest_digit
)
568 pedwarn
("integer constant contains digits beyond the radix");
571 pedwarn
("integer constant out of range");
573 /* If too big to be signed, consider it unsigned. */
574 if
(((HOST_WIDE_INT
) n
& yylval.integer.signedp
) < 0)
577 warning
("integer constant is so large that it is unsigned");
578 yylval.integer.signedp
= UNSIGNED
;
582 yylval.integer.value
= n
;
591 static struct token tokentab2
[] = {
605 /* Read one token, getting characters through lexptr. */
611 register
int namelen
;
612 register
unsigned char *tokstart
;
613 register
struct token
*toktab
;
619 tokstart
= (unsigned char *) lexptr
;
621 /* See if it is a special token of length 2. */
622 if
(! keyword_parsing
)
623 for
(toktab
= tokentab2
; toktab
->operator
!= NULL
; toktab
++)
624 if
(c
== *toktab
->operator
&& tokstart
[1] == toktab
->operator
[1]) {
626 if
(toktab
->token
== ERROR
)
628 char *buf
= (char *) alloca
(40);
629 sprintf
(buf
, "`%s' not allowed in operand of `#if'", toktab
->operator
);
632 return toktab
->token
;
646 /* Capital L may start a wide-string or wide-character constant. */
647 if
(lexptr
[1] == '\'')
651 mask
= MAX_WCHAR_TYPE_MASK
;
654 if
(lexptr
[1] == '"')
658 mask
= MAX_WCHAR_TYPE_MASK
;
659 goto string_constant
;
665 mask
= MAX_CHAR_TYPE_MASK
;
668 if
(keyword_parsing
) {
669 char *start_ptr
= lexptr
- 1;
673 c
= parse_escape
(&lexptr
, mask
);
677 yylval.name.address
= tokstart
;
678 yylval.name.length
= lexptr
- start_ptr
;
682 /* This code for reading a character constant
683 handles multicharacter constants and wide characters.
684 It is mostly copied from c-lex.c. */
686 register HOST_WIDE_INT result
= 0;
687 register num_chars
= 0;
688 unsigned width
= MAX_CHAR_TYPE_SIZE
;
694 width
= MAX_WCHAR_TYPE_SIZE
;
695 #ifdef MULTIBYTE_CHARS
696 max_chars
= MB_CUR_MAX
;
702 max_chars
= MAX_LONG_TYPE_SIZE
/ width
;
704 token_buffer
= (char *) alloca
(max_chars
+ 1);
710 if
(c
== '\'' || c
== EOF
)
715 c
= parse_escape
(&lexptr
, mask
);
720 /* Merge character into result; ignore excess chars. */
721 if
(num_chars
<= max_chars
)
723 if
(width
< HOST_BITS_PER_WIDE_INT
)
724 result
= (result
<< width
) | c
;
727 token_buffer
[num_chars
- 1] = c
;
731 token_buffer
[num_chars
] = 0;
734 error ("malformatted character constant");
735 else if
(num_chars
== 0)
736 error ("empty character constant");
737 else if
(num_chars
> max_chars
)
739 num_chars
= max_chars
;
740 error ("character constant too long");
742 else if
(num_chars
!= 1 && ! traditional
)
743 warning
("multi-character character constant");
745 /* If char type is signed, sign-extend the constant. */
748 int num_bits
= num_chars
* width
;
750 if
(lookup
((U_CHAR
*) "__CHAR_UNSIGNED__",
751 sizeof
("__CHAR_UNSIGNED__") - 1, -1)
752 ||
((result
>> (num_bits
- 1)) & 1) == 0)
754 = result
& (~
(unsigned HOST_WIDE_INT
) 0
755 >> (HOST_BITS_PER_WIDE_INT
- num_bits
));
758 = result | ~
(~
(unsigned HOST_WIDE_INT
) 0
759 >> (HOST_BITS_PER_WIDE_INT
- num_bits
));
763 #ifdef MULTIBYTE_CHARS
764 /* Set the initial shift state and convert the next sequence. */
766 /* In all locales L'\0' is zero and mbtowc will return zero,
769 ||
(num_chars
== 1 && token_buffer
[0] != '\0'))
772 (void) mbtowc
(NULL_PTR
, NULL_PTR
, 0);
773 if
(mbtowc
(& wc
, token_buffer
, num_chars
) == num_chars
)
776 pedwarn
("Ignoring invalid multibyte character");
779 yylval.integer.value
= result
;
783 /* This is always a signed type. */
784 yylval.integer.signedp
= SIGNED
;
788 /* some of these chars are invalid in constant expressions;
789 maybe do something about them later */
821 mask
= MAX_CHAR_TYPE_MASK
;
823 if
(keyword_parsing
) {
824 char *start_ptr
= lexptr
;
829 c
= parse_escape
(&lexptr
, mask
);
833 yylval.name.address
= tokstart
;
834 yylval.name.length
= lexptr
- start_ptr
;
837 yyerror ("string constants not allowed in #if expressions");
841 if
(c
>= '0' && c
<= '9' && !keyword_parsing
) {
843 for
(namelen
= 1; ; namelen
++) {
844 int d
= tokstart
[namelen
];
845 if
(! ((is_idchar
[d
] || d
== '.')
846 ||
((d
== '-' || d
== '+')
847 && (c
== 'e' || c
== 'E'
848 ||
((c
== 'p' || c
== 'P') && ! c89
))
853 return parse_number
(namelen
);
856 /* It is a name. See how long it is. */
858 if
(keyword_parsing
) {
859 for
(namelen
= 0;; namelen
++) {
860 if
(is_space
[tokstart
[namelen
]])
862 if
(tokstart
[namelen
] == '(' || tokstart
[namelen
] == ')')
864 if
(tokstart
[namelen
] == '"' || tokstart
[namelen
] == '\'')
868 if
(!is_idstart
[c
]) {
869 yyerror ("Invalid token in expression");
873 for
(namelen
= 0; is_idchar
[tokstart
[namelen
]]; namelen
++)
878 yylval.name.address
= tokstart
;
879 yylval.name.length
= namelen
;
884 /* Parse a C escape sequence. STRING_PTR points to a variable
885 containing a pointer to the string to parse. That pointer
886 is updated past the characters we use. The value of the
887 escape sequence is returned.
889 RESULT_MASK is used to mask out the result;
890 an error is reported if bits are lost thereby.
892 A negative value means the sequence \ newline was seen,
893 which is supposed to be equivalent to nothing at all.
895 If \ is followed by a null character, we return a negative
896 value and leave the string pointer pointing at the null character.
898 If \ is followed by 000, we return 0 and leave the string pointer
899 after the zeros. A value of 0 does not mean end of string. */
902 parse_escape
(string_ptr
, result_mask
)
904 HOST_WIDE_INT result_mask
;
906 register
int c
= *(*string_ptr
)++;
916 pedwarn
("non-ANSI-standard escape sequence, `\\%c'", c
);
921 return TARGET_NEWLINE
;
943 register HOST_WIDE_INT i
= c
- '0';
944 register
int count
= 0;
947 c
= *(*string_ptr
)++;
948 if
(c
>= '0' && c
<= '7')
949 i
= (i
<< 3) + c
- '0';
956 if
(i
!= (i
& result_mask
))
959 pedwarn
("octal escape sequence out of range");
965 register
unsigned HOST_WIDE_INT i
= 0, overflow
= 0;
966 register
int digits_found
= 0, digit
;
969 c
= *(*string_ptr
)++;
970 if
(c
>= '0' && c
<= '9')
972 else if
(c
>= 'a' && c
<= 'f')
973 digit
= c
- 'a' + 10;
974 else if
(c
>= 'A' && c
<= 'F')
975 digit
= c
- 'A' + 10;
981 overflow |
= i ^
(i
<< 4 >> 4);
982 i
= (i
<< 4) + digit
;
986 yyerror ("\\x used with no following hex digits");
987 if
(overflow |
(i
!= (i
& result_mask
)))
990 pedwarn
("hex escape sequence out of range");
1004 skip_evaluation
= 0;
1005 longjmp
(parse_return_error
, 1);
1011 if
(!skip_evaluation
&& pedantic
)
1012 pedwarn
("integer overflow in preprocessor expression");
1015 static HOST_WIDE_INT
1018 unsigned HOST_WIDE_INT b
;
1020 /* It's unclear from the C standard whether shifts can overflow.
1021 The following code ignores overflow; perhaps a C standard
1022 interpretation ruling is needed. */
1023 if
(b
>= HOST_BITS_PER_WIDE_INT
)
1026 return
(unsigned HOST_WIDE_INT
) a
->value
<< b
;
1029 static HOST_WIDE_INT
1032 unsigned HOST_WIDE_INT b
;
1034 if
(b
>= HOST_BITS_PER_WIDE_INT
)
1035 return a
->signedp ? a
->value
>> (HOST_BITS_PER_WIDE_INT
- 1) : 0;
1036 else if
(a
->signedp
)
1037 return a
->value
>> b
;
1039 return
(unsigned HOST_WIDE_INT
) a
->value
>> b
;
1042 /* This page contains the entry point to this file. */
1044 /* Parse STRING as an expression, and complain if this fails
1045 to use up all of the contents of STRING. */
1046 /* STRING may contain '\0' bytes; it is terminated by the first '\n'
1047 outside a string constant, so that we can diagnose '\0' properly. */
1048 /* We do not support C comments. They should be removed before
1049 this function is called. */
1052 parse_c_expression
(string)
1057 /* if there is some sort of scanning error, just return 0 and assume
1058 the parsing routine has printed an error message somewhere.
1059 there is surely a better thing to do than this. */
1060 if
(setjmp
(parse_return_error
))
1063 if
(yyparse () != 0)
1066 if
(*lexptr
!= '\n')
1067 error ("Junk after end of expression.");
1069 return expression_value
; /* set by yyparse () */
1072 #ifdef TEST_EXP_READER
1081 int main PROTO
((int, char **));
1082 static void initialize_random_junk PROTO
((void));
1084 /* Main program for testing purposes. */
1093 pedantic
= 1 < argc
;
1094 traditional
= 2 < argc
;
1098 initialize_random_junk
();
1101 printf
("enter expression: ");
1103 while
((buf
[n
] = c
= getchar
()) != '\n' && c
!= EOF
)
1107 printf
("parser returned %ld\n", (long) parse_c_expression
(buf
));
1113 /* table to tell if char can be part of a C identifier. */
1114 unsigned char is_idchar
[256];
1115 /* table to tell if char can be first char of a c identifier. */
1116 unsigned char is_idstart
[256];
1117 /* table to tell if c is horizontal or vertical space. */
1118 unsigned char is_space
[256];
1121 * initialize random junk in the hash table and maybe other places
1124 initialize_random_junk
()
1129 * Set up is_idchar and is_idstart tables. These should be
1130 * faster than saying (is_alpha (c) || c == '_'), etc.
1131 * Must do set up these things before calling any routines tthat
1134 for
(i
= 'a'; i
<= 'z'; i
++) {
1135 ++is_idchar
[i
- 'a' + 'A'];
1137 ++is_idstart
[i
- 'a' + 'A'];
1140 for
(i
= '0'; i
<= '9'; i
++)
1156 error (PRINTF_ALIST
(msg
))
1161 VA_START
(args
, msg
);
1162 fprintf
(stderr
, "error: ");
1163 vfprintf
(stderr
, msg
, args
);
1164 fprintf
(stderr
, "\n");
1169 pedwarn
(PRINTF_ALIST
(msg
))
1174 VA_START
(args
, msg
);
1175 fprintf
(stderr
, "pedwarn: ");
1176 vfprintf
(stderr
, msg
, args
);
1177 fprintf
(stderr
, "\n");
1182 warning
(PRINTF_ALIST
(msg
))
1187 VA_START
(args
, msg
);
1188 fprintf
(stderr
, "warning: ");
1189 vfprintf
(stderr
, msg
, args
);
1190 fprintf
(stderr
, "\n");
1195 check_assertion
(name
, sym_length
, tokens_specified
, tokens
)
1198 int tokens_specified
;
1199 struct arglist
*tokens
;
1205 lookup
(name
, len
, hash
)
1210 return
(DEFAULT_SIGNED_CHAR
) ?
0 : ((struct hashnode
*) -1);
1217 return
(GENERIC_PTR
) malloc
(size
);