plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

conv_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 }