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 }