]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/dict/ahd.c
cc, ?[acl]: fix gethunk() and move common memory allocator code to cc/compat
[plan9front.git] / sys / src / cmd / dict / ahd.c
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
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
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
136 ahdprintkey(void)
137 {
138         Bprint(bout, "No pronunciations.\n");
139 }