xref: /plan9/sys/src/cmd/dict/movie.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include "dict.h"
5 
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 };
36 
37 /* Assoc tables must be sorted on first field */
38 
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 };
67 
68 static char	*mget(int, char *, char *, char **);
69 static void	moutall(int, char *, char *);
70 static void	moutall2(int, char *, char *);
71 
72 void
movieprintentry(Entry ent,int cmd)73 movieprintentry(Entry ent, int cmd)
74 {
75 	char *p, *e, *ps, *pe, *pn;
76 	int n;
77 
78 	ps = ent.start;
79 	pe = ent.end;
80 	if(cmd == 'r') {
81 		Bwrite(bout, ps, pe-ps);
82 		return;
83 	}
84 	p = mget(TI, ps, pe, &e);
85 	if(p) {
86 		outpiece(p, e);
87 		outnl(0);
88 	}
89 	if(cmd == 'h')
90 		return;
91 	outnl(2);
92 	n = 0;
93 	p = mget(RD, ps, pe, &e);
94 	if(p) {
95 		outchars("Released: ");
96 		outpiece(p, e);
97 		n++;
98 	}
99 	p = mget(CO, ps, pe, &e);
100 	if(p) {
101 		if(n)
102 			outchars(", ");
103 		outpiece(p, e);
104 		n++;
105 	}
106 	p = mget(RT, ps, pe, &e);
107 	if(p) {
108 		if(n)
109 			outchars(", ");
110 		outchars("Running time: ");
111 		outpiece(p, e);
112 		n++;
113 	}
114 	p = mget(MP, ps, pe, &e);
115 	if(p) {
116 		if(n)
117 			outchars(", ");
118 		outpiece(p, e);
119 		n++;
120 	}
121 	p = mget(BW, ps, pe, &e);
122 	if(p) {
123 		if(n)
124 			outchars(", ");
125 		if(*p == 'c' || *p == 'C')
126 			outchars("Color");
127 		else
128 			outchars("B&W");
129 		n++;
130 	}
131 	if(n) {
132 		outchar('.');
133 		outnl(1);
134 	}
135 	p = mget(VD, ps, pe, &e);
136 	if(p) {
137 		outchars("Video: ");
138 		outpiece(p, e);
139 		outnl(1);
140 	}
141 	p = mget(AU, ps, pe, &e);
142 	if(p) {
143 		outchars("By: ");
144 		moutall2(AU, ps, pe);
145 		outnl(1);
146 	}
147 	p = mget(DR, ps, pe, &e);
148 	if(p) {
149 		outchars("Director: ");
150 		outpiece(p, e);
151 		outnl(1);
152 	}
153 	p = mget(PR, ps, pe, &e);
154 	if(p) {
155 		outchars("Producer: ");
156 		outpiece(p, e);
157 		outnl(1);
158 	}
159 	p = mget(CN, ps, pe, &e);
160 	if(p) {
161 		outchars("Cinematograpy: ");
162 		outpiece(p, e);
163 		outnl(1);
164 	}
165 	p = mget(CR, ps, pe, &e);
166 	if(p) {
167 		outchars("Other Credits: ");
168 		moutall2(CR, ps, pe);
169 	}
170 	outnl(2);
171 	p = mget(CA, ps, pe, &e);
172 	if(p) {
173 		outchars("Cast: ");
174 		moutall2(CA, ps, pe);
175 	}
176 	outnl(2);
177 	p = mget(AW, ps, pe, &e);
178 	if(p) {
179 		outchars("Awards: ");
180 		moutall2(AW, ps, pe);
181 		outnl(2);
182 	}
183 	p = mget(NT, ps, pe, &e);
184 	if(p) {
185 		outpiece(p, e);
186 		outnl(2);
187 	}
188 	p = mget(AB, ps, pe, &e);
189 	if(p) {
190 		outpiece(p, e);
191 		outnl(2);
192 	}
193 	pn = ps;
194 	n = 0;
195 	while((p = mget(TX, pn, pe, &pn)) != 0) {
196 		if(n++)
197 			outnl(1);
198 		outpiece(p, pn);
199 	}
200 	outnl(0);
201 }
202 
203 long
movienextoff(long fromoff)204 movienextoff(long fromoff)
205 {
206 	long a;
207 	char *p;
208 
209 	a = Bseek(bdict, fromoff, 0);
210 	if(a < 0)
211 		return -1;
212 	for(;;) {
213 		p = Brdline(bdict, '\n');
214 		if(!p)
215 			break;
216 		if(p[0] == '$' && p[1] == '$')
217 			return (Boffset(bdict)-Blinelen(bdict));
218 	}
219 	return -1;
220 }
221 
222 void
movieprintkey(void)223 movieprintkey(void)
224 {
225 	Bprint(bout, "No key\n");
226 }
227 
228 /*
229  * write a comma-separated list of all tag values between b and e
230  */
231 static void
moutall(int tag,char * b,char * e)232 moutall(int tag, char *b, char *e)
233 {
234 	char *p, *pn;
235 	int n;
236 
237 	n = 0;
238 	pn = b;
239 	while((p = mget(tag, pn, e, &pn)) != 0) {
240 		if(n++)
241 			outchars(", ");
242 		outpiece(p, pn);
243 	}
244 }
245 
246 /*
247  * like moutall, but values are expected to have form:
248  *    field1_field2
249  * and we are to output 'field2 (field1)' for each
250  * (sometimes field1 has underscores, so search from end)
251  */
252 static void
moutall2(int tag,char * b,char * e)253 moutall2(int tag, char *b, char *e)
254 {
255 	char *p, *pn, *us, *q;
256 	int n;
257 
258 	n = 0;
259 	pn = b;
260 	while((p = mget(tag, pn, e, &pn)) != 0) {
261 		if(n++)
262 			outchars(", ");
263 		us = 0;
264 		for(q = pn-1; q >= p; q--)
265 			if(*q == '_') {
266 				us = q;
267 				break;
268 			}
269 		if(us) {
270 			/*
271 			 * Hack to fix cast list Himself/Herself
272 			 */
273 			if(strncmp(us+1, "Himself", 7) == 0 ||
274 			   strncmp(us+1, "Herself", 7) == 0) {
275 				outpiece(p, us);
276 				outchars(" (");
277 				outpiece(us+1, pn);
278 				outchar(')');
279 			} else {
280 				outpiece(us+1, pn);
281 				outchars(" (");
282 				outpiece(p, us);
283 				outchar(')');
284 			}
285 		} else {
286 			outpiece(p, pn);
287 		}
288 	}
289 }
290 
291 /*
292  * Starting from b, find next line beginning with tagtab[tag].
293  * Don't go past e, but assume *e==0.
294  * Return pointer to beginning of value (after tag), and set
295  * eptr to point at newline that ends the value
296  */
297 static char *
mget(int tag,char * b,char * e,char ** eptr)298 mget(int tag, char *b, char *e, char **eptr)
299 {
300 	char *p, *t, *ans;
301 
302 	if(tag < 0 || tag >= NTAG)
303 		return 0;
304 	t = tagtab[tag];
305 	ans = 0;
306 	for(p = b;;) {
307 		p = strchr(p, '\n');
308 		if(!p || ++p >= e) {
309 			if(ans)
310 				*eptr = e-1;
311 			break;
312 		}
313 		if(!ans) {
314 			if(p[0] == t[0] && p[1] == t[1])
315 				ans = p+3;
316 		} else {
317 			if(p[0] != ' ') {
318 				*eptr = p-1;
319 				break;
320 			}
321 		}
322 	}
323 	return ans;
324 }
325