This source file includes following definitions.
- parse_number
- yylex
- parse_escape
- yyerror
- integer_overflow
- left_shift
- right_shift
- parse_c_expression
- main
- initialize_random_junk
- error
- warning
- lookup
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 %{
27 #include "config.h"
28 #include <setjmp.h>
29
30
31 #ifdef MULTIBYTE_CHARS
32 #include <stdlib.h>
33 #include <locale.h>
34 #endif
35
36 #include <stdio.h>
37
38 typedef unsigned char U_CHAR;
39
40
41 struct arglist {
42 struct arglist *next;
43 U_CHAR *name;
44 int length;
45 int argno;
46 };
47
48
49
50 #ifndef NULL
51 #define NULL 0
52 #endif
53
54 #ifndef GENERIC_PTR
55 #if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__)
56 #define GENERIC_PTR void *
57 #else
58 #define GENERIC_PTR char *
59 #endif
60 #endif
61
62 #ifndef NULL_PTR
63 #define NULL_PTR ((GENERIC_PTR)0)
64 #endif
65
66 int yylex ();
67 void yyerror ();
68 int expression_value;
69
70 static jmp_buf parse_return_error;
71
72
73 static int keyword_parsing = 0;
74
75
76 extern unsigned char is_idstart[], is_idchar[], is_hor_space[];
77
78 extern char *xmalloc ();
79
80
81 extern int pedantic;
82
83
84 extern int traditional;
85
86 #ifndef CHAR_TYPE_SIZE
87 #define CHAR_TYPE_SIZE BITS_PER_UNIT
88 #endif
89
90 #ifndef INT_TYPE_SIZE
91 #define INT_TYPE_SIZE BITS_PER_WORD
92 #endif
93
94 #ifndef LONG_TYPE_SIZE
95 #define LONG_TYPE_SIZE BITS_PER_WORD
96 #endif
97
98 #ifndef WCHAR_TYPE_SIZE
99 #define WCHAR_TYPE_SIZE INT_TYPE_SIZE
100 #endif
101
102
103
104 #define possible_sum_sign(a, b, sum) ((((a) ^ (b)) | ~ ((a) ^ (sum))) < 0)
105
106 static void integer_overflow ();
107 static long left_shift ();
108 static long right_shift ();
109 %}
110
111 %union {
112 struct constant {long value; int unsignedp;} integer;
113 struct name {U_CHAR *address; int length;} name;
114 struct arglist *keywords;
115 int voidval;
116 char *sval;
117 }
118
119 %type <integer> exp exp1 start
120 %type <keywords> keywords
121 %token <integer> INT CHAR
122 %token <name> NAME
123 %token <integer> ERROR
124
125 %right '?' ':'
126 %left ','
127 %left OR
128 %left AND
129 %left '|'
130 %left '^'
131 %left '&'
132 %left EQUAL NOTEQUAL
133 %left '<' '>' LEQ GEQ
134 %left LSH RSH
135 %left '+' '-'
136 %left '*' '/' '%'
137 %right UNARY
138
139
140
141 %%
142
143 start : exp1
144 { expression_value = $1.value; }
145 ;
146
147
148 exp1 : exp
149 | exp1 ',' exp
150 { if (pedantic)
151 pedwarn ("comma operator in operand of `#if'");
152 $$ = $3; }
153 ;
154
155
156 exp : '-' exp %prec UNARY
157 { $$.value = - $2.value;
158 if (($$.value & $2.value) < 0 && ! $2.unsignedp)
159 integer_overflow ();
160 $$.unsignedp = $2.unsignedp; }
161 | '!' exp %prec UNARY
162 { $$.value = ! $2.value;
163 $$.unsignedp = 0; }
164 | '+' exp %prec UNARY
165 { $$ = $2; }
166 | '~' exp %prec UNARY
167 { $$.value = ~ $2.value;
168 $$.unsignedp = $2.unsignedp; }
169 | '#' NAME
170 { $$.value = check_assertion ($2.address, $2.length,
171 0, NULL_PTR);
172 $$.unsignedp = 0; }
173 | '#' NAME
174 { keyword_parsing = 1; }
175 '(' keywords ')'
176 { $$.value = check_assertion ($2.address, $2.length,
177 1, $5);
178 keyword_parsing = 0;
179 $$.unsignedp = 0; }
180 | '(' exp1 ')'
181 { $$ = $2; }
182 ;
183
184
185 exp : exp '*' exp
186 { $$.unsignedp = $1.unsignedp || $3.unsignedp;
187 if ($$.unsignedp)
188 $$.value = (unsigned long) $1.value * $3.value;
189 else
190 {
191 $$.value = $1.value * $3.value;
192 if ($1.value
193 && ($$.value / $1.value != $3.value
194 || ($$.value & $1.value & $3.value) < 0))
195 integer_overflow ();
196 } }
197 | exp '/' exp
198 { if ($3.value == 0)
199 {
200 error ("division by zero in #if");
201 $3.value = 1;
202 }
203 $$.unsignedp = $1.unsignedp || $3.unsignedp;
204 if ($$.unsignedp)
205 $$.value = (unsigned long) $1.value / $3.value;
206 else
207 {
208 $$.value = $1.value / $3.value;
209 if (($$.value & $1.value & $3.value) < 0)
210 integer_overflow ();
211 } }
212 | exp '%' exp
213 { if ($3.value == 0)
214 {
215 error ("division by zero in #if");
216 $3.value = 1;
217 }
218 $$.unsignedp = $1.unsignedp || $3.unsignedp;
219 if ($$.unsignedp)
220 $$.value = (unsigned long) $1.value % $3.value;
221 else
222 $$.value = $1.value % $3.value; }
223 | exp '+' exp
224 { $$.value = $1.value + $3.value;
225 $$.unsignedp = $1.unsignedp || $3.unsignedp;
226 if (! $$.unsignedp
227 && ! possible_sum_sign ($1.value, $3.value,
228 $$.value))
229 integer_overflow (); }
230 | exp '-' exp
231 { $$.value = $1.value - $3.value;
232 $$.unsignedp = $1.unsignedp || $3.unsignedp;
233 if (! $$.unsignedp
234 && ! possible_sum_sign ($$.value, $3.value,
235 $1.value))
236 integer_overflow (); }
237 | exp LSH exp
238 { $$.unsignedp = $1.unsignedp;
239 if ($3.value < 0 && ! $3.unsignedp)
240 $$.value = right_shift (&$1, -$3.value);
241 else
242 $$.value = left_shift (&$1, $3.value); }
243 | exp RSH exp
244 { $$.unsignedp = $1.unsignedp;
245 if ($3.value < 0 && ! $3.unsignedp)
246 $$.value = left_shift (&$1, -$3.value);
247 else
248 $$.value = right_shift (&$1, $3.value); }
249 | exp EQUAL exp
250 { $$.value = ($1.value == $3.value);
251 $$.unsignedp = 0; }
252 | exp NOTEQUAL exp
253 { $$.value = ($1.value != $3.value);
254 $$.unsignedp = 0; }
255 | exp LEQ exp
256 { $$.unsignedp = 0;
257 if ($1.unsignedp || $3.unsignedp)
258 $$.value = (unsigned long) $1.value <= $3.value;
259 else
260 $$.value = $1.value <= $3.value; }
261 | exp GEQ exp
262 { $$.unsignedp = 0;
263 if ($1.unsignedp || $3.unsignedp)
264 $$.value = (unsigned long) $1.value >= $3.value;
265 else
266 $$.value = $1.value >= $3.value; }
267 | exp '<' exp
268 { $$.unsignedp = 0;
269 if ($1.unsignedp || $3.unsignedp)
270 $$.value = (unsigned long) $1.value < $3.value;
271 else
272 $$.value = $1.value < $3.value; }
273 | exp '>' exp
274 { $$.unsignedp = 0;
275 if ($1.unsignedp || $3.unsignedp)
276 $$.value = (unsigned long) $1.value > $3.value;
277 else
278 $$.value = $1.value > $3.value; }
279 | exp '&' exp
280 { $$.value = $1.value & $3.value;
281 $$.unsignedp = $1.unsignedp || $3.unsignedp; }
282 | exp '^' exp
283 { $$.value = $1.value ^ $3.value;
284 $$.unsignedp = $1.unsignedp || $3.unsignedp; }
285 | exp '|' exp
286 { $$.value = $1.value | $3.value;
287 $$.unsignedp = $1.unsignedp || $3.unsignedp; }
288 | exp AND exp
289 { $$.value = ($1.value && $3.value);
290 $$.unsignedp = 0; }
291 | exp OR exp
292 { $$.value = ($1.value || $3.value);
293 $$.unsignedp = 0; }
294 | exp '?' exp ':' exp
295 { $$.value = $1.value ? $3.value : $5.value;
296 $$.unsignedp = $3.unsignedp || $5.unsignedp; }
297 | INT
298 { $$ = yylval.integer; }
299 | CHAR
300 { $$ = yylval.integer; }
301 | NAME
302 { $$.value = 0;
303 $$.unsignedp = 0; }
304 ;
305
306 keywords :
307 { $$ = 0; }
308 | '(' keywords ')' keywords
309 { struct arglist *temp;
310 $$ = (struct arglist *) xmalloc (sizeof (struct arglist));
311 $$->next = $2;
312 $$->name = (U_CHAR *) "(";
313 $$->length = 1;
314 temp = $$;
315 while (temp != 0 && temp->next != 0)
316 temp = temp->next;
317 temp->next = (struct arglist *) xmalloc (sizeof (struct arglist));
318 temp->next->next = $4;
319 temp->next->name = (U_CHAR *) ")";
320 temp->next->length = 1; }
321 | NAME keywords
322 { $$ = (struct arglist *) xmalloc (sizeof (struct arglist));
323 $$->name = $1.address;
324 $$->length = $1.length;
325 $$->next = $2; }
326 ;
327 %%
328
329
330
331
332 static char *lexptr;
333
334
335
336
337
338
339
340 int
341 parse_number (olen)
342 int olen;
343 {
344 register char *p = lexptr;
345 register int c;
346 register unsigned long n = 0, nd, ULONG_MAX_over_base;
347 register int base = 10;
348 register int len = olen;
349 register int overflow = 0;
350 register int digit, largest_digit = 0;
351 int spec_long = 0;
352
353 for (c = 0; c < len; c++)
354 if (p[c] == '.') {
355
356 yyerror ("floating point numbers not allowed in #if expressions");
357 return ERROR;
358 }
359
360 yylval.integer.unsignedp = 0;
361
362 if (len >= 3 && (!strncmp (p, "0x", 2) || !strncmp (p, "0X", 2))) {
363 p += 2;
364 base = 16;
365 len -= 2;
366 }
367 else if (*p == '0')
368 base = 8;
369
370 ULONG_MAX_over_base = (unsigned long) -1 / base;
371
372 for (; len > 0; len--) {
373 c = *p++;
374
375 if (c >= '0' && c <= '9')
376 digit = c - '0';
377 else if (base == 16 && c >= 'a' && c <= 'f')
378 digit = c - 'a' + 10;
379 else if (base == 16 && c >= 'A' && c <= 'F')
380 digit = c - 'A' + 10;
381 else {
382
383 while (1) {
384 if (c == 'l' || c == 'L')
385 {
386 if (spec_long)
387 yyerror ("two `l's in integer constant");
388 spec_long = 1;
389 }
390 else if (c == 'u' || c == 'U')
391 {
392 if (yylval.integer.unsignedp)
393 yyerror ("two `u's in integer constant");
394 yylval.integer.unsignedp = 1;
395 }
396 else
397 break;
398
399 if (--len == 0)
400 break;
401 c = *p++;
402 }
403
404 break;
405 }
406 if (largest_digit < digit)
407 largest_digit = digit;
408 nd = n * base + digit;
409 overflow |= ULONG_MAX_over_base < n | nd < n;
410 n = nd;
411 }
412
413 if (len != 0) {
414 yyerror ("Invalid number in #if expression");
415 return ERROR;
416 }
417
418 if (base <= largest_digit)
419 warning ("integer constant contains digits beyond the radix");
420
421 if (overflow)
422 warning ("integer constant out of range");
423
424
425 if ((long) n < 0 && ! yylval.integer.unsignedp)
426 {
427 if (base == 10)
428 warning ("integer constant is so large that it is unsigned");
429 yylval.integer.unsignedp = 1;
430 }
431
432 lexptr = p;
433 yylval.integer.value = n;
434 return INT;
435 }
436
437 struct token {
438 char *operator;
439 int token;
440 };
441
442 static struct token tokentab2[] = {
443 {"&&", AND},
444 {"||", OR},
445 {"<<", LSH},
446 {">>", RSH},
447 {"==", EQUAL},
448 {"!=", NOTEQUAL},
449 {"<=", LEQ},
450 {">=", GEQ},
451 {"++", ERROR},
452 {"--", ERROR},
453 {NULL, ERROR}
454 };
455
456
457
458 int
459 yylex ()
460 {
461 register int c;
462 register int namelen;
463 register unsigned char *tokstart;
464 register struct token *toktab;
465 int wide_flag;
466
467 retry:
468
469 tokstart = (unsigned char *) lexptr;
470 c = *tokstart;
471
472 if (! keyword_parsing)
473 for (toktab = tokentab2; toktab->operator != NULL; toktab++)
474 if (c == *toktab->operator && tokstart[1] == toktab->operator[1]) {
475 lexptr += 2;
476 if (toktab->token == ERROR)
477 {
478 char *buf = (char *) alloca (40);
479 sprintf (buf, "`%s' not allowed in operand of `#if'", toktab->operator);
480 yyerror (buf);
481 }
482 return toktab->token;
483 }
484
485 switch (c) {
486 case 0:
487 return 0;
488
489 case ' ':
490 case '\t':
491 case '\r':
492 case '\n':
493 lexptr++;
494 goto retry;
495
496 case 'L':
497
498 if (lexptr[1] == '\'')
499 {
500 lexptr++;
501 wide_flag = 1;
502 goto char_constant;
503 }
504 if (lexptr[1] == '"')
505 {
506 lexptr++;
507 wide_flag = 1;
508 goto string_constant;
509 }
510 break;
511
512 case '\'':
513 wide_flag = 0;
514 char_constant:
515 lexptr++;
516 if (keyword_parsing) {
517 char *start_ptr = lexptr - 1;
518 while (1) {
519 c = *lexptr++;
520 if (c == '\\')
521 c = parse_escape (&lexptr);
522 else if (c == '\'')
523 break;
524 }
525 yylval.name.address = tokstart;
526 yylval.name.length = lexptr - start_ptr;
527 return NAME;
528 }
529
530
531
532
533 {
534 register int result = 0;
535 register num_chars = 0;
536 unsigned width = CHAR_TYPE_SIZE;
537 int max_chars;
538 char *token_buffer;
539
540 if (wide_flag)
541 {
542 width = WCHAR_TYPE_SIZE;
543 #ifdef MULTIBYTE_CHARS
544 max_chars = MB_CUR_MAX;
545 #else
546 max_chars = 1;
547 #endif
548 }
549 else
550 max_chars = LONG_TYPE_SIZE / width;
551
552 token_buffer = (char *) alloca (max_chars + 1);
553
554 while (1)
555 {
556 c = *lexptr++;
557
558 if (c == '\'' || c == EOF)
559 break;
560
561 if (c == '\\')
562 {
563 c = parse_escape (&lexptr);
564 if (width < HOST_BITS_PER_INT
565 && (unsigned) c >= (1 << width))
566 pedwarn ("escape sequence out of range for character");
567 }
568
569 num_chars++;
570
571
572 if (num_chars < max_chars + 1)
573 {
574 if (width < HOST_BITS_PER_INT)
575 result = (result << width) | (c & ((1 << width) - 1));
576 else
577 result = c;
578 token_buffer[num_chars - 1] = c;
579 }
580 }
581
582 token_buffer[num_chars] = 0;
583
584 if (c != '\'')
585 error ("malformatted character constant");
586 else if (num_chars == 0)
587 error ("empty character constant");
588 else if (num_chars > max_chars)
589 {
590 num_chars = max_chars;
591 error ("character constant too long");
592 }
593 else if (num_chars != 1 && ! traditional)
594 warning ("multi-character character constant");
595
596
597 if (! wide_flag)
598 {
599 int num_bits = num_chars * width;
600
601 if (lookup ("__CHAR_UNSIGNED__", sizeof ("__CHAR_UNSIGNED__")-1, -1)
602 || ((result >> (num_bits - 1)) & 1) == 0)
603 yylval.integer.value
604 = result & ((unsigned long) ~0 >> (HOST_BITS_PER_LONG - num_bits));
605 else
606 yylval.integer.value
607 = result | ~((unsigned long) ~0 >> (HOST_BITS_PER_LONG - num_bits));
608 }
609 else
610 {
611 #ifdef MULTIBYTE_CHARS
612
613 result = 0;
614
615
616 if (num_chars > 1
617 || (num_chars == 1 && token_buffer[0] != '\0'))
618 {
619 wchar_t wc;
620 (void) mbtowc (NULL_PTR, NULL_PTR, 0);
621 if (mbtowc (& wc, token_buffer, num_chars) == num_chars)
622 result = wc;
623 else
624 warning ("Ignoring invalid multibyte character");
625 }
626 #endif
627 yylval.integer.value = result;
628 }
629 }
630
631
632 yylval.integer.unsignedp = 0;
633
634 return CHAR;
635
636
637
638 case '/':
639 case '+':
640 case '-':
641 case '*':
642 case '%':
643 case '|':
644 case '&':
645 case '^':
646 case '~':
647 case '!':
648 case '@':
649 case '<':
650 case '>':
651 case '[':
652 case ']':
653 case '.':
654 case '?':
655 case ':':
656 case '=':
657 case '{':
658 case '}':
659 case ',':
660 case '#':
661 if (keyword_parsing)
662 break;
663 case '(':
664 case ')':
665 lexptr++;
666 return c;
667
668 case '"':
669 string_constant:
670 if (keyword_parsing) {
671 char *start_ptr = lexptr;
672 lexptr++;
673 while (1) {
674 c = *lexptr++;
675 if (c == '\\')
676 c = parse_escape (&lexptr);
677 else if (c == '"')
678 break;
679 }
680 yylval.name.address = tokstart;
681 yylval.name.length = lexptr - start_ptr;
682 return NAME;
683 }
684 yyerror ("string constants not allowed in #if expressions");
685 return ERROR;
686 }
687
688 if (c >= '0' && c <= '9' && !keyword_parsing) {
689
690 for (namelen = 0;
691 c = tokstart[namelen], is_idchar[c] || c == '.';
692 namelen++)
693 ;
694 return parse_number (namelen);
695 }
696
697
698
699 if (keyword_parsing) {
700 for (namelen = 0;; namelen++) {
701 if (is_hor_space[tokstart[namelen]])
702 break;
703 if (tokstart[namelen] == '(' || tokstart[namelen] == ')')
704 break;
705 if (tokstart[namelen] == '"' || tokstart[namelen] == '\'')
706 break;
707 }
708 } else {
709 if (!is_idstart[c]) {
710 yyerror ("Invalid token in expression");
711 return ERROR;
712 }
713
714 for (namelen = 0; is_idchar[tokstart[namelen]]; namelen++)
715 ;
716 }
717
718 lexptr += namelen;
719 yylval.name.address = tokstart;
720 yylval.name.length = namelen;
721 return NAME;
722 }
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739 int
740 parse_escape (string_ptr)
741 char **string_ptr;
742 {
743 register int c = *(*string_ptr)++;
744 switch (c)
745 {
746 case 'a':
747 return TARGET_BELL;
748 case 'b':
749 return TARGET_BS;
750 case 'e':
751 case 'E':
752 if (pedantic)
753 pedwarn ("non-ANSI-standard escape sequence, `\\%c'", c);
754 return 033;
755 case 'f':
756 return TARGET_FF;
757 case 'n':
758 return TARGET_NEWLINE;
759 case 'r':
760 return TARGET_CR;
761 case 't':
762 return TARGET_TAB;
763 case 'v':
764 return TARGET_VT;
765 case '\n':
766 return -2;
767 case 0:
768 (*string_ptr)--;
769 return 0;
770
771 case '0':
772 case '1':
773 case '2':
774 case '3':
775 case '4':
776 case '5':
777 case '6':
778 case '7':
779 {
780 register int i = c - '0';
781 register int count = 0;
782 while (++count < 3)
783 {
784 c = *(*string_ptr)++;
785 if (c >= '0' && c <= '7')
786 i = (i << 3) + c - '0';
787 else
788 {
789 (*string_ptr)--;
790 break;
791 }
792 }
793 if ((i & ~((1 << CHAR_TYPE_SIZE) - 1)) != 0)
794 {
795 i &= (1 << CHAR_TYPE_SIZE) - 1;
796 warning ("octal character constant does not fit in a byte");
797 }
798 return i;
799 }
800 case 'x':
801 {
802 register unsigned i = 0, overflow = 0, digits_found = 0, digit;
803 for (;;)
804 {
805 c = *(*string_ptr)++;
806 if (c >= '0' && c <= '9')
807 digit = c - '0';
808 else if (c >= 'a' && c <= 'f')
809 digit = c - 'a' + 10;
810 else if (c >= 'A' && c <= 'F')
811 digit = c - 'A' + 10;
812 else
813 {
814 (*string_ptr)--;
815 break;
816 }
817 overflow |= i ^ (i << 4 >> 4);
818 i = (i << 4) + digit;
819 digits_found = 1;
820 }
821 if (!digits_found)
822 yyerror ("\\x used with no following hex digits");
823 if (overflow | (i & ~((1 << BITS_PER_UNIT) - 1)))
824 {
825 i &= (1 << BITS_PER_UNIT) - 1;
826 warning ("hex character constant does not fit in a byte");
827 }
828 return i;
829 }
830 default:
831 return c;
832 }
833 }
834
835 void
836 yyerror (s)
837 char *s;
838 {
839 error (s);
840 longjmp (parse_return_error, 1);
841 }
842
843 static void
844 integer_overflow ()
845 {
846 if (pedantic)
847 pedwarn ("integer overflow in preprocessor expression");
848 }
849
850 static long
851 left_shift (a, b)
852 struct constant *a;
853 unsigned long b;
854 {
855 if (b >= HOST_BITS_PER_LONG)
856 {
857 if (! a->unsignedp && a->value != 0)
858 integer_overflow ();
859 return 0;
860 }
861 else if (a->unsignedp)
862 return (unsigned long) a->value << b;
863 else
864 {
865 long l = a->value << b;
866 if (l >> b != a->value)
867 integer_overflow ();
868 return l;
869 }
870 }
871
872 static long
873 right_shift (a, b)
874 struct constant *a;
875 unsigned long b;
876 {
877 if (b >= HOST_BITS_PER_LONG)
878 return a->unsignedp ? 0 : a->value >> (HOST_BITS_PER_LONG - 1);
879 else if (a->unsignedp)
880 return (unsigned long) a->value >> b;
881 else
882 return a->value >> b;
883 }
884
885
886
887
888
889
890
891
892 int
893 parse_c_expression (string)
894 char *string;
895 {
896 lexptr = string;
897
898 if (lexptr == 0 || *lexptr == 0) {
899 error ("empty #if expression");
900 return 0;
901 }
902
903
904
905
906 if (setjmp (parse_return_error))
907 return 0;
908
909 if (yyparse ())
910 return 0;
911
912 if (*lexptr)
913 error ("Junk after end of expression.");
914
915 return expression_value;
916 }
917
918 #ifdef TEST_EXP_READER
919 extern int yydebug;
920
921
922 int
923 main ()
924 {
925 int n, c;
926 char buf[1024];
927
928
929
930
931 initialize_random_junk ();
932
933 for (;;) {
934 printf ("enter expression: ");
935 n = 0;
936 while ((buf[n] = getchar ()) != '\n' && buf[n] != EOF)
937 n++;
938 if (buf[n] == EOF)
939 break;
940 buf[n] = '\0';
941 printf ("parser returned %d\n", parse_c_expression (buf));
942 }
943
944 return 0;
945 }
946
947
948 unsigned char is_idchar[256];
949
950 unsigned char is_idstart[256];
951
952
953 char is_hor_space[256];
954
955
956
957
958 initialize_random_junk ()
959 {
960 register int i;
961
962
963
964
965
966
967
968 for (i = 'a'; i <= 'z'; i++) {
969 ++is_idchar[i - 'a' + 'A'];
970 ++is_idchar[i];
971 ++is_idstart[i - 'a' + 'A'];
972 ++is_idstart[i];
973 }
974 for (i = '0'; i <= '9'; i++)
975 ++is_idchar[i];
976 ++is_idchar['_'];
977 ++is_idstart['_'];
978 #if DOLLARS_IN_IDENTIFIERS
979 ++is_idchar['$'];
980 ++is_idstart['$'];
981 #endif
982
983
984 ++is_hor_space[' '];
985 ++is_hor_space['\t'];
986 }
987
988 error (msg)
989 {
990 printf ("error: %s\n", msg);
991 }
992
993 warning (msg)
994 {
995 printf ("warning: %s\n", msg);
996 }
997
998 struct hashnode *
999 lookup (name, len, hash)
1000 char *name;
1001 int len;
1002 int hash;
1003 {
1004 return (DEFAULT_SIGNED_CHAR) ? 0 : ((struct hashnode *) -1);
1005 }
1006 #endif