1 /* Parse C expressions for CCCP.
2 Copyright (C) 1987, 1992, 94 - 97, 1998 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 PRINTF_PROTO(ARGS, m, n) PVPROTO (ARGS) ATTRIBUTE_PRINTF(m, n)
32 #define PRINTF_PROTO_1(ARGS) PRINTF_PROTO(ARGS, 1, 2)
36 /* #define YYDEBUG 1 */
37 #include "gansidecl.h"
39 #ifdef MULTIBYTE_CHARS
42 #endif /* MULTIBYTE_CHARS */
44 typedef
unsigned char U_CHAR
;
46 /* This is used for communicating lists of keywords with cccp.c. */
54 /* Find the largest host integer type and set its size and type.
55 Watch out: on some crazy hosts `long' is shorter than `int'. */
59 # include <inttypes.h>
60 # define HOST_WIDE_INT intmax_t
61 # define unsigned_HOST_WIDE_INT uintmax_t
63 # if (HOST_BITS_PER_LONG <= HOST_BITS_PER_INT && HOST_BITS_PER_LONGLONG <= HOST_BITS_PER_INT)
64 # define HOST_WIDE_INT int
66 # if (HOST_BITS_PER_LONGLONG <= HOST_BITS_PER_LONG || ! (defined LONG_LONG_MAX || defined LLONG_MAX))
67 # define HOST_WIDE_INT long
69 # define HOST_WIDE_INT long long
75 #ifndef unsigned_HOST_WIDE_INT
76 #define unsigned_HOST_WIDE_INT unsigned HOST_WIDE_INT
83 #ifndef HOST_BITS_PER_WIDE_INT
84 #define HOST_BITS_PER_WIDE_INT (CHAR_BIT * sizeof (HOST_WIDE_INT))
87 HOST_WIDE_INT parse_c_expression PROTO
((char *, int));
89 static int yylex PROTO
((void));
90 static void yyerror PROTO
((char *)) __attribute__
((noreturn
));
91 static HOST_WIDE_INT expression_value
;
92 #ifdef TEST_EXP_READER
93 static int expression_signedp
;
96 static jmp_buf parse_return_error
;
98 /* Nonzero means count most punctuation as part of a name. */
99 static int keyword_parsing
= 0;
101 /* Nonzero means do not evaluate this expression.
102 This is a count, since unevaluated expressions can nest. */
103 static int skip_evaluation
;
105 /* Nonzero means warn if undefined identifiers are evaluated. */
106 static int warn_undef
;
108 /* some external tables of character types */
109 extern
unsigned char is_idstart
[], is_idchar
[], is_space
[];
111 /* Flag for -pedantic. */
114 /* Flag for -traditional. */
115 extern
int traditional
;
117 /* Flag for -lang-c89. */
120 #ifndef CHAR_TYPE_SIZE
121 #define CHAR_TYPE_SIZE BITS_PER_UNIT
124 #ifndef INT_TYPE_SIZE
125 #define INT_TYPE_SIZE BITS_PER_WORD
128 #ifndef LONG_TYPE_SIZE
129 #define LONG_TYPE_SIZE BITS_PER_WORD
132 #ifndef WCHAR_TYPE_SIZE
133 #define WCHAR_TYPE_SIZE INT_TYPE_SIZE
136 #ifndef MAX_CHAR_TYPE_SIZE
137 #define MAX_CHAR_TYPE_SIZE CHAR_TYPE_SIZE
140 #ifndef MAX_INT_TYPE_SIZE
141 #define MAX_INT_TYPE_SIZE INT_TYPE_SIZE
144 #ifndef MAX_LONG_TYPE_SIZE
145 #define MAX_LONG_TYPE_SIZE LONG_TYPE_SIZE
148 #ifndef MAX_WCHAR_TYPE_SIZE
149 #define MAX_WCHAR_TYPE_SIZE WCHAR_TYPE_SIZE
152 #define MAX_CHAR_TYPE_MASK (MAX_CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT \
153 ?
(~
(~
(HOST_WIDE_INT
) 0 << MAX_CHAR_TYPE_SIZE
)) \
154 : ~
(HOST_WIDE_INT
) 0)
156 #define MAX_WCHAR_TYPE_MASK (MAX_WCHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT \
157 ? ~
(~
(HOST_WIDE_INT
) 0 << MAX_WCHAR_TYPE_SIZE
) \
158 : ~
(HOST_WIDE_INT
) 0)
160 /* Suppose A1 + B1 = SUM1, using 2's complement arithmetic ignoring overflow.
161 Suppose A, B and SUM have the same respective signs as A1, B1, and SUM1.
162 Suppose SIGNEDP is negative if the result is signed, zero if unsigned.
163 Then this yields nonzero if overflow occurred during the addition.
164 Overflow occurs if A and B have the same sign, but A and SUM differ in sign,
165 and SIGNEDP is negative.
166 Use `^' to test whether signs differ, and `< 0' to isolate the sign. */
167 #define overflow_sum_sign(a, b, sum, signedp) \
168 ((~
((a
) ^
(b
)) & ((a
) ^
(sum
)) & (signedp
)) < 0)
172 GENERIC_PTR xmalloc PROTO
((size_t));
173 HOST_WIDE_INT parse_escape PROTO
((char **, HOST_WIDE_INT
));
174 int check_assertion PROTO
((U_CHAR
*, int, int, struct arglist
*));
175 struct hashnode
*lookup PROTO
((U_CHAR
*, int, int));
176 void error PRINTF_PROTO_1
((char *, ...
));
177 void pedwarn PRINTF_PROTO_1
((char *, ...
));
178 void warning PRINTF_PROTO_1
((char *, ...
));
180 static int parse_number PROTO
((int));
181 static HOST_WIDE_INT left_shift PROTO
((struct constant
*, unsigned_HOST_WIDE_INT
));
182 static HOST_WIDE_INT right_shift PROTO
((struct constant
*, unsigned_HOST_WIDE_INT
));
183 static void integer_overflow PROTO
((void));
185 /* `signedp' values */
191 struct constant
{HOST_WIDE_INT value
; int signedp
;} integer
;
192 struct name
{U_CHAR
*address
; int length
;} name
;
193 struct arglist
*keywords
;
196 %type
<integer
> exp exp1 start
197 %type
<keywords
> keywords
198 %token
<integer
> INT CHAR
200 %token
<integer
> ERROR
210 %left
'<' '>' LEQ GEQ
222 expression_value
= $1.value
;
223 #ifdef TEST_EXP_READER
224 expression_signedp
= $1.signedp
;
229 /* Expressions, including the comma operator. */
233 pedwarn
("comma operator in operand of `#if'");
237 /* Expressions, not including the comma operator. */
238 exp
: '-' exp %prec UNARY
239 { $$.value
= - $2.value
;
240 $$.signedp
= $2.signedp
;
241 if
(($$.value
& $2.value
& $$.signedp
) < 0)
242 integer_overflow
(); }
243 |
'!' exp %prec UNARY
244 { $$.value
= ! $2.value
;
245 $$.signedp
= SIGNED
; }
246 |
'+' exp %prec UNARY
248 |
'~' exp %prec UNARY
249 { $$.value
= ~
$2.value
;
250 $$.signedp
= $2.signedp
; }
252 { $$.value
= check_assertion
($2.address
, $2.length
,
254 $$.signedp
= SIGNED
; }
256 { keyword_parsing
= 1; }
258 { $$.value
= check_assertion
($2.address
, $2.length
,
261 $$.signedp
= SIGNED
; }
266 /* Binary operators in order of decreasing precedence. */
268 { $$.signedp
= $1.signedp
& $3.signedp
;
271 $$.value
= $1.value
* $3.value
;
273 && ($$.value
/ $1.value
!= $3.value
274 ||
($$.value
& $1.value
& $3.value
) < 0))
278 $$.value
= ((unsigned_HOST_WIDE_INT
) $1.value
283 if
(!skip_evaluation
)
284 error ("division by zero in #if");
287 $$.signedp
= $1.signedp
& $3.signedp
;
290 $$.value
= $1.value
/ $3.value
;
291 if
(($$.value
& $1.value
& $3.value
) < 0)
295 $$.value
= ((unsigned_HOST_WIDE_INT
) $1.value
300 if
(!skip_evaluation
)
301 error ("division by zero in #if");
304 $$.signedp
= $1.signedp
& $3.signedp
;
306 $$.value
= $1.value %
$3.value
;
308 $$.value
= ((unsigned_HOST_WIDE_INT
) $1.value
311 { $$.value
= $1.value
+ $3.value
;
312 $$.signedp
= $1.signedp
& $3.signedp
;
313 if
(overflow_sum_sign
($1.value
, $3.value
,
314 $$.value
, $$.signedp
))
315 integer_overflow
(); }
317 { $$.value
= $1.value
- $3.value
;
318 $$.signedp
= $1.signedp
& $3.signedp
;
319 if
(overflow_sum_sign
($$.value
, $3.value
,
320 $1.value
, $$.signedp
))
321 integer_overflow
(); }
323 { $$.signedp
= $1.signedp
;
324 if
(($3.value
& $3.signedp
) < 0)
325 $$.value
= right_shift
(&$1, -$3.value
);
327 $$.value
= left_shift
(&$1, $3.value
); }
329 { $$.signedp
= $1.signedp
;
330 if
(($3.value
& $3.signedp
) < 0)
331 $$.value
= left_shift
(&$1, -$3.value
);
333 $$.value
= right_shift
(&$1, $3.value
); }
335 { $$.value
= ($1.value
== $3.value
);
336 $$.signedp
= SIGNED
; }
338 { $$.value
= ($1.value
!= $3.value
);
339 $$.signedp
= SIGNED
; }
341 { $$.signedp
= SIGNED
;
342 if
($1.signedp
& $3.signedp
)
343 $$.value
= $1.value
<= $3.value
;
345 $$.value
= ((unsigned_HOST_WIDE_INT
) $1.value
348 { $$.signedp
= SIGNED
;
349 if
($1.signedp
& $3.signedp
)
350 $$.value
= $1.value
>= $3.value
;
352 $$.value
= ((unsigned_HOST_WIDE_INT
) $1.value
355 { $$.signedp
= SIGNED
;
356 if
($1.signedp
& $3.signedp
)
357 $$.value
= $1.value
< $3.value
;
359 $$.value
= ((unsigned_HOST_WIDE_INT
) $1.value
362 { $$.signedp
= SIGNED
;
363 if
($1.signedp
& $3.signedp
)
364 $$.value
= $1.value
> $3.value
;
366 $$.value
= ((unsigned_HOST_WIDE_INT
) $1.value
369 { $$.value
= $1.value
& $3.value
;
370 $$.signedp
= $1.signedp
& $3.signedp
; }
372 { $$.value
= $1.value ^
$3.value
;
373 $$.signedp
= $1.signedp
& $3.signedp
; }
375 { $$.value
= $1.value |
$3.value
;
376 $$.signedp
= $1.signedp
& $3.signedp
; }
378 { skip_evaluation
+= !$1.value
; }
380 { skip_evaluation
-= !$1.value
;
381 $$.value
= ($1.value
&& $4.value
);
382 $$.signedp
= SIGNED
; }
384 { skip_evaluation
+= !!$1.value
; }
386 { skip_evaluation
-= !!$1.value
;
387 $$.value
= ($1.value ||
$4.value
);
388 $$.signedp
= SIGNED
; }
390 { skip_evaluation
+= !$1.value
; }
392 { skip_evaluation
+= !!$1.value
- !$1.value
; }
394 { skip_evaluation
-= !!$1.value
;
395 $$.value
= $1.value ?
$4.value
: $7.value
;
396 $$.signedp
= $4.signedp
& $7.signedp
; }
398 { $$
= yylval.integer
; }
400 { $$
= yylval.integer
; }
402 { if
(warn_undef
&& !skip_evaluation
)
403 warning
("`%.*s' is not defined",
404 $1.length
, $1.address
);
406 $$.signedp
= SIGNED
; }
411 |
'(' keywords
')' keywords
412 { struct arglist
*temp
;
413 $$
= (struct arglist
*) xmalloc
(sizeof
(struct arglist
));
415 $$
->name
= (U_CHAR
*) "(";
418 while
(temp
!= 0 && temp
->next
!= 0)
420 temp
->next
= (struct arglist
*) xmalloc
(sizeof
(struct arglist
));
421 temp
->next
->next
= $4;
422 temp
->next
->name
= (U_CHAR
*) ")";
423 temp
->next
->length
= 1; }
425 { $$
= (struct arglist
*) xmalloc
(sizeof
(struct arglist
));
426 $$
->name
= $1.address
;
427 $$
->length
= $1.length
;
432 /* During parsing of a C expression, the pointer to the next character
433 is in this variable. */
437 /* Take care of parsing a number (anything that starts with a digit).
438 Set yylval and return the token type; update lexptr.
439 LEN is the number of characters in it. */
441 /* maybe needs to actually deal with floating point numbers */
447 register
char *p
= lexptr
;
449 register unsigned_HOST_WIDE_INT n
= 0, nd
, max_over_base
;
450 register
int base
= 10;
451 register
int len
= olen
;
452 register
int overflow
= 0;
453 register
int digit
, largest_digit
= 0;
456 yylval.integer.signedp
= SIGNED
;
460 if
(len
>= 3 && (p
[1] == 'x' || p
[1] == 'X')) {
467 max_over_base
= (unsigned_HOST_WIDE_INT
) -1 / base
;
469 for
(; len
> 0; len
--) {
472 if
(c
>= '0' && c
<= '9')
474 else if
(base
== 16 && c
>= 'a' && c
<= 'f')
475 digit
= c
- 'a' + 10;
476 else if
(base
== 16 && c
>= 'A' && c
<= 'F')
477 digit
= c
- 'A' + 10;
479 /* `l' means long, and `u' means unsigned. */
481 if
(c
== 'l' || c
== 'L')
483 if
(!pedantic
< spec_long
)
484 yyerror ("too many `l's in integer constant");
487 else if
(c
== 'u' || c
== 'U')
489 if
(! yylval.integer.signedp
)
490 yyerror ("two `u's in integer constant");
491 yylval.integer.signedp
= UNSIGNED
;
494 if
(c
== '.' || c
== 'e' || c
== 'E' || c
== 'p' || c
== 'P')
495 yyerror ("Floating point numbers not allowed in #if expressions");
497 char *buf
= (char *) alloca
(p
- lexptr
+ 40);
498 sprintf
(buf
, "missing white space after number `%.*s'",
499 (int) (p
- lexptr
- 1), lexptr
);
508 /* Don't look for any more digits after the suffixes. */
511 if
(largest_digit
< digit
)
512 largest_digit
= digit
;
513 nd
= n
* base
+ digit
;
514 overflow |
= (max_over_base
< n
) |
(nd
< n
);
518 if
(base
<= largest_digit
)
519 pedwarn
("integer constant contains digits beyond the radix");
522 pedwarn
("integer constant out of range");
524 /* If too big to be signed, consider it unsigned. */
525 if
(((HOST_WIDE_INT
) n
& yylval.integer.signedp
) < 0)
528 warning
("integer constant is so large that it is unsigned");
529 yylval.integer.signedp
= UNSIGNED
;
533 yylval.integer.value
= n
;
542 static struct token tokentab2
[] = {
556 /* Read one token, getting characters through lexptr. */
562 register
int namelen
;
563 register
unsigned char *tokstart
;
564 register
struct token
*toktab
;
570 tokstart
= (unsigned char *) lexptr
;
572 /* See if it is a special token of length 2. */
573 if
(! keyword_parsing
)
574 for
(toktab
= tokentab2
; toktab
->operator
!= NULL
; toktab
++)
575 if
(c
== *toktab
->operator
&& tokstart
[1] == toktab
->operator
[1]) {
577 if
(toktab
->token
== ERROR
)
579 char *buf
= (char *) alloca
(40);
580 sprintf
(buf
, "`%s' not allowed in operand of `#if'", toktab
->operator
);
583 return toktab
->token
;
597 /* Capital L may start a wide-string or wide-character constant. */
598 if
(lexptr
[1] == '\'')
602 mask
= MAX_WCHAR_TYPE_MASK
;
605 if
(lexptr
[1] == '"')
609 mask
= MAX_WCHAR_TYPE_MASK
;
610 goto string_constant
;
616 mask
= MAX_CHAR_TYPE_MASK
;
619 if
(keyword_parsing
) {
620 char *start_ptr
= lexptr
- 1;
624 c
= parse_escape
(&lexptr
, mask
);
628 yylval.name.address
= tokstart
;
629 yylval.name.length
= lexptr
- start_ptr
;
633 /* This code for reading a character constant
634 handles multicharacter constants and wide characters.
635 It is mostly copied from c-lex.c. */
637 register HOST_WIDE_INT result
= 0;
638 register
int num_chars
= 0;
640 unsigned width
= MAX_CHAR_TYPE_SIZE
;
642 #ifdef MULTIBYTE_CHARS
643 int longest_char
= local_mb_cur_max
();
644 char *token_buffer
= (char *) alloca
(longest_char
);
645 (void) local_mbtowc
(NULL_PTR
, NULL_PTR
, 0);
648 max_chars
= MAX_LONG_TYPE_SIZE
/ width
;
650 width
= MAX_WCHAR_TYPE_SIZE
;
656 if
(c
== '\'' || c
== EOF
)
662 c
= parse_escape
(&lexptr
, mask
);
666 #ifdef MULTIBYTE_CHARS
670 for
(i
= 1; i
<= longest_char
; ++i
)
672 token_buffer
[i
- 1] = c
;
673 char_len
= local_mbtowc
(& wc
, token_buffer
, i
);
680 /* mbtowc sometimes needs an extra char before accepting */
685 /* Merge character into result; ignore excess chars. */
686 for
(i
= 1; i
<= char_len
; ++i
)
690 if
(width
< HOST_BITS_PER_INT
)
691 result
= (result
<< width
)
692 |
(token_buffer
[i
- 1]
693 & ((1 << width
) - 1));
695 result
= token_buffer
[i
- 1];
697 num_chars
+= char_len
;
704 warning
("Ignoring invalid multibyte character");
708 #endif /* ! MULTIBYTE_CHARS */
713 if
(chars_seen
== 1) /* only keep the first one */
718 /* Merge character into result; ignore excess chars. */
720 if
(num_chars
<= max_chars
)
722 if
(width
< HOST_BITS_PER_INT
)
723 result
= (result
<< width
) |
(c
& ((1 << width
) - 1));
730 error ("malformatted character constant");
731 else if
(chars_seen
== 0)
732 error ("empty character constant");
733 else if
(num_chars
> max_chars
)
735 num_chars
= max_chars
;
736 error ("character constant too long");
738 else if
(chars_seen
!= 1 && ! traditional
)
739 warning
("multi-character character constant");
741 /* If char type is signed, sign-extend the constant. */
744 int num_bits
= num_chars
* width
;
746 /* We already got an error; avoid invalid shift. */
747 yylval.integer.value
= 0;
748 else if
(lookup
((U_CHAR
*) "__CHAR_UNSIGNED__",
749 sizeof
("__CHAR_UNSIGNED__") - 1, -1)
750 ||
((result
>> (num_bits
- 1)) & 1) == 0)
752 = result
& (~
(unsigned_HOST_WIDE_INT
) 0
753 >> (HOST_BITS_PER_WIDE_INT
- num_bits
));
756 = result | ~
(~
(unsigned_HOST_WIDE_INT
) 0
757 >> (HOST_BITS_PER_WIDE_INT
- num_bits
));
761 yylval.integer.value
= result
;
765 /* This is always a signed type. */
766 yylval.integer.signedp
= SIGNED
;
770 /* some of these chars are invalid in constant expressions;
771 maybe do something about them later */
803 mask
= MAX_CHAR_TYPE_MASK
;
805 if
(keyword_parsing
) {
806 char *start_ptr
= lexptr
;
811 c
= parse_escape
(&lexptr
, mask
);
815 yylval.name.address
= tokstart
;
816 yylval.name.length
= lexptr
- start_ptr
;
819 yyerror ("string constants not allowed in #if expressions");
823 if
(c
>= '0' && c
<= '9' && !keyword_parsing
) {
825 for
(namelen
= 1; ; namelen
++) {
826 int d
= tokstart
[namelen
];
827 if
(! ((is_idchar
[d
] || d
== '.')
828 ||
((d
== '-' || d
== '+')
829 && (c
== 'e' || c
== 'E'
830 ||
((c
== 'p' || c
== 'P') && ! c89
))
835 return parse_number
(namelen
);
838 /* It is a name. See how long it is. */
840 if
(keyword_parsing
) {
841 for
(namelen
= 0;; namelen
++) {
842 if
(is_space
[tokstart
[namelen
]])
844 if
(tokstart
[namelen
] == '(' || tokstart
[namelen
] == ')')
846 if
(tokstart
[namelen
] == '"' || tokstart
[namelen
] == '\'')
850 if
(!is_idstart
[c
]) {
851 yyerror ("Invalid token in expression");
855 for
(namelen
= 0; is_idchar
[tokstart
[namelen
]]; namelen
++)
860 yylval.name.address
= tokstart
;
861 yylval.name.length
= namelen
;
866 /* Parse a C escape sequence. STRING_PTR points to a variable
867 containing a pointer to the string to parse. That pointer
868 is updated past the characters we use. The value of the
869 escape sequence is returned.
871 RESULT_MASK is used to mask out the result;
872 an error is reported if bits are lost thereby.
874 A negative value means the sequence \ newline was seen,
875 which is supposed to be equivalent to nothing at all.
877 If \ is followed by a null character, we return a negative
878 value and leave the string pointer pointing at the null character.
880 If \ is followed by 000, we return 0 and leave the string pointer
881 after the zeros. A value of 0 does not mean end of string. */
884 parse_escape
(string_ptr
, result_mask
)
886 HOST_WIDE_INT result_mask
;
888 register
int c
= *(*string_ptr
)++;
898 pedwarn
("non-ANSI-standard escape sequence, `\\%c'", c
);
903 return TARGET_NEWLINE
;
925 register HOST_WIDE_INT i
= c
- '0';
926 register
int count
= 0;
929 c
= *(*string_ptr
)++;
930 if
(c
>= '0' && c
<= '7')
931 i
= (i
<< 3) + c
- '0';
938 if
(i
!= (i
& result_mask
))
941 pedwarn
("octal escape sequence out of range");
947 register unsigned_HOST_WIDE_INT i
= 0, overflow
= 0;
948 register
int digits_found
= 0, digit
;
951 c
= *(*string_ptr
)++;
952 if
(c
>= '0' && c
<= '9')
954 else if
(c
>= 'a' && c
<= 'f')
955 digit
= c
- 'a' + 10;
956 else if
(c
>= 'A' && c
<= 'F')
957 digit
= c
- 'A' + 10;
963 overflow |
= i ^
(i
<< 4 >> 4);
964 i
= (i
<< 4) + digit
;
968 yyerror ("\\x used with no following hex digits");
969 if
(overflow |
(i
!= (i
& result_mask
)))
972 pedwarn
("hex escape sequence out of range");
987 longjmp
(parse_return_error
, 1);
993 if
(!skip_evaluation
&& pedantic
)
994 pedwarn
("integer overflow in preprocessor expression");
1000 unsigned_HOST_WIDE_INT b
;
1002 /* It's unclear from the C standard whether shifts can overflow.
1003 The following code ignores overflow; perhaps a C standard
1004 interpretation ruling is needed. */
1005 if
(b
>= HOST_BITS_PER_WIDE_INT
)
1008 return
(unsigned_HOST_WIDE_INT
) a
->value
<< b
;
1011 static HOST_WIDE_INT
1014 unsigned_HOST_WIDE_INT b
;
1016 if
(b
>= HOST_BITS_PER_WIDE_INT
)
1017 return a
->signedp ? a
->value
>> (HOST_BITS_PER_WIDE_INT
- 1) : 0;
1018 else if
(a
->signedp
)
1019 return a
->value
>> b
;
1021 return
(unsigned_HOST_WIDE_INT
) a
->value
>> b
;
1024 /* This page contains the entry point to this file. */
1026 /* Parse STRING as an expression, and complain if this fails
1027 to use up all of the contents of STRING.
1028 STRING may contain '\0' bytes; it is terminated by the first '\n'
1029 outside a string constant, so that we can diagnose '\0' properly.
1030 If WARN_UNDEFINED is nonzero, warn if undefined identifiers are evaluated.
1031 We do not support C comments. They should be removed before
1032 this function is called. */
1035 parse_c_expression
(string, warn_undefined
)
1040 warn_undef
= warn_undefined
;
1042 /* if there is some sort of scanning error, just return 0 and assume
1043 the parsing routine has printed an error message somewhere.
1044 there is surely a better thing to do than this. */
1045 if
(setjmp
(parse_return_error
))
1048 if
(yyparse () != 0)
1051 if
(*lexptr
!= '\n')
1052 error ("Junk after end of expression.");
1054 return expression_value
; /* set by yyparse () */
1057 #ifdef TEST_EXP_READER
1066 int main PROTO
((int, char **));
1067 static void initialize_random_junk PROTO
((void));
1068 static void print_unsigned_host_wide_int PROTO
((unsigned_HOST_WIDE_INT
));
1070 /* Main program for testing purposes. */
1078 unsigned_HOST_WIDE_INT u
;
1080 pedantic
= 1 < argc
;
1081 traditional
= 2 < argc
;
1085 initialize_random_junk
();
1088 printf
("enter expression: ");
1090 while
((buf
[n
] = c
= getchar
()) != '\n' && c
!= EOF
)
1094 parse_c_expression
(buf
, 1);
1095 printf
("parser returned ");
1096 u
= (unsigned_HOST_WIDE_INT
) expression_value
;
1097 if
(expression_value
< 0 && expression_signedp
) {
1104 print_unsigned_host_wide_int
(u
);
1105 if
(! expression_signedp
)
1114 print_unsigned_host_wide_int
(u
)
1115 unsigned_HOST_WIDE_INT u
;
1118 print_unsigned_host_wide_int
(u
/ 10);
1119 putchar
('0' + (int) (u %
10));
1123 /* table to tell if char can be part of a C identifier. */
1124 unsigned char is_idchar
[256];
1125 /* table to tell if char can be first char of a c identifier. */
1126 unsigned char is_idstart
[256];
1127 /* table to tell if c is horizontal or vertical space. */
1128 unsigned char is_space
[256];
1131 * initialize random junk in the hash table and maybe other places
1134 initialize_random_junk
()
1139 * Set up is_idchar and is_idstart tables. These should be
1140 * faster than saying (is_alpha (c) || c == '_'), etc.
1141 * Must do set up these things before calling any routines tthat
1144 for
(i
= 'a'; i
<= 'z'; i
++) {
1145 ++is_idchar
[i
- 'a' + 'A'];
1147 ++is_idstart
[i
- 'a' + 'A'];
1150 for
(i
= '0'; i
<= '9'; i
++)
1166 error VPROTO
((char * msg
, ...
))
1173 VA_START
(args
, msg
);
1176 msg
= va_arg
(args
, char *);
1179 fprintf
(stderr
, "error: ");
1180 vfprintf
(stderr
, msg
, args
);
1181 fprintf
(stderr
, "\n");
1186 pedwarn VPROTO
((char * msg
, ...
))
1193 VA_START
(args
, msg
);
1196 msg
= va_arg
(args
, char *);
1199 fprintf
(stderr
, "pedwarn: ");
1200 vfprintf
(stderr
, msg
, args
);
1201 fprintf
(stderr
, "\n");
1206 warning VPROTO
((char * msg
, ...
))
1213 VA_START
(args
, msg
);
1216 msg
= va_arg
(args
, char *);
1219 fprintf
(stderr
, "warning: ");
1220 vfprintf
(stderr
, msg
, args
);
1221 fprintf
(stderr
, "\n");
1226 check_assertion
(name
, sym_length
, tokens_specified
, tokens
)
1229 int tokens_specified
;
1230 struct arglist
*tokens
;
1236 lookup
(name
, len
, hash
)
1241 return
(DEFAULT_SIGNED_CHAR
) ?
0 : ((struct hashnode
*) -1);
1248 return
(GENERIC_PTR
) malloc
(size
);