home *** CD-ROM | disk | FTP | other *** search
- #include "c.h"
- #include <io.h>
- #include <fcntl.h>
- #include <stdio.h>
- #include <time.h>
- #include <signal.h>
- int mmx=0;
- FILE *AssemblerFile;
- static void compile ARGS((char *));
- static int doargs ARGS((int, char **));
- static void emitYYnull ARGS((void));
- static void typestab ARGS((Symbol, void *));
- static void globaltab(Symbol p,void *cl);
- static void statictab(Symbol p,void *cl);
- static void CreateXrefFile(char *name);
- extern void SetFastCompile(Interface *);
- #ifndef _S_IWRITE
- #define _S_IWRITE 0x200
- #endif
- Interface *IR = NULL;
- FILE *xrefFile;
- char *xrefFileName=NULL;
- char *ilFileName=NULL;
- FILE *ilFile;
- static char *infile, *outfile;
- int outputLine = 1; // whether to output #line or just # in cpp
- int verbose=0;
- int Aflag = 0; /* >= 0 if -A specified */
- int Pflag; /* != 0 if -P specified */
- int Xflag=1; /* != 0 if -X specified to permit
- extensions */
- int glevel=0; /* == [0-9] if -g[0-9] specified */
- int xref=0; /* != 0 for cross-reference data */
- Symbol YYnull; /* _YYnull symbol if -n or -nvalidate
- specified */
- Symbol YYcheck; /* _YYcheck symbol if -nvalidate,check
- specified */
- int Savedargc;
- char **Savedargv;
- int GenerateAsm = 0;
- int GenerateCpp = 0;
- int IntermediateLanguageFile;
- #ifdef PEEPHOLE
- int OptimizeFlag = 0;
- #endif
- clock_t AsmTime=0,CppTime = 0;
-
- static int IsAssemblerFile(char *fname)
- {
- char *p;
-
- p = strrchr(fname,'.');
- if (p == NULL) return(0);
- p++;
- if (*p != 'a' && *p != 'A') return(0);
- p++;
- if (*p != 's' && *p != 'S') return(0);
- p++;
- if (*p != 'm' && *p != 'M') return(0);
- p++;
- if (*p) return(0);
- return(1);
- }
- static char *suffix(char *infile,char *s)
- {
- char *outfile;
- char *p = strrchr(infile,'\\');
-
- if (p) p++;
- else p = infile;
- outfile = malloc(strlen(p)+10);
- memset(outfile,0,strlen(p)+10);
- strcpy(outfile,p);
- p = strrchr(outfile,'.');
- if (p) *p = 0;
- strcat(outfile,s);
- return outfile;
- }
- void AssembleFile(char *fname)
- {
- FILE *f;
- char *buffer;
- int s;
-
- f = fopen(fname,"r");
- if (f == NULL) {
- printf("Impossible to open %s\n",fname);
- return;
- }
- glevel = 0;
- AsmInit(fname);
- buffer = malloc(4097);
- while (!feof(f)) {
- s = fread(buffer,1,4096,f);
- buffer[4096] = 0;
- AsmReadBuffer(buffer,s);
- }
- free(buffer);
- AsmReadBuffer("",0);
- WriteCoffFile();
- }
- extern int _stdcall SetConsoleCtrlHandler(void *,int);
- extern char *OutputFileName;
- int _stdcall CtrlHandler(unsigned long event)
- {
- printf("lcc: break. Erasing %s\n",OutputFileName);
- unlink(OutputFileName);
- exit(1);
- return 0;
- }
-
- static void trap(int sig)
- {
- fatal("","Trap signal received. Compilation aborts\n",0);
- }
-
- extern long CharsRead;
- extern int _stdcall GetLastError(void);
- extern int NrOfSpills;
- int main(int argc,char *argv[])
- {
- int i;
- clock_t t0,t1;
- FILE *outf;
- char namebuf[256];
- extern int ReadTime;
-
- t0 = clock();
- signal(SIGSEGV,trap);
- IR = bindings[0].ir;
- Savedargc = argc;
- Savedargv = (char **)malloc(argc * sizeof(char *));
- for (i=0; i<argc;i++) {
- Savedargv[i] = malloc(strlen(argv[i])+1);
- strcpy(Savedargv[i],argv[i]);
- }
- CppInit();
- argc = doargs(argc, argv);
- if (infile == NULL) {
- fprintf(stderr,"no input files\n");
- return(-1);
- }
- SetConsoleCtrlHandler((void *)CtrlHandler,1);
- if (IntermediateLanguageFile && infile) {
- ilFileName = suffix(infile,".lil");
- ilFile = fopen(ilFileName,"w");
-
- }
- if (IsAssemblerFile(infile)) {
- AssembleFile(infile);
- goto doexit;
- }
- #if 0
- if (!OptimizeFlag)
- SetFastCompile(IR);
- #endif
- StartCpp(infile);
- if (GenerateCpp) {
- char *p = strrchr(infile,'\\');
- unsigned char *buffer;
-
- if (p) p++;
- else p = infile;
- outfile = malloc(strlen(p)+10);
- memset(outfile,0,strlen(p)+10);
- strcpy(outfile,p);
- p = strrchr(outfile,'.');
- if (p) *p = 0;
- strcat(outfile,".i");
- outf = fopen(outfile,"w");
- if (outf == NULL) {
- fprint(2, "%s: can't write `%s'\n",
- argv[0], outfile);
- exit(1);
- }
- buffer = malloc(16000);
- while ((i=ReadFromCpp(buffer,16000)) != 0) {
- fwrite(buffer,i,1,outf);
- }
- fclose(outf);
- free(buffer);
- t1 = clock();
- printf("Cpp time: %g sec.\n",(double)(t1-t0)/1000.0);
- SetConsoleCtrlHandler((void *)CtrlHandler,0);
- return(0);
- }
- AsmInit(infile);
- typeInit();
- if (outfile == NULL) {
- if (GenerateAsm && infile) {
- outfile = suffix(infile,".asm");
- }
- else if (GenerateAsm) outfile = tmpnam(NULL);
- }
- if (GenerateAsm && outfile) {
- AssemblerFile = fopen(outfile,"w");
- if (AssemblerFile == NULL) {
- printf("%s: can't write `%s: error %d'\n",
- argv[0], outfile,GetLastError());
- exit(1);
- }
- }
- if (xref) {
- CreateXrefFile(xrefFileName);
- }
- inputInit();
- outputInit();
- if (errfd != 2) {
- sprintf(namebuf,"%s:\n",infile);
- write(errfd,namebuf,strlen(namebuf));
- }
- t = gettok();
- (*IR->progbeg) (argc, argv);
- if (IR->stabinit)
- (*IR->stabinit) (firstfile, argc, argv);
- program();
- if (events.end)
- apply(events.end, NULL, NULL);
- memset(&events, 0, sizeof events);
- emitYYnull();
- CheckStaticUses();
- if (xref && xrefFile) {
- Symbol symroot = NULL;
- Coordinate src;
- foreach(types, GLOBAL, typestab, &symroot);
- foreach(identifiers, GLOBAL, typestab, &symroot);
- foreach(globals,GLOBAL,globaltab,&symroot);
- foreach(globals,GLOBAL,statictab,&symroot);
- src.file = firstfile;
- src.x = 0;
- src.y = lineno;
- if (IR->stabend)
- (*IR->stabend) (&src, symroot,
- ltov(&loci, PERM),
- ltov(&symbols, PERM), NULL);
- DumpDefines();
- DumpDefinedFunctions();
- fclose(xrefFile);
- }
- finalize();
- (*IR->progend) ();
- outflush();
- deallocate(PERM);
- AsmReadBuffer("",0);
- if (IntermediateLanguageFile)
- fclose(ilFile);
- if (errcnt == 0) WriteCoffFile();
- t1 = clock();
- if (verbose)
- printf("Spills:%d Chars read: %d,Memory used:%d,Time = %g sec.\n",
- NrOfSpills,CharsRead,memused,(double)(t1-t0)/1000.0);
- if (errcnt > 0 || warningCount > 0) {
- printf("%d errors, %d warnings\n",errcnt,warningCount);
- }
- doexit:
- if (GenerateAsm) fclose(AssemblerFile);
- fflush(stdout);
- if (outfd) close(outfd);
- if (errfd) close(errfd);
- SetConsoleCtrlHandler((void *)CtrlHandler,0);
- return errcnt > 0;
- }
-
- /* compile - compile str */
- static void compile(char *str)
- {
- inputstring(str);
- t = gettok();
- program();
- }
- extern int Mflag;
- extern int dotokfile;
- extern int TraceDependencies;
- extern void DoCmdLineDirective(char *,int);
- extern void CmdLineAddInclude(char *);
- static void CreateXrefFile(char *name)
- {
- char *p,tmpfName[256],*q;
-
- if (xrefFile) return;
- if (*name) {
- if (!strcmp(infile,name)) {
- fprintf(stderr,"Clobbering input file %s with xref file %s?\n",
- infile,name);
- return;
- }
- xrefFile = fopen(name,"w");
- }
- p = strrchr(infile,'.');
- if (p) {
- *p = 0;
- q = strrchr(infile,'\\');
- if (q) q++;
- else q = infile;
- sprintf(tmpfName,"%s.xrf",q);
- *p = '.';
- xrefFile = fopen(tmpfName,"w");
- }
- if (xrefFile) {
- fprintf(xrefFile,"F %s\n",infile);
- AddToFileTable(infile);
- }
- }
- /* doargs - process program arguments, removing top-half arguments from argv */
- static int doargs(int argc,char *argv[])
- {
- int i, result;
-
- result = -1;
- for (i = 1; i < argc; i++) {
- if (argv[i][0] == '/') argv[i][0] = '-';
- if (strcmp(argv[i], "-g") == 0)
- glevel = 2;
- else if (strncmp(argv[i], "-g", 2) == 0
- && argv[i][2] && argv[i][2] >= '0' && argv[i][2] <= '9') {
- glevel = argv[i][2] - '0';
- /* if (glevel >= 4) IR->stabinit = cdbstabinit; */
- }
- else if (strncmp(argv[i], "-x",2) == 0) {
- xref++;
- xrefFileName = &argv[i][2];
- }
- else if (strcmp(argv[i], "-A") == 0) {
- if (++Aflag >= 2)
- Xflag = 0;
- }
- else if (strncmp(argv[i],"-D",2) == 0) {
- DoCmdLineDirective(argv[i]+2,'D');
- }
- else if (strncmp(argv[i],"-U",2) == 0) {
- DoCmdLineDirective(argv[i]+2,'U');
- }
- else if (strncmp(argv[i],"-M",2) == 0) {
- Mflag = 1;
- if (argv[i][2]) Mflag++;
- TraceDependencies = 1;
- }
- else if (strncmp(argv[i],"-I",2) == 0) {
- CmdLineAddInclude(argv[i]+2);
- }
- else if (strcmp(argv[i],"-z") == 0) {
- IntermediateLanguageFile=1;
- }
- else if (strncmp(argv[i],"-O",2) == 0) {
- OptimizeFlag = 1;
- }
- else if (strcmp(argv[i],"-T") == 0) {
- dotokfile = 1;
- }
- else if (strcmp(argv[i], "-X") == 0)
- Xflag++;
- else if (strcmp(argv[i], "-P") == 0)
- Pflag++;
- else if (strcmp(argv[i], "-w") == 0)
- wflag++;
- else if (strcmp(argv[i], "-b") == 0
- || strcmp(argv[i], "-C") == 0
- || strncmp(argv[i], "-a", 2) == 0)
- profInit(argv[i]);
- else if (strcmp(argv[i], "-n") == 0) {
- if (!YYnull) {
- YYnull = install(string("_YYnull"), &globals, GLOBAL, PERM);
- YYnull->type = ftype(voidtype, inttype);
- YYnull->sclass = STATIC;
- (*IR->defsymbol) (YYnull);
- }
- }
- else if (strncmp(argv[i], "-n", 2) == 0) { /* -nvalid[,check] */
- char *p = strchr(argv[i], ',');
- if (p) {
- YYcheck = install(string(p + 1), &globals, GLOBAL, PERM);
- YYcheck->type = func(voidptype, NULL, 1);
- YYcheck->sclass = EXTERN;
- (*IR->defsymbol) (YYcheck);
- p = stringn(argv[i] + 2, p - (argv[i] + 2));
- }
- else
- p = string(argv[i] + 2);
- YYnull = install(p, &globals, GLOBAL, PERM);
- YYnull->type = func(voidptype, NULL, 1);
- YYnull->sclass = EXTERN;
- (*IR->defsymbol) (YYnull);
- }
- else if (strncmp(argv[i], "-target=", 8) == 0);
- else if (strncmp(argv[i], "-t", 2) == 0)
- traceInit(&argv[i][2]);
- else if (strcmp(argv[i], "-v") == 0) {
- verbose=1;
- }
- else if (strncmp(argv[i], "-s", 2) == 0)
- density = (float)strtod(&argv[i][2], NULL);
- else if (strncmp(argv[i], "-errout=", 8) == 0) {
- char *errfile = argv[i] + 8;
- {
- errfd = open(errfile, ( _O_WRONLY|_O_APPEND | _O_CREAT ),_S_IWRITE);
- if (errfd < 0) {
- errfd = 2;
- fprint(2, "%s: can't write errors to `%s'\n", argv[0], errfile);
- exit(1);
- }
- }
-
- }
- else if (strncmp(argv[i],"-S",2) == 0) {
- GenerateAsm = 1;
- }
- else if (strncmp(argv[i], "-e", 2) == 0) {
- int x;
- if ((x = strtol(&argv[i][2], NULL, 0)) > 0)
- errlimit = x;
- }
- else if (strncmp(argv[i],"-E",2) == 0) {
- GenerateCpp = 1;
- if (argv[i][2] == '+')
- outputLine = 0;
- }
- else {
- result = i;
- infile = argv[i];
- }
- }
- return result;
- }
- /* emitYYnull - compile definition for _YYnull, if it's referenced and named "_YYnull" */
- static void emitYYnull() {
- if (YYnull && YYnull->ref > 0.0
- && strcmp(YYnull->name, "_YYnull") == 0) {
- Aflag = 0;
- YYnull->defined = 0;
- YYnull = NULL;
- compile(stringf("static char *_YYfile = \"%s\";\n", file));
- 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");
- }
- }
-
- /* typestab - emit stab entries for p */
- static void typestab(Symbol p,void *cl)
- {
- if (*(Symbol *) cl == 0 && p->sclass && p->sclass != TYPEDEF)
- *(Symbol *) cl = p;
- if ((p->sclass == TYPEDEF || p->sclass == 0) && IR->stabtype)
- (*IR->stabtype) (p);
- }
-
- static void globaltab(Symbol p,void *cl)
- {
- if (p->scope == GLOBAL && p->sclass != STATIC) {
- if (p->type->op != FUNCTION && p->ref != 0.0)
- fprintf(xrefFile,"E %s %d\n",p->name,p->src.y);
- }
- }
-
- static void statictab(Symbol p,void *cl)
- {
- if (p->sclass == STATIC) {
- if (p->type->op != FUNCTION && p->ref != 0.0)
- fprintf(xrefFile,"S %s %d\n",p->name,p->src.y);
- }
- }
-