Change xified C compiler and linker so that xification occurs after preprocessing...
authorNick Downing <downing.nick@gmail.com>
Thu, 2 Feb 2017 06:43:40 +0000 (17:43 +1100)
committerNick Downing <downing.nick@gmail.com>
Thu, 2 Feb 2017 06:52:14 +0000 (17:52 +1100)
.gitignore
xify/Makefile
xify/cc.c [deleted file]
xify/cc.sh [new file with mode: 0755]
xify/hostcc.sh [new file with mode: 0755]
xify/hostld.sh [new file with mode: 0755]
xify/ld.c [deleted file]
xify/xify.sh
xify/xifyfilt.c [moved from xify/xify.c with 87% similarity]

index adae24d..ea18620 100644 (file)
@@ -8,7 +8,6 @@
 *.protos.nocomm
 *.usedby
 *.uses
-.xify
 ansify.log
 bin/adb/adb
 bin/adb/instrs.adb
@@ -148,6 +147,4 @@ usr.bin/tty
 usr.bin/uniq
 usr.bin/units
 usr.bin/yacc/yacc
-xify/cc
-xify/ld
-xify/xify
+xify/xifyfilt
index de1d994..a1fa85e 100644 (file)
@@ -2,24 +2,14 @@ ROOT=..
 CC=gcc -g -Wall -Wno-char-subscripts -Wno-deprecated-declarations -Wno-maybe-uninitialized -Wno-parentheses -Wno-unused-result
 DESTDIR=${ROOT}/cross
 
-ALL=cc ld xify
-
-all: ${ALL}
-
-cc: cc.c
-       ${CC} -DXIFY -o $@ cc.c
-
-ld: ld.c
-       ${CC} -DXIFY -o $@ ld.c
-
 xifyfilt: xifyfilt.c
        ${CC} -o $@ xifyfilt.c
 
 clean:
-       rm -f ${ALL}
+       rm -f xifyfilt *.o
 
-install: all
-       install -s cc ${DESTDIR}/bin/hostcc
-       install -s ld ${DESTDIR}/bin/hostld
-       install -s xify ${DESTDIR}/lib/xifyfilt
+install: xifyfilt
+       install hostcc.sh ${DESTDIR}/bin/hostcc
+       install hostld.sh ${DESTDIR}/bin/hostld
+       install -s xifyfilt ${DESTDIR}/lib
        install xify.sh ${DESTDIR}/lib/xify
diff --git a/xify/cc.c b/xify/cc.c
deleted file mode 100644 (file)
index d9d3ab7..0000000
--- a/xify/cc.c
+++ /dev/null
@@ -1,840 +0,0 @@
-#if defined(DOSCCS) && !defined(lint)
-static char sccsid[] = "@(#)cc.c 4.13 9/18/85";
-#endif
-/*
- * cc - front end for C compiler
- */
-#include <sys/param.h>
-#include <stdio.h>
-#include <ctype.h>
-#include <signal.h>
-#include <string.h>
-#include <sys/dir.h>
-#include <sys/wait.h>
-#ifdef XIFY
-#include <errno.h>
-#include <sys/stat.h>
-#endif
-
-#ifdef __STDC__
-#include <stdlib.h>
-#include <unistd.h>
-#endif
-
-#ifdef XIFY
-char   *gcc = "/usr/bin/gcc";
-char   *ld;
-char   *xify;
-char   *include;
-char   *crt0;
-#else
-char   *cpp = "/lib/cpp";
-char   *ccom = "/lib/ccom";
-char   *sccom = "/lib/sccom";
-char   *c2 = "/lib/c2";
-char   *as = "/bin/as";
-char   *ld = "/bin/ld";
-char   *crt0 = "/lib/crt0.o";
-#endif
-
-#ifndef XIFY
-char   tmp0[30];               /* big enough for /tmp/ctm%05.5d */
-char   *tmp1, *tmp2, *tmp3, *tmp4, *tmp5;
-#endif
-char   *outfile;
-/*char *savestr(), *strspl(), *setsuf();*/
-/*void idexit();*/
-char   **av, **clist, **llist, **plist;
-int    cflag, eflag, oflag, pflag, sflag, wflag, Rflag, exflag, proflag;
-int    fflag, gflag, Gflag, Mflag, debug;
-char   *dflag;
-int    exfail;
-char   *chpass;
-char   *npassname;
-
-int    nc, nl, np, nxo, na;
-
-#ifdef XIFY
-/* When we run "xify" as a child process, it will output to us on stderr a */
-/* list of dependencies as it encounters them. We receive this list via a */
-/* pipe, and as each dependency is received, we search the include path for */
-/* it, using special rules for "file.h" vs <file.h>, and then check if the */
-/* resolved path is already encountered (xified, or queued for xification). */
-/* If so, we ignore it. Otherwise we queue it. When we queue it, we save two */
-/* further pieces of information. If the path stem came from the include */
-/* path (other than being a relative path from a current file), and the */
-/* remaining path contained at least one directory, we have to "mkdir" the */
-/* path stem plus "/.xify". This is because the "-Idirectory" passed to to */
-/* gcc must exist, even if it is empty. This can occur if the remaining path */
-/* contains ".." elements. So, the first piece of information is which path */
-/* stem was used, or -1 if no extra "mkdir" is necessary (noting that we */
-/* will also "mkdir" the directory containing the xified source). It'd be */
-/* fine to "mkdir" the path stem at the time of queueing, or to "mkdir" all */
-/* path stems whether anything is found through them or not, but this way is */
-/* more consistent if we get an error and abort with things still enqueued. */
-/* The second piece of information is the mtime, so that we do not have to */
-/* "stat" it again when it comes to the head of the queue. When it comes to */
-/* the head of the queue we check for a previous xification of the same file */
-/* left in ".xify" underneath the directory containing the file, since this */
-/* will occur a lot for system includes and if not stale it saves much work. */
-
-#define IN_QUEUE_SIZE 0x100 /* fix this later and make it dynamic */
-
-struct {
-       char *path;
-       struct timespec mtime;
-       int mkdir;
-} in_queue[IN_QUEUE_SIZE];
-int in_queue_head;
-int in_queue_tail;
-
-char   in_path[BUFSIZ];
-char   out_path[BUFSIZ];
-char   err_path[BUFSIZ];
-
-extern char **environ;
-#endif
-
-#define        cunlink(s)      if (s) unlink(s)
-
-#ifndef __P
-#ifdef __STDC__
-#define __P(args) args
-#else
-#define __P(args) ()
-#endif
-#endif
-
-int main __P((int argc, char **argv));
-void idexit __P((void));
-int dexit __P((void));
-void error __P((char *s, char *x));
-int getsuf __P((char as[]));
-char *setsuf __P((char *as, int ch));
-#ifdef XIFY
-int xify_enqueue __P((char *in_name, char *prev_name));
-int xify_file __P((char *in_name, struct timespec *in_mtime));
-#endif
-int callsys __P((/*char *f,*/ char **v));
-int nodup __P((char **l, char *os));
-char *savestr __P((register char *cp));
-char *strspl __P((char *left, char *right));
-
-int main(argc, argv) int argc; char **argv; {
-       char *t;
-#ifndef XIFY
-       char *assource;
-#endif
-       int i, j, c;
-#ifdef XIFY
-       struct stat statbuf;
-#endif
-
-       /* ld currently adds upto 5 args; 10 is room to spare */
-       av = (char **)calloc(argc+/*10*/20, sizeof (char **));
-       clist = (char **)calloc(argc, sizeof (char **));
-       llist = (char **)calloc(argc, sizeof (char **));
-       plist = (char **)calloc(argc, sizeof (char **));
-#ifdef XIFY
-       t = argv[0];
-       j = strlen(t);
-       for (i = j; i > 0 && t[i - 1] != '/'; --i)
-               ;
-       j = (j >= 2 && t[j - 2] == 'c' && t[j - 1] == 'c') ? j - 2 : i;
-       bcopy(t, in_path, j);
-       strcpy(in_path + j, "ld");
-       ld = savestr(in_path);
-       strcpy(in_path + i, "../lib/xify");
-       xify = savestr(in_path);
-       strcpy(in_path + i, "../usr/include/.xify");
-       include = savestr(in_path);
-       strcpy(in_path + i, "../lib/crt0.o");
-       crt0 = savestr(in_path);
-#endif
-       for (i = 1; i < argc; i++) {
-               if (*argv[i] == '-') switch (argv[i][1]) {
-
-               case 'S':
-                       sflag++;
-                       cflag++;
-                       continue;
-               case 'o':
-                       if (++i < argc) {
-                               outfile = argv[i];
-                               switch (getsuf(outfile)) {
-
-                               case 'c':
-                                       error("-o would overwrite %s",
-                                           outfile);
-                                       exit(8);
-                               }
-                       }
-                       continue;
-               case 'R':
-                       Rflag++;
-                       continue;
-               case 'O':
-                       oflag++;
-                       continue;
-               case 'p':
-                       proflag++;
-                       crt0 = "/lib/mcrt0.o";
-                       if (argv[i][2] == 'g')
-                               crt0 = "/usr/lib/gcrt0.o";
-                       continue;
-               case 'f':
-                       fflag++;
-                       continue;
-               case 'g':
-                       if (argv[i][2] == 'o') {
-                           Gflag++;    /* old format for -go */
-                       } else {
-                           gflag++;    /* new format for -g */
-                       }
-                       continue;
-               case 'w':
-                       wflag++;
-                       continue;
-               case 'E':
-                       exflag++;
-               case 'P':
-                       pflag++;
-                       if (argv[i][1]=='P')
-                               fprintf(stderr,
-       "cc: warning: -P option obsolete; you should use -E instead\n");
-                       plist[np++] = argv[i];
-               case 'c':
-                       cflag++;
-                       continue;
-               case 'M':
-                       exflag++;
-                       pflag++;
-                       Mflag++;
-                       /* and fall through */
-#ifdef XIFY
-                       plist[np++] = argv[i];
-                       continue;
-               case 'D':
-                       if (strncmp(argv[i] + 2, "nox_", 4) == 0) {
-                               plist[np++] = strspl("-D", argv[i] + 6);
-                               continue;
-                       }
-                       t = strspl("-D", argv[i]);
-                       goto define;
-               case 'U':
-                       if (strncmp(argv[i] + 2, "nox_", 4) == 0) {
-                               plist[np++] = strspl("-U", argv[i] + 6);
-                               continue;
-                       }
-                       t = strspl("-U", argv[i]);
-               define:
-                       t[2] = 'x';
-                       t[3] = '_';
-                       plist[np++] = t;
-                       continue;
-               case 'I':
-                       plist[np++] = strspl(argv[i], "/.xify");
-                       continue;
-               case 'C':
-                       error("-C not implemented", 0);
-                       exit(1);
-#else
-               case 'D':
-               case 'I':
-               case 'U':
-               case 'C':
-                       plist[np++] = argv[i];
-                       continue;
-#endif
-               case 'L':
-                       llist[nl++] = argv[i];
-                       continue;
-               case 't':
-                       if (chpass)
-                               error("-t overwrites earlier option", 0);
-                       chpass = argv[i]+2;
-                       if (chpass[0]==0)
-                               chpass = "012p";
-                       continue;
-               case 'B':
-                       if (npassname)
-                               error("-B overwrites earlier option", 0);
-                       npassname = argv[i]+2;
-                       if (npassname[0]==0)
-                               npassname = "/usr/c/o";
-                       continue;
-               case 'd':
-                       if (argv[i][2] == '\0') {
-                               debug++;
-                               continue;
-                       }
-                       dflag = argv[i];
-                       continue;
-               }
-               t = argv[i];
-               c = getsuf(t);
-               if (c=='c' || c=='s' || exflag) {
-                       clist[nc++] = t;
-                       t = setsuf(t, 'o');
-               }
-               if (nodup(llist, t)) {
-                       llist[nl++] = t;
-                       if (getsuf(t)=='o')
-                               nxo++;
-               }
-       }
-       if (gflag || Gflag) {
-               if (oflag)
-                       fprintf(stderr, "cc: warning: -g disables -O\n");
-               oflag = 0;
-       }
-       if (npassname && chpass ==0)
-               chpass = "012p";
-       if (chpass && npassname==0)
-               npassname = "/usr/new";
-       if (chpass)
-#ifdef XIFY
-               gcc = strspl(npassname, "gcc");
-#else
-       for (t=chpass; *t; t++) {
-               switch (*t) {
-
-               case '0':
-                       if (fflag)
-                               sccom = strspl(npassname, "sccom");
-                       else
-                               ccom = strspl(npassname, "ccom");
-                       continue;
-               case '2':
-                       c2 = strspl(npassname, "c2");
-                       continue;
-               case 'p':
-                       cpp = strspl(npassname, "cpp");
-                       continue;
-               }
-       }
-#endif
-       if (nc==0)
-               goto nocom;
-       if (signal(SIGINT, SIG_IGN) != SIG_IGN)
-               signal(SIGINT, (void (*) __P((int sig)))idexit);
-       if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
-               signal(SIGTERM, (void (*) __P((int sig)))idexit);
-       if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
-               signal(SIGHUP, (void (*) __P((int sig)))idexit);
-#ifdef XIFY
-       plist[np++] = strspl("-I", include);
-#else
-       if (pflag==0)
-               sprintf(tmp0, "/tmp/ctm%05.5d", getpid());
-       tmp1 = strspl(tmp0, "1");
-       tmp2 = strspl(tmp0, "2");
-       tmp3 = strspl(tmp0, "3");
-       if (pflag==0)
-               tmp4 = strspl(tmp0, "4");
-       if (oflag)
-               tmp5 = strspl(tmp0, "5");
-#endif
-       for (i=0; i<nc; i++) {
-               if (nc > 1 && !Mflag) {
-                       printf("%s:\n", clist[i]);
-                       fflush(stdout);
-               }
-#ifdef XIFY
-               c = getsuf(clist[i]);
-               if (c == 'c') {
-                       if (stat(clist[i], &statbuf)) {
-                               error("not found: %s", clist[i]);
-                               goto nogood;
-                       }
-                       if (xify_file(clist[i], &statbuf.st_mtim))
-                               goto nogood;
-                       clist[i] = savestr(out_path);
-
-                       while (in_queue_head < in_queue_tail) {
-                               if (
-                                       xify_file(
-                                               in_queue[in_queue_head].path,
-                                               &in_queue[in_queue_head].mtime
-                                       )
-                               )
-                                       goto nogood;
-                               if (in_queue[in_queue_head].mkdir >= 0) {
-                                       if (debug)
-                                               fprintf(stderr, "mkdir %s\n", plist[in_queue[in_queue_head].mkdir] + 2);
-                                       if (mkdir(plist[in_queue[in_queue_head].mkdir] + 2, 0777) && errno != EEXIST)
-                                               goto nogood;
-                               }
-                               ++in_queue_head;
-                       }
-               }
-               av[0] = /*"gcc"*/gcc; av[1] = "-o";
-               na = 2;
-               if (cflag && nc==1 && outfile)
-                       av[na++] = outfile;
-               else if (c == 'c' && !exflag)
-                       av[na++] = setsuf(clist[i] + 8, sflag ? 's' : 'o');
-               else
-                       --na;
-               for (j = 0; j < np; ++j)
-                       av[na++] = plist[j];
-               av[na++] = "-fno-strict-aliasing";
-               if (proflag)
-                       av[na++] = "-pg";
-               if (gflag || Gflag)
-                       av[na++] = "-g";
-               if (!wflag) {
-                       av[na++] = "-Wall";
-                       av[na++] = "-Wno-char-subscripts";
-                       av[na++] = "-Wno-deprecated-declarations";
-                       av[na++] = "-Wno-maybe-uninitialized";
-                       av[na++] = "-Wno-parentheses";
-                       av[na++] = "-Wno-strict-aliasing";
-                       av[na++] = "-Wno-unused-result";
-               }
-               if (oflag)
-                       av[na++] = "-O3";
-               if (exflag)
-                       av[na++] = "-E";
-               else if (sflag)
-                       av[na++] = "-S";
-               else
-                       av[na++] = "-c";
-               av[na++] = clist[i];
-               av[na] = 0;
-               if (callsys(/*gcc,*/ av)) {
-               nogood:
-                       cflag++;
-                       eflag++;
-                       continue;
-               }
-#else
-               if (!Mflag && getsuf(clist[i]) == 's') {
-                       assource = clist[i];
-                       goto assemble;
-               } else
-                       assource = tmp3;
-               if (pflag)
-                       tmp4 = setsuf(clist[i], 'i');
-               av[0] = /*"cpp"*/cpp; av[1] = clist[i];
-               na = 2;
-               if (!exflag)
-                       av[na++] = tmp4;
-               for (j = 0; j < np; j++)
-                       av[na++] = plist[j];
-               av[na++] = 0;
-               if (callsys(/*cpp,*/ av)) {
-                       exfail++;
-                       eflag++;
-               }
-               if (pflag || exfail) {
-                       cflag++;
-                       continue;
-               }
-               if (sflag) {
-                       if (nc==1 && outfile)
-                               tmp3 = outfile;
-                       else
-                               tmp3 = setsuf(clist[i], 's');
-                       assource = tmp3;
-               }
-               av[0] = fflag ? /*"sccom"*/sccom : /*"ccom"*/ccom;
-               av[1] = tmp4; av[2] = oflag?tmp5:tmp3; na = 3;
-               if (proflag)
-                       av[na++] = "-XP";
-               if (gflag) {
-                       av[na++] = "-Xg";
-               } else if (Gflag) {
-                       av[na++] = "-XG";
-               }
-               if (wflag)
-                       av[na++] = "-w";
-               av[na] = 0;
-               if (callsys(/*fflag ? sccom : ccom,*/ av)) {
-                       cflag++;
-                       eflag++;
-                       continue;
-               }
-               if (oflag) {
-                       av[0] = /*"c2"*/c2; av[1] = tmp5; av[2] = tmp3; av[3] = 0;
-                       if (callsys(/*c2,*/ av)) {
-                               unlink(tmp3);
-                               tmp3 = assource = tmp5;
-                       } else
-                               unlink(tmp5);
-               }
-               if (sflag)
-                       continue;
-       assemble:
-               cunlink(tmp1); cunlink(tmp2); cunlink(tmp4);
-               av[0] = /*"as"*/as; av[1] = "-o";
-               if (cflag && nc==1 && outfile)
-                       av[2] = outfile;
-               else
-                       av[2] = setsuf(clist[i], 'o');
-               na = 3;
-               if (Rflag)
-                       av[na++] = "-R";
-               if (dflag)
-                       av[na++] = dflag;
-               av[na++] = assource;
-               av[na] = 0;
-               if (callsys(/*as,*/ av) > 1) {
-                       cflag++;
-                       eflag++;
-                       continue;
-               }
-#endif
-       }
-nocom:
-       if (cflag==0 && nl!=0) {
-               i = 0;
-               av[0] = /*"ld"*/ld; av[1] = "-X"; av[2] = crt0; na = 3;
-               if (outfile) {
-                       av[na++] = "-o";
-                       av[na++] = outfile;
-               }
-#ifdef XIFY
-               if (debug)
-                       av[na++] = "-t";
-#endif
-               while (i < nl)
-                       av[na++] = llist[i++];
-#ifndef XIFY
-               if (gflag || Gflag)
-                       av[na++] = "-lg";
-#endif
-               if (proflag)
-                       av[na++] = "-lc_p";
-               else
-                       av[na++] = "-lc";
-               av[na++] = 0;
-               eflag |= callsys(/*ld,*/ av);
-               if (nc==1 && nxo==1 && eflag==0)
-                       unlink(setsuf(clist[0], 'o'));
-       }
-       dexit();
-}
-
-void idexit() {
-
-       eflag = 100;
-       dexit();
-}
-
-int dexit() {
-
-#ifndef XIFY
-       if (!pflag) {
-               cunlink(tmp1);
-               cunlink(tmp2);
-               if (sflag==0)
-                       cunlink(tmp3);
-               cunlink(tmp4);
-               cunlink(tmp5);
-       }
-#endif
-       exit(eflag);
-}
-
-void error(s, x) char *s; char *x; {
-       FILE *diag = exflag ? stderr : stdout;
-
-       fprintf(diag, "cc: ");
-       fprintf(diag, s, x);
-       putc('\n', diag);
-       exfail++;
-       cflag++;
-       eflag++;
-}
-
-int getsuf(as) char as[]; {
-       register int c;
-       register char *s;
-       register int t;
-
-       s = as;
-       c = 0;
-       while (t = *s++)
-               if (t=='/')
-                       c = 0;
-               else
-                       c++;
-       s -= 3;
-       if (c <= MAXNAMLEN && c > 2 && *s++ == '.')
-               return (*s);
-       return (0);
-}
-
-char *setsuf(as, ch) char *as; int ch; {
-       register char *s, *s1;
-
-       s = s1 = savestr(as);
-       while (*s)
-               if (*s++ == '/')
-                       s1 = s;
-       s[-1] = ch;
-       return (s1);
-}
-
-#ifdef XIFY
-int xify_file(in_name, in_mtime) char *in_name; struct timespec *in_mtime; {
-       int i;
-       struct stat out_statbuf;
-       FILE *err_fp;
-       char err_line[BUFSIZ];
-       int e;
-       /* note: out_path is an output parameter on success */
-
-       for (i = strlen(in_name); i > 0 && in_name[i - 1] != '/'; --i)
-               ;
-       bcopy(in_name, out_path, i);
-       strcpy(out_path + i, ".xify/x_");
-       strcat(out_path + i, in_name + i);
-
-       strcpy(err_path, out_path);
-       strcat(err_path, ".deps");
-       
-       if (
-               stat(out_path, &out_statbuf) ||
-               out_statbuf.st_mtim.tv_sec < in_mtime->tv_sec || (
-                       out_statbuf.st_mtim.tv_sec == in_mtime->tv_sec &&
-                       out_statbuf.st_mtim.tv_nsec < in_mtime->tv_nsec
-               )
-               
-       ) {
-               out_path[i + 5] = 0;
-               if (debug)
-                       fprintf(stderr, "mkdir %s\n", out_path);
-               if (mkdir(out_path, 0777) == -1 && errno != EEXIST) {
-                       error("can't mkdir: %s\n", out_path);
-                       return 1;
-               }
-               out_path[i + 5] = '/';
-
-               av[0] = /*"xify"*/xify; av[1] = in_name; av[2] = out_path; av[3] = err_path; av[4] = 0;
-               if (callsys(/*xify,*/ av))
-                       return 1;
-       }
-
- /*fprintf(stderr, "reading deps: %s\n", err_path);*/
-       err_fp = fopen(err_path, "r");
-       if (err_fp == 0) {
-               error("can't find deps: %s", err_path);
-               return 1;
-       }
-       while (fgets(err_line, BUFSIZ, err_fp))
-               if (err_line[0] == '"') {
-                       e = '"';
-                       goto include;
-               }
-               else if (err_line[0] == '<') {
-                       e = '>';
-               include:
-                       for (i = 1; err_line[i] != e; ++i) {
-                               if (err_line[i] == 0)
-                                       goto garbage;
-                       }
-                       err_line[i] = 0;
- /*fprintf(stderr, "found dep: %s\n", err_line);*/
-                       if (xify_enqueue(err_line + 1, err_line[0] == '"' ? in_name : 0))
-                               break;
-               }
-               else {
-               garbage:
-                       error("garbage in deps: %s\n", err_path);
-                       break;
-               }
-       fclose(err_fp);
-       return 0;
-}
-
-int xify_enqueue(in_name, prev_name) char *in_name; char *prev_name; {
-       int i, j, k;
-       struct stat statbuf;
-
-       for (i = strlen(in_name); i > 0 && in_name[i - 1] != '/'; --i)
-               ;
-       if (prev_name) {
-               for (j = strlen(prev_name); j > 0 && prev_name[j - 1] != '/'; --j)
-                       ;
-               bcopy(prev_name, in_path, j);
-               strcpy(in_path + j, in_name);
-               if (stat(in_path, &statbuf) == 0) {
-                       j = -1; /* does not require extra mkdir */
-                       goto found;
-               }
-
-               strcpy(in_path + j + i, ".xify/x_");
-               strcat(in_path + j + i, in_name + i);
-               if (debug)
-                       fprintf(stderr, "unlink %s\n", in_path);
-               if (unlink(in_path)) {
-                       if (errno != ENOENT)
-                               goto cant_unlink;
-               }
-               else {
-                       strcat(in_path, ".deps");
-                       if (debug)
-                               fprintf(stderr, "unlink %s\n", in_path);
-                       if (unlink(in_path) && errno != ENOENT)
-                               goto cant_unlink;
-               }
-       }
-       for (j = 0; j < np; ++j)
-               if (/*plist[j][0] == '-' &&*/ plist[j][1] == 'I') {
-                       k = strlen(plist[j] + 2) - 5; /* remove ".xify" */      
-                       bcopy(plist[j] + 2, in_path, k);
-                       strcpy(in_path + k, in_name);
-                       if (stat(in_path, &statbuf) == 0)
-                               goto found;
-
-                       strcpy(in_path + k + i, ".xify/x_");
-                       strcat(in_path + k + i, in_name + i);
-                       if (debug)
-                               fprintf(stderr, "unlink %s\n", in_path);
-                       if (unlink(in_path)) {
-                               if (errno != ENOENT)
-                                       goto cant_unlink;
-                       }
-                       else {
-                               strcat(in_path, ".deps");
-                               if (debug)
-                                       fprintf(stderr, "unlink %s\n", in_path);
-                               if (unlink(in_path) && errno != ENOENT) {
-                               cant_unlink:
-                                       error("can't unlink: %s\n", in_path);
-                                       return 1;
-                               }
-                       }
-               }
-       /* If we do not find a dependency, we just silently don't xify it, */
-       /* then gcc will complain that it cannot find the xified dependency. */
-       /* This is because the dependency might be #if'd out and not needed. */
-       /*error("not found: %s\n", in_name);*/
-       /*return 1;*/
-       return 0;
-
-found:
-       for (k = 0; k < in_queue_tail; ++k)
-               if (strcmp(in_queue[k].path, in_path) == 0)
-                       return 0;
-
-       if (in_queue_tail >= IN_QUEUE_SIZE) {
-               error("in queue full: %s\n", in_path);
-               return 1;
-       }
-
-       in_queue[in_queue_tail].path = savestr(in_path);
-       in_queue[in_queue_tail].mtime = statbuf.st_mtim;
-       in_queue[in_queue_tail].mkdir = i ? j : -1;
-       ++in_queue_tail;
-       return 0;
-}
-#endif
-
-int callsys(/*f,*/ v) /*char *f;*/ char **v; {
-       int t, status;
-#if 1
-       int i;
-
-       if (debug) {
-               fprintf(stderr, "%s", v[0]);
-               for (i = 1; v[i]; ++i)
-                       fprintf(stderr, " %s", v[i]);
-               fprintf(stderr, "\n");
-       }
-#else
-       char **cpp;
-
-       if (debug) {
-               fprintf(stderr, "%s:", /*f*/v[0]);
-               for (cpp = v; *cpp != 0; cpp++)
-                       fprintf(stderr, " %s", *cpp);
-               fprintf(stderr, "\n");
-       }
-#endif
-       t = vfork();
-       if (t == -1) {
-               printf("No more processes\n");
-               return (100);
-       }
-       if (t == 0) {
-               execv(/*f*/v[0], v);
-               printf("Can't find %s\n", /*f*/v[0]);
-               fflush(stdout);
-               _exit(100);
-       }
-       while (t != wait(&status))
-               ;
-#if 1
-       if (WIFSIGNALED(status) /*&& WTERMSIG(status) != SIGALRM*/) {
-               if (WTERMSIG(status) != SIGINT) {
-                       printf("Fatal error in %s\n", /*f*/v[0]);
-                       eflag = 8;
-               }
-               dexit();
-       }
-       return (WEXITSTATUS(status));
-#else
-       if ((t=(status&0377)) != 0 && t!=14) {
-               if (t!=2) {
-                       printf("Fatal error in %s\n", /*f*/v[0]);
-                       eflag = 8;
-               }
-               dexit();
-       }
-       return ((status>>8) & 0377);
-#endif
-}
-
-int nodup(l, os) char **l; char *os; {
-       register char *t, *s;
-       register int c;
-
-       s = os;
-       if (getsuf(s) != 'o')
-               return (1);
-       while (t = *l++) {
-               while (c = *s++)
-                       if (c != *t++)
-                               break;
-               if (*t==0 && c==0)
-                       return (0);
-               s = os;
-       }
-       return (1);
-}
-
-#define        NSAVETAB        1024
-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;
-       saveleft -= len;
-       return (cp);
-}
-
-char *strspl(left, right) char *left; char *right; {
-       char buf[BUFSIZ];
-
-       strcpy(buf, left);
-       strcat(buf, right);
-       return (savestr(buf));
-}
diff --git a/xify/cc.sh b/xify/cc.sh
new file mode 100755 (executable)
index 0000000..c681a8c
--- /dev/null
@@ -0,0 +1,368 @@
+#!/bin/sh
+
+BIN=`dirname $0`
+cpp="$BIN/../lib/cpp"
+ccom="$BIN/../lib/ccom"
+sccom="$BIN/../lib/sccom"
+c2="$BIN/../lib/c2"
+as="$BIN/as"
+ld="$BIN/ld"
+rm=rm
+
+clist=
+llist=
+plist=
+cflag=
+oflag=
+pflag=
+sflag=
+Rflag=
+exflag=
+proflag=
+fflag=
+gflag=
+Gflag=
+Mflag=
+debug=
+dflag=
+nc=0
+nxo=0
+crt0="$BIN/../lib/crto0.o"
+
+while test $# -ge 1
+do
+  case "$1" in
+  -S)
+    sflag=1
+    cflag=1
+    ;;
+  -o)
+    if test -z "$2"
+    then
+      echo "$0: error: -o where?" >&2
+      exit 1
+    fi
+    outfile=$2
+    shift
+    if echo $outfile |grep -q '\.c$'
+    then
+      echo "$0: error: -o would overwrite $outfile" >&2
+      exit 1
+    fi
+    ;;
+  -R)
+    Rflag=1
+    ;;
+  -O)
+    oflag=1
+    ;;
+  -p)
+    proflag=1
+    crt0="$BIN/../lib/mcrt0.o"
+    ;;
+  -pg)
+    proflag=1
+    crt0="$BIN/../usr/lib/gcrt0.o"
+    ;;
+  -f)
+    fflag=1
+    ;;
+  -go)
+    Gflag=1
+    ;;
+  -g)
+    gflag=1
+    ;;
+  -w)
+    wflag=1
+    ;;
+  -E)
+    exflag=1
+    pflag=1
+    plist="$plist $1" # this is ignored by 4.3bsd cpp
+    ;;
+  -P)
+    pflag=1
+    echo "$0: warning: -P option obsolete; you should use -E instead"
+    plist="$plist $1"
+    ;;
+  -c)
+    cflag=1
+    ;;
+  -M*)
+    exflag=1
+    pflag=1
+    Mflag=1
+    plist="$plist $1"
+    ;;
+  -[DIU]*)
+    plist="$plist $1"
+    ;;
+  -C)
+    plist="$plist $1"
+    ;;
+  -L*)
+    llist="$llist $1"
+    ;;
+  # chpass and passname stuff not implemented
+  -d)
+    debug=1
+    ;;
+  -d*)
+    dflag=$1
+    ;;
+  -*)
+    echo "$0: error: bad flag $1" >&2
+    exit 1
+    ;;
+  *)
+    t=$1
+    if echo $t |grep -q '\.[cs]$' || test -n "$exflag"
+    then
+      clist="$clist $t"
+      nc=`expr $nc + 1`
+      t=`echo $t |sed -e 's/.$/o/'`
+    fi
+
+    dup=
+    for i in $llist
+    do
+      if test "$i" = "$t"
+      then
+        dup=1
+        break
+      fi
+    done
+    if test -z "$dup"
+    then
+      llist="$llist $t"
+      if echo $t |grep -q '\.o$'
+      then
+        nxo=`expr $nxo + 1`
+      fi
+    fi
+    ;;
+  esac
+  shift
+done
+
+#echo "clist=$clist"
+#echo "llist=$llist"
+#echo "plist=$plist"
+#echo "cflag=$cflag"
+#echo "oflag=$oflag"
+#echo "pflag=$pflag"
+#echo "sflag=$sflag"
+#echo "Rflag=$Rflag"
+#echo "exflag=$exflag"
+#echo "proflag=$proflag"
+#echo "fflag=$fflag"
+#echo "gflag=$gflag"
+#echo "Gflag=$Gflag"
+#echo "Mflag=$Mflag"
+#echo "debug=$debug"
+#echo "dflag=$dflag"
+#echo "nc=$nc"
+#echo "nxo=$nxo"
+#echo "crt0=$crt0"
+
+if test \( -n "$gflag" -o -n "$Gflag" \) -a -n "$oflag"
+then
+  echo "$0: warning: -g disables -O" >&2
+  oflag=
+fi
+
+eflag=
+
+if test -n "$clist"
+then
+  # signal stuff not implemented
+
+  if test -z "$pflag"
+  then
+    tmp=`mktemp /tmp/ctmXXXXXX`
+  else
+    tmp=
+  fi
+
+  for i in $clist
+  do
+    if test $nc -gt 1 -a -z "$Mflag"
+    then
+      echo "$i:"
+    fi
+
+    if test -z "$Mflag" && echo $i |grep -q '\.s$'
+    then
+      tmp_s=
+      assource=$i
+    else
+      if test -n "$pflag"
+      then
+        tmp_i=`echo $i |sed -e 's/.$/i/'`
+      else
+        tmp_i="$tmp.i"
+      fi
+
+      j=
+      if test -z "$exflag"
+      then
+        j=" $tmp_i"
+      fi
+      if test -n "$debug"
+      then
+        echo $cpp $i$j$plist
+      fi
+      if ! $cpp $i$j$plist
+      then
+        cflag=1
+        eflag=1
+        continue
+      fi
+      if test -n "$pflag"
+      then
+        cflag=1
+        continue
+      fi
+
+      if test -n "$sflag"
+      then
+        if test $nc -eq 1 -a -n "$outfile"
+        then
+          tmp_s="$outfile"
+        else
+          tmp_s=`echo $i |sed -e 's/.$/s/'`
+        fi
+      else
+        tmp_s="$tmp.s"
+      fi
+
+      if test -n "$fflag"
+      then
+        j="$sccom"
+      else
+        j="$ccom"
+      fi
+      if test -n "$oflag"
+      then
+        k="$tmp.c2s"
+      else
+        k="$tmp_s"
+      fi
+      if test -n "$proflag"
+      then
+        k="$k -XP"
+      fi
+      if test -n "$gflag"
+      then
+        k="$k -Xg"
+      elif test -n "$Gflag"
+      then
+        k="$k -XG"
+      fi
+      if test -n "$wflag"
+      then
+        k="$k -w"
+      fi
+      if test -n "$debug"
+      then
+        echo $j $tmp_i $k
+      fi
+      if ! $j $tmp_i $k
+      then
+        cflag=1
+        eflag=1
+        continue
+      fi
+      $rm -f $tmp_i
+
+      if test -n "$oflag"
+      then
+        if test -n "$debug"
+        then
+          echo $c2 $tmp.c2s $tmp_s
+        fi
+        if ! $c2 $tmp.c2s $tmp_s
+        then
+          $rm -f $tmp_s
+          tmp_s="$tmp.c2s"
+        else
+          $rm -f $tmp.c2s
+        fi
+      fi
+
+      if test -n "$sflag"
+      then
+        continue
+      fi
+
+      assource="$tmp_s"
+    fi
+
+    if test -n "$cflag" -a $nc -eq 1 -a -n "$outfile"
+    then
+      j="$outfile"
+    else
+      j=`echo $i |sed -e 's/.$/o/'`
+    fi
+    if test -n "$Rflag"
+    then
+      j="$j -R"
+    fi
+    if test -n "$dflag"
+    then
+      j="$j $dflag"
+    fi
+    if test -n "$debug"
+    then
+      echo $as -o $j $assource
+    fi
+    if ! $as -o $j $assource && $? -gt 1
+    then
+      cflag=1
+      eflag=1
+      continue
+    fi
+    if test -n "$tmp_s"
+    then
+      $rm -f $tmp_s
+    fi
+  done
+fi
+
+if test -z "$cflag" -a -n "$llist"
+then
+  if test -n "$outfile"
+  then
+    j=" -o $outfile"
+  else
+    j=
+  fi
+  if test -n "$gflag" -o -n "$Gflag"
+  then
+    k=" -lg"
+  else
+    k=
+  fi
+  if test -n "$proflag"
+  then
+    k="$k -lc_p"
+  else
+    k="$k -lc"
+  fi
+  if test -n "$debug"
+  then
+    echo $ld -X $crt0$j $llist$k
+  fi
+  if ! $ld -X $crt0$j $llist$k
+  then
+    eflag=1
+  elif test $nc -eq 1 -a $nxo -eq 1 -a -z "$eflag"
+  then
+    set $clist
+    $rm -f `echo $1 |sed -e 's/.$/o/'`
+  fi
+fi
+
+#echo "eflag=$eflag"
+exit $eflag
diff --git a/xify/hostcc.sh b/xify/hostcc.sh
new file mode 100755 (executable)
index 0000000..a7af0a8
--- /dev/null
@@ -0,0 +1,489 @@
+#!/bin/sh
+
+BIN=`dirname $0`
+cpp=/lib/cpp
+include="$BIN/../usr/include"
+xify="$BIN/../lib/xify"
+cc=/usr/bin/gcc
+ld="$BIN/hostld"
+rm=rm
+
+clist=
+llist=
+plist=
+cflag=
+oflag=
+pflag=
+sflag=
+Rflag=
+exflag=
+proflag=
+fflag=
+gflag=
+Gflag=
+Mflag=
+debug=
+dflag=
+xflag=
+nc=0
+nxo=0
+crt0="$BIN/../lib/crto0.o"
+
+while test $# -ge 1
+do
+  case "$1" in
+  -S)
+    sflag=1
+    cflag=1
+    ;;
+  -o)
+    if test -z "$2"
+    then
+      echo "$0: error: -o where?" >&2
+      exit 1
+    fi
+    outfile=$2
+    shift
+    if echo $outfile |grep -q '\.c$'
+    then
+      echo "$0: error: -o would overwrite $outfile" >&2
+      exit 1
+    fi
+    ;;
+  -R)
+    Rflag=1
+    ;;
+  -O)
+    oflag=1
+    ;;
+  -p)
+    proflag=1
+    crt0="$BIN/../lib/mcrt0.o"
+    ;;
+  -pg)
+    proflag=1
+    crt0="$BIN/../usr/lib/gcrt0.o"
+    ;;
+  -f)
+    fflag=1
+    ;;
+  -go)
+    Gflag=1
+    ;;
+  -g)
+    gflag=1
+    ;;
+  -w)
+    wflag=1
+    ;;
+  -E)
+    exflag=1
+    pflag=1
+    plist="$plist $1" # this is ignored by 4.3bsd cpp
+    ;;
+  -P)
+    pflag=1
+    echo "$0: warning: -P option obsolete; you should use -E instead"
+    plist="$plist $1"
+    ;;
+  -c)
+    cflag=1
+    ;;
+  -M*)
+    exflag=1
+    pflag=1
+    Mflag=1
+    plist="$plist $1"
+    ;;
+  -Dnox_*)
+    plist="$plist `echo $1 |sed -e 's/^-Dnox_/-D/'`"
+    ;;
+  -D*)
+    plist="$plist `echo $1 |sed -e 's/^-D/-Dx_/'`"
+    ;;
+  -Unox_*)
+    plist="$plist `echo $1 |sed -e 's/^-Unox_/-U/'`"
+    ;;
+  -U*)
+    plist="$plist `echo $1 |sed -e 's/^-U/-Ux_/'`"
+    ;;
+  -I*)
+    plist="$plist $1"
+    ;;
+  -C)
+    plist="$plist $1"
+    ;;
+  -L*)
+    llist="$llist $1"
+    ;;
+  # chpass and passname stuff not implemented
+  -d)
+    debug=1
+    ;;
+  -d*)
+    dflag=$1
+    ;;
+  -X)
+    xflag=1
+    ;;
+  -*)
+    echo "$0: error: bad flag $1" >&2
+    exit 1
+    ;;
+  *)
+    t=$1
+    if echo $t |grep -q '\.[cs]$' || test -n "$exflag"
+    then
+      clist="$clist $t"
+      nc=`expr $nc + 1`
+      t=`echo $t |sed -e 's/.$/o/'`
+    fi
+
+    dup=
+    for i in $llist
+    do
+      if test "$i" = "$t"
+      then
+        dup=1
+        break
+      fi
+    done
+    if test -z "$dup"
+    then
+      llist="$llist $t"
+      if echo $t |grep -q '\.o$'
+      then
+        nxo=`expr $nxo + 1`
+      fi
+    fi
+    ;;
+  esac
+  shift
+done
+
+#echo "clist=$clist"
+#echo "llist=$llist"
+#echo "plist=$plist"
+#echo "cflag=$cflag"
+#echo "oflag=$oflag"
+#echo "pflag=$pflag"
+#echo "sflag=$sflag"
+#echo "Rflag=$Rflag"
+#echo "exflag=$exflag"
+#echo "proflag=$proflag"
+#echo "fflag=$fflag"
+#echo "gflag=$gflag"
+#echo "Gflag=$Gflag"
+#echo "Mflag=$Mflag"
+#echo "debug=$debug"
+#echo "dflag=$dflag"
+#echo "xflag=$xflag"
+#echo "nc=$nc"
+#echo "nxo=$nxo"
+#echo "crt0=$crt0"
+
+if test \( -n "$gflag" -o -n "$Gflag" \) -a -n "$oflag"
+then
+  echo "$0: warning: -g disables -O" >&2
+  oflag=
+fi
+
+eflag=
+
+if test -n "$clist"
+then
+  # signal stuff not implemented
+
+  if test -z "$pflag"
+  then
+    tmp=`mktemp /tmp/ctmXXXXXX`
+  else
+    tmp=
+  fi
+
+  for i in $clist
+  do
+    if test $nc -gt 1 -a -z "$Mflag"
+    then
+      echo "$i:"
+    fi
+
+    if test -z "$Mflag" && echo $i |grep -q '\.s$'
+    then
+      tmp_s=
+      assource=$i
+    else
+      if test -n "$pflag"
+      then
+        tmp_i=`echo $i |sed -e 's/.$/i/'`
+      else
+        tmp_i="$tmp.i"
+      fi
+
+      j=
+      if test -z "$exflag"
+      then
+        j=" $tmp_i"
+      fi
+      if test -n "$debug"
+      then
+#        echo $cpp $i$j$plist
+        echo $cpp $i$j -nostdinc$plist -I$include
+      fi
+#      if ! $cpp $i$j$plist
+      if ! $cpp $i$j -nostdinc$plist -I$include
+      then
+        cflag=1
+        eflag=1
+        continue
+      fi
+      if test -n "$pflag"
+      then
+        cflag=1
+        continue
+      fi
+
+      j=
+      if test -z "$xflag"
+      then
+        j=" $tmp.c"
+      fi
+      if test -n "$debug"
+      then
+        echo $xify $tmp_i$j
+      fi
+      if ! $xify $tmp_i$j
+      then
+        cflag=1
+        eflag=1
+        continue
+      fi
+      if test -n "$xflag"
+      then
+        cflag=1
+        continue
+      fi
+
+      if test -n "$sflag"
+      then
+        if test $nc -eq 1 -a -n "$outfile"
+        then
+          tmp_s="$outfile"
+        else
+          tmp_s=`echo $i |sed -e 's/.$/s/'`
+        fi
+      else
+# optimization: don't call compiler and assembler separately unless have -S
+        tmp_s="$tmp.c"
+        assource="$tmp_s"
+# since we can't "goto" out of enclosing if, duplicate all code until "done"
+        if test -n "$cflag" -a $nc -eq 1 -a -n "$outfile"
+        then
+          j="$outfile"
+        else
+          j=`echo $i |sed -e 's/.$/o/'`
+        fi
+    #    if test -n "$Rflag"
+    #    then
+    #      j="$j -R"
+    #    fi
+    #    if test -n "$dflag"
+    #    then
+    #      j="$j $dflag"
+    #    fi
+        j="$j -fno-strict-aliasing"
+        if test -n "$proflag"
+        then
+          j="$j -pg"
+        fi
+        if test -n "$gflag" -o -n "$Gflag"
+        then
+          j="$j -g"
+        fi
+        if test -z "$wflag"
+        then
+          j="$j -Wall -Wno-char-subscripts -Wno-deprecated-declarations -Wno-maybe-uninitialized -Wno-parentheses -Wno-strict-aliasing -Wno-unused-result"
+        fi
+        if test -n "$debug"
+        then
+    #      echo $as -o $j $assource
+          echo $cc -o $j -c $assource
+        fi
+    #    if ! $as -o $j $assource && $? -gt 1
+        if ! $cc -o $j -c $assource
+        then
+          cflag=1
+          eflag=1
+          continue
+        fi
+        if test -n "$tmp_s"
+        then
+          $rm -f $tmp_s
+        fi
+        continue
+# else
+#        tmp_s="$tmp.s"
+# end
+      fi
+
+#      if test -n "$oflag"
+#      then
+#        k="$tmp.c2s"
+#      else
+#        k="$tmp_s"
+#      fi
+#      if test -n "$proflag"
+#      then
+#        k="$k -XP"
+#      fi
+#      if test -n "$gflag"
+#      then
+#        k="$k -Xg"
+#      elif test -n "$Gflag"
+#      then
+#        k="$k -XG"
+#      fi
+#      if test -n "$wflag"
+#      then
+#        k="$k -w"
+#      fi
+#      if test -n "$debug"
+#      then
+#        echo $j $tmp_i $k
+#      fi
+#      if ! $j $tmp_i $k
+#      then
+#        cflag=1
+#        eflag=1
+#        continue
+#      fi
+#      $rm -f $tmp_i
+#
+#      if test -n "$oflag"
+#      then
+#        if test -n "$debug"
+#        then
+#          echo $c2 $tmp.c2s $tmp_s
+#        fi
+#        if ! $c2 $tmp.c2s $tmp_s
+#        then
+#          $rm -f $tmp_s
+#          tmp_s="$tmp.c2s"
+#        else
+#          $rm -f $tmp.c2s
+#        fi
+#      fi
+      j="$tmp_s -fno-strict-aliasing"
+      if test -n "$proflag"
+      then
+        j="$j -pg"
+      fi
+      if test -n "$gflag" -o -n "$Gflag"
+      then
+        j="$j -g"
+      fi
+      if test -z "$wflag"
+      then
+        j="$j -Wall -Wno-char-subscripts -Wno-deprecated-declarations -Wno-maybe-uninitialized -Wno-parentheses -Wno-strict-aliasing -Wno-unused-result"
+      fi
+      if test -n "$debug"
+      then
+        echo $cc -o $j -S $tmp.c
+      fi
+      if ! $cc -o $j -S $tmp.c
+      then
+        cflag=1
+        eflag=1
+        continue
+      fi
+
+#      if test -n "$sflag"
+#      then
+        continue
+#      fi
+#
+#      assource="$tmp_s"
+    fi
+
+    if test -n "$cflag" -a $nc -eq 1 -a -n "$outfile"
+    then
+      j="$outfile"
+    else
+      j=`echo $i |sed -e 's/.$/o/'`
+    fi
+#    if test -n "$Rflag"
+#    then
+#      j="$j -R"
+#    fi
+#    if test -n "$dflag"
+#    then
+#      j="$j $dflag"
+#    fi
+    j="$j -fno-strict-aliasing"
+    if test -n "$proflag"
+    then
+      j="$j -pg"
+    fi
+    if test -n "$gflag" -o -n "$Gflag"
+    then
+      j="$j -g"
+    fi
+    if test -z "$wflag"
+    then
+      j="$j -Wall -Wno-char-subscripts -Wno-deprecated-declarations -Wno-maybe-uninitialized -Wno-parentheses -Wno-strict-aliasing -Wno-unused-result"
+    fi
+    if test -n "$debug"
+    then
+#      echo $as -o $j $assource
+      echo $cc -o $j -c $assource
+    fi
+#    if ! $as -o $j $assource && $? -gt 1
+    if ! $cc -o $j -c $assource
+    then
+      cflag=1
+      eflag=1
+      continue
+    fi
+    if test -n "$tmp_s"
+    then
+      $rm -f $tmp_s
+    fi
+  done
+fi
+
+if test -z "$cflag" -a -n "$llist"
+then
+  if test -n "$outfile"
+  then
+    j=" -o $outfile"
+  else
+    j=
+  fi
+  if test -n "$gflag" -o -n "$Gflag"
+  then
+    k=" -lg"
+  else
+    k=
+  fi
+  if test -n "$proflag"
+  then
+    k="$k -lc_p"
+  else
+    k="$k -lc"
+  fi
+  if test -n "$debug"
+  then
+    echo $ld -X $crt0$j $llist$k
+  fi
+  if ! $ld -X $crt0$j $llist$k
+  then
+    eflag=1
+  elif test $nc -eq 1 -a $nxo -eq 1 -a -z "$eflag"
+  then
+    set $clist
+    $rm -f `echo $1 |sed -e 's/.$/o/'`
+  fi
+fi
+
+#echo "eflag=$eflag"
+exit $eflag
diff --git a/xify/hostld.sh b/xify/hostld.sh
new file mode 100755 (executable)
index 0000000..04069f5
--- /dev/null
@@ -0,0 +1,206 @@
+#!/bin/sh
+
+BIN=`dirname $0`
+cc=/usr/bin/gcc
+ld=/usr/bin/ld
+mkdir=mkdir
+ln=ln
+rm=rm
+
+outfile=
+dirs=
+files=
+Mflag=
+xflag=
+Xflag=
+Sflag=
+rflag=
+arflag=
+sflag=
+nflag=
+Nflag=
+zflag=
+dflag=
+trace=
+ytab=
+objs=
+
+while test $# -ge 1
+do
+  case "$1" in
+  -o)
+    if test -z "$2"
+    then
+      echo "$0: error: -o where?" >&2
+      exit 1
+    fi
+    outfile=$2
+    shift
+    ;;
+  -M)
+    Mflag=1
+    ;;
+  -x)
+    xflag=1
+    ;;
+  -X)
+    Xflag=1
+    ;;
+  -S)
+    Sflag=1
+    ;;
+  -r)
+    rflag=1
+    arflag=1
+    ;;
+  -s)
+    sflag=1
+    xflag=1
+    ;;
+  -n)
+    nflag=1
+    Nflag=
+    zflag=
+    ;;
+  -N)
+    Nflag=1
+    nflag=
+    zflag=
+    ;;
+  -d)
+    dflag=1
+    ;;
+  -i)
+    echo "$0: warning: -i ignored" >&2
+    ;;
+  -t)
+    trace=1
+    ;;
+  -y*)
+    if test "$1" = "-y"
+    then
+      echo "$0: warning: -y: symbol name missing"
+    else
+      ytab="$ytab `echo $1 |sed -e 's/^-y//'`"
+    fi
+    ;;
+  -z)
+    zflag=1
+    Nflag=
+    nflag=
+    ;;
+  -L*)
+    if test "$1" = "-L"
+    then
+      echo "$0: warning: -L: pathname missing"
+    else
+      dirs="$dirs `echo $1 |sed -e 's/^-L//'`"
+    fi
+    ;;
+  -l*)
+    if test "$1" = "-l"
+    then
+      echo "$0: warning: -l: library name missing"
+    else
+      files="$files $1"
+    fi
+    ;;
+  -*)
+    echo "$0: error: bad flag $1" >&2
+    exit 1
+    ;;
+  *)
+    files="$files $1"
+    ;;
+  esac
+  shift
+done
+
+dirs="$dirs $BIN/../lib $BIN/../usr/lib $BIN/../usr/local/lib"
+
+if test -z "$rflag" -a -z "$Nflag" -a -z "$nflag"
+then
+  zflag=1
+fi
+
+#echo "outfile=$outfile"
+#echo "Mflag=$Mflag"
+#echo "xflag=$xflag"
+#echo "Xflag=$Xflag"
+#echo "Sflag=$Sflag"
+#echo "rflag=$rflag"
+#echo "arflag=$arflag"
+#echo "sflag=$sflag"
+#echo "nflag=$nflag"
+#echo "Nflag=$Nflag"
+#echo "zflag=$zflag"
+#echo "dflag=$dflag"
+#echo "trace=$trace"
+#echo "ytab=$ytab"
+#echo "dirs=$dirs"
+#echo "files=$files"
+
+if test -n "$rflag"
+then
+  cmd="$ld"
+else
+  cmd="$cc"
+fi
+if test -n "$outfile"
+then
+  cmd="$cmd -o $outfile"
+fi
+for i in $dirs
+do
+  cmd="$cmd -L$i/.xify"
+done
+if test -n "$rflag"
+then
+  cmd="$cmd -r"
+fi
+for i in $files
+do
+  case "$i" in
+  -lnox_*)
+    cmd="$cmd `echo $i |sed -e 's/^-lnox_/-l/'`"
+    ;;
+  -l*)
+    j=`echo $i |sed -e 's/^-l//'`
+    for k in $dirs
+    do
+      if test -f $k/lib$j.a
+      then
+        if ! test -f $k/.xify/libx_$j.a
+        then
+          if test -n "$trace"
+          then
+            echo $mkdir -p $k/.xify
+          fi
+          $mkdir -p $k/.xify
+          if test -n "$trace"
+          then
+            echo $ln -s ../lib$j.a $k/.xify/libx_$j.a
+          fi
+          $ln -s ../lib$j.a $k/.xify/libx_$j.a
+        fi
+        break
+      fi
+      if test -n "$trace"
+      then
+        echo $rm -f $k/.xify/libx_$j.a
+      fi
+      $rm -f $k/.xify/libx_$j.a
+    done
+    cmd="$cmd -lx_$j"
+    ;;
+  *)
+    cmd="$cmd $i"
+    ;;
+  esac
+done
+if test -n "$trace"
+then
+  echo $cmd
+fi
+$cmd
+exit $?
diff --git a/xify/ld.c b/xify/ld.c
deleted file mode 100644 (file)
index 6cc85f7..0000000
--- a/xify/ld.c
+++ /dev/null
@@ -1,2301 +0,0 @@
-/*
- * Copyright (c) 1980 Regents of the University of California.
- * All rights reserved.  The Berkeley software License Agreement
- * specifies the terms and conditions for redistribution.
- */
-
-#if defined(DOCOPYRIGHT) && !defined(lint)
-char copyright[] =
-"@(#) Copyright (c) 1980 Regents of the University of California.\n\
- All rights reserved.\n";
-#endif
-
-#if defined(DOSCCS) && !defined(lint)
-static char sccsid[] = "@(#)ld.c       5.4 (Berkeley) 11/26/85";
-#endif
-
-/*
- * ld - string table version for VAX
- */
-
-#include <sys/param.h>
-#include <signal.h>
-#include <stdio.h>
-#include <string.h>
-#include <strings.h>
-#include <ctype.h>
-#ifdef XIFY
-#include <errno.h>
-#else
-#include <ar.h>
-#include <a.out.h>
-#include <ranlib.h>
-#endif
-#include <sys/stat.h>
-#include <sys/file.h>
-#ifdef XIFY
-#include <sys/wait.h>
-#endif
-
-#if defined(__STDC__) && !defined(X_)
-#include <stdlib.h>
-#include <unistd.h>
-#else
-#include <sys.h>
-#endif
-
-/*
- * Basic strategy:
- *
- * The loader takes a number of files and libraries as arguments.
- * A first pass examines each file in turn.  Normal files are
- * unconditionally loaded, and the (external) symbols they define and require
- * are noted in the symbol table.   Libraries are searched, and the
- * library members which define needed symbols are remembered
- * in a special data structure so they can be selected on the second
- * pass.  Symbols defined and required by library members are also
- * recorded.
- *
- * After the first pass, the loader knows the size of the basic text
- * data, and bss segments from the sum of the sizes of the modules which
- * were required.  It has computed, for each ``common'' symbol, the
- * maximum size of any reference to it, and these symbols are then assigned
- * storage locations after their sizes are appropriately rounded.
- * The loader now knows all sizes for the eventual output file, and
- * can determine the final locations of external symbols before it
- * begins a second pass.
- *
- * On the second pass each normal file and required library member
- * is processed again.  The symbol table for each such file is
- * reread and relevant parts of it are placed in the output.  The offsets
- * in the local symbol table for externally defined symbols are recorded
- * since relocation information refers to symbols in this way.
- * Armed with all necessary information, the text and data segments
- * are relocated and the result is placed in the output file, which
- * is pasted together, ``in place'', by writing to it in several
- * different places concurrently.
- */
-
-#ifndef XIFY
-/*
- * Internal data structures
- *
- * All internal data structures are segmented and dynamically extended.
- * The basic structures hold 1103 (NSYM) symbols, ~~200 (NROUT)
- * referenced library members, and 100 (NSYMPR) private (local) symbols
- * per object module.  For large programs and/or modules, these structures
- * expand to be up to 40 (NSEG) times as large as this as necessary.
- */
-#define        NSEG    40              /* Number of segments, each data structure */
-#define        NSYM    1103            /* Number of symbols per segment */
-#define        NROUT   250             /* Number of library references per segment */
-#define        NSYMPR  100             /* Number of private symbols per segment */
-
-/*
- * Structure describing each symbol table segment.
- * Each segment has its own hash table.  We record the first
- * address in and first address beyond both the symbol and hash
- * tables, for use in the routine symx and the lookup routine respectively.
- * The symfree routine also understands this structure well as it used
- * to back out symbols from modules we decide that we don't need in pass 1.
- *
- * Csymseg points to the current symbol table segment;
- * csymseg->sy_first[csymseg->sy_used] is the next symbol slot to be allocated,
- * (unless csymseg->sy_used == NSYM in which case we will allocate another
- * symbol table segment first.)
- */
-struct symseg {
-       struct  nlist *sy_first;        /* base of this alloc'ed segment */
-       struct  nlist *sy_last;         /* end of this segment, for n_strx */
-       int     sy_used;                /* symbols used in this seg */
-       struct  nlist **sy_hfirst;      /* base of hash table, this seg */
-       struct  nlist **sy_hlast;       /* end of hash table, this seg */
-} symseg[NSEG], *csymseg;
-
-/*
- * The lookup routine uses quadratic rehash.  Since a quadratic rehash
- * only probes 1/2 of the buckets in the table, and since the hash
- * table is segmented the same way the symbol table is, we make the
- * hash table have twice as many buckets as there are symbol table slots
- * in the segment.  This guarantees that the quadratic rehash will never
- * fail to find an empty bucket if the segment is not full and the
- * symbol is not there.
- */
-#define        HSIZE   (NSYM*2)
-
-/*
- * Xsym converts symbol table indices (ala x) into symbol table pointers.
- * Symx (harder, but never used in loops) inverts pointers into the symbol
- * table into indices using the symseg[] structure.
- */
-#define        xsym(x) (symseg[(x)/NSYM].sy_first+((x)%NSYM))
-/* symx() is a function, defined below */
-
-struct nlist cursym;           /* current symbol */
-struct nlist *lastsym;         /* last symbol entered */
-struct nlist *nextsym;         /* next available symbol table entry */
-struct nlist *addsym;          /* first sym defined during incr load */
-int    nsym;                   /* pass2: number of local symbols in a.out */
-/* nsym + symx(nextsym) is the symbol table size during pass2 */
-
-struct nlist **lookup(), **slookup();
-struct nlist *p_etext, *p_edata, *p_end, *entrypt;
-
-/*
- * Definitions of segmentation for library member table.
- * For each library we encounter on pass 1 we record pointers to all
- * members which we will load on pass 2.  These are recorded as offsets
- * into the archive in the library member table.  Libraries are
- * separated in the table by the special offset value -1.
- */
-off_t  li_init[NROUT];
-struct libseg {
-       off_t   *li_first;
-       int     li_used;
-       int     li_used2;
-} libseg[NSEG] = {
-       li_init, 0, 0,
-}, *clibseg = libseg;
-
-/*
- * In processing each module on pass 2 we must relocate references
- * relative to external symbols.  These references are recorded
- * in the relocation information as relative to local symbol numbers
- * assigned to the external symbols when the module was created.
- * Thus before relocating the module in pass 2 we create a table
- * which maps these internal numbers to symbol table entries.
- * A hash table is constructed, based on the local symbol table indices,
- * for quick lookup of these symbols.
- */
-#define        LHSIZ   31
-struct local {
-       int     l_index;                /* index to symbol in file */
-       struct  nlist *l_symbol;        /* ptr to symbol table */
-       struct  local *l_link;          /* hash link */
-} *lochash[LHSIZ], lhinit[NSYMPR];
-struct locseg {
-       struct  local *lo_first;
-       int     lo_used;
-} locseg[NSEG] = {
-       lhinit, 0
-}, *clocseg;
-
-/*
- * Libraries are typically built with a table of contents,
- * which is the first member of a library with special file
- * name __.SYMDEF and contains a list of symbol names
- * and with each symbol the offset of the library member which defines
- * it.  The loader uses this table to quickly tell which library members
- * are (potentially) useful.  The alternative, examining the symbol
- * table of each library member, is painfully slow for large archives.
- *
- * See <ranlib.h> for the definition of the ranlib structure and an
- * explanation of the __.SYMDEF file format.
- */
-int    tnum;           /* number of symbols in table of contents */
-int    ssiz;           /* size of string table for table of contents */
-struct ranlib *tab;    /* the table of contents (dynamically allocated) */
-char   *tabstr;        /* string table for table of contents */
-
-/*
- * We open each input file or library only once, but in pass2 we
- * (historically) read from such a file at 2 different places at the
- * same time.  These structures are remnants from those days,
- * and now serve only to catch ``Premature EOF''.
- * In order to make I/O more efficient, we provide routines which
- * use the optimal block size returned by stat().
- */
-#define BLKSIZE 1024
-typedef struct {
-       short   *fakeptr;
-       int     bno;
-       int     nibuf;
-       int     nuser;
-       char    *buff;
-       int     bufsize;
-} PAGE;
-
-PAGE   page[2];
-int    p_blksize;
-int    p_blkshift;
-int    p_blkmask;
-
-struct {
-       short   *fakeptr;
-       int     bno;
-       int     nibuf;
-       int     nuser;
-} fpage;
-
-typedef struct {
-       char    *ptr;
-       int     bno;
-       int     nibuf;
-       long    size;
-       long    pos;
-       PAGE    *pno;
-} STREAM;
-
-STREAM text;
-STREAM reloc;
-
-/*
- * Header from the a.out and the archive it is from (if any).
- */
-struct exec filhdr;
-struct ar_hdr archdr;
-#define        OARMAG 0177545
-#endif
-
-/*
- * Options.
- */
-int    trace;
-int    xflag;          /* discard local symbols */
-int    Xflag;          /* discard locals starting with 'L' */
-int    Sflag;          /* discard all except locals and globals*/
-int    rflag;          /* preserve relocation bits, don't define common */
-int    arflag;         /* original copy of rflag */
-int    sflag;          /* discard all symbols */
-int    Mflag;          /* print rudimentary load map */
-int    nflag;          /* pure procedure */
-int    dflag;          /* define common even with rflag */
-int    zflag;          /* demand paged  */
-long   hsize;          /* size of hole at beginning of data to be squashed */
-int    Aflag;          /* doing incremental load */
-int    Nflag;          /* want impure a.out */
-int    funding;        /* reading fundamental file for incremental load */
-int    yflag;          /* number of symbols to be traced */
-char   **ytab;         /* the symbols */
-
-#ifndef XIFY
-/*
- * These are the cumulative sizes, set in pass 1, which
- * appear in the a.out header when the loader is finished.
- */
-off_t  tsize, dsize, bsize, trsize, drsize, ssize;
-
-/*
- * Symbol relocation: c?rel is a scale factor which is
- * added to an old relocation to convert it to new units;
- * i.e. it is the difference between segment origins.
- * (Thus if we are loading from a data segment which began at location
- * 4 in a .o file into an a.out where it will be loaded starting at
- * 1024, cdrel will be 1020.)
- */
-long   ctrel, cdrel, cbrel;
-
-/*
- * Textbase is the start address of all text, 0 unless given by -T.
- * Database is the base of all data, computed before and used during pass2.
- */
-long   textbase, database;
-
-/*
- * The base addresses for the loaded text, data and bss from the
- * current module during pass2 are given by torigin, dorigin and borigin.
- */
-long   torigin, dorigin, borigin;
-#endif
-
-/*
- * Errlev is nonzero when errors have occured.
- * Delarg is an implicit argument to the routine delexit
- * which is called on error.  We do ``delarg = errlev'' before normal
- * exits, and only if delarg is 0 (i.e. errlev was 0) do we make the
- * result file executable.
- */
-int    errlev;
-int    delarg  = 4;
-
-#ifndef XIFY
-/*
- * The biobuf structure and associated routines are used to write
- * into one file at several places concurrently.  Calling bopen
- * with a biobuf structure sets it up to write ``biofd'' starting
- * at the specified offset.  You can then use ``bwrite'' and/or ``bputc''
- * to stuff characters in the stream, much like ``fwrite'' and ``fputc''.
- * Calling bflush drains all the buffers and MUST be done before exit.
- */
-struct biobuf {
-       short   b_nleft;                /* Number free spaces left in b_buf */
-/* Initialize to be less than b_bufsize initially, to boundary align in file */
-       char    *b_ptr;                 /* Next place to stuff characters */
-       char    *b_buf;                 /* Pointer to the buffer */
-       int     b_bufsize;              /* Size of the buffer */
-       off_t   b_off;                  /* Current file offset */
-       struct  biobuf *b_link;         /* Link in chain for bflush() */
-} *biobufs;
-#define        bputc(c,b) ((b)->b_nleft ? (--(b)->b_nleft, *(b)->b_ptr++ = (c)) \
-                      : bflushc(b, c))
-int    biofd;
-off_t  boffset;
-struct biobuf *tout, *dout, *trout, *drout, *sout, *strout;
-
-/*
- * Offset is the current offset in the string file.
- * Its initial value reflects the fact that we will
- * eventually stuff the size of the string table at the
- * beginning of the string table (i.e. offset itself!).
- */
-off_t  offset = sizeof (off_t);
-#endif
-
-int    ofilfnd;                /* -o given; otherwise move l.out to a.out */
-char   *ofilename = "l.out";
-int    ofilemode;              /* respect umask even for unsucessful ld's */
-int    infil;                  /* current input file descriptor */
-char   *filname;               /* and its name */
-
-#define        NDIRS   25
-#define NDEFDIRS 3             /* number of default directories in dirs[] */
-char   *dirs[NDIRS];           /* directories for library search */
-int    ndir;                   /* number of directories */
-
-#ifdef XIFY
-char   *gcc = "/usr/bin/gcc";
-char   *ld = "/usr/bin/ld";
-
-char   **av;
-int    na;
-
-char   in_path[BUFSIZ];
-char   out_path[BUFSIZ];
-
-extern char **environ;
-#else
-/*
- * Base of the string table of the current module (pass1 and pass2).
- */
-char   *curstr;
-
-/*
- * System software page size, as returned by getpagesize.
- */
-int    pagesize;
-#endif
-
-/*char         get();*/
-/*int  delexit();*/
-/*char *savestr();*/
-/*char *malloc();*/
-
-#ifndef __P
-#ifdef __STDC__
-#define __P(args) args
-#else
-#define __P(args) ()
-#endif
-#endif
-
-int main __P((int argc, char **argv));
-#ifndef XIFY
-int htoi __P((register char *p));
-#endif
-void delexit __P((void));
-void endload __P((int argc, char **argv));
-#ifdef XIFY
-void xify_library __P((char *in_name));
-int callsys __P((/*char *f,*/ char **v));
-#else
-void load1arg __P((register char *cp));
-int step __P((off_t nloc));
-void nextlibp __P((off_t val));
-int ldrand __P((void));
-int load1 __P((int libflg, off_t loc));
-void middle __P((void));
-void fixspec __P((struct nlist *sym, long offset));
-void ldrsym __P((register struct nlist *sp, long val, int type));
-void setupout __P((void));
-void outb __P((register struct biobuf **bp, int inc, int bufsize));
-void load2arg __P((char *acp));
-void load2 __P((long loc));
-void tracesym __P((void));
-void load2td __P((long creloc, int position, struct biobuf *b1, struct biobuf *b2));
-#endif
-void finishout __P((void));
-#ifndef XIFY
-void mkfsym __P((char *s));
-void getarhdr __P((void));
-void mget __P((void *_loc, int n, register STREAM *sp));
-void symwrite __P((struct nlist *sp, struct biobuf *bp));
-void dseek __P((register STREAM *sp, long loc, long s));
-char get __P((STREAM *asp));
-int getfile __P((char *acp));
-int libopen __P((char *name, int oflags));
-struct nlist **lookup __P((void));
-void symfree __P((struct nlist *saved));
-struct nlist **slookup __P((char *s));
-int enter __P((register struct nlist **hp));
-int symx __P((struct nlist *sp));
-void symreloc __P((void));
-#endif
-void error __P((int n, char *s));
-#ifndef XIFY
-void readhdr __P((off_t loc));
-int _round __P((int v, u_long r));
-#endif
-char *savestr __P((register char *cp));
-#ifdef XIFY
-char *strspl __P((char *left, char *right));
-#else
-void bopen __P((register struct biobuf *bp, int off, int bufsize));
-void bwrite __P((void *_p, register int cnt, register struct biobuf *bp));
-void bflush __P((void));
-void bflush1 __P((register struct biobuf *bp));
-void bflushc __P((register struct biobuf *bp, int c));
-void bseek __P((register struct biobuf *bp, register off_t off));
-#endif
-
-int main(argc, argv) int argc; char **argv; {
-       register int c, i;
-#ifndef XIFY
-       int num;
-#endif
-       register char *ap, **p;
-#ifndef XIFY
-       char save;
-#endif
-
-       if (signal(SIGINT, SIG_IGN) != SIG_IGN) {
-               signal(SIGINT, (void (*) __P((int sig)))delexit);
-               signal(SIGTERM, (void (*) __P((int sig)))delexit);
-       }
-       if (argc == 1)
-               exit(4);
-#ifndef XIFY
-       pagesize = getpagesize();
-#endif
-
-       /* 
-        * Pull out search directories.
-        */
-       for (c = 1; c < argc; c++) {
-               ap = argv[c];
-               if (ap[0] == '-' && ap[1] == 'L') {
-                       if (ap[2] == 0)
-                               error(1, "-L: pathname missing");
-                       if (ndir >= NDIRS - NDEFDIRS)
-                               error(1, "-L: too many directories");
-#ifdef XIFY
-                       dirs[ndir++] = strspl(&ap[2], "/.xify");
-#else
-                       dirs[ndir++] = &ap[2];
-#endif
-               }
-       }
-       /* add default search directories */
-#ifdef XIFY
-       ap = argv[0];
-       for (i = strlen(ap); i > 0 && ap[i - 1] != '/'; --i)
-               ;
-       bcopy(ap, in_path, i);
-       strcpy(in_path + i, "../lib/.xify");
-       dirs[ndir++] = savestr(in_path);
-       strcpy(in_path + i, "../usr/lib/.xify");
-       dirs[ndir++] = savestr(in_path);
-       strcpy(in_path + i, "../usr/local/lib/.xify");
-       dirs[ndir++] = savestr(in_path);
-#else
-       dirs[ndir++] = "/lib";
-       dirs[ndir++] = "/usr/lib";
-       dirs[ndir++] = "/usr/local/lib";
-#endif
-
-       p = argv+1;
-       /*
-        * Scan files once to find where symbols are defined.
-        */
-       for (c=1; c<argc; c++) {
-#ifndef XIFY
-               if (trace)
-                       printf("%s:\n", *p);
-#endif
-               filname = 0;
-               ap = *p++;
-               if (*ap != '-') {
-#ifndef XIFY
-                       load1arg(ap);
-#endif
-                       continue;
-               }
-               for (i=1; ap[i]; i++) switch (ap[i]) {
-
-               case 'o':
-                       if (++c >= argc)
-                               error(1, "-o where?");
-                       ofilename = *p++;
-                       ofilfnd++;
-                       continue;
-               case 'u':
-               case 'e':
-                       if (++c >= argc)
-                               error(1, "-u or -c: arg missing");
-#ifdef XIFY
-                       error(1, "-u or -c: not implemented");
-#else
-                       enter(slookup(*p++));
-                       if (ap[i]=='e')
-                               entrypt = lastsym;
-#endif
-                       continue;
-               case 'H':
-                       if (++c >= argc)
-                               error(1, "-H: arg missing");
-#ifdef XIFY
-                       error(1, "-H: not implemented");
-#else
-                       if (tsize!=0)
-                               error(1, "-H: too late, some text already loaded");
-                       hsize = atoi(*p++);
-#endif
-                       continue;
-               case 'A':
-                       if (++c >= argc)
-                               error(1, "-A: arg missing");
-#ifdef XIFY
-                       error(1, "-A: not implemented");
-#else
-                       if (Aflag) 
-                               error(1, "-A: only one base file allowed");
-                       Aflag = 1;
-                       nflag = 0;
-                       funding = 1;
-                       load1arg(*p++);
-                       trsize = drsize = tsize = dsize = bsize = 0;
-                       ctrel = cdrel = cbrel = 0;
-                       funding = 0;
-                       addsym = nextsym;
-#endif
-                       continue;
-               case 'D':
-                       if (++c >= argc)
-                               error(1, "-D: arg missing");
-#ifdef XIFY
-                       error(1, "-D: not implemented");
-#else
-                       num = htoi(*p++);
-                       if (dsize > num)
-                               error(1, "-D: too small");
-                       dsize = num;
-#endif
-                       continue;
-               case 'T':
-                       if (++c >= argc)
-                               error(1, "-T: arg missing");
-#ifdef XIFY
-                       error(1, "-T: not implemented");
-#else
-                       if (tsize!=0)
-                               error(1, "-T: too late, some text already loaded");
-                       textbase = htoi(*p++);
-#endif
-                       continue;
-               case 'l':
-#ifndef XIFY
-                       save = ap[--i]; 
-                       ap[i]='-';
-                       load1arg(&ap[i]);
-                       ap[i]=save;
-#endif
-                       goto next;
-               case 'M':
-                       Mflag++;
-                       continue;
-               case 'x':
-                       xflag++;
-                       continue;
-               case 'X':
-                       Xflag++;
-                       continue;
-               case 'S':
-                       Sflag++; 
-                       continue;
-               case 'r':
-                       rflag++;
-                       arflag++;
-                       continue;
-               case 's':
-                       sflag++;
-                       xflag++;
-                       continue;
-               case 'n':
-                       nflag++;
-                       Nflag = zflag = 0;
-                       continue;
-               case 'N':
-                       Nflag++;
-                       nflag = zflag = 0;
-                       continue;
-               case 'd':
-                       dflag++;
-                       continue;
-               case 'i':
-                       printf("ld: -i ignored\n");
-                       continue;
-               case 't':
-                       trace++;
-                       continue;
-               case 'y':
-                       if (ap[i+1] == 0)
-                               error(1, "-y: symbol name missing");
-                       if (yflag == 0) {
-                               ytab = (char **)calloc(argc, sizeof (char **));
-                               if (ytab == 0)
-                                       error(1, "ran out of memory (-y)");
-                       }
-                       ytab[yflag++] = &ap[i+1];
-                       goto next;
-               case 'z':
-                       zflag++;
-                       Nflag = nflag = 0;
-                       continue;
-               case 'L':
-                       goto next;
-               default:
-                       filname = savestr("-x");        /* kludge */
-                       filname[1] = ap[i];             /* kludge */
-#ifndef XIFY
-                       archdr.ar_name[0] = 0;          /* kludge */
-#endif
-                       error(1, "bad flag");
-               }
-next:
-               ;
-       }
-       if (rflag == 0 && Nflag == 0 && nflag == 0)
-               zflag++;
-       endload(argc, argv);
-       exit(0);
-}
-
-#ifndef XIFY
-/*
- * Convert a ascii string which is a hex number.
- * Used by -T and -D options.
- */
-int htoi(p) register char *p; {
-       register int c, n;
-
-       n = 0;
-       while (c = *p++) {
-               n <<= 4;
-               if (isdigit(c))
-                       n += c - '0';
-               else if (c >= 'a' && c <= 'f')
-                       n += 10 + (c - 'a');
-               else if (c >= 'A' && c <= 'F')
-                       n += 10 + (c - 'A');
-               else
-                       error(1, "badly formed hex number");
-       }
-       return (n);
-}
-#endif
-
-void delexit() {
-#ifndef XIFY
-       struct stat stbuf;
-       long size;
-       char c = 0;
-
-       bflush();
-#endif
-       unlink("l.out");
-#ifndef XIFY
-       /*
-        * We have to insure that the last block of the data segment
-        * is allocated a full pagesize block. If the underlying
-        * file system allocates frags that are smaller than pagesize,
-        * a full zero filled pagesize block needs to be allocated so 
-        * that when it is demand paged, the paged in block will be 
-        * appropriately filled with zeros.
-        */
-       fstat(biofd, &stbuf);
-       size = _round(stbuf.st_size, pagesize);
-       if (!rflag && size > stbuf.st_size) {
-               lseek(biofd, size - 1, 0);
-               if (write(biofd, &c, 1) != 1)
-                       delarg |= 4;
-       }
-       if (delarg==0 && Aflag==0)
-               (void) chmod(ofilename, ofilemode);
-#endif
-       exit (delarg);
-}
-
-void endload(argc, argv) int argc; char **argv; {
-       register int c, i; 
-#ifndef XIFY
-       long dnum;
-#endif
-       register char *ap, **p;
-
-#ifdef XIFY
-       /* ld currently adds upto 5 args; 10 is room to spare */
-       av = (char **)calloc(argc+10, sizeof (char **));
-       av[0] = rflag ? /*"ld"*/ld : /*"gcc"*/gcc; av[1] = "-o"; av[2] = ofilename;
-       na = 3;
-       for (i = 0; i < ndir; ++i)
-               av[na++] = strspl("-L", dirs[i]);
-       if (rflag)
-               av[na++] = "-r";
-#else
-       clibseg = libseg;
-       filname = 0;
-       middle();
-       setupout();
-#endif
-       p = argv+1;
-       for (c=1; c<argc; c++) {
-               ap = *p++;
-#ifndef XIFY
-               if (trace)
-                       printf("%s:\n", ap);
-#endif
-               if (*ap != '-') {
-#ifdef XIFY
-                       av[na++] = ap;
-#else
-                       load2arg(ap);
-#endif
-                       continue;
-               }
-               for (i=1; ap[i]; i++) switch (ap[i]) {
-
-#ifndef XIFY
-               case 'D':
-                       dnum = htoi(*p);
-                       if (dorigin < dnum)
-                               while (dorigin < dnum)
-                                       bputc(0, dout), dorigin++;
-                       /* fall into ... */
-               case 'T':
-               case 'u':
-               case 'e':
-#endif
-               case 'o':
-#ifndef XIFY
-               case 'H':
-#endif
-                       ++c; 
-                       ++p;
-                       /* fall into ... */
-               default:
-                       continue;
-#ifndef XIFY
-               case 'A':
-                       funding = 1;
-                       load2arg(*p++);
-                       funding = 0;
-                       c++;
-                       continue;
-#endif
-               case 'y':
-               case 'L':
-                       goto next;
-               case 'l':
-                       ap[--i]='-';
-#ifdef XIFY
-                       filname = ap + i;
-                       if (strncmp(filname + 2, "nox_", 4) == 0)
-                               av[na++] = strspl("-l", filname + 6);
-                       else {
-                               xify_library(filname + 2);
-                               av[na++] = strspl("-lx_", filname + 2);
-                       }
-#else
-
-                       load2arg(&ap[i]);
-#endif
-                       goto next;
-               }
-next:
-               ;
-       }
-#ifdef XIFY
-       if (callsys(/*rflag ? ld : gcc,*/ av))
-               delexit();
-#endif
-       finishout();
-}
-
-#ifdef XIFY
-void xify_library(in_name) char *in_name; {
-       int i, j;
-       struct stat statbuf;
-
-       for (i = 0; i < ndir; ++i) {
-               j = strlen(dirs[i]) - 5; /* remove ".xify" */
-               bcopy(dirs[i], in_path, j);
-               strcpy(in_path + j, "lib");
-               strcat(in_path + j, in_name);
-               strcat(in_path + j, ".a");
-               if (stat(in_path, &statbuf) == 0)
-                       goto found;
-
-               strcpy(in_path + j, ".xify/libx_");
-               strcat(in_path + j, in_name);
-               strcat(in_path + j, ".a");
-               if (trace)
-                       fprintf(stderr, "unlink %s\n", in_path);
-               if (unlink(in_path) && errno != ENOENT) {
-                       filname=in_path;
-                       error(1, "can't unlink\n");
-               }
-       }
-       error(1, "not found\n");
-       exit(1);
-
-found:
-       j += 5; /* j = strlen(dirs[i]); */
-       bcopy(dirs[i], out_path, j);
-       strcpy(out_path + j, "/libx_");
-       strcat(out_path + j, in_name);
-       strcat(out_path + j, ".a");
-       if (stat(out_path, &statbuf) == 0)
-               return;
-       if (trace)
-               fprintf(stderr, "mkdir %s\n", dirs[i]);
-       if (mkdir(dirs[i], 0777) == -1 && errno != EEXIST) {
-               filname = dirs[i];
-               error(1, "can't mkdir\n");
-       }
-       strcpy(in_path, "../lib");
-       strcat(in_path, in_name);
-       strcat(in_path, ".a");
-       if (trace)
-               fprintf(stderr, "symlink %s %s\n", in_path, out_path);
-       if (symlink(in_path, out_path) == -1) {
-               filname = out_path;
-               error(1, "can't symlink\n");
-       }
-}
-
-int callsys(/*f,*/ v) /*char *f;*/ char **v; {
-       int t, status;
-#if 1
-       int i;
-
-       if (/*debug*/trace) {
-               fprintf(stderr, "%s", v[0]);
-               for (i = 1; v[i]; ++i)
-                       fprintf(stderr, " %s", v[i]);
-               fprintf(stderr, "\n");
-       }
-#else
-       char **cpp;
-
-       if (/*debug*/trace) {
-               fprintf(stderr, "%s:", /*f*/v[0]);
-               for (cpp = v; *cpp != 0; cpp++)
-                       fprintf(stderr, " %s", *cpp);
-               fprintf(stderr, "\n");
-       }
-#endif
-       t = vfork();
-       if (t == -1) {
-               printf("No more processes\n");
-               return (100);
-       }
-       if (t == 0) {
-               execv(/*f*/v[0], v);
-               printf("Can't find %s\n", /*f*/v[0]);
-               fflush(stdout);
-               _exit(100);
-       }
-       while (t != wait(&status))
-               ;
-#if 1
-       if (WIFSIGNALED(status) /*&& WTERMSIG(status) != SIGALRM*/) {
-               if (WTERMSIG(status) != SIGINT) {
-                       printf("Fatal error in %s\n", /*f*/v[0]);
-                       /*eflag*/delarg = 8;
-               }
-               /*dexit*/delexit();
-       }
-       return (WEXITSTATUS(status));
-#else
-       if ((t=(status&0377)) != 0 && t!=14) {
-               if (t!=2) {
-                       printf("Fatal error in %s\n", /*f*/v[0]);
-                       /*eflag*/delarg = 8;
-               }
-               /*dexit*/delexit();
-       }
-       return ((status>>8) & 0377);
-#endif
-}
-#else
-/*
- * Scan file to find defined symbols.
- */
-void load1arg(cp) register char *cp; {
-       register struct ranlib *tp;
-       off_t nloc;
-       int kind;
-
-       kind = getfile(cp);
-       if (Mflag)
-               printf("%s\n", filname);
-       switch (kind) {
-
-       /*
-        * Plain file.
-        */
-       case 0:
-               load1(0, 0L);
-               break;
-
-       /*
-        * Archive without table of contents.
-        * (Slowly) process each member.
-        */
-       case 1:
-               error(-1,
-"warning: archive has no table of contents; add one using ranlib(1)");
-               nloc = SARMAG;
-               while (step(nloc))
-                       nloc += sizeof(archdr) +
-                           _round(atol(archdr.ar_size), sizeof (short));
-               break;
-
-       /*
-        * Archive with table of contents.
-        * Read the table of contents and its associated string table.
-        * Pass through the library resolving symbols until nothing changes
-        * for an entire pass (i.e. you can get away with backward references
-        * when there is a table of contents!)
-        */
-       case 2:
-               nloc = SARMAG + sizeof (archdr);
-               dseek(&text, nloc, sizeof (tnum));
-               mget(&tnum, sizeof (tnum), &text);
-               nloc += sizeof (tnum);
-               tab = (struct ranlib *)malloc(tnum);
-               if (tab == 0)
-                       error(1, "ran out of memory (toc)");
-               dseek(&text, nloc, tnum);
-               mget(tab, tnum, &text);
-               nloc += tnum;
-               tnum /= sizeof (struct ranlib);
-               dseek(&text, nloc, sizeof (ssiz));
-               mget(&ssiz, sizeof (ssiz), &text);
-               nloc += sizeof (ssiz);
-               tabstr = (char *)malloc(ssiz);
-               if (tabstr == 0)
-                       error(1, "ran out of memory (tocstr)");
-               dseek(&text, nloc, ssiz);
-               mget(tabstr, ssiz, &text);
-               for (tp = &tab[tnum]; --tp >= tab;) {
-                       if (tp->ran_un.ran_strx < 0 ||
-                           tp->ran_un.ran_strx >= ssiz)
-                               error(1, "mangled archive table of contents");
-                       tp->ran_un.ran_name = tabstr + tp->ran_un.ran_strx;
-               }
-               while (ldrand())
-                       continue;
-               free((char *)tab);
-               free(tabstr);
-               nextlibp(-1);
-               break;
-
-       /*
-        * Table of contents is out of date, so search
-        * as a normal library (but skip the __.SYMDEF file).
-        */
-       case 3:
-               error(-1,
-"warning: table of contents for archive is out of date; rerun ranlib(1)");
-               nloc = SARMAG;
-               do
-                       nloc += sizeof(archdr) +
-                           _round(atol(archdr.ar_size), sizeof(short));
-               while (step(nloc));
-               break;
-       }
-       close(infil);
-}
-
-/*
- * Advance to the next archive member, which
- * is at offset nloc in the archive.  If the member
- * is useful, record its location in the liblist structure
- * for use in pass2.  Mark the end of the archive in libilst with a -1.
- */
-int step(nloc) off_t nloc; {
-
-       dseek(&text, nloc, (long) sizeof archdr);
-       if (text.size <= 0) {
-               nextlibp(-1);
-               return (0);
-       }
-       getarhdr();
-       if (load1(1, nloc + (sizeof archdr)))
-               nextlibp(nloc);
-       return (1);
-}
-
-/*
- * Record the location of a useful archive member.
- * Recording -1 marks the end of files from an archive.
- * The liblist data structure is dynamically extended here.
- */
-void nextlibp(val) off_t val; {
-
-       if (clibseg->li_used == NROUT) {
-               if (++clibseg == &libseg[NSEG])
-                       error(1, "too many files loaded from libraries");
-               clibseg->li_first = (off_t *)malloc(NROUT * sizeof (off_t));
-               if (clibseg->li_first == 0)
-                       error(1, "ran out of memory (nextlibp)");
-       }
-       clibseg->li_first[clibseg->li_used++] = val;
-       if (val != -1 && Mflag)
-               printf("\t%s\n", archdr.ar_name);
-}
-
-/*
- * One pass over an archive with a table of contents.
- * Remember the number of symbols currently defined,
- * then call step on members which look promising (i.e.
- * that define a symbol which is currently externally undefined).
- * Indicate to our caller whether this process netted any more symbols.
- */
-int ldrand() {
-       register struct nlist *sp, **hp;
-       register struct ranlib *tp, *tplast;
-       off_t loc;
-       int nsymt = symx(nextsym);
-
-       tplast = &tab[tnum-1];
-       for (tp = tab; tp <= tplast; tp++) {
-               if ((hp = slookup(tp->ran_un.ran_name)) == 0 || *hp == 0)
-                       continue;
-               sp = *hp;
-               if (sp->n_type != N_EXT+N_UNDF)
-                       continue;
-               step(tp->ran_off);
-               loc = tp->ran_off;
-               while (tp < tplast && (tp+1)->ran_off == loc)
-                       tp++;
-       }
-       return (symx(nextsym) != nsymt);
-}
-
-/*
- * Examine a single file or archive member on pass 1.
- */
-int load1(libflg, loc) int libflg; off_t loc; {
-       register struct nlist *sp;
-       struct nlist *savnext;
-       int ndef, nlocal, type, size, nsymt;
-       register int i;
-       off_t maxoff;
-       struct stat stb;
-
-       readhdr(loc);
-       if (filhdr.a_syms == 0) {
-               if (filhdr.a_text+filhdr.a_data == 0)
-                       return (0);
-               error(1, "no namelist");
-       }
-       if (libflg)
-               maxoff = atol(archdr.ar_size);
-       else {
-               fstat(infil, &stb);
-               maxoff = stb.st_size;
-       }
-       if (N_STROFF(filhdr) + sizeof (off_t) >= maxoff)
-               error(1, "too small (old format .o?)");
-       ctrel = tsize; cdrel += dsize; cbrel += bsize;
-       ndef = 0;
-       nlocal = sizeof(cursym);
-       savnext = nextsym;
-       loc += N_SYMOFF(filhdr);
-       dseek(&text, loc, filhdr.a_syms);
-       dseek(&reloc, loc + filhdr.a_syms, sizeof(off_t));
-       mget(&size, sizeof (size), &reloc);
-       dseek(&reloc, loc + filhdr.a_syms+sizeof (off_t), size-sizeof (off_t));
-       curstr = (char *)malloc(size);
-       if (curstr == NULL)
-               error(1, "no space for string table");
-       mget(curstr+sizeof(off_t), size-sizeof(off_t), &reloc);
-       while (text.size > 0) {
-               mget(&cursym, sizeof(struct nlist), &text);
-               if (cursym.n_un.n_strx) {
-                       if (cursym.n_un.n_strx<sizeof(size) ||
-                           cursym.n_un.n_strx>=size)
-                               error(1, "bad string table index (pass 1)");
-                       cursym.n_un.n_name = curstr + cursym.n_un.n_strx;
-               }
-               type = cursym.n_type;
-               if ((type&N_EXT)==0) {
-                       if (Xflag==0 || cursym.n_un.n_name[0]!='L' ||
-                           type & N_STAB)
-                               nlocal += sizeof cursym;
-                       continue;
-               }
-               symreloc();
-               if (enter(lookup()))
-                       continue;
-               if ((sp = lastsym)->n_type != N_EXT+N_UNDF)
-                       continue;
-               if (cursym.n_type == N_EXT+N_UNDF) {
-                       if (cursym.n_value > sp->n_value)
-                               sp->n_value = cursym.n_value;
-                       continue;
-               }
-               if (sp->n_value != 0 && cursym.n_type == N_EXT+N_TEXT)
-                       continue;
-               ndef++;
-               sp->n_type = cursym.n_type;
-               sp->n_value = cursym.n_value;
-       }
-       if (libflg==0 || ndef) {
-               tsize += filhdr.a_text;
-               dsize += _round(filhdr.a_data, sizeof (long));
-               bsize += _round(filhdr.a_bss, sizeof (long));
-               ssize += nlocal;
-               trsize += filhdr.a_trsize;
-               drsize += filhdr.a_drsize;
-               if (funding)
-                       textbase = (*slookup("_end"))->n_value;
-               nsymt = symx(nextsym);
-               for (i = symx(savnext); i < nsymt; i++) {
-                       sp = xsym(i);
-                       sp->n_un.n_name = savestr(sp->n_un.n_name);
-               }
-               free(curstr);
-               return (1);
-       }
-       /*
-        * No symbols defined by this library member.
-        * Rip out the hash table entries and reset the symbol table.
-        */
-       symfree(savnext);
-       free(curstr);
-       return(0);
-}
-
-void middle() {
-       register struct nlist *sp;
-       long csize, t, corigin, ocsize;
-       int nund, rnd;
-       char s;
-       register int i;
-       int nsymt;
-
-       torigin = 0; 
-       dorigin = 0; 
-       borigin = 0;
-
-       p_etext = *slookup("_etext");
-       p_edata = *slookup("_edata");
-       p_end = *slookup("_end");
-       /*
-        * If there are any undefined symbols, save the relocation bits.
-        */
-       nsymt = symx(nextsym);
-       if (rflag==0) {
-               for (i = 0; i < nsymt; i++) {
-                       sp = xsym(i);
-                       if (sp->n_type==N_EXT+N_UNDF && sp->n_value==0 &&
-                           sp!=p_end && sp!=p_edata && sp!=p_etext) {
-                               rflag++;
-                               dflag = 0;
-                               break;
-                       }
-               }
-       }
-       if (rflag) 
-               sflag = zflag = 0;
-       /*
-        * Assign common locations.
-        */
-       csize = 0;
-       if (!Aflag)
-               addsym = symseg[0].sy_first;
-       database = _round(tsize+textbase,
-           (nflag||zflag? pagesize : sizeof (long)));
-       database += hsize;
-       if (dflag || rflag==0) {
-               ldrsym(p_etext, tsize, N_EXT+N_TEXT);
-               ldrsym(p_edata, dsize, N_EXT+N_DATA);
-               ldrsym(p_end, bsize, N_EXT+N_BSS);
-               for (i = symx(addsym); i < nsymt; i++) {
-                       sp = xsym(i);
-                       if ((s=sp->n_type)==N_EXT+N_UNDF &&
-                           (t = sp->n_value)!=0) {
-                               if (t >= sizeof (double))
-                                       rnd = sizeof (double);
-                               else if (t >= sizeof (long))
-                                       rnd = sizeof (long);
-                               else
-                                       rnd = sizeof (short);
-                               csize = _round(csize, rnd);
-                               sp->n_value = csize;
-                               sp->n_type = N_EXT+N_COMM;
-                               ocsize = csize; 
-                               csize += t;
-                       }
-                       if (s&N_EXT && (s&N_TYPE)==N_UNDF && s&N_STAB) {
-                               sp->n_value = ocsize;
-                               sp->n_type = (s&N_STAB) | (N_EXT+N_COMM);
-                       }
-               }
-       }
-       /*
-        * Now set symbols to their final value
-        */
-       csize = _round(csize, sizeof (long));
-       torigin = textbase;
-       dorigin = database;
-       corigin = dorigin + dsize;
-       borigin = corigin + csize;
-       nund = 0;
-       nsymt = symx(nextsym);
-       for (i = symx(addsym); i<nsymt; i++) {
-               sp = xsym(i);
-               switch (sp->n_type & (N_TYPE+N_EXT)) {
-
-               case N_EXT+N_UNDF:
-                       if (arflag == 0)
-                               errlev |= 01;
-                       if ((arflag==0 || dflag) && sp->n_value==0) {
-                               if (sp==p_end || sp==p_etext || sp==p_edata)
-                                       continue;
-                               if (nund==0)
-                                       printf("Undefined:\n");
-                               nund++;
-                               printf("%s\n", sp->n_un.n_name);
-                       }
-                       continue;
-               case N_EXT+N_ABS:
-               default:
-                       continue;
-               case N_EXT+N_TEXT:
-                       sp->n_value += torigin;
-                       continue;
-               case N_EXT+N_DATA:
-                       sp->n_value += dorigin;
-                       continue;
-               case N_EXT+N_BSS:
-                       sp->n_value += borigin;
-                       continue;
-               case N_EXT+N_COMM:
-                       sp->n_type = (sp->n_type & N_STAB) | (N_EXT+N_BSS);
-                       sp->n_value += corigin;
-                       continue;
-               }
-       }
-       if (sflag || xflag)
-               ssize = 0;
-       bsize += csize;
-       nsym = ssize / (sizeof cursym);
-       if (Aflag) {
-               fixspec(p_etext,torigin);
-               fixspec(p_edata,dorigin);
-               fixspec(p_end,borigin);
-       }
-}
-
-void fixspec(sym, offset) struct nlist *sym; long offset; {
-
-       if(symx(sym) < symx(addsym) && sym!=0)
-               sym->n_value += offset;
-}
-
-void ldrsym(sp, val, type) register struct nlist *sp; long val; int type; {
-
-       if (sp == 0)
-               return;
-       if ((sp->n_type != N_EXT+N_UNDF || sp->n_value) && !Aflag) {
-               printf("%s: ", sp->n_un.n_name);
-               error(0, "user attempt to redfine loader-defined symbol");
-               return;
-       }
-       sp->n_type = type;
-       sp->n_value = val;
-}
-
-off_t  wroff;
-struct biobuf toutb;
-
-void setupout() {
-       int bss;
-       struct stat stbuf;
-       extern char *sys_errlist[];
-       extern int errno;
-
-       ofilemode = 0777 & ~umask(0);
-       biofd = creat(ofilename, 0666 & ofilemode);
-       if (biofd < 0) {
-               filname = ofilename;            /* kludge */
-               archdr.ar_name[0] = 0;          /* kludge */
-               error(1, sys_errlist[errno]);   /* kludge */
-       }
-       fstat(biofd, &stbuf);           /* suppose file exists, wrong*/
-       if (stbuf.st_mode & 0111) {     /* mode, ld fails? */
-               chmod(ofilename, stbuf.st_mode & 0666);
-               ofilemode = stbuf.st_mode;
-       }
-       filhdr.a_magic = nflag ? NMAGIC : (zflag ? ZMAGIC : OMAGIC);
-       filhdr.a_text = nflag ? tsize :
-           _round(tsize, zflag ? pagesize : sizeof (long));
-       filhdr.a_data = zflag ? _round(dsize, pagesize) : dsize;
-       bss = bsize - (filhdr.a_data - dsize);
-       if (bss < 0)
-               bss = 0;
-       filhdr.a_bss = bss;
-       filhdr.a_trsize = trsize;
-       filhdr.a_drsize = drsize;
-       filhdr.a_syms = sflag? 0: (ssize + (sizeof cursym)*symx(nextsym));
-       if (entrypt) {
-               if (entrypt->n_type!=N_EXT+N_TEXT)
-                       error(0, "entry point not in text");
-               else
-                       filhdr.a_entry = entrypt->n_value;
-       } else
-               filhdr.a_entry = 0;
-       filhdr.a_trsize = (rflag ? trsize:0);
-       filhdr.a_drsize = (rflag ? drsize:0);
-       tout = &toutb;
-       bopen(tout, 0, stbuf.st_blksize);
-       bwrite(&filhdr, sizeof (filhdr), tout);
-       if (zflag)
-               bseek(tout, pagesize);
-       wroff = N_TXTOFF(filhdr) + filhdr.a_text;
-       outb(&dout, filhdr.a_data, stbuf.st_blksize);
-       if (rflag) {
-               outb(&trout, filhdr.a_trsize, stbuf.st_blksize);
-               outb(&drout, filhdr.a_drsize, stbuf.st_blksize);
-       }
-       if (sflag==0 || xflag==0) {
-               outb(&sout, filhdr.a_syms, stbuf.st_blksize);
-               wroff += sizeof (offset);
-               outb(&strout, 0, stbuf.st_blksize);
-       }
-}
-
-void outb(bp, inc, bufsize) register struct biobuf **bp; int inc; int bufsize; {
-
-       *bp = (struct biobuf *)malloc(sizeof (struct biobuf));
-       if (*bp == 0)
-               error(1, "ran out of memory (outb)");
-       bopen(*bp, wroff, bufsize);
-       wroff += inc;
-}
-
-void load2arg(acp) char *acp; {
-       register char *cp;
-       off_t loc;
-
-       cp = acp;
-       if (getfile(cp) == 0) {
-               while (*cp)
-                       cp++;
-               while (cp >= acp && *--cp != '/');
-               mkfsym(++cp);
-               load2(0L);
-       } else {        /* scan archive members referenced */
-               for (;;) {
-                       if (clibseg->li_used2 == clibseg->li_used) {
-                               if (clibseg->li_used < NROUT)
-                                       error(1, "libseg botch");
-                               clibseg++;
-                       }
-                       loc = clibseg->li_first[clibseg->li_used2++];
-                       if (loc == -1)
-                               break;
-                       dseek(&text, loc, (long)sizeof(archdr));
-                       getarhdr();
-                       mkfsym(archdr.ar_name);
-                       load2(loc + (long)sizeof(archdr));
-               }
-       }
-       close(infil);
-}
-
-void load2(loc) long loc; {
-       int size;
-       register struct nlist *sp;
-       register struct local *lp;
-       register int symno, i;
-       int type;
-
-       readhdr(loc);
-       if (!funding) {
-               ctrel = torigin;
-               cdrel += dorigin;
-               cbrel += borigin;
-       }
-       /*
-        * Reread the symbol table, recording the numbering
-        * of symbols for fixing external references.
-        */
-       for (i = 0; i < LHSIZ; i++)
-               lochash[i] = 0;
-       clocseg = locseg;
-       clocseg->lo_used = 0;
-       symno = -1;
-       loc += N_TXTOFF(filhdr);
-       dseek(&text, loc+filhdr.a_text+filhdr.a_data+
-               filhdr.a_trsize+filhdr.a_drsize+filhdr.a_syms, sizeof(off_t));
-       mget(&size, sizeof(size), &text);
-       dseek(&text, loc+filhdr.a_text+filhdr.a_data+
-               filhdr.a_trsize+filhdr.a_drsize+filhdr.a_syms+sizeof(off_t),
-               size - sizeof(off_t));
-       curstr = (char *)malloc(size);
-       if (curstr == NULL)
-               error(1, "out of space reading string table (pass 2)");
-       mget(curstr+sizeof(off_t), size-sizeof(off_t), &text);
-       dseek(&text, loc+filhdr.a_text+filhdr.a_data+
-               filhdr.a_trsize+filhdr.a_drsize, filhdr.a_syms);
-       while (text.size > 0) {
-               symno++;
-               mget(&cursym, sizeof(struct nlist), &text);
-               if (cursym.n_un.n_strx) {
-                       if (cursym.n_un.n_strx<sizeof(size) ||
-                           cursym.n_un.n_strx>=size)
-                               error(1, "bad string table index (pass 2)");
-                       cursym.n_un.n_name = curstr + cursym.n_un.n_strx;
-               }
-/* inline expansion of symreloc() */
-               switch (cursym.n_type & 017) {
-
-               case N_TEXT:
-               case N_EXT+N_TEXT:
-                       cursym.n_value += ctrel;
-                       break;
-               case N_DATA:
-               case N_EXT+N_DATA:
-                       cursym.n_value += cdrel;
-                       break;
-               case N_BSS:
-               case N_EXT+N_BSS:
-                       cursym.n_value += cbrel;
-                       break;
-               case N_EXT+N_UNDF:
-                       break;
-               default:
-                       if (cursym.n_type&N_EXT)
-                               cursym.n_type = N_EXT+N_ABS;
-               }
-/* end inline expansion of symreloc() */
-               type = cursym.n_type;
-               if (yflag && cursym.n_un.n_name)
-                       for (i = 0; i < yflag; i++)
-                               /* fast check for 2d character! */
-                               if (ytab[i][1] == cursym.n_un.n_name[1] &&
-                                   !strcmp(ytab[i], cursym.n_un.n_name)) {
-                                       tracesym();
-                                       break;
-                               }
-               if ((type&N_EXT) == 0) {
-                       if (!sflag&&!xflag&&
-                           (!Xflag||cursym.n_un.n_name[0]!='L'||type&N_STAB))
-                               symwrite(&cursym, sout);
-                       continue;
-               }
-               if (funding)
-                       continue;
-               if ((sp = *lookup()) == 0)
-                       error(1, "internal error: symbol not found");
-               if (cursym.n_type == N_EXT+N_UNDF) {
-                       if (clocseg->lo_used == NSYMPR) {
-                               if (++clocseg == &locseg[NSEG])
-                                       error(1, "local symbol overflow");
-                               clocseg->lo_used = 0;
-                       }
-                       if (clocseg->lo_first == 0) {
-                               clocseg->lo_first = (struct local *)
-                                   malloc(NSYMPR * sizeof (struct local));
-                               if (clocseg->lo_first == 0)
-                                       error(1, "out of memory (clocseg)");
-                       }
-                       lp = &clocseg->lo_first[clocseg->lo_used++];
-                       lp->l_index = symno;
-                       lp->l_symbol = sp;
-                       lp->l_link = lochash[symno % LHSIZ];
-                       lochash[symno % LHSIZ] = lp;
-                       continue;
-               }
-               if (cursym.n_type & N_STAB)
-                       continue;
-               if (cursym.n_type!=sp->n_type || cursym.n_value!=sp->n_value) {
-                       printf("%s: ", cursym.n_un.n_name);
-                       error(0, "multiply defined");
-               }
-       }
-       if (funding)
-               return;
-       dseek(&text, loc, filhdr.a_text);
-       dseek(&reloc, loc+filhdr.a_text+filhdr.a_data, filhdr.a_trsize);
-       load2td(ctrel, torigin - textbase, tout, trout);
-       dseek(&text, loc+filhdr.a_text, filhdr.a_data);
-       dseek(&reloc, loc+filhdr.a_text+filhdr.a_data+filhdr.a_trsize,
-           filhdr.a_drsize);
-       load2td(cdrel, dorigin - database, dout, drout);
-       while (filhdr.a_data & (sizeof(long)-1)) {
-               bputc(0, dout);
-               filhdr.a_data++;
-       }
-       torigin += filhdr.a_text;
-       dorigin += _round(filhdr.a_data, sizeof (long));
-       borigin += _round(filhdr.a_bss, sizeof (long));
-       free(curstr);
-}
-
-struct tynames {
-       int     ty_value;
-       char    *ty_name;
-} tynames[] = {
-       N_UNDF, "undefined",
-       N_ABS,  "absolute",
-       N_TEXT, "text",
-       N_DATA, "data",
-       N_BSS,  "bss",
-       N_COMM, "common",
-       0,      0,
-};
-
-void tracesym() {
-       register struct tynames *tp;
-
-       if (cursym.n_type & N_STAB)
-               return;
-       printf("%s", filname);
-       if (archdr.ar_name[0])
-               printf("(%s)", archdr.ar_name);
-       printf(": ");
-       if ((cursym.n_type&N_TYPE) == N_UNDF && cursym.n_value) {
-               printf("definition of common %s size %d\n",
-                   cursym.n_un.n_name, cursym.n_value);
-               return;
-       }
-       for (tp = tynames; tp->ty_name; tp++)
-               if (tp->ty_value == (cursym.n_type&N_TYPE))
-                       break;
-       printf((cursym.n_type&N_TYPE) ? "definition of" : "reference to");
-       if (cursym.n_type&N_EXT)
-               printf(" external");
-       if (tp->ty_name)
-               printf(" %s", tp->ty_name);
-       printf(" %s\n", cursym.n_un.n_name);
-}
-
-/*
- * This routine relocates the single text or data segment argument.
- * Offsets from external symbols are resolved by adding the value
- * of the external symbols.  Non-external reference are updated to account
- * for the relative motion of the segments (ctrel, cdrel, ...).  If
- * a relocation was pc-relative, then we update it to reflect the
- * change in the positioning of the segments by adding the displacement
- * of the referenced segment and subtracting the displacement of the
- * current segment (creloc).
- *
- * If we are saving the relocation information, then we increase
- * each relocation datum address by our base position in the new segment.
- */
-void load2td(creloc, position, b1, b2) long creloc; int position; struct biobuf *b1; struct biobuf *b2; {
-       register struct nlist *sp;
-       register struct local *lp;
-       long tw;
-       register struct relocation_info *rp, *rpend;
-       struct relocation_info *relp;
-       char *codep;
-       register char *cp;
-       int relsz, codesz;
-
-       relsz = reloc.size;
-       relp = (struct relocation_info *)malloc(relsz);
-       codesz = text.size;
-       codep = (char *)malloc(codesz);
-       if (relp == 0 || codep == 0)
-               error(1, "out of memory (load2td)");
-       mget(relp, relsz, &reloc);
-       rpend = &relp[relsz / sizeof (struct relocation_info)];
-       mget(codep, codesz, &text);
-       for (rp = relp; rp < rpend; rp++) {
-               cp = codep + rp->r_address;
-               /*
-                * Pick up previous value at location to be relocated.
-                */
-               switch (rp->r_length) {
-
-               case 0:         /* byte */
-                       tw = *cp;
-                       break;
-
-               case 1:         /* word */
-                       tw = *(short *)cp;
-                       break;
-
-               case 2:         /* long */
-                       tw = *(long *)cp;
-                       break;
-
-               default:
-                       error(1, "load2td botch: bad length");
-               }
-               /*
-                * If relative to an external which is defined,
-                * resolve to a simpler kind of reference in the
-                * result file.  If the external is undefined, just
-                * convert the symbol number to the number of the
-                * symbol in the result file and leave it undefined.
-                */
-               if (rp->r_extern) {
-                       /*
-                        * Search the hash table which maps local
-                        * symbol numbers to symbol tables entries
-                        * in the new a.out file.
-                        */
-                       lp = lochash[rp->r_symbolnum % LHSIZ];
-                       while (lp->l_index != rp->r_symbolnum) {
-                               lp = lp->l_link;
-                               if (lp == 0)
-                                       error(1, "local symbol botch");
-                       }
-                       sp = lp->l_symbol;
-                       if (sp->n_type == N_EXT+N_UNDF)
-                               rp->r_symbolnum = nsym+symx(sp);
-                       else {
-                               rp->r_symbolnum = sp->n_type & N_TYPE;
-                               tw += sp->n_value;
-                               rp->r_extern = 0;
-                       }
-               } else switch (rp->r_symbolnum & N_TYPE) {
-               /*
-                * Relocation is relative to the loaded position
-                * of another segment.  Update by the change in position
-                * of that segment.
-                */
-               case N_TEXT:
-                       tw += ctrel;
-                       break;
-               case N_DATA:
-                       tw += cdrel;
-                       break;
-               case N_BSS:
-                       tw += cbrel;
-                       break;
-               case N_ABS:
-                       break;
-               default:
-                       error(1, "relocation format botch (symbol type))");
-               }
-               /*
-                * Relocation is pc relative, so decrease the relocation
-                * by the amount the current segment is displaced.
-                * (E.g if we are a relative reference to a text location
-                * from data space, we added the increase in the text address
-                * above, and subtract the increase in our (data) address
-                * here, leaving the net change the relative change in the
-                * positioning of our text and data segments.)
-                */
-               if (rp->r_pcrel)
-                       tw -= creloc;
-               /*
-                * Put the value back in the segment,
-                * while checking for overflow.
-                */
-               switch (rp->r_length) {
-
-               case 0:         /* byte */
-                       if (tw < -128 || tw > 127)
-                               error(0, "byte displacement overflow");
-                       *cp = tw;
-                       break;
-               case 1:         /* word */
-                       if (tw < -32768 || tw > 32767)
-                               error(0, "word displacement overflow");
-                       *(short *)cp = tw;
-                       break;
-               case 2:         /* long */
-                       *(long *)cp = tw;
-                       break;
-               }
-               /*
-                * If we are saving relocation information,
-                * we must convert the address in the segment from
-                * the old .o file into an address in the segment in
-                * the new a.out, by adding the position of our
-                * segment in the new larger segment.
-                */
-               if (rflag)
-                       rp->r_address += position;
-       }
-       bwrite(codep, codesz, b1);
-       if (rflag)
-               bwrite(relp, relsz, b2);
-       free((char *)relp);
-       free(codep);
-}
-#endif
-
-void finishout() {
-#ifndef XIFY
-       register int i;
-       int nsymt;
-
-       if (sflag==0) {
-               nsymt = symx(nextsym);
-               for (i = 0; i < nsymt; i++)
-                       symwrite(xsym(i), sout);
-               bwrite(&offset, sizeof offset, sout);
-       }
-#endif
-       if (!ofilfnd) {
-               unlink("a.out");
-               if (link("l.out", "a.out") < 0)
-                       error(1, "cannot move l.out to a.out");
-               ofilename = "a.out";
-       }
-       delarg = errlev;
-       delexit();
-}
-
-#ifndef XIFY
-void mkfsym(s) char *s; {
-
-       if (sflag || xflag)
-               return;
-       cursym.n_un.n_name = s;
-       cursym.n_type = N_TEXT;
-       cursym.n_value = torigin;
-       symwrite(&cursym, sout);
-}
-
-void getarhdr() {
-       register char *cp;
-
-       mget(&archdr, sizeof archdr, &text);
-       for (cp=archdr.ar_name; cp<&archdr.ar_name[sizeof(archdr.ar_name)];)
-               if (*cp++ == ' ') {
-                       cp[-1] = 0;
-                       return;
-               }
-}
-
-void mget(_loc, n, sp) void *_loc; int n; register STREAM *sp; {
-#define loc (*(char **)&_loc)
-       register char *p;
-       register int take;
-
-top:
-       if (n == 0)
-               return;
-       if (sp->size && sp->nibuf) {
-               p = sp->ptr;
-               take = sp->size;
-               if (take > sp->nibuf)
-                       take = sp->nibuf;
-               if (take > n)
-                       take = n;
-               n -= take;
-               sp->size -= take;
-               sp->nibuf -= take;
-               sp->pos += take;
-               do
-                       *loc++ = *p++;
-               while (--take > 0);
-               sp->ptr = p;
-               goto top;
-       }
-       if (n > p_blksize) {
-               take = n - n % p_blksize;
-               lseek(infil, (sp->bno+1)<<p_blkshift, 0);
-               if (take > sp->size || read(infil, loc, take) != take)
-                       error(1, "premature EOF");
-               loc += take;
-               n -= take;
-               sp->size -= take;
-               sp->pos += take;
-               dseek(sp, (sp->bno+1+(take>>p_blkshift))<<p_blkshift, -1);
-               goto top;
-       }
-       *loc++ = get(sp);
-       --n;
-       goto top;
-#undef loc
-}
-
-void symwrite(sp, bp) struct nlist *sp; struct biobuf *bp; {
-       register int len;
-       register char *str;
-
-       str = sp->n_un.n_name;
-       if (str) {
-               sp->n_un.n_strx = offset;
-               len = strlen(str) + 1;
-               bwrite(str, len, strout);
-               offset += len;
-       }
-       bwrite(sp, sizeof (*sp), bp);
-       sp->n_un.n_name = str;
-}
-
-void dseek(sp, loc, s) register STREAM *sp; long loc; long s; {
-       register PAGE *p;
-       register b, o;
-       int n;
-
-       b = loc>>p_blkshift;
-       o = loc&p_blkmask;
-       if (o&01)
-               error(1, "loader error; odd offset");
-       --sp->pno->nuser;
-       if ((p = &page[0])->bno!=b && (p = &page[1])->bno!=b)
-               if (p->nuser==0 || (p = &page[0])->nuser==0) {
-                       if (page[0].nuser==0 && page[1].nuser==0)
-                               if (page[0].bno < page[1].bno)
-                                       p = &page[0];
-                       p->bno = b;
-                       lseek(infil, loc & ~(long)p_blkmask, 0);
-                       if ((n = read(infil, p->buff, p_blksize)) < 0)
-                               n = 0;
-                       p->nibuf = n;
-               } else
-                       error(1, "botch: no pages");
-       ++p->nuser;
-       sp->bno = b;
-       sp->pno = p;
-       if (s != -1) {sp->size = s; sp->pos = 0;}
-       sp->ptr = (char *)(p->buff + o);
-       if ((sp->nibuf = p->nibuf-o) <= 0)
-               sp->size = 0;
-}
-
-char get(asp) STREAM *asp; {
-       register STREAM *sp;
-
-       sp = asp;
-       if ((sp->nibuf -= sizeof(char)) < 0) {
-               dseek(sp, ((long)(sp->bno+1)<<p_blkshift), (long)-1);
-               sp->nibuf -= sizeof(char);
-       }
-       if ((sp->size -= sizeof(char)) <= 0) {
-               if (sp->size < 0)
-                       error(1, "premature EOF");
-               ++fpage.nuser;
-               --sp->pno->nuser;
-               sp->pno = (PAGE *) &fpage;
-       }
-       sp->pos += sizeof(char);
-       return(*sp->ptr++);
-}
-
-int getfile(acp) char *acp; {
-       register int c;
-       char arcmag[SARMAG+1];
-       struct stat stb;
-
-       archdr.ar_name[0] = '\0';
-       filname = acp;
-       if (filname[0] == '-' && filname[1] == 'l')
-               infil = libopen(filname + 2, O_RDONLY);
-       else
-               infil = open(filname, O_RDONLY);
-       if (infil < 0)
-               error(1, "cannot open");
-       fstat(infil, &stb);
-       page[0].bno = page[1].bno = -1;
-       page[0].nuser = page[1].nuser = 0;
-       c = stb.st_blksize;
-       if (c == 0 || (c & (c - 1)) != 0) {
-               /* use default size if not a power of two */
-               c = BLKSIZE;
-       }
-       if (p_blksize != c) {
-               p_blksize = c;
-               p_blkmask = c - 1;
-               for (p_blkshift = 0; c > 1 ; p_blkshift++)
-                       c >>= 1;
-               if (page[0].buff != NULL)
-                       free(page[0].buff);
-               page[0].buff = (char *)malloc(p_blksize);
-               if (page[0].buff == NULL)
-                       error(1, "ran out of memory (getfile)");
-               if (page[1].buff != NULL)
-                       free(page[1].buff);
-               page[1].buff = (char *)malloc(p_blksize);
-               if (page[1].buff == NULL)
-                       error(1, "ran out of memory (getfile)");
-       }
-       text.pno = reloc.pno = (PAGE *) &fpage;
-       fpage.nuser = 2;
-       dseek(&text, 0L, SARMAG);
-       if (text.size <= 0)
-               error(1, "premature EOF");
-       mget(arcmag, SARMAG, &text);
-       arcmag[SARMAG] = 0;
-       if (strcmp(arcmag, ARMAG))
-               return (0);
-       dseek(&text, SARMAG, sizeof archdr);
-       if (text.size <= 0)
-               return (1);
-       getarhdr();
-       if (strncmp(archdr.ar_name, "__.SYMDEF", sizeof(archdr.ar_name)) != 0)
-               return (1);
-       return (stb.st_mtime > atol(archdr.ar_date) ? 3 : 2);
-}
-
-/*
- * Search for a library with given name
- * using the directory search array.
- */
-int libopen(name, oflags) char *name; int oflags; {
-       register char *p, *cp;
-       register int i;
-       static char buf[MAXPATHLEN+1];
-       int fd = -1;
-
-       if (*name == '\0')                      /* backwards compat */
-               name = "a";
-       for (i = 0; i < ndir && fd == -1; i++) {
-               p = buf;
-               for (cp = dirs[i]; *cp; *p++ = *cp++)
-                       ;
-               *p++ = '/';
-               for (cp = "lib"; *cp; *p++ = *cp++)
-                       ;
-               for (cp = name; *cp; *p++ = *cp++)
-                       ;
-               cp = ".a";
-               while (*p++ = *cp++)
-                       ;
-               fd = open(buf, oflags);
-       }
-       if (fd != -1)
-               filname = buf;
-       return (fd);
-}
-
-struct nlist **lookup() {
-       register int sh; 
-       register struct nlist **hp;
-       register char *cp, *cp1;
-       register struct symseg *gp;
-       register int i;
-
-       sh = 0;
-       for (cp = cursym.n_un.n_name; *cp;)
-               sh = (sh<<1) + *cp++;
-       sh = (sh & 0x7fffffff) % HSIZE;
-       for (gp = symseg; gp < &symseg[NSEG]; gp++) {
-               if (gp->sy_first == 0) {
-                       gp->sy_first = (struct nlist *)
-                           calloc(NSYM, sizeof (struct nlist));
-                       gp->sy_hfirst = (struct nlist **)
-                           calloc(HSIZE, sizeof (struct nlist *));
-                       if (gp->sy_first == 0 || gp->sy_hfirst == 0)
-                               error(1, "ran out of space for symbol table");
-                       gp->sy_last = gp->sy_first + NSYM;
-                       gp->sy_hlast = gp->sy_hfirst + HSIZE;
-               }
-               if (gp > csymseg)
-                       csymseg = gp;
-               hp = gp->sy_hfirst + sh;
-               i = 1;
-               do {
-                       if (*hp == 0) {
-                               if (gp->sy_used == NSYM)
-                                       break;
-                               return (hp);
-                       }
-                       cp1 = (*hp)->n_un.n_name; 
-                       for (cp = cursym.n_un.n_name; *cp == *cp1++;)
-                               if (*cp++ == 0)
-                                       return (hp);
-                       hp += i;
-                       i += 2;
-                       if (hp >= gp->sy_hlast)
-                               hp -= HSIZE;
-               } while (i < HSIZE);
-               if (i > HSIZE)
-                       error(1, "hash table botch");
-       }
-       error(1, "symbol table overflow");
-       /*NOTREACHED*/
-#ifdef __GNUC__
-       return 0;
-#endif
-}
-
-void symfree(saved) struct nlist *saved; {
-       register struct symseg *gp;
-       register struct nlist *sp;
-
-       for (gp = csymseg; gp >= symseg; gp--, csymseg--) {
-               sp = gp->sy_first + gp->sy_used;
-               if (sp == saved) {
-                       nextsym = sp;
-                       return;
-               }
-               for (sp--; sp >= gp->sy_first; sp--) {
-                       gp->sy_hfirst[sp->n_hash] = 0;
-                       gp->sy_used--;
-                       if (sp == saved) {
-                               nextsym = sp;
-                               return;
-                       }
-               }
-       }
-       if (saved == 0)
-               return;
-       error(1, "symfree botch");
-}
-
-struct nlist **slookup(s) char *s; {
-
-       cursym.n_un.n_name = s;
-       cursym.n_type = N_EXT+N_UNDF;
-       cursym.n_value = 0;
-       return (lookup());
-}
-
-int enter(hp) register struct nlist **hp; {
-       register struct nlist *sp;
-
-       if (*hp==0) {
-               if (hp < csymseg->sy_hfirst || hp >= csymseg->sy_hlast)
-                       error(1, "enter botch");
-               *hp = lastsym = sp = csymseg->sy_first + csymseg->sy_used;
-               csymseg->sy_used++;
-               sp->n_un.n_name = cursym.n_un.n_name;
-               sp->n_type = cursym.n_type;
-               sp->n_hash = hp - csymseg->sy_hfirst;
-               sp->n_value = cursym.n_value;
-               nextsym = lastsym + 1;
-               return(1);
-       } else {
-               lastsym = *hp;
-               return(0);
-       }
-}
-
-int symx(sp) struct nlist *sp; {
-       register struct symseg *gp;
-
-       if (sp == 0)
-               return (0);
-       for (gp = csymseg; gp >= symseg; gp--)
-               /* <= is sloppy so nextsym will always work */
-               if (sp >= gp->sy_first && sp <= gp->sy_last)
-                       return ((gp - symseg) * NSYM + sp - gp->sy_first);
-       error(1, "symx botch");
-       /*NOTREACHED*/
-#ifdef __GNUC__
-       return -1;
-#endif
-}
-
-void symreloc() {
-       if(funding) return;
-       switch (cursym.n_type & 017) {
-
-       case N_TEXT:
-       case N_EXT+N_TEXT:
-               cursym.n_value += ctrel;
-               return;
-
-       case N_DATA:
-       case N_EXT+N_DATA:
-               cursym.n_value += cdrel;
-               return;
-
-       case N_BSS:
-       case N_EXT+N_BSS:
-               cursym.n_value += cbrel;
-               return;
-
-       case N_EXT+N_UNDF:
-               return;
-
-       default:
-               if (cursym.n_type&N_EXT)
-                       cursym.n_type = N_EXT+N_ABS;
-               return;
-       }
-}
-#endif
-
-void error(n, s) int n; char *s; {
-
-       if (errlev==0)
-               printf("ld:");
-       if (filname) {
-               printf("%s", filname);
-#ifndef XIFY
-               if (n != -1 && archdr.ar_name[0])
-                       printf("(%s)", archdr.ar_name);
-#endif
-               printf(": ");
-       }
-       printf("%s\n", s);
-       if (n == -1)
-               return;
-       if (n)
-               delexit();
-       errlev = 2;
-}
-
-#ifndef XIFY
-void readhdr(loc) off_t loc; {
-
-       dseek(&text, loc, (long)sizeof(filhdr));
-       mget(&filhdr, sizeof(filhdr), &text);
-       if (N_BADMAG(filhdr)) {
-               if (filhdr.a_magic == OARMAG)
-                       error(1, "old archive");
-               error(1, "bad magic number");
-       }
-       if (filhdr.a_text&01 || filhdr.a_data&01)
-               error(1, "text/data size odd");
-       if (filhdr.a_magic == NMAGIC || filhdr.a_magic == ZMAGIC) {
-               cdrel = -_round(filhdr.a_text, pagesize);
-               cbrel = cdrel - filhdr.a_data;
-       } else if (filhdr.a_magic == OMAGIC) {
-               cdrel = -filhdr.a_text;
-               cbrel = cdrel - filhdr.a_data;
-       } else
-               error(1, "bad format");
-}
-
-int _round(v, r) int v; u_long r; {
-
-       r--;
-       v += r;
-       v &= ~(long)r;
-       return(v);
-}
-#endif
-
-#define        NSAVETAB        8192
-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 = malloc(saveleft);
-               if (savetab == 0)
-                       error(1, "ran out of memory (savestr)");
-       }
-       strncpy(savetab, cp, len);
-       cp = savetab;
-       savetab += len;
-       saveleft -= len;
-       return (cp);
-}
-
-#ifdef XIFY
-char *strspl(left, right) char *left; char *right; {
-       char buf[BUFSIZ];
-
-       strcpy(buf, left);
-       strcat(buf, right);
-       return (savestr(buf));
-}
-#else
-void bopen(bp, off, bufsize) register struct biobuf *bp; int off; int bufsize; {
-
-       bp->b_ptr = bp->b_buf = malloc(bufsize);
-       if (bp->b_ptr == (char *)0)
-               error(1, "ran out of memory (bopen)");
-       bp->b_bufsize = bufsize;
-       bp->b_nleft = bufsize - (off % bufsize);
-       bp->b_off = off;
-       bp->b_link = biobufs;
-       biobufs = bp;
-}
-
-int    bwrerror;
-
-void bwrite(_p, cnt, bp) void *_p; register int cnt; register struct biobuf *bp; {
-#define p (*(char **)&_p)
-       register int put;
-       register char *to;
-
-top:
-       if (cnt == 0)
-               return;
-       if (bp->b_nleft) {
-               put = bp->b_nleft;
-               if (put > cnt)
-                       put = cnt;
-               bp->b_nleft -= put;
-               to = bp->b_ptr;
-               bcopy(p, to, put);
-               bp->b_ptr += put;
-               p += put;
-               cnt -= put;
-               goto top;
-       }
-       if (cnt >= bp->b_bufsize) {
-               if (bp->b_ptr != bp->b_buf)
-                       bflush1(bp);
-               put = cnt - cnt % bp->b_bufsize;
-               if (boffset != bp->b_off)
-                       lseek(biofd, bp->b_off, 0);
-               if (write(biofd, p, put) != put) {
-                       bwrerror = 1;
-                       error(1, "output write error");
-               }
-               bp->b_off += put;
-               boffset = bp->b_off;
-               p += put;
-               cnt -= put;
-               goto top;
-       }
-       bflush1(bp);
-       goto top;
-#undef p
-}
-
-void bflush() {
-       register struct biobuf *bp;
-
-       if (bwrerror)
-               return;
-       for (bp = biobufs; bp; bp = bp->b_link)
-               bflush1(bp);
-}
-
-void bflush1(bp) register struct biobuf *bp; {
-       register int cnt = bp->b_ptr - bp->b_buf;
-
-       if (cnt == 0)
-               return;
-       if (boffset != bp->b_off)
-               lseek(biofd, bp->b_off, 0);
-       if (write(biofd, bp->b_buf, cnt) != cnt) {
-               bwrerror = 1;
-               error(1, "output write error");
-       }
-       bp->b_off += cnt;
-       boffset = bp->b_off;
-       bp->b_ptr = bp->b_buf;
-       bp->b_nleft = bp->b_bufsize;
-}
-
-void bflushc(bp, c) register struct biobuf *bp; int c; {
-
-       bflush1(bp);
-       bputc(c, bp);
-}
-
-void bseek(bp, off) register struct biobuf *bp; register off_t off; {
-       bflush1(bp);
-       
-       bp->b_nleft = bp->b_bufsize - (off % bp->b_bufsize);
-       bp->b_off = off;
-}
-#endif
index 3f46cf2..0105d7b 100755 (executable)
@@ -22,5 +22,5 @@ typedef uint32_t x_unsigned_long;
 
 #endif
 EOF
-  "`dirname "$0"`/xifyfilt" <$1 2>$3 |sed -e 's/\(extern\|register\|static\) x_int\([   ]\+\(int\|long\|short\|unsigned\|x_Bignum\|x_Iptr\|x_YYSTYPE\|x_bytetoktype\|x_bool\|x_caddr_t\|x_chptr\|x_datum\|x_inttoktype\|x_lgtype\|x_off_t\|x_time_t\|x_u_char\|x_u_int\|x_u_short\|x_u_long\)\)/\1\2/g; s/va_arg(x_argp, x_\(unsigned_\)\?\(short\|int\|long\))/_va_arg_\1\2(x_argp)/g'
+  "`dirname "$0"`/xifyfilt" <$1 |sed -e 's/\(extern\|register\|static\) x_int\([        ]\+\(int\|long\|short\|unsigned\|x_Bignum\|x_Iptr\|x_YYSTYPE\|x_bytetoktype\|x_bool\|x_caddr_t\|x_chptr\|x_datum\|x_inttoktype\|x_lgtype\|x_off_t\|x_time_t\|x_u_char\|x_u_int\|x_u_short\|x_u_long\)\)/\1\2/g; s/va_arg(x_argp, x_\(unsigned_\)\?\(short\|int\|long\))/_va_arg_\1\2(x_argp)/g'
 ) >$2
similarity index 87%
rename from xify/xify.c
rename to xify/xifyfilt.c
index ee40136..2eb5ec9 100644 (file)
@@ -6,9 +6,9 @@
 
 char buf[1024];
 
-int main() {
-  char *p, *q;
-  int l, m;
+int main(int argc, char **argv) {
+  char *p, *q, *r;
+  int l, m, n;
   int e;
 
   while (fgets(buf, sizeof(buf), stdin)) {
@@ -20,12 +20,12 @@ int main() {
         ++l;
       q = p + l;
       m = 0;
-      if (isalpha(q[m])) {
+      if (isalpha(q[m]) || q[m] == '_') {
         ++m;
         while (isalnum(q[m]) || q[m] == '_')
           ++m;
-        l += m;
         if (m == 7 && memcmp(q, "include", 7) == 0) {
+          l += m;
           while (isblank(p[l]))
             ++l;
           if (p[l] == '<') {
@@ -54,6 +54,9 @@ int main() {
               (l != 0 || m != 8 || memcmp(p, "stdint.h", 8) != 0) &&
               (l != 0 || m != 9 || memcmp(p, "varargs.h", 9) != 0)
             ) {
+#if 1
+              fwrite(p, l, 1, stdout);
+#else
               fwrite(p - 1, l + m + 2, 1, stderr); /* include <> or "" */
               fputc('\n', stderr);
               if (l) {
@@ -61,6 +64,7 @@ int main() {
                 fwrite(p, l, 1, stdout);
                 fwrite(".xify/", 6, 1, stdout);
               }
+#endif
               fwrite("x_", 2, 1, stdout);
               p = q;
               l = m;
@@ -70,10 +74,50 @@ int main() {
             ++l;
           }
         }
+        else if (m == 6 && memcmp(q, "pragma", 6) == 0) {
+          while (isblank(q[m]))
+            ++m;
+          r = q + m;
+          n = 0;
+          if (isalpha(r[n]) || r[n] == '_') {
+            ++n;
+            while (isalnum(r[n]) || r[n] == '_')
+              ++n;
+            if (n == 7 && memcmp(r, "typedef", 7) == 0) {
+              while (isblank(r[n]))
+                ++n;
+              p = r + n;
+              l = 0;
+              while (isalpha(p[l]) || p[l] == '_') {
+                while (isalnum(p[l]) || p[l] == '_')
+                  ++l;
+ fprintf(stderr, "typedef name: ");
+ fwrite(p, l, 1, stderr);
+ putc('\n', stderr);
+                while (isblank(p[l]))
+                  ++l;
+                p += l;
+                l = 0;
+              }
+              if (p[l] != '\n') {
+                fprintf(stderr, "%s: warning: garbage after #pragma typedef: ", argv[0]);
+                while (p[l] && p[l] != '\n')
+                  putc(p[l++], stderr);
+                putc('\n', stderr);
+              }
+              continue;
+            }
+          }
+          fwrite(p, l, 1, stdout);
+          fputs(p + l + m, stdout);
+          continue;
+        }
+        else
+          l += m;
+        fwrite(p, l, 1, stdout);
+        p += l;
+        l = 0;
       }
-      fwrite(p, l, 1, stdout);
-      p += l;
-      l = 0;
     }
     while (p[l]) {
       if (isalpha(p[l]) || p[l] == '_') {
@@ -151,7 +195,7 @@ int main() {
             ++l;
           q = p + l;
           m = 0;
-          if (isalpha(q[m])) {
+          if (isalpha(q[m]) || q[m] == '_') {
             ++m;
             while (isalnum(q[m]) || q[m] == '_')
               ++m;
@@ -166,7 +210,7 @@ int main() {
             ++l;
           q = p + l;
           m = 0;
-          if (isalpha(q[m])) {
+          if (isalpha(q[m]) || q[m] == '_') {
             ++m;
             while (isalnum(q[m]) || q[m] == '_')
               ++m;
@@ -187,7 +231,7 @@ int main() {
                 ++l;
               q = p + l;
               m = 0;
-              if (isalpha(q[m])) {
+              if (isalpha(q[m]) || q[m] == '_') {
                 ++m;
                 while (isalnum(q[m]) || q[m] == '_')
                   ++m;