mirror of
https://github.com/GnoConsortium/gno.git
synced 2024-08-28 17:29:32 +00:00
- basename(argv[0]) is verified to be one of "compile", "cmpl", "assemble", or "asml", or an error is thrown. The latter two were not in the previous version at all. - Use the new GS/OS prefixes (>7)
366 lines
8.8 KiB
C
Executable File
366 lines
8.8 KiB
C
Executable File
/*
|
|
* 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 <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <ctype.h>
|
|
#include <types.h>
|
|
#include <shell.h>
|
|
#include <gsos.h>
|
|
#include <orca.h>
|
|
#include <texttool.h>
|
|
#include <unistd.h>
|
|
#include <gno/gno.h>
|
|
#include <sys/wait.h>
|
|
|
|
#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);
|
|
}
|