home *** CD-ROM | disk | FTP | other *** search
/ Fish 'n' More 2 / fishmore-publicdomainlibraryvol.ii1991xetec.iso / fish / languages / dice_443 / cc.lzh / cc / main.c < prev    next >
C/C++ Source or Header  |  1991-01-13  |  26KB  |  1,355 lines

  1.  
  2. /*
  3.  *  MAIN.C
  4.  *
  5.  *  (c)Copyright 1990, Matthew Dillon, All Rights Reserved
  6.  *
  7.  *  dcc <options> <files>
  8.  */
  9.  
  10. #include "defs.h"
  11.  
  12. #ifndef AZLAT_COMPAT
  13. #define DoLink_Dice    DoLink
  14. #define DoCompile_Dice    DoCompile
  15. #define DoAssemble_Dice DoAssemble
  16. #define DoPrelink_Dice    DoPrelink
  17. #endif
  18.  
  19. #ifdef _DCC
  20. IDENT("DCC",".14");
  21. DCOPYRIGHT;
  22. #endif
  23.  
  24. Prototype   void    myexit(void);
  25. Prototype   int     main(int, char **);
  26. Prototype   void    AddFile(char *);
  27. Prototype   void    help(int);
  28. Prototype   char    *TmpFileName(char *);
  29. Prototype   char    *MungeFile(char *, char *, char *);
  30. Prototype   void    AddName(LIST *, char *, char *);
  31. Prototype   void    AddOpt(LIST *, char *, char *);
  32. Prototype   char    *Tailer(char *);
  33. Prototype   char    *XFilePart(char *);
  34. Prototype   char    *OptListToStr(LIST *);
  35. Prototype   char    *OptListToStr2(LIST *, char *);
  36. Prototype   void    run_cmd(char *);
  37. Prototype   int     OutOfDate(char *, char *);
  38. Prototype   void    HandleCFile(char *, int);
  39. Prototype   void    HandleAFile(char *, int);
  40. Prototype   void    PushTmpFile(char *);
  41. Prototype   void    PopTmpFile(char *);
  42. Prototype   long    LoadSegLock(long);
  43.  
  44. Prototype   int     DoCompile(char *, char *);
  45. Prototype   int     DoCompile_Dice(char *, char *);
  46. Prototype   int     DoCompile_Aztec(char *, char *);
  47. Prototype   int     DoCompile_Lattice(char *, char *);
  48. Prototype   int     DoAssemble(char *, char *);
  49. Prototype   int     DoAssemble_Dice(char *, char *);
  50. Prototype   int     DoAssemble_Aztec(char *, char *);
  51. Prototype   int     DoAssemble_Lattice(char *, char *);
  52. Prototype   char    *DoPrelink(void);
  53. Prototype   char    *DoPrelink_Dice(void);
  54. Prototype   char    *DoPrelink_Aztec(void);
  55. Prototype   char    *DoPrelink_Lattice(void);
  56. Prototype   int     DoLink(char *);
  57. Prototype   int     DoLink_Dice(char *);
  58. Prototype   int     DoLink_Aztec(char *);
  59. Prototype   int     DoLink_Lattice(char *);
  60.  
  61.  
  62. /*
  63.  *  Note that we use exec_dcc if DCC, which only works with 'dcc' programs
  64.  *  thus, the executables are renamed to prevent problems.
  65.  */
  66.  
  67. __aligned char Buf[512];
  68. char TmpFile[64];
  69. char ErrOptStr[128];
  70. char *ErrFile;
  71. char *OutFile;
  72. char *OutDir = "T:";
  73. char *TmpDir = "T:";
  74. char *AmigaLib = "dlib:amigas";
  75. char *AmigaLibApp1 = "";
  76. char *AmigaLibApp2 = "";
  77. char *CLib = "dlib:c";
  78. char *CLibApp = "";
  79. LIST TmpList;
  80. short NewOpt;
  81. short FastOpt;
  82. short FragOpt;
  83. short ChipOpt;
  84. short MC68020Opt;
  85. short MC68881Opt;
  86. short FFPOpt;
  87. short DDebug;
  88. short RegCallOpt;
  89.  
  90. char DLINK[32];
  91. char DAS[32];
  92. char DC1[32];
  93. char DCPP[32];
  94.  
  95. typedef struct NameNode {
  96.     struct Node n_Node;
  97.     char    *n_In;
  98.     char    *n_Out;
  99.     short   n_IsTmp;
  100. } NameNode;
  101.  
  102. LIST   CList;
  103. LIST   AList;
  104. LIST   OList;
  105. LIST   LList;
  106.  
  107. LIST   CppOptList;
  108.  
  109. short    NoLink;
  110. short    NoAsm;
  111. short    SmallCode = 1;
  112. short    SmallData = 1;
  113. short    ConstCode;        /*    -ms            */
  114. short    AbsData;        /*    -mw, -ma        */
  115. short    ResOpt;
  116. short    AltSectOpt;
  117. short    SymOpt;
  118. short    RomOpt;
  119. short    ProtoOnlyOpt;
  120. short    NoIntermediateAssembly;
  121. short    PIOpt;
  122. short    Verbose;
  123. short    NoDefaultLibs;
  124. short    CompilerOpt = DICE_C;
  125. long    AbsDataStart;        /*    -mw <addr>  */
  126.  
  127. extern struct Library *SysBase;
  128.  
  129. void
  130. myexit()
  131. {
  132.     NODE *node;
  133.  
  134.     while (node = RemHead(&TmpList)) {
  135.     remove(node->ln_Name);
  136.     free(node);
  137.     }
  138. }
  139.  
  140. int
  141. main(xac, xav)
  142. int xac;
  143. char *xav[];
  144. {
  145.     int fc = 0;
  146.     int ac;
  147.     char **av;
  148.  
  149. #ifdef LATTICE
  150.     {
  151.     long n = (long)Buf;
  152.     if (n & 3) {
  153.         puts("software error, Buf not aligned");
  154.         exit(1);
  155.     }
  156.     }
  157. #endif
  158. #ifdef NOTDEF
  159.     expand_args(xac, xav, &ac, &av);
  160. #else
  161.     ac = xac;
  162.     av = xav;
  163. #endif
  164.  
  165.     NewList(&CList);
  166.     NewList(&AList);
  167.     NewList(&OList);
  168.     NewList(&LList);
  169.  
  170.     NewList(&TmpList);
  171.  
  172.     NewList(&CppOptList);
  173.  
  174.     atexit(myexit);
  175.  
  176.     if (ac == 1)
  177.     help(0);
  178.  
  179.     {
  180.     char *ptr = av[0];    /*  cmd name */
  181.     char prefix[32];
  182.     short i;
  183.  
  184.     for (i = strlen(ptr); i >= 0 && ptr[i] != ':' && ptr[i] != '/'; --i);
  185.     ++i;
  186.  
  187.     ptr = ptr + i;        /*  base name */
  188.     for (i = 0; ptr[i] && ptr[i] != '_'; ++i);
  189.     if (ptr[i] == '_') {
  190.         strncpy(prefix, ptr, i + 1);
  191.         prefix[i+1] = 0;
  192.     } else {
  193.         prefix[0] = 0;
  194.     }
  195.     sprintf(DLINK, "%s%s", prefix, "dlink");
  196.     sprintf(DAS  , "%s%s", prefix, "das");
  197.     sprintf(DC1  , "%s%s", prefix, "dc1");
  198.     sprintf(DCPP , "%s%s", prefix, "dcpp");
  199.     }
  200.  
  201.     {
  202.     char **argv = av;
  203.     ac = ExtArgsEnv(ac, &argv, "ENV:DCCOPTS");
  204.     av = argv;
  205.     }
  206.  
  207.     {
  208.     long i;
  209.     char *dummy;
  210.  
  211.     for (i = 1; i < ac; ++i) {
  212.         char *ptr = av[i];
  213.  
  214.         if (*ptr == '-') {
  215.         ptr += 2;
  216.  
  217.         switch(ptr[-1]) {
  218.         case '0':       /*  -020        */
  219.             MC68020Opt = 1;
  220.             break;
  221.         case '1':       /*  1.4, 1.3    */
  222.         case '2':       /*  2.0, 2.1..  */
  223.             if (ptr[0] != '.')
  224.             help(1);
  225.             AddOpt(&CppOptList, ptr - 2, "");
  226.             {
  227.             static char ABuf[32];
  228.  
  229.             sprintf(ABuf, "%c%c", ptr[-1], ptr[1]);
  230.             AmigaLibApp2 = ABuf;
  231.             }
  232.             break;
  233.         case '8':
  234.             MC68881Opt = 1;
  235.             break;
  236.         case 'f':
  237.             if (*ptr == 0)
  238.             FastOpt = 1;
  239.             else if (*ptr == 'r')
  240.             FragOpt = 1;
  241.             else if (*ptr == 'f')
  242.             FFPOpt = 1;
  243.             break;
  244.         case 'r':
  245.             if (strcmp(ptr, "om") == 0) {
  246.             RomOpt = 1;
  247.             } else {
  248.             if (PIOpt && ResOpt == 0)
  249.                 puts("DCC: Warning, -r -pi = -pr");
  250.             ResOpt = 1;
  251.             }
  252.             break;
  253.         case 'c':
  254.             if (*ptr == 0)
  255.             NoLink = 1;
  256.             else if (stricmp(ptr, "hip") == 0)
  257.             ChipOpt = 1;
  258.             else
  259.             help(1);
  260.             break;
  261.         case 'a':
  262.             if (strcmp(ptr, "ztec") == 0) {
  263.             CompilerOpt = AZTEC_C;
  264.             break;
  265.             }
  266.             NoAsm = 1;
  267.             NoLink= 1;
  268.             break;
  269.         case 'l':
  270.             if (strcmp(ptr, "attice") == 0) {
  271.             CompilerOpt = LATTICE_C;
  272.             break;
  273.             }
  274.             if (ptr[0] == '0' && ptr[1] == 0) {
  275.             NoDefaultLibs = 1;
  276.             break;
  277.             }
  278.             if (*ptr == 0)
  279.             ptr = av[++i];
  280.             AddName(&LList, ".lib", ptr);
  281.             break;
  282.         case 'I':   /*  -Idir   */
  283.             if (ptr[0] == '0' && ptr[1] == 0) {
  284.             AddOpt(&CppOptList, "-I0", "");
  285.             break;
  286.             }
  287.             if (*ptr == 0)
  288.             ptr = av[++i];
  289.             AddOpt(&CppOptList, "-I", ptr);
  290.             break;
  291.         case 'd':
  292.             if (strcmp(ptr, "ice") == 0) {
  293.             CompilerOpt = DICE_C;
  294.             break;
  295.             }
  296.             DDebug = atoi(ptr);
  297.             break;
  298.         case 'D':   /*  -Ddefine[=str] */
  299.             if (*ptr == 0)
  300.             ptr = av[++i];
  301.             AddOpt(&CppOptList, "-D", ptr);
  302.             break;
  303.         case 'U':   /*  -U      -undefine certain symbols */
  304.             AddOpt(&CppOptList, "-U", ptr);
  305.             break;
  306.         case 'o':
  307.             if (*ptr)
  308.             OutFile = ptr;
  309.             else
  310.             OutFile = av[++i];
  311.             {
  312.             short idx = strlen(OutFile) - 2;
  313.             if (idx >= 0) {
  314.                 if (stricmp(OutFile + idx, ".h") == 0 || stricmp(OutFile + idx, ".c") == 0) {
  315.                 puts("ERROR! -o output file may not end in .c or .h!");
  316.                 exit(20);
  317.                 }
  318.             }
  319.             }
  320.             break;
  321.         case 'O':
  322.             if (*ptr)
  323.             OutDir = ptr;
  324.             else
  325.             OutDir = av[++i];
  326.             break;
  327.         case 'E':   /*  error output append */
  328.             if (*ptr == 0)
  329.             ptr = av[++i];
  330.  
  331.             if (freopen(ptr, "a", stderr)) {
  332.             ErrFile = ptr;
  333.             sprintf(ErrOptStr," -E %s", ptr);
  334.             } else {
  335.             printf("unable to append to %s\n", ptr);
  336.             }
  337.             break;
  338.         case 'p':
  339.             if (strcmp(ptr, "roto") == 0) {
  340.             ProtoOnlyOpt = 1;
  341.             } else if (strcmp(ptr, "i") == 0) {
  342.             PIOpt = 1;
  343.             if (ResOpt)
  344.                 puts("DCC: Warning, -r -pi = -pr");
  345.             } else if (strcmp(ptr, "r") == 0) {
  346.             PIOpt = 1;
  347.             ResOpt = 1;
  348.             } else {
  349.             help(1);
  350.             }
  351.             break;
  352.         case 'T':
  353.             if (*ptr)
  354.             TmpDir = ptr;
  355.             else
  356.             TmpDir = av[++i];
  357.             break;
  358.         case 'm':
  359.             switch(*ptr) {
  360.             case 'C':
  361.             SmallCode = 0;
  362.             break;
  363.             case 'c':
  364.             SmallCode = 1;
  365.             break;
  366.             case 'D':
  367.             SmallData = 0;
  368.             break;
  369.             case 'd':
  370.             SmallData = 1;
  371.             break;
  372.             case 'a':
  373.             case 'w':
  374.             AbsData = 1;
  375.  
  376.             if (*ptr == 'a')
  377.                 AbsData = 2;
  378.  
  379.             ++ptr;
  380.             if (*ptr == 0)
  381.                 ptr = av[++i];
  382.  
  383. #ifdef LATTICE
  384.             AbsDataStart = atoi(ptr);   /*  bug in lattice */
  385. #else
  386.             AbsDataStart = strtol(ptr, &dummy, 0);
  387. #endif
  388.             break;
  389.             case 'r':
  390.             RegCallOpt = 1;
  391.             break;
  392.             case 'R':
  393.             CLibApp = "r";
  394.             AmigaLibApp1 = "r";
  395.             RegCallOpt = 2;
  396.             if (ptr[1] == 'R') {
  397.                 RegCallOpt = 3;
  398.                 if (ptr[2] == 'X')
  399.                 RegCallOpt = 4;
  400.             }
  401.             break;
  402.             case 's':
  403.             if (strcmp(ptr, "as") == 0) {
  404.                 CompilerOpt = LATTICE_C;
  405.                 break;
  406.             }
  407.             if (ptr[1] == '0')
  408.                 ConstCode = 0;
  409.             else
  410.                 ConstCode = 1;
  411.             break;
  412.             case 'S':
  413.             ConstCode = 2;
  414.             break;
  415.             default:
  416.             fprintf(stderr, "bad -s model\n");
  417.             exit(1);
  418.             }
  419.             break;
  420.         case 's':
  421.             SymOpt = 1;
  422.             break;
  423.         case 'S':
  424.             AltSectOpt = 1;
  425.             break;
  426.         case 'v':
  427.             Verbose = 1;
  428.             break;
  429.         case 'n':
  430.             if (strcmp(ptr-1, "new") == 0) {
  431.             NewOpt = 1;
  432.             break;
  433.             }
  434.             /* fall through */
  435.         default:
  436.             fprintf(stderr, "bad option\n");
  437.             help(1);
  438.         }
  439.         continue;
  440.         }
  441.         if (*ptr == '@') {
  442.         FILE *fi = fopen(ptr + 1, "r");
  443.         char buf[128];
  444.  
  445.         if (fi == NULL) {
  446.             printf("unable to open %s\n", ptr + 1);
  447.             exit(1);
  448.         }
  449.         while (fgets(buf, sizeof(buf), fi)) {
  450.             short len = strlen(buf);
  451.             if (len > 0)
  452.             buf[len-1] = 0;
  453.             if (buf[0] && buf[0] != ';' && buf[0] != '#') {
  454.             ++fc;
  455.             AddFile(buf);
  456.             }
  457.         }
  458.         fclose(fi);
  459.         continue;
  460.         }
  461.         ++fc;
  462.         AddFile(ptr);
  463.     }
  464.     if (i > ac) {
  465.         fprintf(stderr, "file argument missing\n");
  466.         help(1);
  467.     }
  468.     }
  469.  
  470. #ifdef AZLAT_COMPAT
  471.     if (CompilerOpt == AZTEC_C) {
  472.     puts("DCC in AZTEC mode");
  473.     FastOpt = 0;
  474.     NoIntermediateAssembly = 1;
  475.     }
  476.     if (CompilerOpt == LATTICE_C) {
  477.     puts("DCC in LATTICE mode");
  478.     FastOpt = 0;
  479.     NoIntermediateAssembly = 1;
  480.     }
  481. #else
  482.     if (CompilerOpt != DICE_C)
  483.     puts("DCC must be recompiled w/ AZLAT_COMPAT defined");
  484. #endif
  485.  
  486.     {
  487.     NameNode *nn;
  488.  
  489.     while (nn = (NameNode *)RemHead(&CList))
  490.         HandleCFile(nn->n_In, fc);
  491.     if (NoAsm == 0) {
  492.         while (nn = (NameNode *)RemHead(&AList))
  493.         HandleAFile(nn->n_In, fc);
  494.     }
  495.     }
  496.  
  497.     if (NoLink == 0) {
  498.     char *lfile = DoPrelink();
  499.     if (lfile)
  500.         PushTmpFile(lfile);
  501.     DoLink(lfile);
  502.     if (lfile) {
  503.         PopTmpFile(lfile);
  504.         remove(lfile);
  505.         free(lfile);
  506.     }
  507.     }
  508.     return(0);
  509. }
  510.  
  511. void
  512. AddFile(ptr)
  513. char *ptr;
  514. {
  515.     char *t = Tailer(ptr);
  516.  
  517.     if (strncmp(t, "a", 1) == 0) {
  518.     AddName(&AList, NULL, ptr);
  519.     } else
  520.     if (strncmp(t, "o", 1) == 0) {
  521.     AddName(&OList, NULL, ptr);
  522.     } else
  523.     if (strncmp(t, "l", 1) == 0) {
  524.     AddName(&LList, NULL, ptr);
  525.     } else {
  526.     AddName(&CList, NULL, ptr);
  527.     }
  528. }
  529.  
  530. DoCompile_Dice(in, out)
  531. char *in;
  532. char *out;
  533. {
  534.     char *qq = "";
  535.     char *cptmp = TmpFileName(".i");
  536.     char *code = (SmallCode) ? " -mc" : " -mC";
  537.     char *data = (SmallData) ? " -md" : " -mD";
  538.     char *rc = qq;
  539.     char *absdata;
  540.     char *concode;
  541.     char *res  = (ResOpt) ? " -r" : qq;
  542.     char *verb = (Verbose) ? " -v" : qq;
  543.     char *optsect = (AltSectOpt) ? " -S" : qq;
  544.     char *protoonly = (ProtoOnlyOpt) ? " -proto" : qq;
  545.     char *mc68020 = (MC68020Opt) ? " -020" : qq;
  546.     char *mc68881 = (MC68881Opt) ? " -881" : qq;
  547.     char *piopt;
  548.     char *ffp = (FFPOpt) ? " -ffp" : qq;
  549.  
  550.     switch(RegCallOpt) {
  551.     case 1:
  552.     rc = " -mr";
  553.     break;
  554.     case 2:
  555.     rc = " -mR";
  556.     break;
  557.     case 3:
  558.     rc = " -mRR";
  559.     break;
  560.     case 4:
  561.     rc = " -mRRX";
  562.     break;
  563.     }
  564.  
  565.     switch(ConstCode) {
  566.     case 1:
  567.     concode = " -ms";
  568.     break;
  569.     case 2:
  570.     concode = " -mS";
  571.     break;
  572.     default:
  573.     concode = qq;
  574.     break;
  575.     }
  576.  
  577.     switch(AbsData) {
  578.     case 1:
  579.     absdata = " -mw";
  580.     break;
  581.     case 2:
  582.     absdata = " -ma";
  583.     break;
  584.     default:
  585.     absdata = qq;
  586.     break;
  587.     }
  588.  
  589.     if (PIOpt) {
  590.     if (ResOpt)
  591.         piopt = " -pr";
  592.     else
  593.         piopt = " -pi";
  594.     res = qq;
  595.     absdata = qq;
  596.     code = qq;
  597.     data = qq;
  598.     } else {
  599.     piopt = qq;
  600.     }
  601.  
  602.     PushTmpFile(cptmp);
  603.     sprintf(Buf+1, "%s %s -o %s%s%s%s", DCPP, in, cptmp, ErrOptStr, OptListToStr(&CppOptList), ffp);
  604.     run_cmd(Buf+1);
  605.     sprintf(Buf+1, "%s %s -o %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
  606.     DC1, cptmp, out, code, data, rc, res, verb,
  607.     optsect, protoonly, concode, absdata, piopt, ErrOptStr,
  608.     mc68020, mc68881, ffp
  609.     );
  610.     run_cmd(Buf+1);
  611.     PopTmpFile(cptmp);
  612.     remove(cptmp);
  613.     free(cptmp);
  614.     return(0);
  615. }
  616.  
  617. DoAssemble_Dice(in, out)
  618. char *in;
  619. char *out;
  620. {
  621.     sprintf(Buf+1, "%s -o%s %s%s", DAS, out, in, ErrOptStr);
  622.     run_cmd(Buf+1);
  623.     return(0);
  624. }
  625.  
  626. char *
  627. DoPrelink_Dice(void)
  628. {
  629.     NameNode *nn;
  630.     char *ltmp = TmpFileName(".lnk");
  631.     FILE *fi = fopen(ltmp, "w");
  632.  
  633.     if (fi == NULL) {
  634.     fprintf(stderr, "couldn't create %s\n", ltmp);
  635.     exit(1);
  636.     }
  637.  
  638.     while (nn = (NameNode *)RemHead(&OList)) {
  639.     fputs(nn->n_In, fi);
  640.     putc('\n', fi);
  641.     }
  642.     while (nn = (NameNode *)RemHead(&LList)) {
  643.     fputs(nn->n_In, fi);
  644.     putc('\n', fi);
  645.     }
  646.     if (RomOpt == 0 && NoDefaultLibs == 0) {
  647.     fprintf(fi, "%s%s.lib", CLib, CLibApp);
  648.     fprintf(fi, " %s%s%s.lib dlib:auto.lib\n", AmigaLib, AmigaLibApp1, AmigaLibApp2);
  649.     }
  650.     fclose(fi);
  651.     return(ltmp);
  652. }
  653.  
  654. /*
  655.  *  dlib:x.o is a special trailer for any autoinit code (in section autoinit,code)
  656.  *  This section is called in sequence just before main() with ac, av pushed on
  657.  *  the stack.    The idea is that any module may reference an autoinit section to
  658.  *  automatically initialize certain aspects of itself without requiring a call
  659.  *  from the main program.
  660.  */
  661.  
  662. DoLink_Dice(lfile)
  663. char *lfile;
  664. {
  665.     char *qq = "";
  666.     char *co = " ";
  667. #ifdef NOTDEF
  668.     char *ro = (NoDefaultLibs) ? qq : "dlib:x.o";
  669. #endif
  670.     char *ro = "dlib:x.o";
  671.     char *symopt = (SymOpt) ? " -s" : qq;
  672.     char *resopt = (ResOpt) ? " -r" : qq;
  673.     char *fragopt= (FragOpt) ? " -frag" : qq;
  674.     char *chipopt= (ChipOpt) ? " -chip" : qq;
  675.     char *piopt;
  676.     char absdata[20];
  677.  
  678.     if (RomOpt == 0 && NoDefaultLibs == 0) {       /*  RomOpt PIOpt ResOpt */
  679.     static char *SCode[] = { "dlib:c.o ",       /*    0      0      0   */
  680.                  "dlib:c.o ",       /*    0      0      1   */
  681.                  "dlib:c_pi.o ",    /*    0      1      0   */
  682.                  "dlib:c_pr.o "     /*    0      1      1   */
  683.                    };
  684.     co = SCode[(short)((PIOpt << 1) | ResOpt)];
  685.     }
  686.  
  687.     if (OutFile == NULL)
  688.     OutFile = "a.out";
  689.  
  690.     if (AbsData) {
  691.     sprintf(absdata, " -ma 0x%lx", AbsDataStart);
  692.     } else {
  693.     absdata[0] = 0;
  694.     }
  695.  
  696.     if (PIOpt) {
  697.     if (ResOpt)
  698.         piopt = " -pr";
  699.     else
  700.         piopt = " -pi";
  701.     resopt = qq;
  702.     if (AbsData) {
  703.         absdata[0] = 0;
  704.         puts("Warning: cannot mix -pi and -ma/-mw");
  705.     }
  706.     } else {
  707.     piopt = qq;
  708.     }
  709.     if (FragOpt) {
  710.     if (ResOpt) {
  711.         puts("Warning: cannot use -frag with -r");
  712.         fragopt = qq;
  713.     }
  714.     }
  715.     sprintf(Buf+1, "%s %s @%s %s -o %s%s%s%s%s%s%s%s",
  716.     DLINK, co, lfile, ro, OutFile,
  717.     symopt,
  718.     resopt,
  719.     fragopt,
  720.     piopt,
  721.     absdata,
  722.     chipopt,
  723.     ErrOptStr
  724.     );
  725.     run_cmd(Buf+1);
  726.     return(0);
  727. }
  728.  
  729.  
  730.  
  731. void
  732. help(code)
  733. {
  734. #ifdef _DCC
  735.     printf("%s\n%s\n", Ident, DCopyright);
  736. #endif
  737.     puts("Refer to DOC/DCC.DOC for options. -f for resident-hack-fast-load");
  738.     exit(code);
  739. }
  740.  
  741. char *
  742. TmpFileName(tail)
  743. char *tail;
  744. {
  745.     char *buf = malloc(strlen(TmpDir) + strlen(tail) + 32);
  746.     char dummy = 0;
  747.  
  748.     sprintf(buf, "%s%06lx%s", TmpDir, (long)&dummy >> 8, tail);
  749.     return(buf);
  750. }
  751.  
  752. char *
  753. MungeFile(file, hdr, tail)
  754. char *file;
  755. char *hdr;
  756. char *tail;
  757. {
  758.     char *base = file;
  759.     char *name;
  760.     short i;
  761.     short hlen = 0;
  762.  
  763.     if (hdr) {
  764.     hlen = strlen(hdr);
  765.     while (*base && *base != ':' && *base != '/')
  766.         ++base;
  767.     if (*base == 0)
  768.         base = file;
  769.     else
  770.         ++base;
  771.     } else {
  772.     hdr = "";
  773.     }
  774.     for (i = strlen(base) - 1; i >= 0; --i) {
  775.     if (base[i] == '.')
  776.         break;
  777.     }
  778.     if (i < 0)
  779.     i = strlen(base);
  780.  
  781.     name = malloc(hlen + i + strlen(tail) + 2);
  782.     strcpy(name, hdr);
  783.     if (hlen && hdr[hlen-1] != ':' && hdr[hlen-1] != '/')
  784.     strcat(name, "/");
  785.     sprintf(name + strlen(name), "%.*s%s", i, base, tail);
  786.     return(name);
  787. }
  788.  
  789. void
  790. AddName(list, tailifnone, file)
  791. LIST *list;
  792. char *tailifnone;
  793. char *file;
  794. {
  795.     NameNode *nn = malloc(sizeof(NameNode));
  796.     short i;
  797.  
  798.     for (i = strlen(file) - 1; i >= 0 && file[i] != '.'; --i);
  799.  
  800.     if (i < 0 && tailifnone) {
  801.     nn->n_In = malloc(strlen(file) + strlen(tailifnone) + 1);
  802.     sprintf(nn->n_In, "%s%s", file, tailifnone);
  803.     } else {
  804.     nn->n_In = malloc(strlen(file) + 1);
  805.     strcpy(nn->n_In, file);
  806.     }
  807.     nn->n_Out = NULL;
  808.     nn->n_IsTmp = 0;
  809.     AddTail(list, &nn->n_Node);
  810. }
  811.  
  812. void
  813. AddOpt(list, opt, body)
  814. LIST *list;
  815. char *opt;
  816. char *body;
  817. {
  818.     NameNode *nn = malloc(sizeof(NameNode));
  819.  
  820.     nn->n_In = opt;
  821.     nn->n_Out= body;
  822.     AddTail(list, &nn->n_Node);
  823. }
  824.  
  825. char *
  826. Tailer(ptr)
  827. char *ptr;
  828. {
  829.     short i;
  830.  
  831.     for (i = strlen(ptr) - 1; i >= 0 && ptr[i] != '.'; --i);
  832.     if (i < 0)
  833.     return("");
  834.     return(ptr + i + 1);
  835. }
  836.  
  837. char *
  838. XFilePart(ptr)
  839. char *ptr;
  840. {
  841.     short i;
  842.  
  843.     for (i = strlen(ptr) - 1; i >= 0 && ptr[i] != ':' && ptr[i] != '/'; --i);
  844.     ++i;
  845.     return(ptr + i);
  846. }
  847.  
  848. char *
  849. OptListToStr(list)
  850. LIST *list;
  851. {
  852.     static char Tmp[512];
  853.     short i;
  854.     NameNode *scan;
  855.  
  856.     i = 0;
  857.     for (scan = (NameNode *)list->lh_Head; scan != (NameNode *)&list->lh_Tail; scan = (NameNode *)scan->n_Node.ln_Succ) {
  858.     sprintf(Tmp + i, " %s%s", scan->n_In, scan->n_Out);
  859.     i += strlen(Tmp + i);
  860.     }
  861.     return(Tmp);
  862. }
  863.  
  864. #ifdef AZLAT_COMPAT
  865.  
  866. char *
  867. OptListToStr2(list, cvt)
  868. LIST *list;
  869. char *cvt;
  870. {
  871.     static char Tmp[512];
  872.     short i;
  873.     NameNode *scan;
  874.  
  875.     i = 0;
  876.     for (scan = (NameNode *)list->lh_Head; scan != (NameNode *)&list->lh_Tail; scan = (NameNode *)scan->n_Node.ln_Succ) {
  877.     sprintf(Tmp + i, " %s%s", scan->n_In, scan->n_Out);
  878.     {
  879.         char *ptr;
  880.         for (ptr = cvt; *ptr; ptr += 2) {
  881.         if (Tmp[i+2] == ptr[0])
  882.             Tmp[i+2] = ptr[1];
  883.         }
  884.     }
  885.     i += strlen(Tmp + i);
  886.     }
  887.     return(Tmp);
  888. }
  889.  
  890. #endif
  891.  
  892. /*
  893.  *  run_cmd(buf)        buf[-1] is valid for BCPL stuff, buf[-1] is
  894.  *            long word aligned.
  895.  */
  896.  
  897. void
  898. run_cmd(buf)
  899. char *buf;
  900. {
  901.     short i;
  902.     short j = strlen(buf);
  903.     int r;
  904.  
  905.     if (Verbose)
  906.     printf("%s\n", buf);
  907.  
  908.     if (ErrFile)
  909.     fclose(stderr);
  910.  
  911. #if INCLUDE_VERSION >= 36
  912.     if (SysBase->lib_Version >= 36) {
  913.     long seg;
  914.     long lock;
  915.     char c;
  916.  
  917.     Process *proc = FindTask(NULL);
  918.     CLI *cli = BTOC(proc->pr_CLI, CLI);
  919.     long oldCommandName;
  920.  
  921.     if (DDebug)
  922.         puts("cmd-begin");
  923.  
  924.     for (i = 0; buf[i] && buf[i] != ' '; ++i);
  925.     c = buf[i];
  926.     buf[i] = 0;
  927.  
  928.     if (cli) {
  929.         oldCommandName = (long)cli->cli_CommandName;
  930.         buf[-1] = i;
  931.         cli->cli_CommandName = CTOB(buf - 1);
  932.     }
  933.  
  934.     if (seg = FindSegment(buf, 0L, 0)) {
  935.         r = RunCommand(((long *)seg)[2], 8192, buf + i + 1, strlen(buf + i + 1));
  936.     } else if ((lock = _SearchPath(buf)) && seg = LoadSegLock(lock)) {
  937.         r = RunCommand(seg, 8192, buf + i + 1, strlen(buf + i + 1));
  938.         UnLoadSeg(seg);
  939.     } else {
  940.         buf[i] = c;
  941.         r = System(buf, NULL);
  942.     }
  943.     if (cli)
  944.         cli->cli_CommandName = (BSTR)oldCommandName;
  945.  
  946.     if (DDebug)
  947.         puts("cmd-end");
  948.     } else {
  949. #else
  950.     {
  951. #endif
  952.  
  953. #ifdef _DCC
  954.     if (FastOpt == 0) {
  955. #endif
  956.         if (Execute(buf, NULL, Output()) != -1) {
  957.         printf("Unable to Execute %s\n", buf);
  958.         exit(1);
  959.         }
  960.         r = 0;
  961. #ifdef NOTDEF
  962.         r = IoErr();
  963.         if (r && r != -1) {
  964.         puts("Non-Zero exit code");
  965.         exit(1);
  966.         }
  967. #endif
  968.  
  969. #ifdef _DCC
  970.     } else {
  971.         for (i = 0; buf[i] && buf[i] != ' '; ++i);
  972.         buf[i] = 0;
  973.         if (i != j) {
  974.         for (++i; buf[i] == ' '; ++i);
  975.         }
  976.         r = exec_dcc(buf, buf + i);
  977.     }
  978. #endif
  979.     }
  980.     if (r) {
  981.     printf("Exit code %d\n", r);
  982.     exit(1);
  983.     }
  984.     if (ErrFile)
  985.     freopen(ErrFile, "a", stderr);
  986. }
  987.  
  988. int
  989. OutOfDate(in, out)
  990. char *in;
  991. char *out;
  992. {
  993.     static FIB *InFib;
  994.     static FIB *OutFib;
  995.     BPTR inLock, outLock;
  996.     FIB *inFib;
  997.     FIB *outFib;
  998.     int r = 1;
  999.  
  1000.     if (NewOpt == 0)
  1001.     return(1);
  1002.  
  1003.     if (InFib == NULL) {
  1004.     InFib = malloc(sizeof(FIB));
  1005.     OutFib = malloc(sizeof(FIB));
  1006.     }
  1007.     inFib = InFib;
  1008.     outFib = OutFib;
  1009.  
  1010.     if (inLock = Lock(in, SHARED_LOCK)) {
  1011.     if (outLock = Lock(out, SHARED_LOCK)) {
  1012.         if (Examine(inLock, inFib) && Examine(outLock, outFib)) {
  1013.         if (inFib->fib_Date.ds_Days < outFib->fib_Date.ds_Days)
  1014.             r = 0;
  1015.         else if (inFib->fib_Date.ds_Days == outFib->fib_Date.ds_Days) {
  1016.             if (inFib->fib_Date.ds_Minute < outFib->fib_Date.ds_Minute)
  1017.             r = 0;
  1018.             else if (inFib->fib_Date.ds_Minute == outFib->fib_Date.ds_Minute) {
  1019.             if (inFib->fib_Date.ds_Tick < outFib->fib_Date.ds_Tick)
  1020.                 r = 0;
  1021.             }
  1022.         }
  1023.         }
  1024.         UnLock(outLock);
  1025.     }
  1026.     UnLock(inLock);
  1027.     }
  1028.     return(r);
  1029. }
  1030.  
  1031. void
  1032. HandleCFile(in, fc)
  1033. char *in;
  1034. int fc;
  1035. {
  1036.     char *asmName;
  1037.     char *objName;
  1038.  
  1039.     if (fc == 1 && OutFile && NoAsm)
  1040.     asmName = OutFile;
  1041.     else
  1042.     asmName = MungeFile(XFilePart(in), TmpDir, ".a");
  1043.  
  1044.     if (fc == 1 && OutFile && NoLink)
  1045.     objName = OutFile;
  1046.     else
  1047.     objName = MungeFile(in, OutDir, ".o");
  1048.  
  1049.     if (NoAsm) {        /*  in -> asmName           */
  1050.     if (OutOfDate(in, asmName))
  1051.         DoCompile(in, asmName);
  1052.     } else {        /*  in -> asmName -> objName*/
  1053.     if (OutOfDate(in, objName)) {
  1054.         PushTmpFile(asmName);
  1055.         if (NoIntermediateAssembly) {
  1056.         DoCompile(in, objName);
  1057.         } else {
  1058.         DoCompile(in, asmName);
  1059.         DoAssemble(asmName, objName);
  1060.         }
  1061.         PopTmpFile(asmName);
  1062.         remove(asmName);
  1063.     }
  1064.     }
  1065.     AddName(&OList, NULL, objName);
  1066. }
  1067.  
  1068. void
  1069. HandleAFile(in, fc)
  1070. char *in;
  1071. int fc;
  1072. {
  1073.     char *objName;
  1074.  
  1075.     if (fc == 1 && OutFile && NoLink)
  1076.     objName = OutFile;
  1077.     else
  1078.     objName = MungeFile(in, OutDir, ".o");
  1079.  
  1080.     if (OutOfDate(in, objName))
  1081.     DoAssemble(in, objName);
  1082.     AddName(&OList, NULL, objName);
  1083. }
  1084.  
  1085. void
  1086. PushTmpFile(name)
  1087. char *name;
  1088. {
  1089.     NODE *node = malloc(sizeof(NODE) + strlen(name) + 1);
  1090.     if (node == NULL) {
  1091.     puts("Ran out of memory!");
  1092.     exit(1);
  1093.     }
  1094.     node->ln_Name = (char *)(node + 1);
  1095.     strcpy(node->ln_Name, name);
  1096.     AddHead(&TmpList, node);
  1097. }
  1098.  
  1099. void
  1100. PopTmpFile(name)
  1101. char *name;
  1102. {
  1103.     NODE *node = RemHead(&TmpList);
  1104.  
  1105.     if (node == NULL || strcmp(name, node->ln_Name) != 0) {
  1106.     puts("PopTmpFile: software error");
  1107.     exit(1);
  1108.     }
  1109.     free(node);
  1110. }
  1111.  
  1112. LoadSegLock(lock)
  1113. long lock;
  1114. {
  1115.     long oldLock;
  1116.     long seg;
  1117.  
  1118.     oldLock = CurrentDir(lock);
  1119.     seg = LoadSeg("");
  1120.     CurrentDir(oldLock);
  1121.     return(seg);
  1122. }
  1123.  
  1124. /*
  1125.  *    AZTEC C, LATTICE C COMPATIBILITY OPTIONS
  1126.  */
  1127.  
  1128. #ifdef AZLAT_COMPAT
  1129.  
  1130. DoLink(lfile)
  1131. char *lfile;
  1132. {
  1133.     switch(CompilerOpt) {
  1134.     case DICE_C:
  1135.     return(DoLink_Dice(lfile));
  1136.     case LATTICE_C:
  1137.     return(DoLink_Lattice(lfile));
  1138.     case AZTEC_C:
  1139.     return(DoLink_Aztec(lfile));
  1140.     }
  1141. }
  1142.  
  1143. DoCompile(in, out)
  1144. char *in;
  1145. char *out;
  1146. {
  1147.     switch(CompilerOpt) {
  1148.     case DICE_C:
  1149.     return(DoCompile_Dice(in, out));
  1150.     case LATTICE_C:
  1151.     return(DoCompile_Lattice(in, out));
  1152.     case AZTEC_C:
  1153.     return(DoCompile_Aztec(in, out));
  1154.     }
  1155.     return(0);
  1156. }
  1157.  
  1158. DoAssemble(in, out)
  1159. char *in;
  1160. char *out;
  1161. {
  1162.     switch(CompilerOpt) {
  1163.     case DICE_C:
  1164.     return(DoAssemble_Dice(in, out));
  1165.     case LATTICE_C:
  1166.     return(DoAssemble_Lattice(in, out));
  1167.     case AZTEC_C:
  1168.     return(DoAssemble_Aztec(in, out));
  1169.     }
  1170.     return(0);
  1171. }
  1172.  
  1173. char *
  1174. DoPrelink(void)
  1175. {
  1176.     switch(CompilerOpt) {
  1177.     case DICE_C:
  1178.     return(DoPrelink_Dice());
  1179.     case LATTICE_C:
  1180.     return(DoPrelink_Lattice());
  1181.     case AZTEC_C:
  1182.     return(DoPrelink_Aztec());
  1183.     }
  1184.     return(0);
  1185. }
  1186.  
  1187. /*
  1188.  *    ------------------------------------------------------------------
  1189.  */
  1190.  
  1191. DoCompile_Lattice(in, out)
  1192. char *in;
  1193. char *out;
  1194. {
  1195.     char *qq = "";
  1196.     char *cptmp = TmpFileName(".i");
  1197.     char *data = (SmallData) ? qq : " -b0";
  1198.  
  1199.     sprintf(Buf, "lc -o%s %s %s %s",
  1200.     out, OptListToStr2(&CppOptList, "DdIi"), data, in
  1201.     );
  1202.     run_cmd(Buf);
  1203.  
  1204.     free(cptmp);
  1205.     return(0);
  1206. }
  1207.  
  1208. DoAssemble_Lattice(in, out)
  1209. char *in;
  1210. char *out;
  1211. {
  1212.     sprintf(Buf, "asm -o%s %s", out, in);
  1213.     run_cmd(Buf);
  1214.     return(0);
  1215. }
  1216.  
  1217. char *
  1218. DoPrelink_Lattice(void)
  1219. {
  1220.     NameNode *nn;
  1221.     char *ltmp = TmpFileName(".lnk");
  1222.     FILE *fi = fopen(ltmp, "w");
  1223.     short libs = 0;
  1224.  
  1225.     if (fi == NULL) {
  1226.     fprintf(stderr, "couldn't create %s\n", ltmp);
  1227.     exit(1);
  1228.     }
  1229.  
  1230.     while (nn = (NameNode *)RemHead(&OList)) {
  1231.     fputs(nn->n_In, fi);
  1232.     putc('\n', fi);
  1233.     }
  1234.  
  1235.     while (nn = (NameNode *)RemHead(&LList)) {
  1236.     if (libs == 0) {
  1237.         fprintf(fi, "LIB ");
  1238.         libs = 1;
  1239.     }
  1240.     fputs(nn->n_In, fi);
  1241.     putc('\n', fi);
  1242.     }
  1243.     if (RomOpt == 0 && NoDefaultLibs == 0) {
  1244.     if (libs == 0) {
  1245.         fprintf(fi, "LIB ");
  1246.         libs = 1;
  1247.     }
  1248.     fprintf(fi, "lib:lc.lib lib:amiga.lib\n");
  1249.     }
  1250.  
  1251.     fclose(fi);
  1252.     return(ltmp);
  1253. }
  1254.  
  1255. DoLink_Lattice(lfile)
  1256. char *lfile;
  1257. {
  1258.     char *qq = "";
  1259.     char *co = " ";
  1260.     char *symopt = (SymOpt) ? " ADDSYM" : qq;
  1261.     char *scopt = (SmallData) ? " SD" : qq;
  1262.     char *sdopt = (SmallCode) ? " SC" : qq;
  1263.  
  1264.     if (RomOpt == 0 && NoDefaultLibs == 0) {       /*  RomOpt PIOpt ResOpt */
  1265.     static char *SCode[] = { "lib:c.o",         /*    0      0      0   */
  1266.                  "lib:cres.o",      /*    0      0      1   */
  1267.                  "lib:c.o",         /*    0      1      0   */
  1268.                  "lib:cres.o"       /*    0      1      1   */
  1269.                    };
  1270.     co = SCode[(short)((PIOpt << 1) | ResOpt)];
  1271.     }
  1272.  
  1273.     if (OutFile == NULL)
  1274.     OutFile = "a.out";
  1275.  
  1276.     sprintf(Buf, "BLink from %s with %s to %s%s%s%s",
  1277.     co, lfile, OutFile, symopt, scopt, sdopt
  1278.     );
  1279.     run_cmd(Buf);
  1280.     return(0);
  1281. }
  1282.  
  1283. /*
  1284.  *  ---------------------------------------------------------------------
  1285.  */
  1286.  
  1287. DoCompile_Aztec(in, out)
  1288. char *in;
  1289. char *out;
  1290. {
  1291.     char *qq = "";
  1292.     char *cptmp = TmpFileName(".i");
  1293.     char *data = (SmallData) ? qq : qq;
  1294.  
  1295.     sprintf(Buf, "cc %s %s %s -o %s",
  1296.     OptListToStr2(&CppOptList, ""), data, in, out
  1297.     );
  1298.     run_cmd(Buf);
  1299.  
  1300.     free(cptmp);
  1301.     return(0);
  1302. }
  1303.  
  1304. DoAssemble_Aztec(in, out)
  1305. char *in;
  1306. char *out;
  1307. {
  1308.     sprintf(Buf, "as %s -o %s", in, out);
  1309.     run_cmd(Buf);
  1310.     return(0);
  1311. }
  1312.  
  1313. char *
  1314. DoPrelink_Aztec(void)
  1315. {
  1316.     NameNode *nn;
  1317.     char *ltmp = TmpFileName(".lnk");
  1318.     FILE *fi = fopen(ltmp, "w");
  1319.  
  1320.     if (fi == NULL) {
  1321.     fprintf(stderr, "couldn't create %s\n", ltmp);
  1322.     exit(1);
  1323.     }
  1324.  
  1325.     while (nn = (NameNode *)RemHead(&OList)) {
  1326.     fputs(nn->n_In, fi);
  1327.     putc('\n', fi);
  1328.     }
  1329.     while (nn = (NameNode *)RemHead(&LList)) {
  1330.     fputs(nn->n_In, fi);
  1331.     putc('\n', fi);
  1332.     }
  1333.     if (RomOpt == 0 && NoDefaultLibs == 0) {
  1334.     fprintf(fi, "-lc\n");
  1335.     }
  1336.     fclose(fi);
  1337.     return(ltmp);
  1338. }
  1339.  
  1340. DoLink_Aztec(lfile)
  1341. char *lfile;
  1342. {
  1343.     char *qq = "";
  1344.  
  1345.     if (OutFile == NULL)
  1346.     OutFile = "a.out";
  1347.  
  1348.     sprintf(Buf, "ln -f %s -o %s", lfile, OutFile);
  1349.     run_cmd(Buf);
  1350.     return(0);
  1351. }
  1352.  
  1353. #endif
  1354.  
  1355.