OSDN Git Service

* gfortran.h (GFC_MAX_LINE): Remove constant definition.
[pf3gnuchains/gcc-fork.git] / gcc / fortran / scanner.c
1 /* Character scanner.
2    Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006
3    Free Software Foundation, Inc.
4    Contributed by Andy Vaught
5
6 This file is part of GCC.
7
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2, or (at your option) any later
11 version.
12
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING.  If not, write to the Free
20 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
21 02110-1301, USA.  */
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"
46 #include "system.h"
47 #include "gfortran.h"
48 #include "toplev.h"
49
50 /* Structure for holding module and include file search path.  */
51 typedef struct gfc_directorylist
52 {
53   char *path;
54   struct gfc_directorylist *next;
55 }
56 gfc_directorylist;
57
58 /* List of include file search directories.  */
59 static gfc_directorylist *include_dirs;
60
61 static gfc_file *file_head, *current_file;
62
63 static int continue_flag, end_flag, openmp_flag;
64 static int continue_count, continue_line;
65 static locus openmp_locus;
66
67 gfc_source_form gfc_current_form;
68 static gfc_linebuf *line_head, *line_tail;
69        
70 locus gfc_current_locus;
71 const char *gfc_source_file;
72 static FILE *gfc_src_file;
73 static char *gfc_src_preprocessor_lines[2];
74
75 extern int pedantic;
76
77 /* Main scanner initialization.  */
78
79 void
80 gfc_scanner_init_1 (void)
81 {
82   file_head = NULL;
83   line_head = NULL;
84   line_tail = NULL;
85
86   continue_count = 0;
87   continue_line = 0;
88
89   end_flag = 0;
90 }
91
92
93 /* Main scanner destructor.  */
94
95 void
96 gfc_scanner_done_1 (void)
97 {
98   gfc_linebuf *lb;
99   gfc_file *f;
100
101   while(line_head != NULL) 
102     {
103       lb = line_head->next;
104       gfc_free(line_head);
105       line_head = lb;
106     }
107      
108   while(file_head != NULL) 
109     {
110       f = file_head->next;
111       gfc_free(file_head->filename);
112       gfc_free(file_head);
113       file_head = f;    
114     }
115
116 }
117
118
119 /* Adds path to the list pointed to by list.  */
120
121 void
122 gfc_add_include_path (const char *path)
123 {
124   gfc_directorylist *dir;
125   const char *p;
126
127   p = path;
128   while (*p == ' ' || *p == '\t')  /* someone might do 'gfortran "-I include"' */
129     if (*p++ == '\0')
130       return;
131
132   dir = include_dirs;
133   if (!dir)
134     {
135       dir = include_dirs = gfc_getmem (sizeof (gfc_directorylist));
136     }
137   else
138     {
139       while (dir->next)
140         dir = dir->next;
141
142       dir->next = gfc_getmem (sizeof (gfc_directorylist));
143       dir = dir->next;
144     }
145
146   dir->next = NULL;
147   dir->path = gfc_getmem (strlen (p) + 2);
148   strcpy (dir->path, p);
149   strcat (dir->path, "/");      /* make '/' last character */
150 }
151
152
153 /* Release resources allocated for options.  */
154
155 void
156 gfc_release_include_path (void)
157 {
158   gfc_directorylist *p;
159
160   gfc_free (gfc_option.module_dir);
161   while (include_dirs != NULL)
162     {
163       p = include_dirs;
164       include_dirs = include_dirs->next;
165       gfc_free (p->path);
166       gfc_free (p);
167     }
168 }
169
170 /* Opens file for reading, searching through the include directories
171    given if necessary.  If the include_cwd argument is true, we try
172    to open the file in the current directory first.  */
173
174 FILE *
175 gfc_open_included_file (const char *name, const bool include_cwd)
176 {
177   char *fullname;
178   gfc_directorylist *p;
179   FILE *f;
180
181   if (include_cwd)
182     {
183       f = gfc_open_file (name);
184       if (f != NULL)
185         return f;
186     }
187
188   for (p = include_dirs; p; p = p->next)
189     {
190       fullname = (char *) alloca(strlen (p->path) + strlen (name) + 1);
191       strcpy (fullname, p->path);
192       strcat (fullname, name);
193
194       f = gfc_open_file (fullname);
195       if (f != NULL)
196         return f;
197     }
198
199   return NULL;
200 }
201
202 /* Test to see if we're at the end of the main source file.  */
203
204 int
205 gfc_at_end (void)
206 {
207
208   return end_flag;
209 }
210
211
212 /* Test to see if we're at the end of the current file.  */
213
214 int
215 gfc_at_eof (void)
216 {
217
218   if (gfc_at_end ())
219     return 1;
220
221   if (line_head == NULL)
222     return 1;                   /* Null file */
223
224   if (gfc_current_locus.lb == NULL)
225     return 1;
226
227   return 0;
228 }
229
230
231 /* Test to see if we're at the beginning of a new line.  */
232
233 int
234 gfc_at_bol (void)
235 {
236   if (gfc_at_eof ())
237     return 1;
238
239   return (gfc_current_locus.nextc == gfc_current_locus.lb->line);
240 }
241
242
243 /* Test to see if we're at the end of a line.  */
244
245 int
246 gfc_at_eol (void)
247 {
248
249   if (gfc_at_eof ())
250     return 1;
251
252   return (*gfc_current_locus.nextc == '\0');
253 }
254
255
256 /* Advance the current line pointer to the next line.  */
257
258 void
259 gfc_advance_line (void)
260 {
261   if (gfc_at_end ())
262     return;
263
264   if (gfc_current_locus.lb == NULL) 
265     {
266       end_flag = 1;
267       return;
268     } 
269
270   gfc_current_locus.lb = gfc_current_locus.lb->next;
271
272   if (gfc_current_locus.lb != NULL)         
273     gfc_current_locus.nextc = gfc_current_locus.lb->line;
274   else 
275     {
276       gfc_current_locus.nextc = NULL;
277       end_flag = 1;
278     }       
279 }
280
281
282 /* Get the next character from the input, advancing gfc_current_file's
283    locus.  When we hit the end of the line or the end of the file, we
284    start returning a '\n' in order to complete the current statement.
285    No Fortran line conventions are implemented here.
286
287    Requiring explicit advances to the next line prevents the parse
288    pointer from being on the wrong line if the current statement ends
289    prematurely.  */
290
291 static int
292 next_char (void)
293 {
294   int c;
295   
296   if (gfc_current_locus.nextc == NULL)
297     return '\n';
298
299   c = *gfc_current_locus.nextc++;
300   if (c == '\0')
301     {
302       gfc_current_locus.nextc--; /* Remain on this line.  */
303       c = '\n';
304     }
305
306   return c;
307 }
308
309 /* Skip a comment.  When we come here the parse pointer is positioned
310    immediately after the comment character.  If we ever implement
311    compiler directives withing comments, here is where we parse the
312    directive.  */
313
314 static void
315 skip_comment_line (void)
316 {
317   char c;
318
319   do
320     {
321       c = next_char ();
322     }
323   while (c != '\n');
324
325   gfc_advance_line ();
326 }
327
328
329 /* Comment lines are null lines, lines containing only blanks or lines
330    on which the first nonblank line is a '!'.
331    Return true if !$ openmp conditional compilation sentinel was
332    seen.  */
333
334 static bool
335 skip_free_comments (void)
336 {
337   locus start;
338   char c;
339   int at_bol;
340
341   for (;;)
342     {
343       at_bol = gfc_at_bol ();
344       start = gfc_current_locus;
345       if (gfc_at_eof ())
346         break;
347
348       do
349         c = next_char ();
350       while (gfc_is_whitespace (c));
351
352       if (c == '\n')
353         {
354           gfc_advance_line ();
355           continue;
356         }
357
358       if (c == '!')
359         {
360           /* If -fopenmp, we need to handle here 2 things:
361              1) don't treat !$omp as comments, but directives
362              2) handle OpenMP conditional compilation, where
363                 !$ should be treated as 2 spaces (for initial lines
364                 only if followed by space).  */
365           if (gfc_option.flag_openmp && at_bol)
366             {
367               locus old_loc = gfc_current_locus;
368               if (next_char () == '$')
369                 {
370                   c = next_char ();
371                   if (c == 'o' || c == 'O')
372                     {
373                       if (((c = next_char ()) == 'm' || c == 'M')
374                           && ((c = next_char ()) == 'p' || c == 'P')
375                           && ((c = next_char ()) == ' ' || continue_flag))
376                         {
377                           while (gfc_is_whitespace (c))
378                             c = next_char ();
379                           if (c != '\n' && c != '!')
380                             {
381                               openmp_flag = 1;
382                               openmp_locus = old_loc;
383                               gfc_current_locus = start;
384                               return false;
385                             }
386                         }
387                       gfc_current_locus = old_loc;
388                       next_char ();
389                       c = next_char ();
390                     }
391                   if (continue_flag || c == ' ')
392                     {
393                       gfc_current_locus = old_loc;
394                       next_char ();
395                       openmp_flag = 0;
396                       return true;
397                     }
398                 }
399               gfc_current_locus = old_loc;
400             }
401           skip_comment_line ();
402           continue;
403         }
404
405       break;
406     }
407
408   if (openmp_flag && at_bol)
409     openmp_flag = 0;
410   gfc_current_locus = start;
411   return false;
412 }
413
414
415 /* Skip comment lines in fixed source mode.  We have the same rules as
416    in skip_free_comment(), except that we can have a 'c', 'C' or '*'
417    in column 1, and a '!' cannot be in column 6.  Also, we deal with
418    lines with 'd' or 'D' in column 1, if the user requested this.  */
419
420 static void
421 skip_fixed_comments (void)
422 {
423   locus start;
424   int col;
425   char c;
426
427   if (! gfc_at_bol ())
428     {
429       start = gfc_current_locus;
430       if (! gfc_at_eof ())
431         {
432           do
433             c = next_char ();
434           while (gfc_is_whitespace (c));
435
436           if (c == '\n')
437             gfc_advance_line ();
438           else if (c == '!')
439             skip_comment_line ();
440         }
441
442       if (! gfc_at_bol ())
443         {
444           gfc_current_locus = start;
445           return;
446         }
447     }
448
449   for (;;)
450     {
451       start = gfc_current_locus;
452       if (gfc_at_eof ())
453         break;
454
455       c = next_char ();
456       if (c == '\n')
457         {
458           gfc_advance_line ();
459           continue;
460         }
461
462       if (c == '!' || c == 'c' || c == 'C' || c == '*')
463         {
464           /* If -fopenmp, we need to handle here 2 things:
465              1) don't treat !$omp|c$omp|*$omp as comments, but directives
466              2) handle OpenMP conditional compilation, where
467                 !$|c$|*$ should be treated as 2 spaces if the characters
468                 in columns 3 to 6 are valid fixed form label columns
469                 characters.  */
470           if (gfc_option.flag_openmp)
471             {
472               if (next_char () == '$')
473                 {
474                   c = next_char ();
475                   if (c == 'o' || c == 'O')
476                     {
477                       if (((c = next_char ()) == 'm' || c == 'M')
478                           && ((c = next_char ()) == 'p' || c == 'P'))
479                         {
480                           c = next_char ();
481                           if (c != '\n'
482                               && ((openmp_flag && continue_flag)
483                                   || c == ' ' || c == '0'))
484                             {
485                               c = next_char ();
486                               while (gfc_is_whitespace (c))
487                                 c = next_char ();
488                               if (c != '\n' && c != '!')
489                                 {
490                                   /* Canonicalize to *$omp.  */
491                                   *start.nextc = '*';
492                                   openmp_flag = 1;
493                                   gfc_current_locus = start;
494                                   return;
495                                 }
496                             }
497                         }
498                     }
499                   else
500                     {
501                       int digit_seen = 0;
502
503                       for (col = 3; col < 6; col++, c = next_char ())
504                         if (c == ' ')
505                           continue;
506                         else if (c < '0' || c > '9')
507                           break;
508                         else
509                           digit_seen = 1;
510
511                       if (col == 6 && c != '\n'
512                           && ((continue_flag && !digit_seen)
513                               || c == ' ' || c == '0'))
514                         {
515                           gfc_current_locus = start;
516                           start.nextc[0] = ' ';
517                           start.nextc[1] = ' ';
518                           continue;
519                         }
520                     }
521                 }
522               gfc_current_locus = start;
523             }
524           skip_comment_line ();
525           continue;
526         }
527
528       if (gfc_option.flag_d_lines != -1 && (c == 'd' || c == 'D'))
529         {
530           if (gfc_option.flag_d_lines == 0)
531             {
532               skip_comment_line ();
533               continue;
534             }
535           else
536             *start.nextc = c = ' ';
537         }
538
539       col = 1;
540
541       while (gfc_is_whitespace (c))
542         {
543           c = next_char ();
544           col++;
545         }
546
547       if (c == '\n')
548         {
549           gfc_advance_line ();
550           continue;
551         }
552
553       if (col != 6 && c == '!')
554         {
555           skip_comment_line ();
556           continue;
557         }
558
559       break;
560     }
561
562   openmp_flag = 0;
563   gfc_current_locus = start;
564 }
565
566
567 /* Skips the current line if it is a comment.  */
568
569 void
570 gfc_skip_comments (void)
571 {
572   if (gfc_current_form == FORM_FREE)
573     skip_free_comments ();
574   else
575     skip_fixed_comments ();
576 }
577
578
579 /* Get the next character from the input, taking continuation lines
580    and end-of-line comments into account.  This implies that comment
581    lines between continued lines must be eaten here.  For higher-level
582    subroutines, this flattens continued lines into a single logical
583    line.  The in_string flag denotes whether we're inside a character
584    context or not.  */
585
586 int
587 gfc_next_char_literal (int in_string)
588 {
589   locus old_loc;
590   int i, c, prev_openmp_flag;
591
592   continue_flag = 0;
593
594 restart:
595   c = next_char ();
596   if (gfc_at_end ())
597     {
598       continue_count = 0;
599       return c;
600     }
601
602   if (gfc_current_form == FORM_FREE)
603     {
604       bool openmp_cond_flag;
605
606       if (!in_string && c == '!')
607         {
608           if (openmp_flag
609               && memcmp (&gfc_current_locus, &openmp_locus,
610                  sizeof (gfc_current_locus)) == 0)
611             goto done;
612
613           /* This line can't be continued */
614           do
615             {
616               c = next_char ();
617             }
618           while (c != '\n');
619
620           /* Avoid truncation warnings for comment ending lines.  */
621           gfc_current_locus.lb->truncated = 0;
622
623           goto done;
624         }
625
626       if (c != '&')
627         goto done;
628
629       /* If the next nonblank character is a ! or \n, we've got a
630          continuation line.  */
631       old_loc = gfc_current_locus;
632
633       c = next_char ();
634       while (gfc_is_whitespace (c))
635         c = next_char ();
636
637       /* Character constants to be continued cannot have commentary
638          after the '&'.  */
639
640       if (in_string && c != '\n')
641         {
642           gfc_current_locus = old_loc;
643           c = '&';
644           goto done;
645         }
646
647       if (c != '!' && c != '\n')
648         {
649           gfc_current_locus = old_loc;
650           c = '&';
651           goto done;
652         }
653
654       prev_openmp_flag = openmp_flag;
655       continue_flag = 1;
656       if (c == '!')
657         skip_comment_line ();
658       else
659         gfc_advance_line ();
660
661       /* We've got a continuation line.  If we are on the very next line after
662          the last continuation, increment the continuation line count and
663          check whether the limit has been exceeded.  */
664       if (gfc_current_locus.lb->linenum == continue_line + 1)
665         {
666           if (++continue_count == gfc_option.max_continue_free)
667             {
668               if (gfc_notification_std (GFC_STD_GNU)
669                   || pedantic)
670                 gfc_warning ("Limit of %d continuations exceeded in statement at %C",
671                               gfc_option.max_continue_free);
672             }
673         }
674       continue_line = gfc_current_locus.lb->linenum;
675
676       /* Now find where it continues. First eat any comment lines.  */
677       openmp_cond_flag = skip_free_comments ();
678
679       if (prev_openmp_flag != openmp_flag)
680         {
681           gfc_current_locus = old_loc;
682           openmp_flag = prev_openmp_flag;
683           c = '&';
684           goto done;
685         }
686
687       /* Now that we have a non-comment line, probe ahead for the
688          first non-whitespace character.  If it is another '&', then
689          reading starts at the next character, otherwise we must back
690          up to where the whitespace started and resume from there.  */
691
692       old_loc = gfc_current_locus;
693
694       c = next_char ();
695       while (gfc_is_whitespace (c))
696         c = next_char ();
697
698       if (openmp_flag)
699         {
700           for (i = 0; i < 5; i++, c = next_char ())
701             {
702               gcc_assert (TOLOWER (c) == "!$omp"[i]);
703               if (i == 4)
704                 old_loc = gfc_current_locus;
705             }
706           while (gfc_is_whitespace (c))
707             c = next_char ();
708         }
709
710       if (c != '&')
711         {
712           if (in_string)
713             {
714               if (gfc_option.warn_ampersand)
715                 gfc_warning_now ("Missing '&' in continued character constant at %C");
716               gfc_current_locus.nextc--;
717             }
718           /* Both !$omp and !$ -fopenmp continuation lines have & on the
719              continuation line only optionally.  */
720           else if (openmp_flag || openmp_cond_flag)
721             gfc_current_locus.nextc--;
722           else
723             {
724               c = ' ';
725               gfc_current_locus = old_loc;
726               goto done;
727             }
728         }
729     }
730   else
731     {
732       /* Fixed form continuation.  */
733       if (!in_string && c == '!')
734         {
735           /* Skip comment at end of line.  */
736           do
737             {
738               c = next_char ();
739             }
740           while (c != '\n');
741
742           /* Avoid truncation warnings for comment ending lines.  */
743           gfc_current_locus.lb->truncated = 0;
744         }
745
746       if (c != '\n')
747         goto done;
748
749       prev_openmp_flag = openmp_flag;
750       continue_flag = 1;
751       old_loc = gfc_current_locus;
752
753       gfc_advance_line ();
754       skip_fixed_comments ();
755
756       /* See if this line is a continuation line.  */
757       if (openmp_flag != prev_openmp_flag)
758         {
759           openmp_flag = prev_openmp_flag;
760           goto not_continuation;
761         }
762
763       if (!openmp_flag)
764         for (i = 0; i < 5; i++)
765           {
766             c = next_char ();
767             if (c != ' ')
768               goto not_continuation;
769           }
770       else
771         for (i = 0; i < 5; i++)
772           {
773             c = next_char ();
774             if (TOLOWER (c) != "*$omp"[i])
775               goto not_continuation;
776           }
777
778       c = next_char ();
779       if (c == '0' || c == ' ' || c == '\n')
780         goto not_continuation;
781
782       /* We've got a continuation line.  If we are on the very next line after
783          the last continuation, increment the continuation line count and
784          check whether the limit has been exceeded.  */
785       if (gfc_current_locus.lb->linenum == continue_line + 1)
786         {
787           if (++continue_count == gfc_option.max_continue_fixed)
788             {
789               if (gfc_notification_std (GFC_STD_GNU)
790                   || pedantic)
791                 gfc_warning ("Limit of %d continuations exceeded in statement at %C",
792                               gfc_option.max_continue_fixed);
793             }
794         }
795
796       if (continue_line < gfc_current_locus.lb->linenum)
797         continue_line = gfc_current_locus.lb->linenum;
798     }
799
800   /* Ready to read first character of continuation line, which might
801      be another continuation line!  */
802   goto restart;
803
804 not_continuation:
805   c = '\n';
806   gfc_current_locus = old_loc;
807
808 done:
809   if (c == '\n')
810     continue_count = 0;
811   continue_flag = 0;
812   return c;
813 }
814
815
816 /* Get the next character of input, folded to lowercase.  In fixed
817    form mode, we also ignore spaces.  When matcher subroutines are
818    parsing character literals, they have to call
819    gfc_next_char_literal().  */
820
821 int
822 gfc_next_char (void)
823 {
824   int c;
825
826   do
827     {
828       c = gfc_next_char_literal (0);
829     }
830   while (gfc_current_form == FORM_FIXED && gfc_is_whitespace (c));
831
832   return TOLOWER (c);
833 }
834
835
836 int
837 gfc_peek_char (void)
838 {
839   locus old_loc;
840   int c;
841
842   old_loc = gfc_current_locus;
843   c = gfc_next_char ();
844   gfc_current_locus = old_loc;
845
846   return c;
847 }
848
849
850 /* Recover from an error.  We try to get past the current statement
851    and get lined up for the next.  The next statement follows a '\n'
852    or a ';'.  We also assume that we are not within a character
853    constant, and deal with finding a '\'' or '"'.  */
854
855 void
856 gfc_error_recovery (void)
857 {
858   char c, delim;
859
860   if (gfc_at_eof ())
861     return;
862
863   for (;;)
864     {
865       c = gfc_next_char ();
866       if (c == '\n' || c == ';')
867         break;
868
869       if (c != '\'' && c != '"')
870         {
871           if (gfc_at_eof ())
872             break;
873           continue;
874         }
875       delim = c;
876
877       for (;;)
878         {
879           c = next_char ();
880
881           if (c == delim)
882             break;
883           if (c == '\n')
884             return;
885           if (c == '\\')
886             {
887               c = next_char ();
888               if (c == '\n')
889                 return;
890             }
891         }
892       if (gfc_at_eof ())
893         break;
894     }
895 }
896
897
898 /* Read ahead until the next character to be read is not whitespace.  */
899
900 void
901 gfc_gobble_whitespace (void)
902 {
903   static int linenum = 0;
904   locus old_loc;
905   int c;
906
907   do
908     {
909       old_loc = gfc_current_locus;
910       c = gfc_next_char_literal (0);
911       /* Issue a warning for nonconforming tabs.  We keep track of the line
912          number because the Fortran matchers will often back up and the same
913          line will be scanned multiple times.  */
914       if (!gfc_option.warn_tabs && c == '\t')
915         {
916 #ifdef USE_MAPPED_LOCATION
917           int cur_linenum = LOCATION_LINE (gfc_current_locus.lb->location);
918 #else
919           int cur_linenum = gfc_current_locus.lb->linenum;
920 #endif
921           if (cur_linenum != linenum)
922             {
923               linenum = cur_linenum;
924               gfc_warning_now ("Nonconforming tab character at %C");
925             }
926         }
927     }
928   while (gfc_is_whitespace (c));
929
930   gfc_current_locus = old_loc;
931 }
932
933
934 /* Load a single line into pbuf.
935
936    If pbuf points to a NULL pointer, it is allocated.
937    We truncate lines that are too long, unless we're dealing with
938    preprocessor lines or if the option -ffixed-line-length-none is set,
939    in which case we reallocate the buffer to fit the entire line, if
940    need be.
941    In fixed mode, we expand a tab that occurs within the statement
942    label region to expand to spaces that leave the next character in
943    the source region.
944    load_line returns whether the line was truncated.
945
946    NOTE: The error machinery isn't available at this point, so we can't
947          easily report line and column numbers consistent with other 
948          parts of gfortran.  */
949
950 static int
951 load_line (FILE * input, char **pbuf, int *pbuflen)
952 {
953   static int linenum = 0, current_line = 1;
954   int c, maxlen, i, preprocessor_flag, buflen = *pbuflen;
955   int trunc_flag = 0, seen_comment = 0;
956   int seen_printable = 0, seen_ampersand = 0;
957   char *buffer;
958
959   /* Determine the maximum allowed line length.  */
960   if (gfc_current_form == FORM_FREE)
961     maxlen = gfc_option.free_line_length;
962   else if (gfc_current_form == FORM_FIXED)
963     maxlen = gfc_option.fixed_line_length;
964   else
965     maxlen = 72;
966
967   if (*pbuf == NULL)
968     {
969       /* Allocate the line buffer, storing its length into buflen.
970          Note that if maxlen==0, indicating that arbitrary-length lines
971          are allowed, the buffer will be reallocated if this length is
972          insufficient; since 132 characters is the length of a standard
973          free-form line, we use that as a starting guess.  */
974       if (maxlen > 0)
975         buflen = maxlen;
976       else
977         buflen = 132;
978
979       *pbuf = gfc_getmem (buflen + 1);
980     }
981
982   i = 0;
983   buffer = *pbuf;
984
985   preprocessor_flag = 0;
986   c = fgetc (input);
987   if (c == '#')
988     /* In order to not truncate preprocessor lines, we have to
989        remember that this is one.  */
990     preprocessor_flag = 1;
991   ungetc (c, input);
992
993   for (;;)
994     {
995       c = fgetc (input);
996
997       if (c == EOF)
998         break;
999       if (c == '\n')
1000         {
1001           /* Check for illegal use of ampersand. See F95 Standard 3.3.1.3.  */
1002           if (gfc_current_form == FORM_FREE 
1003                 && !seen_printable && seen_ampersand)
1004             {
1005               if (pedantic)
1006                 gfc_error_now
1007                   ("'&' not allowed by itself in line %d", current_line);
1008               else
1009                 gfc_warning_now
1010                   ("'&' not allowed by itself in line %d", current_line);
1011             }
1012           break;
1013         }
1014
1015       if (c == '\r')
1016         continue;               /* Gobble characters.  */
1017       if (c == '\0')
1018         continue;
1019
1020       if (c == '\032')
1021         {
1022           /* Ctrl-Z ends the file.  */
1023           while (fgetc (input) != EOF);
1024           break;
1025         }
1026
1027       /* Check for illegal use of ampersand. See F95 Standard 3.3.1.3.  */
1028       if (c == '&')
1029         seen_ampersand = 1;
1030
1031       if ((c != ' ' && c != '&' && c != '!') || (c == '!' && !seen_ampersand))
1032         seen_printable = 1;
1033       
1034       if (gfc_current_form == FORM_FREE 
1035             && c == '!' && !seen_printable && seen_ampersand)
1036         {
1037           if (pedantic)
1038             gfc_error_now (
1039               "'&' not allowed by itself with comment in line %d", current_line);
1040           else
1041             gfc_warning_now (
1042               "'&' not allowed by itself with comment in line %d", current_line);
1043           seen_printable = 1;
1044         }
1045
1046       /* Is this a fixed-form comment?  */
1047       if (gfc_current_form == FORM_FIXED && i == 0
1048           && (c == '*' || c == 'c' || c == 'd'))
1049         seen_comment = 1;
1050
1051       if (gfc_current_form == FORM_FIXED && c == '\t' && i <= 6)
1052         {
1053           if (!gfc_option.warn_tabs && seen_comment == 0
1054               && current_line != linenum)
1055             {
1056               linenum = current_line;
1057               gfc_warning_now (
1058                 "Nonconforming tab character in column 1 of line %d", linenum);
1059             }
1060
1061           while (i <= 6)
1062             {
1063               *buffer++ = ' ';
1064               i++;
1065             }
1066
1067           continue;
1068         }
1069
1070       *buffer++ = c;
1071       i++;
1072
1073       if (maxlen == 0 || preprocessor_flag)
1074         {
1075           if (i >= buflen)
1076             {
1077               /* Reallocate line buffer to double size to hold the
1078                 overlong line.  */
1079               buflen = buflen * 2;
1080               *pbuf = xrealloc (*pbuf, buflen + 1);
1081               buffer = (*pbuf)+i;
1082             }
1083         }
1084       else if (i >= maxlen)
1085         {
1086           /* Truncate the rest of the line.  */
1087           for (;;)
1088             {
1089               c = fgetc (input);
1090               if (c == '\n' || c == EOF)
1091                 break;
1092
1093               trunc_flag = 1;
1094             }
1095
1096           ungetc ('\n', input);
1097         }
1098     }
1099
1100   /* Pad lines to the selected line length in fixed form.  */
1101   if (gfc_current_form == FORM_FIXED
1102       && gfc_option.fixed_line_length != 0
1103       && !preprocessor_flag
1104       && c != EOF)
1105     {
1106       while (i++ < maxlen)
1107         *buffer++ = ' ';
1108     }
1109
1110   *buffer = '\0';
1111   *pbuflen = buflen;
1112   current_line++;
1113
1114   return trunc_flag;
1115 }
1116
1117
1118 /* Get a gfc_file structure, initialize it and add it to
1119    the file stack.  */
1120
1121 static gfc_file *
1122 get_file (const char *name, enum lc_reason reason ATTRIBUTE_UNUSED)
1123 {
1124   gfc_file *f;
1125
1126   f = gfc_getmem (sizeof (gfc_file));
1127
1128   f->filename = gfc_getmem (strlen (name) + 1);
1129   strcpy (f->filename, name);
1130
1131   f->next = file_head;
1132   file_head = f;
1133
1134   f->included_by = current_file;
1135   if (current_file != NULL)
1136     f->inclusion_line = current_file->line;
1137
1138 #ifdef USE_MAPPED_LOCATION
1139   linemap_add (&line_table, reason, false, f->filename, 1);
1140 #endif
1141
1142   return f;
1143 }
1144
1145 /* Deal with a line from the C preprocessor. The
1146    initial octothorp has already been seen.  */
1147
1148 static void
1149 preprocessor_line (char *c)
1150 {
1151   bool flag[5];
1152   int i, line;
1153   char *filename;
1154   gfc_file *f;
1155   int escaped, unescape;
1156
1157   c++;
1158   while (*c == ' ' || *c == '\t')
1159     c++;
1160
1161   if (*c < '0' || *c > '9')
1162     goto bad_cpp_line;
1163
1164   line = atoi (c);
1165
1166   c = strchr (c, ' ');
1167   if (c == NULL)
1168     {
1169       /* No file name given.  Set new line number.  */
1170       current_file->line = line;
1171       return;
1172     }
1173
1174   /* Skip spaces.  */
1175   while (*c == ' ' || *c == '\t')
1176     c++;
1177
1178   /* Skip quote.  */
1179   if (*c != '"')
1180     goto bad_cpp_line;
1181   ++c;
1182
1183   filename = c;
1184
1185   /* Make filename end at quote.  */
1186   unescape = 0;
1187   escaped = false;
1188   while (*c && ! (! escaped && *c == '"'))
1189     {
1190       if (escaped)
1191         escaped = false;
1192       else if (*c == '\\')
1193         {
1194           escaped = true;
1195           unescape++;
1196         }
1197       ++c;
1198     }
1199
1200   if (! *c)
1201     /* Preprocessor line has no closing quote.  */
1202     goto bad_cpp_line;
1203
1204   *c++ = '\0';
1205
1206   /* Undo effects of cpp_quote_string.  */
1207   if (unescape)
1208     {
1209       char *s = filename;
1210       char *d = gfc_getmem (c - filename - unescape);
1211
1212       filename = d;
1213       while (*s)
1214         {
1215           if (*s == '\\')
1216             *d++ = *++s;
1217           else
1218             *d++ = *s;
1219           s++;
1220         }
1221       *d = '\0';
1222     }
1223
1224   /* Get flags.  */
1225
1226   flag[1] = flag[2] = flag[3] = flag[4] = false;
1227
1228   for (;;)
1229     {
1230       c = strchr (c, ' ');
1231       if (c == NULL)
1232         break;
1233
1234       c++;
1235       i = atoi (c);
1236
1237       if (1 <= i && i <= 4)
1238         flag[i] = true;
1239     }
1240
1241   /* Interpret flags.  */
1242
1243   if (flag[1]) /* Starting new file.  */
1244     {
1245       f = get_file (filename, LC_RENAME);
1246       f->up = current_file;
1247       current_file = f;
1248     }
1249
1250   if (flag[2]) /* Ending current file.  */
1251     {
1252       if (!current_file->up
1253           || strcmp (current_file->up->filename, filename) != 0)
1254         {
1255           gfc_warning_now ("%s:%d: file %s left but not entered",
1256                            current_file->filename, current_file->line,
1257                            filename);
1258           if (unescape)
1259             gfc_free (filename);
1260           return;
1261         }
1262       current_file = current_file->up;
1263     }
1264
1265   /* The name of the file can be a temporary file produced by
1266      cpp. Replace the name if it is different.  */
1267
1268   if (strcmp (current_file->filename, filename) != 0)
1269     {
1270       gfc_free (current_file->filename);
1271       current_file->filename = gfc_getmem (strlen (filename) + 1);
1272       strcpy (current_file->filename, filename);
1273     }
1274
1275   /* Set new line number.  */
1276   current_file->line = line;
1277   if (unescape)
1278     gfc_free (filename);
1279   return;
1280
1281  bad_cpp_line:
1282   gfc_warning_now ("%s:%d: Illegal preprocessor directive",
1283                    current_file->filename, current_file->line);
1284   current_file->line++;
1285 }
1286
1287
1288 static try load_file (const char *, bool);
1289
1290 /* include_line()-- Checks a line buffer to see if it is an include
1291    line.  If so, we call load_file() recursively to load the included
1292    file.  We never return a syntax error because a statement like
1293    "include = 5" is perfectly legal.  We return false if no include was
1294    processed or true if we matched an include.  */
1295
1296 static bool
1297 include_line (char *line)
1298 {
1299   char quote, *c, *begin, *stop;
1300
1301   c = line;
1302
1303   if (gfc_option.flag_openmp)
1304     {
1305       if (gfc_current_form == FORM_FREE)
1306         {
1307           while (*c == ' ' || *c == '\t')
1308             c++;
1309           if (*c == '!' && c[1] == '$' && (c[2] == ' ' || c[2] == '\t'))
1310             c += 3;
1311         }
1312       else
1313         {
1314           if ((*c == '!' || *c == 'c' || *c == 'C' || *c == '*')
1315               && c[1] == '$' && (c[2] == ' ' || c[2] == '\t'))
1316             c += 3;
1317         }
1318     }
1319
1320   while (*c == ' ' || *c == '\t')
1321     c++;
1322
1323   if (strncasecmp (c, "include", 7))
1324       return false;
1325
1326   c += 7;
1327   while (*c == ' ' || *c == '\t')
1328     c++;
1329
1330   /* Find filename between quotes.  */
1331   
1332   quote = *c++;
1333   if (quote != '"' && quote != '\'')
1334     return false;
1335
1336   begin = c;
1337
1338   while (*c != quote && *c != '\0')
1339     c++;
1340
1341   if (*c == '\0')
1342     return false;
1343
1344   stop = c++;
1345   
1346   while (*c == ' ' || *c == '\t')
1347     c++;
1348
1349   if (*c != '\0' && *c != '!')
1350     return false;
1351
1352   /* We have an include line at this point.  */
1353
1354   *stop = '\0'; /* It's ok to trash the buffer, as this line won't be
1355                    read by anything else.  */
1356
1357   load_file (begin, false);
1358   return true;
1359 }
1360
1361 /* Load a file into memory by calling load_line until the file ends.  */
1362
1363 static try
1364 load_file (const char *filename, bool initial)
1365 {
1366   char *line;
1367   gfc_linebuf *b;
1368   gfc_file *f;
1369   FILE *input;
1370   int len, line_len;
1371
1372   for (f = current_file; f; f = f->up)
1373     if (strcmp (filename, f->filename) == 0)
1374       {
1375         gfc_error_now ("File '%s' is being included recursively", filename);
1376         return FAILURE;
1377       }
1378
1379   if (initial)
1380     {
1381       if (gfc_src_file)
1382         {
1383           input = gfc_src_file;
1384           gfc_src_file = NULL;
1385         }
1386       else
1387         input = gfc_open_file (filename);
1388       if (input == NULL)
1389         {
1390           gfc_error_now ("Can't open file '%s'", filename);
1391           return FAILURE;
1392         }
1393     }
1394   else
1395     {
1396       input = gfc_open_included_file (filename, false);
1397       if (input == NULL)
1398         {
1399           gfc_error_now ("Can't open included file '%s'", filename);
1400           return FAILURE;
1401         }
1402     }
1403
1404   /* Load the file.  */
1405
1406   f = get_file (filename, initial ? LC_RENAME : LC_ENTER);
1407   f->up = current_file;
1408   current_file = f;
1409   current_file->line = 1;
1410   line = NULL;
1411   line_len = 0;
1412
1413   if (initial && gfc_src_preprocessor_lines[0])
1414     {
1415       preprocessor_line (gfc_src_preprocessor_lines[0]);
1416       gfc_free (gfc_src_preprocessor_lines[0]);
1417       gfc_src_preprocessor_lines[0] = NULL;
1418       if (gfc_src_preprocessor_lines[1])
1419         {
1420           preprocessor_line (gfc_src_preprocessor_lines[1]);
1421           gfc_free (gfc_src_preprocessor_lines[1]);
1422           gfc_src_preprocessor_lines[1] = NULL;
1423         }
1424     }
1425
1426   for (;;)
1427     {
1428       int trunc = load_line (input, &line, &line_len);
1429
1430       len = strlen (line);
1431       if (feof (input) && len == 0)
1432         break;
1433
1434       /* There are three things this line can be: a line of Fortran
1435          source, an include line or a C preprocessor directive.  */
1436
1437       if (line[0] == '#')
1438         {
1439           preprocessor_line (line);
1440           continue;
1441         }
1442
1443       if (include_line (line))
1444         {
1445           current_file->line++;
1446           continue;
1447         }
1448
1449       /* Add line.  */
1450
1451       b = gfc_getmem (gfc_linebuf_header_size + len + 1);
1452
1453 #ifdef USE_MAPPED_LOCATION
1454       b->location
1455         = linemap_line_start (&line_table, current_file->line++, 120);
1456 #else
1457       b->linenum = current_file->line++;
1458 #endif
1459       b->file = current_file;
1460       b->truncated = trunc;
1461       strcpy (b->line, line);
1462
1463       if (line_head == NULL)
1464         line_head = b;
1465       else
1466         line_tail->next = b;
1467
1468       line_tail = b;
1469     }
1470
1471   /* Release the line buffer allocated in load_line.  */
1472   gfc_free (line);
1473
1474   fclose (input);
1475
1476   current_file = current_file->up;
1477 #ifdef USE_MAPPED_LOCATION
1478   linemap_add (&line_table, LC_LEAVE, 0, NULL, 0);
1479 #endif
1480   return SUCCESS;
1481 }
1482
1483
1484 /* Open a new file and start scanning from that file. Returns SUCCESS
1485    if everything went OK, FAILURE otherwise.  If form == FORM_UKNOWN
1486    it tries to determine the source form from the filename, defaulting
1487    to free form.  */
1488
1489 try
1490 gfc_new_file (void)
1491 {
1492   try result;
1493
1494   result = load_file (gfc_source_file, true);
1495
1496   gfc_current_locus.lb = line_head;
1497   gfc_current_locus.nextc = (line_head == NULL) ? NULL : line_head->line;
1498
1499 #if 0 /* Debugging aid.  */
1500   for (; line_head; line_head = line_head->next)
1501     gfc_status ("%s:%3d %s\n", line_head->file->filename, 
1502 #ifdef USE_MAPPED_LOCATION
1503                 LOCATION_LINE (line_head->location),
1504 #else
1505                 line_head->linenum,
1506 #endif
1507                 line_head->line);
1508
1509   exit (0);
1510 #endif
1511
1512   return result;
1513 }
1514
1515 static char *
1516 unescape_filename (const char *ptr)
1517 {
1518   const char *p = ptr, *s;
1519   char *d, *ret;
1520   int escaped, unescape = 0;
1521
1522   /* Make filename end at quote.  */
1523   escaped = false;
1524   while (*p && ! (! escaped && *p == '"'))
1525     {
1526       if (escaped)
1527         escaped = false;
1528       else if (*p == '\\')
1529         {
1530           escaped = true;
1531           unescape++;
1532         }
1533       ++p;
1534     }
1535
1536   if (! *p || p[1])
1537     return NULL;
1538
1539   /* Undo effects of cpp_quote_string.  */
1540   s = ptr;
1541   d = gfc_getmem (p + 1 - ptr - unescape);
1542   ret = d;
1543
1544   while (s != p)
1545     {
1546       if (*s == '\\')
1547         *d++ = *++s;
1548       else
1549         *d++ = *s;
1550       s++;
1551     }
1552   *d = '\0';
1553   return ret;
1554 }
1555
1556 /* For preprocessed files, if the first tokens are of the form # NUM.
1557    handle the directives so we know the original file name.  */
1558
1559 const char *
1560 gfc_read_orig_filename (const char *filename, const char **canon_source_file)
1561 {
1562   int c, len;
1563   char *dirname;
1564
1565   gfc_src_file = gfc_open_file (filename);
1566   if (gfc_src_file == NULL)
1567     return NULL;
1568
1569   c = fgetc (gfc_src_file);
1570   ungetc (c, gfc_src_file);
1571
1572   if (c != '#')
1573     return NULL;
1574
1575   len = 0;
1576   load_line (gfc_src_file, &gfc_src_preprocessor_lines[0], &len);
1577
1578   if (strncmp (gfc_src_preprocessor_lines[0], "# 1 \"", 5) != 0)
1579     return NULL;
1580
1581   filename = unescape_filename (gfc_src_preprocessor_lines[0] + 5);
1582   if (filename == NULL)
1583     return NULL;
1584
1585   c = fgetc (gfc_src_file);
1586   ungetc (c, gfc_src_file);
1587
1588   if (c != '#')
1589     return filename;
1590
1591   len = 0;
1592   load_line (gfc_src_file, &gfc_src_preprocessor_lines[1], &len);
1593
1594   if (strncmp (gfc_src_preprocessor_lines[1], "# 1 \"", 5) != 0)
1595     return filename;
1596
1597   dirname = unescape_filename (gfc_src_preprocessor_lines[1] + 5);
1598   if (dirname == NULL)
1599     return filename;
1600
1601   len = strlen (dirname);
1602   if (len < 3 || dirname[len - 1] != '/' || dirname[len - 2] != '/')
1603     {
1604       gfc_free (dirname);
1605       return filename;
1606     }
1607   dirname[len - 2] = '\0';
1608   set_src_pwd (dirname);
1609
1610   if (! IS_ABSOLUTE_PATH (filename))
1611     {
1612       char *p = gfc_getmem (len + strlen (filename));
1613
1614       memcpy (p, dirname, len - 2);
1615       p[len - 2] = '/';
1616       strcpy (p + len - 1, filename);
1617       *canon_source_file = p;
1618     }
1619
1620   gfc_free (dirname);
1621   return filename;
1622 }