home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 2 / FFMCD02.bin / new / dev / misc / p2c / src / trans.c < prev    next >
C/C++ Source or Header  |  1993-12-21  |  41KB  |  1,543 lines

  1. /* "p2c", a Pascal to C translator.
  2.    Copyright (C) 1989, 1990, 1991 Free Software Foundation.
  3.    Author's address: daveg@csvax.caltech.edu; 256-80 Caltech/Pasadena CA 91125.
  4.  
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation (any version).
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. GNU General Public License for more details.
  13.  
  14. You should have received a copy of the GNU General Public License
  15. along with this program; see the file COPYING.  If not, write to
  16. the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
  17.  
  18.  
  19.  
  20.  
  21. #define define_globals
  22. #define PROTO_TRANS_C
  23. #include "trans.h"
  24.  
  25. #include <time.h>
  26.  
  27.  
  28.  
  29.  
  30.  
  31.  
  32. /* Roadmap:
  33.  
  34.     trans.h         Declarations for all public global variables, types,
  35.                     and macros.  Functions are declared in separate
  36.                     files p2c.{proto,hdrs} which are created
  37.                     mechanically by the makeproto program.
  38.  
  39.     trans.c         Main program.  Parses the p2crc file.  Also reserves
  40.                     storage for public globals in trans.h.
  41.  
  42.     stuff.c         Miscellaneous support routines.
  43.  
  44.     out.c           Routines to handle the writing of C code to the output
  45.                     file.  This includes line breaking and indentation
  46.             support.
  47.  
  48.     comment.c       Routines for managing comments and comment lists.
  49.  
  50.     lex.c           Lexical analyzer.  Manages input files and streams,
  51.                     splits input stream into Pascal tokens.  Parses
  52.             compiler directives and special comments.  Also keeps
  53.             the symbol table.
  54.  
  55.     parse.c         Parsing and writing statements and blocks.
  56.  
  57.     decl.c          Parsing and writing declarations.
  58.  
  59.     expr.c          Manipulating expressions.
  60.  
  61.     pexpr.c         Parsing and writing expressions.
  62.  
  63.     funcs.c         Built-in special functions and procedures.
  64.  
  65.     dir.c           Interface file to "external" functions and procedures
  66.             such as hpmods and citmods.
  67.  
  68.     hpmods.c        Definitions for HP-supplied Pascal modules.
  69.  
  70.     citmods.c       Definitions for some Caltech-local Pascal modules.
  71.                     (Outside of Caltech this file is mostly useful
  72.                     as a large body of examples of how to write your
  73.                     own translator extensions.)
  74.  
  75.  
  76.     p2crc           Control file (read when p2c starts up).
  77.  
  78.     p2c.h           Header file used by translated programs.
  79.  
  80.     p2clib.c        Run-time library used by translated programs.
  81.  
  82. */
  83.  
  84.  
  85.  
  86.  
  87. Static Strlist *tweaksymbols, *synonyms;
  88. Strlist *addmacros;
  89.  
  90.  
  91.  
  92. Static void initrc()
  93. {
  94.     int i;
  95.  
  96.     for (i = 0; i < numparams; i++) {
  97.         switch (rctable[i].kind) {
  98.             case 'S':
  99.         case 'B':
  100.                 *((short *)rctable[i].ptr) = rctable[i].def;
  101.                 break;
  102.             case 'I':
  103.         case 'D':
  104.                 *((int *)rctable[i].ptr) = rctable[i].def;
  105.                 break;
  106.             case 'L':
  107.                 *((long *)rctable[i].ptr) = rctable[i].def;
  108.                 break;
  109.             case 'R':
  110.                 *((double *)rctable[i].ptr) = rctable[i].def/100.0;
  111.                 break;
  112.             case 'U':
  113.             case 'C':
  114.                 *((char *)rctable[i].ptr) = 0;
  115.                 break;
  116.             case 'A':
  117.                 *((Strlist **)rctable[i].ptr) = NULL;
  118.         break;
  119.         case 'X':
  120.         if (rctable[i].def == 1)
  121.             *((Strlist **)rctable[i].ptr) = NULL;
  122.         break;
  123.         }
  124.         rcprevvalues[i] = NULL;
  125.     }
  126.     tweaksymbols = NULL;
  127.     synonyms = NULL;
  128.     addmacros = NULL;
  129.     varmacros = NULL;
  130.     constmacros = NULL;
  131.     fieldmacros = NULL;
  132.     funcmacros = NULL;
  133. }
  134.  
  135.  
  136.  
  137. Static int readrc(rcname, need)
  138. char *rcname;
  139. int need;
  140. {
  141.     FILE *rc;
  142.     char buf[500], *cp, *cp2;
  143.     long val = 0;
  144.     int i;
  145.     Strlist *sl;
  146.  
  147.     rc = fopen(rcname, "r");
  148.     if (!rc) {
  149.         if (need)
  150.             perror(rcname);
  151.         return 0;
  152.     }
  153.     while (fgets(buf, 500, rc)) {
  154.         cp = my_strtok(buf, " =\t\n");
  155.         if (cp && *cp != '#') {
  156.             upc(cp);
  157.             i = numparams;
  158.             while (--i >= 0 && strcmp(rctable[i].name, cp)) ;
  159.             if (i >= 0) {
  160.                 if (rctable[i].kind != 'M') {
  161.                     cp = my_strtok(NULL, " =\t\n");
  162.                     if (cp && *cp == '#')
  163.                         cp = NULL;
  164.                     if (cp && (isdigit(*cp) || *cp == '-' || *cp == '+'))
  165.                         val = atol(cp);
  166.                     else
  167.                         val = rctable[i].def;
  168.                 }
  169.                 switch (rctable[i].kind) {
  170.  
  171.                     case 'S':
  172.                         *((short *)rctable[i].ptr) = val;
  173.                         break;
  174.  
  175.                     case 'I':
  176.                         *((int *)rctable[i].ptr) = val;
  177.                         break;
  178.  
  179.                     case 'D':
  180.                         *((int *)rctable[i].ptr) =
  181.                 parsedelta(cp, rctable[i].def);
  182.                         break;
  183.  
  184.                     case 'L':
  185.                         *((long *)rctable[i].ptr) = val;
  186.                         break;
  187.  
  188.             case 'R':
  189.             if (cp && (isdigit(*cp) || *cp == '-' || *cp == '.'))
  190.                 *((double *)rctable[i].ptr) = atof(cp);
  191.             else
  192.                 *((double *)rctable[i].ptr) = rctable[i].def/100.0;
  193.             break;
  194.  
  195.                     case 'U':
  196.                         if (cp)
  197.                             upc(cp);
  198.  
  199.                     /* fall through */
  200.                     case 'C':
  201.                         val = rctable[i].def;
  202.                         strncpy((char *)rctable[i].ptr, cp ? cp : "", val-1);
  203.                         ((char *)rctable[i].ptr)[val-1] = 0;
  204.                         break;
  205.  
  206.                     case 'F':
  207.                         while (cp && *cp != '#') {
  208.                             sl = strlist_append(&tweaksymbols,
  209.                         format_s("*%s", cp));
  210.                             sl->value = rctable[i].def;
  211.                             cp = my_strtok(NULL, " \t\n");
  212.                         }
  213.                         break;
  214.  
  215.                     case 'G':
  216.                         while (cp && *cp != '#') {
  217.                             sl = strlist_append(&tweaksymbols, cp);
  218.                             sl->value = rctable[i].def;
  219.                             cp = my_strtok(NULL, " \t\n");
  220.                         }
  221.                         break;
  222.  
  223.                     case 'A':
  224.                         while (cp && *cp != '#') {
  225.                             strlist_insert((Strlist **)rctable[i].ptr, cp);
  226.                             cp = my_strtok(NULL, " \t\n");
  227.                         }
  228.                         break;
  229.  
  230.                     case 'M':
  231.                         cp = my_strtok(NULL, "\n");
  232.                         if (cp) {
  233.                             while (isspace(*cp)) cp++;
  234.                             for (cp2 = cp; *cp2 && *cp2 != '#'; cp2++) ;
  235.                             *cp2 = 0;
  236.                             if (*cp) {
  237.                                 sl = strlist_append(&addmacros, cp);
  238.                                 sl->value = rctable[i].def;
  239.                             }
  240.                         }
  241.                         break;
  242.  
  243.             case 'B':
  244.             if (cp)
  245.                 val = parse_breakstr(cp);
  246.             if (val != -1)
  247.                 *((short *)rctable[i].ptr) = val;
  248.             break;
  249.  
  250.                     case 'X':
  251.                         switch (rctable[i].def) {
  252.  
  253.                             case 1:     /* strlist with string values */
  254.                                 if (cp) {
  255.                                     sl = strlist_append((Strlist **)rctable[i].ptr, cp);
  256.                                     cp = my_strtok(NULL, " =\t\n");
  257.                                     if (cp && *cp != '#')
  258.                                         sl->value = (long)stralloc(cp);
  259.                                 }
  260.                                 break;
  261.  
  262.                             case 2:     /* Include */
  263.                                 if (cp)
  264.                                     readrc(for