Annotation of coherent/d/bin/spell/spell2.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Common routines to read and write words
                      3:  * in the compressed dictionary for the
                      4:  * simple (but complete) version of spell.
                      5:  */
                      6: 
                      7: #include <stdio.h>
                      8: #include <ctype.h>
                      9: 
                     10: /*
                     11:  * The coding is as follows:
                     12:  * 1-26 are letters, 27 is `-', 28 is apostrophe.
                     13:  * 0 is the pad character at word's end.
                     14:  * 29 is optional `s', 30-31 is unused.
                     15:  * They are packed with 3 per 16 bits (canonically)
                     16:  * and the 16th bit is the end-of-word marker.
                     17:  * This is all done independent of byte-ordering or
                     18:  * word size.  All that is required is at least 8-bit
                     19:  * bytes (chars) and at least 16-bit words (ints).
                     20:  */
                     21: 
                     22: static char    compress[256];  /* Initialised in init */
                     23: 
                     24: static char    expand[] = {
                     25:        '\0',
                     26:        'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
                     27:        'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
                     28:        'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
                     29:        'y', 'z', '-','\'', '#','\0','\0'
                     30: };
                     31: 
                     32: #define        EWORD   0100000         /* End of word */
                     33: #define        NWORD   50              /* Length of a word */
                     34: #define        NCLONE  500             /* Number of clones to save (maximum) */
                     35: #define        NSPACE  2000            /* Size of string space for plurals */
                     36: 
                     37: static char    word[NWORD];    /* Static space returned by getword() */
                     38: static char    space[NSPACE];
                     39: static char    *spacep = space;
                     40: static char    *clones[NCLONE];        /* Table of saved plurals */
                     41: static int     nclone;
                     42: 
                     43: /*
                     44:  * Initialise the compressed table.
                     45:  * This is independent of character set
                     46:  * representation (e.g. ascii or ebcdic)
                     47:  * and only has to be called if putword is used.
                     48:  */
                     49: init()
                     50: {
                     51:        compress['-'] = 27;
                     52:        compress['\'']= 28;
                     53:        compress['#'] = 29;
                     54:        compress['a'] = compress['A'] = 1;
                     55:        compress['b'] = compress['B'] = 2;
                     56:        compress['c'] = compress['C'] = 3;
                     57:        compress['d'] = compress['D'] = 4;
                     58:        compress['e'] = compress['E'] = 5;
                     59:        compress['f'] = compress['F'] = 6;
                     60:        compress['g'] = compress['G'] = 7;
                     61:        compress['h'] = compress['H'] = 8;
                     62:        compress['i'] = compress['I'] = 9;
                     63:        compress['j'] = compress['J'] = 10;
                     64:        compress['k'] = compress['K'] = 11;
                     65:        compress['l'] = compress['L'] = 12;
                     66:        compress['m'] = compress['M'] = 13;
                     67:        compress['n'] = compress['N'] = 14;
                     68:        compress['o'] = compress['O'] = 15;
                     69:        compress['p'] = compress['P'] = 16;
                     70:        compress['q'] = compress['Q'] = 17;
                     71:        compress['r'] = compress['R'] = 18;
                     72:        compress['s'] = compress['S'] = 19;
                     73:        compress['t'] = compress['T'] = 20;
                     74:        compress['u'] = compress['U'] = 21;
                     75:        compress['v'] = compress['V'] = 22;
                     76:        compress['w'] = compress['W'] = 23;
                     77:        compress['x'] = compress['X'] = 24;
                     78:        compress['y'] = compress['Y'] = 25;
                     79:        compress['z'] = compress['Z'] = 26;
                     80: }
                     81: 
                     82: /*
                     83:  * Read a word from the dictionary,
                     84:  * one `dfp'.  Return pointer to
                     85:  * word or NULL on EOF.
                     86:  * `*' words are cloned into the singular
                     87:  * and plural. The plural is saved until
                     88:  * it comes up in collating order.
                     89:  */
                     90: char *
                     91: getword(dfp)
                     92: FILE *dfp;
                     93: {
                     94:        register char *wp;
                     95:        register int t = EWORD;
                     96:        static int clone;
                     97:        static int saved;
                     98: 
                     99:        if (saved) {
                    100:                saved = 0;
                    101:        } else {
                    102:                clone = 0;
                    103:                wp = word;
                    104:                for (;;) {
                    105:                        register int c;
                    106: 
                    107:                        if ((c = getc(dfp)) == EOF)
                    108:                                break;
                    109:                        t = c;
                    110:                        if ((c = getc(dfp)) == EOF)
                    111:                                goto bad;
                    112:                        t <<= 8;
                    113:                        t |= c;
                    114:                        if ((*wp++ = expand[t&037]) == '#')
                    115:                                clone++;
                    116:                        if ((*wp++ = expand[(t>>5)&037]) == '#')
                    117:                                clone++;
                    118:                        if ((*wp++ = expand[(t>>10)&037]) == '#')
                    119:                                clone++;
                    120:                        if (t & EWORD)
                    121:                                break;
                    122:                }
                    123:                if (wp == word)
                    124:                        return (NULL);
                    125:                if ((t&EWORD) == 0)
                    126:                        goto bad;
                    127:                if (clone)
                    128:                        while (wp > word)
                    129:                                if (*--wp == '#')
                    130:                                        break;
                    131:                *wp = '\0';
                    132:        }
                    133:        if (nclone && strcmp(word, clones[nclone-1])>0) {
                    134:                wp = clones[--nclone];
                    135:                saved++;
                    136:                return (spacep = wp);
                    137:        } else if (clone) {
                    138:                plural(word);
                    139:                clone = 0;
                    140:        }
                    141:        return (word);
                    142: bad:
                    143:        fprintf(stderr, "spell: bad dictionary format\n");
                    144:        exit(1);
                    145: }
                    146: 
                    147: /*
                    148:  * Pluralise the word, by adding an 's' to it.
                    149:  * Save a copy away in the list of pending plurals
                    150:  * (`clones').
                    151:  */
                    152: static
                    153: plural(s)
                    154: char *s;
                    155: {
                    156:        register char *cp;
                    157:        register char *as;
                    158: 
                    159:        for (cp=s; *cp++ != '\0'; )
                    160:                ;
                    161:        *--cp = 's';
                    162:        cp++;
                    163:        *cp++ = '\0';
                    164:        if (nclone >= NCLONE) {
                    165:                fprintf(stderr, "spell: too many saved plurals\n");
                    166:                exit(1);
                    167:        }
                    168:        as = spacep;
                    169:        if ((spacep += cp-s) >= &space[NSPACE]) {
                    170:                fprintf(stderr, "spell: out of memory for plurals\n");
                    171:                exit(1);
                    172:        }
                    173:        strcpy(as, s);
                    174:        clones[nclone++] = as;
                    175:        cp[-2] = '\0';          /* Restore original word */
                    176: }
                    177: 
                    178: /*
                    179:  * Put out the ascii word, onto the
                    180:  * dictionary file in compressed form.
                    181:  */
                    182: putword(wp, dfp)
                    183: register char *wp;
                    184: FILE *dfp;
                    185: {
                    186:        register int l;
                    187: 
                    188:        while ((l = compress[*wp++]) != 0)
                    189:                putlet(l, dfp);
                    190:        putlet(0, dfp);
                    191: }
                    192: 
                    193: /*
                    194:  * Put out a single compressed letter.
                    195:  * 0 Marks end of word.
                    196:  */
                    197: putlet(l, fp)
                    198: register int l;
                    199: register FILE *fp;
                    200: {
                    201:        static int n = 0;
                    202:        static int word = 0;
                    203: 
                    204:        if (l != 0) {
                    205:                word |= l<<(n*5);
                    206:                if (++n < 3)
                    207:                        return;
                    208:        } else
                    209:                word |= EWORD;
                    210:        putc(word>>8, fp);
                    211:        putc(word&0377, fp);
                    212:        n = word = 0;
                    213:        word = 0;
                    214: }

unix.superglobalmegacorp.com

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