ref: a291bbdeddfd41a2f0907ecbd7b819f0eedffdaf
dir: /sys/src/cmd/dict/movie.c/
#include <u.h> #include <libc.h> #include <bio.h> #include "dict.h" /* Possible tags */ enum { BEG, /* beginning of entry */ AB, /* abstract */ AN, /* database serial number */ AS, /* author (one at a time) */ AU, /* all authors */ AW, /* award_awardee */ BW, /* bw or c */ CA, /* cast: character_actor */ CN, /* cinematography */ CO, /* country */ CR, /* miscellaneous job_name */ DE, /* topic keyword */ DR, /* director */ ED, /* editor */ MP, /* MPAA rating (R, PG, etc.) */ NT, /* note */ PR, /* producer and for ...*/ PS, /* producer (repeats info in PR) */ RA, /* rating (letter) */ RD, /* release date */ RT, /* running time */ RV, /* review citation */ ST, /* production or release company (repeats info in PR) */ TI, /* title[; original foreign title] */ TX, /* paragraph of descriptive text */ VD, /* video information (format_time_company; or "Not Avail.") */ NTAG /* number of tags */ }; /* Assoc tables must be sorted on first field */ static char *tagtab[] = { [BEG] "$$", [AB] "AB", [AN] "AN", [AS] "AS", [AU] "AU", [AW] "AW", [BW] "BW", [CA] "CA", [CN] "CN", [CO] "CO", [CR] "CR", [DE] "DE", [DR] "DR", [ED] "ED", [MP] "MP", [NT] "NT", [PR] "PR", [PS] "PS", [RA] "RA", [RD] "RD", [RT] "RT", [RV] "RV", [ST] "ST", [TI] "TI", [TX] "TX", [VD] "VD", }; static char *mget(int, char *, char *, char **); static void moutall(int, char *, char *); static void moutall2(int, char *, char *); void movieprintentry(Entry ent, int cmd) { char *p, *e, *ps, *pe, *pn; int n; ps = ent.start; pe = ent.end; if(cmd == 'r') { Bwrite(bout, ps, pe-ps); return; } p = mget(TI, ps, pe, &e); if(p) { outpiece(p, e); outnl(0); } if(cmd == 'h') return; outnl(2); n = 0; p = mget(RD, ps, pe, &e); if(p) { outchars("Released: "); outpiece(p, e); n++; } p = mget(CO, ps, pe, &e); if(p) { if(n) outchars(", "); outpiece(p, e); n++; } p = mget(RT, ps, pe, &e); if(p) { if(n) outchars(", "); outchars("Running time: "); outpiece(p, e); n++; } p = mget(MP, ps, pe, &e); if(p) { if(n) outchars(", "); outpiece(p, e); n++; } p = mget(BW, ps, pe, &e); if(p) { if(n) outchars(", "); if(*p == 'c' || *p == 'C') outchars("Color"); else outchars("B&W"); n++; } if(n) { outchar('.'); outnl(1); } p = mget(VD, ps, pe, &e); if(p) { outchars("Video: "); outpiece(p, e); outnl(1); } p = mget(AU, ps, pe, &e); if(p) { outchars("By: "); moutall2(AU, ps, pe); outnl(1); } p = mget(DR, ps, pe, &e); if(p) { outchars("Director: "); outpiece(p, e); outnl(1); } p = mget(PR, ps, pe, &e); if(p) { outchars("Producer: "); outpiece(p, e); outnl(1); } p = mget(CN, ps, pe, &e); if(p) { outchars("Cinematograpy: "); outpiece(p, e); outnl(1); } p = mget(CR, ps, pe, &e); if(p) { outchars("Other Credits: "); moutall2(CR, ps, pe); } outnl(2); p = mget(CA, ps, pe, &e); if(p) { outchars("Cast: "); moutall2(CA, ps, pe); } outnl(2); p = mget(AW, ps, pe, &e); if(p) { outchars("Awards: "); moutall2(AW, ps, pe); outnl(2); } p = mget(NT, ps, pe, &e); if(p) { outpiece(p, e); outnl(2); } p = mget(AB, ps, pe, &e); if(p) { outpiece(p, e); outnl(2); } pn = ps; n = 0; while((p = mget(TX, pn, pe, &pn)) != 0) { if(n++) outnl(1); outpiece(p, pn); } outnl(0); } long movienextoff(long fromoff) { long a; char *p; a = Bseek(bdict, fromoff, 0); if(a < 0) return -1; for(;;) { p = Brdline(bdict, '\n'); if(!p) break; if(p[0] == '$' && p[1] == '$') return (Boffset(bdict)-Blinelen(bdict)); } return -1; } void movieprintkey(void) { Bprint(bout, "No key\n"); } /* * write a comma-separated list of all tag values between b and e */ static void moutall(int tag, char *b, char *e) { char *p, *pn; int n; n = 0; pn = b; while((p = mget(tag, pn, e, &pn)) != 0) { if(n++) outchars(", "); outpiece(p, pn); } } /* * like moutall, but values are expected to have form: * field1_field2 * and we are to output 'field2 (field1)' for each * (sometimes field1 has underscores, so search from end) */ static void moutall2(int tag, char *b, char *e) { char *p, *pn, *us, *q; int n; n = 0; pn = b; while((p = mget(tag, pn, e, &pn)) != 0) { if(n++) outchars(", "); us = 0; for(q = pn-1; q >= p; q--) if(*q == '_') { us = q; break; } if(us) { /* * Hack to fix cast list Himself/Herself */ if(strncmp(us+1, "Himself", 7) == 0 || strncmp(us+1, "Herself", 7) == 0) { outpiece(p, us); outchars(" ("); outpiece(us+1, pn); outchar(')'); } else { outpiece(us+1, pn); outchars(" ("); outpiece(p, us); outchar(')'); } } else { outpiece(p, pn); } } } /* * Starting from b, find next line beginning with tagtab[tag]. * Don't go past e, but assume *e==0. * Return pointer to beginning of value (after tag), and set * eptr to point at newline that ends the value */ static char * mget(int tag, char *b, char *e, char **eptr) { char *p, *t, *ans; if(tag < 0 || tag >= NTAG) return 0; t = tagtab[tag]; ans = 0; for(p = b;;) { p = strchr(p, '\n'); if(!p || ++p >= e) { if(ans) *eptr = e-1; break; } if(!ans) { if(p[0] == t[0] && p[1] == t[1]) ans = p+3; } else { if(p[0] != ' ') { *eptr = p-1; break; } } } return ans; }