Blob
1 #include <u.h>2 #include <libc.h>3 #include <bio.h>4 #include "dict.h"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 };37 /* Assoc tables must be sorted on first field */39 static char *tagtab[NTAG];41 static void42 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 }72 static char *mget(int, char *, char *, char **);73 #if 074 static void moutall(int, char *, char *);75 #endif76 static void moutall2(int, char *, char *);78 void79 movieprintentry(Entry ent, int cmd)80 {81 char *p, *e, *ps, *pe, *pn;82 int n;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 else134 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 }209 long210 movienextoff(long fromoff)211 {212 long a;213 char *p;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 }228 void229 movieprintkey(void)230 {231 Bprint(bout, "No key\n");232 }234 /*235 * write a comma-separated list of all tag values between b and e236 */237 #if 0238 static void239 moutall(int tag, char *b, char *e)240 {241 char *p, *pn;242 int n;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 #endif254 /*255 * like moutall, but values are expected to have form:256 * field1_field2257 * and we are to output 'field2 (field1)' for each258 * (sometimes field1 has underscores, so search from end)259 */260 static void261 moutall2(int tag, char *b, char *e)262 {263 char *p, *pn, *us, *q;264 int n;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/Herself280 */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 }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 set303 * eptr to point at newline that ends the value304 */305 static char *306 mget(int tag, char *b, char *e, char **eptr)307 {308 char *p, *t, *ans;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 }