home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / icon / dos / src / icont / tmain.c < prev    next >
C/C++ Source or Header  |  1992-02-10  |  13KB  |  520 lines

  1. /*
  2.  * tmain.c - main program for translator and linker.
  3.  */
  4.  
  5. #include "../h/gsupport.h"
  6. #include "tproto.h"
  7.  
  8. /*
  9.  * Prototypes.
  10.  */
  11.  
  12. hidden    novalue    execute    Params((char *ofile,char *efile,char * *args));
  13. hidden    novalue    report Params((char *s));
  14. hidden    novalue    rmfiles Params((char **p));
  15. hidden    novalue    usage Params((noargs));
  16.  
  17. /*
  18.  * The following code is operating-system dependent [@tmain.01].  Include
  19.  *  files and such.
  20.  */
  21.  
  22. #if PORT
  23. Deliberate syntax error
  24. #endif                    /* PORT */
  25.  
  26. #if AMIGA
  27. #include <libraries/dosextens.h>
  28. #endif                    /* AMIGA */
  29.  
  30. #if ARM || MSDOS || MVS || UNIX || VM || VMS
  31. /* nothing is needed */
  32. #endif                    /* ARM || ... */
  33.  
  34. #if ATARI_ST
  35. char *patharg;
  36. #endif                    /* ATARI_ST */
  37.  
  38. #if MACINTOSH
  39. #if MPW
  40. #include <fcntl.h>    /* MPW3 - for unlink() */
  41. #include <CursorCtl.h>
  42. void SortOptions();
  43. #endif                    /* MPW */
  44. #endif                    /* MACINTOSH */
  45.  
  46. #if OS2
  47. #include <process.h>
  48. #endif                    /* OS2 */
  49. /*
  50.  * End of operating-system specific code.
  51.  */
  52.  
  53. #if IntBits == 16
  54. #ifdef strlen
  55. #undef strlen                /* pre-defined in some contexts */
  56. #endif                    /* strlen */
  57. #endif                    /* Intbits == 16 */
  58.  
  59. /*
  60.  *  Define global variables.
  61.  */
  62.  
  63. #define Global
  64. #define Init(v) = v
  65. #include "globals.h"
  66.  
  67. char *ofile = NULL;            /* linker output file name */
  68.  
  69. char patchpath[MaxPath+18] = "%PatchStringHere->";
  70. char *refpath = RefPath;
  71. char *iconxloc;
  72.  
  73. /*
  74.  * getopt() variables
  75.  */
  76. extern int optindex;        /* index into parent argv vector */
  77. extern int optopt;        /* character checked for validity */
  78. extern char *optarg;        /* argument associated with option */
  79.  
  80. /*
  81.  *  main program
  82.  */
  83. novalue main(argc,argv)
  84. int argc;
  85. char **argv;
  86.    {
  87.    int nolink = 0;            /* suppress linking? */
  88.    int errors = 0;            /* translator and linker errors */
  89.    char **tfiles, **tptr;        /* list of files to translate */
  90.    char **lfiles, **lptr;        /* list of files to link */
  91.    char **rfiles, **rptr;        /* list of files to remove */
  92.    char *efile = NULL;            /* stderr file */
  93.    char buf[MaxFileName];        /* file name construction buffer */
  94.    int c, n;
  95.    struct fileparts *fp;
  96.  
  97. #if AMIGA
  98. #if AZTEC_C
  99.    struct Process *FindTask();
  100.    struct Process *Process = FindTask(0L);
  101.    ULONG stacksize = *((ULONG *)Process->pr_ReturnAddr);
  102.  
  103.    if (stacksize < ICONTMINSTACK) {
  104.       fprintf(stderr,"Icont needs \"stack %d\" to run\n",ICONTMINSTACK);
  105.       exit(-1);
  106.       }
  107. #endif                    /* AZTEC_C */
  108. #endif                    /* AMIGA */
  109.  
  110.  
  111. #if MACINTOSH
  112. #if MPW
  113.    InitCursorCtl(NULL);
  114.    SortOptions(argv);
  115. #endif                    /* MPW */
  116. #endif                    /* MACINTOSH */
  117.  
  118.    iconxloc = (char *)alloc((unsigned)strlen(refpath) + 6);
  119.    strcpy(iconxloc, refpath);
  120.    strcat(iconxloc, "iconx");
  121.  
  122.    if (strlen(patchpath)>18)
  123.       iconxloc = patchpath+18;
  124.  
  125.    /*
  126.     * Process options.
  127.     */
  128.    while ((c = getopt(argc,argv,Options)) != EOF)
  129.       switch (c) {
  130.          case 'C':            /* Ignore: compiler only */
  131.             break;
  132.  
  133.  
  134.          case 'L':            /* -L: enable linker debugging */
  135.  
  136. #ifdef DeBugLinker
  137.             Dflag = 1;
  138. #endif                    /* DeBugLinker */
  139.  
  140.             break;
  141.  
  142.          case 'S':            /* -Sxnnnn: set a size */
  143.             sizearg(optarg,argv);
  144.             break;
  145.          case 'c':            /* -c: compile only (no linking) */
  146.             nolink = 1;
  147.             break;
  148.          case 'e':            /* -e file: redirect stderr */
  149.             efile = optarg;
  150.             break;
  151.          case 'f':            /* Ignore: compiler only */
  152.             break;
  153.          case 'm':            /* -m: preprocess using m4(1) [UNIX] */
  154.             m4pre = 1;
  155.             break;
  156.          case 'n':            /* Ignore: compiler only */
  157.             break;
  158.          case 'o':            /* -o file: name output file */
  159.             ofile = optarg;
  160.             break;
  161.  
  162.          case 'p':            /* -p path: iconx path [ATARI] */
  163. #if ATARI_ST
  164.             patharg = optarg;
  165. #endif                    /* ATARI_ST */
  166.             break;
  167.  
  168.          case 'r':            /* Ignore: compiler only */
  169.             break;
  170.          case 's':            /* -s: suppress informative messages */
  171.             silent = 1;
  172.             break;
  173.          case 't':            /* -t: turn on procedure tracing */
  174.             trace = -1;
  175.             break;
  176.          case 'u':            /* -u: warn about undeclared ids */
  177.             uwarn = 1;
  178.             break;
  179.          case 'v':            /* Ignore: compiler only */
  180.             break;
  181.          default:
  182.          case 'x':            /* -x illegal until after file list */
  183.             usage();
  184.          }
  185.  
  186.    /*
  187.     * Allocate space for lists of file names.
  188.     */
  189.    n = argc - optindex + 1;
  190.    tptr = tfiles = (char **)alloc((unsigned int)(n * sizeof(char *)));
  191.    lptr = lfiles = (char **)alloc((unsigned int)(n * sizeof(char *)));
  192.    rptr = rfiles = (char **)alloc((unsigned int)(2 * n * sizeof(char *)));
  193.  
  194.    /*
  195.     * Scan file name arguments.
  196.     */
  197.    while (optindex < argc)  {
  198.       if (strcmp(argv[optindex],"-x") == 0)    /* stop at -x */
  199.          break;
  200.       else if (strcmp(argv[optindex],"-") == 0) {
  201.  
  202. #if ARM
  203.     /* Different file naming, so we need a different strategy... */
  204.     *tptr++ = "-";
  205.     /* Use makename(), pretending we had an input file named "Stdin" */
  206.     makename(buf,TargetDir,"Stdin",U1Suffix);
  207.     *lptr++ = *rptr++ = salloc(buf);    /* link & remove .u1 */
  208.     makename(buf,TargetDir,"Stdin",U2Suffix);
  209.     *rptr++ = salloc(buf);        /* also remove .u2 */
  210.  
  211. #else                    /* ARM */
  212.  
  213.          *tptr++ = "-";                /* "-" means standard input */
  214.          *lptr++ = *rptr++ = "stdin.u1";
  215.          *rptr++ = "stdin.u2";
  216. #endif                    /* ARM */
  217.  
  218.          }
  219.       else {
  220.          fp = fparse(argv[optindex]);        /* parse file name */
  221.          if (*fp->ext == '\0' || smatch(fp->ext, SourceSuffix)) {
  222.             makename(buf,SourceDir,argv[optindex], SourceSuffix);
  223.             *tptr++ = salloc(buf);        /* translate the .icn file */
  224.             makename(buf,TargetDir,argv[optindex],U1Suffix);
  225.             *lptr++ = *rptr++ = salloc(buf);    /* link & remove .u1 */
  226.             makename(buf,TargetDir,argv[optindex],U2Suffix);
  227.             *rptr++ = salloc(buf);        /* also remove .u2 */
  228.             }
  229.          else if (smatch(fp->ext,U1Suffix) || smatch(fp->ext,U2Suffix)
  230.                || smatch(fp->ext,USuffix)) {
  231.             makename(buf,TargetDir,argv[optindex],U1Suffix);
  232.             *lptr++ = salloc(buf);
  233.             }
  234.          else
  235.             quitf("bad argument %s",argv[optindex]);
  236.          }
  237.       optindex++;
  238.       }
  239.  
  240.    *tptr = *lptr = *rptr = NULL;    /* terminate filename lists */
  241.    if (lptr == lfiles)
  242.       usage();                /* error -- no files named */
  243.  
  244.    /*
  245.     * Round hash table sizes to next power of two, and set masks for hashing.
  246.     */
  247.    chsize = round2(chsize);  cmask = chsize - 1;
  248.    fhsize = round2(fhsize);  fmask = fhsize - 1;
  249.    ghsize = round2(ghsize);  gmask = ghsize - 1;
  250.    ihsize = round2(ihsize);  imask = ihsize - 1;
  251.    lhsize = round2(lhsize);  lmask = lhsize - 1;
  252.  
  253.    /*
  254.     * Translate .icn files to make .u1 and .u2 files.
  255.     */
  256.    if (tptr > tfiles) {
  257.       if (!silent)
  258.          report("Translating");
  259.       errors = trans(tfiles);
  260.       if (errors > 0)            /* exit if errors seen */
  261.          exit(ErrorExit);
  262.       }
  263.  
  264.    /*
  265.     * Link .u1 and .u2 files to make an executable.
  266.     */
  267.    if (nolink) {            /* exit if no linking wanted */
  268.  
  269. #if MACINTOSH
  270. #if MPW
  271.       /*
  272.        *  Set type of translator output ucode (.u) files
  273.        *  to 'TEXT', so they can be easily viewed by editors.
  274.        */
  275.       {
  276.       char **p;
  277.       void setfile();
  278.       for (p = rfiles; *p; ++p)
  279.          setfile(*p,'TEXT','icon');
  280.       }
  281. #endif                    /* MPW */
  282. #endif                    /* MACINTOSH */
  283.  
  284.       exit(NormalExit);
  285.       }
  286.  
  287.    if (ofile == NULL)  {        /* if no -o file, synthesize a name */
  288.       ofile = salloc(makename(buf,TargetDir,lfiles[0],IcodeSuffix));
  289.    } else {                /* add extension in necessary */
  290.       fp = fparse(ofile);
  291.       if (*fp->ext == '\0' && *IcodeSuffix != '\0') /* if no ext given */
  292.          ofile = salloc(makename(buf,NULL,ofile,IcodeSuffix));
  293.    }
  294.  
  295.    if (!silent)
  296.       report("Linking");
  297.    errors = ilink(lfiles,ofile);    /* link .u files to make icode file */
  298.  
  299.    /*
  300.     * Finish by removing intermediate files.
  301.     *  Execute the linked program if so requested and if there were no errors.
  302.     */
  303.  
  304. #if MACINTOSH
  305. #if MPW
  306.    /* Set file type to TEXT so it will be executable as a script. */
  307.    setfile(ofile,'TEXT','icon');
  308. #endif                    /* MPW */
  309. #endif                    /* MACINTOSH */
  310.  
  311.    rmfiles(rfiles);            /* remove intermediate files */
  312.    if (errors > 0) {            /* exit if linker errors seen */
  313.       unlink(ofile);
  314.       exit(ErrorExit);
  315.       }
  316.  
  317. #if !(MACINTOSH && MPW)
  318.    if (optindex < argc)  {
  319.       if (!silent)
  320.          report("Executing");
  321.       execute (ofile, efile, argv+optindex+1);
  322.       }
  323. #endif                    /* !(MACINTOSH && MPW) */
  324.  
  325.    exit(NormalExit);
  326.    }
  327.  
  328. /*
  329.  * execute - execute iconx to run the icon program
  330.  */
  331. static novalue execute(ofile,efile,args)
  332. char *ofile, *efile, **args;
  333.    {
  334.  
  335. #if !(MACINTOSH && MPW)
  336.    int n;
  337.    char **argv, **p;
  338.  
  339.    for (n = 0; args[n] != NULL; n++)    /* count arguments */
  340.       ;
  341.    p = argv = (char **)alloc((unsigned int)((n + 5) * sizeof(char *)));
  342.  
  343.    *p++ = iconxloc;            /* set iconx pathname */
  344.    if (efile != NULL) {            /* if -e given, copy it */
  345.       *p++ = "-e";
  346.       *p++ = efile;
  347.       }
  348.    *p++ = ofile;            /* pass icode file name */
  349.  
  350. #if AMIGA && LATTICE
  351.    *p = *args;
  352.    while (*p++) {
  353.       *p = *args;
  354.       args++;
  355.    }
  356. #else                    /* AMIGA && LATTICE */
  357.    while (*p++ = *args++)        /* copy args into argument vector */
  358.       ;
  359. #endif                    /* AMIGA && LATTICE */
  360.  
  361.    *p = NULL;
  362.  
  363. /*
  364.  * The following code is operating-system dependent [@tmain.02].  It calls
  365.  *  iconx on the way out.
  366.  */
  367.  
  368. #if PORT
  369.    /* something is needed */
  370. Deliberate Syntax Error
  371. #endif                    /* PORT */
  372.  
  373. #if AMIGA
  374. #if AZTEC_C
  375.       execvp(iconxloc,argv);
  376.       return;
  377. #endif                    /* AZTEC_C */
  378. #if LATTICE
  379.       {
  380.       struct ProcID procid;
  381.       if (forkv(iconxloc,argv,NULL,&procid) == 0) { 
  382.          wait(&procid);
  383.          return;
  384.          }
  385.       }
  386. #endif                    /* LATTICE */
  387. #endif                    /* AMIGA */
  388.  
  389. #if ARM
  390.    {
  391.       int i = 7 + strlen(iconxloc);
  392.       int j;
  393.       char *s;
  394.       char buffer[255];
  395.       extern int armquote(char *, char **);
  396.  
  397.       sprintf(buffer, "Chain:%s ", iconxloc);
  398.       for (p = argv + 1; *p; ++p)
  399.       {
  400.          j = armquote(*p, &s);
  401.  
  402.          if (j == -1 || i + j >= 255)
  403.          {
  404.             fprintf(stderr, "Cannot execute: command line too long");
  405.             fflush(stderr);
  406.             return;
  407.          }
  408.  
  409.          strcpy(buffer + i, s);
  410.          i += j;
  411.          buffer[i] = ' ';
  412.       }
  413.       buffer[i] = '\0';
  414.       system(buffer);
  415.    }
  416. #endif                    /* ARM */
  417.  
  418. #if ATARI_ST || MACINTOSH
  419.       fprintf(stderr,"-x not supported\n");
  420.       fflush(stderr);
  421. #endif                    /* ATARI_ST || ... */
  422.  
  423. #if MSDOS
  424. #if LATTICE || MICROSOFT || TURBO
  425.       execvp(iconxloc,argv);    /* execute with path search */
  426. #endif                    /* LATTICE || MICROSOFT || TURBO */
  427. #if MWC || INTEL_386 || ZTC_386 || HIGHC_386
  428.       fprintf(stderr,"-x not supported\n");
  429.       fflush(stderr);
  430. #endif                    /* MWC || INTEL_386 || ... */
  431. #endif                    /* MSDOS */
  432.  
  433. #if MVS || VM
  434. #if SASC
  435.       exit(sysexec(iconxloc, argv));
  436. #endif                    /* SASC */
  437.       fprintf(stderr,"-x not supported\n");
  438.       fflush(stderr);
  439. #endif                                  /* MVS || VM */
  440.  
  441. #if OS2
  442.       execvp(iconxloc,argv);    /* execute with path search */
  443. #endif                    /* OS2 */
  444.  
  445. #if UNIX
  446.       /*
  447.        * If an ICONX environment variable is defined, use that.
  448.        *  If not, first try the predefined path, then search $PATH via execvp. 
  449.        */
  450.       if ((argv[0] = getenv("ICONX")) != NULL && argv[0][0] != '\0') {
  451.          execv(argv[0], argv);    /* exec file specified by $ICONX */
  452.          quitf("cannot execute $ICONX (%s)", argv[0]);
  453.          }
  454.  
  455. #ifdef HardWiredPaths
  456. #ifdef CRAY
  457.       argv[0] = "iconx";
  458.       execv(iconxloc, argv);
  459. #else                    /* CRAY */
  460.       argv[0] = iconxloc;        /* try predefined file */
  461.       execv(argv[0], argv);
  462. #endif                    /* CRAY */
  463. #endif                    /* HardWiredPaths */
  464.  
  465.       argv[0] = "iconx";
  466.       execvp(argv[0], argv);    /* if no iconxloc, search path for "iconx" */
  467.  
  468. #ifdef HardWiredPaths
  469.       quitf("cannot run %s", iconxloc);
  470. #else                    /* HardWiredPaths */
  471.       quitf("cannot find iconx", "");
  472. #endif                    /* HardWiredPaths */
  473. #endif                    /* UNIX */
  474.  
  475. #if VMS
  476.       execv(iconxloc,argv);
  477. #endif                    /* VMS */
  478.  
  479. /*
  480.  * End of operating-system specific code.
  481.  */
  482.  
  483.    quitf("could not run %s",iconxloc);
  484.  
  485. #else                    /* !(MACINTOSH && MPW) */
  486.    printf("-x not supported\n");
  487. #endif                    /* !(MACINZTOSH && MPW) */
  488.  
  489.    }
  490.  
  491. static novalue report(s)
  492. char *s;
  493.    {
  494.  
  495.    fprintf(stderr,"%s:\n",s);
  496.  
  497.    }
  498.  
  499. /*
  500.  * rmfiles - remove a list of files
  501.  */
  502.  
  503. static novalue rmfiles(p)
  504. char **p;
  505.    {
  506.    for (; *p; p++) {
  507.       unlink(*p);
  508.       }
  509.    }
  510.  
  511. /*
  512.  * Print an error message if called incorrectly.  The message depends
  513.  *  on the legal options for this system.
  514.  */
  515. static novalue usage()
  516.    {
  517.    fprintf(stderr,"usage: %s %s file ... [-x args]\n", progname, TUsage);
  518.    exit(ErrorExit);
  519.    }
  520.