home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-11-17 | 40.4 KB | 1,696 lines |
- Newsgroups: comp.os.minix
- Path: sparky!uunet!convex!news.utdallas.edu!wupost!uwm.edu!spool.mu.edu!agate!dog.ee.lbl.gov!news!cod!broman
- From: broman@nosc.mil (Vincent P. Broman)
- Subject: c386 compiler, patched for i80387, bootstrapped by bcc
- Message-ID: <1992Nov17.160026.7727@nosc.mil>
- Reply-To: broman@nosc.mil
- Organization: Naval Ocean Systems Center, San Diego
- Distribution: comp
- Date: Tue, 17 Nov 1992 16:00:26 GMT
- Lines: 1684
-
- I've patched the c386 v4.1 Minix C compiler for 387 floating point operation,
- targeted to a backend of Bruce Evans' assembler and loader, instead
- of gas and gld, c386 being bootstrapped using bcc. This combination was
- almost supported out of the box, but was evidently not tried by the authors.
-
- The widely distributed version of Bruce Evans' assembler does not
- support 387 opcodes, but a newer version found at
- gipsy.vmars.tuwien.ac.at:/pub/minix/bruce/as.zip
- does. Unfortunately, it no longer recognizes '|' as a comment character,
- implementing a logical or instead. While there, get the new ld, too;
- you need it to get a source file as and ld share. Don't throw away
- the old assembler, because the bcc FP emulation routines have names
- that collide with some 387 opcodes. Sigh.
-
- Correct operation of this kind of 387 code in a multitasking environment
- requires patching crtso.s to perform an finit and patching the
- kernel to save the 387 state in the process table on context switches.
- I haven't perfected that yet. The compiler will generate calls to
- FP software emulation routines, but I haven't ported the emulation
- assembler code from gas to bas, yet. I might never.
-
- In the following shar archive:
-
- src.patch contains the changes required for targeting bas/bld, mostly
- in out386_bas.c . The Makefile gets munged, a NO_FLOAT_PRINTF
- option is defined in config.h, so that if your printf cannot emit a .double
- out386_bas will emit 1 or 2 .longs instead, address operands of FP ops
- get length specifiers, and two typos were corrected, one critical.
-
- bcc.patch contains changes needed for bootstrapping with bcc,
- essentially just replacing FP literal constants with cast integer literals.
- bccfp is required to support this.
-
- alloca.s is a bas transcription of the distributed gas routine.
-
- c.c is a cc compiler driver, patched from that posted by CvW a while ago.
- It is table driven and simultaneously supports several compilers and
- compiler parts. E.g. you may want a different cpp from my choice.
- The c386 and c387 it knows about are both really c386, just with and
- without the NOFLOAT option specified. It's slick.
-
- Vincent Broman, code 572 bayside, = o
- Naval Command Control and Ocean Surveillance Center, RDT&E Div. = _ /- _
- San Diego, CA 92152-5000, USA = (_)> (_)
- Internet Email: broman@nosc.mil Fax: +1 619 553 1635 Phone: +1 619 553 1641
- -------------------------------------------------------------------------------
-
- : This is a shar archive. Extract with sh, not csh.
- : The rest of this file will extract:
- : src.patch bcc.patch alloca.s c.c
- echo x src.patch
- sed 's/^X//' > src.patch << 'xEOF'
- Xdiff -c Makefile.orig Makefile
- X*** Makefile.orig Thu Oct 8 21:20:02 1992
- X--- Makefile Sat Oct 10 22:07:46 1992
- X***************
- X*** 4,12 ****
- X # according to the DEFINES set in config.h
- X
- X # Select either GCC or c68 or bcc to compile this (not ACK!!)
- X! CC= cc68
- X! CFLAGS= -O -Qwarn=5
- X! LDFLAGS = -s -m250000
- X
- X HDR = c.h cglbdec.h expr.h gen.h version.h config.h
- X
- X--- 4,13 ----
- X # according to the DEFINES set in config.h
- X
- X # Select either GCC or c68 or bcc to compile this (not ACK!!)
- X! CC= bcc -3
- X! CFLAGS=
- X! LDFLAGS = -i
- X! LIB=
- X
- X HDR = c.h cglbdec.h expr.h gen.h version.h config.h
- X
- X***************
- X*** 15,20 ****
- X--- 16,23 ----
- X stmt.c cmain.c genstmt.c memmgt.c msgout.c \
- X symbol.c decl.c getsym.c genicode.c outgen.c
- X #
- X+ SRCLIB = vfprintf.c
- X+ #
- X SRC68K =config.c68 gen68k.c reg68k.c peep68k.c genffp.c genieee.c \
- X out68k_ack.c out68k_cpm.c out68k_gas.c
- X #
- X***************
- X*** 26,31 ****
- X--- 29,36 ----
- X stmt.o cmain.o genstmt.o memmgt.o msgout.o \
- X symbol.o decl.o getsym.o genicode.o outgen.o
- X #
- X+ OBJLIB = vfprintf.o
- X+ #
- X OBJ68K= gen68k.o reg68k.o peep68k.o genffp.o genieee.o \
- X out68k_ack.o out68k_cpm.o out68k_gas.o
- X #
- X***************
- X*** 39,56 ****
- X @echo " make c68"
- X @echo " make c386"
- X
- X! c68: config_check_c68 $(OBJ) $(OBJ68K) $(OBJ386)
- X! $(CC) $(LDFLAGS) -o c68 $(OBJ) \
- X! $(OBJ68K) \
- X! $(OBJ386)
- X
- X config_check_c68:
- X ./copy-if-change config.c68 config.h
- X
- X! c386: config_check_c386 $(OBJ) $(OBJ68K) $(OBJ386)
- X! $(CC) $(LDFLAGS) -o c386 $(OBJ) \
- X! $(OBJ68K) \
- X! $(OBJ386)
- X
- X config_check_c386:
- X ./copy-if-change config.c386 config.h
- X--- 44,62 ----
- X @echo " make c68"
- X @echo " make c386"
- X
- X! c68: config_check_c68 $(OBJ) $(OBJ68K) $(OBJ386) $(OBJLIB)
- X! $(CC) $(LDFLAGS) -o c68 $(OBJ) \
- X! $(OBJ68K) \
- X! $(OBJ386) $(OBJLIB)
- X
- X config_check_c68:
- X ./copy-if-change config.c68 config.h
- X
- X! c386: config_check_c386 $(OBJ) $(OBJ68K) $(OBJ386) $(OBJLIB)
- X! $(CC) $(LDFLAGS) -o c386 $(OBJ) \
- X! $(OBJ68K) \
- X! $(OBJ386) $(OBJLIB) $(LIB)
- X! chmem =200000 c386
- X
- X config_check_c386:
- X ./copy-if-change config.c386 config.h
- X***************
- X*** 68,70 ****
- X--- 74,79 ----
- X $(OBJ): $(HDR)
- X $(OBJ68K): $(HDR)
- X $(OBJ386): $(HDR)
- X+
- X+ $(OBJLIB): $(HDR)
- X+ $(CC) $(CFLAGS) -c -DINTEL_32BITS `basename $@ .o`.c
- Xdiff -c config.c386.or config.c386
- X*** config.c386.or Thu Oct 8 21:20:11 1992
- X--- config.c386 Sat Oct 10 07:55:33 1992
- X***************
- X*** 20,25 ****
- X--- 20,26 ----
- X /* #define HAS_NLS 1 /* system supports message catalogues */
- X #define HAS_STDARG 1 /* system supports stdarg.h */
- X /* #define NOFLOAT 1 /* Do not generate floating point support */
- X+ #define NO_FLOAT_PRINTF /* no FP printf for emitting float constants */
- X /* #define NODOUBLE 1 /* Treat 'float' and 'double' as same (MFFP version) */
- X /*
- X * These options tend not to be changed except when developing
- X***************
- X*** 50,55 ****
- X--- 51,63 ----
- X #define INTEL_386 1 /* This is an Intel 386 compiler */
- X #define SEPARATE_I_D 1 /* Separate I and D spaces */
- X
- X+ /*
- X+ * if FUNCS_USE_387 is defined, extra library calls are generated if the
- X+ * nofpu option is in effect that allows to use code generated by
- X+ * this compiler to be linked with functions that return values
- X+ * on the 387 stack.
- X+ * there is no provision for returns on the ESP stack.
- X+ */
- X #define FUNCS_USE_387 1 /* ... very special option */
- X
- X /* #define TARGET_GAS /* Assembler Syntax is for GAS/Sun386i */
- X***************
- X*** 144,156 ****
- X #define PROGNAME "c386"
- X #define LIST_NAME "c386.list"
- X #define ICODE_NAME "c386.icode"
- X- /*
- X- * if FUNCS_USE_387 is defined, extra library calls are generated if the
- X- * nofpu option is in effect that allows to use code generated by
- X- * this compiler to be linked with functions that return values
- X- * on the 387 stack
- X- */
- X- #define FUNCS_USE_387
- X #endif
- X
- X #ifndef CPU_DEFINED
- X--- 152,157 ----
- Xdiff -c msgout.c.orig msgout.c
- X*** msgout.c.orig Thu Oct 8 21:21:40 1992
- X--- msgout.c Fri Oct 9 21:29:39 1992
- X***************
- X*** 49,55 ****
- X # define VA_START(a,s) va_start(a,s)
- X # ifdef __STDC__
- X # define P1(p1, p2) (p1 p2, ...)
- X! # define P2(p1, p2, p3, p4) (p1 p2, p3, p4, ...)
- X # else
- X # define P1(p1, p2) (p2) p1 p2;
- X # define P2(p1, p2, p3, p4) (p2, p4) p1 p2; p3 p4;
- X--- 49,55 ----
- X # define VA_START(a,s) va_start(a,s)
- X # ifdef __STDC__
- X # define P1(p1, p2) (p1 p2, ...)
- X! # define P2(p1, p2, p3, p4) (p1 p2, p3 p4, ...)
- X # else
- X # define P1(p1, p2) (p2) p1 p2;
- X # define P2(p1, p2, p3, p4) (p2, p4) p1 p2; p3 p4;
- Xdiff -c out386_bas.ori out386_bas.c
- X*** out386_bas.ori Thu Oct 8 21:18:54 1992
- X--- out386_bas.c Sat Oct 10 06:03:46 1992
- X***************
- X*** 64,69 ****
- X--- 64,70 ----
- X
- X #define BI 1
- X #define SP 2
- X+ #define FP 4
- X
- X static struct oplst {
- X char *s;
- X***************
- X*** 71,76 ****
- X--- 72,78 ----
- X int sa; /* special addressing modes:
- X * BI immediate is bracketed,
- X * SP size prefix needed.
- X+ * FP 387 op
- X */
- X } opl[] =
- X
- X***************
- X*** 119,139 ****
- X "rep", op_rep, SP,
- X "movs", op_smov, BI | SP,
- X "test", op_test, BI | SP,
- X! "fadd", op_fadd, BI | SP,
- X! "fsub", op_fsub, BI | SP,
- X! "fsubr", op_fsubr, BI | SP,
- X! "fmul", op_fmul, BI | SP,
- X! "fdiv", op_fdiv, BI | SP,
- X! "fdivr", op_fdivr, BI | SP,
- X! "fchs", op_fchs, BI | SP,
- X! "fld", op_fld, BI | SP,
- X! "fild", op_fild, BI | SP,
- X! "fst", op_fst, BI | SP,
- X! "fstp", op_fstp, BI | SP,
- X! "fstp %st(0)", op_fpop, BI | SP,
- X! "fcompp", op_fcompp, BI | SP,
- X! "ftst", op_ftst, BI | SP,
- X! "fnstsw", op_fnstsw, BI | SP,
- X "sahf", op_sahf, BI | SP,
- X 0, 0, 0
- X };
- X--- 121,143 ----
- X "rep", op_rep, SP,
- X "movs", op_smov, BI | SP,
- X "test", op_test, BI | SP,
- X! #ifndef NOFLOAT
- X! "fadd", op_fadd, BI | SP | FP,
- X! "fsub", op_fsub, BI | SP | FP,
- X! "fsubr", op_fsubr, BI | SP | FP,
- X! "fmul", op_fmul, BI | SP | FP,
- X! "fdiv", op_fdiv, BI | SP | FP,
- X! "fdivr", op_fdivr, BI | SP | FP,
- X! "fchs", op_fchs, BI | SP | FP,
- X! "fld", op_fld, BI | SP | FP,
- X! "fild", op_fild, BI | SP | FP,
- X! "fst", op_fst, BI | SP | FP,
- X! "fstp", op_fstp, BI | SP | FP,
- X! "fstp st(0)", op_fpop, BI | SP | FP,
- X! "fcompp", op_fcompp, BI | SP | FP,
- X! "ftst", op_ftst, BI | SP | FP,
- X! "fnstsw", op_fnstsw, BI | SP | FP,
- X! #endif
- X "sahf", op_sahf, BI | SP,
- X 0, 0, 0
- X };
- X***************
- X*** 257,262 ****
- X--- 261,276 ----
- X break;
- X }
- X }
- X+ #ifndef NOFLOAT
- X+ if (sa & FP) {
- X+ /* assume that st(n) never appears explicitly as an operand here */
- X+ if (len >= 8)
- X+ oprintf("qword ptr ");
- X+ else if (len >= 4)
- X+ oprintf("dword ptr ");
- X+ /* else fnstsw should not need a length? */
- X+ }
- X+ #endif
- X switch (ap->mode) {
- X case am_immed:
- X oprintf("#");
- X***************
- X*** 290,296 ****
- X oprintf("[%s+%s]",regname[ap->preg],regname[ap->sreg]);
- X break;
- X default:
- X! fatal("out386_bas/putamdoe","illegal address mode %d",ap->mode);
- X break;
- X }
- X }
- X--- 304,310 ----
- X oprintf("[%s+%s]",regname[ap->preg],regname[ap->sreg]);
- X break;
- X default:
- X! fatal("out386_bas/putamode","illegal address mode %d",ap->mode);
- X break;
- X }
- X }
- X***************
- X*** 414,427 ****
- X genfloat(val)
- X double val;
- X {
- X! oprintf("\t.float %20.15e\n",val);
- X }
- X
- X void
- X gendouble(val)
- X double val;
- X {
- X! oprintf("\t.double %20.15e\n",val);
- X }
- X #endif
- X
- X--- 428,453 ----
- X genfloat(val)
- X double val;
- X {
- X! #ifndef NO_FLOAT_PRINTF
- X! oprintf("\t.float %14.7e\n",val);
- X! #else
- X! float fval;
- X! fval = (float) val;
- X! /* this type transfer won't cross compile, of course. */
- X! oprintf("\t.long %d\n", ((long *)&fval)[0]);
- X! #endif
- X }
- X
- X void
- X gendouble(val)
- X double val;
- X {
- X! #ifndef NO_FLOAT_PRINTF
- X! oprintf("\t.double %23.16e\n",val);
- X! #else
- X! /* this type transfer won't cross compile, of course. */
- X! oprintf("\t.long %d, %d\n", ((long *)&val)[0], ((long *)&val)[1]);
- X! #endif
- X }
- X #endif
- X
- xEOF
- echo x bcc.patch
- sed 's/^X//' > bcc.patch << 'xEOF'
- Xdiff -c expr.c expr.c.bcc
- X*** expr.c Thu Oct 8 21:20:55 1992
- X--- expr.c.bcc Fri Oct 9 21:59:04 1992
- X***************
- X*** 673,679 ****
- X } else if (floating(tp)) {
- X ep2 = mk_node(en_fcon, NIL_ENODE, NIL_ENODE);
- X #ifndef NOFLOAT
- X! ep2->v.f = 1.0;
- X #endif
- X if (tp->type == bt_float) {
- X ep2->etype = tp_float.type;
- X--- 673,679 ----
- X } else if (floating(tp)) {
- X ep2 = mk_node(en_fcon, NIL_ENODE, NIL_ENODE);
- X #ifndef NOFLOAT
- X! ep2->v.f = ((double) 1);
- X #endif
- X if (tp->type == bt_float) {
- X ep2->etype = tp_float.type;
- X***************
- X*** 890,896 ****
- X if (floating(tp)) {
- X ep2 = mk_node(en_fcon, NIL_ENODE, NIL_ENODE);
- X #ifndef NOFLOAT
- X! ep2->v.f = 1.0;
- X #endif
- X if (tp->type == bt_float) {
- X ep2->etype = tp_float.type;
- X--- 890,896 ----
- X if (floating(tp)) {
- X ep2 = mk_node(en_fcon, NIL_ENODE, NIL_ENODE);
- X #ifndef NOFLOAT
- X! ep2->v.f = ((double) 1);
- X #endif
- X if (tp->type == bt_float) {
- X ep2->etype = tp_float.type;
- Xdiff -c getsym.c getsym.c.bcc
- X*** getsym.c Thu Oct 8 21:21:32 1992
- X--- getsym.c.bcc Sat Oct 10 07:30:57 1992
- X***************
- X*** 439,452 ****
- X register unsigned long i=0;
- X register int j;
- X #ifndef NOFLOAT
- X! register double r = 0.0;
- X #endif
- X
- X while (isdigit(lastch)) {
- X j = radix36(lastch);
- X i = 10 * i + j;
- X #ifndef NOFLOAT
- X! r = 10.0 * r + (double) j;
- X #endif
- X getch();
- X }
- X--- 439,452 ----
- X register unsigned long i=0;
- X register int j;
- X #ifndef NOFLOAT
- X! register double r = ((double) 0);
- X #endif
- X
- X while (isdigit(lastch)) {
- X j = radix36(lastch);
- X i = 10 * i + j;
- X #ifndef NOFLOAT
- X! r = ((double) 10) * r + (double) j;
- X #endif
- X getch();
- X }
- X***************
- X*** 496,506 ****
- X {
- X #ifndef NOFLOAT
- X double frmul;
- X! frmul = 10.0;
- X while (isdigit(lastch)) {
- X rval += (double) radix36(lastch) / frmul;
- X getch();
- X! frmul *= 10.0;
- X }
- X #endif
- X }
- X--- 496,506 ----
- X {
- X #ifndef NOFLOAT
- X double frmul;
- X! frmul = ((double) 10);
- X while (isdigit(lastch)) {
- X rval += (double) radix36(lastch) / frmul;
- X getch();
- X! frmul *= ((double) 10);
- X }
- X #endif
- X }
- X***************
- X*** 526,538 ****
- X switch (lastch) {
- X case '-':
- X getch();
- X! multiplier = 1/10.0;
- X break;
- X case '+':
- X getch();
- X /* FALL THRU */
- X default:
- X! multiplier = 10.0;
- X break;
- X }
- X getdecimal();
- X--- 526,538 ----
- X switch (lastch) {
- X case '-':
- X getch();
- X! multiplier = ((double) 1) / ((double) 10);
- X break;
- X case '+':
- X getch();
- X /* FALL THRU */
- X default:
- X! multiplier = ((double) 10);
- X break;
- X }
- X getdecimal();
- X***************
- X*** 797,803 ****
- X getch();
- X if (isdigit(lastch)) {
- X #ifndef NOFLOAT
- X! rval = 0.0;
- X #endif
- X getfrac();
- X lastst = rconst;
- X--- 797,803 ----
- X getch();
- X if (isdigit(lastch)) {
- X #ifndef NOFLOAT
- X! rval = ((double) 0);
- X #endif
- X getfrac();
- X lastst = rconst;
- Xdiff -c optimize.c optimize.c.bcc
- X*** optimize.c Sat Jul 25 13:12:46 1992
- X--- optimize.c.bcc Fri Oct 9 22:01:16 1992
- X***************
- X*** 80,86 ****
- X epf = ep0->v.f * ep1->v.f;
- X break;
- X case en_div:
- X! if (ep1->v.f == 0.0) {
- X message(GWARN_DIVZERO);
- X ep->nodetype = en_div;
- X } else {
- X--- 80,86 ----
- X epf = ep0->v.f * ep1->v.f;
- X break;
- X case en_div:
- X! if (ep1->v.f == ((double) 0)) {
- X message(GWARN_DIVZERO);
- X ep->nodetype = en_div;
- X } else {
- xEOF
- echo x alloca.s
- sed 's/^X//' > alloca.s << 'xEOF'
- X .text
- X export alloca
- X export __builtin_alloca
- Xalloca:
- X__builtin_alloca:
- X pop ecx
- X mov eax,[esp]
- X add eax,$3
- X and eax,$-4
- X sub esp,eax
- X mov eax,esp
- X add eax,$4
- X jmp [ecx]
- xEOF
- echo x c.c
- sed 's/^X//' > c.c << 'xEOF'
- X/*
- X * (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
- X * See the copyright notice in the file "../Copyright".
- X */
- X
- X/* Driver for Minix compilers.
- X Written june 1987 by Ceriel J.H. Jacobs, partly derived from old
- X cc-driver, written by Erik Baalbergen.
- X This driver is mostly table-driven, the table being in the form of
- X some global initialized structures.
- X*/
- X
- X/*
- X extensions added by Christoph van Wuellen (this work begun to
- X support my c68 68000 C-Compiler)
- X
- X - support of three alternate C compilers, selectable at runtime:
- X - the default is: ACK compiling system with 16-bit ints
- X - the -c68s option switches to c68 using 16-bit ints
- X - the -c68l option switches to c68 using 32-bit ints
- X - the -sozo option switches to the SOZOBON compiler with
- X 16-bit ints. The postoptimizer is always applied.
- X
- X - two features selectable at compile time:
- X - support of ACK floating point stuff (inclusion of a fpp pass)
- X - support of the new MINIX linker posted to comp.os.minix
- X
- X*/
- X/*
- X extensions added by Vincent Broman 1992:
- X support driving bcc3, bcc0, c386 and c387.
- X */
- X
- X#include <errno.h>
- X#include <signal.h>
- X
- X/*
- X * For all program paths (so not the other files, like libraries) that
- X * start with "/usr/" and are executable according to access(..., 1),
- X * the leading "/usr" is stripped off.
- X */
- X
- X#define SHELL "/bin/sh"
- X
- X#define AS "/usr/bin/as"
- X#define CEM "/usr/lib/cem"
- X#define CG "/usr/lib/cg"
- X#define PP "/usr/lib/cpp"
- X#define CRT "/usr/lib/crtso.o"
- X#define CRT32 "/usr/lib/crtso32.o"
- X#define CV "/usr/lib/cv"
- X#define PC "/usr/lib/em_pc"
- X#define END "/usr/lib/end.o"
- X#define END32 "/usr/lib/end32.o"
- X#define LD "/usr/lib/ld"
- X#define LIBC "/usr/lib/liback.a"
- X#define LIBC68 "/usr/lib/libc68.a"
- X#define LIBC6832 "/usr/lib/libc68_32.a"
- X#define LIBSOZO "/usr/lib/libsozo.a"
- X#define LIBP "/usr/lib/libp.a"
- X#define OPT "/usr/lib/opt"
- X#define PRT "/usr/lib/prtso.o"
- X#define LIBPREFIX "/usr/lib/lib"
- X
- X#define CCCP "/local/bin/cccp"
- X#define DECUSCPP "/local/bin/cpp"
- X#define C386 "/local/bin/c386"
- X#define C387 "/local/bin/c387"
- X#define SC "/local/bin/sc"
- X#define BAS "/local/bin/as"
- X#define BAS87 "/local/bin/as87"
- X#define BLD "/local/bin/ld"
- X#define C386CRT "/usr/local/lib/c386bas/crtso.o"
- X#define C386LIBC "/usr/local/lib/c386bas/libc.a"
- X#define C387CRT "/usr/local/lib/c387bas/crtso.o"
- X#define C387LIBC "/usr/local/lib/c386bas/libc.a" /* not separate yet */
- X#define B3CRT "/usr/local/lib/i386/crtso.o"
- X#define B3LIBC "/usr/local/lib/i386/libc.a"
- X#define B0CRT "/usr/local/lib/i86/crtso.o"
- X#define B0LIBC "/usr/local/lib/i86/libc.a"
- X
- X#define PEM "-R/usr/lib/pem"
- X#define PC_ERR "-r/usr/lib/pc_errors"
- X
- X#define C68 "/usr/lib/c68"
- X#define FPP "/usr/lib/fpp"
- X#define HCC "/usr/lib/hcc"
- X#define TOP "/usr/lib/top"
- X#define NEW_LD "/usr/bin/ld"
- X
- X
- X/* every pass that this program knows about has associated with it
- X a structure, containing such information as its name, where it
- X resides, the flags it accepts, and the like.
- X*/
- Xstruct passinfo {
- X char *p_name; /* name of this pass */
- X char *p_path; /* where is it */
- X char *p_from; /* suffix of source (comma-separated list) */
- X char *p_to; /* suffix of destination */
- X char *p_acceptflags; /* comma separated list; format:
- X flag
- X flag*
- X flag=xxx
- X flag*=xxx[*]
- X where a star matches a, possibly empty,
- X string
- X */
- X int p_flags;
- X#define INPUT 01 /* needs input file as argument */
- X#define OUTPUT 02 /* needs output file as argument */
- X#define LOADER 04 /* this pass is the loader */
- X#define STDIN 010 /* reads from standard input */
- X#define STDOUT 020 /* writes on standard output */
- X#define SOURCE 040 /* give source file name as last argument
- X (hack for pc)
- X */
- X#define O_OUTPUT 0100 /* -o outputfile, hack for as */
- X#define PREPALWAYS 0200 /* always to be preprocessed */
- X#define PREPCOND 0400 /* preprocessed when starting with '#' */
- X#define LD2STEPS 01000 /* ld followed by cv */
- X};
- X
- X#define MAXHEAD 7
- X#define MAXTAIL 4
- X/*
- X * MAXPASS used to be 7, but with FPP possibly defined there is an
- X * additional pass. If you choose the new linker, the number is again
- X * smaller since the new linker does the 'cv' job, too.
- X * A too high number does not matter, anyway.
- X */
- X#define MAXPASS 8
- X
- X/* Every language handled by this program has a "compile" structure
- X associated with it, describing the start-suffix, how the driver for
- X this language is called, which passes must be called, which flags
- X and arguments must be passed to these passes, etc.
- X The language is determined by the suffix of the argument program.
- X However, if this suffix does not determine a language (DEFLANG),
- X the callname is used.
- X Notice that the 's' suffix does not determine a language, because
- X the input file could have been derived from f.i. a C-program.
- X So, if you use "cc x.s", the C-runtime system will be used, but if
- X you use "as x.s", it will not.
- X*/
- Xstruct compile {
- X char *c_suffix; /* starting suffix of this list of passes */
- X char *c_callname; /* affects runtime system loaded with program */
- X struct pass {
- X char *pp_name; /* name of the pass */
- X char *pp_head[MAXHEAD]; /* args in front of filename */
- X char *pp_tail[MAXTAIL]; /* args after filename */
- X } c_passes[MAXPASS];
- X int c_flags;
- X#define DEFLANG 010 /* this suffix determines a language */
- X};
- X
- Xstruct passinfo passinfo[] = {
- X { "cpp", PP, 0, "i", "I*,D*,U*", INPUT|STDOUT },
- X#ifdef C68
- X { "c68", C68, "i,c", "s", "Q*", INPUT|OUTPUT|PREPALWAYS },
- X#endif
- X
- X { "cccp", CCCP, "c", "i", "D*,I*,U*,Wal*,ped*,tri*,nostdinc",
- X INPUT|OUTPUT },
- X { "decuscpp", DECUSCPP, "c", "i", "D*,I*,U*,C,E,N,P,T*,X*",
- X INPUT|OUTPUT },
- X { "app", DECUSCPP, "x", "s", "D*,I*,U*,E,N,P,T*,X*",
- X INPUT|OUTPUT },
- X { "c386", C386, "i", "s", "noopt,noreg,icode,list,warn*,nowarn,trad,noreg",
- X INPUT|OUTPUT },
- X { "c387", C387, "i", "s", "noopt,noreg,icode,list,warn*,nowarn,trad,noreg,nofpu",
- X INPUT|OUTPUT },
- X { "sc", SC, "i,c", "s", "D*,I*,d,p,t", STDIN|STDOUT },
- X { "bas", BAS, "s", "o", "g,j,m", INPUT|O_OUTPUT },
- X { "bas87", BAS87, "s", "o", "g,j,m", INPUT|O_OUTPUT },
- X { "bld", BLD, "o", "out", "M,r,s", INPUT|O_OUTPUT|LOADER },
- X
- X#ifdef FPP
- X { "fpp", FPP, "m", "n", "", INPUT|OUTPUT },
- X#endif
- X#ifdef HCC
- X { "hcc", HCC, "c", "x", "I*,D*,U*", STDIN|STDOUT },
- X#endif
- X#ifdef TOP
- X { "top", TOP, "x", "s", "", INPUT|OUTPUT },
- X#endif
- X { "cem", CEM, "i,c", "k", "R,p,w,T*,I*,D*,U*", INPUT|OUTPUT },
- X { "pc", PC, "i,p", "k", "L,p,w,e,E,T*,{*", INPUT|OUTPUT|SOURCE|PREPCOND },
- X { "opt", OPT, "k", "m", "LIB=L", STDIN|STDOUT },
- X#ifdef FPP
- X /* cg processes fpp output */
- X { "cg", CG, "n", "s", "O=p4", INPUT|OUTPUT },
- X#else
- X { "cg", CG, "m", "s", "O=p4", INPUT|OUTPUT },
- X#endif
- X { "as", AS, "i,s", "o", "T*", INPUT|O_OUTPUT|PREPCOND },
- X#ifdef NEW_LD
- X { "ld", NEW_LD, "o", "out", "m*,r,s,u*,w", INPUT|O_OUTPUT|LOADER },
- X#else
- X { "ld", LD, "o", "out", "r,s", INPUT|LOADER|LD2STEPS },
- X { "cv", CV, "out", 0, "", INPUT|OUTPUT }, /* must come after loader */
- X#endif
- X { 0}
- X};
- X
- Xstruct compile c68_short_pass =
- X{ "c", "cc",
- X { { "c68", {"-Qshort"}, {0} },
- X { "as", {"-"}, {0} },
- X#ifdef NEW_LD
- X { "ld", {"-X_","-a0:2", "-a1:2", "-a2:2", "-a3:2", CRT},
- X {LIBC68, END}},
- X#else
- X { "ld", {"-c", "-a0:2", "-a1:2", "-a2:2", "-a3:2", CRT},
- X {LIBC68, END}},
- X { "cv", {0}, {0} }
- X#endif
- X },
- X DEFLANG
- X};
- X
- Xstruct compile c68_long_pass =
- X{ "c", "cc",
- X { { "c68", {"-Qnoshort"}, {0} },
- X { "as", {"-"}, {0} },
- X#ifdef NEW_LD
- X { "ld", {"-X_","-a0:2", "-a1:2", "-a2:2", "-a3:2", CRT32},
- X {LIBC6832, END32}},
- X#else
- X { "ld", {"-c", "-a0:2", "-a1:2", "-a2:2", "-a3:2", CRT32},
- X {LIBC6832, END32}},
- X { "cv", {0}, {0} }
- X#endif
- X },
- X DEFLANG
- X};
- X
- Xstruct compile sozobon_pass =
- X{ "c", "cc",
- X { { "hcc", {0}, {0} },
- X { "top", {0}, {0} },
- X { "as", {"-"}, {0} },
- X#ifdef NEW_LD
- X { "ld", {"-X_","-a0:2", "-a1:2", "-a2:2", "-a3:2", CRT},
- X {LIBSOZO, END}},
- X#else
- X { "ld", {"-c", "-a0:2", "-a1:2", "-a2:2", "-a3:2", CRT},
- X {LIBSOZO, END}},
- X { "cv", {0}, {0} }
- X#endif
- X },
- X DEFLANG
- X};
- X
- Xstruct compile bcc3_pass =
- X{ "c", "c",
- X { { "sc", {"-3"}, {0} },
- X { "bas", {"-3", "-u", "-w"}, {0} },
- X { "bld", {"-3","-i", B3CRT},
- X {B3LIBC}}
- X },
- X DEFLANG
- X};
- X
- Xstruct compile bcc0_pass =
- X{ "c", "c",
- X { { "sc", {"-0"}, {0} },
- X { "bas", {"-0", "-u", "-w"}, {0} },
- X { "bld", {"-0","-i", B0CRT},
- X {B0LIBC}}
- X },
- X DEFLANG
- X};
- X
- Xstruct compile c386_pass =
- X{ "c", "c",
- X {
- X { "cccp", {"-traditional"}, {0} },
- X { "c386", {0}, {0} },
- X { "bas", {"-3", "-j", "-u", "-w"}, {0} },
- X { "bld", {"-3","-i", C386CRT}, {C386LIBC}}
- X },
- X DEFLANG
- X};
- X
- Xstruct compile c387_pass =
- X{ "c", "c",
- X {
- X { "decuscpp", {0}, {0} },
- X { "c387", {0}, {0} },
- X { "bas87", {"-3", "-j", "-u", "-w"}, {0} },
- X { "bld", {"-3","-i", C387CRT}, {C387LIBC}}
- X },
- X DEFLANG
- X};
- X
- Xstruct compile ack_pass =
- X{ "c", "cc",
- X { { "cem", {"-L"}, {0} },
- X { "opt", {0}, {0} },
- X#ifdef FPP
- X { "fpp", {0}, {0} },
- X#endif
- X { "cg", {0}, {0} },
- X { "as", {"-"}, {0} },
- X#ifdef NEW_LD
- X { "ld", {"-X_","-a0:2", "-a1:2", "-a2:2", "-a3:2", CRT},
- X {LIBC, END}},
- X#else
- X { "ld", {"-c", "-a0:2", "-a1:2", "-a2:2", "-a3:2", CRT},
- X {LIBC, END}},
- X { "cv", {0}, {0} }
- X#endif
- X },
- X DEFLANG
- X};
- X
- X/*
- X * passes[C_ACK_PASS] has to be replaced by an alternate pass
- X * if an alternate compiler is to be used
- X */
- X#define C_ACK_PASS 0 /* look at the initialization of passes[] */
- X
- X
- Xstruct compile passes[] = {
- X{ "c", "cc",
- X { { "cem", {"-L"}, {0} },
- X { "opt", {0}, {0} },
- X#ifdef FPP
- X { "fpp", {0}, {0} },
- X#endif
- X { "cg", {0}, {0} },
- X { "as", {"-"}, {0} },
- X#ifdef NEW_LD
- X { "ld", {"-X_","-a0:2", "-a1:2", "-a2:2", "-a3:2", CRT},
- X {LIBC, END}},
- X#else
- X { "ld", {"-c", "-a0:2", "-a1:2", "-a2:2", "-a3:2", CRT},
- X {LIBC, END}},
- X { "cv", {0}, {0} }
- X#endif
- X },
- X DEFLANG
- X},
- X{ "p", "pc",
- X { { "pc", { PEM, PC_ERR, "-Vw2i2j2p2f8l4" }, {0} },
- X { "opt", {0}, {0} },
- X { "cg", {0}, {0} },
- X { "as", {"-"}, {0} },
- X#ifdef NEW_LD
- X { "ld", {"-X_","-a0:2", "-a1:2", "-a2:2", "-a3:2", PRT},
- X {LIBP, LIBC, END}},
- X#else
- X { "ld", {"-c", "-a0:2", "-a1:2", "-a2:2", "-a3:2", PRT},
- X {LIBP, LIBC,
- X END}},
- X { "cv", {0}, {0} }
- X#endif
- X },
- X DEFLANG
- X},
- X{ "s", "as",
- X { { "as", {0}, {0}}},
- X 0
- X},
- X{ "x", "c",
- X { { "app", {"-P"}, {0}},
- X { "as", {0}, {0}}
- X },
- X DEFLANG
- X},
- X{ 0
- X}
- X};
- X
- X#define MAXARGC 128 /* maximum number of arguments allowed in a list */
- X#define USTR_SIZE 64 /* maximum length of string variable */
- X
- Xtypedef char USTRING[USTR_SIZE];
- X
- Xstruct arglist {
- X int al_argc;
- X char *al_argv[MAXARGC];
- X};
- X
- Xstruct arglist CALLVEC[2];
- X
- Xint kids[] = {-1, -1};
- X
- Xchar *o_FILE = "a.out"; /* default name for executable file */
- X
- X#define init(a) ((a)->al_argc = 1)
- X#define cleanup(str) (str && remove(str))
- X#define library(nm) \
- X mkstr(alloc((unsigned int)strlen(nm) + strlen(LIBPREFIX) + 7), \
- X LIBPREFIX, nm, ".a")
- X
- Xchar *ProgCall = 0;
- X
- Xint RET_CODE = 0;
- X
- Xchar *stopsuffix = 0;
- Xint v_flag = 0;
- Xint t_flag = 0;
- Xint noexec = 0;
- X
- Xchar *mkstr();
- Xchar *alloc();
- Xchar *process();
- Xchar *strcpy(), *strcat();
- X
- XUSTRING curfil;
- XUSTRING newfil;
- Xstruct arglist SRCFILES;
- Xstruct arglist LDFILES;
- Xstruct arglist GEN_LDFILES;
- Xstruct arglist FLAGS;
- X
- Xchar *tmpdir = "/tmp";
- Xchar tmpname[64];
- X
- Xstruct compile *compbase;
- Xstruct pass *loader;
- Xstruct passinfo *loaderinfo;
- Xchar *source;
- X
- Xtrapcc(sig)
- X int sig;
- X{
- X signal(sig, SIG_IGN);
- X if (kids[0] != -1) kill(kids[0], sig);
- X if (kids[1] != -1) kill(kids[1], sig);
- X cleanup(newfil);
- X cleanup(curfil);
- X exit(1);
- X}
- X
- X/*
- X * trade in a nondefault compiler and
- X * ensure that the different C compilers are not called at the same time
- X */
- Xvoid
- Xswitch_c_compilers(compiler)
- Xstruct compile compiler;
- X{
- X static int pass_changed = 0;
- X char *err =
- X"c: the -bcc3 -bcc0 -c386 -c387 -ack, -sozo, -c68s and -c68l flags are exclusive\n";
- X
- X if (pass_changed)
- X {
- X write(2,err,strlen(err));
- X exit(1);
- X }
- X pass_changed = 1;
- X passes[C_ACK_PASS] = compiler;
- X}
- X
- Xmain(argc, argv)
- X char *argv[];
- X{
- X char *str;
- X char **argvec;
- X int count;
- X char *file;
- X
- X ProgCall = *argv++;
- X
- X passes[C_ACK_PASS] = c386_pass; /* initial default compiler */
- X
- X signal(SIGHUP, trapcc);
- X signal(SIGINT, trapcc);
- X signal(SIGQUIT, trapcc);
- X while (--argc > 0) {
- X if (*(str = *argv++) != '-') {
- X append(&SRCFILES, str);
- X continue;
- X }
- X
- X switch (str[1]) {
- X
- X case 'a':
- X if (!strcmp(str,"-ack")) {
- X switch_c_compilers(ack_pass);
- X } else {
- X append(&FLAGS, str);
- X }
- X break;
- X case 'b':
- X if (!strcmp(str,"-bcc3")) {
- X switch_c_compilers(bcc3_pass);
- X } else if (!strcmp(str,"-bcc0")) {
- X switch_c_compilers(bcc0_pass);
- X } else {
- X append(&FLAGS, str);
- X }
- X break;
- X case 'c':
- X if (!strcmp(str,"-c68s")) {
- X switch_c_compilers(c68_short_pass);
- X } else if (!strcmp(str,"-c68l")) {
- X switch_c_compilers(c68_long_pass);
- X } else if (!strcmp(str,"-c386")) {
- X switch_c_compilers(c386_pass);
- X } else if (!strcmp(str,"-c387")) {
- X switch_c_compilers(c387_pass);
- X } else {
- X stopsuffix = "o";
- X }
- X break;
- X case 'F':
- X break;
- X case 'l':
- X append(&SRCFILES, library(&str[2]));
- X break;
- X case 'o':
- X if (argc-- >= 0)
- X o_FILE = *argv++;
- X break;
- X case 'S':
- X stopsuffix = "s";
- X break;
- X case 'v':
- X v_flag++;
- X if (str[2] == 'n')
- X noexec = 1;
- X break;
- X case 't':
- X /* save temporaries */
- X t_flag++;
- X break;
- X case 's':
- X if (!strcmp(str,"-sozo")) {
- X switch_c_compilers(sozobon_pass);
- X } else {
- X append(&FLAGS, str);
- X }
- X break;
- X case 'T':
- X tmpdir = &str[2];
- X /*FALLTHROUGH*/
- X default:
- X append(&FLAGS, str);
- X
- X }
- X }
- X
- X/*
- X * The call to mkbase has to be delayed until now since passes[]
- X * is not initialized till now.
- X */
- X mkbase();
- X mktempname(tmpname);
- X
- X count = SRCFILES.al_argc;
- X argvec = &(SRCFILES.al_argv[0]);
- X
- X while (count-- > 0) {
- X
- X file = *argvec++;
- X source = file;
- X
- X if (SRCFILES.al_argc > 1) {
- X write(1, file, strlen(file));
- X write(1, ":\n", 2);
- X }
- X
- X file = process(file, 1);
- X
- X if (file && ! stopsuffix) append(&LDFILES, file);
- X }
- X
- X clean(&SRCFILES);
- X
- X /* loader ... */
- X if (RET_CODE == 0 && LDFILES.al_argc > 0) {
- X register struct passinfo *pp = passinfo;
- X
- X while (!(pp->p_flags & LOADER)) pp++;
- X mkstr(newfil, tmpname, pp->p_to, "");
- X callld(&LDFILES, (pp->p_flags&LD2STEPS)? newfil: o_FILE,
- X loader, pp);
- X if (RET_CODE == 0) {
- X register int i = GEN_LDFILES.al_argc;
- X
- X while (i-- > 0) {
- X remove(GEN_LDFILES.al_argv[i]);
- X free(GEN_LDFILES.al_argv[i]);
- X }
- X if (pp->p_flags&LD2STEPS) {
- X process(newfil, 0);
- X }
- X }
- X }
- X exit(RET_CODE);
- X}
- X
- Xremove(str)
- X char *str;
- X{
- X if (t_flag)
- X return;
- X if (v_flag) {
- X prs("rm ");
- X prs(str);
- X prs("\n");
- X }
- X if (noexec)
- X return;
- X unlink(str);
- X}
- X
- Xchar *
- Xalloc(u)
- X unsigned u;
- X{
- X char *malloc();
- X register char *p = malloc(u);
- X
- X if (p == 0) panic("no space\n");
- X return p;
- X}
- X
- Xappend(al, arg)
- X struct arglist *al;
- X char *arg;
- X{
- X char *a = alloc((unsigned) (strlen(arg) + 1));
- X
- X strcpy(a, arg);
- X if (al->al_argc >= MAXARGC)
- X panic("argument list overflow\n");
- X al->al_argv[(al->al_argc)++] = a;
- X}
- X
- Xconcat(al1, al2)
- X struct arglist *al1, *al2;
- X{
- X register i = al2->al_argc;
- X register char **p = &(al1->al_argv[al1->al_argc]);
- X register char **q = &(al2->al_argv[0]);
- X
- X if ((al1->al_argc += i) >= MAXARGC)
- X panic("argument list overflow\n");
- X while (i-- > 0)
- X *p++ = *q++;
- X}
- X
- Xchar *
- Xmkstr(dst, arg1, arg2, arg3)
- X char *dst, *arg1, *arg2, *arg3;
- X{
- X register char *p;
- X register char *q = dst;
- X
- X p = arg1;
- X while (*q++ = *p++);
- X q--;
- X p = arg2;
- X while (*q++ = *p++);
- X q--;
- X p = arg3;
- X while (*q++ = *p++);
- X q--;
- X return dst;
- X}
- X
- Xbasename(str, dst)
- X char *str;
- X register char *dst;
- X{
- X register char *p1 = str;
- X register char *p2 = p1;
- X
- X while (*p1)
- X if (*p1++ == '/')
- X p2 = p1;
- X p1--;
- X if (*--p1 == '.') {
- X *p1 = '\0';
- X while (*dst++ = *p2++);
- X *p1 = '.';
- X }
- X else
- X while (*dst++ = *p2++);
- X}
- X
- Xchar *
- Xextension(fln)
- X char *fln;
- X{
- X register char *fn = fln;
- X
- X while (*fn) fn++;
- X while (fn > fln && *fn != '.') fn--;
- X if (fn != fln) return fn+1;
- X return (char *)0;
- X}
- X
- Xrunvec(vec, pass, in, out)
- X struct arglist *vec;
- X struct passinfo *pass;
- X char *in, *out;
- X{
- X int pid, status;
- X
- X if (
- X strncmp(vec->al_argv[1], "/usr/", 5) == 0
- X &&
- X access(vec->al_argv[1] + 4, 1) == 0
- X )
- X strcpy(vec->al_argv[1], vec->al_argv[1] + 4);
- X if (v_flag) {
- X pr_vec(vec);
- X if (pass->p_flags & STDIN) {
- X prs(" <");
- X prs(in);
- X }
- X if (pass->p_flags & STDOUT) {
- X prs(" >");
- X prs(out);
- X }
- X prs("\n");
- X }
- X if (noexec)
- X return 1;
- X if ((pid = fork()) == 0) { /* start up the process */
- X if (pass->p_flags & STDIN) { /* redirect standard input */
- X close(0);
- X if (open(in, 0) != 0)
- X panic("cannot open input file\n");
- X }
- X if (pass->p_flags & STDOUT) { /* redirect standard output */
- X close(1);
- X if (creat(out, 0666) != 1)
- X panic("cannot create output file\n");
- X }
- X ex_vec(vec);
- X }
- X if (pid == -1)
- X panic("no more processes\n");
- X kids[0] = pid;
- X clean(vec);
- X wait(&status);
- X kids[0] = -1;
- X return status ? ((RET_CODE = 1), 0) : 1;
- X}
- X
- Xprs(str)
- X char *str;
- X{
- X if (str && *str)
- X write(2, str, strlen(str));
- X}
- X
- Xpanic(str)
- X char *str;
- X{
- X prs(str);
- X trapcc(SIGINT);
- X}
- X
- Xpr_vec(vec)
- X register struct arglist *vec;
- X{
- X register char **ap = &vec->al_argv[1];
- X
- X vec->al_argv[vec->al_argc] = 0;
- X prs(*ap);
- X while (*++ap) {
- X prs(" ");
- X if (strlen(*ap))
- X prs(*ap);
- X else
- X prs("(empty)");
- X }
- X}
- X
- Xex_vec(vec)
- X register struct arglist *vec;
- X{
- X extern int errno;
- X
- X vec->al_argv[vec->al_argc] = 0;
- X execv(vec->al_argv[1], &(vec->al_argv[1]));
- X if (errno == ENOEXEC) { /* not an a.out, try it with the SHELL */
- X vec->al_argv[0] = SHELL;
- X execv(SHELL, &(vec->al_argv[0]));
- X }
- X if (access(vec->al_argv[1], 1) == 0) {
- X /* File is executable. */
- X prs("Cannot execute ");
- X prs(vec->al_argv[1]);
- X prs(". Not enough memory.\n");
- X prs("Use chmem to reduce its stack allocation\n");
- X } else {
- X prs(vec->al_argv[1]);
- X prs(" is not executable\n");
- X }
- X exit(1);
- X}
- X
- Xmktempname(nm)
- X register char *nm;
- X{
- X register int i;
- X register int pid = getpid();
- X
- X strcpy(nm, tmpdir);
- X strcat(nm, "/");
- X strcat(nm, compbase->c_callname);
- X while (*nm) nm++;
- X
- X for (i = 9; i > 3; i--) {
- X *nm++ = (pid % 10) + '0';
- X pid /= 10;
- X }
- X *nm++ = '.';
- X *nm++ = '\0'; /* null termination */
- X}
- X
- Xmkbase()
- X{
- X register struct compile *p = passes;
- X USTRING callname;
- X
- X basename(ProgCall, callname);
- X while (p->c_suffix) {
- X if (strcmp(p->c_callname, callname) == 0) {
- X compbase = p;
- X mkloader();
- X return;
- X }
- X p++;
- X }
- X /* we should not get here */
- X panic("internal error\n");
- X}
- X
- Xmkloader()
- X{
- X register struct passinfo *p = passinfo;
- X register struct pass *pass;
- X
- X while (!(p->p_flags & LOADER)) p++;
- X loaderinfo = p;
- X pass = &(compbase->c_passes[0]);
- X while (strcmp(pass->pp_name, p->p_name)) pass++;
- X loader = pass;
- X}
- X
- Xneedsprep(name)
- X char *name;
- X{
- X int file;
- X char fc;
- X
- X file = open(name,0);
- X if (file <0) return 0;
- X if (read(file, &fc, 1) != 1) fc = 0;
- X close(file);
- X return fc == '#';
- X}
- X
- Xchar *
- Xapply(pinf, cp, name, passindex, noremove, first, resultname)
- X register struct passinfo *pinf;
- X register struct compile *cp;
- X char *name, *resultname;
- X{
- X /* Apply a pass, indicated by "pinf", with args in
- X cp->c_passes[passindex], to name "name", leaving the result
- X in a file with name "resultname", concatenated with result
- X suffix.
- X When neccessary, the preprocessor is run first.
- X If "noremove" is NOT set, the file "name" is removed.
- X */
- X
- X struct arglist *call = &CALLVEC[0];
- X struct pass *pass = &(cp->c_passes[passindex]);
- X char *outname;
- X
- X if ( /* this pass is the first pass */
- X first
- X &&
- X ( /* preprocessor always needed */
- X (pinf->p_flags & PREPALWAYS)
- X ||/* or only when "needsprep" says so */
- X ( (pinf->p_flags & PREPCOND) && needsprep(name))
- X )
- X ) {
- X mkstr(newfil, tmpname, passinfo[0].p_to, "");
- X mkvec(call, name, newfil, (struct pass *) 0, &passinfo[0]);
- X if (! runvec(call, &passinfo[0], name, newfil)) {
- X cleanup(newfil);
- X return 0;
- X }
- X strcpy(curfil, newfil);
- X newfil[0] = '\0';
- X name = curfil;
- X noremove = 0;
- X }
- X if (pinf->p_to) outname = mkstr(newfil, resultname, pinf->p_to, "");
- X else outname = o_FILE;
- X mkvec(call, name, outname, pass, pinf);
- X if (! runvec(call, pinf, name, outname)) {
- X cleanup(outname);
- X if (! noremove) cleanup(name);
- X return 0;
- X }
- X if (! noremove) cleanup(name);
- X strcpy(curfil, newfil);
- X newfil[0] = '\0';
- X return curfil;
- X}
- X
- Xint
- Xapplicable(pinf, suffix)
- X struct passinfo *pinf;
- X char *suffix;
- X{
- X /* Return one if the pass indicated by "pinfo" is applicable to
- X a file with suffix "suffix".
- X */
- X register char *sfx = pinf->p_from;
- X
- X if (! suffix) return 0;
- X while (*sfx) {
- X char c;
- X register char *p = sfx;
- X
- X while (*p && *p != ',') p++;
- X c = *p; *p = 0;
- X if (strcmp(sfx, suffix) == 0) {
- X *p = c;
- X return 1;
- X }
- X *p = c;
- X if (*p == ',') sfx = p+1;
- X else sfx = p;
- X }
- X return 0;
- X}
- X
- Xchar *
- Xprocess(name, noremove)
- X char *name;
- X{
- X register struct compile *cp = passes;
- X char *suffix = extension(name);
- X USTRING base;
- X register struct pass *pass;
- X register struct passinfo *pinf;
- X
- X if (! suffix) return name;
- X
- X basename(name, base);
- X
- X while (cp->c_suffix) {
- X if ((cp->c_flags & DEFLANG) &&
- X strcmp(cp->c_suffix, suffix) == 0)
- X break;
- X cp++;
- X }
- X if (! cp->c_suffix) cp = compbase;
- X pass = cp->c_passes;
- X while (pass->pp_name) {
- X int first = 1;
- X
- X for (pinf=passinfo; strcmp(pass->pp_name,pinf->p_name);pinf++)
- X ;
- X if (! (pinf->p_flags & LOADER) && applicable(pinf, suffix)) {
- X int cont = ! stopsuffix || ! pinf->p_to ||
- X strcmp(stopsuffix, pinf->p_to) != 0;
- X name = apply(pinf,
- X cp,
- X name,
- X (int)(pass - cp->c_passes),
- X noremove,
- X first,
- X applicable(loaderinfo, pinf->p_to) ||
- X !cont ?
- X strcat(base, ".") :
- X tmpname);
- X first = noremove = 0;
- X suffix = pinf->p_to;
- X if (!cont || !name) break;
- X }
- X pass++;
- X }
- X if (!noremove && name)
- X append(&GEN_LDFILES, name);
- X return name;
- X}
- X
- Xmkvec(call, in, out, pass, pinf)
- X struct arglist *call;
- X char *in, *out;
- X struct pass *pass;
- X register struct passinfo *pinf;
- X{
- X register int i;
- X
- X init(call);
- X append(call, pinf->p_path);
- X scanflags(call, pinf);
- X if (pass) for (i = 0; i < MAXHEAD; i++)
- X if (pass->pp_head[i])
- X append(call, pass->pp_head[i]);
- X else break;
- X if (pinf->p_flags & INPUT)
- X append(call, in);
- X if (pinf->p_flags & OUTPUT)
- X append(call, out);
- X if (pinf->p_flags & O_OUTPUT) {
- X append(call, "-o");
- X append(call, out);
- X }
- X if (pass) for (i = 0; i < MAXTAIL; i++)
- X if (pass->pp_tail[i])
- X append(call, pass->pp_tail[i]);
- X else break;
- X if (pinf->p_flags & SOURCE)
- X append(call, source);
- X}
- X
- Xcallld(in, out, pass, pinf)
- X struct arglist *in;
- X char *out;
- X struct pass *pass;
- X register struct passinfo *pinf;
- X{
- X struct arglist *call = &CALLVEC[0];
- X register int i;
- X
- X init(call);
- X append(call, pinf->p_path);
- X scanflags(call, pinf);
- X append(call, "-o");
- X append(call, out);
- X for (i = 0; i < MAXHEAD; i++)
- X if (pass->pp_head[i])
- X append(call, pass->pp_head[i]);
- X else break;
- X if (pinf->p_flags & INPUT)
- X concat(call, in);
- X if (pinf->p_flags & OUTPUT)
- X append(call, out);
- X for (i = 0; i < MAXTAIL; i++)
- X if (pass->pp_tail[i])
- X append(call, pass->pp_tail[i]);
- X else break;
- X if (! runvec(call, pinf, (char *) 0, out)) {
- X cleanup(out);
- X RET_CODE = 1;
- X }
- X clean(call);
- X}
- X
- Xclean(c)
- X register struct arglist *c;
- X{
- X register int i;
- X
- X for (i = 1; i < c->al_argc; i++) {
- X free(c->al_argv[i]);
- X c->al_argv[i] = 0;
- X }
- X c->al_argc = 0;
- X}
- X
- Xscanflags(call, pinf)
- X struct arglist *call;
- X struct passinfo *pinf;
- X{
- X /* Find out which flags from FLAGS must be passed to pass "pinf",
- X and how.
- X Append them to "call"
- X */
- X register int i;
- X USTRING flg;
- X
- X for (i = 0; i < FLAGS.al_argc; i++) {
- X register char *q = pinf->p_acceptflags;
- X
- X while (*q) {
- X register char *p = FLAGS.al_argv[i] + 1;
- X
- X while ((*q == *p) && *q) {
- X q++; p++;
- X }
- X if (*q == ',' || !*q) {
- X if (! *p) {
- X /* append literally */
- X append(call, FLAGS.al_argv[i]);
- X }
- X break;
- X }
- X if (*q == '*') {
- X register char *s = flg;
- X
- X if (*++q != '=') {
- X /* append literally */
- X append(call, FLAGS.al_argv[i]);
- X break;
- X }
- X *s++ = '-';
- X if (*q) q++; /* skip ',' */
- X while (*q && *q != ',' && *q != '*') {
- X /* copy replacement flag */
- X *s++ = *q++;
- X }
- X if (*q == '*') {
- X /* copy rest */
- X while (*p) *s++ = *p++;
- X }
- X *s = 0;
- X append(call, flg);
- X break;
- X }
- X if (*q == '=') {
- X /* copy replacement */
- X register char *s = flg;
- X
- X *s++ = '-';
- X q++;
- X while (*q && *q != ',') *s++ = *q++;
- X *s = 0;
- X append(call, flg);
- X break;
- X }
- X while (*q && *q++ != ',')
- X ;
- X }
- X }
- X}
- xEOF
-