Annotation of researchv10no/cmd/spell/pcode.c, revision 1.1

1.1     ! root        1: 
        !             2: #include <stdio.h>
        !             3: #include <ctype.h>
        !             4: #include <string.h>
        !             5: #include "code.h"
        !             6: 
        !             7: #ifndef __cplusplus
        !             8: 
        !             9: void   exit(int);
        !            10: void   qsort(void*, unsigned, int, int(*)(void*, void*));
        !            11: 
        !            12: #else
        !            13: 
        !            14: #include <memory.h>
        !            15: extern "C" {
        !            16: void   exit(int);
        !            17: void   qsort(void*, unsigned, int, int(*)(void*, void*));
        !            18: }
        !            19: 
        !            20: #endif
        !            21: 
        !            22: /* read an annotated spelling list in the form
        !            23:        word <tab> affixcode [ , affixcode ] ...
        !            24:    print a reencoded version
        !            25:        octal <tab> word
        !            26:  */
        !            27: 
        !            28: typedef long Bits;
        !            29: typedef        struct  Dict    Dict;
        !            30: struct Dict
        !            31: {
        !            32:        char*   word;
        !            33:        Bits    encode;
        !            34: };
        !            35: 
        !            36: Dict   words[200000];
        !            37: char   space[500000];
        !            38: Bits   encodes[4094];
        !            39: long   nspace;
        !            40: long   nwords;
        !            41: int    ncodes;
        !            42: 
        !            43: void   readinput(FILE*);
        !            44: long   typecode(char*);
        !            45: int    wcmp(void*, void*);
        !            46: void   pdict(void);
        !            47: void   sput(int);
        !            48: 
        !            49: main(int argc, char *argv[])
        !            50: {
        !            51:        FILE* f;
        !            52: 
        !            53:        nwords = 0;
        !            54:        nspace = 0;
        !            55:        ncodes = 0;
        !            56:        if(argc <= 1)
        !            57:                readinput(stdin);
        !            58:        while(argc > 1) {
        !            59:                f = fopen(argv[1], "r");
        !            60:                if(f == 0) {
        !            61:                        fprintf(stderr, "Cannot open %s\n", argv[1]);
        !            62:                        exit(1);
        !            63:                }
        !            64:                readinput(f);
        !            65:                fclose(f);
        !            66:                argc--;
        !            67:                argv++;
        !            68:        }
        !            69:        fprintf(stderr, "words = %ld; space = %ld; codes = %d\n",
        !            70:                nwords, nspace, ncodes);
        !            71:        qsort(words, nwords, sizeof(words[0]), wcmp);
        !            72:        pdict();
        !            73:        return 0;
        !            74: }
        !            75: 
        !            76: wcmp(void *a, void *b)
        !            77: {
        !            78: 
        !            79:        return strcmp(((Dict*)a)->word, ((Dict*)b)->word);
        !            80: }
        !            81: 
        !            82: void
        !            83: readinput(FILE* f)
        !            84: {
        !            85:        long i;
        !            86:        char *code, *bword;
        !            87:        char line[200];
        !            88:        long lineno = 0;
        !            89: 
        !            90:        while(fgets(line, sizeof(line), f)) {
        !            91:                line[strlen(line)-1] = 0;
        !            92:                lineno++;
        !            93:                code = line;
        !            94:                while(isspace(*code))
        !            95:                        code++;
        !            96:                bword = code;
        !            97:                while(*code && !isspace(*code))
        !            98:                        code++;
        !            99: 
        !           100:                i = code-bword;
        !           101:                memcpy(space+nspace, bword, i);
        !           102:                words[nwords].word = space+nspace;
        !           103:                nspace += i;
        !           104:                space[nspace] = 0;
        !           105:                nspace++;
        !           106: 
        !           107:                if(*code) {
        !           108:                        *code++ = 0;
        !           109:                        while(isspace(*code))
        !           110:                                code++;
        !           111:                }
        !           112:                words[nwords].encode = typecode(code);
        !           113:                nwords++;
        !           114:                if(nwords >= sizeof(words)/sizeof(words[0])) {
        !           115:                        fprintf(stderr, "words array too small\n");
        !           116:                        exit(1);
        !           117:                }
        !           118:                if(nspace >= sizeof(space)/sizeof(space[0])) {
        !           119:                        fprintf(stderr, "space array too small\n");
        !           120:                        exit(1);
        !           121:                }
        !           122:        }
        !           123: }
        !           124: 
        !           125: 
        !           126: typedef        struct  Class   Class;
        !           127: struct Class
        !           128: {
        !           129:        char*   codename;
        !           130:        long    bits;
        !           131: };
        !           132: Class  codea[]  =
        !           133: {
        !           134:        { "a", ADJ },
        !           135:        { "adv", ADV },
        !           136:        0
        !           137: };
        !           138: Class  codec[] =
        !           139: {
        !           140:        { "comp", COMP },
        !           141:        0
        !           142: };
        !           143: Class  coded[] =
        !           144: {
        !           145:        { "d", DONT_TOUCH},
        !           146:        0
        !           147: };
        !           148: 
        !           149: Class  codee[] =
        !           150: {
        !           151:        { "ed", ED },
        !           152:        { "er", ACTOR },
        !           153:        0
        !           154: };
        !           155: 
        !           156: Class  codei[] =
        !           157: {
        !           158:        { "in", IN },
        !           159:        { "ion", ION },
        !           160:        0
        !           161: };
        !           162: 
        !           163: Class  codem[] =
        !           164: {
        !           165:        { "man", MAN },
        !           166:        { "ms", MONO },
        !           167:        0
        !           168: };
        !           169: 
        !           170: Class  coden[] =
        !           171: {
        !           172:        { "n", NOUN },
        !           173:        { "na", N_AFFIX },
        !           174:        { "nopref", NOPREF },
        !           175:        0
        !           176: };
        !           177: 
        !           178: Class  codep[] =
        !           179: {
        !           180:        { "pc", PROP_COLLECT },
        !           181:        0
        !           182: };
        !           183: Class  codes[] =
        !           184: {
        !           185:        { "s", STOP },
        !           186:        0
        !           187: };
        !           188: 
        !           189: Class  codev[] =
        !           190: {
        !           191:        { "v", VERB },
        !           192:        { "va", V_AFFIX },
        !           193:        { "vi", V_IRREG },
        !           194:        0
        !           195: };
        !           196: 
        !           197: Class  codey[] =
        !           198: {
        !           199:        { "y", _Y },
        !           200:        0
        !           201: };
        !           202: 
        !           203: Class  codez[] =
        !           204: {
        !           205:        0
        !           206: };
        !           207: Class* codetab[] =
        !           208: {
        !           209:        codea,
        !           210:        codez,
        !           211:        codec,
        !           212:        coded,
        !           213:        codee,
        !           214:        codez,
        !           215:        codez,
        !           216:        codez,
        !           217:        codei,
        !           218:        codez,
        !           219:        codez,
        !           220:        codez,
        !           221:        codem,
        !           222:        coden,
        !           223:        codez,
        !           224:        codep,
        !           225:        codez,
        !           226:        codez,
        !           227:        codes,
        !           228:        codez,
        !           229:        codez,
        !           230:        codev,
        !           231:        codez,
        !           232:        codez,
        !           233:        codey,
        !           234:        codez,
        !           235: };
        !           236: 
        !           237: long
        !           238: typecode(char *str)
        !           239: {
        !           240:        Class *p;
        !           241:        long code;
        !           242:        int n, i;
        !           243:        char *s, *sp, *st;
        !           244: 
        !           245:        code = 0;
        !           246: 
        !           247: loop:
        !           248:        for(s=str; *s != 0 && *s != ','; s++)
        !           249:                ;
        !           250:        for(p = codetab[*str-'a']; sp = p->codename; p++) {
        !           251:                st = str;
        !           252:                for(n=s-str;; st++,sp++) {
        !           253:                        if(*st != *sp)
        !           254:                                goto cont;
        !           255:                        n--;
        !           256:                        if(n == 0)
        !           257:                                break;
        !           258:                }
        !           259:                code |= p->bits;
        !           260:                if(*s == 0)
        !           261:                        goto out;
        !           262:                str = s+1;
        !           263:                goto loop;
        !           264:        cont:;
        !           265:        }
        !           266:        fprintf(stderr, "Unknown affix code \"%s\"\n", str);
        !           267:        return 0;
        !           268: out:
        !           269:        for(i=0; i<ncodes; i++)
        !           270:                if(encodes[i] == code)
        !           271:                        return i;
        !           272:        encodes[i] = code;
        !           273:        ncodes++;
        !           274:        return i;
        !           275: }
        !           276: 
        !           277: void
        !           278: sput(int s)
        !           279: {
        !           280: 
        !           281:        putchar(s>>8);
        !           282:        putchar(s);
        !           283: }
        !           284: 
        !           285: void
        !           286: lput(long l)
        !           287: {
        !           288:        putchar(l>>24);
        !           289:        putchar(l>>16);
        !           290:        putchar(l>>8);
        !           291:        putchar(l);
        !           292: }
        !           293: 
        !           294: /*
        !           295:  * spit out the encoded dictionary
        !           296:  * all numbers are encoded big-endian.
        !           297:  *     struct
        !           298:  *     {
        !           299:  *             short   ncodes;
        !           300:  *             int     encodes[ncodes];
        !           301:  *             struct
        !           302:  *             {
        !           303:  *                     short   encode;
        !           304:  *                     char    word[*];
        !           305:  *             } words[*];
        !           306:  *     };
        !           307:  * 0x8000 flag for code word
        !           308:  * 0x7800 count of number of common bytes with previous word
        !           309:  * 0x07ff index into codes array for affixes
        !           310:  */
        !           311: void
        !           312: pdict(void)
        !           313: {
        !           314:        long i, count;
        !           315:        Bits encode;
        !           316:        int j, c;
        !           317:        char *lastword, *thisword, *word;
        !           318: 
        !           319:        sput(ncodes);
        !           320:        for(i=0; i<ncodes; i++)
        !           321:                lput(encodes[i]);
        !           322: 
        !           323:        count = ncodes*4 + 2;
        !           324:        lastword = "";
        !           325:        for(i=0; i<nwords; i++) {
        !           326:                word = words[i].word;
        !           327:                thisword = word;
        !           328:                for(j=0; *thisword == *lastword; j++) {
        !           329:                        if(*thisword == 0) {
        !           330:                                fprintf(stderr, "identical words: %s\n", word);
        !           331:                                break;
        !           332:                        }
        !           333:                        thisword++;
        !           334:                        lastword++;
        !           335:                }
        !           336:                if(j > 15)
        !           337:                        j = 15;
        !           338:                encode = words[i].encode;
        !           339:                c = (1<<15) | (j<<11) | encode;
        !           340:                sput(c);
        !           341:                count += 2;
        !           342:                for(thisword=word+j; c = *thisword; thisword++) {
        !           343:                        putchar(c);
        !           344:                        count++;
        !           345:                }
        !           346:                lastword = word;
        !           347:        }
        !           348:        fprintf(stderr, "output bytes = %ld\n", count);
        !           349: }

unix.superglobalmegacorp.com

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