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 / icont / tmain.c < prev    next >
C/C++ Source or Header  |  1996-03-22  |  34KB  |  1,370 lines

  1. /*
  2.  * tmain.c - main program for translator and linker.
  3.  */
  4.  
  5. #include "::h:gsupport.h"
  6. #include "tproto.h"
  7.  
  8. #if MACINTOSH
  9. #if THINK_C
  10. #include <string.h>
  11. #include "console.h"
  12. #include "config.h"
  13. #include "cpuconf.h"
  14. #include "macgraph.h"
  15. #include <AppleEvents.h>
  16. #include <GestaltEqu.h>
  17. /* #include <Values.h> */
  18.  
  19. #define MAXLONG  (0x7fffffff)
  20.  
  21. /* #define kSleep MAXLONG */
  22. #define kGestaltMask 1L
  23.  
  24. /* Global */
  25. Boolean gDone;
  26. Boolean g_cOption;
  27.  
  28.  
  29. #endif    /* THINK_C */
  30. #endif    /* MACINTOSH */
  31.  
  32. #if NT || MICROSOFT
  33. #include <io.h>
  34. #endif                    /* NT || MICROSOFT */
  35.  
  36. /*
  37.  * Prototypes.
  38.  */
  39.  
  40. hidden    novalue    execute    Params((char *ofile,char *efile,char * *args));
  41. hidden    novalue    report Params((char *s));
  42. hidden    novalue    rmfiles Params((char **p));
  43. hidden    novalue    usage Params((noargs));
  44. hidden    novalue    expand_proj Params((int *argc, char ***argv));
  45.  
  46. #if MACINTOSH
  47. #if THINK_C
  48. pascal void  MaxApplZone ( void );
  49. void         IncreaseStackSize ( Size extraBytes );
  50.  
  51. void         ToolBoxInit ( void );
  52. void         EventInit ( void );
  53. void         EventLoop ( void );
  54. void         DoEvent ( EventRecord *eventPtr );
  55. pascal OSErr DoOpenDoc ( AppleEvent theAppleEvent,
  56.                          AppleEvent reply,
  57.                                long refCon );
  58. pascal OSErr DoQuitApp ( AppleEvent theAppleEvent,
  59.                          AppleEvent reply,
  60.                                long refCon );
  61. OSErr        GotRequiredParams ( AppleEvent *appleEventPtr );
  62. novalue      MacMain ( int argc, char **argv );             
  63.  
  64. void DoMouseDown (EventRecord *eventPtr);
  65. void HandleMenuChoice (long menuChoice);
  66. void HandleAppleChoice (short item);
  67. void HandleFileChoice (short item);
  68. void HandleOptionsChoice (short item);
  69. void MenuBarInit (void);           
  70. #endif                  /* THINK_C */
  71. #endif                  /* MACINTOSH */
  72.  
  73. /*
  74.  * The following code is operating-system dependent [@tmain.01].  Include
  75.  *  files and such.
  76.  */
  77.  
  78. #if PORT
  79. Deliberate syntax error
  80. #endif                    /* PORT */
  81.  
  82. #if AMIGA
  83. #include <libraries/dosextens.h>
  84. #endif                    /* AMIGA */
  85.  
  86. #if ARM || MVS || UNIX || VM || VMS
  87. /* nothing is needed */
  88. #endif                    /* ARM || ... */
  89.  
  90. #if MSDOS
  91.    char pathToIconDOS[129];
  92. #endif                    /* MSDOS */
  93.  
  94. #if ATARI_ST
  95. char *patharg;
  96. #endif                    /* ATARI_ST */
  97.  
  98. #if MACINTOSH
  99. #if MPW
  100. #include <fcntl.h>    /* MPW3 - for unlink() */
  101. #include <CursorCtl.h>
  102. void SortOptions();
  103. #endif                    /* MPW */
  104. #endif                    /* MACINTOSH */
  105.  
  106. #if OS2
  107. #include <process.h>
  108. #endif                    /* OS2 */
  109. /*
  110.  * End of operating-system specific code.
  111.  */
  112.  
  113. #if IntBits == 16
  114. #ifdef strlen
  115. #undef strlen                /* pre-defined in some contexts */
  116. #endif                    /* strlen */
  117. #endif                    /* Intbits == 16 */
  118.  
  119. /*
  120.  *  Define global variables.
  121.  */
  122.  
  123. #define Global
  124. #define Init(v) = v
  125. #include "tglobals.h"
  126.  
  127. char *ofile = NULL;            /* linker output file name */
  128.  
  129. char patchpath[MaxPath+18] = "%PatchStringHere->";
  130.  
  131. /*
  132.  * The following code is operating-system dependent [@tmain.02].  Definition
  133.  *  of refpath.
  134.  */
  135.  
  136. #if PORT
  137.    /* something is needed */
  138. Deliberate Syntax Error
  139. #endif                    /* PORT */
  140.  
  141. #if UNIX || AMIGA || ATARI_ST || MACINTOSH || MSDOS || MVS || OS2 || VM
  142. char *refpath = RefPath;
  143. #endif                    /* UNIX ... */
  144.  
  145. #if VMS
  146. char *refpath = "ICON_BIN:";
  147. #endif                    /* VMS */
  148.  
  149. /*
  150.  * End of operating-system specific code.
  151.  */
  152.  
  153. /*
  154.  * getopt() variables
  155.  */
  156. extern int optindex;        /* index into parent argv vector */
  157. extern int optopt;        /* character checked for validity */
  158. extern char *optarg;        /* argument associated with option */
  159.  
  160. #ifdef ConsoleWindow
  161. int ConsolePause = 1;
  162. #endif                    /* ConsoleWindow */
  163.  
  164.  
  165.  
  166. #if MACINTOSH
  167. #if THINK_C
  168. void main ( void )
  169. {
  170. /* Increase stack size if neccessary  */
  171.  
  172. /*
  173.    Size extraBytes=32*1024;
  174.    IncreaseStackSize (extraBytes);
  175.  */
  176.  
  177.    MaxApplZone();
  178.  
  179.    ToolBoxInit ();
  180.    EventInit ();
  181.    MenuBarInit();
  182.    
  183.    EventLoop ();
  184. }                    /* end of main () */
  185. #endif               /* THINK_C */
  186. #endif               /* MACINTOSH */
  187.  
  188.  
  189. #ifdef ConsoleWindow
  190. /*
  191.  * expand Icon project (.icp) files
  192.  */
  193. static void expand_proj(int *argc, char ***argv)
  194. {
  195.    int ac = *argc, i, j, k;
  196.    char **av = *argv, buf[1024];
  197.    FILE *f;
  198.    for (i=1; i<ac; i++) {
  199.       if (strstr(av[i], ".ICP") || strstr(av[i], ".icp")) break;
  200.       }
  201.    if (i == ac) return;
  202.    if ((f = fopen(av[i], "r")) == NULL) {
  203.       fprintf(stderr, "icont: can't open %s\n", av[i]);
  204.       fflush(stderr);
  205.       return;
  206.       }
  207.    if ((*argv = malloc(ac * sizeof (char *))) == NULL) {
  208.       fprintf(stderr, "icont: can't malloc for %s\n", av[i]);
  209.       fflush(stderr);
  210.       return;
  211.       }
  212.    for(j=0; j<i; j++) (*argv)[j] = av[j];
  213.    k = j++;
  214.    if(fgets(buf, 1023, f) != NULL) {
  215.       if (strchr(buf, '\n') != NULL)
  216.          buf[strlen(buf)-1] = '\0';
  217.       (*argv)[k++] = salloc(buf);
  218.       while(fgets(buf, 1023, f) != NULL) {
  219.          if (strchr(buf, '\n') != NULL)
  220.             buf[strlen(buf)-1] = '\0';
  221.          (*argc)++;
  222.          if ((*argv = realloc(*argv, *argc * sizeof (char *))) == NULL) {
  223.             fprintf(stderr, "icont: can't malloc for %s\n", av[i]);
  224.             fflush(stderr);
  225.             return;
  226.             }
  227.          (*argv)[k++] = salloc(buf);
  228.          }
  229.       }
  230.    fclose(f);
  231.    for( ; j < ac; j++, k++) (*argv)[k] = av[j];
  232. }
  233. #endif                    /* ConsoleWindow */
  234.  
  235. #ifndef NTConsole
  236. #ifdef MSWindows
  237. novalue icont(int argc, char **argv);
  238. #define int_PASCAL int PASCAL
  239. #define LRESULT_CALLBACK LRESULT CALLBACK
  240. #undef lstrlen
  241. #include <windows.h>
  242. #define lstrlen longstrlen
  243. #include "::wincap:dibutil.h"
  244.  
  245. int CmdParamToArgv(char *s, char ***avp)
  246.    {
  247.    char *t, *t2;
  248.    int rv=0;
  249.    t = salloc(s);
  250.    t2 = t;
  251.    while (*t2) {
  252.       while (*t2 && isspace(*t2)) t2++;
  253.       if (!*t2) break;
  254.       rv++;
  255.       while (*t2 && !isspace(*t2)) t2++;
  256.       }
  257.    rv++; /* make room for "wicont" at front */
  258.  
  259.    *avp = (char **)alloc((rv+1) * sizeof(char *));
  260.    rv = 0;
  261.    (*avp)[rv++] = salloc("wicont.exe");
  262.    t2 = t;
  263.    while (*t2) {
  264.       while (*t2 && isspace(*t2)) t2++;
  265.       if (!*t2) break;
  266.       (*avp)[rv++] = t2;
  267.       while (*t2 && !isspace(*t2)) t2++;
  268.       if (*t2) *t2++ = '\0';
  269.       }
  270.    (*avp)[rv] = NULL;
  271.    return rv;  
  272.    }
  273.  
  274.  
  275. LRESULT_CALLBACK WndProc    Params((HWND, UINT, WPARAM, LPARAM));
  276.  
  277. novalue MSStartup(int argc, char **argv, HINSTANCE hInstance, HINSTANCE hPrevInstance)
  278.    {
  279.    WNDCLASS wc;
  280.    extern FILE *flog;
  281.    /* generate log file?  might make this an option */
  282.    if (0)
  283.       flog = fopen("wicont.log", "w");
  284.    if (!hPrevInstance) {
  285. #if NT
  286.       wc.style = CS_HREDRAW | CS_VREDRAW;
  287. #else                    /* NT */
  288.       wc.style = 0;
  289. #endif                    /* NT */
  290. #ifdef NTConsole
  291.       wc.lpfnWndProc = DefWindowProc;
  292. #else                    /* NTConsole */
  293.       wc.lpfnWndProc = WndProc;
  294. #endif                    /* NTConsole */
  295.       wc.cbClsExtra = 0;
  296.       wc.cbWndExtra = 0;
  297.       wc.hInstance  = hInstance;
  298.       wc.hIcon      = NULL;
  299.       wc.hCursor    = LoadCursor(NULL, IDC_ARROW);
  300.       wc.hbrBackground = GetStockObject(WHITE_BRUSH);
  301.       wc.lpszMenuName = NULL;
  302.       wc.lpszClassName = "iconx";
  303.       RegisterClass(&wc);
  304.       }
  305.    }
  306.  
  307. HANDLE mswinInstance;
  308. int ncmdShow;
  309.  
  310. jmp_buf mark_sj;
  311.  
  312. int_PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
  313.                    LPSTR lpszCmdParam, int nCmdShow)
  314.    {
  315.    int argc;
  316.    char **argv;
  317.  
  318.    mswinInstance = hInstance;
  319.    ncmdShow = nCmdShow;
  320.    argc = CmdParamToArgv(lpszCmdParam, &argv);
  321.    MSStartup(argc, argv, hInstance, hPrevInstance);
  322. #if BORLAND_286
  323.    _InitEasyWin();
  324. #endif                    /* BORLAND_286 */
  325.    if (setjmp(mark_sj) == 0)
  326.       icont(argc,argv);
  327.    wfreersc();
  328.    return 0;
  329. }
  330.  
  331. #define main icont
  332. #endif                    /* MSWindows */
  333. #endif                    /* NTConsole */
  334.  
  335.  
  336. /*
  337.  *  main program
  338.  */
  339.  
  340. #if !THINK_C
  341. novalue main(argc, argv)
  342. #else                           /* THINK_C */
  343. novalue MacMain(argc,argv)
  344. #endif                          /* !THINKC_C */
  345.  
  346. int argc;
  347. char **argv;
  348.    {
  349.    int nolink = 0;            /* suppress linking? */
  350.    int errors = 0;            /* translator and linker errors */
  351.    char **tfiles, **tptr;        /* list of files to translate */
  352.    char **lfiles, **lptr;        /* list of files to link */
  353.    char **rfiles, **rptr;        /* list of files to remove */
  354.    char *efile = NULL;            /* stderr file */
  355.    char buf[MaxFileName];        /* file name construction buffer */
  356.    int c, n;
  357.    char ch;
  358.    struct fileparts *fp;
  359.  
  360. #if NT || MICROSOFT
  361.    struct _finddata_t fd;
  362.    int j;
  363.    long l;
  364. #endif                    /* NT || MICROSOFT */
  365.  
  366.  
  367. #if SCCX_MX
  368.     syntax error!
  369.     The Symantec license agreement requires you to include a copyright
  370.     notice in your program.  This is a good place for it.
  371.    fprintf( stderr,
  372.     "Copyright (c) 1995, Your Name, Your City, Your State.\n");
  373. #endif                    /* SSCX_MX */
  374.  
  375. #if AMIGA
  376. #if AZTEC_C
  377.    struct Process *FindTask();
  378.    struct Process *Process = FindTask(0L);
  379.    ULONG stacksize = *((ULONG *)Process->pr_ReturnAddr);
  380.  
  381.    if (stacksize < ICONTMINSTACK) {
  382.       fprintf(stderr,"Icont needs \"stack %d\" to run\n",ICONTMINSTACK);
  383.       exit(-1);
  384.       }
  385. #endif                    /* AZTEC_C */
  386. #endif                    /* AMIGA */
  387.  
  388.  
  389. #if MACINTOSH
  390. #if MPW
  391.    InitCursorCtl(NULL);
  392.    SortOptions(argv);
  393. #endif                    /* MPW */
  394. #endif                    /* MACINTOSH */
  395.  
  396.    if ((int)strlen(patchpath) > 18)
  397.       iconxloc = patchpath+18;
  398.    else {
  399.       iconxloc = (char *)alloc((unsigned)strlen(refpath) + 8);
  400.       strcpy(iconxloc, refpath);
  401. #if NT
  402. #ifdef MSWindows
  403.       strcat(iconxloc, "w");        /* wiconx */
  404. #else                    /* MSWindows */
  405.       strcat(iconxloc, "nt");        /* nticonx */
  406. #endif                    /* MSWindows */
  407. #endif                    /* NT */
  408.       strcat(iconxloc, "iconx");
  409.       }
  410.  
  411. #ifdef ConsoleWindow
  412.    if ((int)strlen(patchpath) <= 18) {
  413.       free(iconxloc);
  414.       iconxloc = (char *)alloc((unsigned)strlen(refpath) + 7);
  415.       strcpy(iconxloc, refpath);
  416.       strcat(iconxloc, "wiconx");
  417.       }
  418.    expand_proj(&argc, &argv);
  419. #endif                    /* ConsoleWindow */
  420.  
  421.    /*
  422.     * Process options.
  423.     */
  424.    while ((c = getopt(argc,argv,IconOptions)) != EOF)
  425.       switch (c) {
  426.          case 'C':            /* Ignore: compiler only */
  427.             break;
  428.          case 'E':            /* -E: preprocess only */
  429.         pponly = 1;
  430.         nolink = 1;
  431.             break;
  432.  
  433.          case 'L':            /* -L: enable linker debugging */
  434.  
  435. #ifdef DeBugLinker
  436.             Dflag = 1;
  437. #endif                    /* DeBugLinker */
  438.  
  439.             break;
  440.  
  441.          case 'S':            /* -S */
  442.             fprintf(stderr, "Warning, -S option is obsolete\n");
  443.             break;
  444.  
  445. #if MSDOS
  446.          case 'X':            /* -X */
  447. #if ZTC_386
  448.             fprintf(stderr, "Warning: -X option is not available\n");
  449. #else                    /* ZTC_386 */
  450.             makeExe = 1;
  451. #endif                    /* ZTC_386 */
  452.             break;
  453.          case 'I':            /* -C */
  454.             makeExe = 0;
  455.             break;
  456. #endif                    /* MSDOS */
  457.  
  458.          case 'c':            /* -c: compile only (no linking) */
  459.             nolink = 1;
  460.             break;
  461.          case 'e':            /* -e file: redirect stderr */
  462.             efile = optarg;
  463.             break;
  464.          case 'f':            /* -f features: enable features */
  465.             if (index(optarg, 's') || index(optarg, 'a'))
  466.                strinv = 1;        /* this is the only icont feature */
  467.             break;
  468.  
  469. #if OS2
  470.      case 'i':                      /* -i: Don't create .EXE file */
  471.         noexe = 1;
  472.         break;
  473. #endif                    /* OS2 */
  474.  
  475.          case 'm':            /* -m: preprocess using m4(1) [UNIX] */
  476.             m4pre = 1;
  477.             break;
  478.          case 'n':            /* Ignore: compiler only */
  479.             break;
  480.          case 'o':            /* -o file: name output file */
  481.             ofile = optarg;
  482.             break;
  483.  
  484.          case 'p':            /* -p path: iconx path [ATARI] */
  485.  
  486. #if ATARI_ST
  487.             patharg = optarg;
  488. #endif                    /* ATARI_ST */
  489.  
  490.             break;
  491.  
  492. #ifdef ConsoleWindow
  493.      case 'q':
  494.          ConsolePause = 0;
  495.         break;
  496. #endif                    /* ConsoleWindow */
  497.          case 'r':            /* Ignore: compiler only */
  498.             break;
  499.          case 's':            /* -s: suppress informative messages */
  500.             silent = 1;
  501.             verbose = 0;
  502.             break;
  503.          case 't':            /* -t: turn on procedure tracing */
  504.             trace = -1;
  505.             break;
  506.          case 'u':            /* -u: warn about undeclared ids */
  507.             uwarn = 1;
  508.             break;
  509.          case 'v':            /* -v n: set verbosity level */
  510.             if (sscanf(optarg, "%d%c", &verbose, &ch) != 1)
  511.                quitf("bad operand to -v option: %s",optarg);
  512.             if (verbose == 0)
  513.                silent = 1;
  514.             break;
  515.          default:
  516.          case 'x':            /* -x illegal until after file list */
  517.             usage();
  518.          }
  519.  
  520. #if MSDOS && !NT
  521.       /*
  522.        * Define pathToIconDOS as a global accessible from inside
  523.        * separately-compiled compilation units.
  524.        */
  525.       if( makeExe ){
  526.          char *pathCursor;
  527.  
  528.          strcpy (pathToIconDOS, argv[0]);
  529.          pathCursor = (char *)strrchr (pathToIconDOS, '\\');
  530.          if (!pathCursor) {
  531.             fprintf (stderr,
  532.                "Can't understand what directory icont was run from.\n");
  533.             exit(ErrorExit);
  534.             }
  535.             strcpy (++pathCursor, "ixhdr.exe");
  536.          }
  537. #endif                                  /* MSDOS && !NT */
  538.  
  539.    /*
  540.     * Allocate space for lists of file names.
  541.     */
  542.    n = argc - optindex + 1;
  543.  
  544. #if NT || MICROSOFT
  545.    /*
  546.     * allocate additional space for wildcarded names, if any
  547.     */
  548.    {
  549.    for(j=optindex; j < argc; j++) {
  550.       l = _findfirst(argv[j], &fd);
  551.       if (l != -1) {
  552.          while(!_findnext(l, &fd)) n++;
  553.       _findclose(l);
  554.      }
  555.       }
  556.    }
  557. #endif                    /* NT || MICROSOFT */
  558.  
  559.    tptr = tfiles = (char **)alloc((unsigned int)(n * sizeof(char *)));
  560.    lptr = lfiles = (char **)alloc((unsigned int)(n * sizeof(char *)));
  561.    rptr = rfiles = (char **)alloc((unsigned int)(2 * n * sizeof(char *)));
  562.  
  563.    /*
  564.     * Scan file name arguments.
  565.     */
  566.    while (optindex < argc)  {
  567.       if (strcmp(argv[optindex],"-x") == 0)    /* stop at -x */
  568.          break;
  569.       else if (strcmp(argv[optindex],"-") == 0) {
  570.  
  571. #if ARM
  572.     /* Different file naming, so we need a different strategy... */
  573.     *tptr++ = "-";
  574.     /* Use makename(), pretending we had an input file named "Stdin" */
  575.     makename(buf,TargetDir,"Stdin",U1Suffix);
  576.     *lptr++ = *rptr++ = salloc(buf);    /* link & remove .u1 */
  577.     makename(buf,TargetDir,"Stdin",U2Suffix);
  578.     *rptr++ = salloc(buf);        /* also remove .u2 */
  579.  
  580. #else                    /* ARM */
  581.  
  582.          *tptr++ = "-";                /* "-" means standard input */
  583.          *lptr++ = *rptr++ = "stdin.u1";
  584.          *rptr++ = "stdin.u2";
  585. #endif                    /* ARM */
  586.  
  587.          }
  588.       else {
  589. #if NT || MICROSOFT
  590.          char tmp[MaxPath];
  591.          char *p;
  592.      strcpy(tmp, argv[optindex]);
  593.      if ((p = strrchr(tmp, '.')) == NULL ||
  594.           strchr(p, '/') || strchr(p, '\\')) {
  595.         strcat(tmp,".icn");
  596.         }
  597.          l = _findfirst(tmp, &fd);
  598.      if (l == -1) {
  599.         fprintf(stderr,"File %s: no match\n", argv[optindex]);
  600.         fflush(stderr);
  601.         exit(ErrorExit);
  602.         }
  603.      if ((p = strrchr(tmp, '\\')) || (p = strrchr(tmp, '//')) ||
  604.          (p = strrchr(tmp, ':')))
  605.          p++;
  606.          do {
  607.          if (p) {
  608.             strcpy(p, fd.name);
  609.             argv[optindex] = tmp;
  610.             }
  611.          else
  612.             argv[optindex] = fd.name;
  613. #endif                    /* NT || MICROSOFT */
  614.          fp = fparse(argv[optindex]);        /* parse file name */
  615.          if (*fp->ext == '\0' || smatch(fp->ext, SourceSuffix)) {
  616.             makename(buf,SourceDir,argv[optindex], SourceSuffix);
  617. #if VMS
  618.         strcat(buf, fp->version);
  619. #endif                    /* VMS */
  620.             *tptr++ = salloc(buf);        /* translate the .icn file */
  621.             makename(buf,TargetDir,argv[optindex],U1Suffix);
  622.             *lptr++ = *rptr++ = salloc(buf);    /* link & remove .u1 */
  623.             makename(buf,TargetDir,argv[optindex],U2Suffix);
  624.             *rptr++ = salloc(buf);        /* also remove .u2 */
  625.             }
  626.          else if (smatch(fp->ext,U1Suffix) || smatch(fp->ext,U2Suffix)
  627.                || smatch(fp->ext,USuffix)) {
  628.             makename(buf,TargetDir,argv[optindex],U1Suffix);
  629.             *lptr++ = salloc(buf);
  630.             }
  631.          else
  632.             quitf("bad argument %s",argv[optindex]);
  633. #if NT || MICROSOFT
  634.          } while (!_findnext(l, &fd));
  635.      _findclose(l);
  636. #endif                    /* NT || MICROSOFT */
  637.          }
  638.       optindex++;
  639.       }
  640.  
  641.    *tptr = *lptr = *rptr = NULL;    /* terminate filename lists */
  642.    if (lptr == lfiles)
  643.       usage();                /* error -- no files named */
  644.  
  645.    /*
  646.     * Round hash table sizes to next power of two, and set masks for hashing.
  647.     */
  648.    lchsize = round2(lchsize);  cmask = lchsize - 1;
  649.    fhsize = round2(fhsize);  fmask = fhsize - 1;
  650.    ghsize = round2(ghsize);  gmask = ghsize - 1;
  651.    ihsize = round2(ihsize);  imask = ihsize - 1;
  652.    lhsize = round2(lhsize);  lmask = lhsize - 1;
  653.  
  654.    /*
  655.     * Translate .icn files to make .u1 and .u2 files.
  656.     */
  657.    if (tptr > tfiles) {
  658.       if (!silent && !pponly)
  659.          report("Translating");
  660.       errors = trans(tfiles);
  661.       if (errors > 0)            /* exit if errors seen */
  662.          exit(ErrorExit);
  663.       }
  664.  
  665.    /*
  666.     * Link .u1 and .u2 files to make an executable.
  667.     */
  668.    if (nolink) {            /* exit if no linking wanted */
  669.  
  670. #if MACINTOSH
  671. #if MPW
  672.       /*
  673.        *  Set type of translator output ucode (.u) files
  674.        *  to 'TEXT', so they can be easily viewed by editors.
  675.        */
  676.       {
  677.       char **p;
  678.       void setfile();
  679.       for (p = rfiles; *p; ++p)
  680.          setfile(*p,'TEXT','UCOD');
  681.       }
  682. #endif                    /* MPW */
  683. #endif                    /* MACINTOSH */
  684.  
  685.       exit(NormalExit);
  686.       }
  687.  
  688. #if MSDOS
  689. #if NT
  690.    if (ofile == NULL)  {                /* if no -o file, synthesize a name */
  691.       ofile = salloc(makename(buf,TargetDir,lfiles[0],
  692.                               makeExe ? ".cmd" : IcodeSuffix));
  693.    } else {                             /* add extension if necessary */
  694.       fp = fparse(ofile);
  695.       if (*fp->ext == '\0' && *IcodeSuffix != '\0') /* if no ext given */
  696.          ofile = salloc(makename(buf,NULL,ofile,
  697.                                  makeExe ? ".cmd" : IcodeSuffix));
  698.    }
  699. #else                    /* NT */
  700.    if (ofile == NULL)  {                /* if no -o file, synthesize a name */
  701.       ofile = salloc(makename(buf,TargetDir,lfiles[0],
  702.                               makeExe ? ".Exe" : IcodeSuffix));
  703.    } else {                             /* add extension if necessary */
  704.       fp = fparse(ofile);
  705.       if (*fp->ext == '\0' && *IcodeSuffix != '\0') /* if no ext given */
  706.          ofile = salloc(makename(buf,NULL,ofile,
  707.                                  makeExe ? ".Exe" : IcodeSuffix));
  708.    }
  709. #endif                    /* NT */
  710.  
  711. #else                                   /* MSDOS */
  712.  
  713.    if (ofile == NULL)  {        /* if no -o file, synthesize a name */
  714.       ofile = salloc(makename(buf,TargetDir,lfiles[0],IcodeSuffix));
  715.    } else {                /* add extension in necessary */
  716.       fp = fparse(ofile);
  717.       if (*fp->ext == '\0' && *IcodeSuffix != '\0') /* if no ext given */
  718.          ofile = salloc(makename(buf,NULL,ofile,IcodeSuffix));
  719.    }
  720.  
  721. #endif                    /* MSDOS */
  722.  
  723.    if (!silent)
  724.       report("Linking");
  725.    errors = ilink(lfiles,ofile);    /* link .u files to make icode file */
  726.  
  727.    /*
  728.     * Finish by removing intermediate files.
  729.     *  Execute the linked program if so requested and if there were no errors.
  730.     */
  731.  
  732. #if MACINTOSH
  733. #if MPW
  734.    /* Set file type to TEXT so it will be executable as a script. */
  735.    setfile(ofile,'TEXT','ICOD');
  736. #endif                    /* MPW */
  737. #endif                    /* MACINTOSH */
  738.  
  739.    rmfiles(rfiles);            /* remove intermediate files */
  740.    if (errors > 0) {            /* exit if linker errors seen */
  741.       unlink(ofile);
  742.       exit(ErrorExit);
  743.       }
  744. #ifdef ConsoleWindow
  745.    else
  746.       if (!silent)
  747.          fprintf(stderr, "No errors\n");
  748. #endif                    /* ConsoleWindow */
  749.  
  750. #if !(MACINTOSH && MPW)
  751.    if (optindex < argc)  {
  752.       if (!silent)
  753.          report("Executing");
  754.       execute (ofile, efile, argv+optindex+1);
  755.       }
  756. #endif                    /* !(MACINTOSH && MPW) */
  757.  
  758.    exit(NormalExit);
  759.    }
  760.  
  761. /*
  762.  * execute - execute iconx to run the icon program
  763.  */
  764. static novalue execute(ofile,efile,args)
  765. char *ofile, *efile, **args;
  766.    {
  767.  
  768. #if !(MACINTOSH && MPW)
  769.    int n;
  770.    char **argv, **p;
  771.  
  772.    for (n = 0; args[n] != NULL; n++)    /* count arguments */
  773.       ;
  774.    p = argv = (char **)alloc((unsigned int)((n + 5) * sizeof(char *)));
  775.  
  776.    *p++ = iconxloc;            /* set iconx pathname */
  777.    if (efile != NULL) {            /* if -e given, copy it */
  778.       *p++ = "-e";
  779.       *p++ = efile;
  780.       }
  781.    *p++ = ofile;            /* pass icode file name */
  782.  
  783. #if AMIGA && LATTICE
  784.    *p = *args;
  785.    while (*p++) {
  786.       *p = *args;
  787.       args++;
  788.    }
  789. #else                    /* AMIGA && LATTICE */
  790. #ifdef MSWindows
  791.    {
  792.      char cmdline[256], *tmp;
  793.  
  794.      strcpy(cmdline, "wiconx ");
  795.      if (efile != NULL) {
  796.        strcat(cmdline, "-e ");
  797.        strcat(cmdline, efile);
  798.        strcat(cmdline, " ");
  799.      }
  800.    strcat(cmdline, ofile);
  801.    strcat(cmdline, " ");
  802.    while ((tmp = *args++) != NULL) {    /* copy args into argument vector */
  803.      strcat(cmdline, tmp);
  804.      strcat(cmdline, " ");
  805.    }
  806.  
  807.    WinExec(cmdline, SW_SHOW);
  808.    return;
  809.    }
  810. #endif                    /* MSWindows */
  811.  
  812. #if SCCX_MX
  813.    /* Avoids compiler warning */
  814.    while( (*p++ = *args++) != 0)      /* copy args into argument vector */
  815. #else
  816.    while (*p++ = *args++)       /* copy args into argument vector */
  817. #endif                    /* SCCX_MX */
  818.  
  819.       ;
  820. #endif                    /* AMIGA && LATTICE */
  821.  
  822.    *p = NULL;
  823.  
  824. /*
  825.  * The following code is operating-system dependent [@tmain.03].  It calls
  826.  *  iconx on the way out.
  827.  */
  828.  
  829. #if PORT
  830.    /* something is needed */
  831. Deliberate Syntax Error
  832. #endif                    /* PORT */
  833.  
  834. #if AMIGA
  835. #if AZTEC_C
  836.       execvp(iconxloc,argv);
  837.       return;
  838. #endif                    /* AZTEC_C */
  839. #if LATTICE
  840.       {
  841.       struct ProcID procid;
  842.       if (forkv(iconxloc,argv,NULL,&procid) == 0) { 
  843.          wait(&procid);
  844.          return;
  845.          }
  846.       }
  847. #endif                    /* LATTICE */
  848. #endif                    /* AMIGA */
  849.  
  850. #if ARM
  851.    {
  852.       int i = 7 + strlen(iconxloc);
  853.       int j;
  854.       char *s;
  855.       char buffer[255];
  856.       extern int armquote(char *, char **);
  857.  
  858.       sprintf(buffer, "Chain:%s ", iconxloc);
  859.       for (p = argv + 1; *p; ++p)
  860.       {
  861.          j = armquote(*p, &s);
  862.  
  863.          if (j == -1 || i + j >= 255)
  864.          {
  865.             fprintf(stderr, "Cannot execute: command line too long");
  866.             fflush(stderr);
  867.             return;
  868.          }
  869.  
  870.          strcpy(buffer + i, s);
  871.          i += j;
  872.          buffer[i] = ' ';
  873.       }
  874.       buffer[i] = '\0';
  875.       system(buffer);
  876.    }
  877. #endif                    /* ARM */
  878.  
  879. #if ATARI_ST || MACINTOSH
  880.       fprintf(stderr,"-x not supported\n");
  881.       fflush(stderr);
  882. #endif                    /* ATARI_ST || ... */
  883.  
  884. #if MSDOS
  885.       /* No special handling is needed for an .exe files, since iconx
  886.        * recognizes it from the extension andfrom internal .exe data.
  887.        */
  888. #if MICROSOFT || TURBO || BORLAND_286 || BORLAND_386
  889.       execvp(iconxloc,argv);    /* execute with path search */
  890. #endif                    /* MICROSOFT || ... */
  891.  
  892. #if INTEL_386 || ZTC_386 || HIGHC_386 || WATCOM || SCCX_MX
  893.       fprintf(stderr,"-x not supported\n");
  894.       fflush(stderr);
  895. #endif                    /* INTEL_386 || ... */
  896.  
  897. #endif                    /* MSDOS */
  898.  
  899. #if MVS || VM
  900. #if SASC
  901.       exit(sysexec(iconxloc, argv));
  902. #endif                    /* SASC */
  903.       fprintf(stderr,"-x not supported\n");
  904.       fflush(stderr);
  905. #endif                                  /* MVS || VM */
  906.  
  907. #if OS2
  908. #ifdef PresentationManager
  909.       fputs("-x not supported\n", stderr);
  910. #else                    /* PresentationManager */
  911.       execvp(iconxloc,argv);    /* execute with path search */
  912. #endif                    /* PresentationManager */
  913. #endif                    /* OS2 */
  914.  
  915. #if UNIX
  916.       /*
  917.        * If an ICONX environment variable is defined, use that.
  918.        *  If not, first try the predefined path, then search $PATH via execvp. 
  919.        */
  920.       if ((argv[0] = getenv("ICONX")) != NULL && argv[0][0] != '\0') {
  921.          execv(argv[0], argv);    /* exec file specified by $ICONX */
  922.          quitf("cannot execute $ICONX (%s)", argv[0]);
  923.          }
  924.  
  925. #ifdef HardWiredPaths
  926. #ifdef CRAY
  927.       argv[0] = "iconx";
  928.       execv(iconxloc, argv);
  929. #else                    /* CRAY */
  930.       argv[0] = iconxloc;        /* try predefined file */
  931.       execv(argv[0], argv);
  932. #endif                    /* CRAY */
  933. #endif                    /* HardWiredPaths */
  934.  
  935.       argv[0] = "iconx";
  936.       execvp(argv[0], argv);    /* if no iconxloc, search path for "iconx" */
  937.  
  938. #ifdef HardWiredPaths
  939.       quitf("cannot run %s", iconxloc);
  940. #else                    /* HardWiredPaths */
  941.       quitf("cannot find iconx", "");
  942. #endif                    /* HardWiredPaths */
  943. #endif                    /* UNIX */
  944.  
  945. #if VMS
  946.       execv(iconxloc,argv);
  947. #endif                    /* VMS */
  948.  
  949. /*
  950.  * End of operating-system specific code.
  951.  */
  952.  
  953.    quitf("could not run %s",iconxloc);
  954.  
  955. #else                    /* !(MACINTOSH && MPW) */
  956.    printf("-x not supported\n");
  957. #endif                    /* !(MACINZTOSH && MPW) */
  958.  
  959.    }
  960.  
  961. static novalue report(s)
  962. char *s;
  963.    {
  964.  
  965.    fprintf(stderr,"%s:\n",s);
  966.  
  967.    }
  968.  
  969. /*
  970.  * rmfiles - remove a list of files
  971.  */
  972.  
  973. static novalue rmfiles(p)
  974. char **p;
  975.    {
  976.    for (; *p; p++) {
  977.       unlink(*p);
  978.       }
  979.    }
  980.  
  981. /*
  982.  * Print an error message if called incorrectly.  The message depends
  983.  *  on the legal options for this system.
  984.  */
  985. static novalue usage()
  986.    {
  987.  
  988. #if MVS || VM
  989.    fprintf(stderr,"usage: %s %s file ... <-x args>\n", progname, TUsage);
  990. #elif MPW
  991.    fprintf(stderr,"usage: %s %s file ...\n", progname, TUsage);
  992. #else
  993.    fprintf(stderr,"usage: %s %s file ... [-x args]\n", progname, TUsage);
  994. #endif
  995.  
  996.    exit(ErrorExit);
  997.    }
  998.  
  999.  
  1000. #if MACINTOSH
  1001. #if THINK_C
  1002.  
  1003. /*
  1004.  * IncreaseStackSize - increases stack size by extraBytes
  1005.  */
  1006. void IncreaseStackSize (Size extraBytes)
  1007. {
  1008.    SetApplLimit ( GetApplLimit() - extraBytes );
  1009. }
  1010.  
  1011. /*
  1012.  * ToolBoxInit - initializes mac toolbox
  1013.  */
  1014. void ToolBoxInit ( void )
  1015. {
  1016.    InitGraf ( &qd.thePort );
  1017.    InitFonts ();
  1018.    InitWindows ();
  1019.    InitMenus ();
  1020.    TEInit ();
  1021.    InitDialogs ( nil );
  1022.    InitCursor ();
  1023. }
  1024.  
  1025. /*-------------- code for display graphics ----------------------*/
  1026.  
  1027. /*
  1028.  * DoEvent - handles AppleEvent by passing eventPtr to AEProcessAppleEvent
  1029.  *           Command-Q key sequence results exit of the program
  1030.  */
  1031. void DoEvent ( EventRecord *eventPtr )
  1032. {
  1033.    char theChar;
  1034.    
  1035.    switch ( eventPtr->what )
  1036.    {
  1037.       case mouseDown:        DoMouseDown (eventPtr);
  1038.                              break;
  1039. /*
  1040.       case kHighLevelEvent : AEProcessAppleEvent ( eventPtr );
  1041.                              break;
  1042.  */
  1043.       case keyDown:
  1044.       case autoKey:          theChar = eventPtr->message & charCodeMask;
  1045.                              if ( (eventPtr->modifiers & cmdKey) != 0)
  1046.                                 HandleMenuChoice (MenuKey (theChar));
  1047.                              break;
  1048.    }
  1049. }
  1050.  
  1051. /*
  1052.  * DoMouseDown -
  1053.  */
  1054. void DoMouseDown (EventRecord *eventPtr)
  1055. {
  1056.    WindowPtr whichWindow;
  1057.    short thePart;
  1058.    long menuChoice;
  1059.    
  1060.    thePart = FindWindow (eventPtr->where, &whichWindow);
  1061.    switch (thePart) {
  1062.       case inMenuBar:
  1063.          menuChoice = MenuSelect (eventPtr->where);
  1064.          HandleMenuChoice (menuChoice);
  1065.          break;
  1066.       }
  1067. }
  1068.  
  1069. /*
  1070.  * HandleMenuChoice -
  1071.  */
  1072. void HandleMenuChoice (long menuChoice)
  1073. {
  1074.    short menu;
  1075.    short item;
  1076.    
  1077.    if (menuChoice != 0) {
  1078.       menu = HiWord (menuChoice);
  1079.       item = LoWord (menuChoice);
  1080.       
  1081.       switch (menu) {
  1082.          case kAppleMenu:
  1083.             HandleAppleChoice (item);
  1084.             break;
  1085.          case kFileMenu:
  1086.             HandleFileChoice (item);
  1087.             break;
  1088.          case kOptionsMenu:
  1089.             HandleOptionsChoice (item);
  1090.             break;
  1091.          }
  1092.       HiliteMenu (0);
  1093.       }
  1094. }
  1095.  
  1096. void HandleAppleChoice (short item)
  1097. {
  1098.    MenuHandle  appleMenu;
  1099.    Str255      accName;
  1100.    short       accNumber;
  1101.    
  1102.    switch (item) {
  1103.       case kAboutMItem:
  1104.          SysBeep (20);
  1105.          break;
  1106.          /* ******************* open a dialog box **************** */
  1107.       default:
  1108.          appleMenu = GetMHandle (kAppleMenu);
  1109.          GetItem (appleMenu, item, accName);
  1110.          accNumber = OpenDeskAcc (accName);
  1111.          break;
  1112.       }
  1113. }
  1114.  
  1115. void HandleFileChoice (short item)
  1116. {
  1117.    StandardFileReply fileReply;
  1118.    SFTypeList typeList;
  1119.    short numTypes;
  1120.    char *fileName;
  1121.    int argc;
  1122.    char **argv;
  1123.    MenuHandle menu;
  1124.    
  1125.    switch (item) {
  1126.       case kQuitMItem:
  1127.          gDone = true;
  1128.          abort ();
  1129.          break;
  1130.       case kCompileMItem:
  1131.          typeList[0] = 'TEXT';
  1132.          numTypes = 1;
  1133.          StandardGetFile (nil, numTypes, typeList, &fileReply);
  1134.          if (fileReply.sfGood) {
  1135.             fileName = PtoCstr (fileReply.sfFile.name);
  1136.             menu = GetMHandle (kFileMenu);
  1137.             DisableItem (menu, kCompileMItem);
  1138.             menu = GetMHandle (kOptionsMenu);
  1139.             DisableItem (menu, 0);
  1140.             }
  1141.          else
  1142.             break;
  1143.             
  1144.          if (g_cOption) 
  1145.             argc = 3;
  1146.          else 
  1147.             argc = 2;
  1148.    
  1149.          argv = malloc (sizeof (*argv) * argc);
  1150.          argv[0] = malloc (strlen ("ICONT") + 1);
  1151.          strcpy (argv[0], "ICONT");
  1152.          
  1153.          if (g_cOption) {
  1154.             argv[1] = malloc (strlen ("-c") + 1);
  1155.             strcpy (argv[1], "-c");
  1156.             }
  1157.          
  1158.          argv[argc-1] = malloc (strlen(fileName) + 1);
  1159.          strcpy (argv[argc-1], fileName);
  1160.          
  1161.          MacMain (argc, argv);
  1162.          break;
  1163.       }
  1164. }
  1165.  
  1166. void HandleOptionsChoice (short item)
  1167. {
  1168.    MenuHandle menu;
  1169.    
  1170.    switch (item) {
  1171.       case k_cMItem:
  1172.          g_cOption = !g_cOption;
  1173.          menu = GetMHandle (kOptionsMenu);
  1174.          CheckItem (menu, item, g_cOption);
  1175.          break;
  1176.       }
  1177. }
  1178.  
  1179. /*------------------  End of display graphics code ------------------------*/
  1180.  
  1181. void MenuBarInit (void)
  1182. {
  1183.    Handle         menuBar;
  1184.    MenuHandle     menu;
  1185.    OSErr          myErr;
  1186.    long           feature;
  1187.    
  1188.    g_cOption = false;
  1189.    
  1190.    menuBar = GetNewMBar (kMenuBar);
  1191.    SetMenuBar (menuBar);
  1192.    
  1193.    menu = GetMHandle (kAppleMenu);
  1194.    AddResMenu (menu, 'DRVR');
  1195.    
  1196.    menu = GetMHandle (kOptionsMenu);
  1197.    CheckItem (menu, k_cMItem, g_cOption);
  1198.    
  1199.    DrawMenuBar ();
  1200. }
  1201.  
  1202. /*
  1203.  * EventInit - calls Gestalt to check if AppleEvent is available, if so,
  1204.  *   install OpenDocument and QuitApplication handler routines
  1205.  */
  1206. void EventInit ( void )
  1207. {
  1208.    OSErr err;
  1209.    long  feature;
  1210.    
  1211.    err = Gestalt ( gestaltAppleEventsAttr, &feature );
  1212.    
  1213.    if ( err != noErr ) {
  1214.       printf ("Problem in calling Gestalt.");
  1215.       return;
  1216.       }
  1217.    else {
  1218.       if ( ! ( feature & (kGestaltMask << gestaltAppleEventsPresent ) ) ) {
  1219.          printf ("Apple events not available!");
  1220.          return;
  1221.          }
  1222.       }
  1223.    
  1224.    err = AEInstallEventHandler (kCoreEventClass,
  1225.                                 kAEOpenDocuments,
  1226.             (AEEventHandlerUPP)   DoOpenDoc,
  1227.                                 0L,
  1228.                                 false );
  1229.                                 
  1230.    if ( err != noErr )
  1231.       printf ("kAEOpenDocuments Apple Event not available!");
  1232.    
  1233.    err = AEInstallEventHandler (kCoreEventClass,
  1234.                                 kAEQuitApplication,
  1235.              (AEEventHandlerUPP)  DoQuitApp,
  1236.                                 0L,
  1237.                                 false );
  1238.    if ( err != noErr )
  1239.       printf ("kAEQuitApplication Apple Event not available!");
  1240. }
  1241.  
  1242. /*
  1243.  * EventLoop - waits for an event to be processed
  1244.  */
  1245. void EventLoop ( void )
  1246. {
  1247.    EventRecord event;
  1248.    
  1249.    gDone = false;
  1250.    while ( gDone == false ) {
  1251.       if ( WaitNextEvent ( everyEvent, &event, kSleep, nil ) )
  1252.          DoEvent ( &event );
  1253.       }
  1254. }
  1255.  
  1256. /*
  1257.  * DoOpenDoc - called by AEProcessAppleEvent (a ToolBox routine)
  1258.  *
  1259.  *    Calls AECountItems to retrieve number of files is to be processed
  1260.  *    and enters a loop to process each file.  Sets gDone to true
  1261.  *    to terminate program.
  1262.  */
  1263. pascal OSErr DoOpenDoc ( AppleEvent theAppleEvent,
  1264.                          AppleEvent reply,
  1265.                                long refCon )
  1266. {
  1267.    AEDescList fileSpecList;
  1268.    FSSpec     file;
  1269.    OSErr      err;
  1270.    DescType   type;
  1271.    Size       actual;
  1272.    long       count;
  1273.    AEKeyword  keyword;
  1274.    long       i;
  1275.    
  1276.    int        argc;
  1277.    char       **argv;
  1278.    
  1279.    char       *fileName;
  1280.    
  1281.    err = AEGetParamDesc ( &theAppleEvent,
  1282.                           keyDirectObject,
  1283.                           typeAEList,
  1284.                           &fileSpecList );
  1285.    if ( err != noErr ) {
  1286.       printf ("Error AEGetParamDesc");
  1287.       return ( err );
  1288.       }
  1289.    
  1290.    err = GotRequiredParams ( &theAppleEvent );
  1291.    if ( err != noErr ) {
  1292.       printf ("Error GotRequiredParams");
  1293.       return ( err );
  1294.       }
  1295.    
  1296.    err = AECountItems ( &fileSpecList, &count );
  1297.    if ( err != noErr ) {
  1298.       printf ("Error AECountItems");
  1299.       return ( err );
  1300.       }
  1301.  
  1302.    argc = count + 1;
  1303.    argv = malloc (sizeof (*argv) * (argc + 1));
  1304.    argv[0] = malloc (strlen("ICONT") + 1);
  1305.    strcpy (argv[0], "ICONT");
  1306.    
  1307.    for ( i = 1; i <= count; i++ ) {
  1308.       err = AEGetNthPtr ( &fileSpecList,
  1309.                           i,
  1310.                           typeFSS,
  1311.                           &keyword,
  1312.                           &type,
  1313.                           (Ptr) &file,
  1314.                           sizeof (FSSpec),
  1315.                           &actual );
  1316.       if ( err != noErr ) {
  1317.          printf ("Error AEGetNthPtr");
  1318.          return ( err );
  1319.      }
  1320.       
  1321.       fileName = PtoCstr (file.name);
  1322.       argv[i] = malloc(strlen(fileName) + 1);
  1323.       strcpy (argv[i], fileName);
  1324.       }
  1325.    MacMain (argc, argv);
  1326.    gDone = true;
  1327.    return ( noErr );
  1328. }
  1329.  
  1330. /*
  1331.  * DoQuitApp - called by AEProcessAppleEvent (a ToolBox routine)
  1332.  *             sets gDone to true to terminate program
  1333.  */
  1334. pascal OSErr DoQuitApp ( AppleEvent theAppleEvent,
  1335.                          AppleEvent reply,
  1336.                                long refCon )
  1337. {
  1338.    OSErr err = noErr;
  1339.    gDone = true;
  1340.    return err;
  1341. }                               
  1342.  
  1343. /*
  1344.  * GotRequiredParams - check if all required parameters are retrieved
  1345.  */
  1346. OSErr GotRequiredParams ( AppleEvent *appleEventPtr )
  1347. {
  1348.    DescType returnedType;
  1349.    Size     actualSize;
  1350.    OSErr    err;
  1351.  
  1352.    err = AEGetAttributePtr ( appleEventPtr,
  1353.                              keyMissedKeywordAttr,
  1354.                              typeWildCard,
  1355.                              &returnedType,
  1356.                              nil,
  1357.                              0,
  1358.                              &actualSize );
  1359.    if ( err == errAEDescNotFound )
  1360.       return noErr;
  1361.    else
  1362.       if (err == noErr )
  1363.          return errAEEventNotHandled;
  1364.       else
  1365.          return err;
  1366. }
  1367.  
  1368. #endif               /* THINK_C */
  1369. #endif               /* MACINTOSH */
  1370.