ref: 11025d6f4a2c3c7e75010f85c2d3108e602270b7
dir: /sys/src/cmd/dict/ahd.c/
#include <u.h> #include <libc.h> #include <bio.h> #include "dict.h" /* * American Heritage Dictionary (encrypted) */ static Rune intab[256] = { [0x82] L'é', [0x85] L'à', [0x89] L'ë', [0x8a] L'è', [0xa4] L'ñ', [0xf8] L'°', [0xf9] L'·', }; static char tag[64]; enum{ Run, Openper, Openat, Closeat }; void ahdprintentry(Entry e, int cmd) { static int inited; long addr; char *p, *t = tag; int obreaklen; int c, state = Run; if(!inited){ for(c=0; c<256; c++) if(intab[c] == 0) intab[c] = c; inited = 1; } obreaklen = breaklen; breaklen = 80; addr = e.doff; for(p=e.start; p<e.end; p++){ c = intab[(*p ^ (addr++>>1))&0xff]; switch(state){ case Run: if(c == '%'){ t = tag; state = Openper; break; } Putchar: if(c == '\n') outnl(0); else if(c < Runeself) outchar(c); else outrune(c); break; case Openper: if(c == '@') state = Openat; else{ outchar('%'); state = Run; goto Putchar; } break; case Openat: if(c == '@') state = Closeat; else if(t < &tag[sizeof tag-1]) *t++ = c; break; case Closeat: if(c == '%'){ *t = 0; switch(cmd){ case 'h': if(strcmp("EH", tag) == 0) goto out; break; case 'r': outprint("%%@%s@%%", tag); break; } state = Run; }else{ if(t < &tag[sizeof tag-1]) *t++ = '@'; if(t < &tag[sizeof tag-1]) *t++ = c; state = Openat; } break; } } out: outnl(0); breaklen = obreaklen; } long ahdnextoff(long fromoff) { static char *patterns[] = { "%@NL@%", "%@2@%", 0 }; int c, k = 0, state = 0; char *pat = patterns[0]; long defoff = -1; if(Bseek(bdict, fromoff, 0) < 0) return -1; while((c = Bgetc(bdict)) >= 0){ c ^= (fromoff++>>1)&0xff; if(c != pat[state]){ state = 0; continue; } if(pat[++state]) continue; if(pat = patterns[++k]){ /* assign = */ state = 0; defoff = fromoff-6; continue; } return fromoff-5; } return defoff; } void ahdprintkey(void) { Bprint(bout, "No pronunciations.\n"); }