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