slang.c 3.6 KB

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