plan9port

[fork] Plan 9 from user space
git clone git://src.adamsgaard.dk/plan9port # fast
git clone https://src.adamsgaard.dk/plan9port.git # slow
Log | Files | Refs | README | LICENSE Back to index

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 }