Annotation of researchv10no/games/word_clout/small.c, revision 1.1

1.1     ! root        1: #define AMBIGUOUS 1
        !             2: #define STDERR stdout
        !             3: #include <stdio.h>
        !             4: #include <ctype.h>
        !             5: #include "./regexp.h"
        !             6: regexp *regcomp(),*rs;
        !             7: int nwanted,wantps;
        !             8: int accept();
        !             9: char *malloc();
        !            10: #define freecol(x) (col[x].next=colfree,colfree=x)
        !            11: #define getcol(x) ((x=colfree)?(colfree=col[colfree].next):(x=morecol()))
        !            12: #define NHS 114723     /* number of headwords and senses */
        !            13: #define N 400  /* max line length */
        !            14: #define INITTEXT (516673+1)    /* bytes of headword text */
        !            15: #define INITSQ 1980    /* bytes of sense qualifier text */
        !            16: #define INITSQTAB 1063 /*  #qual sense addr with text addr */
        !            17: #define NWINDEX 514104 /* number of 17 bit references */
        !            18: #define X 1    /* extra bit for ref qualified */
        !            19: #define WADDR 17       /* bits in headword or sense addr */
        !            20: #define WMASK ((1<<WADDR)-1)
        !            21: #define WQ (1<<WADDR)
        !            22: #define WBITS (WADDR+X)
        !            23: #define WQTEXT 2518    /* bytes of ref qualifier text */
        !            24: #define NWQ 11582      /* #qual ref addr with text addr */
        !            25: #define WQT 207        /* #tree entries for ref qual sort */
        !            26: #define NCOL 1024      /* intermediate senses in path search */
        !            27: struct col {
        !            28:        unsigned int entry:17;
        !            29:        unsigned int next:15;
        !            30: } *col;
        !            31: int colfree;
        !            32: FILE *f;
        !            33: FILE *wpackfile;
        !            34: union x {
        !            35:        struct headword {
        !            36:                unsigned int type:1;
        !            37:                unsigned int tt:19;
        !            38:                unsigned int v:12;
        !            39:        } h;
        !            40:        struct sense {
        !            41:                unsigned int type:1;
        !            42:                unsigned int st:19;
        !            43:                unsigned int p:4;
        !            44:                unsigned int q:1;
        !            45:                unsigned int v:7;
        !            46:        } s;
        !            47: } p[NHS+2];
        !            48: char tbase[INITTEXT];
        !            49: int text;
        !            50: int z;
        !            51: char in[N];
        !            52: struct squal {
        !            53:        unsigned int saddr:17;
        !            54:        unsigned int qaddr:11;
        !            55:        unsigned int v:4;
        !            56: } sqtab[INITSQTAB];
        !            57: int nsq;
        !            58: char sqbase[INITSQ];
        !            59: int sqtext;
        !            60: int windex;
        !            61: unsigned char arena[(NWINDEX*WBITS)/8+1];
        !            62: struct wqual {
        !            63:        unsigned int waddr:19;
        !            64:        unsigned int qaddr:12;
        !            65: } wqtab[NWQ];
        !            66: int nwq;
        !            67: char wqbase[WQTEXT];
        !            68: int wqtext;
        !            69: struct wqt {
        !            70:        unsigned left:8,right:8,qaddr:12;
        !            71: } wqtree[WQT];
        !            72: int wqt;
        !            73: #define NSET 32
        !            74: int set[NSET];
        !            75: int ncol;
        !            76: char *parts[] = {
        !            77:        "","n","v","adj","adv","pron","conj","prep","interj"
        !            78: };
        !            79: #define NP 9
        !            80: inset(t)
        !            81: char *t;
        !            82: {
        !            83:        char y[128];
        !            84:        int i,j,k;
        !            85:        if(*t!='&') {
        !            86:                i=headw(t);
        !            87:                if(i==0)return 0;
        !            88:                for(j=0; j<NSET; j++)if(p[i+j+1].s.type==0||i+j+1>=z)break;
        !            89:                        else set[j]=i+j+1;
        !            90:                return j;
        !            91:        }
        !            92:        if(isdigit(*++t)) {
        !            93:                for(k=0; isdigit(*t); t++)k=k*10+*t-'0';
        !            94:                i=headw(t);
        !            95:                if(i==0)return 0;
        !            96:                for(j=0; j<NSET; j++)if(p[i+j+1].s.type==0||i+j+1>=z)break;
        !            97:                        else if(j+1==k) {
        !            98:                                set[0]=i+j+1;
        !            99:                                return 1;
        !           100:                        }
        !           101:                return 0;
        !           102:        }
        !           103:        if(strlen(t)>126)err("string to long in inset()");
        !           104:        strcpy(y,t);
        !           105:        for(j=0; y[j]&&y[j]!='.'; j++);
        !           106:        if(y[j]==0)return 0;
        !           107:        y[j]=0;
        !           108:        for(k=1; k<NP; k++)if(strcmp(y,parts[k])==0)break;
        !           109:        if(k>=NP)return 0;
        !           110:        i=headw(y+j+1);
        !           111:        if(i++==0)return 0;
        !           112:        for(j=0; j<NSET&&i<=z&&p[i].s.type==1; i++) {
        !           113:                if(p[i].s.p==k)set[j++]=i;
        !           114:        }
        !           115:        return j;
        !           116: }
        !           117: readnum()
        !           118: {
        !           119:        int j,k;
        !           120:        for(k=0; isdigit(j=getc(f)); k=k*10+j-'0');
        !           121:        if(j!='\n')err("expect number");
        !           122:        fprintf(STDERR,"readnum()=%d\n",k);
        !           123:        return k;
        !           124: }
        !           125: sensequal(zz,t)
        !           126: char *t;
        !           127: {
        !           128:        int i;
        !           129:        if(p[zz].h.type!=1)err("squal on headword");
        !           130:        if(*t==0)return;
        !           131:        p[zz].s.q=1;
        !           132:        sqtab[nsq].saddr=zz;
        !           133:        for(i=0; i<nsq; i++)if(strcmp(t,sqbase+sqtab[i].qaddr)==0)break;
        !           134:        if(i<nsq) {
        !           135:                sqtab[nsq].qaddr=sqtab[i].qaddr;
        !           136:        }
        !           137:        else {
        !           138:                sqtab[nsq].qaddr=sqtext;
        !           139:                strcpy(sqbase+sqtext,t);
        !           140:                sqtext+=strlen(t)+1;
        !           141:                if(sqtext>=INITSQ)err("sqtext overflow");
        !           142:        }
        !           143:        if(++nsq>INITSQTAB)err("nsq overflow");
        !           144: }
        !           145: err(s)
        !           146: char *s;
        !           147: {
        !           148:        int i;
        !           149:        fprintf(STDERR,"err: %s\n",s);
        !           150:        fprintf(STDERR,"type return:"); getchar();
        !           151:        fprintf(STDERR,"input buffer segments:\n");
        !           152:        for(i=0; i<N; i++) {
        !           153:                if(in[i]==0)continue;
        !           154:                fprintf(STDERR,"'%s'\n",in+i);
        !           155:                while(i<N&&in[i])i++;
        !           156:        }
        !           157:        exit(1);
        !           158: }
        !           159: char *squal(zz)
        !           160: {
        !           161:        int il,im,iu;
        !           162:        if(p[zz].h.type==0) {
        !           163:                err("ask for sensqual on headword");
        !           164:        }
        !           165:        if(p[zz].s.q==0)return "";
        !           166:        il=0; iu=nsq;
        !           167:        while(il<iu-1) {
        !           168:                im=(il+iu)/2;
        !           169:                if(sqtab[im].saddr>zz) {
        !           170:                        iu=im;
        !           171:                }
        !           172:                else il=im;
        !           173:        }
        !           174:        if(sqtab[il].saddr!=zz)err("binary botch in squal()");
        !           175:        return sqbase+sqtab[il].qaddr;
        !           176: }
        !           177: char *wqual(wi)
        !           178: {
        !           179:        int il,im,iu;
        !           180:        if((unpackw(wi)&WQ)==0)return "";
        !           181:        il=0; iu=nwq;
        !           182:        while(il<iu-1) {
        !           183:                im=(il+iu)/2;
        !           184:                if(wqtab[im].waddr>wi) {
        !           185:                        iu=im;
        !           186:                }
        !           187:                else il=im;
        !           188:        }
        !           189:        if(wqtab[il].waddr!=wi)err("binary botch wqual");
        !           190:        return wqbase+wqtab[il].qaddr;
        !           191: }
        !           192: opackw(index,value)
        !           193: register value;
        !           194: {
        !           195:        int i,j;
        !           196:        register int mask=(1<<WBITS)-1;
        !           197:        i=index*WBITS;
        !           198:        value<<=i&7;
        !           199:        mask<<=i&7;
        !           200:        j=i>>3;
        !           201:        while(mask&0xff) {
        !           202:                arena[j]&=~mask;
        !           203:                arena[j]|=value;
        !           204:                value>>=8;
        !           205:                mask>>=8;
        !           206:                j++;
        !           207:        }
        !           208: }
        !           209: packw(index,value)
        !           210: register value;
        !           211: {
        !           212:        register i;
        !           213:        register unsigned char *p;
        !           214:        i=index*18;
        !           215:        value<<=i&7;
        !           216:        p=arena+(i>>3);
        !           217:        *p++|=value; value>>=8; *p++|=value; value>>=8;
        !           218:        *p++|=value;
        !           219: }
        !           220: unpackw(index)
        !           221: {
        !           222:        register i,k;
        !           223:        register unsigned char *p;
        !           224:        i=index*18;
        !           225:        p=arena+(i>>3)+2;
        !           226:        k=*p; k=(k<<8)|*--p; k=(k<<8)|*--p; 
        !           227:        return (k>>(i&7))&0x3ffff;
        !           228: }
        !           229: ounpackw(index)
        !           230: {
        !           231:        int i,j,k;
        !           232:        int x;
        !           233:        register int mask=(1<<WBITS)-1;
        !           234:        i=index*WBITS;
        !           235:        j=i>>3;
        !           236:        mask<<=i&7;
        !           237:        x=k=0;
        !           238:        while(mask&0xff) {
        !           239:                k|=(arena[j]&mask)<<x;
        !           240:                mask>>=8;
        !           241:                j++;
        !           242:                x+=8;
        !           243:        }
        !           244:        return k>>(i&7);
        !           245: }
        !           246: dumps(x)
        !           247: {
        !           248:        int i,j,k,l,m,n;
        !           249:        if(x==0) {
        !           250:                fprintf(STDERR,"not found\n");
        !           251:                return;
        !           252:        }
        !           253:        for(i=x; i>0&&p[i].h.type!=0; i--);
        !           254:        if(i==0) {
        !           255:                fprintf(STDERR,"dump of %d no headword\n",x);
        !           256:                return;
        !           257:        }
        !           258:        fprintf(STDERR,"\n&%d%s ",x-i,p[i].h.tt+tbase);
        !           259:        if(p[x].h.type==0) {
        !           260:                fprintf(STDERR,"\n");
        !           261:                while(++x<z&&p[x].h.type!=0)dumps(x);
        !           262:                return;
        !           263:        }
        !           264:        fprintf(STDERR," (%s.)",parts[p[x].s.p]);
        !           265:        if(*squal(x))fprintf(STDERR," [%s]",squal(x));
        !           266:        fprintf(STDERR,":\n");
        !           267:        for(i=p[x].s.st; l=unpackw(i++); ) {
        !           268:                for(j=l&WMASK; j>0&&p[j].h.type!=0; j--);
        !           269:                fprintf(STDERR," &%d%s",(l&WMASK)-j,p[j].h.tt+tbase);
        !           270:                if(l&WQ)fprintf(STDERR," [%s]",wqual(i-1));
        !           271:                fprintf(STDERR,",");
        !           272:        }
        !           273:        fprintf(STDERR,"\n");
        !           274: }
        !           275: char *ma(x)
        !           276: {
        !           277:        char *p;
        !           278:        p=(char*)calloc(x,1);
        !           279:        if(p==0) {
        !           280:                fprintf(STDERR,"can't calloc %d bytes\n",x);
        !           281:                err("quit");
        !           282:        }
        !           283:        return p;
        !           284: }
        !           285: wsym(q,node)
        !           286: char *q;
        !           287: {
        !           288:        int i;
        !           289:        if(wqt==0) {
        !           290:                strcpy(wqbase,q);
        !           291:                wqtext=strlen(q)+1;
        !           292:                wqt++;
        !           293:                return 0;
        !           294:        }
        !           295:        i=strcmp(q,wqbase+wqtree[node].qaddr);
        !           296:        if(i==0)return wqtree[node].qaddr;
        !           297:        if(i<0) {
        !           298:                if(wqtree[node].left)return wsym(q,wqtree[node].left);
        !           299:                wqtree[node].left=wqt;
        !           300:        }
        !           301:        else {
        !           302:                if(wqtree[node].right)return wsym(q,wqtree[node].right);
        !           303:                wqtree[node].right=wqt;
        !           304:        }
        !           305:        strcpy(wqbase+wqtext,q);
        !           306:        i=wqtext;
        !           307:        wqtext+=strlen(q)+1;
        !           308:        if(wqtext>=WQTEXT)err("wqtext ovfl");
        !           309:        wqtree[wqt++].qaddr=i;
        !           310:        if(wqt>=WQT)err("wqt ovfl");
        !           311:        return i;
        !           312: }
        !           313: headw(text)
        !           314: char *text;
        !           315: {
        !           316:        int il,iu,im;
        !           317:        il=1; iu=z;
        !           318:        while(il<iu+1) {
        !           319:                im=(il+iu)/2;
        !           320:                while(im>il&&p[im].h.type!=0)im--;
        !           321:                if(im<=il) {
        !           322:                        while(++im<iu&&p[im].h.type!=0);
        !           323:                        if(im>=iu)break;
        !           324:                }
        !           325:                if(strcmp(p[im].h.tt+tbase,text)>0) {
        !           326:                        iu=im;
        !           327:                }
        !           328:                else {
        !           329:                        il=im;
        !           330:                }
        !           331:        }
        !           332:        if(strcmp(p[il].h.tt+tbase,text))return 0;
        !           333:        return il;
        !           334: }
        !           335: morecol()
        !           336: {
        !           337:        int i;
        !           338:        if(col==0)col=(struct col*)ma(NCOL*sizeof*col);
        !           339:        else col=(struct col*)realloc(col,(ncol+NCOL)*sizeof*col);
        !           340:        for(i=NCOL+ncol-1; i>ncol; i--)col[i].next=i-1;
        !           341:        col[ncol].next=0;
        !           342:        ncol+=NCOL;
        !           343:        colfree=ncol-2;
        !           344:        return ncol-1;
        !           345: }
        !           346: path(a,b)
        !           347: char *a,*b;
        !           348: {
        !           349:        int i,j,k;
        !           350:        int old,new;
        !           351:        int e;
        !           352:        unsigned char psa[NP],psb[NP];
        !           353:        int it;
        !           354:        int pf;
        !           355:        for(i=0; b[i]; i++)if(b[i]=='/') {
        !           356:                nwanted=10;
        !           357:                rsparse(b);
        !           358:                qpath(accept,a);
        !           359:                fprintf(STDERR,"\n");
        !           360:                return;
        !           361:        }
        !           362: #ifdef AMBIGUOUS
        !           363:        if(strncmp(a,"ambiguous ",10)==0) {
        !           364:                ambpath(a+10,b);
        !           365:                fprintf(STDERR,"\n");
        !           366:                return;
        !           367:        }
        !           368: #endif
        !           369:        old=new=0;
        !           370:        it=1;
        !           371:        pf=0;
        !           372:        e=inset(a);
        !           373:        if(e==0) {
        !           374:                fprintf(STDERR,"can't find %s\n",a);
        !           375:                return;
        !           376:        }
        !           377:        for(i=0; i<NP; i++)psa[i]=psb[i]=0;
        !           378:        for(i=0; i<e; i++)psa[p[set[i]].s.p]++;
        !           379:        k=inset(b);
        !           380:        if(k==0) {
        !           381:                fprintf(STDERR,"%s not found\n",b);
        !           382:                return;
        !           383:        }
        !           384:        for(i=0; i<z; i++)if(p[i].s.type)p[i].s.v=0;
        !           385:        for(i=0; i<k; i++) {
        !           386:                if(psa[p[set[i]].s.p]==0)continue;
        !           387:                psb[p[set[i]].s.p]++;
        !           388:                getcol(j);
        !           389:                col[j].entry=set[i];
        !           390:                col[j].next=old;
        !           391:                old=j;
        !           392:                p[set[i]].s.v=it;
        !           393:        }
        !           394:        if(old==0) {
        !           395:                fprintf(STDERR,"%s and %s: no part of speech in common\n",
        !           396:                        a,b);
        !           397:                return;
        !           398:        }
        !           399:        e=inset(a);
        !           400:        for(i=j=0; i<e; i++) {
        !           401:                set[j]=set[i];
        !           402:                if(psb[p[set[i]].s.p])j++;
        !           403:        }
        !           404:        e=j;
        !           405:        if(e==0)err("path 1");
        !           406: loop:
        !           407:        if(old==0) {
        !           408:                if(pf)fprintf(STDERR,"\n");
        !           409:                else fprintf(STDERR," no path from %s to %s\n",a,b);
        !           410:                goto pathx;
        !           411:        }
        !           412:        it++;
        !           413:        while(old) {
        !           414:                i=p[col[old].entry].s.st;
        !           415:                j=old;
        !           416:                old=col[old].next;
        !           417:                freecol(j);
        !           418:                while(j=(unpackw(i++)&WMASK)) {
        !           419:                        if(p[j].s.type&&p[j].s.v==0) {
        !           420:                                getcol(k);
        !           421:                                col[k].next=new;
        !           422:                                col[k].entry=j;
        !           423:                                new=k;
        !           424:                                p[j].s.v=it;
        !           425:                        }
        !           426:                }
        !           427:        }
        !           428:        old=new;
        !           429:        new=0;
        !           430:        for(i=j=0; i<e; i++) {
        !           431:                set[j]=set[i];
        !           432:                if(p[set[i]].s.v) {
        !           433:                        pfound(set[i]);
        !           434:                        pf++;
        !           435:                }
        !           436:                else j++;
        !           437:        }
        !           438:        if(e=j)goto loop;
        !           439:        fprintf(STDERR,"\n");
        !           440: pathx:
        !           441:        freeall(old);
        !           442:        freeall(new);
        !           443: }
        !           444: freeall(x)
        !           445: {
        !           446:        int i;
        !           447:        while(x) {
        !           448:                i=col[x].next;
        !           449:                freecol(x);
        !           450:                x=i;
        !           451:        }
        !           452: }
        !           453: pfound(x)
        !           454: {
        !           455:        int i,j;
        !           456:        do {
        !           457:                for(i=x; i>0&&p[i].h.type; i--);
        !           458:                if(i==0)err("no hw");
        !           459:                fprintf(STDERR," &%d%s",x-i,p[i].h.tt+tbase);
        !           460:                i=p[x].s.st;
        !           461:                while(j=(WMASK&unpackw(i++))) {
        !           462:                        if(p[j].s.type&&p[j].s.v==p[x].s.v-1)break;
        !           463:                }
        !           464:        } while(x=j);
        !           465:        fprintf(STDERR,"\n");
        !           466: }
        !           467: char *avdummy[2];
        !           468: main(ac,av)
        !           469: char *av[];
        !           470: {
        !           471:        int i,j,k,l,m,n;
        !           472:        int nhw,nhs;
        !           473:        int backref;
        !           474:        char *q;
        !           475:        int zz;
        !           476:        int w;
        !           477:        int nw;
        !           478:        char y[128];
        !           479:        if(ac<2) {
        !           480:                fprintf(stderr,"word_clout: need data file");
        !           481:                return 1;
        !           482:        }
        !           483:        f=fopen(av[1],"r");
        !           484:        for(i=0; (j=getc(f))!=EOF&&j!='\n'&&i<N-1; i++)in[i]=j;
        !           485:        if(j==EOF)err("immediate eof");
        !           486:        in[i]=0;
        !           487:        if(strcmp(in,"-huffman")==0) {
        !           488:                goto unpackh;
        !           489:        }
        !           490:        else if(strcmp(in,"-pack")) {
        !           491:                err("expect -huffman or -pack");
        !           492:        }
        !           493:        nhw=readnum();
        !           494:        nhs=readnum();
        !           495: /* now preallocated:
        !           496: *      p=(struct x*)ma((nhs+2)*sizeof*p);
        !           497: *      tbase=(char*)ma(INITTEXT);
        !           498: *      sqbase=(char*)ma(INITSQ);
        !           499: *      sqtab=(struct squal*)ma(INITSQTAB*sizeof*sqtab);
        !           500: *      arena=(unsigned char*)ma(i=(NWINDEX*sizeof*arena*WBITS)/8+1);
        !           501: *      wqtab=(struct wqual*)ma(NWQ*sizeof*wqtab);
        !           502: *      wqbase=(char*)ma(WQTEXT*sizeof*wqbase);
        !           503: *      wqtree=(struct wqt*)ma(WQT*sizeof*wqtree);
        !           504: */
        !           505: readhead:
        !           506:        for(i=0; i<N&&(j=getc(f))!=EOF&&j!='\n'; i++)in[i]=j;
        !           507:        if(i>=N)err("line too long");
        !           508:        if(j==EOF)err("eof in headwords");
        !           509:        in[i]=0;
        !           510:        if(i==0)goto hwdone;
        !           511:        for(j=i-1; j>0&&in[j]!=' '; j--);
        !           512:        in[j++]=0;
        !           513:        p[++z].h.tt=text;
        !           514:        zz=z;
        !           515:        strcpy(text+tbase,in);
        !           516:        text+=strlen(in)+1;
        !           517:        if(text>=INITTEXT)err("inittext too small");
        !           518:        p[z].h.type=0;
        !           519:        for( ; in[j]; j++) {
        !           520:                p[++z].s.type=1;
        !           521:                p[z].s.q=0;
        !           522:                p[z].s.st=0;
        !           523:                k=in[j];
        !           524:                if(k<='z'&&k>='a')p[z].s.p=k-'a';
        !           525:                else p[z].s.p=k-'A';
        !           526:        }
        !           527:        if((j=getc(f))==':') {
        !           528:                for(i=0; i<N&&(j=getc(f))!=EOF&&j!='\n'; i++)in[i]=j;
        !           529:                if(j==EOF)err("eof in sense qual");
        !           530:                if(i>=N)err("squal too long");
        !           531:                in[i]=0;
        !           532:                for(i=0; in[i]; i++)if(in[i]==':'&&in[i+1]==' ')in[i]='-';
        !           533:                for(i=0; in[i]; i++) {
        !           534:                        if(++zz>z)err("too many squal fields");
        !           535:                        for(j=i; in[j]&&in[j]!=':'; j++);
        !           536:                        if(in[j]==0)err("squal not ending :");
        !           537:                        in[j]=0;
        !           538:                        sensequal(zz,in+i);
        !           539:                        i=j;
        !           540:                }
        !           541:                if(zz<z)err("missing squal field");
        !           542:                goto readhead;
        !           543:        }
        !           544:        ungetc(j,f);
        !           545:        goto readhead;
        !           546: hwdone:
        !           547:        fprintf(STDERR,"text=%d\n",text);
        !           548:        z++;
        !           549:        p[z].h.type=0; /* extra slot on end */
        !           550:        for(i=1,j=0; i<z; i++)if(p[i].h.type==1&&p[i].s.q)j++;
        !           551:        fprintf(STDERR,"%d entries %d qual senses\n",i,j);
        !           552:        fprintf(STDERR,"sqtext=%d, nsq=%d\n",sqtext,nsq);
        !           553:        zz=1;
        !           554: readwords:
        !           555:        for(i=0; i<N&&(j=getc(f))!=EOF&&j!='\n'; i++)in[i]=j;
        !           556:        if(j==EOF)goto done;
        !           557:        if(i>=N)err("line too long");
        !           558:        in[i]=0;
        !           559:        while(zz<z&&p[zz].h.type==0)zz++;
        !           560:        for(i=nw=0; in[i]<='z'&&in[i]>='a'; i++)nw=nw*26+in[i]-'a';
        !           561:        w=windex;
        !           562:        p[zz].s.st=w;
        !           563:        windex+=nw+1;
        !           564:        if(windex>NWINDEX)err("windex too big");
        !           565:        while(in[i]==':') {
        !           566:                q=0;
        !           567:                if(in[++i]=='{') {
        !           568:                        for(j=i+1; in[j]&&in[j]!='}'; j++);
        !           569:                        if(in[j]==0)err("missing }");
        !           570:                        in[j]=0;
        !           571:                        q=in+i+1;
        !           572:                        i=j+1;
        !           573:                }
        !           574:                for(k=0; in[i]>='a'&&in[i]<='z'; i++)k=k*26+in[i]-'a';
        !           575:                ++k; /* offset 1 so preserve 0=0 */
        !           576:                if(k!=(k&WMASK))err("exceeds wmask");
        !           577:                if(p[k].h.type==1&&p[k].s.p!=p[zz].s.p) {
        !           578:                        dumps(k);
        !           579:                        dumps(zz);
        !           580:                        err("part bad");
        !           581:                }
        !           582:                if(q) {
        !           583:                        k|=WQ;
        !           584:                        wqtab[nwq].waddr=w;
        !           585:                        wqtab[nwq].qaddr=wsym(q,0);
        !           586:                        nwq++;
        !           587:                        if(nwq>=NWQ)err("nwq ovfl");
        !           588:                }
        !           589:                packw(w++,k);
        !           590:        }
        !           591:        zz++;
        !           592:        goto readwords;
        !           593: done:
        !           594:        fprintf(STDERR,"wqtext=%d nwq=%d windex=%d\n",wqtext,nwq,windex);
        !           595:        fprintf(STDERR,"wqt=%d\n",wqt);
        !           596:        fprintf(STDERR,"zz=%d z=%d\n",zz,z);
        !           597:        m=0;
        !           598:        if(ac>2&&*av[2]=='c') {
        !           599:                for(w=0; w<windex; w++)if(unpackw(w))m++;
        !           600:                fprintf(STDERR,"%d words set\n",m);
        !           601:        }
        !           602:        m=0;
        !           603:        for(zz=1; zz<z; zz++) {
        !           604:                if(p[zz].h.type==0)continue;
        !           605:                i=p[zz].s.st;
        !           606:                while(j=unpackw(i++)) {
        !           607:                        j&=WMASK;
        !           608:                        if(p[j].h.type==0)continue;
        !           609:                        k=p[j].s.st;
        !           610:                        while(l=unpackw(k++)) {
        !           611:                                l&=WMASK;
        !           612:                                if(l==zz)goto backed;
        !           613:                        }
        !           614:                        if(unpackw(k))err("oversubscribed");
        !           615:                        packw(k-1,zz);
        !           616:                        m++;
        !           617:                backed:;
        !           618:                }
        !           619:        }
        !           620:        fprintf(STDERR,"backrefs added %d\n",m);
        !           621:        if(ac>2&&*av[2]=='c')for(zz=1; zz<z; zz++) {
        !           622:                if(p[zz].h.type==0) {
        !           623:                        j=zz;
        !           624:                        continue;
        !           625:                }
        !           626:                for(k=p[zz].s.st; unpackw(k)&WMASK; k++);
        !           627:                if(k+1<z&&(unpackw(k+1)&WMASK)==0) {
        !           628:                        fprintf(STDERR,"%s is missing words\n",
        !           629:                                tbase+p[j].h.tt);
        !           630:                }
        !           631:        }
        !           632:        if(ac>3&&(wpackfile=fopen(av[3],"w")))packit();
        !           633:        goto ahem;
        !           634: unpackh:
        !           635:        unpackit();
        !           636: ahem:  fprintf(STDERR,"ready.\n");
        !           637: loop:
        !           638:        for(i=0; i<N&&(j=getchar())!=EOF&&j!='\n'; i++)in[i]=j;
        !           639:        if(i<N)in[i]=0;
        !           640:        if(j==EOF||strcmp(in,"q")==0) {
        !           641:                exit(0);
        !           642:        }
        !           643:        for(i=0; in[i]&&in[i]!='/'; i++)if(in[i]=='^') {
        !           644:                in[i]=0;
        !           645:                path(in,in+i+1);
        !           646:                goto loop;
        !           647:        }
        !           648:        if(in[i]=='/') {
        !           649:                strcpy(y,in+i+1);
        !           650:                in[i]=0;
        !           651:                if(i>0&&in[i-1]=='.')in[i-1]=0;
        !           652:                for(i=0; y[i]&&y[i]!='/'; i++);
        !           653:                y[i]=0;
        !           654:                k=0;
        !           655:                if(*in=='&')for(k=0; k<NP&&strcmp(in+1,parts[k]); k++);
        !           656:                if(rs)free(rs);
        !           657:                rs=regcomp(y);
        !           658:                for(zz=1; zz<z; zz++) {
        !           659:                        if(p[zz].h.type)continue;
        !           660:                        if(k) {
        !           661:                                for(i=1; p[zz+i].s.type; i++)
        !           662:                                        if(p[zz+i].s.p==k)goto ok;
        !           663:                                continue;
        !           664:                        }
        !           665:                ok:
        !           666:                        if(regexec(rs,p[zz].h.tt+tbase,0,0)) {
        !           667:                                fprintf(stderr," %s,",p[zz].h.tt+tbase);
        !           668:                        }
        !           669:                }
        !           670:                fprintf(stderr,"\n");
        !           671:                goto loop;
        !           672:        }
        !           673:        i=inset(in);
        !           674:        for(j=0; j<i; j++)dumps(set[j]);
        !           675:        if(i==0)fprintf(STDERR,"%s not found\n",in);
        !           676:        goto loop;
        !           677: }
        !           678: /* funct == 0 reject
        !           679:    funct == -1 stop
        !           680:    funct == otherwise, continue
        !           681: */
        !           682: qpath(funct,b)
        !           683: char *b;
        !           684: int (*funct)();
        !           685: {
        !           686:        int i,j,k;
        !           687:        int old,new;
        !           688:        int it;
        !           689:        old=new=0;
        !           690:        it=1;
        !           691:        k=inset(b);
        !           692:        if(k==0) {
        !           693:                fprintf(STDERR,"%s not found\n",b);
        !           694:                return;
        !           695:        }
        !           696:        for(i=0; i<z; i++)if(p[i].s.type)p[i].s.v=0;
        !           697:        for(i=0; i<k; i++) {
        !           698:                getcol(j);
        !           699:                col[j].entry=set[i];
        !           700:                col[j].next=old;
        !           701:                old=j;
        !           702:                p[set[i]].s.v=it;
        !           703:        }
        !           704: loop:
        !           705:        if(old==0) {
        !           706:                goto pathx;
        !           707:        }
        !           708:        it++;
        !           709:        while(old) {
        !           710:                i=p[col[old].entry].s.st;
        !           711:                j=old;
        !           712:                old=col[old].next;
        !           713:                freecol(j);
        !           714:                while(j=(unpackw(i++)&WMASK)) {
        !           715:                        if(p[j].s.type&&p[j].s.v==0) {
        !           716:                                p[j].s.v=it;
        !           717:                                switch((*funct)(j)) {
        !           718:                                case 0:
        !           719:                                        p[j].s.v=0;
        !           720:                                        continue;
        !           721:                                case -1: goto pathx;
        !           722:                                }
        !           723:                                getcol(k);
        !           724:                                col[k].next=new;
        !           725:                                col[k].entry=j;
        !           726:                                new=k;
        !           727:                        }
        !           728:                }
        !           729:        }
        !           730:        old=new;
        !           731:        new=0;
        !           732:        if(old)goto loop;
        !           733: pathx:
        !           734:        freeall(old);
        !           735:        freeall(new);
        !           736: }
        !           737: rsparse(b)
        !           738: char *b;
        !           739: {
        !           740:        int i,j;
        !           741:        wantps=0;
        !           742:        for(i=0; b[i]&&b[i]!='/'; i++);
        !           743:        if(i&&b[i-1]=='.') {
        !           744:                b[i-1]=0;
        !           745:                for(j=0; j<NP; j++)if(strcmp(parts[j],b+1)==0)wantps=j;
        !           746:        }
        !           747:        if(b[i])i++;
        !           748:        for(j=i; b[j]; j++);
        !           749:        while(j&&b[j-1]!='/')j--;
        !           750:        if(j)b[j-1]=0;
        !           751:        if(atoi(b+j))nwanted=atoi(b+j);
        !           752:        if(rs) {
        !           753:                free(rs);
        !           754:        }
        !           755:        rs=regcomp(b+i);
        !           756: }
        !           757: accept(zz)
        !           758: {
        !           759:        int i;
        !           760:        for(i=zz; i&&p[i].h.type; i--);
        !           761:        if(regexec(rs,p[i].h.tt+tbase,0,0)) {
        !           762:                fprintf(stderr," &%d%s,",zz-i,p[i].h.tt+tbase);
        !           763:                if(--nwanted<=0)return -1;
        !           764:                return 1;
        !           765:        }
        !           766:        return 1;
        !           767: }
        !           768: #define NCOMM 100
        !           769: #define NHASCII 128
        !           770: #define NNSEN 50
        !           771: #define NNWDS 100
        !           772: #define NSQR 256
        !           773: #define NWQR 256
        !           774: #define ALLOC(base,num) (base.freq=(long*)ma(num*sizeof(long)),\
        !           775:                        base.code=(long*)ma(num*sizeof(long)),\
        !           776:                        base.tree=(short*)ma(2*num*sizeof(short)))
        !           777: #define FREE(base) (free(base.freq),free(base.code),free(base.tree))
        !           778: #define GEN(base,n) (gencodes(base.freq,n,base.code),flipcodes(n,base.code),\
        !           779:                        entree(base.code,n,base.tree))
        !           780: #define INBIT() (ibuffc?(ibuff>>--ibuffc)&1:(ibuffc=7,((ibuff=getc(f))>>7)&1))
        !           781: struct huff {
        !           782:        long *freq,*code;
        !           783:        short *tree;
        !           784: };
        !           785: struct alpha {
        !           786:        unsigned int k,wqtab;
        !           787: };
        !           788: alphacmp(a,b)
        !           789: struct alpha *a,*b;
        !           790: {
        !           791:        if(p[a->k&WMASK].h.type) {
        !           792:                if(p[b->k&WMASK].h.type)return (a->k&WMASK)-(b->k&WMASK);
        !           793:                return 1;
        !           794:        }
        !           795:        if(p[b->k&WMASK].h.type==0)return (a->k&WMASK)-(b->k&WMASK);
        !           796:        return -1;
        !           797: }
        !           798: wqcmp(a,b)
        !           799: struct wqual *a,*b;
        !           800: {
        !           801:        return a->waddr-b->waddr;
        !           802: }
        !           803: int ibuffc,ibuff;
        !           804: packit()
        !           805: {
        !           806:        struct huff comm,qascii,hascii,nsen,parsp,nwds,nwdsback;
        !           807:        int i,j,k,l,m,n;
        !           808:        int ii,jj,il,iu,im;
        !           809:        int zz;
        !           810:        int sqref[NSQR],wqref[NWQR];
        !           811:        int medians,medianw;
        !           812:        struct alpha wtemp[NNWDS];
        !           813:        /* s & w qualifier text addr from s & w qualifier index */
        !           814:        for(i=j=0; i<sqtext; i++) {
        !           815:                if(i==0||sqbase[i-1]==0) {
        !           816:                        sqref[j++]=i;
        !           817:                        if(j>=NSQR)err("NSQR too small");
        !           818:                }
        !           819:        }
        !           820:        for(i=j=0; i<wqtext; i++) {
        !           821:                if(i==0||wqbase[i-1]==0) {
        !           822:                        wqref[j++]=i;
        !           823:                        if(j>=NWQR)err("NWQR too small");
        !           824:                }
        !           825:        }
        !           826:        ALLOC(comm,NCOMM);
        !           827:        ALLOC(qascii,NHASCII);
        !           828:        ALLOC(hascii,NHASCII);
        !           829:        ALLOC(nsen,NNSEN);
        !           830:        ALLOC(parsp,NP);
        !           831:        ALLOC(nwds,NNWDS);
        !           832:        ALLOC(nwdsback,NNWDS);
        !           833:        /* common substring, number of senses, parts of speech */
        !           834:        for(zz=1; zz<z; zz++) {
        !           835:                if(p[zz].h.type)continue;
        !           836:                j=k,k=p[zz].h.tt;
        !           837:                if(k==0)l=0;
        !           838:                else for(l=0; tbase[k+l]==tbase[j+l]; l++);
        !           839:                if(l>=NCOMM)err("NCOMM too small");
        !           840:                comm.freq[l]++;
        !           841:                for(i=l; tbase[i+k]; i++)hascii.freq[tbase[i+k]]++;
        !           842:                hascii.freq[0]++;
        !           843:                for(n=zz+1; p[n].s.type; n++);
        !           844:                if(n-zz>=NNSEN)err("NNSEN too small");
        !           845:                nsen.freq[n-zz]++;
        !           846:                for(n=zz+1; p[n].s.type; n++)parsp.freq[p[n].s.p]++;
        !           847:        }
        !           848:        /* number of words */
        !           849:        for(zz=1; zz<z; zz++) {
        !           850:                if(p[zz].h.type) {
        !           851:                        for(i=p[zz].s.st,j=0; k=unpackw(i); i++)if((k&WMASK)<zz)j++;
        !           852:                        i-=p[zz].s.st;
        !           853:                        if(i>=NNWDS)err("NNWDS too small");
        !           854:                        nwds.freq[i]++;
        !           855:                        nwdsback.freq[j]++;
        !           856:                }
        !           857:        }
        !           858:        /* ascii in qualifiers */
        !           859:        for(i=0; i<sqtext; i++)qascii.freq[sqbase[i]]++;
        !           860:        for(i=0; i<wqtext; i++)qascii.freq[wqbase[i]]++;
        !           861: 
        !           862:        GEN(qascii,NHASCII);
        !           863:        GEN(hascii,NHASCII);
        !           864:        GEN(comm,NCOMM);
        !           865:        GEN(nsen,NNSEN);
        !           866:        GEN(parsp,NP);
        !           867:        GEN(nwds,NNWDS);
        !           868:        GEN(nwdsback,NNWDS);
        !           869: 
        !           870:        /* median sense qualifier */
        !           871:        for(i=j=0,zz=1; zz<z; zz++) {
        !           872:                if(p[zz].s.type) {
        !           873:                        i++;
        !           874:                        if(p[zz].s.q)j++;
        !           875:                }
        !           876:        }
        !           877:        medians=(7*i)/(10*j);
        !           878:        /* median word qualifier runs */
        !           879:        for(i=j=0,zz=1; zz<z; zz++) {
        !           880:                if(p[zz].h.type) {
        !           881:                        for(ii=p[zz].s.st; jj=unpackw(ii); ii++) {
        !           882:                                i++;
        !           883:                                if(jj&WQ)j++;
        !           884:                        }
        !           885:                }
        !           886:        }
        !           887:        medianw=(7*i)/(10*j);
        !           888: 
        !           889:        /* Start packed output */
        !           890:        fprintf(wpackfile,"-huffman\n");
        !           891: 
        !           892:        /* OUTPUT trees */
        !           893:        outtree(qascii);
        !           894:        outtree(hascii);
        !           895:        outtree(comm);
        !           896:        outtree(nsen);
        !           897:        outtree(parsp);
        !           898:        outtree(nwds);
        !           899:        outtree(nwdsback);
        !           900: 
        !           901:        /* OUTPUT headers */
        !           902:        writesim(500000,text);
        !           903:        writesim(100000,z);
        !           904:        writesim(1000,nsq);
        !           905:        writesim(500000,windex);
        !           906:        writesim(10000,nwq);
        !           907:        writesim(2000,wqtext);
        !           908:        writesim(2000,sqtext);
        !           909:        writesim(100,medians);
        !           910:        writesim(100,medianw);
        !           911: 
        !           912:        /* OUTPUT sense qualifier text */
        !           913:        for(i=0; i<sqtext; i++)outbit(qascii.code[sqbase[i]]);
        !           914:        /* OUTPUT word qualifier text */
        !           915:        for(i=0; i<wqtext; i++)outbit(qascii.code[wqbase[i]]);
        !           916:        /* OUTPUT hw ncommon, text \0, number of senses, part of speech */
        !           917:        for(zz=1; zz<z; zz++) {
        !           918:                if(p[zz].h.type)continue;
        !           919:                j=k,k=p[zz].h.tt;
        !           920:                if(k==0)l=0;
        !           921:                else for(l=0; tbase[k+l]==tbase[j+l]; l++);
        !           922:                outbit(comm.code[l]);
        !           923:                for(i=l; tbase[i+k]; i++)outbit(hascii.code[tbase[i+k]]);
        !           924:                outbit(hascii.code[0]);
        !           925:                for(n=zz+1; p[n].s.type; n++);
        !           926:                outbit(nsen.code[n-zz]);
        !           927:                for(n=zz+1; p[n].s.type; n++)outbit(parsp.code[p[n].s.p]);
        !           928:        }
        !           929:        /* OUTPUT qualified sense run, qualifier reference number */
        !           930:        m=n=0;
        !           931:        for(zz=1; zz<z; zz++) {
        !           932:                if(p[zz].h.type) {
        !           933:                        n++;
        !           934:                        if(p[zz].s.q) {
        !           935:                                writesim(medians,n-m-1);
        !           936:                                m=n;
        !           937:                                j=squal(zz)-sqbase;
        !           938:                                for(i=0; i<NSQR; i++)if(sqref[i]==j)break;
        !           939:                                if(sqref[i]!=j)err("NSQR search botch");
        !           940:                                outbitf(NSQR+i);
        !           941:                        }
        !           942:                }
        !           943:        }
        !           944:        writesim(medians,n-m);
        !           945:        /* sort words into alphabetical order */
        !           946:        for(zz=1; zz<z; zz++) {
        !           947:                if(p[zz].h.type==0)continue;
        !           948:                for(i=p[zz].s.st,j=0; k=unpackw(i); i++) {
        !           949:                        wtemp[j].wqtab=0;
        !           950:                        if(k&WQ) {
        !           951:                                il=0; iu=nwq;
        !           952:                                while(il<iu-1) {
        !           953:                                        im=(il+iu)/2;
        !           954:                                        if(wqtab[im].waddr>i)iu=im;
        !           955:                                        else il=im;
        !           956:                                }
        !           957:                                if(wqtab[il].waddr!=i)err("bin botch");
        !           958:                                wtemp[j].wqtab=il;
        !           959:                        }
        !           960:                        wtemp[j++].k=k;
        !           961:                }
        !           962:                qsort(wtemp,j,sizeof*wtemp,alphacmp);
        !           963:                for(i=p[zz].s.st,j=0; unpackw(i); i++) {
        !           964:                        if(wtemp[j].k&WQ) {
        !           965:                                wqtab[wtemp[j].wqtab].waddr=i;
        !           966:                        }
        !           967:                        opackw(i,wtemp[j++].k);
        !           968:                }
        !           969:        }
        !           970:        qsort(wqtab,nwq,sizeof*wqtab,wqcmp);
        !           971:        /* OUTPUT # words, # words back, back references */
        !           972:        for(zz=1; zz<z; zz++) {
        !           973:                if(p[zz].h.type==0)continue;
        !           974:                for(i=p[zz].s.st,j=0; k=unpackw(i)&WMASK; i++) {
        !           975:                                if(k<zz||p[k].s.type==0)j++;
        !           976:                }
        !           977:                outbit(nwds.code[i-p[zz].s.st]);
        !           978:                outbit(nwdsback.code[j]);
        !           979:                for(i=p[zz].s.st; k=unpackw(i)&WMASK; i++) {
        !           980:                        if(k<zz||p[k].s.type==0)outbitf(WQ|k);
        !           981:                }
        !           982:        }
        !           983:        /* OUTPUT word run, word qualifier index */
        !           984:        m=n=0;
        !           985:        for(zz=1; zz<z; zz++) {
        !           986:                if(p[zz].h.type) {
        !           987:                        for(ii=p[zz].s.st; jj=unpackw(ii); ii++) {
        !           988:                                n++;
        !           989:                                if(jj&WQ) {
        !           990:                                        writesim(medianw,n-m-1);
        !           991:                                        m=n;
        !           992:                                        j=wqual(ii)-wqbase;
        !           993:                                        for(i=0; i<NWQR; i++)if(wqref[i]==j)break;
        !           994:                                        if(wqref[i]!=j)err("NWQR search botch");
        !           995:                                        outbitf(NWQR+i);
        !           996:                                }
        !           997:                        }
        !           998:                }
        !           999:        }
        !          1000:        writesim(medianw,n-m);
        !          1001:        FREE(qascii);
        !          1002:        FREE(hascii);
        !          1003:        FREE(comm);
        !          1004:        FREE(nsen);
        !          1005:        FREE(parsp);
        !          1006:        FREE(nwds);
        !          1007:        FREE(nwdsback);
        !          1008:        outbitf(0xff);
        !          1009:        fclose(wpackfile);
        !          1010: }
        !          1011: outbit(x)
        !          1012: register x;
        !          1013: {
        !          1014:        static obuff,b;
        !          1015:        while(x>1) {
        !          1016:                obuff=(obuff<<1)+(x&1);
        !          1017:                x>>=1;
        !          1018:                if(++b>=8) {
        !          1019:                        b=0;
        !          1020:                        putc(obuff,wpackfile);
        !          1021:                }
        !          1022:        }
        !          1023: }
        !          1024: outbitf(x)
        !          1025: register x;
        !          1026: {
        !          1027:        register y;
        !          1028:        for(y=1; x>1; x>>=1)y=(y<<1)+(x&1);
        !          1029:        outbit(y);
        !          1030: }
        !          1031: inbit() { return INBIT(); }
        !          1032: char *rhalloc(x) { return malloc(x); }
        !          1033: char *rhfree(x) char *x; { free(x); }
        !          1034: wbytes(n) {
        !          1035:        putc(n>>8,wpackfile);
        !          1036:        putc(n,wpackfile);
        !          1037: }
        !          1038: rbytes() {
        !          1039:        int i;
        !          1040:        i=getc(f);
        !          1041:        return (i<<8)+getc(f);
        !          1042: }
        !          1043: decode(tree)
        !          1044: register short *tree;
        !          1045: {
        !          1046:        register int i;
        !          1047:        i=0;
        !          1048:        if(*tree++<2)return *tree&077777;
        !          1049:        do {
        !          1050:                if(INBIT())i=tree[i+1];
        !          1051:                else i=tree[i];
        !          1052:        } while((i&0100000)==0);
        !          1053:        return i&077777;
        !          1054: }
        !          1055: outtree(x)
        !          1056: struct huff x;
        !          1057: {
        !          1058:        int i;
        !          1059:        for(i=0; i<=x.tree[0]; i++)wbytes(x.tree[i]);
        !          1060: }
        !          1061: struct huff intree()
        !          1062: {
        !          1063:        struct huff x;
        !          1064:        int i;
        !          1065:        x.code=0;
        !          1066:        x.freq=0;
        !          1067:        i=rbytes();
        !          1068:        x.tree=(short*)ma((i+1)*sizeof(short));
        !          1069:        x.tree[0]=i;
        !          1070:        for(i=1; i<=x.tree[0]; i++)x.tree[i]=rbytes();
        !          1071:        return x;
        !          1072: }
        !          1073: rfixlen(code)
        !          1074: register code;
        !          1075: {
        !          1076:        register i=0;
        !          1077:        if(code<=1)return 0;
        !          1078:        do {
        !          1079:                i=(i<<1)+INBIT();
        !          1080:        } while((code>>=1)>1);
        !          1081:        return i;
        !          1082: }
        !          1083: unpackit()
        !          1084: {
        !          1085:        int i,j,k,l,m,n;
        !          1086:        int sqref[NSQR],wqref[NWQR];
        !          1087:        struct huff qascii,hascii,comm,nsen,parsp,nwds,nwdsback;
        !          1088:        int medians,medianw;
        !          1089:        int zz;
        !          1090:        int ii,jj;
        !          1091:        fprintf(STDERR,"wait for 'ready.'\n");
        !          1092:        fflush(STDERR);
        !          1093:        qascii=intree();
        !          1094:        hascii=intree();
        !          1095:        comm=intree();
        !          1096:        nsen=intree();
        !          1097:        parsp=intree();
        !          1098:        nwds=intree();
        !          1099:        nwdsback=intree();
        !          1100:        text=readsim(500000);
        !          1101:        z=readsim(100000);
        !          1102:        nsq=readsim(1000);
        !          1103:        windex=readsim(500000);
        !          1104:        nwq=readsim(10000);
        !          1105:        wqtext=readsim(2000);
        !          1106:        sqtext=readsim(2000);
        !          1107:        medians=readsim(100);
        !          1108:        medianw=readsim(100);
        !          1109: 
        !          1110:        for(i=0; i<sqtext; i++)sqbase[i]=decode(qascii.tree);
        !          1111:        for(i=0; i<wqtext; i++)wqbase[i]=decode(qascii.tree);
        !          1112: 
        !          1113:        for(i=j=0; i<sqtext; i++) {
        !          1114:                if(i==0||sqbase[i-1]==0) {
        !          1115:                        sqref[j++]=i;
        !          1116:                }
        !          1117:        }
        !          1118:        for(i=j=0; i<wqtext; i++) {
        !          1119:                if(i==0||wqbase[i-1]==0) {
        !          1120:                        wqref[j++]=i;
        !          1121:                }
        !          1122:        }
        !          1123:        for(k=0,zz=1; zz<z; zz=n) {
        !          1124:                l=decode(comm.tree);
        !          1125:                for(i=0; i<l; i++)tbase[i+k]=tbase[i+j];
        !          1126:                while(tbase[k+l++]=decode(hascii.tree));
        !          1127:                p[zz].h.tt=k;
        !          1128:                j=k;
        !          1129:                k+=l;
        !          1130:                l=decode(nsen.tree);
        !          1131:                for(n=zz+1; n<zz+l; n++) {
        !          1132:                        p[n].s.p=decode(parsp.tree);
        !          1133:                        p[n].s.type=1;
        !          1134:                }
        !          1135:        }
        !          1136:        if(zz!=z)fprintf(STDERR,"botch zz!=z %d %d\n",zz,z);
        !          1137:        if(k!=text)fprintf(STDERR,"botch k!=text %d %d\n",k,text);
        !          1138:        p[z].h.type=0;
        !          1139:        m=n=0;
        !          1140:        l=readsim(medians);
        !          1141:        k=0;
        !          1142:        for(zz=1; zz<z; zz++) {
        !          1143:                if(p[zz].h.type) {
        !          1144:                        n++;
        !          1145:                        if(l==n-m-1) {
        !          1146:                                p[zz].s.q=1;
        !          1147:                                m=n;
        !          1148:                                sqtab[k].saddr=zz;
        !          1149:                                sqtab[k++].qaddr=sqref[rfixlen(NSQR)];
        !          1150:                                l=readsim(medians);
        !          1151:                        }
        !          1152:                }
        !          1153:        }
        !          1154:        if(k!=nsq)fprintf(STDERR,"k!=nsq %d %d\n",k,nsq);
        !          1155:        j=0;
        !          1156:        for(zz=1; zz<z; zz++) {
        !          1157:                if(p[zz].h.type==0)continue;
        !          1158:                l=decode(nwds.tree);
        !          1159:                p[zz].s.st=j;
        !          1160:                m=decode(nwdsback.tree);
        !          1161:                for(i=0; i<m; i++) {
        !          1162:                        packw(j+i,n=rfixlen(WQ));
        !          1163:                        if(p[n].s.type) {
        !          1164:                                packw(p[n].s.st+p[n].s.v++,zz);
        !          1165:                        }
        !          1166:                }
        !          1167:                p[zz].s.v=m;
        !          1168:                j+=l+1;
        !          1169:        }
        !          1170:        if(j!=windex)fprintf(STDERR,"j!=windex %d %d\n",j,windex);
        !          1171:        m=n=0;
        !          1172:        l=readsim(medianw);
        !          1173:        j=0;
        !          1174:        for(zz=1; zz<z; zz++) {
        !          1175:                if(p[zz].h.type) {
        !          1176:                        for(ii=p[zz].s.st; jj=unpackw(ii); ii++) {
        !          1177:                                n++;
        !          1178:                                if(n-m-1==l) {
        !          1179:                                        m=n;
        !          1180:                                        opackw(ii,WQ+jj);
        !          1181:                                        i=wqref[rfixlen(NWQR)];
        !          1182:                                        wqtab[j].waddr=ii;
        !          1183:                                        wqtab[j++].qaddr=i;
        !          1184:                                        l=readsim(medianw);
        !          1185:                                }
        !          1186:                        }
        !          1187:                }
        !          1188:        }
        !          1189:        if(j!=nwq)fprintf(STDERR,"j!=nwq %d %d\n",j,nwq);
        !          1190:        free(qascii.tree);
        !          1191:        free(hascii.tree);
        !          1192:        free(comm.tree);
        !          1193:        free(nsen.tree);
        !          1194:        free(parsp.tree);
        !          1195:        free(nwds.tree);
        !          1196:        free(nwdsback.tree);
        !          1197: }
        !          1198: char *rhalloc();
        !          1199: typedef long huffreq;
        !          1200: typedef long huffcode;
        !          1201: typedef unsigned short hufftree;
        !          1202: typedef int huffnum;
        !          1203: 
        !          1204: /* gencodes((huffreq*)freqtab, (huffnum)n, (huffcode*)output);
        !          1205:    flipcodes((huffnum)n,(huffcode*)output);
        !          1206:    entree((huffcodes*)output.flipped,(huffnum)n,(hufftree*)treearray)
        !          1207: */
        !          1208: #define ENDFLAG 0100000
        !          1209: /*     decoding tree is (hufftree) array; start at 0, add next bit to index;
        !          1210:        if ENDFLAG is set in entry, everything else is the wanted code;
        !          1211:        if not, take the next offset from the entry;
        !          1212: 
        !          1213:        first entry in tree is number of entries in rest of tree;
        !          1214:        offset 0 corresponds to tr[1].
        !          1215: */
        !          1216: entree(cd,ncd,tr)
        !          1217: huffcode *cd;
        !          1218: huffnum ncd;
        !          1219: hufftree *tr;
        !          1220: {
        !          1221:        long i,j,k;
        !          1222:        long x;
        !          1223:        for(i=0; i<2*ncd; i++)tr[i]=0;
        !          1224:        tr++;
        !          1225:        k=2;
        !          1226: 
        !          1227:        for(i=0; i<ncd; i++) {
        !          1228:                j=0;
        !          1229:                for(x=cd[i]; x>1; x>>=1) {
        !          1230:                        j+=x&1;
        !          1231:                        if(tr[j]==0) {
        !          1232:                                if(x>3) {
        !          1233:                                        tr[j]=k;
        !          1234:                                        k+=2;
        !          1235:                                }
        !          1236:                                else {
        !          1237:                                        tr[j]=i|ENDFLAG;
        !          1238:                                }
        !          1239:                        }
        !          1240:                        j=tr[j];
        !          1241:                        if(x>3&&(j&ENDFLAG)) {
        !          1242:                                err("botched huffman code");
        !          1243:                        }
        !          1244:                }
        !          1245:        }
        !          1246:        *--tr=k;
        !          1247: }
        !          1248: /* Huffman codes from counts */
        !          1249: 
        !          1250: /* gencodes(huffreq freq table, huffnum length, huffcode output code table)
        !          1251:        output code words have leading 1-bit set, rest is huffman code.
        !          1252:        program aborts if a code is more than 30 bits -- try increasing
        !          1253:        the minimum counts.
        !          1254:        zero frequency counts produce zero code-words (are ignored).
        !          1255: 
        !          1256:        flipcodes(huffnum length, huffcode code table) flips the bit order of
        !          1257:                the huffman code bits.
        !          1258: */
        !          1259: 
        !          1260: struct code {
        !          1261:        struct code *left,*right;
        !          1262:        huffreq count;
        !          1263:        huffnum val;
        !          1264: };
        !          1265: 
        !          1266: struct code *getcode()
        !          1267: {
        !          1268:        struct code *h;
        !          1269:        h=(struct code*)rhalloc(sizeof*h);
        !          1270:        if(h==0)err("getcode: can't rhalloc code");
        !          1271:        h->left=h->right=0;
        !          1272:        h->val=h->count=0;
        !          1273:        return h;
        !          1274: }
        !          1275: 
        !          1276: tcompare(a,b)
        !          1277: register struct code **a,**b;
        !          1278: {
        !          1279:        if(a[0]->count<b[0]->count)return -1;
        !          1280:        if(a[0]->count>b[0]->count)return 1;
        !          1281:        if(a[0]->val<b[0]->val)return -1;
        !          1282:        if(a[0]->val>b[0]->val)return 1;
        !          1283:        return 0;
        !          1284: }
        !          1285: 
        !          1286: gencodes(infreq,nel,outcodes)
        !          1287: huffreq *infreq;
        !          1288: huffnum nel;
        !          1289: huffcode *outcodes;
        !          1290: {
        !          1291:        struct code **tp,**a,*p,*s;
        !          1292:        long i,j,k;
        !          1293:        long na;
        !          1294:        tp=(struct code**)rhalloc(nel*sizeof*tp);
        !          1295:        if(tp==0)err("gencodes: can't rhalloc tp");
        !          1296:        for(i=0; i<nel; i++) {
        !          1297:                outcodes[i]=0;
        !          1298:                tp[i]=getcode();
        !          1299:                tp[i]->count=infreq[i];
        !          1300:                tp[i]->val=i;
        !          1301:        }
        !          1302:        qsort(tp,nel,sizeof*tp,tcompare);
        !          1303:        for(k=0; k<nel-1; k++) {
        !          1304:                if(tp[k]->count==0)rhfree(tp[k]);
        !          1305:                else break;
        !          1306:        }
        !          1307:        a=&tp[k];
        !          1308:        na=nel-k;
        !          1309:        /* add smallest two and replace in heap till heap gone */
        !          1310:        for(k=na; k>2; ) {
        !          1311:                j=a[1]->count<a[2]->count?1:2;
        !          1312:                p=getcode();
        !          1313:                p->count=a[0]->count+a[j]->count;
        !          1314:                p->left=a[0];
        !          1315:                p->right=a[j];
        !          1316:                a[j]=p;
        !          1317:                for(i=j; (i+=i+1)<k; j=i) {
        !          1318:                        if(i+1<k&&a[i]->count>a[i+1]->count)i++;
        !          1319:                        if(a[j]->count<=a[i]->count)break;
        !          1320:                        p=a[j];
        !          1321:                        a[j]=a[i];
        !          1322:                        a[i]=p;
        !          1323:                }
        !          1324:                a[0]=a[--k];
        !          1325:                for(i=j=0; (i+=i+1)<k; j=i) {
        !          1326:                        if(i+1<k&&a[i]->count>a[i+1]->count)i++;
        !          1327:                        if(a[j]->count<=a[i]->count)break;
        !          1328:                        p=a[j];
        !          1329:                        a[j]=a[i];
        !          1330:                        a[i]=p;
        !          1331:                }
        !          1332:        }
        !          1333:        if(k==2) {
        !          1334:                p=getcode();
        !          1335:                p->count=a[0]->count+a[1]->count;
        !          1336:                p->left=a[0];
        !          1337:                p->right=a[1];
        !          1338:        }
        !          1339:        else p=a[0];
        !          1340:        rhfree(tp);
        !          1341:        ascodes(p,1L,outcodes);
        !          1342: }
        !          1343: 
        !          1344: ascodes(p,hcode,outcodes)
        !          1345: struct code *p;
        !          1346: long *outcodes;
        !          1347: long hcode;
        !          1348: {
        !          1349:        if(hcode<=0)err("ascodes: bitcode overflow");
        !          1350:        if(p->left==0) {
        !          1351:                if(p->right!=0)err("ascodes: tree ends wrong");
        !          1352:                outcodes[p->val]=hcode;
        !          1353:        }
        !          1354:        else {
        !          1355:                if(p->right==0)err("ascodes: tree ends oddly");
        !          1356:                ascodes(p->right,(hcode<<1)|1,outcodes);
        !          1357:                ascodes(p->left,(hcode<<1)|0,outcodes);
        !          1358:        }
        !          1359:        rhfree(p);
        !          1360: }
        !          1361: 
        !          1362: flipcodes(nel,codes)
        !          1363: huffnum nel;
        !          1364: huffcode *codes;
        !          1365: {
        !          1366:        long i,j,k;
        !          1367:        long x;
        !          1368:        for(i=0; i<nel; i++) {
        !          1369:                if(codes[i]==0)continue;
        !          1370:                x=codes[i];
        !          1371:                codes[i]=1;
        !          1372:                while(x>1) {
        !          1373:                        codes[i]=codes[i]*2|(x&1);
        !          1374:                        x>>=1;
        !          1375:                }
        !          1376:        }
        !          1377: }
        !          1378: /* self-similar Huffman codes for neg exp distr.
        !          1379:        calls outbitf(1+forward code)
        !          1380:        calls inbit()
        !          1381: */
        !          1382: writesim(median,intv)
        !          1383: {
        !          1384:        int i;
        !          1385:        static nc,dc,ec,omedian;
        !          1386:        if(median!=omedian) {
        !          1387:                omedian=median;
        !          1388:                for(i=1; (1L<<i)<=median; i++);
        !          1389:                nc=1L<<--i;
        !          1390:                dc=2*nc-median;
        !          1391:                ec=4*nc-median;
        !          1392:        }
        !          1393:        while(intv>=median) {
        !          1394:                outbitf(03L);
        !          1395:                intv-=median;
        !          1396:        }
        !          1397:        outbitf(02L);
        !          1398:        if(intv<dc)outbitf(intv+nc);
        !          1399:        else outbitf(ec+intv);
        !          1400: }
        !          1401: readsim(median) {
        !          1402:        int i,j,k;
        !          1403:        static nc,oi,dc,omedian;
        !          1404:        if(median!=omedian) {
        !          1405:                omedian=median;
        !          1406:                for(i=1; (1L<<i)<=median; i++);
        !          1407:                nc=1L<<--i;
        !          1408:                oi=i;
        !          1409:                dc=2*nc-median;
        !          1410:        }
        !          1411:        k=0; while(INBIT())k+=median;
        !          1412:        for(i=j=0; i<oi; i++)j+=j+INBIT();
        !          1413:        if(j<dc)return k+j;
        !          1414:        return k-dc+j+j+INBIT();
        !          1415: }
        !          1416: #ifdef AMBIGUOUS
        !          1417: prsense(i)
        !          1418: {
        !          1419:        fprintf(STDERR," &%d%s",i-hwof(i),p[hwof(i)].h.tt+tbase);
        !          1420: }
        !          1421: ambpath(a,b)
        !          1422: char *a,*b;
        !          1423: {
        !          1424:        int i,j,k;
        !          1425:        int froma,fromb,nfroma,nfromb;
        !          1426:        int e;
        !          1427:        int it;
        !          1428:        int pf;
        !          1429:        pf=0;
        !          1430:        it=1;
        !          1431:        e=inset(a);
        !          1432:        if(e==0) {
        !          1433:                fprintf(STDERR,"can't find %s\n",a);
        !          1434:                return;
        !          1435:        }
        !          1436:        k=inset(b);
        !          1437:        if(k==0) {
        !          1438:                fprintf(STDERR,"%s not found\n",b);
        !          1439:                return;
        !          1440:        }
        !          1441:        for(i=0; i<z; i++)if(p[i].s.type)p[i].s.v=0; else p[i].h.v=0;
        !          1442:        fromb=0;
        !          1443:        for(i=0; i<k; i++) {
        !          1444:                getcol(j);
        !          1445:                col[j].entry=set[i];
        !          1446:                col[j].next=fromb;
        !          1447:                fromb=j;
        !          1448:                p[set[i]].s.v=it;
        !          1449:        }
        !          1450:        e=inset(a);
        !          1451:        froma=0;
        !          1452:        for(i=0; i<e; i++) {
        !          1453:                getcol(j);
        !          1454:                col[j].entry=set[i];
        !          1455:                col[j].next=froma;
        !          1456:                froma=j;
        !          1457:                p[set[i]].s.v=it;
        !          1458:        }
        !          1459: loop:
        !          1460:        pf=0;
        !          1461:        for(k=froma; k; k=col[k].next) {
        !          1462:                j=hwof(col[k].entry);
        !          1463:                p[j].h.v|=1;
        !          1464:                if(p[j].h.v==3)pf++;
        !          1465:        }
        !          1466:        for(k=fromb; k; k=col[k].next) {
        !          1467:                j=hwof(col[k].entry);
        !          1468:                p[j].h.v|=2;
        !          1469:                if(p[j].h.v==3)pf++;
        !          1470:        }
        !          1471:        if(pf>0) {
        !          1472:                ambiguous(froma,fromb);
        !          1473:                goto pathx;
        !          1474:        }
        !          1475:        if(froma==0&&fromb==0) {
        !          1476:                fprintf(STDERR,"no link found\n");
        !          1477:                return;
        !          1478:        }
        !          1479:        it++;
        !          1480:        nfroma=0;
        !          1481:        while(froma) {
        !          1482:                i=p[col[froma].entry].s.st;
        !          1483:                j=froma;
        !          1484:                froma=col[j].next;
        !          1485:                freecol(j);
        !          1486:                while(j=(unpackw(i++)&WMASK)) {
        !          1487:                        if(p[j].s.type&&p[j].s.v==0) {
        !          1488:                                getcol(k);
        !          1489:                                col[k].next=nfroma;
        !          1490:                                col[k].entry=j;
        !          1491:                                nfroma=k;
        !          1492:                                p[j].s.v=it;
        !          1493:                        }
        !          1494:                }
        !          1495:        }
        !          1496:        froma=nfroma;
        !          1497:        nfromb=0;
        !          1498:        while(fromb) {
        !          1499:                i=p[col[fromb].entry].s.st;
        !          1500:                j=fromb;
        !          1501:                fromb=col[j].next;
        !          1502:                freecol(j);
        !          1503:                while(j=(unpackw(i++)&WMASK)) {
        !          1504:                        if(p[j].s.type&&p[j].s.v==0) {
        !          1505:                                getcol(k);
        !          1506:                                col[k].next=nfromb;
        !          1507:                                col[k].entry=j;
        !          1508:                                nfromb=k;
        !          1509:                                p[j].s.v=it;
        !          1510:                        }
        !          1511:                }
        !          1512:        }
        !          1513:        fromb=nfromb;
        !          1514:        goto loop;
        !          1515: pathx:
        !          1516:        freeall(froma);
        !          1517:        freeall(fromb);
        !          1518: }
        !          1519: hwof(i)
        !          1520: {
        !          1521:        while(i>0&&p[i].h.type!=0)i--;
        !          1522:        if(i==0)err("hwof()");
        !          1523:        return i;
        !          1524: }
        !          1525: ambiguous(fa,fb)
        !          1526: {
        !          1527:        int f,g,i,j,k;
        !          1528:        int dbest;
        !          1529:        int enda,endb;
        !          1530:        int la,lb;
        !          1531:        int length;
        !          1532:        int best,a;
        !          1533:        dbest=9999;
        !          1534:        for(best=0; best<2; best++)
        !          1535:        for(f=fa; f; f=(f==fb)?0:fb)for(g=f; g; g=col[g].next) {
        !          1536:                enda=endb=0;
        !          1537:                la=lb=9999;
        !          1538:                i=hwof(col[g].entry);
        !          1539:                if(p[i].h.v!=3)continue;
        !          1540:                for(j=1; p[i+j].s.type; j++) {
        !          1541:                        if(p[i+j].s.v==0)continue;
        !          1542:                        a=pathtoend(i+j);
        !          1543:                        if(enda==0)enda=a,la=p[i+j].s.v;
        !          1544:                        else
        !          1545:                        if(hwof(col[a].entry)==hwof(col[enda].entry)) {
        !          1546:                                if(p[i+j].s.v<la) {
        !          1547:                                        freeall(enda);
        !          1548:                                        enda=a;
        !          1549:                                        la=p[i+j].s.v;
        !          1550:                                }
        !          1551:                                else freeall(a);
        !          1552:                        }
        !          1553:                        else if(endb==0)endb=a,lb=p[i+j].s.v;
        !          1554:                        else
        !          1555:                        if(hwof(col[a].entry)==hwof(col[endb].entry)) {
        !          1556:                                if(p[i+j].s.v<lb) {
        !          1557:                                        freeall(endb);
        !          1558:                                        endb=a;
        !          1559:                                        lb=p[i+j].s.v;
        !          1560:                                }
        !          1561:                                else freeall(a);
        !          1562:                        }
        !          1563:                }
        !          1564:                length=la+lb;
        !          1565:                if(best==0&&length<dbest)dbest=length;
        !          1566:                else if(best==1&&length==dbest) {
        !          1567:                        prrev(enda);
        !          1568:                        fprintf(STDERR,"\n");
        !          1569:                        prrev(endb);
        !          1570:                        fprintf(STDERR,"\n\n");
        !          1571:                        p[i].h.v=0;
        !          1572:                }
        !          1573:                freeall(enda);
        !          1574:                freeall(endb);
        !          1575:        }
        !          1576: }
        !          1577: pathtoend(x)
        !          1578: {
        !          1579:        int i,j,k;
        !          1580:        for(k=0;;) {
        !          1581:                getcol(j);
        !          1582:                col[j].entry=x;
        !          1583:                col[j].next=k;
        !          1584:                k=j;
        !          1585:                if(p[x].s.v<=1)return k;
        !          1586:                i=p[x].s.st;
        !          1587:                while(j=(WMASK&unpackw(i++))) {
        !          1588:                        if(p[j].s.type&&p[j].s.v==p[x].s.v-1)break;
        !          1589:                }
        !          1590:                x=j;
        !          1591:        }
        !          1592: }
        !          1593: prrev(i)
        !          1594: {
        !          1595:        if(i==0)return;
        !          1596:        prrev(col[i].next);
        !          1597:        prsense(col[i].entry);
        !          1598: }
        !          1599: #endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.