vif.c

     
   1  //! @file vif.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  //! VIF driver.
  25  
  26  #include <vif.h>
  27  
  28  int_4 nglobals = 0;
  29  int_4 nlocals = 0;
  30  int_4 ncommons = 2;               // 0 means local, 1 external
  31  int_4 implicit_r8 = FALSE;
  32  int_4 f4_do_loops = FALSE;
  33  int_4 gcc_ftn_lines = TRUE;
  34  int_4 hollerith = FALSE;
  35  int_4 syntax_only = FALSE;
  36  int_4 no_warnings = FALSE;
  37  
  38  int_4 MAX_FTN_LINES;
  39  FTN_LINE *source, *files;
  40  
  41  int_4 MAX_C_SRC;
  42  C_SRC *object;
  43  
  44  IDENT globals[MAX_IDENTS];
  45  IDENT locals[MAX_IDENTS];
  46  char *commons[MAX_COMMONS];
  47  IMPLICIT implic[26];
  48  LBL labels[MAX_LABELS];
  49  
  50  logical_4 strlens[MAX_STRLENS];
  51  
  52  int_4 compile_only = FALSE;
  53  int_4 abend = FALSE;
  54  int_4 frequency = FALSE;
  55  int_4 load_go = FALSE;
  56  int_4 load_go_erase = FALSE;
  57  int_4 renum = FALSE;
  58  int_4 func;
  59  int_4 end_statements;
  60  int_4 indent = 0;
  61  int_4 line = 0;
  62  int_4 n_c_src = 0;
  63  int_4 nfiles = 0;
  64  int_4 nftnlines = 1;
  65  int_4 nglobtmps = 0;
  66  int_4 nlabels = 0;
  67  int_4 nloctmps = 0;
  68  int_4 new_libnam = FALSE;
  69  int_4 new_object = FALSE;
  70  int_4 pnprocs = -1, nprocs = 0;
  71  int_4 page = 0;
  72  int_4 pcalls = 0;
  73  int_4 prelin, precol;
  74  int_4 quiet_mode = FALSE;
  75  int_4 trace = FALSE;
  76  
  77  int_4 curlin = 1, curcol = START_OF_LINE;
  78  int_4 curret, preret;
  79  RECORD prelex, curlex, retnam;
  80  RECORD libnam, modnam, procnam;
  81  RECORD stat_start;
  82  RECORD program, block;
  83  RECORD hmodule, hsection;
  84  RECORD hdate;
  85  RECORD oflags;
  86  RECORD object_name;
  87  
  88  int_4 reserved (char *lex)
  89  {
  90    static char *words[] = {
  91      "accept", "assign", "automatic", "call", "character", "close", "common", "complex", "continue",
  92      "dimension", "data", "do", "double", "else", "elseif",
  93      "end", "enddo", "endif", "entry", "external", "format", "function", "goto",
  94      "if", "implicit", "integer", "intrinsic", "logical", "long", "open", "pause", "precision", "print",
  95      "procedure", "program", "punch", "read", "real", "repeat", "return", "rewind", "save", "subroutine",
  96      "then", "to", "until", "while", "write",
  97      NULL
  98    };
  99  //
 100    for (char **sym = words; *sym != NULL; sym++) {
 101      if (EQUAL (*sym, lex)) {
 102        return TRUE;
 103      }
 104    }
 105    return FALSE;
 106  }
 107  
 108  int_4 isint_4 (char *s, int_4 *val)
 109  {
 110  // Is 's' an integer denotation, and what is its value?
 111    char *end;
 112    int_4 k = strtol (s, &end, 10);
 113    int_4 rc = (end != NULL && end[0] == '\0');
 114    if (val != NULL && rc) {
 115      *val = k;
 116    }
 117    return rc;
 118  }
 119  
 120  char *date (void)
 121  {
 122    time_t t;
 123    struct tm *info;
 124    t = time (NULL);
 125    info = localtime (&t);
 126    strftime (hdate, RECLN, "%a %d-%b-%Y %H:%M:%S", info);
 127    return hdate;
 128  }
 129  
 130  char *tod (void)
 131  {
 132    static RECORD str;
 133    time_t t;
 134    struct tm *info;
 135    t = time (NULL);
 136    info = localtime (&t);
 137    strftime (str, RECLN, "%H:%M:%S", info);
 138    return str;
 139  }
 140  
 141  char *stralloc (char *text)
 142  {
 143    if (text == NULL) {
 144      return NULL;
 145    } else {
 146      int_4 len = strlen (text) + 1;
 147      char *new = (char *) f_malloc (len);
 148      if (new == NULL) {
 149        OVERFLOW (3101, "stralloc");
 150      }
 151      return strcpy (new, text);
 152    }
 153  }
 154  
 155  char *strallocat (char *text, char *add)
 156  {
 157    if (text == NULL) {
 158      return stralloc (add);
 159    } else {
 160      int_4 len = strlen (text) + strlen (add) + 1;
 161      char *new = (char *) f_malloc (len);
 162      if (new == NULL) {
 163        OVERFLOW (3102, "strallocat");
 164      }
 165      return strcat (strcpy (new, text), add);
 166    }
 167  }
 168  
 169  void prelude (int_4 argc, char **argv, char *project)
 170  {
 171    {
 172      RECORD usr;
 173      if (getlogin_r (usr, RECLN) == 0) {
 174        code (0, HEADER, newpage (usr, basename (project)));
 175      } else {
 176        code (0, HEADER, newpage (VERSION, project));
 177      }
 178      code (0, HEADER, "\n");
 179      if (getlogin_r (usr, RECLN) == 0) {
 180        banner (0, BANNER, _strupper (usr));
 181        code (0, BANNER, "\n");
 182      }
 183      banner (0, BANNER, _strupper (basename (project)));
 184      code (0, BANNER, "\n");
 185    }
 186    code (0, CONSTANTS, newpage ("global-scope", "definitions"));
 187    code (0, CONSTANTS, "#include <vif.h>\n");
 188    code (0, CONSTANTS, "\n");
 189    code (0, CONSTANTS, "static int_4 _km1 = -1, _k0 = 0, _k1 = 1;\n");
 190    code (0, CONSTANTS, "\n");
 191    code (0, COMMON, "\n");
 192    code (0, MESSAGES, newpage ("global-scope", "diagnostics"));
 193    code (0, TYPEDEF, newpage ("global-scope", "typedefs"));
 194    code (0, TYPEDEF, "static FORMAT *__fmt_a = NULL;\n");
 195    code (0, PROTOTYPE, newpage ("global-scope", "prototypes"));
 196    code (0, FREQ, newpage ("global-scope", "frequency-table"));
 197    code (0, FREQ, "#define __ncalls ");
 198    pcalls = code (0, FREQ, NULL);
 199    code (0, FREQ, "\n");
 200    code (0, FREQ, "static CALLS __calls[__ncalls] = {\n");
 201  }
 202  
 203  void postlude (void)
 204  {
 205    RECORD str;
 206    code (0, PROTOTYPE, "\n");
 207    code (0, FREQ, "  {NULL , 0}\n");
 208    _srecordf (str, "%d", nprocs + 1);
 209    patch (pcalls, str);
 210    code (0, FREQ, "};\n");
 211  // Write the common blocks.
 212    if (ncommons > EXTERN) {
 213      code (0, COMMON, newpage ("global-scope", "common-blocks"));
 214      code_common ();
 215    }
 216  // Define character array types encountered.
 217    for (int k = 0, len = 2; k < MAX_STRLENS; k++, len *= 2) {
 218      if (strlens[k]) {
 219        _srecordf (str, "typedef char char_%d[%d];\n", len - 1, len);
 220        code (0, TYPEDEF, str);
 221      }
 222    }
 223  // Add an entry procedure.
 224    if (! compile_only) {
 225      nprocs++;
 226      code (nprocs, BODY, newpage ("global-scope", "entry-point"));
 227      code (nprocs, BODY, "// Global entry point.\n");
 228      code (nprocs, BODY, "int_4 main (int_4 argc, char **argv)\n");
 229      code (nprocs, BODY, "{\n");
 230      code (nprocs, BODY, "_vif_init ();\n");
 231      code (nprocs, BODY, "_ffile[0] = NEW_FTN_FILE (NULL, form_formatted, action_readwrite, 0);\n");
 232      _srecordf (str, "_ffile[%d] = NEW_FTN_FILE (stdin, form_formatted, action_read, MAX_LRECL);\n", STDF_IN);
 233      code (nprocs, BODY, str);
 234      _srecordf (str, "_ffile[%d].buff = (char *) f_malloc (MAX_LRECL + 1);\n", STDF_IN);
 235      code (nprocs, BODY, str);
 236      _srecordf (str, "_ffile[%d] = NEW_FTN_FILE (stdout, form_formatted, action_write, 0);\n", STDF_OUT);
 237      code (nprocs, BODY, str);
 238  #if STDF_OUT != STDF_PUN
 239      _srecordf (str, "_ffile[%d] = NEW_FTN_FILE (stdout, form_formatted, action_write, 0);\n", STDF_PUN);
 240      code (nprocs, BODY, str);
 241  #endif
 242      _srecordf (str, "_ffile[%d] = NEW_FTN_FILE (stdout, form_formatted, action_write, 0);\n", STDF_ERR);
 243      code (nprocs, BODY, str);
 244      if (strlen (block) > 0) {
 245        RECORD call;
 246        RECCLR (call);
 247        _srecordf (call, "%s (); // Block data.\n", block);
 248        code (nprocs, BODY, call);
 249      }
 250      if (strlen (program) > 0) {
 251        RECORD call;
 252        RECCLR (call);
 253        _srecordf (call, "%s (); // Fortran entry point.\n", program);
 254        code (nprocs, BODY, call);
 255      }
 256      if (frequency) {
 257        code (nprocs, BODY, "_vif_freq (__calls);");
 258      }
 259      code (nprocs, BODY, "_vif_exit ();\n");
 260      code (nprocs, BODY, "return EXIT_SUCCESS;\n");
 261      code (nprocs, BODY, "}\n");
 262    }
 263  }
 264  
 265  static void usage (void)
 266  {
 267    printf ("Usage: %s [-O][-f][-g][-k][-p][-v] file [, file, ...]\n", PACKAGE);
 268    printf ("\n");
 269    printf ("  -c     : Compile as a library.\n");
 270    printf ("  -d     : FORTRAN IV style do loops.\n");
 271    printf ("  -f     : Generate a call frequency table.\n");
 272    printf ("  -g     : Execute upon successful compilation.\n");
 273    printf ("  -k     : Backend compiler reports diagnostics at object code line.\n");
 274    printf ("  -l     : Generate a verbose listing file.\n");
 275    printf ("  -o name: sets name for object file to `name.c' and for executable to `name'.\n");
 276    printf ("  -p     : Keep the generated code upon successful compilation in pdf format.\n");
 277    printf ("  -q     : Quiet mode.\n");
 278    printf ("  -r     : Renumber FORTRAN source code.\n");
 279    printf ("  -s     : Check syntax only.\n");
 280    printf ("  -t     : Trace mode.\n");
 281    printf ("  -v     : Print the version and exit.\n");
 282    printf ("  -w     : Suppress warning diagnostics.\n");
 283    printf ("  -W     : Set default REAL length to 8 and default COMPLEX length to 16.\n");
 284    printf ("  -O0    : Do not optimize the object code.\n");
 285    printf ("  -O     : Optimize the object code.\n");
 286    printf ("  -O1    : Optimize the object code.\n");
 287    printf ("  -O2    : Optimize the object code.\n");
 288    printf ("  -O3    : Optimize the object code.\n");
 289    printf ("  -Of    : Optimize the object code.\n");
 290  }
 291  
 292  int_4 optimise = 0, keep = FALSE, pretty = FALSE;
 293  
 294  void version (void)
 295  {
 296    printf ("VIF %s - an experimental VIntage Fortran compiler.\n", VERSION);
 297    printf ("Copyright 2020-2024 J.M. van der Veer.\n\n");
 298    printf ("Backend compiler : %s\n", BACKEND);
 299    printf ("Install directory: %s\n\n", LOCDIR);
 300    printf ("This is free software covered by the GNU General Public License.\n");
 301    printf ("There is ABSOLUTELY NO WARRANTY for VIF;\n");
 302    printf ("not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n");
 303    printf ("See the GNU General Public License for more details.\n");
 304  }
 305  
 306  #define OPTION(s) EQUAL (opt, (s))
 307  
 308  void option (char *opt)
 309  {
 310    if (OPTION ("--frequency")) {
 311      frequency = TRUE;
 312    } else if (OPTION ("--go")) {
 313      load_go = TRUE;
 314    } else if (OPTION ("--keep")) {
 315      keep = TRUE;
 316    } else if (OPTION ("--lib")) {
 317      new_libnam = TRUE;
 318    } else if (OPTION ("--pdf")) {
 319      keep = TRUE;
 320      pretty = TRUE;
 321    } else if (OPTION ("--f4-do-loops")) {
 322      f4_do_loops = TRUE;
 323    } else if (OPTION ("--renumber")) {
 324      renum = TRUE;
 325    } else if (OPTION ("--hollerith")) {
 326      hollerith = TRUE;
 327    } else if (OPTION ("--license")) {
 328      version ();
 329      exit (EXIT_SUCCESS);
 330    } else if (OPTION ("--version")) {
 331      version ();
 332      exit (EXIT_SUCCESS);
 333    } else if (opt[1] == '-' && opt[2] == '\0') {
 334      return;
 335    } else for (int_4 k = 1; opt[k] != '\0'; k++) {
 336      if (opt[k] == 'O') {
 337        optimise = 0;
 338        if (opt[k + 1] == '0') {
 339          _srecordf(oflags, "%s", "-O0 -ggdb");
 340          k++;
 341        } else if (opt[k + 1] == '1') {
 342          _srecordf(oflags, "%s", "-O1");
 343          optimise = 1;
 344          k++;
 345        } else if (opt[k + 1] == '2') {
 346          _srecordf(oflags, "%s", "-O2");
 347          optimise = 2;
 348          k++;
 349        } else if (opt[k + 1] == '3') {
 350          _srecordf(oflags, "%s", "-funroll-all-loops -O3");
 351          optimise = 3;
 352          k++;
 353        } else if (opt[k + 1] == 'f') {
 354          _srecordf(oflags, "%s", "-Ofast");
 355          optimise = 4;
 356          k++;
 357        } else {
 358          _srecordf(oflags, "%s", "-O");
 359          optimise = 1;
 360        }
 361      } else if (opt[k] == 'c') {
 362        compile_only = TRUE;
 363      } else if (opt[k] == 'd') {
 364        f4_do_loops = TRUE;
 365      } else if (opt[k] == 'f') {
 366        frequency = TRUE;
 367      } else if (opt[k] == 'g') {
 368        load_go = TRUE;
 369      } else if (opt[k] == 'k') {
 370        gcc_ftn_lines = FALSE;
 371      } else if (opt[k] == 'l') {
 372        keep = TRUE;
 373      } else if (opt[k] == 'o') {
 374        new_object = TRUE;
 375      } else if (opt[k] == 'p') {
 376        keep = TRUE;
 377        pretty = TRUE;
 378      } else if (opt[k] == 'q') {
 379        quiet_mode = TRUE;
 380      } else if (opt[k] == 'r') {
 381        renum = TRUE;
 382      } else if (opt[k] == 's') {
 383        syntax_only = TRUE;
 384      } else if (opt[k] == 't') {
 385        trace = TRUE;
 386      } else if (opt[k] == 'v') {
 387        version ();
 388        exit (EXIT_SUCCESS);
 389      } else if (opt[k] == 'w') {
 390        no_warnings = TRUE;
 391      } else if (opt[k] == 'W') {
 392        implicit_r8 = TRUE;
 393      } else if (opt[k] == 'x') {
 394        load_go = TRUE;
 395        load_go_erase = TRUE;
 396      } else {
 397        usage ();
 398        exit (EXIT_FAILURE);
 399      }
 400    }
 401  }
 402  
 403  #undef OPTION
 404  
 405  int_4 main (int_4 argc, char **argv)
 406  {
 407    int_4 rc = EXIT_SUCCESS, start = 1;
 408    RECORD c_file, lst_file;
 409  //
 410    MAX_FTN_LINES = INCREMENT;
 411    MAX_C_SRC = INCREMENT;
 412    source = (FTN_LINE *) f_malloc (MAX_FTN_LINES * sizeof (FTN_LINE));
 413    object = (C_SRC *) f_malloc (MAX_C_SRC * sizeof (C_SRC));
 414    files = (FTN_LINE *) f_malloc (MAX_SOURCE_FILES * sizeof (FTN_LINE));
 415  // Options
 416    f4_do_loops = FALSE;
 417    new_libnam = FALSE;
 418    new_object = FALSE;
 419    oflags[0] = '\0';
 420    RECCLR (libnam);
 421    RECCLR (object_name);
 422    while (argv[start] != NULL && argv[start][0] == '-') {
 423      option (argv[start]);
 424      start++;
 425      if (new_libnam) {
 426        new_libnam = FALSE;
 427        if (strlen (libnam) == 0 && argv[start] != NULL) {
 428          strcpy (libnam, argv[start]);
 429          start++;
 430        } else {
 431          usage ();
 432          exit (EXIT_FAILURE);
 433        }
 434      } else if (new_object) {
 435        new_object = FALSE;
 436        if (strlen (object_name) == 0 && argv[start] != NULL) {
 437          strcpy (object_name, argv[start]);
 438          start++;
 439        } else {
 440          usage ();
 441          exit (EXIT_FAILURE);
 442        }
 443      }
 444    }
 445    if (argv[start] == NULL) {
 446      usage ();
 447      exit (EXIT_FAILURE);
 448    }
 449    RECCLR (program);
 450    RECCLR (block);
 451    RECCLR (curlex);
 452    RECCLR (prelex);
 453    for (int_4 k = 0; k < MAX_STRLENS; k++) {
 454      strlens[k] = FALSE;
 455    }
 456    date ();
 457    strcpy (hmodule, "global-scope");
 458    strcpy (hsection, "global-section");
 459  // Import all sources.
 460    RECORD argv_start;
 461    _srecordf (argv_start, argv[start]);
 462    for (int k = start; k < argc; k++) {
 463      get_source (stralloc (argv[k]), 0);
 464    }
 465  // Name for project derives from first source file.
 466    if (strlen (libnam) == 0) {
 467      if (new_object) {
 468        strcpy (libnam, object_name);
 469      } else {
 470        strcpy (libnam, argv_start);
 471      }
 472      for (int k = (int_4) strlen (libnam); k >= 0; k--) {
 473        if (libnam[k] == '.') {
 474          libnam[k] = '\0';
 475          break;
 476        }
 477      }
 478    }
 479  // Fill in what we know at the start.
 480    prelude (argc, argv, libnam);
 481  // Compile all subprograms.
 482    nmodules = 0;
 483    curlin = 1; 
 484    curcol = START_OF_LINE;
 485    scan_modules ();
 486    curlin = 1; 
 487    curcol = START_OF_LINE;
 488    macro_nest = 0;
 489    lhs_factor = FALSE;
 490    subprograms ();
 491  // Fill in what we know afterwards, and write C source.
 492    postlude ();
 493  // Remove stale files.
 494    RECCLR (c_file);
 495    strcpy (c_file, libnam);
 496    strcat (c_file, ".c");
 497    remove (c_file);
 498    strcpy (lst_file, libnam);
 499    strcat (lst_file, ".l");
 500    remove (lst_file);
 501  //
 502    strcpy (c_file, libnam);
 503    if (nerrors == 0) {
 504      strcat (c_file, ".c");
 505    } else {
 506      strcat (c_file, ".l");
 507    }
 508    write_object (c_file);
 509  // Compile intermediate code.
 510    if (syntax_only) {
 511      RECORD str;
 512      _srecordf (str, "** linker     ** no object file generated");
 513      diagnostic (0, str);
 514      if (nerrors == 0) {
 515        rc = EXIT_SUCCESS;
 516      } else {
 517        rc = EXIT_FAILURE;
 518      }
 519    } else if (renum) {
 520      RECORD str;
 521      if (nerrors == 0) {
 522        _srecordf (str, "** renumber   ** fortran file generated");
 523        rc = EXIT_SUCCESS;
 524      } else {
 525        _srecordf (str, "** renumber   ** no fortran file generated");
 526        rc = EXIT_FAILURE;
 527      }
 528      diagnostic (0, str);
 529    } else if (nerrors != 0) {
 530      RECORD str;
 531      nerrors++;
 532      _srecordf (str, "** linker     ** no object file generated");
 533      diagnostic (0, str);
 534      rc = EXIT_FAILURE;
 535    } else {
 536      RECORD cmd, str;
 537      if (compile_only) {
 538        if (optimise > 0) {
 539          _srecordf (cmd, "%s %s %s -c %s.c -o %s.o", BACKEND, oflags, CFLAGS, libnam, libnam);
 540        } else {
 541          _srecordf (cmd, "%s -O0 -ggdb %s -c %s.c -o %s.o", BACKEND, CFLAGS, libnam, libnam);
 542        }
 543      } else {
 544        if (optimise > 0) {
 545  #if defined (BOOTSTRAP)
 546          _srecordf (cmd, "%s %s %s %s.c -o %s %s", BACKEND, oflags, CFLAGS, libnam, libnam, LD_FLAGS);
 547  #else
 548          _srecordf (cmd, "%s %s %s %s.c -o %s -L%s %s", BACKEND, oflags, CFLAGS, libnam, libnam, LOCDIR, LD_FLAGS);
 549  #endif
 550        } else {
 551  #if defined (BOOTSTRAP)
 552          _srecordf (cmd, "%s -O0 -ggdb %s %s.c -o %s %s", BACKEND, CFLAGS, libnam, libnam, LD_FLAGS);
 553  #else
 554          _srecordf (cmd, "%s -O0 -ggdb %s %s.c -o %s -L%s %s", BACKEND, CFLAGS, libnam, libnam, LOCDIR, LD_FLAGS);
 555  #endif
 556        }
 557      }
 558      if (system (cmd) == EXIT_SUCCESS) {
 559        struct stat s;
 560        if (compile_only) {
 561          RECORD obj;
 562          _srecordf (obj, "%s.o", libnam);
 563          stat (obj, &s);
 564        } else {
 565          stat (libnam, &s);
 566        }
 567        _srecordf (str, "** linker     ** object size %ld bytes", s.st_size);
 568        diagnostic (0, str);
 569      } else {
 570        nerrors++;
 571        _srecordf (str, "** linker     ** no object file generated");
 572        diagnostic (0, str);
 573        rc = EXIT_FAILURE;
 574      }
 575      RECORD mov;
 576      _srecordf (mov, "mv %s %s", c_file, lst_file);
 577      system (mov);
 578    }
 579  // Wrap it up
 580    {
 581      RECORD str, sub, err, war;
 582      if (nprocs > 0 && ! compile_only) {
 583        nprocs--; // discount 'main'
 584      }
 585      if (nprocs == 0) {
 586        _srecordf (sub, "no subprograms");
 587      } else if (nprocs == 1) {
 588        _srecordf (sub, "1 subprogram");
 589      } else {
 590        _srecordf (sub, "%d subprograms", nprocs);
 591      }
 592      if (nerrors == 0) {
 593        _srecordf (err, "no errors");
 594      } else if (nerrors == 1) {
 595        _srecordf (err, "1 error");
 596      } else {
 597        _srecordf (err, "%d errors", nerrors);
 598      }
 599      if (nwarns == 0) {
 600        _srecordf (war, "no warnings");
 601      } else if (nwarns == 1) {
 602        _srecordf (war, "1 warning");
 603      } else {
 604        _srecordf (war, "%d warnings", nwarns);
 605      }
 606      _srecordf (str, "** statistics ** %s, %s, %s", sub, err, war);
 607      diagnostic (0, str);
 608    }
 609  // Execution.
 610    if (!renum && load_go && nerrors == 0 && ! syntax_only) {
 611      RECORD cmd;
 612      fprintf (stderr, "** execution  **\n");
 613      if (libnam[0] == '/') {
 614       _srecordf (cmd, "%s | tee ft06f000", libnam);
 615      } else {
 616       _srecordf (cmd, "./%s | tee ft06f000", libnam);
 617      }
 618      rc = system (cmd);
 619      if (!keep) {
 620        _srecordf (cmd, "rm -f ./%s ./%s.c ./%s.s", libnam, libnam, libnam);
 621        (void) system (cmd);
 622      }
 623      if (load_go_erase) {
 624        if (libnam[0] == '/') {
 625          _srecordf (cmd, "rm -f %s", libnam);
 626        } else {
 627          _srecordf (cmd, "rm -f ./%s", libnam);
 628        }
 629        (void) system (cmd);
 630      }
 631    }
 632  // Renumber source files.
 633    if (renum && nerrors == 0) {
 634      for (int k = start; k < argc; k++) {
 635        relabel (stralloc (argv[k]));
 636      }
 637    }
 638  // Write C source again with post-compile information.
 639    remove (c_file);
 640    strcpy (c_file, libnam);
 641    if (rc == EXIT_SUCCESS) {
 642      strcat (c_file, ".c");
 643    } else {
 644      strcat (c_file, ".l");
 645    }
 646    write_object (c_file);
 647  // Pretty listing file as PDF.
 648    if (keep && pretty) {
 649      RECORD cmd;
 650      _srecordf (cmd, "command -v enscript > /dev/null && command -v ps2pdf > /dev/null && enscript --quiet --font=Courier-Bold@9 -l -H1 -r --margins=25:25:40:40 -p - %s | ps2pdf - %s.pdf", c_file, libnam);
 651      (void) system (cmd);
 652    }
 653    if (!keep) {
 654      RECORD cmd;
 655      _srecordf (cmd, "rm -f %s.c %s.s", libnam, libnam);
 656      (void) system (cmd);
 657      _srecordf (cmd, "rm -f %s.c %s.s", libnam, libnam);
 658      (void) system (cmd);
 659    }
 660  // Exeunt.
 661    exit (rc);
 662  }
     


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