home *** CD-ROM | disk | FTP | other *** search
/ ftp.cs.arizona.edu / ftp.cs.arizona.edu.tar / ftp.cs.arizona.edu / icon / historic / v92.tgz / v92.tar / v92 / src / rtt / rttmain.c < prev    next >
C/C++ Source or Header  |  1996-03-22  |  16KB  |  646 lines

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