tune.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <bio.h>
  4. #include "hdr.h"
  5. #include "conv.h"
  6. typedef struct Tmap Tmap;
  7. struct Tmap
  8. {
  9. Rune u;
  10. Rune t;
  11. };
  12. static Tmap t1[] =
  13. {
  14. {0x0b85/*அ*/, 0xe201/**/},
  15. {0x0b86/*ஆ*/, 0xe202/**/},
  16. {0x0b87/*இ*/, 0xe203/**/},
  17. {0x0b88/*ஈ*/, 0xe204/**/},
  18. {0x0b89/*உ*/, 0xe205/**/},
  19. {0x0b8a/*ஊ*/, 0xe206/**/},
  20. {0x0b8e/*எ*/, 0xe207/**/},
  21. {0x0b8f/*ஏ*/, 0xe208/**/},
  22. {0x0b90/*ஐ*/, 0xe209/**/},
  23. {0x0b92/*ஒ*/, 0xe20a/**/},
  24. {0x0b93/*ஓ*/, 0xe20b/**/},
  25. {0x0b94/*ஔ*/, 0xe20c/**/},
  26. {0x0b83/*ஃ*/, 0xe20d/**/}
  27. };
  28. static Rune t2[] =
  29. {
  30. 0x0bcd/*்*/,
  31. 0x0bcd/*்*/, // filler
  32. 0x0bbe/*ா*/,
  33. 0x0bbf/*ி*/,
  34. 0x0bc0/*ீ*/,
  35. 0x0bc1/*ு*/,
  36. 0x0bc2/*ூ*/,
  37. 0x0bc6/*ெ*/,
  38. 0x0bc7/*ே*/,
  39. 0x0bc8/*ை*/,
  40. 0x0bca/*ொ*/,
  41. 0x0bcb/*ோ*/,
  42. 0x0bcc/*ௌ*/
  43. };
  44. static Tmap t3[] =
  45. {
  46. {0x0b95/*க*/, 0xe211/**/},
  47. {0x0b99/*ங*/, 0xe221/**/},
  48. {0x0b9a/*ச*/, 0xe231/**/},
  49. {0x0b9c/*ஜ*/, 0xe331/**/},
  50. {0x0b9e/*ஞ*/, 0xe241/**/},
  51. {0x0b9f/*ட*/, 0xe251/**/},
  52. {0x0ba3/*ண*/, 0xe261/**/},
  53. {0x0ba4/*த*/, 0xe271/**/},
  54. {0x0ba8/*ந*/, 0xe281/**/},
  55. {0x0ba9/*ன*/, 0xe321/**/},
  56. {0x0baa/*ப*/, 0xe291/**/},
  57. {0x0bae/*ம*/, 0xe2a1/**/},
  58. {0x0baf/*ய*/, 0xe2b1/**/},
  59. {0x0bb0/*ர*/, 0xe2c1/**/},
  60. {0x0bb1/*ற*/, 0xe311/**/},
  61. {0x0bb2/*ல*/, 0xe2d1/**/},
  62. {0x0bb3/*ள*/, 0xe301/**/},
  63. {0x0bb4/*ழ*/, 0xe2f1/**/},
  64. {0x0bb5/*வ*/, 0xe2e1/**/},
  65. {0x0bb6/*ஶ*/, 0xe341/**/},
  66. {0x0bb7/*ஷ*/, 0xe351/**/},
  67. {0x0bb8/*ஸ*/, 0xe361/**/},
  68. {0x0bb9/*ஹ*/, 0xe371/**/}
  69. };
  70. static Rune
  71. findbytune(Tmap *tab, int size, Rune t)
  72. {
  73. int i;
  74. for(i = 0; i < size; i++)
  75. if(tab[i].t == t)
  76. return tab[i].u;
  77. return Runeerror;
  78. }
  79. static Rune
  80. findbyuni(Tmap *tab, int size, Rune u)
  81. {
  82. int i;
  83. for(i = 0; i < size; i++)
  84. if(tab[i].u == u)
  85. return tab[i].t;
  86. return Runeerror;
  87. }
  88. static int
  89. findindex(Rune *rstr, int size, Rune r)
  90. {
  91. int i;
  92. for(i = 0; i < size; i++)
  93. if(rstr[i] == r)
  94. return i;
  95. return -1;
  96. }
  97. void
  98. tune_in(int fd, long *x, struct convert *out)
  99. {
  100. Biobuf b;
  101. Rune rbuf[N];
  102. Rune *r, *er, tr;
  103. int c, i;
  104. USED(x);
  105. r = rbuf;
  106. er = rbuf+N-3;
  107. Binit(&b, fd, OREAD);
  108. while((c = Bgetrune(&b)) != Beof){
  109. ninput += b.runesize;
  110. if(r >= er){
  111. OUT(out, rbuf, r-rbuf);
  112. r = rbuf;
  113. }
  114. if(c>=0xe210/**/ && c <= 0xe38c/**/ && (i = c%16) < nelem(t2)){
  115. if(c >= 0xe380/**/){
  116. *r++ = 0x0b95/*க*/;
  117. *r++ = 0x0bcd/*்*/;
  118. *r++ = 0x0bb7/*ஷ*/;
  119. }else
  120. *r++ = findbytune(t3, nelem(t3), c-i+1);
  121. if(i != 1)
  122. *r++ = t2[i];
  123. }else if((tr = findbytune(t1, nelem(t1), c)) != Runeerror)
  124. *r++ = tr;
  125. else switch(c){
  126. case 0xe3d0/**/:
  127. *r++ = 0x0ba3/*ண*/; *r++ = 0x0bbe/*ா*/;
  128. break;
  129. case 0xe3d1/**/:
  130. *r++ = 0x0bb1/*ற*/; *r++ = 0x0bbe/*ா*/;
  131. break;
  132. case 0xe3d2/**/:
  133. *r++ = 0x0ba9/*ன*/; *r++ = 0x0bbe/*ா*/;
  134. break;
  135. case 0xe3d4/**/:
  136. *r++ = 0x0ba3/*ண*/; *r++ = 0x0bc8/*ை*/;
  137. break;
  138. case 0xe3d5/**/:
  139. *r++ = 0x0bb2/*ல*/; *r++ = 0x0bc8/*ை*/;
  140. break;
  141. case 0xe3d6/**/:
  142. *r++ = 0x0bb3/*ள*/; *r++ = 0x0bc8/*ை*/;
  143. break;
  144. case 0xe3d7/**/:
  145. *r++ = 0x0ba9/*ன*/; *r++ = 0x0bc8/*ை*/;
  146. break;
  147. case 0xe38d/**/:
  148. *r++ = 0x0bb6/*ஶ*/; *r++ = 0x0bcd/*்*/; *r++ = 0x0bb0/*ர*/; *r++ = 0x0bc0/*ீ*/;
  149. break;
  150. default:
  151. if(c >= 0xe200 && c <= 0xe3ff){
  152. if(squawk)
  153. EPR "%s: rune 0x%x not in output cs\n", argv0, c);
  154. nerrors++;
  155. if(clean)
  156. break;
  157. c = BADMAP;
  158. }
  159. *r++ = c;
  160. break;
  161. }
  162. }
  163. if(r > rbuf)
  164. OUT(out, rbuf, r-rbuf);
  165. OUT(out, rbuf, 0);
  166. }
  167. void
  168. tune_out(Rune *r, int n, long *x)
  169. {
  170. static int state = 0;
  171. static Rune lastr;
  172. Rune *er, tr, rr;
  173. char *p;
  174. int i;
  175. USED(x);
  176. nrunes += n;
  177. er = r+n;
  178. for(p = obuf; r < er; r++){
  179. switch(state){
  180. case 0:
  181. case0:
  182. if((tr = findbyuni(t3, nelem(t3), *r)) != Runeerror){
  183. lastr = tr;
  184. state = 1;
  185. }else if(*r == 0x0b92/*ஒ*/){
  186. lastr = 0xe20a/**/;
  187. state = 3;
  188. }else if((tr = findbyuni(t1, nelem(t1), *r)) != Runeerror)
  189. p += runetochar(p, &tr);
  190. else
  191. p += runetochar(p, r);
  192. break;
  193. case 1:
  194. case1:
  195. if((i = findindex(t2, nelem(t2), *r)) != -1){
  196. if(lastr && lastr != Runeerror)
  197. lastr += i-1;
  198. if(*r ==0x0bc6/*ெ*/)
  199. state = 5;
  200. else if(*r ==0x0bc7/*ே*/)
  201. state = 4;
  202. else if(lastr == 0xe210/**/)
  203. state = 2;
  204. else if(lastr == 0xe340/**/)
  205. state = 6;
  206. else{
  207. if(lastr)
  208. p += runetochar(p, &lastr);
  209. state = 0;
  210. }
  211. }else if(lastr && lastr != Runeerror && (*r == 0x00b2/*²*/ || *r == 0x00b3/*³*/ || *r == 0x2074/*⁴*/)){
  212. if(squawk)
  213. EPR "%s: character <U+%.4X, U+%.4X> not in output cs\n", argv0, lastr, *r);
  214. lastr = clean ? 0 : Runeerror;
  215. nerrors++;
  216. }else{
  217. if(lastr)
  218. p += runetochar(p, &lastr);
  219. state = 0;
  220. goto case0;
  221. }
  222. break;
  223. case 2:
  224. if(*r == 0x0bb7/*ஷ*/){
  225. lastr = 0xe381/**/;
  226. state = 1;
  227. break;
  228. }
  229. p += runetochar(p, &lastr);
  230. state = 0;
  231. goto case0;
  232. case 3:
  233. state = 0;
  234. if(*r == 0x0bd7/*ௗ*/){
  235. rr = 0xe20c/**/;
  236. p += runetochar(p, &rr);
  237. break;
  238. }
  239. p += runetochar(p, &lastr);
  240. goto case0;
  241. case 4:
  242. state = 0;
  243. if(*r == 0x0bbe/*ா*/){
  244. if(lastr){
  245. if(lastr != Runeerror)
  246. lastr += 3;
  247. p += runetochar(p, &lastr);
  248. }
  249. break;
  250. }
  251. if(lastr)
  252. p += runetochar(p, &lastr);
  253. goto case0;
  254. case 5:
  255. state = 0;
  256. if(*r == 0x0bbe/*ா*/ || *r == 0x0bd7/*ௗ*/){
  257. if(lastr){
  258. if(lastr != Runeerror)
  259. lastr += *r == 0x0bbe/*ா*/ ? 3 : 5;
  260. p += runetochar(p, &lastr);
  261. }
  262. break;
  263. }
  264. if(lastr)
  265. p += runetochar(p, &lastr);
  266. goto case0;
  267. case 6:
  268. if(*r == 0x0bb0/*ர*/){
  269. state = 7;
  270. break;
  271. }
  272. p += runetochar(p, &lastr);
  273. state = 0;
  274. goto case0;
  275. case 7:
  276. if(*r == 0x0bc0/*ீ*/){
  277. rr = 0xe38d/**/;
  278. p += runetochar(p, &rr);
  279. state = 0;
  280. break;
  281. }
  282. p += runetochar(p, &lastr);
  283. lastr = 0xe2c1/**/;
  284. state = 1;
  285. goto case1;
  286. }
  287. }
  288. if(n == 0 && state != 0){
  289. if(lastr)
  290. p += runetochar(p, &lastr);
  291. state = 0;
  292. }
  293. noutput += p-obuf;
  294. write(1, obuf, p-obuf);
  295. }