1 /* Parse C expressions for CCCP.
2 Copyright (C) 1987, 92, 94-98, 1999 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 */
33 /* #define YYDEBUG 1 */
35 #ifdef MULTIBYTE_CHARS
38 #endif /* MULTIBYTE_CHARS */
40 typedef
unsigned char U_CHAR
;
42 /* This is used for communicating lists of keywords with cccp.c. */
50 HOST_WIDEST_INT parse_c_expression PROTO
((char *, int));
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
;
60 static jmp_buf parse_return_error
;
62 /* Nonzero means count most punctuation as part of a name. */
63 static int keyword_parsing
= 0;
65 /* Nonzero means do not evaluate this expression.
66 This is a count, since unevaluated expressions can nest. */
67 static int skip_evaluation
;
69 /* Nonzero means warn if undefined identifiers are evaluated. */
70 static int warn_undef
;
72 /* some external tables of character types */
73 extern
unsigned char is_idstart
[], is_idchar
[], is_space
[];
75 /* Flag for -pedantic. */
78 /* Flag for -traditional. */
79 extern
int traditional
;
81 /* Flag for -lang-c89. */
84 #ifndef CHAR_TYPE_SIZE
85 #define CHAR_TYPE_SIZE BITS_PER_UNIT
89 #define INT_TYPE_SIZE BITS_PER_WORD
92 #ifndef LONG_TYPE_SIZE
93 #define LONG_TYPE_SIZE BITS_PER_WORD
96 #ifndef WCHAR_TYPE_SIZE
97 #define WCHAR_TYPE_SIZE INT_TYPE_SIZE
100 #ifndef MAX_CHAR_TYPE_SIZE
101 #define MAX_CHAR_TYPE_SIZE CHAR_TYPE_SIZE
104 #ifndef MAX_INT_TYPE_SIZE
105 #define MAX_INT_TYPE_SIZE INT_TYPE_SIZE
108 #ifndef MAX_LONG_TYPE_SIZE
109 #define MAX_LONG_TYPE_SIZE LONG_TYPE_SIZE
112 #ifndef MAX_WCHAR_TYPE_SIZE
113 #define MAX_WCHAR_TYPE_SIZE WCHAR_TYPE_SIZE
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)
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)
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)
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
;
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));
149 /* `signedp' values */
155 struct constant
{HOST_WIDEST_INT value
; int signedp
;} integer
;
156 struct name
{U_CHAR
*address
; int length
;} name
;
157 struct arglist
*keywords
;
160 %type
<integer
> exp exp1 start
161 %type
<keywords
> keywords
162 %token
<integer
> INT CHAR
164 %token
<integer
> ERROR
174 %left
'<' '>' LEQ GEQ
186 expression_value
= $1.value
;
187 #ifdef TEST_EXP_READER
188 expression_signedp
= $1.signedp
;
193 /* Expressions, including the comma operator. */
197 pedwarn
("comma operator in operand of `#if'");
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
212 |
'~' exp %prec UNARY
213 { $$.value
= ~
$2.value
;
214 $$.signedp
= $2.signedp
; }
216 { $$.value
= check_assertion
($2.address
, $2.length
,
218 $$.signedp
= SIGNED
; }
220 { keyword_parsing
= 1; }
222 { $$.value
= check_assertion
($2.address
, $2.length
,
225 $$.signedp
= SIGNED
; }
230 /* Binary operators in order of decreasing precedence. */
232 { $$.signedp
= $1.signedp
& $3.signedp
;
235 $$.value
= $1.value
* $3.value
;
237 && ($$.value
/ $1.value
!= $3.value
238 ||
($$.value
& $1.value
& $3.value
) < 0))
242 $$.value
= ((unsigned HOST_WIDEST_INT
) $1.value
247 if
(!skip_evaluation
)
248 error ("division by zero in #if");
251 $$.signedp
= $1.signedp
& $3.signedp
;
254 $$.value
= $1.value
/ $3.value
;
255 if
(($$.value
& $1.value
& $3.value
) < 0)
259 $$.value
= ((unsigned HOST_WIDEST_INT
) $1.value
264 if
(!skip_evaluation
)
265 error ("division by zero in #if");
268 $$.signedp
= $1.signedp
& $3.signedp
;
270 $$.value
= $1.value %
$3.value
;
272 $$.value
= ((unsigned HOST_WIDEST_INT
) $1.value
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
(); }
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
(); }
287 { $$.signedp
= $1.signedp
;
288 if
(($3.value
& $3.signedp
) < 0)
289 $$.value
= right_shift
(&$1, -$3.value
);
291 $$.value
= left_shift
(&$1, $3.value
); }
293 { $$.signedp
= $1.signedp
;
294 if
(($3.value
& $3.signedp
) < 0)
295 $$.value
= left_shift
(&$1, -$3.value
);
297 $$.value
= right_shift
(&$1, $3.value
); }
299 { $$.value
= ($1.value
== $3.value
);
300 $$.signedp
= SIGNED
; }
302 { $$.value
= ($1.value
!= $3.value
);
303 $$.signedp
= SIGNED
; }
305 { $$.signedp
= SIGNED
;
306 if
($1.signedp
& $3.signedp
)
307 $$.value
= $1.value
<= $3.value
;
309 $$.value
= ((unsigned HOST_WIDEST_INT
) $1.value
312 { $$.signedp
= SIGNED
;
313 if
($1.signedp
& $3.signedp
)
314 $$.value
= $1.value
>= $3.value
;
316 $$.value
= ((unsigned HOST_WIDEST_INT
) $1.value
319 { $$.signedp
= SIGNED
;
320 if
($1.signedp
& $3.signedp
)
321 $$.value
= $1.value
< $3.value
;
323 $$.value
= ((unsigned HOST_WIDEST_INT
) $1.value
326 { $$.signedp
= SIGNED
;
327 if
($1.signedp
& $3.signedp
)
328 $$.value
= $1.value
> $3.value
;
330 $$.value
= ((unsigned HOST_WIDEST_INT
) $1.value
333 { $$.value
= $1.value
& $3.value
;
334 $$.signedp
= $1.signedp
& $3.signedp
; }
336 { $$.value
= $1.value ^
$3.value
;
337 $$.signedp
= $1.signedp
& $3.signedp
; }
339 { $$.value
= $1.value |
$3.value
;
340 $$.signedp
= $1.signedp
& $3.signedp
; }
342 { skip_evaluation
+= !$1.value
; }
344 { skip_evaluation
-= !$1.value
;
345 $$.value
= ($1.value
&& $4.value
);
346 $$.signedp
= SIGNED
; }
348 { skip_evaluation
+= !!$1.value
; }
350 { skip_evaluation
-= !!$1.value
;
351 $$.value
= ($1.value ||
$4.value
);
352 $$.signedp
= SIGNED
; }
354 { skip_evaluation
+= !$1.value
; }
356 { skip_evaluation
+= !!$1.value
- !$1.value
; }
358 { skip_evaluation
-= !!$1.value
;
359 $$.value
= $1.value ?
$4.value
: $7.value
;
360 $$.signedp
= $4.signedp
& $7.signedp
; }
362 { $$
= yylval.integer
; }
364 { $$
= yylval.integer
; }
366 { if
(warn_undef
&& !skip_evaluation
)
367 warning
("`%.*s' is not defined",
368 $1.length
, $1.address
);
370 $$.signedp
= SIGNED
; }
375 |
'(' keywords
')' keywords
376 { struct arglist
*temp
;
377 $$
= (struct arglist
*) xmalloc
(sizeof
(struct arglist
));
379 $$
->name
= (U_CHAR
*) "(";
382 while
(temp
!= 0 && temp
->next
!= 0)
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; }
389 { $$
= (struct arglist
*) xmalloc
(sizeof
(struct arglist
));
390 $$
->name
= $1.address
;
391 $$
->length
= $1.length
;
396 /* During parsing of a C expression, the pointer to the next character
397 is in this variable. */
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. */
405 /* maybe needs to actually deal with floating point numbers */
411 register
char *p
= lexptr
;
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;
420 yylval.integer.signedp
= SIGNED
;
424 if
(len
>= 3 && (p
[1] == 'x' || p
[1] == 'X')) {
431 max_over_base
= (unsigned HOST_WIDEST_INT
) -1 / base
;
433 for
(; len
> 0; len
--) {
436 if
(c
>= '0' && c
<= '9')
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;
443 /* `l' means long, and `u' means unsigned. */
445 if
(c
== 'l' || c
== 'L')
447 if
(!pedantic
< spec_long
)
448 yyerror ("too many `l's in integer constant");
451 else if
(c
== 'u' || c
== 'U')
453 if
(! yylval.integer.signedp
)
454 yyerror ("two `u's in integer constant");
455 yylval.integer.signedp
= UNSIGNED
;
458 if
(c
== '.' || c
== 'e' || c
== 'E' || c
== 'p' || c
== 'P')
459 yyerror ("Floating point numbers not allowed in #if expressions");
461 yyerror ("missing white space after number `%.*s'",
462 (int) (p
- lexptr
- 1), lexptr
);
469 /* Don't look for any more digits after the suffixes. */
472 if
(largest_digit
< digit
)
473 largest_digit
= digit
;
474 nd
= n
* base
+ digit
;
475 overflow |
= (max_over_base
< n
) |
(nd
< n
);
479 if
(base
<= largest_digit
)
480 pedwarn
("integer constant contains digits beyond the radix");
483 pedwarn
("integer constant out of range");
485 /* If too big to be signed, consider it unsigned. */
486 if
(((HOST_WIDEST_INT
) n
& yylval.integer.signedp
) < 0)
489 warning
("integer constant is so large that it is unsigned");
490 yylval.integer.signedp
= UNSIGNED
;
494 yylval.integer.value
= n
;
499 const char *operator
;
503 static struct token tokentab2
[] = {
517 /* Read one token, getting characters through lexptr. */
523 register
int namelen
;
524 register
unsigned char *tokstart
;
525 register
struct token
*toktab
;
527 HOST_WIDEST_INT mask
;
531 tokstart
= (unsigned char *) lexptr
;
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]) {
538 if
(toktab
->token
== ERROR
)
539 yyerror ("`%s' not allowed in operand of `#if'", toktab
->operator
);
540 return toktab
->token
;
554 /* Capital L may start a wide-string or wide-character constant. */
555 if
(lexptr
[1] == '\'')
559 mask
= MAX_WCHAR_TYPE_MASK
;
562 if
(lexptr
[1] == '"')
566 mask
= MAX_WCHAR_TYPE_MASK
;
567 goto string_constant
;
573 mask
= MAX_CHAR_TYPE_MASK
;
576 if
(keyword_parsing
) {
577 char *start_ptr
= lexptr
- 1;
581 c
= parse_escape
(&lexptr
, mask
);
585 yylval.name.address
= tokstart
;
586 yylval.name.length
= lexptr
- start_ptr
;
590 /* This code for reading a character constant
591 handles multicharacter constants and wide characters.
592 It is mostly copied from c-lex.c. */
594 register HOST_WIDEST_INT result
= 0;
595 register
int num_chars
= 0;
597 unsigned width
= MAX_CHAR_TYPE_SIZE
;
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);
605 max_chars
= MAX_LONG_TYPE_SIZE
/ width
;
607 width
= MAX_WCHAR_TYPE_SIZE
;
613 if
(c
== '\'' || c
== EOF
)
619 c
= parse_escape
(&lexptr
, mask
);
623 #ifdef MULTIBYTE_CHARS
627 for
(i
= 1; i
<= longest_char
; ++i
)
629 token_buffer
[i
- 1] = c
;
630 char_len
= local_mbtowc
(& wc
, token_buffer
, i
);
637 /* mbtowc sometimes needs an extra char before accepting */
642 /* Merge character into result; ignore excess chars. */
643 for
(i
= 1; i
<= char_len
; ++i
)
647 if
(width
< HOST_BITS_PER_INT
)
648 result
= (result
<< width
)
649 |
(token_buffer
[i
- 1]
650 & ((1 << width
) - 1));
652 result
= token_buffer
[i
- 1];
654 num_chars
+= char_len
;
661 warning
("Ignoring invalid multibyte character");
665 #endif /* ! MULTIBYTE_CHARS */
670 if
(chars_seen
== 1) /* only keep the first one */
675 /* Merge character into result; ignore excess chars. */
677 if
(num_chars
<= max_chars
)
679 if
(width
< HOST_BITS_PER_INT
)
680 result
= (result
<< width
) |
(c
& ((1 << width
) - 1));
687 error ("malformatted character constant");
688 else if
(chars_seen
== 0)
689 error ("empty character constant");
690 else if
(num_chars
> max_chars
)
692 num_chars
= max_chars
;
693 error ("character constant too long");
695 else if
(chars_seen
!= 1 && ! traditional
)
696 warning
("multi-character character constant");
698 /* If char type is signed, sign-extend the constant. */
701 int num_bits
= num_chars
* width
;
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)
709 = result
& (~
(unsigned HOST_WIDEST_INT
) 0
710 >> (HOST_BITS_PER_WIDEST_INT
- num_bits
));
713 = result | ~
(~
(unsigned HOST_WIDEST_INT
) 0
714 >> (HOST_BITS_PER_WIDEST_INT
- num_bits
));
718 yylval.integer.value
= result
;
722 /* This is always a signed type. */
723 yylval.integer.signedp
= SIGNED
;
727 /* some of these chars are invalid in constant expressions;
728 maybe do something about them later */
760 mask
= MAX_CHAR_TYPE_MASK
;
762 if
(keyword_parsing
) {
763 char *start_ptr
= lexptr
;
768 c
= parse_escape
(&lexptr
, mask
);
772 yylval.name.address
= tokstart
;
773 yylval.name.length
= lexptr
- start_ptr
;
776 yyerror ("string constants not allowed in #if expressions");
780 if
(c
>= '0' && c
<= '9' && !keyword_parsing
) {
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
))
792 return parse_number
(namelen
);
795 /* It is a name. See how long it is. */
797 if
(keyword_parsing
) {
798 for
(namelen
= 0;; namelen
++) {
799 if
(is_space
[tokstart
[namelen
]])
801 if
(tokstart
[namelen
] == '(' || tokstart
[namelen
] == ')')
803 if
(tokstart
[namelen
] == '"' || tokstart
[namelen
] == '\'')
807 if
(!is_idstart
[c
]) {
808 yyerror ("Invalid token in expression");
812 for
(namelen
= 0; is_idchar
[tokstart
[namelen
]]; namelen
++)
817 yylval.name.address
= tokstart
;
818 yylval.name.length
= namelen
;
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.
828 RESULT_MASK is used to mask out the result;
829 an error is reported if bits are lost thereby.
831 A negative value means the sequence \ newline was seen,
832 which is supposed to be equivalent to nothing at all.
834 If \ is followed by a null character, we return a negative
835 value and leave the string pointer pointing at the null character.
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. */
841 parse_escape
(string_ptr
, result_mask
)
843 HOST_WIDEST_INT result_mask
;
845 register
int c
= *(*string_ptr
)++;
855 pedwarn
("non-ANSI-standard escape sequence, `\\%c'", c
);
860 return TARGET_NEWLINE
;
882 register HOST_WIDEST_INT i
= c
- '0';
883 register
int count
= 0;
886 c
= *(*string_ptr
)++;
887 if
(c
>= '0' && c
<= '7')
888 i
= (i
<< 3) + c
- '0';
895 if
(i
!= (i
& result_mask
))
898 pedwarn
("octal escape sequence out of range");
904 register
unsigned HOST_WIDEST_INT i
= 0, overflow
= 0;
905 register
int digits_found
= 0, digit
;
908 c
= *(*string_ptr
)++;
909 if
(c
>= '0' && c
<= '9')
911 else if
(c
>= 'a' && c
<= 'f')
912 digit
= c
- 'a' + 10;
913 else if
(c
>= 'A' && c
<= 'F')
914 digit
= c
- 'A' + 10;
920 overflow |
= i ^
(i
<< 4 >> 4);
921 i
= (i
<< 4) + digit
;
925 yyerror ("\\x used with no following hex digits");
926 if
(overflow |
(i
!= (i
& result_mask
)))
929 pedwarn
("hex escape sequence out of range");
941 if
(!skip_evaluation
&& pedantic
)
942 pedwarn
("integer overflow in preprocessor expression");
945 static HOST_WIDEST_INT
948 unsigned HOST_WIDEST_INT b
;
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
)
956 return
(unsigned HOST_WIDEST_INT
) a
->value
<< b
;
959 static HOST_WIDEST_INT
962 unsigned HOST_WIDEST_INT b
;
964 if
(b
>= HOST_BITS_PER_WIDEST_INT
)
965 return a
->signedp ? a
->value
>> (HOST_BITS_PER_WIDEST_INT
- 1) : 0;
967 return a
->value
>> b
;
969 return
(unsigned HOST_WIDEST_INT
) a
->value
>> b
;
972 /* This page contains the entry point to this file. */
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. */
983 parse_c_expression
(string, warn_undefined
)
988 warn_undef
= warn_undefined
;
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
))
1000 error ("Junk after end of expression.");
1002 return expression_value
; /* set by yyparse () */
1006 yyerror VPROTO
((const char * msgid
, ...
))
1008 #ifndef ANSI_PROTOTYPES
1013 VA_START
(args
, msgid
);
1015 #ifndef ANSI_PROTOTYPES
1016 msgid
= va_arg
(args
, const char *);
1019 verror
(msgid
, args
);
1021 skip_evaluation
= 0;
1022 longjmp
(parse_return_error
, 1);
1026 #ifdef TEST_EXP_READER
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
));
1040 /* Main program for testing purposes. */
1048 unsigned HOST_WIDEST_INT u
;
1050 pedantic
= 1 < argc
;
1051 traditional
= 2 < argc
;
1056 initialize_random_junk
();
1059 printf
("enter expression: ");
1061 while
((buf
[n
] = c
= getchar
()) != '\n' && c
!= EOF
)
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
) {
1075 print_unsigned_host_widest_int
(u
);
1076 if
(! expression_signedp
)
1085 print_unsigned_host_widest_int
(u
)
1086 unsigned HOST_WIDEST_INT u
;
1089 print_unsigned_host_widest_int
(u
/ 10);
1090 putchar
('0' + (int) (u %
10));
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];
1102 * initialize random junk in the hash table and maybe other places
1105 initialize_random_junk
()
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
1115 for
(i
= 'a'; i
<= 'z'; i
++) {
1116 ++is_idchar
[TOUPPER
(i
)];
1118 ++is_idstart
[TOUPPER
(i
)];
1121 for
(i
= '0'; i
<= '9'; i
++)
1137 error VPROTO
((char * msgid
, ...
))
1139 #ifndef ANSI_PROTOTYPES
1144 VA_START
(args
, msgid
);
1146 #ifndef ANSI_PROTOTYPES
1147 msgid
= va_arg
(args
, char *);
1150 fprintf
(stderr
, "error: ");
1151 vfprintf
(stderr
, _
(msgid
), args
);
1152 fprintf
(stderr
, "\n");
1157 pedwarn VPROTO
((char * msgid
, ...
))
1159 #ifndef ANSI_PROTOTYPES
1164 VA_START
(args
, msgid
);
1166 #ifndef ANSI_PROTOTYPES
1167 msgid
= va_arg
(args
, char *);
1170 fprintf
(stderr
, "pedwarn: ");
1171 vfprintf
(stderr
, _
(msgid
), args
);
1172 fprintf
(stderr
, "\n");
1177 warning VPROTO
((char * msgid
, ...
))
1179 #ifndef ANSI_PROTOTYPES
1184 VA_START
(args
, msgid
);
1186 #ifndef ANSI_PROTOTYPES
1187 msgid
= va_arg
(args
, char *);
1190 fprintf
(stderr
, "warning: ");
1191 vfprintf
(stderr
, _
(msgid
), args
);
1192 fprintf
(stderr
, "\n");
1198 check_assertion
(name
, sym_length
, tokens_specified
, tokens
)
1201 int tokens_specified
;
1202 struct arglist
*tokens
;
1208 lookup
(name
, len
, hash
)
1213 return
(DEFAULT_SIGNED_CHAR
) ?
0 : ((struct hashnode
*) -1);
1220 return
(PTR
) malloc
(size
);