| #include <u.h> |
| #include <libc.h> |
| #include <bio.h> |
| #include "dict.h" |
| |
| /* |
| * American Heritage Dictionary (encrypted) |
| */ |
| |
| static Rune intab[256]; |
| |
| static void |
| initintab(void) |
| { |
| intab[0x82] = 0xe9; |
| intab[0x85] = 0xe0; |
| intab[0x89] = 0xeb; |
| intab[0x8a] = 0xe8; |
| intab[0xa4] = 0xf1; |
| intab[0xf8] = 0xb0; |
| intab[0xf9] = 0xb7; |
| } |
| |
| 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){ |
| initintab(); |
| 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"); |
| } |