plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

movie.c (5665B)


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