xref: /plan9/sys/src/cmd/dict/movie.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
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