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 {
        DF,             /* definition */
        DX,             /* definition/example */
        ET,             /* etymology */
        EX,             /* example */
        LA,             /* label */
        ME,             /* main entry */
        NU,             /* sense number */
        PR,             /* pronunciation */
        PS,             /* grammar part */
        XR,             /* cross reference */
        XX,             /* cross reference (whole entry) */
};

/* Assoc tables must be sorted on first field */

static Assoc tagtab[] = {
        {"df",  DF},
        {"dx",  DX},
        {"et",  ET},
        {"ex",  EX},
        {"la",  LA},
        {"me",  ME},
        {"nu",  NU},
        {"pr",  PR},
        {"ps",  PS},
        {"xr",  XR},
        {"xx",  XX},
};
static long     sget(char *, char *, char **, char **);
static void     soutpiece(char *, char *);

void
slangprintentry(Entry e, int cmd)
{
        char *p, *pe, *vs, *ve;
        long t;

        p = e.start;
        pe = e.end;
        if(cmd == 'h') {
                t = sget(p, pe, &vs, &ve);
                if(t == ME)
                        soutpiece(vs, ve);
                outnl(0);
                return;
        }
        while(p < pe) {
                switch(sget(p, pe, &vs, &ve)) {
                case DF:
                        soutpiece(vs, ve);
                        outchars(".  ");
                        break;
                case DX:
                        soutpiece(vs, ve);
                        outchars(".  ");
                        break;
                case ET:
                        outchars("[");
                        soutpiece(vs, ve);
                        outchars("] ");
                        break;
                case EX:
                        outchars("E.g., ");
                        soutpiece(vs, ve);
                        outchars(".  ");
                        break;
                case LA:
                        outchars("(");
                        soutpiece(vs, ve);
                        outchars(") ");
                        break;
                case ME:
                        outnl(0);
                        soutpiece(vs, ve);
                        outnl(0);
                        break;
                case NU:
                        outnl(2);
                        soutpiece(vs, ve);
                        outchars(".  ");
                        break;
                case PR:
                        outchars("[");
                        soutpiece(vs, ve);
                        outchars("] ");
                        break;
                case PS:
                        outnl(1);
                        soutpiece(vs, ve);
                        outchars(". ");
                        break;
                case XR:
                        outchars("See ");
                        soutpiece(vs, ve);
                        outchars(".  ");
                        break;
                case XX:
                        outchars("See ");
                        soutpiece(vs, ve);
                        outchars(".  ");
                        break;
                default:
                        ve = pe;        /* will end loop */
                        break;
                }
                p = ve;
        }
        outnl(0);
}

long
slangnextoff(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] == 'm' && p[1] == 'e' && p[2] == ' ')
                        return (Boffset(bdict)-Blinelen(bdict));
        }
        return -1;
}

void
slangprintkey(void)
{
        Bprint(bout, "No key\n");
}

/*
 * Starting from b, find next line beginning with a tag.
 * Don't go past e, but assume *e==0.
 * Return tag value, or -1 if no more tags before e.
 * Set pvb to beginning of value (after tag).
 * Set pve to point at newline that ends the value.
 */
static long
sget(char *b, char *e, char **pvb, char **pve)
{
        char *p;
        char buf[3];
        long t, tans;

        buf[2] = 0;
        tans = -1;
        for(p = b;;) {
                if(p[2] == ' ') {
                        buf[0] = p[0];
                        buf[1] = p[1];
                        t = lookassoc(tagtab, asize(tagtab), buf);
                        if(t < 0) {
                                if(debug)
                                        err("tag %s\n", buf);
                                p += 3;
                        } else {
                                if(tans < 0) {
                                        p += 3;
                                        tans = t;
                                        *pvb = p;
                                } else {
                                        *pve = p;
                                        break;
                                }
                        }
                }
                p = strchr(p, '\n');
                if(!p || ++p >= e) {
                        if(tans >= 0)
                                *pve = e-1;
                        break;
                }
        }
        return tans;
}

static void
soutpiece(char *b, char *e)
{
        int c, lastc;

        lastc = 0;
        while(b < e) {
                c = *b++;
                if(c == '\n')
                        c = ' ';
                if(!(c == ' ' && lastc == ' ') && c != '@')
                        outchar(c);
                lastc = c;
        }
}