]> git.ipfire.org Git - thirdparty/gcc.git/blame_incremental - gcc/fortran/scanner.c
Update copyright years.
[thirdparty/gcc.git] / gcc / fortran / scanner.c
... / ...
CommitLineData
1/* Character scanner.
2 Copyright (C) 2000-2020 Free Software Foundation, Inc.
3 Contributed by Andy Vaught
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9Software Foundation; either version 3, or (at your option) any later
10version.
11
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15for more details.
16
17You should have received a copy of the GNU General Public License
18along 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. */
54gfc_directorylist *include_dirs, *intrinsic_modules_dirs;
55
56static gfc_file *file_head, *current_file;
57
58static int continue_flag, end_flag, gcc_attribute_flag;
59/* If !$omp/!$acc occurred in current comment line. */
60static int openmp_flag, openacc_flag;
61static int continue_count, continue_line;
62static locus openmp_locus;
63static locus openacc_locus;
64static locus gcc_attribute_locus;
65
66gfc_source_form gfc_current_form;
67static gfc_linebuf *line_head, *line_tail;
68
69locus gfc_current_locus;
70const char *gfc_source_file;
71static FILE *gfc_src_file;
72static gfc_char_t *gfc_src_preprocessor_lines[2];
73
74static struct gfc_file_change
75{
76 const char *filename;
77 gfc_linebuf *lb;
78 int line;
79} *file_changes;
80size_t file_changes_cur, file_changes_count;
81size_t file_changes_allocated;
82
83static gfc_char_t *last_error_char;
84
85/* Functions dealing with our wide characters (gfc_char_t) and
86 sequences of such characters. */
87
88int
89gfc_wide_fits_in_byte (gfc_char_t c)
90{
91 return (c <= UCHAR_MAX);
92}
93
94static inline int
95wide_is_ascii (gfc_char_t c)
96{
97 return (gfc_wide_fits_in_byte (c) && ((unsigned char) c & ~0x7f) == 0);
98}
99
100int
101gfc_wide_is_printable (gfc_char_t c)
102{
103 return (gfc_wide_fits_in_byte (c) && ISPRINT ((unsigned char) c));
104}
105
106gfc_char_t
107gfc_wide_tolower (gfc_char_t c)
108{
109 return (wide_is_ascii (c) ? (gfc_char_t) TOLOWER((unsigned char) c) : c);
110}
111
112gfc_char_t
113gfc_wide_toupper (gfc_char_t c)
114{
115 return (wide_is_ascii (c) ? (gfc_char_t) TOUPPER((unsigned char) c) : c);
116}
117
118int
119gfc_wide_is_digit (gfc_char_t c)
120{
121 return (c >= '0' && c <= '9');
122}
123
124static inline int
125wide_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
137size_t
138gfc_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
148gfc_char_t *
149gfc_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
159static gfc_char_t *
160wide_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
170static gfc_char_t *
171wide_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
182char *
183gfc_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
206gfc_char_t *
207gfc_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
225static int
226wide_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
242int
243gfc_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
262void
263gfc_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
279void
280gfc_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
304static void
305add_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
371void
372gfc_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
383void
384gfc_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
392void
393gfc_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
417static FILE *
418open_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
452FILE *
453gfc_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
473int
474gfc_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
482int
483gfc_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
500int
501gfc_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
512int
513gfc_at_eol (void)
514{
515 if (gfc_at_eof ())
516 return 1;
517
518 return (*gfc_current_locus.nextc == '\0');
519}
520
521static void
522add_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
538static void
539report_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
555void
556gfc_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
567void
568gfc_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
578void
579gfc_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
618static gfc_char_t
619next_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
642static void
643skip_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
657int
658gfc_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. */
690static bool
691skip_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. */
716static bool
717skip_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. */
756static bool
757skip_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
800static bool
801skip_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. */
940static bool
941skip_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. */
969static bool
970skip_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
1002static void
1003skip_fixed_comments (void)
1004{
1005 locus start;
1006 int col;
1007 gfc_char_t c;
1008
1009 if (! gfc_at_bol ())
1010 {
1011 start = gfc_current_locus;
1012 if (! gfc_at_eof ())
1013 {
1014 do
1015 c = next_char ();
1016 while (gfc_is_whitespace (c));
1017
1018 if (c == '\n')
1019 gfc_advance_line ();
1020 else if (c == '!')
1021 skip_comment_line ();
1022 }
1023
1024 if (! gfc_at_bol ())
1025 {
1026 gfc_current_locus = start;
1027 return;
1028 }
1029 }
1030
1031 for (;;)
1032 {
1033 start = gfc_current_locus;
1034 if (gfc_at_eof ())
1035 break;
1036
1037 c = next_char ();
1038 if (c == '\n')
1039 {
1040 gfc_advance_line ();
1041 continue;
1042 }
1043
1044 if (c == '!' || c == 'c' || c == 'C' || c == '*')
1045 {
1046 if (skip_gcc_attribute (start))
1047 {
1048 /* Canonicalize to *$omp. */
1049 *start.nextc = '*';
1050 return;
1051 }
1052
1053 if (gfc_current_locus.lb != NULL
1054 && continue_line < gfc_linebuf_linenum (gfc_current_locus.lb))
1055 continue_line = gfc_linebuf_linenum (gfc_current_locus.lb);
1056
1057 /* If -fopenmp/-fopenacc, we need to handle here 2 things:
1058 1) don't treat !$omp/!$acc|c$omp/c$acc|*$omp / *$acc as comments,
1059 but directives
1060 2) handle OpenMP/OpenACC conditional compilation, where
1061 !$|c$|*$ should be treated as 2 spaces if the characters
1062 in columns 3 to 6 are valid fixed form label columns
1063 characters. */
1064 if ((flag_openmp || flag_openmp_simd) && !flag_openacc)
1065 {
1066 if (next_char () == '$')
1067 {
1068 c = next_char ();
1069 if (c == 'o' || c == 'O')
1070 {
1071 if (skip_fixed_omp_sentinel (&start))
1072 return;
1073 }
1074 else
1075 goto check_for_digits;
1076 }
1077 gfc_current_locus = start;
1078 }
1079
1080 if (flag_openacc && !(flag_openmp || flag_openmp_simd))
1081 {
1082 if (next_char () == '$')
1083 {
1084 c = next_char ();
1085 if (c == 'a' || c == 'A')
1086 {
1087 if (skip_fixed_oacc_sentinel (&start))
1088 return;
1089 }
1090 else
1091 goto check_for_digits;
1092 }
1093 gfc_current_locus = start;
1094 }
1095
1096 if (flag_openacc || flag_openmp || flag_openmp_simd)
1097 {
1098 if (next_char () == '$')
1099 {
1100 c = next_char ();
1101 if (c == 'a' || c == 'A')
1102 {
1103 if (skip_fixed_oacc_sentinel (&start))
1104 return;
1105 }
1106 else if (c == 'o' || c == 'O')
1107 {
1108 if (skip_fixed_omp_sentinel (&start))
1109 return;
1110 }
1111 else
1112 goto check_for_digits;
1113 }
1114 gfc_current_locus = start;
1115 }
1116
1117 skip_comment_line ();
1118 continue;
1119
1120 gcc_unreachable ();
1121check_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
1198void
1199gfc_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
1215gfc_char_t
1216gfc_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
1225restart:
1226 c = next_char ();
1227 if (gfc_at_end ())
1228 {
1229 continue_count = 0;
1230 return c;
1231 }
1232
1233 if (gfc_current_form == FORM_FREE)
1234 {
1235 bool openmp_cond_flag;
1236
1237 if (!in_string && c == '!')
1238 {
1239 if (gcc_attribute_flag
1240 && memcmp (&gfc_current_locus, &gcc_attribute_locus,
1241 sizeof (gfc_current_locus)) == 0)
1242 goto done;
1243
1244 if (openmp_flag
1245 && memcmp (&gfc_current_locus, &openmp_locus,
1246 sizeof (gfc_current_locus)) == 0)
1247 goto done;
1248
1249 if (openacc_flag
1250 && memcmp (&gfc_current_locus, &openacc_locus,
1251 sizeof (gfc_current_locus)) == 0)
1252 goto done;
1253
1254 /* This line can't be continued */
1255 do
1256 {
1257 c = next_char ();
1258 }
1259 while (c != '\n');
1260
1261 /* Avoid truncation warnings for comment ending lines. */
1262 gfc_current_locus.lb->truncated = 0;
1263
1264 goto done;
1265 }
1266
1267 /* Check to see if the continuation line was truncated. */
1268 if (warn_line_truncation && gfc_current_locus.lb != NULL
1269 && gfc_current_locus.lb->truncated)
1270 {
1271 int maxlen = flag_free_line_length;
1272 gfc_char_t *current_nextc = gfc_current_locus.nextc;
1273
1274 gfc_current_locus.lb->truncated = 0;
1275 gfc_current_locus.nextc = gfc_current_locus.lb->line + maxlen;
1276 gfc_warning_now (OPT_Wline_truncation,
1277 "Line truncated at %L", &gfc_current_locus);
1278 gfc_current_locus.nextc = current_nextc;
1279 }
1280
1281 if (c != '&')
1282 goto done;
1283
1284 /* If the next nonblank character is a ! or \n, we've got a
1285 continuation line. */
1286 old_loc = gfc_current_locus;
1287
1288 c = next_char ();
1289 while (gfc_is_whitespace (c))
1290 c = next_char ();
1291
1292 /* Character constants to be continued cannot have commentary
1293 after the '&'. However, there are cases where we may think we
1294 are still in a string and we are looking for a possible
1295 doubled quote and we end up here. See PR64506. */
1296
1297 if (in_string && c != '\n')
1298 {
1299 gfc_current_locus = old_loc;
1300 c = '&';
1301 goto done;
1302 }
1303
1304 if (c != '!' && c != '\n')
1305 {
1306 gfc_current_locus = old_loc;
1307 c = '&';
1308 goto done;
1309 }
1310
1311 if (flag_openmp)
1312 prev_openmp_flag = openmp_flag;
1313 if (flag_openacc)
1314 prev_openacc_flag = openacc_flag;
1315
1316 /* This can happen if the input file changed or via cpp's #line
1317 without getting reset (e.g. via input_stmt). It also happens
1318 when pre-including files via -fpre-include=. */
1319 if (continue_count == 0
1320 && gfc_current_locus.lb
1321 && continue_line > gfc_linebuf_linenum (gfc_current_locus.lb) + 1)
1322 continue_line = gfc_linebuf_linenum (gfc_current_locus.lb) + 1;
1323
1324 continue_flag = 1;
1325 if (c == '!')
1326 skip_comment_line ();
1327 else
1328 gfc_advance_line ();
1329
1330 if (gfc_at_eof ())
1331 goto not_continuation;
1332
1333 /* We've got a continuation line. If we are on the very next line after
1334 the last continuation, increment the continuation line count and
1335 check whether the limit has been exceeded. */
1336 if (gfc_linebuf_linenum (gfc_current_locus.lb) == continue_line + 1)
1337 {
1338 if (++continue_count == gfc_option.max_continue_free)
1339 {
1340 if (gfc_notification_std (GFC_STD_GNU) || pedantic)
1341 gfc_warning (0, "Limit of %d continuations exceeded in "
1342 "statement at %C", gfc_option.max_continue_free);
1343 }
1344 }
1345
1346 /* Now find where it continues. First eat any comment lines. */
1347 openmp_cond_flag = skip_free_comments ();
1348
1349 if (gfc_current_locus.lb != NULL
1350 && continue_line < gfc_linebuf_linenum (gfc_current_locus.lb))
1351 continue_line = gfc_linebuf_linenum (gfc_current_locus.lb);
1352
1353 if (flag_openmp)
1354 if (prev_openmp_flag != openmp_flag && !openacc_flag)
1355 {
1356 gfc_current_locus = old_loc;
1357 openmp_flag = prev_openmp_flag;
1358 c = '&';
1359 goto done;
1360 }
1361
1362 if (flag_openacc)
1363 if (prev_openacc_flag != openacc_flag && !openmp_flag)
1364 {
1365 gfc_current_locus = old_loc;
1366 openacc_flag = prev_openacc_flag;
1367 c = '&';
1368 goto done;
1369 }
1370
1371 /* Now that we have a non-comment line, probe ahead for the
1372 first non-whitespace character. If it is another '&', then
1373 reading starts at the next character, otherwise we must back
1374 up to where the whitespace started and resume from there. */
1375
1376 old_loc = gfc_current_locus;
1377
1378 c = next_char ();
1379 while (gfc_is_whitespace (c))
1380 c = next_char ();
1381
1382 if (openmp_flag && !openacc_flag)
1383 {
1384 for (i = 0; i < 5; i++, c = next_char ())
1385 {
1386 gcc_assert (gfc_wide_tolower (c) == (unsigned char) "!$omp"[i]);
1387 if (i == 4)
1388 old_loc = gfc_current_locus;
1389 }
1390 while (gfc_is_whitespace (c))
1391 c = next_char ();
1392 }
1393 if (openacc_flag && !openmp_flag)
1394 {
1395 for (i = 0; i < 5; i++, c = next_char ())
1396 {
1397 gcc_assert (gfc_wide_tolower (c) == (unsigned char) "!$acc"[i]);
1398 if (i == 4)
1399 old_loc = gfc_current_locus;
1400 }
1401 while (gfc_is_whitespace (c))
1402 c = next_char ();
1403 }
1404
1405 /* In case we have an OpenMP directive continued by OpenACC
1406 sentinel, or vice versa, we get both openmp_flag and
1407 openacc_flag on. */
1408
1409 if (openacc_flag && openmp_flag)
1410 {
1411 int is_openmp = 0;
1412 for (i = 0; i < 5; i++, c = next_char ())
1413 {
1414 if (gfc_wide_tolower (c) != (unsigned char) "!$acc"[i])
1415 is_openmp = 1;
1416 if (i == 4)
1417 old_loc = gfc_current_locus;
1418 }
1419 gfc_error (is_openmp
1420 ? G_("Wrong OpenACC continuation at %C: "
1421 "expected !$ACC, got !$OMP")
1422 : G_("Wrong OpenMP continuation at %C: "
1423 "expected !$OMP, got !$ACC"));
1424 }
1425
1426 if (c != '&')
1427 {
1428 if (in_string && gfc_current_locus.nextc)
1429 {
1430 gfc_current_locus.nextc--;
1431 if (warn_ampersand && in_string == INSTRING_WARN)
1432 gfc_warning (OPT_Wampersand,
1433 "Missing %<&%> in continued character "
1434 "constant at %C");
1435 }
1436 else if (!in_string && (c == '\'' || c == '"'))
1437 goto done;
1438 /* Both !$omp and !$ -fopenmp continuation lines have & on the
1439 continuation line only optionally. */
1440 else if (openmp_flag || openacc_flag || openmp_cond_flag)
1441 {
1442 if (gfc_current_locus.nextc)
1443 gfc_current_locus.nextc--;
1444 }
1445 else
1446 {
1447 c = ' ';
1448 gfc_current_locus = old_loc;
1449 goto done;
1450 }
1451 }
1452 }
1453 else /* Fixed form. */
1454 {
1455 /* Fixed form continuation. */
1456 if (in_string != INSTRING_WARN && c == '!')
1457 {
1458 /* Skip comment at end of line. */
1459 do
1460 {
1461 c = next_char ();
1462 }
1463 while (c != '\n');
1464
1465 /* Avoid truncation warnings for comment ending lines. */
1466 gfc_current_locus.lb->truncated = 0;
1467 }
1468
1469 if (c != '\n')
1470 goto done;
1471
1472 /* Check to see if the continuation line was truncated. */
1473 if (warn_line_truncation && gfc_current_locus.lb != NULL
1474 && gfc_current_locus.lb->truncated)
1475 {
1476 gfc_current_locus.lb->truncated = 0;
1477 gfc_warning_now (OPT_Wline_truncation,
1478 "Line truncated at %L", &gfc_current_locus);
1479 }
1480
1481 if (flag_openmp)
1482 prev_openmp_flag = openmp_flag;
1483 if (flag_openacc)
1484 prev_openacc_flag = openacc_flag;
1485
1486 /* This can happen if the input file changed or via cpp's #line
1487 without getting reset (e.g. via input_stmt). It also happens
1488 when pre-including files via -fpre-include=. */
1489 if (continue_count == 0
1490 && gfc_current_locus.lb
1491 && continue_line > gfc_linebuf_linenum (gfc_current_locus.lb) + 1)
1492 continue_line = gfc_linebuf_linenum (gfc_current_locus.lb) + 1;
1493
1494 continue_flag = 1;
1495 old_loc = gfc_current_locus;
1496
1497 gfc_advance_line ();
1498 skip_fixed_comments ();
1499
1500 /* See if this line is a continuation line. */
1501 if (flag_openmp && openmp_flag != prev_openmp_flag && !openacc_flag)
1502 {
1503 openmp_flag = prev_openmp_flag;
1504 goto not_continuation;
1505 }
1506 if (flag_openacc && openacc_flag != prev_openacc_flag && !openmp_flag)
1507 {
1508 openacc_flag = prev_openacc_flag;
1509 goto not_continuation;
1510 }
1511
1512 /* In case we have an OpenMP directive continued by OpenACC
1513 sentinel, or vice versa, we get both openmp_flag and
1514 openacc_flag on. */
1515 if (openacc_flag && openmp_flag)
1516 {
1517 int is_openmp = 0;
1518 for (i = 0; i < 5; i++)
1519 {
1520 c = next_char ();
1521 if (gfc_wide_tolower (c) != (unsigned char) "*$acc"[i])
1522 is_openmp = 1;
1523 }
1524 gfc_error (is_openmp
1525 ? G_("Wrong OpenACC continuation at %C: "
1526 "expected !$ACC, got !$OMP")
1527 : G_("Wrong OpenMP continuation at %C: "
1528 "expected !$OMP, got !$ACC"));
1529 }
1530 else if (!openmp_flag && !openacc_flag)
1531 for (i = 0; i < 5; i++)
1532 {
1533 c = next_char ();
1534 if (c != ' ')
1535 goto not_continuation;
1536 }
1537 else if (openmp_flag)
1538 for (i = 0; i < 5; i++)
1539 {
1540 c = next_char ();
1541 if (gfc_wide_tolower (c) != (unsigned char) "*$omp"[i])
1542 goto not_continuation;
1543 }
1544 else if (openacc_flag)
1545 for (i = 0; i < 5; i++)
1546 {
1547 c = next_char ();
1548 if (gfc_wide_tolower (c) != (unsigned char) "*$acc"[i])
1549 goto not_continuation;
1550 }
1551
1552 c = next_char ();
1553 if (c == '0' || c == ' ' || c == '\n')
1554 goto not_continuation;
1555
1556 /* We've got a continuation line. If we are on the very next line after
1557 the last continuation, increment the continuation line count and
1558 check whether the limit has been exceeded. */
1559 if (gfc_linebuf_linenum (gfc_current_locus.lb) == continue_line + 1)
1560 {
1561 if (++continue_count == gfc_option.max_continue_fixed)
1562 {
1563 if (gfc_notification_std (GFC_STD_GNU) || pedantic)
1564 gfc_warning (0, "Limit of %d continuations exceeded in "
1565 "statement at %C",
1566 gfc_option.max_continue_fixed);
1567 }
1568 }
1569
1570 if (gfc_current_locus.lb != NULL
1571 && continue_line < gfc_linebuf_linenum (gfc_current_locus.lb))
1572 continue_line = gfc_linebuf_linenum (gfc_current_locus.lb);
1573 }
1574
1575 /* Ready to read first character of continuation line, which might
1576 be another continuation line! */
1577 goto restart;
1578
1579not_continuation:
1580 c = '\n';
1581 gfc_current_locus = old_loc;
1582 end_flag = 0;
1583
1584done:
1585 if (c == '\n')
1586 continue_count = 0;
1587 continue_flag = 0;
1588 return c;
1589}
1590
1591
1592/* Get the next character of input, folded to lowercase. In fixed
1593 form mode, we also ignore spaces. When matcher subroutines are
1594 parsing character literals, they have to call
1595 gfc_next_char_literal(). */
1596
1597gfc_char_t
1598gfc_next_char (void)
1599{
1600 gfc_char_t c;
1601
1602 do
1603 {
1604 c = gfc_next_char_literal (NONSTRING);
1605 }
1606 while (gfc_current_form == FORM_FIXED && gfc_is_whitespace (c));
1607
1608 return gfc_wide_tolower (c);
1609}
1610
1611char
1612gfc_next_ascii_char (void)
1613{
1614 gfc_char_t c = gfc_next_char ();
1615
1616 return (gfc_wide_fits_in_byte (c) ? (unsigned char) c
1617 : (unsigned char) UCHAR_MAX);
1618}
1619
1620
1621gfc_char_t
1622gfc_peek_char (void)
1623{
1624 locus old_loc;
1625 gfc_char_t c;
1626
1627 old_loc = gfc_current_locus;
1628 c = gfc_next_char ();
1629 gfc_current_locus = old_loc;
1630
1631 return c;
1632}
1633
1634
1635char
1636gfc_peek_ascii_char (void)
1637{
1638 gfc_char_t c = gfc_peek_char ();
1639
1640 return (gfc_wide_fits_in_byte (c) ? (unsigned char) c
1641 : (unsigned char) UCHAR_MAX);
1642}
1643
1644
1645/* Recover from an error. We try to get past the current statement
1646 and get lined up for the next. The next statement follows a '\n'
1647 or a ';'. We also assume that we are not within a character
1648 constant, and deal with finding a '\'' or '"'. */
1649
1650void
1651gfc_error_recovery (void)
1652{
1653 gfc_char_t c, delim;
1654
1655 if (gfc_at_eof ())
1656 return;
1657
1658 for (;;)
1659 {
1660 c = gfc_next_char ();
1661 if (c == '\n' || c == ';')
1662 break;
1663
1664 if (c != '\'' && c != '"')
1665 {
1666 if (gfc_at_eof ())
1667 break;
1668 continue;
1669 }
1670 delim = c;
1671
1672 for (;;)
1673 {
1674 c = next_char ();
1675
1676 if (c == delim)
1677 break;
1678 if (c == '\n')
1679 return;
1680 if (c == '\\')
1681 {
1682 c = next_char ();
1683 if (c == '\n')
1684 return;
1685 }
1686 }
1687 if (gfc_at_eof ())
1688 break;
1689 }
1690}
1691
1692
1693/* Read ahead until the next character to be read is not whitespace. */
1694
1695void
1696gfc_gobble_whitespace (void)
1697{
1698 static int linenum = 0;
1699 locus old_loc;
1700 gfc_char_t c;
1701
1702 do
1703 {
1704 old_loc = gfc_current_locus;
1705 c = gfc_next_char_literal (NONSTRING);
1706 /* Issue a warning for nonconforming tabs. We keep track of the line
1707 number because the Fortran matchers will often back up and the same
1708 line will be scanned multiple times. */
1709 if (warn_tabs && c == '\t')
1710 {
1711 int cur_linenum = LOCATION_LINE (gfc_current_locus.lb->location);
1712 if (cur_linenum != linenum)
1713 {
1714 linenum = cur_linenum;
1715 gfc_warning_now (OPT_Wtabs, "Nonconforming tab character at %C");
1716 }
1717 }
1718 }
1719 while (gfc_is_whitespace (c));
1720
1721 if (!ISPRINT(c) && c != '\n' && last_error_char != gfc_current_locus.nextc)
1722 {
1723 char buf[20];
1724 last_error_char = gfc_current_locus.nextc;
1725 snprintf (buf, 20, "%2.2X", c);
1726 gfc_error_now ("Invalid character 0x%s at %C", buf);
1727 }
1728
1729 gfc_current_locus = old_loc;
1730}
1731
1732
1733/* Load a single line into pbuf.
1734
1735 If pbuf points to a NULL pointer, it is allocated.
1736 We truncate lines that are too long, unless we're dealing with
1737 preprocessor lines or if the option -ffixed-line-length-none is set,
1738 in which case we reallocate the buffer to fit the entire line, if
1739 need be.
1740 In fixed mode, we expand a tab that occurs within the statement
1741 label region to expand to spaces that leave the next character in
1742 the source region.
1743
1744 If first_char is not NULL, it's a pointer to a single char value holding
1745 the first character of the line, which has already been read by the
1746 caller. This avoids the use of ungetc().
1747
1748 load_line returns whether the line was truncated.
1749
1750 NOTE: The error machinery isn't available at this point, so we can't
1751 easily report line and column numbers consistent with other
1752 parts of gfortran. */
1753
1754static int
1755load_line (FILE *input, gfc_char_t **pbuf, int *pbuflen, const int *first_char)
1756{
1757 int c, maxlen, i, preprocessor_flag, buflen = *pbuflen;
1758 int trunc_flag = 0, seen_comment = 0;
1759 int seen_printable = 0, seen_ampersand = 0, quoted = ' ';
1760 gfc_char_t *buffer;
1761 bool found_tab = false;
1762 bool warned_tabs = false;
1763
1764 /* Determine the maximum allowed line length. */
1765 if (gfc_current_form == FORM_FREE)
1766 maxlen = flag_free_line_length;
1767 else if (gfc_current_form == FORM_FIXED)
1768 maxlen = flag_fixed_line_length;
1769 else
1770 maxlen = 72;
1771
1772 if (*pbuf == NULL)
1773 {
1774 /* Allocate the line buffer, storing its length into buflen.
1775 Note that if maxlen==0, indicating that arbitrary-length lines
1776 are allowed, the buffer will be reallocated if this length is
1777 insufficient; since 132 characters is the length of a standard
1778 free-form line, we use that as a starting guess. */
1779 if (maxlen > 0)
1780 buflen = maxlen;
1781 else
1782 buflen = 132;
1783
1784 *pbuf = gfc_get_wide_string (buflen + 1);
1785 }
1786
1787 i = 0;
1788 buffer = *pbuf;
1789
1790 if (first_char)
1791 c = *first_char;
1792 else
1793 c = getc (input);
1794
1795 /* In order to not truncate preprocessor lines, we have to
1796 remember that this is one. */
1797 preprocessor_flag = (c == '#' ? 1 : 0);
1798
1799 for (;;)
1800 {
1801 if (c == EOF)
1802 break;
1803
1804 if (c == '\n')
1805 {
1806 /* Check for illegal use of ampersand. See F95 Standard 3.3.1.3. */
1807 if (gfc_current_form == FORM_FREE
1808 && !seen_printable && seen_ampersand)
1809 {
1810 if (pedantic)
1811 gfc_error_now ("%<&%> not allowed by itself in line %d",
1812 current_file->line);
1813 else
1814 gfc_warning_now (0, "%<&%> not allowed by itself in line %d",
1815 current_file->line);
1816 }
1817 break;
1818 }
1819
1820 if (c == '\r' || c == '\0')
1821 goto next_char; /* Gobble characters. */
1822
1823 if (c == '&')
1824 {
1825 if (seen_ampersand)
1826 {
1827 seen_ampersand = 0;
1828 seen_printable = 1;
1829 }
1830 else
1831 seen_ampersand = 1;
1832 }
1833
1834 if ((c != '&' && c != '!' && c != ' ') || (c == '!' && !seen_ampersand))
1835 seen_printable = 1;
1836
1837 /* Is this a fixed-form comment? */
1838 if (gfc_current_form == FORM_FIXED && i == 0
1839 && (c == '*' || c == 'c' || c == 'd'))
1840 seen_comment = 1;
1841
1842 if (quoted == ' ')
1843 {
1844 if (c == '\'' || c == '"')
1845 quoted = c;
1846 }
1847 else if (c == quoted)
1848 quoted = ' ';
1849
1850 /* Is this a free-form comment? */
1851 if (c == '!' && quoted == ' ')
1852 seen_comment = 1;
1853
1854 /* Vendor extension: "<tab>1" marks a continuation line. */
1855 if (found_tab)
1856 {
1857 found_tab = false;
1858 if (c >= '1' && c <= '9')
1859 {
1860 *(buffer-1) = c;
1861 goto next_char;
1862 }
1863 }
1864
1865 if (gfc_current_form == FORM_FIXED && c == '\t' && i < 6)
1866 {
1867 found_tab = true;
1868
1869 if (warn_tabs && seen_comment == 0 && !warned_tabs)
1870 {
1871 warned_tabs = true;
1872 gfc_warning_now (OPT_Wtabs,
1873 "Nonconforming tab character in column %d "
1874 "of line %d", i + 1, current_file->line);
1875 }
1876
1877 while (i < 6)
1878 {
1879 *buffer++ = ' ';
1880 i++;
1881 }
1882
1883 goto next_char;
1884 }
1885
1886 *buffer++ = c;
1887 i++;
1888
1889 if (maxlen == 0 || preprocessor_flag)
1890 {
1891 if (i >= buflen)
1892 {
1893 /* Reallocate line buffer to double size to hold the
1894 overlong line. */
1895 buflen = buflen * 2;
1896 *pbuf = XRESIZEVEC (gfc_char_t, *pbuf, (buflen + 1));
1897 buffer = (*pbuf) + i;
1898 }
1899 }
1900 else if (i >= maxlen)
1901 {
1902 bool trunc_warn = true;
1903
1904 /* Enhancement, if the very next non-space character is an ampersand
1905 or comment that we would otherwise warn about, don't mark as
1906 truncated. */
1907
1908 /* Truncate the rest of the line. */
1909 for (;;)
1910 {
1911 c = getc (input);
1912 if (c == '\r' || c == ' ')
1913 continue;
1914
1915 if (c == '\n' || c == EOF)
1916 break;
1917
1918 if (!trunc_warn && c != '!')
1919 trunc_warn = true;
1920
1921 if (trunc_warn && ((gfc_current_form == FORM_FIXED && c == '&')
1922 || c == '!'))
1923 trunc_warn = false;
1924
1925 if (c == '!')
1926 seen_comment = 1;
1927
1928 if (trunc_warn && !seen_comment)
1929 trunc_flag = 1;
1930 }
1931
1932 c = '\n';
1933 continue;
1934 }
1935
1936next_char:
1937 c = getc (input);
1938 }
1939
1940 /* Pad lines to the selected line length in fixed form. */
1941 if (gfc_current_form == FORM_FIXED
1942 && flag_fixed_line_length != 0
1943 && flag_pad_source
1944 && !preprocessor_flag
1945 && c != EOF)
1946 {
1947 while (i++ < maxlen)
1948 *buffer++ = ' ';
1949 }
1950
1951 *buffer = '\0';
1952 *pbuflen = buflen;
1953
1954 return trunc_flag;
1955}
1956
1957
1958/* Get a gfc_file structure, initialize it and add it to
1959 the file stack. */
1960
1961static gfc_file *
1962get_file (const char *name, enum lc_reason reason)
1963{
1964 gfc_file *f;
1965
1966 f = XCNEW (gfc_file);
1967
1968 f->filename = xstrdup (name);
1969
1970 f->next = file_head;
1971 file_head = f;
1972
1973 f->up = current_file;
1974 if (current_file != NULL)
1975 f->inclusion_line = current_file->line;
1976
1977 linemap_add (line_table, reason, false, f->filename, 1);
1978
1979 return f;
1980}
1981
1982
1983/* Deal with a line from the C preprocessor. The
1984 initial octothorp has already been seen. */
1985
1986static void
1987preprocessor_line (gfc_char_t *c)
1988{
1989 bool flag[5];
1990 int i, line;
1991 gfc_char_t *wide_filename;
1992 gfc_file *f;
1993 int escaped, unescape;
1994 char *filename;
1995
1996 c++;
1997 while (*c == ' ' || *c == '\t')
1998 c++;
1999
2000 if (*c < '0' || *c > '9')
2001 goto bad_cpp_line;
2002
2003 line = wide_atoi (c);
2004
2005 c = wide_strchr (c, ' ');
2006 if (c == NULL)
2007 {
2008 /* No file name given. Set new line number. */
2009 current_file->line = line;
2010 return;
2011 }
2012
2013 /* Skip spaces. */
2014 while (*c == ' ' || *c == '\t')
2015 c++;
2016
2017 /* Skip quote. */
2018 if (*c != '"')
2019 goto bad_cpp_line;
2020 ++c;
2021
2022 wide_filename = c;
2023
2024 /* Make filename end at quote. */
2025 unescape = 0;
2026 escaped = false;
2027 while (*c && ! (!escaped && *c == '"'))
2028 {
2029 if (escaped)
2030 escaped = false;
2031 else if (*c == '\\')
2032 {
2033 escaped = true;
2034 unescape++;
2035 }
2036 ++c;
2037 }
2038
2039 if (! *c)
2040 /* Preprocessor line has no closing quote. */
2041 goto bad_cpp_line;
2042
2043 *c++ = '\0';
2044
2045 /* Undo effects of cpp_quote_string. */
2046 if (unescape)
2047 {
2048 gfc_char_t *s = wide_filename;
2049 gfc_char_t *d = gfc_get_wide_string (c - wide_filename - unescape);
2050
2051 wide_filename = d;
2052 while (*s)
2053 {
2054 if (*s == '\\')
2055 *d++ = *++s;
2056 else
2057 *d++ = *s;
2058 s++;
2059 }
2060 *d = '\0';
2061 }
2062
2063 /* Get flags. */
2064
2065 flag[1] = flag[2] = flag[3] = flag[4] = false;
2066
2067 for (;;)
2068 {
2069 c = wide_strchr (c, ' ');
2070 if (c == NULL)
2071 break;
2072
2073 c++;
2074 i = wide_atoi (c);
2075
2076 if (i >= 1 && i <= 4)
2077 flag[i] = true;
2078 }
2079
2080 /* Convert the filename in wide characters into a filename in narrow
2081 characters. */
2082 filename = gfc_widechar_to_char (wide_filename, -1);
2083
2084 /* Interpret flags. */
2085
2086 if (flag[1]) /* Starting new file. */
2087 {
2088 f = get_file (filename, LC_RENAME);
2089 add_file_change (f->filename, f->inclusion_line);
2090 current_file = f;
2091 }
2092
2093 if (flag[2]) /* Ending current file. */
2094 {
2095 if (!current_file->up
2096 || filename_cmp (current_file->up->filename, filename) != 0)
2097 {
2098 linemap_line_start (line_table, current_file->line, 80);
2099 /* ??? One could compute the exact column where the filename
2100 starts and compute the exact location here. */
2101 gfc_warning_now_at (linemap_position_for_column (line_table, 1),
2102 0, "file %qs left but not entered",
2103 filename);
2104 current_file->line++;
2105 if (unescape)
2106 free (wide_filename);
2107 free (filename);
2108 return;
2109 }
2110
2111 add_file_change (NULL, line);
2112 current_file = current_file->up;
2113 linemap_add (line_table, LC_RENAME, false, current_file->filename,
2114 current_file->line);
2115 }
2116
2117 /* The name of the file can be a temporary file produced by
2118 cpp. Replace the name if it is different. */
2119
2120 if (filename_cmp (current_file->filename, filename) != 0)
2121 {
2122 /* FIXME: we leak the old filename because a pointer to it may be stored
2123 in the linemap. Alternative could be using GC or updating linemap to
2124 point to the new name, but there is no API for that currently. */
2125 current_file->filename = xstrdup (filename);
2126
2127 /* We need to tell the linemap API that the filename changed. Just
2128 changing current_file is insufficient. */
2129 linemap_add (line_table, LC_RENAME, false, current_file->filename, line);
2130 }
2131
2132 /* Set new line number. */
2133 current_file->line = line;
2134 if (unescape)
2135 free (wide_filename);
2136 free (filename);
2137 return;
2138
2139 bad_cpp_line:
2140 linemap_line_start (line_table, current_file->line, 80);
2141 /* ??? One could compute the exact column where the directive
2142 starts and compute the exact location here. */
2143 gfc_warning_now_at (linemap_position_for_column (line_table, 2), 0,
2144 "Illegal preprocessor directive");
2145 current_file->line++;
2146}
2147
2148
2149static bool load_file (const char *, const char *, bool);
2150
2151/* include_line()-- Checks a line buffer to see if it is an include
2152 line. If so, we call load_file() recursively to load the included
2153 file. We never return a syntax error because a statement like
2154 "include = 5" is perfectly legal. We return 0 if no include was
2155 processed, 1 if we matched an include or -1 if include was
2156 partially processed, but will need continuation lines. */
2157
2158static int
2159include_line (gfc_char_t *line)
2160{
2161 gfc_char_t quote, *c, *begin, *stop;
2162 char *filename;
2163 const char *include = "include";
2164 bool allow_continuation = flag_dec_include;
2165 int i;
2166
2167 c = line;
2168
2169 if (flag_openmp || flag_openmp_simd)
2170 {
2171 if (gfc_current_form == FORM_FREE)
2172 {
2173 while (*c == ' ' || *c == '\t')
2174 c++;
2175 if (*c == '!' && c[1] == '$' && (c[2] == ' ' || c[2] == '\t'))
2176 c += 3;
2177 }
2178 else
2179 {
2180 if ((*c == '!' || *c == 'c' || *c == 'C' || *c == '*')
2181 && c[1] == '$' && c[2] == ' ')
2182 c += 3;
2183 }
2184 }
2185
2186 if (gfc_current_form == FORM_FREE)
2187 {
2188 while (*c == ' ' || *c == '\t')
2189 c++;
2190 if (gfc_wide_strncasecmp (c, "include", 7))
2191 {
2192 if (!allow_continuation)
2193 return 0;
2194 for (i = 0; i < 7; ++i)
2195 {
2196 gfc_char_t c1 = gfc_wide_tolower (*c);
2197 if (c1 != (unsigned char) include[i])
2198 break;
2199 c++;
2200 }
2201 if (i == 0 || *c != '&')
2202 return 0;
2203 c++;
2204 while (*c == ' ' || *c == '\t')
2205 c++;
2206 if (*c == '\0' || *c == '!')
2207 return -1;
2208 return 0;
2209 }
2210
2211 c += 7;
2212 }
2213 else
2214 {
2215 while (*c == ' ' || *c == '\t')
2216 c++;
2217 if (flag_dec_include && *c == '0' && c - line == 5)
2218 {
2219 c++;
2220 while (*c == ' ' || *c == '\t')
2221 c++;
2222 }
2223 if (c - line < 6)
2224 allow_continuation = false;
2225 for (i = 0; i < 7; ++i)
2226 {
2227 gfc_char_t c1 = gfc_wide_tolower (*c);
2228 if (c1 != (unsigned char) include[i])
2229 break;
2230 c++;
2231 while (*c == ' ' || *c == '\t')
2232 c++;
2233 }
2234 if (!allow_continuation)
2235 {
2236 if (i != 7)
2237 return 0;
2238 }
2239 else if (i != 7)
2240 {
2241 if (i == 0)
2242 return 0;
2243
2244 /* At the end of line or comment this might be continued. */
2245 if (*c == '\0' || *c == '!')
2246 return -1;
2247
2248 return 0;
2249 }
2250 }
2251
2252 while (*c == ' ' || *c == '\t')
2253 c++;
2254
2255 /* Find filename between quotes. */
2256
2257 quote = *c++;
2258 if (quote != '"' && quote != '\'')
2259 {
2260 if (allow_continuation)
2261 {
2262 if (gfc_current_form == FORM_FREE)
2263 {
2264 if (quote == '&')
2265 {
2266 while (*c == ' ' || *c == '\t')
2267 c++;
2268 if (*c == '\0' || *c == '!')
2269 return -1;
2270 }
2271 }
2272 else if (quote == '\0' || quote == '!')
2273 return -1;
2274 }
2275 return 0;
2276 }
2277
2278 begin = c;
2279
2280 bool cont = false;
2281 while (*c != quote && *c != '\0')
2282 {
2283 if (allow_continuation && gfc_current_form == FORM_FREE)
2284 {
2285 if (*c == '&')
2286 cont = true;
2287 else if (*c != ' ' && *c != '\t')
2288 cont = false;
2289 }
2290 c++;
2291 }
2292
2293 if (*c == '\0')
2294 {
2295 if (allow_continuation
2296 && (cont || gfc_current_form != FORM_FREE))
2297 return -1;
2298 return 0;
2299 }
2300
2301 stop = c++;
2302
2303 while (*c == ' ' || *c == '\t')
2304 c++;
2305
2306 if (*c != '\0' && *c != '!')
2307 return 0;
2308
2309 /* We have an include line at this point. */
2310
2311 *stop = '\0'; /* It's ok to trash the buffer, as this line won't be
2312 read by anything else. */
2313
2314 filename = gfc_widechar_to_char (begin, -1);
2315 if (!load_file (filename, NULL, false))
2316 exit (FATAL_EXIT_CODE);
2317
2318 free (filename);
2319 return 1;
2320}
2321
2322/* Similarly, but try to parse an INCLUDE statement, using gfc_next_char etc.
2323 APIs. Return 1 if recognized as valid INCLUDE statement and load_file has
2324 been called, 0 if it is not a valid INCLUDE statement and -1 if eof has
2325 been encountered while parsing it. */
2326static int
2327include_stmt (gfc_linebuf *b)
2328{
2329 int ret = 0, i, length;
2330 const char *include = "include";
2331 gfc_char_t c, quote = 0;
2332 locus str_locus;
2333 char *filename;
2334
2335 continue_flag = 0;
2336 end_flag = 0;
2337 gcc_attribute_flag = 0;
2338 openmp_flag = 0;
2339 openacc_flag = 0;
2340 continue_count = 0;
2341 continue_line = 0;
2342 gfc_current_locus.lb = b;
2343 gfc_current_locus.nextc = b->line;
2344
2345 gfc_skip_comments ();
2346 gfc_gobble_whitespace ();
2347
2348 for (i = 0; i < 7; i++)
2349 {
2350 c = gfc_next_char ();
2351 if (c != (unsigned char) include[i])
2352 {
2353 if (gfc_current_form == FORM_FIXED
2354 && i == 0
2355 && c == '0'
2356 && gfc_current_locus.nextc == b->line + 6)
2357 {
2358 gfc_gobble_whitespace ();
2359 i--;
2360 continue;
2361 }
2362 gcc_assert (i != 0);
2363 if (c == '\n')
2364 {
2365 gfc_advance_line ();
2366 gfc_skip_comments ();
2367 if (gfc_at_eof ())
2368 ret = -1;
2369 }
2370 goto do_ret;
2371 }
2372 }
2373 gfc_gobble_whitespace ();
2374
2375 c = gfc_next_char ();
2376 if (c == '\'' || c == '"')
2377 quote = c;
2378 else
2379 {
2380 if (c == '\n')
2381 {
2382 gfc_advance_line ();
2383 gfc_skip_comments ();
2384 if (gfc_at_eof ())
2385 ret = -1;
2386 }
2387 goto do_ret;
2388 }
2389
2390 str_locus = gfc_current_locus;
2391 length = 0;
2392 do
2393 {
2394 c = gfc_next_char_literal (INSTRING_NOWARN);
2395 if (c == quote)
2396 break;
2397 if (c == '\n')
2398 {
2399 gfc_advance_line ();
2400 gfc_skip_comments ();
2401 if (gfc_at_eof ())
2402 ret = -1;
2403 goto do_ret;
2404 }
2405 length++;
2406 }
2407 while (1);
2408
2409 gfc_gobble_whitespace ();
2410 c = gfc_next_char ();
2411 if (c != '\n')
2412 goto do_ret;
2413
2414 gfc_current_locus = str_locus;
2415 ret = 1;
2416 filename = XNEWVEC (char, length + 1);
2417 for (i = 0; i < length; i++)
2418 {
2419 c = gfc_next_char_literal (INSTRING_WARN);
2420 gcc_assert (gfc_wide_fits_in_byte (c));
2421 filename[i] = (unsigned char) c;
2422 }
2423 filename[length] = '\0';
2424 if (!load_file (filename, NULL, false))
2425 exit (FATAL_EXIT_CODE);
2426
2427 free (filename);
2428
2429do_ret:
2430 continue_flag = 0;
2431 end_flag = 0;
2432 gcc_attribute_flag = 0;
2433 openmp_flag = 0;
2434 openacc_flag = 0;
2435 continue_count = 0;
2436 continue_line = 0;
2437 memset (&gfc_current_locus, '\0', sizeof (locus));
2438 memset (&openmp_locus, '\0', sizeof (locus));
2439 memset (&openacc_locus, '\0', sizeof (locus));
2440 memset (&gcc_attribute_locus, '\0', sizeof (locus));
2441 return ret;
2442}
2443
2444/* Load a file into memory by calling load_line until the file ends. */
2445
2446static bool
2447load_file (const char *realfilename, const char *displayedname, bool initial)
2448{
2449 gfc_char_t *line;
2450 gfc_linebuf *b, *include_b = NULL;
2451 gfc_file *f;
2452 FILE *input;
2453 int len, line_len;
2454 bool first_line;
2455 struct stat st;
2456 int stat_result;
2457 const char *filename;
2458 /* If realfilename and displayedname are different and non-null then
2459 surely realfilename is the preprocessed form of
2460 displayedname. */
2461 bool preprocessed_p = (realfilename && displayedname
2462 && strcmp (realfilename, displayedname));
2463
2464 filename = displayedname ? displayedname : realfilename;
2465
2466 for (f = current_file; f; f = f->up)
2467 if (filename_cmp (filename, f->filename) == 0)
2468 {
2469 fprintf (stderr, "%s:%d: Error: File '%s' is being included "
2470 "recursively\n", current_file->filename, current_file->line,
2471 filename);
2472 return false;
2473 }
2474
2475 if (initial)
2476 {
2477 if (gfc_src_file)
2478 {
2479 input = gfc_src_file;
2480 gfc_src_file = NULL;
2481 }
2482 else
2483 input = gfc_open_file (realfilename);
2484
2485 if (input == NULL)
2486 {
2487 gfc_error_now ("Cannot open file %qs", filename);
2488 return false;
2489 }
2490 }
2491 else
2492 {
2493 input = gfc_open_included_file (realfilename, false, false);
2494 if (input == NULL)
2495 {
2496 /* For -fpre-include file, current_file is NULL. */
2497 if (current_file)
2498 fprintf (stderr, "%s:%d: Error: Can't open included file '%s'\n",
2499 current_file->filename, current_file->line, filename);
2500 else
2501 fprintf (stderr, "Error: Can't open pre-included file '%s'\n",
2502 filename);
2503
2504 return false;
2505 }
2506 stat_result = stat (realfilename, &st);
2507 if (stat_result == 0 && !S_ISREG(st.st_mode))
2508 {
2509 fprintf (stderr, "%s:%d: Error: Included path '%s'"
2510 " is not a regular file\n",
2511 current_file->filename, current_file->line, filename);
2512 fclose (input);
2513 return false;
2514 }
2515 }
2516
2517 /* Load the file.
2518
2519 A "non-initial" file means a file that is being included. In
2520 that case we are creating an LC_ENTER map.
2521
2522 An "initial" file means a main file; one that is not included.
2523 That file has already got at least one (surely more) line map(s)
2524 created by gfc_init. So the subsequent map created in that case
2525 must have LC_RENAME reason.
2526
2527 This latter case is not true for a preprocessed file. In that
2528 case, although the file is "initial", the line maps created by
2529 gfc_init was used during the preprocessing of the file. Now that
2530 the preprocessing is over and we are being fed the result of that
2531 preprocessing, we need to create a brand new line map for the
2532 preprocessed file, so the reason is going to be LC_ENTER. */
2533
2534 f = get_file (filename, (initial && !preprocessed_p) ? LC_RENAME : LC_ENTER);
2535 if (!initial)
2536 add_file_change (f->filename, f->inclusion_line);
2537 current_file = f;
2538 current_file->line = 1;
2539 line = NULL;
2540 line_len = 0;
2541 first_line = true;
2542
2543 if (initial && gfc_src_preprocessor_lines[0])
2544 {
2545 preprocessor_line (gfc_src_preprocessor_lines[0]);
2546 free (gfc_src_preprocessor_lines[0]);
2547 gfc_src_preprocessor_lines[0] = NULL;
2548 if (gfc_src_preprocessor_lines[1])
2549 {
2550 preprocessor_line (gfc_src_preprocessor_lines[1]);
2551 free (gfc_src_preprocessor_lines[1]);
2552 gfc_src_preprocessor_lines[1] = NULL;
2553 }
2554 }
2555
2556 for (;;)
2557 {
2558 int trunc = load_line (input, &line, &line_len, NULL);
2559 int inc_line;
2560
2561 len = gfc_wide_strlen (line);
2562 if (feof (input) && len == 0)
2563 break;
2564
2565 /* If this is the first line of the file, it can contain a byte
2566 order mark (BOM), which we will ignore:
2567 FF FE is UTF-16 little endian,
2568 FE FF is UTF-16 big endian,
2569 EF BB BF is UTF-8. */
2570 if (first_line
2571 && ((line_len >= 2 && line[0] == (unsigned char) '\xFF'
2572 && line[1] == (unsigned char) '\xFE')
2573 || (line_len >= 2 && line[0] == (unsigned char) '\xFE'
2574 && line[1] == (unsigned char) '\xFF')
2575 || (line_len >= 3 && line[0] == (unsigned char) '\xEF'
2576 && line[1] == (unsigned char) '\xBB'
2577 && line[2] == (unsigned char) '\xBF')))
2578 {
2579 int n = line[1] == (unsigned char) '\xBB' ? 3 : 2;
2580 gfc_char_t *new_char = gfc_get_wide_string (line_len);
2581
2582 wide_strcpy (new_char, &line[n]);
2583 free (line);
2584 line = new_char;
2585 len -= n;
2586 }
2587
2588 /* There are three things this line can be: a line of Fortran
2589 source, an include line or a C preprocessor directive. */
2590
2591 if (line[0] == '#')
2592 {
2593 /* When -g3 is specified, it's possible that we emit #define
2594 and #undef lines, which we need to pass to the middle-end
2595 so that it can emit correct debug info. */
2596 if (debug_info_level == DINFO_LEVEL_VERBOSE
2597 && (wide_strncmp (line, "#define ", 8) == 0
2598 || wide_strncmp (line, "#undef ", 7) == 0))
2599 ;
2600 else
2601 {
2602 preprocessor_line (line);
2603 continue;
2604 }
2605 }
2606
2607 /* Preprocessed files have preprocessor lines added before the byte
2608 order mark, so first_line is not about the first line of the file
2609 but the first line that's not a preprocessor line. */
2610 first_line = false;
2611
2612 inc_line = include_line (line);
2613 if (inc_line > 0)
2614 {
2615 current_file->line++;
2616 continue;
2617 }
2618
2619 /* Add line. */
2620
2621 b = XCNEWVAR (gfc_linebuf, gfc_linebuf_header_size
2622 + (len + 1) * sizeof (gfc_char_t));
2623
2624
2625 b->location
2626 = linemap_line_start (line_table, current_file->line++, len);
2627 /* ??? We add the location for the maximum column possible here,
2628 because otherwise if the next call creates a new line-map, it
2629 will not reserve space for any offset. */
2630 if (len > 0)
2631 linemap_position_for_column (line_table, len);
2632
2633 b->file = current_file;
2634 b->truncated = trunc;
2635 wide_strcpy (b->line, line);
2636
2637 if (line_head == NULL)
2638 line_head = b;
2639 else
2640 line_tail->next = b;
2641
2642 line_tail = b;
2643
2644 while (file_changes_cur < file_changes_count)
2645 file_changes[file_changes_cur++].lb = b;
2646
2647 if (flag_dec_include)
2648 {
2649 if (include_b && b != include_b)
2650 {
2651 int inc_line2 = include_stmt (include_b);
2652 if (inc_line2 == 0)
2653 include_b = NULL;
2654 else if (inc_line2 > 0)
2655 {
2656 do
2657 {
2658 if (gfc_current_form == FORM_FIXED)
2659 {
2660 for (gfc_char_t *p = include_b->line; *p; p++)
2661 *p = ' ';
2662 }
2663 else
2664 include_b->line[0] = '\0';
2665 if (include_b == b)
2666 break;
2667 include_b = include_b->next;
2668 }
2669 while (1);
2670 include_b = NULL;
2671 }
2672 }
2673 if (inc_line == -1 && !include_b)
2674 include_b = b;
2675 }
2676 }
2677
2678 /* Release the line buffer allocated in load_line. */
2679 free (line);
2680
2681 fclose (input);
2682
2683 if (!initial)
2684 add_file_change (NULL, current_file->inclusion_line + 1);
2685 current_file = current_file->up;
2686 linemap_add (line_table, LC_LEAVE, 0, NULL, 0);
2687 return true;
2688}
2689
2690
2691/* Open a new file and start scanning from that file. Returns true
2692 if everything went OK, false otherwise. If form == FORM_UNKNOWN
2693 it tries to determine the source form from the filename, defaulting
2694 to free form. */
2695
2696bool
2697gfc_new_file (void)
2698{
2699 bool result;
2700
2701 if (flag_pre_include != NULL
2702 && !load_file (flag_pre_include, NULL, false))
2703 exit (FATAL_EXIT_CODE);
2704
2705 if (gfc_cpp_enabled ())
2706 {
2707 result = gfc_cpp_preprocess (gfc_source_file);
2708 if (!gfc_cpp_preprocess_only ())
2709 result = load_file (gfc_cpp_temporary_file (), gfc_source_file, true);
2710 }
2711 else
2712 result = load_file (gfc_source_file, NULL, true);
2713
2714 gfc_current_locus.lb = line_head;
2715 gfc_current_locus.nextc = (line_head == NULL) ? NULL : line_head->line;
2716
2717#if 0 /* Debugging aid. */
2718 for (; line_head; line_head = line_head->next)
2719 printf ("%s:%3d %s\n", LOCATION_FILE (line_head->location),
2720 LOCATION_LINE (line_head->location), line_head->line);
2721
2722 exit (SUCCESS_EXIT_CODE);
2723#endif
2724
2725 return result;
2726}
2727
2728static char *
2729unescape_filename (const char *ptr)
2730{
2731 const char *p = ptr, *s;
2732 char *d, *ret;
2733 int escaped, unescape = 0;
2734
2735 /* Make filename end at quote. */
2736 escaped = false;
2737 while (*p && ! (! escaped && *p == '"'))
2738 {
2739 if (escaped)
2740 escaped = false;
2741 else if (*p == '\\')
2742 {
2743 escaped = true;
2744 unescape++;
2745 }
2746 ++p;
2747 }
2748
2749 if (!*p || p[1])
2750 return NULL;
2751
2752 /* Undo effects of cpp_quote_string. */
2753 s = ptr;
2754 d = XCNEWVEC (char, p + 1 - ptr - unescape);
2755 ret = d;
2756
2757 while (s != p)
2758 {
2759 if (*s == '\\')
2760 *d++ = *++s;
2761 else
2762 *d++ = *s;
2763 s++;
2764 }
2765 *d = '\0';
2766 return ret;
2767}
2768
2769/* For preprocessed files, if the first tokens are of the form # NUM.
2770 handle the directives so we know the original file name. */
2771
2772const char *
2773gfc_read_orig_filename (const char *filename, const char **canon_source_file)
2774{
2775 int c, len;
2776 char *dirname, *tmp;
2777
2778 gfc_src_file = gfc_open_file (filename);
2779 if (gfc_src_file == NULL)
2780 return NULL;
2781
2782 c = getc (gfc_src_file);
2783
2784 if (c != '#')
2785 return NULL;
2786
2787 len = 0;
2788 load_line (gfc_src_file, &gfc_src_preprocessor_lines[0], &len, &c);
2789
2790 if (wide_strncmp (gfc_src_preprocessor_lines[0], "# 1 \"", 5) != 0)
2791 return NULL;
2792
2793 tmp = gfc_widechar_to_char (&gfc_src_preprocessor_lines[0][5], -1);
2794 filename = unescape_filename (tmp);
2795 free (tmp);
2796 if (filename == NULL)
2797 return NULL;
2798
2799 c = getc (gfc_src_file);
2800
2801 if (c != '#')
2802 return filename;
2803
2804 len = 0;
2805 load_line (gfc_src_file, &gfc_src_preprocessor_lines[1], &len, &c);
2806
2807 if (wide_strncmp (gfc_src_preprocessor_lines[1], "# 1 \"", 5) != 0)
2808 return filename;
2809
2810 tmp = gfc_widechar_to_char (&gfc_src_preprocessor_lines[1][5], -1);
2811 dirname = unescape_filename (tmp);
2812 free (tmp);
2813 if (dirname == NULL)
2814 return filename;
2815
2816 len = strlen (dirname);
2817 if (len < 3 || dirname[len - 1] != '/' || dirname[len - 2] != '/')
2818 {
2819 free (dirname);
2820 return filename;
2821 }
2822 dirname[len - 2] = '\0';
2823 set_src_pwd (dirname);
2824
2825 if (! IS_ABSOLUTE_PATH (filename))
2826 {
2827 char *p = XCNEWVEC (char, len + strlen (filename));
2828
2829 memcpy (p, dirname, len - 2);
2830 p[len - 2] = '/';
2831 strcpy (p + len - 1, filename);
2832 *canon_source_file = p;
2833 }
2834
2835 free (dirname);
2836 return filename;
2837}