home *** CD-ROM | disk | FTP | other *** search
- /* 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
- */
-
- /*
- * Amiga version changes by Jeff Lydiatt labled "Jal".
- */
-
- #include <stdio.h>
- #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[] = /*Jal*/
- " Port by Jeff Lydiatt, J.Montgomery - 13Jun89.\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 = "<STDIN>";
- 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);
- for (i=0; i<NHASH; i++){
- if (symtab[i] != NULL)
- do_public(symtab[i]);
- }
- putlibcalls();
-
- out_end();
- if (cur && cur->e_token == EOFTOK)
- freenode(cur);
- sfree(inname);
- for (i=0; i<NHASH; i++) {
- if (debug>1 && 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",Version2); /*Jal*/
- 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",Version2); /*Jal*/
- 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
-