1 /* Parse C expressions for CCCP.
2 Copyright (C) 1987, 92, 94, 95, 96, 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 */
32 /* #define YYDEBUG 1 */
34 #ifdef MULTIBYTE_CHARS
37 #endif /* MULTIBYTE_CHARS */
39 typedef unsigned char U_CHAR;
41 /* This is used for communicating lists of keywords with cccp.c. */
49 /* Find the largest host integer type and set its size and type.
50 Watch out: on some crazy hosts `long' is shorter than `int'. */
54 # include <inttypes.h>
55 # define HOST_WIDE_INT intmax_t
56 # define unsigned_HOST_WIDE_INT uintmax_t
58 # if (HOST_BITS_PER_LONG <= HOST_BITS_PER_INT && HOST_BITS_PER_LONGLONG <= HOST_BITS_PER_INT)
59 # define HOST_WIDE_INT int
61 # if (HOST_BITS_PER_LONGLONG <= HOST_BITS_PER_LONG || ! (defined LONG_LONG_MAX || defined LLONG_MAX))
62 # define HOST_WIDE_INT long
64 # define HOST_WIDE_INT long long
70 #ifndef unsigned_HOST_WIDE_INT
71 #define unsigned_HOST_WIDE_INT unsigned HOST_WIDE_INT
78 #ifndef HOST_BITS_PER_WIDE_INT
79 #define HOST_BITS_PER_WIDE_INT (CHAR_BIT * sizeof (HOST_WIDE_INT))
82 HOST_WIDE_INT parse_c_expression PROTO((char *, int));
84 static int yylex PROTO((void));
85 static void yyerror PRINTF_PROTO_1((char *, ...)) __attribute__ ((noreturn));
86 static HOST_WIDE_INT expression_value;
87 #ifdef TEST_EXP_READER
88 static int expression_signedp;
91 static jmp_buf parse_return_error;
93 /* Nonzero means count most punctuation as part of a name. */
94 static int keyword_parsing = 0;
96 /* Nonzero means do not evaluate this expression.
97 This is a count, since unevaluated expressions can nest. */
98 static int skip_evaluation;
100 /* Nonzero means warn if undefined identifiers are evaluated. */
101 static int warn_undef;
103 /* some external tables of character types */
104 extern unsigned char is_idstart[], is_idchar[], is_space[];
106 /* Flag for -pedantic. */
109 /* Flag for -traditional. */
110 extern int traditional;
112 /* Flag for -lang-c89. */
115 #ifndef CHAR_TYPE_SIZE
116 #define CHAR_TYPE_SIZE BITS_PER_UNIT
119 #ifndef INT_TYPE_SIZE
120 #define INT_TYPE_SIZE BITS_PER_WORD
123 #ifndef LONG_TYPE_SIZE
124 #define LONG_TYPE_SIZE BITS_PER_WORD
127 #ifndef WCHAR_TYPE_SIZE
128 #define WCHAR_TYPE_SIZE INT_TYPE_SIZE
131 #ifndef MAX_CHAR_TYPE_SIZE
132 #define MAX_CHAR_TYPE_SIZE CHAR_TYPE_SIZE
135 #ifndef MAX_INT_TYPE_SIZE
136 #define MAX_INT_TYPE_SIZE INT_TYPE_SIZE
139 #ifndef MAX_LONG_TYPE_SIZE
140 #define MAX_LONG_TYPE_SIZE LONG_TYPE_SIZE
143 #ifndef MAX_WCHAR_TYPE_SIZE
144 #define MAX_WCHAR_TYPE_SIZE WCHAR_TYPE_SIZE
147 #define MAX_CHAR_TYPE_MASK (MAX_CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT \
148 ? (~ (~ (HOST_WIDE_INT) 0 << MAX_CHAR_TYPE_SIZE)) \
149 : ~ (HOST_WIDE_INT) 0)
151 #define MAX_WCHAR_TYPE_MASK (MAX_WCHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT \
152 ? ~ (~ (HOST_WIDE_INT) 0 << MAX_WCHAR_TYPE_SIZE) \
153 : ~ (HOST_WIDE_INT) 0)
155 /* Suppose A1 + B1 = SUM1, using 2's complement arithmetic ignoring overflow.
156 Suppose A, B and SUM have the same respective signs as A1, B1, and SUM1.
157 Suppose SIGNEDP is negative if the result is signed, zero if unsigned.
158 Then this yields nonzero if overflow occurred during the addition.
159 Overflow occurs if A and B have the same sign, but A and SUM differ in sign,
160 and SIGNEDP is negative.
161 Use `^' to test whether signs differ, and `< 0' to isolate the sign. */
162 #define overflow_sum_sign(a, b, sum, signedp) \
163 ((~((a) ^ (b)) & ((a) ^ (sum)) & (signedp)) < 0)
167 HOST_WIDE_INT parse_escape PROTO((char **, HOST_WIDE_INT));
168 int check_assertion PROTO((U_CHAR *, int, int, struct arglist *));
169 struct hashnode *lookup PROTO((U_CHAR *, int, int));
170 void error PRINTF_PROTO_1((char *, ...));
171 void pedwarn PRINTF_PROTO_1((char *, ...));
172 void warning PRINTF_PROTO_1((char *, ...));
174 static int parse_number PROTO((int));
175 static HOST_WIDE_INT left_shift PROTO((struct constant *, unsigned_HOST_WIDE_INT));
176 static HOST_WIDE_INT right_shift PROTO((struct constant *, unsigned_HOST_WIDE_INT));
177 static void integer_overflow PROTO((void));
179 /* `signedp' values */
185 struct constant {HOST_WIDE_INT value; int signedp;} integer;
186 struct name {U_CHAR *address; int length;} name;
187 struct arglist *keywords;
190 %type <integer> exp exp1 start
191 %type <keywords> keywords
192 %token <integer> INT CHAR
194 %token <integer> ERROR
204 %left '<' '>' LEQ GEQ
216 expression_value = $1.value;
217 #ifdef TEST_EXP_READER
218 expression_signedp = $1.signedp;
223 /* Expressions, including the comma operator. */
227 pedwarn ("comma operator in operand of `#if'");
231 /* Expressions, not including the comma operator. */
232 exp : '-' exp %prec UNARY
233 { $$.value = - $2.value;
234 $$.signedp = $2.signedp;
235 if (($$.value & $2.value & $$.signedp) < 0)
236 integer_overflow (); }
237 | '!' exp %prec UNARY
238 { $$.value = ! $2.value;
239 $$.signedp = SIGNED; }
240 | '+' exp %prec UNARY
242 | '~' exp %prec UNARY
243 { $$.value = ~ $2.value;
244 $$.signedp = $2.signedp; }
246 { $$.value = check_assertion ($2.address, $2.length,
248 $$.signedp = SIGNED; }
250 { keyword_parsing = 1; }
252 { $$.value = check_assertion ($2.address, $2.length,
255 $$.signedp = SIGNED; }
260 /* Binary operators in order of decreasing precedence. */
262 { $$.signedp = $1.signedp & $3.signedp;
265 $$.value = $1.value * $3.value;
267 && ($$.value / $1.value != $3.value
268 || ($$.value & $1.value & $3.value) < 0))
272 $$.value = ((unsigned_HOST_WIDE_INT) $1.value
277 if (!skip_evaluation)
278 error ("division by zero in #if");
281 $$.signedp = $1.signedp & $3.signedp;
284 $$.value = $1.value / $3.value;
285 if (($$.value & $1.value & $3.value) < 0)
289 $$.value = ((unsigned_HOST_WIDE_INT) $1.value
294 if (!skip_evaluation)
295 error ("division by zero in #if");
298 $$.signedp = $1.signedp & $3.signedp;
300 $$.value = $1.value % $3.value;
302 $$.value = ((unsigned_HOST_WIDE_INT) $1.value
305 { $$.value = $1.value + $3.value;
306 $$.signedp = $1.signedp & $3.signedp;
307 if (overflow_sum_sign ($1.value, $3.value,
308 $$.value, $$.signedp))
309 integer_overflow (); }
311 { $$.value = $1.value - $3.value;
312 $$.signedp = $1.signedp & $3.signedp;
313 if (overflow_sum_sign ($$.value, $3.value,
314 $1.value, $$.signedp))
315 integer_overflow (); }
317 { $$.signedp = $1.signedp;
318 if (($3.value & $3.signedp) < 0)
319 $$.value = right_shift (&$1, -$3.value);
321 $$.value = left_shift (&$1, $3.value); }
323 { $$.signedp = $1.signedp;
324 if (($3.value & $3.signedp) < 0)
325 $$.value = left_shift (&$1, -$3.value);
327 $$.value = right_shift (&$1, $3.value); }
329 { $$.value = ($1.value == $3.value);
330 $$.signedp = SIGNED; }
332 { $$.value = ($1.value != $3.value);
333 $$.signedp = SIGNED; }
335 { $$.signedp = SIGNED;
336 if ($1.signedp & $3.signedp)
337 $$.value = $1.value <= $3.value;
339 $$.value = ((unsigned_HOST_WIDE_INT) $1.value
342 { $$.signedp = SIGNED;
343 if ($1.signedp & $3.signedp)
344 $$.value = $1.value >= $3.value;
346 $$.value = ((unsigned_HOST_WIDE_INT) $1.value
349 { $$.signedp = SIGNED;
350 if ($1.signedp & $3.signedp)
351 $$.value = $1.value < $3.value;
353 $$.value = ((unsigned_HOST_WIDE_INT) $1.value
356 { $$.signedp = SIGNED;
357 if ($1.signedp & $3.signedp)
358 $$.value = $1.value > $3.value;
360 $$.value = ((unsigned_HOST_WIDE_INT) $1.value
363 { $$.value = $1.value & $3.value;
364 $$.signedp = $1.signedp & $3.signedp; }
366 { $$.value = $1.value ^ $3.value;
367 $$.signedp = $1.signedp & $3.signedp; }
369 { $$.value = $1.value | $3.value;
370 $$.signedp = $1.signedp & $3.signedp; }
372 { skip_evaluation += !$1.value; }
374 { skip_evaluation -= !$1.value;
375 $$.value = ($1.value && $4.value);
376 $$.signedp = SIGNED; }
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 - !$1.value; }
388 { skip_evaluation -= !!$1.value;
389 $$.value = $1.value ? $4.value : $7.value;
390 $$.signedp = $4.signedp & $7.signedp; }
392 { $$ = yylval.integer; }
394 { $$ = yylval.integer; }
396 { if (warn_undef && !skip_evaluation)
397 warning ("`%.*s' is not defined",
398 $1.length, $1.address);
400 $$.signedp = SIGNED; }
405 | '(' keywords ')' keywords
406 { struct arglist *temp;
407 $$ = (struct arglist *) xmalloc (sizeof (struct arglist));
409 $$->name = (U_CHAR *) "(";
412 while (temp != 0 && temp->next != 0)
414 temp->next = (struct arglist *) xmalloc (sizeof (struct arglist));
415 temp->next->next = $4;
416 temp->next->name = (U_CHAR *) ")";
417 temp->next->length = 1; }
419 { $$ = (struct arglist *) xmalloc (sizeof (struct arglist));
420 $$->name = $1.address;
421 $$->length = $1.length;
426 /* During parsing of a C expression, the pointer to the next character
427 is in this variable. */
431 /* Take care of parsing a number (anything that starts with a digit).
432 Set yylval and return the token type; update lexptr.
433 LEN is the number of characters in it. */
435 /* maybe needs to actually deal with floating point numbers */
441 register char *p = lexptr;
443 register unsigned_HOST_WIDE_INT n = 0, nd, max_over_base;
444 register int base = 10;
445 register int len = olen;
446 register int overflow = 0;
447 register int digit, largest_digit = 0;
450 yylval.integer.signedp = SIGNED;
454 if (len >= 3 && (p[1] == 'x' || p[1] == 'X')) {
461 max_over_base = (unsigned_HOST_WIDE_INT) -1 / base;
463 for (; len > 0; len--) {
466 if (c >= '0' && c <= '9')
468 else if (base == 16 && c >= 'a' && c <= 'f')
469 digit = c - 'a' + 10;
470 else if (base == 16 && c >= 'A' && c <= 'F')
471 digit = c - 'A' + 10;
473 /* `l' means long, and `u' means unsigned. */
475 if (c == 'l' || c == 'L')
477 if (!pedantic < spec_long)
478 yyerror ("too many `l's in integer constant");
481 else if (c == 'u' || c == 'U')
483 if (! yylval.integer.signedp)
484 yyerror ("two `u's in integer constant");
485 yylval.integer.signedp = UNSIGNED;
488 if (c == '.' || c == 'e' || c == 'E' || c == 'p' || c == 'P')
489 yyerror ("Floating point numbers not allowed in #if expressions");
491 yyerror ("missing white space after number `%.*s'",
492 (int) (p - lexptr - 1), lexptr);
499 /* Don't look for any more digits after the suffixes. */
502 if (largest_digit < digit)
503 largest_digit = digit;
504 nd = n * base + digit;
505 overflow |= (max_over_base < n) | (nd < n);
509 if (base <= largest_digit)
510 pedwarn ("integer constant contains digits beyond the radix");
513 pedwarn ("integer constant out of range");
515 /* If too big to be signed, consider it unsigned. */
516 if (((HOST_WIDE_INT) n & yylval.integer.signedp) < 0)
519 warning ("integer constant is so large that it is unsigned");
520 yylval.integer.signedp = UNSIGNED;
524 yylval.integer.value = n;
533 static struct token tokentab2[] = {
547 /* Read one token, getting characters through lexptr. */
553 register int namelen;
554 register unsigned char *tokstart;
555 register struct token *toktab;
561 tokstart = (unsigned char *) lexptr;
563 /* See if it is a special token of length 2. */
564 if (! keyword_parsing)
565 for (toktab = tokentab2; toktab->operator != NULL; toktab++)
566 if (c == *toktab->operator && tokstart[1] == toktab->operator[1]) {
568 if (toktab->token == ERROR)
569 yyerror ("`%s' not allowed in operand of `#if'", toktab->operator);
570 return toktab->token;
584 /* Capital L may start a wide-string or wide-character constant. */
585 if (lexptr[1] == '\'')
589 mask = MAX_WCHAR_TYPE_MASK;
592 if (lexptr[1] == '"')
596 mask = MAX_WCHAR_TYPE_MASK;
597 goto string_constant;
603 mask = MAX_CHAR_TYPE_MASK;
606 if (keyword_parsing) {
607 char *start_ptr = lexptr - 1;
611 c = parse_escape (&lexptr, mask);
615 yylval.name.address = tokstart;
616 yylval.name.length = lexptr - start_ptr;
620 /* This code for reading a character constant
621 handles multicharacter constants and wide characters.
622 It is mostly copied from c-lex.c. */
624 register HOST_WIDE_INT result = 0;
625 register int num_chars = 0;
627 unsigned width = MAX_CHAR_TYPE_SIZE;
629 #ifdef MULTIBYTE_CHARS
630 int longest_char = local_mb_cur_max ();
631 char *token_buffer = (char *) alloca (longest_char);
632 (void) local_mbtowc (NULL_PTR, NULL_PTR, 0);
635 max_chars = MAX_LONG_TYPE_SIZE / width;
637 width = MAX_WCHAR_TYPE_SIZE;
643 if (c == '\'' || c == EOF)
649 c = parse_escape (&lexptr, mask);
653 #ifdef MULTIBYTE_CHARS
657 for (i = 1; i <= longest_char; ++i)
659 token_buffer[i - 1] = c;
660 char_len = local_mbtowc (& wc, token_buffer, i);
667 /* mbtowc sometimes needs an extra char before accepting */
672 /* Merge character into result; ignore excess chars. */
673 for (i = 1; i <= char_len; ++i)
677 if (width < HOST_BITS_PER_INT)
678 result = (result << width)
679 | (token_buffer[i - 1]
680 & ((1 << width) - 1));
682 result = token_buffer[i - 1];
684 num_chars += char_len;
691 warning ("Ignoring invalid multibyte character");
695 #endif /* ! MULTIBYTE_CHARS */
700 if (chars_seen == 1) /* only keep the first one */
705 /* Merge character into result; ignore excess chars. */
707 if (num_chars <= max_chars)
709 if (width < HOST_BITS_PER_INT)
710 result = (result << width) | (c & ((1 << width) - 1));
717 error ("malformatted character constant");
718 else if (chars_seen == 0)
719 error ("empty character constant");
720 else if (num_chars > max_chars)
722 num_chars = max_chars;
723 error ("character constant too long");
725 else if (chars_seen != 1 && ! traditional)
726 warning ("multi-character character constant");
728 /* If char type is signed, sign-extend the constant. */
731 int num_bits = num_chars * width;
733 /* We already got an error; avoid invalid shift. */
734 yylval.integer.value = 0;
735 else if (lookup ((U_CHAR *) "__CHAR_UNSIGNED__",
736 sizeof ("__CHAR_UNSIGNED__") - 1, -1)
737 || ((result >> (num_bits - 1)) & 1) == 0)
739 = result & (~ (unsigned_HOST_WIDE_INT) 0
740 >> (HOST_BITS_PER_WIDE_INT - num_bits));
743 = result | ~(~ (unsigned_HOST_WIDE_INT) 0
744 >> (HOST_BITS_PER_WIDE_INT - num_bits));
748 yylval.integer.value = result;
752 /* This is always a signed type. */
753 yylval.integer.signedp = SIGNED;
757 /* some of these chars are invalid in constant expressions;
758 maybe do something about them later */
790 mask = MAX_CHAR_TYPE_MASK;
792 if (keyword_parsing) {
793 char *start_ptr = lexptr;
798 c = parse_escape (&lexptr, mask);
802 yylval.name.address = tokstart;
803 yylval.name.length = lexptr - start_ptr;
806 yyerror ("string constants not allowed in #if expressions");
810 if (c >= '0' && c <= '9' && !keyword_parsing) {
812 for (namelen = 1; ; namelen++) {
813 int d = tokstart[namelen];
814 if (! ((is_idchar[d] || d == '.')
815 || ((d == '-' || d == '+')
816 && (c == 'e' || c == 'E'
817 || ((c == 'p' || c == 'P') && ! c89))
822 return parse_number (namelen);
825 /* It is a name. See how long it is. */
827 if (keyword_parsing) {
828 for (namelen = 0;; namelen++) {
829 if (is_space[tokstart[namelen]])
831 if (tokstart[namelen] == '(' || tokstart[namelen] == ')')
833 if (tokstart[namelen] == '"' || tokstart[namelen] == '\'')
837 if (!is_idstart[c]) {
838 yyerror ("Invalid token in expression");
842 for (namelen = 0; is_idchar[tokstart[namelen]]; namelen++)
847 yylval.name.address = tokstart;
848 yylval.name.length = namelen;
853 /* Parse a C escape sequence. STRING_PTR points to a variable
854 containing a pointer to the string to parse. That pointer
855 is updated past the characters we use. The value of the
856 escape sequence is returned.
858 RESULT_MASK is used to mask out the result;
859 an error is reported if bits are lost thereby.
861 A negative value means the sequence \ newline was seen,
862 which is supposed to be equivalent to nothing at all.
864 If \ is followed by a null character, we return a negative
865 value and leave the string pointer pointing at the null character.
867 If \ is followed by 000, we return 0 and leave the string pointer
868 after the zeros. A value of 0 does not mean end of string. */
871 parse_escape (string_ptr, result_mask)
873 HOST_WIDE_INT result_mask;
875 register int c = *(*string_ptr)++;
885 pedwarn ("non-ANSI-standard escape sequence, `\\%c'", c);
890 return TARGET_NEWLINE;
912 register HOST_WIDE_INT i = c - '0';
913 register int count = 0;
916 c = *(*string_ptr)++;
917 if (c >= '0' && c <= '7')
918 i = (i << 3) + c - '0';
925 if (i != (i & result_mask))
928 pedwarn ("octal escape sequence out of range");
934 register unsigned_HOST_WIDE_INT i = 0, overflow = 0;
935 register int digits_found = 0, digit;
938 c = *(*string_ptr)++;
939 if (c >= '0' && c <= '9')
941 else if (c >= 'a' && c <= 'f')
942 digit = c - 'a' + 10;
943 else if (c >= 'A' && c <= 'F')
944 digit = c - 'A' + 10;
950 overflow |= i ^ (i << 4 >> 4);
951 i = (i << 4) + digit;
955 yyerror ("\\x used with no following hex digits");
956 if (overflow | (i != (i & result_mask)))
959 pedwarn ("hex escape sequence out of range");
971 if (!skip_evaluation && pedantic)
972 pedwarn ("integer overflow in preprocessor expression");
978 unsigned_HOST_WIDE_INT b;
980 /* It's unclear from the C standard whether shifts can overflow.
981 The following code ignores overflow; perhaps a C standard
982 interpretation ruling is needed. */
983 if (b >= HOST_BITS_PER_WIDE_INT)
986 return (unsigned_HOST_WIDE_INT) a->value << b;
992 unsigned_HOST_WIDE_INT b;
994 if (b >= HOST_BITS_PER_WIDE_INT)
995 return a->signedp ? a->value >> (HOST_BITS_PER_WIDE_INT - 1) : 0;
997 return a->value >> b;
999 return (unsigned_HOST_WIDE_INT) a->value >> b;
1002 /* This page contains the entry point to this file. */
1004 /* Parse STRING as an expression, and complain if this fails
1005 to use up all of the contents of STRING.
1006 STRING may contain '\0' bytes; it is terminated by the first '\n'
1007 outside a string constant, so that we can diagnose '\0' properly.
1008 If WARN_UNDEFINED is nonzero, warn if undefined identifiers are evaluated.
1009 We do not support C comments. They should be removed before
1010 this function is called. */
1013 parse_c_expression (string, warn_undefined)
1018 warn_undef = warn_undefined;
1020 /* if there is some sort of scanning error, just return 0 and assume
1021 the parsing routine has printed an error message somewhere.
1022 there is surely a better thing to do than this. */
1023 if (setjmp (parse_return_error))
1026 if (yyparse () != 0)
1029 if (*lexptr != '\n')
1030 error ("Junk after end of expression.");
1032 return expression_value; /* set by yyparse () */
1036 yyerror VPROTO ((char * msgid, ...))
1038 #ifndef ANSI_PROTOTYPES
1043 VA_START (args, msgid);
1045 #ifndef ANSI_PROTOTYPES
1046 msgid = va_arg (args, char *);
1049 fprintf (stderr, "error: ");
1050 vfprintf (stderr, _(msgid), args);
1051 fprintf (stderr, "\n");
1053 skip_evaluation = 0;
1054 longjmp (parse_return_error, 1);
1058 #ifdef TEST_EXP_READER
1067 int main PROTO((int, char **));
1068 static void initialize_random_junk PROTO((void));
1069 static void print_unsigned_host_wide_int PROTO((unsigned_HOST_WIDE_INT));
1071 /* Main program for testing purposes. */
1079 unsigned_HOST_WIDE_INT u;
1081 pedantic = 1 < argc;
1082 traditional = 2 < argc;
1086 initialize_random_junk ();
1089 printf ("enter expression: ");
1091 while ((buf[n] = c = getchar ()) != '\n' && c != EOF)
1095 parse_c_expression (buf, 1);
1096 printf ("parser returned ");
1097 u = (unsigned_HOST_WIDE_INT) expression_value;
1098 if (expression_value < 0 && expression_signedp) {
1105 print_unsigned_host_wide_int (u);
1106 if (! expression_signedp)
1115 print_unsigned_host_wide_int (u)
1116 unsigned_HOST_WIDE_INT u;
1119 print_unsigned_host_wide_int (u / 10);
1120 putchar ('0' + (int) (u % 10));
1124 /* table to tell if char can be part of a C identifier. */
1125 unsigned char is_idchar[256];
1126 /* table to tell if char can be first char of a c identifier. */
1127 unsigned char is_idstart[256];
1128 /* table to tell if c is horizontal or vertical space. */
1129 unsigned char is_space[256];
1132 * initialize random junk in the hash table and maybe other places
1135 initialize_random_junk ()
1140 * Set up is_idchar and is_idstart tables. These should be
1141 * faster than saying (is_alpha (c) || c == '_'), etc.
1142 * Must do set up these things before calling any routines tthat
1145 for (i = 'a'; i <= 'z'; i++) {
1146 ++is_idchar[i - 'a' + 'A'];
1148 ++is_idstart[i - 'a' + 'A'];
1151 for (i = '0'; i <= '9'; i++)
1167 error VPROTO ((char * msgid, ...))
1169 #ifndef ANSI_PROTOTYPES
1174 VA_START (args, msgid);
1176 #ifndef ANSI_PROTOTYPES
1177 msgid = va_arg (args, char *);
1180 fprintf (stderr, "error: ");
1181 vfprintf (stderr, _(msgid), args);
1182 fprintf (stderr, "\n");
1187 pedwarn VPROTO ((char * msgid, ...))
1189 #ifndef ANSI_PROTOTYPES
1194 VA_START (args, msgid);
1196 #ifndef ANSI_PROTOTYPES
1197 msgid = va_arg (args, char *);
1200 fprintf (stderr, "pedwarn: ");
1201 vfprintf (stderr, _(msgid), args);
1202 fprintf (stderr, "\n");
1207 warning VPROTO ((char * msgid, ...))
1209 #ifndef ANSI_PROTOTYPES
1214 VA_START (args, msgid);
1216 #ifndef ANSI_PROTOTYPES
1217 msgid = va_arg (args, char *);
1220 fprintf (stderr, "warning: ");
1221 vfprintf (stderr, _(msgid), args);
1222 fprintf (stderr, "\n");
1228 check_assertion (name, sym_length, tokens_specified, tokens)
1231 int tokens_specified;
1232 struct arglist *tokens;
1238 lookup (name, len, hash)
1243 return (DEFAULT_SIGNED_CHAR) ? 0 : ((struct hashnode *) -1);
1250 return (PTR) malloc (size);