plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

slang.c (3227B)


      1 #include <u.h>
      2 #include <libc.h>
      3 #include <bio.h>
      4 #include "dict.h"
      5 
      6 /* Possible tags */
      7 enum {
      8 	DF,		/* definition */
      9 	DX,		/* definition/example */
     10 	ET,		/* etymology */
     11 	EX,		/* example */
     12 	LA,		/* label */
     13 	ME,		/* main entry */
     14 	NU,		/* sense number */
     15 	PR,		/* pronunciation */
     16 	PS,		/* grammar part */
     17 	XR,		/* cross reference */
     18 	XX		/* cross reference (whole entry) */
     19 };
     20 
     21 /* Assoc tables must be sorted on first field */
     22 
     23 static Assoc tagtab[] = {
     24 	{"df",	DF},
     25 	{"dx",	DX},
     26 	{"et",	ET},
     27 	{"ex",	EX},
     28 	{"la",	LA},
     29 	{"me",	ME},
     30 	{"nu",	NU},
     31 	{"pr",	PR},
     32 	{"ps",	PS},
     33 	{"xr",	XR},
     34 	{"xx",	XX}
     35 };
     36 static long	sget(char *, char *, char **, char **);
     37 static void	soutpiece(char *, char *);
     38 
     39 void
     40 slangprintentry(Entry e, int cmd)
     41 {
     42 	char *p, *pe, *vs, *ve;
     43 	long t;
     44 
     45 	p = e.start;
     46 	pe = e.end;
     47 	if(cmd == 'h') {
     48 		t = sget(p, pe, &vs, &ve);
     49 		if(t == ME)
     50 			soutpiece(vs, ve);
     51 		outnl(0);
     52 		return;
     53 	}
     54 	while(p < pe) {
     55 		switch(sget(p, pe, &vs, &ve)) {
     56 		case DF:
     57 			soutpiece(vs, ve);
     58 			outchars(".  ");
     59 			break;
     60 		case DX:
     61 			soutpiece(vs, ve);
     62 			outchars(".  ");
     63 			break;
     64 		case ET:
     65 			outchars("[");
     66 			soutpiece(vs, ve);
     67 			outchars("] ");
     68 			break;
     69 		case EX:
     70 			outchars("E.g., ");
     71 			soutpiece(vs, ve);
     72 			outchars(".  ");
     73 			break;
     74 		case LA:
     75 			outchars("(");
     76 			soutpiece(vs, ve);
     77 			outchars(") ");
     78 			break;
     79 		case ME:
     80 			outnl(0);
     81 			soutpiece(vs, ve);
     82 			outnl(0);
     83 			break;
     84 		case NU:
     85 			outnl(2);
     86 			soutpiece(vs, ve);
     87 			outchars(".  ");
     88 			break;
     89 		case PR:
     90 			outchars("[");
     91 			soutpiece(vs, ve);
     92 			outchars("] ");
     93 			break;
     94 		case PS:
     95 			outnl(1);
     96 			soutpiece(vs, ve);
     97 			outchars(". ");
     98 			break;
     99 		case XR:
    100 			outchars("See ");
    101 			soutpiece(vs, ve);
    102 			outchars(".  ");
    103 			break;
    104 		case XX:
    105 			outchars("See ");
    106 			soutpiece(vs, ve);
    107 			outchars(".  ");
    108 			break;
    109 		default:
    110 			ve = pe;	/* will end loop */
    111 			break;
    112 		}
    113 		p = ve;
    114 	}
    115 	outnl(0);
    116 }
    117 
    118 long
    119 slangnextoff(long fromoff)
    120 {
    121 	long a;
    122 	char *p;
    123 
    124 	a = Bseek(bdict, fromoff, 0);
    125 	if(a < 0)
    126 		return -1;
    127 	for(;;) {
    128 		p = Brdline(bdict, '\n');
    129 		if(!p)
    130 			break;
    131 		if(p[0] == 'm' && p[1] == 'e' && p[2] == ' ')
    132 			return (Boffset(bdict)-Blinelen(bdict));
    133 	}
    134 	return -1;
    135 }
    136 
    137 void
    138 slangprintkey(void)
    139 {
    140 	Bprint(bout, "No key\n");
    141 }
    142 
    143 /*
    144  * Starting from b, find next line beginning with a tag.
    145  * Don't go past e, but assume *e==0.
    146  * Return tag value, or -1 if no more tags before e.
    147  * Set pvb to beginning of value (after tag).
    148  * Set pve to point at newline that ends the value.
    149  */
    150 static long
    151 sget(char *b, char *e, char **pvb, char **pve)
    152 {
    153 	char *p;
    154 	char buf[3];
    155 	long t, tans;
    156 
    157 	buf[2] = 0;
    158 	tans = -1;
    159 	for(p = b;;) {
    160 		if(p[2] == ' ') {
    161 			buf[0] = p[0];
    162 			buf[1] = p[1];
    163 			t = lookassoc(tagtab, asize(tagtab), buf);
    164 			if(t < 0) {
    165 				if(debug)
    166 					err("tag %s\n", buf);
    167 				p += 3;
    168 			} else {
    169 				if(tans < 0) {
    170 					p += 3;
    171 					tans = t;
    172 					*pvb = p;
    173 				} else {
    174 					*pve = p;
    175 					break;
    176 				}
    177 			}
    178 		}
    179 		p = strchr(p, '\n');
    180 		if(!p || ++p >= e) {
    181 			if(tans >= 0)
    182 				*pve = e-1;
    183 			break;
    184 		}
    185 	}
    186 	return tans;
    187 }
    188 
    189 static void
    190 soutpiece(char *b, char *e)
    191 {
    192 	int c, lastc;
    193 
    194 	lastc = 0;
    195 	while(b < e) {
    196 		c = *b++;
    197 		if(c == '\n')
    198 			c = ' ';
    199 		if(!(c == ' ' && lastc == ' ') && c != '@')
    200 			outchar(c);
    201 		lastc = c;
    202 	}
    203 }