]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/dict/slang.c
cc, ?[acl]: fix gethunk() and move common memory allocator code to cc/compat
[plan9front.git] / sys / src / cmd / dict / slang.c
1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include "dict.h"
5
6 /* Possible tags */
7 enum {
8         DF,             /* definition */
9         DX,             /* definition/example */
10         ET,             /* etymology */
11         EX,             /* example */
12         LA,             /* label */
13         ME,             /* main entry */
14         NU,             /* sense number */
15         PR,             /* pronunciation */
16         PS,             /* grammar part */
17         XR,             /* cross reference */
18         XX,             /* cross reference (whole entry) */
19 };
20
21 /* Assoc tables must be sorted on first field */
22
23 static Assoc tagtab[] = {
24         {"df",  DF},
25         {"dx",  DX},
26         {"et",  ET},
27         {"ex",  EX},
28         {"la",  LA},
29         {"me",  ME},
30         {"nu",  NU},
31         {"pr",  PR},
32         {"ps",  PS},
33         {"xr",  XR},
34         {"xx",  XX},
35 };
36 static long     sget(char *, char *, char **, char **);
37 static void     soutpiece(char *, char *);
38
39 void
40 slangprintentry(Entry e, int cmd)
41 {
42         char *p, *pe, *vs, *ve;
43         long t;
44
45         p = e.start;
46         pe = e.end;
47         if(cmd == 'h') {
48                 t = sget(p, pe, &vs, &ve);
49                 if(t == ME)
50                         soutpiece(vs, ve);
51                 outnl(0);
52                 return;
53         }
54         while(p < pe) {
55                 switch(sget(p, pe, &vs, &ve)) {
56                 case DF:
57                         soutpiece(vs, ve);
58                         outchars(".  ");
59                         break;
60                 case DX:
61                         soutpiece(vs, ve);
62                         outchars(".  ");
63                         break;
64                 case ET:
65                         outchars("[");
66                         soutpiece(vs, ve);
67                         outchars("] ");
68                         break;
69                 case EX:
70                         outchars("E.g., ");
71                         soutpiece(vs, ve);
72                         outchars(".  ");
73                         break;
74                 case LA:
75                         outchars("(");
76                         soutpiece(vs, ve);
77                         outchars(") ");
78                         break;
79                 case ME:
80                         outnl(0);
81                         soutpiece(vs, ve);
82                         outnl(0);
83                         break;
84                 case NU:
85                         outnl(2);
86                         soutpiece(vs, ve);
87                         outchars(".  ");
88                         break;
89                 case PR:
90                         outchars("[");
91                         soutpiece(vs, ve);
92                         outchars("] ");
93                         break;
94                 case PS:
95                         outnl(1);
96                         soutpiece(vs, ve);
97                         outchars(". ");
98                         break;
99                 case XR:
100                         outchars("See ");
101                         soutpiece(vs, ve);
102                         outchars(".  ");
103                         break;
104                 case XX:
105                         outchars("See ");
106                         soutpiece(vs, ve);
107                         outchars(".  ");
108                         break;
109                 default:
110                         ve = pe;        /* will end loop */
111                         break;
112                 }
113                 p = ve;
114         }
115         outnl(0);
116 }
117
118 long
119 slangnextoff(long fromoff)
120 {
121         long a;
122         char *p;
123
124         a = Bseek(bdict, fromoff, 0);
125         if(a < 0)
126                 return -1;
127         for(;;) {
128                 p = Brdline(bdict, '\n');
129                 if(!p)
130                         break;
131                 if(p[0] == 'm' && p[1] == 'e' && p[2] == ' ')
132                         return (Boffset(bdict)-Blinelen(bdict));
133         }
134         return -1;
135 }
136
137 void
138 slangprintkey(void)
139 {
140         Bprint(bout, "No key\n");
141 }
142
143 /*
144  * Starting from b, find next line beginning with a tag.
145  * Don't go past e, but assume *e==0.
146  * Return tag value, or -1 if no more tags before e.
147  * Set pvb to beginning of value (after tag).
148  * Set pve to point at newline that ends the value.
149  */
150 static long
151 sget(char *b, char *e, char **pvb, char **pve)
152 {
153         char *p;
154         char buf[3];
155         long t, tans;
156
157         buf[2] = 0;
158         tans = -1;
159         for(p = b;;) {
160                 if(p[2] == ' ') {
161                         buf[0] = p[0];
162                         buf[1] = p[1];
163                         t = lookassoc(tagtab, asize(tagtab), buf);
164                         if(t < 0) {
165                                 if(debug)
166                                         err("tag %s\n", buf);
167                                 p += 3;
168                         } else {
169                                 if(tans < 0) {
170                                         p += 3;
171                                         tans = t;
172                                         *pvb = p;
173                                 } else {
174                                         *pve = p;
175                                         break;
176                                 }
177                         }
178                 }
179                 p = strchr(p, '\n');
180                 if(!p || ++p >= e) {
181                         if(tans >= 0)
182                                 *pve = e-1;
183                         break;
184                 }
185         }
186         return tans;
187 }
188
189 static void
190 soutpiece(char *b, char *e)
191 {
192         int c, lastc;
193
194         lastc = 0;
195         while(b < e) {
196                 c = *b++;
197                 if(c == '\n')
198                         c = ' ';
199                 if(!(c == ' ' && lastc == ' ') && c != '@')
200                         outchar(c);
201                 lastc = c;
202         }
203 }