4 /* Macros for Rune support of ctype.h-like functions */
6 #define isupper(r) (L'A' <= (r) && (r) <= L'Z')
7 #define islower(r) (L'a' <= (r) && (r) <= L'z')
8 #define isalpha(r) (isupper(r) || islower(r))
9 #define islatin1(r) (0xC0 <= (r) && (r) <= 0xFF)
11 #define isdigit(r) (L'0' <= (r) && (r) <= L'9')
13 #define isalnum(r) (isalpha(r) || isdigit(r))
15 #define isspace(r) ((r) == L' ' || (r) == L'\t' \
16 || (0x0A <= (r) && (r) <= 0x0D))
18 #define tolower(r) ((r)-'A'+'a')
20 #define sgn(v) ((v) < 0 ? -1 : ((v) > 0 ? 1 : 0))
23 char *filename = "/lib/words";
32 int rev = 1; /*-1 for reverse-ordered file, not implemented*/
33 int (*compare)(Rune*, Rune*);
37 Rune key[50], orig[50];
38 Rune latin_fold_tab[] =
40 /* Table to fold latin 1 characters to ASCII equivalents
41 based at Rune value 0xc0
52 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'c',
53 'e', 'e', 'e', 'e', 'i', 'i', 'i', 'i',
54 'd', 'n', 'o', 'o', 'o', 'o', 'o', 0 ,
55 'o', 'u', 'u', 'u', 'u', 'y', 0 , 0 ,
56 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'c',
57 'e', 'e', 'e', 'e', 'i', 'i', 'i', 'i',
58 'd', 'n', 'o', 'o', 'o', 'o', 'o', 0 ,
59 'o', 'u', 'u', 'u', 'u', 'y', 0 , 'y',
63 int acomp(Rune*, Rune*);
64 int getword(Biobuf*, Rune *rp, int n);
65 void torune(char*, Rune*);
66 void rcanon(Rune*, Rune*);
67 int ncomp(Rune*, Rune*);
72 fprint(2, "usage: %s [-dfinx] [-t c] [string] [file]\n", argv0);
77 main(int argc, char *argv[])
81 Binit(&bin, 0, OREAD);
82 Binit(&bout, 1, OWRITE);
98 chartorune(&tab, EARGF(usage()));
104 fprint(2, "%s: bad option %c\n", argv0, ARGC());
109 torune(argv[0], orig);
122 dfile = Bopen(filename, OREAD);
124 fprint(2, "look: can't open %s\n", filename);
125 exits("no dictionary");
133 if(!getword(&bin, orig, sizeof(orig)/sizeof(orig[0])))
139 if (!exact || !acomp(word, key))
140 Bprint(&bout, "%S\n", entry);
141 while(getword(dfile, entry, sizeof(entry)/sizeof(entry[0]))) {
143 n = compare(key, word);
149 if (!exact || !acomp(word, orig))
150 Bprint(&bout, "%S\n", entry);
167 top = Bseek(dfile, 0, 2);
170 Bseek(dfile, mid, 0);
173 while(c>=0 && c!='\n');
174 mid = Boffset(dfile);
175 if(!getword(dfile, entry, sizeof(entry)/sizeof(entry[0])))
178 n = compare(key, word);
194 Bseek(dfile, bot, 0);
195 while(getword(dfile, entry, sizeof(entry)/sizeof(entry[0]))) {
197 n = compare(key, word);
215 * acomp(s, t) returns:
216 * -2 if s strictly precedes t
217 * -1 if s is a prefix of t
218 * 0 if s is the same as t
219 * 1 if t is a prefix of s
220 * 2 if t strictly precedes s
224 acomp(Rune *s, Rune *t)
248 torune(char *old, Rune *new)
250 do old += chartorune(new, old);
255 rcanon(Rune *old, Rune *new)
259 while((r = *old++) && r != tab) {
260 if (islatin1(r) && latin_fold_tab[r-0xc0])
261 r = latin_fold_tab[r-0xc0];
263 if(!(isalnum(r) || r == L' ' || r == L'\t'))
274 ncomp(Rune *s, Rune *t)
276 Rune *is, *it, *js, *jt;
284 ssgn = tsgn = -2*rev;
293 for(is = s; isdigit(*is); is++)
295 for(it = t; isdigit(*it); it++)
302 if(b = *--it - *--is)
317 while(isdigit(*s) && isdigit(*t))
330 getword(Biobuf *f, Rune *rp, int n)
344 fprint(2, "Look: word too long. Bailing out.\n");