|
DataMuseum.dkPresents historical artifacts from the history of: Commodore CBM-900 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Commodore CBM-900 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - download
Length: 4716 (0x126c) Types: TextFile Notes: UNIX file Names: »spell2.c«
└─⟦f27320a65⟧ Bits:30001972 Commodore 900 hard disk image with partial source code └─⟦f4b8d8c84⟧ UNIX Filesystem └─ ⟦this⟧ »cmd/spell/spell2.c«
/* * Common routines to read and write words * in the compressed dictionary for the * simple (but complete) version of spell. */ #include <stdio.h> #include <ctype.h> /* * The coding is as follows: * 1-26 are letters, 27 is `-', 28 is apostrophe. * 0 is the pad character at word's end. * 29 is optional `s', 30-31 is unused. * They are packed with 3 per 16 bits (canonically) * and the 16th bit is the end-of-word marker. * This is all done independent of byte-ordering or * word size. All that is required is at least 8-bit * bytes (chars) and at least 16-bit words (ints). */ static char compress[256]; /* Initialised in init */ static char expand[] = { '\0', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '-','\'', '#','\0','\0' }; #define EWORD 0100000 /* End of word */ #define NWORD 50 /* Length of a word */ #define NCLONE 500 /* Number of clones to save (maximum) */ #define NSPACE 2000 /* Size of string space for plurals */ static char word[NWORD]; /* Static space returned by getword() */ static char space[NSPACE]; static char *spacep = space; static char *clones[NCLONE]; /* Table of saved plurals */ static int nclone; /* * Initialise the compressed table. * This is independent of character set * representation (e.g. ascii or ebcdic) * and only has to be called if putword is used. */ init() { compress['-'] = 27; compress['\'']= 28; compress['#'] = 29; compress['a'] = compress['A'] = 1; compress['b'] = compress['B'] = 2; compress['c'] = compress['C'] = 3; compress['d'] = compress['D'] = 4; compress['e'] = compress['E'] = 5; compress['f'] = compress['F'] = 6; compress['g'] = compress['G'] = 7; compress['h'] = compress['H'] = 8; compress['i'] = compress['I'] = 9; compress['j'] = compress['J'] = 10; compress['k'] = compress['K'] = 11; compress['l'] = compress['L'] = 12; compress['m'] = compress['M'] = 13; compress['n'] = compress['N'] = 14; compress['o'] = compress['O'] = 15; compress['p'] = compress['P'] = 16; compress['q'] = compress['Q'] = 17; compress['r'] = compress['R'] = 18; compress['s'] = compress['S'] = 19; compress['t'] = compress['T'] = 20; compress['u'] = compress['U'] = 21; compress['v'] = compress['V'] = 22; compress['w'] = compress['W'] = 23; compress['x'] = compress['X'] = 24; compress['y'] = compress['Y'] = 25; compress['z'] = compress['Z'] = 26; } /* * Read a word from the dictionary, * one `dfp'. Return pointer to * word or NULL on EOF. * `*' words are cloned into the singular * and plural. The plural is saved until * it comes up in collating order. */ char * getword(dfp) FILE *dfp; { register char *wp; register int t = EWORD; static int clone; static int saved; if (saved) { saved = 0; } else { clone = 0; wp = word; for (;;) { register int c; if ((c = getc(dfp)) == EOF) break; t = c; if ((c = getc(dfp)) == EOF) goto bad; t <<= 8; t |= c; if ((*wp++ = expand[t&037]) == '#') clone++; if ((*wp++ = expand[(t>>5)&037]) == '#') clone++; if ((*wp++ = expand[(t>>10)&037]) == '#') clone++; if (t & EWORD) break; } if (wp == word) return (NULL); if ((t&EWORD) == 0) goto bad; if (clone) while (wp > word) if (*--wp == '#') break; *wp = '\0'; } if (nclone && strcmp(word, clones[nclone-1])>0) { wp = clones[--nclone]; saved++; return (spacep = wp); } else if (clone) { plural(word); clone = 0; } return (word); bad: fprintf(stderr, "spell: bad dictionary format\n"); exit(1); } /* * Pluralise the word, by adding an 's' to it. * Save a copy away in the list of pending plurals * (`clones'). */ static plural(s) char *s; { register char *cp; register char *as; for (cp=s; *cp++ != '\0'; ) ; *--cp = 's'; cp++; *cp++ = '\0'; if (nclone >= NCLONE) { fprintf(stderr, "spell: too many saved plurals\n"); exit(1); } as = spacep; if ((spacep += cp-s) >= &space[NSPACE]) { fprintf(stderr, "spell: out of memory for plurals\n"); exit(1); } strcpy(as, s); clones[nclone++] = as; cp[-2] = '\0'; /* Restore original word */ } /* * Put out the ascii word, onto the * dictionary file in compressed form. */ putword(wp, dfp) register char *wp; FILE *dfp; { register int l; while ((l = compress[*wp++]) != 0) putlet(l, dfp); putlet(0, dfp); } /* * Put out a single compressed letter. * 0 Marks end of word. */ putlet(l, fp) register int l; register FILE *fp; { static int n = 0; static int word = 0; if (l != 0) { word |= l<<(n*5); if (++n < 3) return; } else word |= EWORD; putc(word>>8, fp); putc(word&0377, fp); n = word = 0; word = 0; }