#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;
}
|