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 / icont / twindows.c < prev    next >
C/C++ Source or Header  |  2001-12-12  |  20KB  |  749 lines

  1. /*
  2.  * twindows.c - main program for translator and linker under Windows.
  3.  *
  4.  * THIS FILE IS UNTESTED.
  5.  *
  6.  * It is file is based on the old tmain.c from Icon 9.3.2, but it
  7.  * HAS NOT BEEN TESTED and probably needs some additional work.
  8.  */
  9.  
  10. #include "../h/gsupport.h"
  11. #include "tproto.h"
  12.  
  13. #if SCCX_MX
  14.    #include "../h/filepat.h"
  15.    /* This sets the stack size so it runs in a Windows DOS box */
  16.    unsigned _stack = 100000;
  17. #endif      /* SCCX_MX */
  18.  
  19. #ifdef MSWindows
  20.    #ifdef NTConsole
  21.       #define int_PASCAL int PASCAL
  22.       #define LRESULT_CALLBACK LRESULT CALLBACK
  23.       #include <windows.h>
  24.       #include "../h/filepat.h"
  25.    #endif                /* NTConsole */
  26. #endif                    /* MSWindows */
  27.  
  28. #if WildCards
  29.    #ifndef ConsoleWindow
  30.       #include "../h/filepat.h"
  31.    #endif                /* ConsoleWindow */
  32. #endif                    /* WildCards */
  33.  
  34. /*
  35.  * Prototypes.
  36.  */
  37.  
  38. static    void    execute    (char *ofile,char *efile,char * *args);
  39. static    void    rmfiles (char **p);
  40. static    void    usage (void);
  41.  
  42. #if MSDOS
  43.    char pathToIconDOS[129];
  44. #endif                    /* MSDOS */
  45.  
  46. /*
  47.  *  Define global variables.
  48.  */
  49.  
  50. #define Global
  51. #define Init(v) = v
  52. #include "tglobals.h"
  53.  
  54. char *ofile = NULL;            /* linker output file name */
  55.  
  56. char patchpath[MaxPath+18] = "%PatchStringHere->";
  57.  
  58. char *refpath = RefPath;
  59.  
  60. /*
  61.  * getopt() variables
  62.  */
  63. extern int optind;        /* index into parent argv vector */
  64. extern int optopt;        /* character checked for validity */
  65. extern char *optarg;        /* argument associated with option */
  66.  
  67. #ifdef ConsoleWindow
  68.    int ConsolePause = 1;
  69. #endif                    /* ConsoleWindow */
  70.  
  71. #ifdef ConsoleWindow
  72. /*
  73.  * expand Icon project (.icp) files
  74.  */
  75. void expand_proj(int *argc, char ***argv)
  76. {
  77.    int ac = *argc, i, j, k;
  78.    char **av = *argv, buf[1024];
  79.    FILE *f;
  80.    for (i=1; i<ac; i++) {
  81.       if (strstr(av[i], ".ICP") || strstr(av[i], ".icp")) break;
  82.       }
  83.    if (i == ac) return;
  84.    if ((f = fopen(av[i], "r")) == NULL) {
  85.       fprintf(stderr, "icont: can't open %s\n", av[i]);
  86.       fflush(stderr);
  87.       return;
  88.       }
  89.    if ((*argv = malloc(ac * sizeof (char *))) == NULL) {
  90.       fprintf(stderr, "icont: can't malloc for %s\n", av[i]);
  91.       fflush(stderr);
  92.       return;
  93.       }
  94.    for(j=0; j<i; j++) (*argv)[j] = av[j];
  95.    k = j++;
  96.    if(fgets(buf, 1023, f) != NULL) {
  97.       if (strchr(buf, '\n') != NULL)
  98.          buf[strlen(buf)-1] = '\0';
  99.       (*argv)[k++] = salloc(buf);
  100.       while(fgets(buf, 1023, f) != NULL) {
  101.          if (strchr(buf, '\n') != NULL)
  102.             buf[strlen(buf)-1] = '\0';
  103.          (*argc)++;
  104.          if ((*argv = realloc(*argv, *argc * sizeof (char *))) == NULL) {
  105.             fprintf(stderr, "icont: can't malloc for %s\n", av[i]);
  106.             fflush(stderr);
  107.             return;
  108.             }
  109.          (*argv)[k++] = salloc(buf);
  110.          }
  111.       }
  112.    fclose(f);
  113.    for( ; j < ac; j++, k++) (*argv)[k] = av[j];
  114. }
  115. #endif                    /* ConsoleWindow */
  116.  
  117. #ifndef NTConsole
  118. #ifdef MSWindows
  119. void icont(int argc, char **argv);
  120. #define int_PASCAL int PASCAL
  121. #define LRESULT_CALLBACK LRESULT CALLBACK
  122. #undef lstrlen
  123. #include <windows.h>
  124. #define lstrlen longstrlen
  125. #include "../wincap/dibutil.h"
  126.  
  127. int CmdParamToArgv(char *s, char ***avp)
  128.    {
  129.    char tmp[MaxPath], dir[MaxPath];
  130.    char *t, *t2;
  131.    int rv=0, i;
  132.    FILE *f;
  133.    t = salloc(s);
  134.    t2 = t;
  135.    *avp = malloc(2 * sizeof(char *));
  136.    (*avp)[rv] = NULL;
  137.  
  138.    while (*t2) {
  139.       while (*t2 && isspace(*t2)) t2++;
  140.       switch (*t2) {
  141.      case '\0': break;
  142.      case '"': {
  143.         char *t3 = ++t2;            /* skip " */
  144.             while (*t2 && (*t2 != '"')) t2++;
  145.             if (*t2)
  146.            *t2++ = '\0';
  147.         *avp = realloc(*avp, (rv + 2) * sizeof (char *));
  148.         (*avp)[rv++] = salloc(t3);
  149.             (*avp)[rv] = NULL;
  150.         break;
  151.         }
  152.          default: {
  153.             FINDDATA_T fd;
  154.         char *t3 = t2;
  155.             while (*t2 && !isspace(*t2)) t2++;
  156.         if (*t2)
  157.            *t2++ = '\0';
  158.             strcpy(tmp, t3);
  159.         if (!FINDFIRST(tmp, &fd)) {
  160.            *avp = realloc(*avp, (rv + 2) * sizeof (char *));
  161.            (*avp)[rv++] = salloc(t3);
  162.                (*avp)[rv] = NULL;
  163.                }
  164.         else {
  165.                int end;
  166.                strcpy(dir, t3);
  167.            do {
  168.               end = strlen(dir)-1;
  169.               while (end >= 0 && dir[end] != '\\' && dir[end] != '/' &&
  170.             dir[end] != ':') {
  171.                      dir[end] = '\0';
  172.              end--;
  173.                  }
  174.           strcat(dir, FILENAME(&fd));
  175.               *avp = realloc(*avp, (rv + 2) * sizeof (char *));
  176.               (*avp)[rv++] = salloc(dir);
  177.                   (*avp)[rv] = NULL;
  178.               } while (FINDNEXT(&fd));
  179.            FINDCLOSE(&fd);
  180.            }
  181.             break;
  182.         }
  183.          }
  184.       }
  185.    free(t);
  186.    return rv;
  187.    }
  188.  
  189. LRESULT_CALLBACK WndProc    (HWND, UINT, WPARAM, LPARAM);
  190. char *lognam;
  191. char tmplognam[128];
  192. extern FILE *flog;
  193.  
  194. void MSStartup(int argc, char **argv, HINSTANCE hInstance, HINSTANCE hPrevInstance)
  195.    {
  196.    WNDCLASS wc;
  197.  
  198.    /*
  199.     * Select log file name.  Might make this a command-line option.
  200.     * Default to "WICON.LOG".  The log file is used by Wi to report
  201.     * translation errors and jump to the offending source code line.
  202.     */
  203.    if ((lognam = getenv("WICONLOG")) == NULL)
  204.       lognam = "WICON.LOG";
  205.    if (flog = fopen(lognam, "r")) {
  206.       fclose(flog);
  207.       flog = NULL;
  208.       remove(lognam);
  209.       }
  210.    lognam = strdup(lognam);
  211.    flog = fopen(tmpnam(tmplognam), "w");
  212.    if (flog == NULL) {
  213.       fprintf(stderr, "unable to open logfile");
  214.       exit(EXIT_FAILURE);
  215.       }
  216.  
  217.    if (!hPrevInstance) {
  218. #if NT
  219.       wc.style = CS_HREDRAW | CS_VREDRAW;
  220. #else                    /* NT */
  221.       wc.style = 0;
  222. #endif                    /* NT */
  223. #ifdef NTConsole
  224.       wc.lpfnWndProc = DefWindowProc;
  225. #else                    /* NTConsole */
  226.       wc.lpfnWndProc = WndProc;
  227. #endif                    /* NTConsole */
  228.       wc.cbClsExtra = 0;
  229.       wc.cbWndExtra = 0;
  230.       wc.hInstance  = hInstance;
  231.       wc.hIcon      = NULL;
  232.       wc.hCursor    = LoadCursor(NULL, IDC_ARROW);
  233.       wc.hbrBackground = GetStockObject(WHITE_BRUSH);
  234.       wc.lpszMenuName = NULL;
  235.       wc.lpszClassName = "iconx";
  236.       RegisterClass(&wc);
  237.       }
  238.    }
  239.  
  240. HANDLE mswinInstance;
  241. int ncmdShow;
  242.  
  243. jmp_buf mark_sj;
  244.  
  245. int_PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
  246.                    LPSTR lpszCmdParam, int nCmdShow)
  247.    {
  248.    int argc;
  249.    char **argv;
  250.  
  251.    mswinInstance = hInstance;
  252.    ncmdShow = nCmdShow;
  253.    argc = CmdParamToArgv(GetCommandLine(), &argv);
  254.    MSStartup(argc, argv, hInstance, hPrevInstance);
  255. #if BORLAND_286
  256.    _InitEasyWin();
  257. #endif                    /* BORLAND_286 */
  258.    if (setjmp(mark_sj) == 0)
  259.       icont(argc,argv);
  260.    while (--argc>=0)
  261.       free(argv[argc]);
  262.    free(argv);
  263.    wfreersc();
  264.    return 0;
  265. }
  266.  
  267. #define main icont
  268. #endif                    /* MSWindows */
  269. #endif                    /* NTConsole */
  270.  
  271. /*
  272.  *  main program
  273.  */
  274. int main(argc, argv)
  275. int argc;
  276. char **argv;
  277.    {
  278.    int nolink = 0;            /* suppress linking? */
  279.    int errors = 0;            /* translator and linker errors */
  280.    char **tfiles, **tptr;        /* list of files to translate */
  281.    char **lfiles, **lptr;        /* list of files to link */
  282.    char **rfiles, **rptr;        /* list of files to remove */
  283.    char *efile = NULL;            /* stderr file */
  284.    char buf[MaxFileName];        /* file name construction buffer */
  285.    int c, n;
  286.    char ch;
  287.    struct fileparts *fp;
  288.  
  289. #if WildCards
  290.    FINDDATA_T fd;
  291.    int j;
  292. #endif                    /* WildCards */
  293.  
  294.    if ((int)strlen(patchpath) > 18)
  295.       iconxloc = patchpath+18;
  296.    else {
  297.       iconxloc = (char *)alloc((unsigned)strlen(refpath) + 8);
  298.       strcpy(iconxloc, refpath);
  299. #if NT
  300. #ifdef MSWindows
  301.       strcat(iconxloc, "w");        /* wiconx */
  302. #else                    /* MSWindows */
  303.       strcat(iconxloc, "nt");        /* nticonx */
  304. #endif                    /* MSWindows */
  305. #endif                    /* NT */
  306.       strcat(iconxloc, "iconx");
  307.       }
  308.  
  309. #ifdef ConsoleWindow
  310.    if ((int)strlen(patchpath) <= 18) {
  311.       free(iconxloc);
  312.       iconxloc = (char *)alloc((unsigned)strlen(refpath) + 7);
  313.       strcpy(iconxloc, refpath);
  314.       strcat(iconxloc, "wiconx");
  315.       }
  316.    expand_proj(&argc, &argv);
  317. #endif                    /* ConsoleWindow */
  318.  
  319.    /*
  320.     * Process options.
  321.     */
  322.    while ((c = getopt(argc,argv,IconOptions)) != EOF)
  323.       switch (c) {
  324.          case 'C':            /* Ignore: compiler only */
  325.             break;
  326.          case 'E':            /* -E: preprocess only */
  327.         pponly = 1;
  328.         nolink = 1;
  329.             break;
  330.  
  331.          case 'L':            /* -L: enable linker debugging */
  332. #ifdef DeBugLinker
  333.             Dflag = 1;
  334. #endif                    /* DeBugLinker */
  335.             break;
  336.  
  337.          case 'S':            /* -S */
  338.             fprintf(stderr, "Warning, -S option is obsolete\n");
  339.             break;
  340.  
  341. #if MSDOS
  342.          case 'X':            /* -X */
  343. #if ZTC_386
  344.             fprintf(stderr, "Warning: -X option is not available\n");
  345. #else                    /* ZTC_386 */
  346.             makeExe = 1;
  347. #endif                    /* ZTC_386 */
  348.             break;
  349.          case 'I':            /* -C */
  350.             makeExe = 0;
  351.             break;
  352. #ifdef SCCX_MX
  353.          case 'A':
  354.             makeExe = 2;
  355.             break;
  356. #endif                  /* SCCX_MX */
  357. #endif                    /* MSDOS */
  358.  
  359.          case 'c':            /* -c: compile only (no linking) */
  360.             nolink = 1;
  361.             break;
  362.          case 'e':            /* -e file: redirect stderr */
  363.             efile = optarg;
  364.             break;
  365.          case 'f':            /* -f features: enable features */
  366.             if (strchr(optarg, 's') || strchr(optarg, 'a'))
  367.                strinv = 1;        /* this is the only icont feature */
  368.             break;
  369.          case 'n':            /* Ignore: compiler only */
  370.             break;
  371.          case 'o':            /* -o file: name output file */
  372.             ofile = optarg;
  373.             break;
  374.  
  375. #ifdef ConsoleWindow
  376.      case 'q':
  377.         ConsolePause = 0;
  378.         break;
  379. #endif                    /* ConsoleWindow */
  380.  
  381.          case 'r':            /* Ignore: compiler only */
  382.             break;
  383.          case 's':            /* -s: suppress informative messages */
  384.             silent = 1;
  385.             verbose = 0;
  386.             break;
  387.          case 't':            /* -t: turn on procedure tracing */
  388.             trace = -1;
  389.             break;
  390.          case 'u':            /* -u: warn about undeclared ids */
  391.             uwarn = 1;
  392.             break;
  393.          case 'v':            /* -v n: set verbosity level */
  394.             if (sscanf(optarg, "%d%c", &verbose, &ch) != 1)
  395.                quitf("bad operand to -v option: %s",optarg);
  396.             if (verbose == 0)
  397.                silent = 1;
  398.             break;
  399.          default:
  400.          case 'x':            /* -x illegal until after file list */
  401.             usage();
  402.          }
  403.  
  404. #if MSDOS && !NT
  405.       /*
  406.        * Define pathToIconDOS as a global accessible from inside
  407.        * separately-compiled compilation units.
  408.        */
  409.       if( makeExe ){
  410.          char *pathCursor;
  411.  
  412.          strcpy (pathToIconDOS, argv[0]);
  413.          pathCursor = (char *)strrchr (pathToIconDOS, '\\');
  414.          if (!pathCursor) {
  415.             fprintf (stderr,
  416.                "Can't understand what directory icont was run from.\n");
  417.             exit(EXIT_FAILURE);
  418.             }
  419.             strcpy( ++pathCursor, (makeExe==1) ?  "ixhdr.exe" : "iconx.exe");
  420.          }
  421. #endif                                  /* MSDOS && !NT */
  422.  
  423.    /*
  424.     * Allocate space for lists of file names.
  425.     */
  426.    n = argc - optind + 1;
  427.  
  428. #if WildCards
  429.    {
  430.    for(j=optind; j < argc; j++) {
  431.       if (FINDFIRST(argv[j], &fd))
  432.          while(FINDNEXT(&fd)) n++;
  433.       FINDCLOSE(&fd);
  434.       }
  435.    }
  436. #endif                    /* WildCards */
  437.  
  438.    tptr = tfiles = (char **)alloc((unsigned int)(n * sizeof(char *)));
  439.    lptr = lfiles = (char **)alloc((unsigned int)(n * sizeof(char *)));
  440.    rptr = rfiles = (char **)alloc((unsigned int)(2 * n * sizeof(char *)));
  441.  
  442.    /*
  443.     * Scan file name arguments.
  444.     */
  445.    while (optind < argc)  {
  446.       if (strcmp(argv[optind],"-x") == 0)    /* stop at -x */
  447.          break;
  448.       else if (strcmp(argv[optind],"-") == 0) {
  449.          *tptr++ = "-";                /* "-" means standard input */
  450.          *lptr++ = *rptr++ = "stdin.u1";
  451.          *rptr++ = "stdin.u2";
  452.          }
  453.       else {
  454. #if WildCards
  455.      char tmp[MaxPath], dir[MaxPath];
  456.          int matches = 0;
  457.  
  458.      fp = fparse(argv[optind]);
  459.      /* Save because *fp will get overwritten frequently */
  460.      strcpy(dir, fp->dir);
  461.      if (*fp->ext == '\0')
  462.         makename(tmp,NULL,argv[optind], SourceSuffix);
  463.      else
  464.         strcpy(tmp, argv[optind]);
  465.  
  466.      if (strchr(tmp, '*') || strchr(tmp, '?')) {
  467.         if (!FINDFIRST(tmp, &fd)) {
  468.            fprintf(stderr, "File %s: no match\n", tmp);
  469.            fflush(stderr);
  470.            }
  471.         else matches = 1;
  472.         }
  473.          do {
  474.      if (matches) {
  475.         makename(tmp,dir,FILENAME(&fd),NULL);
  476.         argv[optind] = tmp;
  477.         }
  478. #endif                    /* WildCards */
  479.          fp = fparse(argv[optind]);        /* parse file name */
  480.          if (*fp->ext == '\0' || smatch(fp->ext, SourceSuffix)) {
  481.             makename(buf,SourceDir,argv[optind], SourceSuffix);
  482.             *tptr++ = salloc(buf);        /* translate the .icn file */
  483.             makename(buf,TargetDir,argv[optind],U1Suffix);
  484.             *lptr++ = *rptr++ = salloc(buf);    /* link & remove .u1 */
  485.             makename(buf,TargetDir,argv[optind],U2Suffix);
  486.             *rptr++ = salloc(buf);        /* also remove .u2 */
  487.             }
  488.          else if (smatch(fp->ext,U1Suffix) || smatch(fp->ext,U2Suffix)
  489.                || smatch(fp->ext,USuffix)) {
  490.             makename(buf,TargetDir,argv[optind],U1Suffix);
  491.             *lptr++ = salloc(buf);
  492.             }
  493.          else
  494.             quitf("bad argument %s",argv[optind]);
  495. #if WildCards
  496.      if (!matches)
  497.         break;
  498.          } while (FINDNEXT(&fd));
  499.      if (matches)
  500.      FINDCLOSE(&fd);
  501. #endif                    /* WildCards */
  502.          }
  503.       optind++;
  504.       }
  505.  
  506.    *tptr = *lptr = *rptr = NULL;    /* terminate filename lists */
  507.    if (lptr == lfiles)
  508.       usage();                /* error -- no files named */
  509.  
  510.    /*
  511.     * Initialize globals.
  512.     */
  513.    initglob();
  514.  
  515.    /*
  516.     * Translate .icn files to make .u1 and .u2 files.
  517.     */
  518.    if (tptr > tfiles) {
  519.       if (!pponly)
  520.          report("Translating");
  521.       errors = trans(tfiles, TargetDir);
  522.       if (errors > 0) {            /* exit if errors seen */
  523.          exit(EXIT_FAILURE);
  524.      }
  525.       }
  526.  
  527.    /*
  528.     * Link .u1 and .u2 files to make an executable.
  529.     */
  530.    if (nolink) {            /* exit if no linking wanted */
  531.       exit(EXIT_SUCCESS);
  532.       }
  533.  
  534. #if MSDOS
  535.  
  536. #if NT
  537.    {
  538.    if (ofile == NULL)  {                /* if no -o file, synthesize a name */
  539.       ofile = salloc(makename(buf,TargetDir,lfiles[0],
  540.                               makeExe ? ".exe" : IcodeSuffix));
  541.       }
  542.    else {                             /* add extension if necessary */
  543.       fp = fparse(ofile);
  544.       if (*fp->ext == '\0' && *IcodeSuffix != '\0') /* if no ext given */
  545.          ofile = salloc(makename(buf,NULL,ofile,
  546.                                  makeExe ? ".exe" : IcodeSuffix));
  547.       }
  548.    }
  549. #else                    /* NT */
  550.    if (ofile == NULL)  {                /* if no -o file, synthesize a name */
  551.       ofile = salloc(makename(buf,TargetDir,lfiles[0],
  552.                               makeExe ? ".Exe" : IcodeSuffix));
  553.       }
  554.    else {                             /* add extension if necessary */
  555.       fp = fparse(ofile);
  556.       if (*fp->ext == '\0' && *IcodeSuffix != '\0') /* if no ext given */
  557.          ofile = salloc(makename(buf,NULL,ofile,
  558.                                  makeExe ? ".Exe" : IcodeSuffix));
  559.    }
  560. #endif                    /* NT */
  561.  
  562. #else                                   /* MSDOS */
  563.  
  564.    if (ofile == NULL)  {        /* if no -o file, synthesize a name */
  565.       ofile = salloc(makename(buf,TargetDir,lfiles[0],IcodeSuffix));
  566.    } else {                /* add extension in necessary */
  567.       fp = fparse(ofile);
  568.       if (*fp->ext == '\0' && *IcodeSuffix != '\0') /* if no ext given */
  569.          ofile = salloc(makename(buf,NULL,ofile,IcodeSuffix));
  570.    }
  571.  
  572. #endif                    /* MSDOS */
  573.  
  574.    report("Linking");
  575.    errors = ilink(lfiles,ofile);    /* link .u files to make icode file */
  576.  
  577. #if NT
  578.    if (!stricmp(".exe", ofile+strlen(ofile)-4)) {
  579.       FILE *f, *f2;
  580.       char tmp[MaxPath], tmp2[MaxPath];
  581.       /* if we generated a .exe, we need to rename it and then prepend wiconx
  582.        */
  583.       strcpy(tmp, ofile);
  584.       strcpy(tmp+strlen(tmp)-4, ".bat");
  585.       rename(ofile, tmp);
  586. #ifdef MSWindows
  587.       if ((f = pathOpen("wiconx.exe", ReadBinary)) == NULL) {
  588.      report("Tried to open wiconx to build .exe, but couldn't\n");
  589.          errors++;
  590.          }
  591. #else                    /* MS Windows */
  592.       if ((f = pathOpen("nticonx.exe", ReadBinary)) == NULL) {
  593.      report("Tried to open wiconx to build .exe, but couldn't\n");
  594.      errors++;
  595.          }
  596. #endif                    /* MS Windows */
  597.       else {
  598.          f2 = fopen(ofile, WriteBinary);
  599.      while ((c = fgetc(f)) != EOF) {
  600.         fputc(c, f2);
  601.         }
  602.      fclose(f);
  603.      if ((f = fopen(tmp, ReadBinary)) == NULL) {
  604.         report("tried to read .bat to append to .exe, but couldn't\n");
  605.         errors++;
  606.         }
  607.      else {
  608.         while ((c = fgetc(f)) != EOF) {
  609.            fputc(c, f2);
  610.            }
  611.         fclose(f);
  612.         }
  613.      fclose(f2);
  614.      unlink(tmp);
  615.          }
  616.       }
  617. #endif                    /* NT */
  618.  
  619.    /*
  620.     * Finish by removing intermediate files.
  621.     *  Execute the linked program if so requested and if there were no errors.
  622.     */
  623.    rmfiles(rfiles);            /* remove intermediate files */
  624.    if (errors > 0) {            /* exit if linker errors seen */
  625.       remove(ofile);
  626.       exit(EXIT_FAILURE);
  627.       }
  628. #ifdef ConsoleWindow
  629.    else
  630.       report("No errors\n");
  631. #endif                    /* ConsoleWindow */
  632.  
  633.    if (optind < argc)  {
  634.       report("Executing");
  635.       execute (ofile, efile, argv+optind+1);
  636.       }
  637.  
  638.    free(tfiles);
  639.    free(lfiles);
  640.    free(rfiles);
  641.  
  642.    exit(EXIT_SUCCESS);
  643.    return 0;
  644.    }
  645.  
  646. /*
  647.  * execute - execute iconx to run the icon program
  648.  */
  649. static void execute(ofile,efile,args)
  650. char *ofile, *efile, **args;
  651.    {
  652.  
  653.    int n;
  654.    char **argv, **p;
  655.  
  656.    for (n = 0; args[n] != NULL; n++)    /* count arguments */
  657.       ;
  658.    p = argv = (char **)alloc((unsigned int)((n + 5) * sizeof(char *)));
  659.  
  660.    *p++ = iconxloc;            /* set iconx pathname */
  661.    if (efile != NULL) {            /* if -e given, copy it */
  662.       *p++ = "-e";
  663.       *p++ = efile;
  664.       }
  665.    *p++ = ofile;            /* pass icode file name */
  666.  
  667. #ifdef MSWindows
  668. #ifndef NTConsole
  669.    {
  670.       char cmdline[256], *tmp;
  671.  
  672.       strcpy(cmdline, "wiconx ");
  673.       if (efile != NULL) {
  674.          strcat(cmdline, "-e ");
  675.          strcat(cmdline, efile);
  676.          strcat(cmdline, " ");
  677.       }
  678.    strcat(cmdline, ofile);
  679.    strcat(cmdline, " ");
  680.    while ((tmp = *args++) != NULL) {    /* copy args into argument vector */
  681.       strcat(cmdline, tmp);
  682.       strcat(cmdline, " ");
  683.    }
  684.  
  685.    WinExec(cmdline, SW_SHOW);
  686.    return;
  687.    }
  688. #endif                    /* NTConsole */
  689. #endif                    /* MSWindows */
  690.  
  691.    while ((*p++ = *args++) != 0)      /* copy args into argument vector */
  692.       ;
  693.    *p = NULL;
  694.  
  695.    /*
  696.     * Call iconx on the way out.
  697.     */
  698.  
  699. #if MSDOS
  700.       /* No special handling is needed for an .exe files, since iconx
  701.        * recognizes it from the extension andfrom internal .exe data.
  702.        */
  703. #if MICROSOFT || TURBO || BORLAND_286 || BORLAND_386
  704.       execvp(iconxloc,argv);    /* execute with path search */
  705. #endif                    /* MICROSOFT || ... */
  706.  
  707. #if INTEL_386 || ZTC_386 || HIGHC_386 || WATCOM || SCCX_MX
  708.       fprintf(stderr,"-x not supported\n");
  709.       fflush(stderr);
  710. #endif                    /* INTEL_386 || ... */
  711. #endif                    /* MSDOS */
  712.  
  713.    quitf("could not run %s",iconxloc);
  714.    }
  715.  
  716. void report(s)
  717. char *s;
  718.    {
  719.    char *c = (strchr(s, '\n') ? "" : ":\n") ;
  720.    if (!silent)
  721.       fprintf(stderr,"%s%s",s,c);
  722. #ifdef ConsoleWindow
  723.    else if (flog != NULL)
  724.       fprintf(flog, "%s%s",s,c);
  725. #endif                    /* ConsoleWindow */
  726.    }
  727.  
  728. /*
  729.  * rmfiles - remove a list of files
  730.  */
  731.  
  732. static void rmfiles(p)
  733. char **p;
  734.    {
  735.    for (; *p; p++) {
  736.       remove(*p);
  737.       }
  738.    }
  739.  
  740. /*
  741.  * Print an error message if called incorrectly.  The message depends
  742.  *  on the legal options for this system.
  743.  */
  744. static void usage()
  745.    {
  746.    fprintf(stderr,"usage: %s %s file ... [-x args]\n", progname, TUsage);
  747.    exit(EXIT_FAILURE);
  748.    }
  749.