mirror of
https://github.com/9fans/plan9port.git
synced 2025-01-15 11:20:03 +00:00
203 lines
3.2 KiB
C
203 lines
3.2 KiB
C
#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;
|
|
}
|
|
}
|