/* Copyright (c) 1988 by Sozobon, Limited. Author: Johann Ruegg * * Permission is granted to anyone to use this software for any purpose * on any computer system, and to redistribute it freely, with the * following restrictions: * 1) No charge may be made other than reasonable charges for reproduction. * 2) Modified versions must be clearly marked as such. * 3) The authors are not responsible for any harmful consequences * of using this software, even if they result from defects in it. * * main.c * * Main routine, error handling, keyword lookup. * * * Revised: Dec 1988 Joe Montgomery * * Revised main.c to use Amiga File System Naming Conventions * Added ?,C,F switches. ? help * C force data,bss into Chip memory * F force data,bss into Fast memory * To be added -o switch to specify assembly output * * other modules: * Revised out.c to use MOTOROLA assembly directives in order * to be compatible with C.Gibbs a68k assembler & blink * Added END statement * Changed .comm label,size to label DC.x 0 * Revised d2.c so that externs are declared as XREF ----- * Revised g2.c & gen.c to declare all called functions XREF * (will need to change this to declare only external functions) * * * All changes labeled JMM */ #include #include "param.h" #include "nodes.h" #include "tok.h" extern short usechipmemory,usefastmemory; int lineno; int nmerrors; int oflags[26]; int xflags[26]; int pflag = 0; /* enable profiling */ static int anydebug; #define debug oflags['z'-'a'] FILE *input; FILE *output; #if CC68 FILE *fopenb(); #define fopen fopenb #endif char *inname; #if NEEDBUF char my_ibuf[BUFSIZ]; #endif NODEP cur; /* JMM changed defines to be compatible with AMIGA */ static char *defines[] = { "MC68000", "mc68000", "SOZOBON", "MCH_AMIGA", "AmigaDOS", NULL }; static char Version[] = "zc: Amiga Version 1.01 Copyright (c) 1988 by Sozobon, Limited.\n"; static char Version2[] = " modified by J.Montgomery. Now generates Motorola compatible \n"; static char Version3[] = " assembly code.\n"; extern char *outfilename,*errorfile; main(argc, argv) char **argv; { char *p, *getenv(); int shownames; int i; /* JMM added switches to force data,bss into chip or fast memory */ usefastmemory = 0; usechipmemory = 0; /* don't force data into either chip or fast*/ outfilename = (char *) NULL; /* JMM force hcc to always print out version */ printf(Version); if (sizeof(NODE) & 3) { printf("sizeof NODE not mult of 4\n"); exit(1); } /* * Define the "built-in" macros */ for (i=0; defines[i] != NULL; i++) optdef(defines[i]); /* * Parse the INCLUDE environment variable, if present. */ if ((p = getenv("INCLUDE")) != NULL){ if( doincl(p) == 1 )exit(0); } shownames = 0; if (isatty(0)) { write(1, "\33v", 2); setbuf(stdout, NULL); } /* put author here */ while (argc-- > 1) { argv++; if(argv[0][0] == '?') { doopt(&argv[0][0]); exit(1); } if(argv[0][0] == '-') doopt(&argv[0][1]); #if CC68 else if (argv[0][0] == '+') { upstr(&argv[0][1]); doopt(&argv[0][1]); } #endif else { if (argc > 1 || shownames) { shownames++; printf("%s:\n", argv[0]); } if (input != NULL) fclose(input); input = fopen(argv[0], ROPEN); if (input == NULL) { printf("Cant open %s\n", argv[0]); exit(1); } #if NEEDBUF setbuf(input, my_ibuf); #endif inname = argv[0]; dofile(); } } if (input == NULL) { input = stdin; output = stdout; inname = ""; dofile(); } exit(0); } doincl(s) char *s; { char *malloc(), *strcpy(); char buf[256]; char dir[128]; register char *p; strcpy(buf, s); /* * Convert ',' and ';' to nulls */ for (p=buf; *p != '\0' ;p++) if (*p == ',' || *p == ';') *p = '\0'; p[1] = '\0'; /* double null terminated */ /* * Grab each directory, make sure it ends with a slash, * and add it to the directory list. */ for (p=buf; *p != '\0' ;p++) { strcpy(dir, p); /* JMM use Amiga file naming conventions */ if (dir[strlen(dir)-1] != '/' && dir[strlen(dir)-1] != ':') strcat(dir, "/"); optincl( strcpy(malloc((unsigned) (strlen(dir) + 1)), dir) ); while (*p != '\0') p++; } } extern int nodesmade, nodesavail; extern NODEP deflist[], symtab[], tagtab; extern NODEP strsave; extern int level; dofile() { char *scopy(); int i; out_start(inname); inname = scopy(inname); lineno = 1; nmerrors = 0; advnode(); level = 0; program(); dumpstrs(strsave); out_end(); if (cur && cur->e_token == EOFTOK) freenode(cur); sfree(inname); for (i=0; i1 && deflist[i]) { printf("defines[%d]", i); printlist(deflist[i]); } freenode(deflist[i]); deflist[i] = NULL; if (debug && symtab[i]) { printf("gsyms[%d]", i); printlist(symtab[i]); } freenode(symtab[i]); symtab[i] = NULL; } if (debug) { printf("structs"); printlist(tagtab); } freenode(tagtab); tagtab = NULL; freenode(strsave); strsave = NULL; if (nmerrors) { printf("%d errors\n", nmerrors); exit(1); } if (nodesmade != nodesavail) { printf("lost %d nodes!!!\n", nodesmade-nodesavail); exit(1); } /* printf("Space = %ldK\n", ((long)nodesavail*sizeof(NODE))/1024); */ } dooutfile(s) char *s; { char *malloc(), *strcpy(); outfilename = strcpy(malloc((unsigned)(strlen(s) + 1)), s ); } doerrorfile(s) char *s; { char *malloc(),*strcpy(); errorfile = strcpy(malloc((unsigned)(strlen(s) + 1)), s); } doopt(s) char *s; { register char c; while ((c = *s++)) { #ifdef DEBUG if (c >= 'a' && c <='z') { oflags[c-'a']++; anydebug++; } else #endif if ( (c >= 'A' && c <= 'Z') || c == '?') { switch (c) { case 'D': optdef(s); return; case 'U': optundef(s); return; case 'I': doincl(s); return; case 'P': pflag = 1; continue; case 'V': printf("%s %s",Version2,Version3); continue; /* JMM added ?,C,F,O,E switches */ case 'E': /* specify error file */ doerrorfile(s); return(1); case 'O': dooutfile(s); return(1); case 'C': if(usefastmemory){ printf(" Can't use both Chip & Fast memory\n"); return(1); } usechipmemory = 1; continue; case 'F': if(usechipmemory){ printf(" Can't use both Chip & Fast memory\n"); return(1); } usefastmemory = 1; continue; case '?': printf("%s %s",Version2,Version3); printf(" The Correct Syntax is \n"); printf("zc [FLAGS] SOURCEFILE \n"); printf(" The valid compiler flags are : \n"); printf("\n -Dxxxx Define xxxx\n -Uxxxx Undefine xxxx\n"); printf(" -Ixxxx Include Directory = xxxx\n -P profiler\n"); printf(" -Oxxxx outputfile name = xxxx\n"); printf(" -V display compiler version\n -? Help\n"); printf(" -C force Data,Bss into Chip memory \n"); printf(" -F force Data,Bss into Fast memory \n"); return(1); continue; } #ifdef DEBUG xflags[c-'A']++; anydebug++; #endif } } return(0); } errors(s,t) char *s, *t; { optnl(); printf("error in %s on line %d: %s %s\n", inname, lineno, s,t); nmerrors++; } errorn(s,np) char *s; NODE *np; { optnl(); printf("error in %s on line %d: %s ", inname, lineno, s); put_nnm(np); putchar('\n'); nmerrors++; } error(s) char *s; { optnl(); printf("error in %s on line %d: %s\n", inname, lineno, s); nmerrors++; } warns(s,t) char *s, *t; { optnl(); printf("warning in %s on line %d: %s %s\n", inname, lineno, s,t); } warnn(s,np) char *s; NODE *np; { optnl(); printf("warning in %s on line %d: %s ", inname, lineno, s); put_nnm(np); putchar('\n'); } warn(s) char *s; { optnl(); printf("warning in %s on line %d: %s\n", inname, lineno, s); } fatals(s,t) char *s, *t; { optnl(); printf("fatal error in %s on line %d: %s %s\n", inname, lineno, s,t); exit(1); } fataln(s,np) char *s; NODE *np; { optnl(); printf("fatal error in %s on line %d: %s ", inname, lineno, s); put_nnm(np); putchar('\n'); exit(1); } fatal(s) char *s; { optnl(); printf("fatal error in %s on line %d: %s\n", inname, lineno, s); exit(1); } static optnl() { if (anydebug) putchar('\n'); } struct kwtbl { char *name; int kwval; int kflags; } kwtab[] = { /* must be sorted */ {"asm", K_ASM}, {"auto", K_AUTO}, {"break", K_BREAK}, {"case", K_CASE}, {"char", K_CHAR}, {"continue", K_CONTINUE}, {"default", K_DEFAULT}, {"do", K_DO}, {"double", K_DOUBLE}, {"else", K_ELSE}, {"enum", K_ENUM}, {"extern", K_EXTERN}, {"float", K_FLOAT}, {"for", K_FOR}, {"goto", K_GOTO}, {"if", K_IF}, {"int", K_INT}, {"long", K_LONG}, {"register", K_REGISTER}, {"return", K_RETURN}, {"short", K_SHORT}, {"sizeof", K_SIZEOF}, {"static", K_STATIC}, {"struct", K_STRUCT}, {"switch", K_SWITCH}, {"typedef", K_TYPEDEF}, {"union", K_UNION}, {"unsigned", K_UNSIGNED}, {"void", K_VOID}, {"while", K_WHILE}, {0,0} }; #define FIRST_C 'a' #define LAST_C 'z' struct kwtbl *kwstart[LAST_C-FIRST_C+1]; kw_init() { register struct kwtbl *p; register c; for (p=kwtab; p->name; p++) { c = p->name[0]; if (kwstart[c-FIRST_C] == 0) kwstart[c-FIRST_C] = p; } } kw_tok(tp) NODE *tp; { register struct kwtbl *kp; register char *nm; register i; static first = 0; nm = tp->n_name; if (first == 0) { kw_init(); first = 1; } i = nm[0]; if (i < FIRST_C || i > LAST_C) return; kp = kwstart[i-FIRST_C]; if (kp) for (; kp->name; kp++) { i = strcmp(nm, kp->name); if (i == 0) { tp->e_token = kp->kwval; tp->e_flags = kp->kflags; return; } else if (i < 0) return; } } #if CC68 /* fix args since stupid lib makes all lower case */ upstr(s) char *s; { while (*s) { if (*s >= 'a' && *s <= 'z') *s += 'A'-'a'; s++; } } downstr(s) char *s; { while (*s) { if (*s >= 'A' && *s <= 'Z') *s -= 'A'-'a'; s++; } } #endif