tVarious fixes, add spell. - plan9port - [fork] Plan 9 from user space
 (HTM) git clone git://src.adamsgaard.dk/plan9port
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit d49a2e4801752c8a1211c7fac8cc08055a6b6fa5
 (DIR) parent fb7cc74a929c86ef1c84a971d7a05deaf4d30c85
 (HTM) Author: rsc <devnull@localhost>
       Date:   Tue,  9 Mar 2004 12:45:12 +0000
       
       Various fixes, add spell.
       
       Diffstat:
         A lib/amspell                         |       0 
         A lib/brspell                         |       0 
         M src/cmd/mkfile                      |       2 +-
         A src/cmd/spell/code.h                |      28 ++++++++++++++++++++++++++++
         A src/cmd/spell/mkfile                |      12 ++++++++++++
         A src/cmd/spell/spell.rc              |      21 +++++++++++++++++++++
         A src/cmd/spell/sprog.c               |    1381 +++++++++++++++++++++++++++++++
         M src/cmd/test.c                      |      15 ++-------------
         M src/cmd/win.c                       |       2 +-
         M src/libthread/threadimpl.h          |       1 +
         M src/mkfile                          |      20 ++++----------------
         M src/mkmk.sh                         |       3 +--
       
       12 files changed, 1452 insertions(+), 33 deletions(-)
       ---
 (DIR) diff --git a/lib/amspell b/lib/amspell
       Binary files differ.
 (DIR) diff --git a/lib/brspell b/lib/brspell
       Binary files differ.
 (DIR) diff --git a/src/cmd/mkfile b/src/cmd/mkfile
       t@@ -8,7 +8,7 @@ SHORTLIB=sec fs mux regexp9 thread bio 9
        <$PLAN9/src/mkmany
        
        BUGGERED='CVS|faces|factotum|oplumb|plumb2|mk|vac|9term|upas|venti|htmlfmt'
       -DIRS=`ls -l |sed -n 's/^d.* //p' |egrep -v "$BUGGERED"`
       +DIRS=`ls -l |sed -n 's/^d.* //p' |egrep -v "^($BUGGERED)$"`
        
        <$PLAN9/src/mkdirs
        
 (DIR) diff --git a/src/cmd/spell/code.h b/src/cmd/spell/code.h
       t@@ -0,0 +1,28 @@
       +
       +/*
       + * affix codes
       + */
       +
       +#define        ED                (1<<0)        /* +ed, +ing */
       +#define        ADJ                (1<<1)        /* (nce)-t_ce, +ize,+al, +ness, -t+cy, +ity, +ly */        
       +#define        NOUN                (1<<2)        /* +s (+es), +make, +hood, +ship +less  */
       +#define PROP_COLLECT        (1<<3)        /* +'s,  +an, +ship(for -manship) +less */
       +#define ACTOR                (1<<4)        /* +er  */
       +#define        EST                (1<<5)
       +#define COMP                (EST|ACTOR)        /* +er,+est */
       +#define        DONT_TOUCH        (1<<6)
       +#define        ION                (1<<7)        /* +ion, +or */
       +#define        N_AFFIX                (1<<8)         /* +ic, +ive, +ize, +like, +al, +ful, +ism, +ist, -t+cy, +c (maniac) */
       +#define        V_AFFIX                (1<<9)        /* +able, +ive, +ity((bility), +ment */
       +#define        V_IRREG                (1<<10)        /* +ing +es +s*/
       +#define        VERB                (V_IRREG|ED) 
       +#define MAN                (1<<11)        /* +man, +men, +women, +woman */
       +#define        ADV                (1<<12)        /* +hood, +ness */
       +#define STOP                (1<<14)        /* stop list */
       +#define        NOPREF                (1<<13)        /* no prefix */
       +
       +#define MONO                (1<<15)        /* double final consonant as in fib->fibbing */
       +#define IN                (1<<16) /* in- im- ir, not un- */
       +#define _Y                (1<<17)        /* +y */
       +
       +#define ALL                (~(NOPREF|STOP|DONT_TOUCH|MONO|IN))    /*anything goes (no stop or nopref)*/
 (DIR) diff --git a/src/cmd/spell/mkfile b/src/cmd/spell/mkfile
       t@@ -0,0 +1,12 @@
       +PLAN9=../../..
       +<$PLAN9/src/mkhdr
       +
       +TARG=sprog
       +OFILES=sprog.$O\
       +
       +HFILES =\
       +        code.h\
       +
       +SHORTLIB=bio 9
       +<$PLAN9/src/mkone
       +
 (DIR) diff --git a/src/cmd/spell/spell.rc b/src/cmd/spell/spell.rc
       t@@ -0,0 +1,21 @@
       +#!/bin/rc
       +
       +spellflags=()
       +deroffargs=()
       +fflag=''
       +for(x){
       +        switch($x){
       +        case -[abcvx]
       +                spellflags=($spellflags $x)
       +        case -f
       +                fflag=$x
       +        case *
       +                if(~ $fflag -f)        {
       +                        spellflags=($spellflags -f $x)
       +                        fflag=''
       +                }
       +                if not                deroffargs=($deroffargs $x)
       +        }
       +}
       +
       +deroff -w $deroffargs | sort -u | aux/sprog $spellflags
 (DIR) diff --git a/src/cmd/spell/sprog.c b/src/cmd/spell/sprog.c
       t@@ -0,0 +1,1381 @@
       +#include <u.h>
       +#include <libc.h>
       +#include <bio.h>
       +#include <ctype.h>
       +#include "code.h"
       +
       +/* fig leaves for possibly signed char quantities */
       +#define ISUPPER(c)        isupper((c)&0xff)
       +#define ISLOWER(c)        islower((c)&0xff)
       +#define        ISALPHA(c)        isalpha((c)&0xff)
       +#define        ISDIGIT(c)        isdigit((c)&0xff)
       +#define ISVOWEL(c)        voweltab[(c)&0xff]
       +#define Tolower(c)        (ISUPPER(c)? (c)-'A'+'a': (c))
       +#define pair(a,b)        (((a)<<8) | (b))
       +#define DLEV                2
       +#define DSIZ                40
       +
       +typedef        long        Bits;
       +#define        Set(h, f)        ((long)(h) & (f))
       +
       +Bits         nop(char*, char*, char*, int, int);
       +Bits         strip(char*, char*, char*, int, int);
       +Bits         ize(char*, char*, char*, int, int);
       +Bits         i_to_y(char*, char*, char*, int, int);
       +Bits         ily(char*, char*, char*, int, int);
       +Bits         subst(char*, char*, char*, int, int);
       +Bits         CCe(char*, char*, char*, int, int);
       +Bits         tion(char*, char*, char*, int, int);
       +Bits         an(char*, char*, char*, int, int);
       +Bits         s(char*, char*, char*, int, int);
       +Bits         es(char*, char*, char*, int, int);
       +Bits         bility(char*, char*, char*, int, int);
       +Bits         y_to_e(char*, char*, char*, int, int);
       +Bits         VCe(char*, char*, char*, int, int);
       +
       +Bits         trypref(char*, char*, int, int);
       +Bits        tryword(char*, char*, int, int);
       +Bits         trysuff(char*, int, int);
       +Bits        dict(char*, char*);
       +void        typeprint(Bits);
       +void        pcomma(char*);
       +
       +void        ise(void);
       +int        ordinal(void);
       +char*        skipv(char*);
       +int        inun(char*, Bits);
       +char*        ztos(char*);
       +void        readdict(char*);
       +
       +typedef        struct        Ptab        Ptab;
       +struct        Ptab
       +{
       +        char*        s;
       +        int        flag;
       +};
       +
       +typedef        struct        Suftab        Suftab;
       +struct        Suftab
       +{
       +        char        *suf;
       +        Bits        (*p1)(char*, char*, char*, int, int);
       +        int        n1;
       +        char        *d1;
       +        char        *a1;
       +        int        flag;
       +        int        affixable;
       +        Bits        (*p2)(char*, char*, char*, int, int);
       +        int        n2;
       +        char        *d2;
       +        char        *a2;
       +};
       +
       +Suftab        staba[] = {
       +        {"aibohp",subst,1,"-e+ia","",NOUN, NOUN},
       +        0
       +};
       +
       +Suftab        stabc[] =
       +{
       +        {"cai",strip,1,"","+c",N_AFFIX, ADJ|NOUN},
       +        {"citsi",strip,2,"","+ic",N_AFFIX, ADJ | N_AFFIX | NOUN},
       +        {"citi",ize,1,"-e+ic","",N_AFFIX, ADJ },
       +        {"cihparg",i_to_y,1,"-y+ic","",NOUN, ADJ|NOUN },
       +        {"cipocs",ize,1,"-e+ic","",NOUN, ADJ },
       +        {"cirtem",i_to_y,1,"-y+ic","",NOUN, ADJ },
       +        {"cigol",i_to_y,1,"-y+ic","",NOUN, ADJ },
       +        {"cimono",i_to_y,1,"-y+ic","",NOUN, ADJ },
       +        {"cibohp",subst,1,"-e+ic","",NOUN, ADJ },
       +        0
       +};
       +Suftab        stabd[] =
       +{
       +        {"de",strip,1,"","+d",ED,ADJ |COMP,i_to_y,2,"-y+ied","+ed"},
       +        {"dooh",ily,4,"-y+ihood","+hood",NOUN | ADV, NOUN},
       +        0
       +};
       +Suftab        stabe[] =
       +{
       +        /*
       +         * V_affix for comment ->commence->commentment??
       +         */
       +        {"ecna",subst,1,"-t+ce","",ADJ,N_AFFIX|_Y|NOUN|VERB|ACTOR|V_AFFIX},
       +        {"ecne",subst,1,"-t+ce","",ADJ,N_AFFIX|_Y|NOUN|VERB|ACTOR|V_AFFIX},
       +        {"elbaif",i_to_y,4,"-y+iable","",V_IRREG,ADJ},
       +        {"elba",CCe,4,"-e+able","+able",V_AFFIX,ADJ},
       +        {"evi",subst,0,"-ion+ive","",N_AFFIX | V_AFFIX,NOUN | N_AFFIX| ADJ},
       +        {"ezi",CCe,3,"-e+ize","+ize",N_AFFIX|ADJ ,V_AFFIX | VERB |ION | COMP},
       +        {"ekil",strip,4,"","+like",N_AFFIX ,ADJ},
       +        0
       +};
       +Suftab        stabg[] =
       +{
       +        {"gniee",strip,3,"","+ing",V_IRREG ,ADJ|NOUN},
       +        {"gnikam",strip,6,"","+making",NOUN,NOUN},
       +        {"gnipeek",strip,7,"","+keeping",NOUN,NOUN},
       +        {"gni",CCe,3,"-e+ing","+ing",V_IRREG ,ADJ|ED|NOUN},
       +        0
       +};
       +Suftab        stabl[] =
       +{
       +        {"ladio",strip,2,"","+al",NOUN |ADJ,ADJ},
       +        {"laci",strip,2,"","+al",NOUN |ADJ,ADJ |NOUN|N_AFFIX},
       +        {"latnem",strip,2,"","+al",N_AFFIX,ADJ},
       +        {"lanoi",strip,2,"","+al",N_AFFIX,ADJ|NOUN},
       +        {"luf",ily,3,"-y+iful","+ful",N_AFFIX,ADJ | NOUN},
       +        0
       +};
       +Suftab        stabm[] =
       +{
       +                /* congregational + ism */
       +        {"msi",CCe,3,"-e+ism","ism",N_AFFIX|ADJ,NOUN},
       +        {"margo",subst,-1,"-ph+m","",NOUN,NOUN},
       +        0
       +};
       +Suftab        stabn[] =
       +{
       +        {"noitacifi",i_to_y,6,"-y+ication","",ION,NOUN | N_AFFIX},
       +        {"noitazi",ize,4,"-e+ation","",ION,NOUN| N_AFFIX},
       +        {"noit",tion,3,"-e+ion","+ion",ION,NOUN| N_AFFIX | V_AFFIX |VERB|ACTOR},
       +        {"naino",an,3,"","+ian",NOUN|PROP_COLLECT,NOUN| N_AFFIX},
       +        {"namow",strip,5,"","+woman",MAN,PROP_COLLECT|N_AFFIX},
       +        {"nam",strip,3,"","+man",MAN,PROP_COLLECT | N_AFFIX | VERB},
       +        {"na",an,1,"","+n",NOUN|PROP_COLLECT,NOUN | N_AFFIX},
       +        {"nemow",strip,5,"","+women",MAN,PROP_COLLECT},
       +        {"nem",strip,3,"","+man",MAN,PROP_COLLECT},
       +        {"nosrep",strip,6,"","+person",MAN,PROP_COLLECT},
       +        0
       +};
       +Suftab        stabp[] =
       +{
       +        {"pihs",strip,4,"","+ship",NOUN|PROP_COLLECT,NOUN| N_AFFIX},
       +        0
       +};
       +Suftab        stabr[] =
       +{
       +        {"rehparg",subst,1,"-y+er","",ACTOR,NOUN,strip,2,"","+er"},
       +        {"reyhparg",nop,0,"","",0,NOUN},
       +        {"reyl",nop,0,"","",0,NOUN},
       +        {"rekam",strip,5,"","+maker",NOUN,NOUN},
       +        {"repeek",strip,6,"","+keeper",NOUN,NOUN},
       +        {"re",strip,1,"","+r",ACTOR,NOUN | N_AFFIX|VERB|ADJ,        i_to_y,2,"-y+ier","+er"},
       +        {"rota",tion,2,"-e+or","",ION,NOUN| N_AFFIX|_Y},
       +        {"rotc",tion,2,"","+or",ION,NOUN| N_AFFIX},
       +        {"rotp",tion,2,"","+or",ION,NOUN| N_AFFIX},
       +        0
       +};
       +Suftab        stabs[] =
       +{
       +        {"ssen",ily,4,"-y+iness","+ness",ADJ|ADV,NOUN| N_AFFIX},
       +        {"ssel",ily,4,"-y+iless","+less",NOUN | PROP_COLLECT,ADJ },
       +        {"se",s,1,"","+s",NOUN | V_IRREG,DONT_TOUCH ,        es,2,"-y+ies","+es"},
       +        {"s'",s,2,"","+'s",PROP_COLLECT | NOUN,DONT_TOUCH },
       +        {"s",s,1,"","+s",NOUN | V_IRREG,DONT_TOUCH  },
       +        0
       +};
       +Suftab        stabt[] =
       +{
       +        {"tnem",strip,4,"","+ment",V_AFFIX,NOUN | N_AFFIX | ADJ|VERB},
       +        {"tse",strip,2,"","+st",EST,DONT_TOUCH,        i_to_y,3,"-y+iest","+est" },
       +        {"tsigol",i_to_y,2,"-y+ist","",N_AFFIX,NOUN | N_AFFIX},
       +        {"tsi",CCe,3,"-e+ist","+ist",N_AFFIX|ADJ,NOUN | N_AFFIX|COMP},
       +        0
       +};
       +Suftab        staby[] =
       +{
       +        {"ycna",subst,1,"-t+cy","",ADJ | N_AFFIX,NOUN | N_AFFIX},
       +        {"ycne",subst,1,"-t+cy","",ADJ | N_AFFIX,NOUN | N_AFFIX},
       +        {"ytilib",bility,5,"-le+ility","",ADJ | V_AFFIX,NOUN | N_AFFIX},
       +        {"ytisuo",nop,0,"","",NOUN},
       +        {"ytilb",nop,0,"","",0,NOUN},
       +        {"yti",CCe,3,"-e+ity","+ity",ADJ ,NOUN | N_AFFIX },
       +        {"ylb",y_to_e,1,"-e+y","",ADJ,ADV},
       +        {"ylc",nop,0,"","",0},
       +        {"ylelb",nop,0,"","",0},
       +        {"ylelp",nop,0,"","",0},
       +        {"yl",ily,2,"-y+ily","+ly",ADJ,ADV|COMP},
       +        {"yrtem",subst,0,"-er+ry","",NOUN,NOUN | N_AFFIX},
       +        {"y",CCe,1,"-e+y","+y",_Y,ADJ|COMP},
       +        0
       +};
       +Suftab        stabz[] =
       +{
       +        0
       +};
       +Suftab*        suftab[] =
       +{
       +        staba,
       +        stabz,
       +        stabc,
       +        stabd,
       +        stabe,
       +        stabz,
       +        stabg,
       +        stabz,
       +        stabz,
       +        stabz,
       +        stabz,
       +        stabl,
       +        stabm,
       +        stabn,
       +        stabz,
       +        stabp,
       +        stabz,
       +        stabr,
       +        stabs,
       +        stabt,
       +        stabz,
       +        stabz,
       +        stabz,
       +        stabz,
       +        staby,
       +        stabz,
       +};
       +
       +Ptab        ptaba[] =
       +{
       +        "anti", 0,
       +        "auto", 0,
       +        0
       +};
       +Ptab        ptabb[] =
       +{
       +        "bio", 0,
       +        0
       +};
       +Ptab        ptabc[] =
       +{
       +        "counter", 0,
       +        0
       +};
       +Ptab        ptabd[] =
       +{
       +        "dis", 0,
       +        0
       +};
       +Ptab        ptabe[] =
       +{
       +        "electro", 0,
       +        0
       +};
       +Ptab        ptabf[] =
       +{
       +        "femto", 0,
       +        0
       +};
       +Ptab        ptabg[] =
       +{
       +        "geo", 0,
       +        "giga", 0,
       +        0
       +};
       +Ptab        ptabh[] =
       +{
       +        "hyper", 0,
       +        0
       +};
       +Ptab        ptabi[] =
       +{
       +        "immuno", 0,
       +        "im", IN,
       +        "intra", 0,
       +        "inter", 0,
       +        "in", IN,
       +        "ir", IN,
       +        "iso", 0,
       +        0
       +};
       +Ptab        ptabj[] =
       +{
       +        0
       +};
       +Ptab        ptabk[] =
       +{
       +        "kilo", 0,
       +        0
       +};
       +Ptab        ptabl[] =
       +{
       +        0
       +};
       +Ptab        ptabm[] =
       +{
       +        "magneto", 0,
       +        "mega", 0,
       +        "meta", 0,
       +        "micro", 0,
       +        "mid", 0,
       +        "milli", 0,
       +        "mini", 0,
       +        "mis", 0,
       +        "mono", 0,
       +        "multi", 0,
       +        0
       +};
       +Ptab        ptabn[] =
       +{
       +        "nano", 0,
       +        "neuro", 0,
       +        "non", 0,
       +        0
       +};
       +Ptab        ptabo[] =
       +{
       +        "out", 0,
       +        "over", 0,
       +        0
       +};
       +Ptab        ptabp[] =
       +{
       +        "para", 0,
       +        "photo", 0,
       +        "pico", 0,
       +        "poly", 0,
       +        "pre", 0,
       +        "pseudo", 0,
       +        "psycho", 0,
       +        0
       +};
       +Ptab        ptabq[] =
       +{
       +        "quasi", 0,
       +        0
       +};
       +Ptab        ptabr[] =
       +{
       +        "radio", 0,
       +        "re", 0,
       +        0
       +};
       +Ptab        ptabs[] =
       +{
       +        "semi", 0,
       +        "stereo", 0,
       +        "sub", 0,
       +        "super", 0,
       +        0
       +};
       +Ptab        ptabt[] =
       +{
       +        "tele", 0,
       +        "tera", 0,
       +        "thermo", 0,
       +        0
       +};
       +Ptab        ptabu[] =
       +{
       +        "ultra", 0,
       +        "under", 0,        /*must precede un*/
       +        "un", IN,
       +        0
       +};
       +Ptab        ptabv[] =
       +{
       +        0
       +};
       +Ptab        ptabw[] =
       +{
       +        0
       +};
       +Ptab        ptabx[] =
       +{
       +        0
       +};
       +Ptab        ptaby[] =
       +{
       +        0
       +};
       +Ptab        ptabz[] =
       +{
       +        0
       +};
       +
       +Ptab*        preftab[] =
       +{
       +        ptaba,
       +        ptabb,
       +        ptabc,
       +        ptabd,
       +        ptabe,
       +        ptabf,
       +        ptabg,
       +        ptabh,
       +        ptabi,
       +        ptabj,
       +        ptabk,
       +        ptabl,
       +        ptabm,
       +        ptabn,
       +        ptabo,
       +        ptabp,
       +        ptabq,
       +        ptabr,
       +        ptabs,
       +        ptabt,
       +        ptabu,
       +        ptabv,
       +        ptabw,
       +        ptabx,
       +        ptaby,
       +        ptabz,
       +};
       +
       +typedef struct {
       +        char *mesg;
       +        enum { NONE, SUFF, PREF} type;
       +} Deriv;
       +
       +int        aflag;
       +int        cflag;
       +int        fflag;
       +int        vflag;
       +int        xflag;
       +int         nflag;
       +char        word[500];
       +char*        original;
       +Deriv        emptyderiv;
       +Deriv        deriv[DSIZ+3];
       +char        affix[DSIZ*10];        /* 10 is longest affix message */
       +int        prefcount;
       +int         suffcount;
       +char*        acmeid;
       +char        space[300000];        /* must be as large as "words"+"space" in pcode run */
       +Bits        encode[2048];        /* must be as long as "codes" in pcode run */
       +int        nencode;
       +char        voweltab[256];
       +char*        spacep[128*128+1];        /* pointer to words starting with 'xx' */
       +Biobuf        bin;
       +Biobuf        bout;
       +
       +char*        codefile = "#9/lib/amspell";
       +char*        brfile = "#9/lib/brspell";
       +char*        Usage = "usage";
       +
       +void
       +main(int argc, char *argv[])
       +{
       +        char *ep, *cp;
       +        char *dp;
       +        int j, i, c;
       +        int low;
       +        Bits h;
       +
       +        Binit(&bin, 0, OREAD);
       +        Binit(&bout, 1, OWRITE);
       +        for(i=0; c = "aeiouyAEIOUY"[i]; i++)
       +                voweltab[c] = 1;
       +        while(argc > 1) {
       +                if(argv[1][0] != '-')
       +                        break;
       +                for(i=1; c = argv[1][i]; i++)
       +                switch(c) {
       +                default:
       +                        fprint(2, "usage: spell [-bcCvx] [-f file]\n");
       +                        exits(Usage);
       +
       +                case 'a':
       +                        aflag++;
       +                        continue;
       +
       +                case 'b':
       +                        ise();
       +                        if(!fflag)
       +                                codefile = brfile;
       +                        continue;
       +
       +                case 'C':                /* for "correct" */
       +                        vflag++;
       +                case 'c':                /* for ocr */
       +                        cflag++;
       +                        continue;
       +
       +                case 'v':
       +                        vflag++;
       +                        continue;
       +
       +                case 'x':
       +                        xflag++;
       +                        continue;
       +
       +                case 'f':
       +                        if(argc <= 2) {
       +                                fprint(2, "spell: -f requires another argument\n");
       +                                exits(Usage);
       +                        }
       +                        argv++;
       +                        argc--;
       +                        codefile = argv[1];
       +                        fflag++;
       +                        goto brk;
       +                }
       +        brk:
       +                argv++;
       +                argc--;
       +        }
       +        readdict(codefile);
       +        if(argc > 1) {
       +                fprint(2, "usage: spell [-bcCvx] [-f file]\n");
       +                exits(Usage);
       +        }
       +        if(aflag)
       +                cflag = vflag = 0;
       +
       +        for(;;) {
       +                affix[0] = 0;
       +                original = Brdline(&bin, '\n');
       +                if(original == 0)
       +                        exits(0);
       +                original[Blinelen(&bin)-1] = 0;
       +                low = 0;
       +
       +                if(aflag) {
       +                        acmeid = original;
       +                        while(*original != ':')
       +                                if(*original++ == 0)
       +                                        exits(0);
       +                        while(*++original != ':')
       +                                if(*original == 0)
       +                                        exits(0);
       +                        *original++ = 0;
       +                }
       +                for(ep=word,dp=original; j = *dp; ep++,dp++) {
       +                        if(ISLOWER(j))
       +                                low++;
       +                        if(ep >= word+sizeof(word)-1)
       +                                break;
       +                        *ep = j;
       +                }
       +                *ep = 0;
       +
       +                if(ISDIGIT(word[0]) && ordinal())
       +                        continue;
       +
       +                h = 0;
       +                if(!low && !(h = trypref(ep,".",0,ALL|STOP|DONT_TOUCH)))
       +                        for(cp=original+1,dp=word+1; dp<ep; dp++,cp++)
       +                                *dp = Tolower(*cp);
       +                if(!h)
       +                for(;;) {        /* at most twice */
       +                        if(h = trypref(ep,".",0,ALL|STOP|DONT_TOUCH))
       +                                break;
       +                        if(h = trysuff(ep,0,ALL|STOP|DONT_TOUCH))
       +                                break;
       +                        if(!ISUPPER(word[0]))
       +                                break;
       +                        cp = original;
       +                        dp = word;
       +                        while(*dp = *cp++) {
       +                                        if(!low)
       +                                                *dp = Tolower(*dp);
       +                                dp++;
       +                        }
       +                        word[0] = Tolower(word[0]);
       +                }
       +
       +                if(cflag) {
       +                        if(!h || Set(h,STOP))
       +                                print("-");
       +                        else if(!vflag)
       +                                print("+");
       +                        else 
       +                                print("%c",'0' + (suffcount>0) +
       +                                   (prefcount>4? 8: 2*prefcount));
       +                } else if(!h || Set(h,STOP)) {
       +                        if(aflag)
       +                                Bprint(&bout, "%s:%s\n", acmeid, original);
       +                        else
       +                                Bprint(&bout, "%s\n", original);
       +                } else if(affix[0] != 0 && affix[0] != '.')
       +                        print("%s\t%s\n", affix, original);
       +        }
       +        exits(0);
       +}
       +
       +/*        strip exactly one suffix and do
       + *        indicated routine(s), which may recursively
       + *        strip suffixes
       + */
       +Bits
       +trysuff(char* ep, int lev, int flag)
       +{
       +        Suftab *t;
       +        char *cp, *sp;
       +        Bits h = 0;
       +        int initchar = ep[-1];
       +
       +        flag &= ~MONO;
       +        lev += DLEV;
       +        if(lev < DSIZ) {
       +                deriv[lev]  = emptyderiv;
       +                deriv[lev-1] = emptyderiv;
       +        }
       +        if(!ISLOWER(initchar))
       +                return h;
       +        for(t=suftab[initchar-'a']; sp=t->suf; t++) {
       +                cp = ep;
       +                while(*sp)
       +                        if(*--cp != *sp++)
       +                                goto next;
       +                for(sp=ep-t->n1; --sp >= word && !ISVOWEL(*sp);)
       +                        ;
       +                if(sp < word)
       +                        continue;
       +                if(!(t->affixable & flag))
       +                        return 0;
       +                h = (*t->p1)(ep-t->n1, t->d1, t->a1, lev+1, t->flag|STOP);
       +                if(!h && t->p2!=0) {
       +                        if(lev < DSIZ) {
       +                                deriv[lev] = emptyderiv;
       +                                deriv[lev+1] = emptyderiv;
       +                        }
       +                        h = (*t->p2)(ep-t->n2, t->d2, t->a2, lev, t->flag|STOP);
       +                }
       +                break;
       +        next:;
       +        }
       +        return h;
       +}
       +
       +Bits
       +nop(char* ep, char* d, char* a, int lev, int flag)
       +{
       +        USED(ep);
       +        USED(d);
       +        USED(a);
       +        USED(lev);
       +        USED(flag);
       +        return 0;
       +}
       +
       +Bits
       +cstrip(char* ep, char* d, char* a, int lev, int flag)
       +{
       +        int temp = ep[0];
       +
       +        if(ISVOWEL(temp) && ISVOWEL(ep[-1])) {
       +                switch(pair(ep[-1],ep[0])) {
       +                case pair('a', 'a'):
       +                case pair('a', 'e'):
       +                case pair('a', 'i'):
       +                case pair('e', 'a'):
       +                case pair('e', 'e'):
       +                case pair('e', 'i'):
       +                case pair('i', 'i'):
       +                case pair('o', 'a'):
       +                        return 0;
       +                }
       +        } else
       +        if(temp==ep[-1]&&temp==ep[-2])
       +                return 0;
       +        return strip(ep,d,a,lev,flag);
       +}
       +
       +Bits
       +strip(char* ep, char* d, char* a, int lev, int flag)
       +{
       +        Bits h = trypref(ep, a, lev, flag);
       +
       +        USED(d);
       +        if(Set(h,MONO) && ISVOWEL(*ep) && ISVOWEL(ep[-2]))
       +                h = 0;
       +        if(h)
       +                return h;
       +        if(ISVOWEL(*ep) && !ISVOWEL(ep[-1]) && ep[-1]==ep[-2]) {
       +                h = trypref(ep-1,a,lev,flag|MONO);
       +                if(h)
       +                        return h;
       +        }
       +        return trysuff(ep,lev,flag);
       +}
       +
       +Bits
       +s(char* ep, char* d, char* a, int lev, int flag)
       +{
       +        if(lev > DLEV+1)
       +                return 0;
       +        if(*ep=='s') {
       +                switch(ep[-1]) {
       +                case 'y':
       +                        if(ISVOWEL(ep[-2])||ISUPPER(*word))
       +                                break;        /*says Kennedys*/
       +                case 'x':
       +                case 'z':
       +                case 's':
       +                        return 0;
       +                case 'h':
       +                        switch(ep[-2]) {
       +                        case 'c':
       +                        case 's':
       +                                return 0;
       +                        }
       +                }
       +        }
       +        return strip(ep,d,a,lev,flag);
       +}
       +
       +Bits
       +an(char* ep, char* d, char* a, int lev, int flag)
       +{
       +        USED(d);
       +        if(!ISUPPER(*word))        /*must be proper name*/
       +                return 0;
       +        return trypref(ep,a,lev,flag);
       +}
       +
       +Bits
       +ize(char* ep, char* d, char* a, int lev, int flag)
       +{
       +        int temp = ep[-1];
       +        Bits h;
       +
       +        USED(a);
       +        ep[-1] = 'e';
       +        h = strip(ep,"",d,lev,flag);
       +        ep[-1] = temp;
       +        return h;
       +}
       +
       +Bits
       +y_to_e(char* ep, char* d, char* a, int lev, int flag)
       +{
       +        Bits h;
       +        int  temp;
       +
       +        USED(a);
       +        switch(ep[-1]) {
       +        case 'a':
       +        case 'e':
       +        case 'i':
       +                return 0;
       +        }
       +        temp = *ep;
       +        *ep++ = 'e';
       +        h = strip(ep,"",d,lev,flag);
       +        ep[-1] = temp;
       +        return h;
       +}
       +
       +Bits
       +ily(char* ep, char* d, char* a, int lev, int flag)
       +{
       +        int temp = ep[0];
       +        char *cp = ep;
       +
       +        if(temp==ep[-1]&&temp==ep[-2])                /* sillly */
       +                return 0;
       +        if(*--cp=='y' && !ISVOWEL(*--cp))        /* happyly */
       +                while(cp>word)
       +                        if(ISVOWEL(*--cp))        /* shyness */
       +                                return 0;
       +        if(ep[-1]=='i')
       +                return i_to_y(ep,d,a,lev,flag);
       +        return cstrip(ep,d,a,lev,flag);
       +}
       +
       +Bits
       +bility(char* ep, char* d, char* a, int lev, int flag)
       +{
       +        *ep++ = 'l';
       +        return y_to_e(ep,d,a,lev,flag);
       +}
       +
       +Bits
       +i_to_y(char* ep, char* d, char* a, int lev, int flag)
       +{
       +        Bits h;
       +        int temp;
       +
       +        if(ISUPPER(*word))
       +                return 0;
       +        if((temp=ep[-1])=='i' && !ISVOWEL(ep[-2])) {
       +                ep[-1] = 'y';
       +                a = d;
       +        }
       +        h = cstrip(ep,"",a,lev,flag);
       +        ep[-1] = temp;
       +        return h;
       +}
       +
       +Bits
       +es(char* ep, char* d, char* a, int lev, int flag)
       +{
       +        if(lev>DLEV)
       +                return 0;
       +        switch(ep[-1]) {
       +        default:
       +                return 0;
       +        case 'i':
       +                return i_to_y(ep,d,a,lev,flag);
       +        case 'h':
       +                switch(ep[-2]) {
       +                default:
       +                        return 0;
       +                case 'c':
       +                case 's':
       +                        break;
       +                }
       +        case 's':
       +        case 'z':
       +        case 'x':
       +                return strip(ep,d,a,lev,flag);
       +        }
       +}
       +
       +Bits
       +subst(char* ep, char* d, char* a, int lev, int flag)
       +{
       +        char *u,*t;
       +        Bits h;
       +
       +        USED(a);
       +        if(skipv(skipv(ep-1)) < word)
       +                return 0;
       +        for(t=d; *t!='+'; t++)
       +                continue;
       +        for(u=ep; *--t!='-';)
       +                *--u = *t;
       +        h = strip(ep,"",d,lev,flag);
       +        while(*++t != '+')
       +                continue;
       +        while(*++t)
       +                *u++ = *t;
       +        return h;
       +}
       +
       +Bits
       +tion(char* ep, char* d, char* a, int lev, int flag)
       +{
       +        switch(ep[-2]) {
       +        default:
       +                return trypref(ep,a,lev,flag);
       +        case 'a':
       +        case 'e':
       +        case 'i':
       +        case 'o':
       +        case 'u':
       +                return y_to_e(ep,d,a,lev,flag);
       +        }
       +}
       +
       +/*
       + * possible consonant-consonant-e ending
       + */
       +Bits
       +CCe(char* ep, char* d, char* a, int lev, int flag)
       +{
       +        Bits h;
       +
       +        switch(ep[-1]) {
       +        case 'l':
       +                if(ISVOWEL(ep[-2]))
       +                        break;
       +                switch(ep[-2]) {
       +                case 'l':
       +                case 'r':
       +                case 'w':
       +                        break;
       +                default:
       +                        return y_to_e(ep,d,a,lev,flag);
       +                }
       +                break;
       +        case 'c':
       +        case 'g':
       +                if(*ep == 'a')        /* prevent -able for -eable */
       +                        return 0;
       +        case 's':
       +        case 'v':
       +        case 'z':
       +                if(ep[-2]==ep[-1])
       +                        break;
       +                if(ISVOWEL(ep[-2]))
       +                        break;
       +        case 'u':
       +                if(h = y_to_e(ep,d,a,lev,flag))
       +                        return h;
       +                if(!(ep[-2]=='n' && ep[-1]=='g'))
       +                        return 0;
       +        }
       +        return VCe(ep,d,a,lev,flag);
       +}
       +
       +/*
       + * possible consonant-vowel-consonant-e ending
       + */
       +Bits
       +VCe(char* ep, char* d, char* a, int lev, int flag)
       +{
       +        int c;
       +        Bits h;
       +
       +        c = ep[-1];
       +        if(c=='e')
       +                return 0;
       +        if(!ISVOWEL(c) && ISVOWEL(ep[-2])) {
       +                c = *ep;
       +                *ep++ = 'e';
       +                h = trypref(ep,d,lev,flag);
       +                if(!h)
       +                        h = trysuff(ep,lev,flag);
       +                if(h)
       +                        return h;
       +                ep--;
       +                *ep = c;
       +        }
       +        return cstrip(ep,d,a,lev,flag);
       +}
       +
       +Ptab*
       +lookuppref(uchar** wp, char* ep)
       +{
       +        Ptab *sp;
       +        uchar *bp,*cp;
       +        unsigned int initchar = Tolower(**wp);
       +
       +        if(!ISALPHA(initchar))
       +                return 0;
       +        for(sp=preftab[initchar-'a'];sp->s;sp++) {
       +                bp = *wp;
       +                for(cp= (uchar*)sp->s;*cp; )
       +                        if(*bp++!=*cp++)
       +                                goto next;
       +                for(cp=bp;cp<(uchar*)ep;cp++)
       +                        if(ISVOWEL(*cp)) {
       +                                *wp = bp;
       +                                return sp;
       +                        }
       +        next:;
       +        }
       +        return 0;
       +}
       +
       +/*        while word is not in dictionary try stripping
       + *        prefixes. Fail if no more prefixes.
       + */
       +Bits
       +trypref(char* ep, char* a, int lev, int flag)
       +{
       +        Ptab *tp;
       +        char *bp, *cp;
       +        char *pp;
       +        Bits h;
       +        char space[20];
       +
       +        if(lev<DSIZ) {
       +                deriv[lev].mesg = a;
       +                deriv[lev].type = *a=='.'? NONE: SUFF;
       +        }
       +        if(h = tryword(word,ep,lev,flag)) {
       +                if(Set(h, flag&~MONO) && (flag&MONO) <= Set(h, MONO))
       +                        return h;
       +                h = 0;
       +        }
       +        bp = word;
       +        pp = space;
       +        if(lev<DSIZ) {
       +                deriv[lev+1].mesg = pp;
       +                deriv[lev+1].type = 0;
       +        }
       +        while(tp=lookuppref((uchar**)&bp,ep)) {
       +                *pp++ = '+';
       +                cp = tp->s;
       +                while(pp<space+sizeof(space) && (*pp = *cp++))
       +                        pp++;
       +                deriv[lev+1].type += PREF;
       +                h = tryword(bp,ep,lev+1,flag);
       +                if(Set(h,NOPREF) ||
       +                   ((tp->flag&IN) && inun(bp-2,h)==0)) {
       +                        h = 0;
       +                        break;
       +                }
       +                if(Set(h,flag&~MONO) && (flag&MONO) <= Set(h, MONO))
       +                        break;
       +                h = 0;
       +        }
       +        if(lev < DSIZ) {
       +                deriv[lev+1] = emptyderiv;
       +                deriv[lev+2] = emptyderiv;
       +        }
       +        return h;
       +}
       +
       +Bits
       +tryword(char* bp, char* ep, int lev, int flag)
       +{
       +        int  j;
       +        Bits h = 0;
       +        char duple[3];
       +
       +        if(ep-bp <= 1)
       +                return h;
       +        if(flag&MONO) {
       +                if(lev<DSIZ) {
       +                        deriv[++lev].mesg = duple;
       +                        deriv[lev].type = SUFF;
       +                }
       +                duple[0] = '+';
       +                duple[1] = *ep;
       +                duple[2] = 0;
       +        }
       +        h = dict(bp, ep);
       +        if(vflag==0 || h==0)
       +                return h;
       +        /*
       +         * when derivations are wanted, collect them
       +         * for printing
       +         */
       +        j = lev;
       +        prefcount = suffcount = 0;
       +        do {
       +                if(j<DSIZ && deriv[j].type) {
       +                        strcat(affix, deriv[j].mesg);
       +                        if(deriv[j].type == SUFF)
       +                                suffcount++;
       +                        else if(deriv[j].type != NONE)
       +                                prefcount = deriv[j].type/PREF;
       +                }
       +        } while(--j > 0);
       +        return h;
       +}
       +
       +int
       +inun(char* bp, Bits h)
       +{
       +        if(*bp == 'u')
       +                return Set(h, IN) == 0;
       +        /* *bp == 'i' */
       +        if(Set(h, IN) == 0)
       +                return 0;
       +        switch(bp[2]) {
       +        case 'r':
       +                return bp[1] == 'r';
       +        case 'm':
       +        case 'p':
       +                return bp[1] == 'm';
       +        }
       +        return bp[1] == 'n';
       +}
       +
       +char*
       +skipv(char *s)
       +{
       +        if(s >= word && ISVOWEL(*s))
       +                s--;
       +        while(s >= word && !ISVOWEL(*s))
       +                s--;
       +        return s;
       +}
       +
       +/*
       + * crummy way to Britishise
       + */
       +void
       +ise(void)
       +{
       +        Suftab *p;
       +        int i;
       +
       +        for(i=0; i<26; i++)
       +                for(p = suftab[i]; p->suf; p++) {
       +                        p->suf = ztos(p->suf);
       +                        p->d1 = ztos(p->d1);
       +                        p->a1 = ztos(p->a1);
       +                }
       +}
       +
       +char*
       +ztos(char *as)
       +{
       +        char *s, *ds;
       +
       +        for(s=as; *s; s++)
       +                if(*s == 'z')
       +                        goto copy;
       +        return as;
       +
       +copy:
       +        ds = strdup(as);
       +        for(s=ds; *s; s++)
       +                if(*s == 'z')
       +                        *s = 's';
       +        return ds;
       +}
       +
       +Bits
       +dict(char* bp, char* ep)
       +{
       +        char *cp, *cp1, *w, *wp, *we;
       +        int n, f;
       +
       +        w = bp;
       +        we = ep;
       +        n = ep-bp;
       +        if(n <= 1)
       +                return NOUN;
       +
       +        f = w[0] & 0x7f;
       +        f *= 128;
       +        f += w[1] & 0x7f;
       +        bp = spacep[f];
       +        ep = spacep[f+1];
       +
       +loop:
       +        if(bp >= ep) {
       +                if(xflag) 
       +                        fprint(2, "=%.*s\n", utfnlen(w, n), w);
       +                return 0;
       +        }
       +        /*
       +         * find the beginning of some word in the middle
       +         */
       +        cp = bp + (ep-bp)/2;
       +
       +        while(cp > bp && !(*cp & 0x80))
       +                cp--;
       +        while(cp > bp && (cp[-1] & 0x80))
       +                cp--;
       +
       +        wp = w + 2;        /* skip two letters */
       +        cp1 = cp + 2;        /* skip affix code */
       +        for(;;) {
       +                if(wp >= we) {
       +                        if(*cp1 & 0x80)
       +                                goto found;
       +                        else
       +                                f = 1;
       +                        break;
       +                }
       +                if(*cp1 & 0x80) {
       +                        f = -1;
       +                        break;
       +                }
       +                f = *cp1++ - *wp++;
       +                if(f != 0)
       +                        break;
       +        }
       +
       +        if(f < 0) {
       +                while(!(*cp1 & 0x80))
       +                        cp1++;
       +                bp = cp1;
       +                goto loop;
       +        }
       +        ep = cp;
       +        goto loop;
       +
       +found:
       +        f = ((cp[0] & 0x7) << 8) |
       +                (cp[1] & 0xff);
       +        if(xflag) {
       +                fprint(2, "=%.*s ", utfnlen(w, n), w);
       +                typeprint(encode[f]);
       +        }
       +        return encode[f];
       +}
       +
       +void
       +typeprint(Bits h)
       +{
       +
       +        pcomma("");
       +        if(h & NOUN)
       +                pcomma("n");
       +        if(h & PROP_COLLECT)
       +                pcomma("pc");
       +        if(h & VERB) {
       +                if((h & VERB) == VERB)
       +                        pcomma("v");
       +                else
       +                if((h & VERB) == V_IRREG)
       +                        pcomma("vi");
       +                else
       +                if(h & ED)
       +                        pcomma("ed");
       +        }
       +        if(h & ADJ)
       +                pcomma("a");
       +        if(h & COMP) {
       +                if((h & COMP) == ACTOR)
       +                        pcomma("er");
       +                else
       +                        pcomma("comp");
       +        }
       +        if(h & DONT_TOUCH)
       +                pcomma("d");
       +        if(h & N_AFFIX)
       +                pcomma("na");
       +        if(h & ADV)
       +                pcomma("adv");
       +        if(h & ION)
       +                pcomma("ion");
       +        if(h & V_AFFIX)
       +                pcomma("va");
       +        if(h & MAN)
       +                pcomma("man");
       +        if(h & NOPREF)
       +                pcomma("nopref");
       +        if(h & MONO)
       +                pcomma("ms");
       +        if(h & IN)
       +                pcomma("in");
       +        if(h & _Y)
       +                pcomma("y");
       +        if(h & STOP)
       +                pcomma("s");
       +        fprint(2, "\n");
       +}
       +
       +void
       +pcomma(char *s)
       +{
       +        static int flag;
       +
       +        if(*s == 0) {
       +                flag = 0;
       +                return;
       +        }
       +        if(!flag) {
       +                fprint(2, "%s", s);
       +                flag = 1;
       +        } else
       +                fprint(2, ",%s", s);
       +}
       +
       +/*
       + * is the word on of the following
       + *        12th        teen
       + *        21st        end in 1
       + *        23rd        end in 3
       + *        77th        default
       + * called knowing word[0] is a digit
       + */
       +int
       +ordinal(void)
       +{
       +        char *cp = word;
       +        static char sp[4];
       +
       +        while(ISDIGIT(*cp))
       +                cp++;
       +        strncpy(sp,cp,3);
       +        if(ISUPPER(cp[0]) && ISUPPER(cp[1])) {
       +                sp[0] = Tolower(cp[0]);
       +                sp[1] = Tolower(cp[1]);
       +        }
       +        return 0 == strncmp(sp,
       +                cp[-2]=='1'? "th":        /* out of bounds if 1 digit */
       +                *--cp=='1'? "st":        /* harmless */
       +                *cp=='2'? "nd":
       +                *cp=='3'? "rd":
       +                "th", 3);
       +}
       +
       +/*
       + * read in the dictionary.
       + * format is
       + * {
       + *        short        nencode;
       + *        long        encode[nencode];
       + *        char        space[*];
       + * };
       + *
       + * the encodings are a table all different
       + * affixes.
       + * the dictionary proper has 2 bytes
       + * that demark and then the rest of the
       + * word. the 2 bytes have the following
       + *        0x80 0x00        flag
       + *        0x78 0x00        count of prefix bytes
       + *                        common with prev word
       + *        0x07 0xff        affix code
       + *
       + * all ints are big endians in the file.
       + */
       +void
       +readdict(char *file)
       +{
       +        char *s, *is, *lasts, *ls;
       +        int c, i, sp, p;
       +        int f;
       +        long l;
       +
       +        lasts = 0;
       +        f = open(file, 0);
       +        if(f == -1) {
       +                fprint(2, "cannot open %s\n", file);
       +                exits("open");
       +        }
       +        if(read(f, space, 2) != 2)
       +                goto bad;
       +        nencode = ((space[0]&0xff)<<8) | (space[1]&0xff);
       +        if(read(f, space, 4*nencode) != 4*nencode)
       +                goto bad;
       +        s = space;
       +        for(i=0; i<nencode; i++) {
       +                l = (long)(s[0] & 0xff) << 24;
       +                l |= (s[1] & 0xff) << 16;
       +                l |= (s[2] & 0xff) << 8;
       +                l |= s[3] & 0xff;
       +                encode[i] = (Bits)l;
       +                s += 4;
       +        }
       +        l = read(f, space, sizeof(space));
       +        if(l == sizeof(space))
       +                goto noroom;
       +        is = space + (sizeof(space) - l);
       +        memmove(is, space, l);
       +
       +        s = space;
       +        c = *is++ & 0xff;
       +        sp = -1;
       +        i = 0;
       +
       +loop:
       +        if(s > is)
       +                goto noroom;
       +        if(c < 0) {
       +                close(f);
       +                while(sp < 128*128)
       +                        spacep[++sp] = s;
       +                *s = 0x80;                /* fence */
       +                return;
       +        }
       +        p = (c>>3) & 0xf;
       +        *s++ = c;
       +        *s++ = *is++ & 0xff;
       +        if(p <= 0)
       +                i = (*is++ & 0xff)*128;
       +        if(p <= 1) {
       +                if(!(*is & 0x80))
       +                        i = i/128*128 + (*is++ & 0xff);
       +                if(i <= sp) {
       +                        fprint(2, "the dict isnt sorted or \n");
       +                        fprint(2, "memmove didn't work\n");
       +                        goto bad;
       +                }
       +                while(sp < i)
       +                        spacep[++sp] = s-2;
       +        }
       +        ls = lasts;
       +        lasts = s;
       +        for(p-=2; p>0; p--)
       +                *s++ = *ls++;
       +        for(;;) {
       +                if(is >= space+sizeof(space)) {
       +                        c = -1;
       +                        break;
       +                }
       +                c = *is++ & 0xff;
       +                if(c & 0x80)
       +                        break;
       +                *s++ = c;
       +        }
       +        *s = 0;
       +        goto loop;
       +
       +bad:
       +        fprint(2, "trouble reading %s\n", file);
       +        exits("read");
       +noroom:
       +        fprint(2, "not enough space for dictionary\n");
       +        exits("space");
       +}
 (DIR) diff --git a/src/cmd/test.c b/src/cmd/test.c
       t@@ -12,6 +12,8 @@
        #include <libc.h>
        #define EQ(a,b)        ((tmp=a)==0?0:(strcmp(tmp,b)==0))
        
       +extern int isatty(int); /* <unistd.h> */
       +
        int        ap;
        int        ac;
        char        **av;
       t@@ -21,7 +23,6 @@ void        synbad(char *, char *);
        int        fsizep(char *);
        int        isdir(char *);
        int        isreg(char *);
       -int        isatty(int);
        int        isint(char *, int *);
        int        hasmode(char *, ulong);
        int        tio(char *, int);
       t@@ -258,18 +259,6 @@ isreg(char *f)
        }
        
        int
       -isatty(int fd)
       -{
       -        Dir d1, d2;
       -
       -        if(localfstat(fd, &d1) < 0)
       -                return 0;
       -        if(localstat("/dev/cons", &d2) < 0)
       -                return 0;
       -        return d1.type==d2.type && d1.dev==d2.dev && d1.qid.path==d2.qid.path;
       -}
       -
       -int
        fsizep(char *f)
        {
                Dir dir;
 (DIR) diff --git a/src/cmd/win.c b/src/cmd/win.c
       t@@ -610,7 +610,7 @@ sendtype(int fd0)
                                }
                        print("no breakchar\n");
                        ntypebreak = 0;
       -cont2:
       +cont2:;
                }
        }
        
 (DIR) diff --git a/src/libthread/threadimpl.h b/src/libthread/threadimpl.h
       t@@ -197,6 +197,7 @@ void                _threadsysfatal(char*, va_list);
        long                _xdec(long*);
        void                _xinc(long*);
        void                _threadremove(Proc*, Thread*);
       +void                threadstatus(void);
        
        extern int                        _threaddebuglevel;
        extern char*                _threadexitsallstatus;
 (DIR) diff --git a/src/mkfile b/src/mkfile
       t@@ -1,22 +1,10 @@
        <mkhdr
        
       +BUGGERED="String|html|httpd|ip|venti"
       +LIBDIRS=`ls -ld lib* | sed -n 's/^d.* //p' |egrep -v "^lib($BUGGERED)$"`
       +
        DIRS=\
       -        lib9\
       -        libbin\
       -        libbio\
       -        libcomplete\
       -        libdraw\
       -        libflate\
       -        libframe\
       -        libfs\
       -#        libhttpd\
       -#        libip\
       -        libmux\
       -        libplumb\
       -        libregexp\
       -        libsec\
       -        libthread\
       -#        libventi\
       +        $LIBDIRS\
                cmd\
        
        <mkdirs
 (DIR) diff --git a/src/mkmk.sh b/src/mkmk.sh
       t@@ -156,10 +156,9 @@ cd libregexp
        9c  regexec.c
        9c  regsub.c
        9c  regaux.c
       -9c  rregaux.c
        9c  rregexec.c
        9c  rregsub.c
       -9ar rvc ../../lib/libregexp9.a regcomp.o regerror.o regexec.o regsub.o regaux.o rregaux.o rregexec.o rregsub.o
       +9ar rvc ../../lib/libregexp9.a regcomp.o regerror.o regexec.o regsub.o regaux.o rregexec.o rregsub.o
        cd ..
        cd cmd/mk
        9c  arc.c