home *** CD-ROM | disk | FTP | other *** search
- /*
- * 68K/386 32-bit C compiler.
- *
- * copyright (c) 1996, David Lindauer
- *
- * This compiler is intended for educational use. It may not be used
- * for profit without the express written consent of the author.
- *
- * It may be freely redistributed, as long as this notice remains intact
- * and sources are distributed along with any executables derived from them.
- *
- * The author is not responsible for damages, either direct or consequential,
- * that may arise from use of this software.
- *
- * v1.5 August 1996
- * David Lindauer, gclind01@starbase.spd.louisville.edu
- *
- * Credits to Mathew Brandt for original K&R C compiler
- *
- */
- #include <stdio.h>
- #include <malloc.h>
- #include <string.h>
- #include "utype.h"
- #include "cmdline.h"
- #include "expr.h"
- #include "c.h"
- #include "gen.h"
- #include "cglbdec.h"
-
- extern unsigned _stklen = 4096*3; /* Getline only eats up about 5 or 6K */
- #define DOS 1
- #ifdef DOS
- char *getenv(char *);
- #endif
- #define VERSION 120
-
- typedef struct list {
- struct list *link;
- void *data;
- } LIST;
-
- extern TABLE tagtable;
- extern int total_errors;
- extern int diagcount;
-
- FILE *tempfil;
-
- char *usage_text = " [+i/f+l/w/C/D/E/I/O/S] file list";
-
- void bool_setup(char select, char *string);
- void err_setup(char select, char *string);
- void incl_setup(char select, char *string);
- void def_setup(char select, char *string);
- void codegen_setup(char select, char *string);
- void optimize_setup(char select, char *string);
- void warning_setup(char select, char *string);
- void parsefile(char select, char *string);
- ARGLIST ArgList[] = {
- { 'i', ARG_BOOL, bool_setup },
- { 'f', ARG_CONCATSTRING, parsefile },
- { 'l', ARG_BOOL, bool_setup },
- { 'w', ARG_CONCATSTRING, warning_setup },
- { 'C', ARG_CONCATSTRING, codegen_setup },
- { 'O', ARG_CONCATSTRING, optimize_setup },
- { 'E', ARG_CONCATSTRING, err_setup },
- { 'I', ARG_CONCATSTRING, incl_setup },
- { 'D', ARG_CONCATSTRING, def_setup },
- { 'S', ARG_BOOL, bool_setup },
- { 0, 0, 0 }
- };
-
- LIST *clist = 0;
- LIST *deflist = 0;
- int prm_stackcheck = FALSE;
- int prm_warning = TRUE;
- int prm_asmfile = TRUE;
- int prm_listfile = FALSE;
- int prm_largedata = FALSE;
- int prm_68020 = FALSE;
- int prm_maxerr = 25;
- int prm_diag = FALSE;
- int prm_bss = TRUE;
- int prm_cppfile = FALSE;
- int prm_packing = FALSE;
- int prm_revbits = FALSE;
- int prm_lines = TRUE;
- int prm_cplusplus = FALSE;
- int prm_cmangle = TRUE;
- int basear = 1, basedr = 1, basefr = 1;
- char *prm_searchpath = 0;
-
- char *infile,
- listfile[40],
- outfile[40],
- cppfile[40];
-
- static char *tempFile;
-
- void bool_setup(char select, char *string)
- {
- int bool = (int)string;
- if (select == 'S')
- prm_asmfile = bool;
- if (select == 'l')
- prm_listfile = bool;
- if (select == 'i')
- prm_cppfile = bool;
- }
- void codegen_setup(char select, char *string)
- {
- int bool = TRUE;
- while (*string) {
- switch (*string) {
- #ifndef i386
- case 'L':
- prm_largedata = bool;
- break;
- case '2':
- prm_68020 = bool;
- break;
- #endif
- case 'd':
- prm_diag = bool;
- break;
- case 'p':
- prm_packing = bool;
- break;
- case 'r':
- prm_revbits = bool;
- break;
- case 'b':
- prm_bss=bool;
- break;
- case 'l':
- prm_lines = bool;
- break;
- case 'm':
- prm_cmangle = bool;
- break;
- case 'S':
- prm_stackcheck = bool;
- break;
- case '-':
- bool = FALSE;
- break;
- case '+':
- bool = TRUE;
- break;
- }
- string++;
- }
- }
- void optimize_setup(char select, char *string)
- {
- int bool = TRUE;
- while (*string) {
- switch (*string) {
- case 'R':
- string++;
- while (*string && *string != '+' && *string != '-') {
- switch (*string++) {
- case 'a':
- basear = bool;
- break;
- case 'd':
- basedr = bool;
- break;
- case 'f':
- basefr = bool;
- break;
- }
- if (!*string)
- return;
- }
- break;
- case '-':
- bool = FALSE;
- break;
- case '+':
- bool = TRUE;
- break;
- }
- string++;
- }
- }
- void err_setup(char select, char *string)
- {
- prm_maxerr = atoi(string);
- }
- void incl_setup(char select, char * string)
- {
- prm_searchpath = malloc(strlen(string)+1);
- strcpy(prm_searchpath,string);
- }
- void def_setup(char select, char *string)
- {
- char *s = malloc(strlen(string)+1);
- LIST *l = malloc(sizeof(LIST));
- strcpy(s,string);
- l->link = deflist;
- deflist = l;
- l->data = s;
- }
- void setglbdefs(void)
- {
- LIST *l = deflist;
- while (l) {
- glbdefine(l->data);
- l = l->link;
- }
- if (prm_cplusplus) {
- glbdefine("__cplusplus");
- }
- #ifdef i386
- glbdefine("_i386_");
- #else
- glbdefine("_m68k_");
- #endif
- }
- void InsertAnyFile(FILE *inf, FILE *outf, char *filename, char *path, int drive)
- {
- char *newbuffer, buffer[100],*p = buffer;
- LIST *r = &clist;
-
- if (drive != -1) {
- *p++ = drive + 'A';
- *p++ = ':';
- }
- if (path) {
- strcpy(p,path);
- strcat(p,"\\");
- }
- else
- *p = 0;
- /* Allocate buffer and make .C if no extension */
- strcat(buffer,filename);
- AddExt(buffer,".C");
- newbuffer = (char *) malloc(strlen(buffer) + 1);
- strcpy(newbuffer,buffer);
-
- /* Insert file */
- while (r->link)
- r = r->link;
- r->link = malloc(sizeof(LIST));
- r = r->link;
- r->link = 0;
- r->data = newbuffer;
- }
- void dumperrs(FILE *file);
- void setfile(char *buf,char *orgbuf,char *ext)
- {
- char *p = strrchr(orgbuf,'\\');
- if (!p) p = orgbuf;
- else p++;
- strcpy(buf,p);
- StripExt(buf);
- AddExt(buf,ext);
- }
- int parse_arbitrary(char *string)
- {
- char *argv[40];
- int rv;
- int argc = 1;
- if (!string || !*string)
- return 1;
- while (1) {
- while (*string == ' ')
- string++;
- if (!*string)
- break;
- argv[argc++] = string;
- while (*string && *string != ' ') string++;
- if (!*string)
- break;
- *string = 0;
- string++;
- }
- rv = parse_args(&argc,argv,TRUE);
- if (argc !=1)
- fatal("Filename present in secondary arguments");
- return rv;
- }
- void parsefile(char select, char *string)
- {
- FILE *temp = 0;
- if (!(temp = fopen(string,"r")))
- fatal("Argument file not found");
- while (!feof(temp)) {
- char buf[256];
- buf[0] = 0;
- fgets(buf,256,temp);
- if (buf[strlen(buf)-1] == '\n')
- buf[strlen(buf)-1] = 0;
- if (!parse_arbitrary(buf))
- break;
- }
- fclose(temp);
- }
- #ifdef DOS
- void addinclude(void)
- {
- char *string = getenv("CCINCL");
- if (string && string[0]) {
- char temp[500];
- strcpy(temp,string);
- if (prm_searchpath) {
- strcat(temp,";");
- strcat(temp,prm_searchpath);
- free(prm_searchpath);
- }
- prm_searchpath = malloc(strlen(temp)+1);
- strcpy(prm_searchpath,temp);
- }
- }
- int parseenv(char *name)
- {
- char *string = getenv(name);
- return parse_arbitrary(string);
- }
- #endif
- int main(int argc,char *argv[])
- {
- char buffer[40];
- char *p;
- #ifdef i386
- banner(VMSG("CC386"));
- #else
- banner(VMSG("CC68K"));
- #endif
- outfile[0] = 0;
-
- #ifdef DOS
- #ifdef i386
- if (!parseenv("CC386"))
- #else
- if (!parseenv("CC68K"))
- #endif
- usage(argv[0]);
- #endif
- if (!parse_args(&argc, argv, TRUE) || (argc == 1))
- usage(argv[0]);
-
- if (prm_68020)
- prm_largedata = FALSE;
-
- #ifdef DOS
- addinclude();
- #endif
- // Scan the command line for file names or response files
- FileRecurse(argc-1,&argv[1],0,InsertAnyFile,".C",FALSE);
-
- while (clist) {
- memini();
- symini();
- kwini();
- cglbini();
- initini();
- preprocini();
- exprini();
- declini();
- funcini();
- peepini();
- genstmtini();
- outcodeini();
- regini();
- printf("file: %s\n",clist->data);
- strcpy(buffer,clist->data);
- #ifdef i386
- setfile(outfile,buffer,".ASM");
- #else
- setfile(outfile,buffer,".SRC");
- #endif
- setfile(cppfile,buffer,".I");
- setfile(listfile,buffer,".LST");
- prm_cplusplus = FALSE;
- AddExt(buffer,".C");
- p = strrchr(buffer,'.');
- if (*(p-1) != '.') {
- if (p[1] == 'c' || p[1] == 'C')
- if (p[2] == 'p' || p[2] == 'P')
- if (p[3] == 'p' || p[3] == 'P')
- prm_cplusplus = TRUE;
- }
- infile = litlate(buffer);
-
- #ifdef i386
- if (prm_asmfile) {
- if (!(tempfil = fopen(tempFile = tmpnam(0),"w+")))
- fatal("Error opening temp file");
- }
- #endif
- if (prm_cppfile) {
- if (!(cppFile = fopen(cppfile,"w")))
- fatal("Can't open cpp file %s",cppfile);
- }
- if (!(inputFile = fopen(infile,"r")))
- fatal("Can't open input file %s",infile);
- if (prm_asmfile) {
- if (!(outputFile = fopen(outfile,"w"))) {
- fclose(inputFile);
- fatal("Can't open output file %s",outfile);
- }
- }
- if (prm_listfile)
- if (!(listFile = fopen(listfile,"w"))) {
- fclose(inputFile);
- fclose(outputFile);
- fatal("Can't open list file %s",listfile);
- }
- lineno = 0;
- initerr();
- initsym();
- setglbdefs();
- getch();
- getsym();
- compile();
- initrundown();
- putexterns();
- dumperrs(stdout);
- summary();
- release_global();
- fclose(inputFile);
- if (prm_asmfile) {
- fclose(outputFile);
- #ifdef i386
- fclose(tempfil);
- remove(tempFile);
- #endif
- }
- if (prm_listfile)
- fclose(listFile);
- if (prm_cppfile)
- fclose(cppFile);
- clist = clist->link;
- }
- if (total_errors)
- return(1);
- else
- return(0);
- }
- void dumperrs(FILE *file)
- {
- if (diagcount)
- fprintf(file,"%d Diagnostics detected\n",diagcount);
- if (total_errors)
- fprintf(file,"%d Total errors\n",total_errors);
- }
- void summary(void)
- {
- if (prm_listfile) {
- fprintf(listFile,"\f\n *** global scope symbol table ***\n\n");
- list_table(&gsyms,0);
- fprintf(listFile,"\n *** structures and unions ***\n\n");
- list_table(&tagtable,0);
- dumperrs(listFile);
- }
- }