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