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 */
35 #define PRINTF_PROTO(ARGS, m, n) PVPROTO (ARGS) ATTRIBUTE_PRINTF(m, n)
37 #define PRINTF_PROTO_1(ARGS) PRINTF_PROTO(ARGS, 1, 2)
41 /* #define YYDEBUG 1 */
43 #ifdef MULTIBYTE_CHARS
47 #include "gansidecl.h"
49 typedef unsigned char U_CHAR;
51 /* This is used for communicating lists of keywords with cccp.c. */
59 /* Find the largest host integer type and set its size and type.
60 Watch out: on some crazy hosts `long' is shorter than `int'. */
64 # include <inttypes.h>
65 # define HOST_WIDE_INT intmax_t
66 # define unsigned_HOST_WIDE_INT uintmax_t
68 # if (HOST_BITS_PER_LONG <= HOST_BITS_PER_INT && HOST_BITS_PER_LONGLONG <= HOST_BITS_PER_INT)
69 # define HOST_WIDE_INT int
71 # if (HOST_BITS_PER_LONGLONG <= HOST_BITS_PER_LONG || ! (defined LONG_LONG_MAX || defined LLONG_MAX))
72 # define HOST_WIDE_INT long
74 # define HOST_WIDE_INT long long
80 #ifndef unsigned_HOST_WIDE_INT
81 #define unsigned_HOST_WIDE_INT unsigned HOST_WIDE_INT
88 #ifndef HOST_BITS_PER_WIDE_INT
89 #define HOST_BITS_PER_WIDE_INT (CHAR_BIT * sizeof (HOST_WIDE_INT))
92 HOST_WIDE_INT parse_c_expression PROTO((char *, int));
94 static int yylex PROTO((void));
95 static void yyerror PROTO((char *)) __attribute__ ((noreturn));
96 static HOST_WIDE_INT expression_value;
97 #ifdef TEST_EXP_READER
98 static int expression_signedp;
101 static jmp_buf parse_return_error;
103 /* Nonzero means count most punctuation as part of a name. */
104 static int keyword_parsing = 0;
106 /* Nonzero means do not evaluate this expression.
107 This is a count, since unevaluated expressions can nest. */
108 static int skip_evaluation;
110 /* Nonzero means warn if undefined identifiers are evaluated. */
111 static int warn_undef;
113 /* some external tables of character types */
114 extern unsigned char is_idstart[], is_idchar[], is_space[];
116 /* Flag for -pedantic. */
119 /* Flag for -traditional. */
120 extern int traditional;
122 /* Flag for -lang-c89. */
125 #ifndef CHAR_TYPE_SIZE
126 #define CHAR_TYPE_SIZE BITS_PER_UNIT
129 #ifndef INT_TYPE_SIZE
130 #define INT_TYPE_SIZE BITS_PER_WORD
133 #ifndef LONG_TYPE_SIZE
134 #define LONG_TYPE_SIZE BITS_PER_WORD
137 #ifndef WCHAR_TYPE_SIZE
138 #define WCHAR_TYPE_SIZE INT_TYPE_SIZE
141 #ifndef MAX_CHAR_TYPE_SIZE
142 #define MAX_CHAR_TYPE_SIZE CHAR_TYPE_SIZE
145 #ifndef MAX_INT_TYPE_SIZE
146 #define MAX_INT_TYPE_SIZE INT_TYPE_SIZE
149 #ifndef MAX_LONG_TYPE_SIZE
150 #define MAX_LONG_TYPE_SIZE LONG_TYPE_SIZE
153 #ifndef MAX_WCHAR_TYPE_SIZE
154 #define MAX_WCHAR_TYPE_SIZE WCHAR_TYPE_SIZE
157 #define MAX_CHAR_TYPE_MASK (MAX_CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT \
158 ? (~ (~ (HOST_WIDE_INT) 0 << MAX_CHAR_TYPE_SIZE)) \
159 : ~ (HOST_WIDE_INT) 0)
161 #define MAX_WCHAR_TYPE_MASK (MAX_WCHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT \
162 ? ~ (~ (HOST_WIDE_INT) 0 << MAX_WCHAR_TYPE_SIZE) \
163 : ~ (HOST_WIDE_INT) 0)
165 /* Suppose A1 + B1 = SUM1, using 2's complement arithmetic ignoring overflow.
166 Suppose A, B and SUM have the same respective signs as A1, B1, and SUM1.
167 Suppose SIGNEDP is negative if the result is signed, zero if unsigned.
168 Then this yields nonzero if overflow occurred during the addition.
169 Overflow occurs if A and B have the same sign, but A and SUM differ in sign,
170 and SIGNEDP is negative.
171 Use `^' to test whether signs differ, and `< 0' to isolate the sign. */
172 #define overflow_sum_sign(a, b, sum, signedp) \
173 ((~((a) ^ (b)) & ((a) ^ (sum)) & (signedp)) < 0)
177 GENERIC_PTR xmalloc PROTO((size_t));
178 HOST_WIDE_INT parse_escape PROTO((char **, HOST_WIDE_INT));
179 int check_assertion PROTO((U_CHAR *, int, int, struct arglist *));
180 struct hashnode *lookup PROTO((U_CHAR *, int, int));
181 void error PRINTF_PROTO_1((char *, ...));
182 void pedwarn PRINTF_PROTO_1((char *, ...));
183 void warning PRINTF_PROTO_1((char *, ...));
185 static int parse_number PROTO((int));
186 static HOST_WIDE_INT left_shift PROTO((struct constant *, unsigned_HOST_WIDE_INT));
187 static HOST_WIDE_INT right_shift PROTO((struct constant *, unsigned_HOST_WIDE_INT));
188 static void integer_overflow PROTO((void));
190 /* `signedp' values */
196 struct constant {HOST_WIDE_INT value; int signedp;} integer;
197 struct name {U_CHAR *address; int length;} name;
198 struct arglist *keywords;
201 %type <integer> exp exp1 start
202 %type <keywords> keywords
203 %token <integer> INT CHAR
205 %token <integer> ERROR
215 %left '<' '>' LEQ GEQ
227 expression_value = $1.value;
228 #ifdef TEST_EXP_READER
229 expression_signedp = $1.signedp;
234 /* Expressions, including the comma operator. */
238 pedwarn ("comma operator in operand of `#if'");
242 /* Expressions, not including the comma operator. */
243 exp : '-' exp %prec UNARY
244 { $$.value = - $2.value;
245 $$.signedp = $2.signedp;
246 if (($$.value & $2.value & $$.signedp) < 0)
247 integer_overflow (); }
248 | '!' exp %prec UNARY
249 { $$.value = ! $2.value;
250 $$.signedp = SIGNED; }
251 | '+' exp %prec UNARY
253 | '~' exp %prec UNARY
254 { $$.value = ~ $2.value;
255 $$.signedp = $2.signedp; }
257 { $$.value = check_assertion ($2.address, $2.length,
259 $$.signedp = SIGNED; }
261 { keyword_parsing = 1; }
263 { $$.value = check_assertion ($2.address, $2.length,
266 $$.signedp = SIGNED; }
271 /* Binary operators in order of decreasing precedence. */
273 { $$.signedp = $1.signedp & $3.signedp;
276 $$.value = $1.value * $3.value;
278 && ($$.value / $1.value != $3.value
279 || ($$.value & $1.value & $3.value) < 0))
283 $$.value = ((unsigned_HOST_WIDE_INT) $1.value
288 if (!skip_evaluation)
289 error ("division by zero in #if");
292 $$.signedp = $1.signedp & $3.signedp;
295 $$.value = $1.value / $3.value;
296 if (($$.value & $1.value & $3.value) < 0)
300 $$.value = ((unsigned_HOST_WIDE_INT) $1.value
305 if (!skip_evaluation)
306 error ("division by zero in #if");
309 $$.signedp = $1.signedp & $3.signedp;
311 $$.value = $1.value % $3.value;
313 $$.value = ((unsigned_HOST_WIDE_INT) $1.value
316 { $$.value = $1.value + $3.value;
317 $$.signedp = $1.signedp & $3.signedp;
318 if (overflow_sum_sign ($1.value, $3.value,
319 $$.value, $$.signedp))
320 integer_overflow (); }
322 { $$.value = $1.value - $3.value;
323 $$.signedp = $1.signedp & $3.signedp;
324 if (overflow_sum_sign ($$.value, $3.value,
325 $1.value, $$.signedp))
326 integer_overflow (); }
328 { $$.signedp = $1.signedp;
329 if (($3.value & $3.signedp) < 0)
330 $$.value = right_shift (&$1, -$3.value);
332 $$.value = left_shift (&$1, $3.value); }
334 { $$.signedp = $1.signedp;
335 if (($3.value & $3.signedp) < 0)
336 $$.value = left_shift (&$1, -$3.value);
338 $$.value = right_shift (&$1, $3.value); }
340 { $$.value = ($1.value == $3.value);
341 $$.signedp = SIGNED; }
343 { $$.value = ($1.value != $3.value);
344 $$.signedp = SIGNED; }
346 { $$.signedp = SIGNED;
347 if ($1.signedp & $3.signedp)
348 $$.value = $1.value <= $3.value;
350 $$.value = ((unsigned_HOST_WIDE_INT) $1.value
353 { $$.signedp = SIGNED;
354 if ($1.signedp & $3.signedp)
355 $$.value = $1.value >= $3.value;
357 $$.value = ((unsigned_HOST_WIDE_INT) $1.value
360 { $$.signedp = SIGNED;
361 if ($1.signedp & $3.signedp)
362 $$.value = $1.value < $3.value;
364 $$.value = ((unsigned_HOST_WIDE_INT) $1.value
367 { $$.signedp = SIGNED;
368 if ($1.signedp & $3.signedp)
369 $$.value = $1.value > $3.value;
371 $$.value = ((unsigned_HOST_WIDE_INT) $1.value
374 { $$.value = $1.value & $3.value;
375 $$.signedp = $1.signedp & $3.signedp; }
377 { $$.value = $1.value ^ $3.value;
378 $$.signedp = $1.signedp & $3.signedp; }
380 { $$.value = $1.value | $3.value;
381 $$.signedp = $1.signedp & $3.signedp; }
383 { skip_evaluation += !$1.value; }
385 { skip_evaluation -= !$1.value;
386 $$.value = ($1.value && $4.value);
387 $$.signedp = SIGNED; }
389 { skip_evaluation += !!$1.value; }
391 { skip_evaluation -= !!$1.value;
392 $$.value = ($1.value || $4.value);
393 $$.signedp = SIGNED; }
395 { skip_evaluation += !$1.value; }
397 { skip_evaluation += !!$1.value - !$1.value; }
399 { skip_evaluation -= !!$1.value;
400 $$.value = $1.value ? $4.value : $7.value;
401 $$.signedp = $4.signedp & $7.signedp; }
403 { $$ = yylval.integer; }
405 { $$ = yylval.integer; }
407 { if (warn_undef && !skip_evaluation)
408 warning ("`%.*s' is not defined",
409 $1.length, $1.address);
411 $$.signedp = SIGNED; }
416 | '(' keywords ')' keywords
417 { struct arglist *temp;
418 $$ = (struct arglist *) xmalloc (sizeof (struct arglist));
420 $$->name = (U_CHAR *) "(";
423 while (temp != 0 && temp->next != 0)
425 temp->next = (struct arglist *) xmalloc (sizeof (struct arglist));
426 temp->next->next = $4;
427 temp->next->name = (U_CHAR *) ")";
428 temp->next->length = 1; }
430 { $$ = (struct arglist *) xmalloc (sizeof (struct arglist));
431 $$->name = $1.address;
432 $$->length = $1.length;
437 /* During parsing of a C expression, the pointer to the next character
438 is in this variable. */
442 /* Take care of parsing a number (anything that starts with a digit).
443 Set yylval and return the token type; update lexptr.
444 LEN is the number of characters in it. */
446 /* maybe needs to actually deal with floating point numbers */
452 register char *p = lexptr;
454 register unsigned_HOST_WIDE_INT n = 0, nd, max_over_base;
455 register int base = 10;
456 register int len = olen;
457 register int overflow = 0;
458 register int digit, largest_digit = 0;
461 yylval.integer.signedp = SIGNED;
465 if (len >= 3 && (p[1] == 'x' || p[1] == 'X')) {
472 max_over_base = (unsigned_HOST_WIDE_INT) -1 / base;
474 for (; len > 0; len--) {
477 if (c >= '0' && c <= '9')
479 else if (base == 16 && c >= 'a' && c <= 'f')
480 digit = c - 'a' + 10;
481 else if (base == 16 && c >= 'A' && c <= 'F')
482 digit = c - 'A' + 10;
484 /* `l' means long, and `u' means unsigned. */
486 if (c == 'l' || c == 'L')
488 if (!pedantic < spec_long)
489 yyerror ("too many `l's in integer constant");
492 else if (c == 'u' || c == 'U')
494 if (! yylval.integer.signedp)
495 yyerror ("two `u's in integer constant");
496 yylval.integer.signedp = UNSIGNED;
499 if (c == '.' || c == 'e' || c == 'E' || c == 'p' || c == 'P')
500 yyerror ("Floating point numbers not allowed in #if expressions");
502 char *buf = (char *) alloca (p - lexptr + 40);
503 sprintf (buf, "missing white space after number `%.*s'",
504 (int) (p - lexptr - 1), lexptr);
513 /* Don't look for any more digits after the suffixes. */
516 if (largest_digit < digit)
517 largest_digit = digit;
518 nd = n * base + digit;
519 overflow |= (max_over_base < n) | (nd < n);
523 if (base <= largest_digit)
524 pedwarn ("integer constant contains digits beyond the radix");
527 pedwarn ("integer constant out of range");
529 /* If too big to be signed, consider it unsigned. */
530 if (((HOST_WIDE_INT) n & yylval.integer.signedp) < 0)
533 warning ("integer constant is so large that it is unsigned");
534 yylval.integer.signedp = UNSIGNED;
538 yylval.integer.value = n;
547 static struct token tokentab2[] = {
561 /* Read one token, getting characters through lexptr. */
567 register int namelen;
568 register unsigned char *tokstart;
569 register struct token *toktab;
575 tokstart = (unsigned char *) lexptr;
577 /* See if it is a special token of length 2. */
578 if (! keyword_parsing)
579 for (toktab = tokentab2; toktab->operator != NULL; toktab++)
580 if (c == *toktab->operator && tokstart[1] == toktab->operator[1]) {
582 if (toktab->token == ERROR)
584 char *buf = (char *) alloca (40);
585 sprintf (buf, "`%s' not allowed in operand of `#if'", toktab->operator);
588 return toktab->token;
602 /* Capital L may start a wide-string or wide-character constant. */
603 if (lexptr[1] == '\'')
607 mask = MAX_WCHAR_TYPE_MASK;
610 if (lexptr[1] == '"')
614 mask = MAX_WCHAR_TYPE_MASK;
615 goto string_constant;
621 mask = MAX_CHAR_TYPE_MASK;
624 if (keyword_parsing) {
625 char *start_ptr = lexptr - 1;
629 c = parse_escape (&lexptr, mask);
633 yylval.name.address = tokstart;
634 yylval.name.length = lexptr - start_ptr;
638 /* This code for reading a character constant
639 handles multicharacter constants and wide characters.
640 It is mostly copied from c-lex.c. */
642 register HOST_WIDE_INT result = 0;
643 register int num_chars = 0;
644 unsigned width = MAX_CHAR_TYPE_SIZE;
650 width = MAX_WCHAR_TYPE_SIZE;
651 #ifdef MULTIBYTE_CHARS
652 max_chars = MB_CUR_MAX;
658 max_chars = MAX_LONG_TYPE_SIZE / width;
660 token_buffer = (char *) alloca (max_chars + 1);
666 if (c == '\'' || c == EOF)
671 c = parse_escape (&lexptr, mask);
676 /* Merge character into result; ignore excess chars. */
677 if (num_chars <= max_chars)
679 if (width < HOST_BITS_PER_WIDE_INT)
680 result = (result << width) | c;
683 token_buffer[num_chars - 1] = c;
687 token_buffer[num_chars] = 0;
690 error ("malformatted character constant");
691 else if (num_chars == 0)
692 error ("empty character constant");
693 else if (num_chars > max_chars)
695 num_chars = max_chars;
696 error ("character constant too long");
698 else if (num_chars != 1 && ! traditional)
699 warning ("multi-character character constant");
701 /* If char type is signed, sign-extend the constant. */
704 int num_bits = num_chars * width;
706 if (lookup ((U_CHAR *) "__CHAR_UNSIGNED__",
707 sizeof ("__CHAR_UNSIGNED__") - 1, -1)
708 || ((result >> (num_bits - 1)) & 1) == 0)
710 = result & (~ (unsigned_HOST_WIDE_INT) 0
711 >> (HOST_BITS_PER_WIDE_INT - num_bits));
714 = result | ~(~ (unsigned_HOST_WIDE_INT) 0
715 >> (HOST_BITS_PER_WIDE_INT - num_bits));
719 #ifdef MULTIBYTE_CHARS
720 /* Set the initial shift state and convert the next sequence. */
722 /* In all locales L'\0' is zero and mbtowc will return zero,
725 || (num_chars == 1 && token_buffer[0] != '\0'))
728 (void) mbtowc (NULL_PTR, NULL_PTR, 0);
729 if (mbtowc (& wc, token_buffer, num_chars) == num_chars)
732 pedwarn ("Ignoring invalid multibyte character");
735 yylval.integer.value = result;
739 /* This is always a signed type. */
740 yylval.integer.signedp = SIGNED;
744 /* some of these chars are invalid in constant expressions;
745 maybe do something about them later */
777 mask = MAX_CHAR_TYPE_MASK;
779 if (keyword_parsing) {
780 char *start_ptr = lexptr;
785 c = parse_escape (&lexptr, mask);
789 yylval.name.address = tokstart;
790 yylval.name.length = lexptr - start_ptr;
793 yyerror ("string constants not allowed in #if expressions");
797 if (c >= '0' && c <= '9' && !keyword_parsing) {
799 for (namelen = 1; ; namelen++) {
800 int d = tokstart[namelen];
801 if (! ((is_idchar[d] || d == '.')
802 || ((d == '-' || d == '+')
803 && (c == 'e' || c == 'E'
804 || ((c == 'p' || c == 'P') && ! c89))
809 return parse_number (namelen);
812 /* It is a name. See how long it is. */
814 if (keyword_parsing) {
815 for (namelen = 0;; namelen++) {
816 if (is_space[tokstart[namelen]])
818 if (tokstart[namelen] == '(' || tokstart[namelen] == ')')
820 if (tokstart[namelen] == '"' || tokstart[namelen] == '\'')
824 if (!is_idstart[c]) {
825 yyerror ("Invalid token in expression");
829 for (namelen = 0; is_idchar[tokstart[namelen]]; namelen++)
834 yylval.name.address = tokstart;
835 yylval.name.length = namelen;
840 /* Parse a C escape sequence. STRING_PTR points to a variable
841 containing a pointer to the string to parse. That pointer
842 is updated past the characters we use. The value of the
843 escape sequence is returned.
845 RESULT_MASK is used to mask out the result;
846 an error is reported if bits are lost thereby.
848 A negative value means the sequence \ newline was seen,
849 which is supposed to be equivalent to nothing at all.
851 If \ is followed by a null character, we return a negative
852 value and leave the string pointer pointing at the null character.
854 If \ is followed by 000, we return 0 and leave the string pointer
855 after the zeros. A value of 0 does not mean end of string. */
858 parse_escape (string_ptr, result_mask)
860 HOST_WIDE_INT result_mask;
862 register int c = *(*string_ptr)++;
872 pedwarn ("non-ANSI-standard escape sequence, `\\%c'", c);
877 return TARGET_NEWLINE;
899 register HOST_WIDE_INT i = c - '0';
900 register int count = 0;
903 c = *(*string_ptr)++;
904 if (c >= '0' && c <= '7')
905 i = (i << 3) + c - '0';
912 if (i != (i & result_mask))
915 pedwarn ("octal escape sequence out of range");
921 register unsigned_HOST_WIDE_INT i = 0, overflow = 0;
922 register int digits_found = 0, digit;
925 c = *(*string_ptr)++;
926 if (c >= '0' && c <= '9')
928 else if (c >= 'a' && c <= 'f')
929 digit = c - 'a' + 10;
930 else if (c >= 'A' && c <= 'F')
931 digit = c - 'A' + 10;
937 overflow |= i ^ (i << 4 >> 4);
938 i = (i << 4) + digit;
942 yyerror ("\\x used with no following hex digits");
943 if (overflow | (i != (i & result_mask)))
946 pedwarn ("hex escape sequence out of range");
961 longjmp (parse_return_error, 1);
967 if (!skip_evaluation && pedantic)
968 pedwarn ("integer overflow in preprocessor expression");
974 unsigned_HOST_WIDE_INT b;
976 /* It's unclear from the C standard whether shifts can overflow.
977 The following code ignores overflow; perhaps a C standard
978 interpretation ruling is needed. */
979 if (b >= HOST_BITS_PER_WIDE_INT)
982 return (unsigned_HOST_WIDE_INT) a->value << b;
988 unsigned_HOST_WIDE_INT b;
990 if (b >= HOST_BITS_PER_WIDE_INT)
991 return a->signedp ? a->value >> (HOST_BITS_PER_WIDE_INT - 1) : 0;
993 return a->value >> b;
995 return (unsigned_HOST_WIDE_INT) a->value >> b;
998 /* This page contains the entry point to this file. */
1000 /* Parse STRING as an expression, and complain if this fails
1001 to use up all of the contents of STRING.
1002 STRING may contain '\0' bytes; it is terminated by the first '\n'
1003 outside a string constant, so that we can diagnose '\0' properly.
1004 If WARN_UNDEFINED is nonzero, warn if undefined identifiers are evaluated.
1005 We do not support C comments. They should be removed before
1006 this function is called. */
1009 parse_c_expression (string, warn_undefined)
1014 warn_undef = warn_undefined;
1016 /* if there is some sort of scanning error, just return 0 and assume
1017 the parsing routine has printed an error message somewhere.
1018 there is surely a better thing to do than this. */
1019 if (setjmp (parse_return_error))
1022 if (yyparse () != 0)
1025 if (*lexptr != '\n')
1026 error ("Junk after end of expression.");
1028 return expression_value; /* set by yyparse () */
1031 #ifdef TEST_EXP_READER
1040 int main PROTO((int, char **));
1041 static void initialize_random_junk PROTO((void));
1042 static void print_unsigned_host_wide_int PROTO((unsigned_HOST_WIDE_INT));
1044 /* Main program for testing purposes. */
1052 unsigned_HOST_WIDE_INT u;
1054 pedantic = 1 < argc;
1055 traditional = 2 < argc;
1059 initialize_random_junk ();
1062 printf ("enter expression: ");
1064 while ((buf[n] = c = getchar ()) != '\n' && c != EOF)
1068 parse_c_expression (buf, 1);
1069 printf ("parser returned ");
1070 u = (unsigned_HOST_WIDE_INT) expression_value;
1071 if (expression_value < 0 && expression_signedp) {
1078 print_unsigned_host_wide_int (u);
1079 if (! expression_signedp)
1088 print_unsigned_host_wide_int (u)
1089 unsigned_HOST_WIDE_INT u;
1092 print_unsigned_host_wide_int (u / 10);
1093 putchar ('0' + (int) (u % 10));
1097 /* table to tell if char can be part of a C identifier. */
1098 unsigned char is_idchar[256];
1099 /* table to tell if char can be first char of a c identifier. */
1100 unsigned char is_idstart[256];
1101 /* table to tell if c is horizontal or vertical space. */
1102 unsigned char is_space[256];
1105 * initialize random junk in the hash table and maybe other places
1108 initialize_random_junk ()
1113 * Set up is_idchar and is_idstart tables. These should be
1114 * faster than saying (is_alpha (c) || c == '_'), etc.
1115 * Must do set up these things before calling any routines tthat
1118 for (i = 'a'; i <= 'z'; i++) {
1119 ++is_idchar[i - 'a' + 'A'];
1121 ++is_idstart[i - 'a' + 'A'];
1124 for (i = '0'; i <= '9'; i++)
1140 error VPROTO ((char * msg, ...))
1147 VA_START (args, msg);
1150 msg = va_arg (args, char *);
1153 fprintf (stderr, "error: ");
1154 vfprintf (stderr, msg, args);
1155 fprintf (stderr, "\n");
1160 pedwarn VPROTO ((char * msg, ...))
1167 VA_START (args, msg);
1170 msg = va_arg (args, char *);
1173 fprintf (stderr, "pedwarn: ");
1174 vfprintf (stderr, msg, args);
1175 fprintf (stderr, "\n");
1180 warning VPROTO ((char * msg, ...))
1187 VA_START (args, msg);
1190 msg = va_arg (args, char *);
1193 fprintf (stderr, "warning: ");
1194 vfprintf (stderr, msg, args);
1195 fprintf (stderr, "\n");
1200 check_assertion (name, sym_length, tokens_specified, tokens)
1203 int tokens_specified;
1204 struct arglist *tokens;
1210 lookup (name, len, hash)
1215 return (DEFAULT_SIGNED_CHAR) ? 0 : ((struct hashnode *) -1);
1222 return (GENERIC_PTR) malloc (size);