Subversion Repositories planix.SVN

Rev

Rev 2 | Blame | Compare with Previous | Last modification | View Log | RSS feed

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