]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/dict/robert.c
cc, ?[acl]: fix gethunk() and move common memory allocator code to cc/compat
[plan9front.git] / sys / src / cmd / dict / robert.c
1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include "dict.h"
5
6 /*
7  * Robert Électronique.
8  */
9
10 enum
11 {
12         CIT = MULTIE+1, /* citation ptr followed by long int and ascii label */
13         BROM,           /* bold roman */
14         ITON,           /* start italic */
15         ROM,            /* roman */
16         SYM,            /* symbol font? */
17         HEL,            /* helvetica */
18         BHEL,           /* helvetica bold */
19         SMALL,          /* smaller? */
20         ITOFF,          /* end italic */
21         SUP,            /* following character is superscript */
22         SUB             /* following character is subscript */
23 };
24
25 static Rune intab[256] = {
26         /*0*/   /*1*/   /*2*/   /*3*/   /*4*/   /*5*/   /*6*/   /*7*/
27 /*00*/  NONE,   L'☺', L'☻', L'♥', L'♦', L'♣', L'♠', L'•',
28         0x25d8, L'ʘ',  L'\n',  L'♂', L'♀', L'♪', 0x266b, L'※',
29 /*10*/  L'⇨', L'⇦', L'↕', L'‼', L'¶',  L'§',  L'⁃', L'↨',
30         L'↑', L'↓', L'→', L'←', L'⌙', L'↔', 0x25b4, 0x25be,
31 /*20*/  L' ',   L'!',   L'"',   L'#',   L'$',   L'%',   L'&',   L''',
32         L'(',   L')',   L'*',   L'+',   L',',   L'-',   L'.',   L'/',
33 /*30*/  L'0',   L'1',   L'2',   L'3',   L'4',   L'5',   L'6',   L'7',
34         L'8',   L'9',   L':',   L';',   L'<',   L'=',   L'>',   L'?',
35 /*40*/  L'@',   L'A',   L'B',   L'C',   L'D',   L'E',   L'F',   L'G',
36         L'H',   L'I',   L'J',   L'K',   L'L',   L'M',   L'N',   L'O',
37 /*50*/  L'P',   L'Q',   L'R',   L'S',   L'T',   L'U',   L'V',   L'W',
38         L'X',   L'Y',   L'Z',   L'[',   L'\\',  L']',   L'^',   L'_',
39 /*60*/  L'`',   L'a',   L'b',   L'c',   L'd',   L'e',   L'f',   L'g',
40         L'h',   L'i',   L'j',   L'k',   L'l',   L'm',   L'n',   L'o',
41 /*70*/  L'p',   L'q',   L'r',   L's',   L't',   L'u',   L'v',   L'w',
42         L'x',   L'y',   L'z',   L'{',   L'|',   L'}',   L'~',   L'\7f',
43 /*80*/  L'Ç',  L'ü',  L'é',  L'â',  L'ä',  L'à',  L'å',  L'ç',
44         L'ê',  L'ë',  L'è',  L'ï',  L'î',  L'ì',  L'Ä',  L'Å',
45 /*90*/  L'É',  L'æ',  L'Æ',  L'ô',  L'ö',  L'ò',  L'û',  L'ù',
46         L'ÿ',  L'Ö',  L'Ü',  L'¢',  L'£',  L'¥',  L'₧', L'ʃ',
47 /*a0*/  L'á',  L'í',  L'ó',  L'ú',  L'ñ',  L'Ñ',  L'ª',  L'º',
48         L'¿',  L'⌐', L'¬',  L'½',  L'¼',  L'¡',  L'«',  L'»',
49 /*b0*/  NONE,   NONE,   NONE,   NONE,   NONE,   NONE,   NONE,   NONE,
50         NONE,   NONE,   NONE,   NONE,   NONE,   NONE,   NONE,   NONE,
51 /*c0*/  NONE,   NONE,   NONE,   NONE,   NONE,   NONE,   NONE,   NONE,
52         CIT,    BROM,   NONE,   ITON,   ROM,    SYM,    HEL,    BHEL,
53 /*d0*/  NONE,   SMALL,  ITOFF,  SUP,    SUB,    NONE,   NONE,   NONE,
54         NONE,   NONE,   NONE,   NONE,   NONE,   NONE,   NONE,   NONE,
55 /*e0*/  L'α',  L'ß',  L'γ',  L'π',  L'Σ',  L'σ',  L'µ',  L'τ',
56         L'Φ',  L'Θ',  L'Ω',  L'δ',  L'∞', L'Ø',  L'ε',  L'∩',
57 /*f0*/  L'≡', L'±',  L'≥', L'≤', L'⌠', L'⌡', L'÷',  L'≈',
58         L'°',  L'∙', L'·',  L'√', L'ⁿ', L'²',  L'∎', L' ',
59 };
60
61 static Rune suptab[] = {
62         ['0'] L'⁰',   ['1'] L'¹',    ['2'] L'²',    ['3'] L'³',
63         ['4'] L'⁴',   ['5'] L'⁵',   ['6'] L'⁶',   ['7'] L'⁷',
64         ['8'] L'⁸',   ['9'] L'⁹',   ['+'] L'⁺',   ['-'] L'⁻',
65         ['='] L'⁼',   ['('] L'⁽',   [')'] L'⁾',   ['a'] L'ª',
66         ['n'] L'ⁿ',   ['o'] L'º'
67 };
68
69 static Rune subtab[] = {
70         ['0'] L'₀',   ['1'] L'₁',   ['2'] L'₂',   ['3'] L'₃',
71         ['4'] L'₄',   ['5'] L'₅',   ['6'] L'₆',   ['7'] L'₇',
72         ['8'] L'₈',   ['9'] L'₉',   ['+'] L'₊',   ['-'] L'₋',
73         ['='] L'₌',   ['('] L'₍',   [')'] L'₎'
74 };
75
76 #define GSHORT(p)       (((p)[0]<<8) | (p)[1])
77 #define GLONG(p)        (((p)[0]<<24) | ((p)[1]<<16) | ((p)[2]<<8) | (p)[3])
78
79 static char     cfile[] = "/lib/dict/robert/cits.rob";
80 static char     dfile[] = "/lib/dict/robert/defs.rob";
81 static char     efile[] = "/lib/dict/robert/etym.rob";
82 static char     kfile[] = "/lib/dict/robert/_phon";
83
84 static Biobuf * cb;
85 static Biobuf * db;
86 static Biobuf * eb;
87
88 static Biobuf * Bouvrir(char*);
89 static void     citation(int, int);
90 static void     robertprintentry(Entry*, Entry*, int);
91
92 void
93 robertindexentry(Entry e, int cmd)
94 {
95         uchar *p = (uchar *)e.start;
96         long ea, el, da, dl, fa;
97         Entry def, etym;
98
99         ea = GLONG(&p[0]);
100         el = GSHORT(&p[4]);
101         da = GLONG(&p[6]);
102         dl = GSHORT(&p[10]);
103         fa = GLONG(&p[12]);
104         USED(fa);
105
106         if(db == 0)
107                 db = Bouvrir(dfile);
108         if((def.start = malloc(dl+1)) == nil)
109                 sysfatal("malloc: %r");
110         def.end = def.start + dl;
111         def.doff = da;
112         Bseek(db, da, 0);
113         Bread(db, def.start, dl);
114         *def.end = 0;
115         if(cmd == 'h'){
116                 robertprintentry(&def, 0, cmd);
117         }else{
118                 if(eb == 0)
119                         eb = Bouvrir(efile);
120                 if((etym.start = malloc(el+1)) == nil)
121                         sysfatal("malloc: %r");
122                 etym.end = etym.start + el;
123                 etym.doff = ea;
124                 Bseek(eb, ea, 0);
125                 Bread(eb, etym.start, el);
126                 *etym.end = 0;
127                 robertprintentry(&def, &etym, cmd);
128                 free(etym.start);
129         }
130         free(def.start);
131 }
132
133 static void
134 robertprintentry(Entry *def, Entry *etym, int cmd)
135 {
136         uchar *p, *pe;
137         Rune r; int c, n;
138         int baseline = 0;
139         int lineno = 0;
140         int cit = 0;
141
142         p = (uchar *)def->start;
143         pe = (uchar *)def->end;
144         while(p < pe){
145                 if(cmd == 'r'){
146                         outchar(*p++);
147                         continue;
148                 }
149                 c = *p++;
150                 switch(r = intab[c]){   /* assign = */
151                 case BROM:
152                 case ITON:
153                 case ROM:
154                 case SYM:
155                 case HEL:
156                 case BHEL:
157                 case SMALL:
158                 case ITOFF:
159                 case NONE:
160                         if(debug)
161                                 outprint("\\%.2ux", c);
162                         baseline = 0;
163                         break;
164
165                 case SUP:
166                         baseline = 1;
167                         break;
168
169                 case SUB:
170                         baseline = -1;
171                         break;
172
173                 case CIT:
174                         n = p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24);
175                         p += 4;
176                         if(debug)
177                                 outprint("[%d]", n);
178                         while(*p == ' ' || ('0'<=*p && *p<='9') || *p == '.'){
179                                 if(debug)
180                                         outchar(*p);
181                                 ++p;
182                         }
183                         ++cit;
184                         outnl(2);
185                         citation(n, cmd);
186                         baseline = 0;
187                         break;
188
189                 case '\n':
190                         outnl(0);
191                         baseline = 0;
192                         ++lineno;
193                         break;
194
195                 default:
196                         if(baseline > 0 && r < nelem(suptab))
197                                 r = suptab[r];
198                         else if(baseline < 0 && r < nelem(subtab))
199                                 r = subtab[r];
200                         if(cit){
201                                 outchar('\n');
202                                 cit = 0;
203                         }
204                         outrune(r);
205                         baseline = 0;
206                         break;
207                 }
208                 if(r == '\n'){
209                         if(cmd == 'h')
210                                 break;
211                         if(lineno == 1 && etym)
212                                 robertprintentry(etym, 0, cmd);
213                 }
214         }
215         outnl(0);
216 }
217
218 static void
219 citation(int addr, int cmd)
220 {
221         Entry cit;
222
223         if(cb == 0)
224                 cb = Bouvrir(cfile);
225         Bseek(cb, addr, 0);
226         cit.start = Brdline(cb, 0xc8);
227         cit.end = cit.start + Blinelen(cb) - 1;
228         cit.doff = addr;
229         *cit.end = 0;
230         robertprintentry(&cit, 0, cmd);
231 }
232
233 long
234 robertnextoff(long fromoff)
235 {
236         return (fromoff & ~15) + 16;
237 }
238
239 void
240 robertprintkey(void)
241 {
242         Biobuf *db;
243         char *l;
244
245         db = Bouvrir(kfile);
246         while(l = Brdline(db, '\n'))    /* assign = */
247                 Bwrite(bout, l, Blinelen(db));
248         Bterm(db);
249 }
250
251 void
252 robertflexentry(Entry e, int cmd)
253 {
254         uchar *p, *pe;
255         Rune r; int c;
256         int lineno = 1;
257
258         p = (uchar *)e.start;
259         pe = (uchar *)e.end;
260         while(p < pe){
261                 if(cmd == 'r'){
262                         Bputc(bout, *p++);
263                         continue;
264                 }
265                 c = *p++;
266                 r = intab[c];
267                 if(r == '$')
268                         r = '\n';
269                 if(r == '\n'){
270                         ++lineno;
271                         if(cmd == 'h' && lineno > 2)
272                                 break;
273                 }
274                 if(cmd == 'h' && lineno < 2)
275                         continue;
276                 if(r > MULTIE){
277                         if(debug)
278                                 Bprint(bout, "\\%.2ux", c);
279                         continue;
280                 }
281                 if(r < Runeself)
282                         Bputc(bout, r);
283                 else
284                         Bputrune(bout, r);
285         }
286         outnl(0);
287 }
288
289 long
290 robertnextflex(long fromoff)
291 {
292         int c;
293
294         if(Bseek(bdict, fromoff, 0) < 0)
295                 return -1;
296         while((c = Bgetc(bdict)) >= 0){
297                 if(c == '$')
298                         return Boffset(bdict);
299         }
300         return -1;
301 }
302
303 static Biobuf *
304 Bouvrir(char *fichier)
305 {
306         Biobuf *db;
307
308         db = Bopen(fichier, OREAD);
309         if(db == 0){
310                 fprint(2, "%s: impossible d'ouvrir %s: %r\n", argv0, fichier);
311                 exits("ouvrir");
312         }
313         return db;
314 }