home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_progs / prog_c / cc.lzh / CC / MANX / CC.C < prev    next >
Encoding:
C/C++ Source or Header  |  1991-11-01  |  10.2 KB  |  479 lines

  1. /* Z editor options
  2. :ma=1
  3. :ts=6
  4. :bk=0
  5. :wm=0
  6. */
  7.  
  8. /*
  9.     This program, both executable and sources, are
  10.     Copyright 1986, Jay Ts,  Box 890 West Oneonta NY 13861.
  11.     You may copy, distribute, alter, and use them, but absolutely no
  12.     permission is granted to remove copyright notices from them or
  13.     distribute them, in whole or in part, as, or as part of, a
  14.     commercial product.
  15. */
  16.  
  17. /* put copyright notice in executable */
  18. char copyright_message[] = "\nCopyright 1986, Jay Ts\n";
  19.  
  20. #include "stdio.h"
  21.  
  22. #define isdigit(x)     ((x) >= '0' && (x) <= '9' ? 1 : 0)
  23.  
  24. /* add option to string of options */
  25.  
  26. #define addopt(x,opt)        \
  27. {                    \
  28.     strcat((x)," ");        \
  29.     strcat((x),(opt));    \
  30.     strcat((x)," ");        \
  31. }
  32.  
  33. extern char *getenv(), *mktemp();
  34. extern int geterrs();
  35.  
  36. char pname[32];    /* the name of the final output file */
  37. char tfile[32];    /* temp file defined by CCTEMP environment variable */
  38. char errfile[32];    /* file to which error messages are written */
  39.  
  40. char cli[256];    /* CLI command string */
  41. char ccopts[128]; /* strings of options for each phase */
  42. char asopts[128];
  43. char lnopts[128];
  44.  
  45. /* lists of source file names, and number of files in each list */
  46.  
  47. #define MFIL 32
  48. char cfiles[MFIL][32], afiles[MFIL][32], lfiles[MFIL][32];
  49. int numcfiles = 0, numafiles = 0, numlfiles = 0;
  50.  
  51. /* flags */
  52.  
  53. int dontlink = 0;  /* don't link, just leave .o file in current directory */
  54. int printonly = 0; /* print what is to be done, but don't do it */
  55. int lintflag = 0;  /* allow compiler to print warning messages, then quit */
  56. int zdefined = 0;  /* -z option has been defined on command line */
  57. int edefined = 0;  /* -e option has been defined on command line */
  58.  
  59. main(argc,argv)
  60. int argc;
  61. char *argv[];
  62. {
  63.     int i, l;
  64.     char *s;
  65.  
  66.     if(argc < 2)
  67.     {
  68.         printf("usage: cc [-opts] { Csrc.c | Asrc.a | objfile.o }\n");
  69.         exit(0);
  70.     }
  71.  
  72.     if(argv[1][0] == '?')   /* standard AmigaDOS help query: cc ? */
  73.     {
  74.         if( ! getenv("DOC"))
  75.         {
  76.             printf("cc: can't help, DOC environment variable not set\n");
  77.             exit(0);
  78.         }
  79.         else
  80.         {
  81.             strcpy(cli,"more <* >* ");
  82.             strcat(cli,getenv("DOC"));
  83.             strcat(cli,"cc.doc");
  84.             Execute(cli,0L,0L);
  85.             exit(0);
  86.         }
  87.     }
  88.  
  89.     /* make sure environment variables are set */
  90.  
  91.     if( ! getenv("ML")) printf("environment variable ML unset\n");
  92.     if( ! getenv("CLIB")) printf("environment variable CLIB unset\n");
  93.     if( ! getenv("CCTEMP")) printf("environment variable CCTEMP unset\n");
  94.     if( ! getenv("INCLUDE")) printf("environment variable INCLUDE unset\n");
  95.  
  96.     /* set up temporary file for error output */
  97.  
  98.     strcpy(tfile, getenv("CCTEMP"));
  99.     strcpy(errfile,tfile);
  100.     strcat(errfile,"ccom_XXXX");
  101.     if(mktemp(errfile) != errfile)
  102.     {
  103.         printf("cc: mktemp() failed\n");
  104.         exit(1);
  105.     }
  106.  
  107.     /* initialize options strings for three stages */
  108.     strcpy(ccopts, " -B -i");
  109.     strcat(ccopts, getenv("INCLUDE"));
  110.     strcat(ccopts, "/manx ");
  111.     strcpy(asopts, "");
  112.     strcpy(lnopts, "");
  113.  
  114.     /*
  115.         Process arguments for this program.  They are either
  116.         options or file names.
  117.  
  118.         Note that these are case sensitive for T/t C/c and F/f options.
  119.     */
  120.  
  121.     for(i = 1; i < argc; i++)
  122.     {
  123.         Chk_Abort();
  124.         if(argv[i][0] == '-' || argv[i][0] == '+') /* an option */
  125.         {
  126.             s = argv[i];
  127.             switch(s[1])
  128.             {
  129.                 case 'p':
  130.                 case 'P':
  131.                     printonly = 1;
  132.                     break;
  133.                 case 'v':
  134.                 case 'V':
  135.                     addopt(lnopts,s);
  136.                     addopt(asopts,s);
  137.                     break;
  138.                 case 'i':
  139.                 case 'I':
  140.                     if(s[0] == '-') addopt(asopts,s);
  141.                     addopt(ccopts,s);
  142.                     break;
  143.                 case 'c':    /* Lower case only! */
  144.                     if(s[0] == '-') dontlink = 1;
  145.                     else
  146.                     {
  147.                         addopt(ccopts,s);
  148.                         s[0] = '-';
  149.                         addopt(asopts,s);
  150.                     }
  151.                     break;
  152.                 case 'd':
  153.                 case 'D':
  154.                     if(s[0] == '-') addopt(ccopts,s)
  155.                     else
  156.                     {
  157.                         addopt(ccopts,s);
  158.                         s[0] = '-';
  159.                         addopt(asopts,s);
  160.                     }
  161.                     break;
  162.                 case 's':
  163.                 case 'S':
  164.                     if(strlen(s) == 2)
  165.                     {
  166.                         dontlink = lintflag = 1;
  167.                         addopt(ccopts,"-a");
  168.                     }
  169.                     else addopt(asopts,s);
  170.                     break;
  171.                 case 'e':
  172.                 case 'E':
  173.                     if(isdigit(s[2]))
  174.                     {
  175.                         edefined = 1;
  176.                         addopt(ccopts,s)
  177.                     }
  178.                     else addopt(asopts,s);
  179.                     break;
  180.                 case 'l':
  181.                 case 'L':
  182.                     if(s[0] == '+'
  183.                     || s[0] == '-' && isdigit(s[2])) addopt(ccopts,s)
  184.                     else if(strlen(s) < 3) addopt(asopts,s)
  185.                     else
  186.                     {
  187.                         addopt(lnopts,s);
  188.                         addlibopt(&s[2]);
  189.                     }
  190.                     break;
  191.                 case 'z':
  192.                 case 'Z':
  193.                     if(isdigit(s[2]))
  194.                     {
  195.                         zdefined = 1;
  196.                         addopt(ccopts,s);
  197.                     }
  198.                     else addopt(asopts,s);
  199.                     break;
  200.                 case 'a':
  201.                 case 'A':
  202.                 case 'h':
  203.                 case 'H':
  204.                     dontlink = 1;
  205.                 case 't':    /* Lower case only! */
  206.                 case 'y':
  207.                 case 'Y':
  208.                 case 'b':
  209.                 case 'B':
  210.                 case 'q':
  211.                 case 'Q':
  212.                     addopt(ccopts,s);
  213.                     break;
  214.                 case 'n':
  215.                 case 'N':
  216.                     addopt(asopts,s);
  217.                     break;
  218.                 case 'T':    /* Upper case only! */
  219.                 case 'w':
  220.                 case 'W':
  221.                     addopt(lnopts,s);
  222.                     break;
  223.                 case 'f':    /* Lower case only! */
  224.                     addopt(lnopts,s);
  225.                     s = argv[++i];
  226.                     addopt(lnopts,s);
  227.                     break;
  228.                 case 'O':
  229.                 case 'o':
  230.                 case 'C':    /* Upper case only! */
  231.                 case 'F':    /* Upper case only! */
  232.                     addopt(lnopts,s);
  233.                     break;
  234.                 default:
  235.                     printf("bad option: \"%s\"\n", argv[i]);
  236.                     exit(1);
  237.                     break;
  238.             }
  239.         }
  240.         else  /* a file -- add to appropriate list */
  241.         {
  242.             l = strlen(argv[i]);
  243.             if(argv[i][l-2] == '.')
  244.             {
  245.                 /*
  246.                     The first file in the argument list is
  247.                     special -- the output of the linker is
  248.                     named after it.  This name is held
  249.                     in the string pname.
  250.                 */
  251.  
  252.                 switch(argv[i][l-1])
  253.                 {
  254.                     case 'c':
  255.                         if(!numcfiles && !numafiles && !numlfiles)
  256.                             strncpy(pname,argv[i],l-2);
  257.                         if(numcfiles == MFIL) toomany(".c");
  258.                         strncpy(cfiles[numcfiles],argv[i],l-2);
  259.                         ++numcfiles;
  260.                         break;
  261.                     case 'a':
  262.                         if(!numcfiles && !numafiles && !numlfiles)
  263.                             strncpy(pname,argv[i],l-2);
  264.                         if(numafiles == MFIL) toomany(".a");
  265.                         strncpy(afiles[numafiles],argv[i],l-2);
  266.                         ++numafiles;
  267.                         break;
  268.                     case 'o':
  269.                         if(!numcfiles && !numafiles && !numlfiles)
  270.                             strncpy(pname,argv[i],l-2);
  271.                         if(numlfiles == MFIL) toomany(".o");
  272.                         strncpy(lfiles[numlfiles],argv[i],l-2);
  273.                         ++numlfiles;
  274.                         break;
  275.                     default:
  276.                         printf("not a .[cao] file: \"%s\"\n",
  277.                             argv[i]);
  278.                         exit(1);
  279.                         break;
  280.                 }
  281.             }
  282.             else
  283.             {
  284.                 printf("cc: not a .[cao] file: \"%s\"\n", argv[i]);
  285.                 exit(1);
  286.             }
  287.         }
  288.     }
  289.  
  290.     if(!numcfiles && !numafiles && !numlfiles)
  291.     {
  292.         printf("cc: no files to compile, assemble or link\n");
  293.         exit(1);
  294.     }
  295.  
  296.     /* the below are default options which were found to be useful */
  297.  
  298.     if( ! zdefined) strcat(ccopts, " -z4000 ");    /* larger string table */
  299.     if( ! edefined) strcat(ccopts, " -e200 ");    /* larger expr space */
  300.     if( ! lintflag) strcat(ccopts, " -s ");    /* don't print warnings */
  301.  
  302.     /* run compilation stage: compile .c files into .o files */
  303.  
  304.     for(i = 0; i < numcfiles; ++i) /* do for each .c file on command line */
  305.     {
  306.         strcpy(cli,"c:");            /* build command string */
  307.         strcat(cli,"ccom >");        /* COMPILER */
  308.         strcat(cli,errfile);        /* add error redirection */
  309.         strcat(cli,ccopts);        /* add options */
  310.         if( ! dontlink || lintflag)    /* add output file name */
  311.         {
  312.             strcat(cli," -o ");
  313.             strcat(cli,tfile);
  314.             strcat(cli,cfiles[i]);
  315.             strcat(cli,".o ");
  316.         }
  317.         strcat(cli,cfiles[i]);        /* add .c source file name */
  318.         strcat(cli,".c");
  319.  
  320.         if(printonly) printf("%s\n",cli);
  321.         else
  322.         {
  323.             Chk_Abort();
  324.             Execute(cli,0L,0L);
  325.             if(geterrs()) cleanup(20);
  326.         }
  327.     }
  328.  
  329.     /* assembly stage: assemble files on command line ending with ".a" */
  330.  
  331.     for(i = 0; i < numafiles; i++)
  332.     {
  333.         strcpy(cli,"c:");            /* build command string */
  334.         strcat(cli,"as >");        /* ASSEMBLER */
  335.         strcat(cli,errfile);        /* redirect output */
  336.         strcat(cli,asopts);        /* add options */
  337.         if( ! dontlink)            /* add output name */
  338.         {
  339.             strcat(cli," -o ");
  340.             strcat(cli,tfile);
  341.             strcat(cli,afiles[i]);
  342.             strcat(cli,".o ");
  343.         }
  344.         strcat(cli,afiles[i]); /* add source file name */
  345.         strcat(cli,".a");
  346.  
  347.         if(printonly) printf("%s\n",cli);
  348.         else
  349.         {
  350.             Chk_Abort();
  351.             Execute(cli,0L,0L);
  352.             if(geterrs()) cleanup(20);
  353.         }
  354.     }
  355.  
  356.     /* LINK */
  357.  
  358.     if( ! dontlink )
  359.     {
  360.         addlibopt("c");    /* by default, always load with c.lib */
  361.  
  362.         strcpy(cli,"c:");            /* build CLI command string */
  363.         strcat(cli,"ln >");        /* LINKER */
  364.         strcat(cli,errfile);        /* add error redirection */
  365.  
  366.         for(i = 0; i < numcfiles; i++) /* add .o files from .c compile */
  367.         {
  368.             strcat(cli, " ");
  369.             strcat(cli, tfile);
  370.             strcat(cli, cfiles[i]);
  371.             strcat(cli, ".o");
  372.         }
  373.  
  374.         for(i = 0; i < numafiles; i++) /* add .o files from .a assembly */
  375.         {
  376.             strcat(cli, " ");
  377.             strcat(cli, tfile);
  378.             strcat(cli, afiles[i]);
  379.             strcat(cli, ".o");
  380.         }
  381.  
  382.         for(i = 0; i < numlfiles; i++) /* add .o files from arg. list */
  383.         {
  384.             strcat(cli, " ");
  385.             strcat(cli, lfiles[i]);
  386.             strcat(cli, ".o");
  387.         }
  388.  
  389.         strcat(cli, " -o ");    /* name output file named by first ... */
  390.         strcat(cli, pname);    /* ... source file listed in arguments */
  391.         strcat(cli, lnopts);    /* add options */
  392.         strcat(cli, " -lc");    /* always link with std. C library */
  393.  
  394.         if(printonly) printf("%s\n",cli);
  395.         else
  396.         {
  397.             Chk_Abort();
  398.             Execute(cli,0L,0L);
  399.             geterrs();
  400.         }
  401.     }
  402.  
  403.     cleanup(0);
  404. }
  405.  
  406. cleanup(rval)
  407. int rval;
  408. {
  409.     int i;
  410.     char delcom[32];
  411.  
  412.     /* delete object files in CCTEMP that were made by compile */
  413.  
  414.     if( ! dontlink || lintflag)
  415.     for(i = 0; i < numcfiles; i++)
  416.     {
  417.         strcpy(delcom,tfile);
  418.         strcat(delcom,cfiles[i]);
  419.         strcat(delcom,".o");
  420.  
  421.         if(printonly) printf("delete %s\n",delcom);
  422.         DeleteFile(delcom);
  423.     }
  424.  
  425.     /* delete object files in CCTEMP that were made by assembly */
  426.  
  427.     if( ! dontlink)
  428.     for(i = 0; i < numafiles; i++)
  429.     {
  430.         strcpy(delcom,tfile);
  431.         strcat(delcom,afiles[i]);
  432.         strcat(delcom,".o");
  433.  
  434.         if(printonly) printf("delete %s\n",delcom);
  435.         DeleteFile(delcom);
  436.     }
  437.  
  438.     /* delete intermediate error file */
  439.  
  440.     DeleteFile(errfile);
  441.  
  442.     exit(rval);
  443. }
  444.  
  445. /* copy library file from ML into CLIB, if it's not already there */
  446.  
  447. addlibopt(s)
  448. char *s;
  449. {
  450.     char libname[32], envlibname[64], srclibname[64], cpycom[64];
  451.  
  452.     strcpy(libname, s);
  453.     strcat(libname, ".lib");
  454.  
  455.     strcpy(srclibname,getenv("ML"));
  456.     strcat(srclibname, libname);
  457.  
  458.     strcpy(envlibname, getenv("CLIB"));
  459.     strcat(envlibname, libname);
  460.  
  461.     if(access(envlibname,0))
  462.     {
  463.         strcpy(cpycom, "copy ");
  464.         strcat(cpycom, srclibname);
  465.         strcat(cpycom, " ");
  466.         strcat(cpycom, envlibname);
  467.         if(printonly) printf("%s\n",cpycom);
  468.         else Execute(cpycom,0L,0L);
  469.     }
  470. }
  471.  
  472. toomany(s)
  473. char *s;
  474. {
  475.     printf("cc: can't handle more than %d ",MFIL);
  476.     printf("%s files\n",s);
  477.     exit(10);
  478. }
  479.