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 */
38 #ifdef MULTIBYTE_CHARS
41 #endif /* MULTIBYTE_CHARS */
43 typedef unsigned char U_CHAR;
45 /* This is used for communicating lists of keywords with cccp.c. */
53 /* Find the largest host integer type and set its size and type.
54 Watch out: on some crazy hosts `long' is shorter than `int'. */
58 # include <inttypes.h>
59 # define HOST_WIDE_INT intmax_t
60 # define unsigned_HOST_WIDE_INT uintmax_t
62 # if (HOST_BITS_PER_LONG <= HOST_BITS_PER_INT && HOST_BITS_PER_LONGLONG <= HOST_BITS_PER_INT)
63 # define HOST_WIDE_INT int
65 # if (HOST_BITS_PER_LONGLONG <= HOST_BITS_PER_LONG || ! (defined LONG_LONG_MAX || defined LLONG_MAX))
66 # define HOST_WIDE_INT long
68 # define HOST_WIDE_INT long long
74 #ifndef unsigned_HOST_WIDE_INT
75 #define unsigned_HOST_WIDE_INT unsigned HOST_WIDE_INT
82 #ifndef HOST_BITS_PER_WIDE_INT
83 #define HOST_BITS_PER_WIDE_INT (CHAR_BIT * sizeof (HOST_WIDE_INT))
86 HOST_WIDE_INT parse_c_expression PROTO((char *, int));
88 static int yylex PROTO((void));
89 static void yyerror PROTO((char *)) __attribute__ ((noreturn));
90 static HOST_WIDE_INT expression_value;
91 #ifdef TEST_EXP_READER
92 static int expression_signedp;
95 static jmp_buf parse_return_error;
97 /* Nonzero means count most punctuation as part of a name. */
98 static int keyword_parsing = 0;
100 /* Nonzero means do not evaluate this expression.
101 This is a count, since unevaluated expressions can nest. */
102 static int skip_evaluation;
104 /* Nonzero means warn if undefined identifiers are evaluated. */
105 static int warn_undef;
107 /* some external tables of character types */
108 extern unsigned char is_idstart[], is_idchar[], is_space[];
110 /* Flag for -pedantic. */
113 /* Flag for -traditional. */
114 extern int traditional;
116 /* Flag for -lang-c89. */
119 #ifndef CHAR_TYPE_SIZE
120 #define CHAR_TYPE_SIZE BITS_PER_UNIT
123 #ifndef INT_TYPE_SIZE
124 #define INT_TYPE_SIZE BITS_PER_WORD
127 #ifndef LONG_TYPE_SIZE
128 #define LONG_TYPE_SIZE BITS_PER_WORD
131 #ifndef WCHAR_TYPE_SIZE
132 #define WCHAR_TYPE_SIZE INT_TYPE_SIZE
135 #ifndef MAX_CHAR_TYPE_SIZE
136 #define MAX_CHAR_TYPE_SIZE CHAR_TYPE_SIZE
139 #ifndef MAX_INT_TYPE_SIZE
140 #define MAX_INT_TYPE_SIZE INT_TYPE_SIZE
143 #ifndef MAX_LONG_TYPE_SIZE
144 #define MAX_LONG_TYPE_SIZE LONG_TYPE_SIZE
147 #ifndef MAX_WCHAR_TYPE_SIZE
148 #define MAX_WCHAR_TYPE_SIZE WCHAR_TYPE_SIZE
151 #define MAX_CHAR_TYPE_MASK (MAX_CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT \
152 ? (~ (~ (HOST_WIDE_INT) 0 << MAX_CHAR_TYPE_SIZE)) \
153 : ~ (HOST_WIDE_INT) 0)
155 #define MAX_WCHAR_TYPE_MASK (MAX_WCHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT \
156 ? ~ (~ (HOST_WIDE_INT) 0 << MAX_WCHAR_TYPE_SIZE) \
157 : ~ (HOST_WIDE_INT) 0)
159 /* Suppose A1 + B1 = SUM1, using 2's complement arithmetic ignoring overflow.
160 Suppose A, B and SUM have the same respective signs as A1, B1, and SUM1.
161 Suppose SIGNEDP is negative if the result is signed, zero if unsigned.
162 Then this yields nonzero if overflow occurred during the addition.
163 Overflow occurs if A and B have the same sign, but A and SUM differ in sign,
164 and SIGNEDP is negative.
165 Use `^' to test whether signs differ, and `< 0' to isolate the sign. */
166 #define overflow_sum_sign(a, b, sum, signedp) \
167 ((~((a) ^ (b)) & ((a) ^ (sum)) & (signedp)) < 0)
171 HOST_WIDE_INT parse_escape PROTO((char **, HOST_WIDE_INT));
172 int check_assertion PROTO((U_CHAR *, int, int, struct arglist *));
173 struct hashnode *lookup PROTO((U_CHAR *, int, int));
174 void error PRINTF_PROTO_1((char *, ...));
175 void pedwarn PRINTF_PROTO_1((char *, ...));
176 void warning PRINTF_PROTO_1((char *, ...));
178 static int parse_number PROTO((int));
179 static HOST_WIDE_INT left_shift PROTO((struct constant *, unsigned_HOST_WIDE_INT));
180 static HOST_WIDE_INT right_shift PROTO((struct constant *, unsigned_HOST_WIDE_INT));
181 static void integer_overflow PROTO((void));
183 /* `signedp' values */
189 struct constant {HOST_WIDE_INT value; int signedp;} integer;
190 struct name {U_CHAR *address; int length;} name;
191 struct arglist *keywords;
194 %type <integer> exp exp1 start
195 %type <keywords> keywords
196 %token <integer> INT CHAR
198 %token <integer> ERROR
208 %left '<' '>' LEQ GEQ
220 expression_value = $1.value;
221 #ifdef TEST_EXP_READER
222 expression_signedp = $1.signedp;
227 /* Expressions, including the comma operator. */
231 pedwarn ("comma operator in operand of `#if'");
235 /* Expressions, not including the comma operator. */
236 exp : '-' exp %prec UNARY
237 { $$.value = - $2.value;
238 $$.signedp = $2.signedp;
239 if (($$.value & $2.value & $$.signedp) < 0)
240 integer_overflow (); }
241 | '!' exp %prec UNARY
242 { $$.value = ! $2.value;
243 $$.signedp = SIGNED; }
244 | '+' exp %prec UNARY
246 | '~' exp %prec UNARY
247 { $$.value = ~ $2.value;
248 $$.signedp = $2.signedp; }
250 { $$.value = check_assertion ($2.address, $2.length,
252 $$.signedp = SIGNED; }
254 { keyword_parsing = 1; }
256 { $$.value = check_assertion ($2.address, $2.length,
259 $$.signedp = SIGNED; }
264 /* Binary operators in order of decreasing precedence. */
266 { $$.signedp = $1.signedp & $3.signedp;
269 $$.value = $1.value * $3.value;
271 && ($$.value / $1.value != $3.value
272 || ($$.value & $1.value & $3.value) < 0))
276 $$.value = ((unsigned_HOST_WIDE_INT) $1.value
281 if (!skip_evaluation)
282 error ("division by zero in #if");
285 $$.signedp = $1.signedp & $3.signedp;
288 $$.value = $1.value / $3.value;
289 if (($$.value & $1.value & $3.value) < 0)
293 $$.value = ((unsigned_HOST_WIDE_INT) $1.value
298 if (!skip_evaluation)
299 error ("division by zero in #if");
302 $$.signedp = $1.signedp & $3.signedp;
304 $$.value = $1.value % $3.value;
306 $$.value = ((unsigned_HOST_WIDE_INT) $1.value
309 { $$.value = $1.value + $3.value;
310 $$.signedp = $1.signedp & $3.signedp;
311 if (overflow_sum_sign ($1.value, $3.value,
312 $$.value, $$.signedp))
313 integer_overflow (); }
315 { $$.value = $1.value - $3.value;
316 $$.signedp = $1.signedp & $3.signedp;
317 if (overflow_sum_sign ($$.value, $3.value,
318 $1.value, $$.signedp))
319 integer_overflow (); }
321 { $$.signedp = $1.signedp;
322 if (($3.value & $3.signedp) < 0)
323 $$.value = right_shift (&$1, -$3.value);
325 $$.value = left_shift (&$1, $3.value); }
327 { $$.signedp = $1.signedp;
328 if (($3.value & $3.signedp) < 0)
329 $$.value = left_shift (&$1, -$3.value);
331 $$.value = right_shift (&$1, $3.value); }
333 { $$.value = ($1.value == $3.value);
334 $$.signedp = SIGNED; }
336 { $$.value = ($1.value != $3.value);
337 $$.signedp = SIGNED; }
339 { $$.signedp = SIGNED;
340 if ($1.signedp & $3.signedp)
341 $$.value = $1.value <= $3.value;
343 $$.value = ((unsigned_HOST_WIDE_INT) $1.value
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 { $$.value = $1.value & $3.value;
368 $$.signedp = $1.signedp & $3.signedp; }
370 { $$.value = $1.value ^ $3.value;
371 $$.signedp = $1.signedp & $3.signedp; }
373 { $$.value = $1.value | $3.value;
374 $$.signedp = $1.signedp & $3.signedp; }
376 { skip_evaluation += !$1.value; }
378 { skip_evaluation -= !$1.value;
379 $$.value = ($1.value && $4.value);
380 $$.signedp = SIGNED; }
382 { skip_evaluation += !!$1.value; }
384 { skip_evaluation -= !!$1.value;
385 $$.value = ($1.value || $4.value);
386 $$.signedp = SIGNED; }
388 { skip_evaluation += !$1.value; }
390 { skip_evaluation += !!$1.value - !$1.value; }
392 { skip_evaluation -= !!$1.value;
393 $$.value = $1.value ? $4.value : $7.value;
394 $$.signedp = $4.signedp & $7.signedp; }
396 { $$ = yylval.integer; }
398 { $$ = yylval.integer; }
400 { if (warn_undef && !skip_evaluation)
401 warning ("`%.*s' is not defined",
402 $1.length, $1.address);
404 $$.signedp = SIGNED; }
409 | '(' keywords ')' keywords
410 { struct arglist *temp;
411 $$ = (struct arglist *) xmalloc (sizeof (struct arglist));
413 $$->name = (U_CHAR *) "(";
416 while (temp != 0 && temp->next != 0)
418 temp->next = (struct arglist *) xmalloc (sizeof (struct arglist));
419 temp->next->next = $4;
420 temp->next->name = (U_CHAR *) ")";
421 temp->next->length = 1; }
423 { $$ = (struct arglist *) xmalloc (sizeof (struct arglist));
424 $$->name = $1.address;
425 $$->length = $1.length;
430 /* During parsing of a C expression, the pointer to the next character
431 is in this variable. */
435 /* Take care of parsing a number (anything that starts with a digit).
436 Set yylval and return the token type; update lexptr.
437 LEN is the number of characters in it. */
439 /* maybe needs to actually deal with floating point numbers */
445 register char *p = lexptr;
447 register unsigned_HOST_WIDE_INT n = 0, nd, max_over_base;
448 register int base = 10;
449 register int len = olen;
450 register int overflow = 0;
451 register int digit, largest_digit = 0;
454 yylval.integer.signedp = SIGNED;
458 if (len >= 3 && (p[1] == 'x' || p[1] == 'X')) {
465 max_over_base = (unsigned_HOST_WIDE_INT) -1 / base;
467 for (; len > 0; len--) {
470 if (c >= '0' && c <= '9')
472 else if (base == 16 && c >= 'a' && c <= 'f')
473 digit = c - 'a' + 10;
474 else if (base == 16 && c >= 'A' && c <= 'F')
475 digit = c - 'A' + 10;
477 /* `l' means long, and `u' means unsigned. */
479 if (c == 'l' || c == 'L')
481 if (!pedantic < spec_long)
482 yyerror ("too many `l's in integer constant");
485 else if (c == 'u' || c == 'U')
487 if (! yylval.integer.signedp)
488 yyerror ("two `u's in integer constant");
489 yylval.integer.signedp = UNSIGNED;
492 if (c == '.' || c == 'e' || c == 'E' || c == 'p' || c == 'P')
493 yyerror ("Floating point numbers not allowed in #if expressions");
495 char *buf = (char *) alloca (p - lexptr + 40);
496 sprintf (buf, "missing white space after number `%.*s'",
497 (int) (p - lexptr - 1), lexptr);
506 /* Don't look for any more digits after the suffixes. */
509 if (largest_digit < digit)
510 largest_digit = digit;
511 nd = n * base + digit;
512 overflow |= (max_over_base < n) | (nd < n);
516 if (base <= largest_digit)
517 pedwarn ("integer constant contains digits beyond the radix");
520 pedwarn ("integer constant out of range");
522 /* If too big to be signed, consider it unsigned. */
523 if (((HOST_WIDE_INT) n & yylval.integer.signedp) < 0)
526 warning ("integer constant is so large that it is unsigned");
527 yylval.integer.signedp = UNSIGNED;
531 yylval.integer.value = n;
540 static struct token tokentab2[] = {
554 /* Read one token, getting characters through lexptr. */
560 register int namelen;
561 register unsigned char *tokstart;
562 register struct token *toktab;
568 tokstart = (unsigned char *) lexptr;
570 /* See if it is a special token of length 2. */
571 if (! keyword_parsing)
572 for (toktab = tokentab2; toktab->operator != NULL; toktab++)
573 if (c == *toktab->operator && tokstart[1] == toktab->operator[1]) {
575 if (toktab->token == ERROR)
577 char *buf = (char *) alloca (40);
578 sprintf (buf, "`%s' not allowed in operand of `#if'", toktab->operator);
581 return toktab->token;
595 /* Capital L may start a wide-string or wide-character constant. */
596 if (lexptr[1] == '\'')
600 mask = MAX_WCHAR_TYPE_MASK;
603 if (lexptr[1] == '"')
607 mask = MAX_WCHAR_TYPE_MASK;
608 goto string_constant;
614 mask = MAX_CHAR_TYPE_MASK;
617 if (keyword_parsing) {
618 char *start_ptr = lexptr - 1;
622 c = parse_escape (&lexptr, mask);
626 yylval.name.address = tokstart;
627 yylval.name.length = lexptr - start_ptr;
631 /* This code for reading a character constant
632 handles multicharacter constants and wide characters.
633 It is mostly copied from c-lex.c. */
635 register HOST_WIDE_INT result = 0;
636 register int num_chars = 0;
638 unsigned width = MAX_CHAR_TYPE_SIZE;
640 #ifdef MULTIBYTE_CHARS
641 int longest_char = local_mb_cur_max ();
642 char *token_buffer = (char *) alloca (longest_char);
643 (void) local_mbtowc (NULL_PTR, NULL_PTR, 0);
646 max_chars = MAX_LONG_TYPE_SIZE / width;
648 width = MAX_WCHAR_TYPE_SIZE;
654 if (c == '\'' || c == EOF)
660 c = parse_escape (&lexptr, mask);
664 #ifdef MULTIBYTE_CHARS
668 for (i = 1; i <= longest_char; ++i)
670 token_buffer[i - 1] = c;
671 char_len = local_mbtowc (& wc, token_buffer, i);
678 /* mbtowc sometimes needs an extra char before accepting */
683 /* Merge character into result; ignore excess chars. */
684 for (i = 1; i <= char_len; ++i)
688 if (width < HOST_BITS_PER_INT)
689 result = (result << width)
690 | (token_buffer[i - 1]
691 & ((1 << width) - 1));
693 result = token_buffer[i - 1];
695 num_chars += char_len;
702 warning ("Ignoring invalid multibyte character");
706 #endif /* ! MULTIBYTE_CHARS */
711 if (chars_seen == 1) /* only keep the first one */
716 /* Merge character into result; ignore excess chars. */
718 if (num_chars <= max_chars)
720 if (width < HOST_BITS_PER_INT)
721 result = (result << width) | (c & ((1 << width) - 1));
728 error ("malformatted character constant");
729 else if (chars_seen == 0)
730 error ("empty character constant");
731 else if (num_chars > max_chars)
733 num_chars = max_chars;
734 error ("character constant too long");
736 else if (chars_seen != 1 && ! traditional)
737 warning ("multi-character character constant");
739 /* If char type is signed, sign-extend the constant. */
742 int num_bits = num_chars * width;
744 /* We already got an error; avoid invalid shift. */
745 yylval.integer.value = 0;
746 else if (lookup ((U_CHAR *) "__CHAR_UNSIGNED__",
747 sizeof ("__CHAR_UNSIGNED__") - 1, -1)
748 || ((result >> (num_bits - 1)) & 1) == 0)
750 = result & (~ (unsigned_HOST_WIDE_INT) 0
751 >> (HOST_BITS_PER_WIDE_INT - num_bits));
754 = result | ~(~ (unsigned_HOST_WIDE_INT) 0
755 >> (HOST_BITS_PER_WIDE_INT - num_bits));
759 yylval.integer.value = result;
763 /* This is always a signed type. */
764 yylval.integer.signedp = SIGNED;
768 /* some of these chars are invalid in constant expressions;
769 maybe do something about them later */
801 mask = MAX_CHAR_TYPE_MASK;
803 if (keyword_parsing) {
804 char *start_ptr = lexptr;
809 c = parse_escape (&lexptr, mask);
813 yylval.name.address = tokstart;
814 yylval.name.length = lexptr - start_ptr;
817 yyerror ("string constants not allowed in #if expressions");
821 if (c >= '0' && c <= '9' && !keyword_parsing) {
823 for (namelen = 1; ; namelen++) {
824 int d = tokstart[namelen];
825 if (! ((is_idchar[d] || d == '.')
826 || ((d == '-' || d == '+')
827 && (c == 'e' || c == 'E'
828 || ((c == 'p' || c == 'P') && ! c89))
833 return parse_number (namelen);
836 /* It is a name. See how long it is. */
838 if (keyword_parsing) {
839 for (namelen = 0;; namelen++) {
840 if (is_space[tokstart[namelen]])
842 if (tokstart[namelen] == '(' || tokstart[namelen] == ')')
844 if (tokstart[namelen] == '"' || tokstart[namelen] == '\'')
848 if (!is_idstart[c]) {
849 yyerror ("Invalid token in expression");
853 for (namelen = 0; is_idchar[tokstart[namelen]]; namelen++)
858 yylval.name.address = tokstart;
859 yylval.name.length = namelen;
864 /* Parse a C escape sequence. STRING_PTR points to a variable
865 containing a pointer to the string to parse. That pointer
866 is updated past the characters we use. The value of the
867 escape sequence is returned.
869 RESULT_MASK is used to mask out the result;
870 an error is reported if bits are lost thereby.
872 A negative value means the sequence \ newline was seen,
873 which is supposed to be equivalent to nothing at all.
875 If \ is followed by a null character, we return a negative
876 value and leave the string pointer pointing at the null character.
878 If \ is followed by 000, we return 0 and leave the string pointer
879 after the zeros. A value of 0 does not mean end of string. */
882 parse_escape (string_ptr, result_mask)
884 HOST_WIDE_INT result_mask;
886 register int c = *(*string_ptr)++;
896 pedwarn ("non-ANSI-standard escape sequence, `\\%c'", c);
901 return TARGET_NEWLINE;
923 register HOST_WIDE_INT i = c - '0';
924 register int count = 0;
927 c = *(*string_ptr)++;
928 if (c >= '0' && c <= '7')
929 i = (i << 3) + c - '0';
936 if (i != (i & result_mask))
939 pedwarn ("octal escape sequence out of range");
945 register unsigned_HOST_WIDE_INT i = 0, overflow = 0;
946 register int digits_found = 0, digit;
949 c = *(*string_ptr)++;
950 if (c >= '0' && c <= '9')
952 else if (c >= 'a' && c <= 'f')
953 digit = c - 'a' + 10;
954 else if (c >= 'A' && c <= 'F')
955 digit = c - 'A' + 10;
961 overflow |= i ^ (i << 4 >> 4);
962 i = (i << 4) + digit;
966 yyerror ("\\x used with no following hex digits");
967 if (overflow | (i != (i & result_mask)))
970 pedwarn ("hex escape sequence out of range");
985 longjmp (parse_return_error, 1);
991 if (!skip_evaluation && pedantic)
992 pedwarn ("integer overflow in preprocessor expression");
998 unsigned_HOST_WIDE_INT b;
1000 /* It's unclear from the C standard whether shifts can overflow.
1001 The following code ignores overflow; perhaps a C standard
1002 interpretation ruling is needed. */
1003 if (b >= HOST_BITS_PER_WIDE_INT)
1006 return (unsigned_HOST_WIDE_INT) a->value << b;
1009 static HOST_WIDE_INT
1012 unsigned_HOST_WIDE_INT b;
1014 if (b >= HOST_BITS_PER_WIDE_INT)
1015 return a->signedp ? a->value >> (HOST_BITS_PER_WIDE_INT - 1) : 0;
1016 else if (a->signedp)
1017 return a->value >> b;
1019 return (unsigned_HOST_WIDE_INT) a->value >> b;
1022 /* This page contains the entry point to this file. */
1024 /* Parse STRING as an expression, and complain if this fails
1025 to use up all of the contents of STRING.
1026 STRING may contain '\0' bytes; it is terminated by the first '\n'
1027 outside a string constant, so that we can diagnose '\0' properly.
1028 If WARN_UNDEFINED is nonzero, warn if undefined identifiers are evaluated.
1029 We do not support C comments. They should be removed before
1030 this function is called. */
1033 parse_c_expression (string, warn_undefined)
1038 warn_undef = warn_undefined;
1040 /* if there is some sort of scanning error, just return 0 and assume
1041 the parsing routine has printed an error message somewhere.
1042 there is surely a better thing to do than this. */
1043 if (setjmp (parse_return_error))
1046 if (yyparse () != 0)
1049 if (*lexptr != '\n')
1050 error ("Junk after end of expression.");
1052 return expression_value; /* set by yyparse () */
1055 #ifdef TEST_EXP_READER
1064 int main PROTO((int, char **));
1065 static void initialize_random_junk PROTO((void));
1066 static void print_unsigned_host_wide_int PROTO((unsigned_HOST_WIDE_INT));
1068 /* Main program for testing purposes. */
1076 unsigned_HOST_WIDE_INT u;
1078 pedantic = 1 < argc;
1079 traditional = 2 < argc;
1083 initialize_random_junk ();
1086 printf ("enter expression: ");
1088 while ((buf[n] = c = getchar ()) != '\n' && c != EOF)
1092 parse_c_expression (buf, 1);
1093 printf ("parser returned ");
1094 u = (unsigned_HOST_WIDE_INT) expression_value;
1095 if (expression_value < 0 && expression_signedp) {
1102 print_unsigned_host_wide_int (u);
1103 if (! expression_signedp)
1112 print_unsigned_host_wide_int (u)
1113 unsigned_HOST_WIDE_INT u;
1116 print_unsigned_host_wide_int (u / 10);
1117 putchar ('0' + (int) (u % 10));
1121 /* table to tell if char can be part of a C identifier. */
1122 unsigned char is_idchar[256];
1123 /* table to tell if char can be first char of a c identifier. */
1124 unsigned char is_idstart[256];
1125 /* table to tell if c is horizontal or vertical space. */
1126 unsigned char is_space[256];
1129 * initialize random junk in the hash table and maybe other places
1132 initialize_random_junk ()
1137 * Set up is_idchar and is_idstart tables. These should be
1138 * faster than saying (is_alpha (c) || c == '_'), etc.
1139 * Must do set up these things before calling any routines tthat
1142 for (i = 'a'; i <= 'z'; i++) {
1143 ++is_idchar[i - 'a' + 'A'];
1145 ++is_idstart[i - 'a' + 'A'];
1148 for (i = '0'; i <= '9'; i++)
1164 error VPROTO ((char * msg, ...))
1166 #ifndef ANSI_PROTOTYPES
1171 VA_START (args, msg);
1173 #ifndef ANSI_PROTOTYPES
1174 msg = va_arg (args, char *);
1177 fprintf (stderr, "error: ");
1178 vfprintf (stderr, msg, args);
1179 fprintf (stderr, "\n");
1184 pedwarn VPROTO ((char * msg, ...))
1186 #ifndef ANSI_PROTOTYPES
1191 VA_START (args, msg);
1193 #ifndef ANSI_PROTOTYPES
1194 msg = va_arg (args, char *);
1197 fprintf (stderr, "pedwarn: ");
1198 vfprintf (stderr, msg, args);
1199 fprintf (stderr, "\n");
1204 warning VPROTO ((char * msg, ...))
1206 #ifndef ANSI_PROTOTYPES
1211 VA_START (args, msg);
1213 #ifndef ANSI_PROTOTYPES
1214 msg = va_arg (args, char *);
1217 fprintf (stderr, "warning: ");
1218 vfprintf (stderr, msg, args);
1219 fprintf (stderr, "\n");
1224 check_assertion (name, sym_length, tokens_specified, tokens)
1227 int tokens_specified;
1228 struct arglist *tokens;
1234 lookup (name, len, hash)
1239 return (DEFAULT_SIGNED_CHAR) ? 0 : ((struct hashnode *) -1);
1246 return (PTR) malloc (size);