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