home *** CD-ROM | disk | FTP | other *** search
/ CD Shareware Magazine 1996 December / CD_shareware_12-96.iso / DOS / Programa / CCDL122.ZIP / SOURCE / CMAIN.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-08-04  |  9.7 KB  |  458 lines

  1. /*
  2.  * 68K/386 32-bit C compiler.
  3.  *
  4.  * copyright (c) 1996, David Lindauer
  5.  * 
  6.  * This compiler is intended for educational use.  It may not be used
  7.  * for profit without the express written consent of the author.
  8.  *
  9.  * It may be freely redistributed, as long as this notice remains intact
  10.  * and sources are distributed along with any executables derived from them.
  11.  *
  12.  * The author is not responsible for damages, either direct or consequential,
  13.  * that may arise from use of this software.
  14.  *
  15.  * v1.5 August 1996
  16.  * David Lindauer, gclind01@starbase.spd.louisville.edu
  17.  *
  18.  * Credits to Mathew Brandt for original K&R C compiler
  19.  *
  20.  */
  21. #include        <stdio.h>
  22. #include                <malloc.h>
  23. #include                 <string.h>
  24. #include                "utype.h"    
  25. #include                "cmdline.h"    
  26. #include        "expr.h"
  27. #include        "c.h"
  28. #include        "gen.h"
  29. #include        "cglbdec.h"
  30.  
  31. extern unsigned _stklen = 4096*3;        /* Getline only eats up about 5 or 6K */
  32. #define DOS 1
  33. #ifdef DOS
  34. char *getenv(char *);
  35. #endif
  36. #define VERSION 120
  37.  
  38. typedef struct list {
  39.         struct list *link;
  40.         void *data;
  41. } LIST;
  42.  
  43. extern TABLE    tagtable;
  44. extern int      total_errors;
  45. extern int diagcount;
  46.  
  47. FILE *tempfil;
  48.  
  49. char *usage_text = " [+i/f+l/w/C/D/E/I/O/S] file list";
  50.  
  51. void bool_setup(char select, char *string);
  52. void err_setup(char select, char *string);
  53. void incl_setup(char select, char *string);
  54. void def_setup(char select, char *string);
  55. void codegen_setup(char select, char *string);
  56. void optimize_setup(char select, char *string);
  57. void warning_setup(char select, char *string);
  58. void parsefile(char select, char *string);
  59. ARGLIST ArgList[] = {
  60.   { 'i', ARG_BOOL, bool_setup },
  61.   { 'f', ARG_CONCATSTRING, parsefile },
  62.   { 'l', ARG_BOOL, bool_setup },
  63.   { 'w', ARG_CONCATSTRING, warning_setup },
  64.   { 'C', ARG_CONCATSTRING, codegen_setup },
  65.   { 'O', ARG_CONCATSTRING, optimize_setup },
  66.   { 'E', ARG_CONCATSTRING, err_setup },
  67.   { 'I', ARG_CONCATSTRING, incl_setup },
  68.     { 'D', ARG_CONCATSTRING, def_setup },
  69.   { 'S', ARG_BOOL, bool_setup },
  70.   { 0, 0, 0 }
  71. };
  72.  
  73. LIST *clist = 0;
  74. LIST *deflist = 0;
  75. int prm_stackcheck = FALSE;
  76. int prm_warning = TRUE;
  77. int prm_asmfile = TRUE;
  78. int prm_listfile = FALSE;
  79. int prm_largedata = FALSE;
  80. int prm_68020 = FALSE;
  81. int prm_maxerr = 25;
  82. int prm_diag = FALSE;
  83. int prm_bss = TRUE;
  84. int prm_cppfile = FALSE;
  85. int prm_packing = FALSE;
  86. int prm_revbits = FALSE;
  87. int prm_lines = TRUE;
  88. int prm_cplusplus = FALSE;
  89. int prm_cmangle = TRUE;
  90. int basear = 1, basedr = 1, basefr = 1;
  91. char *prm_searchpath = 0;
  92.  
  93. char     *infile,
  94.                 listfile[40],
  95.                 outfile[40],
  96.                                 cppfile[40];
  97.  
  98. static char *tempFile;
  99.  
  100. void bool_setup(char select, char *string)
  101. {
  102.     int bool = (int)string;
  103.     if (select == 'S')
  104.         prm_asmfile = bool;
  105.   if (select == 'l')
  106.         prm_listfile = bool;
  107.     if (select == 'i')
  108.         prm_cppfile = bool;
  109. }
  110. void codegen_setup(char select, char *string)
  111. {
  112.         int bool = TRUE;
  113.         while (*string) {
  114.             switch (*string) {
  115. #ifndef i386
  116.                 case 'L':
  117.                     prm_largedata = bool;
  118.                     break;
  119.                 case '2':
  120.                     prm_68020 = bool;
  121.                     break;
  122. #endif
  123.                 case 'd':
  124.                     prm_diag = bool;
  125.                     break;
  126.                 case 'p':
  127.                     prm_packing = bool;
  128.                     break;
  129.                 case 'r':
  130.                     prm_revbits = bool;
  131.                     break;
  132.                 case 'b':
  133.                     prm_bss=bool;
  134.                     break;
  135.                 case 'l':
  136.                     prm_lines = bool;
  137.                     break;
  138.                 case 'm':
  139.                     prm_cmangle = bool;
  140.                     break;
  141.                 case 'S':
  142.                     prm_stackcheck = bool;
  143.                     break;
  144.                 case '-':
  145.                     bool = FALSE;
  146.                     break;
  147.                 case '+':
  148.                     bool = TRUE;
  149.                     break;
  150.             }
  151.             string++;
  152.         }
  153. }
  154. void optimize_setup(char select, char *string)
  155. {
  156.         int bool = TRUE;
  157.         while (*string) {
  158.             switch (*string) {
  159.                 case 'R':
  160.                     string++;
  161.                     while (*string && *string != '+' && *string != '-') {
  162.                         switch (*string++) {
  163.                             case 'a':
  164.                                 basear = bool;
  165.                                 break;
  166.                             case 'd':
  167.                                 basedr = bool;
  168.                                 break;
  169.                             case 'f':
  170.                                 basefr = bool;
  171.                                 break;
  172.                         }
  173.                         if (!*string)
  174.                             return;
  175.                     }
  176.                     break;
  177.                 case '-':
  178.                     bool = FALSE;
  179.                     break;
  180.                 case '+':
  181.                     bool = TRUE;
  182.                     break;
  183.             }
  184.             string++;
  185.         }
  186. }
  187. void err_setup(char select, char *string)
  188. {
  189.     prm_maxerr = atoi(string);
  190. }
  191. void incl_setup(char select, char * string)
  192. {
  193.     prm_searchpath = malloc(strlen(string)+1);
  194.     strcpy(prm_searchpath,string);
  195. }
  196. void def_setup(char select, char *string)
  197. {
  198.     char *s = malloc(strlen(string)+1);
  199.     LIST *l = malloc(sizeof(LIST));
  200.     strcpy(s,string);
  201.     l->link = deflist;
  202.     deflist = l;
  203.     l->data = s;
  204. }
  205. void setglbdefs(void)
  206. {
  207.     LIST *l = deflist;
  208.     while (l) {
  209.         glbdefine(l->data);
  210.         l = l->link;
  211.     }
  212.     if (prm_cplusplus) {
  213.         glbdefine("__cplusplus");
  214.     }
  215. #ifdef i386
  216.     glbdefine("_i386_");
  217. #else
  218.     glbdefine("_m68k_");
  219. #endif
  220. }
  221. void InsertAnyFile(FILE *inf, FILE *outf, char *filename, char *path, int drive)
  222. {
  223.   char *newbuffer, buffer[100],*p = buffer;
  224.     LIST *r = &clist;
  225.  
  226.     if (drive != -1) {
  227.         *p++ = drive + 'A';
  228.         *p++ = ':';
  229.     }
  230.     if (path) {
  231.         strcpy(p,path);
  232.         strcat(p,"\\");
  233.     }
  234.     else
  235.         *p = 0;
  236.   /* Allocate buffer and make .C if no extension */
  237.     strcat(buffer,filename);
  238.   AddExt(buffer,".C");
  239.   newbuffer = (char *) malloc(strlen(buffer) + 1);
  240.   strcpy(newbuffer,buffer);
  241.  
  242.   /* Insert file */
  243.     while (r->link)
  244.         r = r->link;
  245.     r->link = malloc(sizeof(LIST));
  246.     r = r->link;
  247.     r->link = 0;
  248.     r->data = newbuffer;
  249. }
  250. void dumperrs(FILE *file);
  251. void setfile(char *buf,char *orgbuf,char *ext)
  252. {
  253.     char *p = strrchr(orgbuf,'\\');
  254.     if (!p) p = orgbuf;
  255.     else p++;
  256.     strcpy(buf,p);
  257.     StripExt(buf);
  258.     AddExt(buf,ext);
  259. }
  260. int parse_arbitrary(char *string)
  261. {
  262.     char *argv[40];
  263.     int rv;
  264.     int argc = 1;
  265.     if (!string || !*string)
  266.         return 1;
  267.     while (1) {
  268.         while (*string == ' ') 
  269.             string++;
  270.         if (!*string)
  271.             break;
  272.         argv[argc++] = string;
  273.         while (*string && *string != ' ') string++;
  274.         if (!*string)
  275.             break;
  276.         *string = 0;
  277.         string++;
  278.     }
  279.   rv = parse_args(&argc,argv,TRUE);
  280.     if (argc !=1)
  281.         fatal("Filename present in secondary arguments");
  282.     return rv;
  283. }
  284. void parsefile(char select, char *string)
  285. {
  286.     FILE *temp = 0;
  287.     if (!(temp = fopen(string,"r")))
  288.         fatal("Argument file not found");
  289.     while (!feof(temp)) {
  290.         char buf[256];
  291.         buf[0] = 0;
  292.         fgets(buf,256,temp);
  293.         if (buf[strlen(buf)-1] == '\n')
  294.             buf[strlen(buf)-1] = 0;
  295.         if (!parse_arbitrary(buf))
  296.             break;
  297.     }
  298.     fclose(temp);
  299. }
  300. #ifdef DOS
  301. void addinclude(void)
  302. {
  303.     char *string = getenv("CCINCL");
  304.     if (string && string[0]) {
  305.         char temp[500];
  306.         strcpy(temp,string);
  307.         if (prm_searchpath) {
  308.             strcat(temp,";");
  309.             strcat(temp,prm_searchpath);
  310.             free(prm_searchpath);
  311.         }
  312.         prm_searchpath = malloc(strlen(temp)+1);
  313.         strcpy(prm_searchpath,temp);
  314.     }
  315. }
  316. int parseenv(char *name)
  317. {
  318.     char *string = getenv(name);
  319.     return parse_arbitrary(string);
  320. }
  321. #endif
  322. int main(int argc,char *argv[])
  323. {
  324.     char buffer[40];
  325.     char *p;
  326. #ifdef i386
  327.   banner(VMSG("CC386"));
  328. #else
  329.   banner(VMSG("CC68K"));
  330. #endif
  331.   outfile[0] = 0;
  332.  
  333. #ifdef DOS
  334. #ifdef i386
  335.   if (!parseenv("CC386"))
  336. #else
  337.   if (!parseenv("CC68K"))
  338. #endif
  339.     usage(argv[0]);
  340. #endif
  341.   if (!parse_args(&argc, argv, TRUE) || (argc == 1))
  342.     usage(argv[0]);
  343.  
  344.     if (prm_68020)
  345.         prm_largedata = FALSE;
  346.  
  347. #ifdef DOS
  348.     addinclude();
  349. #endif
  350.   // Scan the command line for file names or response files
  351.      FileRecurse(argc-1,&argv[1],0,InsertAnyFile,".C",FALSE);
  352.  
  353.     while (clist) {
  354.         memini();
  355.       symini();
  356.         kwini();
  357.         cglbini();
  358.         initini();
  359.         preprocini();
  360.         exprini();
  361.         declini();
  362.         funcini();
  363.         peepini();
  364.         genstmtini();
  365.         outcodeini();
  366.         regini();
  367.         printf("file: %s\n",clist->data);
  368.       strcpy(buffer,clist->data);
  369. #ifdef i386
  370.         setfile(outfile,buffer,".ASM");
  371. #else
  372.         setfile(outfile,buffer,".SRC");
  373. #endif
  374.         setfile(cppfile,buffer,".I");
  375.         setfile(listfile,buffer,".LST");
  376.         prm_cplusplus = FALSE;
  377.       AddExt(buffer,".C");
  378.         p = strrchr(buffer,'.');
  379.         if (*(p-1) != '.') {
  380.             if (p[1] == 'c' || p[1] == 'C')
  381.                 if (p[2] == 'p' || p[2] == 'P')
  382.                     if (p[3] == 'p' || p[3] == 'P')
  383.                         prm_cplusplus = TRUE;
  384.         }
  385.         infile = litlate(buffer);
  386.  
  387. #ifdef i386
  388.         if (prm_asmfile) {
  389.             if (!(tempfil = fopen(tempFile = tmpnam(0),"w+")))
  390.                 fatal("Error opening temp file");
  391.         }
  392. #endif
  393.         if (prm_cppfile) {
  394.             if (!(cppFile = fopen(cppfile,"w")))
  395.                 fatal("Can't open cpp file %s",cppfile);
  396.         }
  397.       if (!(inputFile = fopen(infile,"r")))
  398.         fatal("Can't open input file %s",infile);
  399.         if (prm_asmfile) {
  400.           if (!(outputFile = fopen(outfile,"w"))) {
  401.             fclose(inputFile);
  402.             fatal("Can't open output file %s",outfile);
  403.           }
  404.         }
  405.       if (prm_listfile)
  406.           if (!(listFile = fopen(listfile,"w"))) {
  407.             fclose(inputFile);
  408.             fclose(outputFile);
  409.             fatal("Can't open list file %s",listfile);
  410.           }
  411.        lineno = 0;
  412.         initerr();
  413.       initsym();
  414.         setglbdefs();
  415.       getch();
  416.       getsym();
  417.       compile();
  418.         initrundown();
  419.       putexterns();
  420.         dumperrs(stdout);
  421.         summary();
  422.       release_global();
  423.       fclose(inputFile);
  424.         if (prm_asmfile) {
  425.           fclose(outputFile);
  426. #ifdef i386
  427.             fclose(tempfil);
  428.             remove(tempFile);
  429. #endif
  430.         }
  431.       if (prm_listfile)
  432.         fclose(listFile);
  433.       if (prm_cppfile)
  434.         fclose(cppFile);
  435.         clist = clist->link;
  436.     }
  437.   if (total_errors)
  438.        return(1);
  439.   else
  440.     return(0);
  441. }
  442. void dumperrs(FILE *file)
  443. {
  444.     if (diagcount)
  445.         fprintf(file,"%d Diagnostics detected\n",diagcount);
  446.     if (total_errors)
  447.         fprintf(file,"%d Total errors\n",total_errors);
  448. }
  449. void summary(void)
  450. {       
  451.     if (prm_listfile) {
  452.     fprintf(listFile,"\f\n *** global scope symbol table ***\n\n");
  453.     list_table(&gsyms,0);
  454.     fprintf(listFile,"\n *** structures and unions ***\n\n");
  455.     list_table(&tagtable,0);
  456.         dumperrs(listFile);
  457.   }
  458. }