1 /* Parse C expressions for CCCP.
2 Copyright (C) 1987, 1992, 1994, 1995, 1996 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__ < 6)
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_hor_space[];
158 /* Flag for -pedantic. */
161 /* Flag for -traditional. */
162 extern int traditional;
164 #ifndef CHAR_TYPE_SIZE
165 #define CHAR_TYPE_SIZE BITS_PER_UNIT
168 #ifndef INT_TYPE_SIZE
169 #define INT_TYPE_SIZE BITS_PER_WORD
172 #ifndef LONG_TYPE_SIZE
173 #define LONG_TYPE_SIZE BITS_PER_WORD
176 #ifndef WCHAR_TYPE_SIZE
177 #define WCHAR_TYPE_SIZE INT_TYPE_SIZE
180 #ifndef MAX_CHAR_TYPE_SIZE
181 #define MAX_CHAR_TYPE_SIZE CHAR_TYPE_SIZE
184 #ifndef MAX_INT_TYPE_SIZE
185 #define MAX_INT_TYPE_SIZE INT_TYPE_SIZE
188 #ifndef MAX_LONG_TYPE_SIZE
189 #define MAX_LONG_TYPE_SIZE LONG_TYPE_SIZE
192 #ifndef MAX_WCHAR_TYPE_SIZE
193 #define MAX_WCHAR_TYPE_SIZE WCHAR_TYPE_SIZE
196 #if MAX_CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT
197 #define MAX_CHAR_TYPE_MASK (~ (~ (HOST_WIDE_INT) 0 << MAX_CHAR_TYPE_SIZE))
199 #define MAX_CHAR_TYPE_MASK (~ (HOST_WIDE_INT) 0)
202 #if MAX_WCHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT
203 #define MAX_WCHAR_TYPE_MASK (~ (~ (HOST_WIDE_INT) 0 << MAX_WCHAR_TYPE_SIZE))
205 #define MAX_WCHAR_TYPE_MASK (~ (HOST_WIDE_INT) 0)
208 /* Suppose A1 + B1 = SUM1, using 2's complement arithmetic ignoring overflow.
209 Suppose A, B and SUM have the same respective signs as A1, B1, and SUM1.
210 Suppose SIGNEDP is negative if the result is signed, zero if unsigned.
211 Then this yields nonzero if overflow occurred during the addition.
212 Overflow occurs if A and B have the same sign, but A and SUM differ in sign,
213 and SIGNEDP is negative.
214 Use `^' to test whether signs differ, and `< 0' to isolate the sign. */
215 #define overflow_sum_sign(a, b, sum, signedp) \
216 ((~((a) ^ (b)) & ((a) ^ (sum)) & (signedp)) < 0)
220 GENERIC_PTR xmalloc PROTO((size_t));
221 HOST_WIDE_INT parse_escape PROTO((char **, HOST_WIDE_INT));
222 int check_assertion PROTO((U_CHAR *, int, int, struct arglist *));
223 struct hashnode *lookup PROTO((U_CHAR *, int, int));
224 void error PRINTF_PROTO_1((char *, ...));
225 void pedwarn PRINTF_PROTO_1((char *, ...));
226 void warning PRINTF_PROTO_1((char *, ...));
228 static int parse_number PROTO((int));
229 static HOST_WIDE_INT left_shift PROTO((struct constant *, unsigned HOST_WIDE_INT));
230 static HOST_WIDE_INT right_shift PROTO((struct constant *, unsigned HOST_WIDE_INT));
231 static void integer_overflow PROTO((void));
233 /* `signedp' values */
239 struct constant {HOST_WIDE_INT value; int signedp;} integer;
240 struct name {U_CHAR *address; int length;} name;
241 struct arglist *keywords;
244 %type <integer> exp exp1 start
245 %type <keywords> keywords
246 %token <integer> INT CHAR
248 %token <integer> ERROR
258 %left '<' '>' LEQ GEQ
269 { expression_value = $1.value; }
272 /* Expressions, including the comma operator. */
276 pedwarn ("comma operator in operand of `#if'");
280 /* Expressions, not including the comma operator. */
281 exp : '-' exp %prec UNARY
282 { $$.value = - $2.value;
283 $$.signedp = $2.signedp;
284 if (($$.value & $2.value & $$.signedp) < 0)
285 integer_overflow (); }
286 | '!' exp %prec UNARY
287 { $$.value = ! $2.value;
288 $$.signedp = SIGNED; }
289 | '+' exp %prec UNARY
291 | '~' exp %prec UNARY
292 { $$.value = ~ $2.value;
293 $$.signedp = $2.signedp; }
295 { $$.value = check_assertion ($2.address, $2.length,
297 $$.signedp = SIGNED; }
299 { keyword_parsing = 1; }
301 { $$.value = check_assertion ($2.address, $2.length,
304 $$.signedp = SIGNED; }
309 /* Binary operators in order of decreasing precedence. */
311 { $$.signedp = $1.signedp & $3.signedp;
314 $$.value = $1.value * $3.value;
316 && ($$.value / $1.value != $3.value
317 || ($$.value & $1.value & $3.value) < 0))
321 $$.value = ((unsigned HOST_WIDE_INT) $1.value
326 if (!skip_evaluation)
327 error ("division by zero in #if");
330 $$.signedp = $1.signedp & $3.signedp;
333 $$.value = $1.value / $3.value;
334 if (($$.value & $1.value & $3.value) < 0)
338 $$.value = ((unsigned HOST_WIDE_INT) $1.value
343 if (!skip_evaluation)
344 error ("division by zero in #if");
347 $$.signedp = $1.signedp & $3.signedp;
349 $$.value = $1.value % $3.value;
351 $$.value = ((unsigned HOST_WIDE_INT) $1.value
354 { $$.value = $1.value + $3.value;
355 $$.signedp = $1.signedp & $3.signedp;
356 if (overflow_sum_sign ($1.value, $3.value,
357 $$.value, $$.signedp))
358 integer_overflow (); }
360 { $$.value = $1.value - $3.value;
361 $$.signedp = $1.signedp & $3.signedp;
362 if (overflow_sum_sign ($$.value, $3.value,
363 $1.value, $$.signedp))
364 integer_overflow (); }
366 { $$.signedp = $1.signedp;
367 if (($3.value & $3.signedp) < 0)
368 $$.value = right_shift (&$1, -$3.value);
370 $$.value = left_shift (&$1, $3.value); }
372 { $$.signedp = $1.signedp;
373 if (($3.value & $3.signedp) < 0)
374 $$.value = left_shift (&$1, -$3.value);
376 $$.value = right_shift (&$1, $3.value); }
378 { $$.value = ($1.value == $3.value);
379 $$.signedp = SIGNED; }
381 { $$.value = ($1.value != $3.value);
382 $$.signedp = SIGNED; }
384 { $$.signedp = SIGNED;
385 if ($1.signedp & $3.signedp)
386 $$.value = $1.value <= $3.value;
388 $$.value = ((unsigned HOST_WIDE_INT) $1.value
391 { $$.signedp = SIGNED;
392 if ($1.signedp & $3.signedp)
393 $$.value = $1.value >= $3.value;
395 $$.value = ((unsigned HOST_WIDE_INT) $1.value
398 { $$.signedp = SIGNED;
399 if ($1.signedp & $3.signedp)
400 $$.value = $1.value < $3.value;
402 $$.value = ((unsigned HOST_WIDE_INT) $1.value
405 { $$.signedp = SIGNED;
406 if ($1.signedp & $3.signedp)
407 $$.value = $1.value > $3.value;
409 $$.value = ((unsigned HOST_WIDE_INT) $1.value
412 { $$.value = $1.value & $3.value;
413 $$.signedp = $1.signedp & $3.signedp; }
415 { $$.value = $1.value ^ $3.value;
416 $$.signedp = $1.signedp & $3.signedp; }
418 { $$.value = $1.value | $3.value;
419 $$.signedp = $1.signedp & $3.signedp; }
421 { skip_evaluation += !$1.value; }
423 { skip_evaluation -= !$1.value;
424 $$.value = ($1.value && $4.value);
425 $$.signedp = SIGNED; }
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 - !$1.value; }
437 { skip_evaluation -= !!$1.value;
438 $$.value = $1.value ? $4.value : $7.value;
439 $$.signedp = $4.signedp & $7.signedp; }
441 { $$ = yylval.integer; }
443 { $$ = yylval.integer; }
446 $$.signedp = SIGNED; }
451 | '(' keywords ')' keywords
452 { struct arglist *temp;
453 $$ = (struct arglist *) xmalloc (sizeof (struct arglist));
455 $$->name = (U_CHAR *) "(";
458 while (temp != 0 && temp->next != 0)
460 temp->next = (struct arglist *) xmalloc (sizeof (struct arglist));
461 temp->next->next = $4;
462 temp->next->name = (U_CHAR *) ")";
463 temp->next->length = 1; }
465 { $$ = (struct arglist *) xmalloc (sizeof (struct arglist));
466 $$->name = $1.address;
467 $$->length = $1.length;
472 /* During parsing of a C expression, the pointer to the next character
473 is in this variable. */
477 /* Take care of parsing a number (anything that starts with a digit).
478 Set yylval and return the token type; update lexptr.
479 LEN is the number of characters in it. */
481 /* maybe needs to actually deal with floating point numbers */
487 register char *p = lexptr;
489 register unsigned HOST_WIDE_INT n = 0, nd, max_over_base;
490 register int base = 10;
491 register int len = olen;
492 register int overflow = 0;
493 register int digit, largest_digit = 0;
496 yylval.integer.signedp = SIGNED;
500 if (len >= 3 && (p[1] == 'x' || p[1] == 'X')) {
507 max_over_base = (unsigned HOST_WIDE_INT) -1 / base;
509 for (; len > 0; len--) {
512 if (c >= '0' && c <= '9')
514 else if (base == 16 && c >= 'a' && c <= 'f')
515 digit = c - 'a' + 10;
516 else if (base == 16 && c >= 'A' && c <= 'F')
517 digit = c - 'A' + 10;
519 /* `l' means long, and `u' means unsigned. */
521 if (c == 'l' || c == 'L')
523 if (!pedantic < spec_long)
524 yyerror ("too many `l's in integer constant");
527 else if (c == 'u' || c == 'U')
529 if (! yylval.integer.signedp)
530 yyerror ("two `u's in integer constant");
531 yylval.integer.signedp = UNSIGNED;
534 if (c == '.' || c == 'e' || c == 'E')
535 yyerror ("Floating point numbers not allowed in #if expressions");
537 char *buf = (char *) alloca (p - lexptr + 40);
538 sprintf (buf, "missing white space after number `%.*s'",
539 (int) (p - lexptr - 1), lexptr);
548 /* Don't look for any more digits after the suffixes. */
551 if (largest_digit < digit)
552 largest_digit = digit;
553 nd = n * base + digit;
554 overflow |= (max_over_base < n) | (nd < n);
558 if (base <= largest_digit)
559 warning ("integer constant contains digits beyond the radix");
562 warning ("integer constant out of range");
564 /* If too big to be signed, consider it unsigned. */
565 if (((HOST_WIDE_INT) n & yylval.integer.signedp) < 0)
568 warning ("integer constant is so large that it is unsigned");
569 yylval.integer.signedp = UNSIGNED;
573 yylval.integer.value = n;
582 static struct token tokentab2[] = {
596 /* Read one token, getting characters through lexptr. */
602 register int namelen;
603 register unsigned char *tokstart;
604 register struct token *toktab;
610 tokstart = (unsigned char *) lexptr;
612 /* See if it is a special token of length 2. */
613 if (! keyword_parsing)
614 for (toktab = tokentab2; toktab->operator != NULL; toktab++)
615 if (c == *toktab->operator && tokstart[1] == toktab->operator[1]) {
617 if (toktab->token == ERROR)
619 char *buf = (char *) alloca (40);
620 sprintf (buf, "`%s' not allowed in operand of `#if'", toktab->operator);
623 return toktab->token;
637 /* Capital L may start a wide-string or wide-character constant. */
638 if (lexptr[1] == '\'')
642 mask = MAX_WCHAR_TYPE_MASK;
645 if (lexptr[1] == '"')
649 mask = MAX_WCHAR_TYPE_MASK;
650 goto string_constant;
656 mask = MAX_CHAR_TYPE_MASK;
659 if (keyword_parsing) {
660 char *start_ptr = lexptr - 1;
664 c = parse_escape (&lexptr, mask);
668 yylval.name.address = tokstart;
669 yylval.name.length = lexptr - start_ptr;
673 /* This code for reading a character constant
674 handles multicharacter constants and wide characters.
675 It is mostly copied from c-lex.c. */
677 register HOST_WIDE_INT result = 0;
678 register num_chars = 0;
679 unsigned width = MAX_CHAR_TYPE_SIZE;
685 width = MAX_WCHAR_TYPE_SIZE;
686 #ifdef MULTIBYTE_CHARS
687 max_chars = MB_CUR_MAX;
693 max_chars = MAX_LONG_TYPE_SIZE / width;
695 token_buffer = (char *) alloca (max_chars + 1);
701 if (c == '\'' || c == EOF)
706 c = parse_escape (&lexptr, mask);
711 /* Merge character into result; ignore excess chars. */
712 if (num_chars <= max_chars)
714 if (width < HOST_BITS_PER_WIDE_INT)
715 result = (result << width) | c;
718 token_buffer[num_chars - 1] = c;
722 token_buffer[num_chars] = 0;
725 error ("malformatted character constant");
726 else if (num_chars == 0)
727 error ("empty character constant");
728 else if (num_chars > max_chars)
730 num_chars = max_chars;
731 error ("character constant too long");
733 else if (num_chars != 1 && ! traditional)
734 warning ("multi-character character constant");
736 /* If char type is signed, sign-extend the constant. */
739 int num_bits = num_chars * width;
741 if (lookup ((U_CHAR *) "__CHAR_UNSIGNED__",
742 sizeof ("__CHAR_UNSIGNED__") - 1, -1)
743 || ((result >> (num_bits - 1)) & 1) == 0)
745 = result & (~ (unsigned HOST_WIDE_INT) 0
746 >> (HOST_BITS_PER_WIDE_INT - num_bits));
749 = result | ~(~ (unsigned HOST_WIDE_INT) 0
750 >> (HOST_BITS_PER_WIDE_INT - num_bits));
754 #ifdef MULTIBYTE_CHARS
755 /* Set the initial shift state and convert the next sequence. */
757 /* In all locales L'\0' is zero and mbtowc will return zero,
760 || (num_chars == 1 && token_buffer[0] != '\0'))
763 (void) mbtowc (NULL_PTR, NULL_PTR, 0);
764 if (mbtowc (& wc, token_buffer, num_chars) == num_chars)
767 warning ("Ignoring invalid multibyte character");
770 yylval.integer.value = result;
774 /* This is always a signed type. */
775 yylval.integer.signedp = SIGNED;
779 /* some of these chars are invalid in constant expressions;
780 maybe do something about them later */
812 mask = MAX_CHAR_TYPE_MASK;
814 if (keyword_parsing) {
815 char *start_ptr = lexptr;
820 c = parse_escape (&lexptr, mask);
824 yylval.name.address = tokstart;
825 yylval.name.length = lexptr - start_ptr;
828 yyerror ("string constants not allowed in #if expressions");
832 if (c >= '0' && c <= '9' && !keyword_parsing) {
834 for (namelen = 1; ; namelen++) {
835 int d = tokstart[namelen];
836 if (! ((is_idchar[d] || d == '.')
837 || ((d == '-' || d == '+') && (c == 'e' || c == 'E')
842 return parse_number (namelen);
845 /* It is a name. See how long it is. */
847 if (keyword_parsing) {
848 for (namelen = 0;; namelen++) {
849 if (is_hor_space[tokstart[namelen]])
851 if (tokstart[namelen] == '(' || tokstart[namelen] == ')')
853 if (tokstart[namelen] == '"' || tokstart[namelen] == '\'')
857 if (!is_idstart[c]) {
858 yyerror ("Invalid token in expression");
862 for (namelen = 0; is_idchar[tokstart[namelen]]; namelen++)
867 yylval.name.address = tokstart;
868 yylval.name.length = namelen;
873 /* Parse a C escape sequence. STRING_PTR points to a variable
874 containing a pointer to the string to parse. That pointer
875 is updated past the characters we use. The value of the
876 escape sequence is returned.
878 RESULT_MASK is used to mask out the result;
879 an error is reported if bits are lost thereby.
881 A negative value means the sequence \ newline was seen,
882 which is supposed to be equivalent to nothing at all.
884 If \ is followed by a null character, we return a negative
885 value and leave the string pointer pointing at the null character.
887 If \ is followed by 000, we return 0 and leave the string pointer
888 after the zeros. A value of 0 does not mean end of string. */
891 parse_escape (string_ptr, result_mask)
893 HOST_WIDE_INT result_mask;
895 register int c = *(*string_ptr)++;
905 pedwarn ("non-ANSI-standard escape sequence, `\\%c'", c);
910 return TARGET_NEWLINE;
932 register HOST_WIDE_INT i = c - '0';
933 register int count = 0;
936 c = *(*string_ptr)++;
937 if (c >= '0' && c <= '7')
938 i = (i << 3) + c - '0';
945 if (i != (i & result_mask))
948 pedwarn ("octal escape sequence out of range");
954 register unsigned HOST_WIDE_INT i = 0, overflow = 0;
955 register int digits_found = 0, digit;
958 c = *(*string_ptr)++;
959 if (c >= '0' && c <= '9')
961 else if (c >= 'a' && c <= 'f')
962 digit = c - 'a' + 10;
963 else if (c >= 'A' && c <= 'F')
964 digit = c - 'A' + 10;
970 overflow |= i ^ (i << 4 >> 4);
971 i = (i << 4) + digit;
975 yyerror ("\\x used with no following hex digits");
976 if (overflow | (i != (i & result_mask)))
979 pedwarn ("hex escape sequence out of range");
994 longjmp (parse_return_error, 1);
1000 if (!skip_evaluation && pedantic)
1001 pedwarn ("integer overflow in preprocessor expression");
1004 static HOST_WIDE_INT
1007 unsigned HOST_WIDE_INT b;
1009 /* It's unclear from the C standard whether shifts can overflow.
1010 The following code ignores overflow; perhaps a C standard
1011 interpretation ruling is needed. */
1012 if (b >= HOST_BITS_PER_WIDE_INT)
1015 return (unsigned HOST_WIDE_INT) a->value << b;
1018 static HOST_WIDE_INT
1021 unsigned HOST_WIDE_INT b;
1023 if (b >= HOST_BITS_PER_WIDE_INT)
1024 return a->signedp ? a->value >> (HOST_BITS_PER_WIDE_INT - 1) : 0;
1025 else if (a->signedp)
1026 return a->value >> b;
1028 return (unsigned HOST_WIDE_INT) a->value >> b;
1031 /* This page contains the entry point to this file. */
1033 /* Parse STRING as an expression, and complain if this fails
1034 to use up all of the contents of STRING. */
1035 /* STRING may contain '\0' bytes; it is terminated by the first '\n'
1036 outside a string constant, so that we can diagnose '\0' properly. */
1037 /* We do not support C comments. They should be removed before
1038 this function is called. */
1041 parse_c_expression (string)
1046 if (lexptr == 0 || *lexptr == 0) {
1047 error ("empty #if expression");
1048 return 0; /* don't include the #if group */
1051 /* if there is some sort of scanning error, just return 0 and assume
1052 the parsing routine has printed an error message somewhere.
1053 there is surely a better thing to do than this. */
1054 if (setjmp (parse_return_error))
1058 return 0; /* actually this is never reached
1059 the way things stand. */
1060 if (*lexptr != '\n')
1061 error ("Junk after end of expression.");
1063 return expression_value; /* set by yyparse () */
1066 #ifdef TEST_EXP_READER
1075 int main PROTO((int, char **));
1076 static void initialize_random_junk PROTO((void));
1078 /* Main program for testing purposes. */
1087 pedantic = 1 < argc;
1088 traditional = 2 < argc;
1092 initialize_random_junk ();
1095 printf ("enter expression: ");
1097 while ((buf[n] = c = getchar ()) != '\n' && c != EOF)
1101 printf ("parser returned %ld\n", (long) parse_c_expression (buf));
1107 /* table to tell if char can be part of a C identifier. */
1108 unsigned char is_idchar[256];
1109 /* table to tell if char can be first char of a c identifier. */
1110 unsigned char is_idstart[256];
1111 /* table to tell if c is horizontal space. isspace () thinks that
1112 newline is space; this is not a good idea for this program. */
1113 unsigned char is_hor_space[256];
1116 * initialize random junk in the hash table and maybe other places
1119 initialize_random_junk ()
1124 * Set up is_idchar and is_idstart tables. These should be
1125 * faster than saying (is_alpha (c) || c == '_'), etc.
1126 * Must do set up these things before calling any routines tthat
1129 for (i = 'a'; i <= 'z'; i++) {
1130 ++is_idchar[i - 'a' + 'A'];
1132 ++is_idstart[i - 'a' + 'A'];
1135 for (i = '0'; i <= '9'; i++)
1142 /* horizontal space table */
1143 ++is_hor_space[' '];
1144 ++is_hor_space['\t'];
1148 error (PRINTF_ALIST (msg))
1153 VA_START (args, msg);
1154 fprintf (stderr, "error: ");
1155 vfprintf (stderr, msg, args);
1156 fprintf (stderr, "\n");
1161 pedwarn (PRINTF_ALIST (msg))
1166 VA_START (args, msg);
1167 fprintf (stderr, "pedwarn: ");
1168 vfprintf (stderr, msg, args);
1169 fprintf (stderr, "\n");
1174 warning (PRINTF_ALIST (msg))
1179 VA_START (args, msg);
1180 fprintf (stderr, "warning: ");
1181 vfprintf (stderr, msg, args);
1182 fprintf (stderr, "\n");
1187 check_assertion (name, sym_length, tokens_specified, tokens)
1190 int tokens_specified;
1191 struct arglist *tokens;
1197 lookup (name, len, hash)
1202 return (DEFAULT_SIGNED_CHAR) ? 0 : ((struct hashnode *) -1);
1209 return (GENERIC_PTR) malloc (size);