1 /* Character scanner.
2    Copyright (C) 2000-2020 Free Software Foundation, Inc.
3    Contributed by Andy Vaught
4 
5 This file is part of GCC.
6 
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
11 
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3.  If not see
19 <http://www.gnu.org/licenses/>.  */
20 
21 /* Set of subroutines to (ultimately) return the next character to the
22    various matching subroutines.  This file's job is to read files and
23    build up lines that are parsed by the parser.  This means that we
24    handle continuation lines and "include" lines.
25 
26    The first thing the scanner does is to load an entire file into
27    memory.  We load the entire file into memory for a couple reasons.
28    The first is that we want to be able to deal with nonseekable input
29    (pipes, stdin) and there is a lot of backing up involved during
30    parsing.
31 
32    The second is that we want to be able to print the locus of errors,
33    and an error on line 999999 could conflict with something on line
34    one.  Given nonseekable input, we've got to store the whole thing.
35 
36    One thing that helps are the column truncation limits that give us
37    an upper bound on the size of individual lines.  We don't store the
38    truncated stuff.
39 
40    From the scanner's viewpoint, the higher level subroutines ask for
41    new characters and do a lot of jumping backwards.  */
42 
43 #include "config.h"
44 #include "system.h"
45 #include "coretypes.h"
46 #include "gfortran.h"
47 #include "toplev.h"	/* For set_src_pwd.  */
48 #include "debug.h"
49 #include "options.h"
50 #include "cpp.h"
51 #include "scanner.h"
52 
53 /* List of include file search directories.  */
54 gfc_directorylist *include_dirs, *intrinsic_modules_dirs;
55 
56 static gfc_file *file_head, *current_file;
57 
58 static int continue_flag, end_flag, gcc_attribute_flag;
59 /* If !$omp/!$acc occurred in current comment line.  */
60 static int openmp_flag, openacc_flag;
61 static int continue_count, continue_line;
62 static locus openmp_locus;
63 static locus openacc_locus;
64 static locus gcc_attribute_locus;
65 
66 gfc_source_form gfc_current_form;
67 static gfc_linebuf *line_head, *line_tail;
68 
69 locus gfc_current_locus;
70 const char *gfc_source_file;
71 static FILE *gfc_src_file;
72 static gfc_char_t *gfc_src_preprocessor_lines[2];
73 
74 static struct gfc_file_change
75 {
76   const char *filename;
77   gfc_linebuf *lb;
78   int line;
79 } *file_changes;
80 size_t file_changes_cur, file_changes_count;
81 size_t file_changes_allocated;
82 
83 static gfc_char_t *last_error_char;
84 
85 /* Functions dealing with our wide characters (gfc_char_t) and
86    sequences of such characters.  */
87 
88 int
gfc_wide_fits_in_byte(gfc_char_t c)89 gfc_wide_fits_in_byte (gfc_char_t c)
90 {
91   return (c <= UCHAR_MAX);
92 }
93 
94 static inline int
wide_is_ascii(gfc_char_t c)95 wide_is_ascii (gfc_char_t c)
96 {
97   return (gfc_wide_fits_in_byte (c) && ((unsigned char) c & ~0x7f) == 0);
98 }
99 
100 int
gfc_wide_is_printable(gfc_char_t c)101 gfc_wide_is_printable (gfc_char_t c)
102 {
103   return (gfc_wide_fits_in_byte (c) && ISPRINT ((unsigned char) c));
104 }
105 
106 gfc_char_t
gfc_wide_tolower(gfc_char_t c)107 gfc_wide_tolower (gfc_char_t c)
108 {
109   return (wide_is_ascii (c) ? (gfc_char_t) TOLOWER((unsigned char) c) : c);
110 }
111 
112 gfc_char_t
gfc_wide_toupper(gfc_char_t c)113 gfc_wide_toupper (gfc_char_t c)
114 {
115   return (wide_is_ascii (c) ? (gfc_char_t) TOUPPER((unsigned char) c) : c);
116 }
117 
118 int
gfc_wide_is_digit(gfc_char_t c)119 gfc_wide_is_digit (gfc_char_t c)
120 {
121   return (c >= '0' && c <= '9');
122 }
123 
124 static inline int
wide_atoi(gfc_char_t * c)125 wide_atoi (gfc_char_t *c)
126 {
127 #define MAX_DIGITS 20
128   char buf[MAX_DIGITS+1];
129   int i = 0;
130 
131   while (gfc_wide_is_digit(*c) && i < MAX_DIGITS)
132     buf[i++] = *c++;
133   buf[i] = '\0';
134   return atoi (buf);
135 }
136 
137 size_t
gfc_wide_strlen(const gfc_char_t * str)138 gfc_wide_strlen (const gfc_char_t *str)
139 {
140   size_t i;
141 
142   for (i = 0; str[i]; i++)
143     ;
144 
145   return i;
146 }
147 
148 gfc_char_t *
gfc_wide_memset(gfc_char_t * b,gfc_char_t c,size_t len)149 gfc_wide_memset (gfc_char_t *b, gfc_char_t c, size_t len)
150 {
151   size_t i;
152 
153   for (i = 0; i < len; i++)
154     b[i] = c;
155 
156   return b;
157 }
158 
159 static gfc_char_t *
wide_strcpy(gfc_char_t * dest,const gfc_char_t * src)160 wide_strcpy (gfc_char_t *dest, const gfc_char_t *src)
161 {
162   gfc_char_t *d;
163 
164   for (d = dest; (*d = *src) != '\0'; ++src, ++d)
165     ;
166 
167   return dest;
168 }
169 
170 static gfc_char_t *
wide_strchr(const gfc_char_t * s,gfc_char_t c)171 wide_strchr (const gfc_char_t *s, gfc_char_t c)
172 {
173   do {
174     if (*s == c)
175       {
176         return CONST_CAST(gfc_char_t *, s);
177       }
178   } while (*s++);
179   return 0;
180 }
181 
182 char *
gfc_widechar_to_char(const gfc_char_t * s,int length)183 gfc_widechar_to_char (const gfc_char_t *s, int length)
184 {
185   size_t len, i;
186   char *res;
187 
188   if (s == NULL)
189     return NULL;
190 
191   /* Passing a negative length is used to indicate that length should be
192      calculated using gfc_wide_strlen().  */
193   len = (length >= 0 ? (size_t) length : gfc_wide_strlen (s));
194   res = XNEWVEC (char, len + 1);
195 
196   for (i = 0; i < len; i++)
197     {
198       gcc_assert (gfc_wide_fits_in_byte (s[i]));
199       res[i] = (unsigned char) s[i];
200     }
201 
202   res[len] = '\0';
203   return res;
204 }
205 
206 gfc_char_t *
gfc_char_to_widechar(const char * s)207 gfc_char_to_widechar (const char *s)
208 {
209   size_t len, i;
210   gfc_char_t *res;
211 
212   if (s == NULL)
213     return NULL;
214 
215   len = strlen (s);
216   res = gfc_get_wide_string (len + 1);
217 
218   for (i = 0; i < len; i++)
219     res[i] = (unsigned char) s[i];
220 
221   res[len] = '\0';
222   return res;
223 }
224 
225 static int
wide_strncmp(const gfc_char_t * s1,const char * s2,size_t n)226 wide_strncmp (const gfc_char_t *s1, const char *s2, size_t n)
227 {
228   gfc_char_t c1, c2;
229 
230   while (n-- > 0)
231     {
232       c1 = *s1++;
233       c2 = *s2++;
234       if (c1 != c2)
235 	return (c1 > c2 ? 1 : -1);
236       if (c1 == '\0')
237 	return 0;
238     }
239   return 0;
240 }
241 
242 int
gfc_wide_strncasecmp(const gfc_char_t * s1,const char * s2,size_t n)243 gfc_wide_strncasecmp (const gfc_char_t *s1, const char *s2, size_t n)
244 {
245   gfc_char_t c1, c2;
246 
247   while (n-- > 0)
248     {
249       c1 = gfc_wide_tolower (*s1++);
250       c2 = TOLOWER (*s2++);
251       if (c1 != c2)
252 	return (c1 > c2 ? 1 : -1);
253       if (c1 == '\0')
254 	return 0;
255     }
256   return 0;
257 }
258 
259 
260 /* Main scanner initialization.  */
261 
262 void
gfc_scanner_init_1(void)263 gfc_scanner_init_1 (void)
264 {
265   file_head = NULL;
266   line_head = NULL;
267   line_tail = NULL;
268 
269   continue_count = 0;
270   continue_line = 0;
271 
272   end_flag = 0;
273   last_error_char = NULL;
274 }
275 
276 
277 /* Main scanner destructor.  */
278 
279 void
gfc_scanner_done_1(void)280 gfc_scanner_done_1 (void)
281 {
282   gfc_linebuf *lb;
283   gfc_file *f;
284 
285   while(line_head != NULL)
286     {
287       lb = line_head->next;
288       free (line_head);
289       line_head = lb;
290     }
291 
292   while(file_head != NULL)
293     {
294       f = file_head->next;
295       free (file_head->filename);
296       free (file_head);
297       file_head = f;
298     }
299 }
300 
301 
302 /* Adds path to the list pointed to by list.  */
303 
304 static void
add_path_to_list(gfc_directorylist ** list,const char * path,bool use_for_modules,bool head,bool warn)305 add_path_to_list (gfc_directorylist **list, const char *path,
306 		  bool use_for_modules, bool head, bool warn)
307 {
308   gfc_directorylist *dir;
309   const char *p;
310   char *q;
311   struct stat st;
312   size_t len;
313   int i;
314 
315   p = path;
316   while (*p == ' ' || *p == '\t')  /* someone might do "-I include" */
317     if (*p++ == '\0')
318       return;
319 
320   /* Strip trailing directory separators from the path, as this
321      will confuse Windows systems.  */
322   len = strlen (p);
323   q = (char *) alloca (len + 1);
324   memcpy (q, p, len + 1);
325   i = len - 1;
326   while (i >=0 && IS_DIR_SEPARATOR (q[i]))
327     q[i--] = '\0';
328 
329   if (stat (q, &st))
330     {
331       if (errno != ENOENT)
332 	gfc_warning_now (0, "Include directory %qs: %s", path,
333 			 xstrerror(errno));
334       else if (warn)
335 	gfc_warning_now (OPT_Wmissing_include_dirs,
336 			 "Nonexistent include directory %qs", path);
337       return;
338     }
339   else if (!S_ISDIR (st.st_mode))
340     {
341       gfc_fatal_error ("%qs is not a directory", path);
342       return;
343     }
344 
345   if (head || *list == NULL)
346     {
347       dir = XCNEW (gfc_directorylist);
348       if (!head)
349         *list = dir;
350     }
351   else
352     {
353       dir = *list;
354       while (dir->next)
355 	dir = dir->next;
356 
357       dir->next = XCNEW (gfc_directorylist);
358       dir = dir->next;
359     }
360 
361   dir->next = head ? *list : NULL;
362   if (head)
363     *list = dir;
364   dir->use_for_modules = use_for_modules;
365   dir->path = XCNEWVEC (char, strlen (p) + 2);
366   strcpy (dir->path, p);
367   strcat (dir->path, "/");	/* make '/' last character */
368 }
369 
370 
371 void
gfc_add_include_path(const char * path,bool use_for_modules,bool file_dir,bool warn)372 gfc_add_include_path (const char *path, bool use_for_modules, bool file_dir,
373 		      bool warn)
374 {
375   add_path_to_list (&include_dirs, path, use_for_modules, file_dir, warn);
376 
377   /* For '#include "..."' these directories are automatically searched.  */
378   if (!file_dir)
379     gfc_cpp_add_include_path (xstrdup(path), true);
380 }
381 
382 
383 void
gfc_add_intrinsic_modules_path(const char * path)384 gfc_add_intrinsic_modules_path (const char *path)
385 {
386   add_path_to_list (&intrinsic_modules_dirs, path, true, false, false);
387 }
388 
389 
390 /* Release resources allocated for options.  */
391 
392 void
gfc_release_include_path(void)393 gfc_release_include_path (void)
394 {
395   gfc_directorylist *p;
396 
397   while (include_dirs != NULL)
398     {
399       p = include_dirs;
400       include_dirs = include_dirs->next;
401       free (p->path);
402       free (p);
403     }
404 
405   while (intrinsic_modules_dirs != NULL)
406     {
407       p = intrinsic_modules_dirs;
408       intrinsic_modules_dirs = intrinsic_modules_dirs->next;
409       free (p->path);
410       free (p);
411     }
412 
413   free (gfc_option.module_dir);
414 }
415 
416 
417 static FILE *
open_included_file(const char * name,gfc_directorylist * list,bool module,bool system)418 open_included_file (const char *name, gfc_directorylist *list,
419 		    bool module, bool system)
420 {
421   char *fullname;
422   gfc_directorylist *p;
423   FILE *f;
424 
425   for (p = list; p; p = p->next)
426     {
427       if (module && !p->use_for_modules)
428 	continue;
429 
430       fullname = (char *) alloca(strlen (p->path) + strlen (name) + 1);
431       strcpy (fullname, p->path);
432       strcat (fullname, name);
433 
434       f = gfc_open_file (fullname);
435       if (f != NULL)
436 	{
437 	  if (gfc_cpp_makedep ())
438 	    gfc_cpp_add_dep (fullname, system);
439 
440 	  return f;
441 	}
442     }
443 
444   return NULL;
445 }
446 
447 
448 /* Opens file for reading, searching through the include directories
449    given if necessary.  If the include_cwd argument is true, we try
450    to open the file in the current directory first.  */
451 
452 FILE *
gfc_open_included_file(const char * name,bool include_cwd,bool module)453 gfc_open_included_file (const char *name, bool include_cwd, bool module)
454 {
455   FILE *f = NULL;
456 
457   if (IS_ABSOLUTE_PATH (name) || include_cwd)
458     {
459       f = gfc_open_file (name);
460       if (f && gfc_cpp_makedep ())
461 	gfc_cpp_add_dep (name, false);
462     }
463 
464   if (!f)
465     f = open_included_file (name, include_dirs, module, false);
466 
467   return f;
468 }
469 
470 
471 /* Test to see if we're at the end of the main source file.  */
472 
473 int
gfc_at_end(void)474 gfc_at_end (void)
475 {
476   return end_flag;
477 }
478 
479 
480 /* Test to see if we're at the end of the current file.  */
481 
482 int
gfc_at_eof(void)483 gfc_at_eof (void)
484 {
485   if (gfc_at_end ())
486     return 1;
487 
488   if (line_head == NULL)
489     return 1;			/* Null file */
490 
491   if (gfc_current_locus.lb == NULL)
492     return 1;
493 
494   return 0;
495 }
496 
497 
498 /* Test to see if we're at the beginning of a new line.  */
499 
500 int
gfc_at_bol(void)501 gfc_at_bol (void)
502 {
503   if (gfc_at_eof ())
504     return 1;
505 
506   return (gfc_current_locus.nextc == gfc_current_locus.lb->line);
507 }
508 
509 
510 /* Test to see if we're at the end of a line.  */
511 
512 int
gfc_at_eol(void)513 gfc_at_eol (void)
514 {
515   if (gfc_at_eof ())
516     return 1;
517 
518   return (*gfc_current_locus.nextc == '\0');
519 }
520 
521 static void
add_file_change(const char * filename,int line)522 add_file_change (const char *filename, int line)
523 {
524   if (file_changes_count == file_changes_allocated)
525     {
526       if (file_changes_allocated)
527 	file_changes_allocated *= 2;
528       else
529 	file_changes_allocated = 16;
530       file_changes = XRESIZEVEC (struct gfc_file_change, file_changes,
531 				 file_changes_allocated);
532     }
533   file_changes[file_changes_count].filename = filename;
534   file_changes[file_changes_count].lb = NULL;
535   file_changes[file_changes_count++].line = line;
536 }
537 
538 static void
report_file_change(gfc_linebuf * lb)539 report_file_change (gfc_linebuf *lb)
540 {
541   size_t c = file_changes_cur;
542   while (c < file_changes_count
543 	 && file_changes[c].lb == lb)
544     {
545       if (file_changes[c].filename)
546 	(*debug_hooks->start_source_file) (file_changes[c].line,
547 					   file_changes[c].filename);
548       else
549 	(*debug_hooks->end_source_file) (file_changes[c].line);
550       ++c;
551     }
552   file_changes_cur = c;
553 }
554 
555 void
gfc_start_source_files(void)556 gfc_start_source_files (void)
557 {
558   /* If the debugger wants the name of the main source file,
559      we give it.  */
560   if (debug_hooks->start_end_main_source_file)
561     (*debug_hooks->start_source_file) (0, gfc_source_file);
562 
563   file_changes_cur = 0;
564   report_file_change (gfc_current_locus.lb);
565 }
566 
567 void
gfc_end_source_files(void)568 gfc_end_source_files (void)
569 {
570   report_file_change (NULL);
571 
572   if (debug_hooks->start_end_main_source_file)
573     (*debug_hooks->end_source_file) (0);
574 }
575 
576 /* Advance the current line pointer to the next line.  */
577 
578 void
gfc_advance_line(void)579 gfc_advance_line (void)
580 {
581   if (gfc_at_end ())
582     return;
583 
584   if (gfc_current_locus.lb == NULL)
585     {
586       end_flag = 1;
587       return;
588     }
589 
590   if (gfc_current_locus.lb->next
591       && !gfc_current_locus.lb->next->dbg_emitted)
592     {
593       report_file_change (gfc_current_locus.lb->next);
594       gfc_current_locus.lb->next->dbg_emitted = true;
595     }
596 
597   gfc_current_locus.lb = gfc_current_locus.lb->next;
598 
599   if (gfc_current_locus.lb != NULL)
600     gfc_current_locus.nextc = gfc_current_locus.lb->line;
601   else
602     {
603       gfc_current_locus.nextc = NULL;
604       end_flag = 1;
605     }
606 }
607 
608 
609 /* Get the next character from the input, advancing gfc_current_file's
610    locus.  When we hit the end of the line or the end of the file, we
611    start returning a '\n' in order to complete the current statement.
612    No Fortran line conventions are implemented here.
613 
614    Requiring explicit advances to the next line prevents the parse
615    pointer from being on the wrong line if the current statement ends
616    prematurely.  */
617 
618 static gfc_char_t
next_char(void)619 next_char (void)
620 {
621   gfc_char_t c;
622 
623   if (gfc_current_locus.nextc == NULL)
624     return '\n';
625 
626   c = *gfc_current_locus.nextc++;
627   if (c == '\0')
628     {
629       gfc_current_locus.nextc--; /* Remain on this line.  */
630       c = '\n';
631     }
632 
633   return c;
634 }
635 
636 
637 /* Skip a comment.  When we come here the parse pointer is positioned
638    immediately after the comment character.  If we ever implement
639    compiler directives within comments, here is where we parse the
640    directive.  */
641 
642 static void
skip_comment_line(void)643 skip_comment_line (void)
644 {
645   gfc_char_t c;
646 
647   do
648     {
649       c = next_char ();
650     }
651   while (c != '\n');
652 
653   gfc_advance_line ();
654 }
655 
656 
657 int
gfc_define_undef_line(void)658 gfc_define_undef_line (void)
659 {
660   char *tmp;
661 
662   /* All lines beginning with '#' are either #define or #undef.  */
663   if (debug_info_level != DINFO_LEVEL_VERBOSE || gfc_peek_ascii_char () != '#')
664     return 0;
665 
666   if (wide_strncmp (gfc_current_locus.nextc, "#define ", 8) == 0)
667     {
668       tmp = gfc_widechar_to_char (&gfc_current_locus.nextc[8], -1);
669       (*debug_hooks->define) (gfc_linebuf_linenum (gfc_current_locus.lb),
670 			      tmp);
671       free (tmp);
672     }
673 
674   if (wide_strncmp (gfc_current_locus.nextc, "#undef ", 7) == 0)
675     {
676       tmp = gfc_widechar_to_char (&gfc_current_locus.nextc[7], -1);
677       (*debug_hooks->undef) (gfc_linebuf_linenum (gfc_current_locus.lb),
678 			     tmp);
679       free (tmp);
680     }
681 
682   /* Skip the rest of the line.  */
683   skip_comment_line ();
684 
685   return 1;
686 }
687 
688 
689 /* Return true if GCC$ was matched.  */
690 static bool
skip_gcc_attribute(locus start)691 skip_gcc_attribute (locus start)
692 {
693   bool r = false;
694   char c;
695   locus old_loc = gfc_current_locus;
696 
697   if ((c = next_char ()) == 'g' || c == 'G')
698     if ((c = next_char ()) == 'c' || c == 'C')
699       if ((c = next_char ()) == 'c' || c == 'C')
700 	if ((c = next_char ()) == '$')
701 	  r = true;
702 
703   if (r == false)
704     gfc_current_locus = old_loc;
705   else
706    {
707       gcc_attribute_flag = 1;
708       gcc_attribute_locus = old_loc;
709       gfc_current_locus = start;
710    }
711 
712   return r;
713 }
714 
715 /* Return true if CC was matched.  */
716 static bool
skip_free_oacc_sentinel(locus start,locus old_loc)717 skip_free_oacc_sentinel (locus start, locus old_loc)
718 {
719   bool r = false;
720   char c;
721 
722   if ((c = next_char ()) == 'c' || c == 'C')
723     if ((c = next_char ()) == 'c' || c == 'C')
724       r = true;
725 
726   if (r)
727    {
728       if ((c = next_char ()) == ' ' || c == '\t'
729 	  || continue_flag)
730 	{
731 	  while (gfc_is_whitespace (c))
732 	    c = next_char ();
733 	  if (c != '\n' && c != '!')
734 	    {
735 	      openacc_flag = 1;
736 	      openacc_locus = old_loc;
737 	      gfc_current_locus = start;
738 	    }
739 	  else
740 	    r = false;
741 	}
742       else
743 	{
744 	  gfc_warning_now (0, "!$ACC at %C starts a commented "
745 			   "line as it neither is followed "
746 			   "by a space nor is a "
747 			   "continuation line");
748 	  r = false;
749 	}
750    }
751 
752   return r;
753 }
754 
755 /* Return true if MP was matched.  */
756 static bool
skip_free_omp_sentinel(locus start,locus old_loc)757 skip_free_omp_sentinel (locus start, locus old_loc)
758 {
759   bool r = false;
760   char c;
761 
762   if ((c = next_char ()) == 'm' || c == 'M')
763     if ((c = next_char ()) == 'p' || c == 'P')
764       r = true;
765 
766   if (r)
767    {
768       if ((c = next_char ()) == ' ' || c == '\t'
769 	  || continue_flag)
770 	{
771 	  while (gfc_is_whitespace (c))
772 	    c = next_char ();
773 	  if (c != '\n' && c != '!')
774 	    {
775 	      openmp_flag = 1;
776 	      openmp_locus = old_loc;
777 	      gfc_current_locus = start;
778 	    }
779 	  else
780 	    r = false;
781 	}
782       else
783 	{
784 	  gfc_warning_now (0, "!$OMP at %C starts a commented "
785 			   "line as it neither is followed "
786 			   "by a space nor is a "
787 			   "continuation line");
788 	  r = false;
789 	}
790    }
791 
792   return r;
793 }
794 
795 /* Comment lines are null lines, lines containing only blanks or lines
796    on which the first nonblank line is a '!'.
797    Return true if !$ openmp or openacc conditional compilation sentinel was
798    seen.  */
799 
800 static bool
skip_free_comments(void)801 skip_free_comments (void)
802 {
803   locus start;
804   gfc_char_t c;
805   int at_bol;
806 
807   for (;;)
808     {
809       at_bol = gfc_at_bol ();
810       start = gfc_current_locus;
811       if (gfc_at_eof ())
812 	break;
813 
814       do
815 	c = next_char ();
816       while (gfc_is_whitespace (c));
817 
818       if (c == '\n')
819 	{
820 	  gfc_advance_line ();
821 	  continue;
822 	}
823 
824       if (c == '!')
825 	{
826 	  /* Keep the !GCC$ line.  */
827 	  if (at_bol && skip_gcc_attribute (start))
828 	    return false;
829 
830 	  /* If -fopenmp/-fopenacc, we need to handle here 2 things:
831 	     1) don't treat !$omp/!$acc as comments, but directives
832 	     2) handle OpenMP/OpenACC conditional compilation, where
833 		!$ should be treated as 2 spaces (for initial lines
834 		only if followed by space).  */
835 	  if (at_bol)
836 	  {
837 	    if ((flag_openmp || flag_openmp_simd)
838 		&& flag_openacc)
839 	      {
840 		locus old_loc = gfc_current_locus;
841 		if (next_char () == '$')
842 		  {
843 		    c = next_char ();
844 		    if (c == 'o' || c == 'O')
845 		      {
846 			if (skip_free_omp_sentinel (start, old_loc))
847 			  return false;
848 			gfc_current_locus = old_loc;
849 			next_char ();
850 			c = next_char ();
851 		      }
852 		    else if (c == 'a' || c == 'A')
853 		      {
854 			if (skip_free_oacc_sentinel (start, old_loc))
855 			  return false;
856 			gfc_current_locus = old_loc;
857 			next_char ();
858 			c = next_char ();
859 		      }
860 		    if (continue_flag || c == ' ' || c == '\t')
861 		      {
862 			gfc_current_locus = old_loc;
863 			next_char ();
864 			openmp_flag = openacc_flag = 0;
865 			return true;
866 		      }
867 		  }
868 		gfc_current_locus = old_loc;
869 	      }
870 	    else if ((flag_openmp || flag_openmp_simd)
871 		     && !flag_openacc)
872 	      {
873 		locus old_loc = gfc_current_locus;
874 		if (next_char () == '$')
875 		  {
876 		    c = next_char ();
877 		    if (c == 'o' || c == 'O')
878 		      {
879 			if (skip_free_omp_sentinel (start, old_loc))
880 			  return false;
881 			gfc_current_locus = old_loc;
882 			next_char ();
883 			c = next_char ();
884 		      }
885 		    if (continue_flag || c == ' ' || c == '\t')
886 		      {
887 			gfc_current_locus = old_loc;
888 			next_char ();
889 			openmp_flag = 0;
890 			return true;
891 		      }
892 		  }
893 		gfc_current_locus = old_loc;
894 	      }
895 	    else if (flag_openacc
896 		     && !(flag_openmp || flag_openmp_simd))
897 	      {
898 		locus old_loc = gfc_current_locus;
899 		if (next_char () == '$')
900 		  {
901 		    c = next_char ();
902 		      if (c == 'a' || c == 'A')
903 			{
904 			  if (skip_free_oacc_sentinel (start, old_loc))
905 			    return false;
906 			  gfc_current_locus = old_loc;
907 			  next_char();
908 			  c = next_char();
909 			}
910 		      if (continue_flag || c == ' ' || c == '\t')
911 			{
912 			  gfc_current_locus = old_loc;
913 			  next_char();
914 			  openacc_flag = 0;
915 			  return true;
916 			}
917 		  }
918 		gfc_current_locus = old_loc;
919 	      }
920 	  }
921 	  skip_comment_line ();
922 	  continue;
923 	}
924 
925       break;
926     }
927 
928   if (openmp_flag && at_bol)
929     openmp_flag = 0;
930 
931   if (openacc_flag && at_bol)
932     openacc_flag = 0;
933 
934   gcc_attribute_flag = 0;
935   gfc_current_locus = start;
936   return false;
937 }
938 
939 /* Return true if MP was matched in fixed form.  */
940 static bool
skip_fixed_omp_sentinel(locus * start)941 skip_fixed_omp_sentinel (locus *start)
942 {
943   gfc_char_t c;
944   if (((c = next_char ()) == 'm' || c == 'M')
945       && ((c = next_char ()) == 'p' || c == 'P'))
946     {
947       c = next_char ();
948       if (c != '\n'
949 	  && (continue_flag
950 	      || c == ' ' || c == '\t' || c == '0'))
951 	{
952 	  do
953 	    c = next_char ();
954 	  while (gfc_is_whitespace (c));
955 	  if (c != '\n' && c != '!')
956 	    {
957 	      /* Canonicalize to *$omp.  */
958 	      *start->nextc = '*';
959 	      openmp_flag = 1;
960 	      gfc_current_locus = *start;
961 	      return true;
962 	    }
963 	}
964     }
965   return false;
966 }
967 
968 /* Return true if CC was matched in fixed form.  */
969 static bool
skip_fixed_oacc_sentinel(locus * start)970 skip_fixed_oacc_sentinel (locus *start)
971 {
972   gfc_char_t c;
973   if (((c = next_char ()) == 'c' || c == 'C')
974       && ((c = next_char ()) == 'c' || c == 'C'))
975     {
976       c = next_char ();
977       if (c != '\n'
978 	  && (continue_flag
979 	      || c == ' ' || c == '\t' || c == '0'))
980 	{
981 	  do
982 	    c = next_char ();
983 	  while (gfc_is_whitespace (c));
984 	  if (c != '\n' && c != '!')
985 	    {
986 	      /* Canonicalize to *$acc.  */
987 	      *start->nextc = '*';
988 	      openacc_flag = 1;
989 	      gfc_current_locus = *start;
990 	      return true;
991 	    }
992 	}
993     }
994   return false;
995 }
996 
997 /* Skip comment lines in fixed source mode.  We have the same rules as
998    in skip_free_comment(), except that we can have a 'c', 'C' or '*'
999    in column 1, and a '!' cannot be in column 6.  Also, we deal with
1000    lines with 'd' or 'D' in column 1, if the user requested this.  */
1001 
1002 static void
skip_fixed_comments(void)1003 skip_fixed_comments (void)
1004 {
1005   locus start;
1006   int col;
1007   gfc_char_t c;
1008 
1009   if (! gfc_at_bol ())
1010     {
1011       start = gfc_current_locus;
1012       if (! gfc_at_eof ())
1013 	{
1014 	  do
1015 	    c = next_char ();
1016 	  while (gfc_is_whitespace (c));
1017 
1018 	  if (c == '\n')
1019 	    gfc_advance_line ();
1020 	  else if (c == '!')
1021 	    skip_comment_line ();
1022 	}
1023 
1024       if (! gfc_at_bol ())
1025 	{
1026 	  gfc_current_locus = start;
1027 	  return;
1028 	}
1029     }
1030 
1031   for (;;)
1032     {
1033       start = gfc_current_locus;
1034       if (gfc_at_eof ())
1035 	break;
1036 
1037       c = next_char ();
1038       if (c == '\n')
1039 	{
1040 	  gfc_advance_line ();
1041 	  continue;
1042 	}
1043 
1044       if (c == '!' || c == 'c' || c == 'C' || c == '*')
1045 	{
1046 	  if (skip_gcc_attribute (start))
1047 	    {
1048 	      /* Canonicalize to *$omp.  */
1049 	      *start.nextc = '*';
1050 	      return;
1051 	    }
1052 
1053 	  if (gfc_current_locus.lb != NULL
1054 	      && continue_line < gfc_linebuf_linenum (gfc_current_locus.lb))
1055 	    continue_line = gfc_linebuf_linenum (gfc_current_locus.lb);
1056 
1057 	  /* If -fopenmp/-fopenacc, we need to handle here 2 things:
1058 	     1) don't treat !$omp/!$acc|c$omp/c$acc|*$omp / *$acc as comments,
1059 		but directives
1060 	     2) handle OpenMP/OpenACC conditional compilation, where
1061 		!$|c$|*$ should be treated as 2 spaces if the characters
1062 		in columns 3 to 6 are valid fixed form label columns
1063 		characters.  */
1064 	  if ((flag_openmp || flag_openmp_simd) && !flag_openacc)
1065 	    {
1066 	      if (next_char () == '$')
1067 		{
1068 		  c = next_char ();
1069 		  if (c == 'o' || c == 'O')
1070 		    {
1071 		      if (skip_fixed_omp_sentinel (&start))
1072 			return;
1073 		    }
1074 		  else
1075 		    goto check_for_digits;
1076 		}
1077 	      gfc_current_locus = start;
1078 	    }
1079 
1080 	  if (flag_openacc && !(flag_openmp || flag_openmp_simd))
1081 	    {
1082 	      if (next_char () == '$')
1083 		{
1084 		  c = next_char ();
1085 		  if (c == 'a' || c == 'A')
1086 		    {
1087 		      if (skip_fixed_oacc_sentinel (&start))
1088 			return;
1089 		    }
1090 		  else
1091 		    goto check_for_digits;
1092 		}
1093 	      gfc_current_locus = start;
1094 	    }
1095 
1096 	  if (flag_openacc || flag_openmp || flag_openmp_simd)
1097 	    {
1098 	      if (next_char () == '$')
1099 		{
1100 		  c = next_char ();
1101 		  if (c == 'a' || c == 'A')
1102 		    {
1103 		      if (skip_fixed_oacc_sentinel (&start))
1104 			return;
1105 		    }
1106 		  else if (c == 'o' || c == 'O')
1107 		    {
1108 		      if (skip_fixed_omp_sentinel (&start))
1109 			return;
1110 		    }
1111 		  else
1112 		    goto check_for_digits;
1113 		}
1114 	      gfc_current_locus = start;
1115 	    }
1116 
1117 	  skip_comment_line ();
1118 	  continue;
1119 
1120 	  gcc_unreachable ();
1121 check_for_digits:
1122 	  {
1123 	    int digit_seen = 0;
1124 
1125 	    for (col = 3; col < 6; col++, c = next_char ())
1126 	      if (c == ' ')
1127 		continue;
1128 	      else if (c == '\t')
1129 		{
1130 		  col = 6;
1131 		  break;
1132 		}
1133 	      else if (c < '0' || c > '9')
1134 		break;
1135 	      else
1136 		digit_seen = 1;
1137 
1138 	    if (col == 6 && c != '\n'
1139 		&& ((continue_flag && !digit_seen)
1140 		    || c == ' ' || c == '\t' || c == '0'))
1141 	      {
1142 		gfc_current_locus = start;
1143 		start.nextc[0] = ' ';
1144 		start.nextc[1] = ' ';
1145 		continue;
1146 	      }
1147 	    }
1148 	  skip_comment_line ();
1149 	  continue;
1150 	}
1151 
1152       if (gfc_option.flag_d_lines != -1 && (c == 'd' || c == 'D'))
1153 	{
1154 	  if (gfc_option.flag_d_lines == 0)
1155 	    {
1156 	      skip_comment_line ();
1157 	      continue;
1158 	    }
1159 	  else
1160 	    *start.nextc = c = ' ';
1161 	}
1162 
1163       col = 1;
1164 
1165       while (gfc_is_whitespace (c))
1166 	{
1167 	  c = next_char ();
1168 	  col++;
1169 	}
1170 
1171       if (c == '\n')
1172 	{
1173 	  gfc_advance_line ();
1174 	  continue;
1175 	}
1176 
1177       if (col != 6 && c == '!')
1178 	{
1179 	  if (gfc_current_locus.lb != NULL
1180 	      && continue_line < gfc_linebuf_linenum (gfc_current_locus.lb))
1181 	    continue_line = gfc_linebuf_linenum (gfc_current_locus.lb);
1182 	  skip_comment_line ();
1183 	  continue;
1184 	}
1185 
1186       break;
1187     }
1188 
1189   openmp_flag = 0;
1190   openacc_flag = 0;
1191   gcc_attribute_flag = 0;
1192   gfc_current_locus = start;
1193 }
1194 
1195 
1196 /* Skips the current line if it is a comment.  */
1197 
1198 void
gfc_skip_comments(void)1199 gfc_skip_comments (void)
1200 {
1201   if (gfc_current_form == FORM_FREE)
1202     skip_free_comments ();
1203   else
1204     skip_fixed_comments ();
1205 }
1206 
1207 
1208 /* Get the next character from the input, taking continuation lines
1209    and end-of-line comments into account.  This implies that comment
1210    lines between continued lines must be eaten here.  For higher-level
1211    subroutines, this flattens continued lines into a single logical
1212    line.  The in_string flag denotes whether we're inside a character
1213    context or not.  */
1214 
1215 gfc_char_t
gfc_next_char_literal(gfc_instring in_string)1216 gfc_next_char_literal (gfc_instring in_string)
1217 {
1218   locus old_loc;
1219   int i, prev_openmp_flag, prev_openacc_flag;
1220   gfc_char_t c;
1221 
1222   continue_flag = 0;
1223   prev_openacc_flag = prev_openmp_flag = 0;
1224 
1225 restart:
1226   c = next_char ();
1227   if (gfc_at_end ())
1228     {
1229       continue_count = 0;
1230       return c;
1231     }
1232 
1233   if (gfc_current_form == FORM_FREE)
1234     {
1235       bool openmp_cond_flag;
1236 
1237       if (!in_string && c == '!')
1238 	{
1239 	  if (gcc_attribute_flag
1240 	      && memcmp (&gfc_current_locus, &gcc_attribute_locus,
1241 		 sizeof (gfc_current_locus)) == 0)
1242 	    goto done;
1243 
1244 	  if (openmp_flag
1245 	      && memcmp (&gfc_current_locus, &openmp_locus,
1246 		 sizeof (gfc_current_locus)) == 0)
1247 	    goto done;
1248 
1249 	  if (openacc_flag
1250 	      && memcmp (&gfc_current_locus, &openacc_locus,
1251 	         sizeof (gfc_current_locus)) == 0)
1252 	    goto done;
1253 
1254 	  /* This line can't be continued */
1255 	  do
1256 	    {
1257 	      c = next_char ();
1258 	    }
1259 	  while (c != '\n');
1260 
1261 	  /* Avoid truncation warnings for comment ending lines.  */
1262 	  gfc_current_locus.lb->truncated = 0;
1263 
1264 	  goto done;
1265 	}
1266 
1267       /* Check to see if the continuation line was truncated.  */
1268       if (warn_line_truncation && gfc_current_locus.lb != NULL
1269 	  && gfc_current_locus.lb->truncated)
1270 	{
1271 	  int maxlen = flag_free_line_length;
1272 	  gfc_char_t *current_nextc = gfc_current_locus.nextc;
1273 
1274 	  gfc_current_locus.lb->truncated = 0;
1275 	  gfc_current_locus.nextc =  gfc_current_locus.lb->line + maxlen;
1276 	  gfc_warning_now (OPT_Wline_truncation,
1277 			   "Line truncated at %L", &gfc_current_locus);
1278 	  gfc_current_locus.nextc = current_nextc;
1279 	}
1280 
1281       if (c != '&')
1282 	goto done;
1283 
1284       /* If the next nonblank character is a ! or \n, we've got a
1285 	 continuation line.  */
1286       old_loc = gfc_current_locus;
1287 
1288       c = next_char ();
1289       while (gfc_is_whitespace (c))
1290 	c = next_char ();
1291 
1292       /* Character constants to be continued cannot have commentary
1293 	 after the '&'. However, there are cases where we may think we
1294 	 are still in a string and we are looking for a possible
1295 	 doubled quote and we end up here. See PR64506.  */
1296 
1297       if (in_string && c != '\n')
1298 	{
1299 	  gfc_current_locus = old_loc;
1300 	  c = '&';
1301 	  goto done;
1302 	}
1303 
1304       if (c != '!' && c != '\n')
1305 	{
1306 	  gfc_current_locus = old_loc;
1307 	  c = '&';
1308 	  goto done;
1309 	}
1310 
1311       if (flag_openmp)
1312 	prev_openmp_flag = openmp_flag;
1313       if (flag_openacc)
1314 	prev_openacc_flag = openacc_flag;
1315 
1316       /* This can happen if the input file changed or via cpp's #line
1317 	 without getting reset (e.g. via input_stmt). It also happens
1318 	 when pre-including files via -fpre-include=.  */
1319       if (continue_count == 0
1320 	  && gfc_current_locus.lb
1321 	  && continue_line > gfc_linebuf_linenum (gfc_current_locus.lb) + 1)
1322 	continue_line = gfc_linebuf_linenum (gfc_current_locus.lb) + 1;
1323 
1324       continue_flag = 1;
1325       if (c == '!')
1326 	skip_comment_line ();
1327       else
1328 	gfc_advance_line ();
1329 
1330       if (gfc_at_eof ())
1331 	goto not_continuation;
1332 
1333       /* We've got a continuation line.  If we are on the very next line after
1334 	 the last continuation, increment the continuation line count and
1335 	 check whether the limit has been exceeded.  */
1336       if (gfc_linebuf_linenum (gfc_current_locus.lb) == continue_line + 1)
1337 	{
1338 	  if (++continue_count == gfc_option.max_continue_free)
1339 	    {
1340 	      if (gfc_notification_std (GFC_STD_GNU) || pedantic)
1341 		gfc_warning (0, "Limit of %d continuations exceeded in "
1342 			     "statement at %C", gfc_option.max_continue_free);
1343 	    }
1344 	}
1345 
1346       /* Now find where it continues. First eat any comment lines.  */
1347       openmp_cond_flag = skip_free_comments ();
1348 
1349       if (gfc_current_locus.lb != NULL
1350 	  && continue_line < gfc_linebuf_linenum (gfc_current_locus.lb))
1351 	continue_line = gfc_linebuf_linenum (gfc_current_locus.lb);
1352 
1353       if (flag_openmp)
1354 	if (prev_openmp_flag != openmp_flag && !openacc_flag)
1355 	  {
1356 	    gfc_current_locus = old_loc;
1357 	    openmp_flag = prev_openmp_flag;
1358 	    c = '&';
1359 	    goto done;
1360 	  }
1361 
1362       if (flag_openacc)
1363 	if (prev_openacc_flag != openacc_flag && !openmp_flag)
1364 	  {
1365 	    gfc_current_locus = old_loc;
1366 	    openacc_flag = prev_openacc_flag;
1367 	    c = '&';
1368 	    goto done;
1369 	  }
1370 
1371       /* Now that we have a non-comment line, probe ahead for the
1372 	 first non-whitespace character.  If it is another '&', then
1373 	 reading starts at the next character, otherwise we must back
1374 	 up to where the whitespace started and resume from there.  */
1375 
1376       old_loc = gfc_current_locus;
1377 
1378       c = next_char ();
1379       while (gfc_is_whitespace (c))
1380 	c = next_char ();
1381 
1382       if (openmp_flag && !openacc_flag)
1383 	{
1384 	  for (i = 0; i < 5; i++, c = next_char ())
1385 	    {
1386 	      gcc_assert (gfc_wide_tolower (c) == (unsigned char) "!$omp"[i]);
1387 	      if (i == 4)
1388 		old_loc = gfc_current_locus;
1389 	    }
1390 	  while (gfc_is_whitespace (c))
1391 	    c = next_char ();
1392 	}
1393       if (openacc_flag && !openmp_flag)
1394 	{
1395 	  for (i = 0; i < 5; i++, c = next_char ())
1396 	    {
1397 	      gcc_assert (gfc_wide_tolower (c) == (unsigned char) "!$acc"[i]);
1398 	      if (i == 4)
1399 		old_loc = gfc_current_locus;
1400 	    }
1401 	  while (gfc_is_whitespace (c))
1402 	    c = next_char ();
1403 	}
1404 
1405       /* In case we have an OpenMP directive continued by OpenACC
1406 	 sentinel, or vice versa, we get both openmp_flag and
1407 	 openacc_flag on.  */
1408 
1409       if (openacc_flag && openmp_flag)
1410 	{
1411 	  int is_openmp = 0;
1412 	  for (i = 0; i < 5; i++, c = next_char ())
1413 	    {
1414 	      if (gfc_wide_tolower (c) != (unsigned char) "!$acc"[i])
1415 		is_openmp = 1;
1416 	      if (i == 4)
1417 		old_loc = gfc_current_locus;
1418 	    }
1419 	  gfc_error (is_openmp
1420 		     ? G_("Wrong OpenACC continuation at %C: "
1421 			  "expected !$ACC, got !$OMP")
1422 		     : G_("Wrong OpenMP continuation at %C: "
1423 			  "expected !$OMP, got !$ACC"));
1424 	}
1425 
1426       if (c != '&')
1427 	{
1428 	  if (in_string && gfc_current_locus.nextc)
1429 	    {
1430 	      gfc_current_locus.nextc--;
1431 	      if (warn_ampersand && in_string == INSTRING_WARN)
1432 		gfc_warning (OPT_Wampersand,
1433 			     "Missing %<&%> in continued character "
1434 			     "constant at %C");
1435 	    }
1436 	  else if (!in_string && (c == '\'' || c == '"'))
1437 	      goto done;
1438 	  /* Both !$omp and !$ -fopenmp continuation lines have & on the
1439 	     continuation line only optionally.  */
1440 	  else if (openmp_flag || openacc_flag || openmp_cond_flag)
1441 	    {
1442 	      if (gfc_current_locus.nextc)
1443 		  gfc_current_locus.nextc--;
1444 	    }
1445 	  else
1446 	    {
1447 	      c = ' ';
1448 	      gfc_current_locus = old_loc;
1449 	      goto done;
1450 	    }
1451 	}
1452     }
1453   else /* Fixed form.  */
1454     {
1455       /* Fixed form continuation.  */
1456       if (in_string != INSTRING_WARN && c == '!')
1457 	{
1458 	  /* Skip comment at end of line.  */
1459 	  do
1460 	    {
1461 	      c = next_char ();
1462 	    }
1463 	  while (c != '\n');
1464 
1465 	  /* Avoid truncation warnings for comment ending lines.  */
1466 	  gfc_current_locus.lb->truncated = 0;
1467 	}
1468 
1469       if (c != '\n')
1470 	goto done;
1471 
1472       /* Check to see if the continuation line was truncated.  */
1473       if (warn_line_truncation && gfc_current_locus.lb != NULL
1474 	  && gfc_current_locus.lb->truncated)
1475 	{
1476 	  gfc_current_locus.lb->truncated = 0;
1477 	  gfc_warning_now (OPT_Wline_truncation,
1478 			   "Line truncated at %L", &gfc_current_locus);
1479 	}
1480 
1481       if (flag_openmp)
1482 	prev_openmp_flag = openmp_flag;
1483       if (flag_openacc)
1484 	prev_openacc_flag = openacc_flag;
1485 
1486       /* This can happen if the input file changed or via cpp's #line
1487 	 without getting reset (e.g. via input_stmt). It also happens
1488 	 when pre-including files via -fpre-include=.  */
1489       if (continue_count == 0
1490 	  && gfc_current_locus.lb
1491 	  && continue_line > gfc_linebuf_linenum (gfc_current_locus.lb) + 1)
1492 	continue_line = gfc_linebuf_linenum (gfc_current_locus.lb) + 1;
1493 
1494       continue_flag = 1;
1495       old_loc = gfc_current_locus;
1496 
1497       gfc_advance_line ();
1498       skip_fixed_comments ();
1499 
1500       /* See if this line is a continuation line.  */
1501       if (flag_openmp && openmp_flag != prev_openmp_flag && !openacc_flag)
1502 	{
1503 	  openmp_flag = prev_openmp_flag;
1504 	  goto not_continuation;
1505 	}
1506       if (flag_openacc && openacc_flag != prev_openacc_flag && !openmp_flag)
1507 	{
1508 	  openacc_flag = prev_openacc_flag;
1509 	  goto not_continuation;
1510 	}
1511 
1512       /* In case we have an OpenMP directive continued by OpenACC
1513 	 sentinel, or vice versa, we get both openmp_flag and
1514 	 openacc_flag on.  */
1515       if (openacc_flag && openmp_flag)
1516 	{
1517 	  int is_openmp = 0;
1518 	  for (i = 0; i < 5; i++)
1519 	    {
1520 	      c = next_char ();
1521 	      if (gfc_wide_tolower (c) != (unsigned char) "*$acc"[i])
1522 		is_openmp = 1;
1523 	    }
1524 	  gfc_error (is_openmp
1525 		     ? G_("Wrong OpenACC continuation at %C: "
1526 			  "expected !$ACC, got !$OMP")
1527 		     : G_("Wrong OpenMP continuation at %C: "
1528 			  "expected !$OMP, got !$ACC"));
1529 	}
1530       else if (!openmp_flag && !openacc_flag)
1531 	for (i = 0; i < 5; i++)
1532 	  {
1533 	    c = next_char ();
1534 	    if (c != ' ')
1535 	      goto not_continuation;
1536 	  }
1537       else if (openmp_flag)
1538 	for (i = 0; i < 5; i++)
1539 	  {
1540 	    c = next_char ();
1541 	    if (gfc_wide_tolower (c) != (unsigned char) "*$omp"[i])
1542 	      goto not_continuation;
1543 	  }
1544       else if (openacc_flag)
1545 	for (i = 0; i < 5; i++)
1546 	  {
1547 	    c = next_char ();
1548 	    if (gfc_wide_tolower (c) != (unsigned char) "*$acc"[i])
1549 	      goto not_continuation;
1550 	  }
1551 
1552       c = next_char ();
1553       if (c == '0' || c == ' ' || c == '\n')
1554 	goto not_continuation;
1555 
1556       /* We've got a continuation line.  If we are on the very next line after
1557 	 the last continuation, increment the continuation line count and
1558 	 check whether the limit has been exceeded.  */
1559       if (gfc_linebuf_linenum (gfc_current_locus.lb) == continue_line + 1)
1560 	{
1561 	  if (++continue_count == gfc_option.max_continue_fixed)
1562 	    {
1563 	      if (gfc_notification_std (GFC_STD_GNU) || pedantic)
1564 		gfc_warning (0, "Limit of %d continuations exceeded in "
1565 			     "statement at %C",
1566 			     gfc_option.max_continue_fixed);
1567 	    }
1568 	}
1569 
1570       if (gfc_current_locus.lb != NULL
1571 	  && continue_line < gfc_linebuf_linenum (gfc_current_locus.lb))
1572 	continue_line = gfc_linebuf_linenum (gfc_current_locus.lb);
1573     }
1574 
1575   /* Ready to read first character of continuation line, which might
1576      be another continuation line!  */
1577   goto restart;
1578 
1579 not_continuation:
1580   c = '\n';
1581   gfc_current_locus = old_loc;
1582   end_flag = 0;
1583 
1584 done:
1585   if (c == '\n')
1586     continue_count = 0;
1587   continue_flag = 0;
1588   return c;
1589 }
1590 
1591 
1592 /* Get the next character of input, folded to lowercase.  In fixed
1593    form mode, we also ignore spaces.  When matcher subroutines are
1594    parsing character literals, they have to call
1595    gfc_next_char_literal().  */
1596 
1597 gfc_char_t
gfc_next_char(void)1598 gfc_next_char (void)
1599 {
1600   gfc_char_t c;
1601 
1602   do
1603     {
1604       c = gfc_next_char_literal (NONSTRING);
1605     }
1606   while (gfc_current_form == FORM_FIXED && gfc_is_whitespace (c));
1607 
1608   return gfc_wide_tolower (c);
1609 }
1610 
1611 char
gfc_next_ascii_char(void)1612 gfc_next_ascii_char (void)
1613 {
1614   gfc_char_t c = gfc_next_char ();
1615 
1616   return (gfc_wide_fits_in_byte (c) ? (unsigned char) c
1617 				    : (unsigned char) UCHAR_MAX);
1618 }
1619 
1620 
1621 gfc_char_t
gfc_peek_char(void)1622 gfc_peek_char (void)
1623 {
1624   locus old_loc;
1625   gfc_char_t c;
1626 
1627   old_loc = gfc_current_locus;
1628   c = gfc_next_char ();
1629   gfc_current_locus = old_loc;
1630 
1631   return c;
1632 }
1633 
1634 
1635 char
gfc_peek_ascii_char(void)1636 gfc_peek_ascii_char (void)
1637 {
1638   gfc_char_t c = gfc_peek_char ();
1639 
1640   return (gfc_wide_fits_in_byte (c) ? (unsigned char) c
1641 				    : (unsigned char) UCHAR_MAX);
1642 }
1643 
1644 
1645 /* Recover from an error.  We try to get past the current statement
1646    and get lined up for the next.  The next statement follows a '\n'
1647    or a ';'.  We also assume that we are not within a character
1648    constant, and deal with finding a '\'' or '"'.  */
1649 
1650 void
gfc_error_recovery(void)1651 gfc_error_recovery (void)
1652 {
1653   gfc_char_t c, delim;
1654 
1655   if (gfc_at_eof ())
1656     return;
1657 
1658   for (;;)
1659     {
1660       c = gfc_next_char ();
1661       if (c == '\n' || c == ';')
1662 	break;
1663 
1664       if (c != '\'' && c != '"')
1665 	{
1666 	  if (gfc_at_eof ())
1667 	    break;
1668 	  continue;
1669 	}
1670       delim = c;
1671 
1672       for (;;)
1673 	{
1674 	  c = next_char ();
1675 
1676 	  if (c == delim)
1677 	    break;
1678 	  if (c == '\n')
1679 	    return;
1680 	  if (c == '\\')
1681 	    {
1682 	      c = next_char ();
1683 	      if (c == '\n')
1684 		return;
1685 	    }
1686 	}
1687       if (gfc_at_eof ())
1688 	break;
1689     }
1690 }
1691 
1692 
1693 /* Read ahead until the next character to be read is not whitespace.  */
1694 
1695 void
gfc_gobble_whitespace(void)1696 gfc_gobble_whitespace (void)
1697 {
1698   static int linenum = 0;
1699   locus old_loc;
1700   gfc_char_t c;
1701 
1702   do
1703     {
1704       old_loc = gfc_current_locus;
1705       c = gfc_next_char_literal (NONSTRING);
1706       /* Issue a warning for nonconforming tabs.  We keep track of the line
1707 	 number because the Fortran matchers will often back up and the same
1708 	 line will be scanned multiple times.  */
1709       if (warn_tabs && c == '\t')
1710 	{
1711 	  int cur_linenum = LOCATION_LINE (gfc_current_locus.lb->location);
1712 	  if (cur_linenum != linenum)
1713 	    {
1714 	      linenum = cur_linenum;
1715 	      gfc_warning_now (OPT_Wtabs, "Nonconforming tab character at %C");
1716 	    }
1717 	}
1718     }
1719   while (gfc_is_whitespace (c));
1720 
1721   if (!ISPRINT(c) && c != '\n' && last_error_char != gfc_current_locus.nextc)
1722     {
1723       char buf[20];
1724       last_error_char = gfc_current_locus.nextc;
1725       snprintf (buf, 20, "%2.2X", c);
1726       gfc_error_now ("Invalid character 0x%s at %C", buf);
1727     }
1728 
1729   gfc_current_locus = old_loc;
1730 }
1731 
1732 
1733 /* Load a single line into pbuf.
1734 
1735    If pbuf points to a NULL pointer, it is allocated.
1736    We truncate lines that are too long, unless we're dealing with
1737    preprocessor lines or if the option -ffixed-line-length-none is set,
1738    in which case we reallocate the buffer to fit the entire line, if
1739    need be.
1740    In fixed mode, we expand a tab that occurs within the statement
1741    label region to expand to spaces that leave the next character in
1742    the source region.
1743 
1744    If first_char is not NULL, it's a pointer to a single char value holding
1745    the first character of the line, which has already been read by the
1746    caller.  This avoids the use of ungetc().
1747 
1748    load_line returns whether the line was truncated.
1749 
1750    NOTE: The error machinery isn't available at this point, so we can't
1751 	 easily report line and column numbers consistent with other
1752 	 parts of gfortran.  */
1753 
1754 static int
load_line(FILE * input,gfc_char_t ** pbuf,int * pbuflen,const int * first_char)1755 load_line (FILE *input, gfc_char_t **pbuf, int *pbuflen, const int *first_char)
1756 {
1757   int c, maxlen, i, preprocessor_flag, buflen = *pbuflen;
1758   int quoted = ' ', comment_ix = -1;
1759   bool seen_comment = false;
1760   bool first_comment = true;
1761   bool trunc_flag = false;
1762   bool seen_printable = false;
1763   bool seen_ampersand = false;
1764   bool found_tab = false;
1765   bool warned_tabs = false;
1766   gfc_char_t *buffer;
1767 
1768   /* Determine the maximum allowed line length.  */
1769   if (gfc_current_form == FORM_FREE)
1770     maxlen = flag_free_line_length;
1771   else if (gfc_current_form == FORM_FIXED)
1772     maxlen = flag_fixed_line_length;
1773   else
1774     maxlen = 72;
1775 
1776   if (*pbuf == NULL)
1777     {
1778       /* Allocate the line buffer, storing its length into buflen.
1779 	 Note that if maxlen==0, indicating that arbitrary-length lines
1780 	 are allowed, the buffer will be reallocated if this length is
1781 	 insufficient; since 132 characters is the length of a standard
1782 	 free-form line, we use that as a starting guess.  */
1783       if (maxlen > 0)
1784 	buflen = maxlen;
1785       else
1786 	buflen = 132;
1787 
1788       *pbuf = gfc_get_wide_string (buflen + 1);
1789     }
1790 
1791   i = 0;
1792   buffer = *pbuf;
1793 
1794   if (first_char)
1795     c = *first_char;
1796   else
1797     c = getc (input);
1798 
1799   /* In order to not truncate preprocessor lines, we have to
1800      remember that this is one.  */
1801   preprocessor_flag = (c == '#');
1802 
1803   for (;;)
1804     {
1805       if (c == EOF)
1806 	break;
1807 
1808       if (c == '\n')
1809 	{
1810 	  /* Check for illegal use of ampersand. See F95 Standard 3.3.1.3.  */
1811 	  if (gfc_current_form == FORM_FREE
1812 	      && !seen_printable && seen_ampersand)
1813 	    {
1814 	      if (pedantic)
1815 		gfc_error_now ("%<&%> not allowed by itself in line %d",
1816 			       current_file->line);
1817 	      else
1818 		gfc_warning_now (0, "%<&%> not allowed by itself in line %d",
1819 				 current_file->line);
1820 	    }
1821 	  break;
1822 	}
1823 
1824       if (c == '\r' || c == '\0')
1825 	goto next_char;			/* Gobble characters.  */
1826 
1827       if (c == '&')
1828 	{
1829 	  if (seen_ampersand)
1830 	    {
1831 	      seen_ampersand = false;
1832 	      seen_printable = true;
1833 	    }
1834 	  else
1835 	    seen_ampersand = true;
1836 	}
1837 
1838       if ((c != '&' && c != '!' && c != ' ') || (c == '!' && !seen_ampersand))
1839 	seen_printable = true;
1840 
1841       /* Is this a fixed-form comment?  */
1842       if (gfc_current_form == FORM_FIXED && i == 0
1843 	  && (c == '*' || c == 'c' || c == 'C'
1844 	      || (gfc_option.flag_d_lines != -1 && (c == 'd' || c == 'D'))))
1845 	{
1846 	  seen_comment = true;
1847 	  comment_ix = i;
1848 	}
1849 
1850       if (quoted == ' ')
1851 	{
1852 	  if (c == '\'' || c == '"')
1853 	    quoted = c;
1854 	}
1855       else if (c == quoted)
1856 	quoted = ' ';
1857 
1858       /* Is this a free-form comment?  */
1859       if (c == '!' && quoted == ' ')
1860 	{
1861 	  if (seen_comment)
1862 	    first_comment = false;
1863 	  seen_comment = true;
1864 	  comment_ix = i;
1865 	}
1866 
1867       /* For truncation and tab warnings, set seen_comment to false if one has
1868 	 either an OpenMP or OpenACC directive - or a !GCC$ attribute.  If
1869 	 OpenMP is enabled, use '!$' as as conditional compilation sentinel
1870 	 and OpenMP directive ('!$omp').  */
1871       if (seen_comment && first_comment && flag_openmp && comment_ix + 1 == i
1872 	  && c == '$')
1873 	first_comment = seen_comment = false;
1874       if (seen_comment && first_comment && comment_ix + 4 == i)
1875 	{
1876 	  if (((*pbuf)[comment_ix+1] == 'g' || (*pbuf)[comment_ix+1] == 'G')
1877 	      && ((*pbuf)[comment_ix+2] == 'c' || (*pbuf)[comment_ix+2] == 'C')
1878 	      && ((*pbuf)[comment_ix+3] == 'c' || (*pbuf)[comment_ix+3] == 'C')
1879 	      && (*pbuf)[comment_ix+4] == '$')
1880 	    first_comment = seen_comment = false;
1881 	  if (flag_openacc
1882 	      && (*pbuf)[comment_ix+1] == '$'
1883 	      && ((*pbuf)[comment_ix+2] == 'a' || (*pbuf)[comment_ix+2] == 'A')
1884 	      && ((*pbuf)[comment_ix+3] == 'c' || (*pbuf)[comment_ix+3] == 'C')
1885 	      && ((*pbuf)[comment_ix+4] == 'c' || (*pbuf)[comment_ix+4] == 'C'))
1886 	    first_comment = seen_comment = false;
1887 	}
1888 
1889       /* Vendor extension: "<tab>1" marks a continuation line.  */
1890       if (found_tab)
1891 	{
1892 	  found_tab = false;
1893 	  if (c >= '1' && c <= '9')
1894 	    {
1895 	      *(buffer-1) = c;
1896 	      goto next_char;
1897 	    }
1898 	}
1899 
1900       if (gfc_current_form == FORM_FIXED && c == '\t' && i < 6)
1901 	{
1902 	  found_tab = true;
1903 
1904 	  if (warn_tabs && seen_comment == 0 && !warned_tabs)
1905 	    {
1906 	      warned_tabs = true;
1907 	      gfc_warning_now (OPT_Wtabs,
1908 			       "Nonconforming tab character in column %d "
1909 			       "of line %d", i + 1, current_file->line);
1910 	    }
1911 
1912 	  while (i < 6)
1913 	    {
1914 	      *buffer++ = ' ';
1915 	      i++;
1916 	    }
1917 
1918 	  goto next_char;
1919 	}
1920 
1921       *buffer++ = c;
1922       i++;
1923 
1924       if (maxlen == 0 || preprocessor_flag)
1925 	{
1926 	  if (i >= buflen)
1927 	    {
1928 	      /* Reallocate line buffer to double size to hold the
1929 		overlong line.  */
1930 	      buflen = buflen * 2;
1931 	      *pbuf = XRESIZEVEC (gfc_char_t, *pbuf, (buflen + 1));
1932 	      buffer = (*pbuf) + i;
1933 	    }
1934 	}
1935       else if (i >= maxlen)
1936 	{
1937 	  bool trunc_warn = true;
1938 
1939 	  /* Enhancement, if the very next non-space character is an ampersand
1940 	     or comment that we would otherwise warn about, don't mark as
1941 	     truncated.  */
1942 
1943 	  /* Truncate the rest of the line.  */
1944 	  for (;;)
1945 	    {
1946 	      c = getc (input);
1947 	      if (c == '\r' || c == ' ')
1948 	        continue;
1949 
1950 	      if (c == '\n' || c == EOF)
1951 		break;
1952 
1953 	      if (!trunc_warn && c != '!')
1954 		trunc_warn = true;
1955 
1956 	      if (trunc_warn && ((gfc_current_form == FORM_FIXED && c == '&')
1957 		  || c == '!'))
1958 		trunc_warn = false;
1959 
1960 	      if (c == '!')
1961 		seen_comment = 1;
1962 
1963 	      if (trunc_warn && !seen_comment)
1964 		trunc_flag = 1;
1965 	    }
1966 
1967 	  c = '\n';
1968 	  continue;
1969 	}
1970 
1971 next_char:
1972       c = getc (input);
1973     }
1974 
1975   /* Pad lines to the selected line length in fixed form.  */
1976   if (gfc_current_form == FORM_FIXED
1977       && flag_fixed_line_length != 0
1978       && flag_pad_source
1979       && !preprocessor_flag
1980       && c != EOF)
1981     {
1982       while (i++ < maxlen)
1983 	*buffer++ = ' ';
1984     }
1985 
1986   *buffer = '\0';
1987   *pbuflen = buflen;
1988 
1989   return trunc_flag;
1990 }
1991 
1992 
1993 /* Get a gfc_file structure, initialize it and add it to
1994    the file stack.  */
1995 
1996 static gfc_file *
get_file(const char * name,enum lc_reason reason)1997 get_file (const char *name, enum lc_reason reason)
1998 {
1999   gfc_file *f;
2000 
2001   f = XCNEW (gfc_file);
2002 
2003   f->filename = xstrdup (name);
2004 
2005   f->next = file_head;
2006   file_head = f;
2007 
2008   f->up = current_file;
2009   if (current_file != NULL)
2010     f->inclusion_line = current_file->line;
2011 
2012   linemap_add (line_table, reason, false, f->filename, 1);
2013 
2014   return f;
2015 }
2016 
2017 
2018 /* Deal with a line from the C preprocessor. The
2019    initial octothorp has already been seen.  */
2020 
2021 static void
preprocessor_line(gfc_char_t * c)2022 preprocessor_line (gfc_char_t *c)
2023 {
2024   bool flag[5];
2025   int i, line;
2026   gfc_char_t *wide_filename;
2027   gfc_file *f;
2028   int escaped, unescape;
2029   char *filename;
2030 
2031   c++;
2032   while (*c == ' ' || *c == '\t')
2033     c++;
2034 
2035   if (*c < '0' || *c > '9')
2036     goto bad_cpp_line;
2037 
2038   line = wide_atoi (c);
2039 
2040   c = wide_strchr (c, ' ');
2041   if (c == NULL)
2042     {
2043       /* No file name given.  Set new line number.  */
2044       current_file->line = line;
2045       return;
2046     }
2047 
2048   /* Skip spaces.  */
2049   while (*c == ' ' || *c == '\t')
2050     c++;
2051 
2052   /* Skip quote.  */
2053   if (*c != '"')
2054     goto bad_cpp_line;
2055   ++c;
2056 
2057   wide_filename = c;
2058 
2059   /* Make filename end at quote.  */
2060   unescape = 0;
2061   escaped = false;
2062   while (*c && ! (!escaped && *c == '"'))
2063     {
2064       if (escaped)
2065 	escaped = false;
2066       else if (*c == '\\')
2067 	{
2068 	  escaped = true;
2069 	  unescape++;
2070 	}
2071       ++c;
2072     }
2073 
2074   if (! *c)
2075     /* Preprocessor line has no closing quote.  */
2076     goto bad_cpp_line;
2077 
2078   *c++ = '\0';
2079 
2080   /* Undo effects of cpp_quote_string.  */
2081   if (unescape)
2082     {
2083       gfc_char_t *s = wide_filename;
2084       gfc_char_t *d = gfc_get_wide_string (c - wide_filename - unescape);
2085 
2086       wide_filename = d;
2087       while (*s)
2088 	{
2089 	  if (*s == '\\')
2090 	    *d++ = *++s;
2091 	  else
2092 	    *d++ = *s;
2093 	  s++;
2094 	}
2095       *d = '\0';
2096     }
2097 
2098   /* Get flags.  */
2099 
2100   flag[1] = flag[2] = flag[3] = flag[4] = false;
2101 
2102   for (;;)
2103     {
2104       c = wide_strchr (c, ' ');
2105       if (c == NULL)
2106 	break;
2107 
2108       c++;
2109       i = wide_atoi (c);
2110 
2111       if (i >= 1 && i <= 4)
2112 	flag[i] = true;
2113     }
2114 
2115   /* Convert the filename in wide characters into a filename in narrow
2116      characters.  */
2117   filename = gfc_widechar_to_char (wide_filename, -1);
2118 
2119   /* Interpret flags.  */
2120 
2121   if (flag[1]) /* Starting new file.  */
2122     {
2123       f = get_file (filename, LC_RENAME);
2124       add_file_change (f->filename, f->inclusion_line);
2125       current_file = f;
2126     }
2127 
2128   if (flag[2]) /* Ending current file.  */
2129     {
2130       if (!current_file->up
2131 	  || filename_cmp (current_file->up->filename, filename) != 0)
2132 	{
2133 	  linemap_line_start (line_table, current_file->line, 80);
2134 	  /* ??? One could compute the exact column where the filename
2135 	     starts and compute the exact location here.  */
2136 	  gfc_warning_now_at (linemap_position_for_column (line_table, 1),
2137 			      0, "file %qs left but not entered",
2138 			      filename);
2139 	  current_file->line++;
2140 	  if (unescape)
2141 	    free (wide_filename);
2142 	  free (filename);
2143 	  return;
2144 	}
2145 
2146       add_file_change (NULL, line);
2147       current_file = current_file->up;
2148       linemap_add (line_table, LC_RENAME, false, current_file->filename,
2149 		   current_file->line);
2150     }
2151 
2152   /* The name of the file can be a temporary file produced by
2153      cpp. Replace the name if it is different.  */
2154 
2155   if (filename_cmp (current_file->filename, filename) != 0)
2156     {
2157        /* FIXME: we leak the old filename because a pointer to it may be stored
2158           in the linemap.  Alternative could be using GC or updating linemap to
2159           point to the new name, but there is no API for that currently.  */
2160       current_file->filename = xstrdup (filename);
2161 
2162       /* We need to tell the linemap API that the filename changed.  Just
2163 	 changing current_file is insufficient.  */
2164       linemap_add (line_table, LC_RENAME, false, current_file->filename, line);
2165     }
2166 
2167   /* Set new line number.  */
2168   current_file->line = line;
2169   if (unescape)
2170     free (wide_filename);
2171   free (filename);
2172   return;
2173 
2174  bad_cpp_line:
2175   linemap_line_start (line_table, current_file->line, 80);
2176   /* ??? One could compute the exact column where the directive
2177      starts and compute the exact location here.  */
2178   gfc_warning_now_at (linemap_position_for_column (line_table, 2), 0,
2179 		      "Illegal preprocessor directive");
2180   current_file->line++;
2181 }
2182 
2183 
2184 static bool load_file (const char *, const char *, bool);
2185 
2186 /* include_line()-- Checks a line buffer to see if it is an include
2187    line.  If so, we call load_file() recursively to load the included
2188    file.  We never return a syntax error because a statement like
2189    "include = 5" is perfectly legal.  We return 0 if no include was
2190    processed, 1 if we matched an include or -1 if include was
2191    partially processed, but will need continuation lines.  */
2192 
2193 static int
include_line(gfc_char_t * line)2194 include_line (gfc_char_t *line)
2195 {
2196   gfc_char_t quote, *c, *begin, *stop;
2197   char *filename;
2198   const char *include = "include";
2199   bool allow_continuation = flag_dec_include;
2200   int i;
2201 
2202   c = line;
2203 
2204   if (flag_openmp || flag_openmp_simd)
2205     {
2206       if (gfc_current_form == FORM_FREE)
2207 	{
2208 	  while (*c == ' ' || *c == '\t')
2209 	    c++;
2210 	  if (*c == '!' && c[1] == '$' && (c[2] == ' ' || c[2] == '\t'))
2211 	    c += 3;
2212 	}
2213       else
2214 	{
2215 	  if ((*c == '!' || *c == 'c' || *c == 'C' || *c == '*')
2216 	      && c[1] == '$' && c[2] == ' ')
2217 	    c += 3;
2218 	}
2219     }
2220 
2221   if (gfc_current_form == FORM_FREE)
2222     {
2223       while (*c == ' ' || *c == '\t')
2224 	c++;
2225       if (gfc_wide_strncasecmp (c, "include", 7))
2226 	{
2227 	  if (!allow_continuation)
2228 	    return 0;
2229 	  for (i = 0; i < 7; ++i)
2230 	    {
2231 	      gfc_char_t c1 = gfc_wide_tolower (*c);
2232 	      if (c1 != (unsigned char) include[i])
2233 		break;
2234 	      c++;
2235 	    }
2236 	  if (i == 0 || *c != '&')
2237 	    return 0;
2238 	  c++;
2239 	  while (*c == ' ' || *c == '\t')
2240 	    c++;
2241 	  if (*c == '\0' || *c == '!')
2242 	    return -1;
2243 	  return 0;
2244 	}
2245 
2246       c += 7;
2247     }
2248   else
2249     {
2250       while (*c == ' ' || *c == '\t')
2251 	c++;
2252       if (flag_dec_include && *c == '0' && c - line == 5)
2253 	{
2254 	  c++;
2255 	  while (*c == ' ' || *c == '\t')
2256 	    c++;
2257 	}
2258       if (c - line < 6)
2259 	allow_continuation = false;
2260       for (i = 0; i < 7; ++i)
2261 	{
2262 	  gfc_char_t c1 = gfc_wide_tolower (*c);
2263 	  if (c1 != (unsigned char) include[i])
2264 	    break;
2265 	  c++;
2266 	  while (*c == ' ' || *c == '\t')
2267 	    c++;
2268 	}
2269       if (!allow_continuation)
2270 	{
2271 	  if (i != 7)
2272 	    return 0;
2273 	}
2274       else if (i != 7)
2275 	{
2276 	  if (i == 0)
2277 	    return 0;
2278 
2279 	  /* At the end of line or comment this might be continued.  */
2280 	  if (*c == '\0' || *c == '!')
2281 	    return -1;
2282 
2283 	  return 0;
2284 	}
2285     }
2286 
2287   while (*c == ' ' || *c == '\t')
2288     c++;
2289 
2290   /* Find filename between quotes.  */
2291 
2292   quote = *c++;
2293   if (quote != '"' && quote != '\'')
2294     {
2295       if (allow_continuation)
2296 	{
2297 	  if (gfc_current_form == FORM_FREE)
2298 	    {
2299 	      if (quote == '&')
2300 		{
2301 		  while (*c == ' ' || *c == '\t')
2302 		    c++;
2303 		  if (*c == '\0' || *c == '!')
2304 		    return -1;
2305 		}
2306 	    }
2307 	  else if (quote == '\0' || quote == '!')
2308 	    return -1;
2309 	}
2310       return 0;
2311     }
2312 
2313   begin = c;
2314 
2315   bool cont = false;
2316   while (*c != quote && *c != '\0')
2317     {
2318       if (allow_continuation && gfc_current_form == FORM_FREE)
2319 	{
2320 	  if (*c == '&')
2321 	    cont = true;
2322 	  else if (*c != ' ' && *c != '\t')
2323 	    cont = false;
2324 	}
2325       c++;
2326     }
2327 
2328   if (*c == '\0')
2329     {
2330       if (allow_continuation
2331 	  && (cont || gfc_current_form != FORM_FREE))
2332 	return -1;
2333       return 0;
2334     }
2335 
2336   stop = c++;
2337 
2338   while (*c == ' ' || *c == '\t')
2339     c++;
2340 
2341   if (*c != '\0' && *c != '!')
2342     return 0;
2343 
2344   /* We have an include line at this point.  */
2345 
2346   *stop = '\0'; /* It's ok to trash the buffer, as this line won't be
2347 		   read by anything else.  */
2348 
2349   filename = gfc_widechar_to_char (begin, -1);
2350   if (!load_file (filename, NULL, false))
2351     exit (FATAL_EXIT_CODE);
2352 
2353   free (filename);
2354   return 1;
2355 }
2356 
2357 /* Similarly, but try to parse an INCLUDE statement, using gfc_next_char etc.
2358    APIs.  Return 1 if recognized as valid INCLUDE statement and load_file has
2359    been called, 0 if it is not a valid INCLUDE statement and -1 if eof has
2360    been encountered while parsing it.  */
2361 static int
include_stmt(gfc_linebuf * b)2362 include_stmt (gfc_linebuf *b)
2363 {
2364   int ret = 0, i, length;
2365   const char *include = "include";
2366   gfc_char_t c, quote = 0;
2367   locus str_locus;
2368   char *filename;
2369 
2370   continue_flag = 0;
2371   end_flag = 0;
2372   gcc_attribute_flag = 0;
2373   openmp_flag = 0;
2374   openacc_flag = 0;
2375   continue_count = 0;
2376   continue_line = 0;
2377   gfc_current_locus.lb = b;
2378   gfc_current_locus.nextc = b->line;
2379 
2380   gfc_skip_comments ();
2381   gfc_gobble_whitespace ();
2382 
2383   for (i = 0; i < 7; i++)
2384     {
2385       c = gfc_next_char ();
2386       if (c != (unsigned char) include[i])
2387 	{
2388 	  if (gfc_current_form == FORM_FIXED
2389 	      && i == 0
2390 	      && c == '0'
2391 	      && gfc_current_locus.nextc == b->line + 6)
2392 	    {
2393 	      gfc_gobble_whitespace ();
2394 	      i--;
2395 	      continue;
2396 	    }
2397 	  gcc_assert (i != 0);
2398 	  if (c == '\n')
2399 	    {
2400 	      gfc_advance_line ();
2401 	      gfc_skip_comments ();
2402 	      if (gfc_at_eof ())
2403 		ret = -1;
2404 	    }
2405 	  goto do_ret;
2406 	}
2407     }
2408   gfc_gobble_whitespace ();
2409 
2410   c = gfc_next_char ();
2411   if (c == '\'' || c == '"')
2412     quote = c;
2413   else
2414     {
2415       if (c == '\n')
2416 	{
2417 	  gfc_advance_line ();
2418 	  gfc_skip_comments ();
2419 	  if (gfc_at_eof ())
2420 	    ret = -1;
2421 	}
2422       goto do_ret;
2423     }
2424 
2425   str_locus = gfc_current_locus;
2426   length = 0;
2427   do
2428     {
2429       c = gfc_next_char_literal (INSTRING_NOWARN);
2430       if (c == quote)
2431 	break;
2432       if (c == '\n')
2433 	{
2434 	  gfc_advance_line ();
2435 	  gfc_skip_comments ();
2436 	  if (gfc_at_eof ())
2437 	    ret = -1;
2438 	  goto do_ret;
2439 	}
2440       length++;
2441     }
2442   while (1);
2443 
2444   gfc_gobble_whitespace ();
2445   c = gfc_next_char ();
2446   if (c != '\n')
2447     goto do_ret;
2448 
2449   gfc_current_locus = str_locus;
2450   ret = 1;
2451   filename = XNEWVEC (char, length + 1);
2452   for (i = 0; i < length; i++)
2453     {
2454       c = gfc_next_char_literal (INSTRING_WARN);
2455       gcc_assert (gfc_wide_fits_in_byte (c));
2456       filename[i] = (unsigned char) c;
2457     }
2458   filename[length] = '\0';
2459   if (!load_file (filename, NULL, false))
2460     exit (FATAL_EXIT_CODE);
2461 
2462   free (filename);
2463 
2464 do_ret:
2465   continue_flag = 0;
2466   end_flag = 0;
2467   gcc_attribute_flag = 0;
2468   openmp_flag = 0;
2469   openacc_flag = 0;
2470   continue_count = 0;
2471   continue_line = 0;
2472   memset (&gfc_current_locus, '\0', sizeof (locus));
2473   memset (&openmp_locus, '\0', sizeof (locus));
2474   memset (&openacc_locus, '\0', sizeof (locus));
2475   memset (&gcc_attribute_locus, '\0', sizeof (locus));
2476   return ret;
2477 }
2478 
2479 /* Load a file into memory by calling load_line until the file ends.  */
2480 
2481 static bool
load_file(const char * realfilename,const char * displayedname,bool initial)2482 load_file (const char *realfilename, const char *displayedname, bool initial)
2483 {
2484   gfc_char_t *line;
2485   gfc_linebuf *b, *include_b = NULL;
2486   gfc_file *f;
2487   FILE *input;
2488   int len, line_len;
2489   bool first_line;
2490   struct stat st;
2491   int stat_result;
2492   const char *filename;
2493   /* If realfilename and displayedname are different and non-null then
2494      surely realfilename is the preprocessed form of
2495      displayedname.  */
2496   bool preprocessed_p = (realfilename && displayedname
2497 			 && strcmp (realfilename, displayedname));
2498 
2499   filename = displayedname ? displayedname : realfilename;
2500 
2501   for (f = current_file; f; f = f->up)
2502     if (filename_cmp (filename, f->filename) == 0)
2503       {
2504 	fprintf (stderr, "%s:%d: Error: File '%s' is being included "
2505 		 "recursively\n", current_file->filename, current_file->line,
2506 		 filename);
2507 	return false;
2508       }
2509 
2510   if (initial)
2511     {
2512       if (gfc_src_file)
2513 	{
2514 	  input = gfc_src_file;
2515 	  gfc_src_file = NULL;
2516 	}
2517       else
2518 	input = gfc_open_file (realfilename);
2519 
2520       if (input == NULL)
2521 	{
2522 	  gfc_error_now ("Cannot open file %qs", filename);
2523 	  return false;
2524 	}
2525     }
2526   else
2527     {
2528       input = gfc_open_included_file (realfilename, false, false);
2529       if (input == NULL)
2530 	{
2531 	  /* For -fpre-include file, current_file is NULL.  */
2532 	  if (current_file)
2533 	    fprintf (stderr, "%s:%d: Error: Can't open included file '%s'\n",
2534 		     current_file->filename, current_file->line, filename);
2535 	  else
2536 	    fprintf (stderr, "Error: Can't open pre-included file '%s'\n",
2537 		     filename);
2538 
2539 	  return false;
2540 	}
2541       stat_result = stat (realfilename, &st);
2542       if (stat_result == 0 && !S_ISREG(st.st_mode))
2543 	{
2544 	  fprintf (stderr, "%s:%d: Error: Included path '%s'"
2545 		   " is not a regular file\n",
2546 		   current_file->filename, current_file->line, filename);
2547 	  fclose (input);
2548 	  return false;
2549 	}
2550     }
2551 
2552   /* Load the file.
2553 
2554      A "non-initial" file means a file that is being included.  In
2555      that case we are creating an LC_ENTER map.
2556 
2557      An "initial" file means a main file; one that is not included.
2558      That file has already got at least one (surely more) line map(s)
2559      created by gfc_init.  So the subsequent map created in that case
2560      must have LC_RENAME reason.
2561 
2562      This latter case is not true for a preprocessed file.  In that
2563      case, although the file is "initial", the line maps created by
2564      gfc_init was used during the preprocessing of the file.  Now that
2565      the preprocessing is over and we are being fed the result of that
2566      preprocessing, we need to create a brand new line map for the
2567      preprocessed file, so the reason is going to be LC_ENTER.  */
2568 
2569   f = get_file (filename, (initial && !preprocessed_p) ? LC_RENAME : LC_ENTER);
2570   if (!initial)
2571     add_file_change (f->filename, f->inclusion_line);
2572   current_file = f;
2573   current_file->line = 1;
2574   line = NULL;
2575   line_len = 0;
2576   first_line = true;
2577 
2578   if (initial && gfc_src_preprocessor_lines[0])
2579     {
2580       preprocessor_line (gfc_src_preprocessor_lines[0]);
2581       free (gfc_src_preprocessor_lines[0]);
2582       gfc_src_preprocessor_lines[0] = NULL;
2583       if (gfc_src_preprocessor_lines[1])
2584 	{
2585 	  preprocessor_line (gfc_src_preprocessor_lines[1]);
2586 	  free (gfc_src_preprocessor_lines[1]);
2587 	  gfc_src_preprocessor_lines[1] = NULL;
2588 	}
2589     }
2590 
2591   for (;;)
2592     {
2593       int trunc = load_line (input, &line, &line_len, NULL);
2594       int inc_line;
2595 
2596       len = gfc_wide_strlen (line);
2597       if (feof (input) && len == 0)
2598 	break;
2599 
2600       /* If this is the first line of the file, it can contain a byte
2601 	 order mark (BOM), which we will ignore:
2602 	   FF FE is UTF-16 little endian,
2603 	   FE FF is UTF-16 big endian,
2604 	   EF BB BF is UTF-8.  */
2605       if (first_line
2606 	  && ((line_len >= 2 && line[0] == (unsigned char) '\xFF'
2607 			     && line[1] == (unsigned char) '\xFE')
2608 	      || (line_len >= 2 && line[0] == (unsigned char) '\xFE'
2609 			        && line[1] == (unsigned char) '\xFF')
2610 	      || (line_len >= 3 && line[0] == (unsigned char) '\xEF'
2611 				&& line[1] == (unsigned char) '\xBB'
2612 				&& line[2] == (unsigned char) '\xBF')))
2613 	{
2614 	  int n = line[1] == (unsigned char) '\xBB' ? 3 : 2;
2615 	  gfc_char_t *new_char = gfc_get_wide_string (line_len);
2616 
2617 	  wide_strcpy (new_char, &line[n]);
2618 	  free (line);
2619 	  line = new_char;
2620 	  len -= n;
2621 	}
2622 
2623       /* There are three things this line can be: a line of Fortran
2624 	 source, an include line or a C preprocessor directive.  */
2625 
2626       if (line[0] == '#')
2627 	{
2628 	  /* When -g3 is specified, it's possible that we emit #define
2629 	     and #undef lines, which we need to pass to the middle-end
2630 	     so that it can emit correct debug info.  */
2631 	  if (debug_info_level == DINFO_LEVEL_VERBOSE
2632 	      && (wide_strncmp (line, "#define ", 8) == 0
2633 		  || wide_strncmp (line, "#undef ", 7) == 0))
2634 	    ;
2635 	  else
2636 	    {
2637 	      preprocessor_line (line);
2638 	      continue;
2639 	    }
2640 	}
2641 
2642       /* Preprocessed files have preprocessor lines added before the byte
2643 	 order mark, so first_line is not about the first line of the file
2644 	 but the first line that's not a preprocessor line.  */
2645       first_line = false;
2646 
2647       inc_line = include_line (line);
2648       if (inc_line > 0)
2649 	{
2650 	  current_file->line++;
2651 	  continue;
2652 	}
2653 
2654       /* Add line.  */
2655 
2656       b = XCNEWVAR (gfc_linebuf, gfc_linebuf_header_size
2657 		    + (len + 1) * sizeof (gfc_char_t));
2658 
2659 
2660       b->location
2661 	= linemap_line_start (line_table, current_file->line++, len);
2662       /* ??? We add the location for the maximum column possible here,
2663 	 because otherwise if the next call creates a new line-map, it
2664 	 will not reserve space for any offset.  */
2665       if (len > 0)
2666 	linemap_position_for_column (line_table, len);
2667 
2668       b->file = current_file;
2669       b->truncated = trunc;
2670       wide_strcpy (b->line, line);
2671 
2672       if (line_head == NULL)
2673 	line_head = b;
2674       else
2675 	line_tail->next = b;
2676 
2677       line_tail = b;
2678 
2679       while (file_changes_cur < file_changes_count)
2680 	file_changes[file_changes_cur++].lb = b;
2681 
2682       if (flag_dec_include)
2683 	{
2684 	  if (include_b && b != include_b)
2685 	    {
2686 	      int inc_line2 = include_stmt (include_b);
2687 	      if (inc_line2 == 0)
2688 		include_b = NULL;
2689 	      else if (inc_line2 > 0)
2690 		{
2691 		  do
2692 		    {
2693 		      if (gfc_current_form == FORM_FIXED)
2694 			{
2695 			  for (gfc_char_t *p = include_b->line; *p; p++)
2696 			    *p = ' ';
2697 			}
2698 		      else
2699 			include_b->line[0] = '\0';
2700                       if (include_b == b)
2701 			break;
2702 		      include_b = include_b->next;
2703 		    }
2704 		  while (1);
2705 		  include_b = NULL;
2706 		}
2707 	    }
2708 	  if (inc_line == -1 && !include_b)
2709 	    include_b = b;
2710 	}
2711     }
2712 
2713   /* Release the line buffer allocated in load_line.  */
2714   free (line);
2715 
2716   fclose (input);
2717 
2718   if (!initial)
2719     add_file_change (NULL, current_file->inclusion_line + 1);
2720   current_file = current_file->up;
2721   linemap_add (line_table, LC_LEAVE, 0, NULL, 0);
2722   return true;
2723 }
2724 
2725 
2726 /* Open a new file and start scanning from that file. Returns true
2727    if everything went OK, false otherwise.  If form == FORM_UNKNOWN
2728    it tries to determine the source form from the filename, defaulting
2729    to free form.  */
2730 
2731 bool
gfc_new_file(void)2732 gfc_new_file (void)
2733 {
2734   bool result;
2735 
2736   if (flag_pre_include != NULL
2737       && !load_file (flag_pre_include, NULL, false))
2738     exit (FATAL_EXIT_CODE);
2739 
2740   if (gfc_cpp_enabled ())
2741     {
2742       result = gfc_cpp_preprocess (gfc_source_file);
2743       if (!gfc_cpp_preprocess_only ())
2744         result = load_file (gfc_cpp_temporary_file (), gfc_source_file, true);
2745     }
2746   else
2747     result = load_file (gfc_source_file, NULL, true);
2748 
2749   gfc_current_locus.lb = line_head;
2750   gfc_current_locus.nextc = (line_head == NULL) ? NULL : line_head->line;
2751 
2752 #if 0 /* Debugging aid.  */
2753   for (; line_head; line_head = line_head->next)
2754     printf ("%s:%3d %s\n", LOCATION_FILE (line_head->location),
2755 	    LOCATION_LINE (line_head->location), line_head->line);
2756 
2757   exit (SUCCESS_EXIT_CODE);
2758 #endif
2759 
2760   return result;
2761 }
2762 
2763 static char *
unescape_filename(const char * ptr)2764 unescape_filename (const char *ptr)
2765 {
2766   const char *p = ptr, *s;
2767   char *d, *ret;
2768   int escaped, unescape = 0;
2769 
2770   /* Make filename end at quote.  */
2771   escaped = false;
2772   while (*p && ! (! escaped && *p == '"'))
2773     {
2774       if (escaped)
2775 	escaped = false;
2776       else if (*p == '\\')
2777 	{
2778 	  escaped = true;
2779 	  unescape++;
2780 	}
2781       ++p;
2782     }
2783 
2784   if (!*p || p[1])
2785     return NULL;
2786 
2787   /* Undo effects of cpp_quote_string.  */
2788   s = ptr;
2789   d = XCNEWVEC (char, p + 1 - ptr - unescape);
2790   ret = d;
2791 
2792   while (s != p)
2793     {
2794       if (*s == '\\')
2795 	*d++ = *++s;
2796       else
2797 	*d++ = *s;
2798       s++;
2799     }
2800   *d = '\0';
2801   return ret;
2802 }
2803 
2804 /* For preprocessed files, if the first tokens are of the form # NUM.
2805    handle the directives so we know the original file name.  */
2806 
2807 const char *
gfc_read_orig_filename(const char * filename,const char ** canon_source_file)2808 gfc_read_orig_filename (const char *filename, const char **canon_source_file)
2809 {
2810   int c, len;
2811   char *dirname, *tmp;
2812 
2813   gfc_src_file = gfc_open_file (filename);
2814   if (gfc_src_file == NULL)
2815     return NULL;
2816 
2817   c = getc (gfc_src_file);
2818 
2819   if (c != '#')
2820     return NULL;
2821 
2822   len = 0;
2823   load_line (gfc_src_file, &gfc_src_preprocessor_lines[0], &len, &c);
2824 
2825   if (wide_strncmp (gfc_src_preprocessor_lines[0], "# 1 \"", 5) != 0)
2826     return NULL;
2827 
2828   tmp = gfc_widechar_to_char (&gfc_src_preprocessor_lines[0][5], -1);
2829   filename = unescape_filename (tmp);
2830   free (tmp);
2831   if (filename == NULL)
2832     return NULL;
2833 
2834   c = getc (gfc_src_file);
2835 
2836   if (c != '#')
2837     return filename;
2838 
2839   len = 0;
2840   load_line (gfc_src_file, &gfc_src_preprocessor_lines[1], &len, &c);
2841 
2842   if (wide_strncmp (gfc_src_preprocessor_lines[1], "# 1 \"", 5) != 0)
2843     return filename;
2844 
2845   tmp = gfc_widechar_to_char (&gfc_src_preprocessor_lines[1][5], -1);
2846   dirname = unescape_filename (tmp);
2847   free (tmp);
2848   if (dirname == NULL)
2849     return filename;
2850 
2851   len = strlen (dirname);
2852   if (len < 3 || dirname[len - 1] != '/' || dirname[len - 2] != '/')
2853     {
2854       free (dirname);
2855       return filename;
2856     }
2857   dirname[len - 2] = '\0';
2858   set_src_pwd (dirname);
2859 
2860   if (! IS_ABSOLUTE_PATH (filename))
2861     {
2862       char *p = XCNEWVEC (char, len + strlen (filename));
2863 
2864       memcpy (p, dirname, len - 2);
2865       p[len - 2] = '/';
2866       strcpy (p + len - 1, filename);
2867       *canon_source_file = p;
2868     }
2869 
2870   free (dirname);
2871   return filename;
2872 }
2873