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