home *** CD-ROM | disk | FTP | other *** search
/ Total Destruction / Total_Destruction.iso / addons / Lccwin32.exe / Lccwin32 / lccpub / src / Main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-11-11  |  12.6 KB  |  460 lines

  1. #include "c.h"
  2. #include <io.h>
  3. #include <fcntl.h>
  4. #include <stdio.h>
  5. #include <time.h>
  6. #include <signal.h>
  7. int mmx=0;
  8. FILE *AssemblerFile;
  9. static void compile ARGS((char *));
  10. static int doargs ARGS((int, char **));
  11. static void emitYYnull ARGS((void));
  12. static void typestab ARGS((Symbol, void *));
  13. static void globaltab(Symbol p,void *cl);
  14. static void statictab(Symbol p,void *cl);
  15. static void CreateXrefFile(char *name);
  16. extern void SetFastCompile(Interface *);
  17. #ifndef _S_IWRITE
  18. #define _S_IWRITE 0x200
  19. #endif
  20. Interface      *IR = NULL;
  21. FILE *xrefFile;
  22. char *xrefFileName=NULL;
  23. char *ilFileName=NULL;
  24. FILE *ilFile;
  25. static char    *infile, *outfile;
  26. int             outputLine = 1; // whether to output #line or just # in cpp
  27. int                verbose=0;
  28. int             Aflag = 0;          /* >= 0 if -A specified */
  29. int             Pflag;          /* != 0 if -P specified */
  30. int             Xflag=1;          /* != 0 if -X specified to permit
  31.                                  extensions */
  32. int             glevel=0;         /* == [0-9] if -g[0-9] specified */
  33. int             xref=0;           /* != 0 for cross-reference data */
  34. Symbol          YYnull;         /* _YYnull  symbol if -n or -nvalidate
  35.                                  specified */
  36. Symbol          YYcheck;        /* _YYcheck symbol if -nvalidate,check
  37.                                  specified */
  38. int Savedargc;
  39. char **Savedargv;
  40. int GenerateAsm = 0;
  41. int GenerateCpp = 0;
  42. int IntermediateLanguageFile;
  43. #ifdef PEEPHOLE
  44. int OptimizeFlag = 0;
  45. #endif
  46. clock_t AsmTime=0,CppTime = 0;
  47.  
  48. static int IsAssemblerFile(char *fname)
  49. {
  50.     char *p;
  51.  
  52.     p = strrchr(fname,'.');
  53.     if (p == NULL) return(0);
  54.     p++;
  55.     if (*p != 'a' && *p != 'A') return(0);
  56.     p++;
  57.     if (*p != 's' && *p != 'S') return(0);
  58.     p++;
  59.     if (*p != 'm' && *p != 'M') return(0);
  60.     p++;
  61.     if (*p) return(0);
  62.     return(1);
  63. }
  64. static char *suffix(char *infile,char *s)
  65. {
  66.     char *outfile;
  67.     char *p = strrchr(infile,'\\');
  68.  
  69.     if (p) p++;
  70.     else p = infile;
  71.     outfile = malloc(strlen(p)+10);
  72.     memset(outfile,0,strlen(p)+10);
  73.     strcpy(outfile,p);
  74.     p = strrchr(outfile,'.');
  75.     if (p) *p = 0;
  76.     strcat(outfile,s);
  77.     return outfile;
  78. }
  79. void AssembleFile(char *fname)
  80. {
  81.     FILE *f;
  82.     char *buffer;
  83.     int s;
  84.  
  85.     f = fopen(fname,"r");
  86.     if (f == NULL) {
  87.         printf("Impossible to open %s\n",fname);
  88.         return;
  89.     }
  90.     glevel = 0;
  91.     AsmInit(fname);
  92.     buffer = malloc(4097);
  93.     while (!feof(f)) {
  94.         s = fread(buffer,1,4096,f);
  95.         buffer[4096] = 0;
  96.         AsmReadBuffer(buffer,s);
  97.     }
  98.     free(buffer);
  99.     AsmReadBuffer("",0);
  100.     WriteCoffFile();
  101. }
  102. extern int _stdcall SetConsoleCtrlHandler(void *,int);
  103. extern char *OutputFileName;
  104. int _stdcall CtrlHandler(unsigned long event)
  105. {
  106.     printf("lcc: break. Erasing %s\n",OutputFileName);
  107.     unlink(OutputFileName);
  108.     exit(1);
  109.     return 0;
  110. }
  111.  
  112. static void trap(int sig)
  113. {
  114.     fatal("","Trap signal received. Compilation aborts\n",0);
  115. }
  116.  
  117. extern long CharsRead;
  118. extern int _stdcall GetLastError(void);
  119. extern int NrOfSpills;
  120. int             main(int argc,char *argv[])
  121. {
  122.     int i;
  123.     clock_t t0,t1;
  124.     FILE *outf;
  125.     char namebuf[256];
  126.     extern int ReadTime;
  127.  
  128.     t0 = clock();
  129.     signal(SIGSEGV,trap);
  130.     IR = bindings[0].ir;
  131.     Savedargc = argc;
  132.     Savedargv = (char **)malloc(argc * sizeof(char *));
  133.     for (i=0; i<argc;i++) {
  134.         Savedargv[i] = malloc(strlen(argv[i])+1);
  135.         strcpy(Savedargv[i],argv[i]);
  136.     }
  137.     CppInit();
  138.     argc = doargs(argc, argv);
  139.     if (infile == NULL) {
  140.         fprintf(stderr,"no input files\n");
  141.         return(-1);
  142.     }
  143.     SetConsoleCtrlHandler((void *)CtrlHandler,1);
  144.     if (IntermediateLanguageFile && infile) {
  145.         ilFileName = suffix(infile,".lil");
  146.         ilFile = fopen(ilFileName,"w");
  147.  
  148.     }
  149.     if (IsAssemblerFile(infile)) {
  150.         AssembleFile(infile);
  151.         goto doexit;
  152.     }
  153. #if 0
  154.     if (!OptimizeFlag)
  155.         SetFastCompile(IR);
  156. #endif
  157.     StartCpp(infile);
  158.     if (GenerateCpp) {
  159.         char *p = strrchr(infile,'\\');
  160.         unsigned char *buffer;
  161.  
  162.         if (p) p++;
  163.         else p = infile;
  164.         outfile = malloc(strlen(p)+10);
  165.         memset(outfile,0,strlen(p)+10);
  166.         strcpy(outfile,p);
  167.         p = strrchr(outfile,'.');
  168.         if (p) *p = 0;
  169.         strcat(outfile,".i");
  170.         outf = fopen(outfile,"w");
  171.         if (outf == NULL) {
  172.             fprint(2, "%s: can't write `%s'\n",
  173.                    argv[0], outfile);
  174.             exit(1);
  175.         }
  176.         buffer = malloc(16000);
  177.         while ((i=ReadFromCpp(buffer,16000)) != 0) {
  178.             fwrite(buffer,i,1,outf);
  179.         }
  180.         fclose(outf);
  181.         free(buffer);
  182.         t1 = clock();
  183.         printf("Cpp time: %g sec.\n",(double)(t1-t0)/1000.0);
  184.         SetConsoleCtrlHandler((void *)CtrlHandler,0);
  185.         return(0);
  186.     }
  187.     AsmInit(infile);
  188.     typeInit();
  189.     if (outfile == NULL) {
  190.         if (GenerateAsm && infile) {
  191.             outfile = suffix(infile,".asm");
  192.         }
  193.         else if (GenerateAsm) outfile = tmpnam(NULL);
  194.     }
  195.     if (GenerateAsm && outfile) {
  196.         AssemblerFile = fopen(outfile,"w");
  197.         if (AssemblerFile == NULL) {
  198.             printf("%s: can't write `%s: error %d'\n",
  199.                    argv[0], outfile,GetLastError());
  200.             exit(1);
  201.         }
  202.     }
  203.     if (xref) {
  204.         CreateXrefFile(xrefFileName);
  205.     }
  206.     inputInit();
  207.     outputInit();
  208.     if (errfd != 2) {
  209.     sprintf(namebuf,"%s:\n",infile);
  210.     write(errfd,namebuf,strlen(namebuf));
  211.     }
  212.     t = gettok();
  213.     (*IR->progbeg) (argc, argv);
  214.     if (IR->stabinit)
  215.         (*IR->stabinit) (firstfile, argc, argv);
  216.     program();
  217.     if (events.end)
  218.         apply(events.end, NULL, NULL);
  219.     memset(&events, 0, sizeof events);
  220.     emitYYnull();
  221.     CheckStaticUses();
  222.     if (xref && xrefFile) {
  223.         Symbol          symroot = NULL;
  224.         Coordinate      src;
  225.         foreach(types, GLOBAL, typestab, &symroot);
  226.         foreach(identifiers, GLOBAL, typestab, &symroot);
  227.         foreach(globals,GLOBAL,globaltab,&symroot);
  228.         foreach(globals,GLOBAL,statictab,&symroot);
  229.         src.file = firstfile;
  230.         src.x = 0;
  231.         src.y = lineno;
  232.         if (IR->stabend)
  233.             (*IR->stabend) (&src, symroot,
  234.                             ltov(&loci, PERM),
  235.                             ltov(&symbols, PERM), NULL);
  236.         DumpDefines();
  237.         DumpDefinedFunctions();
  238.         fclose(xrefFile);
  239.     }
  240.     finalize();
  241.     (*IR->progend) ();
  242.     outflush();
  243.     deallocate(PERM);
  244.     AsmReadBuffer("",0);
  245.     if (IntermediateLanguageFile)
  246.         fclose(ilFile);
  247.     if (errcnt == 0) WriteCoffFile();
  248.     t1 = clock();
  249.     if (verbose)
  250.         printf("Spills:%d Chars read: %d,Memory used:%d,Time = %g sec.\n",
  251.             NrOfSpills,CharsRead,memused,(double)(t1-t0)/1000.0);
  252.     if (errcnt > 0 || warningCount > 0) {
  253.         printf("%d errors, %d warnings\n",errcnt,warningCount);
  254.     }
  255. doexit:
  256.     if (GenerateAsm) fclose(AssemblerFile);
  257.     fflush(stdout);
  258.     if (outfd) close(outfd);
  259.     if (errfd) close(errfd);
  260.     SetConsoleCtrlHandler((void *)CtrlHandler,0);
  261.     return errcnt > 0;
  262. }
  263.  
  264. /* compile - compile str */
  265. static void     compile(char *str)
  266. {
  267.     inputstring(str);
  268.     t = gettok();
  269.     program();
  270. }
  271. extern int Mflag;
  272. extern int dotokfile;
  273. extern int TraceDependencies;
  274. extern void DoCmdLineDirective(char *,int);
  275. extern void CmdLineAddInclude(char *);
  276. static void CreateXrefFile(char *name)
  277. {
  278.     char *p,tmpfName[256],*q;
  279.  
  280.     if (xrefFile) return;
  281.     if (*name) {
  282.         if (!strcmp(infile,name)) {
  283.             fprintf(stderr,"Clobbering input file %s with xref file %s?\n",
  284.                 infile,name);
  285.             return;
  286.         }
  287.         xrefFile = fopen(name,"w");
  288.     }
  289.     p = strrchr(infile,'.');
  290.     if (p) {
  291.         *p = 0;
  292.         q = strrchr(infile,'\\');
  293.         if (q) q++;
  294.         else q = infile;
  295.         sprintf(tmpfName,"%s.xrf",q);
  296.         *p = '.';
  297.         xrefFile = fopen(tmpfName,"w");
  298.     }
  299.     if (xrefFile) {
  300.         fprintf(xrefFile,"F %s\n",infile);
  301.         AddToFileTable(infile);
  302.     }
  303. }
  304. /* doargs - process program arguments, removing top-half arguments from argv */
  305. static int      doargs(int argc,char *argv[])
  306. {
  307.     int             i, result;
  308.  
  309.     result = -1;
  310.     for (i = 1; i < argc; i++) {
  311.         if (argv[i][0] == '/') argv[i][0] = '-';
  312.         if (strcmp(argv[i], "-g") == 0)
  313.             glevel = 2;
  314.         else if (strncmp(argv[i], "-g", 2) == 0
  315.                  && argv[i][2] && argv[i][2] >= '0' && argv[i][2] <= '9') {
  316.             glevel = argv[i][2] - '0';
  317.             /* if (glevel >= 4) IR->stabinit = cdbstabinit; */
  318.         }
  319.         else if (strncmp(argv[i], "-x",2) == 0) {
  320.             xref++;
  321.             xrefFileName = &argv[i][2];
  322.         }
  323.         else if (strcmp(argv[i], "-A") == 0) {
  324.             if (++Aflag >= 2)
  325.                 Xflag = 0;
  326.         }
  327.         else if (strncmp(argv[i],"-D",2) == 0) {
  328.             DoCmdLineDirective(argv[i]+2,'D');
  329.         }
  330.         else if (strncmp(argv[i],"-U",2) == 0) {
  331.             DoCmdLineDirective(argv[i]+2,'U');
  332.         }
  333.         else if (strncmp(argv[i],"-M",2) == 0) {
  334.             Mflag = 1;
  335.             if (argv[i][2]) Mflag++;
  336.             TraceDependencies = 1;
  337.         }
  338.         else if (strncmp(argv[i],"-I",2) == 0) {
  339.             CmdLineAddInclude(argv[i]+2);
  340.         }
  341.         else if (strcmp(argv[i],"-z") == 0) {
  342.             IntermediateLanguageFile=1;
  343.         }
  344.         else if (strncmp(argv[i],"-O",2) == 0) {
  345.             OptimizeFlag = 1;
  346.         }
  347.         else if (strcmp(argv[i],"-T") == 0) {
  348.             dotokfile = 1;
  349.         }
  350.         else if (strcmp(argv[i], "-X") == 0)
  351.             Xflag++;
  352.         else if (strcmp(argv[i], "-P") == 0)
  353.             Pflag++;
  354.         else if (strcmp(argv[i], "-w") == 0)
  355.             wflag++;
  356.         else if (strcmp(argv[i], "-b") == 0
  357.                  || strcmp(argv[i], "-C") == 0
  358.                  || strncmp(argv[i], "-a", 2) == 0)
  359.             profInit(argv[i]);
  360.         else if (strcmp(argv[i], "-n") == 0) {
  361.             if (!YYnull) {
  362.                 YYnull = install(string("_YYnull"), &globals, GLOBAL, PERM);
  363.                 YYnull->type = ftype(voidtype, inttype);
  364.                 YYnull->sclass = STATIC;
  365.                 (*IR->defsymbol) (YYnull);
  366.             }
  367.         }
  368.         else if (strncmp(argv[i], "-n", 2) == 0) {  /* -nvalid[,check] */
  369.             char           *p = strchr(argv[i], ',');
  370.             if (p) {
  371.                 YYcheck = install(string(p + 1), &globals, GLOBAL, PERM);
  372.                 YYcheck->type = func(voidptype, NULL, 1);
  373.                 YYcheck->sclass = EXTERN;
  374.                 (*IR->defsymbol) (YYcheck);
  375.                 p = stringn(argv[i] + 2, p - (argv[i] + 2));
  376.             }
  377.             else
  378.                 p = string(argv[i] + 2);
  379.             YYnull = install(p, &globals, GLOBAL, PERM);
  380.             YYnull->type = func(voidptype, NULL, 1);
  381.             YYnull->sclass = EXTERN;
  382.             (*IR->defsymbol) (YYnull);
  383.         }
  384.         else if (strncmp(argv[i], "-target=", 8) == 0);
  385.         else if (strncmp(argv[i], "-t", 2) == 0)
  386.             traceInit(&argv[i][2]);
  387.         else if (strcmp(argv[i], "-v") == 0) {
  388.             verbose=1;
  389.         }
  390.         else if (strncmp(argv[i], "-s", 2) == 0)
  391.             density = (float)strtod(&argv[i][2], NULL);
  392.         else if (strncmp(argv[i], "-errout=", 8) == 0) {
  393.             char           *errfile = argv[i] + 8;
  394.             {
  395.                 errfd = open(errfile, ( _O_WRONLY|_O_APPEND | _O_CREAT ),_S_IWRITE);
  396.                 if (errfd < 0) {
  397.                     errfd = 2;
  398.                     fprint(2, "%s: can't write errors to `%s'\n", argv[0], errfile);
  399.                     exit(1);
  400.                 }
  401.             }
  402.  
  403.         }
  404.         else if (strncmp(argv[i],"-S",2) == 0) {
  405.             GenerateAsm = 1;
  406.         }
  407.         else if (strncmp(argv[i], "-e", 2) == 0) {
  408.             int             x;
  409.             if ((x = strtol(&argv[i][2], NULL, 0)) > 0)
  410.                 errlimit = x;
  411.         }
  412.         else if (strncmp(argv[i],"-E",2) == 0) {
  413.             GenerateCpp = 1;
  414.             if (argv[i][2] == '+')
  415.                 outputLine = 0;
  416.         }
  417.         else {
  418.             result = i;
  419.             infile = argv[i];
  420.         }
  421.     }
  422.     return result;
  423. }
  424. /* emitYYnull - compile definition for _YYnull, if it's referenced and named "_YYnull" */
  425. static void     emitYYnull() {
  426.     if (YYnull && YYnull->ref > 0.0
  427.             && strcmp(YYnull->name, "_YYnull") == 0) {
  428.         Aflag = 0;
  429.         YYnull->defined = 0;
  430.         YYnull = NULL;
  431.         compile(stringf("static char *_YYfile = \"%s\";\n", file));
  432.         compile("static void _YYnull(int line,...) {\nchar buf[200];\nsprintf(buf, \"null pointer dereferenced @%s:%d\\n\", _YYfile, line);\nwrite(2, buf, strlen(buf));\nabort();\n}\n");
  433.     }
  434. }
  435.  
  436. /* typestab - emit stab entries for p */
  437. static void     typestab(Symbol p,void *cl)
  438. {
  439.     if (*(Symbol *) cl == 0 && p->sclass && p->sclass != TYPEDEF)
  440.         *(Symbol *) cl = p;
  441.     if ((p->sclass == TYPEDEF || p->sclass == 0) && IR->stabtype)
  442.         (*IR->stabtype) (p);
  443. }
  444.  
  445. static void globaltab(Symbol p,void *cl)
  446. {
  447.     if (p->scope == GLOBAL && p->sclass != STATIC) {
  448.         if (p->type->op != FUNCTION && p->ref != 0.0)
  449.             fprintf(xrefFile,"E %s %d\n",p->name,p->src.y);
  450.     }
  451. }
  452.  
  453. static void statictab(Symbol p,void *cl)
  454. {
  455.     if (p->sclass == STATIC) {
  456.         if (p->type->op != FUNCTION && p->ref != 0.0)
  457.             fprintf(xrefFile,"S %s %d\n",p->name,p->src.y);
  458.     }
  459. }
  460.