Blob
1 #include <u.h>2 #include <libc.h>3 #include <bio.h>4 #include "dict.h"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 };21 /* Assoc tables must be sorted on first field */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 *);39 void40 slangprintentry(Entry e, int cmd)41 {42 char *p, *pe, *vs, *ve;43 long t;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 }118 long119 slangnextoff(long fromoff)120 {121 long a;122 char *p;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 }137 void138 slangprintkey(void)139 {140 Bprint(bout, "No key\n");141 }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 long151 sget(char *b, char *e, char **pvb, char **pve)152 {153 char *p;154 char buf[3];155 long t, tans;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 }189 static void190 soutpiece(char *b, char *e)191 {192 int c, lastc;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 }