Blob


1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include "dict.h"
6 /* Possible tags */
7 enum {
8 BEG, /* beginning of entry */
9 AB, /* abstract */
10 AN, /* database serial number */
11 AS, /* author (one at a time) */
12 AU, /* all authors */
13 AW, /* award_awardee */
14 BW, /* bw or c */
15 CA, /* cast: character_actor */
16 CN, /* cinematography */
17 CO, /* country */
18 CR, /* miscellaneous job_name */
19 DE, /* topic keyword */
20 DR, /* director */
21 ED, /* editor */
22 MP, /* MPAA rating (R, PG, etc.) */
23 NT, /* note */
24 PR, /* producer and for ...*/
25 PS, /* producer (repeats info in PR) */
26 RA, /* rating (letter) */
27 RD, /* release date */
28 RT, /* running time */
29 RV, /* review citation */
30 ST, /* production or release company (repeats info in PR) */
31 TI, /* title[; original foreign title] */
32 TX, /* paragraph of descriptive text */
33 VD, /* video information (format_time_company; or "Not Avail.") */
34 NTAG /* number of tags */
35 };
37 /* Assoc tables must be sorted on first field */
39 static char *tagtab[] = {
40 [BEG] "$$",
41 [AB] "AB",
42 [AN] "AN",
43 [AS] "AS",
44 [AU] "AU",
45 [AW] "AW",
46 [BW] "BW",
47 [CA] "CA",
48 [CN] "CN",
49 [CO] "CO",
50 [CR] "CR",
51 [DE] "DE",
52 [DR] "DR",
53 [ED] "ED",
54 [MP] "MP",
55 [NT] "NT",
56 [PR] "PR",
57 [PS] "PS",
58 [RA] "RA",
59 [RD] "RD",
60 [RT] "RT",
61 [RV] "RV",
62 [ST] "ST",
63 [TI] "TI",
64 [TX] "TX",
65 [VD] "VD",
66 };
68 static char *mget(int, char *, char *, char **);
69 #if 0
70 static void moutall(int, char *, char *);
71 #endif
72 static void moutall2(int, char *, char *);
74 void
75 movieprintentry(Entry ent, int cmd)
76 {
77 char *p, *e, *ps, *pe, *pn;
78 int n;
80 ps = ent.start;
81 pe = ent.end;
82 if(cmd == 'r') {
83 Bwrite(bout, ps, pe-ps);
84 return;
85 }
86 p = mget(TI, ps, pe, &e);
87 if(p) {
88 outpiece(p, e);
89 outnl(0);
90 }
91 if(cmd == 'h')
92 return;
93 outnl(2);
94 n = 0;
95 p = mget(RD, ps, pe, &e);
96 if(p) {
97 outchars("Released: ");
98 outpiece(p, e);
99 n++;
101 p = mget(CO, ps, pe, &e);
102 if(p) {
103 if(n)
104 outchars(", ");
105 outpiece(p, e);
106 n++;
108 p = mget(RT, ps, pe, &e);
109 if(p) {
110 if(n)
111 outchars(", ");
112 outchars("Running time: ");
113 outpiece(p, e);
114 n++;
116 p = mget(MP, ps, pe, &e);
117 if(p) {
118 if(n)
119 outchars(", ");
120 outpiece(p, e);
121 n++;
123 p = mget(BW, ps, pe, &e);
124 if(p) {
125 if(n)
126 outchars(", ");
127 if(*p == 'c' || *p == 'C')
128 outchars("Color");
129 else
130 outchars("B&W");
131 n++;
133 if(n) {
134 outchar('.');
135 outnl(1);
137 p = mget(VD, ps, pe, &e);
138 if(p) {
139 outchars("Video: ");
140 outpiece(p, e);
141 outnl(1);
143 p = mget(AU, ps, pe, &e);
144 if(p) {
145 outchars("By: ");
146 moutall2(AU, ps, pe);
147 outnl(1);
149 p = mget(DR, ps, pe, &e);
150 if(p) {
151 outchars("Director: ");
152 outpiece(p, e);
153 outnl(1);
155 p = mget(PR, ps, pe, &e);
156 if(p) {
157 outchars("Producer: ");
158 outpiece(p, e);
159 outnl(1);
161 p = mget(CN, ps, pe, &e);
162 if(p) {
163 outchars("Cinematograpy: ");
164 outpiece(p, e);
165 outnl(1);
167 p = mget(CR, ps, pe, &e);
168 if(p) {
169 outchars("Other Credits: ");
170 moutall2(CR, ps, pe);
172 outnl(2);
173 p = mget(CA, ps, pe, &e);
174 if(p) {
175 outchars("Cast: ");
176 moutall2(CA, ps, pe);
178 outnl(2);
179 p = mget(AW, ps, pe, &e);
180 if(p) {
181 outchars("Awards: ");
182 moutall2(AW, ps, pe);
183 outnl(2);
185 p = mget(NT, ps, pe, &e);
186 if(p) {
187 outpiece(p, e);
188 outnl(2);
190 p = mget(AB, ps, pe, &e);
191 if(p) {
192 outpiece(p, e);
193 outnl(2);
195 pn = ps;
196 n = 0;
197 while((p = mget(TX, pn, pe, &pn)) != 0) {
198 if(n++)
199 outnl(1);
200 outpiece(p, pn);
202 outnl(0);
205 long
206 movienextoff(long fromoff)
208 long a;
209 char *p;
211 a = Bseek(bdict, fromoff, 0);
212 if(a < 0)
213 return -1;
214 for(;;) {
215 p = Brdline(bdict, '\n');
216 if(!p)
217 break;
218 if(p[0] == '$' && p[1] == '$')
219 return (Boffset(bdict)-Blinelen(bdict));
221 return -1;
224 void
225 movieprintkey(void)
227 Bprint(bout, "No key\n");
230 /*
231 * write a comma-separated list of all tag values between b and e
232 */
233 #if 0
234 static void
235 moutall(int tag, char *b, char *e)
237 char *p, *pn;
238 int n;
240 n = 0;
241 pn = b;
242 while((p = mget(tag, pn, e, &pn)) != 0) {
243 if(n++)
244 outchars(", ");
245 outpiece(p, pn);
248 #endif
250 /*
251 * like moutall, but values are expected to have form:
252 * field1_field2
253 * and we are to output 'field2 (field1)' for each
254 * (sometimes field1 has underscores, so search from end)
255 */
256 static void
257 moutall2(int tag, char *b, char *e)
259 char *p, *pn, *us, *q;
260 int n;
262 n = 0;
263 pn = b;
264 while((p = mget(tag, pn, e, &pn)) != 0) {
265 if(n++)
266 outchars(", ");
267 us = 0;
268 for(q = pn-1; q >= p; q--)
269 if(*q == '_') {
270 us = q;
271 break;
273 if(us) {
274 /*
275 * Hack to fix cast list Himself/Herself
276 */
277 if(strncmp(us+1, "Himself", 7) == 0 ||
278 strncmp(us+1, "Herself", 7) == 0) {
279 outpiece(p, us);
280 outchars(" (");
281 outpiece(us+1, pn);
282 outchar(')');
283 } else {
284 outpiece(us+1, pn);
285 outchars(" (");
286 outpiece(p, us);
287 outchar(')');
289 } else {
290 outpiece(p, pn);
295 /*
296 * Starting from b, find next line beginning with tagtab[tag].
297 * Don't go past e, but assume *e==0.
298 * Return pointer to beginning of value (after tag), and set
299 * eptr to point at newline that ends the value
300 */
301 static char *
302 mget(int tag, char *b, char *e, char **eptr)
304 char *p, *t, *ans;
306 if(tag < 0 || tag >= NTAG)
307 return 0;
308 t = tagtab[tag];
309 ans = 0;
310 for(p = b;;) {
311 p = strchr(p, '\n');
312 if(!p || ++p >= e) {
313 if(ans)
314 *eptr = e-1;
315 break;
317 if(!ans) {
318 if(p[0] == t[0] && p[1] == t[1])
319 ans = p+3;
320 } else {
321 if(p[0] != ' ') {
322 *eptr = p-1;
323 break;
327 return ans;