1 /* Parse C expressions for CCCP.
2 Copyright (C) 1987, 1992, 1994, 1995, 1996, 1997, 1998,
3 1999, 2000 Free Software Foundation.
5 This program is free software; you can redistribute it and/or modify it
6 under the terms of the GNU General Public License as published by the
7 Free Software Foundation; either version 2, or (at your option) any
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
24 Adapted from expread.y of GDB by Paul Rubin, July 1986. */
26 /* Parse a C expression from text in a string */
34 /* #define YYDEBUG 1 */
36 #ifdef MULTIBYTE_CHARS
39 #endif /* MULTIBYTE_CHARS */
41 typedef unsigned char U_CHAR;
43 /* This is used for communicating lists of keywords with cccp.c. */
51 HOST_WIDEST_INT parse_c_expression PARAMS ((char *, int));
53 static int yylex PARAMS ((void));
54 static void yyerror PARAMS ((const char *, ...))
55 ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
56 static HOST_WIDEST_INT expression_value;
57 #ifdef TEST_EXP_READER
58 static int expression_signedp;
61 static jmp_buf parse_return_error;
63 /* Nonzero means count most punctuation as part of a name. */
64 static int keyword_parsing = 0;
66 /* Nonzero means do not evaluate this expression.
67 This is a count, since unevaluated expressions can nest. */
68 static int skip_evaluation;
70 /* Nonzero means warn if undefined identifiers are evaluated. */
71 static int warn_undef;
73 /* some external tables of character types */
74 extern unsigned char is_idstart[], is_idchar[], is_space[];
76 /* Flag for -pedantic. */
79 /* Flag for -traditional. */
80 extern int traditional;
82 /* Flag for -lang-c89. */
85 #ifndef CHAR_TYPE_SIZE
86 #define CHAR_TYPE_SIZE BITS_PER_UNIT
90 #define INT_TYPE_SIZE BITS_PER_WORD
93 #ifndef LONG_TYPE_SIZE
94 #define LONG_TYPE_SIZE BITS_PER_WORD
97 #ifndef WCHAR_TYPE_SIZE
98 #define WCHAR_TYPE_SIZE INT_TYPE_SIZE
101 #ifndef MAX_CHAR_TYPE_SIZE
102 #define MAX_CHAR_TYPE_SIZE CHAR_TYPE_SIZE
105 #ifndef MAX_INT_TYPE_SIZE
106 #define MAX_INT_TYPE_SIZE INT_TYPE_SIZE
109 #ifndef MAX_LONG_TYPE_SIZE
110 #define MAX_LONG_TYPE_SIZE LONG_TYPE_SIZE
113 #ifndef MAX_WCHAR_TYPE_SIZE
114 #define MAX_WCHAR_TYPE_SIZE WCHAR_TYPE_SIZE
117 #define MAX_CHAR_TYPE_MASK (MAX_CHAR_TYPE_SIZE < HOST_BITS_PER_WIDEST_INT \
118 ? (~ (~ (HOST_WIDEST_INT) 0 << MAX_CHAR_TYPE_SIZE)) \
119 : ~ (HOST_WIDEST_INT) 0)
121 #define MAX_WCHAR_TYPE_MASK (MAX_WCHAR_TYPE_SIZE < HOST_BITS_PER_WIDEST_INT \
122 ? ~ (~ (HOST_WIDEST_INT) 0 << MAX_WCHAR_TYPE_SIZE) \
123 : ~ (HOST_WIDEST_INT) 0)
125 /* Suppose A1 + B1 = SUM1, using 2's complement arithmetic ignoring overflow.
126 Suppose A, B and SUM have the same respective signs as A1, B1, and SUM1.
127 Suppose SIGNEDP is negative if the result is signed, zero if unsigned.
128 Then this yields nonzero if overflow occurred during the addition.
129 Overflow occurs if A and B have the same sign, but A and SUM differ in sign,
130 and SIGNEDP is negative.
131 Use `^' to test whether signs differ, and `< 0' to isolate the sign. */
132 #define overflow_sum_sign(a, b, sum, signedp) \
133 ((~((a) ^ (b)) & ((a) ^ (sum)) & (signedp)) < 0)
137 HOST_WIDEST_INT parse_escape PARAMS ((char **, HOST_WIDEST_INT));
138 int check_assertion PARAMS ((U_CHAR *, int, int, struct arglist *));
139 struct hashnode *lookup PARAMS ((U_CHAR *, int, int));
140 void error PARAMS ((const char *, ...)) ATTRIBUTE_PRINTF_1;
141 void verror PARAMS ((const char *, va_list));
142 void pedwarn PARAMS ((const char *, ...)) ATTRIBUTE_PRINTF_1;
143 void warning PARAMS ((const char *, ...)) ATTRIBUTE_PRINTF_1;
145 static int parse_number PARAMS ((int));
146 static HOST_WIDEST_INT left_shift PARAMS ((struct constant *, unsigned HOST_WIDEST_INT));
147 static HOST_WIDEST_INT right_shift PARAMS ((struct constant *, unsigned HOST_WIDEST_INT));
148 static void integer_overflow PARAMS ((void));
150 /* `signedp' values */
156 struct constant {HOST_WIDEST_INT value; int signedp;} integer;
157 struct name {U_CHAR *address; int length;} name;
158 struct arglist *keywords;
161 %type <integer> exp exp1 start
162 %type <keywords> keywords
163 %token <integer> INT CHAR
165 %token <integer> ERROR
175 %left '<' '>' LEQ GEQ
187 expression_value = $1.value;
188 #ifdef TEST_EXP_READER
189 expression_signedp = $1.signedp;
194 /* Expressions, including the comma operator. */
198 pedwarn ("comma operator in operand of `#if'");
202 /* Expressions, not including the comma operator. */
203 exp : '-' exp %prec UNARY
204 { $$.value = - $2.value;
205 $$.signedp = $2.signedp;
206 if (($$.value & $2.value & $$.signedp) < 0)
207 integer_overflow (); }
208 | '!' exp %prec UNARY
209 { $$.value = ! $2.value;
210 $$.signedp = SIGNED; }
211 | '+' exp %prec UNARY
213 | '~' exp %prec UNARY
214 { $$.value = ~ $2.value;
215 $$.signedp = $2.signedp; }
217 { $$.value = check_assertion ($2.address, $2.length,
219 $$.signedp = SIGNED; }
221 { keyword_parsing = 1; }
223 { $$.value = check_assertion ($2.address, $2.length,
226 $$.signedp = SIGNED; }
231 /* Binary operators in order of decreasing precedence. */
233 { $$.signedp = $1.signedp & $3.signedp;
236 $$.value = $1.value * $3.value;
238 && ($$.value / $1.value != $3.value
239 || ($$.value & $1.value & $3.value) < 0))
243 $$.value = ((unsigned HOST_WIDEST_INT) $1.value
248 if (!skip_evaluation)
249 error ("division by zero in #if");
252 $$.signedp = $1.signedp & $3.signedp;
255 $$.value = $1.value / $3.value;
256 if (($$.value & $1.value & $3.value) < 0)
260 $$.value = ((unsigned HOST_WIDEST_INT) $1.value
265 if (!skip_evaluation)
266 error ("division by zero in #if");
269 $$.signedp = $1.signedp & $3.signedp;
271 $$.value = $1.value % $3.value;
273 $$.value = ((unsigned HOST_WIDEST_INT) $1.value
276 { $$.value = $1.value + $3.value;
277 $$.signedp = $1.signedp & $3.signedp;
278 if (overflow_sum_sign ($1.value, $3.value,
279 $$.value, $$.signedp))
280 integer_overflow (); }
282 { $$.value = $1.value - $3.value;
283 $$.signedp = $1.signedp & $3.signedp;
284 if (overflow_sum_sign ($$.value, $3.value,
285 $1.value, $$.signedp))
286 integer_overflow (); }
288 { $$.signedp = $1.signedp;
289 if (($3.value & $3.signedp) < 0)
290 $$.value = right_shift (&$1, -$3.value);
292 $$.value = left_shift (&$1, $3.value); }
294 { $$.signedp = $1.signedp;
295 if (($3.value & $3.signedp) < 0)
296 $$.value = left_shift (&$1, -$3.value);
298 $$.value = right_shift (&$1, $3.value); }
300 { $$.value = ($1.value == $3.value);
301 $$.signedp = SIGNED; }
303 { $$.value = ($1.value != $3.value);
304 $$.signedp = SIGNED; }
306 { $$.signedp = SIGNED;
307 if ($1.signedp & $3.signedp)
308 $$.value = $1.value <= $3.value;
310 $$.value = ((unsigned HOST_WIDEST_INT) $1.value
313 { $$.signedp = SIGNED;
314 if ($1.signedp & $3.signedp)
315 $$.value = $1.value >= $3.value;
317 $$.value = ((unsigned HOST_WIDEST_INT) $1.value
320 { $$.signedp = SIGNED;
321 if ($1.signedp & $3.signedp)
322 $$.value = $1.value < $3.value;
324 $$.value = ((unsigned HOST_WIDEST_INT) $1.value
327 { $$.signedp = SIGNED;
328 if ($1.signedp & $3.signedp)
329 $$.value = $1.value > $3.value;
331 $$.value = ((unsigned HOST_WIDEST_INT) $1.value
334 { $$.value = $1.value & $3.value;
335 $$.signedp = $1.signedp & $3.signedp; }
337 { $$.value = $1.value ^ $3.value;
338 $$.signedp = $1.signedp & $3.signedp; }
340 { $$.value = $1.value | $3.value;
341 $$.signedp = $1.signedp & $3.signedp; }
343 { skip_evaluation += !$1.value; }
345 { skip_evaluation -= !$1.value;
346 $$.value = ($1.value && $4.value);
347 $$.signedp = SIGNED; }
349 { skip_evaluation += !!$1.value; }
351 { skip_evaluation -= !!$1.value;
352 $$.value = ($1.value || $4.value);
353 $$.signedp = SIGNED; }
355 { skip_evaluation += !$1.value; }
357 { skip_evaluation += !!$1.value - !$1.value; }
359 { skip_evaluation -= !!$1.value;
360 $$.value = $1.value ? $4.value : $7.value;
361 $$.signedp = $4.signedp & $7.signedp; }
363 { $$ = yylval.integer; }
365 { $$ = yylval.integer; }
367 { if (warn_undef && !skip_evaluation)
368 warning ("`%.*s' is not defined",
369 $1.length, $1.address);
371 $$.signedp = SIGNED; }
376 | '(' keywords ')' keywords
377 { struct arglist *temp;
378 $$ = (struct arglist *) xmalloc (sizeof (struct arglist));
380 $$->name = (U_CHAR *) "(";
383 while (temp != 0 && temp->next != 0)
385 temp->next = (struct arglist *) xmalloc (sizeof (struct arglist));
386 temp->next->next = $4;
387 temp->next->name = (U_CHAR *) ")";
388 temp->next->length = 1; }
390 { $$ = (struct arglist *) xmalloc (sizeof (struct arglist));
391 $$->name = $1.address;
392 $$->length = $1.length;
397 /* During parsing of a C expression, the pointer to the next character
398 is in this variable. */
402 /* Take care of parsing a number (anything that starts with a digit).
403 Set yylval and return the token type; update lexptr.
404 LEN is the number of characters in it. */
406 /* maybe needs to actually deal with floating point numbers */
412 register char *p = lexptr;
414 register unsigned HOST_WIDEST_INT n = 0, nd, max_over_base;
415 register int base = 10;
416 register int len = olen;
417 register int overflow = 0;
418 register int digit, largest_digit = 0;
421 yylval.integer.signedp = SIGNED;
425 if (len >= 3 && (p[1] == 'x' || p[1] == 'X')) {
432 max_over_base = (unsigned HOST_WIDEST_INT) -1 / base;
434 for (; len > 0; len--) {
437 if (c >= '0' && c <= '9')
439 else if (base == 16 && c >= 'a' && c <= 'f')
440 digit = c - 'a' + 10;
441 else if (base == 16 && c >= 'A' && c <= 'F')
442 digit = c - 'A' + 10;
444 /* `l' means long, and `u' means unsigned. */
446 if (c == 'l' || c == 'L')
448 if (!pedantic < spec_long)
449 yyerror ("too many `l's in integer constant");
452 else if (c == 'u' || c == 'U')
454 if (! yylval.integer.signedp)
455 yyerror ("two `u's in integer constant");
456 yylval.integer.signedp = UNSIGNED;
459 if (c == '.' || c == 'e' || c == 'E' || c == 'p' || c == 'P')
460 yyerror ("Floating point numbers not allowed in #if expressions");
462 yyerror ("missing white space after number `%.*s'",
463 (int) (p - lexptr - 1), lexptr);
470 /* Don't look for any more digits after the suffixes. */
473 if (largest_digit < digit)
474 largest_digit = digit;
475 nd = n * base + digit;
476 overflow |= (max_over_base < n) | (nd < n);
480 if (base <= largest_digit)
481 pedwarn ("integer constant contains digits beyond the radix");
484 pedwarn ("integer constant out of range");
486 /* If too big to be signed, consider it unsigned. */
487 if (((HOST_WIDEST_INT) n & yylval.integer.signedp) < 0)
490 warning ("integer constant is so large that it is unsigned");
491 yylval.integer.signedp = UNSIGNED;
495 yylval.integer.value = n;
500 const char *operator;
504 static struct token tokentab2[] = {
518 /* Read one token, getting characters through lexptr. */
524 register int namelen;
525 register unsigned char *tokstart;
526 register struct token *toktab;
528 HOST_WIDEST_INT mask;
532 tokstart = (unsigned char *) lexptr;
534 /* See if it is a special token of length 2. */
535 if (! keyword_parsing)
536 for (toktab = tokentab2; toktab->operator != NULL; toktab++)
537 if (c == *toktab->operator && tokstart[1] == toktab->operator[1]) {
539 if (toktab->token == ERROR)
540 yyerror ("`%s' not allowed in operand of `#if'", toktab->operator);
541 return toktab->token;
555 /* Capital L may start a wide-string or wide-character constant. */
556 if (lexptr[1] == '\'')
560 mask = MAX_WCHAR_TYPE_MASK;
563 if (lexptr[1] == '"')
567 mask = MAX_WCHAR_TYPE_MASK;
568 goto string_constant;
574 mask = MAX_CHAR_TYPE_MASK;
577 if (keyword_parsing) {
578 char *start_ptr = lexptr - 1;
582 c = parse_escape (&lexptr, mask);
586 yylval.name.address = tokstart;
587 yylval.name.length = lexptr - start_ptr;
591 /* This code for reading a character constant
592 handles multicharacter constants and wide characters.
593 It is mostly copied from c-lex.c. */
595 register HOST_WIDEST_INT result = 0;
596 register int num_chars = 0;
598 unsigned width = MAX_CHAR_TYPE_SIZE;
600 #ifdef MULTIBYTE_CHARS
601 int longest_char = local_mb_cur_max ();
602 char *token_buffer = (char *) alloca (longest_char);
603 (void) local_mbtowc (NULL_PTR, NULL_PTR, 0);
606 max_chars = MAX_LONG_TYPE_SIZE / width;
608 width = MAX_WCHAR_TYPE_SIZE;
614 if (c == '\'' || c == EOF)
620 c = parse_escape (&lexptr, mask);
624 #ifdef MULTIBYTE_CHARS
628 for (i = 1; i <= longest_char; ++i)
630 token_buffer[i - 1] = c;
631 char_len = local_mbtowc (& wc, token_buffer, i);
638 /* mbtowc sometimes needs an extra char before accepting */
643 /* Merge character into result; ignore excess chars. */
644 for (i = 1; i <= char_len; ++i)
648 if (width < HOST_BITS_PER_INT)
649 result = (result << width)
650 | (token_buffer[i - 1]
651 & ((1 << width) - 1));
653 result = token_buffer[i - 1];
655 num_chars += char_len;
662 warning ("Ignoring invalid multibyte character");
666 #endif /* ! MULTIBYTE_CHARS */
671 if (chars_seen == 1) /* only keep the first one */
676 /* Merge character into result; ignore excess chars. */
678 if (num_chars <= max_chars)
680 if (width < HOST_BITS_PER_INT)
681 result = (result << width) | (c & ((1 << width) - 1));
688 error ("malformatted character constant");
689 else if (chars_seen == 0)
690 error ("empty character constant");
691 else if (num_chars > max_chars)
693 num_chars = max_chars;
694 error ("character constant too long");
696 else if (chars_seen != 1 && ! traditional)
697 warning ("multi-character character constant");
699 /* If char type is signed, sign-extend the constant. */
702 int num_bits = num_chars * width;
704 /* We already got an error; avoid invalid shift. */
705 yylval.integer.value = 0;
706 else if (lookup ((U_CHAR *) "__CHAR_UNSIGNED__",
707 sizeof ("__CHAR_UNSIGNED__") - 1, -1)
708 || ((result >> (num_bits - 1)) & 1) == 0)
710 = result & (~ (unsigned HOST_WIDEST_INT) 0
711 >> (HOST_BITS_PER_WIDEST_INT - num_bits));
714 = result | ~(~ (unsigned HOST_WIDEST_INT) 0
715 >> (HOST_BITS_PER_WIDEST_INT - num_bits));
719 yylval.integer.value = result;
723 /* This is always a signed type. */
724 yylval.integer.signedp = SIGNED;
728 /* some of these chars are invalid in constant expressions;
729 maybe do something about them later */
761 mask = MAX_CHAR_TYPE_MASK;
763 if (keyword_parsing) {
764 char *start_ptr = lexptr;
769 c = parse_escape (&lexptr, mask);
773 yylval.name.address = tokstart;
774 yylval.name.length = lexptr - start_ptr;
777 yyerror ("string constants not allowed in #if expressions");
781 if (c >= '0' && c <= '9' && !keyword_parsing) {
783 for (namelen = 1; ; namelen++) {
784 int d = tokstart[namelen];
785 if (! ((is_idchar[d] || d == '.')
786 || ((d == '-' || d == '+')
787 && (c == 'e' || c == 'E'
788 || ((c == 'p' || c == 'P') && ! c89))
793 return parse_number (namelen);
796 /* It is a name. See how long it is. */
798 if (keyword_parsing) {
799 for (namelen = 0;; namelen++) {
800 if (is_space[tokstart[namelen]])
802 if (tokstart[namelen] == '(' || tokstart[namelen] == ')')
804 if (tokstart[namelen] == '"' || tokstart[namelen] == '\'')
808 if (!is_idstart[c]) {
809 yyerror ("Invalid token in expression");
813 for (namelen = 0; is_idchar[tokstart[namelen]]; namelen++)
818 yylval.name.address = tokstart;
819 yylval.name.length = namelen;
824 /* Parse a C escape sequence. STRING_PTR points to a variable
825 containing a pointer to the string to parse. That pointer
826 is updated past the characters we use. The value of the
827 escape sequence is returned.
829 RESULT_MASK is used to mask out the result;
830 an error is reported if bits are lost thereby.
832 A negative value means the sequence \ newline was seen,
833 which is supposed to be equivalent to nothing at all.
835 If \ is followed by a null character, we return a negative
836 value and leave the string pointer pointing at the null character.
838 If \ is followed by 000, we return 0 and leave the string pointer
839 after the zeros. A value of 0 does not mean end of string. */
842 parse_escape (string_ptr, result_mask)
844 HOST_WIDEST_INT result_mask;
846 register int c = *(*string_ptr)++;
856 pedwarn ("non-ANSI-standard escape sequence, `\\%c'", c);
861 return TARGET_NEWLINE;
883 register HOST_WIDEST_INT i = c - '0';
884 register int count = 0;
887 c = *(*string_ptr)++;
888 if (c >= '0' && c <= '7')
889 i = (i << 3) + c - '0';
896 if (i != (i & result_mask))
899 pedwarn ("octal escape sequence out of range");
905 register unsigned HOST_WIDEST_INT i = 0, overflow = 0;
906 register int digits_found = 0, digit;
909 c = *(*string_ptr)++;
910 if (c >= '0' && c <= '9')
912 else if (c >= 'a' && c <= 'f')
913 digit = c - 'a' + 10;
914 else if (c >= 'A' && c <= 'F')
915 digit = c - 'A' + 10;
921 overflow |= i ^ (i << 4 >> 4);
922 i = (i << 4) + digit;
926 yyerror ("\\x used with no following hex digits");
927 if (overflow | (i != (i & result_mask)))
930 pedwarn ("hex escape sequence out of range");
942 if (!skip_evaluation && pedantic)
943 pedwarn ("integer overflow in preprocessor expression");
946 static HOST_WIDEST_INT
949 unsigned HOST_WIDEST_INT b;
951 /* It's unclear from the C standard whether shifts can overflow.
952 The following code ignores overflow; perhaps a C standard
953 interpretation ruling is needed. */
954 if (b >= HOST_BITS_PER_WIDEST_INT)
957 return (unsigned HOST_WIDEST_INT) a->value << b;
960 static HOST_WIDEST_INT
963 unsigned HOST_WIDEST_INT b;
965 if (b >= HOST_BITS_PER_WIDEST_INT)
966 return a->signedp ? a->value >> (HOST_BITS_PER_WIDEST_INT - 1) : 0;
968 return a->value >> b;
970 return (unsigned HOST_WIDEST_INT) a->value >> b;
973 /* This page contains the entry point to this file. */
975 /* Parse STRING as an expression, and complain if this fails
976 to use up all of the contents of STRING.
977 STRING may contain '\0' bytes; it is terminated by the first '\n'
978 outside a string constant, so that we can diagnose '\0' properly.
979 If WARN_UNDEFINED is nonzero, warn if undefined identifiers are evaluated.
980 We do not support C comments. They should be removed before
981 this function is called. */
984 parse_c_expression (string, warn_undefined)
989 warn_undef = warn_undefined;
991 /* if there is some sort of scanning error, just return 0 and assume
992 the parsing routine has printed an error message somewhere.
993 there is surely a better thing to do than this. */
994 if (setjmp (parse_return_error))
1000 if (*lexptr != '\n')
1001 error ("Junk after end of expression.");
1003 return expression_value; /* set by yyparse () */
1007 yyerror VPARAMS ((const char * msgid, ...))
1009 #ifndef ANSI_PROTOTYPES
1014 VA_START (args, msgid);
1016 #ifndef ANSI_PROTOTYPES
1017 msgid = va_arg (args, const char *);
1020 verror (msgid, args);
1022 skip_evaluation = 0;
1023 longjmp (parse_return_error, 1);
1027 #ifdef TEST_EXP_READER
1037 int main PARAMS ((int, char **));
1038 static void initialize_random_junk PARAMS ((void));
1039 static void print_unsigned_host_widest_int PARAMS ((unsigned HOST_WIDEST_INT));
1041 /* Main program for testing purposes. */
1049 unsigned HOST_WIDEST_INT u;
1051 pedantic = 1 < argc;
1052 traditional = 2 < argc;
1057 initialize_random_junk ();
1060 printf ("enter expression: ");
1062 while ((buf[n] = c = getchar ()) != '\n' && c != EOF)
1066 parse_c_expression (buf, 1);
1067 printf ("parser returned ");
1068 u = (unsigned HOST_WIDEST_INT) expression_value;
1069 if (expression_value < 0 && expression_signedp) {
1076 print_unsigned_host_widest_int (u);
1077 if (! expression_signedp)
1086 print_unsigned_host_widest_int (u)
1087 unsigned HOST_WIDEST_INT u;
1090 print_unsigned_host_widest_int (u / 10);
1091 putchar ('0' + (int) (u % 10));
1095 /* table to tell if char can be part of a C identifier. */
1096 unsigned char is_idchar[256];
1097 /* table to tell if char can be first char of a c identifier. */
1098 unsigned char is_idstart[256];
1099 /* table to tell if c is horizontal or vertical space. */
1100 unsigned char is_space[256];
1103 * initialize random junk in the hash table and maybe other places
1106 initialize_random_junk ()
1111 * Set up is_idchar and is_idstart tables. These should be
1112 * faster than saying (is_alpha (c) || c == '_'), etc.
1113 * Must do set up these things before calling any routines tthat
1116 for (i = 'a'; i <= 'z'; i++) {
1117 ++is_idchar[TOUPPER(i)];
1119 ++is_idstart[TOUPPER(i)];
1122 for (i = '0'; i <= '9'; i++)
1138 error VPARAMS ((char * msgid, ...))
1140 #ifndef ANSI_PROTOTYPES
1145 VA_START (args, msgid);
1147 #ifndef ANSI_PROTOTYPES
1148 msgid = va_arg (args, char *);
1151 fprintf (stderr, "error: ");
1152 vfprintf (stderr, _(msgid), args);
1153 fprintf (stderr, "\n");
1158 pedwarn VPARAMS ((char * msgid, ...))
1160 #ifndef ANSI_PROTOTYPES
1165 VA_START (args, msgid);
1167 #ifndef ANSI_PROTOTYPES
1168 msgid = va_arg (args, char *);
1171 fprintf (stderr, "pedwarn: ");
1172 vfprintf (stderr, _(msgid), args);
1173 fprintf (stderr, "\n");
1178 warning VPARAMS ((char * msgid, ...))
1180 #ifndef ANSI_PROTOTYPES
1185 VA_START (args, msgid);
1187 #ifndef ANSI_PROTOTYPES
1188 msgid = va_arg (args, char *);
1191 fprintf (stderr, "warning: ");
1192 vfprintf (stderr, _(msgid), args);
1193 fprintf (stderr, "\n");
1199 check_assertion (name, sym_length, tokens_specified, tokens)
1202 int tokens_specified;
1203 struct arglist *tokens;
1209 lookup (name, len, hash)
1214 return (DEFAULT_SIGNED_CHAR) ? 0 : ((struct hashnode *) -1);
1221 return (PTR) malloc (size);