]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/fortran/scanner.c
re PR ada/29802 (wrong directory in makefile for ada and libada when srcdir=.)
[thirdparty/gcc.git] / gcc / fortran / scanner.c
CommitLineData
6de9cd9a 1/* Character scanner.
6c7a4dfd 2 Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006
ec378180 3 Free Software Foundation, Inc.
6de9cd9a
DN
4 Contributed by Andy Vaught
5
9fc4d79b 6This file is part of GCC.
6de9cd9a 7
9fc4d79b
TS
8GCC is free software; you can redistribute it and/or modify it under
9the terms of the GNU General Public License as published by the Free
10Software Foundation; either version 2, or (at your option) any later
11version.
6de9cd9a 12
9fc4d79b
TS
13GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16for more details.
6de9cd9a
DN
17
18You should have received a copy of the GNU General Public License
9fc4d79b 19along with GCC; see the file COPYING. If not, write to the Free
ab57747b
KC
20Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
2102110-1301, USA. */
6de9cd9a
DN
22
23/* Set of subroutines to (ultimately) return the next character to the
24 various matching subroutines. This file's job is to read files and
25 build up lines that are parsed by the parser. This means that we
26 handle continuation lines and "include" lines.
27
28 The first thing the scanner does is to load an entire file into
29 memory. We load the entire file into memory for a couple reasons.
30 The first is that we want to be able to deal with nonseekable input
31 (pipes, stdin) and there is a lot of backing up involved during
32 parsing.
33
34 The second is that we want to be able to print the locus of errors,
35 and an error on line 999999 could conflict with something on line
36 one. Given nonseekable input, we've got to store the whole thing.
37
38 One thing that helps are the column truncation limits that give us
39 an upper bound on the size of individual lines. We don't store the
40 truncated stuff.
41
42 From the scanner's viewpoint, the higher level subroutines ask for
43 new characters and do a lot of jumping backwards. */
44
45#include "config.h"
d22e4895 46#include "system.h"
6de9cd9a 47#include "gfortran.h"
2d7c7df6 48#include "toplev.h"
6de9cd9a
DN
49
50/* Structure for holding module and include file search path. */
51typedef struct gfc_directorylist
52{
53 char *path;
54 struct gfc_directorylist *next;
55}
56gfc_directorylist;
57
58/* List of include file search directories. */
59static gfc_directorylist *include_dirs;
60
d4fa05b9 61static gfc_file *file_head, *current_file;
6de9cd9a 62
6c7a4dfd 63static int continue_flag, end_flag, openmp_flag;
5a06474c 64static int continue_count, continue_line;
6c7a4dfd 65static locus openmp_locus;
6de9cd9a 66
d4fa05b9
TS
67gfc_source_form gfc_current_form;
68static gfc_linebuf *line_head, *line_tail;
69
63645982 70locus gfc_current_locus;
e0bcf78c 71const char *gfc_source_file;
2d7c7df6
JJ
72static FILE *gfc_src_file;
73static char *gfc_src_preprocessor_lines[2];
74
5a06474c 75extern int pedantic;
6de9cd9a
DN
76
77/* Main scanner initialization. */
78
79void
80gfc_scanner_init_1 (void)
81{
d4fa05b9
TS
82 file_head = NULL;
83 line_head = NULL;
84 line_tail = NULL;
6de9cd9a 85
5a06474c
JD
86 continue_count = 0;
87 continue_line = 0;
88
6de9cd9a
DN
89 end_flag = 0;
90}
91
92
93/* Main scanner destructor. */
94
95void
96gfc_scanner_done_1 (void)
97{
d4fa05b9
TS
98 gfc_linebuf *lb;
99 gfc_file *f;
6de9cd9a 100
d4fa05b9 101 while(line_head != NULL)
6de9cd9a 102 {
d4fa05b9
TS
103 lb = line_head->next;
104 gfc_free(line_head);
105 line_head = lb;
6de9cd9a 106 }
d4fa05b9
TS
107
108 while(file_head != NULL)
6de9cd9a 109 {
d4fa05b9
TS
110 f = file_head->next;
111 gfc_free(file_head->filename);
112 gfc_free(file_head);
113 file_head = f;
6de9cd9a 114 }
d4fa05b9 115
6de9cd9a
DN
116}
117
118
119/* Adds path to the list pointed to by list. */
120
121void
122gfc_add_include_path (const char *path)
123{
124 gfc_directorylist *dir;
125 const char *p;
126
127 p = path;
128 while (*p == ' ' || *p == '\t') /* someone might do 'gfortran "-I include"' */
129 if (*p++ == '\0')
130 return;
131
132 dir = include_dirs;
133 if (!dir)
134 {
135 dir = include_dirs = gfc_getmem (sizeof (gfc_directorylist));
136 }
137 else
138 {
139 while (dir->next)
140 dir = dir->next;
141
142 dir->next = gfc_getmem (sizeof (gfc_directorylist));
143 dir = dir->next;
144 }
145
146 dir->next = NULL;
147 dir->path = gfc_getmem (strlen (p) + 2);
148 strcpy (dir->path, p);
149 strcat (dir->path, "/"); /* make '/' last character */
150}
151
152
153/* Release resources allocated for options. */
154
155void
156gfc_release_include_path (void)
157{
158 gfc_directorylist *p;
159
160 gfc_free (gfc_option.module_dir);
161 while (include_dirs != NULL)
162 {
163 p = include_dirs;
164 include_dirs = include_dirs->next;
165 gfc_free (p->path);
166 gfc_free (p);
167 }
168}
169
6de9cd9a 170/* Opens file for reading, searching through the include directories
b424a572
FXC
171 given if necessary. If the include_cwd argument is true, we try
172 to open the file in the current directory first. */
6de9cd9a
DN
173
174FILE *
b424a572 175gfc_open_included_file (const char *name, const bool include_cwd)
6de9cd9a 176{
200cfbe7 177 char *fullname;
6de9cd9a
DN
178 gfc_directorylist *p;
179 FILE *f;
180
b424a572
FXC
181 if (include_cwd)
182 {
183 f = gfc_open_file (name);
184 if (f != NULL)
185 return f;
186 }
6de9cd9a
DN
187
188 for (p = include_dirs; p; p = p->next)
189 {
200cfbe7 190 fullname = (char *) alloca(strlen (p->path) + strlen (name) + 1);
6de9cd9a
DN
191 strcpy (fullname, p->path);
192 strcat (fullname, name);
193
194 f = gfc_open_file (fullname);
195 if (f != NULL)
196 return f;
197 }
198
199 return NULL;
200}
201
6de9cd9a
DN
202/* Test to see if we're at the end of the main source file. */
203
204int
205gfc_at_end (void)
206{
207
208 return end_flag;
209}
210
211
212/* Test to see if we're at the end of the current file. */
213
214int
215gfc_at_eof (void)
216{
217
218 if (gfc_at_end ())
219 return 1;
220
d4fa05b9 221 if (line_head == NULL)
6de9cd9a
DN
222 return 1; /* Null file */
223
63645982 224 if (gfc_current_locus.lb == NULL)
6de9cd9a
DN
225 return 1;
226
227 return 0;
228}
229
230
231/* Test to see if we're at the beginning of a new line. */
232
233int
234gfc_at_bol (void)
235{
6de9cd9a
DN
236 if (gfc_at_eof ())
237 return 1;
238
63645982 239 return (gfc_current_locus.nextc == gfc_current_locus.lb->line);
6de9cd9a
DN
240}
241
242
243/* Test to see if we're at the end of a line. */
244
245int
246gfc_at_eol (void)
247{
248
249 if (gfc_at_eof ())
250 return 1;
251
63645982 252 return (*gfc_current_locus.nextc == '\0');
6de9cd9a
DN
253}
254
255
256/* Advance the current line pointer to the next line. */
257
258void
259gfc_advance_line (void)
260{
6de9cd9a
DN
261 if (gfc_at_end ())
262 return;
263
63645982 264 if (gfc_current_locus.lb == NULL)
6de9cd9a 265 {
d4fa05b9
TS
266 end_flag = 1;
267 return;
268 }
6de9cd9a 269
63645982 270 gfc_current_locus.lb = gfc_current_locus.lb->next;
6de9cd9a 271
63645982
TS
272 if (gfc_current_locus.lb != NULL)
273 gfc_current_locus.nextc = gfc_current_locus.lb->line;
d4fa05b9
TS
274 else
275 {
63645982 276 gfc_current_locus.nextc = NULL;
d4fa05b9
TS
277 end_flag = 1;
278 }
6de9cd9a
DN
279}
280
281
282/* Get the next character from the input, advancing gfc_current_file's
283 locus. When we hit the end of the line or the end of the file, we
284 start returning a '\n' in order to complete the current statement.
285 No Fortran line conventions are implemented here.
286
287 Requiring explicit advances to the next line prevents the parse
288 pointer from being on the wrong line if the current statement ends
289 prematurely. */
290
291static int
292next_char (void)
293{
6de9cd9a 294 int c;
d4fa05b9 295
63645982 296 if (gfc_current_locus.nextc == NULL)
6de9cd9a
DN
297 return '\n';
298
63645982 299 c = *gfc_current_locus.nextc++;
6de9cd9a
DN
300 if (c == '\0')
301 {
63645982 302 gfc_current_locus.nextc--; /* Remain on this line. */
6de9cd9a
DN
303 c = '\n';
304 }
305
306 return c;
307}
308
6de9cd9a
DN
309/* Skip a comment. When we come here the parse pointer is positioned
310 immediately after the comment character. If we ever implement
311 compiler directives withing comments, here is where we parse the
312 directive. */
313
314static void
315skip_comment_line (void)
316{
317 char c;
318
319 do
320 {
321 c = next_char ();
322 }
323 while (c != '\n');
324
325 gfc_advance_line ();
326}
327
328
329/* Comment lines are null lines, lines containing only blanks or lines
0d3abf6f
JJ
330 on which the first nonblank line is a '!'.
331 Return true if !$ openmp conditional compilation sentinel was
332 seen. */
6de9cd9a 333
0d3abf6f 334static bool
6de9cd9a
DN
335skip_free_comments (void)
336{
337 locus start;
338 char c;
6c7a4dfd 339 int at_bol;
6de9cd9a
DN
340
341 for (;;)
342 {
6c7a4dfd 343 at_bol = gfc_at_bol ();
63645982 344 start = gfc_current_locus;
6de9cd9a
DN
345 if (gfc_at_eof ())
346 break;
347
348 do
6c7a4dfd 349 c = next_char ();
6de9cd9a
DN
350 while (gfc_is_whitespace (c));
351
352 if (c == '\n')
353 {
354 gfc_advance_line ();
355 continue;
356 }
357
358 if (c == '!')
359 {
6c7a4dfd
JJ
360 /* If -fopenmp, we need to handle here 2 things:
361 1) don't treat !$omp as comments, but directives
362 2) handle OpenMP conditional compilation, where
363 !$ should be treated as 2 spaces (for initial lines
364 only if followed by space). */
365 if (gfc_option.flag_openmp && at_bol)
366 {
367 locus old_loc = gfc_current_locus;
368 if (next_char () == '$')
369 {
370 c = next_char ();
371 if (c == 'o' || c == 'O')
372 {
373 if (((c = next_char ()) == 'm' || c == 'M')
374 && ((c = next_char ()) == 'p' || c == 'P')
375 && ((c = next_char ()) == ' ' || continue_flag))
376 {
377 while (gfc_is_whitespace (c))
378 c = next_char ();
379 if (c != '\n' && c != '!')
380 {
381 openmp_flag = 1;
382 openmp_locus = old_loc;
383 gfc_current_locus = start;
0d3abf6f 384 return false;
6c7a4dfd
JJ
385 }
386 }
387 gfc_current_locus = old_loc;
388 next_char ();
389 c = next_char ();
390 }
391 if (continue_flag || c == ' ')
392 {
393 gfc_current_locus = old_loc;
394 next_char ();
b30c6a0d 395 openmp_flag = 0;
0d3abf6f 396 return true;
6c7a4dfd
JJ
397 }
398 }
399 gfc_current_locus = old_loc;
400 }
6de9cd9a
DN
401 skip_comment_line ();
402 continue;
403 }
404
405 break;
406 }
407
6c7a4dfd
JJ
408 if (openmp_flag && at_bol)
409 openmp_flag = 0;
63645982 410 gfc_current_locus = start;
0d3abf6f 411 return false;
6de9cd9a
DN
412}
413
414
415/* Skip comment lines in fixed source mode. We have the same rules as
416 in skip_free_comment(), except that we can have a 'c', 'C' or '*'
e0bcf78c
TS
417 in column 1, and a '!' cannot be in column 6. Also, we deal with
418 lines with 'd' or 'D' in column 1, if the user requested this. */
6de9cd9a
DN
419
420static void
421skip_fixed_comments (void)
422{
423 locus start;
424 int col;
425 char c;
426
6c7a4dfd
JJ
427 if (! gfc_at_bol ())
428 {
429 start = gfc_current_locus;
430 if (! gfc_at_eof ())
431 {
432 do
433 c = next_char ();
434 while (gfc_is_whitespace (c));
435
436 if (c == '\n')
437 gfc_advance_line ();
438 else if (c == '!')
439 skip_comment_line ();
440 }
441
442 if (! gfc_at_bol ())
443 {
444 gfc_current_locus = start;
445 return;
446 }
447 }
448
6de9cd9a
DN
449 for (;;)
450 {
63645982 451 start = gfc_current_locus;
6de9cd9a
DN
452 if (gfc_at_eof ())
453 break;
454
455 c = next_char ();
456 if (c == '\n')
457 {
458 gfc_advance_line ();
459 continue;
460 }
461
462 if (c == '!' || c == 'c' || c == 'C' || c == '*')
463 {
6c7a4dfd
JJ
464 /* If -fopenmp, we need to handle here 2 things:
465 1) don't treat !$omp|c$omp|*$omp as comments, but directives
466 2) handle OpenMP conditional compilation, where
467 !$|c$|*$ should be treated as 2 spaces if the characters
468 in columns 3 to 6 are valid fixed form label columns
469 characters. */
470 if (gfc_option.flag_openmp)
471 {
472 if (next_char () == '$')
473 {
474 c = next_char ();
475 if (c == 'o' || c == 'O')
476 {
477 if (((c = next_char ()) == 'm' || c == 'M')
478 && ((c = next_char ()) == 'p' || c == 'P'))
479 {
480 c = next_char ();
481 if (c != '\n'
482 && ((openmp_flag && continue_flag)
483 || c == ' ' || c == '0'))
484 {
485 c = next_char ();
486 while (gfc_is_whitespace (c))
487 c = next_char ();
488 if (c != '\n' && c != '!')
489 {
490 /* Canonicalize to *$omp. */
491 *start.nextc = '*';
492 openmp_flag = 1;
493 gfc_current_locus = start;
494 return;
495 }
496 }
497 }
498 }
499 else
500 {
501 int digit_seen = 0;
502
503 for (col = 3; col < 6; col++, c = next_char ())
504 if (c == ' ')
505 continue;
506 else if (c < '0' || c > '9')
507 break;
508 else
509 digit_seen = 1;
510
511 if (col == 6 && c != '\n'
512 && ((continue_flag && !digit_seen)
513 || c == ' ' || c == '0'))
514 {
515 gfc_current_locus = start;
516 start.nextc[0] = ' ';
517 start.nextc[1] = ' ';
518 continue;
519 }
520 }
521 }
522 gfc_current_locus = start;
523 }
6de9cd9a
DN
524 skip_comment_line ();
525 continue;
526 }
527
e0bcf78c
TS
528 if (gfc_option.flag_d_lines != -1 && (c == 'd' || c == 'D'))
529 {
530 if (gfc_option.flag_d_lines == 0)
531 {
532 skip_comment_line ();
533 continue;
534 }
535 else
536 *start.nextc = c = ' ';
537 }
538
6de9cd9a 539 col = 1;
e0bcf78c
TS
540
541 while (gfc_is_whitespace (c))
6de9cd9a
DN
542 {
543 c = next_char ();
544 col++;
545 }
6de9cd9a
DN
546
547 if (c == '\n')
548 {
549 gfc_advance_line ();
550 continue;
551 }
552
553 if (col != 6 && c == '!')
554 {
555 skip_comment_line ();
556 continue;
557 }
558
559 break;
560 }
561
6c7a4dfd 562 openmp_flag = 0;
63645982 563 gfc_current_locus = start;
6de9cd9a
DN
564}
565
566
6c7a4dfd 567/* Skips the current line if it is a comment. */
6de9cd9a
DN
568
569void
570gfc_skip_comments (void)
571{
6c7a4dfd 572 if (gfc_current_form == FORM_FREE)
6de9cd9a
DN
573 skip_free_comments ();
574 else
575 skip_fixed_comments ();
576}
577
578
579/* Get the next character from the input, taking continuation lines
580 and end-of-line comments into account. This implies that comment
581 lines between continued lines must be eaten here. For higher-level
582 subroutines, this flattens continued lines into a single logical
583 line. The in_string flag denotes whether we're inside a character
584 context or not. */
585
586int
587gfc_next_char_literal (int in_string)
588{
589 locus old_loc;
6c7a4dfd 590 int i, c, prev_openmp_flag;
6de9cd9a
DN
591
592 continue_flag = 0;
593
594restart:
595 c = next_char ();
596 if (gfc_at_end ())
5a06474c
JD
597 {
598 continue_count = 0;
599 return c;
600 }
6de9cd9a 601
d4fa05b9 602 if (gfc_current_form == FORM_FREE)
6de9cd9a 603 {
0d3abf6f
JJ
604 bool openmp_cond_flag;
605
6de9cd9a
DN
606 if (!in_string && c == '!')
607 {
6c7a4dfd
JJ
608 if (openmp_flag
609 && memcmp (&gfc_current_locus, &openmp_locus,
610 sizeof (gfc_current_locus)) == 0)
611 goto done;
612
6de9cd9a
DN
613 /* This line can't be continued */
614 do
615 {
616 c = next_char ();
617 }
618 while (c != '\n');
619
a34938be
RG
620 /* Avoid truncation warnings for comment ending lines. */
621 gfc_current_locus.lb->truncated = 0;
622
6de9cd9a
DN
623 goto done;
624 }
625
626 if (c != '&')
627 goto done;
628
629 /* If the next nonblank character is a ! or \n, we've got a
6c7a4dfd 630 continuation line. */
63645982 631 old_loc = gfc_current_locus;
6de9cd9a
DN
632
633 c = next_char ();
634 while (gfc_is_whitespace (c))
635 c = next_char ();
636
637 /* Character constants to be continued cannot have commentary
6c7a4dfd 638 after the '&'. */
6de9cd9a
DN
639
640 if (in_string && c != '\n')
641 {
63645982 642 gfc_current_locus = old_loc;
6de9cd9a
DN
643 c = '&';
644 goto done;
645 }
646
647 if (c != '!' && c != '\n')
648 {
63645982 649 gfc_current_locus = old_loc;
6de9cd9a
DN
650 c = '&';
651 goto done;
652 }
653
6c7a4dfd 654 prev_openmp_flag = openmp_flag;
6de9cd9a
DN
655 continue_flag = 1;
656 if (c == '!')
657 skip_comment_line ();
658 else
659 gfc_advance_line ();
660
5a06474c
JD
661 /* We've got a continuation line. If we are on the very next line after
662 the last continuation, increment the continuation line count and
663 check whether the limit has been exceeded. */
664 if (gfc_current_locus.lb->linenum == continue_line + 1)
665 {
666 if (++continue_count == gfc_option.max_continue_free)
667 {
668 if (gfc_notification_std (GFC_STD_GNU)
669 || pedantic)
670 gfc_warning ("Limit of %d continuations exceeded in statement at %C",
671 gfc_option.max_continue_free);
672 }
673 }
674 continue_line = gfc_current_locus.lb->linenum;
675
676 /* Now find where it continues. First eat any comment lines. */
0d3abf6f 677 openmp_cond_flag = skip_free_comments ();
6de9cd9a 678
6c7a4dfd
JJ
679 if (prev_openmp_flag != openmp_flag)
680 {
681 gfc_current_locus = old_loc;
682 openmp_flag = prev_openmp_flag;
683 c = '&';
684 goto done;
685 }
686
6de9cd9a 687 /* Now that we have a non-comment line, probe ahead for the
6c7a4dfd
JJ
688 first non-whitespace character. If it is another '&', then
689 reading starts at the next character, otherwise we must back
690 up to where the whitespace started and resume from there. */
6de9cd9a 691
63645982 692 old_loc = gfc_current_locus;
6de9cd9a
DN
693
694 c = next_char ();
695 while (gfc_is_whitespace (c))
696 c = next_char ();
697
6c7a4dfd
JJ
698 if (openmp_flag)
699 {
700 for (i = 0; i < 5; i++, c = next_char ())
701 {
702 gcc_assert (TOLOWER (c) == "!$omp"[i]);
703 if (i == 4)
704 old_loc = gfc_current_locus;
705 }
706 while (gfc_is_whitespace (c))
707 c = next_char ();
708 }
709
6de9cd9a 710 if (c != '&')
3fbab549 711 {
5a06474c
JD
712 if (in_string)
713 {
714 if (gfc_option.warn_ampersand)
715 gfc_warning_now ("Missing '&' in continued character constant at %C");
716 gfc_current_locus.nextc--;
717 }
0d3abf6f
JJ
718 /* Both !$omp and !$ -fopenmp continuation lines have & on the
719 continuation line only optionally. */
720 else if (openmp_flag || openmp_cond_flag)
721 gfc_current_locus.nextc--;
5a06474c
JD
722 else
723 {
724 c = ' ';
725 gfc_current_locus = old_loc;
726 goto done;
727 }
3fbab549 728 }
6de9cd9a
DN
729 }
730 else
731 {
732 /* Fixed form continuation. */
733 if (!in_string && c == '!')
734 {
735 /* Skip comment at end of line. */
736 do
737 {
738 c = next_char ();
739 }
740 while (c != '\n');
a34938be
RG
741
742 /* Avoid truncation warnings for comment ending lines. */
743 gfc_current_locus.lb->truncated = 0;
6de9cd9a
DN
744 }
745
746 if (c != '\n')
747 goto done;
748
6c7a4dfd 749 prev_openmp_flag = openmp_flag;
6de9cd9a 750 continue_flag = 1;
63645982 751 old_loc = gfc_current_locus;
6de9cd9a
DN
752
753 gfc_advance_line ();
0d3abf6f 754 skip_fixed_comments ();
6de9cd9a
DN
755
756 /* See if this line is a continuation line. */
6c7a4dfd 757 if (openmp_flag != prev_openmp_flag)
6de9cd9a 758 {
6c7a4dfd
JJ
759 openmp_flag = prev_openmp_flag;
760 goto not_continuation;
6de9cd9a
DN
761 }
762
6c7a4dfd
JJ
763 if (!openmp_flag)
764 for (i = 0; i < 5; i++)
765 {
766 c = next_char ();
767 if (c != ' ')
768 goto not_continuation;
769 }
770 else
771 for (i = 0; i < 5; i++)
772 {
773 c = next_char ();
774 if (TOLOWER (c) != "*$omp"[i])
775 goto not_continuation;
776 }
777
6de9cd9a 778 c = next_char ();
6c7a4dfd 779 if (c == '0' || c == ' ' || c == '\n')
6de9cd9a 780 goto not_continuation;
5a06474c
JD
781
782 /* We've got a continuation line. If we are on the very next line after
783 the last continuation, increment the continuation line count and
784 check whether the limit has been exceeded. */
785 if (gfc_current_locus.lb->linenum == continue_line + 1)
786 {
787 if (++continue_count == gfc_option.max_continue_fixed)
788 {
789 if (gfc_notification_std (GFC_STD_GNU)
790 || pedantic)
791 gfc_warning ("Limit of %d continuations exceeded in statement at %C",
792 gfc_option.max_continue_fixed);
793 }
794 }
795
796 if (continue_line < gfc_current_locus.lb->linenum)
797 continue_line = gfc_current_locus.lb->linenum;
6de9cd9a
DN
798 }
799
800 /* Ready to read first character of continuation line, which might
801 be another continuation line! */
802 goto restart;
803
804not_continuation:
805 c = '\n';
63645982 806 gfc_current_locus = old_loc;
6de9cd9a
DN
807
808done:
5a06474c
JD
809 if (c == '\n')
810 continue_count = 0;
6de9cd9a
DN
811 continue_flag = 0;
812 return c;
813}
814
815
816/* Get the next character of input, folded to lowercase. In fixed
817 form mode, we also ignore spaces. When matcher subroutines are
818 parsing character literals, they have to call
819 gfc_next_char_literal(). */
820
821int
822gfc_next_char (void)
823{
824 int c;
825
826 do
827 {
828 c = gfc_next_char_literal (0);
829 }
d4fa05b9 830 while (gfc_current_form == FORM_FIXED && gfc_is_whitespace (c));
6de9cd9a
DN
831
832 return TOLOWER (c);
833}
834
835
836int
837gfc_peek_char (void)
838{
839 locus old_loc;
840 int c;
841
63645982 842 old_loc = gfc_current_locus;
6de9cd9a 843 c = gfc_next_char ();
63645982 844 gfc_current_locus = old_loc;
6de9cd9a
DN
845
846 return c;
847}
848
849
850/* Recover from an error. We try to get past the current statement
851 and get lined up for the next. The next statement follows a '\n'
852 or a ';'. We also assume that we are not within a character
853 constant, and deal with finding a '\'' or '"'. */
854
855void
856gfc_error_recovery (void)
857{
858 char c, delim;
859
860 if (gfc_at_eof ())
861 return;
862
863 for (;;)
864 {
865 c = gfc_next_char ();
866 if (c == '\n' || c == ';')
867 break;
868
869 if (c != '\'' && c != '"')
870 {
871 if (gfc_at_eof ())
872 break;
873 continue;
874 }
875 delim = c;
876
877 for (;;)
878 {
879 c = next_char ();
880
881 if (c == delim)
882 break;
883 if (c == '\n')
ba1defa5 884 return;
6de9cd9a
DN
885 if (c == '\\')
886 {
887 c = next_char ();
888 if (c == '\n')
ba1defa5 889 return;
6de9cd9a
DN
890 }
891 }
892 if (gfc_at_eof ())
893 break;
894 }
6de9cd9a
DN
895}
896
897
898/* Read ahead until the next character to be read is not whitespace. */
899
900void
901gfc_gobble_whitespace (void)
902{
840bd9f7 903 static int linenum = 0;
6de9cd9a
DN
904 locus old_loc;
905 int c;
906
907 do
908 {
63645982 909 old_loc = gfc_current_locus;
6de9cd9a 910 c = gfc_next_char_literal (0);
840bd9f7
SK
911 /* Issue a warning for nonconforming tabs. We keep track of the line
912 number because the Fortran matchers will often back up and the same
913 line will be scanned multiple times. */
45a82bd9 914 if (!gfc_option.warn_tabs && c == '\t')
840bd9f7 915 {
45a82bd9
PB
916#ifdef USE_MAPPED_LOCATION
917 int cur_linenum = LOCATION_LINE (gfc_current_locus.lb->location);
918#else
919 int cur_linenum = gfc_current_locus.lb->linenum;
920#endif
921 if (cur_linenum != linenum)
922 {
923 linenum = cur_linenum;
924 gfc_warning_now ("Nonconforming tab character at %C");
925 }
840bd9f7 926 }
6de9cd9a
DN
927 }
928 while (gfc_is_whitespace (c));
929
63645982 930 gfc_current_locus = old_loc;
6de9cd9a
DN
931}
932
933
f56c5d5d
TS
934/* Load a single line into pbuf.
935
936 If pbuf points to a NULL pointer, it is allocated.
937 We truncate lines that are too long, unless we're dealing with
938 preprocessor lines or if the option -ffixed-line-length-none is set,
939 in which case we reallocate the buffer to fit the entire line, if
940 need be.
941 In fixed mode, we expand a tab that occurs within the statement
942 label region to expand to spaces that leave the next character in
ba1defa5 943 the source region.
1526c4b5
JD
944 load_line returns whether the line was truncated.
945
946 NOTE: The error machinery isn't available at this point, so we can't
947 easily report line and column numbers consistent with other
948 parts of gfortran. */
6de9cd9a 949
ba1defa5 950static int
d1e3d6ae 951load_line (FILE * input, char **pbuf, int *pbuflen)
6de9cd9a 952{
840bd9f7 953 static int linenum = 0, current_line = 1;
d1e3d6ae 954 int c, maxlen, i, preprocessor_flag, buflen = *pbuflen;
840bd9f7 955 int trunc_flag = 0, seen_comment = 0;
1526c4b5 956 int seen_printable = 0, seen_ampersand = 0;
f56c5d5d
TS
957 char *buffer;
958
1dde8683 959 /* Determine the maximum allowed line length. */
f56c5d5d 960 if (gfc_current_form == FORM_FREE)
1dde8683 961 maxlen = gfc_option.free_line_length;
16ab8e74 962 else if (gfc_current_form == FORM_FIXED)
1dde8683 963 maxlen = gfc_option.fixed_line_length;
f56c5d5d 964 else
16ab8e74 965 maxlen = 72;
f56c5d5d
TS
966
967 if (*pbuf == NULL)
968 {
1dde8683
BM
969 /* Allocate the line buffer, storing its length into buflen.
970 Note that if maxlen==0, indicating that arbitrary-length lines
971 are allowed, the buffer will be reallocated if this length is
972 insufficient; since 132 characters is the length of a standard
973 free-form line, we use that as a starting guess. */
f56c5d5d
TS
974 if (maxlen > 0)
975 buflen = maxlen;
976 else
1dde8683 977 buflen = 132;
6de9cd9a 978
f56c5d5d
TS
979 *pbuf = gfc_getmem (buflen + 1);
980 }
6de9cd9a
DN
981
982 i = 0;
f56c5d5d 983 buffer = *pbuf;
6de9cd9a 984
fa841200
TS
985 preprocessor_flag = 0;
986 c = fgetc (input);
987 if (c == '#')
f56c5d5d
TS
988 /* In order to not truncate preprocessor lines, we have to
989 remember that this is one. */
fa841200
TS
990 preprocessor_flag = 1;
991 ungetc (c, input);
992
6de9cd9a
DN
993 for (;;)
994 {
995 c = fgetc (input);
996
997 if (c == EOF)
998 break;
999 if (c == '\n')
1526c4b5
JD
1000 {
1001 /* Check for illegal use of ampersand. See F95 Standard 3.3.1.3. */
1002 if (gfc_current_form == FORM_FREE
1003 && !seen_printable && seen_ampersand)
1004 {
1005 if (pedantic)
1006 gfc_error_now
1007 ("'&' not allowed by itself in line %d", current_line);
1008 else
1009 gfc_warning_now
1010 ("'&' not allowed by itself in line %d", current_line);
1011 }
1012 break;
1013 }
6de9cd9a
DN
1014
1015 if (c == '\r')
d4fa05b9 1016 continue; /* Gobble characters. */
6de9cd9a
DN
1017 if (c == '\0')
1018 continue;
1019
d4fa05b9
TS
1020 if (c == '\032')
1021 {
1022 /* Ctrl-Z ends the file. */
1023 while (fgetc (input) != EOF);
1024 break;
1025 }
1026
1526c4b5
JD
1027 /* Check for illegal use of ampersand. See F95 Standard 3.3.1.3. */
1028 if (c == '&')
1029 seen_ampersand = 1;
1030
1031 if ((c != ' ' && c != '&' && c != '!') || (c == '!' && !seen_ampersand))
1032 seen_printable = 1;
1033
1034 if (gfc_current_form == FORM_FREE
1035 && c == '!' && !seen_printable && seen_ampersand)
1036 {
1037 if (pedantic)
1038 gfc_error_now (
1039 "'&' not allowed by itself with comment in line %d", current_line);
1040 else
1041 gfc_warning_now (
1042 "'&' not allowed by itself with comment in line %d", current_line);
1043 seen_printable = 1;
1044 }
1045
840bd9f7
SK
1046 /* Is this a fixed-form comment? */
1047 if (gfc_current_form == FORM_FIXED && i == 0
1048 && (c == '*' || c == 'c' || c == 'd'))
1049 seen_comment = 1;
1050
d4fa05b9 1051 if (gfc_current_form == FORM_FIXED && c == '\t' && i <= 6)
840bd9f7 1052 {
840bd9f7
SK
1053 if (!gfc_option.warn_tabs && seen_comment == 0
1054 && current_line != linenum)
1055 {
1056 linenum = current_line;
1057 gfc_warning_now (
1058 "Nonconforming tab character in column 1 of line %d", linenum);
1059 }
1060
6de9cd9a
DN
1061 while (i <= 6)
1062 {
1063 *buffer++ = ' ';
1064 i++;
1065 }
1066
1067 continue;
1068 }
1069
1070 *buffer++ = c;
1071 i++;
1072
d1e3d6ae 1073 if (maxlen == 0 || preprocessor_flag)
f56c5d5d 1074 {
d1e3d6ae
JJ
1075 if (i >= buflen)
1076 {
1077 /* Reallocate line buffer to double size to hold the
3fbab549 1078 overlong line. */
d1e3d6ae
JJ
1079 buflen = buflen * 2;
1080 *pbuf = xrealloc (*pbuf, buflen + 1);
1081 buffer = (*pbuf)+i;
1082 }
f56c5d5d 1083 }
d1e3d6ae 1084 else if (i >= maxlen)
16ab8e74 1085 {
f56c5d5d 1086 /* Truncate the rest of the line. */
6de9cd9a
DN
1087 for (;;)
1088 {
1089 c = fgetc (input);
1090 if (c == '\n' || c == EOF)
1091 break;
a34938be
RG
1092
1093 trunc_flag = 1;
6de9cd9a
DN
1094 }
1095
1096 ungetc ('\n', input);
1097 }
1098 }
1099
f56c5d5d
TS
1100 /* Pad lines to the selected line length in fixed form. */
1101 if (gfc_current_form == FORM_FIXED
043c2d9e 1102 && gfc_option.fixed_line_length != 0
f56c5d5d
TS
1103 && !preprocessor_flag
1104 && c != EOF)
043c2d9e
BF
1105 {
1106 while (i++ < maxlen)
1107 *buffer++ = ' ';
1108 }
f56c5d5d 1109
6de9cd9a 1110 *buffer = '\0';
d1e3d6ae 1111 *pbuflen = buflen;
840bd9f7 1112 current_line++;
ba1defa5
RG
1113
1114 return trunc_flag;
6de9cd9a
DN
1115}
1116
1117
d4fa05b9
TS
1118/* Get a gfc_file structure, initialize it and add it to
1119 the file stack. */
1120
1121static gfc_file *
e0bcf78c 1122get_file (const char *name, enum lc_reason reason ATTRIBUTE_UNUSED)
d4fa05b9
TS
1123{
1124 gfc_file *f;
1125
1126 f = gfc_getmem (sizeof (gfc_file));
1127
1128 f->filename = gfc_getmem (strlen (name) + 1);
1129 strcpy (f->filename, name);
1130
1131 f->next = file_head;
1132 file_head = f;
1133
1134 f->included_by = current_file;
1135 if (current_file != NULL)
1136 f->inclusion_line = current_file->line;
1137
c8cc8542
PB
1138#ifdef USE_MAPPED_LOCATION
1139 linemap_add (&line_table, reason, false, f->filename, 1);
1140#endif
1141
d4fa05b9
TS
1142 return f;
1143}
1144
1145/* Deal with a line from the C preprocessor. The
1146 initial octothorp has already been seen. */
6de9cd9a
DN
1147
1148static void
d4fa05b9 1149preprocessor_line (char *c)
6de9cd9a 1150{
d4fa05b9
TS
1151 bool flag[5];
1152 int i, line;
1153 char *filename;
1154 gfc_file *f;
2d7c7df6 1155 int escaped, unescape;
6de9cd9a 1156
d4fa05b9
TS
1157 c++;
1158 while (*c == ' ' || *c == '\t')
1159 c++;
6de9cd9a 1160
d4fa05b9 1161 if (*c < '0' || *c > '9')
fa841200 1162 goto bad_cpp_line;
6de9cd9a 1163
d4fa05b9
TS
1164 line = atoi (c);
1165
4c3a6ca1 1166 c = strchr (c, ' ');
fa841200 1167 if (c == NULL)
4c3a6ca1
JJ
1168 {
1169 /* No file name given. Set new line number. */
1170 current_file->line = line;
1171 return;
1172 }
d7d528c8
ES
1173
1174 /* Skip spaces. */
1175 while (*c == ' ' || *c == '\t')
1176 c++;
1177
1178 /* Skip quote. */
1179 if (*c != '"')
fa841200 1180 goto bad_cpp_line;
d7d528c8
ES
1181 ++c;
1182
d4fa05b9
TS
1183 filename = c;
1184
d7d528c8 1185 /* Make filename end at quote. */
2d7c7df6 1186 unescape = 0;
d7d528c8
ES
1187 escaped = false;
1188 while (*c && ! (! escaped && *c == '"'))
1189 {
1190 if (escaped)
1191 escaped = false;
2d7c7df6
JJ
1192 else if (*c == '\\')
1193 {
1194 escaped = true;
1195 unescape++;
1196 }
d7d528c8
ES
1197 ++c;
1198 }
1199
1200 if (! *c)
fa841200
TS
1201 /* Preprocessor line has no closing quote. */
1202 goto bad_cpp_line;
d7d528c8 1203
d4fa05b9
TS
1204 *c++ = '\0';
1205
2d7c7df6
JJ
1206 /* Undo effects of cpp_quote_string. */
1207 if (unescape)
1208 {
1209 char *s = filename;
1210 char *d = gfc_getmem (c - filename - unescape);
d7d528c8 1211
2d7c7df6
JJ
1212 filename = d;
1213 while (*s)
1214 {
1215 if (*s == '\\')
1216 *d++ = *++s;
1217 else
1218 *d++ = *s;
1219 s++;
1220 }
1221 *d = '\0';
1222 }
d7d528c8 1223
d4fa05b9 1224 /* Get flags. */
4c3a6ca1 1225
1e39a151 1226 flag[1] = flag[2] = flag[3] = flag[4] = false;
6de9cd9a 1227
6de9cd9a
DN
1228 for (;;)
1229 {
d4fa05b9
TS
1230 c = strchr (c, ' ');
1231 if (c == NULL)
1232 break;
6de9cd9a 1233
d4fa05b9
TS
1234 c++;
1235 i = atoi (c);
6de9cd9a 1236
d4fa05b9
TS
1237 if (1 <= i && i <= 4)
1238 flag[i] = true;
1239 }
4c3a6ca1 1240
d4fa05b9 1241 /* Interpret flags. */
4c3a6ca1 1242
94b00ee4 1243 if (flag[1]) /* Starting new file. */
d4fa05b9 1244 {
c8cc8542 1245 f = get_file (filename, LC_RENAME);
d4fa05b9
TS
1246 f->up = current_file;
1247 current_file = f;
1248 }
4c3a6ca1 1249
d4fa05b9
TS
1250 if (flag[2]) /* Ending current file. */
1251 {
94b00ee4
JJ
1252 if (!current_file->up
1253 || strcmp (current_file->up->filename, filename) != 0)
4c3a6ca1
JJ
1254 {
1255 gfc_warning_now ("%s:%d: file %s left but not entered",
1256 current_file->filename, current_file->line,
1257 filename);
2d7c7df6
JJ
1258 if (unescape)
1259 gfc_free (filename);
4c3a6ca1
JJ
1260 return;
1261 }
94b00ee4 1262 current_file = current_file->up;
d4fa05b9 1263 }
4c3a6ca1 1264
d4fa05b9
TS
1265 /* The name of the file can be a temporary file produced by
1266 cpp. Replace the name if it is different. */
4c3a6ca1 1267
d4fa05b9
TS
1268 if (strcmp (current_file->filename, filename) != 0)
1269 {
1270 gfc_free (current_file->filename);
1271 current_file->filename = gfc_getmem (strlen (filename) + 1);
1272 strcpy (current_file->filename, filename);
1273 }
fa841200 1274
4c3a6ca1
JJ
1275 /* Set new line number. */
1276 current_file->line = line;
2d7c7df6
JJ
1277 if (unescape)
1278 gfc_free (filename);
fa841200
TS
1279 return;
1280
1281 bad_cpp_line:
4c3a6ca1 1282 gfc_warning_now ("%s:%d: Illegal preprocessor directive",
fa841200
TS
1283 current_file->filename, current_file->line);
1284 current_file->line++;
d4fa05b9
TS
1285}
1286
1287
e0bcf78c 1288static try load_file (const char *, bool);
d4fa05b9
TS
1289
1290/* include_line()-- Checks a line buffer to see if it is an include
1291 line. If so, we call load_file() recursively to load the included
1292 file. We never return a syntax error because a statement like
1293 "include = 5" is perfectly legal. We return false if no include was
1294 processed or true if we matched an include. */
1295
1296static bool
1297include_line (char *line)
1298{
1299 char quote, *c, *begin, *stop;
9b9e4cd6 1300
d4fa05b9 1301 c = line;
9b9e4cd6
JJ
1302
1303 if (gfc_option.flag_openmp)
1304 {
1305 if (gfc_current_form == FORM_FREE)
1306 {
1307 while (*c == ' ' || *c == '\t')
1308 c++;
1309 if (*c == '!' && c[1] == '$' && (c[2] == ' ' || c[2] == '\t'))
1310 c += 3;
1311 }
1312 else
1313 {
1314 if ((*c == '!' || *c == 'c' || *c == 'C' || *c == '*')
1315 && c[1] == '$' && (c[2] == ' ' || c[2] == '\t'))
1316 c += 3;
1317 }
1318 }
1319
d4fa05b9
TS
1320 while (*c == ' ' || *c == '\t')
1321 c++;
1322
1323 if (strncasecmp (c, "include", 7))
1324 return false;
1325
1326 c += 7;
1327 while (*c == ' ' || *c == '\t')
1328 c++;
1329
1330 /* Find filename between quotes. */
1331
1332 quote = *c++;
1333 if (quote != '"' && quote != '\'')
1334 return false;
1335
1336 begin = c;
1337
1338 while (*c != quote && *c != '\0')
1339 c++;
1340
1341 if (*c == '\0')
1342 return false;
1343
1344 stop = c++;
1345
1346 while (*c == ' ' || *c == '\t')
1347 c++;
1348
1349 if (*c != '\0' && *c != '!')
1350 return false;
1351
f7b529fa 1352 /* We have an include line at this point. */
d4fa05b9
TS
1353
1354 *stop = '\0'; /* It's ok to trash the buffer, as this line won't be
1355 read by anything else. */
1356
1357 load_file (begin, false);
1358 return true;
1359}
1360
1361/* Load a file into memory by calling load_line until the file ends. */
1362
1363static try
e0bcf78c 1364load_file (const char *filename, bool initial)
d4fa05b9 1365{
f56c5d5d 1366 char *line;
d4fa05b9
TS
1367 gfc_linebuf *b;
1368 gfc_file *f;
1369 FILE *input;
d1e3d6ae 1370 int len, line_len;
d4fa05b9
TS
1371
1372 for (f = current_file; f; f = f->up)
1373 if (strcmp (filename, f->filename) == 0)
1374 {
1375 gfc_error_now ("File '%s' is being included recursively", filename);
1376 return FAILURE;
1377 }
1378
1379 if (initial)
1380 {
2d7c7df6
JJ
1381 if (gfc_src_file)
1382 {
1383 input = gfc_src_file;
1384 gfc_src_file = NULL;
1385 }
1386 else
1387 input = gfc_open_file (filename);
d4fa05b9
TS
1388 if (input == NULL)
1389 {
1390 gfc_error_now ("Can't open file '%s'", filename);
1391 return FAILURE;
1392 }
1393 }
1394 else
1395 {
b424a572 1396 input = gfc_open_included_file (filename, false);
d4fa05b9
TS
1397 if (input == NULL)
1398 {
1399 gfc_error_now ("Can't open included file '%s'", filename);
1400 return FAILURE;
1401 }
1402 }
1403
1404 /* Load the file. */
1405
c8cc8542 1406 f = get_file (filename, initial ? LC_RENAME : LC_ENTER);
d4fa05b9
TS
1407 f->up = current_file;
1408 current_file = f;
1409 current_file->line = 1;
f56c5d5d 1410 line = NULL;
d1e3d6ae 1411 line_len = 0;
d4fa05b9 1412
2d7c7df6
JJ
1413 if (initial && gfc_src_preprocessor_lines[0])
1414 {
1415 preprocessor_line (gfc_src_preprocessor_lines[0]);
1416 gfc_free (gfc_src_preprocessor_lines[0]);
1417 gfc_src_preprocessor_lines[0] = NULL;
1418 if (gfc_src_preprocessor_lines[1])
1419 {
1420 preprocessor_line (gfc_src_preprocessor_lines[1]);
1421 gfc_free (gfc_src_preprocessor_lines[1]);
1422 gfc_src_preprocessor_lines[1] = NULL;
1423 }
1424 }
1425
16ab8e74 1426 for (;;)
d4fa05b9 1427 {
d1e3d6ae 1428 int trunc = load_line (input, &line, &line_len);
d4fa05b9
TS
1429
1430 len = strlen (line);
6de9cd9a
DN
1431 if (feof (input) && len == 0)
1432 break;
1433
d4fa05b9
TS
1434 /* There are three things this line can be: a line of Fortran
1435 source, an include line or a C preprocessor directive. */
6de9cd9a 1436
d4fa05b9
TS
1437 if (line[0] == '#')
1438 {
1439 preprocessor_line (line);
1440 continue;
1441 }
6de9cd9a 1442
d4fa05b9
TS
1443 if (include_line (line))
1444 {
1445 current_file->line++;
1446 continue;
6de9cd9a
DN
1447 }
1448
d4fa05b9
TS
1449 /* Add line. */
1450
4cdf7223 1451 b = gfc_getmem (gfc_linebuf_header_size + len + 1);
d4fa05b9 1452
c8cc8542
PB
1453#ifdef USE_MAPPED_LOCATION
1454 b->location
1455 = linemap_line_start (&line_table, current_file->line++, 120);
1456#else
d4fa05b9 1457 b->linenum = current_file->line++;
c8cc8542 1458#endif
d4fa05b9 1459 b->file = current_file;
ba1defa5 1460 b->truncated = trunc;
d4fa05b9
TS
1461 strcpy (b->line, line);
1462
1463 if (line_head == NULL)
1464 line_head = b;
1465 else
1466 line_tail->next = b;
1467
1468 line_tail = b;
6de9cd9a 1469 }
d4fa05b9 1470
f56c5d5d
TS
1471 /* Release the line buffer allocated in load_line. */
1472 gfc_free (line);
1473
d4fa05b9
TS
1474 fclose (input);
1475
1476 current_file = current_file->up;
c8cc8542
PB
1477#ifdef USE_MAPPED_LOCATION
1478 linemap_add (&line_table, LC_LEAVE, 0, NULL, 0);
1479#endif
d4fa05b9 1480 return SUCCESS;
6de9cd9a
DN
1481}
1482
1483
d4fa05b9
TS
1484/* Open a new file and start scanning from that file. Returns SUCCESS
1485 if everything went OK, FAILURE otherwise. If form == FORM_UKNOWN
1486 it tries to determine the source form from the filename, defaulting
1487 to free form. */
6de9cd9a
DN
1488
1489try
e0bcf78c 1490gfc_new_file (void)
6de9cd9a 1491{
d4fa05b9 1492 try result;
6de9cd9a 1493
d4fa05b9 1494 result = load_file (gfc_source_file, true);
6de9cd9a 1495
63645982
TS
1496 gfc_current_locus.lb = line_head;
1497 gfc_current_locus.nextc = (line_head == NULL) ? NULL : line_head->line;
6de9cd9a 1498
d4fa05b9
TS
1499#if 0 /* Debugging aid. */
1500 for (; line_head; line_head = line_head->next)
1501 gfc_status ("%s:%3d %s\n", line_head->file->filename,
c8cc8542
PB
1502#ifdef USE_MAPPED_LOCATION
1503 LOCATION_LINE (line_head->location),
1504#else
1505 line_head->linenum,
1506#endif
1507 line_head->line);
6de9cd9a 1508
d4fa05b9
TS
1509 exit (0);
1510#endif
6de9cd9a 1511
d4fa05b9 1512 return result;
6de9cd9a 1513}
2d7c7df6
JJ
1514
1515static char *
1516unescape_filename (const char *ptr)
1517{
1518 const char *p = ptr, *s;
1519 char *d, *ret;
1520 int escaped, unescape = 0;
1521
1522 /* Make filename end at quote. */
1523 escaped = false;
1524 while (*p && ! (! escaped && *p == '"'))
1525 {
1526 if (escaped)
1527 escaped = false;
1528 else if (*p == '\\')
1529 {
1530 escaped = true;
1531 unescape++;
1532 }
1533 ++p;
1534 }
1535
1536 if (! *p || p[1])
1537 return NULL;
1538
1539 /* Undo effects of cpp_quote_string. */
1540 s = ptr;
1541 d = gfc_getmem (p + 1 - ptr - unescape);
1542 ret = d;
1543
1544 while (s != p)
1545 {
1546 if (*s == '\\')
1547 *d++ = *++s;
1548 else
1549 *d++ = *s;
1550 s++;
1551 }
1552 *d = '\0';
1553 return ret;
1554}
1555
1556/* For preprocessed files, if the first tokens are of the form # NUM.
1557 handle the directives so we know the original file name. */
1558
1559const char *
1560gfc_read_orig_filename (const char *filename, const char **canon_source_file)
1561{
1562 int c, len;
1563 char *dirname;
1564
1565 gfc_src_file = gfc_open_file (filename);
1566 if (gfc_src_file == NULL)
1567 return NULL;
1568
1569 c = fgetc (gfc_src_file);
1570 ungetc (c, gfc_src_file);
1571
1572 if (c != '#')
1573 return NULL;
1574
1575 len = 0;
1576 load_line (gfc_src_file, &gfc_src_preprocessor_lines[0], &len);
1577
1578 if (strncmp (gfc_src_preprocessor_lines[0], "# 1 \"", 5) != 0)
1579 return NULL;
1580
1581 filename = unescape_filename (gfc_src_preprocessor_lines[0] + 5);
1582 if (filename == NULL)
1583 return NULL;
1584
1585 c = fgetc (gfc_src_file);
1586 ungetc (c, gfc_src_file);
1587
1588 if (c != '#')
1589 return filename;
1590
1591 len = 0;
1592 load_line (gfc_src_file, &gfc_src_preprocessor_lines[1], &len);
1593
1594 if (strncmp (gfc_src_preprocessor_lines[1], "# 1 \"", 5) != 0)
1595 return filename;
1596
1597 dirname = unescape_filename (gfc_src_preprocessor_lines[1] + 5);
1598 if (dirname == NULL)
1599 return filename;
1600
1601 len = strlen (dirname);
1602 if (len < 3 || dirname[len - 1] != '/' || dirname[len - 2] != '/')
1603 {
1604 gfc_free (dirname);
1605 return filename;
1606 }
1607 dirname[len - 2] = '\0';
1608 set_src_pwd (dirname);
1609
1610 if (! IS_ABSOLUTE_PATH (filename))
1611 {
1612 char *p = gfc_getmem (len + strlen (filename));
1613
1614 memcpy (p, dirname, len - 2);
1615 p[len - 2] = '/';
1616 strcpy (p + len - 1, filename);
1617 *canon_source_file = p;
1618 }
1619
1620 gfc_free (dirname);
1621 return filename;
1622}