URI:
       tFighting the good fight. - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
   DIR commit 5a8e63b2f016735364d17866d5e2bcb35d20c78b
   DIR parent d51419bf4397cf13d0c50bf84c125477c6bed307
  HTML Author: rsc <devnull@localhost>
       Date:   Sun, 29 Feb 2004 22:10:26 +0000
       
       Fighting the good fight.
       
       Move libfmt, libutf into subdirectories of lib9.
       
       Add poll-based socket i/o to libthread, so that we can
       avoid using multiple procs when possible, thus removing
       dependence on crappy pthreads implementations.
       
       Convert samterm, acme to the single-proc libthread.
       
       Bring libcomplete, acme up-to-date w.r.t. Plan 9 distribution.
       
       Diffstat:
         M src/cmd/9pserve.c                   |     184 ++++++++++++-------------------
         M src/cmd/acme/acme.c                 |      62 ++++++++++++++++++++-----------
         M src/cmd/acme/dat.h                  |       5 ++++-
         M src/cmd/acme/ecmd.c                 |       7 +++++--
         M src/cmd/acme/exec.c                 |      74 ++++++++++++++++++++++++++-----
         M src/cmd/acme/fns.h                  |       5 +++--
         M src/cmd/acme/fsys.c                 |      11 +++++++----
         M src/cmd/acme/look.c                 |      76 ++++++++++---------------------
         M src/cmd/acme/mkfile                 |       4 +++-
         M src/cmd/acme/text.c                 |      50 ++++++++++++++++++++++++++-----
         M src/cmd/acme/time.c                 |       4 ++--
         M src/cmd/acme/util.c                 |     130 ++++++++++++++++++++-----------
         M src/cmd/acme/wind.c                 |       6 ++++--
         M src/cmd/acme/xfid.c                 |       5 ++++-
         M src/cmd/mkfile                      |       2 +-
         M src/cmd/samterm/plan9.c             |      15 +++++++++------
         M src/lib9/await.c                    |      21 +++++++++++++++++----
         M src/lib9/mkfile                     |      71 +++++++++++++++++++++++++++++++
         M src/lib9/nan.c                      |       2 +-
         M src/lib9/wait.c                     |      20 ++++++++++++++++----
         M src/libcomplete/complete.c          |      35 ++++++++++++++++++-------------
         M src/libdraw/x11-itrans.c            |       2 +-
         M src/libdraw/x11-keyboard.c          |       8 ++++++--
         M src/libdraw/x11-mouse.c             |       8 ++++++--
         D src/libfmt/LICENSE                  |      19 -------------------
         D src/libfmt/NOTICE                   |      19 -------------------
         D src/libfmt/README                   |      19 -------------------
         D src/libfmt/charstod.c               |      85 -------------------------------
         D src/libfmt/dofmt.c                  |     558 -------------------------------
         D src/libfmt/dorfmt.c                 |      61 -------------------------------
         D src/libfmt/errfmt.c                 |      28 ----------------------------
         D src/libfmt/fltfmt.c                 |     610 -------------------------------
         D src/libfmt/fmt.c                    |     221 -------------------------------
         D src/libfmt/fmtdef.h                 |     121 -------------------------------
         D src/libfmt/fmtfd.c                  |      46 -------------------------------
         D src/libfmt/fmtfdflush.c             |      33 -------------------------------
         D src/libfmt/fmtlock.c                |      28 ----------------------------
         D src/libfmt/fmtprint.c               |      47 -------------------------------
         D src/libfmt/fmtquote.c               |     262 -------------------------------
         D src/libfmt/fmtrune.c                |      40 -------------------------------
         D src/libfmt/fmtstr.c                 |      65 -------------------------------
         D src/libfmt/fmtvprint.c              |      46 -------------------------------
         D src/libfmt/fprint.c                 |      28 ----------------------------
         D src/libfmt/mkfile                   |      57 -------------------------------
         D src/libfmt/nan.h                    |       4 ----
         D src/libfmt/nan64.c                  |      76 -------------------------------
         D src/libfmt/pow10.c                  |      57 -------------------------------
         D src/libfmt/print.3                  |     469 -------------------------------
         D src/libfmt/print.c                  |      28 ----------------------------
         D src/libfmt/runefmtstr.c             |      65 -------------------------------
         D src/libfmt/runeseprint.c            |      30 ------------------------------
         D src/libfmt/runesmprint.c            |      30 ------------------------------
         D src/libfmt/runesnprint.c            |      31 -------------------------------
         D src/libfmt/runesprint.c             |      30 ------------------------------
         D src/libfmt/runevseprint.c           |      39 -------------------------------
         D src/libfmt/runevsmprint.c           |      37 -------------------------------
         D src/libfmt/runevsnprint.c           |      38 -------------------------------
         D src/libfmt/seprint.c                |      27 ---------------------------
         D src/libfmt/smprint.c                |      27 ---------------------------
         D src/libfmt/snprint.c                |      28 ----------------------------
         D src/libfmt/sprint.c                 |      27 ---------------------------
         D src/libfmt/strtod.c                 |     539 -------------------------------
         D src/libfmt/strtod.h                 |       4 ----
         D src/libfmt/test.c                   |      39 -------------------------------
         D src/libfmt/vfprint.c                |      31 -------------------------------
         D src/libfmt/vseprint.c               |      37 -------------------------------
         D src/libfmt/vsmprint.c               |      36 -------------------------------
         D src/libfmt/vsnprint.c               |      37 -------------------------------
         M src/libfs/fs.c                      |       7 ++++---
         M src/libfs/read.c                    |       5 +++++
         M src/libfs/write.c                   |      29 +++++++++++++++++++++++++++--
         M src/libplumb/mkfile                 |       1 +
         M src/libthread/channel.c             |      18 ++++++++++--------
         M src/libthread/create.c              |       4 ++++
         M src/libthread/exec-unix.c           |     139 ++++++++++---------------------
         M src/libthread/main.c                |       7 +++++++
         M src/libthread/mkfile                |       2 ++
         M src/libthread/proctab.c             |      19 +++++++++++++++++++
         M src/libthread/sched.c               |      34 +++++++++++++++++++++++++++++++
         M src/libthread/threadimpl.h          |       3 ++-
         D src/libutf/LICENSE                  |      13 -------------
         D src/libutf/NOTICE                   |      13 -------------
         D src/libutf/README                   |      13 -------------
         D src/libutf/lib9.h                   |      17 -----------------
         D src/libutf/mkfile                   |      31 -------------------------------
         D src/libutf/rune.c                   |     177 -------------------------------
         D src/libutf/runestrcat.c             |      25 -------------------------
         D src/libutf/runestrchr.c             |      35 -------------------------------
         D src/libutf/runestrcmp.c             |      35 -------------------------------
         D src/libutf/runestrcpy.c             |      28 ----------------------------
         D src/libutf/runestrdup.c             |      30 ------------------------------
         D src/libutf/runestrecpy.c            |      32 -------------------------------
         D src/libutf/runestrlen.c             |      24 ------------------------
         D src/libutf/runestrncat.c            |      32 -------------------------------
         D src/libutf/runestrncmp.c            |      37 -------------------------------
         D src/libutf/runestrncpy.c            |      33 -------------------------------
         D src/libutf/runestrrchr.c            |      30 ------------------------------
         D src/libutf/runestrstr.c             |      44 -------------------------------
         D src/libutf/runetype.c               |    1152 -------------------------------
         D src/libutf/utfdef.h                 |      14 --------------
         D src/libutf/utfecpy.c                |      36 -------------------------------
         D src/libutf/utflen.c                 |      38 -------------------------------
         D src/libutf/utfnlen.c                |      41 -------------------------------
         D src/libutf/utfrrune.c               |      46 -------------------------------
         D src/libutf/utfrune.c                |      45 -------------------------------
         D src/libutf/utfutf.c                 |      41 -------------------------------
         M src/mkfile                          |       6 ++----
       
       107 files changed, 665 insertions(+), 6637 deletions(-)
       ---
   DIR diff --git a/src/cmd/9pserve.c b/src/cmd/9pserve.c
       t@@ -76,6 +76,7 @@ int isunix;
        Queue *outq;
        Queue *inq;
        int verbose;
       +int msize = 8192;
        
        void *gethash(Hash**, uint);
        int puthash(Hash**, uint, void*);
       t@@ -94,7 +95,6 @@ void *erealloc(void*, int);
        Queue *qalloc(void);
        int sendq(Queue*, void*);
        void *recvq(Queue*);
       -void pollthread(void*);
        void connthread(void*);
        void connoutthread(void*);
        void listenthread(void*);
       t@@ -125,7 +125,6 @@ threadmain(int argc, char **argv)
        {
                char *file;
        
       -        if(verbose) fprint(2, "9pserve running\n");
                ARGBEGIN{
                default:
                        usage();
       t@@ -143,6 +142,7 @@ threadmain(int argc, char **argv)
                        break;
                }ARGEND
        
       +        if(verbose) fprint(2, "9pserve running\n");
                if(argc != 1)
                        usage();
                addr = argv[0];
       t@@ -150,8 +150,19 @@ threadmain(int argc, char **argv)
                if((afd = announce(addr, adir)) < 0)
                        sysfatal("announce %s: %r", addr);
        
       -        proccreate(mainproc, nil, STACK);
       -        threadexits(0);
       +        if(verbose) fprint(2, "9pserve forking\n");
       +        switch(fork()){
       +        case -1:
       +                sysfatal("fork: %r");
       +        case 0:
       +                if(verbose) fprint(2, "running mainproc\n");
       +                mainproc(nil);
       +                if(verbose) fprint(2, "mainproc finished\n");
       +                _exits(0);
       +        default:
       +                if(verbose) fprint(2, "9pserve exiting\n");
       +                _exits(0);
       +        }
        }
        
        void
       t@@ -161,8 +172,6 @@ mainproc(void *v)
                Fcall f;
                USED(v);
        
       -        yield();        /* let threadmain exit */
       -
                atnotify(ignorepipe, 1);
                fmtinstall('D', dirfmt);
                fmtinstall('M', dirmodefmt);
       t@@ -174,7 +183,7 @@ mainproc(void *v)
        
                f.type = Tversion;
                f.version = "9P2000";
       -        f.msize = 8192;
       +        f.msize = msize;
                f.tag = NOTAG;
                n = convS2M(&f, vbuf, sizeof vbuf);
                if(verbose > 1) fprint(2, "* <- %F\n", &f);
       t@@ -182,12 +191,13 @@ mainproc(void *v)
                n = read9pmsg(0, vbuf, sizeof vbuf);
                if(convM2S(vbuf, n, &f) != n)
                        sysfatal("convM2S failure");
       +        if(f.msize < msize)
       +                msize = f.msize;
                if(verbose > 1) fprint(2, "* -> %F\n", &f);
        
                threadcreate(inputthread, nil, STACK);
                threadcreate(outputthread, nil, STACK);
                threadcreate(listenthread, nil, STACK);
       -        threadcreateidle(pollthread, nil, STACK);
                threadexits(0);
        }
        
       t@@ -296,8 +306,8 @@ connthread(void *arg)
                        case Tversion:
                                m->rx.tag = m->tx.tag;
                                m->rx.msize = m->tx.msize;
       -                        if(m->rx.msize > 8192)
       -                                m->rx.msize = 8192;
       +                        if(m->rx.msize > msize)
       +                                m->rx.msize = msize;
                                m->rx.version = "9P2000";
                                m->rx.type = Rversion;
                                send9pmsg(m);
       t@@ -480,7 +490,7 @@ openfdthread(void *v)
                                m->internal = 1;
                                m->c = c;
                                m->tx.type = Tread;
       -                        m->tx.count = 8192;
       +                        m->tx.count = msize - IOHDRSZ;
                                m->tx.fid = fid->fid;
                                m->tx.tag = m->tag;
                                m->tx.offset = tot;
       t@@ -506,7 +516,10 @@ openfdthread(void *v)
                }else{
                        for(;;){
                                if(verbose) fprint(2, "twrite...");
       -                        if((n=ioread(io, c->fd, buf, sizeof buf)) <= 0){
       +                        n = sizeof buf;
       +                        if(n > msize)
       +                                n = msize;
       +                        if((n=ioread(io, c->fd, buf, n)) <= 0){
                                        if(n < 0)
                                                fprint(2, "pipe read error: %r\n");
                                        m = nil;
       t@@ -1122,106 +1135,23 @@ struct Ioproc
                int index;
        };
        
       -static struct Ioproc **pio;
       -static struct pollfd *pfd;
       -static int npfd;
       -static struct Ioproc *iofree;
       -
        Ioproc*
        ioproc(void)
        {
       -        Ioproc *io;
       -
       -        if(iofree == nil){
       -                pfd = erealloc(pfd, (npfd+1)*sizeof(pfd[0]));
       -                pfd[npfd].events = 0;
       -                pfd[npfd].fd = -1;
       -                iofree = emalloc(sizeof(Ioproc));
       -                iofree->index = npfd;
       -                iofree->c = chancreate(sizeof(ulong), 1);
       -                pio = erealloc(pio, (npfd+1)*sizeof(pio[0]));
       -                pio[npfd] = iofree;
       -                npfd++;
       -        }
       -        io = iofree;
       -        iofree = io->next;
       -        return io;
       +        return (Ioproc*)-1;
        }
        
        void
        closeioproc(Ioproc *io)
        {
       -        io->next = iofree;
       -        iofree = io;
       -}
       -
       -void
       -pollthread(void *v)
       -{
       -        int i, n;
       -
       -        for(;;){
       -                yield();
       -                for(i=0; i<npfd; i++)
       -                        pfd[i].revents = 0;
       -                if(verbose){
       -                        fprint(2, "poll:");
       -                        for(i=0; i<npfd; i++)
       -                                if(pfd[i].events)
       -                                        fprint(2, " %d%c", pfd[i].fd, pfd[i].events==POLLIN ? 'r' : pfd[i].events==POLLOUT ? 'w' : '?');
       -                        fprint(2, "\n");
       -                }
       -                n = poll(pfd, npfd, -1);
       -                if(n <= 0)
       -                        continue;
       -                for(i=0; i<npfd; i++)
       -                        if(pfd[i].fd != -1 && pfd[i].revents){
       -                                pfd[i].fd = -1;
       -                                pfd[i].events = 0;
       -                                pfd[i].revents = 0;
       -                                nbsendul(pio[i]->c, 1);
       -                        }
       -        }        
       -}
       -
       -static void
       -noblock(int fd)
       -{
       -        fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0)|O_NONBLOCK);
       -}
       -
       -static void
       -xwait(Ioproc *io, int fd, int e)
       -{
       -        if(verbose) fprint(2, "wait for %d%c\n", fd, e==POLLIN ? 'r' : 'w');
       -        pfd[io->index].fd = fd;
       -        pfd[io->index].events = e;
       -        recvul(io->c);
       -        if(verbose) fprint(2, "got %d\n", fd);
       -}
       -
       -static void
       -rwait(Ioproc *io, int fd)
       -{
       -        xwait(io, fd, POLLIN);
       -}
       -
       -static void
       -wwait(Ioproc *io, int fd)
       -{
       -        xwait(io, fd, POLLOUT);
        }
        
        long
        ioread(Ioproc *io, int fd, void *v, long n)
        {
       -        long r;
                USED(io);
        
       -        noblock(fd);
       -        while((r=read(fd, v, n)) < 0 && errno == EWOULDBLOCK)
       -                rwait(io, fd);
       -        return r;
       +        return threadread(fd, v, n);
        }
        
        long
       t@@ -1247,9 +1177,16 @@ iorecvfd(Ioproc *io, int fd)
        {
                int r;
        
       -        noblock(fd);
       -        while((r=recvfd(fd)) < 0 && errno == EWOULDBLOCK)
       -                rwait(io, fd);
       +        threadfdnoblock(fd);
       +        while((r=recvfd(fd)) < 0){
       +                if(errno == EINTR)
       +                        continue;
       +                if(errno == EWOULDBLOCK || errno == EAGAIN){
       +                        threadfdwait(fd, 'r');
       +                        continue;
       +                }
       +                break;
       +        }
                return r;
        }
        
       t@@ -1258,23 +1195,24 @@ iosendfd(Ioproc *io, int s, int fd)
        {
                int r;
        
       -        noblock(s);
       -        while((r=sendfd(s, fd)) < 0 && errno == EWOULDBLOCK)
       -                wwait(io, s);
       -if(r < 0) fprint(2, "sent %d, %d\n", s, fd);
       +        threadfdnoblock(s);
       +        while((r=sendfd(s, fd)) < 0){
       +                if(errno == EINTR)
       +                        continue;
       +                if(errno == EWOULDBLOCK || errno == EAGAIN){
       +                        threadfdwait(fd, 'w');
       +                        continue;
       +                }
       +                break;
       +        }
                return r;
        }
        
        static long
        _iowrite(Ioproc *io, int fd, void *v, long n)
        {
       -        long r;
                USED(io);
       -
       -        noblock(fd);
       -        while((r=write(fd, v, n)) < 0 && errno == EWOULDBLOCK)
       -                wwait(io, fd);
       -        return r;
       +        return threadwrite(fd, v, n);
        }
        
        long
       t@@ -1305,9 +1243,16 @@ iolisten(Ioproc *io, char *dir, char *ndir)
        
                if((fd = _p9netfd(dir)) < 0)
                        return -1;
       -        noblock(fd);
       -        while((r=listen(dir, ndir)) < 0 && errno == EWOULDBLOCK)
       -                rwait(io, fd);
       +        threadfdnoblock(fd);
       +        while((r=listen(dir, ndir)) < 0){
       +                if(errno == EINTR)
       +                        continue;
       +                if(errno == EWOULDBLOCK || errno == EAGAIN){
       +                        threadfdwait(fd, 'r');
       +                        continue;
       +                }
       +                break;
       +        }
                return r;
        }
        
       t@@ -1317,9 +1262,16 @@ ioaccept(Ioproc *io, int fd, char *dir)
                int r;
                USED(io);
        
       -        noblock(fd);
       -        while((r=accept(fd, dir)) < 0 && errno == EWOULDBLOCK)
       -                rwait(io, fd);
       +        threadfdnoblock(fd);
       +        while((r=accept(fd, dir)) < 0){
       +                if(errno == EINTR)
       +                        continue;
       +                if(errno == EWOULDBLOCK || errno == EAGAIN){
       +                        threadfdwait(fd, 'r');
       +                        continue;
       +                }
       +                break;
       +        }
                return r;
        }
        
   DIR diff --git a/src/cmd/acme/acme.c b/src/cmd/acme/acme.c
       t@@ -59,7 +59,6 @@ threadmain(int argc, char *argv[])
        {
                int i;
                char *p, *loadfile;
       -        char buf[256];
                Column *c;
                int ncol;
                Display *d;
       t@@ -70,6 +69,9 @@ threadmain(int argc, char *argv[])
        
                loadfile = nil;
                ARGBEGIN{
       +        case 'a':
       +                globalautoindent = TRUE;
       +                break;
                case 'b':
                        bartflag = TRUE;
                        break;
       t@@ -98,7 +100,7 @@ threadmain(int argc, char *argv[])
                        break;
                default:
                Usage:
       -                fprint(2, "usage: acme -c ncol -f fontname -F fixedwidthfontname -l loadfile\n");
       +                fprint(2, "usage: acme -a -c ncol -f fontname -F fixedwidthfontname -l loadfile\n");
                        exits("usage");
                }ARGEND
        
       t@@ -183,7 +185,7 @@ threadmain(int argc, char *argv[])
                        fprint(2, "acme: can't initialize plumber: %r\n");
                else{
                        cplumb = chancreate(sizeof(Plumbmsg*), 0);
       -                proccreate(plumbproc, nil, STACK);
       +                threadcreate(plumbproc, nil, STACK);
                }
                plumbsendfd = plumbopen("send", OWRITE|OCEXEC);
        
       t@@ -315,7 +317,7 @@ acmeerrorproc(void *v)
                USED(v);
                threadsetname("acmeerrorproc");
                buf = emalloc(8192+1);
       -        while((n=read(errorfd, buf, 8192)) >= 0){
       +        while((n=threadread(errorfd, buf, 8192)) >= 0){
                        buf[n] = '\0';
                        sendp(cerr, estrdup(buf));
                }
       t@@ -324,8 +326,7 @@ acmeerrorproc(void *v)
        void
        acmeerrorinit(void)
        {
       -        int fd, pfd[2];
       -        char buf[64];
       +        int pfd[2];
        
                if(pipe(pfd) < 0)
                        error("can't create pipe");
       t@@ -351,7 +352,7 @@ acmeerrorinit(void)
                errorfd = pfd[1];
                if(errorfd < 0)
                        error("can't re-open acmeerror file");
       -        proccreate(acmeerrorproc, nil, STACK);
       +        threadcreate(acmeerrorproc, nil, STACK);
        }
        
        void
       t@@ -362,7 +363,7 @@ plumbproc(void *v)
                USED(v);
                threadsetname("plumbproc");
                for(;;){
       -                m = plumbrecv(plumbeditfd);
       +                m = threadplumbrecv(plumbeditfd);
                        if(m == nil)
                                threadexits(nil);
                        sendp(cplumb, m);
       t@@ -399,6 +400,7 @@ keyboardthread(void *v)
                                        winlock(t->w, 'K');
                                        wincommit(t->w, t);
                                        winunlock(t->w);
       +                                flushwarnings(1);
                                        flushimage(display, 1);
                                }
                                alts[KTimer].c = nil;
       t@@ -425,6 +427,7 @@ keyboardthread(void *v)
                                }
                                if(nbrecv(keyboardctl->c, &r) > 0)
                                        goto casekeyboard;
       +                        flushwarnings(1);
                                flushimage(display, 1);
                                break;
                        }
       t@@ -467,6 +470,7 @@ mousethread(void *v)
                                draw(screen, screen->r, display->white, nil, ZP);
                                scrlresize();
                                rowresize(&row, screen->clipr);
       +                        flushwarnings(1);
                                flushimage(display, 1);
                                break;
                        case MPlumb:
       t@@ -477,6 +481,7 @@ mousethread(void *v)
                                        else if(strcmp(act, "showdata")==0)
                                                plumbshow(pm);
                                }
       +                        flushwarnings(1);
                                flushimage(display, 1);
                                plumbfree(pm);
                                break;
       t@@ -562,6 +567,7 @@ mousethread(void *v)
                                        goto Continue;
                                }
            Continue:
       +                        flushwarnings(0);
                                flushimage(display, 1);
                                qunlock(&row.lk);
                                break;
       t@@ -916,36 +922,48 @@ iconinit(void)
        void
        acmeputsnarf(void)
        {
       -        int fd, i, n;
       +        int i, n;
       +        Fmt f;
       +        char *s;
        
       -        if(snarffd<0 || snarfbuf.nc==0)
       +        if(snarfbuf.nc==0)
                        return;
                if(snarfbuf.nc > MAXSNARF)
                        return;
       -        fd = open("/dev/snarf", OWRITE);
       -        if(fd < 0)
       -                return;
       +
       +        fmtstrinit(&f);
                for(i=0; i<snarfbuf.nc; i+=n){
                        n = snarfbuf.nc-i;
                        if(n >= NSnarf)
                                n = NSnarf;
                        bufread(&snarfbuf, i, snarfrune, n);
       -                if(fprint(fd, "%.*S", n, snarfrune) < 0)
       +                if(fmtprint(&f, "%.*S", n, snarfrune) < 0)
                                break;
                }
       -        close(fd);
       +        s = fmtstrflush(&f);
       +        if(s && s[0])
       +                putsnarf(s);
       +        free(s);
        }
        
        void
       -acmegetsnarf()
       +acmegetsnarf(void)
        {
       -        int nulls;
       +        char *s;
       +        int nb, nr, nulls, len;
       +        Rune *r;
        
       -        if(snarfbuf.nc > MAXSNARF)
       -                return;
       -        if(snarffd < 0)
       +        s = getsnarf();
       +        if(s == nil || s[0]==0){
       +                free(s);
                        return;
       -        seek(snarffd, 0, 0);
       +        }
       +
       +        len = strlen(s);
       +        r = runemalloc(len+1);
       +        cvttorunes(s, len, r, &nb, &nr, &nulls);
                bufreset(&snarfbuf);
       -        bufload(&snarfbuf, 0, snarffd, &nulls);
       +        bufinsert(&snarfbuf, 0, r, nr);
       +        free(r);
       +        free(s);
        }
   DIR diff --git a/src/cmd/acme/dat.h b/src/cmd/acme/dat.h
       t@@ -232,6 +232,7 @@ struct Window
                uchar        isscratch;
                uchar        filemenu;
                uchar        dirty;
       +        uchar        autoindent;
                int                id;
                Range        addr;
                Range        limit;
       t@@ -486,6 +487,7 @@ enum        /* editing */
                Collecting,
        };
        
       +uint                globalincref;
        uint                seq;
        uint                maxtab;        /* size of a tab, in units of the '0' character */
        
       t@@ -524,10 +526,11 @@ Image                *tagcols[NCOL];
        Image                *textcols[NCOL];
        int                        plumbsendfd;
        int                        plumbeditfd;
       -extern char                wdir[];
       +extern char                wdir[]; /* must use extern because no dimension given */
        int                        editing;
        int                        erroutfd;
        int                        messagesize;                /* negotiated in 9P version setup */
       +int                        globalautoindent;
        
        Channel        *ckeyboard;        /* chan(Rune)[10] */
        Channel        *cplumb;                /* chan(Plumbmsg*) */
   DIR diff --git a/src/cmd/acme/ecmd.c b/src/cmd/acme/ecmd.c
       t@@ -596,7 +596,7 @@ runpipe(Text *t, int cmd, Rune *cr, int ncr, int state)
        
                r = skipbl(cr, ncr, &n);
                if(n == 0)
       -                editerror("no command specified for >");
       +                editerror("no command specified for %c", cmd);
                w = nil;
                if(state == Inserting){
                        w = t->w;
       t@@ -949,12 +949,15 @@ filelooper(Cmd *cp, int XY)
                /*
                 * add a ref to all windows to keep safe windows accessed by X
                 * that would not otherwise have a ref to hold them up during
       -         * the shenanigans.
       +         * the shenanigans.  note this with globalincref so that any
       +         * newly created windows start with an extra reference.
                 */
                allwindows(alllocker, (void*)1);
       +        globalincref = 1;
                for(i=0; i<loopstruct.nw; i++)
                        cmdexec(&loopstruct.w[i]->body, cp->u.cmd);
                allwindows(alllocker, (void*)0);
       +        globalincref = 0;
                free(loopstruct.w);
                loopstruct.w = nil;
        
   DIR diff --git a/src/cmd/acme/exec.c b/src/cmd/acme/exec.c
       t@@ -462,7 +462,7 @@ getname(Text *t, Text *argt, Rune *arg, int narg, int isput)
                        dir.nr = 0;
                        if(n>0 && arg[0]!='/'){
                                dir = dirname(t, nil, 0);
       -                        if(n==1 && dir.r[0]=='.'){        /* sigh */
       +                        if(dir.nr==1 && dir.r[0]=='.'){        /* sigh */
                                        free(dir.r);
                                        dir.r = nil;
                                        dir.nr = 0;
       t@@ -606,15 +606,15 @@ putfile(File *f, int q0, int q1, Rune *namer, int nname)
                                f->qidpath = d->qid.path;
                                f->mtime = d->mtime;
                                if(f->unread)
       -                                warningew(w, nil, "%s not written; file already exists\n", name);
       +                                warning(nil, "%s not written; file already exists\n", name);
                                else
       -                                warningew(w, nil, "%s modified%s%s since last read\n", name, d->muid[0]?" by ":"", d->muid);
       +                                warning(nil, "%s modified%s%s since last read\n", name, d->muid[0]?" by ":"", d->muid);
                                goto Rescue1;
                        }
                }
                fd = create(name, OWRITE, 0666);
                if(fd < 0){
       -                warningew(w, nil, "can't create file %s: %r\n", name);
       +                warning(nil, "can't create file %s: %r\n", name);
                        goto Rescue1;
                }
                r = fbufalloc();
       t@@ -623,7 +623,7 @@ putfile(File *f, int q0, int q1, Rune *namer, int nname)
                d = dirfstat(fd);
                isapp = (d!=nil && d->length>0 && (d->qid.type&QTAPPEND));
                if(isapp){
       -                warningew(w, nil, "%s not written; file is append only\n", name);
       +                warning(nil, "%s not written; file is append only\n", name);
                        goto Rescue2;
                }
        
       t@@ -634,7 +634,7 @@ putfile(File *f, int q0, int q1, Rune *namer, int nname)
                        bufread(&f->b, q, r, n);
                        m = snprint(s, BUFSIZE+1, "%.*S", n, r);
                        if(write(fd, s, m) != m){
       -                        warningew(w, nil, "can't write file %s: %r\n", name);
       +                        warning(nil, "can't write file %s: %r\n", name);
                                goto Rescue2;
                        }
                }
       t@@ -701,7 +701,7 @@ put(Text *et, Text *_0, Text *argt, int _1, int _2, Rune *arg, int narg)
                f = w->body.file;
                name = getname(&w->body, argt, arg, narg, TRUE);
                if(name == nil){
       -                warningew(w, nil, "no file name\n");
       +                warning(nil, "no file name\n");
                        return;
                }
                namer = bytetorune(name, &nname);
       t@@ -1163,6 +1163,58 @@ incl(Text *et, Text *_0, Text *argt, int _1, int _2, Rune *arg, int narg)
                }
        }
        
       +static Rune LON[] = { 'O', 'N', 0 };
       +static Rune LOFF[] = { 'O', 'F', 'F', 0 };
       +static Rune Lon[] = { 'o', 'n', 0 };
       +
       +static int
       +indentval(Rune *s, int n)
       +{
       +        if(n < 2)
       +                return -1;
       +        if(runestrncmp(s, LON, n) == 0){
       +                globalautoindent = TRUE;
       +                warning(nil, "Indent ON\n");
       +                return -2;
       +        }
       +        if(runestrncmp(s, LOFF, n) == 0){
       +                globalautoindent = FALSE;
       +                warning(nil, "Indent OFF\n");
       +                return -2;
       +        }
       +        return runestrncmp(s, Lon, n) == 0;
       +}
       +
       +void
       +indent(Text *et, Text *_0, Text *argt, int _1, int _2, Rune *arg, int narg)
       +{
       +        Rune *a, *r;
       +        Window *w;
       +        int na, len, autoindent;
       +
       +        USED(_0);
       +        USED(_1);
       +        USED(_2);
       +
       +        if(et==nil || et->w==nil)
       +                return;
       +        w = et->w;
       +        autoindent = -1;
       +        getarg(argt, FALSE, TRUE, &r, &len);
       +        if(r!=nil && len>0)
       +                autoindent = indentval(r, len);
       +        else{
       +                a = findbl(arg, narg, &na);
       +                if(a != arg)
       +                        autoindent = indentval(arg, narg-na);
       +        }
       +        if(autoindent >= 0)
       +                w->autoindent = autoindent;
       +        if(autoindent != 2)
       +                warning(nil, "%.*S: Indent %s\n", w->body.file->nname, w->body.file->name,
       +                        w->autoindent ? "on" : "off");
       +}
       +
        void
        tab(Text *et, Text *_0, Text *argt, int _1, int _2, Rune *arg, int narg)
        {
       t@@ -1375,7 +1427,7 @@ runproc(void *argvp)
                av[ac++] = arg;
                av[ac] = nil;
                c->av = av;
       -        procexec(cpid, sfd, av[0], av);
       +        threadexec(cpid, sfd, av[0], av);
        /* libthread uses execvp so no need to do this */
        #if 0
                e = av[0];
       t@@ -1419,10 +1471,10 @@ Hard:
                                c->text = news;
                        }
                }
       -        procexecl(cpid, sfd, "rc", "rc", "-c", t, nil);
       +        threadexecl(cpid, sfd, "rc", "rc", "-c", t, nil);
        
           Fail:
       -        /* procexec hasn't happened, so send a zero */
       +        /* threadexec hasn't happened, so send a zero */
                close(sfd[0]);
                close(sfd[1]);
                if(sfd[2] != sfd[1])
       t@@ -1482,7 +1534,7 @@ run(Window *win, char *s, Rune *rdir, int ndir, int newns, char *argaddr, char *
                arg[7] = c;
                arg[8] = cpid;
                arg[9] = (void*)iseditcmd;
       -        proccreate(runproc, arg, STACK);
       +        threadcreate(runproc, arg, STACK);
                /* mustn't block here because must be ready to answer mount() call in run() */
                arg = emalloc(2*sizeof(void*));
                arg[0] = c;
   DIR diff --git a/src/cmd/acme/fns.h b/src/cmd/acme/fns.h
       t@@ -27,7 +27,7 @@ void        clearmouse(void);
        void        allwindows(void(*)(Window*, void*), void*);
        uint loadfile(int, uint, int*, int(*)(void*, uint, Rune*, int), void*);
        
       -Window*        errorwin(Mntdir*, int, Window*);
       +Window*        errorwin(Mntdir*, int);
        Runestr cleanrname(Runestr);
        void        run(Window*, char*, Rune*, int, int, char*, char*, int);
        void fsysclose(void);
       t@@ -85,7 +85,8 @@ Window*        makenewwindow(Text *t);
        int        expand(Text*, uint, uint, Expand*);
        Rune*        skipbl(Rune*, int, int*);
        Rune*        findbl(Rune*, int, int*);
       -char*        edittext(Window*, int, Rune*, int);        
       +char*        edittext(Window*, int, Rune*, int);
       +void                flushwarnings(int);
        
        #define        runemalloc(a)                (Rune*)emalloc((a)*sizeof(Rune))
        #define        runerealloc(a, b)        (Rune*)erealloc((a), (b)*sizeof(Rune))
   DIR diff --git a/src/cmd/acme/fsys.c b/src/cmd/acme/fsys.c
       t@@ -111,8 +111,7 @@ void
        fsysinit(void)
        {
                int p[2];
       -        int n, fd;
       -        char buf[256], *u;
       +        char *u;
        
                if(pipe(p) < 0)
                        error("can't create pipe");
       t@@ -122,7 +121,7 @@ fsysinit(void)
                fmtinstall('F', fcallfmt);
                if((u = getuser()) != nil)
                        user = estrdup(u);
       -        proccreate(fsysproc, nil, STACK);
       +        threadcreate(fsysproc, nil, STACK);
        }
        
        void
       t@@ -138,7 +137,7 @@ fsysproc(void *v)
                x = nil;
                for(;;){
                        buf = emalloc(messagesize+UTFmax);        /* overflow for appending partial rune in xfidwrite */
       -                n = read9pmsg(sfd, buf, messagesize);
       +                n = threadread9pmsg(sfd, buf, messagesize);
                        if(n <= 0){
                                if(closing)
                                        break;
       t@@ -255,7 +254,11 @@ respond(Xfid *x, Fcall *t, char *err)
                        x->buf = emalloc(messagesize);
                n = convS2M(t, x->buf, messagesize);
                if(n <= 0)
       +{
       +fprint(2, "convert error (n=%d, msgsize %d): have %F\n", n, messagesize, &x->fcall);
       +fprint(2, "\tresponse: %F\n", t);
                        error("convert error in convS2M");
       +}
                if(write(sfd, x->buf, n) != n)
                        error("write error in respond");
                free(x->buf);
   DIR diff --git a/src/cmd/acme/look.c b/src/cmd/acme/look.c
       t@@ -320,60 +320,18 @@ isfilec(Rune r)
                return FALSE;
        }
        
       +/* Runestr wrapper for cleanname */
        Runestr
        cleanrname(Runestr rs)
        {
       -        int i, j, found;
       -        Rune *b;
       -        int n;
       -        static Rune Lslashdotdot[] = { '/', '.', '.', 0 };
       -
       -        b = rs.r;
       -        n = rs.nr;
       -
       -        /* compress multiple slashes */
       -        for(i=0; i<n-1; i++)
       -                if(b[i]=='/' && b[i+1]=='/'){
       -                        runemove(b+i, b+i+1, n-i-1);
       -                        --n;
       -                        --i;
       -                }
       -        /*  eliminate ./ */
       -        for(i=0; i<n-1; i++)
       -                if(b[i]=='.' && b[i+1]=='/' && (i==0 || b[i-1]=='/')){
       -                        runemove(b+i, b+i+2, n-i-2);
       -                        n -= 2;
       -                        --i;
       -                }
       -        /* eliminate trailing . */
       -        if(n>=2 && b[n-2]=='/' && b[n-1]=='.')
       -                --n;
       -        do{
       -                /* compress xx/.. */
       -                found = FALSE;
       -                for(i=1; i<=n-3; i++)
       -                        if(runeeq(b+i, 3, Lslashdotdot, 3)){
       -                                if(i==n-3 || b[i+3]=='/'){
       -                                        found = TRUE;
       -                                        break;
       -                                }
       -                        }
       -                if(found)
       -                        for(j=i-1; j>=0; --j)
       -                                if(j==0 || b[j-1]=='/'){
       -                                        i += 3;                /* character beyond .. */
       -                                        if(i<n && b[i]=='/')
       -                                                ++i;
       -                                        runemove(b+j, b+i, n-i);
       -                                        n -= (i-j);
       -                                        break;
       -                                }
       -        }while(found);
       -        if(n == 0){
       -                *b = '.';
       -                n = 1;
       -        }
       -        return (Runestr){b, n};
       +        char *s;
       +        int nb, nulls;
       +
       +        s = runetobyte(rs.r, rs.nr);
       +        cleanname(s);
       +        cvttorunes(s, strlen(s), rs.r, &nb, &rs.nr, &nulls);
       +        free(s);
       +        return rs;
        }
        
        Runestr
       t@@ -407,6 +365,11 @@ includename(Text *t, Rune *r, int n)
                Window *w;
                char buf[128];
                Rune Lsysinclude[] = { '/', 's', 'y', 's', '/', 'i', 'n', 'c', 'l', 'u', 'd', 'e', 0 };
       +        Rune Lusrinclude[] = { '/', 'u', 's', 'r', '/', 'i', 'n', 'c', 'l', 'u', 'd', 'e', 0 };
       +        Rune Lusrlocalinclude[] = { '/', 'u', 's', 'r', '/', 'l', 'o', 'c', 'a', 'l', 
       +                        '/', 'i', 'n', 'c', 'l', 'u', 'd', 'e', 0 };
       +        Rune Lusrlocalplan9include[] = { '/', 'u', 's', 'r', '/', 'l', 'o', 'c', 'a', 'l', 
       +                        '/', 'p', 'l', 'a', 'n', '9', '/', 'i', 'n', 'c', 'l', 'u', 'd', 'e', 0 };
                Runestr file;
                int i;
        
       t@@ -429,6 +392,12 @@ includename(Text *t, Rune *r, int n)
        
                if(file.r == nil)
                        file = includefile(Lsysinclude, r, n);
       +        if(file.r == nil)
       +                file = includefile(Lusrlocalplan9include, r, n);
       +        if(file.r == nil)
       +                file = includefile(Lusrlocalinclude, r, n);
       +        if(file.r == nil)
       +                file = includefile(Lusrinclude, r, n);
                if(file.r==nil && objdir!=nil)
                        file = includefile(objdir, r, n);
                if(file.r == nil)
       t@@ -702,13 +671,16 @@ openfile(Text *t, Expand *e)
                        t->w->dirty = FALSE;
                        winsettag(t->w);
                        textsetselect(&t->w->tag, t->w->tag.file->b.nc, t->w->tag.file->b.nc);
       -                if(ow != nil)
       +                if(ow != nil){
                                for(i=ow->nincl; --i>=0; ){
                                        n = runestrlen(ow->incl[i]);
                                        rp = runemalloc(n);
                                        runemove(rp, ow->incl[i], n);
                                        winaddincl(w, rp, n);
                                }
       +                        w->autoindent = ow->autoindent;
       +                }else
       +                        w->autoindent = globalautoindent;
                }
                if(e->a1 == e->a0)
                        eval = FALSE;
   DIR diff --git a/src/cmd/acme/mkfile b/src/cmd/acme/mkfile
       t@@ -1,3 +1,5 @@
       +# Acme is up-to-date w.r.t. sources as of 29 February 2004
       +
        PLAN9=../../..
        <$PLAN9/src/mkhdr
        
       t@@ -36,6 +38,6 @@ UPDATE=\
        
        <$PLAN9/src/mkone
        
       -LDFLAGS=$LDFLAGS -lcomplete -lplumb -lfs -lmux -lthread -lframe -ldraw -lbio -l9 -lfmt -lutf -L$X11/lib -lX11
       +LDFLAGS=$LDFLAGS -lcomplete -lplumb -lfs -lmux -lthread -lframe -ldraw -lbio -l9 -L$X11/lib -lX11
        
        edit.$O ecmd.$O elog.$O:        edit.h
   DIR diff --git a/src/cmd/acme/text.c b/src/cmd/acme/text.c
       t@@ -537,7 +537,7 @@ textfilewidth(Text *t, uint q0, int oneelement)
                q = q0;
                while(q > 0){
                        r = textreadc(t, q-1);
       -                if(r<=' ')
       +                if(r <= ' ')
                                break;
                        if(oneelement && r=='/')
                                break;
       t@@ -608,10 +608,11 @@ textcomplete(Text *t)
                }
        
                if(!c->advance){
       -                warning(nil, "%.*S%s%.*S*\n",
       +                warning(nil, "%.*S%s%.*S*%s\n",
                                dir.nr, dir.r,
                                dir.nr>0 && dir.r[dir.nr-1]!='/' ? "/" : "",
       -                        nstr, str);
       +                        nstr, str,
       +                        c->nmatch ? "" : ": no matches in:");
                        for(i=0; i<c->nfile; i++)
                                warning(nil, " %s\n", c->filename[i]);
                }
       t@@ -643,25 +644,45 @@ texttype(Text *t, Rune r)
                rp = &r;
                switch(r){
                case Kleft:
       -                if(t->q0 > 0)
       +                if(t->q0 > 0){
       +                        textcommit(t, TRUE);
                                textshow(t, t->q0-1, t->q0-1, TRUE);
       +                }
                        return;
                case Kright:
       -                if(t->q1 < t->file->b.nc)
       +                if(t->q1 < t->file->b.nc){
       +                        textcommit(t, TRUE);
                                textshow(t, t->q1+1, t->q1+1, TRUE);
       +                }
                        return;
                case Kdown:
       +                n = t->fr.maxlines/3;
       +                goto case_Down;
                case Kpgdown:
       -                n = t->fr.maxlines/2;
       +                n = 2*t->fr.maxlines/3;
       +        case_Down:
                        q0 = t->org+frcharofpt(&t->fr, Pt(t->fr.r.min.x, t->fr.r.min.y+n*t->fr.font->height));
                        textsetorigin(t, q0, FALSE);
                        return;
                case Kup:
       +                n = t->fr.maxlines/3;
       +                goto case_Up;
                case Kpgup:
       -                n = t->fr.maxlines/2;
       +                n = 2*t->fr.maxlines/3;
       +        case_Up:
                        q0 = textbacknl(t, t->org, n);
                        textsetorigin(t, q0, FALSE);
                        return;
       +        case Khome:
       +                textshow(t, 0, 0, FALSE);
       +                return;
       +        case Kend:
       +                if(t->w)
       +                        wincommit(t->w, t);
       +                else
       +                        textcommit(t, TRUE);
       +                textshow(t, t->file->b.nc, t->file->b.nc, FALSE);
       +                return;
                }
                if(t->what == Body){
                        seq++;
       t@@ -734,6 +755,21 @@ texttype(Text *t, Rune r)
                        for(i=0; i<t->file->ntext; i++)
                                textfill(t->file->text[i]);
                        return;
       +        case '\n':
       +                if(t->w->autoindent){
       +                        /* find beginning of previous line using backspace code */
       +                        nnb = textbswidth(t, 0x15); /* ^U case */
       +                        rp = runemalloc(nnb + 1);
       +                        nr = 0;
       +                        rp[nr++] = r;
       +                        for(i=0; i<nnb; i++){
       +                                r = textreadc(t, t->q0-nnb+i);
       +                                if(r != ' ' && r != '\t')
       +                                        break;
       +                                rp[nr++] = r;
       +                        }
       +                }
       +                break; /* fall through to normal code */
                }
                /* otherwise ordinary character; just insert, typically in caches of all texts */
                for(i=0; i<t->file->ntext; i++){
   DIR diff --git a/src/cmd/acme/time.c b/src/cmd/acme/time.c
       t@@ -50,7 +50,7 @@ timerproc(void *v)
                nt = 0;
                old = msec();
                for(;;){
       -                sleep(1);        /* will sleep minimum incr */
       +                threadsleep(1);        /* will sleep minimum incr */
                        new = msec();
                        dt = new-old;
                        old = new;
       t@@ -98,7 +98,7 @@ void
        timerinit(void)
        {
                ctimer = chancreate(sizeof(Timer*), 100);
       -        proccreate(timerproc, nil, STACK);
       +        threadcreate(timerproc, nil, STACK);
        }
        
        Timer*
   DIR diff --git a/src/cmd/acme/util.c b/src/cmd/acme/util.c
       t@@ -62,9 +62,11 @@ errorwin1(Rune *dir, int ndir, Rune **incl, int nincl)
                int i, n;
                static Rune Lpluserrors[] = { '+', 'E', 'r', 'r', 'o', 'r', 's', 0 };
        
       -        r = runemalloc(ndir+7);
       -        if(n = ndir)        /* assign = */
       +        r = runemalloc(ndir+8);
       +        if(n = ndir){        /* assign = */
                        runemove(r, dir, ndir);
       +                r[n++] = L'/';
       +        }
                runemove(r+n, Lpluserrors, 7);
                n += 7;
                w = lookfile(r, n);
       t@@ -83,12 +85,13 @@ errorwin1(Rune *dir, int ndir, Rune **incl, int nincl)
                        runemove(r, incl[i], n);
                        winaddincl(w, r, n);
                }
       +        w->autoindent = globalautoindent;
                return w;
        }
        
        /* make new window, if necessary; return with it locked */
        Window*
       -errorwin(Mntdir *md, int owner, Window *e)
       +errorwin(Mntdir *md, int owner)
        {
                Window *w;
        
       t@@ -97,51 +100,100 @@ errorwin(Mntdir *md, int owner, Window *e)
                                w = errorwin1(nil, 0, nil, 0);
                        else
                                w = errorwin1(md->dir, md->ndir, md->incl, md->nincl);
       -                if(w != e)
       -                        winlock(w, owner);
       +                winlock(w, owner);
                        if(w->col != nil)
                                break;
                        /* window was deleted too fast */
       -                if(w != e)
       -                        winunlock(w);
       +                winunlock(w);
                }
                return w;
        }
        
       -static void
       -printwarning(Window *ew, Mntdir *md, Rune *r)
       +typedef struct Warning Warning;
       +
       +struct Warning{
       +        Mntdir *md;
       +        Buffer buf;
       +        Warning *next;
       +};
       +
       +static Warning *warnings;
       +
       +static
       +void
       +addwarningtext(Mntdir *md, Rune *r, int nr)
        {
       -        int nr, q0, owner;
       +        Warning *warn;
       +        
       +        for(warn = warnings; warn; warn=warn->next){
       +                if(warn->md == md){
       +                        bufinsert(&warn->buf, warn->buf.nc, r, nr);
       +                        return;
       +                }
       +        }
       +        warn = emalloc(sizeof(Warning));
       +        warn->next = warnings;
       +        warnings = warn;
       +        bufinsert(&warn->buf, 0, r, nr);
       +}
       +
       +void
       +flushwarnings(int dolock)
       +{
       +        Warning *warn, *next;
                Window *w;
                Text *t;
       +        int owner, nr, q0, n;
       +        Rune *r;
        
       -        if(r == nil)
       -                error("runevsmprint failed");
       -        nr = runestrlen(r);
       -
       +        if(dolock)
       +                qlock(&row.lk);
                if(row.ncol == 0){        /* really early error */
                        rowinit(&row, screen->clipr);
                        rowadd(&row, nil, -1);
                        rowadd(&row, nil, -1);
                        if(row.ncol == 0)
       -                        error("initializing columns in warning()");
       +                        error("initializing columns in flushwarnings()");
                }
        
       -        w = errorwin(md, 'E', ew);
       -        t = &w->body;
       -        owner = w->owner;
       -        if(owner == 0)
       -                w->owner = 'E';
       -        wincommit(w, t);
       -        q0 = textbsinsert(t, t->file->b.nc, r, nr, TRUE, &nr);
       -        textshow(t, q0, q0+nr, 1);
       -        winsettag(t->w);
       -        textscrdraw(t);
       -        w->owner = owner;
       -        w->dirty = FALSE;
       -        if(ew != w)
       +        for(warn=warnings; warn; warn=next) {
       +                w = errorwin(warn->md, 'E');
       +                t = &w->body;
       +                owner = w->owner;
       +                if(owner == 0)
       +                        w->owner = 'E';
       +                wincommit(w, t);
       +                /*
       +                 * Most commands don't generate much output. For instance,
       +                 * Edit ,>cat goes through /dev/cons and is already in blocks
       +                 * because of the i/o system, but a few can.  Edit ,p will
       +                 * put the entire result into a single hunk.  So it's worth doing
       +                 * this in blocks (and putting the text in a buffer in the first
       +                 * place), to avoid a big memory footprint.
       +                 */
       +                r = fbufalloc();
       +                q0 = t->file->b.nc;
       +                for(n = 0; n < warn->buf.nc; n += nr){
       +                        nr = warn->buf.nc - n;
       +                        if(nr > RBUFSIZE)
       +                                nr = RBUFSIZE;
       +                        bufread(&warn->buf, n, r, nr);
       +                        textbsinsert(t, t->file->b.nc, r, nr, TRUE, &nr);
       +                }
       +                textshow(t, q0, t->file->b.nc, 1);
       +                free(r);
       +                winsettag(t->w);
       +                textscrdraw(t);
       +                w->owner = owner;
       +                w->dirty = FALSE;
                        winunlock(w);
       -        free(r);
       +                bufclose(&warn->buf);
       +                next = warn->next;
       +                free(warn);
       +        }
       +        warnings = nil;
       +        if(dolock)
       +                qunlock(&row.lk);
        }
        
        void
       t@@ -153,23 +205,9 @@ warning(Mntdir *md, char *s, ...)
                va_start(arg, s);
                r = runevsmprint(s, arg);
                va_end(arg);
       -        printwarning(nil, md, r);
       -}
       -
       -/*
       - * Warningew is like warning but avoids locking the error window
       - * if it's already locked by checking that ew!=error window.
       - */
       -void
       -warningew(Window *ew, Mntdir *md, char *s, ...)
       -{
       -        Rune *r;
       -        va_list arg;
       -
       -        va_start(arg, s);
       -        r = runevsmprint(s, arg);
       -        va_end(arg);
       -        printwarning(ew, md, r);
       +        if(r == nil)
       +                error("runevsmprint failed");
       +        addwarningtext(md, r, runestrlen(r));
        }
        
        int
   DIR diff --git a/src/cmd/acme/wind.c b/src/cmd/acme/wind.c
       t@@ -26,6 +26,8 @@ wininit(Window *w, Window *clone, Rectangle r)
                w->body.w = w;
                w->id = ++winid;
                incref(&w->ref);
       +        if(globalincref)
       +                incref(&w->ref);
                w->ctlfid = ~0;
                w->utflastqid = -1;
                r1 = r;
       t@@ -141,7 +143,7 @@ winlock(Window *w, int owner)
                int i;
                File *f;
        
       -fprint(2, "winlock %p %d %lux\n", w, owner, getcallerpc(&w));
       +//fprint(2, "winlock %p %d %lux\n", w, owner, getcallerpc(&w));
                f = w->body.file;
                for(i=0; i<f->ntext; i++)
                        winlock1(f->text[i]->w, owner);
       t@@ -153,7 +155,7 @@ winunlock(Window *w)
                int i;
                File *f;
        
       -fprint(2, "winunlock %p %lux\n", w, getcallerpc(&w));
       +//fprint(2, "winunlock %p %lux\n", w, getcallerpc(&w));
                f = w->body.file;
                for(i=0; i<f->ntext; i++){
                        w = f->text[i]->w;
   DIR diff --git a/src/cmd/acme/xfid.c b/src/cmd/acme/xfid.c
       t@@ -383,7 +383,7 @@ xfidwrite(Xfid *x)
                x->fcall.data[x->fcall.count] = 0;
                switch(qid){
                case Qcons:
       -                w = errorwin(x->f->mntdir, 'X', nil);
       +                w = errorwin(x->f->mntdir, 'X');
                        t=&w->body;
                        goto BodyTag;
        
       t@@ -543,6 +543,7 @@ xfidwrite(Xfid *x)
                }
                if(w)
                        winunlock(w);
       +        flushwarnings(1);
        }
        
        void
       t@@ -813,6 +814,7 @@ xfideventwrite(Xfid *x, Window *w)
                                qunlock(&row.lk);
                                goto Rescue;
                        }
       +                flushwarnings(0);
                        qunlock(&row.lk);
        
                }
       t@@ -1030,6 +1032,7 @@ xfidindexread(Xfid *x)
                                b[n++] = '\n';
                        }
                }
       +        flushwarnings(0);
                qunlock(&row.lk);
                off = x->fcall.offset;
                cnt = x->fcall.count;
   DIR diff --git a/src/cmd/mkfile b/src/cmd/mkfile
       t@@ -2,7 +2,7 @@ PLAN9=../..
        <$PLAN9/src/mkhdr
        
        TARG=`ls *.c | sed 's/\.c//'`
       -LDFLAGS=$LDFLAGS -lthread -lsec -lfs -lmux -lregexp9 -lbio -l9 -lfmt -lutf
       +LDFLAGS=$LDFLAGS -lthread -lsec -lfs -lmux -lregexp9 -lbio -l9
        
        <$PLAN9/src/mkmany
        
   DIR diff --git a/src/cmd/samterm/plan9.c b/src/cmd/samterm/plan9.c
       t@@ -99,10 +99,11 @@ extproc(void *argv)
                c = arg[0];
                fd = (int)arg[1];
        
       +        threadfdnoblock(fd);
                i = 0;
                for(;;){
                        i = 1-i;        /* toggle */
       -                n = read(fd, plumbbuf[i].data, sizeof plumbbuf[i].data);
       +                n = threadread(fd, plumbbuf[i].data, sizeof plumbbuf[i].data);
                        if(n <= 0){
                                fprint(2, "samterm: extern read error: %r\n");
                                threadexits("extern");        /* not a fatal error */
       t@@ -165,7 +166,7 @@ extstart(void)
                plumbc = chancreate(sizeof(int), 0);
                arg[0] = plumbc;
                arg[1] = (void*)fd;
       -        proccreate(extproc, arg, STACK);
       +        threadcreate(extproc, arg, STACK);
                atexit(removeextern);
        }
        
       t@@ -226,9 +227,10 @@ plumbproc(void *argv)
                fdp = arg[1];
        
                i = 0;
       +        threadfdnoblock(*fdp);
                for(;;){
                        i = 1-i;        /* toggle */
       -                n = read(*fdp, plumbbuf[i].data, READBUFSIZE);
       +                n = threadread(*fdp, plumbbuf[i].data, READBUFSIZE);
                        if(n <= 0){
                                fprint(2, "samterm: plumb read error: %r\n");
                                threadexits("plumb");        /* not a fatal error */
       t@@ -258,7 +260,7 @@ plumbstart(void)
                }
                arg[0] =plumbc;
                arg[1] = &fd;
       -        proccreate(plumbproc, arg, STACK);
       +        threadcreate(plumbproc, arg, STACK);
                return 1;
        }
        #endif
       t@@ -278,9 +280,10 @@ hostproc(void *arg)
                c = arg;
        
                i = 0;
       +        threadfdnoblock(hostfd[0]);
                for(;;){
                        i = 1-i;        /* toggle */
       -                n = read(hostfd[0], hostbuf[i].data, sizeof hostbuf[i].data);
       +                n = threadread(hostfd[0], hostbuf[i].data, sizeof hostbuf[i].data);
                        if(n <= 0){
                                fprint(2, "samterm: host read error: %r\n");
                                threadexitsall("host");
       t@@ -295,5 +298,5 @@ void
        hoststart(void)
        {
                hostc = chancreate(sizeof(int), 0);
       -        proccreate(hostproc, hostc, STACK);
       +        threadcreate(hostproc, hostc, STACK);
        }
   DIR diff --git a/src/lib9/await.c b/src/lib9/await.c
       t@@ -71,8 +71,8 @@ _p9strsig(char *s)
                return 0;
        }
        
       -int
       -await(char *str, int n)
       +static int
       +_await(char *str, int n, int opt)
        {
                int pid, status, cd;
                struct rusage ru;
       t@@ -80,8 +80,8 @@ await(char *str, int n)
                ulong u, s;
        
                for(;;){
       -                pid = wait3(&status, 0, &ru);
       -                if(pid < 0)
       +                pid = wait3(&status, opt, &ru);
       +                if(pid <= 0)
                                return -1;
                        u = ru.ru_utime.tv_sec*1000+((ru.ru_utime.tv_usec+500)/1000);
                        s = ru.ru_stime.tv_sec*1000+((ru.ru_stime.tv_usec+500)/1000);
       t@@ -103,3 +103,16 @@ await(char *str, int n)
                        }
                }
        }
       +
       +int
       +await(char *str, int n)
       +{
       +        return _await(str, n, 0);
       +}
       +
       +int
       +awaitnohang(char *str, int n)
       +{
       +        return _await(str, n, WNOHANG);
       +}
       +
   DIR diff --git a/src/lib9/mkfile b/src/lib9/mkfile
       t@@ -3,7 +3,71 @@ PLAN9=../..
        
        LIB=lib9.a
        
       +NUM=\
       +        charstod.$O\
       +        pow10.$O\
       +
       +# Could add errfmt, but we want to pick it up from lib9 instead.
       +FMTOFILES=\
       +        dofmt.$O\
       +        errfmt.$O\
       +        fltfmt.$O\
       +        fmt.$O\
       +        fmtfd.$O\
       +        fmtfdflush.$O\
       +        fmtlock.$O\
       +        fmtprint.$O\
       +        fmtquote.$O\
       +        fmtrune.$O\
       +        fmtstr.$O\
       +        fmtvprint.$O\
       +        fprint.$O\
       +        nan64.$O\
       +        print.$O\
       +        runefmtstr.$O\
       +        runeseprint.$O\
       +        runesmprint.$O\
       +        runesnprint.$O\
       +        runesprint.$O\
       +        runevseprint.$O\
       +        runevsmprint.$O\
       +        runevsnprint.$O\
       +        seprint.$O\
       +        smprint.$O\
       +        snprint.$O\
       +        sprint.$O\
       +        strtod.$O\
       +        vfprint.$O\
       +        vseprint.$O\
       +        vsmprint.$O\
       +        vsnprint.$O\
       +        $NUM\
       +
       +UTFOFILES=\
       +        rune.$O\
       +        runestrcat.$O\
       +        runestrchr.$O\
       +        runestrcmp.$O\
       +        runestrcpy.$O\
       +        runestrdup.$O\
       +        runestrlen.$O\
       +        runestrecpy.$O\
       +        runestrncat.$O\
       +        runestrncmp.$O\
       +        runestrncpy.$O\
       +        runestrrchr.$O\
       +        runestrstr.$O\
       +        runetype.$O\
       +        utfecpy.$O\
       +        utflen.$O\
       +        utfnlen.$O\
       +        utfrrune.$O\
       +        utfrune.$O\
       +        utfutf.$O\
       +
        OFILES=\
       +        $FMTOFILES\
       +        $UTFOFILES\
                _exits.$O\
                _p9dialparse.$O\
                _p9dir.$O\
       t@@ -85,3 +149,10 @@ HFILES=\
                $PLAN9/include/lib9.h\
        
        <$PLAN9/src/mksyslib
       +
       +%.$O: fmt/%.c
       +        $CC $CFLAGS -Ifmt fmt/$stem.c
       +
       +%.$O: utf/%.c
       +        $CC $CFLAGS utf/$stem.c
       +
   DIR diff --git a/src/lib9/nan.c b/src/lib9/nan.c
       t@@ -1,6 +1,6 @@
        #include <u.h>
        #include <libc.h>
       -#include "../libfmt/nan.h"
       +#include "fmt/nan.h"
        
        double
        NaN(void)
   DIR diff --git a/src/lib9/wait.c b/src/lib9/wait.c
       t@@ -1,15 +1,15 @@
        #include <u.h>
        #include <libc.h>
        
       -Waitmsg*
       -wait(void)
       +static Waitmsg*
       +_wait(int nohang)
        {
                int n, l;
                char buf[512], *fld[5];
                Waitmsg *w;
        
       -        n = await(buf, sizeof buf-1);
       -        if(n < 0)
       +        n = (nohang ? awaitnohang : await)(buf, sizeof buf-1);
       +        if(n <= 0)
                        return nil;
                buf[n] = '\0';
                if(tokenize(buf, fld, nelem(fld)) != nelem(fld)){
       t@@ -29,3 +29,15 @@ wait(void)
                return w;
        }
        
       +Waitmsg*
       +wait(void)
       +{
       +        return _wait(0);
       +}
       +
       +Waitmsg*
       +waitnohang(void)
       +{
       +        return _wait(1);
       +}
       +
   DIR diff --git a/src/libcomplete/complete.c b/src/libcomplete/complete.c
       t@@ -41,7 +41,7 @@ strpcmp(const void *va, const void *vb)
        Completion*
        complete(char *dir, char *s)
        {
       -        long i, l, n, nmatch, len, nbytes;
       +        long i, l, n, nfile, len, nbytes;
                int fd, minlen;
                Dir *dirp;
                char **name, *p;
       t@@ -58,8 +58,10 @@ complete(char *dir, char *s)
                        return nil;
        
                n = dirreadall(fd, &dirp);
       -        if(n <= 0)
       +        if(n <= 0){
       +                close(fd);
                        return nil;
       +        }
        
                /* find longest string, for allocation */
                len = 0;
       t@@ -78,49 +80,51 @@ complete(char *dir, char *s)
        
                /* find the matches */
                len = strlen(s);
       -        nmatch = 0;
       +        nfile = 0;
                minlen = 1000000;
                for(i=0; i<n; i++)
                        if(strncmp(s, dirp[i].name, len) == 0){
       -                        name[nmatch] = dirp[i].name;
       -                        mode[nmatch] = dirp[i].mode;
       +                        name[nfile] = dirp[i].name;
       +                        mode[nfile] = dirp[i].mode;
                                if(minlen > strlen(dirp[i].name))
                                        minlen = strlen(dirp[i].name);
       -                        nmatch++;
       +                        nfile++;
                        }
        
       -        if(nmatch > 0) {
       +        if(nfile > 0) {
                        /* report interesting results */
                        /* trim length back to longest common initial string */
       -                for(i=1; i<nmatch; i++)
       +                for(i=1; i<nfile; i++)
                                minlen = longestprefixlength(name[0], name[i], minlen);
        
                        /* build the answer */
       -                c->complete = (nmatch == 1);
       +                c->complete = (nfile == 1);
                        c->advance = c->complete || (minlen > len);
                        c->string = (char*)(c+1);
                        memmove(c->string, name[0]+len, minlen-len);
                        if(c->complete)
                                c->string[minlen++ - len] = (mode[0]&DMDIR)? '/' : ' ';
                        c->string[minlen - len] = '\0';
       +                c->nmatch = nfile;
                } else {
                        /* no match, so return all possible strings */
                        for(i=0; i<n; i++){
                                name[i] = dirp[i].name;
                                mode[i] = dirp[i].mode;
                        }
       -                nmatch = n;
       +                nfile = n;
       +                c->nmatch = 0;
                }
        
                /* attach list of names */
       -        nbytes = nmatch * sizeof(char*);
       -        for(i=0; i<nmatch; i++)
       +        nbytes = nfile * sizeof(char*);
       +        for(i=0; i<nfile; i++)
                        nbytes += strlen(name[i]) + 1 + 1;
                c->filename = malloc(nbytes);
                if(c->filename == nil)
                        goto Return;
       -        p = (char*)(c->filename + nmatch);
       -        for(i=0; i<nmatch; i++){
       +        p = (char*)(c->filename + nfile);
       +        for(i=0; i<nfile; i++){
                        c->filename[i] = p;
                        strcpy(p, name[i]);
                        p += strlen(p);
       t@@ -128,12 +132,13 @@ complete(char *dir, char *s)
                                *p++ = '/';
                        *p++ = '\0';
                }
       -        c->nfile = nmatch;
       +        c->nfile = nfile;
                qsort(c->filename, c->nfile, sizeof(c->filename[0]), strpcmp);
        
          Return:
                free(name);
                free(mode);
                free(dirp);
       +        close(fd);
                return c;
        }
   DIR diff --git a/src/libdraw/x11-itrans.c b/src/libdraw/x11-itrans.c
       t@@ -454,7 +454,7 @@ _xselect(XEvent *e, XDisplay *xd)
        
                memset(&r, 0, sizeof r);
                xe = (XSelectionRequestEvent*)e;
       -if(0) fprint(2, "xselect target=%d requestor=%d property=%d selection=%d\n",
       +if(1) fprint(2, "xselect target=%d requestor=%d property=%d selection=%d\n",
                xe->target, xe->requestor, xe->property, xe->selection);
                r.xselection.property = xe->property;
                if(xe->target == _x.targets){
   DIR diff --git a/src/libdraw/x11-keyboard.c b/src/libdraw/x11-keyboard.c
       t@@ -34,6 +34,7 @@ void
        _ioproc(void *arg)
        {
                int i;
       +        int fd;
                Keyboardctl *kc;
                Rune r;
                XEvent xevent;
       t@@ -41,9 +42,11 @@ _ioproc(void *arg)
                kc = arg;
                threadsetname("kbdproc");
                kc->pid = getpid();
       +        fd = XConnectionNumber(_x.kbdcon);
                XSelectInput(_x.kbdcon, _x.drawable, KeyPressMask);
                for(;;){
       -                XWindowEvent(_x.kbdcon, _x.drawable, KeyPressMask, &xevent);
       +                while(XCheckWindowEvent(_x.kbdcon, _x.drawable, KeyPressMask, &xevent) == False)
       +                        threadfdwait(fd, 'r');
                        switch(xevent.type){
                        case KeyPress:
                                i = _xtoplan9kbd(&xevent);
       t@@ -65,11 +68,12 @@ initkeyboard(char *file)
        {
                Keyboardctl *kc;
        
       +        threadfdwaitsetup();
                kc = mallocz(sizeof(Keyboardctl), 1);
                if(kc == nil)
                        return nil;
                kc->c = chancreate(sizeof(Rune), 20);
       -        proccreate(_ioproc, kc, 4096);
       +        threadcreate(_ioproc, kc, 4096);
                return kc;
        }
        
   DIR diff --git a/src/libdraw/x11-mouse.c b/src/libdraw/x11-mouse.c
       t@@ -47,7 +47,7 @@ static
        void
        _ioproc(void *arg)
        {
       -        int one;
       +        int fd, one;
                ulong mask;
                Mouse m;
                Mousectl *mc;
       t@@ -60,7 +60,10 @@ _ioproc(void *arg)
                mc->pid = getpid();
                mask = MouseMask|ExposureMask|StructureNotifyMask;
                XSelectInput(_x.mousecon, _x.drawable, mask);
       +        fd = XConnectionNumber(_x.mousecon);
                for(;;){
       +                while(XPending(_x.mousecon) == False)
       +                        threadfdwait(fd, 'r');
                        XNextEvent(_x.mousecon, &xevent);
                        switch(xevent.type){
                        case Expose:
       t@@ -105,12 +108,13 @@ initmouse(char *file, Image *i)
        {
                Mousectl *mc;
        
       +        threadfdwaitsetup();
                mc = mallocz(sizeof(Mousectl), 1);
                if(i)
                        mc->display = i->display;
                mc->c = chancreate(sizeof(Mouse), 0);
                mc->resizec = chancreate(sizeof(int), 2);
       -        proccreate(_ioproc, mc, 16384);
       +        threadcreate(_ioproc, mc, 16384);
                return mc;
        }
        
   DIR diff --git a/src/libfmt/LICENSE b/src/libfmt/LICENSE
       t@@ -1,19 +0,0 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *                Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
       - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       -*/
       -
       -This is a Unix port of the Plan 9 formatted I/O package.
       -
       -Please send comments about the packaging
       -to Russ Cox <rsc@post.harvard.edu>.
       -
   DIR diff --git a/src/libfmt/NOTICE b/src/libfmt/NOTICE
       t@@ -1,19 +0,0 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *                Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
       - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       -*/
       -
       -This is a Unix port of the Plan 9 formatted I/O package.
       -
       -Please send comments about the packaging
       -to Russ Cox <rsc@post.harvard.edu>.
       -
   DIR diff --git a/src/libfmt/README b/src/libfmt/README
       t@@ -1,19 +0,0 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *                Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
       - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       -*/
       -
       -This is a Unix port of the Plan 9 formatted I/O package.
       -
       -Please send comments about the packaging
       -to Russ Cox <rsc@post.harvard.edu>.
       -
   DIR diff --git a/src/libfmt/charstod.c b/src/libfmt/charstod.c
       t@@ -1,85 +0,0 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
       - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       -#include <stdarg.h>
       -#include <string.h>
       -#include "utf.h"
       -#include "fmt.h"
       -#include "fmtdef.h"
       -
       -/*
       - * Reads a floating-point number by interpreting successive characters
       - * returned by (*f)(vp).  The last call it makes to f terminates the
       - * scan, so is not a character in the number.  It may therefore be
       - * necessary to back up the input stream up one byte after calling charstod.
       - */
       -
       -double
       -fmtcharstod(int(*f)(void*), void *vp)
       -{
       -        double num, dem;
       -        int neg, eneg, dig, exp, c;
       -
       -        num = 0;
       -        neg = 0;
       -        dig = 0;
       -        exp = 0;
       -        eneg = 0;
       -
       -        c = (*f)(vp);
       -        while(c == ' ' || c == '\t')
       -                c = (*f)(vp);
       -        if(c == '-' || c == '+'){
       -                if(c == '-')
       -                        neg = 1;
       -                c = (*f)(vp);
       -        }
       -        while(c >= '0' && c <= '9'){
       -                num = num*10 + c-'0';
       -                c = (*f)(vp);
       -        }
       -        if(c == '.')
       -                c = (*f)(vp);
       -        while(c >= '0' && c <= '9'){
       -                num = num*10 + c-'0';
       -                dig++;
       -                c = (*f)(vp);
       -        }
       -        if(c == 'e' || c == 'E'){
       -                c = (*f)(vp);
       -                if(c == '-' || c == '+'){
       -                        if(c == '-'){
       -                                dig = -dig;
       -                                eneg = 1;
       -                        }
       -                        c = (*f)(vp);
       -                }
       -                while(c >= '0' && c <= '9'){
       -                        exp = exp*10 + c-'0';
       -                        c = (*f)(vp);
       -                }
       -        }
       -        exp -= dig;
       -        if(exp < 0){
       -                exp = -exp;
       -                eneg = !eneg;
       -        }
       -        dem = __fmtpow10(exp);
       -        if(eneg)
       -                num /= dem;
       -        else
       -                num *= dem;
       -        if(neg)
       -                return -num;
       -        return num;
       -}
   DIR diff --git a/src/libfmt/dofmt.c b/src/libfmt/dofmt.c
       t@@ -1,558 +0,0 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
       - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       -#include <stdarg.h>
       -#include <string.h>
       -#include "utf.h"
       -#include "fmt.h"
       -#include "fmtdef.h"
       -
       -/* format the output into f->to and return the number of characters fmted  */
       -int
       -dofmt(Fmt *f, char *fmt)
       -{
       -        Rune rune, *rt, *rs;
       -        int r;
       -        char *t, *s;
       -        int n, nfmt;
       -
       -        nfmt = f->nfmt;
       -        for(;;){
       -                if(f->runes){
       -                        rt = (Rune*)f->to;
       -                        rs = (Rune*)f->stop;
       -                        while((r = *(uchar*)fmt) && r != '%'){
       -                                if(r < Runeself)
       -                                        fmt++;
       -                                else{
       -                                        fmt += chartorune(&rune, fmt);
       -                                        r = rune;
       -                                }
       -                                FMTRCHAR(f, rt, rs, r);
       -                        }
       -                        fmt++;
       -                        f->nfmt += rt - (Rune *)f->to;
       -                        f->to = rt;
       -                        if(!r)
       -                                return f->nfmt - nfmt;
       -                        f->stop = rs;
       -                }else{
       -                        t = (char*)f->to;
       -                        s = (char*)f->stop;
       -                        while((r = *(uchar*)fmt) && r != '%'){
       -                                if(r < Runeself){
       -                                        FMTCHAR(f, t, s, r);
       -                                        fmt++;
       -                                }else{
       -                                        n = chartorune(&rune, fmt);
       -                                        if(t + n > s){
       -                                                t = (char*)__fmtflush(f, t, n);
       -                                                if(t != nil)
       -                                                        s = (char*)f->stop;
       -                                                else
       -                                                        return -1;
       -                                        }
       -                                        while(n--)
       -                                                *t++ = *fmt++;
       -                                }
       -                        }
       -                        fmt++;
       -                        f->nfmt += t - (char *)f->to;
       -                        f->to = t;
       -                        if(!r)
       -                                return f->nfmt - nfmt;
       -                        f->stop = s;
       -                }
       -
       -                fmt = (char*)__fmtdispatch(f, fmt, 0);
       -                if(fmt == nil)
       -                        return -1;
       -        }
       -        return 0;        /* not reached */
       -}
       -
       -void *
       -__fmtflush(Fmt *f, void *t, int len)
       -{
       -        if(f->runes)
       -                f->nfmt += (Rune*)t - (Rune*)f->to;
       -        else
       -                f->nfmt += (char*)t - (char *)f->to;
       -        f->to = t;
       -        if(f->flush == 0 || (*f->flush)(f) == 0 || (char*)f->to + len > (char*)f->stop){
       -                f->stop = f->to;
       -                return nil;
       -        }
       -        return f->to;
       -}
       -
       -/*
       - * put a formatted block of memory sz bytes long of n runes into the output buffer,
       - * left/right justified in a field of at least f->width charactes
       - */
       -int
       -__fmtpad(Fmt *f, int n)
       -{
       -        char *t, *s;
       -        int i;
       -
       -        t = (char*)f->to;
       -        s = (char*)f->stop;
       -        for(i = 0; i < n; i++)
       -                FMTCHAR(f, t, s, ' ');
       -        f->nfmt += t - (char *)f->to;
       -        f->to = t;
       -        return 0;
       -}
       -
       -int
       -__rfmtpad(Fmt *f, int n)
       -{
       -        Rune *t, *s;
       -        int i;
       -
       -        t = (Rune*)f->to;
       -        s = (Rune*)f->stop;
       -        for(i = 0; i < n; i++)
       -                FMTRCHAR(f, t, s, ' ');
       -        f->nfmt += t - (Rune *)f->to;
       -        f->to = t;
       -        return 0;
       -}
       -
       -int
       -__fmtcpy(Fmt *f, const void *vm, int n, int sz)
       -{
       -        Rune *rt, *rs, r;
       -        char *t, *s, *m, *me;
       -        ulong fl;
       -        int nc, w;
       -
       -        m = (char*)vm;
       -        me = m + sz;
       -        w = f->width;
       -        fl = f->flags;
       -        if((fl & FmtPrec) && n > f->prec)
       -                n = f->prec;
       -        if(f->runes){
       -                if(!(fl & FmtLeft) && __rfmtpad(f, w - n) < 0)
       -                        return -1;
       -                rt = (Rune*)f->to;
       -                rs = (Rune*)f->stop;
       -                for(nc = n; nc > 0; nc--){
       -                        r = *(uchar*)m;
       -                        if(r < Runeself)
       -                                m++;
       -                        else if((me - m) >= UTFmax || fullrune(m, me-m))
       -                                m += chartorune(&r, m);
       -                        else
       -                                break;
       -                        FMTRCHAR(f, rt, rs, r);
       -                }
       -                f->nfmt += rt - (Rune *)f->to;
       -                f->to = rt;
       -                if(m < me)
       -                        return -1;
       -                if(fl & FmtLeft && __rfmtpad(f, w - n) < 0)
       -                        return -1;
       -        }else{
       -                if(!(fl & FmtLeft) && __fmtpad(f, w - n) < 0)
       -                        return -1;
       -                t = (char*)f->to;
       -                s = (char*)f->stop;
       -                for(nc = n; nc > 0; nc--){
       -                        r = *(uchar*)m;
       -                        if(r < Runeself)
       -                                m++;
       -                        else if((me - m) >= UTFmax || fullrune(m, me-m))
       -                                m += chartorune(&r, m);
       -                        else
       -                                break;
       -                        FMTRUNE(f, t, s, r);
       -                }
       -                f->nfmt += t - (char *)f->to;
       -                f->to = t;
       -                if(fl & FmtLeft && __fmtpad(f, w - n) < 0)
       -                        return -1;
       -        }
       -        return 0;
       -}
       -
       -int
       -__fmtrcpy(Fmt *f, const void *vm, int n)
       -{
       -        Rune r, *m, *me, *rt, *rs;
       -        char *t, *s;
       -        ulong fl;
       -        int w;
       -
       -        m = (Rune*)vm;
       -        w = f->width;
       -        fl = f->flags;
       -        if((fl & FmtPrec) && n > f->prec)
       -                n = f->prec;
       -        if(f->runes){
       -                if(!(fl & FmtLeft) && __rfmtpad(f, w - n) < 0)
       -                        return -1;
       -                rt = (Rune*)f->to;
       -                rs = (Rune*)f->stop;
       -                for(me = m + n; m < me; m++)
       -                        FMTRCHAR(f, rt, rs, *m);
       -                f->nfmt += rt - (Rune *)f->to;
       -                f->to = rt;
       -                if(fl & FmtLeft && __rfmtpad(f, w - n) < 0)
       -                        return -1;
       -        }else{
       -                if(!(fl & FmtLeft) && __fmtpad(f, w - n) < 0)
       -                        return -1;
       -                t = (char*)f->to;
       -                s = (char*)f->stop;
       -                for(me = m + n; m < me; m++){
       -                        r = *m;
       -                        FMTRUNE(f, t, s, r);
       -                }
       -                f->nfmt += t - (char *)f->to;
       -                f->to = t;
       -                if(fl & FmtLeft && __fmtpad(f, w - n) < 0)
       -                        return -1;
       -        }
       -        return 0;
       -}
       -
       -/* fmt out one character */
       -int
       -__charfmt(Fmt *f)
       -{
       -        char x[1];
       -
       -        x[0] = va_arg(f->args, int);
       -        f->prec = 1;
       -        return __fmtcpy(f, (const char*)x, 1, 1);
       -}
       -
       -/* fmt out one rune */
       -int
       -__runefmt(Fmt *f)
       -{
       -        Rune x[1];
       -
       -        x[0] = va_arg(f->args, int);
       -        return __fmtrcpy(f, (const void*)x, 1);
       -}
       -
       -/* public helper routine: fmt out a null terminated string already in hand */
       -int
       -fmtstrcpy(Fmt *f, char *s)
       -{
       -        int p, i;
       -        if(!s)
       -                return __fmtcpy(f, "<nil>", 5, 5);
       -        /* if precision is specified, make sure we don't wander off the end */
       -        if(f->flags & FmtPrec){
       -                p = f->prec;
       -                for(i = 0; i < p; i++)
       -                        if(s[i] == 0)
       -                                break;
       -                return __fmtcpy(f, s, utfnlen(s, i), i);        /* BUG?: won't print a partial rune at end */
       -        }
       -
       -        return __fmtcpy(f, s, utflen(s), strlen(s));
       -}
       -
       -/* fmt out a null terminated utf string */
       -int
       -__strfmt(Fmt *f)
       -{
       -        char *s;
       -
       -        s = va_arg(f->args, char *);
       -        return fmtstrcpy(f, s);
       -}
       -
       -/* public helper routine: fmt out a null terminated rune string already in hand */
       -int
       -fmtrunestrcpy(Fmt *f, Rune *s)
       -{
       -        Rune *e;
       -        int n, p;
       -
       -        if(!s)
       -                return __fmtcpy(f, "<nil>", 5, 5);
       -        /* if precision is specified, make sure we don't wander off the end */
       -        if(f->flags & FmtPrec){
       -                p = f->prec;
       -                for(n = 0; n < p; n++)
       -                        if(s[n] == 0)
       -                                break;
       -        }else{
       -                for(e = s; *e; e++)
       -                        ;
       -                n = e - s;
       -        }
       -        return __fmtrcpy(f, s, n);
       -}
       -
       -/* fmt out a null terminated rune string */
       -int
       -__runesfmt(Fmt *f)
       -{
       -        Rune *s;
       -
       -        s = va_arg(f->args, Rune *);
       -        return fmtrunestrcpy(f, s);
       -}
       -
       -/* fmt a % */
       -int
       -__percentfmt(Fmt *f)
       -{
       -        Rune x[1];
       -
       -        x[0] = f->r;
       -        f->prec = 1;
       -        return __fmtrcpy(f, (const void*)x, 1);
       -}
       -
       -/* fmt an integer */
       -int
       -__ifmt(Fmt *f)
       -{
       -        char buf[70], *p, *conv;
       -        uvlong vu;
       -        ulong u;
       -        int neg, base, i, n, fl, w, isv;
       -
       -        neg = 0;
       -        fl = f->flags;
       -        isv = 0;
       -        vu = 0;
       -        u = 0;
       -        /*
       -         * Unsigned verbs
       -         */
       -        switch(f->r){
       -        case 'o':
       -        case 'u':
       -        case 'x':
       -        case 'X':
       -                fl |= FmtUnsigned;
       -                break;
       -        }
       -        if(f->r == 'p'){
       -                u = (ulong)va_arg(f->args, void*);
       -                f->r = 'x';
       -                fl |= FmtUnsigned;
       -        }else if(fl & FmtVLong){
       -                isv = 1;
       -                if(fl & FmtUnsigned)
       -                        vu = va_arg(f->args, uvlong);
       -                else
       -                        vu = va_arg(f->args, vlong);
       -        }else if(fl & FmtLong){
       -                if(fl & FmtUnsigned)
       -                        u = va_arg(f->args, ulong);
       -                else
       -                        u = va_arg(f->args, long);
       -        }else if(fl & FmtByte){
       -                if(fl & FmtUnsigned)
       -                        u = (uchar)va_arg(f->args, int);
       -                else
       -                        u = (char)va_arg(f->args, int);
       -        }else if(fl & FmtShort){
       -                if(fl & FmtUnsigned)
       -                        u = (ushort)va_arg(f->args, int);
       -                else
       -                        u = (short)va_arg(f->args, int);
       -        }else{
       -                if(fl & FmtUnsigned)
       -                        u = va_arg(f->args, uint);
       -                else
       -                        u = va_arg(f->args, int);
       -        }
       -        conv = "0123456789abcdef";
       -        switch(f->r){
       -        case 'd':
       -        case 'i':
       -                base = 10;
       -                break;
       -        case 'u':
       -                base = 10;
       -                break;
       -        case 'x':
       -                base = 16;
       -                break;
       -        case 'X':
       -                base = 16;
       -                conv = "0123456789ABCDEF";
       -                break;
       -        case 'b':
       -                base = 2;
       -                break;
       -        case 'o':
       -                base = 8;
       -                break;
       -        default:
       -                return -1;
       -        }
       -        if(!(fl & FmtUnsigned)){
       -                if(isv && (vlong)vu < 0){
       -                        vu = -(vlong)vu;
       -                        neg = 1;
       -                }else if(!isv && (long)u < 0){
       -                        u = -(long)u;
       -                        neg = 1;
       -                }
       -        }else{
       -                fl &= ~(FmtSign|FmtSpace);        /* no + for unsigned conversions */
       -        }
       -        p = buf + sizeof buf - 1;
       -        n = 0;
       -        if(isv){
       -                while(vu){
       -                        i = vu % base;
       -                        vu /= base;
       -                        if((fl & FmtComma) && n % 4 == 3){
       -                                *p-- = ',';
       -                                n++;
       -                        }
       -                        *p-- = conv[i];
       -                        n++;
       -                }
       -        }else{
       -                while(u){
       -                        i = u % base;
       -                        u /= base;
       -                        if((fl & FmtComma) && n % 4 == 3){
       -                                *p-- = ',';
       -                                n++;
       -                        }
       -                        *p-- = conv[i];
       -                        n++;
       -                }
       -        }
       -        if(n == 0){
       -                if(!(fl & FmtPrec) || f->prec != 0){
       -                        *p-- = '0';
       -                        n = 1;
       -                }
       -                fl &= ~FmtSharp;
       -        }
       -        for(w = f->prec; n < w && p > buf+3; n++)
       -                *p-- = '0';
       -        if(neg || (fl & (FmtSign|FmtSpace)))
       -                n++;
       -        if(fl & FmtSharp){
       -                if(base == 16)
       -                        n += 2;
       -                else if(base == 8){
       -                        if(p[1] == '0')
       -                                fl &= ~FmtSharp;
       -                        else
       -                                n++;
       -                }
       -        }
       -        if((fl & FmtZero) && !(fl & (FmtLeft|FmtPrec))){
       -                for(w = f->width; n < w && p > buf+3; n++)
       -                        *p-- = '0';
       -                f->width = 0;
       -        }
       -        if(fl & FmtSharp){
       -                if(base == 16)
       -                        *p-- = f->r;
       -                if(base == 16 || base == 8)
       -                        *p-- = '0';
       -        }
       -        if(neg)
       -                *p-- = '-';
       -        else if(fl & FmtSign)
       -                *p-- = '+';
       -        else if(fl & FmtSpace)
       -                *p-- = ' ';
       -        f->flags &= ~FmtPrec;
       -        return __fmtcpy(f, p + 1, n, n);
       -}
       -
       -int
       -__countfmt(Fmt *f)
       -{
       -        void *p;
       -        ulong fl;
       -
       -        fl = f->flags;
       -        p = va_arg(f->args, void*);
       -        if(fl & FmtVLong){
       -                *(vlong*)p = f->nfmt;
       -        }else if(fl & FmtLong){
       -                *(long*)p = f->nfmt;
       -        }else if(fl & FmtByte){
       -                *(char*)p = f->nfmt;
       -        }else if(fl & FmtShort){
       -                *(short*)p = f->nfmt;
       -        }else{
       -                *(int*)p = f->nfmt;
       -        }
       -        return 0;
       -}
       -
       -int
       -__flagfmt(Fmt *f)
       -{
       -        switch(f->r){
       -        case ',':
       -                f->flags |= FmtComma;
       -                break;
       -        case '-':
       -                f->flags |= FmtLeft;
       -                break;
       -        case '+':
       -                f->flags |= FmtSign;
       -                break;
       -        case '#':
       -                f->flags |= FmtSharp;
       -                break;
       -        case ' ':
       -                f->flags |= FmtSpace;
       -                break;
       -        case 'u':
       -                f->flags |= FmtUnsigned;
       -                break;
       -        case 'h':
       -                if(f->flags & FmtShort)
       -                        f->flags |= FmtByte;
       -                f->flags |= FmtShort;
       -                break;
       -        case 'L':
       -                f->flags |= FmtLDouble;
       -                break;
       -        case 'l':
       -                if(f->flags & FmtLong)
       -                        f->flags |= FmtVLong;
       -                f->flags |= FmtLong;
       -                break;
       -        }
       -        return 1;
       -}
       -
       -/* default error format */
       -int
       -__badfmt(Fmt *f)
       -{
       -        char x[3];
       -
       -        x[0] = '%';
       -        x[1] = f->r;
       -        x[2] = '%';
       -        f->prec = 3;
       -        __fmtcpy(f, (const void*)x, 3, 3);
       -        return 0;
       -}
   DIR diff --git a/src/libfmt/dorfmt.c b/src/libfmt/dorfmt.c
       t@@ -1,61 +0,0 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
       - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       -#include <stdarg.h>
       -#include <string.h>
       -#include "utf.h"
       -#include "fmt.h"
       -#include "fmtdef.h"
       -
       -/* format the output into f->to and return the number of characters fmted  */
       -
       -int
       -dorfmt(Fmt *f, const Rune *fmt)
       -{
       -        Rune *rt, *rs;
       -        int r;
       -        char *t, *s;
       -        int nfmt;
       -
       -        nfmt = f->nfmt;
       -        for(;;){
       -                if(f->runes){
       -                        rt = f->to;
       -                        rs = f->stop;
       -                        while((r = *fmt++) && r != '%'){
       -                                FMTRCHAR(f, rt, rs, r);
       -                        }
       -                        f->nfmt += rt - (Rune *)f->to;
       -                        f->to = rt;
       -                        if(!r)
       -                                return f->nfmt - nfmt;
       -                        f->stop = rs;
       -                }else{
       -                        t = f->to;
       -                        s = f->stop;
       -                        while((r = *fmt++) && r != '%'){
       -                                FMTRUNE(f, t, f->stop, r);
       -                        }
       -                        f->nfmt += t - (char *)f->to;
       -                        f->to = t;
       -                        if(!r)
       -                                return f->nfmt - nfmt;
       -                        f->stop = s;
       -                }
       -
       -                fmt = __fmtdispatch(f, fmt, 1);
       -                if(fmt == nil)
       -                        return -1;
       -        }
       -        return 0;                /* not reached */
       -}
   DIR diff --git a/src/libfmt/errfmt.c b/src/libfmt/errfmt.c
       t@@ -1,28 +0,0 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
       - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       -#include <stdarg.h>
       -#include <errno.h>
       -#include <string.h>
       -#include "utf.h"
       -#include "fmt.h"
       -#include "fmtdef.h"
       -
       -int
       -__errfmt(Fmt *f)
       -{
       -        char *s;
       -
       -        s = strerror(errno);
       -        return fmtstrcpy(f, s);
       -}
   DIR diff --git a/src/libfmt/fltfmt.c b/src/libfmt/fltfmt.c
       t@@ -1,610 +0,0 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
       - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       -#include <stdio.h>
       -#include <math.h>
       -#include <float.h>
       -#include <string.h>
       -#include <stdlib.h>
       -#include <errno.h>
       -#include <stdarg.h>
       -#include "fmt.h"
       -#include "fmtdef.h"
       -#include "nan.h"
       -
       -enum
       -{
       -        FDEFLT        = 6,
       -        NSIGNIF        = 17
       -};
       -
       -/*
       - * first few powers of 10, enough for about 1/2 of the
       - * total space for doubles.
       - */
       -static double pows10[] =
       -{
       -          1e0,   1e1,   1e2,   1e3,   1e4,   1e5,   1e6,   1e7,   1e8,   1e9,  
       -         1e10,  1e11,  1e12,  1e13,  1e14,  1e15,  1e16,  1e17,  1e18,  1e19,  
       -         1e20,  1e21,  1e22,  1e23,  1e24,  1e25,  1e26,  1e27,  1e28,  1e29,  
       -         1e30,  1e31,  1e32,  1e33,  1e34,  1e35,  1e36,  1e37,  1e38,  1e39,  
       -         1e40,  1e41,  1e42,  1e43,  1e44,  1e45,  1e46,  1e47,  1e48,  1e49,  
       -         1e50,  1e51,  1e52,  1e53,  1e54,  1e55,  1e56,  1e57,  1e58,  1e59,  
       -         1e60,  1e61,  1e62,  1e63,  1e64,  1e65,  1e66,  1e67,  1e68,  1e69,  
       -         1e70,  1e71,  1e72,  1e73,  1e74,  1e75,  1e76,  1e77,  1e78,  1e79,  
       -         1e80,  1e81,  1e82,  1e83,  1e84,  1e85,  1e86,  1e87,  1e88,  1e89,  
       -         1e90,  1e91,  1e92,  1e93,  1e94,  1e95,  1e96,  1e97,  1e98,  1e99,  
       -        1e100, 1e101, 1e102, 1e103, 1e104, 1e105, 1e106, 1e107, 1e108, 1e109, 
       -        1e110, 1e111, 1e112, 1e113, 1e114, 1e115, 1e116, 1e117, 1e118, 1e119, 
       -        1e120, 1e121, 1e122, 1e123, 1e124, 1e125, 1e126, 1e127, 1e128, 1e129, 
       -        1e130, 1e131, 1e132, 1e133, 1e134, 1e135, 1e136, 1e137, 1e138, 1e139, 
       -        1e140, 1e141, 1e142, 1e143, 1e144, 1e145, 1e146, 1e147, 1e148, 1e149, 
       -        1e150, 1e151, 1e152, 1e153, 1e154, 1e155, 1e156, 1e157, 1e158, 1e159, 
       -};
       -
       -static double
       -pow10(int n)
       -{
       -        double d;
       -        int neg;
       -
       -        neg = 0;
       -        if(n < 0){
       -                if(n < DBL_MIN_10_EXP){
       -                        return 0.;
       -                }
       -                neg = 1;
       -                n = -n;
       -        }else if(n > DBL_MAX_10_EXP){
       -                return HUGE_VAL;
       -        }
       -        if(n < (int)(sizeof(pows10)/sizeof(pows10[0])))
       -                d = pows10[n];
       -        else{
       -                d = pows10[sizeof(pows10)/sizeof(pows10[0]) - 1];
       -                for(;;){
       -                        n -= sizeof(pows10)/sizeof(pows10[0]) - 1;
       -                        if(n < (int)(sizeof(pows10)/sizeof(pows10[0]))){
       -                                d *= pows10[n];
       -                                break;
       -                        }
       -                        d *= pows10[sizeof(pows10)/sizeof(pows10[0]) - 1];
       -                }
       -        }
       -        if(neg){
       -                return 1./d;
       -        }
       -        return d;
       -}
       -
       -static int
       -xadd(char *a, int n, int v)
       -{
       -        char *b;
       -        int c;
       -
       -        if(n < 0 || n >= NSIGNIF)
       -                return 0;
       -        for(b = a+n; b >= a; b--) {
       -                c = *b + v;
       -                if(c <= '9') {
       -                        *b = c;
       -                        return 0;
       -                }
       -                *b = '0';
       -                v = 1;
       -        }
       -        *a = '1';        /* overflow adding */
       -        return 1;
       -}
       -
       -static int
       -xsub(char *a, int n, int v)
       -{
       -        char *b;
       -        int c;
       -
       -        for(b = a+n; b >= a; b--) {
       -                c = *b - v;
       -                if(c >= '0') {
       -                        *b = c;
       -                        return 0;
       -                }
       -                *b = '9';
       -                v = 1;
       -        }
       -        *a = '9';        /* underflow subtracting */
       -        return 1;
       -}
       -
       -static void
       -xaddexp(char *p, int e)
       -{
       -        char se[9];
       -        int i;
       -
       -        *p++ = 'e';
       -        if(e < 0) {
       -                *p++ = '-';
       -                e = -e;
       -        }
       -        i = 0;
       -        while(e) {
       -                se[i++] = e % 10 + '0';
       -                e /= 10;
       -        }
       -        if(i == 0) {
       -                *p++ = '0';
       -        } else {
       -                while(i > 0)
       -                        *p++ = se[--i];
       -        }
       -        *p++ = '\0';
       -}
       -
       -static char*
       -xdodtoa(char *s1, double f, int chr, int prec, int *decpt, int *rsign)
       -{
       -        char s2[NSIGNIF+10];
       -        double g, h;
       -        int e, d, i;
       -        int c2, sign, oerr;
       -
       -        if(chr == 'F')
       -                chr = 'f';
       -        if(prec > NSIGNIF)
       -                prec = NSIGNIF;
       -        if(prec < 0)
       -                prec = 0;
       -        if(__isNaN(f)) {
       -                *decpt = 9999;
       -                *rsign = 0;
       -                strcpy(s1, "nan");
       -                return &s1[3];
       -        }
       -        sign = 0;
       -        if(f < 0) {
       -                f = -f;
       -                sign++;
       -        }
       -        *rsign = sign;
       -        if(__isInf(f, 1) || __isInf(f, -1)) {
       -                *decpt = 9999;
       -                strcpy(s1, "inf");
       -                return &s1[3];
       -        }
       -
       -        e = 0;
       -        g = f;
       -        if(g != 0) {
       -                frexp(f, &e);
       -                e = (int)(e * .301029995664);
       -                if(e >= -150 && e <= +150) {
       -                        d = 0;
       -                        h = f;
       -                } else {
       -                        d = e/2;
       -                        h = f * pow10(-d);
       -                }
       -                g = h * pow10(d-e);
       -                while(g < 1) {
       -                        e--;
       -                        g = h * pow10(d-e);
       -                }
       -                while(g >= 10) {
       -                        e++;
       -                        g = h * pow10(d-e);
       -                }
       -        }
       -
       -        /*
       -         * convert NSIGNIF digits and convert
       -         * back to get accuracy.
       -         */
       -        for(i=0; i<NSIGNIF; i++) {
       -                d = (int)g;
       -                s1[i] = d + '0';
       -                g = (g - d) * 10;
       -        }
       -        s1[i] = 0;
       -
       -        /*
       -         * try decimal rounding to eliminate 9s
       -         */
       -        c2 = prec + 1;
       -        if(chr == 'f')
       -                c2 += e;
       -        oerr = errno;
       -        if(c2 >= NSIGNIF-2) {
       -                strcpy(s2, s1);
       -                d = e;
       -                s1[NSIGNIF-2] = '0';
       -                s1[NSIGNIF-1] = '0';
       -                xaddexp(s1+NSIGNIF, e-NSIGNIF+1);
       -                g = fmtstrtod(s1, nil);
       -                if(g == f)
       -                        goto found;
       -                if(xadd(s1, NSIGNIF-3, 1)) {
       -                        e++;
       -                        xaddexp(s1+NSIGNIF, e-NSIGNIF+1);
       -                }
       -                g = fmtstrtod(s1, nil);
       -                if(g == f)
       -                        goto found;
       -                strcpy(s1, s2);
       -                e = d;
       -        }
       -
       -        /*
       -         * convert back so s1 gets exact answer
       -         */
       -        for(d = 0; d < 10; d++) {
       -                xaddexp(s1+NSIGNIF, e-NSIGNIF+1);
       -                g = fmtstrtod(s1, nil);
       -                if(f > g) {
       -                        if(xadd(s1, NSIGNIF-1, 1))
       -                                e--;
       -                        continue;
       -                }
       -                if(f < g) {
       -                        if(xsub(s1, NSIGNIF-1, 1))
       -                                e++;
       -                        continue;
       -                }
       -                break;
       -        }
       -
       -found:
       -        errno = oerr;
       -
       -        /*
       -         * sign
       -         */
       -        d = 0;
       -        i = 0;
       -
       -        /*
       -         * round & adjust 'f' digits
       -         */
       -        c2 = prec + 1;
       -        if(chr == 'f'){
       -                if(xadd(s1, c2+e, 5))
       -                        e++;
       -                c2 += e;
       -                if(c2 < 0){
       -                        c2 = 0;
       -                        e = -prec - 1;
       -                }
       -        }else{
       -                if(xadd(s1, c2, 5))
       -                        e++;
       -        }
       -        if(c2 > NSIGNIF){
       -                c2 = NSIGNIF;
       -        }
       -
       -        *decpt = e + 1;
       -
       -        /*
       -         * terminate the converted digits
       -         */
       -        s1[c2] = '\0';
       -        return &s1[c2];
       -}
       -
       -/*
       - * this function works like the standard dtoa, if you want it.
       - */
       -#if 0
       -static char*
       -__dtoa(double f, int mode, int ndigits, int *decpt, int *rsign, char **rve)
       -{
       -        static char s2[NSIGNIF + 10];
       -        char *es;
       -        int chr, prec;
       -
       -        switch(mode) {
       -        /* like 'e' */
       -        case 2:
       -        case 4:
       -        case 6:
       -        case 8:
       -                chr = 'e';
       -                break;
       -        /* like 'g' */
       -        case 0:
       -        case 1:
       -        default:
       -                chr = 'g';
       -                break;
       -        /* like 'f' */
       -        case 3:
       -        case 5:
       -        case 7:
       -        case 9:
       -                chr = 'f';
       -                break;
       -        }
       -
       -        if(chr != 'f' && ndigits){
       -                ndigits--;
       -        }
       -        prec = ndigits;
       -        if(prec > NSIGNIF)
       -                prec = NSIGNIF;
       -        if(ndigits == 0)
       -                prec = NSIGNIF;
       -        es = xdodtoa(s2, f, chr, prec, decpt, rsign);
       -
       -        /*
       -         * strip trailing 0
       -         */
       -        for(; es > s2 + 1; es--){
       -                if(es[-1] != '0'){
       -                        break;
       -                }
       -        }
       -        *es = '\0';
       -        if(rve != NULL)
       -                *rve = es;
       -        return s2;
       -}
       -#endif
       -
       -static int
       -fmtzdotpad(Fmt *f, int n, int pt)
       -{
       -        char *t, *s;
       -        int i;
       -        Rune *rt, *rs;
       -
       -        if(f->runes){
       -                rt = (Rune*)f->to;
       -                rs = (Rune*)f->stop;
       -                for(i = 0; i < n; i++){
       -                        if(i == pt){
       -                                FMTRCHAR(f, rt, rs, '.');
       -                        }
       -                        FMTRCHAR(f, rt, rs, '0');
       -                }
       -                f->nfmt += rt - (Rune*)f->to;
       -                f->to = rt;
       -        }else{
       -                t = (char*)f->to;
       -                s = (char*)f->stop;
       -                for(i = 0; i < n; i++){
       -                        if(i == pt){
       -                                FMTCHAR(f, t, s, '.');
       -                        }
       -                        FMTCHAR(f, t, s, '0');
       -                }
       -                f->nfmt += t - (char *)f->to;
       -                f->to = t;
       -        }
       -        return 0;
       -}
       -
       -int
       -__efgfmt(Fmt *fmt)
       -{
       -        double f;
       -        char s1[NSIGNIF+10];
       -        int e, d, n;
       -        int c1, c2, c3, c4, ucase, sign, chr, prec, fl;
       -
       -        f = va_arg(fmt->args, double);
       -        prec = FDEFLT;
       -        fl = fmt->flags;
       -        fmt->flags = 0;
       -        if(fl & FmtPrec)
       -                prec = fmt->prec;
       -        chr = fmt->r;
       -        ucase = 0;
       -        if(chr == 'E'){
       -                chr = 'e';
       -                ucase = 1;
       -        }else if(chr == 'F'){
       -                chr = 'f';
       -                ucase = 1;
       -        }else if(chr == 'G'){
       -                chr = 'g';
       -                ucase = 1;
       -        }
       -        if(prec > 0 && chr == 'g')
       -                prec--;
       -        if(prec < 0)
       -                prec = 0;
       -
       -        xdodtoa(s1, f, chr, prec, &e, &sign);
       -        e--;
       -        if(*s1 == 'i' || *s1 == 'n'){
       -                if(ucase){
       -                        if(*s1 == 'i'){
       -                                strcpy(s1, "INF");
       -                        }else{
       -                                strcpy(s1, "NAN");
       -                        }
       -                }
       -                fmt->flags = fl & (FmtWidth|FmtLeft);
       -                return __fmtcpy(fmt, (const void*)s1, 3, 3);
       -        }
       -
       -        /*
       -         * copy into final place
       -         * c1 digits of leading '0'
       -         * c2 digits from conversion
       -         * c3 digits of trailing '0'
       -         * c4 digits after '.'
       -         */
       -        c1 = 0;
       -        c2 = prec + 1;
       -        c3 = 0;
       -        c4 = prec;
       -        switch(chr) {
       -        default:
       -                chr = 'e';
       -                break;
       -        case 'g':
       -                /*
       -                 * decide on 'e' of 'f' style convers
       -                 */
       -                if(e >= -4 && e <= prec) {
       -                        c1 = -e;
       -                        c4 = prec - e;
       -                        chr = 'h';        /* flag for 'f' style */
       -                }
       -                break;
       -        case 'f':
       -                c1 = -e;
       -                if(c1 > prec)
       -                        c1 = prec + 1;
       -                c2 += e;
       -                break;
       -        }
       -
       -        /*
       -         * clean up c1 c2 and c3
       -         */
       -        if(c1 < 0)
       -                c1 = 0;
       -        if(c2 < 0)
       -                c2 = 0;
       -        if(c2 > NSIGNIF) {
       -                c3 = c2-NSIGNIF;
       -                c2 = NSIGNIF;
       -        }
       -
       -        /*
       -         * trim trailing zeros for %g
       -         */
       -        if(!(fl & FmtSharp)
       -        && (chr == 'g' || chr == 'h')){
       -                if(c4 >= c3){
       -                        c4 -= c3;
       -                        c3 = 0;
       -                }else{
       -                        c3 -= c4;
       -                        c4 = 0;
       -                }
       -                while(c4 && c2 > 1 && s1[c2 - 1] == '0'){
       -                        c4--;
       -                        c2--;
       -                }
       -        }
       -
       -        /*
       -         * calculate the total length
       -         */
       -        n = c1 + c2 + c3;
       -        if(sign || (fl & (FmtSign|FmtSpace)))
       -                n++;
       -        if(c4 || (fl & FmtSharp)){
       -                n++;
       -        }
       -        if(chr == 'e' || chr == 'g'){
       -                n += 4;
       -                if(e >= 100)
       -                        n++;
       -        }
       -
       -        /*
       -         * pad to width if right justified
       -         */
       -        if((fl & (FmtWidth|FmtLeft)) == FmtWidth && n < fmt->width){
       -                if(fl & FmtZero){
       -                        c1 += fmt->width - n;
       -                }else{
       -                        if(__fmtpad(fmt, fmt->width - n) < 0){
       -                                return -1;
       -                        }
       -                }
       -        }
       -
       -        /*
       -         * sign
       -         */
       -        d = 0;
       -        if(sign)
       -                d = '-';
       -        else if(fl & FmtSign)
       -                d = '+';
       -        else if(fl & FmtSpace)
       -                d = ' ';
       -        if(d && fmtrune(fmt, d) < 0){
       -                return -1;
       -        }
       -
       -        /*
       -         * copy digits
       -         */
       -        c4 = c1 + c2 + c3 - c4;
       -        if(c1 > 0){
       -                if(fmtzdotpad(fmt, c1, c4) < 0){
       -                        return -1;
       -                }
       -                c4 -= c1;
       -        }
       -        d = 0;
       -        if(c4 >= 0 && c4 < c2){
       -                if(__fmtcpy(fmt, s1, c4, c4) < 0 || fmtrune(fmt, '.') < 0)
       -                        return -1;
       -                d = c4;
       -                c2 -= c4;
       -                c4 = -1;
       -        }
       -        if(__fmtcpy(fmt, (const void*)(s1 + d), c2, c2) < 0){
       -                return -1;
       -        }
       -        c4 -= c2;
       -        if(c3 > 0){
       -                if(fmtzdotpad(fmt, c3, c4) < 0){
       -                        return -1;
       -                }
       -                c4 -= c3;
       -        }
       -
       -        /*
       -         * strip trailing '0' on g conv
       -         */
       -        if((fl & FmtSharp) && c4 == 0 && fmtrune(fmt, '.') < 0){
       -                return -1;
       -        }
       -        if(chr == 'e' || chr == 'g') {
       -                d = 0;
       -                if(ucase)
       -                        s1[d++] = 'E';
       -                else
       -                        s1[d++] = 'e';
       -                c1 = e;
       -                if(c1 < 0) {
       -                        s1[d++] = '-';
       -                        c1 = -c1;
       -                } else
       -                        s1[d++] = '+';
       -                if(c1 >= 100) {
       -                        s1[d++] = c1/100 + '0';
       -                        c1 = c1%100;
       -                }
       -                s1[d++] = c1/10 + '0';
       -                s1[d++] = c1%10 + '0';
       -                if(__fmtcpy(fmt, s1, d, d) < 0){
       -                        return -1;
       -                }
       -        }
       -        if((fl & (FmtWidth|FmtLeft)) == (FmtWidth|FmtLeft) && n < fmt->width){
       -                if(__fmtpad(fmt, fmt->width - n) < 0){
       -                        return -1;
       -                }
       -        }
       -        return 0;
       -}
   DIR diff --git a/src/libfmt/fmt.c b/src/libfmt/fmt.c
       t@@ -1,221 +0,0 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
       - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       -#include <stdarg.h>
       -#include <string.h>
       -#include "utf.h"
       -#include "fmt.h"
       -#include "fmtdef.h"
       -
       -enum
       -{
       -        Maxfmt = 64
       -};
       -
       -typedef struct Convfmt Convfmt;
       -struct Convfmt
       -{
       -        int        c;
       -        volatile        Fmts        fmt;        /* for spin lock in fmtfmt; avoids race due to write order */
       -};
       -
       -struct
       -{
       -        /* lock by calling __fmtlock, __fmtunlock */
       -        int        nfmt;
       -        Convfmt        fmt[Maxfmt];
       -} fmtalloc;
       -
       -static Convfmt knownfmt[] = {
       -        ' ',        __flagfmt,
       -        '#',        __flagfmt,
       -        '%',        __percentfmt,
       -        '+',        __flagfmt,
       -        ',',        __flagfmt,
       -        '-',        __flagfmt,
       -        'C',        __runefmt,        /* Plan 9 addition */
       -        'E',        __efgfmt,
       -        'F',        __efgfmt,        /* ANSI only */
       -        'G',        __efgfmt,
       -        'L',        __flagfmt,        /* ANSI only */
       -        'S',        __runesfmt,        /* Plan 9 addition */
       -        'X',        __ifmt,
       -        'b',        __ifmt,                /* Plan 9 addition */
       -        'c',        __charfmt,
       -        'd',        __ifmt,
       -        'e',        __efgfmt,
       -        'f',        __efgfmt,
       -        'g',        __efgfmt,
       -        'h',        __flagfmt,
       -        'i',        __ifmt,                /* ANSI only */
       -        'l',        __flagfmt,
       -        'n',        __countfmt,
       -        'o',        __ifmt,
       -        'p',        __ifmt,
       -        'r',        __errfmt,
       -        's',        __strfmt,
       -        'u',        __flagfmt,        /* in Unix, __ifmt */
       -        'x',        __ifmt,
       -        0,        nil,
       -};
       -
       -
       -int        (*fmtdoquote)(int);
       -
       -/*
       - * __fmtlock() must be set
       - */
       -static int
       -__fmtinstall(int c, Fmts f)
       -{
       -        Convfmt *p, *ep;
       -
       -        if(c<=0 || c>=65536)
       -                return -1;
       -        if(!f)
       -                f = __badfmt;
       -
       -        ep = &fmtalloc.fmt[fmtalloc.nfmt];
       -        for(p=fmtalloc.fmt; p<ep; p++)
       -                if(p->c == c)
       -                        break;
       -
       -        if(p == &fmtalloc.fmt[Maxfmt])
       -                return -1;
       -
       -        p->fmt = f;
       -        if(p == ep){        /* installing a new format character */
       -                fmtalloc.nfmt++;
       -                p->c = c;
       -        }
       -
       -        return 0;
       -}
       -
       -int
       -fmtinstall(int c, Fmts f)
       -{
       -        int ret;
       -
       -        __fmtlock();
       -        ret = __fmtinstall(c, f);
       -        __fmtunlock();
       -        return ret;
       -}
       -
       -static Fmts
       -fmtfmt(int c)
       -{
       -        Convfmt *p, *ep;
       -
       -        ep = &fmtalloc.fmt[fmtalloc.nfmt];
       -        for(p=fmtalloc.fmt; p<ep; p++)
       -                if(p->c == c){
       -                        while(p->fmt == nil)        /* loop until value is updated */
       -                                ;
       -                        return p->fmt;
       -                }
       -
       -        /* is this a predefined format char? */
       -        __fmtlock();
       -        for(p=knownfmt; p->c; p++)
       -                if(p->c == c){
       -                        __fmtinstall(p->c, p->fmt);
       -                        __fmtunlock();
       -                        return p->fmt;
       -                }
       -        __fmtunlock();
       -
       -        return __badfmt;
       -}
       -
       -void*
       -__fmtdispatch(Fmt *f, void *fmt, int isrunes)
       -{
       -        Rune rune, r;
       -        int i, n;
       -
       -        f->flags = 0;
       -        f->width = f->prec = 0;
       -
       -        for(;;){
       -                if(isrunes){
       -                        r = *(Rune*)fmt;
       -                        fmt = (Rune*)fmt + 1;
       -                }else{
       -                        fmt = (char*)fmt + chartorune(&rune, (char*)fmt);
       -                        r = rune;
       -                }
       -                f->r = r;
       -                switch(r){
       -                case '\0':
       -                        return nil;
       -                case '.':
       -                        f->flags |= FmtWidth|FmtPrec;
       -                        continue;
       -                case '0':
       -                        if(!(f->flags & FmtWidth)){
       -                                f->flags |= FmtZero;
       -                                continue;
       -                        }
       -                        /* fall through */
       -                case '1': case '2': case '3': case '4':
       -                case '5': case '6': case '7': case '8': case '9':
       -                        i = 0;
       -                        while(r >= '0' && r <= '9'){
       -                                i = i * 10 + r - '0';
       -                                if(isrunes){
       -                                        r = *(Rune*)fmt;
       -                                        fmt = (Rune*)fmt + 1;
       -                                }else{
       -                                        r = *(char*)fmt;
       -                                        fmt = (char*)fmt + 1;
       -                                }
       -                        }
       -                        if(isrunes)
       -                                fmt = (Rune*)fmt - 1;
       -                        else
       -                                fmt = (char*)fmt - 1;
       -                numflag:
       -                        if(f->flags & FmtWidth){
       -                                f->flags |= FmtPrec;
       -                                f->prec = i;
       -                        }else{
       -                                f->flags |= FmtWidth;
       -                                f->width = i;
       -                        }
       -                        continue;
       -                case '*':
       -                        i = va_arg(f->args, int);
       -                        if(i < 0){
       -                                /*
       -                                 * negative precision =>
       -                                 * ignore the precision.
       -                                 */
       -                                if(f->flags & FmtPrec){
       -                                        f->flags &= ~FmtPrec;
       -                                        f->prec = 0;
       -                                        continue;
       -                                }
       -                                i = -i;
       -                                f->flags |= FmtLeft;
       -                        }
       -                        goto numflag;
       -                }
       -                n = (*fmtfmt(r))(f);
       -                if(n < 0)
       -                        return nil;
       -                if(n == 0)
       -                        return fmt;
       -        }
       -}
   DIR diff --git a/src/libfmt/fmtdef.h b/src/libfmt/fmtdef.h
       t@@ -1,121 +0,0 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
       - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       -/*
       - * dofmt -- format to a buffer
       - * the number of characters formatted is returned,
       - * or -1 if there was an error.
       - * if the buffer is ever filled, flush is called.
       - * it should reset the buffer and return whether formatting should continue.
       - */
       -#define uchar _fmtuchar
       -#define ushort _fmtushort
       -#define uint _fmtuint
       -#define ulong _fmtulong
       -#define vlong _fmtvlong
       -#define uvlong _fmtuvlong
       -
       -#define USED(x) if(x);else
       -
       -typedef unsigned char                uchar;
       -typedef unsigned short                ushort;
       -typedef unsigned int                uint;
       -typedef unsigned long                ulong;
       -
       -#ifndef NOVLONGS
       -typedef unsigned long long        uvlong;
       -typedef long long                vlong;
       -#endif
       -
       -#define nil                0        /* cannot be ((void*)0) because used for function pointers */
       -
       -typedef int (*Fmts)(Fmt*);
       -
       -typedef struct Quoteinfo Quoteinfo;
       -struct Quoteinfo
       -{
       -        int        quoted;                /* if set, string must be quoted */
       -        int        nrunesin;        /* number of input runes that can be accepted */
       -        int        nbytesin;        /* number of input bytes that can be accepted */
       -        int        nrunesout;        /* number of runes that will be generated */
       -        int        nbytesout;        /* number of bytes that will be generated */
       -};
       -
       -void        *__fmtflush(Fmt*, void*, int);
       -void        *__fmtdispatch(Fmt*, void*, int);
       -int        __floatfmt(Fmt*, double);
       -int        __fmtpad(Fmt*, int);
       -int        __rfmtpad(Fmt*, int);
       -int        __fmtFdFlush(Fmt*);
       -
       -int        __efgfmt(Fmt*);
       -int        __charfmt(Fmt*);
       -int        __runefmt(Fmt*);
       -int        __runesfmt(Fmt*);
       -int        __countfmt(Fmt*);
       -int        __flagfmt(Fmt*);
       -int        __percentfmt(Fmt*);
       -int        __ifmt(Fmt*);
       -int        __strfmt(Fmt*);
       -int        __badfmt(Fmt*);
       -int        __fmtcpy(Fmt*, const void*, int, int);
       -int        __fmtrcpy(Fmt*, const void*, int n);
       -int        __errfmt(Fmt *f);
       -
       -double        __fmtpow10(int);
       -
       -void        __fmtlock(void);
       -void        __fmtunlock(void);
       -
       -#define FMTCHAR(f, t, s, c)\
       -        do{\
       -        if(t + 1 > (char*)s){\
       -                t = __fmtflush(f, t, 1);\
       -                if(t != nil)\
       -                        s = f->stop;\
       -                else\
       -                        return -1;\
       -        }\
       -        *t++ = c;\
       -        }while(0)
       -
       -#define FMTRCHAR(f, t, s, c)\
       -        do{\
       -        if(t + 1 > (Rune*)s){\
       -                t = __fmtflush(f, t, sizeof(Rune));\
       -                if(t != nil)\
       -                        s = f->stop;\
       -                else\
       -                        return -1;\
       -        }\
       -        *t++ = c;\
       -        }while(0)
       -
       -#define FMTRUNE(f, t, s, r)\
       -        do{\
       -        Rune _rune;\
       -        int _runelen;\
       -        if(t + UTFmax > (char*)s && t + (_runelen = runelen(r)) > (char*)s){\
       -                t = __fmtflush(f, t, _runelen);\
       -                if(t != nil)\
       -                        s = f->stop;\
       -                else\
       -                        return -1;\
       -        }\
       -        if(r < Runeself)\
       -                *t++ = r;\
       -        else{\
       -                _rune = r;\
       -                t += runetochar(t, &_rune);\
       -        }\
       -        }while(0)
   DIR diff --git a/src/libfmt/fmtfd.c b/src/libfmt/fmtfd.c
       t@@ -1,46 +0,0 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
       - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       -#include <stdarg.h>
       -#include <string.h>
       -#include "utf.h"
       -#include "fmt.h"
       -#include "fmtdef.h"
       -
       -/*
       - * public routine for final flush of a formatting buffer
       - * to a file descriptor; returns total char count.
       - */
       -int
       -fmtfdflush(Fmt *f)
       -{
       -        if(__fmtFdFlush(f) <= 0)
       -                return -1;
       -        return f->nfmt;
       -}
       -
       -/*
       - * initialize an output buffer for buffered printing
       - */
       -int
       -fmtfdinit(Fmt *f, int fd, char *buf, int size)
       -{
       -        f->runes = 0;
       -        f->start = buf;
       -        f->to = buf;
       -        f->stop = buf + size;
       -        f->flush = __fmtFdFlush;
       -        f->farg = (void*)fd;
       -        f->nfmt = 0;
       -        return 0;
       -}
   DIR diff --git a/src/libfmt/fmtfdflush.c b/src/libfmt/fmtfdflush.c
       t@@ -1,33 +0,0 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
       - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       -#include <stdarg.h>
       -#include <unistd.h>
       -#include "fmt.h"
       -#include "fmtdef.h"
       -
       -/*
       - * generic routine for flushing a formatting buffer
       - * to a file descriptor
       - */
       -int
       -__fmtFdFlush(Fmt *f)
       -{
       -        int n;
       -
       -        n = (char*)f->to - (char*)f->start;
       -        if(n && write((int)f->farg, f->start, n) != n)
       -                return 0;
       -        f->to = f->start;
       -        return 1;
       -}
   DIR diff --git a/src/libfmt/fmtlock.c b/src/libfmt/fmtlock.c
       t@@ -1,28 +0,0 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
       - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       -#include <stdarg.h>
       -#include "fmt.h"
       -#include "fmtdef.h"
       -
       -void
       -__fmtlock(void)
       -{
       -        ;
       -}
       -
       -void
       -__fmtunlock(void)
       -{
       -        ;
       -}
   DIR diff --git a/src/libfmt/fmtprint.c b/src/libfmt/fmtprint.c
       t@@ -1,47 +0,0 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
       - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       -#include <stdarg.h>
       -#include <string.h>
       -#include "utf.h"
       -#include "fmt.h"
       -#include "fmtdef.h"
       -
       -
       -/*
       - * format a string into the output buffer
       - * designed for formats which themselves call fmt,
       - * but ignore any width flags
       - */
       -int
       -fmtprint(Fmt *f, char *fmt, ...)
       -{
       -        va_list va;
       -        int n;
       -
       -        f->flags = 0;
       -        f->width = 0;
       -        f->prec = 0;
       -        va = f->args;
       -        va_start(f->args, fmt);
       -        n = dofmt(f, fmt);
       -        va_end(f->args);
       -        f->flags = 0;
       -        f->width = 0;
       -        f->prec = 0;
       -        f->args = va;
       -        if(n >= 0)
       -                return 0;
       -        return n;
       -}
       -
   DIR diff --git a/src/libfmt/fmtquote.c b/src/libfmt/fmtquote.c
       t@@ -1,262 +0,0 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
       - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       -#include <stdarg.h>
       -#include <string.h>
       -#include "utf.h"
       -#include "fmt.h"
       -#include "fmtdef.h"
       -
       -/*
       - * How many bytes of output UTF will be produced by quoting (if necessary) this string?
       - * How many runes? How much of the input will be consumed?
       - * The parameter q is filled in by __quotesetup.
       - * The string may be UTF or Runes (s or r).
       - * Return count does not include NUL.
       - * Terminate the scan at the first of:
       - *        NUL in input
       - *        count exceeded in input
       - *        count exceeded on output
       - * *ninp is set to number of input bytes accepted.
       - * nin may be <0 initially, to avoid checking input by count.
       - */
       -void
       -__quotesetup(char *s, Rune *r, int nin, int nout, Quoteinfo *q, int sharp, int runesout)
       -{
       -        int w;
       -        Rune c;
       -
       -        q->quoted = 0;
       -        q->nbytesout = 0;
       -        q->nrunesout = 0;
       -        q->nbytesin = 0;
       -        q->nrunesin = 0;
       -        if(sharp || nin==0 || (s && *s=='\0') || (r && *r=='\0')){
       -                if(nout < 2)
       -                        return;
       -                q->quoted = 1;
       -                q->nbytesout = 2;
       -                q->nrunesout = 2;
       -        }
       -        for(; nin!=0; nin-=w){
       -                if(s)
       -                        w = chartorune(&c, s);
       -                else{
       -                        c = *r;
       -                        w = runelen(c);
       -                }
       -
       -                if(c == '\0')
       -                        break;
       -                if(runesout){
       -                        if(q->nrunesout+1 > nout)
       -                                break;
       -                }else{
       -                        if(q->nbytesout+w > nout)
       -                                break;
       -                }
       -
       -                if((c <= L' ') || (c == L'\'') || (fmtdoquote!=nil && fmtdoquote(c))){
       -                        if(!q->quoted){
       -                                if(runesout){
       -                                        if(1+q->nrunesout+1+1 > nout)        /* no room for quotes */
       -                                                break;
       -                                }else{
       -                                        if(1+q->nbytesout+w+1 > nout)        /* no room for quotes */
       -                                                break;
       -                                }
       -                                q->nrunesout += 2;        /* include quotes */
       -                                q->nbytesout += 2;        /* include quotes */
       -                                q->quoted = 1;
       -                        }
       -                        if(c == '\'')        {
       -                                if(runesout){
       -                                        if(1+q->nrunesout+1 > nout)        /* no room for quotes */
       -                                                break;
       -                                }else{
       -                                        if(1+q->nbytesout+w > nout)        /* no room for quotes */
       -                                                break;
       -                                }
       -                                q->nbytesout++;
       -                                q->nrunesout++;        /* quotes reproduce as two characters */
       -                        }
       -                }
       -
       -                /* advance input */
       -                if(s)
       -                        s += w;
       -                else
       -                        r++;
       -                q->nbytesin += w;
       -                q->nrunesin++;
       -
       -                /* advance output */
       -                q->nbytesout += w;
       -                q->nrunesout++;
       -        }
       -}
       -
       -static int
       -qstrfmt(char *sin, Rune *rin, Quoteinfo *q, Fmt *f)
       -{
       -        Rune r, *rm, *rme;
       -        char *t, *s, *m, *me;
       -        Rune *rt, *rs;
       -        ulong fl;
       -        int nc, w;
       -
       -        m = sin;
       -        me = m + q->nbytesin;
       -        rm = rin;
       -        rme = rm + q->nrunesin;
       -
       -        w = f->width;
       -        fl = f->flags;
       -        if(f->runes){
       -                if(!(fl & FmtLeft) && __rfmtpad(f, w - q->nrunesout) < 0)
       -                        return -1;
       -        }else{
       -                if(!(fl & FmtLeft) && __fmtpad(f, w - q->nbytesout) < 0)
       -                        return -1;
       -        }
       -        t = (char*)f->to;
       -        s = (char*)f->stop;
       -        rt = (Rune*)f->to;
       -        rs = (Rune*)f->stop;
       -        if(f->runes)
       -                FMTRCHAR(f, rt, rs, '\'');
       -        else
       -                FMTRUNE(f, t, s, '\'');
       -        for(nc = q->nrunesin; nc > 0; nc--){
       -                if(sin){
       -                        r = *(uchar*)m;
       -                        if(r < Runeself)
       -                                m++;
       -                        else if((me - m) >= UTFmax || fullrune(m, me-m))
       -                                m += chartorune(&r, m);
       -                        else
       -                                break;
       -                }else{
       -                        if(rm >= rme)
       -                                break;
       -                        r = *(uchar*)rm++;
       -                }
       -                if(f->runes){
       -                        FMTRCHAR(f, rt, rs, r);
       -                        if(r == '\'')
       -                                FMTRCHAR(f, rt, rs, r);
       -                }else{
       -                        FMTRUNE(f, t, s, r);
       -                        if(r == '\'')
       -                                FMTRUNE(f, t, s, r);
       -                }
       -        }
       -
       -        if(f->runes){
       -                FMTRCHAR(f, rt, rs, '\'');
       -                USED(rs);
       -                f->nfmt += rt - (Rune *)f->to;
       -                f->to = rt;
       -                if(fl & FmtLeft && __rfmtpad(f, w - q->nrunesout) < 0)
       -                        return -1;
       -        }else{
       -                FMTRUNE(f, t, s, '\'');
       -                USED(s);
       -                f->nfmt += t - (char *)f->to;
       -                f->to = t;
       -                if(fl & FmtLeft && __fmtpad(f, w - q->nbytesout) < 0)
       -                        return -1;
       -        }
       -        return 0;
       -}
       -
       -int
       -__quotestrfmt(int runesin, Fmt *f)
       -{
       -        int outlen;
       -        Rune *r;
       -        char *s;
       -        Quoteinfo q;
       -
       -        f->flags &= ~FmtPrec;        /* ignored for %q %Q, so disable for %s %S in easy case */
       -        if(runesin){
       -                r = va_arg(f->args, Rune *);
       -                s = nil;
       -        }else{
       -                s = va_arg(f->args, char *);
       -                r = nil;
       -        }
       -        if(!s && !r)
       -                return __fmtcpy(f, (void*)"<nil>", 5, 5);
       -
       -        if(f->flush)
       -                outlen = 0x7FFFFFFF;        /* if we can flush, no output limit */
       -        else if(f->runes)
       -                outlen = (Rune*)f->stop - (Rune*)f->to;
       -        else
       -                outlen = (char*)f->stop - (char*)f->to;
       -
       -        __quotesetup(s, r, -1, outlen, &q, f->flags&FmtSharp, f->runes);
       -//print("bytes in %d bytes out %d runes in %d runesout %d\n", q.nbytesin, q.nbytesout, q.nrunesin, q.nrunesout);
       -
       -        if(runesin){
       -                if(!q.quoted)
       -                        return __fmtrcpy(f, r, q.nrunesin);
       -                return qstrfmt(nil, r, &q, f);
       -        }
       -
       -        if(!q.quoted)
       -                return __fmtcpy(f, s, q.nrunesin, q.nbytesin);
       -        return qstrfmt(s, nil, &q, f);
       -}
       -
       -int
       -quotestrfmt(Fmt *f)
       -{
       -        return __quotestrfmt(0, f);
       -}
       -
       -int
       -quoterunestrfmt(Fmt *f)
       -{
       -        return __quotestrfmt(1, f);
       -}
       -
       -void
       -quotefmtinstall(void)
       -{
       -        fmtinstall('q', quotestrfmt);
       -        fmtinstall('Q', quoterunestrfmt);
       -}
       -
       -int
       -__needsquotes(char *s, int *quotelenp)
       -{
       -        Quoteinfo q;
       -
       -        __quotesetup(s, nil, -1, 0x7FFFFFFF, &q, 0, 0);
       -        *quotelenp = q.nbytesout;
       -
       -        return q.quoted;
       -}
       -
       -int
       -__runeneedsquotes(Rune *r, int *quotelenp)
       -{
       -        Quoteinfo q;
       -
       -        __quotesetup(nil, r, -1, 0x7FFFFFFF, &q, 0, 0);
       -        *quotelenp = q.nrunesout;
       -
       -        return q.quoted;
       -}
   DIR diff --git a/src/libfmt/fmtrune.c b/src/libfmt/fmtrune.c
       t@@ -1,40 +0,0 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
       - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       -#include <stdarg.h>
       -#include <string.h>
       -#include "utf.h"
       -#include "fmt.h"
       -#include "fmtdef.h"
       -
       -int
       -fmtrune(Fmt *f, int r)
       -{
       -        Rune *rt;
       -        char *t;
       -        int n;
       -
       -        if(f->runes){
       -                rt = (Rune*)f->to;
       -                FMTRCHAR(f, rt, f->stop, r);
       -                f->to = rt;
       -                n = 1;
       -        }else{
       -                t = (char*)f->to;
       -                FMTRUNE(f, t, f->stop, r);
       -                n = t - (char*)f->to;
       -                f->to = t;
       -        }
       -        f->nfmt += n;
       -        return 0;
       -}
   DIR diff --git a/src/libfmt/fmtstr.c b/src/libfmt/fmtstr.c
       t@@ -1,65 +0,0 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
       - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       -#include <stdarg.h>
       -#include <string.h>
       -#include <stdlib.h>
       -#include "utf.h"
       -#include "fmt.h"
       -#include "fmtdef.h"
       -
       -static int
       -fmtStrFlush(Fmt *f)
       -{
       -        char *s;
       -        int n;
       -
       -        n = (int)f->farg;
       -        n += 256;
       -        f->farg = (void*)n;
       -        s = (char*)f->start;
       -        f->start = realloc(s, n);
       -        if(f->start == nil){
       -                f->start = s;
       -                return 0;
       -        }
       -        f->to = (char*)f->start + ((char*)f->to - s);
       -        f->stop = (char*)f->start + n - 1;
       -        return 1;
       -}
       -
       -int
       -fmtstrinit(Fmt *f)
       -{
       -        int n;
       -
       -        f->runes = 0;
       -        n = 32;
       -        f->start = malloc(n);
       -        if(f->start == nil)
       -                return -1;
       -        f->to = f->start;
       -        f->stop = (char*)f->start + n - 1;
       -        f->flush = fmtStrFlush;
       -        f->farg = (void*)n;
       -        f->nfmt = 0;
       -        return 0;
       -}
       -
       -char*
       -fmtstrflush(Fmt *f)
       -{
       -        *(char*)f->to = '\0';
       -        f->to = f->start;
       -        return (char*)f->start;
       -}
   DIR diff --git a/src/libfmt/fmtvprint.c b/src/libfmt/fmtvprint.c
       t@@ -1,46 +0,0 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
       - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       -#include <stdarg.h>
       -#include <string.h>
       -#include "utf.h"
       -#include "fmt.h"
       -#include "fmtdef.h"
       -
       -
       -/*
       - * format a string into the output buffer
       - * designed for formats which themselves call fmt,
       - * but ignore any width flags
       - */
       -int
       -fmtvprint(Fmt *f, char *fmt, va_list args)
       -{
       -        va_list va;
       -        int n;
       -
       -        f->flags = 0;
       -        f->width = 0;
       -        f->prec = 0;
       -        va = f->args;
       -        f->args = args;
       -        n = dofmt(f, fmt);
       -        f->flags = 0;
       -        f->width = 0;
       -        f->prec = 0;
       -        f->args = va;
       -        if(n >= 0)
       -                return 0;
       -        return n;
       -}
       -
   DIR diff --git a/src/libfmt/fprint.c b/src/libfmt/fprint.c
       t@@ -1,28 +0,0 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
       - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       -#include <stdarg.h>
       -#include "utf.h"
       -#include "fmt.h"
       -
       -int
       -fprint(int fd, char *fmt, ...)
       -{
       -        int n;
       -        va_list args;
       -
       -        va_start(args, fmt);
       -        n = vfprint(fd, fmt, args);
       -        va_end(args);
       -        return n;
       -}
   DIR diff --git a/src/libfmt/mkfile b/src/libfmt/mkfile
       t@@ -1,57 +0,0 @@
       -PLAN9=../..
       -<$PLAN9/src/mkhdr
       -
       -LIB=libfmt.a
       -
       -NUM=\
       -        charstod.$O\
       -        pow10.$O\
       -
       -# Could add errfmt, but we want to pick it up from lib9 instead.
       -OFILES=\
       -        dofmt.$O\
       -        errfmt.$O\
       -        fltfmt.$O\
       -        fmt.$O\
       -        fmtfd.$O\
       -        fmtfdflush.$O\
       -        fmtlock.$O\
       -        fmtprint.$O\
       -        fmtquote.$O\
       -        fmtrune.$O\
       -        fmtstr.$O\
       -        fmtvprint.$O\
       -        fprint.$O\
       -        nan64.$O\
       -        print.$O\
       -        runefmtstr.$O\
       -        runeseprint.$O\
       -        runesmprint.$O\
       -        runesnprint.$O\
       -        runesprint.$O\
       -        runevseprint.$O\
       -        runevsmprint.$O\
       -        runevsnprint.$O\
       -        seprint.$O\
       -        smprint.$O\
       -        snprint.$O\
       -        sprint.$O\
       -        strtod.$O\
       -        vfprint.$O\
       -        vseprint.$O\
       -        vsmprint.$O\
       -        vsnprint.$O\
       -        $NUM\
       -
       -HFILES=\
       -        fmtdef.h\
       -        $PLAN9/include/fmt.h\
       -
       -<$PLAN9/src/mksyslib
       -
       -$NAN.$O: nan.h
       -strtod.$O: nan.h
       -
       -test: $LIB test.$O
       -        $CC -o test test.$O $LIB -L$PLAN9/lib -lutf
       -
   DIR diff --git a/src/libfmt/nan.h b/src/libfmt/nan.h
       t@@ -1,4 +0,0 @@
       -extern double __NaN(void);
       -extern double __Inf(int);
       -extern int __isNaN(double);
       -extern int __isInf(double, int);
   DIR diff --git a/src/libfmt/nan64.c b/src/libfmt/nan64.c
       t@@ -1,76 +0,0 @@
       -/*
       - * 64-bit IEEE not-a-number routines.
       - * This is big/little-endian portable assuming that 
       - * the 64-bit doubles and 64-bit integers have the
       - * same byte ordering.
       - */
       -
       -#include "nan.h"
       -
       -#ifdef __APPLE__
       -#define _NEEDLL
       -#endif
       -
       -typedef unsigned long long uvlong;
       -typedef unsigned long ulong;
       -
       -#ifdef _NEEDLL
       -static uvlong uvnan    = 0x7FF0000000000001LL;
       -static uvlong uvinf    = 0x7FF0000000000000LL;
       -static uvlong uvneginf = 0xFFF0000000000000LL;
       -#else
       -static uvlong uvnan    = 0x7FF0000000000001;
       -static uvlong uvinf    = 0x7FF0000000000000;
       -static uvlong uvneginf = 0xFFF0000000000000;
       -#endif
       -
       -double
       -__NaN(void)
       -{
       -        uvlong *p;
       -
       -        /* gcc complains about "return *(double*)&uvnan;" */
       -        p = &uvnan;
       -        return *(double*)p;
       -}
       -
       -int
       -__isNaN(double d)
       -{
       -        uvlong x;
       -        double *p;
       -
       -        p = &d;
       -        x = *(uvlong*)p;
       -        return (ulong)(x>>32)==0x7FF00000 && !__isInf(d, 0);
       -}
       -
       -double
       -__Inf(int sign)
       -{
       -        uvlong *p;
       -
       -        if(sign < 0)
       -                p = &uvinf;
       -        else
       -                p = &uvneginf;
       -        return *(double*)p;
       -}
       -
       -int
       -__isInf(double d, int sign)
       -{
       -        uvlong x;
       -        double *p;
       -
       -        p = &d;
       -        x = *(uvlong*)p;
       -        if(sign == 0)
       -                return x==uvinf || x==uvneginf;
       -        else if(sign > 0)
       -                return x==uvinf;
       -        else
       -                return x==uvneginf;
       -}
       -
       -
   DIR diff --git a/src/libfmt/pow10.c b/src/libfmt/pow10.c
       t@@ -1,57 +0,0 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
       - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       -#include <stdarg.h>
       -#include <string.h>
       -#include "utf.h"
       -#include "fmt.h"
       -#include "fmtdef.h"
       -
       -/*
       - * this table might overflow 127-bit exponent representations.
       - * in that case, truncate it after 1.0e38.
       - * it is important to get all one can from this
       - * routine since it is used in atof to scale numbers.
       - * the presumption is that C converts fp numbers better
       - * than multipication of lower powers of 10.
       - */
       -
       -static
       -double        tab[] =
       -{
       -        1.0e0, 1.0e1, 1.0e2, 1.0e3, 1.0e4, 1.0e5, 1.0e6, 1.0e7, 1.0e8, 1.0e9,
       -        1.0e10,1.0e11,1.0e12,1.0e13,1.0e14,1.0e15,1.0e16,1.0e17,1.0e18,1.0e19,
       -        1.0e20,1.0e21,1.0e22,1.0e23,1.0e24,1.0e25,1.0e26,1.0e27,1.0e28,1.0e29,
       -        1.0e30,1.0e31,1.0e32,1.0e33,1.0e34,1.0e35,1.0e36,1.0e37,1.0e38,1.0e39,
       -        1.0e40,1.0e41,1.0e42,1.0e43,1.0e44,1.0e45,1.0e46,1.0e47,1.0e48,1.0e49,
       -        1.0e50,1.0e51,1.0e52,1.0e53,1.0e54,1.0e55,1.0e56,1.0e57,1.0e58,1.0e59,
       -        1.0e60,1.0e61,1.0e62,1.0e63,1.0e64,1.0e65,1.0e66,1.0e67,1.0e68,1.0e69,
       -};
       -
       -double
       -__fmtpow10(int n)
       -{
       -        int m;
       -
       -        if(n < 0) {
       -                n = -n;
       -                if(n < (int)(sizeof(tab)/sizeof(tab[0])))
       -                        return 1/tab[n];
       -                m = n/2;
       -                return __fmtpow10(-m) * __fmtpow10(m-n);
       -        }
       -        if(n < (int)(sizeof(tab)/sizeof(tab[0])))
       -                return tab[n];
       -        m = n/2;
       -        return __fmtpow10(m) * __fmtpow10(n-m);
       -}
   DIR diff --git a/src/libfmt/print.3 b/src/libfmt/print.3
       t@@ -1,469 +0,0 @@
       -.TH PRINT 3
       -.de EX
       -.nf
       -.ft B
       -..
       -.de EE
       -.fi
       -.ft R
       -..
       -.SH NAME
       -print, fprint, sprint, snprint, seprint, smprint, vfprint, vsnprint, vseprint, vsmprint \- print formatted output
       -.SH SYNOPSIS
       -.B #include <utf.h>
       -.PP
       -.B #include <fmt.h>
       -.PP
       -.ta \w'\fLchar* 'u
       -.B
       -int        print(char *format, ...)
       -.PP
       -.B
       -int        fprint(int fd, char *format, ...)
       -.PP
       -.B
       -int        sprint(char *s, char *format, ...)
       -.PP
       -.B
       -int        snprint(char *s, int len, char *format, ...)
       -.PP
       -.B
       -char*        seprint(char *s, char *e, char *format, ...)
       -.PP
       -.B
       -char*        smprint(char *format, ...)
       -.PP
       -.B
       -int        runesprint(Rune *s, char *format, ...)
       -.PP
       -.B
       -int        runesnprint(Rune *s, int len, char *format, ...)
       -.PP
       -.B
       -Rune*        runeseprint(Rune *s, Rune *e, char *format, ...)
       -.PP
       -.B
       -Rune*        runesmprint(char *format, ...)
       -.PP
       -.B
       -int        vfprint(int fd, char *format, va_list v)
       -.PP
       -.B
       -int        vsnprint(char *s, int len, char *format, va_list v)
       -.PP
       -.B
       -char*        vseprint(char *s, char *e, char *format, va_list v)
       -.PP
       -.B
       -char*        vsmprint(char *format, va_list v)
       -.PP
       -.B
       -int        runevsnprint(Rune *s, int len, char *format, va_list v)
       -.PP
       -.B
       -Rune*        runevseprint(Rune *s, Rune *e, char *format, va_list v)
       -.PP
       -.B
       -Rune*        runevsmprint(Rune *format, va_list v)
       -.PP
       -.B
       -.SH DESCRIPTION
       -.I Print
       -writes text to the standard output.
       -.I Fprint
       -writes to the named output
       -file descriptor.
       -.I Sprint
       -places text
       -followed by the NUL character
       -.RB ( \e0 )
       -in consecutive bytes starting at
       -.IR s ;
       -it is the user's responsibility to ensure that
       -enough storage is available.
       -Each function returns the number of bytes
       -transmitted (not including the NUL
       -in the case of
       -.IR sprint ),
       -or
       -a negative value if an output error was encountered.
       -.PP
       -.I Snprint
       -is like
       -.IR sprint ,
       -but will not place more than
       -.I len
       -bytes in
       -.IR s .
       -Its result is always NUL-terminated and holds the maximal
       -number of characters that can fit.
       -.I Seprint
       -is like
       -.IR snprint ,
       -except that the end is indicated by a pointer
       -.I e
       -rather than a count and the return value points to the terminating NUL of the
       -resulting string.
       -.I Smprint
       -is like
       -.IR sprint ,
       -except that it prints into and returns a string of the required length, which is
       -allocated by
       -.IR malloc (3).
       -.PP
       -The routines
       -.IR runesprint ,
       -.IR runesnprint ,
       -.IR runeseprint ,
       -and
       -.I runesmprint
       -are the same as
       -.IR sprint ,
       -.IR snprint ,
       -.IR seprint
       -and
       -.I smprint
       -except that their output is rune strings instead of byte strings.
       -.PP
       -Finally, the routines
       -.IR vfprint ,
       -.IR vsnprint ,
       -.IR vseprint ,
       -.IR vsmprint ,
       -.IR runevsnprint ,
       -.IR runevseprint ,
       -and
       -.I runevsmprint
       -are like their
       -.BR v-less
       -relatives except they take as arguments a
       -.B va_list
       -parameter, so they can be called within a variadic function.
       -The Example section shows a representative usage.
       -.PP
       -Each of these functions
       -converts, formats, and prints its
       -trailing arguments
       -under control of a
       -.IR format 
       -string.
       -The
       -format
       -contains two types of objects:
       -plain characters, which are simply copied to the
       -output stream,
       -and conversion specifications,
       -each of which results in fetching of
       -zero or more
       -arguments.
       -The results are undefined if there are arguments of the
       -wrong type or too few
       -arguments for the format.
       -If the format is exhausted while
       -arguments remain, the excess
       -is ignored.
       -.PP
       -Each conversion specification has the following format:
       -.IP
       -.B "% [flags] verb
       -.PP
       -The verb is a single character and each flag is a single character or a
       -(decimal) numeric string.
       -Up to two numeric strings may be used;
       -the first is called
       -.IR width ,
       -the second
       -.IR precision .
       -A period can be used to separate them, and if the period is
       -present then
       -.I width
       -and
       -.I precision
       -are taken to be zero if missing, otherwise they are `omitted'.
       -Either or both of the numbers may be replaced with the character
       -.BR * ,
       -meaning that the actual number will be obtained from the argument list
       -as an integer.
       -The flags and numbers are arguments to
       -the
       -.I verb
       -described below.
       -.PP
       -The numeric verbs
       -.BR d ,
       -.BR i ,
       -.BR u ,
       -.BR o ,
       -.BR b ,
       -.BR x ,
       -and
       -.B X
       -format their arguments in decimal, decimal,
       -unsigned decimal, octal, binary, hexadecimal, and upper case hexadecimal.
       -Each interprets the flags
       -.BR 0 ,
       -.BR h ,
       -.BR hh ,
       -.BR l ,
       -.BR + ,
       -.BR - ,
       -.BR , ,
       -and
       -.B #
       -to mean pad with zeros,
       -short, byte, long, always print a sign, left justified, commas every three digits,
       -and alternate format.
       -Also, a space character in the flag
       -position is like
       -.BR + ,
       -but prints a space instead of a plus sign for non-negative values.
       -If neither
       -short nor long is specified,
       -then the argument is an
       -.BR int .
       -If an unsigned verb is specified,
       -then the argument is interpreted as a
       -positive number and no sign is output;
       -space and
       -.B +
       -flags are ignored for unsigned verbs.
       -If two
       -.B l
       -flags are given,
       -then the argument is interpreted as a
       -.B vlong
       -(usually an 8-byte, sometimes a 4-byte integer).
       -If
       -.I precision
       -is not omitted, the number is padded on the left with zeros
       -until at least
       -.I precision
       -digits appear.
       -If
       -.I precision
       -is explicitly 0, and the number is 0,
       -no digits are generated, and alternate formatting
       -does not apply.
       -Then, if alternate format is specified,
       -for
       -.B o
       -conversion, the number is preceded by a
       -.B 0
       -if it doesn't already begin with one.
       -For non-zero numbers and
       -.B x
       -conversion, the number is preceded by
       -.BR 0x ;
       -for
       -.B X
       -conversion, the number is preceded by
       -.BR 0X .
       -Finally, if
       -.I width
       -is not omitted, the number is padded on the left (or right, if
       -left justification is specified) with enough blanks to
       -make the field at least
       -.I width
       -characters long.
       -.PP
       -The floating point verbs
       -.BR f ,
       -.BR e ,
       -.BR E ,
       -.BR g ,
       -and
       -.B G
       -take a
       -.B double
       -argument.
       -Each interprets the flags
       -.BR 0 ,
       -.BR L
       -.BR + ,
       -.BR - ,
       -and
       -.B #
       -to mean pad with zeros,
       -long double argument,
       -always print a sign,
       -left justified,
       -and
       -alternate format.
       -.I Width
       -is the minimum field width and,
       -if the converted value takes up less than
       -.I width
       -characters, it is padded on the left (or right, if `left justified')
       -with spaces.
       -.I Precision
       -is the number of digits that are converted after the decimal place for
       -.BR e ,
       -.BR E ,
       -and
       -.B f
       -conversions,
       -and
       -.I precision
       -is the maximum number of significant digits for
       -.B g
       -and
       -.B G
       -conversions.
       -The 
       -.B f
       -verb produces output of the form
       -.RB [ - ] digits [ .digits\fR].
       -.B E
       -conversion appends an exponent
       -.BR E [ - ] digits ,
       -and
       -.B e
       -conversion appends an exponent
       -.BR e [ - ] digits .
       -The
       -.B g
       -verb will output the argument in either
       -.B e
       -or
       -.B f
       -with the goal of producing the smallest output.
       -Also, trailing zeros are omitted from the fraction part of
       -the output, and a trailing decimal point appears only if it is followed
       -by a digit.
       -The
       -.B G
       -verb is similar, but uses
       -.B E
       -format instead of
       -.BR e .
       -When alternate format is specified, the result will always contain a decimal point,
       -and for
       -.B g
       -and
       -.B G
       -conversions, trailing zeros are not removed.
       -.PP
       -The
       -.B s
       -verb copies a string
       -(pointer to
       -.BR char )
       -to the output.
       -The number of characters copied
       -.RI ( n )
       -is the minimum
       -of the size of the string and
       -.IR precision .
       -These
       -.I n
       -characters are justified within a field of
       -.I width
       -characters as described above.
       -If a
       -.I precision
       -is given, it is safe for the string not to be nul-terminated
       -as long as it is at least
       -.I precision
       -characters (not bytes!) long.
       -The
       -.B S
       -verb is similar, but it interprets its pointer as an array
       -of runes (see
       -.IR utf (7));
       -the runes are converted to
       -.SM UTF
       -before output.
       -.PP
       -The
       -.B c
       -verb copies a single
       -.B char
       -(promoted to
       -.BR int )
       -justified within a field of
       -.I width
       -characters as described above.
       -The
       -.B C
       -verb is similar, but works on runes.
       -.PP
       -The
       -.B p
       -verb formats a pointer value.
       -At the moment, it is a synonym for
       -.BR x ,
       -but that will change if pointers and integers are different sizes.
       -.PP
       -The
       -.B r
       -verb takes no arguments; it copies the error string returned by a call to
       -.IR strerror (3)
       -with an argument of
       -.IR errno.
       -.PP
       -Custom verbs may be installed using
       -.IR fmtinstall (3).
       -.SH EXAMPLE
       -This function prints an error message with a variable
       -number of arguments and then quits.
       -.IP
       -.EX
       -.ta 6n +6n +6n
       -void fatal(char *msg, ...)
       -{
       -        char buf[1024], *out;
       -        va_list arg;
       -
       -        out = vseprint(buf, buf+sizeof buf, "Fatal error: ");
       -        va_start(arg, msg);
       -        out = vseprint(out, buf+sizeof buf, msg, arg);
       -        va_end(arg);
       -        write(2, buf, out-buf);
       -        exit(1);
       -}
       -.EE
       -.SH SEE ALSO
       -.IR fmtinstall (3),
       -.IR fprintf (3),
       -.IR utf (7)
       -.SH DIAGNOSTICS
       -Routines that write to a file descriptor or call
       -.IR malloc
       -set
       -.IR errstr .
       -.SH BUGS
       -The formatting is close to that specified for ANSI
       -.IR fprintf (3);
       -the main difference is that
       -.B b
       -and
       -.B r
       -are not in ANSI and some
       -.B C9X
       -verbs are missing.
       -Also, and distinctly not a bug,
       -.I print
       -and friends generate
       -.SM UTF
       -rather than
       -.SM ASCII.
       -.PP
       -There is no
       -.BR runeprint ,
       -.BR runefprint ,
       -etc. because runes are byte-order dependent and should not be written directly to a file; use the
       -UTF output of
       -.I print
       -or
       -.I fprint
       -instead.
       -Also,
       -.I sprint
       -is deprecated for safety reasons; use
       -.IR snprint ,
       -.IR seprint ,
       -or
       -.I smprint
       -instead.
       -Safety also precludes the existence of
       -.IR runesprint .
   DIR diff --git a/src/libfmt/print.c b/src/libfmt/print.c
       t@@ -1,28 +0,0 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
       - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       -#include <stdarg.h>
       -#include "utf.h"
       -#include "fmt.h"
       -
       -int
       -print(char *fmt, ...)
       -{
       -        int n;
       -        va_list args;
       -
       -        va_start(args, fmt);
       -        n = vfprint(1, fmt, args);
       -        va_end(args);
       -        return n;
       -}
   DIR diff --git a/src/libfmt/runefmtstr.c b/src/libfmt/runefmtstr.c
       t@@ -1,65 +0,0 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
       - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       -#include <stdarg.h>
       -#include <string.h>
       -#include <stdlib.h>
       -#include "utf.h"
       -#include "fmt.h"
       -#include "fmtdef.h"
       -
       -static int
       -runeFmtStrFlush(Fmt *f)
       -{
       -        Rune *s;
       -        int n;
       -
       -        n = (int)f->farg;
       -        n += 256;
       -        f->farg = (void*)n;
       -        s = (Rune*)f->start;
       -        f->start = realloc(s, sizeof(Rune)*n);
       -        if(f->start == nil){
       -                f->start = s;
       -                return 0;
       -        }
       -        f->to = (Rune*)f->start + ((Rune*)f->to - s);
       -        f->stop = (Rune*)f->start + n - 1;
       -        return 1;
       -}
       -
       -int
       -runefmtstrinit(Fmt *f)
       -{
       -        int n;
       -
       -        f->runes = 1;
       -        n = 32;
       -        f->start = malloc(sizeof(Rune)*n);
       -        if(f->start == nil)
       -                return -1;
       -        f->to = f->start;
       -        f->stop = (Rune*)f->start + n - 1;
       -        f->flush = runeFmtStrFlush;
       -        f->farg = (void*)n;
       -        f->nfmt = 0;
       -        return 0;
       -}
       -
       -Rune*
       -runefmtstrflush(Fmt *f)
       -{
       -        *(Rune*)f->to = '\0';
       -        f->to = f->start;
       -        return f->start;
       -}
   DIR diff --git a/src/libfmt/runeseprint.c b/src/libfmt/runeseprint.c
       t@@ -1,30 +0,0 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
       - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       -#include <stdarg.h>
       -#include <string.h>
       -#include "utf.h"
       -#include "fmt.h"
       -#include "fmtdef.h"
       -
       -Rune*
       -runeseprint(Rune *buf, Rune *e, char *fmt, ...)
       -{
       -        Rune *p;
       -        va_list args;
       -
       -        va_start(args, fmt);
       -        p = runevseprint(buf, e, fmt, args);
       -        va_end(args);
       -        return p;
       -}
   DIR diff --git a/src/libfmt/runesmprint.c b/src/libfmt/runesmprint.c
       t@@ -1,30 +0,0 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
       - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       -#include <stdarg.h>
       -#include <string.h>
       -#include "utf.h"
       -#include "fmt.h"
       -#include "fmtdef.h"
       -
       -Rune*
       -runesmprint(char *fmt, ...)
       -{
       -        va_list args;
       -        Rune *p;
       -
       -        va_start(args, fmt);
       -        p = runevsmprint(fmt, args);
       -        va_end(args);
       -        return p;
       -}
   DIR diff --git a/src/libfmt/runesnprint.c b/src/libfmt/runesnprint.c
       t@@ -1,31 +0,0 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
       - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       -#include <stdarg.h>
       -#include <string.h>
       -#include "utf.h"
       -#include "fmt.h"
       -#include "fmtdef.h"
       -
       -int
       -runesnprint(Rune *buf, int len, char *fmt, ...)
       -{
       -        int n;
       -        va_list args;
       -
       -        va_start(args, fmt);
       -        n = runevsnprint(buf, len, fmt, args);
       -        va_end(args);
       -        return n;
       -}
       -
   DIR diff --git a/src/libfmt/runesprint.c b/src/libfmt/runesprint.c
       t@@ -1,30 +0,0 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
       - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       -#include <stdarg.h>
       -#include <string.h>
       -#include "utf.h"
       -#include "fmt.h"
       -#include "fmtdef.h"
       -
       -int
       -runesprint(Rune *buf, char *fmt, ...)
       -{
       -        int n;
       -        va_list args;
       -
       -        va_start(args, fmt);
       -        n = runevsnprint(buf, 256, fmt, args);
       -        va_end(args);
       -        return n;
       -}
   DIR diff --git a/src/libfmt/runevseprint.c b/src/libfmt/runevseprint.c
       t@@ -1,39 +0,0 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
       - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       -#include <stdarg.h>
       -#include <string.h>
       -#include "utf.h"
       -#include "fmt.h"
       -#include "fmtdef.h"
       -
       -Rune*
       -runevseprint(Rune *buf, Rune *e, char *fmt, va_list args)
       -{
       -        Fmt f;
       -
       -        if(e <= buf)
       -                return nil;
       -        f.runes = 1;
       -        f.start = buf;
       -        f.to = buf;
       -        f.stop = e - 1;
       -        f.flush = nil;
       -        f.farg = nil;
       -        f.nfmt = 0;
       -        f.args = args;
       -        dofmt(&f, fmt);
       -        *(Rune*)f.to = '\0';
       -        return (Rune*)f.to;
       -}
       -
   DIR diff --git a/src/libfmt/runevsmprint.c b/src/libfmt/runevsmprint.c
       t@@ -1,37 +0,0 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
       - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       -#include <stdarg.h>
       -#include <stdlib.h>
       -#include "utf.h"
       -#include "fmt.h"
       -#include "fmtdef.h"
       -
       -/*
       - * print into an allocated string buffer
       - */
       -Rune*
       -runevsmprint(char *fmt, va_list args)
       -{
       -        Fmt f;
       -        int n;
       -
       -        if(runefmtstrinit(&f) < 0)
       -                return nil;
       -        f.args = args;
       -        n = dofmt(&f, fmt);
       -        if(n < 0)
       -                return nil;
       -        *(Rune*)f.to = '\0';
       -        return (Rune*)f.start;
       -}
   DIR diff --git a/src/libfmt/runevsnprint.c b/src/libfmt/runevsnprint.c
       t@@ -1,38 +0,0 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
       - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       -#include <stdarg.h>
       -#include <string.h>
       -#include "utf.h"
       -#include "fmt.h"
       -#include "fmtdef.h"
       -
       -int
       -runevsnprint(Rune *buf, int len, char *fmt, va_list args)
       -{
       -        Fmt f;
       -
       -        if(len <= 0)
       -                return -1;
       -        f.runes = 1;
       -        f.start = buf;
       -        f.to = buf;
       -        f.stop = buf + len - 1;
       -        f.flush = nil;
       -        f.farg = nil;
       -        f.nfmt = 0;
       -        f.args = args;
       -        dofmt(&f, fmt);
       -        *(Rune*)f.to = '\0';
       -        return (Rune*)f.to - buf;
       -}
   DIR diff --git a/src/libfmt/seprint.c b/src/libfmt/seprint.c
       t@@ -1,27 +0,0 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
       - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       -#include <stdarg.h>
       -#include "fmt.h"
       -
       -char*
       -seprint(char *buf, char *e, char *fmt, ...)
       -{
       -        char *p;
       -        va_list args;
       -
       -        va_start(args, fmt);
       -        p = vseprint(buf, e, fmt, args);
       -        va_end(args);
       -        return p;
       -}
   DIR diff --git a/src/libfmt/smprint.c b/src/libfmt/smprint.c
       t@@ -1,27 +0,0 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
       - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       -#include <stdarg.h>
       -#include "fmt.h"
       -
       -char*
       -smprint(char *fmt, ...)
       -{
       -        va_list args;
       -        char *p;
       -
       -        va_start(args, fmt);
       -        p = vsmprint(fmt, args);
       -        va_end(args);
       -        return p;
       -}
   DIR diff --git a/src/libfmt/snprint.c b/src/libfmt/snprint.c
       t@@ -1,28 +0,0 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
       - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       -#include <stdarg.h>
       -#include "fmt.h"
       -
       -int
       -snprint(char *buf, int len, char *fmt, ...)
       -{
       -        int n;
       -        va_list args;
       -
       -        va_start(args, fmt);
       -        n = vsnprint(buf, len, fmt, args);
       -        va_end(args);
       -        return n;
       -}
       -
   DIR diff --git a/src/libfmt/sprint.c b/src/libfmt/sprint.c
       t@@ -1,27 +0,0 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
       - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       -#include <stdarg.h>
       -#include "fmt.h"
       -
       -int
       -sprint(char *buf, char *fmt, ...)
       -{
       -        int n;
       -        va_list args;
       -
       -        va_start(args, fmt);
       -        n = vsnprint(buf, 65536, fmt, args);        /* big number, but sprint is deprecated anyway */
       -        va_end(args);
       -        return n;
       -}
   DIR diff --git a/src/libfmt/strtod.c b/src/libfmt/strtod.c
       t@@ -1,539 +0,0 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
       - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       -#include <stdlib.h>
       -#include <math.h>
       -#include <ctype.h>
       -#include <stdlib.h>
       -#include <string.h>
       -#include <errno.h>
       -#include "fmt.h"
       -#include "nan.h"
       -
       -#ifndef nelem
       -#define nelem(x)        (sizeof(x)/sizeof *(x))
       -#endif
       -#define nil ((void*)0)
       -#define ulong _fmtulong
       -typedef unsigned long ulong;
       -
       -static ulong
       -umuldiv(ulong a, ulong b, ulong c)
       -{
       -        double d;
       -
       -        d = ((double)a * (double)b) / (double)c;
       -        if(d >= 4294967295.)
       -                d = 4294967295.;
       -        return (ulong)d;
       -}
       -
       -/*
       - * This routine will convert to arbitrary precision
       - * floating point entirely in multi-precision fixed.
       - * The answer is the closest floating point number to
       - * the given decimal number. Exactly half way are
       - * rounded ala ieee rules.
       - * Method is to scale input decimal between .500 and .999...
       - * with external power of 2, then binary search for the
       - * closest mantissa to this decimal number.
       - * Nmant is is the required precision. (53 for ieee dp)
       - * Nbits is the max number of bits/word. (must be <= 28)
       - * Prec is calculated - the number of words of fixed mantissa.
       - */
       -enum
       -{
       -        Nbits        = 28,                                /* bits safely represented in a ulong */
       -        Nmant        = 53,                                /* bits of precision required */
       -        Prec        = (Nmant+Nbits+1)/Nbits,        /* words of Nbits each to represent mantissa */
       -        Sigbit        = 1<<(Prec*Nbits-Nmant),        /* first significant bit of Prec-th word */
       -        Ndig        = 1500,
       -        One        = (ulong)(1<<Nbits),
       -        Half        = (ulong)(One>>1),
       -        Maxe        = 310,
       -
       -        Fsign        = 1<<0,                /* found - */
       -        Fesign        = 1<<1,                /* found e- */
       -        Fdpoint        = 1<<2,                /* found . */
       -
       -        S0        = 0,                /* _                _S0        +S1        #S2        .S3 */
       -        S1,                        /* _+                #S2        .S3 */
       -        S2,                        /* _+#                #S2        .S4        eS5 */
       -        S3,                        /* _+.                #S4 */
       -        S4,                        /* _+#.#        #S4        eS5 */
       -        S5,                        /* _+#.#e        +S6        #S7 */
       -        S6,                        /* _+#.#e+        #S7 */
       -        S7,                        /* _+#.#e+#        #S7 */
       -};
       -
       -static        int        xcmp(char*, char*);
       -static        int        fpcmp(char*, ulong*);
       -static        void        frnorm(ulong*);
       -static        void        divascii(char*, int*, int*, int*);
       -static        void        mulascii(char*, int*, int*, int*);
       -
       -typedef        struct        Tab        Tab;
       -struct        Tab
       -{
       -        int        bp;
       -        int        siz;
       -        char*        cmp;
       -};
       -
       -double
       -fmtstrtod(const char *as, char **aas)
       -{
       -        int na, ex, dp, bp, c, i, flag, state;
       -        ulong low[Prec], hig[Prec], mid[Prec];
       -        double d;
       -        char *s, a[Ndig];
       -
       -        flag = 0;        /* Fsign, Fesign, Fdpoint */
       -        na = 0;                /* number of digits of a[] */
       -        dp = 0;                /* na of decimal point */
       -        ex = 0;                /* exonent */
       -
       -        state = S0;
       -        for(s=(char*)as;; s++) {
       -                c = *s;
       -                if(c >= '0' && c <= '9') {
       -                        switch(state) {
       -                        case S0:
       -                        case S1:
       -                        case S2:
       -                                state = S2;
       -                                break;
       -                        case S3:
       -                        case S4:
       -                                state = S4;
       -                                break;
       -
       -                        case S5:
       -                        case S6:
       -                        case S7:
       -                                state = S7;
       -                                ex = ex*10 + (c-'0');
       -                                continue;
       -                        }
       -                        if(na == 0 && c == '0') {
       -                                dp--;
       -                                continue;
       -                        }
       -                        if(na < Ndig-50)
       -                                a[na++] = c;
       -                        continue;
       -                }
       -                switch(c) {
       -                case '\t':
       -                case '\n':
       -                case '\v':
       -                case '\f':
       -                case '\r':
       -                case ' ':
       -                        if(state == S0)
       -                                continue;
       -                        break;
       -                case '-':
       -                        if(state == S0)
       -                                flag |= Fsign;
       -                        else
       -                                flag |= Fesign;
       -                case '+':
       -                        if(state == S0)
       -                                state = S1;
       -                        else
       -                        if(state == S5)
       -                                state = S6;
       -                        else
       -                                break;        /* syntax */
       -                        continue;
       -                case '.':
       -                        flag |= Fdpoint;
       -                        dp = na;
       -                        if(state == S0 || state == S1) {
       -                                state = S3;
       -                                continue;
       -                        }
       -                        if(state == S2) {
       -                                state = S4;
       -                                continue;
       -                        }
       -                        break;
       -                case 'e':
       -                case 'E':
       -                        if(state == S2 || state == S4) {
       -                                state = S5;
       -                                continue;
       -                        }
       -                        break;
       -                }
       -                break;
       -        }
       -
       -        /*
       -         * clean up return char-pointer
       -         */
       -        switch(state) {
       -        case S0:
       -                if(xcmp(s, "nan") == 0) {
       -                        if(aas != nil)
       -                                *aas = s+3;
       -                        goto retnan;
       -                }
       -        case S1:
       -                if(xcmp(s, "infinity") == 0) {
       -                        if(aas != nil)
       -                                *aas = s+8;
       -                        goto retinf;
       -                }
       -                if(xcmp(s, "inf") == 0) {
       -                        if(aas != nil)
       -                                *aas = s+3;
       -                        goto retinf;
       -                }
       -        case S3:
       -                if(aas != nil)
       -                        *aas = (char*)as;
       -                goto ret0;        /* no digits found */
       -        case S6:
       -                s--;                /* back over +- */
       -        case S5:
       -                s--;                /* back over e */
       -                break;
       -        }
       -        if(aas != nil)
       -                *aas = s;
       -
       -        if(flag & Fdpoint)
       -        while(na > 0 && a[na-1] == '0')
       -                na--;
       -        if(na == 0)
       -                goto ret0;        /* zero */
       -        a[na] = 0;
       -        if(!(flag & Fdpoint))
       -                dp = na;
       -        if(flag & Fesign)
       -                ex = -ex;
       -        dp += ex;
       -        if(dp < -Maxe){
       -                errno = ERANGE;
       -                goto ret0;        /* underflow by exp */
       -        } else
       -        if(dp > +Maxe)
       -                goto retinf;        /* overflow by exp */
       -
       -        /*
       -         * normalize the decimal ascii number
       -         * to range .[5-9][0-9]* e0
       -         */
       -        bp = 0;                /* binary exponent */
       -        while(dp > 0)
       -                divascii(a, &na, &dp, &bp);
       -        while(dp < 0 || a[0] < '5')
       -                mulascii(a, &na, &dp, &bp);
       -
       -        /* close approx by naive conversion */
       -        mid[0] = 0;
       -        mid[1] = 1;
       -        for(i=0; c=a[i]; i++) {
       -                mid[0] = mid[0]*10 + (c-'0');
       -                mid[1] = mid[1]*10;
       -                if(i >= 8)
       -                        break;
       -        }
       -        low[0] = umuldiv(mid[0], One, mid[1]);
       -        hig[0] = umuldiv(mid[0]+1, One, mid[1]);
       -        for(i=1; i<Prec; i++) {
       -                low[i] = 0;
       -                hig[i] = One-1;
       -        }
       -
       -        /* binary search for closest mantissa */
       -        for(;;) {
       -                /* mid = (hig + low) / 2 */
       -                c = 0;
       -                for(i=0; i<Prec; i++) {
       -                        mid[i] = hig[i] + low[i];
       -                        if(c)
       -                                mid[i] += One;
       -                        c = mid[i] & 1;
       -                        mid[i] >>= 1;
       -                }
       -                frnorm(mid);
       -
       -                /* compare */
       -                c = fpcmp(a, mid);
       -                if(c > 0) {
       -                        c = 1;
       -                        for(i=0; i<Prec; i++)
       -                                if(low[i] != mid[i]) {
       -                                        c = 0;
       -                                        low[i] = mid[i];
       -                                }
       -                        if(c)
       -                                break;        /* between mid and hig */
       -                        continue;
       -                }
       -                if(c < 0) {
       -                        for(i=0; i<Prec; i++)
       -                                hig[i] = mid[i];
       -                        continue;
       -                }
       -
       -                /* only hard part is if even/odd roundings wants to go up */
       -                c = mid[Prec-1] & (Sigbit-1);
       -                if(c == Sigbit/2 && (mid[Prec-1]&Sigbit) == 0)
       -                        mid[Prec-1] -= c;
       -                break;        /* exactly mid */
       -        }
       -
       -        /* normal rounding applies */
       -        c = mid[Prec-1] & (Sigbit-1);
       -        mid[Prec-1] -= c;
       -        if(c >= Sigbit/2) {
       -                mid[Prec-1] += Sigbit;
       -                frnorm(mid);
       -        }
       -        goto out;
       -
       -ret0:
       -        return 0;
       -
       -retnan:
       -        return __NaN();
       -
       -retinf:
       -        /*
       -         * Unix strtod requires these.  Plan 9 would return Inf(0) or Inf(-1). */
       -        errno = ERANGE;
       -        if(flag & Fsign)
       -                return -HUGE_VAL;
       -        return HUGE_VAL;
       -
       -out:
       -        d = 0;
       -        for(i=0; i<Prec; i++)
       -                d = d*One + mid[i];
       -        if(flag & Fsign)
       -                d = -d;
       -        d = ldexp(d, bp - Prec*Nbits);
       -        if(d == 0){        /* underflow */
       -                errno = ERANGE;
       -        }
       -        return d;
       -}
       -
       -static void
       -frnorm(ulong *f)
       -{
       -        int i, c;
       -
       -        c = 0;
       -        for(i=Prec-1; i>0; i--) {
       -                f[i] += c;
       -                c = f[i] >> Nbits;
       -                f[i] &= One-1;
       -        }
       -        f[0] += c;
       -}
       -
       -static int
       -fpcmp(char *a, ulong* f)
       -{
       -        ulong tf[Prec];
       -        int i, d, c;
       -
       -        for(i=0; i<Prec; i++)
       -                tf[i] = f[i];
       -
       -        for(;;) {
       -                /* tf *= 10 */
       -                for(i=0; i<Prec; i++)
       -                        tf[i] = tf[i]*10;
       -                frnorm(tf);
       -                d = (tf[0] >> Nbits) + '0';
       -                tf[0] &= One-1;
       -
       -                /* compare next digit */
       -                c = *a;
       -                if(c == 0) {
       -                        if('0' < d)
       -                                return -1;
       -                        if(tf[0] != 0)
       -                                goto cont;
       -                        for(i=1; i<Prec; i++)
       -                                if(tf[i] != 0)
       -                                        goto cont;
       -                        return 0;
       -                }
       -                if(c > d)
       -                        return +1;
       -                if(c < d)
       -                        return -1;
       -                a++;
       -        cont:;
       -        }
       -        return 0;
       -}
       -
       -static void
       -divby(char *a, int *na, int b)
       -{
       -        int n, c;
       -        char *p;
       -
       -        p = a;
       -        n = 0;
       -        while(n>>b == 0) {
       -                c = *a++;
       -                if(c == 0) {
       -                        while(n) {
       -                                c = n*10;
       -                                if(c>>b)
       -                                        break;
       -                                n = c;
       -                        }
       -                        goto xx;
       -                }
       -                n = n*10 + c-'0';
       -                (*na)--;
       -        }
       -        for(;;) {
       -                c = n>>b;
       -                n -= c<<b;
       -                *p++ = c + '0';
       -                c = *a++;
       -                if(c == 0)
       -                        break;
       -                n = n*10 + c-'0';
       -        }
       -        (*na)++;
       -xx:
       -        while(n) {
       -                n = n*10;
       -                c = n>>b;
       -                n -= c<<b;
       -                *p++ = c + '0';
       -                (*na)++;
       -        }
       -        *p = 0;
       -}
       -
       -static        Tab        tab1[] =
       -{
       -         1,  0, "",
       -         3,  1, "7",
       -         6,  2, "63",
       -         9,  3, "511",
       -        13,  4, "8191",
       -        16,  5, "65535",
       -        19,  6, "524287",
       -        23,  7, "8388607",
       -        26,  8, "67108863",
       -        27,  9, "134217727",
       -};
       -
       -static void
       -divascii(char *a, int *na, int *dp, int *bp)
       -{
       -        int b, d;
       -        Tab *t;
       -
       -        d = *dp;
       -        if(d >= (int)(nelem(tab1)))
       -                d = (int)(nelem(tab1))-1;
       -        t = tab1 + d;
       -        b = t->bp;
       -        if(memcmp(a, t->cmp, t->siz) > 0)
       -                d--;
       -        *dp -= d;
       -        *bp += b;
       -        divby(a, na, b);
       -}
       -
       -static void
       -mulby(char *a, char *p, char *q, int b)
       -{
       -        int n, c;
       -
       -        n = 0;
       -        *p = 0;
       -        for(;;) {
       -                q--;
       -                if(q < a)
       -                        break;
       -                c = *q - '0';
       -                c = (c<<b) + n;
       -                n = c/10;
       -                c -= n*10;
       -                p--;
       -                *p = c + '0';
       -        }
       -        while(n) {
       -                c = n;
       -                n = c/10;
       -                c -= n*10;
       -                p--;
       -                *p = c + '0';
       -        }
       -}
       -
       -static        Tab        tab2[] =
       -{
       -         1,  1, "",                                /* dp = 0-0 */
       -         3,  3, "125",
       -         6,  5, "15625",
       -         9,  7, "1953125",
       -        13, 10, "1220703125",
       -        16, 12, "152587890625",
       -        19, 14, "19073486328125",
       -        23, 17, "11920928955078125",
       -        26, 19, "1490116119384765625",
       -        27, 19, "7450580596923828125",                /* dp 8-9 */
       -};
       -
       -static void
       -mulascii(char *a, int *na, int *dp, int *bp)
       -{
       -        char *p;
       -        int d, b;
       -        Tab *t;
       -
       -        d = -*dp;
       -        if(d >= (int)(nelem(tab2)))
       -                d = (int)(nelem(tab2))-1;
       -        t = tab2 + d;
       -        b = t->bp;
       -        if(memcmp(a, t->cmp, t->siz) < 0)
       -                d--;
       -        p = a + *na;
       -        *bp -= b;
       -        *dp += d;
       -        *na += d;
       -        mulby(a, p+d, p, b);
       -}
       -
       -static int
       -xcmp(char *a, char *b)
       -{
       -        int c1, c2;
       -
       -        while(c1 = *b++) {
       -                c2 = *a++;
       -                if(isupper(c2))
       -                        c2 = tolower(c2);
       -                if(c1 != c2)
       -                        return 1;
       -        }
       -        return 0;
       -}
   DIR diff --git a/src/libfmt/strtod.h b/src/libfmt/strtod.h
       t@@ -1,4 +0,0 @@
       -extern double __NaN(void);
       -extern double __Inf(int);
       -extern double __isNaN(double);
       -extern double __isInf(double, int);
   DIR diff --git a/src/libfmt/test.c b/src/libfmt/test.c
       t@@ -1,39 +0,0 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
       - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       -#include <stdarg.h>
       -#include <utf.h>
       -#include "fmt.h"
       -
       -int
       -main(int argc, char *argv[])
       -{
       -        quotefmtinstall();
       -        print("hello world\n");
       -        print("x: %x\n", 0x87654321);
       -        print("u: %u\n", 0x87654321);
       -        print("d: %d\n", 0x87654321);
       -        print("s: %s\n", "hi there");
       -        print("q: %q\n", "hi i'm here");
       -        print("c: %c\n", '!');
       -        print("g: %g %g %g\n", 3.14159, 3.14159e10, 3.14159e-10);
       -        print("e: %e %e %e\n", 3.14159, 3.14159e10, 3.14159e-10);
       -        print("f: %f %f %f\n", 3.14159, 3.14159e10, 3.14159e-10);
       -        print("smiley: %C\n", (Rune)0x263a);
       -        print("%g %.18\n", 2e25, 2e25);
       -        print("%2.18g\n", 1.0);
       -        print("%f\n", 3.1415927/4);
       -        print("%d\n", 23);
       -        print("%i\n", 23);
       -        return 0;
       -}
   DIR diff --git a/src/libfmt/vfprint.c b/src/libfmt/vfprint.c
       t@@ -1,31 +0,0 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
       - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       -#include <stdarg.h>
       -#include "fmt.h"
       -#include "fmtdef.h"
       -
       -int
       -vfprint(int fd, char *fmt, va_list args)
       -{
       -        Fmt f;
       -        char buf[256];
       -        int n;
       -
       -        fmtfdinit(&f, fd, buf, sizeof(buf));
       -        f.args = args;
       -        n = dofmt(&f, fmt);
       -        if(n > 0 && __fmtFdFlush(&f) == 0)
       -                return -1;
       -        return n;
       -}
   DIR diff --git a/src/libfmt/vseprint.c b/src/libfmt/vseprint.c
       t@@ -1,37 +0,0 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
       - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       -#include <stdarg.h>
       -#include "fmt.h"
       -#include "fmtdef.h"
       -
       -char*
       -vseprint(char *buf, char *e, char *fmt, va_list args)
       -{
       -        Fmt f;
       -
       -        if(e <= buf)
       -                return nil;
       -        f.runes = 0;
       -        f.start = buf;
       -        f.to = buf;
       -        f.stop = e - 1;
       -        f.flush = 0;
       -        f.farg = nil;
       -        f.nfmt = 0;
       -        f.args = args;
       -        dofmt(&f, fmt);
       -        *(char*)f.to = '\0';
       -        return (char*)f.to;
       -}
       -
   DIR diff --git a/src/libfmt/vsmprint.c b/src/libfmt/vsmprint.c
       t@@ -1,36 +0,0 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
       - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       -#include <stdlib.h>
       -#include <stdarg.h>
       -#include "fmt.h"
       -#include "fmtdef.h"
       -
       -/*
       - * print into an allocated string buffer
       - */
       -char*
       -vsmprint(char *fmt, va_list args)
       -{
       -        Fmt f;
       -        int n;
       -
       -        if(fmtstrinit(&f) < 0)
       -                return nil;
       -        f.args = args;
       -        n = dofmt(&f, fmt);
       -        if(n < 0)
       -                return nil;
       -        *(char*)f.to = '\0';
       -        return (char*)f.start;
       -}
   DIR diff --git a/src/libfmt/vsnprint.c b/src/libfmt/vsnprint.c
       t@@ -1,37 +0,0 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
       - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       -#include <stdlib.h>
       -#include <stdarg.h>
       -#include "fmt.h"
       -#include "fmtdef.h"
       -
       -int
       -vsnprint(char *buf, int len, char *fmt, va_list args)
       -{
       -        Fmt f;
       -
       -        if(len <= 0)
       -                return -1;
       -        f.runes = 0;
       -        f.start = buf;
       -        f.to = buf;
       -        f.stop = buf + len - 1;
       -        f.flush = 0;
       -        f.farg = nil;
       -        f.nfmt = 0;
       -        f.args = args;
       -        dofmt(&f, fmt);
       -        *(char*)f.to = '\0';
       -        return (char*)f.to - buf;
       -}
   DIR diff --git a/src/libfs/fs.c b/src/libfs/fs.c
       t@@ -5,6 +5,7 @@
        #include <libc.h>
        #include <fcall.h>
        #include <fs.h>
       +#include <thread.h>
        #include "fsimpl.h"
        
        static int _fssend(Mux*, void*);
       t@@ -270,7 +271,7 @@ _fsrecv(Mux *mux)
                Fsys *fs;
        
                fs = mux->aux;
       -        n = readn(fs->fd, buf, 4);
       +        n = threadreadn(fs->fd, buf, 4);
                if(n != 4)
                        return nil;
                n = GBIT32(buf);
       t@@ -280,12 +281,12 @@ _fsrecv(Mux *mux)
                        return nil;
                }
                PBIT32(pkt, n);
       -        if(readn(fs->fd, pkt+4, n-4) != n-4){
       +        if(threadreadn(fs->fd, pkt+4, n-4) != n-4){
                        free(pkt);
                        return nil;
                }
                if(pkt[4] == Ropenfd){
       -                if((nfd=recvfd(fs->fd)) < 0){
       +                if((nfd=threadrecvfd(fs->fd)) < 0){
                                fprint(2, "recv fd error: %r\n");
                                free(pkt);
                                return nil;
   DIR diff --git a/src/libfs/read.c b/src/libfs/read.c
       t@@ -12,7 +12,12 @@ fspread(Fid *fid, void *buf, long n, vlong offset)
        {
                Fcall tx, rx;
                void *freep;
       +        uint msize;
        
       +        msize = fid->fs->msize - IOHDRSZ;
       +fprint(2, "n %d msize %d\n", n, msize);
       +        if(n > msize)
       +                n = msize;
                tx.type = Tread;
                tx.fid = fid->fid;
                if(offset == -1){
   DIR diff --git a/src/libfs/write.c b/src/libfs/write.c
       t@@ -7,8 +7,8 @@
        #include <fs.h>
        #include "fsimpl.h"
        
       -long
       -fspwrite(Fid *fid, void *buf, long n, vlong offset)
       +static long
       +_fspwrite(Fid *fid, void *buf, long n, vlong offset)
        {
                Fcall tx, rx;
                void *freep;
       t@@ -40,6 +40,31 @@ fspwrite(Fid *fid, void *buf, long n, vlong offset)
        }
        
        long
       +fspwrite(Fid *fid, void *buf, long n, vlong offset)
       +{
       +        long tot, want, got;
       +        uint msize;
       +
       +        msize = fid->fs->msize - IOHDRSZ;
       +        tot = 0;
       +        while(tot < n){
       +                want = n - tot;
       +                if(want > msize)
       +                        want = msize;
       +                got = _fspwrite(fid, buf, want, offset);
       +                if(got < 0){
       +                        if(tot == 0)
       +                                return got;
       +                        break;
       +                }
       +                tot += got;
       +                if(offset != -1)
       +                        offset += got;
       +        }
       +        return tot;
       +}
       +
       +long
        fswrite(Fid *fid, void *buf, long n)
        {
                return fspwrite(fid, buf, n, -1);
   DIR diff --git a/src/libplumb/mkfile b/src/libplumb/mkfile
       t@@ -5,6 +5,7 @@ LIB=libplumb.a
        OFILES=\
                event.$O\
                mesg.$O\
       +        thread.$O\
        
        HFILES=$PLAN9/include/plumb.h
        
   DIR diff --git a/src/libthread/channel.c b/src/libthread/channel.c
       t@@ -65,9 +65,7 @@ chaninit(Channel *c, int elemsize, int elemcnt)
        {
                if(elemcnt < 0 || elemsize <= 0 || c == nil)
                        return -1;
       -        c->f = 0;
       -        c->n = 0;
       -        c->freed = 0;
       +        memset(c, 0, sizeof *c);
                c->e = elemsize;
                c->s = elemcnt;
                _threaddebug(DBGCHAN, "chaninit %p", c);
       t@@ -104,13 +102,16 @@ alt(Alt *alts)
                 * chanlock.  Instead, we delay the note until we've dropped
                 * the lock.
                 */
       +
       +        /*
       +         * T might be nil here -- the scheduler sends on threadwaitchan
       +         * directly (in non-blocking mode, of course!).
       +         */
                t = _threadgetproc()->thread;
       -        if(t->moribund || _threadexitsallstatus)
       +        if((t && t->moribund) || _threadexitsallstatus)
                        yield();        /* won't return */
                s = _procsplhi();
                lock(&chanlock);
       -        t->alt = alts;
       -        t->chan = Chanalt;
        
                /* test whether any channels can proceed */
                n = 0;
       t@@ -125,7 +126,6 @@ alt(Alt *alts)
                        if(c==nil){
                                unlock(&chanlock);
                                _procsplx(s);
       -                        t->chan = Channone;
                                return -1;
                        }
                        if(canexec(xa))
       t@@ -138,7 +138,6 @@ alt(Alt *alts)
                        if(xa->op == CHANNOBLK){
                                unlock(&chanlock);
                                _procsplx(s);
       -                        t->chan = Channone;
        _threadnalt++;
                                return xa - alts;
                        }
       t@@ -159,6 +158,9 @@ _threadnalt++;
                         * we need to be here.
                         */
                    Again:
       +                t->alt = alts;
       +                t->chan = Chanalt;
       +
                        unlock(&chanlock);
                        _procsplx(s);
                        r = _threadrendezvous((ulong)&c, 0);
   DIR diff --git a/src/libthread/create.c b/src/libthread/create.c
       t@@ -86,6 +86,7 @@ proccreate(void (*f)(void*), void *arg, uint stacksize)
        
                p = _threadgetproc();
                if(p->idle){
       +                fprint(2, "cannot create procs once there is an idle thread\n");
                        werrstr("cannot create procs once there is an idle thread");
                        return -1;
                }
       t@@ -124,6 +125,7 @@ threadcreateidle(void (*f)(void *arg), void *arg, uint stacksize)
                int id;
        
                if(_threadprocs!=1){
       +                fprint(2, "cannot have idle thread in multi-proc program\n");
                        werrstr("cannot have idle thread in multi-proc program");
                        return -1;
                }
       t@@ -153,6 +155,8 @@ _newproc(void (*f)(void *arg), void *arg, uint stacksize, char *name, int grp, i
                else
                        *_threadpq.tail = p;
                _threadpq.tail = &p->next;
       +        if(_threadprocs == 1)
       +                _threadmultiproc();
                _threadprocs++;
                unlock(&_threadpq.lock);
                return p;
   DIR diff --git a/src/libthread/exec-unix.c b/src/libthread/exec-unix.c
       t@@ -2,28 +2,18 @@
        #include <unistd.h>
        #include "threadimpl.h"
        
       +static void efork(int[3], int[2], char*, char**);
        void
       -procexec(Channel *pidc, int fd[3], char *prog, char *args[])
       +threadexec(Channel *pidc, int fd[3], char *prog, char *args[])
        {
       -        int n;
       -        Proc *p;
       -        Thread *t;
       -
       -        _threaddebug(DBGEXEC, "procexec %s", prog);
       -        /* must be only thread in proc */
       -        p = _threadgetproc();
       -        t = p->thread;
       -        if(p->threads.head != t || p->threads.head->nextt != nil){
       -                werrstr("not only thread in proc");
       -        Bad:
       -                _threaddebug(DBGEXEC, "procexec bad %r");
       -                if(pidc)
       -                        sendul(pidc, ~0);
       -                return;
       -        }
       +        int pfd[2];
       +        int n, pid;
       +        char exitstr[ERRMAX];
        
       +        _threaddebug(DBGEXEC, "threadexec %s", prog);
       +        
                /*
       -         * We want procexec to behave like exec; if exec succeeds,
       +         * We want threadexec to behave like exec; if exec succeeds,
                 * never return, and if it fails, return with errstr set.
                 * Unfortunately, the exec happens in another proc since
                 * we have to wait for the exec'ed process to finish.
       t@@ -34,114 +24,77 @@ procexec(Channel *pidc, int fd[3], char *prog, char *args[])
                 * then the proc doing the exec sends the errstr down the
                 * pipe to us.
                 */
       -        if(pipe(p->exec.fd) < 0)
       +        if(pipe(pfd) < 0)
                        goto Bad;
       -        if(fcntl(p->exec.fd[0], F_SETFD, 1) < 0)
       +        if(fcntl(pfd[0], F_SETFD, 1) < 0)
                        goto Bad;
       -        if(fcntl(p->exec.fd[1], F_SETFD, 1) < 0)
       +        if(fcntl(pfd[1], F_SETFD, 1) < 0)
                        goto Bad;
        
       -        /* exec in parallel via the scheduler */
       -        assert(p->needexec==0);
       -        p->exec.prog = prog;
       -        p->exec.args = args;
       -        p->exec.stdfd = fd;
       -        p->needexec = 1;
       -        _sched();
       +        switch(pid = fork()){
       +        case -1:
       +                close(pfd[0]);
       +                close(pfd[1]);
       +                goto Bad;
       +        case 0:
       +                efork(fd, pfd, prog, args);
       +                _exit(0);
       +        default:
       +                break;
       +        }
        
       -        close(p->exec.fd[1]);
       -        if((n = read(p->exec.fd[0], p->exitstr, ERRMAX-1)) > 0){        /* exec failed */
       -                p->exitstr[n] = '\0';
       -                errstr(p->exitstr, ERRMAX);
       -                close(p->exec.fd[0]);
       +        close(pfd[1]);
       +        if((n = read(pfd[0], exitstr, ERRMAX-1)) > 0){        /* exec failed */
       +                exitstr[n] = '\0';
       +                errstr(exitstr, ERRMAX);
       +                close(pfd[0]);
                        goto Bad;
                }
       -        close(p->exec.fd[0]);
       +        close(pfd[0]);
                close(fd[0]);
                if(fd[1] != fd[0])
                        close(fd[1]);
                if(fd[2] != fd[1] && fd[2] != fd[0])
                        close(fd[2]);
                if(pidc)
       -                sendul(pidc, t->ret);
       +                sendul(pidc, pid);
        
       -        _threaddebug(DBGEXEC, "procexec schedexecwait");
       -        /* wait for exec'ed program, then exit */
       -        _schedexecwait();
       -}
       +        _threaddebug(DBGEXEC, "threadexec schedexecwait");
       +        threadexits(0);
        
       -void
       -procexecl(Channel *pidc, int fd[3], char *f, ...)
       -{
       -        procexec(pidc, fd, f, &f+1);
       +Bad:
       +        _threaddebug(DBGEXEC, "threadexec bad %r");
       +        if(pidc)
       +                sendul(pidc, ~0);
        }
        
        void
       -_schedexecwait(void)
       +threadexecl(Channel *pidc, int fd[3], char *f, ...)
        {
       -        int pid;
       -        Channel *c;
       -        Proc *p;
       -        Thread *t;
       -        Waitmsg *w;
       -
       -        p = _threadgetproc();
       -        t = p->thread;
       -        pid = t->ret;
       -        _threaddebug(DBGEXEC, "_schedexecwait %d", t->ret);
       -
       -        for(;;){
       -                w = wait();
       -                if(w == nil)
       -                        break;
       -                if(w->pid == pid)
       -                        break;
       -                free(w);
       -        }
       -        if(w != nil){
       -                if((c = _threadwaitchan) != nil)
       -                        sendp(c, w);
       -                else
       -                        free(w);
       -        }
       -        threadexits("procexec");
       +        threadexec(pidc, fd, f, &f+1);
        }
        
        static void
       -efork(void *ve)
       +efork(int stdfd[3], int fd[2], char *prog, char **args)
        {
                char buf[ERRMAX];
       -        Execargs *e;
                int i;
        
       -        e = ve;
       -        _threaddebug(DBGEXEC, "_schedexec %s -- calling execv", e->prog);
       -        dup(e->stdfd[0], 0);
       -        dup(e->stdfd[1], 1);
       -        dup(e->stdfd[2], 2);
       +        _threaddebug(DBGEXEC, "_schedexec %s -- calling execv", prog);
       +        dup(stdfd[0], 0);
       +        dup(stdfd[1], 1);
       +        dup(stdfd[2], 2);
                for(i=3; i<40; i++)
       -                if(i != e->fd[1])
       +                if(i != fd[1])
                                close(i);
                rfork(RFNOTEG);
       -        execvp(e->prog, e->args);
       +        execvp(prog, args);
                _threaddebug(DBGEXEC, "_schedexec failed: %r");
                rerrstr(buf, sizeof buf);
                if(buf[0]=='\0')
                        strcpy(buf, "exec failed");
       -        write(e->fd[1], buf, strlen(buf));
       -        close(e->fd[1]);
       +        write(fd[1], buf, strlen(buf));
       +        close(fd[1]);
                _exits(buf);
        }
        
       -int
       -_schedexec(Execargs *e)
       -{
       -        int pid;
       -
       -        pid = fork();
       -        if(pid == 0){
       -                efork(e);
       -                _exit(1);
       -        }
       -        return pid;
       -}
   DIR diff --git a/src/libthread/main.c b/src/libthread/main.c
       t@@ -24,6 +24,12 @@ _threaddie(int x)
                        exit(_threadexitsallstatus[0] ? 1 : 0);
        }
        
       +static void
       +_nop(int x)
       +{
       +        USED(x);
       +}
       +
        int
        main(int argc, char **argv)
        {
       t@@ -31,6 +37,7 @@ main(int argc, char **argv)
                Proc *p;
        
                signal(SIGTERM, _threaddie);
       +        signal(SIGCHLD, _nop);
        //        rfork(RFREND);
        
        //_threaddebuglevel = (DBGSCHED|DBGCHAN|DBGREND)^~0;
   DIR diff --git a/src/libthread/mkfile b/src/libthread/mkfile
       t@@ -12,6 +12,7 @@ OFILES=\
                debug.$O\
                exec-unix.$O\
                exit.$O\
       +        fdwait.$O\
                getpid.$O\
                id.$O\
                iocall.$O\
       t@@ -30,6 +31,7 @@ OFILES=\
                memsetd.$O\
                note.$O\
                proctab.$O\
       +        read9pmsg.$O\
                ref.$O\
                rendez.$O\
                sched.$O\
   DIR diff --git a/src/libthread/proctab.c b/src/libthread/proctab.c
       t@@ -6,6 +6,18 @@ enum
                PTABHASH = 257,
        };
        
       +static int multi;
       +static Proc *theproc;
       +
       +void
       +_threadmultiproc(void)
       +{
       +        if(multi == 0){
       +                multi = 1;
       +                _threadsetproc(theproc);
       +        }
       +}
       +
        static Lock ptablock;
        Proc *ptab[PTABHASH];
        
       t@@ -14,6 +26,10 @@ _threadsetproc(Proc *p)
        {
                int h;
        
       +        if(!multi){
       +                theproc = p;
       +                return;
       +        }
                lock(&ptablock);
                h = ((unsigned)p->pid)%PTABHASH;
                p->link = ptab[h];
       t@@ -27,6 +43,9 @@ __threadgetproc(int rm)
                Proc **l, *p;
                int h, pid;
        
       +        if(!multi)
       +                return theproc;
       +
                pid = _threadgetpid();
        
                lock(&ptablock);
   DIR diff --git a/src/libthread/sched.c b/src/libthread/sched.c
       t@@ -1,4 +1,5 @@
        #include <signal.h>
       +#include <errno.h>
        #include "threadimpl.h"
        
        //static Thread        *runthread(Proc*);
       t@@ -67,10 +68,12 @@ _schedinit(void *arg)
                                t = nil;
                                _sched();
                        }
       +/*
                        if(p->needexec){
                                t->ret = _schedexec(&p->exec);
                                p->needexec = 0;
                        }
       +*/
                        if(p->newproc){
                                t->ret = _schedfork(p->newproc);
                                if(t->ret < 0){
       t@@ -90,14 +93,45 @@ _schedinit(void *arg)
        static Thread*
        runthread(Proc *p)
        {
       +        Channel *c;
                Thread *t;
                Tqueue *q;
       +        Waitmsg *w;
       +        int e, sent;
        
                if(p->nthreads==0 || (p->nthreads==1 && p->idle))
                        return nil;
                q = &p->ready;
       +relock:
                lock(&p->readylock);
                if(q->head == nil){
       +                e = errno;
       +                if((c = _threadwaitchan) != nil){
       +                        if(c->n <= c->s){
       +                                sent = 0;
       +                                for(;;){
       +                                        if((w = p->waitmsg) != nil)
       +                                                p->waitmsg = nil;
       +                                        else
       +                                                w = waitnohang();
       +                                        if(w == nil)
       +                                                break;
       +                                        if(sent == 0){
       +                                                unlock(&p->readylock);
       +                                                sent = 1;
       +                                        }
       +                                        if(nbsendp(c, w) != 1)
       +                                                break;
       +                                }
       +                                p->waitmsg = w;
       +                                if(sent)
       +                                        goto relock;
       +                        }
       +                }else{
       +                        while((w = waitnohang()) != nil)
       +                                free(w);
       +                }
       +                errno = e;
                        if(p->idle){
                                if(p->idle->state != Ready){
                                        fprint(2, "everyone is asleep\n");
   DIR diff --git a/src/libthread/threadimpl.h b/src/libthread/threadimpl.h
       t@@ -139,6 +139,7 @@ struct Proc
                void                *arg;                        /* passed between shared and unshared stk */
                char                str[ERRMAX];        /* used by threadexits to avoid malloc */
                char                errbuf[ERRMAX];        /* errstr */
       +        Waitmsg                *waitmsg;
        
                void*        udata;                /* User per-proc data pointer */
        };
       t@@ -181,6 +182,7 @@ void                __threaddebug(ulong, char*, ...);
        void                _threadexitsall(char*);
        void                _threadflagrendez(Thread*);
        Proc*        _threadgetproc(void);
       +extern void        _threadmultiproc(void);
        Proc*        _threaddelproc(void);
        void                _threadsetproc(Proc*);
        void                _threadinitstack(Thread*, void(*)(void*), void*);
       t@@ -195,7 +197,6 @@ long                _xdec(long*);
        void                _xinc(long*);
        void                _threadremove(Proc*, Thread*);
        
       -extern int        _threadmultiproc;
        extern int                        _threaddebuglevel;
        extern char*                _threadexitsallstatus;
        extern Pqueue                _threadpq;
   DIR diff --git a/src/libutf/LICENSE b/src/libutf/LICENSE
       t@@ -1,13 +0,0 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 1998-2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
       - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
   DIR diff --git a/src/libutf/NOTICE b/src/libutf/NOTICE
       t@@ -1,13 +0,0 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 1998-2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
       - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
   DIR diff --git a/src/libutf/README b/src/libutf/README
       t@@ -1,13 +0,0 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 1998-2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
       - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
   DIR diff --git a/src/libutf/lib9.h b/src/libutf/lib9.h
       t@@ -1,17 +0,0 @@
       -#include <string.h>
       -#include "utf.h"
       -
       -#define nil ((void*)0)
       -
       -#define uchar _fmtuchar
       -#define ushort _fmtushort
       -#define uint _fmtuint
       -#define ulong _fmtulong
       -#define vlong _fmtvlong
       -#define uvlong _fmtuvlong
       -
       -typedef unsigned char                uchar;
       -typedef unsigned short                ushort;
       -typedef unsigned int                uint;
       -typedef unsigned long                ulong;
       -
   DIR diff --git a/src/libutf/mkfile b/src/libutf/mkfile
       t@@ -1,31 +0,0 @@
       -PLAN9=../..
       -<$PLAN9/src/mkhdr
       -
       -LIB=libutf.a
       -
       -OFILES=\
       -        rune.$O\
       -        runestrcat.$O\
       -        runestrchr.$O\
       -        runestrcmp.$O\
       -        runestrcpy.$O\
       -        runestrdup.$O\
       -        runestrlen.$O\
       -        runestrecpy.$O\
       -        runestrncat.$O\
       -        runestrncmp.$O\
       -        runestrncpy.$O\
       -        runestrrchr.$O\
       -        runestrstr.$O\
       -        runetype.$O\
       -        utfecpy.$O\
       -        utflen.$O\
       -        utfnlen.$O\
       -        utfrrune.$O\
       -        utfrune.$O\
       -        utfutf.$O\
       -
       -HFILES=\
       -        $PLAN9/include/utf.h\
       -
       -<$PLAN9/src/mksyslib
   DIR diff --git a/src/libutf/rune.c b/src/libutf/rune.c
       t@@ -1,177 +0,0 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
       - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       -#include <stdarg.h>
       -#include <string.h>
       -#include "utf.h"
       -#include "utfdef.h"
       -
       -enum
       -{
       -        Bit1        = 7,
       -        Bitx        = 6,
       -        Bit2        = 5,
       -        Bit3        = 4,
       -        Bit4        = 3,
       -
       -        T1        = ((1<<(Bit1+1))-1) ^ 0xFF,        /* 0000 0000 */
       -        Tx        = ((1<<(Bitx+1))-1) ^ 0xFF,        /* 1000 0000 */
       -        T2        = ((1<<(Bit2+1))-1) ^ 0xFF,        /* 1100 0000 */
       -        T3        = ((1<<(Bit3+1))-1) ^ 0xFF,        /* 1110 0000 */
       -        T4        = ((1<<(Bit4+1))-1) ^ 0xFF,        /* 1111 0000 */
       -
       -        Rune1        = (1<<(Bit1+0*Bitx))-1,                /* 0000 0000 0111 1111 */
       -        Rune2        = (1<<(Bit2+1*Bitx))-1,                /* 0000 0111 1111 1111 */
       -        Rune3        = (1<<(Bit3+2*Bitx))-1,                /* 1111 1111 1111 1111 */
       -
       -        Maskx        = (1<<Bitx)-1,                        /* 0011 1111 */
       -        Testx        = Maskx ^ 0xFF,                        /* 1100 0000 */
       -
       -        Bad        = Runeerror,
       -};
       -
       -int
       -chartorune(Rune *rune, char *str)
       -{
       -        int c, c1, c2;
       -        long l;
       -
       -        /*
       -         * one character sequence
       -         *        00000-0007F => T1
       -         */
       -        c = *(uchar*)str;
       -        if(c < Tx) {
       -                *rune = c;
       -                return 1;
       -        }
       -
       -        /*
       -         * two character sequence
       -         *        0080-07FF => T2 Tx
       -         */
       -        c1 = *(uchar*)(str+1) ^ Tx;
       -        if(c1 & Testx)
       -                goto bad;
       -        if(c < T3) {
       -                if(c < T2)
       -                        goto bad;
       -                l = ((c << Bitx) | c1) & Rune2;
       -                if(l <= Rune1)
       -                        goto bad;
       -                *rune = l;
       -                return 2;
       -        }
       -
       -        /*
       -         * three character sequence
       -         *        0800-FFFF => T3 Tx Tx
       -         */
       -        c2 = *(uchar*)(str+2) ^ Tx;
       -        if(c2 & Testx)
       -                goto bad;
       -        if(c < T4) {
       -                l = ((((c << Bitx) | c1) << Bitx) | c2) & Rune3;
       -                if(l <= Rune2)
       -                        goto bad;
       -                *rune = l;
       -                return 3;
       -        }
       -
       -        /*
       -         * bad decoding
       -         */
       -bad:
       -        *rune = Bad;
       -        return 1;
       -}
       -
       -int
       -runetochar(char *str, Rune *rune)
       -{
       -        long c;
       -
       -        /*
       -         * one character sequence
       -         *        00000-0007F => 00-7F
       -         */
       -        c = *rune;
       -        if(c <= Rune1) {
       -                str[0] = c;
       -                return 1;
       -        }
       -
       -        /*
       -         * two character sequence
       -         *        0080-07FF => T2 Tx
       -         */
       -        if(c <= Rune2) {
       -                str[0] = T2 | (c >> 1*Bitx);
       -                str[1] = Tx | (c & Maskx);
       -                return 2;
       -        }
       -
       -        /*
       -         * three character sequence
       -         *        0800-FFFF => T3 Tx Tx
       -         */
       -        str[0] = T3 |  (c >> 2*Bitx);
       -        str[1] = Tx | ((c >> 1*Bitx) & Maskx);
       -        str[2] = Tx |  (c & Maskx);
       -        return 3;
       -}
       -
       -int
       -runelen(long c)
       -{
       -        Rune rune;
       -        char str[10];
       -
       -        rune = c;
       -        return runetochar(str, &rune);
       -}
       -
       -int
       -runenlen(Rune *r, int nrune)
       -{
       -        int nb, c;
       -
       -        nb = 0;
       -        while(nrune--) {
       -                c = *r++;
       -                if(c <= Rune1)
       -                        nb++;
       -                else
       -                if(c <= Rune2)
       -                        nb += 2;
       -                else
       -                        nb += 3;
       -        }
       -        return nb;
       -}
       -
       -int
       -fullrune(char *str, int n)
       -{
       -        int c;
       -
       -        if(n > 0) {
       -                c = *(uchar*)str;
       -                if(c < Tx)
       -                        return 1;
       -                if(n > 1)
       -                        if(c < T3 || n > 2)
       -                                return 1;
       -        }
       -        return 0;
       -}
   DIR diff --git a/src/libutf/runestrcat.c b/src/libutf/runestrcat.c
       t@@ -1,25 +0,0 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
       - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       -#include <stdarg.h>
       -#include <string.h>
       -#include "utf.h"
       -#include "utfdef.h"
       -
       -Rune*
       -runestrcat(Rune *s1, Rune *s2)
       -{
       -
       -        runestrcpy(runestrchr(s1, 0), s2);
       -        return s1;
       -}
   DIR diff --git a/src/libutf/runestrchr.c b/src/libutf/runestrchr.c
       t@@ -1,35 +0,0 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
       - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       -#include <stdarg.h>
       -#include <string.h>
       -#include "utf.h"
       -#include "utfdef.h"
       -
       -Rune*
       -runestrchr(Rune *s, Rune c)
       -{
       -        Rune c0 = c;
       -        Rune c1;
       -
       -        if(c == 0) {
       -                while(*s++)
       -                        ;
       -                return s-1;
       -        }
       -
       -        while(c1 = *s++)
       -                if(c1 == c0)
       -                        return s-1;
       -        return 0;
       -}
   DIR diff --git a/src/libutf/runestrcmp.c b/src/libutf/runestrcmp.c
       t@@ -1,35 +0,0 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
       - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       -#include <stdarg.h>
       -#include <string.h>
       -#include "utf.h"
       -#include "utfdef.h"
       -
       -int
       -runestrcmp(Rune *s1, Rune *s2)
       -{
       -        Rune c1, c2;
       -
       -        for(;;) {
       -                c1 = *s1++;
       -                c2 = *s2++;
       -                if(c1 != c2) {
       -                        if(c1 > c2)
       -                                return 1;
       -                        return -1;
       -                }
       -                if(c1 == 0)
       -                        return 0;
       -        }
       -}
   DIR diff --git a/src/libutf/runestrcpy.c b/src/libutf/runestrcpy.c
       t@@ -1,28 +0,0 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
       - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       -#include <stdarg.h>
       -#include <string.h>
       -#include "utf.h"
       -#include "utfdef.h"
       -
       -Rune*
       -runestrcpy(Rune *s1, Rune *s2)
       -{
       -        Rune *os1;
       -
       -        os1 = s1;
       -        while(*s1++ = *s2++)
       -                ;
       -        return os1;
       -}
   DIR diff --git a/src/libutf/runestrdup.c b/src/libutf/runestrdup.c
       t@@ -1,30 +0,0 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
       - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       -#include <stdarg.h>
       -#include <string.h>
       -#include <stdlib.h>
       -#include "utf.h"
       -#include "utfdef.h"
       -
       -Rune*
       -runestrdup(Rune *s) 
       -{  
       -        Rune *ns;
       -
       -        ns = malloc(sizeof(Rune)*(runestrlen(s) + 1));
       -        if(ns == 0)
       -                return 0;
       -
       -        return runestrcpy(ns, s);
       -}
   DIR diff --git a/src/libutf/runestrecpy.c b/src/libutf/runestrecpy.c
       t@@ -1,32 +0,0 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
       - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       -#include <stdarg.h>
       -#include <string.h>
       -#include "utf.h"
       -#include "utfdef.h"
       -
       -Rune*
       -runestrecpy(Rune *s1, Rune *es1, Rune *s2)
       -{
       -        if(s1 >= es1)
       -                return s1;
       -
       -        while(*s1++ = *s2++){
       -                if(s1 == es1){
       -                        *--s1 = '\0';
       -                        break;
       -                }
       -        }
       -        return s1;
       -}
   DIR diff --git a/src/libutf/runestrlen.c b/src/libutf/runestrlen.c
       t@@ -1,24 +0,0 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
       - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       -#include <stdarg.h>
       -#include <string.h>
       -#include "utf.h"
       -#include "utfdef.h"
       -
       -long
       -runestrlen(Rune *s)
       -{
       -
       -        return runestrchr(s, 0) - s;
       -}
   DIR diff --git a/src/libutf/runestrncat.c b/src/libutf/runestrncat.c
       t@@ -1,32 +0,0 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
       - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       -#include <stdarg.h>
       -#include <string.h>
       -#include "utf.h"
       -#include "utfdef.h"
       -
       -Rune*
       -runestrncat(Rune *s1, Rune *s2, long n)
       -{
       -        Rune *os1;
       -
       -        os1 = s1;
       -        s1 = runestrchr(s1, 0);
       -        while(*s1++ = *s2++)
       -                if(--n < 0) {
       -                        s1[-1] = 0;
       -                        break;
       -                }
       -        return os1;
       -}
   DIR diff --git a/src/libutf/runestrncmp.c b/src/libutf/runestrncmp.c
       t@@ -1,37 +0,0 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
       - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       -#include <stdarg.h>
       -#include <string.h>
       -#include "utf.h"
       -#include "utfdef.h"
       -
       -int
       -runestrncmp(Rune *s1, Rune *s2, long n)
       -{
       -        Rune c1, c2;
       -
       -        while(n > 0) {
       -                c1 = *s1++;
       -                c2 = *s2++;
       -                n--;
       -                if(c1 != c2) {
       -                        if(c1 > c2)
       -                                return 1;
       -                        return -1;
       -                }
       -                if(c1 == 0)
       -                        break;
       -        }
       -        return 0;
       -}
   DIR diff --git a/src/libutf/runestrncpy.c b/src/libutf/runestrncpy.c
       t@@ -1,33 +0,0 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
       - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       -#include <stdarg.h>
       -#include <string.h>
       -#include "utf.h"
       -#include "utfdef.h"
       -
       -Rune*
       -runestrncpy(Rune *s1, Rune *s2, long n)
       -{
       -        int i;
       -        Rune *os1;
       -
       -        os1 = s1;
       -        for(i = 0; i < n; i++)
       -                if((*s1++ = *s2++) == 0) {
       -                        while(++i < n)
       -                                *s1++ = 0;
       -                        return os1;
       -                }
       -        return os1;
       -}
   DIR diff --git a/src/libutf/runestrrchr.c b/src/libutf/runestrrchr.c
       t@@ -1,30 +0,0 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
       - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       -#include <stdarg.h>
       -#include <string.h>
       -#include "utf.h"
       -#include "utfdef.h"
       -
       -Rune*
       -runestrrchr(Rune *s, Rune c)
       -{
       -        Rune *r;
       -
       -        if(c == 0)
       -                return runestrchr(s, 0);
       -        r = 0;
       -        while(s = runestrchr(s, c))
       -                r = s++;
       -        return r;
       -}
   DIR diff --git a/src/libutf/runestrstr.c b/src/libutf/runestrstr.c
       t@@ -1,44 +0,0 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
       - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       -#include <stdarg.h>
       -#include <string.h>
       -#include "utf.h"
       -#include "utfdef.h"
       -
       -/*
       - * Return pointer to first occurrence of s2 in s1,
       - * 0 if none
       - */
       -Rune*
       -runestrstr(Rune *s1, Rune *s2)
       -{
       -        Rune *p, *pa, *pb;
       -        int c0, c;
       -
       -        c0 = *s2;
       -        if(c0 == 0)
       -                return s1;
       -        s2++;
       -        for(p=runestrchr(s1, c0); p; p=runestrchr(p+1, c0)) {
       -                pa = p;
       -                for(pb=s2;; pb++) {
       -                        c = *pb;
       -                        if(c == 0)
       -                                return p;
       -                        if(c != *++pa)
       -                                break;
       -                }
       -        }
       -        return 0;
       -}
   DIR diff --git a/src/libutf/runetype.c b/src/libutf/runetype.c
       t@@ -1,1152 +0,0 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
       - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       -#include <stdarg.h>
       -#include <string.h>
       -#include "utf.h"
       -#include "utfdef.h"
       -
       -/*
       - * alpha ranges -
       - *        only covers ranges not in lower||upper
       - */
       -static
       -Rune        __alpha2[] =
       -{
       -        0x00d8,        0x00f6,        /* Ø - ö */
       -        0x00f8,        0x01f5,        /* ø - ǵ */
       -        0x0250,        0x02a8,        /* ɐ - ʨ */
       -        0x038e,        0x03a1,        /* Ύ - Ρ */
       -        0x03a3,        0x03ce,        /* Σ - ώ */
       -        0x03d0,        0x03d6,        /* ϐ - ϖ */
       -        0x03e2,        0x03f3,        /* Ϣ - ϳ */
       -        0x0490,        0x04c4,        /* Ґ - ӄ */
       -        0x0561,        0x0587,        /* ա - և */
       -        0x05d0,        0x05ea,        /* א - ת */
       -        0x05f0,        0x05f2,        /* װ - ײ */
       -        0x0621,        0x063a,        /* ء - غ */
       -        0x0640,        0x064a,        /* ـ - ي */
       -        0x0671,        0x06b7,        /* ٱ - ڷ */
       -        0x06ba,        0x06be,        /* ں - ھ */
       -        0x06c0,        0x06ce,        /* ۀ - ێ */
       -        0x06d0,        0x06d3,        /* ې - ۓ */
       -        0x0905,        0x0939,        /* अ - ह */
       -        0x0958,        0x0961,        /* क़ - ॡ */
       -        0x0985,        0x098c,        /* অ - ঌ */
       -        0x098f,        0x0990,        /* এ - ঐ */
       -        0x0993,        0x09a8,        /* ও - ন */
       -        0x09aa,        0x09b0,        /* প - র */
       -        0x09b6,        0x09b9,        /* শ - হ */
       -        0x09dc,        0x09dd,        /* ড় - ঢ় */
       -        0x09df,        0x09e1,        /* য় - ৡ */
       -        0x09f0,        0x09f1,        /* ৰ - ৱ */
       -        0x0a05,        0x0a0a,        /* ਅ - ਊ */
       -        0x0a0f,        0x0a10,        /* ਏ - ਐ */
       -        0x0a13,        0x0a28,        /* ਓ - ਨ */
       -        0x0a2a,        0x0a30,        /* ਪ - ਰ */
       -        0x0a32,        0x0a33,        /* ਲ - ਲ਼ */
       -        0x0a35,        0x0a36,        /* ਵ - ਸ਼ */
       -        0x0a38,        0x0a39,        /* ਸ - ਹ */
       -        0x0a59,        0x0a5c,        /* ਖ਼ - ੜ */
       -        0x0a85,        0x0a8b,        /* અ - ઋ */
       -        0x0a8f,        0x0a91,        /* એ - ઑ */
       -        0x0a93,        0x0aa8,        /* ઓ - ન */
       -        0x0aaa,        0x0ab0,        /* પ - ર */
       -        0x0ab2,        0x0ab3,        /* લ - ળ */
       -        0x0ab5,        0x0ab9,        /* વ - હ */
       -        0x0b05,        0x0b0c,        /* ଅ - ଌ */
       -        0x0b0f,        0x0b10,        /* ଏ - ଐ */
       -        0x0b13,        0x0b28,        /* ଓ - ନ */
       -        0x0b2a,        0x0b30,        /* ପ - ର */
       -        0x0b32,        0x0b33,        /* ଲ - ଳ */
       -        0x0b36,        0x0b39,        /* ଶ - ହ */
       -        0x0b5c,        0x0b5d,        /* ଡ଼ - ଢ଼ */
       -        0x0b5f,        0x0b61,        /* ୟ - ୡ */
       -        0x0b85,        0x0b8a,        /* அ - ஊ */
       -        0x0b8e,        0x0b90,        /* எ - ஐ */
       -        0x0b92,        0x0b95,        /* ஒ - க */
       -        0x0b99,        0x0b9a,        /* ங - ச */
       -        0x0b9e,        0x0b9f,        /* ஞ - ட */
       -        0x0ba3,        0x0ba4,        /* ண - த */
       -        0x0ba8,        0x0baa,        /* ந - ப */
       -        0x0bae,        0x0bb5,        /* ம - வ */
       -        0x0bb7,        0x0bb9,        /* ஷ - ஹ */
       -        0x0c05,        0x0c0c,        /* అ - ఌ */
       -        0x0c0e,        0x0c10,        /* ఎ - ఐ */
       -        0x0c12,        0x0c28,        /* ఒ - న */
       -        0x0c2a,        0x0c33,        /* ప - ళ */
       -        0x0c35,        0x0c39,        /* వ - హ */
       -        0x0c60,        0x0c61,        /* ౠ - ౡ */
       -        0x0c85,        0x0c8c,        /* ಅ - ಌ */
       -        0x0c8e,        0x0c90,        /* ಎ - ಐ */
       -        0x0c92,        0x0ca8,        /* ಒ - ನ */
       -        0x0caa,        0x0cb3,        /* ಪ - ಳ */
       -        0x0cb5,        0x0cb9,        /* ವ - ಹ */
       -        0x0ce0,        0x0ce1,        /* ೠ - ೡ */
       -        0x0d05,        0x0d0c,        /* അ - ഌ */
       -        0x0d0e,        0x0d10,        /* എ - ഐ */
       -        0x0d12,        0x0d28,        /* ഒ - ന */
       -        0x0d2a,        0x0d39,        /* പ - ഹ */
       -        0x0d60,        0x0d61,        /* ൠ - ൡ */
       -        0x0e01,        0x0e30,        /* ก - ะ */
       -        0x0e32,        0x0e33,        /* า - ำ */
       -        0x0e40,        0x0e46,        /* เ - ๆ */
       -        0x0e5a,        0x0e5b,        /* ๚ - ๛ */
       -        0x0e81,        0x0e82,        /* ກ - ຂ */
       -        0x0e87,        0x0e88,        /* ງ - ຈ */
       -        0x0e94,        0x0e97,        /* ດ - ທ */
       -        0x0e99,        0x0e9f,        /* ນ - ຟ */
       -        0x0ea1,        0x0ea3,        /* ມ - ຣ */
       -        0x0eaa,        0x0eab,        /* ສ - ຫ */
       -        0x0ead,        0x0eae,        /* ອ - ຮ */
       -        0x0eb2,        0x0eb3,        /* າ - ຳ */
       -        0x0ec0,        0x0ec4,        /* ເ - ໄ */
       -        0x0edc,        0x0edd,        /* ໜ - ໝ */
       -        0x0f18,        0x0f19,        /* ༘ - ༙ */
       -        0x0f40,        0x0f47,        /* ཀ - ཇ */
       -        0x0f49,        0x0f69,        /* ཉ - ཀྵ */
       -        0x10d0,        0x10f6,        /* ა - ჶ */
       -        0x1100,        0x1159,        /* ᄀ - ᅙ */
       -        0x115f,        0x11a2,        /* ᅟ - ᆢ */
       -        0x11a8,        0x11f9,        /* ᆨ - ᇹ */
       -        0x1e00,        0x1e9b,        /* Ḁ - ẛ */
       -        0x1f50,        0x1f57,        /* ὐ - ὗ */
       -        0x1f80,        0x1fb4,        /* ᾀ - ᾴ */
       -        0x1fb6,        0x1fbc,        /* ᾶ - ᾼ */
       -        0x1fc2,        0x1fc4,        /* ῂ - ῄ */
       -        0x1fc6,        0x1fcc,        /* ῆ - ῌ */
       -        0x1fd0,        0x1fd3,        /* ῐ - ΐ */
       -        0x1fd6,        0x1fdb,        /* ῖ - Ί */
       -        0x1fe0,        0x1fec,        /* ῠ - Ῥ */
       -        0x1ff2,        0x1ff4,        /* ῲ - ῴ */
       -        0x1ff6,        0x1ffc,        /* ῶ - ῼ */
       -        0x210a,        0x2113,        /* ℊ - ℓ */
       -        0x2115,        0x211d,        /* ℕ - ℝ */
       -        0x2120,        0x2122,        /* ℠ - ™ */
       -        0x212a,        0x2131,        /* K - ℱ */
       -        0x2133,        0x2138,        /* ℳ - ℸ */
       -        0x3041,        0x3094,        /* ぁ - ゔ */
       -        0x30a1,        0x30fa,        /* ァ - ヺ */
       -        0x3105,        0x312c,        /* ㄅ - ㄬ */
       -        0x3131,        0x318e,        /* ㄱ - ㆎ */
       -        0x3192,        0x319f,        /* ㆒ - ㆟ */
       -        0x3260,        0x327b,        /* ㉠ - ㉻ */
       -        0x328a,        0x32b0,        /* ㊊ - ㊰ */
       -        0x32d0,        0x32fe,        /* ㋐ - ㋾ */
       -        0x3300,        0x3357,        /* ㌀ - ㍗ */
       -        0x3371,        0x3376,        /* ㍱ - ㍶ */
       -        0x337b,        0x3394,        /* ㍻ - ㎔ */
       -        0x3399,        0x339e,        /* ㎙ - ㎞ */
       -        0x33a9,        0x33ad,        /* ㎩ - ㎭ */
       -        0x33b0,        0x33c1,        /* ㎰ - ㏁ */
       -        0x33c3,        0x33c5,        /* ㏃ - ㏅ */
       -        0x33c7,        0x33d7,        /* ㏇ - ㏗ */
       -        0x33d9,        0x33dd,        /* ㏙ - ㏝ */
       -        0x4e00,        0x9fff,        /* 一 - 鿿 */
       -        0xac00,        0xd7a3,        /* 가 - 힣 */
       -        0xf900,        0xfb06,        /* 豈 - st */
       -        0xfb13,        0xfb17,        /* ﬓ - ﬗ */
       -        0xfb1f,        0xfb28,        /* ײַ - ﬨ */
       -        0xfb2a,        0xfb36,        /* שׁ - זּ */
       -        0xfb38,        0xfb3c,        /* טּ - לּ */
       -        0xfb40,        0xfb41,        /* נּ - סּ */
       -        0xfb43,        0xfb44,        /* ףּ - פּ */
       -        0xfb46,        0xfbb1,        /* צּ - ﮱ */
       -        0xfbd3,        0xfd3d,        /* ﯓ - ﴽ */
       -        0xfd50,        0xfd8f,        /* ﵐ - ﶏ */
       -        0xfd92,        0xfdc7,        /* ﶒ - ﷇ */
       -        0xfdf0,        0xfdf9,        /* ﷰ - ﷹ */
       -        0xfe70,        0xfe72,        /* ﹰ - ﹲ */
       -        0xfe76,        0xfefc,        /* ﹶ - ﻼ */
       -        0xff66,        0xff6f,        /* ヲ - ッ */
       -        0xff71,        0xff9d,        /* ア - ン */
       -        0xffa0,        0xffbe,        /* ᅠ - ᄒ */
       -        0xffc2,        0xffc7,        /* ᅡ - ᅦ */
       -        0xffca,        0xffcf,        /* ᅧ - ᅬ */
       -        0xffd2,        0xffd7,        /* ᅭ - ᅲ */
       -        0xffda,        0xffdc,        /* ᅳ - ᅵ */
       -};
       -
       -/*
       - * alpha singlets -
       - *        only covers ranges not in lower||upper
       - */
       -static
       -Rune        __alpha1[] =
       -{
       -        0x00aa,        /* ª */
       -        0x00b5,        /* µ */
       -        0x00ba,        /* º */
       -        0x03da,        /* Ϛ */
       -        0x03dc,        /* Ϝ */
       -        0x03de,        /* Ϟ */
       -        0x03e0,        /* Ϡ */
       -        0x06d5,        /* ە */
       -        0x09b2,        /* ল */
       -        0x0a5e,        /* ਫ਼ */
       -        0x0a8d,        /* ઍ */
       -        0x0ae0,        /* ૠ */
       -        0x0b9c,        /* ஜ */
       -        0x0cde,        /* ೞ */
       -        0x0e4f,        /* ๏ */
       -        0x0e84,        /* ຄ */
       -        0x0e8a,        /* ຊ */
       -        0x0e8d,        /* ຍ */
       -        0x0ea5,        /* ລ */
       -        0x0ea7,        /* ວ */
       -        0x0eb0,        /* ະ */
       -        0x0ebd,        /* ຽ */
       -        0x1fbe,        /* ι */
       -        0x207f,        /* ⁿ */
       -        0x20a8,        /* ₨ */
       -        0x2102,        /* ℂ */
       -        0x2107,        /* ℇ */
       -        0x2124,        /* ℤ */
       -        0x2126,        /* Ω */
       -        0x2128,        /* ℨ */
       -        0xfb3e,        /* מּ */
       -        0xfe74,        /* ﹴ */
       -};
       -
       -/*
       - * space ranges
       - */
       -static
       -Rune        __space2[] =
       -{
       -        0x0009,        0x000a,        /* tab and newline */
       -        0x0020,        0x0020,        /* space */
       -        0x00a0,        0x00a0,        /*   */
       -        0x2000,        0x200b,        /*   - ​ */
       -        0x2028,        0x2029,        /* 
 - 
 */
       -        0x3000,        0x3000,        /*   */
       -        0xfeff,        0xfeff,        /*  */
       -};
       -
       -/*
       - * lower case ranges
       - *        3rd col is conversion excess 500
       - */
       -static
       -Rune        __toupper2[] =
       -{
       -        0x0061,        0x007a, 468,        /* a-z A-Z */
       -        0x00e0,        0x00f6, 468,        /* à-ö À-Ö */
       -        0x00f8,        0x00fe, 468,        /* ø-þ Ø-Þ */
       -        0x0256,        0x0257, 295,        /* ɖ-ɗ Ɖ-Ɗ */
       -        0x0258,        0x0259, 298,        /* ɘ-ə Ǝ-Ə */
       -        0x028a,        0x028b, 283,        /* ʊ-ʋ Ʊ-Ʋ */
       -        0x03ad,        0x03af, 463,        /* έ-ί Έ-Ί */
       -        0x03b1,        0x03c1, 468,        /* α-ρ Α-Ρ */
       -        0x03c3,        0x03cb, 468,        /* σ-ϋ Σ-Ϋ */
       -        0x03cd,        0x03ce, 437,        /* ύ-ώ Ύ-Ώ */
       -        0x0430,        0x044f, 468,        /* а-я А-Я */
       -        0x0451,        0x045c, 420,        /* ё-ќ Ё-Ќ */
       -        0x045e,        0x045f, 420,        /* ў-џ Ў-Џ */
       -        0x0561,        0x0586, 452,        /* ա-ֆ Ա-Ֆ */
       -        0x1f00,        0x1f07, 508,        /* ἀ-ἇ Ἀ-Ἇ */
       -        0x1f10,        0x1f15, 508,        /* ἐ-ἕ Ἐ-Ἕ */
       -        0x1f20,        0x1f27, 508,        /* ἠ-ἧ Ἠ-Ἧ */
       -        0x1f30,        0x1f37, 508,        /* ἰ-ἷ Ἰ-Ἷ */
       -        0x1f40,        0x1f45, 508,        /* ὀ-ὅ Ὀ-Ὅ */
       -        0x1f60,        0x1f67, 508,        /* ὠ-ὧ Ὠ-Ὧ */
       -        0x1f70,        0x1f71, 574,        /* ὰ-ά Ὰ-Ά */
       -        0x1f72,        0x1f75, 586,        /* ὲ-ή Ὲ-Ή */
       -        0x1f76,        0x1f77, 600,        /* ὶ-ί Ὶ-Ί */
       -        0x1f78,        0x1f79, 628,        /* ὸ-ό Ὸ-Ό */
       -        0x1f7a,        0x1f7b, 612,        /* ὺ-ύ Ὺ-Ύ */
       -        0x1f7c,        0x1f7d, 626,        /* ὼ-ώ Ὼ-Ώ */
       -        0x1f80,        0x1f87, 508,        /* ᾀ-ᾇ ᾈ-ᾏ */
       -        0x1f90,        0x1f97, 508,        /* ᾐ-ᾗ ᾘ-ᾟ */
       -        0x1fa0,        0x1fa7, 508,        /* ᾠ-ᾧ ᾨ-ᾯ */
       -        0x1fb0,        0x1fb1, 508,        /* ᾰ-ᾱ Ᾰ-Ᾱ */
       -        0x1fd0,        0x1fd1, 508,        /* ῐ-ῑ Ῐ-Ῑ */
       -        0x1fe0,        0x1fe1, 508,        /* ῠ-ῡ Ῠ-Ῡ */
       -        0x2170,        0x217f, 484,        /* ⅰ-ⅿ Ⅰ-Ⅿ */
       -        0x24d0,        0x24e9, 474,        /* ⓐ-ⓩ Ⓐ-Ⓩ */
       -        0xff41,        0xff5a, 468,        /* a-z A-Z */
       -};
       -
       -/*
       - * lower case singlets
       - *        2nd col is conversion excess 500
       - */
       -static
       -Rune        __toupper1[] =
       -{
       -        0x00ff, 621,        /* ÿ Ÿ */
       -        0x0101, 499,        /* ā Ā */
       -        0x0103, 499,        /* ă Ă */
       -        0x0105, 499,        /* ą Ą */
       -        0x0107, 499,        /* ć Ć */
       -        0x0109, 499,        /* ĉ Ĉ */
       -        0x010b, 499,        /* ċ Ċ */
       -        0x010d, 499,        /* č Č */
       -        0x010f, 499,        /* ď Ď */
       -        0x0111, 499,        /* đ Đ */
       -        0x0113, 499,        /* ē Ē */
       -        0x0115, 499,        /* ĕ Ĕ */
       -        0x0117, 499,        /* ė Ė */
       -        0x0119, 499,        /* ę Ę */
       -        0x011b, 499,        /* ě Ě */
       -        0x011d, 499,        /* ĝ Ĝ */
       -        0x011f, 499,        /* ğ Ğ */
       -        0x0121, 499,        /* ġ Ġ */
       -        0x0123, 499,        /* ģ Ģ */
       -        0x0125, 499,        /* ĥ Ĥ */
       -        0x0127, 499,        /* ħ Ħ */
       -        0x0129, 499,        /* ĩ Ĩ */
       -        0x012b, 499,        /* ī Ī */
       -        0x012d, 499,        /* ĭ Ĭ */
       -        0x012f, 499,        /* į Į */
       -        0x0131, 268,        /* ı I */
       -        0x0133, 499,        /* ij IJ */
       -        0x0135, 499,        /* ĵ Ĵ */
       -        0x0137, 499,        /* ķ Ķ */
       -        0x013a, 499,        /* ĺ Ĺ */
       -        0x013c, 499,        /* ļ Ļ */
       -        0x013e, 499,        /* ľ Ľ */
       -        0x0140, 499,        /* ŀ Ŀ */
       -        0x0142, 499,        /* ł Ł */
       -        0x0144, 499,        /* ń Ń */
       -        0x0146, 499,        /* ņ Ņ */
       -        0x0148, 499,        /* ň Ň */
       -        0x014b, 499,        /* ŋ Ŋ */
       -        0x014d, 499,        /* ō Ō */
       -        0x014f, 499,        /* ŏ Ŏ */
       -        0x0151, 499,        /* ő Ő */
       -        0x0153, 499,        /* œ Œ */
       -        0x0155, 499,        /* ŕ Ŕ */
       -        0x0157, 499,        /* ŗ Ŗ */
       -        0x0159, 499,        /* ř Ř */
       -        0x015b, 499,        /* ś Ś */
       -        0x015d, 499,        /* ŝ Ŝ */
       -        0x015f, 499,        /* ş Ş */
       -        0x0161, 499,        /* š Š */
       -        0x0163, 499,        /* ţ Ţ */
       -        0x0165, 499,        /* ť Ť */
       -        0x0167, 499,        /* ŧ Ŧ */
       -        0x0169, 499,        /* ũ Ũ */
       -        0x016b, 499,        /* ū Ū */
       -        0x016d, 499,        /* ŭ Ŭ */
       -        0x016f, 499,        /* ů Ů */
       -        0x0171, 499,        /* ű Ű */
       -        0x0173, 499,        /* ų Ų */
       -        0x0175, 499,        /* ŵ Ŵ */
       -        0x0177, 499,        /* ŷ Ŷ */
       -        0x017a, 499,        /* ź Ź */
       -        0x017c, 499,        /* ż Ż */
       -        0x017e, 499,        /* ž Ž */
       -        0x017f, 200,        /* ſ S */
       -        0x0183, 499,        /* ƃ Ƃ */
       -        0x0185, 499,        /* ƅ Ƅ */
       -        0x0188, 499,        /* ƈ Ƈ */
       -        0x018c, 499,        /* ƌ Ƌ */
       -        0x0192, 499,        /* ƒ Ƒ */
       -        0x0199, 499,        /* ƙ Ƙ */
       -        0x01a1, 499,        /* ơ Ơ */
       -        0x01a3, 499,        /* ƣ Ƣ */
       -        0x01a5, 499,        /* ƥ Ƥ */
       -        0x01a8, 499,        /* ƨ Ƨ */
       -        0x01ad, 499,        /* ƭ Ƭ */
       -        0x01b0, 499,        /* ư Ư */
       -        0x01b4, 499,        /* ƴ Ƴ */
       -        0x01b6, 499,        /* ƶ Ƶ */
       -        0x01b9, 499,        /* ƹ Ƹ */
       -        0x01bd, 499,        /* ƽ Ƽ */
       -        0x01c5, 499,        /* Dž DŽ */
       -        0x01c6, 498,        /* dž DŽ */
       -        0x01c8, 499,        /* Lj LJ */
       -        0x01c9, 498,        /* lj LJ */
       -        0x01cb, 499,        /* Nj NJ */
       -        0x01cc, 498,        /* nj NJ */
       -        0x01ce, 499,        /* ǎ Ǎ */
       -        0x01d0, 499,        /* ǐ Ǐ */
       -        0x01d2, 499,        /* ǒ Ǒ */
       -        0x01d4, 499,        /* ǔ Ǔ */
       -        0x01d6, 499,        /* ǖ Ǖ */
       -        0x01d8, 499,        /* ǘ Ǘ */
       -        0x01da, 499,        /* ǚ Ǚ */
       -        0x01dc, 499,        /* ǜ Ǜ */
       -        0x01df, 499,        /* ǟ Ǟ */
       -        0x01e1, 499,        /* ǡ Ǡ */
       -        0x01e3, 499,        /* ǣ Ǣ */
       -        0x01e5, 499,        /* ǥ Ǥ */
       -        0x01e7, 499,        /* ǧ Ǧ */
       -        0x01e9, 499,        /* ǩ Ǩ */
       -        0x01eb, 499,        /* ǫ Ǫ */
       -        0x01ed, 499,        /* ǭ Ǭ */
       -        0x01ef, 499,        /* ǯ Ǯ */
       -        0x01f2, 499,        /* Dz DZ */
       -        0x01f3, 498,        /* dz DZ */
       -        0x01f5, 499,        /* ǵ Ǵ */
       -        0x01fb, 499,        /* ǻ Ǻ */
       -        0x01fd, 499,        /* ǽ Ǽ */
       -        0x01ff, 499,        /* ǿ Ǿ */
       -        0x0201, 499,        /* ȁ Ȁ */
       -        0x0203, 499,        /* ȃ Ȃ */
       -        0x0205, 499,        /* ȅ Ȅ */
       -        0x0207, 499,        /* ȇ Ȇ */
       -        0x0209, 499,        /* ȉ Ȉ */
       -        0x020b, 499,        /* ȋ Ȋ */
       -        0x020d, 499,        /* ȍ Ȍ */
       -        0x020f, 499,        /* ȏ Ȏ */
       -        0x0211, 499,        /* ȑ Ȑ */
       -        0x0213, 499,        /* ȓ Ȓ */
       -        0x0215, 499,        /* ȕ Ȕ */
       -        0x0217, 499,        /* ȗ Ȗ */
       -        0x0253, 290,        /* ɓ Ɓ */
       -        0x0254, 294,        /* ɔ Ɔ */
       -        0x025b, 297,        /* ɛ Ɛ */
       -        0x0260, 295,        /* ɠ Ɠ */
       -        0x0263, 293,        /* ɣ Ɣ */
       -        0x0268, 291,        /* ɨ Ɨ */
       -        0x0269, 289,        /* ɩ Ɩ */
       -        0x026f, 289,        /* ɯ Ɯ */
       -        0x0272, 287,        /* ɲ Ɲ */
       -        0x0283, 282,        /* ʃ Ʃ */
       -        0x0288, 282,        /* ʈ Ʈ */
       -        0x0292, 281,        /* ʒ Ʒ */
       -        0x03ac, 462,        /* ά Ά */
       -        0x03cc, 436,        /* ό Ό */
       -        0x03d0, 438,        /* ϐ Β */
       -        0x03d1, 443,        /* ϑ Θ */
       -        0x03d5, 453,        /* ϕ Φ */
       -        0x03d6, 446,        /* ϖ Π */
       -        0x03e3, 499,        /* ϣ Ϣ */
       -        0x03e5, 499,        /* ϥ Ϥ */
       -        0x03e7, 499,        /* ϧ Ϧ */
       -        0x03e9, 499,        /* ϩ Ϩ */
       -        0x03eb, 499,        /* ϫ Ϫ */
       -        0x03ed, 499,        /* ϭ Ϭ */
       -        0x03ef, 499,        /* ϯ Ϯ */
       -        0x03f0, 414,        /* ϰ Κ */
       -        0x03f1, 420,        /* ϱ Ρ */
       -        0x0461, 499,        /* ѡ Ѡ */
       -        0x0463, 499,        /* ѣ Ѣ */
       -        0x0465, 499,        /* ѥ Ѥ */
       -        0x0467, 499,        /* ѧ Ѧ */
       -        0x0469, 499,        /* ѩ Ѩ */
       -        0x046b, 499,        /* ѫ Ѫ */
       -        0x046d, 499,        /* ѭ Ѭ */
       -        0x046f, 499,        /* ѯ Ѯ */
       -        0x0471, 499,        /* ѱ Ѱ */
       -        0x0473, 499,        /* ѳ Ѳ */
       -        0x0475, 499,        /* ѵ Ѵ */
       -        0x0477, 499,        /* ѷ Ѷ */
       -        0x0479, 499,        /* ѹ Ѹ */
       -        0x047b, 499,        /* ѻ Ѻ */
       -        0x047d, 499,        /* ѽ Ѽ */
       -        0x047f, 499,        /* ѿ Ѿ */
       -        0x0481, 499,        /* ҁ Ҁ */
       -        0x0491, 499,        /* ґ Ґ */
       -        0x0493, 499,        /* ғ Ғ */
       -        0x0495, 499,        /* ҕ Ҕ */
       -        0x0497, 499,        /* җ Җ */
       -        0x0499, 499,        /* ҙ Ҙ */
       -        0x049b, 499,        /* қ Қ */
       -        0x049d, 499,        /* ҝ Ҝ */
       -        0x049f, 499,        /* ҟ Ҟ */
       -        0x04a1, 499,        /* ҡ Ҡ */
       -        0x04a3, 499,        /* ң Ң */
       -        0x04a5, 499,        /* ҥ Ҥ */
       -        0x04a7, 499,        /* ҧ Ҧ */
       -        0x04a9, 499,        /* ҩ Ҩ */
       -        0x04ab, 499,        /* ҫ Ҫ */
       -        0x04ad, 499,        /* ҭ Ҭ */
       -        0x04af, 499,        /* ү Ү */
       -        0x04b1, 499,        /* ұ Ұ */
       -        0x04b3, 499,        /* ҳ Ҳ */
       -        0x04b5, 499,        /* ҵ Ҵ */
       -        0x04b7, 499,        /* ҷ Ҷ */
       -        0x04b9, 499,        /* ҹ Ҹ */
       -        0x04bb, 499,        /* һ Һ */
       -        0x04bd, 499,        /* ҽ Ҽ */
       -        0x04bf, 499,        /* ҿ Ҿ */
       -        0x04c2, 499,        /* ӂ Ӂ */
       -        0x04c4, 499,        /* ӄ Ӄ */
       -        0x04c8, 499,        /* ӈ Ӈ */
       -        0x04cc, 499,        /* ӌ Ӌ */
       -        0x04d1, 499,        /* ӑ Ӑ */
       -        0x04d3, 499,        /* ӓ Ӓ */
       -        0x04d5, 499,        /* ӕ Ӕ */
       -        0x04d7, 499,        /* ӗ Ӗ */
       -        0x04d9, 499,        /* ә Ә */
       -        0x04db, 499,        /* ӛ Ӛ */
       -        0x04dd, 499,        /* ӝ Ӝ */
       -        0x04df, 499,        /* ӟ Ӟ */
       -        0x04e1, 499,        /* ӡ Ӡ */
       -        0x04e3, 499,        /* ӣ Ӣ */
       -        0x04e5, 499,        /* ӥ Ӥ */
       -        0x04e7, 499,        /* ӧ Ӧ */
       -        0x04e9, 499,        /* ө Ө */
       -        0x04eb, 499,        /* ӫ Ӫ */
       -        0x04ef, 499,        /* ӯ Ӯ */
       -        0x04f1, 499,        /* ӱ Ӱ */
       -        0x04f3, 499,        /* ӳ Ӳ */
       -        0x04f5, 499,        /* ӵ Ӵ */
       -        0x04f9, 499,        /* ӹ Ӹ */
       -        0x1e01, 499,        /* ḁ Ḁ */
       -        0x1e03, 499,        /* ḃ Ḃ */
       -        0x1e05, 499,        /* ḅ Ḅ */
       -        0x1e07, 499,        /* ḇ Ḇ */
       -        0x1e09, 499,        /* ḉ Ḉ */
       -        0x1e0b, 499,        /* ḋ Ḋ */
       -        0x1e0d, 499,        /* ḍ Ḍ */
       -        0x1e0f, 499,        /* ḏ Ḏ */
       -        0x1e11, 499,        /* ḑ Ḑ */
       -        0x1e13, 499,        /* ḓ Ḓ */
       -        0x1e15, 499,        /* ḕ Ḕ */
       -        0x1e17, 499,        /* ḗ Ḗ */
       -        0x1e19, 499,        /* ḙ Ḙ */
       -        0x1e1b, 499,        /* ḛ Ḛ */
       -        0x1e1d, 499,        /* ḝ Ḝ */
       -        0x1e1f, 499,        /* ḟ Ḟ */
       -        0x1e21, 499,        /* ḡ Ḡ */
       -        0x1e23, 499,        /* ḣ Ḣ */
       -        0x1e25, 499,        /* ḥ Ḥ */
       -        0x1e27, 499,        /* ḧ Ḧ */
       -        0x1e29, 499,        /* ḩ Ḩ */
       -        0x1e2b, 499,        /* ḫ Ḫ */
       -        0x1e2d, 499,        /* ḭ Ḭ */
       -        0x1e2f, 499,        /* ḯ Ḯ */
       -        0x1e31, 499,        /* ḱ Ḱ */
       -        0x1e33, 499,        /* ḳ Ḳ */
       -        0x1e35, 499,        /* ḵ Ḵ */
       -        0x1e37, 499,        /* ḷ Ḷ */
       -        0x1e39, 499,        /* ḹ Ḹ */
       -        0x1e3b, 499,        /* ḻ Ḻ */
       -        0x1e3d, 499,        /* ḽ Ḽ */
       -        0x1e3f, 499,        /* ḿ Ḿ */
       -        0x1e41, 499,        /* ṁ Ṁ */
       -        0x1e43, 499,        /* ṃ Ṃ */
       -        0x1e45, 499,        /* ṅ Ṅ */
       -        0x1e47, 499,        /* ṇ Ṇ */
       -        0x1e49, 499,        /* ṉ Ṉ */
       -        0x1e4b, 499,        /* ṋ Ṋ */
       -        0x1e4d, 499,        /* ṍ Ṍ */
       -        0x1e4f, 499,        /* ṏ Ṏ */
       -        0x1e51, 499,        /* ṑ Ṑ */
       -        0x1e53, 499,        /* ṓ Ṓ */
       -        0x1e55, 499,        /* ṕ Ṕ */
       -        0x1e57, 499,        /* ṗ Ṗ */
       -        0x1e59, 499,        /* ṙ Ṙ */
       -        0x1e5b, 499,        /* ṛ Ṛ */
       -        0x1e5d, 499,        /* ṝ Ṝ */
       -        0x1e5f, 499,        /* ṟ Ṟ */
       -        0x1e61, 499,        /* ṡ Ṡ */
       -        0x1e63, 499,        /* ṣ Ṣ */
       -        0x1e65, 499,        /* ṥ Ṥ */
       -        0x1e67, 499,        /* ṧ Ṧ */
       -        0x1e69, 499,        /* ṩ Ṩ */
       -        0x1e6b, 499,        /* ṫ Ṫ */
       -        0x1e6d, 499,        /* ṭ Ṭ */
       -        0x1e6f, 499,        /* ṯ Ṯ */
       -        0x1e71, 499,        /* ṱ Ṱ */
       -        0x1e73, 499,        /* ṳ Ṳ */
       -        0x1e75, 499,        /* ṵ Ṵ */
       -        0x1e77, 499,        /* ṷ Ṷ */
       -        0x1e79, 499,        /* ṹ Ṹ */
       -        0x1e7b, 499,        /* ṻ Ṻ */
       -        0x1e7d, 499,        /* ṽ Ṽ */
       -        0x1e7f, 499,        /* ṿ Ṿ */
       -        0x1e81, 499,        /* ẁ Ẁ */
       -        0x1e83, 499,        /* ẃ Ẃ */
       -        0x1e85, 499,        /* ẅ Ẅ */
       -        0x1e87, 499,        /* ẇ Ẇ */
       -        0x1e89, 499,        /* ẉ Ẉ */
       -        0x1e8b, 499,        /* ẋ Ẋ */
       -        0x1e8d, 499,        /* ẍ Ẍ */
       -        0x1e8f, 499,        /* ẏ Ẏ */
       -        0x1e91, 499,        /* ẑ Ẑ */
       -        0x1e93, 499,        /* ẓ Ẓ */
       -        0x1e95, 499,        /* ẕ Ẕ */
       -        0x1ea1, 499,        /* ạ Ạ */
       -        0x1ea3, 499,        /* ả Ả */
       -        0x1ea5, 499,        /* ấ Ấ */
       -        0x1ea7, 499,        /* ầ Ầ */
       -        0x1ea9, 499,        /* ẩ Ẩ */
       -        0x1eab, 499,        /* ẫ Ẫ */
       -        0x1ead, 499,        /* ậ Ậ */
       -        0x1eaf, 499,        /* ắ Ắ */
       -        0x1eb1, 499,        /* ằ Ằ */
       -        0x1eb3, 499,        /* ẳ Ẳ */
       -        0x1eb5, 499,        /* ẵ Ẵ */
       -        0x1eb7, 499,        /* ặ Ặ */
       -        0x1eb9, 499,        /* ẹ Ẹ */
       -        0x1ebb, 499,        /* ẻ Ẻ */
       -        0x1ebd, 499,        /* ẽ Ẽ */
       -        0x1ebf, 499,        /* ế Ế */
       -        0x1ec1, 499,        /* ề Ề */
       -        0x1ec3, 499,        /* ể Ể */
       -        0x1ec5, 499,        /* ễ Ễ */
       -        0x1ec7, 499,        /* ệ Ệ */
       -        0x1ec9, 499,        /* ỉ Ỉ */
       -        0x1ecb, 499,        /* ị Ị */
       -        0x1ecd, 499,        /* ọ Ọ */
       -        0x1ecf, 499,        /* ỏ Ỏ */
       -        0x1ed1, 499,        /* ố Ố */
       -        0x1ed3, 499,        /* ồ Ồ */
       -        0x1ed5, 499,        /* ổ Ổ */
       -        0x1ed7, 499,        /* ỗ Ỗ */
       -        0x1ed9, 499,        /* ộ Ộ */
       -        0x1edb, 499,        /* ớ Ớ */
       -        0x1edd, 499,        /* ờ Ờ */
       -        0x1edf, 499,        /* ở Ở */
       -        0x1ee1, 499,        /* ỡ Ỡ */
       -        0x1ee3, 499,        /* ợ Ợ */
       -        0x1ee5, 499,        /* ụ Ụ */
       -        0x1ee7, 499,        /* ủ Ủ */
       -        0x1ee9, 499,        /* ứ Ứ */
       -        0x1eeb, 499,        /* ừ Ừ */
       -        0x1eed, 499,        /* ử Ử */
       -        0x1eef, 499,        /* ữ Ữ */
       -        0x1ef1, 499,        /* ự Ự */
       -        0x1ef3, 499,        /* ỳ Ỳ */
       -        0x1ef5, 499,        /* ỵ Ỵ */
       -        0x1ef7, 499,        /* ỷ Ỷ */
       -        0x1ef9, 499,        /* ỹ Ỹ */
       -        0x1f51, 508,        /* ὑ Ὑ */
       -        0x1f53, 508,        /* ὓ Ὓ */
       -        0x1f55, 508,        /* ὕ Ὕ */
       -        0x1f57, 508,        /* ὗ Ὗ */
       -        0x1fb3, 509,        /* ᾳ ᾼ */
       -        0x1fc3, 509,        /* ῃ ῌ */
       -        0x1fe5, 507,        /* ῥ Ῥ */
       -        0x1ff3, 509,        /* ῳ ῼ */
       -};
       -
       -/*
       - * upper case ranges
       - *        3rd col is conversion excess 500
       - */
       -static
       -Rune        __tolower2[] =
       -{
       -        0x0041,        0x005a, 532,        /* A-Z a-z */
       -        0x00c0,        0x00d6, 532,        /* À-Ö à-ö */
       -        0x00d8,        0x00de, 532,        /* Ø-Þ ø-þ */
       -        0x0189,        0x018a, 705,        /* Ɖ-Ɗ ɖ-ɗ */
       -        0x018e,        0x018f, 702,        /* Ǝ-Ə ɘ-ə */
       -        0x01b1,        0x01b2, 717,        /* Ʊ-Ʋ ʊ-ʋ */
       -        0x0388,        0x038a, 537,        /* Έ-Ί έ-ί */
       -        0x038e,        0x038f, 563,        /* Ύ-Ώ ύ-ώ */
       -        0x0391,        0x03a1, 532,        /* Α-Ρ α-ρ */
       -        0x03a3,        0x03ab, 532,        /* Σ-Ϋ σ-ϋ */
       -        0x0401,        0x040c, 580,        /* Ё-Ќ ё-ќ */
       -        0x040e,        0x040f, 580,        /* Ў-Џ ў-џ */
       -        0x0410,        0x042f, 532,        /* А-Я а-я */
       -        0x0531,        0x0556, 548,        /* Ա-Ֆ ա-ֆ */
       -        0x10a0,        0x10c5, 548,        /* Ⴀ-Ⴥ ა-ჵ */
       -        0x1f08,        0x1f0f, 492,        /* Ἀ-Ἇ ἀ-ἇ */
       -        0x1f18,        0x1f1d, 492,        /* Ἐ-Ἕ ἐ-ἕ */
       -        0x1f28,        0x1f2f, 492,        /* Ἠ-Ἧ ἠ-ἧ */
       -        0x1f38,        0x1f3f, 492,        /* Ἰ-Ἷ ἰ-ἷ */
       -        0x1f48,        0x1f4d, 492,        /* Ὀ-Ὅ ὀ-ὅ */
       -        0x1f68,        0x1f6f, 492,        /* Ὠ-Ὧ ὠ-ὧ */
       -        0x1f88,        0x1f8f, 492,        /* ᾈ-ᾏ ᾀ-ᾇ */
       -        0x1f98,        0x1f9f, 492,        /* ᾘ-ᾟ ᾐ-ᾗ */
       -        0x1fa8,        0x1faf, 492,        /* ᾨ-ᾯ ᾠ-ᾧ */
       -        0x1fb8,        0x1fb9, 492,        /* Ᾰ-Ᾱ ᾰ-ᾱ */
       -        0x1fba,        0x1fbb, 426,        /* Ὰ-Ά ὰ-ά */
       -        0x1fc8,        0x1fcb, 414,        /* Ὲ-Ή ὲ-ή */
       -        0x1fd8,        0x1fd9, 492,        /* Ῐ-Ῑ ῐ-ῑ */
       -        0x1fda,        0x1fdb, 400,        /* Ὶ-Ί ὶ-ί */
       -        0x1fe8,        0x1fe9, 492,        /* Ῠ-Ῡ ῠ-ῡ */
       -        0x1fea,        0x1feb, 388,        /* Ὺ-Ύ ὺ-ύ */
       -        0x1ff8,        0x1ff9, 372,        /* Ὸ-Ό ὸ-ό */
       -        0x1ffa,        0x1ffb, 374,        /* Ὼ-Ώ ὼ-ώ */
       -        0x2160,        0x216f, 516,        /* Ⅰ-Ⅿ ⅰ-ⅿ */
       -        0x24b6,        0x24cf, 526,        /* Ⓐ-Ⓩ ⓐ-ⓩ */
       -        0xff21,        0xff3a, 532,        /* A-Z a-z */
       -};
       -
       -/*
       - * upper case singlets
       - *        2nd col is conversion excess 500
       - */
       -static
       -Rune        __tolower1[] =
       -{
       -        0x0100, 501,        /* Ā ā */
       -        0x0102, 501,        /* Ă ă */
       -        0x0104, 501,        /* Ą ą */
       -        0x0106, 501,        /* Ć ć */
       -        0x0108, 501,        /* Ĉ ĉ */
       -        0x010a, 501,        /* Ċ ċ */
       -        0x010c, 501,        /* Č č */
       -        0x010e, 501,        /* Ď ď */
       -        0x0110, 501,        /* Đ đ */
       -        0x0112, 501,        /* Ē ē */
       -        0x0114, 501,        /* Ĕ ĕ */
       -        0x0116, 501,        /* Ė ė */
       -        0x0118, 501,        /* Ę ę */
       -        0x011a, 501,        /* Ě ě */
       -        0x011c, 501,        /* Ĝ ĝ */
       -        0x011e, 501,        /* Ğ ğ */
       -        0x0120, 501,        /* Ġ ġ */
       -        0x0122, 501,        /* Ģ ģ */
       -        0x0124, 501,        /* Ĥ ĥ */
       -        0x0126, 501,        /* Ħ ħ */
       -        0x0128, 501,        /* Ĩ ĩ */
       -        0x012a, 501,        /* Ī ī */
       -        0x012c, 501,        /* Ĭ ĭ */
       -        0x012e, 501,        /* Į į */
       -        0x0130, 301,        /* İ i */
       -        0x0132, 501,        /* IJ ij */
       -        0x0134, 501,        /* Ĵ ĵ */
       -        0x0136, 501,        /* Ķ ķ */
       -        0x0139, 501,        /* Ĺ ĺ */
       -        0x013b, 501,        /* Ļ ļ */
       -        0x013d, 501,        /* Ľ ľ */
       -        0x013f, 501,        /* Ŀ ŀ */
       -        0x0141, 501,        /* Ł ł */
       -        0x0143, 501,        /* Ń ń */
       -        0x0145, 501,        /* Ņ ņ */
       -        0x0147, 501,        /* Ň ň */
       -        0x014a, 501,        /* Ŋ ŋ */
       -        0x014c, 501,        /* Ō ō */
       -        0x014e, 501,        /* Ŏ ŏ */
       -        0x0150, 501,        /* Ő ő */
       -        0x0152, 501,        /* Œ œ */
       -        0x0154, 501,        /* Ŕ ŕ */
       -        0x0156, 501,        /* Ŗ ŗ */
       -        0x0158, 501,        /* Ř ř */
       -        0x015a, 501,        /* Ś ś */
       -        0x015c, 501,        /* Ŝ ŝ */
       -        0x015e, 501,        /* Ş ş */
       -        0x0160, 501,        /* Š š */
       -        0x0162, 501,        /* Ţ ţ */
       -        0x0164, 501,        /* Ť ť */
       -        0x0166, 501,        /* Ŧ ŧ */
       -        0x0168, 501,        /* Ũ ũ */
       -        0x016a, 501,        /* Ū ū */
       -        0x016c, 501,        /* Ŭ ŭ */
       -        0x016e, 501,        /* Ů ů */
       -        0x0170, 501,        /* Ű ű */
       -        0x0172, 501,        /* Ų ų */
       -        0x0174, 501,        /* Ŵ ŵ */
       -        0x0176, 501,        /* Ŷ ŷ */
       -        0x0178, 379,        /* Ÿ ÿ */
       -        0x0179, 501,        /* Ź ź */
       -        0x017b, 501,        /* Ż ż */
       -        0x017d, 501,        /* Ž ž */
       -        0x0181, 710,        /* Ɓ ɓ */
       -        0x0182, 501,        /* Ƃ ƃ */
       -        0x0184, 501,        /* Ƅ ƅ */
       -        0x0186, 706,        /* Ɔ ɔ */
       -        0x0187, 501,        /* Ƈ ƈ */
       -        0x018b, 501,        /* Ƌ ƌ */
       -        0x0190, 703,        /* Ɛ ɛ */
       -        0x0191, 501,        /* Ƒ ƒ */
       -        0x0193, 705,        /* Ɠ ɠ */
       -        0x0194, 707,        /* Ɣ ɣ */
       -        0x0196, 711,        /* Ɩ ɩ */
       -        0x0197, 709,        /* Ɨ ɨ */
       -        0x0198, 501,        /* Ƙ ƙ */
       -        0x019c, 711,        /* Ɯ ɯ */
       -        0x019d, 713,        /* Ɲ ɲ */
       -        0x01a0, 501,        /* Ơ ơ */
       -        0x01a2, 501,        /* Ƣ ƣ */
       -        0x01a4, 501,        /* Ƥ ƥ */
       -        0x01a7, 501,        /* Ƨ ƨ */
       -        0x01a9, 718,        /* Ʃ ʃ */
       -        0x01ac, 501,        /* Ƭ ƭ */
       -        0x01ae, 718,        /* Ʈ ʈ */
       -        0x01af, 501,        /* Ư ư */
       -        0x01b3, 501,        /* Ƴ ƴ */
       -        0x01b5, 501,        /* Ƶ ƶ */
       -        0x01b7, 719,        /* Ʒ ʒ */
       -        0x01b8, 501,        /* Ƹ ƹ */
       -        0x01bc, 501,        /* Ƽ ƽ */
       -        0x01c4, 502,        /* DŽ dž */
       -        0x01c5, 501,        /* Dž dž */
       -        0x01c7, 502,        /* LJ lj */
       -        0x01c8, 501,        /* Lj lj */
       -        0x01ca, 502,        /* NJ nj */
       -        0x01cb, 501,        /* Nj nj */
       -        0x01cd, 501,        /* Ǎ ǎ */
       -        0x01cf, 501,        /* Ǐ ǐ */
       -        0x01d1, 501,        /* Ǒ ǒ */
       -        0x01d3, 501,        /* Ǔ ǔ */
       -        0x01d5, 501,        /* Ǖ ǖ */
       -        0x01d7, 501,        /* Ǘ ǘ */
       -        0x01d9, 501,        /* Ǚ ǚ */
       -        0x01db, 501,        /* Ǜ ǜ */
       -        0x01de, 501,        /* Ǟ ǟ */
       -        0x01e0, 501,        /* Ǡ ǡ */
       -        0x01e2, 501,        /* Ǣ ǣ */
       -        0x01e4, 501,        /* Ǥ ǥ */
       -        0x01e6, 501,        /* Ǧ ǧ */
       -        0x01e8, 501,        /* Ǩ ǩ */
       -        0x01ea, 501,        /* Ǫ ǫ */
       -        0x01ec, 501,        /* Ǭ ǭ */
       -        0x01ee, 501,        /* Ǯ ǯ */
       -        0x01f1, 502,        /* DZ dz */
       -        0x01f2, 501,        /* Dz dz */
       -        0x01f4, 501,        /* Ǵ ǵ */
       -        0x01fa, 501,        /* Ǻ ǻ */
       -        0x01fc, 501,        /* Ǽ ǽ */
       -        0x01fe, 501,        /* Ǿ ǿ */
       -        0x0200, 501,        /* Ȁ ȁ */
       -        0x0202, 501,        /* Ȃ ȃ */
       -        0x0204, 501,        /* Ȅ ȅ */
       -        0x0206, 501,        /* Ȇ ȇ */
       -        0x0208, 501,        /* Ȉ ȉ */
       -        0x020a, 501,        /* Ȋ ȋ */
       -        0x020c, 501,        /* Ȍ ȍ */
       -        0x020e, 501,        /* Ȏ ȏ */
       -        0x0210, 501,        /* Ȑ ȑ */
       -        0x0212, 501,        /* Ȓ ȓ */
       -        0x0214, 501,        /* Ȕ ȕ */
       -        0x0216, 501,        /* Ȗ ȗ */
       -        0x0386, 538,        /* Ά ά */
       -        0x038c, 564,        /* Ό ό */
       -        0x03e2, 501,        /* Ϣ ϣ */
       -        0x03e4, 501,        /* Ϥ ϥ */
       -        0x03e6, 501,        /* Ϧ ϧ */
       -        0x03e8, 501,        /* Ϩ ϩ */
       -        0x03ea, 501,        /* Ϫ ϫ */
       -        0x03ec, 501,        /* Ϭ ϭ */
       -        0x03ee, 501,        /* Ϯ ϯ */
       -        0x0460, 501,        /* Ѡ ѡ */
       -        0x0462, 501,        /* Ѣ ѣ */
       -        0x0464, 501,        /* Ѥ ѥ */
       -        0x0466, 501,        /* Ѧ ѧ */
       -        0x0468, 501,        /* Ѩ ѩ */
       -        0x046a, 501,        /* Ѫ ѫ */
       -        0x046c, 501,        /* Ѭ ѭ */
       -        0x046e, 501,        /* Ѯ ѯ */
       -        0x0470, 501,        /* Ѱ ѱ */
       -        0x0472, 501,        /* Ѳ ѳ */
       -        0x0474, 501,        /* Ѵ ѵ */
       -        0x0476, 501,        /* Ѷ ѷ */
       -        0x0478, 501,        /* Ѹ ѹ */
       -        0x047a, 501,        /* Ѻ ѻ */
       -        0x047c, 501,        /* Ѽ ѽ */
       -        0x047e, 501,        /* Ѿ ѿ */
       -        0x0480, 501,        /* Ҁ ҁ */
       -        0x0490, 501,        /* Ґ ґ */
       -        0x0492, 501,        /* Ғ ғ */
       -        0x0494, 501,        /* Ҕ ҕ */
       -        0x0496, 501,        /* Җ җ */
       -        0x0498, 501,        /* Ҙ ҙ */
       -        0x049a, 501,        /* Қ қ */
       -        0x049c, 501,        /* Ҝ ҝ */
       -        0x049e, 501,        /* Ҟ ҟ */
       -        0x04a0, 501,        /* Ҡ ҡ */
       -        0x04a2, 501,        /* Ң ң */
       -        0x04a4, 501,        /* Ҥ ҥ */
       -        0x04a6, 501,        /* Ҧ ҧ */
       -        0x04a8, 501,        /* Ҩ ҩ */
       -        0x04aa, 501,        /* Ҫ ҫ */
       -        0x04ac, 501,        /* Ҭ ҭ */
       -        0x04ae, 501,        /* Ү ү */
       -        0x04b0, 501,        /* Ұ ұ */
       -        0x04b2, 501,        /* Ҳ ҳ */
       -        0x04b4, 501,        /* Ҵ ҵ */
       -        0x04b6, 501,        /* Ҷ ҷ */
       -        0x04b8, 501,        /* Ҹ ҹ */
       -        0x04ba, 501,        /* Һ һ */
       -        0x04bc, 501,        /* Ҽ ҽ */
       -        0x04be, 501,        /* Ҿ ҿ */
       -        0x04c1, 501,        /* Ӂ ӂ */
       -        0x04c3, 501,        /* Ӄ ӄ */
       -        0x04c7, 501,        /* Ӈ ӈ */
       -        0x04cb, 501,        /* Ӌ ӌ */
       -        0x04d0, 501,        /* Ӑ ӑ */
       -        0x04d2, 501,        /* Ӓ ӓ */
       -        0x04d4, 501,        /* Ӕ ӕ */
       -        0x04d6, 501,        /* Ӗ ӗ */
       -        0x04d8, 501,        /* Ә ә */
       -        0x04da, 501,        /* Ӛ ӛ */
       -        0x04dc, 501,        /* Ӝ ӝ */
       -        0x04de, 501,        /* Ӟ ӟ */
       -        0x04e0, 501,        /* Ӡ ӡ */
       -        0x04e2, 501,        /* Ӣ ӣ */
       -        0x04e4, 501,        /* Ӥ ӥ */
       -        0x04e6, 501,        /* Ӧ ӧ */
       -        0x04e8, 501,        /* Ө ө */
       -        0x04ea, 501,        /* Ӫ ӫ */
       -        0x04ee, 501,        /* Ӯ ӯ */
       -        0x04f0, 501,        /* Ӱ ӱ */
       -        0x04f2, 501,        /* Ӳ ӳ */
       -        0x04f4, 501,        /* Ӵ ӵ */
       -        0x04f8, 501,        /* Ӹ ӹ */
       -        0x1e00, 501,        /* Ḁ ḁ */
       -        0x1e02, 501,        /* Ḃ ḃ */
       -        0x1e04, 501,        /* Ḅ ḅ */
       -        0x1e06, 501,        /* Ḇ ḇ */
       -        0x1e08, 501,        /* Ḉ ḉ */
       -        0x1e0a, 501,        /* Ḋ ḋ */
       -        0x1e0c, 501,        /* Ḍ ḍ */
       -        0x1e0e, 501,        /* Ḏ ḏ */
       -        0x1e10, 501,        /* Ḑ ḑ */
       -        0x1e12, 501,        /* Ḓ ḓ */
       -        0x1e14, 501,        /* Ḕ ḕ */
       -        0x1e16, 501,        /* Ḗ ḗ */
       -        0x1e18, 501,        /* Ḙ ḙ */
       -        0x1e1a, 501,        /* Ḛ ḛ */
       -        0x1e1c, 501,        /* Ḝ ḝ */
       -        0x1e1e, 501,        /* Ḟ ḟ */
       -        0x1e20, 501,        /* Ḡ ḡ */
       -        0x1e22, 501,        /* Ḣ ḣ */
       -        0x1e24, 501,        /* Ḥ ḥ */
       -        0x1e26, 501,        /* Ḧ ḧ */
       -        0x1e28, 501,        /* Ḩ ḩ */
       -        0x1e2a, 501,        /* Ḫ ḫ */
       -        0x1e2c, 501,        /* Ḭ ḭ */
       -        0x1e2e, 501,        /* Ḯ ḯ */
       -        0x1e30, 501,        /* Ḱ ḱ */
       -        0x1e32, 501,        /* Ḳ ḳ */
       -        0x1e34, 501,        /* Ḵ ḵ */
       -        0x1e36, 501,        /* Ḷ ḷ */
       -        0x1e38, 501,        /* Ḹ ḹ */
       -        0x1e3a, 501,        /* Ḻ ḻ */
       -        0x1e3c, 501,        /* Ḽ ḽ */
       -        0x1e3e, 501,        /* Ḿ ḿ */
       -        0x1e40, 501,        /* Ṁ ṁ */
       -        0x1e42, 501,        /* Ṃ ṃ */
       -        0x1e44, 501,        /* Ṅ ṅ */
       -        0x1e46, 501,        /* Ṇ ṇ */
       -        0x1e48, 501,        /* Ṉ ṉ */
       -        0x1e4a, 501,        /* Ṋ ṋ */
       -        0x1e4c, 501,        /* Ṍ ṍ */
       -        0x1e4e, 501,        /* Ṏ ṏ */
       -        0x1e50, 501,        /* Ṑ ṑ */
       -        0x1e52, 501,        /* Ṓ ṓ */
       -        0x1e54, 501,        /* Ṕ ṕ */
       -        0x1e56, 501,        /* Ṗ ṗ */
       -        0x1e58, 501,        /* Ṙ ṙ */
       -        0x1e5a, 501,        /* Ṛ ṛ */
       -        0x1e5c, 501,        /* Ṝ ṝ */
       -        0x1e5e, 501,        /* Ṟ ṟ */
       -        0x1e60, 501,        /* Ṡ ṡ */
       -        0x1e62, 501,        /* Ṣ ṣ */
       -        0x1e64, 501,        /* Ṥ ṥ */
       -        0x1e66, 501,        /* Ṧ ṧ */
       -        0x1e68, 501,        /* Ṩ ṩ */
       -        0x1e6a, 501,        /* Ṫ ṫ */
       -        0x1e6c, 501,        /* Ṭ ṭ */
       -        0x1e6e, 501,        /* Ṯ ṯ */
       -        0x1e70, 501,        /* Ṱ ṱ */
       -        0x1e72, 501,        /* Ṳ ṳ */
       -        0x1e74, 501,        /* Ṵ ṵ */
       -        0x1e76, 501,        /* Ṷ ṷ */
       -        0x1e78, 501,        /* Ṹ ṹ */
       -        0x1e7a, 501,        /* Ṻ ṻ */
       -        0x1e7c, 501,        /* Ṽ ṽ */
       -        0x1e7e, 501,        /* Ṿ ṿ */
       -        0x1e80, 501,        /* Ẁ ẁ */
       -        0x1e82, 501,        /* Ẃ ẃ */
       -        0x1e84, 501,        /* Ẅ ẅ */
       -        0x1e86, 501,        /* Ẇ ẇ */
       -        0x1e88, 501,        /* Ẉ ẉ */
       -        0x1e8a, 501,        /* Ẋ ẋ */
       -        0x1e8c, 501,        /* Ẍ ẍ */
       -        0x1e8e, 501,        /* Ẏ ẏ */
       -        0x1e90, 501,        /* Ẑ ẑ */
       -        0x1e92, 501,        /* Ẓ ẓ */
       -        0x1e94, 501,        /* Ẕ ẕ */
       -        0x1ea0, 501,        /* Ạ ạ */
       -        0x1ea2, 501,        /* Ả ả */
       -        0x1ea4, 501,        /* Ấ ấ */
       -        0x1ea6, 501,        /* Ầ ầ */
       -        0x1ea8, 501,        /* Ẩ ẩ */
       -        0x1eaa, 501,        /* Ẫ ẫ */
       -        0x1eac, 501,        /* Ậ ậ */
       -        0x1eae, 501,        /* Ắ ắ */
       -        0x1eb0, 501,        /* Ằ ằ */
       -        0x1eb2, 501,        /* Ẳ ẳ */
       -        0x1eb4, 501,        /* Ẵ ẵ */
       -        0x1eb6, 501,        /* Ặ ặ */
       -        0x1eb8, 501,        /* Ẹ ẹ */
       -        0x1eba, 501,        /* Ẻ ẻ */
       -        0x1ebc, 501,        /* Ẽ ẽ */
       -        0x1ebe, 501,        /* Ế ế */
       -        0x1ec0, 501,        /* Ề ề */
       -        0x1ec2, 501,        /* Ể ể */
       -        0x1ec4, 501,        /* Ễ ễ */
       -        0x1ec6, 501,        /* Ệ ệ */
       -        0x1ec8, 501,        /* Ỉ ỉ */
       -        0x1eca, 501,        /* Ị ị */
       -        0x1ecc, 501,        /* Ọ ọ */
       -        0x1ece, 501,        /* Ỏ ỏ */
       -        0x1ed0, 501,        /* Ố ố */
       -        0x1ed2, 501,        /* Ồ ồ */
       -        0x1ed4, 501,        /* Ổ ổ */
       -        0x1ed6, 501,        /* Ỗ ỗ */
       -        0x1ed8, 501,        /* Ộ ộ */
       -        0x1eda, 501,        /* Ớ ớ */
       -        0x1edc, 501,        /* Ờ ờ */
       -        0x1ede, 501,        /* Ở ở */
       -        0x1ee0, 501,        /* Ỡ ỡ */
       -        0x1ee2, 501,        /* Ợ ợ */
       -        0x1ee4, 501,        /* Ụ ụ */
       -        0x1ee6, 501,        /* Ủ ủ */
       -        0x1ee8, 501,        /* Ứ ứ */
       -        0x1eea, 501,        /* Ừ ừ */
       -        0x1eec, 501,        /* Ử ử */
       -        0x1eee, 501,        /* Ữ ữ */
       -        0x1ef0, 501,        /* Ự ự */
       -        0x1ef2, 501,        /* Ỳ ỳ */
       -        0x1ef4, 501,        /* Ỵ ỵ */
       -        0x1ef6, 501,        /* Ỷ ỷ */
       -        0x1ef8, 501,        /* Ỹ ỹ */
       -        0x1f59, 492,        /* Ὑ ὑ */
       -        0x1f5b, 492,        /* Ὓ ὓ */
       -        0x1f5d, 492,        /* Ὕ ὕ */
       -        0x1f5f, 492,        /* Ὗ ὗ */
       -        0x1fbc, 491,        /* ᾼ ᾳ */
       -        0x1fcc, 491,        /* ῌ ῃ */
       -        0x1fec, 493,        /* Ῥ ῥ */
       -        0x1ffc, 491,        /* ῼ ῳ */
       -};
       -
       -/*
       - * title characters are those between
       - * upper and lower case. ie DZ Dz dz
       - */
       -static
       -Rune        __totitle1[] =
       -{
       -        0x01c4, 501,        /* DŽ Dž */
       -        0x01c6, 499,        /* dž Dž */
       -        0x01c7, 501,        /* LJ Lj */
       -        0x01c9, 499,        /* lj Lj */
       -        0x01ca, 501,        /* NJ Nj */
       -        0x01cc, 499,        /* nj Nj */
       -        0x01f1, 501,        /* DZ Dz */
       -        0x01f3, 499,        /* dz Dz */
       -};
       -
       -static
       -Rune*
       -bsearch(Rune c, Rune *t, int n, int ne)
       -{
       -        Rune *p;
       -        int m;
       -
       -        while(n > 1) {
       -                m = n/2;
       -                p = t + m*ne;
       -                if(c >= p[0]) {
       -                        t = p;
       -                        n = n-m;
       -                } else
       -                        n = m;
       -        }
       -        if(n && c >= t[0])
       -                return t;
       -        return 0;
       -}
       -
       -Rune
       -tolowerrune(Rune c)
       -{
       -        Rune *p;
       -
       -        p = bsearch(c, __tolower2, nelem(__tolower2)/3, 3);
       -        if(p && c >= p[0] && c <= p[1])
       -                return c + p[2] - 500;
       -        p = bsearch(c, __tolower1, nelem(__tolower1)/2, 2);
       -        if(p && c == p[0])
       -                return c + p[1] - 500;
       -        return c;
       -}
       -
       -Rune
       -toupperrune(Rune c)
       -{
       -        Rune *p;
       -
       -        p = bsearch(c, __toupper2, nelem(__toupper2)/3, 3);
       -        if(p && c >= p[0] && c <= p[1])
       -                return c + p[2] - 500;
       -        p = bsearch(c, __toupper1, nelem(__toupper1)/2, 2);
       -        if(p && c == p[0])
       -                return c + p[1] - 500;
       -        return c;
       -}
       -
       -Rune
       -totitlerune(Rune c)
       -{
       -        Rune *p;
       -
       -        p = bsearch(c, __totitle1, nelem(__totitle1)/2, 2);
       -        if(p && c == p[0])
       -                return c + p[1] - 500;
       -        return c;
       -}
       -
       -int
       -islowerrune(Rune c)
       -{
       -        Rune *p;
       -
       -        p = bsearch(c, __toupper2, nelem(__toupper2)/3, 3);
       -        if(p && c >= p[0] && c <= p[1])
       -                return 1;
       -        p = bsearch(c, __toupper1, nelem(__toupper1)/2, 2);
       -        if(p && c == p[0])
       -                return 1;
       -        return 0;
       -}
       -
       -int
       -isupperrune(Rune c)
       -{
       -        Rune *p;
       -
       -        p = bsearch(c, __tolower2, nelem(__tolower2)/3, 3);
       -        if(p && c >= p[0] && c <= p[1])
       -                return 1;
       -        p = bsearch(c, __tolower1, nelem(__tolower1)/2, 2);
       -        if(p && c == p[0])
       -                return 1;
       -        return 0;
       -}
       -
       -int
       -isalpharune(Rune c)
       -{
       -        Rune *p;
       -
       -        if(isupperrune(c) || islowerrune(c))
       -                return 1;
       -        p = bsearch(c, __alpha2, nelem(__alpha2)/2, 2);
       -        if(p && c >= p[0] && c <= p[1])
       -                return 1;
       -        p = bsearch(c, __alpha1, nelem(__alpha1), 1);
       -        if(p && c == p[0])
       -                return 1;
       -        return 0;
       -}
       -
       -int
       -istitlerune(Rune c)
       -{
       -        return isupperrune(c) && islowerrune(c);
       -}
       -
       -int
       -isspacerune(Rune c)
       -{
       -        Rune *p;
       -
       -        p = bsearch(c, __space2, nelem(__space2)/2, 2);
       -        if(p && c >= p[0] && c <= p[1])
       -                return 1;
       -        return 0;
       -}
   DIR diff --git a/src/libutf/utfdef.h b/src/libutf/utfdef.h
       t@@ -1,14 +0,0 @@
       -#define uchar _utfuchar
       -#define ushort _utfushort
       -#define uint _utfuint
       -#define ulong _utfulong
       -#define vlong _utfvlong
       -#define uvlong _utfuvlong
       -
       -typedef unsigned char                uchar;
       -typedef unsigned short                ushort;
       -typedef unsigned int                uint;
       -typedef unsigned long                ulong;
       -
       -#define nelem(x) (sizeof(x)/sizeof((x)[0]))
       -#define nil ((void*)0)
   DIR diff --git a/src/libutf/utfecpy.c b/src/libutf/utfecpy.c
       t@@ -1,36 +0,0 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
       - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       -#include <stdarg.h>
       -#include <string.h>
       -#include "utf.h"
       -#include "utfdef.h"
       -
       -char*
       -utfecpy(char *to, char *e, char *from)
       -{
       -        char *end;
       -
       -        if(to >= e)
       -                return to;
       -        end = memccpy(to, from, '\0', e - to);
       -        if(end == nil){
       -                end = e-1;
       -                while(end>to && (*--end&0xC0)==0x80)
       -                        ;
       -                *end = '\0';
       -        }else{
       -                end--;
       -        }
       -        return end;
       -}
   DIR diff --git a/src/libutf/utflen.c b/src/libutf/utflen.c
       t@@ -1,38 +0,0 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
       - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       -#include <stdarg.h>
       -#include <string.h>
       -#include "utf.h"
       -#include "utfdef.h"
       -
       -int
       -utflen(char *s)
       -{
       -        int c;
       -        long n;
       -        Rune rune;
       -
       -        n = 0;
       -        for(;;) {
       -                c = *(uchar*)s;
       -                if(c < Runeself) {
       -                        if(c == 0)
       -                                return n;
       -                        s++;
       -                } else
       -                        s += chartorune(&rune, s);
       -                n++;
       -        }
       -        return 0;
       -}
   DIR diff --git a/src/libutf/utfnlen.c b/src/libutf/utfnlen.c
       t@@ -1,41 +0,0 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
       - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       -#include <stdarg.h>
       -#include <string.h>
       -#include "utf.h"
       -#include "utfdef.h"
       -
       -int
       -utfnlen(char *s, long m)
       -{
       -        int c;
       -        long n;
       -        Rune rune;
       -        char *es;
       -
       -        es = s + m;
       -        for(n = 0; s < es; n++) {
       -                c = *(uchar*)s;
       -                if(c < Runeself){
       -                        if(c == '\0')
       -                                break;
       -                        s++;
       -                        continue;
       -                }
       -                if(!fullrune(s, es-s))
       -                        break;
       -                s += chartorune(&rune, s);
       -        }
       -        return n;
       -}
   DIR diff --git a/src/libutf/utfrrune.c b/src/libutf/utfrrune.c
       t@@ -1,46 +0,0 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
       - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       -#include <stdarg.h>
       -#include <string.h>
       -#include "utf.h"
       -#include "utfdef.h"
       -
       -char*
       -utfrrune(char *s, long c)
       -{
       -        long c1;
       -        Rune r;
       -        char *s1;
       -
       -        if(c < Runesync)                /* not part of utf sequence */
       -                return strrchr(s, c);
       -
       -        s1 = 0;
       -        for(;;) {
       -                c1 = *(uchar*)s;
       -                if(c1 < Runeself) {        /* one byte rune */
       -                        if(c1 == 0)
       -                                return s1;
       -                        if(c1 == c)
       -                                s1 = s;
       -                        s++;
       -                        continue;
       -                }
       -                c1 = chartorune(&r, s);
       -                if(r == c)
       -                        s1 = s;
       -                s += c1;
       -        }
       -        return 0;
       -}
   DIR diff --git a/src/libutf/utfrune.c b/src/libutf/utfrune.c
       t@@ -1,45 +0,0 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
       - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       -#include <stdarg.h>
       -#include <string.h>
       -#include "utf.h"
       -#include "utfdef.h"
       -
       -char*
       -utfrune(char *s, long c)
       -{
       -        long c1;
       -        Rune r;
       -        int n;
       -
       -        if(c < Runesync)                /* not part of utf sequence */
       -                return strchr(s, c);
       -
       -        for(;;) {
       -                c1 = *(uchar*)s;
       -                if(c1 < Runeself) {        /* one byte rune */
       -                        if(c1 == 0)
       -                                return 0;
       -                        if(c1 == c)
       -                                return s;
       -                        s++;
       -                        continue;
       -                }
       -                n = chartorune(&r, s);
       -                if(r == c)
       -                        return s;
       -                s += n;
       -        }
       -        return 0;
       -}
   DIR diff --git a/src/libutf/utfutf.c b/src/libutf/utfutf.c
       t@@ -1,41 +0,0 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
       - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       -#include <stdarg.h>
       -#include <string.h>
       -#include "utf.h"
       -#include "utfdef.h"
       -
       -
       -/*
       - * Return pointer to first occurrence of s2 in s1,
       - * 0 if none
       - */
       -char*
       -utfutf(char *s1, char *s2)
       -{
       -        char *p;
       -        long f, n1, n2;
       -        Rune r;
       -
       -        n1 = chartorune(&r, s2);
       -        f = r;
       -        if(f <= Runesync)                /* represents self */
       -                return strstr(s1, s2);
       -
       -        n2 = strlen(s2);
       -        for(p=s1; p=utfrune(p, f); p+=n1)
       -                if(strncmp(p, s2, n2) == 0)
       -                        return p;
       -        return 0;
       -}
   DIR diff --git a/src/mkfile b/src/mkfile
       t@@ -4,18 +4,16 @@ DIRS=\
                libbio\
                libdraw\
                libflate\
       -        libfmt\
                libframe\
                libfs\
       -        libhttpd\
       +#        libhttpd\
        #        libip\
                libmux\
                libplumb\
                libregexp\
                libsec\
                libthread\
       -        libutf\
       -        libventi\
       +#        libventi\
                cmd\
        
        <mkdirs