ahd.c (2173B)
1 #include <u.h> 2 #include <libc.h> 3 #include <bio.h> 4 #include "dict.h" 5 6 /* 7 * American Heritage Dictionary (encrypted) 8 */ 9 10 static Rune intab[256]; 11 12 static void 13 initintab(void) 14 { 15 intab[0x82] = 0xe9; 16 intab[0x85] = 0xe0; 17 intab[0x89] = 0xeb; 18 intab[0x8a] = 0xe8; 19 intab[0xa4] = 0xf1; 20 intab[0xf8] = 0xb0; 21 intab[0xf9] = 0xb7; 22 } 23 24 static char tag[64]; 25 26 enum{ 27 Run, Openper, Openat, Closeat 28 }; 29 30 void 31 ahdprintentry(Entry e, int cmd) 32 { 33 static int inited; 34 long addr; 35 char *p, *t = tag; 36 int obreaklen; 37 int c, state = Run; 38 39 if(!inited){ 40 initintab(); 41 for(c=0; c<256; c++) 42 if(intab[c] == 0) 43 intab[c] = c; 44 inited = 1; 45 } 46 obreaklen = breaklen; 47 breaklen = 80; 48 addr = e.doff; 49 for(p=e.start; p<e.end; p++){ 50 c = intab[(*p ^ (addr++>>1))&0xff]; 51 switch(state){ 52 case Run: 53 if(c == '%'){ 54 t = tag; 55 state = Openper; 56 break; 57 } 58 Putchar: 59 if(c == '\n') 60 outnl(0); 61 else if(c < Runeself) 62 outchar(c); 63 else 64 outrune(c); 65 break; 66 67 case Openper: 68 if(c == '@') 69 state = Openat; 70 else{ 71 outchar('%'); 72 state = Run; 73 goto Putchar; 74 } 75 break; 76 77 case Openat: 78 if(c == '@') 79 state = Closeat; 80 else if(t < &tag[sizeof tag-1]) 81 *t++ = c; 82 break; 83 84 case Closeat: 85 if(c == '%'){ 86 *t = 0; 87 switch(cmd){ 88 case 'h': 89 if(strcmp("EH", tag) == 0) 90 goto out; 91 break; 92 case 'r': 93 outprint("%%@%s@%%", tag); 94 break; 95 } 96 state = Run; 97 }else{ 98 if(t < &tag[sizeof tag-1]) 99 *t++ = '@'; 100 if(t < &tag[sizeof tag-1]) 101 *t++ = c; 102 state = Openat; 103 } 104 break; 105 } 106 } 107 out: 108 outnl(0); 109 breaklen = obreaklen; 110 } 111 112 long 113 ahdnextoff(long fromoff) 114 { 115 static char *patterns[] = { "%@NL@%", "%@2@%", 0 }; 116 int c, k = 0, state = 0; 117 char *pat = patterns[0]; 118 long defoff = -1; 119 120 if(Bseek(bdict, fromoff, 0) < 0) 121 return -1; 122 while((c = Bgetc(bdict)) >= 0){ 123 c ^= (fromoff++>>1)&0xff; 124 if(c != pat[state]){ 125 state = 0; 126 continue; 127 } 128 if(pat[++state]) 129 continue; 130 if(pat = patterns[++k]){ /* assign = */ 131 state = 0; 132 defoff = fromoff-6; 133 continue; 134 } 135 return fromoff-5; 136 } 137 return defoff; 138 } 139 140 void 141 ahdprintkey(void) 142 { 143 Bprint(bout, "No pronunciations.\n"); 144 }