123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764 |
- /*
- * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
- * See the copyright notice in the ACK home directory, in the file "Copyright".
- */
- /* $Id$ */
- /*
- Driver for the CEMCOM compiler: works like /bin/cc and accepts
- most of the options accepted by /bin/cc and /usr/em/bin/ack.
- Date written: dec 4, 1985
- Adapted for 68000 (Aug 19, 1986)
- Merged the vax and mantra versions (Nov 10, 1986)
- Author: Erik Baalbergen
- */
- #include <stdio.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <errno.h>
- #include <signal.h>
- #define MAXARGC 256 /* maximum number of arguments allowed in a list */
- #define USTR_SIZE 1024 /* maximum length of string variable */
- struct arglist {
- int al_argc;
- char *al_argv[MAXARGC];
- };
- /* some system-dependent variables */
- char *PP = "/lib/cpp";
- char *CEM = "/usr/em/lib/em_cemcom";
- char *ENCODE = "/usr/em/lib/em_encode";
- char *DECODE = "/usr/em/lib/em_decode";
- char *OPT = "/usr/em/lib/em_opt";
- char *SHELL = "/bin/sh";
- #ifndef MANTRA
- char *CG = "/usr/em/lib/vax4/cg";
- char *AS = "/bin/as";
- char *AS_FIX = "/user1/erikb/bin/mcomm";
- char *LD = "/bin/ld";
- char *LIBDIR = "/user1/cem/lib";
- char *V_FLAG = "-Vs2.2w4.4i4.4l4.4f4.4d8.4p4.4";
- #else MANTRA
- char *CG = "/usr/em/lib/m68k2/cg";
- char *AS = "/usr/em/lib/m68k2/as";
- char *LD = "/usr/em/lib/em_led";
- char *CV = "/usr/em/lib/m68k2/cv";
- char *LIBDIR = "/usr/em/lib/m68k2";
- char *V_FLAG = "-Vs2.2w2.2i2.2l4.2f4.2d8.2p4.2";
- #endif MANTRA
- struct arglist LD_HEAD = {
- 2,
- {
- #ifndef MANTRA
- "/usr/em/lib/vax4/head_em",
- "/usr/em/lib/vax4/head_cc"
- #else MANTRA
- "/usr/em/lib/m68k2/head_em",
- "/usr/em/lib/m68k2/head_cc"
- #endif MANTRA
- }
- };
- struct arglist LD_TAIL = {
- #ifndef MANTRA
- 4,
- {
- "/user1/cem/lib/libc.a",
- "/user1/cem/lib/stb.o",
- "/usr/em/lib/vax4/tail_mon",
- "/usr/em/lib/vax4/tail_em"
- }
- #else MANTRA
- 7,
- {
- "/usr/em/lib/m68k2/tail_cc.1s",
- "/usr/em/lib/m68k2/tail_cc.2g",
- "/usr/em/lib/m68k2/tail_cem",
- "/usr/em/lib/m68k2/tail_fp.a",
- "/usr/em/lib/m68k2/tail_em.rt",
- "/usr/em/lib/m68k2/tail_mon",
- "/usr/em/lib/m68k2/end_em"
- }
- #endif MANTRA
- };
- char *o_FILE = "a.out";
- #ifdef MANTRA
- char *cv_FILE = "cv.out";
- #endif MANTRA
- #define remove(str) (((FLAG(t) == 0) && unlink(str)), (str)[0] = '\0')
- #define cleanup(str) (str && remove(str))
- #define mkname(dst, s1, s2) mkstr(dst, (s1), (s2), 0)
- #define init(al) (al)->al_argc = 1
- #define library(nm) \
- mkstr(alloc((unsigned int)strlen(nm) + strlen(LIBDIR) + 7), \
- LIBDIR, "/lib", nm, ".a", 0)
- struct arglist SRCFILES, LDFILES, GEN_LDFILES, PP_FLAGS, CEM_FLAGS,
- OPT_FLAGS, DECODE_FLAGS, ENCODE_FLAGS, CG_FLAGS, AS_FLAGS,
- O_FLAGS, DEBUG_FLAGS, CALL_VEC;
- #ifndef MANTRA
- struct arglist LD_FLAGS;
- #else MANTRA
- struct arglist LD_FLAGS = {
- 5,
- {
- "-b0:0x80000",
- "-a0:2",
- "-a1:2",
- "-a2:2",
- "-a3:2"
- }
- };
- struct arglist CV_FLAGS;
- int Nc_flag = 0;
- #endif MANTRA
- /* option naming */
- #define NAME(chr) chr
- #define FLAG(chr) NAME(chr)_flag
- int E_flag, P_flag, S_flag, c_flag, e_flag, k_flag,
- m_flag, o_flag, t_flag, v_flag;
- /* various passes */
- struct prog {
- char *p_name;
- char **p_task;
- struct arglist *p_flags;
- } ProgParts[] = {
- { "cpp", &PP, &PP_FLAGS },
- { "cem", &CEM, &CEM_FLAGS },
- { "opt", &OPT, &OPT_FLAGS },
- { "decode", &DECODE, &DECODE_FLAGS },
- { "encode", &ENCODE, &ENCODE_FLAGS },
- { "be", &CG, &CG_FLAGS },
- { "cg", &CG, &CG_FLAGS },
- { "as", &AS, &AS_FLAGS },
- { "ld", &LD, &LD_FLAGS },
- #ifdef MANTRA
- { "cv", &CV, &CV_FLAGS },
- #endif MANTRA
- { 0, 0, 0 }
- };
- /* various forward declarations */
- int trap();
- char *mkstr();
- char *alloc();
- long sizeof_file();
- /* various globals */
- char *ProgCall = 0;
- int debug = 0;
- int exec = 1;
- int RET_CODE = 0;
- main(argc, argv)
- char *argv[];
- {
- char *str, **argvec, *file, *ldfile = 0;
- int count, ext;
- char Nfile[USTR_SIZE], kfile[USTR_SIZE], sfile[USTR_SIZE],
- mfile[USTR_SIZE], ofile[USTR_SIZE], BASE[USTR_SIZE];
- register struct arglist *call = &CALL_VEC;
- set_traps(trap);
- ProgCall = *argv++;
- append(&CEM_FLAGS, "-L");
- while (--argc > 0) {
- if (*(str = *argv++) != '-') {
- append(&SRCFILES, str);
- continue;
- }
- switch (str[1]) {
- case '-':
- switch (str[2]) {
- case 'C':
- case 'E':
- case 'P':
- FLAG(E) = 1;
- append(&PP_FLAGS, str);
- PP = CEM;
- FLAG(P) = (str[2] == 'P');
- break;
- default:
- append(&DEBUG_FLAGS, str);
- break;
- }
- break;
- case 'B':
- PP = CEM = &str[2];
- break;
- case 'C':
- case 'E':
- case 'P':
- FLAG(E) = 1;
- append(&PP_FLAGS, str);
- FLAG(P) = (str[1] == 'P');
- break;
- case 'c':
- if (str[2] == '.') {
- switch (str[3]) {
- case 's':
- FLAG(S) = 1;
- break;
- case 'k':
- FLAG(k) = 1;
- break;
- case 'o':
- FLAG(c) = 1;
- break;
- case 'm':
- FLAG(m) = 1;
- break;
- case 'e':
- FLAG(e) = 1;
- break;
- default:
- bad_option(str);
- }
- }
- else
- if (str[2] == '\0')
- FLAG(c) = 1;
- else
- bad_option(str);
- break;
- case 'D':
- case 'I':
- case 'U':
- append(&PP_FLAGS, str);
- break;
- case 'k':
- FLAG(k) = 1;
- break;
- case 'l':
- if (str[2] == '\0') /* no standard libraries */
- LD_HEAD.al_argc = LD_TAIL.al_argc = 0;
- else /* use library from library directory */
- append(&SRCFILES, library(&str[2]));
- break;
- case 'L': /* change default library directory */
- LIBDIR = &str[2];
- break;
- case 'm':
- FLAG(m) = 1;
- break;
- #ifdef MANTRA
- case 'N':
- switch (str[2]) {
- case 'c': /* no a.out conversion */
- Nc_flag = 1;
- break;
- case 'l': /* no default options to led */
- LD_FLAGS.al_argc = 0;
- break;
- default:
- bad_option(str);
- }
- break;
- #endif MANTRA
- case 'o':
- FLAG(o) = 1;
- if (argc-- < 0)
- bad_option(str);
- else
- o_FILE = *argv++;
- break;
- case 'O':
- append(&O_FLAGS, "-O");
- break;
- case 'R':
- if (str[2] == '\0')
- append(&CEM_FLAGS, str);
- else
- Roption(str);
- break;
- case 'S':
- FLAG(S) = 1;
- break;
- case 't':
- FLAG(t) = 1;
- break;
- case 'v': /* set debug switches */
- FLAG(v) = 1;
- switch (str[2]) {
- case 'd':
- debug = 1;
- break;
- case 'n': /* no execute */
- exec = 0;
- break;
- case '\0':
- break;
- default:
- bad_option(str);
- }
- break;
- case 'V':
- V_FLAG = str;
- break;
- default:
- append(&LD_FLAGS, str);
- }
- }
- if (debug) report("Note: debug output");
- if (exec == 0)
- report("Note: no execution");
- count = SRCFILES.al_argc;
- argvec = &(SRCFILES.al_argv[0]);
- Nfile[0] = '\0';
- while (count-- > 0) {
- basename(file = *argvec++, BASE);
- if (FLAG(E)) {
- char ifile[USTR_SIZE];
- init(call);
- append(call, PP);
- concat(call, &DEBUG_FLAGS);
- concat(call, &PP_FLAGS);
- append(call, file);
- runvec(call, FLAG(P) ? mkname(ifile, BASE, ".i") : 0);
- continue;
- }
- ext = extension(file);
- /* .c to .k and .N */
- if (ext == 'c' || ext == 'i') {
- init(call);
- append(call, CEM);
- concat(call, &DEBUG_FLAGS);
- append(call, V_FLAG);
- concat(call, &CEM_FLAGS);
- concat(call, &PP_FLAGS);
- append(call, file);
- append(call, mkname(kfile, BASE, ".k"));
- append(call, mkname(Nfile, BASE, ".N"));
- if (runvec(call, (char *)0)) {
- file = kfile;
- ext = 'k';
- if (sizeof_file(Nfile) <= 0L)
- remove(Nfile);
- }
- else {
- remove(kfile);
- remove(Nfile);
- continue;
- }
- }
- /* .e to .k */
- if (ext == 'e') {
- init(call);
- append(call, ENCODE);
- concat(call, &ENCODE_FLAGS);
- append(call, file);
- append(call, mkname(kfile, BASE, ".k"));
- if (runvec(call, (char *)0) == 0)
- continue;
- file = kfile;
- ext = 'k';
- }
- if (FLAG(k))
- continue;
- /* decode .k or .m */
- if (FLAG(e) && (ext == 'k' || ext == 'm')) {
- char efile[USTR_SIZE];
- init(call);
- append(call, DECODE);
- concat(call, &DECODE_FLAGS);
- append(call, file);
- append(call, mkname(efile, BASE, ".e"));
- runvec(call, (char *)0);
- cleanup(kfile);
- continue;
- }
- /* .k to .m */
- if (ext == 'k') {
- init(call);
- append(call, OPT);
- concat(call, &OPT_FLAGS);
- append(call, file);
- if (runvec(call, mkname(mfile, BASE, ".m")) == 0)
- continue;
- file = mfile;
- ext = 'm';
- cleanup(kfile);
- }
- if (FLAG(m))
- continue;
- /* .m to .s */
- if (ext == 'm') {
- init(call);
- append(call, CG);
- concat(call, &CG_FLAGS);
- append(call, file);
- append(call, mkname(sfile, BASE, ".s"));
- if (runvec(call, (char *)0) == 0)
- continue;
- if (Nfile[0] != '\0') {
- #ifndef MANTRA
- init(call);
- append(call, AS_FIX);
- append(call, Nfile);
- append(call, sfile);
- runvec(call, (char *)0);
- #endif MANTRA
- remove(Nfile);
- }
- cleanup(mfile);
- file = sfile;
- ext = 's';
- }
- if (FLAG(S))
- continue;
- /* .s to .o */
- if (ext == 's') {
- ldfile = FLAG(c) ?
- ofile :
- alloc((unsigned)strlen(BASE) + 3);
- init(call);
- append(call, AS);
- concat(call, &AS_FLAGS);
- #ifdef MANTRA
- append(call, "-");
- #endif MANTRA
- append(call, "-o");
- append(call, mkname(ldfile, BASE, ".o"));
- append(call, file);
- if (runvec(call, (char *)0) == 0)
- continue;
- file = ldfile;
- ext = 'o';
- cleanup(sfile);
- }
- if (FLAG(c))
- continue;
- append(&LDFILES, file);
- if (ldfile) {
- append(&GEN_LDFILES, ldfile);
- ldfile = 0;
- }
- }
- /* *.o to a.out */
- if (RET_CODE == 0 && LDFILES.al_argc > 0) {
- init(call);
- append(call, LD);
- concat(call, &LD_FLAGS);
- append(call, "-o");
- #ifndef MANTRA
- append(call, o_FILE);
- #else MANTRA
- append(call, Nc_flag ? o_FILE : cv_FILE);
- #endif MANTRA
- concat(call, &LD_HEAD);
- concat(call, &LDFILES);
- concat(call, &LD_TAIL);
- if (runvec(call, (char *)0)) {
- register i = GEN_LDFILES.al_argc;
- while (i-- > 0)
- remove(GEN_LDFILES.al_argv[i]);
- #ifdef MANTRA
- /* convert to local a.out format */
- if (Nc_flag == 0) {
- init(call);
- append(call, CV);
- concat(call, &CV_FLAGS);
- append(call, cv_FILE);
- append(call, o_FILE);
- if (runvec(call, (char *)0))
- remove(cv_FILE);
- }
- #endif MANTRA
- }
- }
- exit(RET_CODE);
- }
- #define BUFSIZE (USTR_SIZE * MAXARGC)
- char alloc_buf[BUFSIZE];
- char *
- alloc(u)
- unsigned u;
- {
- static char *bufptr = &alloc_buf[0];
- register char *p = bufptr;
- if ((bufptr += u) >= &alloc_buf[BUFSIZE])
- panic("no space");
- return p;
- }
- append(al, arg)
- register struct arglist *al;
- char *arg;
- {
- if (al->al_argc >= MAXARGC)
- panic("argument list overflow");
- al->al_argv[(al->al_argc)++] = arg;
- }
- concat(al1, al2)
- struct arglist *al1, *al2;
- {
- register int i = al2->al_argc;
- register char **p = &(al1->al_argv[al1->al_argc]);
- register char **q = &(al2->al_argv[0]);
- if ((al1->al_argc += i) >= MAXARGC)
- panic("argument list overflow");
- while (i-- > 0)
- *p++ = *q++;
- }
- /* The next function is a dirty old one, taking a variable number of
- arguments.
- Take care that the last argument is a null-valued pointer!
- */
- /*VARARGS1*/
- char *
- mkstr(dst, arg)
- char *dst, *arg;
- {
- char **vec = (char **) &arg;
- register char *p;
- register char *q = dst;
- while (p = *vec++) {
- while (*q++ = *p++);
- q--;
- }
- return dst;
- }
- Roption(str)
- char *str; /* of the form "prog=/-arg" */
- {
- char *eq;
- char *prog, *arg;
- char bc;
- char *cindex();
- prog = &str[2];
- if (eq = cindex(prog, '='))
- bc = '=';
- else
- if (eq = cindex(prog, '-'))
- bc = '-';
- else {
- bad_option(str);
- return;
- }
- *eq++ = '\0';
- if (arg = eq) {
- char *opt = 0;
- struct prog *pp = &ProgParts[0];
- if (bc == '-')
- opt = mkstr(alloc((unsigned)strlen(arg) + 2),
- "-", arg, 0);
- while (pp->p_name) {
- if (strcmp(prog, pp->p_name) == 0) {
- if (opt)
- append(pp->p_flags, opt);
- else
- *(pp->p_task) = arg;
- return;
- }
- pp++;
- }
- }
- bad_option(str);
- }
- basename(str, dst)
- char *str;
- register char *dst;
- {
- register char *p1 = str;
- register char *p2 = p1;
- while (*p1)
- if (*p1++ == '/')
- p2 = p1;
- p1--;
- if (*--p1 == '.') {
- *p1 = '\0';
- while (*dst++ = *p2++) {}
- *p1 = '.';
- }
- else
- while (*dst++ = *p2++) {}
- }
- int
- extension(fn)
- register char *fn;
- {
- char c;
- while (*fn++) {}
- fn--;
- c = *--fn;
- return (*--fn == '.') ? c : 0;
- }
- long
- sizeof_file(nm)
- char *nm;
- {
- struct stat stbuf;
- if (stat(nm, &stbuf) == 0)
- return stbuf.st_size;
- return -1;
- }
- char * sysmsg[] = {
- 0,
- "Hangup",
- "Interrupt",
- "Quit",
- "Illegal instruction",
- "Trace/BPT trap",
- "IOT trap",
- "EMT trap",
- "Floating exception",
- "Killed",
- "Bus error",
- "Memory fault",
- "Bad system call",
- "Broken pipe",
- "Alarm call",
- "Terminated",
- "Signal 16"
- };
- runvec(vec, outp)
- struct arglist *vec;
- char *outp;
- {
- int status, fd;
- char *task = vec->al_argv[1];
- vec->al_argv[vec->al_argc] = 0;
- if (FLAG(v))
- print_vec(vec);
- if (exec == 0)
- return 1;
- if (fork() == 0) { /* start up the process */
- extern int errno;
- if (outp) { /* redirect standard output */
- close(1);
- if ((fd = creat(outp, 0666)) < 0)
- panic("cannot create %s", outp);
- if (fd != 1)
- panic("illegal redirection");
- }
- if (debug) report("exec %s", task);
- execv(task, &(vec->al_argv[1]));
- /* not an a.out file, let's try it with the SHELL */
- if (debug) report("try it with %s", SHELL);
- if (errno == ENOEXEC) {
- vec->al_argv[0] = SHELL;
- execv(SHELL, &(vec->al_argv[0]));
- }
- /* failed, so ... */
- panic("cannot execute %s", task);
- exit(1);
- }
- else {
- int loworder, highorder, sig;
- wait(&status);
- loworder = status & 0377;
- highorder = (status >> 8) & 0377;
- if (loworder == 0) {
- if (highorder)
- report("%s: exit status %d", task, highorder);
- return highorder ? ((RET_CODE = 1), 0) : 1;
- }
- else {
- sig = loworder & 0177;
- if (sig == 0177)
- report("%s: stopped by ptrace", task);
- else
- if (sysmsg[sig])
- report("%s: %s%s", task, sysmsg[sig],
- (loworder & 0200)
- ? " - core dumped"
- : "");
- RET_CODE = 1;
- return 0;
- }
- }
- /*NOTREACHED*/
- }
- bad_option(str)
- char *str;
- {
- report("bad option %s", str);
- }
- /*VARARGS1*/
- report(fmt, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)
- char *fmt;
- {
- fprintf(stderr, "%s: ", ProgCall);
- fprintf(stderr, fmt, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
- fprintf(stderr, "\n");
- }
- /*VARARGS1*/
- panic(fmt, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)
- char *fmt;
- {
- fprintf(stderr, "%s: ", ProgCall);
- fprintf(stderr, fmt, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
- fprintf(stderr, "\n");
- exit(1);
- }
- set_traps(f)
- int (*f)();
- {
- signal(SIGHUP, f);
- signal(SIGINT, f);
- signal(SIGQUIT, f);
- signal(SIGALRM, f);
- signal(SIGTERM, f);
- }
- /*ARGSUSED*/
- trap(sig)
- {
- set_traps(SIG_IGN);
- panic("Trapped");
- }
- print_vec(vec)
- struct arglist *vec;
- {
- register i;
- for (i = 1; i < vec->al_argc; i++)
- printf("%s ", vec->al_argv[i]);
- printf("\n");
- }
- char *
- cindex(s, c)
- char *s, c;
- {
- while (*s)
- if (*s++ == c)
- return s - 1;
- return (char *) 0;
- }
|