Blob


1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include "dict.h"
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 };
21 /* Assoc tables must be sorted on first field */
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 *);
39 void
40 slangprintentry(Entry e, int cmd)
41 {
42 char *p, *pe, *vs, *ve;
43 long t;
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;
113 p = ve;
115 outnl(0);
118 long
119 slangnextoff(long fromoff)
121 long a;
122 char *p;
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));
134 return -1;
137 void
138 slangprintkey(void)
140 Bprint(bout, "No key\n");
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)
153 char *p;
154 char buf[3];
155 long t, tans;
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;
179 p = strchr(p, '\n');
180 if(!p || ++p >= e) {
181 if(tans >= 0)
182 *pve = e-1;
183 break;
186 return tans;
189 static void
190 soutpiece(char *b, char *e)
192 int c, lastc;
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;