blob: 400019bcd977df3f3dfad8de72e1bfe56a15de99 [file] [log] [blame]
#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;
}
}