OSDN Git Service

2006-10-14 Jerry DeLisle <jvdelisle@gcc.gnu.org>
[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                       return true;
396                     }
397                 }
398               gfc_current_locus = old_loc;
399             }
400           skip_comment_line ();
401           continue;
402         }
403
404       break;
405     }
406
407   if (openmp_flag && at_bol)
408     openmp_flag = 0;
409   gfc_current_locus = start;
410   return false;
411 }
412
413
414 /* Skip comment lines in fixed source mode.  We have the same rules as
415    in skip_free_comment(), except that we can have a 'c', 'C' or '*'
416    in column 1, and a '!' cannot be in column 6.  Also, we deal with
417    lines with 'd' or 'D' in column 1, if the user requested this.  */
418
419 static void
420 skip_fixed_comments (void)
421 {
422   locus start;
423   int col;
424   char c;
425
426   if (! gfc_at_bol ())
427     {
428       start = gfc_current_locus;
429       if (! gfc_at_eof ())
430         {
431           do
432             c = next_char ();
433           while (gfc_is_whitespace (c));
434
435           if (c == '\n')
436             gfc_advance_line ();
437           else if (c == '!')
438             skip_comment_line ();
439         }
440
441       if (! gfc_at_bol ())
442         {
443           gfc_current_locus = start;
444           return;
445         }
446     }
447
448   for (;;)
449     {
450       start = gfc_current_locus;
451       if (gfc_at_eof ())
452         break;
453
454       c = next_char ();
455       if (c == '\n')
456         {
457           gfc_advance_line ();
458           continue;
459         }
460
461       if (c == '!' || c == 'c' || c == 'C' || c == '*')
462         {
463           /* If -fopenmp, we need to handle here 2 things:
464              1) don't treat !$omp|c$omp|*$omp as comments, but directives
465              2) handle OpenMP conditional compilation, where
466                 !$|c$|*$ should be treated as 2 spaces if the characters
467                 in columns 3 to 6 are valid fixed form label columns
468                 characters.  */
469           if (gfc_option.flag_openmp)
470             {
471               if (next_char () == '$')
472                 {
473                   c = next_char ();
474                   if (c == 'o' || c == 'O')
475                     {
476                       if (((c = next_char ()) == 'm' || c == 'M')
477                           && ((c = next_char ()) == 'p' || c == 'P'))
478                         {
479                           c = next_char ();
480                           if (c != '\n'
481                               && ((openmp_flag && continue_flag)
482                                   || c == ' ' || c == '0'))
483                             {
484                               c = next_char ();
485                               while (gfc_is_whitespace (c))
486                                 c = next_char ();
487                               if (c != '\n' && c != '!')
488                                 {
489                                   /* Canonicalize to *$omp.  */
490                                   *start.nextc = '*';
491                                   openmp_flag = 1;
492                                   gfc_current_locus = start;
493                                   return;
494                                 }
495                             }
496                         }
497                     }
498                   else
499                     {
500                       int digit_seen = 0;
501
502                       for (col = 3; col < 6; col++, c = next_char ())
503                         if (c == ' ')
504                           continue;
505                         else if (c < '0' || c > '9')
506                           break;
507                         else
508                           digit_seen = 1;
509
510                       if (col == 6 && c != '\n'
511                           && ((continue_flag && !digit_seen)
512                               || c == ' ' || c == '0'))
513                         {
514                           gfc_current_locus = start;
515                           start.nextc[0] = ' ';
516                           start.nextc[1] = ' ';
517                           continue;
518                         }
519                     }
520                 }
521               gfc_current_locus = start;
522             }
523           skip_comment_line ();
524           continue;
525         }
526
527       if (gfc_option.flag_d_lines != -1 && (c == 'd' || c == 'D'))
528         {
529           if (gfc_option.flag_d_lines == 0)
530             {
531               skip_comment_line ();
532               continue;
533             }
534           else
535             *start.nextc = c = ' ';
536         }
537
538       col = 1;
539
540       while (gfc_is_whitespace (c))
541         {
542           c = next_char ();
543           col++;
544         }
545
546       if (c == '\n')
547         {
548           gfc_advance_line ();
549           continue;
550         }
551
552       if (col != 6 && c == '!')
553         {
554           skip_comment_line ();
555           continue;
556         }
557
558       break;
559     }
560
561   openmp_flag = 0;
562   gfc_current_locus = start;
563 }
564
565
566 /* Skips the current line if it is a comment.  */
567
568 void
569 gfc_skip_comments (void)
570 {
571   if (gfc_current_form == FORM_FREE)
572     skip_free_comments ();
573   else
574     skip_fixed_comments ();
575 }
576
577
578 /* Get the next character from the input, taking continuation lines
579    and end-of-line comments into account.  This implies that comment
580    lines between continued lines must be eaten here.  For higher-level
581    subroutines, this flattens continued lines into a single logical
582    line.  The in_string flag denotes whether we're inside a character
583    context or not.  */
584
585 int
586 gfc_next_char_literal (int in_string)
587 {
588   locus old_loc;
589   int i, c, prev_openmp_flag;
590
591   continue_flag = 0;
592
593 restart:
594   c = next_char ();
595   if (gfc_at_end ())
596     {
597       continue_count = 0;
598       return c;
599     }
600
601   if (gfc_current_form == FORM_FREE)
602     {
603       bool openmp_cond_flag;
604
605       if (!in_string && c == '!')
606         {
607           if (openmp_flag
608               && memcmp (&gfc_current_locus, &openmp_locus,
609                  sizeof (gfc_current_locus)) == 0)
610             goto done;
611
612           /* This line can't be continued */
613           do
614             {
615               c = next_char ();
616             }
617           while (c != '\n');
618
619           /* Avoid truncation warnings for comment ending lines.  */
620           gfc_current_locus.lb->truncated = 0;
621
622           goto done;
623         }
624
625       if (c != '&')
626         goto done;
627
628       /* If the next nonblank character is a ! or \n, we've got a
629          continuation line.  */
630       old_loc = gfc_current_locus;
631
632       c = next_char ();
633       while (gfc_is_whitespace (c))
634         c = next_char ();
635
636       /* Character constants to be continued cannot have commentary
637          after the '&'.  */
638
639       if (in_string && c != '\n')
640         {
641           gfc_current_locus = old_loc;
642           c = '&';
643           goto done;
644         }
645
646       if (c != '!' && c != '\n')
647         {
648           gfc_current_locus = old_loc;
649           c = '&';
650           goto done;
651         }
652
653       prev_openmp_flag = openmp_flag;
654       continue_flag = 1;
655       if (c == '!')
656         skip_comment_line ();
657       else
658         gfc_advance_line ();
659
660       /* We've got a continuation line.  If we are on the very next line after
661          the last continuation, increment the continuation line count and
662          check whether the limit has been exceeded.  */
663       if (gfc_current_locus.lb->linenum == continue_line + 1)
664         {
665           if (++continue_count == gfc_option.max_continue_free)
666             {
667               if (gfc_notification_std (GFC_STD_GNU)
668                   || pedantic)
669                 gfc_warning ("Limit of %d continuations exceeded in statement at %C",
670                               gfc_option.max_continue_free);
671             }
672         }
673       continue_line = gfc_current_locus.lb->linenum;
674
675       /* Now find where it continues. First eat any comment lines.  */
676       openmp_cond_flag = skip_free_comments ();
677
678       if (prev_openmp_flag != openmp_flag)
679         {
680           gfc_current_locus = old_loc;
681           openmp_flag = prev_openmp_flag;
682           c = '&';
683           goto done;
684         }
685
686       /* Now that we have a non-comment line, probe ahead for the
687          first non-whitespace character.  If it is another '&', then
688          reading starts at the next character, otherwise we must back
689          up to where the whitespace started and resume from there.  */
690
691       old_loc = gfc_current_locus;
692
693       c = next_char ();
694       while (gfc_is_whitespace (c))
695         c = next_char ();
696
697       if (openmp_flag)
698         {
699           for (i = 0; i < 5; i++, c = next_char ())
700             {
701               gcc_assert (TOLOWER (c) == "!$omp"[i]);
702               if (i == 4)
703                 old_loc = gfc_current_locus;
704             }
705           while (gfc_is_whitespace (c))
706             c = next_char ();
707         }
708
709       if (c != '&')
710         {
711           if (in_string)
712             {
713               if (gfc_option.warn_ampersand)
714                 gfc_warning_now ("Missing '&' in continued character constant at %C");
715               gfc_current_locus.nextc--;
716             }
717           /* Both !$omp and !$ -fopenmp continuation lines have & on the
718              continuation line only optionally.  */
719           else if (openmp_flag || openmp_cond_flag)
720             gfc_current_locus.nextc--;
721           else
722             {
723               c = ' ';
724               gfc_current_locus = old_loc;
725               goto done;
726             }
727         }
728     }
729   else
730     {
731       /* Fixed form continuation.  */
732       if (!in_string && c == '!')
733         {
734           /* Skip comment at end of line.  */
735           do
736             {
737               c = next_char ();
738             }
739           while (c != '\n');
740
741           /* Avoid truncation warnings for comment ending lines.  */
742           gfc_current_locus.lb->truncated = 0;
743         }
744
745       if (c != '\n')
746         goto done;
747
748       prev_openmp_flag = openmp_flag;
749       continue_flag = 1;
750       old_loc = gfc_current_locus;
751
752       gfc_advance_line ();
753       skip_fixed_comments ();
754
755       /* See if this line is a continuation line.  */
756       if (openmp_flag != prev_openmp_flag)
757         {
758           openmp_flag = prev_openmp_flag;
759           goto not_continuation;
760         }
761
762       if (!openmp_flag)
763         for (i = 0; i < 5; i++)
764           {
765             c = next_char ();
766             if (c != ' ')
767               goto not_continuation;
768           }
769       else
770         for (i = 0; i < 5; i++)
771           {
772             c = next_char ();
773             if (TOLOWER (c) != "*$omp"[i])
774               goto not_continuation;
775           }
776
777       c = next_char ();
778       if (c == '0' || c == ' ' || c == '\n')
779         goto not_continuation;
780
781       /* We've got a continuation line.  If we are on the very next line after
782          the last continuation, increment the continuation line count and
783          check whether the limit has been exceeded.  */
784       if (gfc_current_locus.lb->linenum == continue_line + 1)
785         {
786           if (++continue_count == gfc_option.max_continue_fixed)
787             {
788               if (gfc_notification_std (GFC_STD_GNU)
789                   || pedantic)
790                 gfc_warning ("Limit of %d continuations exceeded in statement at %C",
791                               gfc_option.max_continue_fixed);
792             }
793         }
794
795       if (continue_line < gfc_current_locus.lb->linenum)
796         continue_line = gfc_current_locus.lb->linenum;
797     }
798
799   /* Ready to read first character of continuation line, which might
800      be another continuation line!  */
801   goto restart;
802
803 not_continuation:
804   c = '\n';
805   gfc_current_locus = old_loc;
806
807 done:
808   if (c == '\n')
809     continue_count = 0;
810   continue_flag = 0;
811   return c;
812 }
813
814
815 /* Get the next character of input, folded to lowercase.  In fixed
816    form mode, we also ignore spaces.  When matcher subroutines are
817    parsing character literals, they have to call
818    gfc_next_char_literal().  */
819
820 int
821 gfc_next_char (void)
822 {
823   int c;
824
825   do
826     {
827       c = gfc_next_char_literal (0);
828     }
829   while (gfc_current_form == FORM_FIXED && gfc_is_whitespace (c));
830
831   return TOLOWER (c);
832 }
833
834
835 int
836 gfc_peek_char (void)
837 {
838   locus old_loc;
839   int c;
840
841   old_loc = gfc_current_locus;
842   c = gfc_next_char ();
843   gfc_current_locus = old_loc;
844
845   return c;
846 }
847
848
849 /* Recover from an error.  We try to get past the current statement
850    and get lined up for the next.  The next statement follows a '\n'
851    or a ';'.  We also assume that we are not within a character
852    constant, and deal with finding a '\'' or '"'.  */
853
854 void
855 gfc_error_recovery (void)
856 {
857   char c, delim;
858
859   if (gfc_at_eof ())
860     return;
861
862   for (;;)
863     {
864       c = gfc_next_char ();
865       if (c == '\n' || c == ';')
866         break;
867
868       if (c != '\'' && c != '"')
869         {
870           if (gfc_at_eof ())
871             break;
872           continue;
873         }
874       delim = c;
875
876       for (;;)
877         {
878           c = next_char ();
879
880           if (c == delim)
881             break;
882           if (c == '\n')
883             return;
884           if (c == '\\')
885             {
886               c = next_char ();
887               if (c == '\n')
888                 return;
889             }
890         }
891       if (gfc_at_eof ())
892         break;
893     }
894 }
895
896
897 /* Read ahead until the next character to be read is not whitespace.  */
898
899 void
900 gfc_gobble_whitespace (void)
901 {
902   static int linenum = 0;
903   locus old_loc;
904   int c;
905
906   do
907     {
908       old_loc = gfc_current_locus;
909       c = gfc_next_char_literal (0);
910       /* Issue a warning for nonconforming tabs.  We keep track of the line
911          number because the Fortran matchers will often back up and the same
912          line will be scanned multiple times.  */
913       if (!gfc_option.warn_tabs && c == '\t')
914         {
915 #ifdef USE_MAPPED_LOCATION
916           int cur_linenum = LOCATION_LINE (gfc_current_locus.lb->location);
917 #else
918           int cur_linenum = gfc_current_locus.lb->linenum;
919 #endif
920           if (cur_linenum != linenum)
921             {
922               linenum = cur_linenum;
923               gfc_warning_now ("Nonconforming tab character at %C");
924             }
925         }
926     }
927   while (gfc_is_whitespace (c));
928
929   gfc_current_locus = old_loc;
930 }
931
932
933 /* Load a single line into pbuf.
934
935    If pbuf points to a NULL pointer, it is allocated.
936    We truncate lines that are too long, unless we're dealing with
937    preprocessor lines or if the option -ffixed-line-length-none is set,
938    in which case we reallocate the buffer to fit the entire line, if
939    need be.
940    In fixed mode, we expand a tab that occurs within the statement
941    label region to expand to spaces that leave the next character in
942    the source region.
943    load_line returns whether the line was truncated.
944
945    NOTE: The error machinery isn't available at this point, so we can't
946          easily report line and column numbers consistent with other 
947          parts of gfortran.  */
948
949 static int
950 load_line (FILE * input, char **pbuf, int *pbuflen)
951 {
952   static int linenum = 0, current_line = 1;
953   int c, maxlen, i, preprocessor_flag, buflen = *pbuflen;
954   int trunc_flag = 0, seen_comment = 0;
955   int seen_printable = 0, seen_ampersand = 0;
956   char *buffer;
957
958   /* Determine the maximum allowed line length.
959      The default for free-form is GFC_MAX_LINE, for fixed-form or for
960      unknown form it is 72. Refer to the documentation in gfc_option_t.  */
961   if (gfc_current_form == FORM_FREE)
962     {
963       if (gfc_option.free_line_length == -1)
964         maxlen = GFC_MAX_LINE;
965       else
966         maxlen = gfc_option.free_line_length;
967     }
968   else if (gfc_current_form == FORM_FIXED)
969     {
970       if (gfc_option.fixed_line_length == -1)
971         maxlen = 72;
972       else
973         maxlen = gfc_option.fixed_line_length;
974     }
975   else
976     maxlen = 72;
977
978   if (*pbuf == NULL)
979     {
980       /* Allocate the line buffer, storing its length into buflen.  */
981       if (maxlen > 0)
982         buflen = maxlen;
983       else
984         buflen = GFC_MAX_LINE;
985
986       *pbuf = gfc_getmem (buflen + 1);
987     }
988
989   i = 0;
990   buffer = *pbuf;
991
992   preprocessor_flag = 0;
993   c = fgetc (input);
994   if (c == '#')
995     /* In order to not truncate preprocessor lines, we have to
996        remember that this is one.  */
997     preprocessor_flag = 1;
998   ungetc (c, input);
999
1000   for (;;)
1001     {
1002       c = fgetc (input);
1003
1004       if (c == EOF)
1005         break;
1006       if (c == '\n')
1007         {
1008           /* Check for illegal use of ampersand. See F95 Standard 3.3.1.3.  */
1009           if (gfc_current_form == FORM_FREE 
1010                 && !seen_printable && seen_ampersand)
1011             {
1012               if (pedantic)
1013                 gfc_error_now
1014                   ("'&' not allowed by itself in line %d", current_line);
1015               else
1016                 gfc_warning_now
1017                   ("'&' not allowed by itself in line %d", current_line);
1018             }
1019           break;
1020         }
1021
1022       if (c == '\r')
1023         continue;               /* Gobble characters.  */
1024       if (c == '\0')
1025         continue;
1026
1027       if (c == '\032')
1028         {
1029           /* Ctrl-Z ends the file.  */
1030           while (fgetc (input) != EOF);
1031           break;
1032         }
1033
1034       /* Check for illegal use of ampersand. See F95 Standard 3.3.1.3.  */
1035       if (c == '&')
1036         seen_ampersand = 1;
1037
1038       if ((c != ' ' && c != '&' && c != '!') || (c == '!' && !seen_ampersand))
1039         seen_printable = 1;
1040       
1041       if (gfc_current_form == FORM_FREE 
1042             && c == '!' && !seen_printable && seen_ampersand)
1043         {
1044           if (pedantic)
1045             gfc_error_now (
1046               "'&' not allowed by itself with comment in line %d", current_line);
1047           else
1048             gfc_warning_now (
1049               "'&' not allowed by itself with comment in line %d", current_line);
1050           seen_printable = 1;
1051         }
1052
1053       /* Is this a fixed-form comment?  */
1054       if (gfc_current_form == FORM_FIXED && i == 0
1055           && (c == '*' || c == 'c' || c == 'd'))
1056         seen_comment = 1;
1057
1058       if (gfc_current_form == FORM_FIXED && c == '\t' && i <= 6)
1059         {
1060           if (!gfc_option.warn_tabs && seen_comment == 0
1061               && current_line != linenum)
1062             {
1063               linenum = current_line;
1064               gfc_warning_now (
1065                 "Nonconforming tab character in column 1 of line %d", linenum);
1066             }
1067
1068           while (i <= 6)
1069             {
1070               *buffer++ = ' ';
1071               i++;
1072             }
1073
1074           continue;
1075         }
1076
1077       *buffer++ = c;
1078       i++;
1079
1080       if (maxlen == 0 || preprocessor_flag)
1081         {
1082           if (i >= buflen)
1083             {
1084               /* Reallocate line buffer to double size to hold the
1085                 overlong line.  */
1086               buflen = buflen * 2;
1087               *pbuf = xrealloc (*pbuf, buflen + 1);
1088               buffer = (*pbuf)+i;
1089             }
1090         }
1091       else if (i >= maxlen)
1092         {
1093           /* Truncate the rest of the line.  */
1094           for (;;)
1095             {
1096               c = fgetc (input);
1097               if (c == '\n' || c == EOF)
1098                 break;
1099
1100               trunc_flag = 1;
1101             }
1102
1103           ungetc ('\n', input);
1104         }
1105     }
1106
1107   /* Pad lines to the selected line length in fixed form.  */
1108   if (gfc_current_form == FORM_FIXED
1109       && gfc_option.fixed_line_length != 0
1110       && !preprocessor_flag
1111       && c != EOF)
1112     {
1113       while (i++ < maxlen)
1114         *buffer++ = ' ';
1115     }
1116
1117   *buffer = '\0';
1118   *pbuflen = buflen;
1119   current_line++;
1120
1121   return trunc_flag;
1122 }
1123
1124
1125 /* Get a gfc_file structure, initialize it and add it to
1126    the file stack.  */
1127
1128 static gfc_file *
1129 get_file (const char *name, enum lc_reason reason ATTRIBUTE_UNUSED)
1130 {
1131   gfc_file *f;
1132
1133   f = gfc_getmem (sizeof (gfc_file));
1134
1135   f->filename = gfc_getmem (strlen (name) + 1);
1136   strcpy (f->filename, name);
1137
1138   f->next = file_head;
1139   file_head = f;
1140
1141   f->included_by = current_file;
1142   if (current_file != NULL)
1143     f->inclusion_line = current_file->line;
1144
1145 #ifdef USE_MAPPED_LOCATION
1146   linemap_add (&line_table, reason, false, f->filename, 1);
1147 #endif
1148
1149   return f;
1150 }
1151
1152 /* Deal with a line from the C preprocessor. The
1153    initial octothorp has already been seen.  */
1154
1155 static void
1156 preprocessor_line (char *c)
1157 {
1158   bool flag[5];
1159   int i, line;
1160   char *filename;
1161   gfc_file *f;
1162   int escaped, unescape;
1163
1164   c++;
1165   while (*c == ' ' || *c == '\t')
1166     c++;
1167
1168   if (*c < '0' || *c > '9')
1169     goto bad_cpp_line;
1170
1171   line = atoi (c);
1172
1173   c = strchr (c, ' ');
1174   if (c == NULL)
1175     {
1176       /* No file name given.  Set new line number.  */
1177       current_file->line = line;
1178       return;
1179     }
1180
1181   /* Skip spaces.  */
1182   while (*c == ' ' || *c == '\t')
1183     c++;
1184
1185   /* Skip quote.  */
1186   if (*c != '"')
1187     goto bad_cpp_line;
1188   ++c;
1189
1190   filename = c;
1191
1192   /* Make filename end at quote.  */
1193   unescape = 0;
1194   escaped = false;
1195   while (*c && ! (! escaped && *c == '"'))
1196     {
1197       if (escaped)
1198         escaped = false;
1199       else if (*c == '\\')
1200         {
1201           escaped = true;
1202           unescape++;
1203         }
1204       ++c;
1205     }
1206
1207   if (! *c)
1208     /* Preprocessor line has no closing quote.  */
1209     goto bad_cpp_line;
1210
1211   *c++ = '\0';
1212
1213   /* Undo effects of cpp_quote_string.  */
1214   if (unescape)
1215     {
1216       char *s = filename;
1217       char *d = gfc_getmem (c - filename - unescape);
1218
1219       filename = d;
1220       while (*s)
1221         {
1222           if (*s == '\\')
1223             *d++ = *++s;
1224           else
1225             *d++ = *s;
1226           s++;
1227         }
1228       *d = '\0';
1229     }
1230
1231   /* Get flags.  */
1232
1233   flag[1] = flag[2] = flag[3] = flag[4] = false;
1234
1235   for (;;)
1236     {
1237       c = strchr (c, ' ');
1238       if (c == NULL)
1239         break;
1240
1241       c++;
1242       i = atoi (c);
1243
1244       if (1 <= i && i <= 4)
1245         flag[i] = true;
1246     }
1247
1248   /* Interpret flags.  */
1249
1250   if (flag[1]) /* Starting new file.  */
1251     {
1252       f = get_file (filename, LC_RENAME);
1253       f->up = current_file;
1254       current_file = f;
1255     }
1256
1257   if (flag[2]) /* Ending current file.  */
1258     {
1259       if (!current_file->up
1260           || strcmp (current_file->up->filename, filename) != 0)
1261         {
1262           gfc_warning_now ("%s:%d: file %s left but not entered",
1263                            current_file->filename, current_file->line,
1264                            filename);
1265           if (unescape)
1266             gfc_free (filename);
1267           return;
1268         }
1269       current_file = current_file->up;
1270     }
1271
1272   /* The name of the file can be a temporary file produced by
1273      cpp. Replace the name if it is different.  */
1274
1275   if (strcmp (current_file->filename, filename) != 0)
1276     {
1277       gfc_free (current_file->filename);
1278       current_file->filename = gfc_getmem (strlen (filename) + 1);
1279       strcpy (current_file->filename, filename);
1280     }
1281
1282   /* Set new line number.  */
1283   current_file->line = line;
1284   if (unescape)
1285     gfc_free (filename);
1286   return;
1287
1288  bad_cpp_line:
1289   gfc_warning_now ("%s:%d: Illegal preprocessor directive",
1290                    current_file->filename, current_file->line);
1291   current_file->line++;
1292 }
1293
1294
1295 static try load_file (const char *, bool);
1296
1297 /* include_line()-- Checks a line buffer to see if it is an include
1298    line.  If so, we call load_file() recursively to load the included
1299    file.  We never return a syntax error because a statement like
1300    "include = 5" is perfectly legal.  We return false if no include was
1301    processed or true if we matched an include.  */
1302
1303 static bool
1304 include_line (char *line)
1305 {
1306   char quote, *c, *begin, *stop;
1307
1308   c = line;
1309
1310   if (gfc_option.flag_openmp)
1311     {
1312       if (gfc_current_form == FORM_FREE)
1313         {
1314           while (*c == ' ' || *c == '\t')
1315             c++;
1316           if (*c == '!' && c[1] == '$' && (c[2] == ' ' || c[2] == '\t'))
1317             c += 3;
1318         }
1319       else
1320         {
1321           if ((*c == '!' || *c == 'c' || *c == 'C' || *c == '*')
1322               && c[1] == '$' && (c[2] == ' ' || c[2] == '\t'))
1323             c += 3;
1324         }
1325     }
1326
1327   while (*c == ' ' || *c == '\t')
1328     c++;
1329
1330   if (strncasecmp (c, "include", 7))
1331       return false;
1332
1333   c += 7;
1334   while (*c == ' ' || *c == '\t')
1335     c++;
1336
1337   /* Find filename between quotes.  */
1338   
1339   quote = *c++;
1340   if (quote != '"' && quote != '\'')
1341     return false;
1342
1343   begin = c;
1344
1345   while (*c != quote && *c != '\0')
1346     c++;
1347
1348   if (*c == '\0')
1349     return false;
1350
1351   stop = c++;
1352   
1353   while (*c == ' ' || *c == '\t')
1354     c++;
1355
1356   if (*c != '\0' && *c != '!')
1357     return false;
1358
1359   /* We have an include line at this point.  */
1360
1361   *stop = '\0'; /* It's ok to trash the buffer, as this line won't be
1362                    read by anything else.  */
1363
1364   load_file (begin, false);
1365   return true;
1366 }
1367
1368 /* Load a file into memory by calling load_line until the file ends.  */
1369
1370 static try
1371 load_file (const char *filename, bool initial)
1372 {
1373   char *line;
1374   gfc_linebuf *b;
1375   gfc_file *f;
1376   FILE *input;
1377   int len, line_len;
1378
1379   for (f = current_file; f; f = f->up)
1380     if (strcmp (filename, f->filename) == 0)
1381       {
1382         gfc_error_now ("File '%s' is being included recursively", filename);
1383         return FAILURE;
1384       }
1385
1386   if (initial)
1387     {
1388       if (gfc_src_file)
1389         {
1390           input = gfc_src_file;
1391           gfc_src_file = NULL;
1392         }
1393       else
1394         input = gfc_open_file (filename);
1395       if (input == NULL)
1396         {
1397           gfc_error_now ("Can't open file '%s'", filename);
1398           return FAILURE;
1399         }
1400     }
1401   else
1402     {
1403       input = gfc_open_included_file (filename, false);
1404       if (input == NULL)
1405         {
1406           gfc_error_now ("Can't open included file '%s'", filename);
1407           return FAILURE;
1408         }
1409     }
1410
1411   /* Load the file.  */
1412
1413   f = get_file (filename, initial ? LC_RENAME : LC_ENTER);
1414   f->up = current_file;
1415   current_file = f;
1416   current_file->line = 1;
1417   line = NULL;
1418   line_len = 0;
1419
1420   if (initial && gfc_src_preprocessor_lines[0])
1421     {
1422       preprocessor_line (gfc_src_preprocessor_lines[0]);
1423       gfc_free (gfc_src_preprocessor_lines[0]);
1424       gfc_src_preprocessor_lines[0] = NULL;
1425       if (gfc_src_preprocessor_lines[1])
1426         {
1427           preprocessor_line (gfc_src_preprocessor_lines[1]);
1428           gfc_free (gfc_src_preprocessor_lines[1]);
1429           gfc_src_preprocessor_lines[1] = NULL;
1430         }
1431     }
1432
1433   for (;;)
1434     {
1435       int trunc = load_line (input, &line, &line_len);
1436
1437       len = strlen (line);
1438       if (feof (input) && len == 0)
1439         break;
1440
1441       /* There are three things this line can be: a line of Fortran
1442          source, an include line or a C preprocessor directive.  */
1443
1444       if (line[0] == '#')
1445         {
1446           preprocessor_line (line);
1447           continue;
1448         }
1449
1450       if (include_line (line))
1451         {
1452           current_file->line++;
1453           continue;
1454         }
1455
1456       /* Add line.  */
1457
1458       b = gfc_getmem (gfc_linebuf_header_size + len + 1);
1459
1460 #ifdef USE_MAPPED_LOCATION
1461       b->location
1462         = linemap_line_start (&line_table, current_file->line++, 120);
1463 #else
1464       b->linenum = current_file->line++;
1465 #endif
1466       b->file = current_file;
1467       b->truncated = trunc;
1468       strcpy (b->line, line);
1469
1470       if (line_head == NULL)
1471         line_head = b;
1472       else
1473         line_tail->next = b;
1474
1475       line_tail = b;
1476     }
1477
1478   /* Release the line buffer allocated in load_line.  */
1479   gfc_free (line);
1480
1481   fclose (input);
1482
1483   current_file = current_file->up;
1484 #ifdef USE_MAPPED_LOCATION
1485   linemap_add (&line_table, LC_LEAVE, 0, NULL, 0);
1486 #endif
1487   return SUCCESS;
1488 }
1489
1490
1491 /* Open a new file and start scanning from that file. Returns SUCCESS
1492    if everything went OK, FAILURE otherwise.  If form == FORM_UKNOWN
1493    it tries to determine the source form from the filename, defaulting
1494    to free form.  */
1495
1496 try
1497 gfc_new_file (void)
1498 {
1499   try result;
1500
1501   result = load_file (gfc_source_file, true);
1502
1503   gfc_current_locus.lb = line_head;
1504   gfc_current_locus.nextc = (line_head == NULL) ? NULL : line_head->line;
1505
1506 #if 0 /* Debugging aid.  */
1507   for (; line_head; line_head = line_head->next)
1508     gfc_status ("%s:%3d %s\n", line_head->file->filename, 
1509 #ifdef USE_MAPPED_LOCATION
1510                 LOCATION_LINE (line_head->location),
1511 #else
1512                 line_head->linenum,
1513 #endif
1514                 line_head->line);
1515
1516   exit (0);
1517 #endif
1518
1519   return result;
1520 }
1521
1522 static char *
1523 unescape_filename (const char *ptr)
1524 {
1525   const char *p = ptr, *s;
1526   char *d, *ret;
1527   int escaped, unescape = 0;
1528
1529   /* Make filename end at quote.  */
1530   escaped = false;
1531   while (*p && ! (! escaped && *p == '"'))
1532     {
1533       if (escaped)
1534         escaped = false;
1535       else if (*p == '\\')
1536         {
1537           escaped = true;
1538           unescape++;
1539         }
1540       ++p;
1541     }
1542
1543   if (! *p || p[1])
1544     return NULL;
1545
1546   /* Undo effects of cpp_quote_string.  */
1547   s = ptr;
1548   d = gfc_getmem (p + 1 - ptr - unescape);
1549   ret = d;
1550
1551   while (s != p)
1552     {
1553       if (*s == '\\')
1554         *d++ = *++s;
1555       else
1556         *d++ = *s;
1557       s++;
1558     }
1559   *d = '\0';
1560   return ret;
1561 }
1562
1563 /* For preprocessed files, if the first tokens are of the form # NUM.
1564    handle the directives so we know the original file name.  */
1565
1566 const char *
1567 gfc_read_orig_filename (const char *filename, const char **canon_source_file)
1568 {
1569   int c, len;
1570   char *dirname;
1571
1572   gfc_src_file = gfc_open_file (filename);
1573   if (gfc_src_file == NULL)
1574     return NULL;
1575
1576   c = fgetc (gfc_src_file);
1577   ungetc (c, gfc_src_file);
1578
1579   if (c != '#')
1580     return NULL;
1581
1582   len = 0;
1583   load_line (gfc_src_file, &gfc_src_preprocessor_lines[0], &len);
1584
1585   if (strncmp (gfc_src_preprocessor_lines[0], "# 1 \"", 5) != 0)
1586     return NULL;
1587
1588   filename = unescape_filename (gfc_src_preprocessor_lines[0] + 5);
1589   if (filename == NULL)
1590     return NULL;
1591
1592   c = fgetc (gfc_src_file);
1593   ungetc (c, gfc_src_file);
1594
1595   if (c != '#')
1596     return filename;
1597
1598   len = 0;
1599   load_line (gfc_src_file, &gfc_src_preprocessor_lines[1], &len);
1600
1601   if (strncmp (gfc_src_preprocessor_lines[1], "# 1 \"", 5) != 0)
1602     return filename;
1603
1604   dirname = unescape_filename (gfc_src_preprocessor_lines[1] + 5);
1605   if (dirname == NULL)
1606     return filename;
1607
1608   len = strlen (dirname);
1609   if (len < 3 || dirname[len - 1] != '/' || dirname[len - 2] != '/')
1610     {
1611       gfc_free (dirname);
1612       return filename;
1613     }
1614   dirname[len - 2] = '\0';
1615   set_src_pwd (dirname);
1616
1617   if (! IS_ABSOLUTE_PATH (filename))
1618     {
1619       char *p = gfc_getmem (len + strlen (filename));
1620
1621       memcpy (p, dirname, len - 2);
1622       p[len - 2] = '/';
1623       strcpy (p + len - 1, filename);
1624       *canon_source_file = p;
1625     }
1626
1627   gfc_free (dirname);
1628   return filename;
1629 }