fpp.c

     
   1  //! @file fpp.c
   2  //! @author J. Marcel van der Veer
   3  //
   4  //! @section Copyright
   5  //
   6  // This file is part of VIF - vintage FORTRAN compiler.
   7  // Copyright 2020-2024 J. Marcel van der Veer <algol68g@xs4all.nl>.
   8  //
   9  //! @section License
  10  //
  11  // This program is free software; you can redistribute it and/or modify it 
  12  // under the terms of the GNU General Public License as published by the 
  13  // Free Software Foundation; either version 3 of the License, or 
  14  // (at your option) any later version.
  15  //
  16  // This program is distributed in the hope that it will be useful, but 
  17  // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
  18  // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 
  19  // more details. You should have received a copy of the GNU General Public 
  20  // License along with this program. If not, see <http://www.gnu.org/licenses/>.
  21  
  22  //! @section Synopsis
  23  //!
  24  //! Fortran preprocessor.
  25  
  26  #include <vif.h>
  27  
  28  void fpp (char *, char *, int_4 nest);
  29  
  30  int_4 register_file(char *name)
  31  {
  32    for (int_4 k = 1; k <= nfiles; k++) {
  33      if (strcmp (files[k].text, name) == 0) {
  34         return k;
  35      }
  36    }
  37    nfiles++;
  38    if (nfiles >= MAX_SOURCE_FILES) {
  39      FATAL (1701, "too many source files", NULL);
  40    }
  41    files[nfiles].num = nfiles;
  42    files[nfiles].text = stralloc (name);
  43    return nfiles;
  44  }
  45  
  46  void get_source (char *name, int_4 nest)
  47  {
  48    FILE *in;
  49    char *ext;
  50    int_4 lines = 1, nisn = 0, actfile;
  51    if (nest > MAX_NEST) {
  52      FATAL (1702, "include nesting too deep", name);
  53    }
  54    if (strlen (name) < 3) {
  55      FATAL (1703, "source file name", name);
  56    }
  57    ext = &name[strlen (name) - 2];
  58    if (EQUAL (ext, ".f") || EQUAL (ext, ".F")) {
  59      ;// Ok
  60    } else if (EQUAL (ext, ".ftn") || EQUAL (ext, ".FTN")) {
  61      ;// Ok
  62    } else if (EQUAL (ext, ".h") || EQUAL (ext, ".H")) {
  63      ;// Ok
  64    } else {
  65      FATAL (1704, "source file format", name);
  66    }
  67    if ((in = fopen (name, "r")) == NULL) {
  68      FATAL (1705, "cannot read", name);
  69    };
  70    RECORD path;
  71    _srecordf (path, "%s", dirname (name));
  72    actfile = register_file(name);
  73    while (!feof (in)) {
  74      RECORD fetch;
  75      RECCLR (fetch);
  76      if (fgets (fetch, RECLN, in) != NULL) {
  77        int_4 len = strlen (fetch);
  78        if (len > 1) {
  79          if (fetch[0] == '#') {
  80            int_4 savfile = actfile;
  81            fpp (fetch, path, nest);
  82            actfile = savfile;
  83            lines++;
  84          } else {
  85            if (fetch[len - 1] == '\n') {
  86              fetch[len - 1] = '\0';
  87            }
  88            if (nftnlines == MAX_FTN_LINES) {
  89              MAX_FTN_LINES += INCREMENT;
  90              source = (FTN_LINE *) f_realloc (source, MAX_FTN_LINES * sizeof (FTN_LINE));
  91            }
  92            source[nftnlines].file = &files[actfile];
  93            source[nftnlines].num = lines;
  94            source[nftnlines].len = len;
  95            source[nftnlines].inc = nest;
  96            source[nftnlines].text = stralloc (fetch);
  97            if (fetch[0] == '\0' || IS_COMMENT (fetch[0])) {
  98              source[nftnlines].isn = 0;
  99            } else if (nisn > 0 && fetch[5] != ' ') {
 100              source[nftnlines].isn = nisn;
 101            } else {
 102              source[nftnlines].isn = ++nisn;
 103            }
 104            lines++;
 105            nftnlines++;
 106          }
 107        }
 108      }
 109    }
 110    files[nfiles].len = lines - 1;
 111    fclose (in);
 112  }
 113  
 114  void fpp (char *cmd, char *path, int_4 nest)
 115  {
 116    if (cmd[0] == '#') {
 117      cmd++;
 118    }
 119    while (cmd[0] == ' ') {
 120      cmd++;
 121    }
 122    if (LEQUAL ("echo", cmd)) {
 123      cmd = &cmd[strlen ("echo")];
 124      while (cmd[0] == ' ') {
 125        cmd++;
 126      }
 127      int_4 N = strlen (cmd);
 128      if (N > 0 && cmd[N - 1] == '\n') {
 129        cmd[N - 1] = '\0';
 130      }
 131      ECHO (1706, cmd, NULL);
 132    } else if (LEQUAL ("pragma", cmd)) {
 133      cmd = &cmd[strlen ("pragma")];
 134      while (cmd[0] == ' ') {
 135        cmd++;
 136      }
 137      int_4 N = strlen (cmd);
 138      if (N > 0 && cmd[N - 1] == '\n') {
 139        cmd[N - 1] = '\0';
 140      }
 141      option (cmd);
 142    } else if (LEQUAL ("include", cmd)) {
 143      RECORD fn;
 144      (void) strtok (cmd, "'");
 145      char *str = strtok (NULL, "'");
 146      if (str != NULL) {
 147        _srecordf (fn, "%s/%s", path, str);
 148        get_source (fn, nest + 1);
 149      } else {
 150        FATAL (1707, "filename required", cmd);
 151      }
 152    } else {
 153      FATAL (1708, "preprocessor directive", cmd);
 154    }
 155  }
     


© 2002-2024 J.M. van der Veer (jmvdveer@xs4all.nl)