1 /* Character scanner.
2    Copyright (C) 2000-2018 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 -fopenmp/-fopenacc, we need to handle here 2 things:
1054 	     1) don't treat !$omp/!$acc|c$omp/c$acc|*$omp / *$acc as comments,
1055 		but directives
1056 	     2) handle OpenMP/OpenACC conditional compilation, where
1057 		!$|c$|*$ should be treated as 2 spaces if the characters
1058 		in columns 3 to 6 are valid fixed form label columns
1059 		characters.  */
1060 	  if (gfc_current_locus.lb != NULL
1061 	      && continue_line < gfc_linebuf_linenum (gfc_current_locus.lb))
1062 	    continue_line = gfc_linebuf_linenum (gfc_current_locus.lb);
1063 
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       continue_flag = 1;
1317       if (c == '!')
1318 	skip_comment_line ();
1319       else
1320 	gfc_advance_line ();
1321 
1322       if (gfc_at_eof ())
1323 	goto not_continuation;
1324 
1325       /* We've got a continuation line.  If we are on the very next line after
1326 	 the last continuation, increment the continuation line count and
1327 	 check whether the limit has been exceeded.  */
1328       if (gfc_linebuf_linenum (gfc_current_locus.lb) == continue_line + 1)
1329 	{
1330 	  if (++continue_count == gfc_option.max_continue_free)
1331 	    {
1332 	      if (gfc_notification_std (GFC_STD_GNU) || pedantic)
1333 		gfc_warning (0, "Limit of %d continuations exceeded in "
1334 			     "statement at %C", gfc_option.max_continue_free);
1335 	    }
1336 	}
1337 
1338       /* Now find where it continues. First eat any comment lines.  */
1339       openmp_cond_flag = skip_free_comments ();
1340 
1341       if (gfc_current_locus.lb != NULL
1342 	  && continue_line < gfc_linebuf_linenum (gfc_current_locus.lb))
1343 	continue_line = gfc_linebuf_linenum (gfc_current_locus.lb);
1344 
1345       if (flag_openmp)
1346 	if (prev_openmp_flag != openmp_flag && !openacc_flag)
1347 	  {
1348 	    gfc_current_locus = old_loc;
1349 	    openmp_flag = prev_openmp_flag;
1350 	    c = '&';
1351 	    goto done;
1352 	  }
1353 
1354       if (flag_openacc)
1355 	if (prev_openacc_flag != openacc_flag && !openmp_flag)
1356 	  {
1357 	    gfc_current_locus = old_loc;
1358 	    openacc_flag = prev_openacc_flag;
1359 	    c = '&';
1360 	    goto done;
1361 	  }
1362 
1363       /* Now that we have a non-comment line, probe ahead for the
1364 	 first non-whitespace character.  If it is another '&', then
1365 	 reading starts at the next character, otherwise we must back
1366 	 up to where the whitespace started and resume from there.  */
1367 
1368       old_loc = gfc_current_locus;
1369 
1370       c = next_char ();
1371       while (gfc_is_whitespace (c))
1372 	c = next_char ();
1373 
1374       if (openmp_flag && !openacc_flag)
1375 	{
1376 	  for (i = 0; i < 5; i++, c = next_char ())
1377 	    {
1378 	      gcc_assert (gfc_wide_tolower (c) == (unsigned char) "!$omp"[i]);
1379 	      if (i == 4)
1380 		old_loc = gfc_current_locus;
1381 	    }
1382 	  while (gfc_is_whitespace (c))
1383 	    c = next_char ();
1384 	}
1385       if (openacc_flag && !openmp_flag)
1386 	{
1387 	  for (i = 0; i < 5; i++, c = next_char ())
1388 	    {
1389 	      gcc_assert (gfc_wide_tolower (c) == (unsigned char) "!$acc"[i]);
1390 	      if (i == 4)
1391 		old_loc = gfc_current_locus;
1392 	    }
1393 	  while (gfc_is_whitespace (c))
1394 	    c = next_char ();
1395 	}
1396 
1397       /* In case we have an OpenMP directive continued by OpenACC
1398 	 sentinel, or vice versa, we get both openmp_flag and
1399 	 openacc_flag on.  */
1400 
1401       if (openacc_flag && openmp_flag)
1402 	{
1403 	  int is_openmp = 0;
1404 	  for (i = 0; i < 5; i++, c = next_char ())
1405 	    {
1406 	      if (gfc_wide_tolower (c) != (unsigned char) "!$acc"[i])
1407 		is_openmp = 1;
1408 	      if (i == 4)
1409 		old_loc = gfc_current_locus;
1410 	    }
1411 	  gfc_error (is_openmp
1412 		     ? G_("Wrong OpenACC continuation at %C: "
1413 			  "expected !$ACC, got !$OMP")
1414 		     : G_("Wrong OpenMP continuation at %C: "
1415 			  "expected !$OMP, got !$ACC"));
1416 	}
1417 
1418       if (c != '&')
1419 	{
1420 	  if (in_string && gfc_current_locus.nextc)
1421 	    {
1422 	      gfc_current_locus.nextc--;
1423 	      if (warn_ampersand && in_string == INSTRING_WARN)
1424 		gfc_warning (OPT_Wampersand,
1425 			     "Missing %<&%> in continued character "
1426 			     "constant at %C");
1427 	    }
1428 	  else if (!in_string && (c == '\'' || c == '"'))
1429 	      goto done;
1430 	  /* Both !$omp and !$ -fopenmp continuation lines have & on the
1431 	     continuation line only optionally.  */
1432 	  else if (openmp_flag || openacc_flag || openmp_cond_flag)
1433 	    {
1434 	      if (gfc_current_locus.nextc)
1435 		  gfc_current_locus.nextc--;
1436 	    }
1437 	  else
1438 	    {
1439 	      c = ' ';
1440 	      gfc_current_locus = old_loc;
1441 	      goto done;
1442 	    }
1443 	}
1444     }
1445   else /* Fixed form.  */
1446     {
1447       /* Fixed form continuation.  */
1448       if (in_string != INSTRING_WARN && c == '!')
1449 	{
1450 	  /* Skip comment at end of line.  */
1451 	  do
1452 	    {
1453 	      c = next_char ();
1454 	    }
1455 	  while (c != '\n');
1456 
1457 	  /* Avoid truncation warnings for comment ending lines.  */
1458 	  gfc_current_locus.lb->truncated = 0;
1459 	}
1460 
1461       if (c != '\n')
1462 	goto done;
1463 
1464       /* Check to see if the continuation line was truncated.  */
1465       if (warn_line_truncation && gfc_current_locus.lb != NULL
1466 	  && gfc_current_locus.lb->truncated)
1467 	{
1468 	  gfc_current_locus.lb->truncated = 0;
1469 	  gfc_warning_now (OPT_Wline_truncation,
1470 			   "Line truncated at %L", &gfc_current_locus);
1471 	}
1472 
1473       if (flag_openmp)
1474 	prev_openmp_flag = openmp_flag;
1475       if (flag_openacc)
1476 	prev_openacc_flag = openacc_flag;
1477 
1478       continue_flag = 1;
1479       old_loc = gfc_current_locus;
1480 
1481       gfc_advance_line ();
1482       skip_fixed_comments ();
1483 
1484       /* See if this line is a continuation line.  */
1485       if (flag_openmp && openmp_flag != prev_openmp_flag && !openacc_flag)
1486 	{
1487 	  openmp_flag = prev_openmp_flag;
1488 	  goto not_continuation;
1489 	}
1490       if (flag_openacc && openacc_flag != prev_openacc_flag && !openmp_flag)
1491 	{
1492 	  openacc_flag = prev_openacc_flag;
1493 	  goto not_continuation;
1494 	}
1495 
1496       /* In case we have an OpenMP directive continued by OpenACC
1497 	 sentinel, or vice versa, we get both openmp_flag and
1498 	 openacc_flag on.  */
1499       if (openacc_flag && openmp_flag)
1500 	{
1501 	  int is_openmp = 0;
1502 	  for (i = 0; i < 5; i++)
1503 	    {
1504 	      c = next_char ();
1505 	      if (gfc_wide_tolower (c) != (unsigned char) "*$acc"[i])
1506 		is_openmp = 1;
1507 	    }
1508 	  gfc_error (is_openmp
1509 		     ? G_("Wrong OpenACC continuation at %C: "
1510 			  "expected !$ACC, got !$OMP")
1511 		     : G_("Wrong OpenMP continuation at %C: "
1512 			  "expected !$OMP, got !$ACC"));
1513 	}
1514       else if (!openmp_flag && !openacc_flag)
1515 	for (i = 0; i < 5; i++)
1516 	  {
1517 	    c = next_char ();
1518 	    if (c != ' ')
1519 	      goto not_continuation;
1520 	  }
1521       else if (openmp_flag)
1522 	for (i = 0; i < 5; i++)
1523 	  {
1524 	    c = next_char ();
1525 	    if (gfc_wide_tolower (c) != (unsigned char) "*$omp"[i])
1526 	      goto not_continuation;
1527 	  }
1528       else if (openacc_flag)
1529 	for (i = 0; i < 5; i++)
1530 	  {
1531 	    c = next_char ();
1532 	    if (gfc_wide_tolower (c) != (unsigned char) "*$acc"[i])
1533 	      goto not_continuation;
1534 	  }
1535 
1536       c = next_char ();
1537       if (c == '0' || c == ' ' || c == '\n')
1538 	goto not_continuation;
1539 
1540       /* We've got a continuation line.  If we are on the very next line after
1541 	 the last continuation, increment the continuation line count and
1542 	 check whether the limit has been exceeded.  */
1543       if (gfc_linebuf_linenum (gfc_current_locus.lb) == continue_line + 1)
1544 	{
1545 	  if (++continue_count == gfc_option.max_continue_fixed)
1546 	    {
1547 	      if (gfc_notification_std (GFC_STD_GNU) || pedantic)
1548 		gfc_warning (0, "Limit of %d continuations exceeded in "
1549 			     "statement at %C",
1550 			     gfc_option.max_continue_fixed);
1551 	    }
1552 	}
1553 
1554       if (gfc_current_locus.lb != NULL
1555 	  && continue_line < gfc_linebuf_linenum (gfc_current_locus.lb))
1556 	continue_line = gfc_linebuf_linenum (gfc_current_locus.lb);
1557     }
1558 
1559   /* Ready to read first character of continuation line, which might
1560      be another continuation line!  */
1561   goto restart;
1562 
1563 not_continuation:
1564   c = '\n';
1565   gfc_current_locus = old_loc;
1566   end_flag = 0;
1567 
1568 done:
1569   if (c == '\n')
1570     continue_count = 0;
1571   continue_flag = 0;
1572   return c;
1573 }
1574 
1575 
1576 /* Get the next character of input, folded to lowercase.  In fixed
1577    form mode, we also ignore spaces.  When matcher subroutines are
1578    parsing character literals, they have to call
1579    gfc_next_char_literal().  */
1580 
1581 gfc_char_t
gfc_next_char(void)1582 gfc_next_char (void)
1583 {
1584   gfc_char_t c;
1585 
1586   do
1587     {
1588       c = gfc_next_char_literal (NONSTRING);
1589     }
1590   while (gfc_current_form == FORM_FIXED && gfc_is_whitespace (c));
1591 
1592   return gfc_wide_tolower (c);
1593 }
1594 
1595 char
gfc_next_ascii_char(void)1596 gfc_next_ascii_char (void)
1597 {
1598   gfc_char_t c = gfc_next_char ();
1599 
1600   return (gfc_wide_fits_in_byte (c) ? (unsigned char) c
1601 				    : (unsigned char) UCHAR_MAX);
1602 }
1603 
1604 
1605 gfc_char_t
gfc_peek_char(void)1606 gfc_peek_char (void)
1607 {
1608   locus old_loc;
1609   gfc_char_t c;
1610 
1611   old_loc = gfc_current_locus;
1612   c = gfc_next_char ();
1613   gfc_current_locus = old_loc;
1614 
1615   return c;
1616 }
1617 
1618 
1619 char
gfc_peek_ascii_char(void)1620 gfc_peek_ascii_char (void)
1621 {
1622   gfc_char_t c = gfc_peek_char ();
1623 
1624   return (gfc_wide_fits_in_byte (c) ? (unsigned char) c
1625 				    : (unsigned char) UCHAR_MAX);
1626 }
1627 
1628 
1629 /* Recover from an error.  We try to get past the current statement
1630    and get lined up for the next.  The next statement follows a '\n'
1631    or a ';'.  We also assume that we are not within a character
1632    constant, and deal with finding a '\'' or '"'.  */
1633 
1634 void
gfc_error_recovery(void)1635 gfc_error_recovery (void)
1636 {
1637   gfc_char_t c, delim;
1638 
1639   if (gfc_at_eof ())
1640     return;
1641 
1642   for (;;)
1643     {
1644       c = gfc_next_char ();
1645       if (c == '\n' || c == ';')
1646 	break;
1647 
1648       if (c != '\'' && c != '"')
1649 	{
1650 	  if (gfc_at_eof ())
1651 	    break;
1652 	  continue;
1653 	}
1654       delim = c;
1655 
1656       for (;;)
1657 	{
1658 	  c = next_char ();
1659 
1660 	  if (c == delim)
1661 	    break;
1662 	  if (c == '\n')
1663 	    return;
1664 	  if (c == '\\')
1665 	    {
1666 	      c = next_char ();
1667 	      if (c == '\n')
1668 		return;
1669 	    }
1670 	}
1671       if (gfc_at_eof ())
1672 	break;
1673     }
1674 }
1675 
1676 
1677 /* Read ahead until the next character to be read is not whitespace.  */
1678 
1679 void
gfc_gobble_whitespace(void)1680 gfc_gobble_whitespace (void)
1681 {
1682   static int linenum = 0;
1683   locus old_loc;
1684   gfc_char_t c;
1685 
1686   do
1687     {
1688       old_loc = gfc_current_locus;
1689       c = gfc_next_char_literal (NONSTRING);
1690       /* Issue a warning for nonconforming tabs.  We keep track of the line
1691 	 number because the Fortran matchers will often back up and the same
1692 	 line will be scanned multiple times.  */
1693       if (warn_tabs && c == '\t')
1694 	{
1695 	  int cur_linenum = LOCATION_LINE (gfc_current_locus.lb->location);
1696 	  if (cur_linenum != linenum)
1697 	    {
1698 	      linenum = cur_linenum;
1699 	      gfc_warning_now (OPT_Wtabs, "Nonconforming tab character at %C");
1700 	    }
1701 	}
1702     }
1703   while (gfc_is_whitespace (c));
1704 
1705   if (!ISPRINT(c) && c != '\n' && last_error_char != gfc_current_locus.nextc)
1706     {
1707       char buf[20];
1708       last_error_char = gfc_current_locus.nextc;
1709       snprintf (buf, 20, "%2.2X", c);
1710       gfc_error_now ("Invalid character 0x%s at %C", buf);
1711     }
1712 
1713   gfc_current_locus = old_loc;
1714 }
1715 
1716 
1717 /* Load a single line into pbuf.
1718 
1719    If pbuf points to a NULL pointer, it is allocated.
1720    We truncate lines that are too long, unless we're dealing with
1721    preprocessor lines or if the option -ffixed-line-length-none is set,
1722    in which case we reallocate the buffer to fit the entire line, if
1723    need be.
1724    In fixed mode, we expand a tab that occurs within the statement
1725    label region to expand to spaces that leave the next character in
1726    the source region.
1727 
1728    If first_char is not NULL, it's a pointer to a single char value holding
1729    the first character of the line, which has already been read by the
1730    caller.  This avoids the use of ungetc().
1731 
1732    load_line returns whether the line was truncated.
1733 
1734    NOTE: The error machinery isn't available at this point, so we can't
1735 	 easily report line and column numbers consistent with other
1736 	 parts of gfortran.  */
1737 
1738 static int
load_line(FILE * input,gfc_char_t ** pbuf,int * pbuflen,const int * first_char)1739 load_line (FILE *input, gfc_char_t **pbuf, int *pbuflen, const int *first_char)
1740 {
1741   static int linenum = 0, current_line = 1;
1742   int c, maxlen, i, preprocessor_flag, buflen = *pbuflen;
1743   int trunc_flag = 0, seen_comment = 0;
1744   int seen_printable = 0, seen_ampersand = 0, quoted = ' ';
1745   gfc_char_t *buffer;
1746   bool found_tab = false;
1747 
1748   /* Determine the maximum allowed line length.  */
1749   if (gfc_current_form == FORM_FREE)
1750     maxlen = flag_free_line_length;
1751   else if (gfc_current_form == FORM_FIXED)
1752     maxlen = flag_fixed_line_length;
1753   else
1754     maxlen = 72;
1755 
1756   if (*pbuf == NULL)
1757     {
1758       /* Allocate the line buffer, storing its length into buflen.
1759 	 Note that if maxlen==0, indicating that arbitrary-length lines
1760 	 are allowed, the buffer will be reallocated if this length is
1761 	 insufficient; since 132 characters is the length of a standard
1762 	 free-form line, we use that as a starting guess.  */
1763       if (maxlen > 0)
1764 	buflen = maxlen;
1765       else
1766 	buflen = 132;
1767 
1768       *pbuf = gfc_get_wide_string (buflen + 1);
1769     }
1770 
1771   i = 0;
1772   buffer = *pbuf;
1773 
1774   if (first_char)
1775     c = *first_char;
1776   else
1777     c = getc (input);
1778 
1779   /* In order to not truncate preprocessor lines, we have to
1780      remember that this is one.  */
1781   preprocessor_flag = (c == '#' ? 1 : 0);
1782 
1783   for (;;)
1784     {
1785       if (c == EOF)
1786 	break;
1787 
1788       if (c == '\n')
1789 	{
1790 	  /* Check for illegal use of ampersand. See F95 Standard 3.3.1.3.  */
1791 	  if (gfc_current_form == FORM_FREE
1792 	      && !seen_printable && seen_ampersand)
1793 	    {
1794 	      if (pedantic)
1795 		gfc_error_now ("%<&%> not allowed by itself in line %d",
1796 			       current_line);
1797 	      else
1798 		gfc_warning_now (0, "%<&%> not allowed by itself in line %d",
1799 				 current_line);
1800 	    }
1801 	  break;
1802 	}
1803 
1804       if (c == '\r' || c == '\0')
1805 	goto next_char;			/* Gobble characters.  */
1806 
1807       if (c == '&')
1808 	{
1809 	  if (seen_ampersand)
1810 	    {
1811 	      seen_ampersand = 0;
1812 	      seen_printable = 1;
1813 	    }
1814 	  else
1815 	    seen_ampersand = 1;
1816 	}
1817 
1818       if ((c != '&' && c != '!' && c != ' ') || (c == '!' && !seen_ampersand))
1819 	seen_printable = 1;
1820 
1821       /* Is this a fixed-form comment?  */
1822       if (gfc_current_form == FORM_FIXED && i == 0
1823 	  && (c == '*' || c == 'c' || c == 'd'))
1824 	seen_comment = 1;
1825 
1826       if (quoted == ' ')
1827 	{
1828 	  if (c == '\'' || c == '"')
1829 	    quoted = c;
1830 	}
1831       else if (c == quoted)
1832 	quoted = ' ';
1833 
1834       /* Is this a free-form comment?  */
1835       if (c == '!' && quoted == ' ')
1836         seen_comment = 1;
1837 
1838       /* Vendor extension: "<tab>1" marks a continuation line.  */
1839       if (found_tab)
1840 	{
1841 	  found_tab = false;
1842 	  if (c >= '1' && c <= '9')
1843 	    {
1844 	      *(buffer-1) = c;
1845 	      goto next_char;
1846 	    }
1847 	}
1848 
1849       if (gfc_current_form == FORM_FIXED && c == '\t' && i < 6)
1850 	{
1851 	  found_tab = true;
1852 
1853 	  if (warn_tabs && seen_comment == 0 && current_line != linenum)
1854 	    {
1855 	      linenum = current_line;
1856 	      gfc_warning_now (OPT_Wtabs,
1857 			       "Nonconforming tab character in column %d "
1858 			       "of line %d", i+1, linenum);
1859 	    }
1860 
1861 	  while (i < 6)
1862 	    {
1863 	      *buffer++ = ' ';
1864 	      i++;
1865 	    }
1866 
1867 	  goto next_char;
1868 	}
1869 
1870       *buffer++ = c;
1871       i++;
1872 
1873       if (maxlen == 0 || preprocessor_flag)
1874 	{
1875 	  if (i >= buflen)
1876 	    {
1877 	      /* Reallocate line buffer to double size to hold the
1878 		overlong line.  */
1879 	      buflen = buflen * 2;
1880 	      *pbuf = XRESIZEVEC (gfc_char_t, *pbuf, (buflen + 1));
1881 	      buffer = (*pbuf) + i;
1882 	    }
1883 	}
1884       else if (i >= maxlen)
1885 	{
1886 	  bool trunc_warn = true;
1887 
1888 	  /* Enhancement, if the very next non-space character is an ampersand
1889 	     or comment that we would otherwise warn about, don't mark as
1890 	     truncated.  */
1891 
1892 	  /* Truncate the rest of the line.  */
1893 	  for (;;)
1894 	    {
1895 	      c = getc (input);
1896 	      if (c == '\r' || c == ' ')
1897 	        continue;
1898 
1899 	      if (c == '\n' || c == EOF)
1900 		break;
1901 
1902 	      if (!trunc_warn && c != '!')
1903 		trunc_warn = true;
1904 
1905 	      if (trunc_warn && ((gfc_current_form == FORM_FIXED && c == '&')
1906 		  || c == '!'))
1907 		trunc_warn = false;
1908 
1909 	      if (c == '!')
1910 		seen_comment = 1;
1911 
1912 	      if (trunc_warn && !seen_comment)
1913 		trunc_flag = 1;
1914 	    }
1915 
1916 	  c = '\n';
1917 	  continue;
1918 	}
1919 
1920 next_char:
1921       c = getc (input);
1922     }
1923 
1924   /* Pad lines to the selected line length in fixed form.  */
1925   if (gfc_current_form == FORM_FIXED
1926       && flag_fixed_line_length != 0
1927       && !preprocessor_flag
1928       && c != EOF)
1929     {
1930       while (i++ < maxlen)
1931 	*buffer++ = ' ';
1932     }
1933 
1934   *buffer = '\0';
1935   *pbuflen = buflen;
1936   current_line++;
1937 
1938   return trunc_flag;
1939 }
1940 
1941 
1942 /* Get a gfc_file structure, initialize it and add it to
1943    the file stack.  */
1944 
1945 static gfc_file *
get_file(const char * name,enum lc_reason reason ATTRIBUTE_UNUSED)1946 get_file (const char *name, enum lc_reason reason ATTRIBUTE_UNUSED)
1947 {
1948   gfc_file *f;
1949 
1950   f = XCNEW (gfc_file);
1951 
1952   f->filename = xstrdup (name);
1953 
1954   f->next = file_head;
1955   file_head = f;
1956 
1957   f->up = current_file;
1958   if (current_file != NULL)
1959     f->inclusion_line = current_file->line;
1960 
1961   linemap_add (line_table, reason, false, f->filename, 1);
1962 
1963   return f;
1964 }
1965 
1966 
1967 /* Deal with a line from the C preprocessor. The
1968    initial octothorp has already been seen.  */
1969 
1970 static void
preprocessor_line(gfc_char_t * c)1971 preprocessor_line (gfc_char_t *c)
1972 {
1973   bool flag[5];
1974   int i, line;
1975   gfc_char_t *wide_filename;
1976   gfc_file *f;
1977   int escaped, unescape;
1978   char *filename;
1979 
1980   c++;
1981   while (*c == ' ' || *c == '\t')
1982     c++;
1983 
1984   if (*c < '0' || *c > '9')
1985     goto bad_cpp_line;
1986 
1987   line = wide_atoi (c);
1988 
1989   c = wide_strchr (c, ' ');
1990   if (c == NULL)
1991     {
1992       /* No file name given.  Set new line number.  */
1993       current_file->line = line;
1994       return;
1995     }
1996 
1997   /* Skip spaces.  */
1998   while (*c == ' ' || *c == '\t')
1999     c++;
2000 
2001   /* Skip quote.  */
2002   if (*c != '"')
2003     goto bad_cpp_line;
2004   ++c;
2005 
2006   wide_filename = c;
2007 
2008   /* Make filename end at quote.  */
2009   unescape = 0;
2010   escaped = false;
2011   while (*c && ! (!escaped && *c == '"'))
2012     {
2013       if (escaped)
2014 	escaped = false;
2015       else if (*c == '\\')
2016 	{
2017 	  escaped = true;
2018 	  unescape++;
2019 	}
2020       ++c;
2021     }
2022 
2023   if (! *c)
2024     /* Preprocessor line has no closing quote.  */
2025     goto bad_cpp_line;
2026 
2027   *c++ = '\0';
2028 
2029   /* Undo effects of cpp_quote_string.  */
2030   if (unescape)
2031     {
2032       gfc_char_t *s = wide_filename;
2033       gfc_char_t *d = gfc_get_wide_string (c - wide_filename - unescape);
2034 
2035       wide_filename = d;
2036       while (*s)
2037 	{
2038 	  if (*s == '\\')
2039 	    *d++ = *++s;
2040 	  else
2041 	    *d++ = *s;
2042 	  s++;
2043 	}
2044       *d = '\0';
2045     }
2046 
2047   /* Get flags.  */
2048 
2049   flag[1] = flag[2] = flag[3] = flag[4] = false;
2050 
2051   for (;;)
2052     {
2053       c = wide_strchr (c, ' ');
2054       if (c == NULL)
2055 	break;
2056 
2057       c++;
2058       i = wide_atoi (c);
2059 
2060       if (i >= 1 && i <= 4)
2061 	flag[i] = true;
2062     }
2063 
2064   /* Convert the filename in wide characters into a filename in narrow
2065      characters.  */
2066   filename = gfc_widechar_to_char (wide_filename, -1);
2067 
2068   /* Interpret flags.  */
2069 
2070   if (flag[1]) /* Starting new file.  */
2071     {
2072       f = get_file (filename, LC_RENAME);
2073       add_file_change (f->filename, f->inclusion_line);
2074       current_file = f;
2075     }
2076 
2077   if (flag[2]) /* Ending current file.  */
2078     {
2079       if (!current_file->up
2080 	  || filename_cmp (current_file->up->filename, filename) != 0)
2081 	{
2082 	  linemap_line_start (line_table, current_file->line, 80);
2083 	  /* ??? One could compute the exact column where the filename
2084 	     starts and compute the exact location here.  */
2085 	  gfc_warning_now_at (linemap_position_for_column (line_table, 1),
2086 			      0, "file %qs left but not entered",
2087 			      filename);
2088 	  current_file->line++;
2089 	  if (unescape)
2090 	    free (wide_filename);
2091 	  free (filename);
2092 	  return;
2093 	}
2094 
2095       add_file_change (NULL, line);
2096       current_file = current_file->up;
2097       linemap_add (line_table, LC_RENAME, false, current_file->filename,
2098 		   current_file->line);
2099     }
2100 
2101   /* The name of the file can be a temporary file produced by
2102      cpp. Replace the name if it is different.  */
2103 
2104   if (filename_cmp (current_file->filename, filename) != 0)
2105     {
2106        /* FIXME: we leak the old filename because a pointer to it may be stored
2107           in the linemap.  Alternative could be using GC or updating linemap to
2108           point to the new name, but there is no API for that currently.  */
2109       current_file->filename = xstrdup (filename);
2110     }
2111 
2112   /* Set new line number.  */
2113   current_file->line = line;
2114   if (unescape)
2115     free (wide_filename);
2116   free (filename);
2117   return;
2118 
2119  bad_cpp_line:
2120   linemap_line_start (line_table, current_file->line, 80);
2121   /* ??? One could compute the exact column where the directive
2122      starts and compute the exact location here.  */
2123   gfc_warning_now_at (linemap_position_for_column (line_table, 2), 0,
2124 		      "Illegal preprocessor directive");
2125   current_file->line++;
2126 }
2127 
2128 
2129 static bool load_file (const char *, const char *, bool);
2130 
2131 /* include_line()-- Checks a line buffer to see if it is an include
2132    line.  If so, we call load_file() recursively to load the included
2133    file.  We never return a syntax error because a statement like
2134    "include = 5" is perfectly legal.  We return false if no include was
2135    processed or true if we matched an include.  */
2136 
2137 static bool
include_line(gfc_char_t * line)2138 include_line (gfc_char_t *line)
2139 {
2140   gfc_char_t quote, *c, *begin, *stop;
2141   char *filename;
2142 
2143   c = line;
2144 
2145   if (flag_openmp || flag_openmp_simd)
2146     {
2147       if (gfc_current_form == FORM_FREE)
2148 	{
2149 	  while (*c == ' ' || *c == '\t')
2150 	    c++;
2151 	  if (*c == '!' && c[1] == '$' && (c[2] == ' ' || c[2] == '\t'))
2152 	    c += 3;
2153 	}
2154       else
2155 	{
2156 	  if ((*c == '!' || *c == 'c' || *c == 'C' || *c == '*')
2157 	      && c[1] == '$' && (c[2] == ' ' || c[2] == '\t'))
2158 	    c += 3;
2159 	}
2160     }
2161 
2162   while (*c == ' ' || *c == '\t')
2163     c++;
2164 
2165   if (gfc_wide_strncasecmp (c, "include", 7))
2166     return false;
2167 
2168   c += 7;
2169   while (*c == ' ' || *c == '\t')
2170     c++;
2171 
2172   /* Find filename between quotes.  */
2173 
2174   quote = *c++;
2175   if (quote != '"' && quote != '\'')
2176     return false;
2177 
2178   begin = c;
2179 
2180   while (*c != quote && *c != '\0')
2181     c++;
2182 
2183   if (*c == '\0')
2184     return false;
2185 
2186   stop = c++;
2187 
2188   while (*c == ' ' || *c == '\t')
2189     c++;
2190 
2191   if (*c != '\0' && *c != '!')
2192     return false;
2193 
2194   /* We have an include line at this point.  */
2195 
2196   *stop = '\0'; /* It's ok to trash the buffer, as this line won't be
2197 		   read by anything else.  */
2198 
2199   filename = gfc_widechar_to_char (begin, -1);
2200   if (!load_file (filename, NULL, false))
2201     exit (FATAL_EXIT_CODE);
2202 
2203   free (filename);
2204   return true;
2205 }
2206 
2207 
2208 /* Load a file into memory by calling load_line until the file ends.  */
2209 
2210 static bool
load_file(const char * realfilename,const char * displayedname,bool initial)2211 load_file (const char *realfilename, const char *displayedname, bool initial)
2212 {
2213   gfc_char_t *line;
2214   gfc_linebuf *b;
2215   gfc_file *f;
2216   FILE *input;
2217   int len, line_len;
2218   bool first_line;
2219   struct stat st;
2220   int stat_result;
2221   const char *filename;
2222   /* If realfilename and displayedname are different and non-null then
2223      surely realfilename is the preprocessed form of
2224      displayedname.  */
2225   bool preprocessed_p = (realfilename && displayedname
2226 			 && strcmp (realfilename, displayedname));
2227 
2228   filename = displayedname ? displayedname : realfilename;
2229 
2230   for (f = current_file; f; f = f->up)
2231     if (filename_cmp (filename, f->filename) == 0)
2232       {
2233 	fprintf (stderr, "%s:%d: Error: File '%s' is being included "
2234 		 "recursively\n", current_file->filename, current_file->line,
2235 		 filename);
2236 	return false;
2237       }
2238 
2239   if (initial)
2240     {
2241       if (gfc_src_file)
2242 	{
2243 	  input = gfc_src_file;
2244 	  gfc_src_file = NULL;
2245 	}
2246       else
2247 	input = gfc_open_file (realfilename);
2248 
2249       if (input == NULL)
2250 	{
2251 	  gfc_error_now ("Can't open file %qs", filename);
2252 	  return false;
2253 	}
2254     }
2255   else
2256     {
2257       input = gfc_open_included_file (realfilename, false, false);
2258       if (input == NULL)
2259 	{
2260 	  fprintf (stderr, "%s:%d: Error: Can't open included file '%s'\n",
2261 		   current_file->filename, current_file->line, filename);
2262 	  return false;
2263 	}
2264       stat_result = stat (realfilename, &st);
2265       if (stat_result == 0 && !S_ISREG(st.st_mode))
2266 	{
2267 	  fprintf (stderr, "%s:%d: Error: Included path '%s'"
2268 		   " is not a regular file\n",
2269 		   current_file->filename, current_file->line, filename);
2270 	  fclose (input);
2271 	  return false;
2272 	}
2273     }
2274 
2275   /* Load the file.
2276 
2277      A "non-initial" file means a file that is being included.  In
2278      that case we are creating an LC_ENTER map.
2279 
2280      An "initial" file means a main file; one that is not included.
2281      That file has already got at least one (surely more) line map(s)
2282      created by gfc_init.  So the subsequent map created in that case
2283      must have LC_RENAME reason.
2284 
2285      This latter case is not true for a preprocessed file.  In that
2286      case, although the file is "initial", the line maps created by
2287      gfc_init was used during the preprocessing of the file.  Now that
2288      the preprocessing is over and we are being fed the result of that
2289      preprocessing, we need to create a brand new line map for the
2290      preprocessed file, so the reason is going to be LC_ENTER.  */
2291 
2292   f = get_file (filename, (initial && !preprocessed_p) ? LC_RENAME : LC_ENTER);
2293   if (!initial)
2294     add_file_change (f->filename, f->inclusion_line);
2295   current_file = f;
2296   current_file->line = 1;
2297   line = NULL;
2298   line_len = 0;
2299   first_line = true;
2300 
2301   if (initial && gfc_src_preprocessor_lines[0])
2302     {
2303       preprocessor_line (gfc_src_preprocessor_lines[0]);
2304       free (gfc_src_preprocessor_lines[0]);
2305       gfc_src_preprocessor_lines[0] = NULL;
2306       if (gfc_src_preprocessor_lines[1])
2307 	{
2308 	  preprocessor_line (gfc_src_preprocessor_lines[1]);
2309 	  free (gfc_src_preprocessor_lines[1]);
2310 	  gfc_src_preprocessor_lines[1] = NULL;
2311 	}
2312     }
2313 
2314   for (;;)
2315     {
2316       int trunc = load_line (input, &line, &line_len, NULL);
2317 
2318       len = gfc_wide_strlen (line);
2319       if (feof (input) && len == 0)
2320 	break;
2321 
2322       /* If this is the first line of the file, it can contain a byte
2323 	 order mark (BOM), which we will ignore:
2324 	   FF FE is UTF-16 little endian,
2325 	   FE FF is UTF-16 big endian,
2326 	   EF BB BF is UTF-8.  */
2327       if (first_line
2328 	  && ((line_len >= 2 && line[0] == (unsigned char) '\xFF'
2329 			     && line[1] == (unsigned char) '\xFE')
2330 	      || (line_len >= 2 && line[0] == (unsigned char) '\xFE'
2331 			        && line[1] == (unsigned char) '\xFF')
2332 	      || (line_len >= 3 && line[0] == (unsigned char) '\xEF'
2333 				&& line[1] == (unsigned char) '\xBB'
2334 				&& line[2] == (unsigned char) '\xBF')))
2335 	{
2336 	  int n = line[1] == (unsigned char) '\xBB' ? 3 : 2;
2337 	  gfc_char_t *new_char = gfc_get_wide_string (line_len);
2338 
2339 	  wide_strcpy (new_char, &line[n]);
2340 	  free (line);
2341 	  line = new_char;
2342 	  len -= n;
2343 	}
2344 
2345       /* There are three things this line can be: a line of Fortran
2346 	 source, an include line or a C preprocessor directive.  */
2347 
2348       if (line[0] == '#')
2349 	{
2350 	  /* When -g3 is specified, it's possible that we emit #define
2351 	     and #undef lines, which we need to pass to the middle-end
2352 	     so that it can emit correct debug info.  */
2353 	  if (debug_info_level == DINFO_LEVEL_VERBOSE
2354 	      && (wide_strncmp (line, "#define ", 8) == 0
2355 		  || wide_strncmp (line, "#undef ", 7) == 0))
2356 	    ;
2357 	  else
2358 	    {
2359 	      preprocessor_line (line);
2360 	      continue;
2361 	    }
2362 	}
2363 
2364       /* Preprocessed files have preprocessor lines added before the byte
2365          order mark, so first_line is not about the first line of the file
2366 	 but the first line that's not a preprocessor line.  */
2367       first_line = false;
2368 
2369       if (include_line (line))
2370 	{
2371 	  current_file->line++;
2372 	  continue;
2373 	}
2374 
2375       /* Add line.  */
2376 
2377       b = XCNEWVAR (gfc_linebuf, gfc_linebuf_header_size
2378 		    + (len + 1) * sizeof (gfc_char_t));
2379 
2380 
2381       b->location
2382 	= linemap_line_start (line_table, current_file->line++, len);
2383       /* ??? We add the location for the maximum column possible here,
2384 	 because otherwise if the next call creates a new line-map, it
2385 	 will not reserve space for any offset.  */
2386       if (len > 0)
2387 	linemap_position_for_column (line_table, len);
2388 
2389       b->file = current_file;
2390       b->truncated = trunc;
2391       wide_strcpy (b->line, line);
2392 
2393       if (line_head == NULL)
2394 	line_head = b;
2395       else
2396 	line_tail->next = b;
2397 
2398       line_tail = b;
2399 
2400       while (file_changes_cur < file_changes_count)
2401 	file_changes[file_changes_cur++].lb = b;
2402     }
2403 
2404   /* Release the line buffer allocated in load_line.  */
2405   free (line);
2406 
2407   fclose (input);
2408 
2409   if (!initial)
2410     add_file_change (NULL, current_file->inclusion_line + 1);
2411   current_file = current_file->up;
2412   linemap_add (line_table, LC_LEAVE, 0, NULL, 0);
2413   return true;
2414 }
2415 
2416 
2417 /* Open a new file and start scanning from that file. Returns true
2418    if everything went OK, false otherwise.  If form == FORM_UNKNOWN
2419    it tries to determine the source form from the filename, defaulting
2420    to free form.  */
2421 
2422 bool
gfc_new_file(void)2423 gfc_new_file (void)
2424 {
2425   bool result;
2426 
2427   if (gfc_cpp_enabled ())
2428     {
2429       result = gfc_cpp_preprocess (gfc_source_file);
2430       if (!gfc_cpp_preprocess_only ())
2431         result = load_file (gfc_cpp_temporary_file (), gfc_source_file, true);
2432     }
2433   else
2434     result = load_file (gfc_source_file, NULL, true);
2435 
2436   gfc_current_locus.lb = line_head;
2437   gfc_current_locus.nextc = (line_head == NULL) ? NULL : line_head->line;
2438 
2439 #if 0 /* Debugging aid.  */
2440   for (; line_head; line_head = line_head->next)
2441     printf ("%s:%3d %s\n", LOCATION_FILE (line_head->location),
2442 	    LOCATION_LINE (line_head->location), line_head->line);
2443 
2444   exit (SUCCESS_EXIT_CODE);
2445 #endif
2446 
2447   return result;
2448 }
2449 
2450 static char *
unescape_filename(const char * ptr)2451 unescape_filename (const char *ptr)
2452 {
2453   const char *p = ptr, *s;
2454   char *d, *ret;
2455   int escaped, unescape = 0;
2456 
2457   /* Make filename end at quote.  */
2458   escaped = false;
2459   while (*p && ! (! escaped && *p == '"'))
2460     {
2461       if (escaped)
2462 	escaped = false;
2463       else if (*p == '\\')
2464 	{
2465 	  escaped = true;
2466 	  unescape++;
2467 	}
2468       ++p;
2469     }
2470 
2471   if (!*p || p[1])
2472     return NULL;
2473 
2474   /* Undo effects of cpp_quote_string.  */
2475   s = ptr;
2476   d = XCNEWVEC (char, p + 1 - ptr - unescape);
2477   ret = d;
2478 
2479   while (s != p)
2480     {
2481       if (*s == '\\')
2482 	*d++ = *++s;
2483       else
2484 	*d++ = *s;
2485       s++;
2486     }
2487   *d = '\0';
2488   return ret;
2489 }
2490 
2491 /* For preprocessed files, if the first tokens are of the form # NUM.
2492    handle the directives so we know the original file name.  */
2493 
2494 const char *
gfc_read_orig_filename(const char * filename,const char ** canon_source_file)2495 gfc_read_orig_filename (const char *filename, const char **canon_source_file)
2496 {
2497   int c, len;
2498   char *dirname, *tmp;
2499 
2500   gfc_src_file = gfc_open_file (filename);
2501   if (gfc_src_file == NULL)
2502     return NULL;
2503 
2504   c = getc (gfc_src_file);
2505 
2506   if (c != '#')
2507     return NULL;
2508 
2509   len = 0;
2510   load_line (gfc_src_file, &gfc_src_preprocessor_lines[0], &len, &c);
2511 
2512   if (wide_strncmp (gfc_src_preprocessor_lines[0], "# 1 \"", 5) != 0)
2513     return NULL;
2514 
2515   tmp = gfc_widechar_to_char (&gfc_src_preprocessor_lines[0][5], -1);
2516   filename = unescape_filename (tmp);
2517   free (tmp);
2518   if (filename == NULL)
2519     return NULL;
2520 
2521   c = getc (gfc_src_file);
2522 
2523   if (c != '#')
2524     return filename;
2525 
2526   len = 0;
2527   load_line (gfc_src_file, &gfc_src_preprocessor_lines[1], &len, &c);
2528 
2529   if (wide_strncmp (gfc_src_preprocessor_lines[1], "# 1 \"", 5) != 0)
2530     return filename;
2531 
2532   tmp = gfc_widechar_to_char (&gfc_src_preprocessor_lines[1][5], -1);
2533   dirname = unescape_filename (tmp);
2534   free (tmp);
2535   if (dirname == NULL)
2536     return filename;
2537 
2538   len = strlen (dirname);
2539   if (len < 3 || dirname[len - 1] != '/' || dirname[len - 2] != '/')
2540     {
2541       free (dirname);
2542       return filename;
2543     }
2544   dirname[len - 2] = '\0';
2545   set_src_pwd (dirname);
2546 
2547   if (! IS_ABSOLUTE_PATH (filename))
2548     {
2549       char *p = XCNEWVEC (char, len + strlen (filename));
2550 
2551       memcpy (p, dirname, len - 2);
2552       p[len - 2] = '/';
2553       strcpy (p + len - 1, filename);
2554       *canon_source_file = p;
2555     }
2556 
2557   free (dirname);
2558   return filename;
2559 }
2560