URI:
       tconv_ksc.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
       ---
       tconv_ksc.c (2733B)
       ---
            1 #ifdef        PLAN9
            2 #include        <u.h>
            3 #include        <libc.h>
            4 #include        <bio.h>
            5 #else
            6 #include        <stdio.h>
            7 #include        <unistd.h>
            8 #include        "plan9.h"
            9 #endif
           10 #include        "hdr.h"
           11 #include        "conv.h"
           12 #include        "ksc.h"
           13 
           14 /*
           15         contributed by kuro@vodka.Eng.Sun.COM (Teruhiko Kurosaka)
           16 */
           17 
           18 /*
           19         a state machine for interpreting shift-ksc.
           20 */
           21 
           22 #define        SS2        0x8e
           23 #define        SS3        0x8f
           24 /*
           25  * Convert EUC in Koran locale to Unicode.
           26  * Only codeset 0 and 1 are used.
           27  */
           28 void
           29 ukscproc(int c, Rune **r, long input_loc)
           30 {
           31         static enum { init, cs1last /*, cs2, cs3first, cs3last*/} state = init;
           32         static int korean646 = 1; /* fixed to 1 for now. */
           33         static int lastc;
           34         int n;
           35         long l;
           36 
           37         switch(state)
           38         {
           39         case init:
           40                 if (c < 0){
           41                         return;
           42                 }else if (c < 128){
           43                         if(korean646 && (c=='\\')){
           44                                 emit(0x20A9);
           45                         } else {
           46                                 emit(c);
           47                         }
           48 /*                }else if (c==SS2){
           49                         state = cs2;
           50                 }else if (c==SS3){
           51                         state = cs3first;
           52  */                }else{
           53                         lastc = c;
           54                         state = cs1last;
           55                 }
           56                 return;
           57 
           58         case cs1last: /* 2nd byte of codeset 1 (KSC 5601) */
           59                 if(c < 0){
           60                         if(squawk)
           61                                 EPR "%s: unexpected EOF in %s\n", argv0, file);
           62                         c = 0x21 | (lastc&0x80);
           63                 }
           64                 n = ((lastc&0x7f)-33)*94 + (c&0x7f)-33;
           65                  if((n >= ksc5601max) || ((l = tabksc5601[n]) < 0)){
           66                         nerrors++;
           67                         if(squawk)
           68                                 EPR "%s: unknown ksc5601 %d (from 0x%x,0x%x) near byte %ld in %s\n", argv0, n, lastc, c, input_loc, file);
           69                         if(!clean)
           70                                 emit(BADMAP);
           71                 } else {
           72                         emit(l);
           73                 }
           74                 state = init;
           75                 return;
           76         default:
           77                 if(squawk)
           78                         EPR "%s: ukscproc: unknown state %d\n",
           79                                 argv0, init);
           80         }
           81 }
           82 
           83 void
           84 uksc_in(int fd, long *notused, struct convert *out)
           85 {
           86         Rune ob[N];
           87         Rune *r, *re;
           88         uchar ibuf[N];
           89         int n, i;
           90         long nin;
           91 
           92         USED(notused);
           93         r = ob;
           94         re = ob+N-3;
           95         nin = 0;
           96         while((n = read(fd, ibuf, sizeof ibuf)) > 0){
           97                 for(i = 0; i < n; i++){
           98                         ukscproc(ibuf[i], &r, nin++);
           99                         if(r >= re){
          100                                 OUT(out, ob, r-ob);
          101                                 r = ob;
          102                         }
          103                 }
          104                 if(r > ob){
          105                         OUT(out, ob, r-ob);
          106                         r = ob;
          107                 }
          108         }
          109         ukscproc(-1, &r, nin);
          110         if(r > ob)
          111                 OUT(out, ob, r-ob);
          112         OUT(out, ob, 0);
          113 }
          114 
          115 void
          116 uksc_out(Rune *base, int n, long *notused)
          117 {
          118         char *p;
          119         int i;
          120         Rune r;
          121         long l;
          122         static int first = 1;
          123 
          124         USED(notused);
          125         if(first){
          126                 first = 0;
          127                 for(i = 0; i < NRUNE; i++)
          128                         tab[i] = -1;
          129                 for(i = 0; i < ksc5601max; i++)
          130                         if((l = tabksc5601[i]) != -1){
          131                                 if(l < 0)
          132                                         tab[-l] = i;
          133                                 else
          134                                         tab[l] = i;
          135                         }
          136         }
          137         nrunes += n;
          138         p = obuf;
          139         for(i = 0; i < n; i++){
          140                 r = base[i];
          141                 if(r < 128)
          142                         *p++ = r;
          143                 else {
          144                         if(tab[r] != -1){
          145                                 *p++ = 0x80 | (tab[r]/94 + 0x21);
          146                                 *p++ = 0x80 | (tab[r]%94 + 0x21);
          147                                 continue;
          148                         }
          149                         if(squawk)
          150                                 EPR "%s: rune 0x%x not in output cs\n", argv0, r);
          151                         nerrors++;
          152                         if(clean)
          153                                 continue;
          154                         *p++ = BYTEBADMAP;
          155                 }
          156         }
          157         noutput += p-obuf;
          158         if(p > obuf)
          159                 write(1, obuf, p-obuf);
          160 }