BSD 4_1c_2 release
[unix-history] / usr / src / ucb / pascal / utilities / pc.c
static char sccsid[] = "@(#)pc.c 3.20 2/3/83";
#include <stdio.h>
#include <signal.h>
#include <wait.h>
/*
* Pc - front end for Pascal compiler.
*/
char *pc0 = "/usr/lib/pc0";
char *pc1 = "/lib/f1";
char *pc2 = "/usr/lib/pc2";
char *c2 = "/lib/c2";
char *pc3 = "/usr/lib/pc3";
char *ld = "/bin/ld";
char *as = "/bin/as";
char *lpc = "-lpc";
char *crt0 = "/lib/crt0.o";
char *mcrt0 = "/lib/mcrt0.o";
char *gcrt0 = "/usr/lib/gcrt0.o";
char *mktemp();
char *tname[2];
char *tfile[2];
char *setsuf(), *savestr();
int Jflag, Sflag, Oflag, Tlflag, cflag, gflag, pflag, wflag;
int debug;
#define NARGS 512
int ldargx = 3;
int pc0argx = 3;
char *pc0args[NARGS] = { "pc0", "-o", "XXX" };
char *pc1args[3] = { "pc1", 0, };
char *pc2args[2] = { "pc2", 0 };
char *c2args[4] = { "c2", 0, 0, 0 };
int pc3argx = 1;
#define pc3args pc0args
#define ldargs pc0args
/* char *pc3args[NARGS] = { "pc3", 0 }; */
/* char *ldargs[NARGS] = { "ld", "-X", "/lib/crt0.o", 0, }; */
int asargx;
char *asargs[6] = { "as", 0, };
char *mesg[] = {
0,
"Hangup",
"Interrupt",
"Quit",
"Illegal instruction",
"Trace/BPT trap",
"IOT trap",
"EMT trap",
"Floating exception",
"Killed",
"Bus error",
"Segmentation fault",
"Bad system call",
"Broken pipe",
"Alarm clock",
"Terminated",
"Signal 16",
"Stopped (signal)",
"Stopped",
"Continued",
"Child exited",
"Stopped (tty input)",
"Stopped (tty output)",
"Tty input interrupt",
"Cputime limit exceeded",
"Filesize limit exceeded",
"Signal 26",
"Signal 27",
"Signal 28",
"Signal 29",
"Signal 30",
"Signal 31",
"Signal 32"
};
/*
* If the number of .p arguments (np) is 1, and the number of .o arguments
* (nxo) is 0, and we successfully create an ``a.out'', then we remove
* the one .ps .o file (onepso).
*/
int np, nxo;
char *onepso;
int errs;
int onintr();
main(argc, argv)
int argc;
char **argv;
{
register char *argp;
register int i;
int savargx;
char *t, c;
int j;
argc--, argv++;
if (argc == 0) {
execl("/bin/cat", "cat", "/usr/lib/how_pc");
exit(1);
}
if (signal(SIGINT, SIG_IGN) != SIG_IGN) {
signal(SIGINT, onintr);
signal(SIGTERM, onintr);
}
for (i = 0; i < argc; i++) {
argp = argv[i];
if (argp[0] != '-')
continue;
switch (argp[1]) {
case 'd':
if (argp[2] == 0)
debug++;
continue;
case 'i':
pc0args[pc0argx++] = "-i";
while (i+1 < argc && argv[i+1][0] != '-' &&
getsuf(argv[i+1]) != 'p') {
pc0args[pc0argx++] = argv[i+1];
i++;
}
if (i+1 == argc) {
fprintf(stderr, "pc: bad -i construction\n");
exit(1);
}
continue;
case 'o':
i++;
if (i == argc) {
fprintf(stderr, "pc: -o must specify file\n");
exit(1);
}
c = getsuf(argv[i]);
if (c == 'o' || c == 'p' || c == 'c') {
fprintf(stderr, "pc: -o would overwrite %s\n",
argv[i]);
exit(1);
}
continue;
case 'O':
Oflag = 1;
continue;
case 'S':
Sflag = 1;
continue;
case 'J':
Jflag = 1;
continue;
case 'T':
switch (argp[2]) {
case '0':
pc0 = "/usr/src/ucb/pascal/pc0/a.out";
if (argp[3] != '\0') {
pc0 = &argp[3];
}
continue;
case '1':
pc1 = "/usr/src/lib/pcc/fort";
if (argp[3] != '\0') {
pc1 = &argp[3];
}
continue;
case '2':
pc2 = "/usr/src/ucb/pascal/utilities/pc2";
if (argp[3] != '\0') {
pc2 = &argp[3];
}
continue;
case '3':
pc3 = "/usr/src/ucb/pascal/utilities/pc3";
if (argp[3] != '\0') {
pc3 = &argp[3];
}
continue;
case 'l':
Tlflag = 1;
lpc = "/usr/src/usr.lib/libpc/libpc";
if (argp[3] != '\0') {
lpc = &argp[3];
}
continue;
}
continue;
case 'c':
cflag = 1;
continue;
case 'l':
if (argp[2])
continue;
/* fall into ... */
case 'b':
case 's':
case 'z':
case 'C':
pc0args[pc0argx++] = argp;
continue;
case 'w':
wflag = 1;
pc0args[pc0argx++] = argp;
continue;
case 'g':
gflag = 1;
pc0args[pc0argx++] = argp;
continue;
case 't':
fprintf(stderr, "pc: -t is default; -C for checking\n");
continue;
case 'p':
if (argp[2] == 'g')
crt0 = gcrt0;
else
crt0 = mcrt0;
if (!Tlflag)
lpc = "-lpc_p";
pflag = 1;
continue;
}
}
if (gflag && Oflag) {
fprintf(stderr, "pc: warning: -g overrides -O\n");
Oflag = 0;
}
tname[0] = mktemp("/tmp/p0XXXXXX");
tname[1] = mktemp("/tmp/p1XXXXXX");
savargx = pc0argx;
for (i = 0; i < argc; i++) {
argp = argv[i];
if (argp[0] == '-')
continue;
if (suffix(argp) == 's') {
asargx = 1;
if (Jflag)
asargs[asargx++] = "-J";
asargs[asargx++] = argp;
asargs[asargx++] = "-o";
tfile[1] = setsuf(argp, 'o');
asargs[asargx++] = tfile[1];
asargs[asargx] = 0;
if (dosys(as, asargs, 0, 0))
continue;
tfile[1] = 0;
continue;
}
if (suffix(argp) != 'p')
continue;
tfile[0] = tname[0];
pc0args[2] = tfile[0];
pc0argx = savargx;
if (pflag)
pc0args[pc0argx++] = "-p";
pc0args[pc0argx++] = argp;
pc0args[pc0argx] = 0;
if (dosys(pc0, pc0args, 0, 0))
continue;
pc1args[1] = tfile[0];
tfile[1] = tname[1];
if (dosys(pc1, pc1args, 0, tfile[1]))
continue;
unlink(tfile[0]);
tfile[0] = tname[0];
if (Oflag) {
if (dosys(c2, c2args, tfile[1], tfile[0]))
continue;
unlink(tfile[1]);
tfile[1] = tfile[0];
tfile[0] = tname[1];
}
if (Sflag)
tfile[0] = setsuf(argp, 's');
if (dosys(pc2, pc2args, tfile[1], tfile[0]))
continue;
unlink(tfile[1]);
tfile[1] = 0;
if (Sflag) {
tfile[0] = 0;
continue;
}
asargx = 1;
if (Jflag)
asargs[asargx++] = "-J";
asargs[asargx++] = tfile[0];
asargs[asargx++] = "-o";
tfile[1] = setsuf(argp, 'o');
asargs[asargx++] = tfile[1];
asargs[asargx] = 0;
if (dosys(as, asargs, 0, 0))
continue;
tfile[1] = 0;
remove();
}
if (errs || cflag || Sflag)
done();
/* char *pc3args[NARGS] = { "pc3", 0 }; */
pc3args[0] = "pc3";
if (wflag)
pc3args[pc3argx++] = "-w";
pc3args[pc3argx++] = "/usr/lib/pcexterns.o";
for (i = 0; i < argc; i++) {
argp = argv[i];
if (!strcmp(argp, "-o"))
i++;
if (argp[0] == '-')
continue;
switch (getsuf(argp)) {
case 'o':
pc3args[pc3argx++] = argp;
nxo++;
continue;
case 's':
case 'p':
onepso = pc3args[pc3argx++] =
savestr(setsuf(argp, 'o'));
np++;
continue;
}
}
pc3args[pc3argx] = 0;
if (dosys(pc3, pc3args, 0, 0) > 1)
done();
errs = 0;
/* char *ldargs[NARGS] = { "ld", "-X", "/lib/crt0.o", 0, }; */
ldargs[0] = "ld";
ldargs[1] = "-X";
ldargs[2] = crt0;
for (i = 0; i < argc; i++) {
argp = argv[i];
if (argp[0] != '-') {
switch (getsuf(argp)) {
case 'p':
case 's':
ldargs[ldargx] = savestr(setsuf(argp, 'o'));
break;
default:
ldargs[ldargx] = argp;
break;
}
if (getsuf(ldargs[ldargx]) == 'o')
for (j = 0; j < ldargx; j++)
if (!strcmp(ldargs[j], ldargs[ldargx]))
goto duplicate;
ldargx++;
duplicate:
continue;
}
switch (argp[1]) {
case 'i':
while (i+1 < argc && argv[i+1][0] != '-' &&
getsuf(argv[i+1]) != 'p')
i++;
continue;
case 'd':
if (argp[2] == 0)
continue;
ldargs[ldargx++] = argp;
continue;
case 'o':
ldargs[ldargx++] = argp;
i++;
ldargs[ldargx++] = argv[i];
continue;
case 'l':
if (argp[2])
ldargs[ldargx++] = argp;
continue;
case 'c':
case 'g':
case 'w':
case 'p':
case 'S':
case 'J':
case 'T':
case 'O':
case 'C':
case 'b':
case 's':
case 'z':
continue;
default:
ldargs[ldargx++] = argp;
continue;
}
}
ldargs[ldargx++] = lpc;
if (gflag)
ldargs[ldargx++] = "-lg";
if (pflag) {
ldargs[ldargx++] = "-lm_p";
ldargs[ldargx++] = "-lc_p";
} else {
#ifndef sun
ldargs[ldargx++] = "-lm";
ldargs[ldargx++] = "-lc";
#else
ldargs[ldargx++] = "-lMm";
ldargs[ldargx++] = "-lMc";
#endif
}
ldargs[ldargx] = 0;
if (dosys(ld, ldargs, 0, 0)==0 && np == 1 && nxo == 0)
unlink(onepso);
done();
}
dosys(cmd, argv, in, out)
char *cmd, **argv, *in, *out;
{
union wait status;
int pid;
if (debug) {
int i;
printf("%s:", cmd);
for (i = 0; argv[i]; i++)
printf(" %s", argv[i]);
if (in)
printf(" <%s", in);
if (out)
printf(" >%s", out);
printf("\n");
}
pid = vfork();
if (pid < 0) {
fprintf(stderr, "pc: No more processes\n");
done();
}
if (pid == 0) {
if (in) {
close(0);
if (open(in, 0) != 0) {
perror(in);
exit(1);
}
}
if (out) {
close(1);
unlink(out);
if (creat(out, 0666) != 1) {
perror(out);
exit(1);
}
}
signal(SIGINT, SIG_DFL);
execv(cmd, argv);
perror(cmd);
exit(1);
}
while (wait(&status) != pid)
;
if (WIFSIGNALED(status)) {
if (status.w_termsig != SIGINT) {
fprintf(stderr, "%s: %s", cmd, mesg[status.w_termsig]);
if (status.w_coredump)
fprintf(stderr, " (core dumped)");
fprintf(stderr, "\n");
}
errs = 100;
done();
/*NOTREACHED*/
}
if (status.w_retcode) {
errs = 1;
remove();
}
return (status.w_retcode);
}
done()
{
remove();
exit(errs);
}
remove()
{
if (tfile[0])
unlink(tfile[0]);
if (tfile[1])
unlink(tfile[1]);
}
onintr()
{
errs = 1;
done();
}
getsuf(cp)
char *cp;
{
if (*cp == 0)
return;
while (cp[1])
cp++;
if (cp[-1] != '.')
return (0);
return (*cp);
}
char *
setsuf(as, ch)
char *as;
{
register char *s, *s1;
s = s1 = savestr(as);
while (*s)
if (*s++ == '/')
s1 = s;
s[-1] = ch;
return (s1);
}
#define NSAVETAB 512
char *savetab;
int saveleft;
char *
savestr(cp)
register char *cp;
{
register int len;
len = strlen(cp) + 1;
if (len > saveleft) {
saveleft = NSAVETAB;
if (len > saveleft)
saveleft = len;
savetab = (char *)malloc(saveleft);
if (savetab == 0) {
fprintf(stderr, "ran out of memory (savestr)\n");
exit(1);
}
}
strncpy(savetab, cp, len);
cp = savetab;
savetab += len;
return (cp);
}
suffix(cp)
char *cp;
{
if (cp[0] == 0 || cp[1] == 0)
return (0);
while (cp[1])
cp++;
if (cp[-1] == '.')
return (*cp);
return (0);
}