OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [gcc/] [fortran/] [scanner.c] - Blame information for rev 20

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 12 jlechner
/* Character scanner.
2
   Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006
3
   Free Software Foundation, Inc.
4
   Contributed by Andy Vaught
5
 
6
This file is part of GCC.
7
 
8
GCC is free software; you can redistribute it and/or modify it under
9
the terms of the GNU General Public License as published by the Free
10
Software Foundation; either version 2, or (at your option) any later
11
version.
12
 
13
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14
WARRANTY; without even the implied warranty of MERCHANTABILITY or
15
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16
for more details.
17
 
18
You should have received a copy of the GNU General Public License
19
along with GCC; see the file COPYING.  If not, write to the Free
20
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
21
02110-1301, USA.  */
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"
46
#include "system.h"
47
#include "gfortran.h"
48
#include "toplev.h"
49
 
50
/* Structure for holding module and include file search path.  */
51
typedef struct gfc_directorylist
52
{
53
  char *path;
54
  struct gfc_directorylist *next;
55
}
56
gfc_directorylist;
57
 
58
/* List of include file search directories.  */
59
static gfc_directorylist *include_dirs;
60
 
61
static gfc_file *file_head, *current_file;
62
 
63
static int continue_flag, end_flag;
64
 
65
gfc_source_form gfc_current_form;
66
static gfc_linebuf *line_head, *line_tail;
67
 
68
locus gfc_current_locus;
69
const char *gfc_source_file;
70
static FILE *gfc_src_file;
71
static char *gfc_src_preprocessor_lines[2];
72
 
73
 
74
/* Main scanner initialization.  */
75
 
76
void
77
gfc_scanner_init_1 (void)
78
{
79
  file_head = NULL;
80
  line_head = NULL;
81
  line_tail = NULL;
82
 
83
  end_flag = 0;
84
}
85
 
86
 
87
/* Main scanner destructor.  */
88
 
89
void
90
gfc_scanner_done_1 (void)
91
{
92
  gfc_linebuf *lb;
93
  gfc_file *f;
94
 
95
  while(line_head != NULL)
96
    {
97
      lb = line_head->next;
98
      gfc_free(line_head);
99
      line_head = lb;
100
    }
101
 
102
  while(file_head != NULL)
103
    {
104
      f = file_head->next;
105
      gfc_free(file_head->filename);
106
      gfc_free(file_head);
107
      file_head = f;
108
    }
109
 
110
}
111
 
112
 
113
/* Adds path to the list pointed to by list.  */
114
 
115
void
116
gfc_add_include_path (const char *path)
117
{
118
  gfc_directorylist *dir;
119
  const char *p;
120
 
121
  p = path;
122
  while (*p == ' ' || *p == '\t')  /* someone might do 'gfortran "-I include"' */
123
    if (*p++ == '\0')
124
      return;
125
 
126
  dir = include_dirs;
127
  if (!dir)
128
    {
129
      dir = include_dirs = gfc_getmem (sizeof (gfc_directorylist));
130
    }
131
  else
132
    {
133
      while (dir->next)
134
        dir = dir->next;
135
 
136
      dir->next = gfc_getmem (sizeof (gfc_directorylist));
137
      dir = dir->next;
138
    }
139
 
140
  dir->next = NULL;
141
  dir->path = gfc_getmem (strlen (p) + 2);
142
  strcpy (dir->path, p);
143
  strcat (dir->path, "/");      /* make '/' last character */
144
}
145
 
146
 
147
/* Release resources allocated for options.  */
148
 
149
void
150
gfc_release_include_path (void)
151
{
152
  gfc_directorylist *p;
153
 
154
  gfc_free (gfc_option.module_dir);
155
  while (include_dirs != NULL)
156
    {
157
      p = include_dirs;
158
      include_dirs = include_dirs->next;
159
      gfc_free (p->path);
160
      gfc_free (p);
161
    }
162
}
163
 
164
/* Opens file for reading, searching through the include directories
165
   given if necessary.  If the include_cwd argument is true, we try
166
   to open the file in the current directory first.  */
167
 
168
FILE *
169
gfc_open_included_file (const char *name, const bool include_cwd)
170
{
171
  char *fullname;
172
  gfc_directorylist *p;
173
  FILE *f;
174
 
175
  if (include_cwd)
176
    {
177
      f = gfc_open_file (name);
178
      if (f != NULL)
179
        return f;
180
    }
181
 
182
  for (p = include_dirs; p; p = p->next)
183
    {
184
      fullname = (char *) alloca(strlen (p->path) + strlen (name) + 1);
185
      strcpy (fullname, p->path);
186
      strcat (fullname, name);
187
 
188
      f = gfc_open_file (fullname);
189
      if (f != NULL)
190
        return f;
191
    }
192
 
193
  return NULL;
194
}
195
 
196
/* Test to see if we're at the end of the main source file.  */
197
 
198
int
199
gfc_at_end (void)
200
{
201
 
202
  return end_flag;
203
}
204
 
205
 
206
/* Test to see if we're at the end of the current file.  */
207
 
208
int
209
gfc_at_eof (void)
210
{
211
 
212
  if (gfc_at_end ())
213
    return 1;
214
 
215
  if (line_head == NULL)
216
    return 1;                   /* Null file */
217
 
218
  if (gfc_current_locus.lb == NULL)
219
    return 1;
220
 
221
  return 0;
222
}
223
 
224
 
225
/* Test to see if we're at the beginning of a new line.  */
226
 
227
int
228
gfc_at_bol (void)
229
{
230
  if (gfc_at_eof ())
231
    return 1;
232
 
233
  return (gfc_current_locus.nextc == gfc_current_locus.lb->line);
234
}
235
 
236
 
237
/* Test to see if we're at the end of a line.  */
238
 
239
int
240
gfc_at_eol (void)
241
{
242
 
243
  if (gfc_at_eof ())
244
    return 1;
245
 
246
  return (*gfc_current_locus.nextc == '\0');
247
}
248
 
249
 
250
/* Advance the current line pointer to the next line.  */
251
 
252
void
253
gfc_advance_line (void)
254
{
255
  if (gfc_at_end ())
256
    return;
257
 
258
  if (gfc_current_locus.lb == NULL)
259
    {
260
      end_flag = 1;
261
      return;
262
    }
263
 
264
  gfc_current_locus.lb = gfc_current_locus.lb->next;
265
 
266
  if (gfc_current_locus.lb != NULL)
267
    gfc_current_locus.nextc = gfc_current_locus.lb->line;
268
  else
269
    {
270
      gfc_current_locus.nextc = NULL;
271
      end_flag = 1;
272
    }
273
}
274
 
275
 
276
/* Get the next character from the input, advancing gfc_current_file's
277
   locus.  When we hit the end of the line or the end of the file, we
278
   start returning a '\n' in order to complete the current statement.
279
   No Fortran line conventions are implemented here.
280
 
281
   Requiring explicit advances to the next line prevents the parse
282
   pointer from being on the wrong line if the current statement ends
283
   prematurely.  */
284
 
285
static int
286
next_char (void)
287
{
288
  int c;
289
 
290
  if (gfc_current_locus.nextc == NULL)
291
    return '\n';
292
 
293
  c = *gfc_current_locus.nextc++;
294
  if (c == '\0')
295
    {
296
      gfc_current_locus.nextc--; /* Remain on this line.  */
297
      c = '\n';
298
    }
299
 
300
  return c;
301
}
302
 
303
/* Skip a comment.  When we come here the parse pointer is positioned
304
   immediately after the comment character.  If we ever implement
305
   compiler directives withing comments, here is where we parse the
306
   directive.  */
307
 
308
static void
309
skip_comment_line (void)
310
{
311
  char c;
312
 
313
  do
314
    {
315
      c = next_char ();
316
    }
317
  while (c != '\n');
318
 
319
  gfc_advance_line ();
320
}
321
 
322
 
323
/* Comment lines are null lines, lines containing only blanks or lines
324
   on which the first nonblank line is a '!'.  */
325
 
326
static void
327
skip_free_comments (void)
328
{
329
  locus start;
330
  char c;
331
 
332
  for (;;)
333
    {
334
      start = gfc_current_locus;
335
      if (gfc_at_eof ())
336
        break;
337
 
338
      do
339
        {
340
          c = next_char ();
341
        }
342
      while (gfc_is_whitespace (c));
343
 
344
      if (c == '\n')
345
        {
346
          gfc_advance_line ();
347
          continue;
348
        }
349
 
350
      if (c == '!')
351
        {
352
          skip_comment_line ();
353
          continue;
354
        }
355
 
356
      break;
357
    }
358
 
359
  gfc_current_locus = start;
360
}
361
 
362
 
363
/* Skip comment lines in fixed source mode.  We have the same rules as
364
   in skip_free_comment(), except that we can have a 'c', 'C' or '*'
365
   in column 1, and a '!' cannot be in column 6.  Also, we deal with
366
   lines with 'd' or 'D' in column 1, if the user requested this.  */
367
 
368
static void
369
skip_fixed_comments (void)
370
{
371
  locus start;
372
  int col;
373
  char c;
374
 
375
  for (;;)
376
    {
377
      start = gfc_current_locus;
378
      if (gfc_at_eof ())
379
        break;
380
 
381
      c = next_char ();
382
      if (c == '\n')
383
        {
384
          gfc_advance_line ();
385
          continue;
386
        }
387
 
388
      if (c == '!' || c == 'c' || c == 'C' || c == '*')
389
        {
390
          skip_comment_line ();
391
          continue;
392
        }
393
 
394
      if (gfc_option.flag_d_lines != -1 && (c == 'd' || c == 'D'))
395
        {
396
          if (gfc_option.flag_d_lines == 0)
397
            {
398
              skip_comment_line ();
399
              continue;
400
            }
401
          else
402
            *start.nextc = c = ' ';
403
        }
404
 
405
      col = 1;
406
 
407
      while (gfc_is_whitespace (c))
408
        {
409
          c = next_char ();
410
          col++;
411
        }
412
 
413
      if (c == '\n')
414
        {
415
          gfc_advance_line ();
416
          continue;
417
        }
418
 
419
      if (col != 6 && c == '!')
420
        {
421
          skip_comment_line ();
422
          continue;
423
        }
424
 
425
      break;
426
    }
427
 
428
  gfc_current_locus = start;
429
}
430
 
431
 
432
/* Skips the current line if it is a comment.  Assumes that we are at
433
   the start of the current line.  */
434
 
435
void
436
gfc_skip_comments (void)
437
{
438
 
439
  if (!gfc_at_bol () || gfc_current_form == FORM_FREE)
440
    skip_free_comments ();
441
  else
442
    skip_fixed_comments ();
443
}
444
 
445
 
446
/* Get the next character from the input, taking continuation lines
447
   and end-of-line comments into account.  This implies that comment
448
   lines between continued lines must be eaten here.  For higher-level
449
   subroutines, this flattens continued lines into a single logical
450
   line.  The in_string flag denotes whether we're inside a character
451
   context or not.  */
452
 
453
int
454
gfc_next_char_literal (int in_string)
455
{
456
  locus old_loc;
457
  int i, c;
458
 
459
  continue_flag = 0;
460
 
461
restart:
462
  c = next_char ();
463
  if (gfc_at_end ())
464
    return c;
465
 
466
  if (gfc_current_form == FORM_FREE)
467
    {
468
 
469
      if (!in_string && c == '!')
470
        {
471
          /* This line can't be continued */
472
          do
473
            {
474
              c = next_char ();
475
            }
476
          while (c != '\n');
477
 
478
          /* Avoid truncation warnings for comment ending lines.  */
479
          gfc_current_locus.lb->truncated = 0;
480
 
481
          goto done;
482
        }
483
 
484
      if (c != '&')
485
        goto done;
486
 
487
      /* If the next nonblank character is a ! or \n, we've got a
488
         continuation line.  */
489
      old_loc = gfc_current_locus;
490
 
491
      c = next_char ();
492
      while (gfc_is_whitespace (c))
493
        c = next_char ();
494
 
495
      /* Character constants to be continued cannot have commentary
496
         after the '&'.  */
497
 
498
      if (in_string && c != '\n')
499
        {
500
          gfc_current_locus = old_loc;
501
          c = '&';
502
          goto done;
503
        }
504
 
505
      if (c != '!' && c != '\n')
506
        {
507
          gfc_current_locus = old_loc;
508
          c = '&';
509
          goto done;
510
        }
511
 
512
      continue_flag = 1;
513
      if (c == '!')
514
        skip_comment_line ();
515
      else
516
        gfc_advance_line ();
517
 
518
      /* We've got a continuation line and need to find where it continues.
519
         First eat any comment lines.  */
520
      gfc_skip_comments ();
521
 
522
      /* Now that we have a non-comment line, probe ahead for the
523
         first non-whitespace character.  If it is another '&', then
524
         reading starts at the next character, otherwise we must back
525
         up to where the whitespace started and resume from there.  */
526
 
527
      old_loc = gfc_current_locus;
528
 
529
      c = next_char ();
530
      while (gfc_is_whitespace (c))
531
        c = next_char ();
532
 
533
      if (c != '&')
534
       {
535
         if (in_string && gfc_option.warn_ampersand)
536
           gfc_warning ("Missing '&' in continued character constant at %C");
537
 
538
         gfc_current_locus.nextc--;
539
       }
540
    }
541
  else
542
    {
543
      /* Fixed form continuation.  */
544
      if (!in_string && c == '!')
545
        {
546
          /* Skip comment at end of line.  */
547
          do
548
            {
549
              c = next_char ();
550
            }
551
          while (c != '\n');
552
 
553
          /* Avoid truncation warnings for comment ending lines.  */
554
          gfc_current_locus.lb->truncated = 0;
555
        }
556
 
557
      if (c != '\n')
558
        goto done;
559
 
560
      continue_flag = 1;
561
      old_loc = gfc_current_locus;
562
 
563
      gfc_advance_line ();
564
      gfc_skip_comments ();
565
 
566
      /* See if this line is a continuation line.  */
567
      for (i = 0; i < 5; i++)
568
        {
569
          c = next_char ();
570
          if (c != ' ')
571
            goto not_continuation;
572
        }
573
 
574
      c = next_char ();
575
      if (c == '0' || c == ' ')
576
        goto not_continuation;
577
    }
578
 
579
  /* Ready to read first character of continuation line, which might
580
     be another continuation line!  */
581
  goto restart;
582
 
583
not_continuation:
584
  c = '\n';
585
  gfc_current_locus = old_loc;
586
 
587
done:
588
  continue_flag = 0;
589
  return c;
590
}
591
 
592
 
593
/* Get the next character of input, folded to lowercase.  In fixed
594
   form mode, we also ignore spaces.  When matcher subroutines are
595
   parsing character literals, they have to call
596
   gfc_next_char_literal().  */
597
 
598
int
599
gfc_next_char (void)
600
{
601
  int c;
602
 
603
  do
604
    {
605
      c = gfc_next_char_literal (0);
606
    }
607
  while (gfc_current_form == FORM_FIXED && gfc_is_whitespace (c));
608
 
609
  return TOLOWER (c);
610
}
611
 
612
 
613
int
614
gfc_peek_char (void)
615
{
616
  locus old_loc;
617
  int c;
618
 
619
  old_loc = gfc_current_locus;
620
  c = gfc_next_char ();
621
  gfc_current_locus = old_loc;
622
 
623
  return c;
624
}
625
 
626
 
627
/* Recover from an error.  We try to get past the current statement
628
   and get lined up for the next.  The next statement follows a '\n'
629
   or a ';'.  We also assume that we are not within a character
630
   constant, and deal with finding a '\'' or '"'.  */
631
 
632
void
633
gfc_error_recovery (void)
634
{
635
  char c, delim;
636
 
637
  if (gfc_at_eof ())
638
    return;
639
 
640
  for (;;)
641
    {
642
      c = gfc_next_char ();
643
      if (c == '\n' || c == ';')
644
        break;
645
 
646
      if (c != '\'' && c != '"')
647
        {
648
          if (gfc_at_eof ())
649
            break;
650
          continue;
651
        }
652
      delim = c;
653
 
654
      for (;;)
655
        {
656
          c = next_char ();
657
 
658
          if (c == delim)
659
            break;
660
          if (c == '\n')
661
            return;
662
          if (c == '\\')
663
            {
664
              c = next_char ();
665
              if (c == '\n')
666
                return;
667
            }
668
        }
669
      if (gfc_at_eof ())
670
        break;
671
    }
672
}
673
 
674
 
675
/* Read ahead until the next character to be read is not whitespace.  */
676
 
677
void
678
gfc_gobble_whitespace (void)
679
{
680
  locus old_loc;
681
  int c;
682
 
683
  do
684
    {
685
      old_loc = gfc_current_locus;
686
      c = gfc_next_char_literal (0);
687
    }
688
  while (gfc_is_whitespace (c));
689
 
690
  gfc_current_locus = old_loc;
691
}
692
 
693
 
694
/* Load a single line into pbuf.
695
 
696
   If pbuf points to a NULL pointer, it is allocated.
697
   We truncate lines that are too long, unless we're dealing with
698
   preprocessor lines or if the option -ffixed-line-length-none is set,
699
   in which case we reallocate the buffer to fit the entire line, if
700
   need be.
701
   In fixed mode, we expand a tab that occurs within the statement
702
   label region to expand to spaces that leave the next character in
703
   the source region.
704
   load_line returns whether the line was truncated.  */
705
 
706
static int
707
load_line (FILE * input, char **pbuf, int *pbuflen)
708
{
709
  int c, maxlen, i, preprocessor_flag, buflen = *pbuflen;
710
  int trunc_flag = 0;
711
  char *buffer;
712
 
713
  /* Determine the maximum allowed line length.
714
     The default for free-form is GFC_MAX_LINE, for fixed-form or for
715
     unknown form it is 72. Refer to the documentation in gfc_option_t.  */
716
  if (gfc_current_form == FORM_FREE)
717
    {
718
      if (gfc_option.free_line_length == -1)
719
        maxlen = GFC_MAX_LINE;
720
      else
721
        maxlen = gfc_option.free_line_length;
722
    }
723
  else if (gfc_current_form == FORM_FIXED)
724
    {
725
      if (gfc_option.fixed_line_length == -1)
726
        maxlen = 72;
727
      else
728
        maxlen = gfc_option.fixed_line_length;
729
    }
730
  else
731
    maxlen = 72;
732
 
733
  if (*pbuf == NULL)
734
    {
735
      /* Allocate the line buffer, storing its length into buflen.  */
736
      if (maxlen > 0)
737
        buflen = maxlen;
738
      else
739
        buflen = GFC_MAX_LINE;
740
 
741
      *pbuf = gfc_getmem (buflen + 1);
742
    }
743
 
744
  i = 0;
745
  buffer = *pbuf;
746
 
747
  preprocessor_flag = 0;
748
  c = fgetc (input);
749
  if (c == '#')
750
    /* In order to not truncate preprocessor lines, we have to
751
       remember that this is one.  */
752
    preprocessor_flag = 1;
753
  ungetc (c, input);
754
 
755
  for (;;)
756
    {
757
      c = fgetc (input);
758
 
759
      if (c == EOF)
760
        break;
761
      if (c == '\n')
762
        break;
763
 
764
      if (c == '\r')
765
        continue;               /* Gobble characters.  */
766
      if (c == '\0')
767
        continue;
768
 
769
      if (c == '\032')
770
        {
771
          /* Ctrl-Z ends the file.  */
772
          while (fgetc (input) != EOF);
773
          break;
774
        }
775
 
776
      if (gfc_current_form == FORM_FIXED && c == '\t' && i <= 6)
777
        {                       /* Tab expansion.  */
778
          while (i <= 6)
779
            {
780
              *buffer++ = ' ';
781
              i++;
782
            }
783
 
784
          continue;
785
        }
786
 
787
      *buffer++ = c;
788
      i++;
789
 
790
      if (maxlen == 0 || preprocessor_flag)
791
        {
792
          if (i >= buflen)
793
            {
794
              /* Reallocate line buffer to double size to hold the
795
                overlong line.  */
796
              buflen = buflen * 2;
797
              *pbuf = xrealloc (*pbuf, buflen + 1);
798
              buffer = (*pbuf)+i;
799
            }
800
        }
801
      else if (i >= maxlen)
802
        {
803
          /* Truncate the rest of the line.  */
804
          for (;;)
805
            {
806
              c = fgetc (input);
807
              if (c == '\n' || c == EOF)
808
                break;
809
 
810
              trunc_flag = 1;
811
            }
812
 
813
          ungetc ('\n', input);
814
        }
815
    }
816
 
817
  /* Pad lines to the selected line length in fixed form.  */
818
  if (gfc_current_form == FORM_FIXED
819
      && gfc_option.fixed_line_length != 0
820
      && !preprocessor_flag
821
      && c != EOF)
822
    {
823
      while (i++ < maxlen)
824
        *buffer++ = ' ';
825
    }
826
 
827
  *buffer = '\0';
828
  *pbuflen = buflen;
829
 
830
  return trunc_flag;
831
}
832
 
833
 
834
/* Get a gfc_file structure, initialize it and add it to
835
   the file stack.  */
836
 
837
static gfc_file *
838
get_file (const char *name, enum lc_reason reason ATTRIBUTE_UNUSED)
839
{
840
  gfc_file *f;
841
 
842
  f = gfc_getmem (sizeof (gfc_file));
843
 
844
  f->filename = gfc_getmem (strlen (name) + 1);
845
  strcpy (f->filename, name);
846
 
847
  f->next = file_head;
848
  file_head = f;
849
 
850
  f->included_by = current_file;
851
  if (current_file != NULL)
852
    f->inclusion_line = current_file->line;
853
 
854
#ifdef USE_MAPPED_LOCATION
855
  linemap_add (&line_table, reason, false, f->filename, 1);
856
#endif
857
 
858
  return f;
859
}
860
 
861
/* Deal with a line from the C preprocessor. The
862
   initial octothorp has already been seen.  */
863
 
864
static void
865
preprocessor_line (char *c)
866
{
867
  bool flag[5];
868
  int i, line;
869
  char *filename;
870
  gfc_file *f;
871
  int escaped, unescape;
872
 
873
  c++;
874
  while (*c == ' ' || *c == '\t')
875
    c++;
876
 
877
  if (*c < '0' || *c > '9')
878
    goto bad_cpp_line;
879
 
880
  line = atoi (c);
881
 
882
  c = strchr (c, ' ');
883
  if (c == NULL)
884
    {
885
      /* No file name given.  Set new line number.  */
886
      current_file->line = line;
887
      return;
888
    }
889
 
890
  /* Skip spaces.  */
891
  while (*c == ' ' || *c == '\t')
892
    c++;
893
 
894
  /* Skip quote.  */
895
  if (*c != '"')
896
    goto bad_cpp_line;
897
  ++c;
898
 
899
  filename = c;
900
 
901
  /* Make filename end at quote.  */
902
  unescape = 0;
903
  escaped = false;
904
  while (*c && ! (! escaped && *c == '"'))
905
    {
906
      if (escaped)
907
        escaped = false;
908
      else if (*c == '\\')
909
        {
910
          escaped = true;
911
          unescape++;
912
        }
913
      ++c;
914
    }
915
 
916
  if (! *c)
917
    /* Preprocessor line has no closing quote.  */
918
    goto bad_cpp_line;
919
 
920
  *c++ = '\0';
921
 
922
  /* Undo effects of cpp_quote_string.  */
923
  if (unescape)
924
    {
925
      char *s = filename;
926
      char *d = gfc_getmem (c - filename - unescape);
927
 
928
      filename = d;
929
      while (*s)
930
        {
931
          if (*s == '\\')
932
            *d++ = *++s;
933
          else
934
            *d++ = *s;
935
          s++;
936
        }
937
      *d = '\0';
938
    }
939
 
940
  /* Get flags.  */
941
 
942
  flag[1] = flag[2] = flag[3] = flag[4] = false;
943
 
944
  for (;;)
945
    {
946
      c = strchr (c, ' ');
947
      if (c == NULL)
948
        break;
949
 
950
      c++;
951
      i = atoi (c);
952
 
953
      if (1 <= i && i <= 4)
954
        flag[i] = true;
955
    }
956
 
957
  /* Interpret flags.  */
958
 
959
  if (flag[1]) /* Starting new file.  */
960
    {
961
      f = get_file (filename, LC_RENAME);
962
      f->up = current_file;
963
      current_file = f;
964
    }
965
 
966
  if (flag[2]) /* Ending current file.  */
967
    {
968
      if (!current_file->up
969
          || strcmp (current_file->up->filename, filename) != 0)
970
        {
971
          gfc_warning_now ("%s:%d: file %s left but not entered",
972
                           current_file->filename, current_file->line,
973
                           filename);
974
          if (unescape)
975
            gfc_free (filename);
976
          return;
977
        }
978
      current_file = current_file->up;
979
    }
980
 
981
  /* The name of the file can be a temporary file produced by
982
     cpp. Replace the name if it is different.  */
983
 
984
  if (strcmp (current_file->filename, filename) != 0)
985
    {
986
      gfc_free (current_file->filename);
987
      current_file->filename = gfc_getmem (strlen (filename) + 1);
988
      strcpy (current_file->filename, filename);
989
    }
990
 
991
  /* Set new line number.  */
992
  current_file->line = line;
993
  if (unescape)
994
    gfc_free (filename);
995
  return;
996
 
997
 bad_cpp_line:
998
  gfc_warning_now ("%s:%d: Illegal preprocessor directive",
999
                   current_file->filename, current_file->line);
1000
  current_file->line++;
1001
}
1002
 
1003
 
1004
static try load_file (const char *, bool);
1005
 
1006
/* include_line()-- Checks a line buffer to see if it is an include
1007
   line.  If so, we call load_file() recursively to load the included
1008
   file.  We never return a syntax error because a statement like
1009
   "include = 5" is perfectly legal.  We return false if no include was
1010
   processed or true if we matched an include.  */
1011
 
1012
static bool
1013
include_line (char *line)
1014
{
1015
  char quote, *c, *begin, *stop;
1016
 
1017
  c = line;
1018
  while (*c == ' ' || *c == '\t')
1019
    c++;
1020
 
1021
  if (strncasecmp (c, "include", 7))
1022
      return false;
1023
 
1024
  c += 7;
1025
  while (*c == ' ' || *c == '\t')
1026
    c++;
1027
 
1028
  /* Find filename between quotes.  */
1029
 
1030
  quote = *c++;
1031
  if (quote != '"' && quote != '\'')
1032
    return false;
1033
 
1034
  begin = c;
1035
 
1036
  while (*c != quote && *c != '\0')
1037
    c++;
1038
 
1039
  if (*c == '\0')
1040
    return false;
1041
 
1042
  stop = c++;
1043
 
1044
  while (*c == ' ' || *c == '\t')
1045
    c++;
1046
 
1047
  if (*c != '\0' && *c != '!')
1048
    return false;
1049
 
1050
  /* We have an include line at this point.  */
1051
 
1052
  *stop = '\0'; /* It's ok to trash the buffer, as this line won't be
1053
                   read by anything else.  */
1054
 
1055
  load_file (begin, false);
1056
  return true;
1057
}
1058
 
1059
/* Load a file into memory by calling load_line until the file ends.  */
1060
 
1061
static try
1062
load_file (const char *filename, bool initial)
1063
{
1064
  char *line;
1065
  gfc_linebuf *b;
1066
  gfc_file *f;
1067
  FILE *input;
1068
  int len, line_len;
1069
 
1070
  for (f = current_file; f; f = f->up)
1071
    if (strcmp (filename, f->filename) == 0)
1072
      {
1073
        gfc_error_now ("File '%s' is being included recursively", filename);
1074
        return FAILURE;
1075
      }
1076
 
1077
  if (initial)
1078
    {
1079
      if (gfc_src_file)
1080
        {
1081
          input = gfc_src_file;
1082
          gfc_src_file = NULL;
1083
        }
1084
      else
1085
        input = gfc_open_file (filename);
1086
      if (input == NULL)
1087
        {
1088
          gfc_error_now ("Can't open file '%s'", filename);
1089
          return FAILURE;
1090
        }
1091
    }
1092
  else
1093
    {
1094
      input = gfc_open_included_file (filename, false);
1095
      if (input == NULL)
1096
        {
1097
          gfc_error_now ("Can't open included file '%s'", filename);
1098
          return FAILURE;
1099
        }
1100
    }
1101
 
1102
  /* Load the file.  */
1103
 
1104
  f = get_file (filename, initial ? LC_RENAME : LC_ENTER);
1105
  f->up = current_file;
1106
  current_file = f;
1107
  current_file->line = 1;
1108
  line = NULL;
1109
  line_len = 0;
1110
 
1111
  if (initial && gfc_src_preprocessor_lines[0])
1112
    {
1113
      preprocessor_line (gfc_src_preprocessor_lines[0]);
1114
      gfc_free (gfc_src_preprocessor_lines[0]);
1115
      gfc_src_preprocessor_lines[0] = NULL;
1116
      if (gfc_src_preprocessor_lines[1])
1117
        {
1118
          preprocessor_line (gfc_src_preprocessor_lines[1]);
1119
          gfc_free (gfc_src_preprocessor_lines[1]);
1120
          gfc_src_preprocessor_lines[1] = NULL;
1121
        }
1122
    }
1123
 
1124
  for (;;)
1125
    {
1126
      int trunc = load_line (input, &line, &line_len);
1127
 
1128
      len = strlen (line);
1129
      if (feof (input) && len == 0)
1130
        break;
1131
 
1132
      /* There are three things this line can be: a line of Fortran
1133
         source, an include line or a C preprocessor directive.  */
1134
 
1135
      if (line[0] == '#')
1136
        {
1137
          preprocessor_line (line);
1138
          continue;
1139
        }
1140
 
1141
      if (include_line (line))
1142
        {
1143
          current_file->line++;
1144
          continue;
1145
        }
1146
 
1147
      /* Add line.  */
1148
 
1149
      b = gfc_getmem (gfc_linebuf_header_size + len + 1);
1150
 
1151
#ifdef USE_MAPPED_LOCATION
1152
      b->location
1153
        = linemap_line_start (&line_table, current_file->line++, 120);
1154
#else
1155
      b->linenum = current_file->line++;
1156
#endif
1157
      b->file = current_file;
1158
      b->truncated = trunc;
1159
      strcpy (b->line, line);
1160
 
1161
      if (line_head == NULL)
1162
        line_head = b;
1163
      else
1164
        line_tail->next = b;
1165
 
1166
      line_tail = b;
1167
    }
1168
 
1169
  /* Release the line buffer allocated in load_line.  */
1170
  gfc_free (line);
1171
 
1172
  fclose (input);
1173
 
1174
  current_file = current_file->up;
1175
#ifdef USE_MAPPED_LOCATION
1176
  linemap_add (&line_table, LC_LEAVE, 0, NULL, 0);
1177
#endif
1178
  return SUCCESS;
1179
}
1180
 
1181
 
1182
/* Open a new file and start scanning from that file. Returns SUCCESS
1183
   if everything went OK, FAILURE otherwise.  If form == FORM_UKNOWN
1184
   it tries to determine the source form from the filename, defaulting
1185
   to free form.  */
1186
 
1187
try
1188
gfc_new_file (void)
1189
{
1190
  try result;
1191
 
1192
  result = load_file (gfc_source_file, true);
1193
 
1194
  gfc_current_locus.lb = line_head;
1195
  gfc_current_locus.nextc = (line_head == NULL) ? NULL : line_head->line;
1196
 
1197
#if 0 /* Debugging aid.  */
1198
  for (; line_head; line_head = line_head->next)
1199
    gfc_status ("%s:%3d %s\n", line_head->file->filename,
1200
#ifdef USE_MAPPED_LOCATION
1201
                LOCATION_LINE (line_head->location),
1202
#else
1203
                line_head->linenum,
1204
#endif
1205
                line_head->line);
1206
 
1207
  exit (0);
1208
#endif
1209
 
1210
  return result;
1211
}
1212
 
1213
static char *
1214
unescape_filename (const char *ptr)
1215
{
1216
  const char *p = ptr, *s;
1217
  char *d, *ret;
1218
  int escaped, unescape = 0;
1219
 
1220
  /* Make filename end at quote.  */
1221
  escaped = false;
1222
  while (*p && ! (! escaped && *p == '"'))
1223
    {
1224
      if (escaped)
1225
        escaped = false;
1226
      else if (*p == '\\')
1227
        {
1228
          escaped = true;
1229
          unescape++;
1230
        }
1231
      ++p;
1232
    }
1233
 
1234
  if (! *p || p[1])
1235
    return NULL;
1236
 
1237
  /* Undo effects of cpp_quote_string.  */
1238
  s = ptr;
1239
  d = gfc_getmem (p + 1 - ptr - unescape);
1240
  ret = d;
1241
 
1242
  while (s != p)
1243
    {
1244
      if (*s == '\\')
1245
        *d++ = *++s;
1246
      else
1247
        *d++ = *s;
1248
      s++;
1249
    }
1250
  *d = '\0';
1251
  return ret;
1252
}
1253
 
1254
/* For preprocessed files, if the first tokens are of the form # NUM.
1255
   handle the directives so we know the original file name.  */
1256
 
1257
const char *
1258
gfc_read_orig_filename (const char *filename, const char **canon_source_file)
1259
{
1260
  int c, len;
1261
  char *dirname;
1262
 
1263
  gfc_src_file = gfc_open_file (filename);
1264
  if (gfc_src_file == NULL)
1265
    return NULL;
1266
 
1267
  c = fgetc (gfc_src_file);
1268
  ungetc (c, gfc_src_file);
1269
 
1270
  if (c != '#')
1271
    return NULL;
1272
 
1273
  len = 0;
1274
  load_line (gfc_src_file, &gfc_src_preprocessor_lines[0], &len);
1275
 
1276
  if (strncmp (gfc_src_preprocessor_lines[0], "# 1 \"", 5) != 0)
1277
    return NULL;
1278
 
1279
  filename = unescape_filename (gfc_src_preprocessor_lines[0] + 5);
1280
  if (filename == NULL)
1281
    return NULL;
1282
 
1283
  c = fgetc (gfc_src_file);
1284
  ungetc (c, gfc_src_file);
1285
 
1286
  if (c != '#')
1287
    return filename;
1288
 
1289
  len = 0;
1290
  load_line (gfc_src_file, &gfc_src_preprocessor_lines[1], &len);
1291
 
1292
  if (strncmp (gfc_src_preprocessor_lines[1], "# 1 \"", 5) != 0)
1293
    return filename;
1294
 
1295
  dirname = unescape_filename (gfc_src_preprocessor_lines[1] + 5);
1296
  if (dirname == NULL)
1297
    return filename;
1298
 
1299
  len = strlen (dirname);
1300
  if (len < 3 || dirname[len - 1] != '/' || dirname[len - 2] != '/')
1301
    {
1302
      gfc_free (dirname);
1303
      return filename;
1304
    }
1305
  dirname[len - 2] = '\0';
1306
  set_src_pwd (dirname);
1307
 
1308
  if (! IS_ABSOLUTE_PATH (filename))
1309
    {
1310
      char *p = gfc_getmem (len + strlen (filename));
1311
 
1312
      memcpy (p, dirname, len - 2);
1313
      p[len - 2] = '/';
1314
      strcpy (p + len - 1, filename);
1315
      *canon_source_file = p;
1316
    }
1317
 
1318
  gfc_free (dirname);
1319
  return filename;
1320
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.