home *** CD-ROM | disk | FTP | other *** search
/ ftp.cs.arizona.edu / ftp.cs.arizona.edu.tar / ftp.cs.arizona.edu / icon / historic / v941.tgz / icon.v941src.tar / icon.v941src / src / rtt / rttmain.c < prev    next >
C/C++ Source or Header  |  2002-01-18  |  15KB  |  587 lines

  1. #include "rtt.h"
  2.  
  3. #if !NT
  4. #include "../h/filepat.h"        /* added for filepat change */
  5. #endif                    /* NT */
  6.  
  7. #if MACINTOSH
  8. #include <console.h>
  9. #endif                    /* MACINTOSH */
  10.  
  11. #if SCCX_MX
  12. unsigned _stack = 100000;
  13. #endif
  14. /*
  15.  * prototypes for static functions.
  16.  */
  17. static void add_tdef (char *name);
  18.  
  19. /*
  20.  * refpath is used to locate the standard include files for the Icon.
  21.  *  run-time system. If patchpath has been patched in the binary of rtt,
  22.  *  the string that was patched in is used for refpath.
  23.  */
  24. char patchpath[MaxPath+18] = "%PatchStringHere->";
  25.  
  26. #ifdef RefPath
  27.    char *refpath = RefPath;
  28. #else
  29.    char *refpath = "";
  30. #endif                    /* RefPath */
  31.  
  32. /*
  33.  * The following code is operating-system dependent [@rttmain.02].
  34.  * The relative path to grttin.h and rt.h depends on whether they are
  35.  *  interpreted as relative to where rtt.exe is or where rtt.exe is
  36.  *  invoked.
  37.  */
  38.  
  39. #if PORT
  40.    /* something is needed */
  41. Deliberate Syntax Error
  42. #endif                    /* PORT */
  43.  
  44. #if AMIGA
  45. char *grttin_path = "/src/h/grttin.h";
  46. char *rt_path = "/src/h/rt.h";
  47. #endif                    /* AMIGA */
  48.  
  49. #if MACINTOSH
  50. char *grttin_path = "::h:grttin.h";
  51. char *rt_path = "::h:rt.h";
  52. #endif                    /* MACINTOSH */
  53.  
  54. #if MSDOS || OS2
  55. char *grttin_path = "..\\h\\grttin.h";
  56. char *rt_path = "..\\h\\rt.h";
  57. #endif                    /* MSDOS || OS2 */
  58.  
  59. #if VMS
  60. char *grttin_path = "grttin.h";
  61. char *rt_path = "rt.h";
  62. #endif                                  /* VMS */
  63.  
  64. #if UNIX
  65. char *grttin_path = "../src/h/grttin.h";
  66. char *rt_path = "../src/h/rt.h";
  67. #endif                    /* UNIX */
  68.  
  69. /*
  70.  * End of operating-system specific code.
  71.  */
  72.  
  73. static char *ostr = "+ECPD:I:U:d:cir:st:x";
  74.  
  75. static char *options =
  76.    "[-E] [-C] [-P] [-Dname[=[text]]] [-Uname] [-Ipath] [-dfile]\n    \
  77. [-rpath] [-tname] [-x] [files]";
  78.  
  79. /*
  80.  *  Note: rtt presently does not process system include files. If this
  81.  *   is needed, it may be necessary to add other options that set
  82.  *   manifest constants in such include files.  See pmain.c for the
  83.  *   stand-alone preprocessor for examples of what's needed.
  84.  */
  85.  
  86. char *progname = "rtt";
  87. char *compiler_def;
  88. FILE *out_file;
  89. char *inclname;
  90. int def_fnd;
  91. char *largeints = NULL;
  92.  
  93. int iconx_flg = 0;
  94. int enable_out = 0;
  95.  
  96. static char *curlst_nm = "rttcur.lst";
  97. static FILE *curlst;
  98. static char *cur_src;
  99.  
  100. extern int line_cntrl;
  101.  
  102. /*
  103.  * tdefnm is used to construct a list of identifiers that
  104.  *  must be treated by rtt as typedef names.
  105.  */
  106. struct tdefnm {
  107.    char *name;
  108.    struct tdefnm *next;
  109.    };
  110.  
  111. static char *dbname = "rt.db";
  112. static int pp_only = 0;
  113. static char *opt_lst;
  114. static char **opt_args;
  115. static char *in_header;
  116. static struct tdefnm *tdefnm_lst = NULL;
  117.  
  118. /*
  119.  * getopt() variables
  120.  */
  121. extern int optind;        /* index into parent argv vector */
  122. extern int optopt;        /* character checked for validity */
  123. extern char *optarg;        /* argument associated with option */
  124.  
  125. #if TURBO
  126. unsigned _stklen = 30000;
  127. #endif                    /* TURBO */
  128.  
  129. #if ZTC_386
  130. #ifndef DOS386
  131. int _stack = 32 * 1024;        /* need large stack    */
  132. #endif                /* DOS386 */
  133. #endif                /* ZTC_386 */
  134.  
  135. #ifdef ConsoleWindow
  136. int ConsolePause = 1;
  137. #endif                    /* ConsoleWindow */
  138.  
  139. #ifndef NTConsole
  140. #ifdef MSWindows
  141. int rtt(int argc, char **argv);
  142. #define int_PASCAL int PASCAL
  143. #define LRESULT_CALLBACK LRESULT CALLBACK
  144. #undef Reset
  145. #include <windows.h>
  146. #include "../wincap/dibutil.h"
  147.  
  148. int CmdParamToArgv(char *s, char ***avp)
  149.    {
  150.    char *t, *t2;
  151.    int rv=0;
  152.    t = salloc(s);
  153.    t2 = t;
  154.    while (*t2) {
  155.       while (*t2 && isspace(*t2)) t2++;
  156.       if (!*t2) break;
  157.       rv++;
  158.       while (*t2 && !isspace(*t2)) t2++;
  159.       }
  160.    rv++; /* make room for "iconx" at front */
  161.    *avp = (char **)alloc(rv * sizeof(char *));
  162.    rv = 0;
  163.    (*avp)[rv++] = salloc("iconx.exe");
  164.    t2 = t;
  165.    while (*t2) {
  166.       while (*t2 && isspace(*t2)) t2++;
  167.       if (!*t2) break;
  168.       (*avp)[rv++] = t2;
  169.       while (*t2 && !isspace(*t2)) t2++;
  170.       if (*t2) *t2++ = '\0';
  171.       }
  172.    return rv;
  173.    }
  174.  
  175. LRESULT_CALLBACK WndProc    (HWND, UINT, WPARAM, LPARAM);
  176.  
  177. void MSStartup(int argc, char **argv, HINSTANCE hInstance, HINSTANCE hPrevInstance)
  178.    {
  179.    WNDCLASS wc;
  180.    if (!hPrevInstance) {
  181. #if NT
  182.       wc.style = CS_HREDRAW | CS_VREDRAW;
  183. #else                    /* NT */
  184.       wc.style = 0;
  185. #endif                    /* NT */
  186. #ifdef NTConsole
  187.       wc.lpfnWndProc = DefWindowProc;
  188. #else                    /* NTConsole */
  189.       wc.lpfnWndProc = WndProc;
  190. #endif                    /* NTConsole */
  191.       wc.cbClsExtra = 0;
  192.       wc.cbWndExtra = 0;
  193.       wc.hInstance  = hInstance;
  194.       wc.hIcon      = NULL;
  195.       wc.hCursor    = LoadCursor(NULL, IDC_ARROW);
  196.       wc.hbrBackground = GetStockObject(WHITE_BRUSH);
  197.       wc.lpszMenuName = NULL;
  198.       wc.lpszClassName = "iconx";
  199.       RegisterClass(&wc);
  200.       }
  201.    }
  202.  
  203. HANDLE mswinInstance;
  204. int ncmdShow;
  205.  
  206.  
  207. int_PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
  208.                    LPSTR lpszCmdParam, int nCmdShow)
  209.    {
  210.    int argc;
  211.    char **argv;
  212.  
  213.    mswinInstance = hInstance;
  214.    ncmdShow = nCmdShow;
  215.    argc = CmdParamToArgv(lpszCmdParam, &argv);
  216.    MSStartup(argc, argv, hInstance, hPrevInstance);
  217. #if BORLAND_286
  218.    _InitEasyWin();
  219. #endif                    /* BORLAND_286 */
  220.    (void)rtt(argc, argv);
  221.    fclose(stderr);
  222.    fclose(fopen("icont.fin","w"));
  223. }
  224.  
  225. #define main rtt
  226. #endif                    /* MSWindows */
  227. #endif                    /* NTConsole */
  228.  
  229. int main(argc, argv)
  230. int argc;
  231. char **argv;
  232.    {
  233.    int c;
  234.    int nopts;
  235.    char buf[MaxFileName];        /* file name construction buffer */
  236.    struct fileparts *fp;
  237.  
  238.    /*
  239.     * See if the location of include files has been patched into the
  240.     *  rtt executable.
  241.     */
  242.    if ((int)strlen(patchpath) > 18)
  243.       refpath = patchpath+18;
  244. #if UNIX
  245.    else
  246.       refpath = relfile(argv[0], "/../");
  247. #endif                    /* UNIX */
  248.  
  249.    /*
  250.     * Initialize the string table and indicate that File must be treated
  251.     *  as a typedef name.
  252.     */
  253.    init_str();
  254.    add_tdef("FILE");
  255.  
  256.    /*
  257.     * By default, the spelling of white space in unimportant (it can
  258.     *  only be significant with the -E option) and #line directives
  259.     *  are required in the output.
  260.     */
  261.    whsp_image = NoSpelling;
  262.    line_cntrl = 1;
  263.  
  264. #if MACINTOSH
  265.    argc = ccommand(&argv);
  266. #endif                    /* MACINTOSH */
  267.  
  268.    /*
  269.     * opt_lst and opt_args are the options and corresponding arguments
  270.     *  that are passed along to the preprocessor initialization routine.
  271.     *  Their number is at most the number of arguments to rtt.
  272.     */
  273.    opt_lst = alloc(argc);
  274.    opt_args = alloc(argc * sizeof (char *));
  275.    nopts = 0;
  276.  
  277.    /*
  278.     * Process options.
  279.     */
  280.    while ((c = getopt(argc, argv, ostr)) != EOF)
  281.       switch (c) {
  282.          case 'E': /* run preprocessor only */
  283.             pp_only = 1;
  284.             if (whsp_image == NoSpelling)
  285.                whsp_image = NoComment;
  286.             break;
  287.          case 'C':  /* retain spelling of white space, only effective with -E */
  288.             whsp_image = FullImage;
  289.             break;
  290.           case 'P': /* do not produce #line directives in output */
  291.             line_cntrl = 0;
  292.             break;
  293.           case 'd': /* -d name: name of data base */
  294.             dbname = optarg;
  295.             break;
  296. #ifdef ConsoleWindow
  297.          case 'q':
  298.             ConsolePause = 0;
  299.             break;
  300. #endif                    /* ConsoleWindow */
  301.          case 'r':  /* -r path: location of include files */
  302.             refpath = optarg;
  303.             break;
  304.          case 't':  /* -t ident : treat ident as a typedef name */
  305.             add_tdef(optarg);
  306.             break;
  307.          case 'x':  /* produce code for interpreter rather than compiler */
  308.             iconx_flg = 1;
  309.             break;
  310.          case 'D':  /* define preprocessor symbol */
  311.          case 'I':  /* path to search for preprocessor includes */
  312.          case 'U':  /* undefine preprocessor symbol */
  313.  
  314.             /*
  315.              * Save these options for the preprocessor initialization routine.
  316.              */
  317.             opt_lst[nopts] = c;
  318.             opt_args[nopts] = optarg;
  319.             ++nopts;
  320.             break;
  321.          default:
  322.             show_usage();
  323.          }
  324.  
  325. #if MACINTOSH
  326.    iconx_flg = 1;     /* Produce interpreter code */
  327. #endif                    /* MACINTOSH */
  328.  
  329. #ifdef Rttx
  330.    if (!iconx_flg) {
  331.       fprintf(stdout,
  332.          "rtt was compiled to only support the intepreter, use -x\n");
  333.       exit(EXIT_FAILURE);
  334.       }
  335. #endif                    /* Rttx */
  336.  
  337.    if (iconx_flg)
  338.       compiler_def = "#define COMPILER 0\n";
  339.    else
  340.       compiler_def = "#define COMPILER 1\n";
  341.    in_header = alloc(strlen(refpath) + strlen(grttin_path) + 1);
  342.    strcpy(in_header, refpath);
  343.    strcat(in_header, grttin_path);
  344.    inclname = alloc(strlen(refpath) + strlen(rt_path) + 1);
  345.    strcpy(inclname, refpath);
  346.    strcat(inclname, rt_path);
  347.  
  348.    opt_lst[nopts] = '\0';
  349.  
  350.    /*
  351.     * At least one file name must be given on the command line.
  352.     */
  353.    if (optind == argc)
  354.      show_usage();
  355.  
  356.    /*
  357.     * When creating the compiler run-time system, rtt outputs a list
  358.     *  of names of C files created, because most of the file names are
  359.     *  not derived from the names of the input files.
  360.     */
  361.    if (!iconx_flg) {
  362.       curlst = fopen(curlst_nm, "w");
  363.       if (curlst == NULL)
  364.          err2("cannot open ", curlst_nm);
  365.       }
  366.  
  367.    /*
  368.     * Unless the input is only being preprocessed, set up the in-memory data
  369.     *  base (possibly loading it from a file).
  370.     */
  371.    if (!pp_only) {
  372.       fp = fparse(dbname);
  373.       if (*fp->ext == '\0')
  374.          dbname = salloc(makename(buf, SourceDir, dbname, DBSuffix));
  375.       else if (!smatch(fp->ext, DBSuffix))
  376.          err2("bad data base name:", dbname);
  377.       loaddb(dbname);
  378.       }
  379.  
  380.    /*
  381.     * Scan file name arguments, and translate the files.
  382.     */
  383.    while (optind < argc)  {
  384.  
  385. #if PatternMatch
  386.       FINDDATA_T fd;
  387.  
  388.       if (!FINDFIRST(argv[optind], &fd)) {
  389.          fprintf(stderr,"File %s: no match\n", argv[optind]);
  390.      fflush(stderr);
  391.      exit(EXIT_FAILURE);
  392.          }
  393.       do {
  394.       argv[optind] = FILENAME(&fd);
  395. #endif                    /* PatternMatch */
  396.       trans(argv[optind]);
  397. #if PatternMatch
  398.       } while (FINDNEXT(&fd));
  399.       FINDCLOSE(&fd);
  400. #endif                    /* PatternMatch */
  401.       optind++;
  402.       }
  403.  
  404. #ifndef Rttx
  405.    /*
  406.     * Unless the user just requested the preprocessor be run, we
  407.     *   have created C files and updated the in-memory data base.
  408.     *   If this is the compiler's run-time system, we must dump
  409.     *   to data base to a file and create a list of all output files
  410.     *   produced in all runs of rtt that created the data base.
  411.     */
  412.    if (!(pp_only || iconx_flg)) {
  413.       if (fclose(curlst) != 0)
  414.          err2("cannot close ", curlst_nm);
  415.       dumpdb(dbname);
  416.       full_lst("rttfull.lst");
  417.       }
  418. #endif                    /* Rttx */
  419.  
  420.    return EXIT_SUCCESS;
  421.    }
  422.  
  423. /*
  424.  * trans - translate a source file.
  425.  */
  426. void trans(src_file)
  427. char *src_file;
  428.    {
  429.    char *cname;
  430.    char buf[MaxFileName];        /* file name construction buffer */
  431.    char *buf_ptr;
  432.    char *s;
  433.    struct fileparts *fp;
  434.    struct tdefnm *td;
  435.    struct token *t;
  436.    static char *test_largeints = "#ifdef LargeInts\nyes\n#endif\n";
  437.    static int first_time = 1;
  438.  
  439.    cur_src = src_file;
  440.  
  441.    /*
  442.     * Read standard header file for preprocessor directives and
  443.     * typedefs, but don't write anything to output.
  444.     */
  445.    enable_out = 0;
  446.    init_preproc(in_header, opt_lst, opt_args);
  447.    str_src("<rtt initialization>", compiler_def, (int)strlen(compiler_def));
  448.    init_sym();
  449.    for (td = tdefnm_lst; td != NULL; td = td->next)
  450.       sym_add(TypeDefName, td->name, OtherDcl, 1);
  451.    init_lex();
  452.    yyparse();
  453.    if (first_time) {
  454.       first_time = 0;
  455.       /*
  456.        * Now that the standard include files have been processed, see if
  457.        *  Largeints is defined and make sure it matches what's in the data base.
  458.        */
  459.       s = "NoLargeInts";
  460.       str_src("<rtt initialization>", test_largeints,
  461.          (int)strlen(test_largeints));
  462.       while ((t = preproc()) != NULL)
  463.           if (strcmp(t->image, "yes"))
  464.              s = "LargeInts";
  465.       if (largeints == NULL)
  466.          largeints = s;
  467.       else if (strcmp(largeints, s) != 0)
  468.          err2("header file definition of LargeInts/NoLargeInts does not match ",
  469.             dbname);
  470.       }
  471.    enable_out = 1;
  472.  
  473.    /*
  474.     * Make sure we have a .r file or standard input.
  475.     */
  476.    if (strcmp(cur_src, "-") == 0) {
  477.       source("-"); /* tell preprocessor to read standard input */
  478.       cname = salloc(makename(buf, TargetDir, "stdin", CSuffix));
  479.       }
  480.    else {
  481.       fp = fparse(cur_src);
  482.       if (*fp->ext == '\0')
  483.          cur_src = salloc(makename(buf, SourceDir, cur_src, RttSuffix));
  484.       else if (!smatch(fp->ext, RttSuffix))
  485.          err2("unknown file suffix ", cur_src);
  486.       cur_src = spec_str(cur_src);
  487.  
  488.       /*
  489.        * For the compiler, remove from the data base the list of
  490.        *  files produced from this input file.
  491.        */
  492.       if (!iconx_flg)
  493.          clr_dpnd(cur_src);
  494.       source(cur_src);  /* tell preprocessor to read source file */
  495.  
  496.       /*
  497.        * For the interpreter prepend "x" to the file name for the .c file.
  498.        */
  499.       buf_ptr = buf;
  500.       if (iconx_flg)
  501.          *buf_ptr++ = 'x';
  502.       makename(buf_ptr, TargetDir, cur_src, CSuffix);
  503.       cname = salloc(buf);
  504.       }
  505.  
  506.    if (pp_only)
  507.       output(stdout); /* invoke standard preprocessor output routine */
  508.    else {
  509.       /*
  510.        * For the compiler, non-RTL code is put in a file whose name
  511.        *  is derived from input file name. The flag def_fnd indicates
  512.        *  if anything interesting is put in the file.
  513.        */
  514.       def_fnd = 0;
  515.       if ((out_file = fopen(cname, "w")) == NULL)
  516.          err2("cannot open output file ", cname);
  517.       else
  518.          addrmlst(cname, out_file);
  519.       prologue(); /* output standard comments and preprocessor directives */
  520.       yyparse();  /* translate the input */
  521.       fprintf(out_file, "\n");
  522.       if (fclose(out_file) != 0)
  523.          err2("cannot close ", cname);
  524.  
  525.       /*
  526.        * For the Compiler, note the name of the "primary" output file
  527.        *  in the data base and list of created files.
  528.        */
  529.       if (!iconx_flg)
  530.          put_c_fl(cname, def_fnd);
  531.       }
  532.    }
  533.  
  534. /*
  535.  * add_tdef - add identifier to list of typedef names.
  536.  */
  537. static void add_tdef(name)
  538. char *name;
  539.    {
  540.    struct tdefnm *td;
  541.  
  542.    td = NewStruct(tdefnm);
  543.    td->name = spec_str(name);
  544.    td->next = tdefnm_lst;
  545.    tdefnm_lst = td;
  546.    }
  547.  
  548. /*
  549.  * Add name of file to the output list, and if it contains "interesting"
  550.  *  code, add it to the dependency list in the data base.
  551.  */
  552. void put_c_fl(fname, keep)
  553. char *fname;
  554. int keep;
  555.    {
  556.    struct fileparts *fp;
  557.  
  558.    fp = fparse(fname);
  559.    fprintf(curlst, "%s\n", fp->name);
  560.    if (keep)
  561.       add_dpnd(src_lkup(cur_src), fname);
  562.    }
  563.  
  564. /*
  565.  * Print an error message if called incorrectly.
  566.  */
  567. void show_usage()
  568.    {
  569.    fprintf(stderr, "usage: %s %s\n", progname, options);
  570.    exit(EXIT_FAILURE);
  571.    }
  572.  
  573. /*
  574.  * yyerror - error routine called by yacc.
  575.  */
  576. void yyerror(s)
  577. char *s;
  578.    {
  579.    struct token *t;
  580.  
  581.    t = yylval.t;
  582.    if (t == NULL)
  583.       err2(s, " at end of file");
  584.    else
  585.       errt1(t, s);
  586.    }
  587.