1219b2ee8SDavid du Colombier #include <u.h>
2219b2ee8SDavid du Colombier #include <libc.h>
3219b2ee8SDavid du Colombier #include <bio.h>
4219b2ee8SDavid du Colombier #include "dict.h"
5219b2ee8SDavid du Colombier
6219b2ee8SDavid du Colombier /*
7219b2ee8SDavid du Colombier * Robert Électronique.
8219b2ee8SDavid du Colombier */
9219b2ee8SDavid du Colombier
10219b2ee8SDavid du Colombier enum
11219b2ee8SDavid du Colombier {
12219b2ee8SDavid du Colombier CIT = MULTIE+1, /* citation ptr followed by long int and ascii label */
13219b2ee8SDavid du Colombier BROM, /* bold roman */
14219b2ee8SDavid du Colombier ITON, /* start italic */
15219b2ee8SDavid du Colombier ROM, /* roman */
16219b2ee8SDavid du Colombier SYM, /* symbol font? */
17219b2ee8SDavid du Colombier HEL, /* helvetica */
18219b2ee8SDavid du Colombier BHEL, /* helvetica bold */
19219b2ee8SDavid du Colombier SMALL, /* smaller? */
20219b2ee8SDavid du Colombier ITOFF, /* end italic */
21219b2ee8SDavid du Colombier SUP, /* following character is superscript */
22219b2ee8SDavid du Colombier SUB /* following character is subscript */
23219b2ee8SDavid du Colombier };
24219b2ee8SDavid du Colombier
25219b2ee8SDavid du Colombier static Rune intab[256] = {
26219b2ee8SDavid du Colombier /*0*/ /*1*/ /*2*/ /*3*/ /*4*/ /*5*/ /*6*/ /*7*/
27219b2ee8SDavid du Colombier /*00*/ NONE, L'☺', L'☻', L'♥', L'♦', L'♣', L'♠', L'•',
28219b2ee8SDavid du Colombier 0x25d8, L'ʘ', L'\n', L'♂', L'♀', L'♪', 0x266b, L'※',
29219b2ee8SDavid du Colombier /*10*/ L'⇨', L'⇦', L'↕', L'‼', L'¶', L'§', L'⁃', L'↨',
30219b2ee8SDavid du Colombier L'↑', L'↓', L'→', L'←', L'⌙', L'↔', 0x25b4, 0x25be,
31219b2ee8SDavid du Colombier /*20*/ L' ', L'!', L'"', L'#', L'$', L'%', L'&', L''',
32219b2ee8SDavid du Colombier L'(', L')', L'*', L'+', L',', L'-', L'.', L'/',
33219b2ee8SDavid du Colombier /*30*/ L'0', L'1', L'2', L'3', L'4', L'5', L'6', L'7',
34219b2ee8SDavid du Colombier L'8', L'9', L':', L';', L'<', L'=', L'>', L'?',
35219b2ee8SDavid du Colombier /*40*/ L'@', L'A', L'B', L'C', L'D', L'E', L'F', L'G',
36219b2ee8SDavid du Colombier L'H', L'I', L'J', L'K', L'L', L'M', L'N', L'O',
37219b2ee8SDavid du Colombier /*50*/ L'P', L'Q', L'R', L'S', L'T', L'U', L'V', L'W',
38219b2ee8SDavid du Colombier L'X', L'Y', L'Z', L'[', L'\\', L']', L'^', L'_',
39219b2ee8SDavid du Colombier /*60*/ L'`', L'a', L'b', L'c', L'd', L'e', L'f', L'g',
40219b2ee8SDavid du Colombier L'h', L'i', L'j', L'k', L'l', L'm', L'n', L'o',
41219b2ee8SDavid du Colombier /*70*/ L'p', L'q', L'r', L's', L't', L'u', L'v', L'w',
42219b2ee8SDavid du Colombier L'x', L'y', L'z', L'{', L'|', L'}', L'~', L'',
43219b2ee8SDavid du Colombier /*80*/ L'Ç', L'ü', L'é', L'â', L'ä', L'à', L'å', L'ç',
44219b2ee8SDavid du Colombier L'ê', L'ë', L'è', L'ï', L'î', L'ì', L'Ä', L'Å',
45219b2ee8SDavid du Colombier /*90*/ L'É', L'æ', L'Æ', L'ô', L'ö', L'ò', L'û', L'ù',
46219b2ee8SDavid du Colombier L'ÿ', L'Ö', L'Ü', L'¢', L'£', L'¥', L'₧', L'ʃ',
47219b2ee8SDavid du Colombier /*a0*/ L'á', L'í', L'ó', L'ú', L'ñ', L'Ñ', L'ª', L'º',
48219b2ee8SDavid du Colombier L'¿', L'⌐', L'¬', L'½', L'¼', L'¡', L'«', L'»',
49219b2ee8SDavid du Colombier /*b0*/ NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE,
50219b2ee8SDavid du Colombier NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE,
51219b2ee8SDavid du Colombier /*c0*/ NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE,
52219b2ee8SDavid du Colombier CIT, BROM, NONE, ITON, ROM, SYM, HEL, BHEL,
53219b2ee8SDavid du Colombier /*d0*/ NONE, SMALL, ITOFF, SUP, SUB, NONE, NONE, NONE,
54219b2ee8SDavid du Colombier NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE,
55219b2ee8SDavid du Colombier /*e0*/ L'α', L'ß', L'γ', L'π', L'Σ', L'σ', L'µ', L'τ',
56219b2ee8SDavid du Colombier L'Φ', L'Θ', L'Ω', L'δ', L'∞', L'Ø', L'ε', L'∩',
57219b2ee8SDavid du Colombier /*f0*/ L'≡', L'±', L'≥', L'≤', L'⌠', L'⌡', L'÷', L'≈',
58219b2ee8SDavid du Colombier L'°', L'∙', L'·', L'√', L'ⁿ', L'²', L'∎', L' ',
59219b2ee8SDavid du Colombier };
60219b2ee8SDavid du Colombier
61219b2ee8SDavid du Colombier static Rune suptab[] = {
62219b2ee8SDavid du Colombier ['0'] L'⁰', ['1'] L'ⁱ', ['2'] L'', ['3'] L'',
63219b2ee8SDavid du Colombier ['4'] L'⁴', ['5'] L'⁵', ['6'] L'⁶', ['7'] L'⁷',
64219b2ee8SDavid du Colombier ['8'] L'⁸', ['9'] L'⁹', ['+'] L'⁺', ['-'] L'⁻',
65219b2ee8SDavid du Colombier ['='] L'⁼', ['('] L'⁽', [')'] L'⁾', ['a'] L'ª',
66219b2ee8SDavid du Colombier ['n'] L'ⁿ', ['o'] L'º'
67219b2ee8SDavid du Colombier };
68219b2ee8SDavid du Colombier
69219b2ee8SDavid du Colombier static Rune subtab[] = {
70219b2ee8SDavid du Colombier ['0'] L'₀', ['1'] L'₁', ['2'] L'₂', ['3'] L'₃',
71219b2ee8SDavid du Colombier ['4'] L'₄', ['5'] L'₅', ['6'] L'₆', ['7'] L'₇',
72219b2ee8SDavid du Colombier ['8'] L'₈', ['9'] L'₉', ['+'] L'₊', ['-'] L'₋',
73219b2ee8SDavid du Colombier ['='] L'₌', ['('] L'₍', [')'] L'₎'
74219b2ee8SDavid du Colombier };
75219b2ee8SDavid du Colombier
76219b2ee8SDavid du Colombier #define GSHORT(p) (((p)[0]<<8) | (p)[1])
77219b2ee8SDavid du Colombier #define GLONG(p) (((p)[0]<<24) | ((p)[1]<<16) | ((p)[2]<<8) | (p)[3])
78219b2ee8SDavid du Colombier
79219b2ee8SDavid du Colombier static char cfile[] = "/lib/dict/robert/cits.rob";
80219b2ee8SDavid du Colombier static char dfile[] = "/lib/dict/robert/defs.rob";
81219b2ee8SDavid du Colombier static char efile[] = "/lib/dict/robert/etym.rob";
82219b2ee8SDavid du Colombier static char kfile[] = "/lib/dict/robert/_phon";
83219b2ee8SDavid du Colombier
84219b2ee8SDavid du Colombier static Biobuf * cb;
85219b2ee8SDavid du Colombier static Biobuf * db;
86219b2ee8SDavid du Colombier static Biobuf * eb;
87219b2ee8SDavid du Colombier
88219b2ee8SDavid du Colombier static Biobuf * Bouvrir(char*);
89219b2ee8SDavid du Colombier static void citation(int, int);
90219b2ee8SDavid du Colombier static void robertprintentry(Entry*, Entry*, int);
91219b2ee8SDavid du Colombier
92219b2ee8SDavid du Colombier void
robertindexentry(Entry e,int cmd)93219b2ee8SDavid du Colombier robertindexentry(Entry e, int cmd)
94219b2ee8SDavid du Colombier {
95219b2ee8SDavid du Colombier uchar *p = (uchar *)e.start;
96219b2ee8SDavid du Colombier long ea, el, da, dl, fa;
97219b2ee8SDavid du Colombier Entry def, etym;
98219b2ee8SDavid du Colombier
99219b2ee8SDavid du Colombier ea = GLONG(&p[0]);
100219b2ee8SDavid du Colombier el = GSHORT(&p[4]);
101219b2ee8SDavid du Colombier da = GLONG(&p[6]);
102219b2ee8SDavid du Colombier dl = GSHORT(&p[10]);
103219b2ee8SDavid du Colombier fa = GLONG(&p[12]);
104219b2ee8SDavid du Colombier USED(fa);
105219b2ee8SDavid du Colombier
106219b2ee8SDavid du Colombier if(db == 0)
107219b2ee8SDavid du Colombier db = Bouvrir(dfile);
108219b2ee8SDavid du Colombier def.start = malloc(dl+1);
109219b2ee8SDavid du Colombier def.end = def.start + dl;
110219b2ee8SDavid du Colombier def.doff = da;
111219b2ee8SDavid du Colombier Bseek(db, da, 0);
112219b2ee8SDavid du Colombier Bread(db, def.start, dl);
113219b2ee8SDavid du Colombier *def.end = 0;
114219b2ee8SDavid du Colombier if(cmd == 'h'){
115219b2ee8SDavid du Colombier robertprintentry(&def, 0, cmd);
116219b2ee8SDavid du Colombier }else{
117219b2ee8SDavid du Colombier if(eb == 0)
118219b2ee8SDavid du Colombier eb = Bouvrir(efile);
119219b2ee8SDavid du Colombier etym.start = malloc(el+1);
120219b2ee8SDavid du Colombier etym.end = etym.start + el;
121219b2ee8SDavid du Colombier etym.doff = ea;
122219b2ee8SDavid du Colombier Bseek(eb, ea, 0);
123219b2ee8SDavid du Colombier Bread(eb, etym.start, el);
124219b2ee8SDavid du Colombier *etym.end = 0;
125219b2ee8SDavid du Colombier robertprintentry(&def, &etym, cmd);
126219b2ee8SDavid du Colombier free(etym.start);
127219b2ee8SDavid du Colombier }
128219b2ee8SDavid du Colombier free(def.start);
129219b2ee8SDavid du Colombier }
130219b2ee8SDavid du Colombier
131219b2ee8SDavid du Colombier static void
robertprintentry(Entry * def,Entry * etym,int cmd)132219b2ee8SDavid du Colombier robertprintentry(Entry *def, Entry *etym, int cmd)
133219b2ee8SDavid du Colombier {
134219b2ee8SDavid du Colombier uchar *p, *pe;
135219b2ee8SDavid du Colombier Rune r; int c, n;
136219b2ee8SDavid du Colombier int baseline = 0;
137219b2ee8SDavid du Colombier int lineno = 0;
138219b2ee8SDavid du Colombier int cit = 0;
139219b2ee8SDavid du Colombier
140219b2ee8SDavid du Colombier p = (uchar *)def->start;
141219b2ee8SDavid du Colombier pe = (uchar *)def->end;
142219b2ee8SDavid du Colombier while(p < pe){
143219b2ee8SDavid du Colombier if(cmd == 'r'){
144219b2ee8SDavid du Colombier outchar(*p++);
145219b2ee8SDavid du Colombier continue;
146219b2ee8SDavid du Colombier }
147219b2ee8SDavid du Colombier c = *p++;
148219b2ee8SDavid du Colombier switch(r = intab[c]){ /* assign = */
149219b2ee8SDavid du Colombier case BROM:
150219b2ee8SDavid du Colombier case ITON:
151219b2ee8SDavid du Colombier case ROM:
152219b2ee8SDavid du Colombier case SYM:
153219b2ee8SDavid du Colombier case HEL:
154219b2ee8SDavid du Colombier case BHEL:
155219b2ee8SDavid du Colombier case SMALL:
156219b2ee8SDavid du Colombier case ITOFF:
157219b2ee8SDavid du Colombier case NONE:
158219b2ee8SDavid du Colombier if(debug)
159219b2ee8SDavid du Colombier outprint("\\%.2ux", c);
160219b2ee8SDavid du Colombier baseline = 0;
161219b2ee8SDavid du Colombier break;
162219b2ee8SDavid du Colombier
163219b2ee8SDavid du Colombier case SUP:
164219b2ee8SDavid du Colombier baseline = 1;
165219b2ee8SDavid du Colombier break;
166219b2ee8SDavid du Colombier
167219b2ee8SDavid du Colombier case SUB:
168219b2ee8SDavid du Colombier baseline = -1;
169219b2ee8SDavid du Colombier break;
170219b2ee8SDavid du Colombier
171219b2ee8SDavid du Colombier case CIT:
172219b2ee8SDavid du Colombier n = p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24);
173219b2ee8SDavid du Colombier p += 4;
174219b2ee8SDavid du Colombier if(debug)
175219b2ee8SDavid du Colombier outprint("[%d]", n);
176219b2ee8SDavid du Colombier while(*p == ' ' || ('0'<=*p && *p<='9') || *p == '.'){
177219b2ee8SDavid du Colombier if(debug)
178219b2ee8SDavid du Colombier outchar(*p);
179219b2ee8SDavid du Colombier ++p;
180219b2ee8SDavid du Colombier }
181219b2ee8SDavid du Colombier ++cit;
182219b2ee8SDavid du Colombier outnl(2);
183219b2ee8SDavid du Colombier citation(n, cmd);
184219b2ee8SDavid du Colombier baseline = 0;
185219b2ee8SDavid du Colombier break;
186219b2ee8SDavid du Colombier
187219b2ee8SDavid du Colombier case '\n':
188219b2ee8SDavid du Colombier outnl(0);
189219b2ee8SDavid du Colombier baseline = 0;
190219b2ee8SDavid du Colombier ++lineno;
191219b2ee8SDavid du Colombier break;
192219b2ee8SDavid du Colombier
193219b2ee8SDavid du Colombier default:
194219b2ee8SDavid du Colombier if(baseline > 0 && r < nelem(suptab))
195219b2ee8SDavid du Colombier r = suptab[r];
196219b2ee8SDavid du Colombier else if(baseline < 0 && r < nelem(subtab))
197219b2ee8SDavid du Colombier r = subtab[r];
198219b2ee8SDavid du Colombier if(cit){
199219b2ee8SDavid du Colombier outchar('\n');
200219b2ee8SDavid du Colombier cit = 0;
201219b2ee8SDavid du Colombier }
202219b2ee8SDavid du Colombier outrune(r);
203219b2ee8SDavid du Colombier baseline = 0;
204219b2ee8SDavid du Colombier break;
205219b2ee8SDavid du Colombier }
206219b2ee8SDavid du Colombier if(r == '\n'){
207219b2ee8SDavid du Colombier if(cmd == 'h')
208219b2ee8SDavid du Colombier break;
209219b2ee8SDavid du Colombier if(lineno == 1 && etym)
210219b2ee8SDavid du Colombier robertprintentry(etym, 0, cmd);
211219b2ee8SDavid du Colombier }
212219b2ee8SDavid du Colombier }
213219b2ee8SDavid du Colombier outnl(0);
214219b2ee8SDavid du Colombier }
215219b2ee8SDavid du Colombier
216219b2ee8SDavid du Colombier static void
citation(int addr,int cmd)217219b2ee8SDavid du Colombier citation(int addr, int cmd)
218219b2ee8SDavid du Colombier {
219219b2ee8SDavid du Colombier Entry cit;
220219b2ee8SDavid du Colombier
221219b2ee8SDavid du Colombier if(cb == 0)
222219b2ee8SDavid du Colombier cb = Bouvrir(cfile);
223219b2ee8SDavid du Colombier Bseek(cb, addr, 0);
224219b2ee8SDavid du Colombier cit.start = Brdline(cb, 0xc8);
225*7dd7cddfSDavid du Colombier cit.end = cit.start + Blinelen(cb) - 1;
226219b2ee8SDavid du Colombier cit.doff = addr;
227219b2ee8SDavid du Colombier *cit.end = 0;
228219b2ee8SDavid du Colombier robertprintentry(&cit, 0, cmd);
229219b2ee8SDavid du Colombier }
230219b2ee8SDavid du Colombier
231219b2ee8SDavid du Colombier long
robertnextoff(long fromoff)232219b2ee8SDavid du Colombier robertnextoff(long fromoff)
233219b2ee8SDavid du Colombier {
234219b2ee8SDavid du Colombier return (fromoff & ~15) + 16;
235219b2ee8SDavid du Colombier }
236219b2ee8SDavid du Colombier
237219b2ee8SDavid du Colombier void
robertprintkey(void)238219b2ee8SDavid du Colombier robertprintkey(void)
239219b2ee8SDavid du Colombier {
240219b2ee8SDavid du Colombier Biobuf *db;
241219b2ee8SDavid du Colombier char *l;
242219b2ee8SDavid du Colombier
243219b2ee8SDavid du Colombier db = Bouvrir(kfile);
244219b2ee8SDavid du Colombier while(l = Brdline(db, '\n')) /* assign = */
245*7dd7cddfSDavid du Colombier Bwrite(bout, l, Blinelen(db));
246219b2ee8SDavid du Colombier Bterm(db);
247219b2ee8SDavid du Colombier }
248219b2ee8SDavid du Colombier
249219b2ee8SDavid du Colombier void
robertflexentry(Entry e,int cmd)250219b2ee8SDavid du Colombier robertflexentry(Entry e, int cmd)
251219b2ee8SDavid du Colombier {
252219b2ee8SDavid du Colombier uchar *p, *pe;
253219b2ee8SDavid du Colombier Rune r; int c;
254219b2ee8SDavid du Colombier int lineno = 1;
255219b2ee8SDavid du Colombier
256219b2ee8SDavid du Colombier p = (uchar *)e.start;
257219b2ee8SDavid du Colombier pe = (uchar *)e.end;
258219b2ee8SDavid du Colombier while(p < pe){
259219b2ee8SDavid du Colombier if(cmd == 'r'){
260*7dd7cddfSDavid du Colombier Bputc(bout, *p++);
261219b2ee8SDavid du Colombier continue;
262219b2ee8SDavid du Colombier }
263219b2ee8SDavid du Colombier c = *p++;
264219b2ee8SDavid du Colombier r = intab[c];
265219b2ee8SDavid du Colombier if(r == '$')
266219b2ee8SDavid du Colombier r = '\n';
267219b2ee8SDavid du Colombier if(r == '\n'){
268219b2ee8SDavid du Colombier ++lineno;
269219b2ee8SDavid du Colombier if(cmd == 'h' && lineno > 2)
270219b2ee8SDavid du Colombier break;
271219b2ee8SDavid du Colombier }
272219b2ee8SDavid du Colombier if(cmd == 'h' && lineno < 2)
273219b2ee8SDavid du Colombier continue;
274219b2ee8SDavid du Colombier if(r > MULTIE){
275219b2ee8SDavid du Colombier if(debug)
276219b2ee8SDavid du Colombier Bprint(bout, "\\%.2ux", c);
277219b2ee8SDavid du Colombier continue;
278219b2ee8SDavid du Colombier }
279219b2ee8SDavid du Colombier if(r < Runeself)
280*7dd7cddfSDavid du Colombier Bputc(bout, r);
281219b2ee8SDavid du Colombier else
282219b2ee8SDavid du Colombier Bputrune(bout, r);
283219b2ee8SDavid du Colombier }
284219b2ee8SDavid du Colombier outnl(0);
285219b2ee8SDavid du Colombier }
286219b2ee8SDavid du Colombier
287219b2ee8SDavid du Colombier long
robertnextflex(long fromoff)288219b2ee8SDavid du Colombier robertnextflex(long fromoff)
289219b2ee8SDavid du Colombier {
290219b2ee8SDavid du Colombier int c;
291219b2ee8SDavid du Colombier
292219b2ee8SDavid du Colombier if(Bseek(bdict, fromoff, 0) < 0)
293219b2ee8SDavid du Colombier return -1;
294*7dd7cddfSDavid du Colombier while((c = Bgetc(bdict)) >= 0){
295219b2ee8SDavid du Colombier if(c == '$')
296219b2ee8SDavid du Colombier return Boffset(bdict);
297219b2ee8SDavid du Colombier }
298219b2ee8SDavid du Colombier return -1;
299219b2ee8SDavid du Colombier }
300219b2ee8SDavid du Colombier
301219b2ee8SDavid du Colombier static Biobuf *
Bouvrir(char * fichier)302219b2ee8SDavid du Colombier Bouvrir(char *fichier)
303219b2ee8SDavid du Colombier {
304219b2ee8SDavid du Colombier Biobuf *db;
305219b2ee8SDavid du Colombier
306219b2ee8SDavid du Colombier db = Bopen(fichier, OREAD);
307219b2ee8SDavid du Colombier if(db == 0){
308219b2ee8SDavid du Colombier fprint(2, "%s: impossible d'ouvrir %s: %r\n", argv0, fichier);
309219b2ee8SDavid du Colombier exits("ouvrir");
310219b2ee8SDavid du Colombier }
311219b2ee8SDavid du Colombier return db;
312219b2ee8SDavid du Colombier }
313