aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/dict/ahd.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/dict/ahd.c')
-rw-r--r--src/cmd/dict/ahd.c139
1 files changed, 139 insertions, 0 deletions
diff --git a/src/cmd/dict/ahd.c b/src/cmd/dict/ahd.c
new file mode 100644
index 00000000..18a56d00
--- /dev/null
+++ b/src/cmd/dict/ahd.c
@@ -0,0 +1,139 @@
+#include <u.h>
+#include <libc.h>
+#include <bio.h>
+#include "dict.h"
+
+/*
+ * American Heritage Dictionary (encrypted)
+ */
+
+static Rune intab[256] = {
+ [0x82] 0xe9,
+ [0x85] 0xe0,
+ [0x89] 0xeb,
+ [0x8a] 0xe8,
+ [0xa4] 0xf1,
+ [0xf8] 0xb0,
+ [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){
+ 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");
+}