Merge from mainline
[official-gcc.git] / gcc / ch / lex.c
blob8b05f52ec29f6e125f1b04e69f671ee9ef2dfb55
1 /* Lexical analyzer for GNU CHILL. -*- C -*-
2 Copyright (C) 1992, 1993, 1994, 1998, 1999, 2000, 2001
3 Free Software Foundation, Inc.
5 This file is part of GNU CC.
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
22 #include "config.h"
23 #include "system.h"
24 #include <sys/stat.h>
26 #include "tree.h"
27 #include "input.h"
29 #include "lex.h"
30 #include "ch-tree.h"
31 #include "flags.h"
32 #include "parse.h"
33 #include "obstack.h"
34 #include "toplev.h"
35 #include "tm_p.h"
37 #ifdef MULTIBYTE_CHARS
38 #include <locale.h>
39 #endif
41 /* include the keyword recognizers */
42 #include "hash.h"
44 FILE* finput;
46 #if 0
47 static int last_token = 0;
48 /* Sun's C compiler warns about the safer sequence
49 do { .. } while 0
50 when there's a 'return' inside the braces, so don't use it */
51 #define RETURN_TOKEN(X) { last_token = X; return (X); }
52 #endif
54 /* This is set non-zero to force incoming tokens to lowercase. */
55 extern int ignore_case;
57 extern int module_number;
58 extern int serious_errors;
60 /* This is non-zero to recognize only uppercase special words. */
61 extern int special_UC;
63 extern struct obstack permanent_obstack;
64 extern struct obstack temporary_obstack;
66 /* forward declarations */
67 static void close_input_file PARAMS ((const char *));
68 static tree convert_bitstring PARAMS ((char *));
69 static tree convert_integer PARAMS ((char *));
70 static void maybe_downcase PARAMS ((char *));
71 static int maybe_number PARAMS ((const char *));
72 static tree equal_number PARAMS ((void));
73 static void handle_use_seizefile_directive PARAMS ((int));
74 static int handle_name PARAMS ((tree));
75 static char *readstring PARAMS ((int, int *));
76 static void read_directive PARAMS ((void));
77 static tree read_identifier PARAMS ((int));
78 static tree read_number PARAMS ((int));
79 static void skip_c_comment PARAMS ((void));
80 static void skip_line_comment PARAMS ((void));
81 static int skip_whitespace PARAMS ((void));
82 static tree string_or_char PARAMS ((int, const char *));
83 static void ch_lex_init PARAMS ((void));
84 static void skip_directive PARAMS ((void));
85 static int same_file PARAMS ((const char *, const char *));
86 static int getlc PARAMS ((FILE *));
88 /* next variables are public, because ch-actions uses them */
90 /* the default grantfile name, set by lang_init */
91 tree default_grant_file = 0;
93 /* These tasking-related variables are NULL at the start of each
94 compiler pass, and are set to an expression tree if and when
95 a compiler directive is parsed containing an expression.
96 The NULL state is significant; it means 'no user-specified
97 signal_code (or whatever) has been parsed'. */
99 /* process type, set by <> PROCESS_TYPE = number <> */
100 tree process_type = NULL_TREE;
102 /* send buffer default priority,
103 set by <> SEND_BUFFER_DEFAULT_PRIORITY = number <> */
104 tree send_buffer_prio = NULL_TREE;
106 /* send signal default priority,
107 set by <> SEND_SIGNAL_DEFAULT_PRIORITY = number <> */
108 tree send_signal_prio = NULL_TREE;
110 /* signal code, set by <> SIGNAL_CODE = number <> */
111 tree signal_code = NULL_TREE;
113 /* flag for range checking */
114 int range_checking = 1;
116 /* flag for NULL pointer checking */
117 int empty_checking = 1;
119 /* flag to indicate making all procedure local variables
120 to be STATIC */
121 int all_static_flag = 0;
123 /* flag to indicate -fruntime-checking command line option.
124 Needed for initializing range_checking and empty_checking
125 before pass 2 */
126 int runtime_checking_flag = 1;
128 /* The elements of `ridpointers' are identifier nodes
129 for the reserved type names and storage classes.
130 It is indexed by a RID_... value. */
131 tree ridpointers[(int) RID_MAX];
133 /* Nonzero tells yylex to ignore \ in string constants. */
134 static int ignore_escape_flag = 0;
136 static int maxtoken; /* Current nominal length of token buffer. */
137 char *token_buffer; /* Pointer to token buffer.
138 Actual allocated length is maxtoken + 2.
139 This is not static because objc-parse.y uses it. */
141 /* implement yylineno handling for flex */
142 #define yylineno lineno
144 static int inside_c_comment = 0;
146 static int saw_eol = 0; /* 1 if we've just seen a '\n' */
147 static int saw_eof = 0; /* 1 if we've just seen an EOF */
149 typedef struct string_list
151 struct string_list *next;
152 char *str;
153 } STRING_LIST;
155 /* list of paths specified on the compiler command line by -L options. */
156 static STRING_LIST *seize_path_list = (STRING_LIST *)0;
158 /* List of seize file names. Each TREE_VALUE is an identifier
159 (file name) from a <>USE_SEIZE_FILE<> directive.
160 The TREE_PURPOSE is non-NULL if a USE_SEIZE_FILE directive has been
161 written to the grant file. */
162 static tree files_to_seize = NULL_TREE;
163 /* Last node on files_to_seize list. */
164 static tree last_file_to_seize = NULL_TREE;
165 /* Pointer into files_to_seize list: Next unparsed file to read. */
166 static tree next_file_to_seize = NULL_TREE;
168 /* The most recent use_seize_file directive. */
169 tree use_seizefile_name = NULL_TREE;
171 /* If non-NULL, the name of the seizefile we're currently processing. */
172 tree current_seizefile_name = NULL_TREE;
174 /* called to reset for pass 2 */
175 static void
176 ch_lex_init ()
178 current_seizefile_name = NULL_TREE;
180 lineno = 0;
182 saw_eol = 0;
183 saw_eof = 0;
184 /* Initialize these compiler-directive variables. */
185 process_type = NULL_TREE;
186 send_buffer_prio = NULL_TREE;
187 send_signal_prio = NULL_TREE;
188 signal_code = NULL_TREE;
189 all_static_flag = 0;
190 /* reinitialize rnage checking and empty checking */
191 range_checking = runtime_checking_flag;
192 empty_checking = runtime_checking_flag;
196 const char *
197 init_parse (filename)
198 const char *filename;
200 int lowercase_standard_names = ignore_case || ! special_UC;
202 /* Open input file. */
203 if (filename == 0 || !strcmp (filename, "-"))
205 finput = stdin;
206 filename = "stdin";
208 else
209 finput = fopen (filename, "r");
211 if (finput == 0)
212 fatal_io_error ("can't open %s", filename);
214 #ifdef IO_BUFFER_SIZE
215 setvbuf (finput, (char *) xmalloc (IO_BUFFER_SIZE), _IOFBF, IO_BUFFER_SIZE);
216 #endif
218 /* Make identifier nodes long enough for the language-specific slots. */
219 set_identifier_size (sizeof (struct lang_identifier));
221 /* Start it at 0, because check_newline is called at the very beginning
222 and will increment it to 1. */
223 lineno = 0;
225 /* Initialize these compiler-directive variables. */
226 process_type = NULL_TREE;
227 send_buffer_prio = NULL_TREE;
228 send_signal_prio = NULL_TREE;
229 signal_code = NULL_TREE;
231 maxtoken = 40;
232 token_buffer = xmalloc ((unsigned)(maxtoken + 2));
234 init_chill_expand ();
236 #define ENTER_STANDARD_NAME(RID, LOWER, UPPER) \
237 ridpointers[(int) RID] = \
238 get_identifier (lowercase_standard_names ? LOWER : UPPER)
240 ENTER_STANDARD_NAME (RID_ALL, "all", "ALL");
241 ENTER_STANDARD_NAME (RID_ASSERTFAIL, "assertfail", "ASSERTFAIL");
242 ENTER_STANDARD_NAME (RID_ASSOCIATION, "association", "ASSOCIATION");
243 ENTER_STANDARD_NAME (RID_BIN, "bin", "BIN");
244 ENTER_STANDARD_NAME (RID_BOOL, "bool", "BOOL");
245 ENTER_STANDARD_NAME (RID_BOOLS, "bools", "BOOLS");
246 ENTER_STANDARD_NAME (RID_BYTE, "byte", "BYTE");
247 ENTER_STANDARD_NAME (RID_CHAR, "char", "CHAR");
248 ENTER_STANDARD_NAME (RID_DOUBLE, "double", "DOUBLE");
249 ENTER_STANDARD_NAME (RID_DURATION, "duration", "DURATION");
250 ENTER_STANDARD_NAME (RID_DYNAMIC, "dynamic", "DYNAMIC");
251 ENTER_STANDARD_NAME (RID_ELSE, "else", "ELSE");
252 ENTER_STANDARD_NAME (RID_EMPTY, "empty", "EMPTY");
253 ENTER_STANDARD_NAME (RID_FALSE, "false", "FALSE");
254 ENTER_STANDARD_NAME (RID_FLOAT, "float", "FLOAT");
255 ENTER_STANDARD_NAME (RID_GENERAL, "general", "GENERAL");
256 ENTER_STANDARD_NAME (RID_IN, "in", "IN");
257 ENTER_STANDARD_NAME (RID_INLINE, "inline", "INLINE");
258 ENTER_STANDARD_NAME (RID_INOUT, "inout", "INOUT");
259 ENTER_STANDARD_NAME (RID_INSTANCE, "instance", "INSTANCE");
260 ENTER_STANDARD_NAME (RID_INT, "int", "INT");
261 ENTER_STANDARD_NAME (RID_LOC, "loc", "LOC");
262 ENTER_STANDARD_NAME (RID_LONG, "long", "LONG");
263 ENTER_STANDARD_NAME (RID_LONG_REAL, "long_real", "LONG_REAL");
264 ENTER_STANDARD_NAME (RID_NULL, "null", "NULL");
265 ENTER_STANDARD_NAME (RID_OUT, "out", "OUT");
266 ENTER_STANDARD_NAME (RID_OVERFLOW, "overflow", "OVERFLOW");
267 ENTER_STANDARD_NAME (RID_PTR, "ptr", "PTR");
268 ENTER_STANDARD_NAME (RID_READ, "read", "READ");
269 ENTER_STANDARD_NAME (RID_REAL, "real", "REAL");
270 ENTER_STANDARD_NAME (RID_RANGE, "range", "RANGE");
271 ENTER_STANDARD_NAME (RID_RANGEFAIL, "rangefail", "RANGEFAIL");
272 ENTER_STANDARD_NAME (RID_RECURSIVE, "recursive", "RECURSIVE");
273 ENTER_STANDARD_NAME (RID_SHORT, "short", "SHORT");
274 ENTER_STANDARD_NAME (RID_SIMPLE, "simple", "SIMPLE");
275 ENTER_STANDARD_NAME (RID_TIME, "time", "TIME");
276 ENTER_STANDARD_NAME (RID_TRUE, "true", "TRUE");
277 ENTER_STANDARD_NAME (RID_UBYTE, "ubyte", "UBYTE");
278 ENTER_STANDARD_NAME (RID_UINT, "uint", "UINT");
279 ENTER_STANDARD_NAME (RID_ULONG, "ulong", "ULONG");
280 ENTER_STANDARD_NAME (RID_UNSIGNED, "unsigned", "UNSIGNED");
281 ENTER_STANDARD_NAME (RID_USHORT, "ushort", "USHORT");
282 ENTER_STANDARD_NAME (RID_VOID, "void", "VOID");
284 return filename;
287 void
288 finish_parse ()
290 if (finput != NULL)
291 fclose (finput);
294 static int yywrap PARAMS ((void));
295 static int yy_refill PARAMS ((void));
297 #define YY_PUTBACK_SIZE 5
298 #define YY_BUF_SIZE 1000
300 static char yy_buffer[YY_PUTBACK_SIZE + YY_BUF_SIZE];
301 static char *yy_cur = yy_buffer + YY_PUTBACK_SIZE;
302 static char *yy_lim = yy_buffer + YY_PUTBACK_SIZE;
304 static int
305 yy_refill ()
307 char *buf = yy_buffer + YY_PUTBACK_SIZE;
308 int c, result;
309 bcopy (yy_cur - YY_PUTBACK_SIZE, yy_buffer, YY_PUTBACK_SIZE);
310 yy_cur = buf;
312 retry:
313 if (saw_eof)
315 if (yywrap ())
316 return EOF;
317 saw_eof = 0;
318 goto retry;
321 result = 0;
322 while (saw_eol)
324 c = check_newline ();
325 if (c == EOF)
327 saw_eof = 1;
328 goto retry;
330 else if (c != '\n')
332 saw_eol = 0;
333 buf[result++] = c;
337 while (result < YY_BUF_SIZE)
339 c = getc(finput);
340 if (c == EOF)
342 saw_eof = 1;
343 break;
345 buf[result++] = c;
347 /* Because we might switch input files on a compiler directive
348 (that end with '>', don't read past a '>', just in case. */
349 if (c == '>')
350 break;
352 if (c == '\n')
354 #ifdef YYDEBUG
355 extern int yydebug;
356 if (yydebug)
357 fprintf (stderr, "-------------------------- finished Line %d\n",
358 yylineno);
359 #endif
360 saw_eol = 1;
361 break;
365 yy_lim = yy_cur + result;
367 return yy_lim > yy_cur ? *yy_cur++ : EOF;
370 #define input() (yy_cur < yy_lim ? *yy_cur++ : yy_refill ())
372 #define unput(c) (*--yy_cur = (c))
375 int starting_pass_2 = 0;
378 yylex ()
380 int nextc;
381 int len;
382 char* tmp;
383 int base;
384 int ch;
385 retry:
386 ch = input ();
387 if (starting_pass_2)
389 starting_pass_2 = 0;
390 unput (ch);
391 return END_PASS_1;
393 switch (ch)
395 case ' ': case '\t': case '\n': case '\f': case '\b': case '\v': case '\r':
396 goto retry;
397 case '[':
398 return LPC;
399 case ']':
400 return RPC;
401 case '{':
402 return LC;
403 case '}':
404 return RC;
405 case '(':
406 nextc = input ();
407 if (nextc == ':')
408 return LPC;
409 unput (nextc);
410 return LPRN;
411 case ')':
412 return RPRN;
413 case ':':
414 nextc = input ();
415 if (nextc == ')')
416 return RPC;
417 else if (nextc == '=')
418 return ASGN;
419 unput (nextc);
420 return COLON;
421 case ',':
422 return COMMA;
423 case ';':
424 return SC;
425 case '+':
426 return PLUS;
427 case '-':
428 nextc = input ();
429 if (nextc == '>')
430 return ARROW;
431 if (nextc == '-')
433 skip_line_comment ();
434 goto retry;
436 unput (nextc);
437 return SUB;
438 case '*':
439 return MUL;
440 case '=':
441 return EQL;
442 case '/':
443 nextc = input ();
444 if (nextc == '/')
445 return CONCAT;
446 else if (nextc == '=')
447 return NE;
448 else if (nextc == '*')
450 skip_c_comment ();
451 goto retry;
453 unput (nextc);
454 return DIV;
455 case '<':
456 nextc = input ();
457 if (nextc == '=')
458 return LTE;
459 if (nextc == '>')
461 read_directive ();
462 goto retry;
464 unput (nextc);
465 return LT;
466 case '>':
467 nextc = input ();
468 if (nextc == '=')
469 return GTE;
470 unput (nextc);
471 return GT;
473 case 'D': case 'd':
474 base = 10;
475 goto maybe_digits;
476 case 'B': case 'b':
477 base = 2;
478 goto maybe_digits;
479 case 'H': case 'h':
480 base = 16;
481 goto maybe_digits;
482 case 'O': case 'o':
483 base = 8;
484 goto maybe_digits;
485 case 'C': case 'c':
486 nextc = input ();
487 if (nextc == '\'')
489 int byte_val = 0;
490 char *start;
491 int len = 0; /* Number of hex digits seen. */
492 for (;;)
494 ch = input ();
495 if (ch == '\'')
496 break;
497 if (ch == '_')
498 continue;
499 if (!ISXDIGIT (ch)) /* error on non-hex digit */
501 if (pass == 1)
502 error ("invalid C'xx' ");
503 break;
505 if (ch >= 'a')
506 ch -= ' ';
507 ch -= '0';
508 if (ch > 9)
509 ch -= 7;
510 byte_val *= 16;
511 byte_val += (int)ch;
513 if (len & 1) /* collected two digits, save byte */
514 obstack_1grow (&temporary_obstack, (char) byte_val);
515 len++;
517 start = obstack_finish (&temporary_obstack);
518 yylval.ttype = string_or_char (len >> 1, start);
519 obstack_free (&temporary_obstack, start);
520 return len == 2 ? SINGLECHAR : STRING;
522 unput (nextc);
523 goto letter;
525 maybe_digits:
526 nextc = input ();
527 if (nextc == '\'')
529 char *start;
530 obstack_1grow (&temporary_obstack, ch);
531 obstack_1grow (&temporary_obstack, nextc);
532 for (;;)
534 ch = input ();
535 if (ISALNUM (ch))
536 obstack_1grow (&temporary_obstack, ch);
537 else if (ch != '_')
538 break;
540 obstack_1grow (&temporary_obstack, '\0');
541 start = obstack_finish (&temporary_obstack);
542 if (ch != '\'')
544 unput (ch);
545 yylval.ttype = convert_integer (start); /* Pass base? */
546 return NUMBER;
548 else
550 yylval.ttype = convert_bitstring (start);
551 return BITSTRING;
554 unput (nextc);
555 goto letter;
557 case 'A': case 'E':
558 case 'F': case 'G': case 'I': case 'J':
559 case 'K': case 'L': case 'M': case 'N':
560 case 'P': case 'Q': case 'R': case 'S': case 'T':
561 case 'U': case 'V': case 'W': case 'X': case 'Y':
562 case 'Z':
563 case 'a': case 'e':
564 case 'f': case 'g': case 'i': case 'j':
565 case 'k': case 'l': case 'm': case 'n':
566 case 'p': case 'q': case 'r': case 's': case 't':
567 case 'u': case 'v': case 'w': case 'x': case 'y':
568 case 'z':
569 case '_':
570 letter:
571 return handle_name (read_identifier (ch));
572 case '\'':
573 tmp = readstring ('\'', &len);
574 yylval.ttype = string_or_char (len, tmp);
575 free (tmp);
576 return len == 1 ? SINGLECHAR : STRING;
577 case '\"':
578 tmp = readstring ('\"', &len);
579 yylval.ttype = build_chill_string (len, tmp);
580 free (tmp);
581 return STRING;
582 case '.':
583 nextc = input ();
584 unput (nextc);
585 if (ISDIGIT (nextc)) /* || nextc == '_') we don't start numbers with '_' */
586 goto number;
587 return DOT;
588 case '0': case '1': case '2': case '3': case '4':
589 case '5': case '6': case '7': case '8': case '9':
590 number:
591 yylval.ttype = read_number (ch);
592 return TREE_CODE (yylval.ttype) == REAL_CST ? FLOATING : NUMBER;
593 default:
594 return ch;
598 static void
599 close_input_file (fn)
600 const char *fn;
602 if (finput == NULL)
603 abort ();
605 if (finput != stdin && fclose (finput) == EOF)
607 error ("can't close %s", fn);
608 abort ();
610 finput = NULL;
613 /* Return an identifier, starting with FIRST and then reading
614 more characters using input(). Return an IDENTIFIER_NODE. */
616 static tree
617 read_identifier (first)
618 int first; /* First letter of identifier */
620 tree id;
621 char *start;
622 for (;;)
624 obstack_1grow (&temporary_obstack, first);
625 first = input ();
626 if (first == EOF)
627 break;
628 if (! ISALNUM (first) && first != '_')
630 unput (first);
631 break;
634 obstack_1grow (&temporary_obstack, '\0');
635 start = obstack_finish (&temporary_obstack);
636 maybe_downcase (start);
637 id = get_identifier (start);
638 obstack_free (&temporary_obstack, start);
639 return id;
642 /* Given an identifier ID, check to see if it is a reserved name,
643 and return the appropriate token type. */
645 static int
646 handle_name (id)
647 tree id;
649 struct resword *tp;
650 tp = in_word_set (IDENTIFIER_POINTER (id), IDENTIFIER_LENGTH (id));
651 if (tp != NULL
652 && special_UC == ISUPPER ((unsigned char) tp->name[0])
653 && (tp->flags == RESERVED || tp->flags == PREDEF))
655 if (tp->rid != NORID)
656 yylval.ttype = ridpointers[tp->rid];
657 else if (tp->token == THIS)
658 yylval.ttype = lookup_name (get_identifier ("__whoami"));
659 return tp->token;
661 yylval.ttype = id;
662 return NAME;
665 static tree
666 read_number (ch)
667 int ch; /* Initial character */
669 tree num;
670 char *start;
671 int is_float = 0;
672 for (;;)
674 if (ch != '_')
675 obstack_1grow (&temporary_obstack, ch);
676 ch = input ();
677 if (! ISDIGIT (ch) && ch != '_')
678 break;
680 if (ch == '.')
684 if (ch != '_')
685 obstack_1grow (&temporary_obstack, ch);
686 ch = input ();
687 } while (ISDIGIT (ch) || ch == '_');
688 is_float++;
690 if (ch == 'd' || ch == 'D' || ch == 'e' || ch == 'E')
692 /* Convert exponent indication [eEdD] to 'e'. */
693 obstack_1grow (&temporary_obstack, 'e');
694 ch = input ();
695 if (ch == '+' || ch == '-')
697 obstack_1grow (&temporary_obstack, ch);
698 ch = input ();
700 if (ISDIGIT (ch) || ch == '_')
704 if (ch != '_')
705 obstack_1grow (&temporary_obstack, ch);
706 ch = input ();
707 } while (ISDIGIT (ch) || ch == '_');
709 else
711 error ("malformed exponent part of floating-point literal");
713 is_float++;
715 if (ch != EOF)
716 unput (ch);
717 obstack_1grow (&temporary_obstack, '\0');
718 start = obstack_finish (&temporary_obstack);
719 if (is_float)
721 REAL_VALUE_TYPE value;
722 tree type = double_type_node;
723 errno = 0;
724 value = REAL_VALUE_ATOF (start, TYPE_MODE (type));
725 obstack_free (&temporary_obstack, start);
726 if (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
727 && REAL_VALUE_ISINF (value) && pedantic)
728 pedwarn ("real number exceeds range of REAL");
729 num = build_real (type, value);
731 else
732 num = convert_integer (start);
733 CH_DERIVED_FLAG (num) = 1;
734 return num;
737 /* Skip to the end of a compiler directive. */
739 static void
740 skip_directive ()
742 int ch = input ();
743 for (;;)
745 if (ch == EOF)
747 error ("end-of-file in '<>' directive");
748 break;
750 if (ch == '\n')
751 break;
752 if (ch == '<')
754 ch = input ();
755 if (ch == '>')
756 break;
758 ch = input ();
760 starting_pass_2 = 0;
763 /* Read a compiler directive. ("<>{WS}" have already been read. ) */
764 static void
765 read_directive ()
767 struct resword *tp;
768 tree id;
769 int ch = skip_whitespace();
770 if (ISALPHA (ch) || ch == '_')
771 id = read_identifier (ch);
772 else if (ch == EOF)
774 error ("end-of-file in '<>' directive");
775 to_global_binding_level ();
776 return;
778 else
780 warning ("unrecognized compiler directive");
781 skip_directive ();
782 return;
784 tp = in_word_set (IDENTIFIER_POINTER (id), IDENTIFIER_LENGTH (id));
785 if (tp == NULL || special_UC != ISUPPER ((unsigned char) tp->name[0]))
787 if (pass == 1)
788 warning ("unrecognized compiler directive `%s'",
789 IDENTIFIER_POINTER (id));
791 else
792 switch (tp->token)
794 case ALL_STATIC_OFF:
795 all_static_flag = 0;
796 break;
797 case ALL_STATIC_ON:
798 all_static_flag = 1;
799 break;
800 case EMPTY_OFF:
801 empty_checking = 0;
802 break;
803 case EMPTY_ON:
804 empty_checking = 1;
805 break;
806 case IGNORED_DIRECTIVE:
807 break;
808 case PROCESS_TYPE_TOKEN:
809 process_type = equal_number ();
810 break;
811 case RANGE_OFF:
812 range_checking = 0;
813 break;
814 case RANGE_ON:
815 range_checking = 1;
816 break;
817 case SEND_SIGNAL_DEFAULT_PRIORITY:
818 send_signal_prio = equal_number ();
819 break;
820 case SEND_BUFFER_DEFAULT_PRIORITY:
821 send_buffer_prio = equal_number ();
822 break;
823 case SIGNAL_CODE:
824 signal_code = equal_number ();
825 break;
826 case USE_SEIZE_FILE:
827 handle_use_seizefile_directive (0);
828 break;
829 case USE_SEIZE_FILE_RESTRICTED:
830 handle_use_seizefile_directive (1);
831 break;
832 default:
833 if (pass == 1)
834 warning ("unrecognized compiler directive `%s'",
835 IDENTIFIER_POINTER (id));
836 break;
838 skip_directive ();
842 tree
843 build_chill_string (len, str)
844 int len;
845 const char *str;
847 tree t;
849 push_obstacks (&permanent_obstack, &permanent_obstack);
850 t = build_string (len, str);
851 TREE_TYPE (t) = build_string_type (char_type_node,
852 build_int_2 (len, 0));
853 CH_DERIVED_FLAG (t) = 1;
854 pop_obstacks ();
855 return t;
859 static tree
860 string_or_char (len, str)
861 int len;
862 const char *str;
864 tree result;
866 push_obstacks (&permanent_obstack, &permanent_obstack);
867 if (len == 1)
869 result = build_int_2 ((unsigned char)str[0], 0);
870 CH_DERIVED_FLAG (result) = 1;
871 TREE_TYPE (result) = char_type_node;
873 else
874 result = build_chill_string (len, str);
875 pop_obstacks ();
876 return result;
880 static void
881 maybe_downcase (str)
882 char *str;
884 if (! ignore_case)
885 return;
886 while (*str)
888 *str = TOLOWER (*str);
889 str++;
894 static int
895 maybe_number (s)
896 const char *s;
898 char fc;
900 /* check for decimal number */
901 if (*s >= '0' && *s <= '9')
903 while (*s)
905 if (*s >= '0' && *s <= '9')
906 s++;
907 else
908 return 0;
910 return 1;
913 fc = *s;
914 if (s[1] != '\'')
915 return 0;
916 s += 2;
917 while (*s)
919 switch (fc)
921 case 'd':
922 case 'D':
923 if (*s < '0' || *s > '9')
924 return 0;
925 break;
926 case 'h':
927 case 'H':
928 if (!ISXDIGIT ((unsigned char) *s))
929 return 0;
930 break;
931 case 'b':
932 case 'B':
933 if (*s < '0' || *s > '1')
934 return 0;
935 break;
936 case 'o':
937 case 'O':
938 if (*s < '0' || *s > '7')
939 return 0;
940 break;
941 default:
942 return 0;
944 s++;
946 return 1;
949 static char *
950 readstring (terminator, len)
951 char terminator;
952 int *len;
954 int c;
955 unsigned allocated = 1024;
956 char *tmp = xmalloc (allocated);
957 unsigned i = 0;
959 for (;;)
961 c = input ();
962 if (c == terminator)
964 if ((c = input ()) != terminator)
966 unput (c);
967 break;
969 else
970 c = terminator;
972 if (c == '\n' || c == EOF)
973 goto unterminated;
974 if (c == '^')
976 c = input();
977 if (c == EOF || c == '\n')
978 goto unterminated;
979 if (c == '^')
980 goto storeit;
981 if (c == '(')
983 int cc, count = 0;
984 int base = 10;
985 int next_apos = 0;
986 int check_base = 1;
987 c = 0;
988 while (1)
990 cc = input ();
991 if (cc == terminator)
993 if (!(terminator == '\'' && next_apos))
995 error ("unterminated control sequence");
996 serious_errors++;
997 goto done;
1000 if (cc == EOF || cc == '\n')
1002 c = cc;
1003 goto unterminated;
1005 if (next_apos)
1007 next_apos = 0;
1008 if (cc != '\'')
1010 error ("invalid integer literal in control sequence");
1011 serious_errors++;
1012 goto done;
1014 continue;
1016 if (cc == ' ' || cc == '\t')
1017 continue;
1018 if (cc == ')')
1020 if ((c < 0 || c > 255) && (pass == 1))
1021 error ("control sequence overflow");
1022 if (! count && pass == 1)
1023 error ("invalid control sequence");
1024 break;
1026 else if (cc == ',')
1028 if ((c < 0 || c > 255) && (pass == 1))
1029 error ("control sequence overflow");
1030 if (! count && pass == 1)
1031 error ("invalid control sequence");
1032 tmp[i++] = c;
1033 if (i == allocated)
1035 allocated += 1024;
1036 tmp = xrealloc (tmp, allocated);
1038 c = count = 0;
1039 base = 10;
1040 check_base = 1;
1041 continue;
1043 else if (cc == '_')
1045 if (! count && pass == 1)
1046 error ("invalid integer literal in control sequence");
1047 continue;
1049 if (check_base)
1051 if (cc == 'D' || cc == 'd')
1053 base = 10;
1054 next_apos = 1;
1056 else if (cc == 'H' || cc == 'h')
1058 base = 16;
1059 next_apos = 1;
1061 else if (cc == 'O' || cc == 'o')
1063 base = 8;
1064 next_apos = 1;
1066 else if (cc == 'B' || cc == 'b')
1068 base = 2;
1069 next_apos = 1;
1071 check_base = 0;
1072 if (next_apos)
1073 continue;
1075 if (base == 2)
1077 if (cc < '0' || cc > '1')
1078 cc = -1;
1079 else
1080 cc -= '0';
1082 else if (base == 8)
1084 if (cc < '0' || cc > '8')
1085 cc = -1;
1086 else
1087 cc -= '0';
1089 else if (base == 10)
1091 if (! ISDIGIT (cc))
1092 cc = -1;
1093 else
1094 cc -= '0';
1096 else if (base == 16)
1098 if (!ISXDIGIT (cc))
1099 cc = -1;
1100 else
1102 if (cc >= 'a')
1103 cc -= ' ';
1104 cc -= '0';
1105 if (cc > 9)
1106 cc -= 7;
1109 else
1111 error ("invalid base in read control sequence");
1112 abort ();
1114 if (cc == -1)
1116 /* error in control sequence */
1117 if (pass == 1)
1118 error ("invalid digit in control sequence");
1119 cc = 0;
1121 c = (c * base) + cc;
1122 count++;
1125 else
1126 c ^= 64;
1128 storeit:
1129 tmp[i++] = c;
1130 if (i == allocated)
1132 allocated += 1024;
1133 tmp = xrealloc (tmp, allocated);
1136 done:
1137 tmp [*len = i] = '\0';
1138 return tmp;
1140 unterminated:
1141 if (c == '\n')
1142 unput ('\n');
1143 *len = 1;
1144 if (pass == 1)
1145 error ("unterminated string literal");
1146 to_global_binding_level ();
1147 tmp[0] = '\0';
1148 return tmp;
1151 /* Convert an integer INTCHARS into an INTEGER_CST.
1152 INTCHARS is on the temporary_obstack, and is popped by this function. */
1154 static tree
1155 convert_integer (intchars)
1156 char *intchars;
1158 #ifdef YYDEBUG
1159 extern int yydebug;
1160 #endif
1161 char *p = intchars;
1162 char *oldp = p;
1163 int base = 10, tmp;
1164 int valid_chars = 0;
1165 int overflow = 0;
1166 tree type;
1167 HOST_WIDE_INT val_lo = 0, val_hi = 0;
1168 tree val;
1170 /* determine the base */
1171 switch (*p)
1173 case 'd':
1174 case 'D':
1175 p += 2;
1176 break;
1177 case 'o':
1178 case 'O':
1179 p += 2;
1180 base = 8;
1181 break;
1182 case 'h':
1183 case 'H':
1184 p += 2;
1185 base = 16;
1186 break;
1187 case 'b':
1188 case 'B':
1189 p += 2;
1190 base = 2;
1191 break;
1192 default:
1193 if (!ISDIGIT (*p)) /* this test is for equal_number () */
1195 obstack_free (&temporary_obstack, intchars);
1196 return 0;
1198 break;
1201 while (*p)
1203 tmp = *p++;
1204 if ((tmp == '\'') || (tmp == '_'))
1205 continue;
1206 if (tmp < '0')
1207 goto bad_char;
1208 if (tmp >= 'a') /* uppercase the char */
1209 tmp -= ' ';
1210 switch (base) /* validate the characters */
1212 case 2:
1213 if (tmp > '1')
1214 goto bad_char;
1215 break;
1216 case 8:
1217 if (tmp > '7')
1218 goto bad_char;
1219 break;
1220 case 10:
1221 if (tmp > '9')
1222 goto bad_char;
1223 break;
1224 case 16:
1225 if (tmp > 'F')
1226 goto bad_char;
1227 if (tmp > '9' && tmp < 'A')
1228 goto bad_char;
1229 break;
1230 default:
1231 abort ();
1233 tmp -= '0';
1234 if (tmp > 9)
1235 tmp -= 7;
1236 if (mul_double (val_lo, val_hi, base, 0, &val_lo, &val_hi))
1237 overflow++;
1238 add_double (val_lo, val_hi, tmp, 0, &val_lo, &val_hi);
1239 if (val_hi < 0)
1240 overflow++;
1241 valid_chars++;
1243 bad_char:
1244 obstack_free (&temporary_obstack, intchars);
1245 if (!valid_chars)
1247 if (pass == 2)
1248 error ("invalid number format `%s'", oldp);
1249 return 0;
1251 val = build_int_2 (val_lo, val_hi);
1252 /* We set the type to long long (or long long unsigned) so that
1253 constant fold of literals is less likely to overflow. */
1254 if (int_fits_type_p (val, long_long_integer_type_node))
1255 type = long_long_integer_type_node;
1256 else
1258 if (! int_fits_type_p (val, long_long_unsigned_type_node))
1259 overflow++;
1260 type = long_long_unsigned_type_node;
1262 TREE_TYPE (val) = type;
1263 CH_DERIVED_FLAG (val) = 1;
1265 if (overflow)
1266 error ("integer literal too big");
1268 return val;
1271 /* Convert a bitstring literal on the temporary_obstack to
1272 a bitstring CONSTRUCTOR. Free the literal from the obstack. */
1274 static tree
1275 convert_bitstring (p)
1276 char *p;
1278 #ifdef YYDEBUG
1279 extern int yydebug;
1280 #endif
1281 int bl = 0, valid_chars = 0, bits_per_char = 0, c, k;
1282 tree initlist = NULL_TREE;
1283 tree val;
1285 /* Move p to stack so we can re-use temporary_obstack for result. */
1286 char *oldp = (char*) alloca (strlen (p) + 1);
1287 strcpy (oldp, p);
1288 obstack_free (&temporary_obstack, p);
1289 p = oldp;
1291 switch (*p)
1293 case 'h':
1294 case 'H':
1295 bits_per_char = 4;
1296 break;
1297 case 'o':
1298 case 'O':
1299 bits_per_char = 3;
1300 break;
1301 case 'b':
1302 case 'B':
1303 bits_per_char = 1;
1304 break;
1306 p += 2;
1308 while (*p)
1310 c = *p++;
1311 if (c == '_' || c == '\'')
1312 continue;
1313 if (c >= 'a')
1314 c -= ' ';
1315 c -= '0';
1316 if (c > 9)
1317 c -= 7;
1318 valid_chars++;
1320 for (k = BYTES_BIG_ENDIAN ? bits_per_char - 1 : 0;
1321 BYTES_BIG_ENDIAN ? k >= 0 : k < bits_per_char;
1322 bl++, BYTES_BIG_ENDIAN ? k-- : k++)
1324 if (c & (1 << k))
1325 initlist = tree_cons (NULL_TREE, build_int_2 (bl, 0), initlist);
1328 #if 0
1329 /* as long as BOOLS(0) is valid it must tbe possible to
1330 specify an empty bitstring */
1331 if (!valid_chars)
1333 if (pass == 2)
1334 error ("invalid number format `%s'", oldp);
1335 return 0;
1337 #endif
1338 val = build (CONSTRUCTOR,
1339 build_bitstring_type (size_int (bl)),
1340 NULL_TREE, nreverse (initlist));
1341 TREE_CONSTANT (val) = 1;
1342 CH_DERIVED_FLAG (val) = 1;
1343 return val;
1346 /* Check if two filenames name the same file.
1347 This is done by stat'ing both files and comparing their inodes.
1349 Note: we have to take care of seize_path_list. Therefore do it the same
1350 way as in yywrap. FIXME: This probably can be done better. */
1352 static int
1353 same_file (filename1, filename2)
1354 const char *filename1;
1355 const char *filename2;
1357 struct stat s[2];
1358 const char *fn_input[2];
1359 int i, stat_status;
1361 if (grant_only_flag)
1362 /* do nothing in this case */
1363 return 0;
1365 /* if filenames are equal -- return 1, cause there is no need
1366 to search in the include list in this case */
1367 if (strcmp (filename1, filename2) == 0)
1368 return 1;
1370 fn_input[0] = filename1;
1371 fn_input[1] = filename2;
1373 for (i = 0; i < 2; i++)
1375 stat_status = stat (fn_input[i], &s[i]);
1376 if (stat_status < 0
1377 && strchr (fn_input[i], '/') == 0)
1379 STRING_LIST *plp;
1380 char *path;
1382 for (plp = seize_path_list; plp != 0; plp = plp->next)
1384 path = (char *) xmalloc (strlen (fn_input[i])
1385 + strlen (plp->str) + 2);
1386 sprintf (path, "%s/%s", plp->str, fn_input[i]);
1387 stat_status = stat (path, &s[i]);
1388 free (path);
1389 if (stat_status >= 0)
1390 break;
1394 if (stat_status < 0)
1395 fatal_io_error ("can't find %s", fn_input[i]);
1397 return s[0].st_ino == s[1].st_ino && s[0].st_dev == s[1].st_dev;
1401 * Note that simply appending included file names to a list in this
1402 * way completely eliminates the need for nested files, and the
1403 * associated book-keeping, since the EOF processing in the lexer
1404 * will simply process the files one at a time, in the order that the
1405 * USE_SEIZE_FILE directives were scanned.
1407 static void
1408 handle_use_seizefile_directive (restricted)
1409 int restricted;
1411 tree seen;
1412 int len;
1413 int c = skip_whitespace ();
1414 char *use_seizefile_str = readstring (c, &len);
1416 if (pass > 1)
1417 return;
1419 if (c != '\'' && c != '\"')
1421 error ("USE_SEIZE_FILE directive must be followed by string");
1422 return;
1425 use_seizefile_name = get_identifier (use_seizefile_str);
1426 CH_USE_SEIZEFILE_RESTRICTED (use_seizefile_name) = restricted;
1428 if (!grant_only_flag)
1430 /* If file foo.ch contains a <> use_seize_file "bar.grt" <>,
1431 and file bar.ch contains a <> use_seize_file "foo.grt" <>,
1432 then if we're compiling foo.ch, we will indirectly be
1433 asked to seize foo.grt. Don't. */
1434 extern char *grant_file_name;
1435 if (strcmp (use_seizefile_str, grant_file_name) == 0)
1436 return;
1438 /* Check if the file is already on the list. */
1439 for (seen = files_to_seize; seen != NULL_TREE; seen = TREE_CHAIN (seen))
1440 if (same_file (IDENTIFIER_POINTER (TREE_VALUE (seen)),
1441 use_seizefile_str))
1442 return; /* Previously seen; nothing to do. */
1445 /* Haven't been asked to seize this file yet, so add
1446 its name to the list. */
1448 tree pl = perm_tree_cons (0, use_seizefile_name, NULL_TREE);
1449 if (files_to_seize == NULL_TREE)
1450 files_to_seize = pl;
1451 else
1452 TREE_CHAIN (last_file_to_seize) = pl;
1453 if (next_file_to_seize == NULL_TREE)
1454 next_file_to_seize = pl;
1455 last_file_to_seize = pl;
1461 * get input, convert to lower case for comparison
1463 static int
1464 getlc (file)
1465 FILE *file;
1467 register int c;
1469 c = getc (file);
1470 if (ignore_case)
1471 c = TOLOWER (c);
1472 return c;
1475 #if defined HANDLE_PRAGMA
1476 /* Local versions of these macros, that can be passed as function pointers. */
1477 static int
1478 pragma_getc ()
1480 return getc (finput);
1483 static void
1484 pragma_ungetc (arg)
1485 int arg;
1487 ungetc (arg, finput);
1489 #endif /* HANDLE_PRAGMA */
1491 #ifdef HANDLE_GENERIC_PRAGMAS
1492 /* Handle a generic #pragma directive.
1493 BUFFER contains the text we read after `#pragma'. Processes the entire input
1494 line and return non-zero iff the pragma was successfully processed. */
1496 static int
1497 handle_generic_pragma (buffer)
1498 char * buffer;
1500 register int c;
1502 for (;;)
1504 char * buff;
1506 handle_pragma_token (buffer, NULL);
1508 c = getc (finput);
1510 while (c == ' ' || c == '\t')
1511 c = getc (finput);
1512 ungetc (c, finput);
1514 if (c == '\n' || c == EOF)
1515 return handle_pragma_token (NULL, NULL);
1517 /* Read the next word of the pragma into the buffer. */
1518 buff = buffer;
1521 * buff ++ = c;
1522 c = getc (finput);
1524 while (c != EOF && ! ISSPACE (c) && buff < buffer + 128);
1525 /* XXX shared knowledge about size of buffer. */
1527 ungetc (c, finput);
1529 * -- buff = 0;
1532 #endif /* HANDLE_GENERIC_PRAGMAS */
1534 /* At the beginning of a line, increment the line number and process
1535 any #-directive on this line. If the line is a #-directive, read
1536 the entire line and return a newline. Otherwise, return the line's
1537 first non-whitespace character.
1539 (Each language front end has a check_newline() function that is called
1540 from lang_init() for that language. One of the things this function
1541 must do is read the first line of the input file, and if it is a #line
1542 directive, extract the filename from it and use it to initialize
1543 main_input_filename. Proper generation of debugging information in
1544 the normal "front end calls cpp then calls cc1XXXX environment" depends
1545 upon this being done.) */
1548 check_newline ()
1550 register int c;
1552 lineno++;
1554 /* Read first nonwhite char on the line. */
1556 c = getc (finput);
1558 while (c == ' ' || c == '\t')
1559 c = getc (finput);
1561 if (c != '#' || inside_c_comment)
1563 /* If not #, return it so caller will use it. */
1564 return c;
1567 /* Read first nonwhite char after the `#'. */
1569 c = getc (finput);
1570 while (c == ' ' || c == '\t')
1571 c = getc (finput);
1573 /* If a letter follows, then if the word here is `line', skip
1574 it and ignore it; otherwise, ignore the line, with an error
1575 if the word isn't `pragma', `ident', `define', or `undef'. */
1577 if (ignore_case)
1578 c = TOLOWER (c);
1580 if (c >= 'a' && c <= 'z')
1582 if (c == 'p')
1584 if (getlc (finput) == 'r'
1585 && getlc (finput) == 'a'
1586 && getlc (finput) == 'g'
1587 && getlc (finput) == 'm'
1588 && getlc (finput) == 'a'
1589 && (c = getlc (finput), ISSPACE (c)))
1591 #ifdef HANDLE_PRAGMA
1592 static char buffer [128];
1593 char * buff = buffer;
1595 /* Read the pragma name into a buffer. */
1596 while (c = getlc (finput), ISSPACE (c))
1597 continue;
1601 * buff ++ = c;
1602 c = getlc (finput);
1604 while (c != EOF && ! ISSPACE (c) && c != '\n'
1605 && buff < buffer + 128);
1607 pragma_ungetc (c);
1609 * -- buff = 0;
1611 if (HANDLE_PRAGMA (pragma_getc, pragma_ungetc, buffer))
1612 goto skipline;
1613 #endif /* HANDLE_PRAGMA */
1615 #ifdef HANDLE_GENERIC_PRAGMAS
1616 if (handle_generic_pragma (buffer))
1617 goto skipline;
1618 #endif /* HANDLE_GENERIC_PRAGMAS */
1620 goto skipline;
1624 else if (c == 'd')
1626 if (getlc (finput) == 'e'
1627 && getlc (finput) == 'f'
1628 && getlc (finput) == 'i'
1629 && getlc (finput) == 'n'
1630 && getlc (finput) == 'e'
1631 && (c = getlc (finput), ISSPACE (c)))
1633 #if 0 /*def DWARF_DEBUGGING_INFO*/
1634 if (c != '\n'
1635 && (debug_info_level == DINFO_LEVEL_VERBOSE)
1636 && (write_symbols == DWARF_DEBUG))
1637 dwarfout_define (lineno, get_directive_line (finput));
1638 #endif /* DWARF_DEBUGGING_INFO */
1639 goto skipline;
1642 else if (c == 'u')
1644 if (getlc (finput) == 'n'
1645 && getlc (finput) == 'd'
1646 && getlc (finput) == 'e'
1647 && getlc (finput) == 'f'
1648 && (c = getlc (finput), ISSPACE (c)))
1650 #if 0 /*def DWARF_DEBUGGING_INFO*/
1651 if (c != '\n'
1652 && (debug_info_level == DINFO_LEVEL_VERBOSE)
1653 && (write_symbols == DWARF_DEBUG))
1654 dwarfout_undef (lineno, get_directive_line (finput));
1655 #endif /* DWARF_DEBUGGING_INFO */
1656 goto skipline;
1659 else if (c == 'l')
1661 if (getlc (finput) == 'i'
1662 && getlc (finput) == 'n'
1663 && getlc (finput) == 'e'
1664 && ((c = getlc (finput)) == ' ' || c == '\t'))
1665 goto linenum;
1667 #if 0
1668 else if (c == 'i')
1670 if (getlc (finput) == 'd'
1671 && getlc (finput) == 'e'
1672 && getlc (finput) == 'n'
1673 && getlc (finput) == 't'
1674 && ((c = getlc (finput)) == ' ' || c == '\t'))
1676 /* #ident. The pedantic warning is now in cpp. */
1678 /* Here we have just seen `#ident '.
1679 A string constant should follow. */
1681 while (c == ' ' || c == '\t')
1682 c = getlc (finput);
1684 /* If no argument, ignore the line. */
1685 if (c == '\n')
1686 return c;
1688 ungetc (c, finput);
1689 token = yylex ();
1690 if (token != STRING
1691 || TREE_CODE (yylval.ttype) != STRING_CST)
1693 error ("invalid #ident");
1694 goto skipline;
1697 if (!flag_no_ident)
1699 #ifdef ASM_OUTPUT_IDENT
1700 extern FILE *asm_out_file;
1701 ASM_OUTPUT_IDENT (asm_out_file, TREE_STRING_POINTER (yylval.ttype));
1702 #endif
1705 /* Skip the rest of this line. */
1706 goto skipline;
1709 #endif
1711 error ("undefined or invalid # directive");
1712 goto skipline;
1715 linenum:
1716 /* Here we have either `#line' or `# <nonletter>'.
1717 In either case, it should be a line number; a digit should follow. */
1719 while (c == ' ' || c == '\t')
1720 c = getlc (finput);
1722 /* If the # is the only nonwhite char on the line,
1723 just ignore it. Check the new newline. */
1724 if (c == '\n')
1725 return c;
1727 /* Something follows the #; read a token. */
1729 if (ISDIGIT(c))
1731 int old_lineno = lineno;
1732 int used_up = 0;
1733 int l = 0;
1734 extern struct obstack permanent_obstack;
1738 l = l * 10 + (c - '0'); /* FIXME Not portable */
1739 c = getlc(finput);
1740 } while (ISDIGIT(c));
1741 /* subtract one, because it is the following line that
1742 gets the specified number */
1744 l--;
1746 /* Is this the last nonwhite stuff on the line? */
1747 c = getlc (finput);
1748 while (c == ' ' || c == '\t')
1749 c = getlc (finput);
1750 if (c == '\n')
1752 /* No more: store the line number and check following line. */
1753 lineno = l;
1754 return c;
1757 /* More follows: it must be a string constant (filename). */
1759 /* Read the string constant, but don't treat \ as special. */
1760 ignore_escape_flag = 1;
1761 ignore_escape_flag = 0;
1763 if (c != '\"')
1765 error ("invalid #line");
1766 goto skipline;
1769 for (;;)
1771 c = getc (finput);
1772 if (c == EOF || c == '\n')
1774 error ("invalid #line");
1775 return c;
1777 if (c == '\"')
1779 obstack_1grow(&permanent_obstack, 0);
1780 input_filename = obstack_finish (&permanent_obstack);
1781 break;
1783 obstack_1grow(&permanent_obstack, c);
1786 lineno = l;
1788 /* Each change of file name
1789 reinitializes whether we are now in a system header. */
1790 in_system_header = 0;
1792 if (main_input_filename == 0)
1793 main_input_filename = input_filename;
1795 /* Is this the last nonwhite stuff on the line? */
1796 c = getlc (finput);
1797 while (c == ' ' || c == '\t')
1798 c = getlc (finput);
1799 if (c == '\n')
1800 return c;
1802 used_up = 0;
1804 /* `1' after file name means entering new file.
1805 `2' after file name means just left a file. */
1807 if (ISDIGIT (c))
1809 if (c == '1')
1811 /* Pushing to a new file. */
1812 struct file_stack *p
1813 = (struct file_stack *) xmalloc (sizeof (struct file_stack));
1814 input_file_stack->line = old_lineno;
1815 p->next = input_file_stack;
1816 p->name = input_filename;
1817 input_file_stack = p;
1818 input_file_stack_tick++;
1819 #ifdef DWARF_DEBUGGING_INFO
1820 if (debug_info_level == DINFO_LEVEL_VERBOSE
1821 && write_symbols == DWARF_DEBUG)
1822 dwarfout_start_new_source_file (input_filename);
1823 #endif /* DWARF_DEBUGGING_INFO */
1825 used_up = 1;
1827 else if (c == '2')
1829 /* Popping out of a file. */
1830 if (input_file_stack->next)
1832 struct file_stack *p = input_file_stack;
1833 input_file_stack = p->next;
1834 free (p);
1835 input_file_stack_tick++;
1836 #ifdef DWARF_DEBUGGING_INFO
1837 if (debug_info_level == DINFO_LEVEL_VERBOSE
1838 && write_symbols == DWARF_DEBUG)
1839 dwarfout_resume_previous_source_file (input_file_stack->line);
1840 #endif /* DWARF_DEBUGGING_INFO */
1842 else
1843 error ("#-lines for entering and leaving files don't match");
1845 used_up = 1;
1849 /* If we have handled a `1' or a `2',
1850 see if there is another number to read. */
1851 if (used_up)
1853 /* Is this the last nonwhite stuff on the line? */
1854 c = getlc (finput);
1855 while (c == ' ' || c == '\t')
1856 c = getlc (finput);
1857 if (c == '\n')
1858 return c;
1859 used_up = 0;
1862 /* `3' after file name means this is a system header file. */
1864 if (c == '3')
1865 in_system_header = 1;
1867 else
1868 error ("invalid #-line");
1870 /* skip the rest of this line. */
1871 skipline:
1872 while (c != '\n' && c != EOF)
1873 c = getc (finput);
1874 return c;
1878 tree
1879 get_chill_filename ()
1881 return (build_chill_string (
1882 strlen (input_filename) + 1, /* +1 to get a zero terminated string */
1883 input_filename));
1886 tree
1887 get_chill_linenumber ()
1889 return build_int_2 ((HOST_WIDE_INT)lineno, 0);
1893 /* Assuming '/' and '*' have been read, skip until we've
1894 read the terminating '*' and '/'. */
1896 static void
1897 skip_c_comment ()
1899 int c = input();
1900 int start_line = lineno;
1902 inside_c_comment++;
1903 for (;;)
1904 if (c == EOF)
1906 error_with_file_and_line (input_filename, start_line,
1907 "unterminated comment");
1908 break;
1910 else if (c != '*')
1911 c = input();
1912 else if ((c = input ()) == '/')
1913 break;
1914 inside_c_comment--;
1918 /* Assuming "--" has been read, skip until '\n'. */
1920 static void
1921 skip_line_comment ()
1923 for (;;)
1925 int c = input ();
1927 if (c == EOF)
1928 return;
1929 if (c == '\n')
1930 break;
1932 unput ('\n');
1936 static int
1937 skip_whitespace ()
1939 for (;;)
1941 int c = input ();
1943 if (c == EOF)
1944 return c;
1945 if (c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == '\v')
1946 continue;
1947 if (c == '/')
1949 c = input ();
1950 if (c == '*')
1952 skip_c_comment ();
1953 continue;
1955 else
1957 unput (c);
1958 return '/';
1961 if (c == '-')
1963 c = input ();
1964 if (c == '-')
1966 skip_line_comment ();
1967 continue;
1969 else
1971 unput (c);
1972 return '-';
1975 return c;
1980 * avoid recursive calls to yylex to parse the ' = digits' or
1981 * ' = SYNvalue' which are supposed to follow certain compiler
1982 * directives. Read the input stream, and return the value parsed.
1984 /* FIXME: overflow check in here */
1985 /* FIXME: check for EOF around here */
1986 static tree
1987 equal_number ()
1989 int c, result;
1990 char *tokenbuf;
1991 char *cursor;
1992 tree retval = integer_zero_node;
1994 c = skip_whitespace();
1995 if ((char)c != '=')
1997 if (pass == 2)
1998 error ("missing `=' in compiler directive");
1999 return integer_zero_node;
2001 c = skip_whitespace();
2003 /* collect token into tokenbuf for later analysis */
2004 while (TRUE)
2006 if (ISSPACE (c) || c == '<')
2007 break;
2008 obstack_1grow (&temporary_obstack, c);
2009 c = input ();
2011 unput (c); /* put uninteresting char back */
2012 obstack_1grow (&temporary_obstack, '\0'); /* terminate token */
2013 tokenbuf = obstack_finish (&temporary_obstack);
2014 maybe_downcase (tokenbuf);
2016 if (*tokenbuf == '-')
2017 /* will fail in the next test */
2018 result = BITSTRING;
2019 else if (maybe_number (tokenbuf))
2021 if (pass == 1)
2022 return integer_zero_node;
2023 push_obstacks_nochange ();
2024 end_temporary_allocation ();
2025 yylval.ttype = convert_integer (tokenbuf);
2026 tokenbuf = 0; /* Was freed by convert_integer. */
2027 result = yylval.ttype ? NUMBER : 0;
2028 pop_obstacks ();
2030 else
2031 result = 0;
2033 if (result == NUMBER)
2035 retval = yylval.ttype;
2037 else if (result == BITSTRING)
2039 if (pass == 1)
2040 error ("invalid value follows `=' in compiler directive");
2041 goto finish;
2043 else /* not a number */
2045 cursor = tokenbuf;
2046 c = *cursor;
2047 if (!ISALPHA (c) && c != '_')
2049 if (pass == 1)
2050 error ("invalid value follows `=' in compiler directive");
2051 goto finish;
2054 for (cursor = &tokenbuf[1]; *cursor != '\0'; cursor++)
2055 if (ISALPHA ((unsigned char) *cursor) || *cursor == '_' ||
2056 ISDIGIT (*cursor))
2057 continue;
2058 else
2060 if (pass == 1)
2061 error ("invalid `%c' character in name", *cursor);
2062 goto finish;
2064 if (pass == 1)
2065 goto finish;
2066 else
2068 tree value = lookup_name (get_identifier (tokenbuf));
2069 if (value == NULL_TREE
2070 || TREE_CODE (value) != CONST_DECL
2071 || TREE_CODE (DECL_INITIAL (value)) != INTEGER_CST)
2073 if (pass == 2)
2074 error ("`%s' not integer constant synonym ",
2075 tokenbuf);
2076 goto finish;
2078 obstack_free (&temporary_obstack, tokenbuf);
2079 tokenbuf = 0;
2080 push_obstacks_nochange ();
2081 end_temporary_allocation ();
2082 retval = convert (chill_taskingcode_type_node, DECL_INITIAL (value));
2083 pop_obstacks ();
2087 /* check the value */
2088 if (TREE_CODE (retval) != INTEGER_CST)
2090 if (pass == 2)
2091 error ("invalid value follows `=' in compiler directive");
2093 else if (TREE_INT_CST_HIGH (retval) != 0 ||
2094 TREE_INT_CST_LOW (retval) > TREE_INT_CST_LOW (TYPE_MAX_VALUE (chill_unsigned_type_node)))
2096 if (pass == 2)
2097 error ("value out of range in compiler directive");
2099 finish:
2100 if (tokenbuf)
2101 obstack_free (&temporary_obstack, tokenbuf);
2102 return retval;
2106 * add a possible grant-file path to the list
2108 void
2109 register_seize_path (path)
2110 const char *path;
2112 int pathlen = strlen (path);
2113 char *new_path = (char *)xmalloc (pathlen + 1);
2114 STRING_LIST *pl = (STRING_LIST *)xmalloc (sizeof (STRING_LIST));
2116 /* strip off trailing slash if any */
2117 if (path[pathlen - 1] == '/')
2118 pathlen--;
2120 memcpy (new_path, path, pathlen);
2121 pl->str = new_path;
2122 pl->next = seize_path_list;
2123 seize_path_list = pl;
2127 /* Used by decode_decl to indicate that a <> use_seize_file NAME <>
2128 directive has been written to the grantfile. */
2130 void
2131 mark_use_seizefile_written (name)
2132 tree name;
2134 tree node;
2136 for (node = files_to_seize; node != NULL_TREE; node = TREE_CHAIN (node))
2137 if (TREE_VALUE (node) == name)
2139 TREE_PURPOSE (node) = integer_one_node;
2140 break;
2145 static int
2146 yywrap ()
2148 extern char *chill_real_input_filename;
2150 close_input_file (input_filename);
2152 use_seizefile_name = NULL_TREE;
2154 if (next_file_to_seize && !grant_only_flag)
2156 FILE *grt_in = NULL;
2157 const char *seizefile_name_chars
2158 = IDENTIFIER_POINTER (TREE_VALUE (next_file_to_seize));
2160 /* find a seize file, open it. If it's not at the path the
2161 * user gave us, and that path contains no slashes, look on
2162 * the seize_file paths, specified by the '-I' options.
2164 grt_in = fopen (seizefile_name_chars, "r");
2165 if (grt_in == NULL
2166 && strchr (seizefile_name_chars, '/') == NULL)
2168 STRING_LIST *plp;
2169 char *path;
2171 for (plp = seize_path_list; plp != NULL; plp = plp->next)
2173 path = (char *)xmalloc (strlen (seizefile_name_chars)
2174 + strlen (plp->str) + 2);
2176 sprintf (path, "%s/%s", plp->str, seizefile_name_chars);
2177 grt_in = fopen (path, "r");
2178 if (grt_in == NULL)
2179 free (path);
2180 else
2182 seizefile_name_chars = path;
2183 break;
2188 if (grt_in == NULL)
2189 fatal_io_error ("can't open %s", seizefile_name_chars);
2191 finput = grt_in;
2192 input_filename = seizefile_name_chars;
2194 lineno = 0;
2195 current_seizefile_name = TREE_VALUE (next_file_to_seize);
2197 next_file_to_seize = TREE_CHAIN (next_file_to_seize);
2199 saw_eof = 0;
2200 return 0;
2203 if (pass == 1)
2205 next_file_to_seize = files_to_seize;
2206 current_seizefile_name = NULL_TREE;
2208 if (strcmp (main_input_filename, "stdin"))
2209 finput = fopen (chill_real_input_filename, "r");
2210 else
2211 finput = stdin;
2212 if (finput == NULL)
2214 error ("can't reopen %s", chill_real_input_filename);
2215 return 1;
2217 input_filename = main_input_filename;
2218 ch_lex_init ();
2219 lineno = 0;
2220 /* Read a line directive if there is one. */
2221 ungetc (check_newline (), finput);
2222 starting_pass_2 = 1;
2223 saw_eof = 0;
2224 if (module_number == 0)
2225 warning ("no modules seen");
2226 return 0;
2228 return 1;