ahd.c 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <bio.h>
  4. #include "dict.h"
  5. /*
  6. * American Heritage Dictionary (encrypted)
  7. */
  8. static Rune intab[256] = {
  9. [0x82] L'é',
  10. [0x85] L'à',
  11. [0x89] L'ë',
  12. [0x8a] L'è',
  13. [0xa4] L'ñ',
  14. [0xf8] L'°',
  15. [0xf9] L'·',
  16. };
  17. static char tag[64];
  18. enum{
  19. Run, Openper, Openat, Closeat
  20. };
  21. void
  22. ahdprintentry(Entry e, int cmd)
  23. {
  24. static int inited;
  25. long addr;
  26. char *p, *t = tag;
  27. int obreaklen;
  28. int c, state = Run;
  29. if(!inited){
  30. for(c=0; c<256; c++)
  31. if(intab[c] == 0)
  32. intab[c] = c;
  33. inited = 1;
  34. }
  35. obreaklen = breaklen;
  36. breaklen = 80;
  37. addr = e.doff;
  38. for(p=e.start; p<e.end; p++){
  39. c = intab[(*p ^ (addr++>>1))&0xff];
  40. switch(state){
  41. case Run:
  42. if(c == '%'){
  43. t = tag;
  44. state = Openper;
  45. break;
  46. }
  47. Putchar:
  48. if(c == '\n')
  49. outnl(0);
  50. else if(c < Runeself)
  51. outchar(c);
  52. else
  53. outrune(c);
  54. break;
  55. case Openper:
  56. if(c == '@')
  57. state = Openat;
  58. else{
  59. outchar('%');
  60. state = Run;
  61. goto Putchar;
  62. }
  63. break;
  64. case Openat:
  65. if(c == '@')
  66. state = Closeat;
  67. else if(t < &tag[sizeof tag-1])
  68. *t++ = c;
  69. break;
  70. case Closeat:
  71. if(c == '%'){
  72. *t = 0;
  73. switch(cmd){
  74. case 'h':
  75. if(strcmp("EH", tag) == 0)
  76. goto out;
  77. break;
  78. case 'r':
  79. outprint("%%@%s@%%", tag);
  80. break;
  81. }
  82. state = Run;
  83. }else{
  84. if(t < &tag[sizeof tag-1])
  85. *t++ = '@';
  86. if(t < &tag[sizeof tag-1])
  87. *t++ = c;
  88. state = Openat;
  89. }
  90. break;
  91. }
  92. }
  93. out:
  94. outnl(0);
  95. breaklen = obreaklen;
  96. }
  97. long
  98. ahdnextoff(long fromoff)
  99. {
  100. static char *patterns[] = { "%@NL@%", "%@2@%", 0 };
  101. int c, k = 0, state = 0;
  102. char *pat = patterns[0];
  103. long defoff = -1;
  104. if(Bseek(bdict, fromoff, 0) < 0)
  105. return -1;
  106. while((c = Bgetc(bdict)) >= 0){
  107. c ^= (fromoff++>>1)&0xff;
  108. if(c != pat[state]){
  109. state = 0;
  110. continue;
  111. }
  112. if(pat[++state])
  113. continue;
  114. if(pat = patterns[++k]){ /* assign = */
  115. state = 0;
  116. defoff = fromoff-6;
  117. continue;
  118. }
  119. return fromoff-5;
  120. }
  121. return defoff;
  122. }
  123. void
  124. ahdprintkey(void)
  125. {
  126. Bprint(bout, "No pronunciations.\n");
  127. }