/* * comp.c * * parsing code for compile, cmpl * * 'cmplg' is not supported * * Copyright 1991-1998 Procyon, Inc. * * March 12, 1992 - switched from strcmp to stricmp on invoke name check * * $Id: compile.c,v 1.1 1998/02/15 00:05:28 gdr-ftp Exp $ */ /* The options are set up in the following format: Low High Byte 0 Byte 1 Byte 2 Byte 3 76543210 76543210 76543210 76543210 yz qrstuvwx ijklmnop abcdefgh kflag 0 - do not save output 1 - save to object filename pointed to by dfile 2 - .root has already been made, make .a files 3 - at least one alphabetic suffix has been used */ #include #include #include #include #include #include #include #include #include #include #include #include #define PATH_LINKER "16/linker" #define PATH_EDITOR "15/editor" longword optTab[] = { 0x80000000, 0x40000000, 0x20000000, 0x10000000, 0x08000000, 0x04000000, 0x02000000, 0x01000000, 0x00800000, 0x00400000, 0x00200000, 0x00100000, 0x00000000,/* 0x00080000,*/ /* disable +m option because of bug! */ 0x00040000, 0x00020000, 0x00010000, 0x00008000, 0x00004000, 0x00002000, 0x00001000, 0x00000800, 0x00000400, 0x00000200, 0x00000100, 0x00000080, 0x00000040 }; char *sources[40]; int numSources; typedef struct langInfo { word number; char *name; char *info; } langInfo; langInfo langTable[] = { {3, "asm65816", NULL}, {4, "IBASIC", NULL}, {5, "pascal", NULL}, {7, "smallc", NULL}, {8, "cc", NULL}, {9, "link", NULL}, {10, "apwc", NULL}, {11, "pascal", NULL}, {16, "modula2", NULL}, {21, "rez", NULL}, {265, "linker", NULL}, {-1,"",NULL}}; char *invoke; void doError(char *err) { printf("%s: %s\n",invoke,err); exit(2); } int parseSp(int i, char *s) { while ((s[i] != ' ') && (s[i])) { i++; } if (s[i]) return ++i; else return i; } int parsecp(int i, char *s) { while ((s[i] != ')') && (s[i])) { i++; } return i; } char *expandFName(char *name) { char *p,*q; Expand_DevicesPB ed; p = malloc(256l); memcpy(p,name,name[0]+1); ed.pathname = p; EXPAND_DEVICES(&ed); q = malloc(p[0]+1); memcpy(q,p,p[0]+1); free(p); return q; } void expandVar2dfile(char *varname, Get_LInfoPB *g) { char varval[80]; Get_VarPB gp; int i,n = 1; int l; gp.var_name = varname; gp.value = varval; GET_VAR(&gp); for (i = 1; i <= varval[0]; i++) { if (varval[i] == '$') { for (l = g->sfile[0]; l > 0; l--) { if (g->sfile[l] == '.') { memcpy(g->dfile+n,g->sfile+1,(size_t)l-1); n+=l-1; break; } } } else if (varval[i] == '%') { doError("% operator in KeepName not supported"); } else g->dfile[n++] = varval[i]; } g->dfile[0] = n-1; } #ifdef __STACK_CHECK__ static void printStack (void) { fprintf(stderr, "stack usage: %d bytes\n", _endStackCheck()); } #endif char sfile[65], dfile[65], parms[256], istring[256]; char linksfile[256]; Get_LInfoPB gl; GSString255 pathGS; int main (int argc,char *argv[]) { static char invokeCmd[40]; int lastind, ind=0, langind; char *cmd1, *cmdline, *temps; int pid, wpid, index, sind; FileInfoRecGS fi; int err; GSString255Ptr expPathGS; union wait status; #ifdef __STACK_CHECK__ _beginStackCheck(); atexit(printStack); #endif invoke = basename(argv[0]); if ((strcasecmp(invoke, "compile") == 0) || (strcasecmp(invoke, "assemble") == 0)) { gl.lops = 1; } else if ((strcasecmp(invoke, "cmpl") == 0) || (strcasecmp(invoke, "asml") == 0)) { gl.lops = 3; } else { doError("invalid invocation"); } cmd1 = commandline(); cmdline = malloc(strlen(cmd1)+1); strcpy(cmdline,cmd1); sfile[0] = dfile[0] = parms[0] = istring[0] = 0; gl.pflags = 0x00000000l; gl.mflags = 0l; gl.kflag = 0; gl.sfile = sfile; gl.dfile = dfile; gl.parms = parms; gl.istring = istring; numSources = 0; linksfile[1] = 0; ind = parseSp(ind,cmdline); while ((cmdline[ind] == '+') || (cmdline[ind] == '-')) { if (cmdline[ind] == '+') gl.pflags |= optTab[toupper(cmdline[ind+1])-'A']; else gl.mflags |= optTab[toupper(cmdline[ind+1])-'A']; ind = parseSp(ind,cmdline); } lastind = ind; /* ind = parseSp(ind,cmdline); sfile[0]=ind-lastind; if (cmdline[ind]) sfile[0]--; strncpy(sfile+1,(cmdline+lastind),sfile[0]); */ while (cmdline[ind]) { if (!strncasecmp(cmdline+ind,"keep=",5)) { gl.kflag = 1; lastind = ind; ind = parseSp(ind,cmdline); dfile[0] = (ind-lastind)-5; if (cmdline[ind]) dfile[0]--; strncpy(dfile+1,(cmdline+lastind+5),dfile[0]); continue; } if (!strncasecmp(cmdline+ind,"names=(",7)) { lastind = ind; ind = parsecp(ind,cmdline); parms[0] = (ind-lastind)-7; strncpy(parms+1,(cmdline+lastind+7),parms[0]); ind = parseSp(ind,cmdline); continue; } langind = 0; while (langTable[langind].number != -1) { int l = strlen(langTable[langind].name); if ((!strncasecmp(cmdline+ind,langTable[langind].name,l)) && (*(cmdline+ind+l) == '=')) { lastind = ind; ind = parsecp(ind,cmdline); langTable[langind].info = malloc(ind-lastind-l+2); langTable[langind].info[0] = (ind-lastind-l-2); strncpy(langTable[langind].info+1,(cmdline+lastind+l+2), langTable[langind].info[0]); ind = parseSp(ind,cmdline); goto loopit; } langind++; } lastind = ind; ind = parseSp(ind,cmdline); temps = sources[numSources] = malloc(ind-lastind+2); strncpy(sources[numSources]+1,(cmdline+lastind),(ind-lastind)); sources[numSources][0] = ind-lastind; if (cmdline[ind]) sources[numSources][0]--; sources[numSources]=expandFName(sources[numSources]); free(temps); numSources++; loopit: ; } if (numSources == 0) { fprintf(stderr,"No source files specified.\n"); exit(1); } gl.merr = 0; gl.merrf = 0; gl.org = 0l; for (sind = 0; sind < numSources; sind ++) { memcpy(sfile,sources[sind],sources[sind][0]+1); /* if no keepname is specified on the command line, check the variable "KeepName" for one */ if (gl.dfile[0] == 0) { expandVar2dfile("\pKeepName",&gl); if (gl.dfile[0]) gl.kflag = 1; /* was something expanded? */ } pathGS.length = sources[sind][0]; memcpy(pathGS.text,sources[sind]+1,pathGS.length); dfile[dfile[0]+1] = 0; strcat(linksfile+1,dfile+1); strcat(linksfile+1," "); fi.pCount = 4; fi.pathname = &pathGS; GetFileInfoGS(&fi); if (err = toolerror()) { printf("%s:",invoke); ERROR(&err); exit(err); } index = 0; while (langTable[index].number != -1) { if (((word)fi.auxType) == langTable[index].number) break; index++; } if (langTable[index].number == -1) doError("Unsupported language type"); if (langTable[index].info != NULL) memcpy(gl.istring,langTable[index].info,langTable[index].info[0]+1); else gl.istring[0] = 0; /* set istring to null */ /* printf("source address %08lX\n",&gl); printf("sfile : %p\n",gl.sfile); printf("dfile : %p\n",gl.dfile); printf("parms : %p\n",gl.parms); printf("kflag : %d\n",gl.kflag); printf("istring : %p\n",gl.istring); printf("mflags : %08lX\n",gl.mflags); printf("pflags : %08lX\n\n",gl.pflags); */ SET_LINFO(&gl); sprintf(invokeCmd,"16/%s",langTable[index].name); if ((pid = exec(invokeCmd,invokeCmd)) >= 0) { waitlp1: wpid = wait(&status); if ((wpid != pid) || (status.w_stopval == WSTOPPED)) goto waitlp1; } GET_LINFO(&gl); if ((gl.merrf > gl.merr) && (langTable[index].number != 9) && (langTable[index].number != 265) && (gl.pflags & 0x08000000l)) { printf("%s:[%ld] %p\n",langTable[index].name,gl.org,gl.parms); if ((pid = exec(PATH_EDITOR,PATH_EDITOR)) >= 0) { waitlp9: wpid = wait(&status); if ((wpid != pid) || (status.w_stopval == WSTOPPED)) goto waitlp9; } exit(gl.merrf); } } /*gl.kflag = 1;*/ /*linksfile[0] = strlen(linksfile+1); memcpy(sfile,linksfile,linksfile[0]+1);*/ SET_LINFO(&gl); if (gl.lops & 2) if ((pid = exec(PATH_LINKER,PATH_LINKER)) >= 0) { waitlp2: wpid = wait(&status); if ((wpid != pid) || (status.w_stopval == WSTOPPED)) goto waitlp2; } GET_LINFO(&gl); exit(gl.merrf); }