]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/fortran/scanner.c
tl_editting.f90: gcc-cvs signalled missing LF at EOF.
[thirdparty/gcc.git] / gcc / fortran / scanner.c
CommitLineData
6de9cd9a 1/* Character scanner.
ec378180
KH
2 Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005
3 Free Software Foundation, Inc.
6de9cd9a
DN
4 Contributed by Andy Vaught
5
9fc4d79b 6This file is part of GCC.
6de9cd9a 7
9fc4d79b
TS
8GCC is free software; you can redistribute it and/or modify it under
9the terms of the GNU General Public License as published by the Free
10Software Foundation; either version 2, or (at your option) any later
11version.
6de9cd9a 12
9fc4d79b
TS
13GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16for more details.
6de9cd9a
DN
17
18You should have received a copy of the GNU General Public License
9fc4d79b 19along with GCC; see the file COPYING. If not, write to the Free
ab57747b
KC
20Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
2102110-1301, USA. */
6de9cd9a
DN
22
23/* Set of subroutines to (ultimately) return the next character to the
24 various matching subroutines. This file's job is to read files and
25 build up lines that are parsed by the parser. This means that we
26 handle continuation lines and "include" lines.
27
28 The first thing the scanner does is to load an entire file into
29 memory. We load the entire file into memory for a couple reasons.
30 The first is that we want to be able to deal with nonseekable input
31 (pipes, stdin) and there is a lot of backing up involved during
32 parsing.
33
34 The second is that we want to be able to print the locus of errors,
35 and an error on line 999999 could conflict with something on line
36 one. Given nonseekable input, we've got to store the whole thing.
37
38 One thing that helps are the column truncation limits that give us
39 an upper bound on the size of individual lines. We don't store the
40 truncated stuff.
41
42 From the scanner's viewpoint, the higher level subroutines ask for
43 new characters and do a lot of jumping backwards. */
44
45#include "config.h"
d22e4895 46#include "system.h"
6de9cd9a
DN
47#include "gfortran.h"
48
49/* Structure for holding module and include file search path. */
50typedef struct gfc_directorylist
51{
52 char *path;
53 struct gfc_directorylist *next;
54}
55gfc_directorylist;
56
57/* List of include file search directories. */
58static gfc_directorylist *include_dirs;
59
d4fa05b9 60static gfc_file *file_head, *current_file;
6de9cd9a 61
d4fa05b9 62static int continue_flag, end_flag;
6de9cd9a 63
d4fa05b9
TS
64gfc_source_form gfc_current_form;
65static gfc_linebuf *line_head, *line_tail;
66
63645982 67locus gfc_current_locus;
d4fa05b9
TS
68char *gfc_source_file;
69
6de9cd9a
DN
70
71/* Main scanner initialization. */
72
73void
74gfc_scanner_init_1 (void)
75{
d4fa05b9
TS
76 file_head = NULL;
77 line_head = NULL;
78 line_tail = NULL;
6de9cd9a 79
6de9cd9a
DN
80 end_flag = 0;
81}
82
83
84/* Main scanner destructor. */
85
86void
87gfc_scanner_done_1 (void)
88{
d4fa05b9
TS
89 gfc_linebuf *lb;
90 gfc_file *f;
6de9cd9a 91
d4fa05b9 92 while(line_head != NULL)
6de9cd9a 93 {
d4fa05b9
TS
94 lb = line_head->next;
95 gfc_free(line_head);
96 line_head = lb;
6de9cd9a 97 }
d4fa05b9
TS
98
99 while(file_head != NULL)
6de9cd9a 100 {
d4fa05b9
TS
101 f = file_head->next;
102 gfc_free(file_head->filename);
103 gfc_free(file_head);
104 file_head = f;
6de9cd9a 105 }
d4fa05b9 106
6de9cd9a
DN
107}
108
109
110/* Adds path to the list pointed to by list. */
111
112void
113gfc_add_include_path (const char *path)
114{
115 gfc_directorylist *dir;
116 const char *p;
117
118 p = path;
119 while (*p == ' ' || *p == '\t') /* someone might do 'gfortran "-I include"' */
120 if (*p++ == '\0')
121 return;
122
123 dir = include_dirs;
124 if (!dir)
125 {
126 dir = include_dirs = gfc_getmem (sizeof (gfc_directorylist));
127 }
128 else
129 {
130 while (dir->next)
131 dir = dir->next;
132
133 dir->next = gfc_getmem (sizeof (gfc_directorylist));
134 dir = dir->next;
135 }
136
137 dir->next = NULL;
138 dir->path = gfc_getmem (strlen (p) + 2);
139 strcpy (dir->path, p);
140 strcat (dir->path, "/"); /* make '/' last character */
141}
142
143
144/* Release resources allocated for options. */
145
146void
147gfc_release_include_path (void)
148{
149 gfc_directorylist *p;
150
151 gfc_free (gfc_option.module_dir);
152 while (include_dirs != NULL)
153 {
154 p = include_dirs;
155 include_dirs = include_dirs->next;
156 gfc_free (p->path);
157 gfc_free (p);
158 }
159}
160
6de9cd9a
DN
161/* Opens file for reading, searching through the include directories
162 given if necessary. */
163
164FILE *
165gfc_open_included_file (const char *name)
166{
167 char fullname[PATH_MAX];
168 gfc_directorylist *p;
169 FILE *f;
170
171 f = gfc_open_file (name);
172 if (f != NULL)
173 return f;
174
175 for (p = include_dirs; p; p = p->next)
176 {
177 if (strlen (p->path) + strlen (name) + 1 > PATH_MAX)
178 continue;
179
180 strcpy (fullname, p->path);
181 strcat (fullname, name);
182
183 f = gfc_open_file (fullname);
184 if (f != NULL)
185 return f;
186 }
187
188 return NULL;
189}
190
6de9cd9a
DN
191/* Test to see if we're at the end of the main source file. */
192
193int
194gfc_at_end (void)
195{
196
197 return end_flag;
198}
199
200
201/* Test to see if we're at the end of the current file. */
202
203int
204gfc_at_eof (void)
205{
206
207 if (gfc_at_end ())
208 return 1;
209
d4fa05b9 210 if (line_head == NULL)
6de9cd9a
DN
211 return 1; /* Null file */
212
63645982 213 if (gfc_current_locus.lb == NULL)
6de9cd9a
DN
214 return 1;
215
216 return 0;
217}
218
219
220/* Test to see if we're at the beginning of a new line. */
221
222int
223gfc_at_bol (void)
224{
6de9cd9a
DN
225 if (gfc_at_eof ())
226 return 1;
227
63645982 228 return (gfc_current_locus.nextc == gfc_current_locus.lb->line);
6de9cd9a
DN
229}
230
231
232/* Test to see if we're at the end of a line. */
233
234int
235gfc_at_eol (void)
236{
237
238 if (gfc_at_eof ())
239 return 1;
240
63645982 241 return (*gfc_current_locus.nextc == '\0');
6de9cd9a
DN
242}
243
244
245/* Advance the current line pointer to the next line. */
246
247void
248gfc_advance_line (void)
249{
6de9cd9a
DN
250 if (gfc_at_end ())
251 return;
252
63645982 253 if (gfc_current_locus.lb == NULL)
6de9cd9a 254 {
d4fa05b9
TS
255 end_flag = 1;
256 return;
257 }
6de9cd9a 258
63645982 259 gfc_current_locus.lb = gfc_current_locus.lb->next;
6de9cd9a 260
63645982
TS
261 if (gfc_current_locus.lb != NULL)
262 gfc_current_locus.nextc = gfc_current_locus.lb->line;
d4fa05b9
TS
263 else
264 {
63645982 265 gfc_current_locus.nextc = NULL;
d4fa05b9
TS
266 end_flag = 1;
267 }
6de9cd9a
DN
268}
269
270
271/* Get the next character from the input, advancing gfc_current_file's
272 locus. When we hit the end of the line or the end of the file, we
273 start returning a '\n' in order to complete the current statement.
274 No Fortran line conventions are implemented here.
275
276 Requiring explicit advances to the next line prevents the parse
277 pointer from being on the wrong line if the current statement ends
278 prematurely. */
279
280static int
281next_char (void)
282{
6de9cd9a 283 int c;
d4fa05b9 284
63645982 285 if (gfc_current_locus.nextc == NULL)
6de9cd9a
DN
286 return '\n';
287
63645982 288 c = *gfc_current_locus.nextc++;
6de9cd9a
DN
289 if (c == '\0')
290 {
63645982 291 gfc_current_locus.nextc--; /* Remain on this line. */
6de9cd9a
DN
292 c = '\n';
293 }
294
295 return c;
296}
297
6de9cd9a
DN
298/* Skip a comment. When we come here the parse pointer is positioned
299 immediately after the comment character. If we ever implement
300 compiler directives withing comments, here is where we parse the
301 directive. */
302
303static void
304skip_comment_line (void)
305{
306 char c;
307
308 do
309 {
310 c = next_char ();
311 }
312 while (c != '\n');
313
314 gfc_advance_line ();
315}
316
317
318/* Comment lines are null lines, lines containing only blanks or lines
319 on which the first nonblank line is a '!'. */
320
321static void
322skip_free_comments (void)
323{
324 locus start;
325 char c;
326
327 for (;;)
328 {
63645982 329 start = gfc_current_locus;
6de9cd9a
DN
330 if (gfc_at_eof ())
331 break;
332
333 do
334 {
335 c = next_char ();
336 }
337 while (gfc_is_whitespace (c));
338
339 if (c == '\n')
340 {
341 gfc_advance_line ();
342 continue;
343 }
344
345 if (c == '!')
346 {
347 skip_comment_line ();
348 continue;
349 }
350
351 break;
352 }
353
63645982 354 gfc_current_locus = start;
6de9cd9a
DN
355}
356
357
358/* Skip comment lines in fixed source mode. We have the same rules as
359 in skip_free_comment(), except that we can have a 'c', 'C' or '*'
e2435498 360 in column 1, and a '!' cannot be in column 6. */
6de9cd9a
DN
361
362static void
363skip_fixed_comments (void)
364{
365 locus start;
366 int col;
367 char c;
368
369 for (;;)
370 {
63645982 371 start = gfc_current_locus;
6de9cd9a
DN
372 if (gfc_at_eof ())
373 break;
374
375 c = next_char ();
376 if (c == '\n')
377 {
378 gfc_advance_line ();
379 continue;
380 }
381
382 if (c == '!' || c == 'c' || c == 'C' || c == '*')
383 {
384 skip_comment_line ();
385 continue;
386 }
387
388 col = 1;
389 do
390 {
391 c = next_char ();
392 col++;
393 }
394 while (gfc_is_whitespace (c));
395
396 if (c == '\n')
397 {
398 gfc_advance_line ();
399 continue;
400 }
401
402 if (col != 6 && c == '!')
403 {
404 skip_comment_line ();
405 continue;
406 }
407
408 break;
409 }
410
63645982 411 gfc_current_locus = start;
6de9cd9a
DN
412}
413
414
415/* Skips the current line if it is a comment. Assumes that we are at
416 the start of the current line. */
417
418void
419gfc_skip_comments (void)
420{
421
d4fa05b9 422 if (!gfc_at_bol () || gfc_current_form == FORM_FREE)
6de9cd9a
DN
423 skip_free_comments ();
424 else
425 skip_fixed_comments ();
426}
427
428
429/* Get the next character from the input, taking continuation lines
430 and end-of-line comments into account. This implies that comment
431 lines between continued lines must be eaten here. For higher-level
432 subroutines, this flattens continued lines into a single logical
433 line. The in_string flag denotes whether we're inside a character
434 context or not. */
435
436int
437gfc_next_char_literal (int in_string)
438{
439 locus old_loc;
440 int i, c;
441
442 continue_flag = 0;
443
444restart:
445 c = next_char ();
446 if (gfc_at_end ())
447 return c;
448
d4fa05b9 449 if (gfc_current_form == FORM_FREE)
6de9cd9a
DN
450 {
451
452 if (!in_string && c == '!')
453 {
454 /* This line can't be continued */
455 do
456 {
457 c = next_char ();
458 }
459 while (c != '\n');
460
a34938be
RG
461 /* Avoid truncation warnings for comment ending lines. */
462 gfc_current_locus.lb->truncated = 0;
463
6de9cd9a
DN
464 goto done;
465 }
466
467 if (c != '&')
468 goto done;
469
470 /* If the next nonblank character is a ! or \n, we've got a
f7b529fa 471 continuation line. */
63645982 472 old_loc = gfc_current_locus;
6de9cd9a
DN
473
474 c = next_char ();
475 while (gfc_is_whitespace (c))
476 c = next_char ();
477
478 /* Character constants to be continued cannot have commentary
479 after the '&'. */
480
481 if (in_string && c != '\n')
482 {
63645982 483 gfc_current_locus = old_loc;
6de9cd9a
DN
484 c = '&';
485 goto done;
486 }
487
488 if (c != '!' && c != '\n')
489 {
63645982 490 gfc_current_locus = old_loc;
6de9cd9a
DN
491 c = '&';
492 goto done;
493 }
494
495 continue_flag = 1;
496 if (c == '!')
497 skip_comment_line ();
498 else
499 gfc_advance_line ();
500
501 /* We've got a continuation line and need to find where it continues.
502 First eat any comment lines. */
503 gfc_skip_comments ();
504
505 /* Now that we have a non-comment line, probe ahead for the
506 first non-whitespace character. If it is another '&', then
507 reading starts at the next character, otherwise we must back
508 up to where the whitespace started and resume from there. */
509
63645982 510 old_loc = gfc_current_locus;
6de9cd9a
DN
511
512 c = next_char ();
513 while (gfc_is_whitespace (c))
514 c = next_char ();
515
516 if (c != '&')
63645982 517 gfc_current_locus = old_loc;
6de9cd9a
DN
518
519 }
520 else
521 {
522 /* Fixed form continuation. */
523 if (!in_string && c == '!')
524 {
525 /* Skip comment at end of line. */
526 do
527 {
528 c = next_char ();
529 }
530 while (c != '\n');
a34938be
RG
531
532 /* Avoid truncation warnings for comment ending lines. */
533 gfc_current_locus.lb->truncated = 0;
6de9cd9a
DN
534 }
535
536 if (c != '\n')
537 goto done;
538
539 continue_flag = 1;
63645982 540 old_loc = gfc_current_locus;
6de9cd9a
DN
541
542 gfc_advance_line ();
543 gfc_skip_comments ();
544
545 /* See if this line is a continuation line. */
546 for (i = 0; i < 5; i++)
547 {
548 c = next_char ();
549 if (c != ' ')
550 goto not_continuation;
551 }
552
553 c = next_char ();
554 if (c == '0' || c == ' ')
555 goto not_continuation;
556 }
557
558 /* Ready to read first character of continuation line, which might
559 be another continuation line! */
560 goto restart;
561
562not_continuation:
563 c = '\n';
63645982 564 gfc_current_locus = old_loc;
6de9cd9a
DN
565
566done:
567 continue_flag = 0;
568 return c;
569}
570
571
572/* Get the next character of input, folded to lowercase. In fixed
573 form mode, we also ignore spaces. When matcher subroutines are
574 parsing character literals, they have to call
575 gfc_next_char_literal(). */
576
577int
578gfc_next_char (void)
579{
580 int c;
581
582 do
583 {
584 c = gfc_next_char_literal (0);
585 }
d4fa05b9 586 while (gfc_current_form == FORM_FIXED && gfc_is_whitespace (c));
6de9cd9a
DN
587
588 return TOLOWER (c);
589}
590
591
592int
593gfc_peek_char (void)
594{
595 locus old_loc;
596 int c;
597
63645982 598 old_loc = gfc_current_locus;
6de9cd9a 599 c = gfc_next_char ();
63645982 600 gfc_current_locus = old_loc;
6de9cd9a
DN
601
602 return c;
603}
604
605
606/* Recover from an error. We try to get past the current statement
607 and get lined up for the next. The next statement follows a '\n'
608 or a ';'. We also assume that we are not within a character
609 constant, and deal with finding a '\'' or '"'. */
610
611void
612gfc_error_recovery (void)
613{
614 char c, delim;
615
616 if (gfc_at_eof ())
617 return;
618
619 for (;;)
620 {
621 c = gfc_next_char ();
622 if (c == '\n' || c == ';')
623 break;
624
625 if (c != '\'' && c != '"')
626 {
627 if (gfc_at_eof ())
628 break;
629 continue;
630 }
631 delim = c;
632
633 for (;;)
634 {
635 c = next_char ();
636
637 if (c == delim)
638 break;
639 if (c == '\n')
ba1defa5 640 return;
6de9cd9a
DN
641 if (c == '\\')
642 {
643 c = next_char ();
644 if (c == '\n')
ba1defa5 645 return;
6de9cd9a
DN
646 }
647 }
648 if (gfc_at_eof ())
649 break;
650 }
6de9cd9a
DN
651}
652
653
654/* Read ahead until the next character to be read is not whitespace. */
655
656void
657gfc_gobble_whitespace (void)
658{
659 locus old_loc;
660 int c;
661
662 do
663 {
63645982 664 old_loc = gfc_current_locus;
6de9cd9a
DN
665 c = gfc_next_char_literal (0);
666 }
667 while (gfc_is_whitespace (c));
668
63645982 669 gfc_current_locus = old_loc;
6de9cd9a
DN
670}
671
672
f56c5d5d
TS
673/* Load a single line into pbuf.
674
675 If pbuf points to a NULL pointer, it is allocated.
676 We truncate lines that are too long, unless we're dealing with
677 preprocessor lines or if the option -ffixed-line-length-none is set,
678 in which case we reallocate the buffer to fit the entire line, if
679 need be.
680 In fixed mode, we expand a tab that occurs within the statement
681 label region to expand to spaces that leave the next character in
ba1defa5
RG
682 the source region.
683 load_line returns wether the line was truncated. */
6de9cd9a 684
ba1defa5 685static int
d1e3d6ae 686load_line (FILE * input, char **pbuf, int *pbuflen)
6de9cd9a 687{
d1e3d6ae 688 int c, maxlen, i, preprocessor_flag, buflen = *pbuflen;
ba1defa5 689 int trunc_flag = 0;
f56c5d5d
TS
690 char *buffer;
691
1f2959f0 692 /* Determine the maximum allowed line length. */
f56c5d5d
TS
693 if (gfc_current_form == FORM_FREE)
694 maxlen = GFC_MAX_LINE;
695 else
696 maxlen = gfc_option.fixed_line_length;
697
698 if (*pbuf == NULL)
699 {
700 /* Allocate the line buffer, storing its length into buflen. */
701 if (maxlen > 0)
702 buflen = maxlen;
703 else
704 buflen = GFC_MAX_LINE;
6de9cd9a 705
f56c5d5d
TS
706 *pbuf = gfc_getmem (buflen + 1);
707 }
6de9cd9a
DN
708
709 i = 0;
f56c5d5d 710 buffer = *pbuf;
6de9cd9a 711
fa841200
TS
712 preprocessor_flag = 0;
713 c = fgetc (input);
714 if (c == '#')
f56c5d5d
TS
715 /* In order to not truncate preprocessor lines, we have to
716 remember that this is one. */
fa841200
TS
717 preprocessor_flag = 1;
718 ungetc (c, input);
719
6de9cd9a
DN
720 for (;;)
721 {
722 c = fgetc (input);
723
724 if (c == EOF)
725 break;
726 if (c == '\n')
727 break;
728
729 if (c == '\r')
d4fa05b9 730 continue; /* Gobble characters. */
6de9cd9a
DN
731 if (c == '\0')
732 continue;
733
d4fa05b9
TS
734 if (c == '\032')
735 {
736 /* Ctrl-Z ends the file. */
737 while (fgetc (input) != EOF);
738 break;
739 }
740
741 if (gfc_current_form == FORM_FIXED && c == '\t' && i <= 6)
1f2959f0 742 { /* Tab expansion. */
6de9cd9a
DN
743 while (i <= 6)
744 {
745 *buffer++ = ' ';
746 i++;
747 }
748
749 continue;
750 }
751
752 *buffer++ = c;
753 i++;
754
d1e3d6ae 755 if (maxlen == 0 || preprocessor_flag)
f56c5d5d 756 {
d1e3d6ae
JJ
757 if (i >= buflen)
758 {
759 /* Reallocate line buffer to double size to hold the
760 overlong line. */
761 buflen = buflen * 2;
762 *pbuf = xrealloc (*pbuf, buflen + 1);
763 buffer = (*pbuf)+i;
764 }
f56c5d5d 765 }
d1e3d6ae 766 else if (i >= maxlen)
f56c5d5d
TS
767 {
768 /* Truncate the rest of the line. */
6de9cd9a
DN
769 for (;;)
770 {
771 c = fgetc (input);
772 if (c == '\n' || c == EOF)
773 break;
a34938be
RG
774
775 trunc_flag = 1;
6de9cd9a
DN
776 }
777
778 ungetc ('\n', input);
779 }
780 }
781
f56c5d5d
TS
782 /* Pad lines to the selected line length in fixed form. */
783 if (gfc_current_form == FORM_FIXED
784 && gfc_option.fixed_line_length > 0
785 && !preprocessor_flag
786 && c != EOF)
d1e3d6ae 787 while (i++ < gfc_option.fixed_line_length)
f56c5d5d
TS
788 *buffer++ = ' ';
789
6de9cd9a 790 *buffer = '\0';
d1e3d6ae 791 *pbuflen = buflen;
ba1defa5
RG
792
793 return trunc_flag;
6de9cd9a
DN
794}
795
796
d4fa05b9
TS
797/* Get a gfc_file structure, initialize it and add it to
798 the file stack. */
799
800static gfc_file *
4d28e183 801get_file (char *name, enum lc_reason reason ATTRIBUTE_UNUSED)
d4fa05b9
TS
802{
803 gfc_file *f;
804
805 f = gfc_getmem (sizeof (gfc_file));
806
807 f->filename = gfc_getmem (strlen (name) + 1);
808 strcpy (f->filename, name);
809
810 f->next = file_head;
811 file_head = f;
812
813 f->included_by = current_file;
814 if (current_file != NULL)
815 f->inclusion_line = current_file->line;
816
c8cc8542
PB
817#ifdef USE_MAPPED_LOCATION
818 linemap_add (&line_table, reason, false, f->filename, 1);
819#endif
820
d4fa05b9
TS
821 return f;
822}
823
824/* Deal with a line from the C preprocessor. The
825 initial octothorp has already been seen. */
6de9cd9a
DN
826
827static void
d4fa05b9 828preprocessor_line (char *c)
6de9cd9a 829{
d4fa05b9
TS
830 bool flag[5];
831 int i, line;
832 char *filename;
833 gfc_file *f;
d7d528c8 834 int escaped;
6de9cd9a 835
d4fa05b9
TS
836 c++;
837 while (*c == ' ' || *c == '\t')
838 c++;
6de9cd9a 839
d4fa05b9 840 if (*c < '0' || *c > '9')
fa841200 841 goto bad_cpp_line;
6de9cd9a 842
d4fa05b9
TS
843 line = atoi (c);
844
4c3a6ca1 845 c = strchr (c, ' ');
fa841200 846 if (c == NULL)
4c3a6ca1
JJ
847 {
848 /* No file name given. Set new line number. */
849 current_file->line = line;
850 return;
851 }
d7d528c8
ES
852
853 /* Skip spaces. */
854 while (*c == ' ' || *c == '\t')
855 c++;
856
857 /* Skip quote. */
858 if (*c != '"')
fa841200 859 goto bad_cpp_line;
d7d528c8
ES
860 ++c;
861
d4fa05b9
TS
862 filename = c;
863
d7d528c8
ES
864 /* Make filename end at quote. */
865 escaped = false;
866 while (*c && ! (! escaped && *c == '"'))
867 {
868 if (escaped)
869 escaped = false;
870 else
871 escaped = *c == '\\';
872 ++c;
873 }
874
875 if (! *c)
fa841200
TS
876 /* Preprocessor line has no closing quote. */
877 goto bad_cpp_line;
d7d528c8 878
d4fa05b9
TS
879 *c++ = '\0';
880
d7d528c8
ES
881
882
d4fa05b9 883 /* Get flags. */
4c3a6ca1 884
d4fa05b9 885 flag[1] = flag[2] = flag[3] = flag[4] = flag[5] = false;
6de9cd9a 886
6de9cd9a
DN
887 for (;;)
888 {
d4fa05b9
TS
889 c = strchr (c, ' ');
890 if (c == NULL)
891 break;
6de9cd9a 892
d4fa05b9
TS
893 c++;
894 i = atoi (c);
6de9cd9a 895
d4fa05b9
TS
896 if (1 <= i && i <= 4)
897 flag[i] = true;
898 }
4c3a6ca1 899
d4fa05b9 900 /* Interpret flags. */
4c3a6ca1 901
d4fa05b9
TS
902 if (flag[1] || flag[3]) /* Starting new file. */
903 {
c8cc8542 904 f = get_file (filename, LC_RENAME);
d4fa05b9
TS
905 f->up = current_file;
906 current_file = f;
907 }
4c3a6ca1 908
d4fa05b9
TS
909 if (flag[2]) /* Ending current file. */
910 {
4c3a6ca1
JJ
911 if (strcmp (current_file->filename, filename) != 0)
912 {
913 gfc_warning_now ("%s:%d: file %s left but not entered",
914 current_file->filename, current_file->line,
915 filename);
916 return;
917 }
918 if (current_file->up)
919 current_file = current_file->up;
d4fa05b9 920 }
4c3a6ca1 921
d4fa05b9
TS
922 /* The name of the file can be a temporary file produced by
923 cpp. Replace the name if it is different. */
4c3a6ca1 924
d4fa05b9
TS
925 if (strcmp (current_file->filename, filename) != 0)
926 {
927 gfc_free (current_file->filename);
928 current_file->filename = gfc_getmem (strlen (filename) + 1);
929 strcpy (current_file->filename, filename);
930 }
fa841200 931
4c3a6ca1
JJ
932 /* Set new line number. */
933 current_file->line = line;
fa841200
TS
934 return;
935
936 bad_cpp_line:
4c3a6ca1 937 gfc_warning_now ("%s:%d: Illegal preprocessor directive",
fa841200
TS
938 current_file->filename, current_file->line);
939 current_file->line++;
d4fa05b9
TS
940}
941
942
943static try load_file (char *, bool);
944
945/* include_line()-- Checks a line buffer to see if it is an include
946 line. If so, we call load_file() recursively to load the included
947 file. We never return a syntax error because a statement like
948 "include = 5" is perfectly legal. We return false if no include was
949 processed or true if we matched an include. */
950
951static bool
952include_line (char *line)
953{
954 char quote, *c, *begin, *stop;
955
956 c = line;
957 while (*c == ' ' || *c == '\t')
958 c++;
959
960 if (strncasecmp (c, "include", 7))
961 return false;
962
963 c += 7;
964 while (*c == ' ' || *c == '\t')
965 c++;
966
967 /* Find filename between quotes. */
968
969 quote = *c++;
970 if (quote != '"' && quote != '\'')
971 return false;
972
973 begin = c;
974
975 while (*c != quote && *c != '\0')
976 c++;
977
978 if (*c == '\0')
979 return false;
980
981 stop = c++;
982
983 while (*c == ' ' || *c == '\t')
984 c++;
985
986 if (*c != '\0' && *c != '!')
987 return false;
988
f7b529fa 989 /* We have an include line at this point. */
d4fa05b9
TS
990
991 *stop = '\0'; /* It's ok to trash the buffer, as this line won't be
992 read by anything else. */
993
994 load_file (begin, false);
995 return true;
996}
997
998/* Load a file into memory by calling load_line until the file ends. */
999
1000static try
1001load_file (char *filename, bool initial)
1002{
f56c5d5d 1003 char *line;
d4fa05b9
TS
1004 gfc_linebuf *b;
1005 gfc_file *f;
1006 FILE *input;
d1e3d6ae 1007 int len, line_len;
d4fa05b9
TS
1008
1009 for (f = current_file; f; f = f->up)
1010 if (strcmp (filename, f->filename) == 0)
1011 {
1012 gfc_error_now ("File '%s' is being included recursively", filename);
1013 return FAILURE;
1014 }
1015
1016 if (initial)
1017 {
1018 input = gfc_open_file (filename);
1019 if (input == NULL)
1020 {
1021 gfc_error_now ("Can't open file '%s'", filename);
1022 return FAILURE;
1023 }
1024 }
1025 else
1026 {
1027 input = gfc_open_included_file (filename);
1028 if (input == NULL)
1029 {
1030 gfc_error_now ("Can't open included file '%s'", filename);
1031 return FAILURE;
1032 }
1033 }
1034
1035 /* Load the file. */
1036
c8cc8542 1037 f = get_file (filename, initial ? LC_RENAME : LC_ENTER);
d4fa05b9
TS
1038 f->up = current_file;
1039 current_file = f;
1040 current_file->line = 1;
f56c5d5d 1041 line = NULL;
d1e3d6ae 1042 line_len = 0;
d4fa05b9
TS
1043
1044 for (;;)
1045 {
d1e3d6ae 1046 int trunc = load_line (input, &line, &line_len);
d4fa05b9
TS
1047
1048 len = strlen (line);
6de9cd9a
DN
1049 if (feof (input) && len == 0)
1050 break;
1051
d4fa05b9
TS
1052 /* There are three things this line can be: a line of Fortran
1053 source, an include line or a C preprocessor directive. */
6de9cd9a 1054
d4fa05b9
TS
1055 if (line[0] == '#')
1056 {
1057 preprocessor_line (line);
1058 continue;
1059 }
6de9cd9a 1060
d4fa05b9
TS
1061 if (include_line (line))
1062 {
1063 current_file->line++;
1064 continue;
6de9cd9a
DN
1065 }
1066
d4fa05b9
TS
1067 /* Add line. */
1068
4cdf7223 1069 b = gfc_getmem (gfc_linebuf_header_size + len + 1);
d4fa05b9 1070
c8cc8542
PB
1071#ifdef USE_MAPPED_LOCATION
1072 b->location
1073 = linemap_line_start (&line_table, current_file->line++, 120);
1074#else
d4fa05b9 1075 b->linenum = current_file->line++;
c8cc8542 1076#endif
d4fa05b9 1077 b->file = current_file;
ba1defa5 1078 b->truncated = trunc;
d4fa05b9
TS
1079 strcpy (b->line, line);
1080
1081 if (line_head == NULL)
1082 line_head = b;
1083 else
1084 line_tail->next = b;
1085
1086 line_tail = b;
6de9cd9a 1087 }
d4fa05b9 1088
f56c5d5d
TS
1089 /* Release the line buffer allocated in load_line. */
1090 gfc_free (line);
1091
d4fa05b9
TS
1092 fclose (input);
1093
1094 current_file = current_file->up;
c8cc8542
PB
1095#ifdef USE_MAPPED_LOCATION
1096 linemap_add (&line_table, LC_LEAVE, 0, NULL, 0);
1097#endif
d4fa05b9 1098 return SUCCESS;
6de9cd9a
DN
1099}
1100
1101
1102/* Determine the source form from the filename extension. We assume
f7b529fa 1103 case insensitivity. */
6de9cd9a
DN
1104
1105static gfc_source_form
1106form_from_filename (const char *filename)
1107{
1108
1109 static const struct
1110 {
1111 const char *extension;
1112 gfc_source_form form;
1113 }
1114 exttype[] =
1115 {
1116 {
1117 ".f90", FORM_FREE}
1118 ,
1119 {
1120 ".f95", FORM_FREE}
1121 ,
1122 {
1123 ".f", FORM_FIXED}
1124 ,
1125 {
1126 ".for", FORM_FIXED}
1127 ,
1128 {
1129 "", FORM_UNKNOWN}
1130 }; /* sentinel value */
1131
1132 gfc_source_form f_form;
1133 const char *fileext;
1134 int i;
1135
1136 /* Find end of file name. */
1137 i = 0;
1138 while ((i < PATH_MAX) && (filename[i] != '\0'))
1139 i++;
1140
1141 /* Improperly terminated or too-long filename. */
1142 if (i == PATH_MAX)
1143 return FORM_UNKNOWN;
1144
1145 /* Find last period. */
1146 while (i >= 0 && (filename[i] != '.'))
1147 i--;
1148
1149 /* Did we see a file extension? */
1150 if (i < 0)
1151 return FORM_UNKNOWN; /* Nope */
1152
1153 /* Get file extension and compare it to others. */
1154 fileext = &(filename[i]);
1155
1156 i = -1;
1157 f_form = FORM_UNKNOWN;
1158 do
1159 {
1160 i++;
1161 if (strcasecmp (fileext, exttype[i].extension) == 0)
1162 {
1163 f_form = exttype[i].form;
1164 break;
1165 }
1166 }
1167 while (exttype[i].form != FORM_UNKNOWN);
1168
1169 return f_form;
1170}
1171
1172
d4fa05b9
TS
1173/* Open a new file and start scanning from that file. Returns SUCCESS
1174 if everything went OK, FAILURE otherwise. If form == FORM_UKNOWN
1175 it tries to determine the source form from the filename, defaulting
1176 to free form. */
6de9cd9a
DN
1177
1178try
1179gfc_new_file (const char *filename, gfc_source_form form)
1180{
d4fa05b9 1181 try result;
6de9cd9a 1182
d4fa05b9 1183 if (filename != NULL)
6de9cd9a 1184 {
d4fa05b9
TS
1185 gfc_source_file = gfc_getmem (strlen (filename) + 1);
1186 strcpy (gfc_source_file, filename);
6de9cd9a 1187 }
6de9cd9a 1188 else
d4fa05b9 1189 gfc_source_file = NULL;
6de9cd9a
DN
1190
1191 /* Decide which form the file will be read in as. */
d4fa05b9 1192
6de9cd9a 1193 if (form != FORM_UNKNOWN)
d4fa05b9 1194 gfc_current_form = form;
6de9cd9a
DN
1195 else
1196 {
d4fa05b9 1197 gfc_current_form = form_from_filename (filename);
6de9cd9a 1198
d4fa05b9 1199 if (gfc_current_form == FORM_UNKNOWN)
6de9cd9a 1200 {
d4fa05b9
TS
1201 gfc_current_form = FORM_FREE;
1202 gfc_warning_now ("Reading file '%s' as free form.",
1203 (filename[0] == '\0') ? "<stdin>" : filename);
6de9cd9a
DN
1204 }
1205 }
1206
d4fa05b9 1207 result = load_file (gfc_source_file, true);
6de9cd9a 1208
63645982
TS
1209 gfc_current_locus.lb = line_head;
1210 gfc_current_locus.nextc = (line_head == NULL) ? NULL : line_head->line;
6de9cd9a 1211
d4fa05b9
TS
1212#if 0 /* Debugging aid. */
1213 for (; line_head; line_head = line_head->next)
1214 gfc_status ("%s:%3d %s\n", line_head->file->filename,
c8cc8542
PB
1215#ifdef USE_MAPPED_LOCATION
1216 LOCATION_LINE (line_head->location),
1217#else
1218 line_head->linenum,
1219#endif
1220 line_head->line);
6de9cd9a 1221
d4fa05b9
TS
1222 exit (0);
1223#endif
6de9cd9a 1224
d4fa05b9 1225 return result;
6de9cd9a 1226}