1*9a747e4fSDavid du Colombier #include <plan9.h> 2*9a747e4fSDavid du Colombier 3*9a747e4fSDavid du Colombier char *argv0; 4*9a747e4fSDavid du Colombier enum 5*9a747e4fSDavid du Colombier { 6*9a747e4fSDavid du Colombier Bit1 = 7, 7*9a747e4fSDavid du Colombier Bitx = 6, 8*9a747e4fSDavid du Colombier Bit2 = 5, 9*9a747e4fSDavid du Colombier Bit3 = 4, 10*9a747e4fSDavid du Colombier Bit4 = 3, 11*9a747e4fSDavid du Colombier 12*9a747e4fSDavid du Colombier T1 = ((1<<(Bit1+1))-1) ^ 0xFF, /* 0000 0000 */ 13*9a747e4fSDavid du Colombier Tx = ((1<<(Bitx+1))-1) ^ 0xFF, /* 1000 0000 */ 14*9a747e4fSDavid du Colombier T2 = ((1<<(Bit2+1))-1) ^ 0xFF, /* 1100 0000 */ 15*9a747e4fSDavid du Colombier T3 = ((1<<(Bit3+1))-1) ^ 0xFF, /* 1110 0000 */ 16*9a747e4fSDavid du Colombier T4 = ((1<<(Bit4+1))-1) ^ 0xFF, /* 1111 0000 */ 17*9a747e4fSDavid du Colombier 18*9a747e4fSDavid du Colombier Rune1 = (1<<(Bit1+0*Bitx))-1, /* 0000 0000 0111 1111 */ 19*9a747e4fSDavid du Colombier Rune2 = (1<<(Bit2+1*Bitx))-1, /* 0000 0111 1111 1111 */ 20*9a747e4fSDavid du Colombier Rune3 = (1<<(Bit3+2*Bitx))-1, /* 1111 1111 1111 1111 */ 21*9a747e4fSDavid du Colombier 22*9a747e4fSDavid du Colombier Maskx = (1<<Bitx)-1, /* 0011 1111 */ 23*9a747e4fSDavid du Colombier Testx = Maskx ^ 0xFF, /* 1100 0000 */ 24*9a747e4fSDavid du Colombier 25*9a747e4fSDavid du Colombier Bad = Runeerror 26*9a747e4fSDavid du Colombier }; 27*9a747e4fSDavid du Colombier 28*9a747e4fSDavid du Colombier int 29*9a747e4fSDavid du Colombier chartorune(Rune *rune, char *str) 30*9a747e4fSDavid du Colombier { 31*9a747e4fSDavid du Colombier int c, c1, c2; 32*9a747e4fSDavid du Colombier long l; 33*9a747e4fSDavid du Colombier 34*9a747e4fSDavid du Colombier /* 35*9a747e4fSDavid du Colombier * one character sequence 36*9a747e4fSDavid du Colombier * 00000-0007F => T1 37*9a747e4fSDavid du Colombier */ 38*9a747e4fSDavid du Colombier c = *(uchar*)str; 39*9a747e4fSDavid du Colombier if(c < Tx) { 40*9a747e4fSDavid du Colombier *rune = c; 41*9a747e4fSDavid du Colombier return 1; 42*9a747e4fSDavid du Colombier } 43*9a747e4fSDavid du Colombier 44*9a747e4fSDavid du Colombier /* 45*9a747e4fSDavid du Colombier * two character sequence 46*9a747e4fSDavid du Colombier * 0080-07FF => T2 Tx 47*9a747e4fSDavid du Colombier */ 48*9a747e4fSDavid du Colombier c1 = *(uchar*)(str+1) ^ Tx; 49*9a747e4fSDavid du Colombier if(c1 & Testx) 50*9a747e4fSDavid du Colombier goto bad; 51*9a747e4fSDavid du Colombier if(c < T3) { 52*9a747e4fSDavid du Colombier if(c < T2) 53*9a747e4fSDavid du Colombier goto bad; 54*9a747e4fSDavid du Colombier l = ((c << Bitx) | c1) & Rune2; 55*9a747e4fSDavid du Colombier if(l <= Rune1) 56*9a747e4fSDavid du Colombier goto bad; 57*9a747e4fSDavid du Colombier *rune = l; 58*9a747e4fSDavid du Colombier return 2; 59*9a747e4fSDavid du Colombier } 60*9a747e4fSDavid du Colombier 61*9a747e4fSDavid du Colombier /* 62*9a747e4fSDavid du Colombier * three character sequence 63*9a747e4fSDavid du Colombier * 0800-FFFF => T3 Tx Tx 64*9a747e4fSDavid du Colombier */ 65*9a747e4fSDavid du Colombier c2 = *(uchar*)(str+2) ^ Tx; 66*9a747e4fSDavid du Colombier if(c2 & Testx) 67*9a747e4fSDavid du Colombier goto bad; 68*9a747e4fSDavid du Colombier if(c < T4) { 69*9a747e4fSDavid du Colombier l = ((((c << Bitx) | c1) << Bitx) | c2) & Rune3; 70*9a747e4fSDavid du Colombier if(l <= Rune2) 71*9a747e4fSDavid du Colombier goto bad; 72*9a747e4fSDavid du Colombier *rune = l; 73*9a747e4fSDavid du Colombier return 3; 74*9a747e4fSDavid du Colombier } 75*9a747e4fSDavid du Colombier 76*9a747e4fSDavid du Colombier /* 77*9a747e4fSDavid du Colombier * bad decoding 78*9a747e4fSDavid du Colombier */ 79*9a747e4fSDavid du Colombier bad: 80*9a747e4fSDavid du Colombier *rune = Bad; 81*9a747e4fSDavid du Colombier return 1; 82*9a747e4fSDavid du Colombier } 83*9a747e4fSDavid du Colombier 84*9a747e4fSDavid du Colombier int 85*9a747e4fSDavid du Colombier runetochar(char *str, Rune *rune) 86*9a747e4fSDavid du Colombier { 87*9a747e4fSDavid du Colombier long c; 88*9a747e4fSDavid du Colombier 89*9a747e4fSDavid du Colombier /* 90*9a747e4fSDavid du Colombier * one character sequence 91*9a747e4fSDavid du Colombier * 00000-0007F => 00-7F 92*9a747e4fSDavid du Colombier */ 93*9a747e4fSDavid du Colombier c = *rune; 94*9a747e4fSDavid du Colombier if(c <= Rune1) { 95*9a747e4fSDavid du Colombier str[0] = c; 96*9a747e4fSDavid du Colombier return 1; 97*9a747e4fSDavid du Colombier } 98*9a747e4fSDavid du Colombier 99*9a747e4fSDavid du Colombier /* 100*9a747e4fSDavid du Colombier * two character sequence 101*9a747e4fSDavid du Colombier * 0080-07FF => T2 Tx 102*9a747e4fSDavid du Colombier */ 103*9a747e4fSDavid du Colombier if(c <= Rune2) { 104*9a747e4fSDavid du Colombier str[0] = T2 | (c >> 1*Bitx); 105*9a747e4fSDavid du Colombier str[1] = Tx | (c & Maskx); 106*9a747e4fSDavid du Colombier return 2; 107*9a747e4fSDavid du Colombier } 108*9a747e4fSDavid du Colombier 109*9a747e4fSDavid du Colombier /* 110*9a747e4fSDavid du Colombier * three character sequence 111*9a747e4fSDavid du Colombier * 0800-FFFF => T3 Tx Tx 112*9a747e4fSDavid du Colombier */ 113*9a747e4fSDavid du Colombier str[0] = T3 | (c >> 2*Bitx); 114*9a747e4fSDavid du Colombier str[1] = Tx | ((c >> 1*Bitx) & Maskx); 115*9a747e4fSDavid du Colombier str[2] = Tx | (c & Maskx); 116*9a747e4fSDavid du Colombier return 3; 117*9a747e4fSDavid du Colombier } 118*9a747e4fSDavid du Colombier 119*9a747e4fSDavid du Colombier int 120*9a747e4fSDavid du Colombier runelen(long c) 121*9a747e4fSDavid du Colombier { 122*9a747e4fSDavid du Colombier Rune rune; 123*9a747e4fSDavid du Colombier char str[10]; 124*9a747e4fSDavid du Colombier 125*9a747e4fSDavid du Colombier rune = c; 126*9a747e4fSDavid du Colombier return runetochar(str, &rune); 127*9a747e4fSDavid du Colombier } 128*9a747e4fSDavid du Colombier 129*9a747e4fSDavid du Colombier int 130*9a747e4fSDavid du Colombier utflen(char *s) 131*9a747e4fSDavid du Colombier { 132*9a747e4fSDavid du Colombier int c; 133*9a747e4fSDavid du Colombier long n; 134*9a747e4fSDavid du Colombier Rune rune; 135*9a747e4fSDavid du Colombier 136*9a747e4fSDavid du Colombier n = 0; 137*9a747e4fSDavid du Colombier for(;;) { 138*9a747e4fSDavid du Colombier c = *(uchar*)s; 139*9a747e4fSDavid du Colombier if(c < Runeself) { 140*9a747e4fSDavid du Colombier if(c == 0) 141*9a747e4fSDavid du Colombier return n; 142*9a747e4fSDavid du Colombier s++; 143*9a747e4fSDavid du Colombier } else 144*9a747e4fSDavid du Colombier s += chartorune(&rune, s); 145*9a747e4fSDavid du Colombier n++; 146*9a747e4fSDavid du Colombier } 147*9a747e4fSDavid du Colombier return 0; 148*9a747e4fSDavid du Colombier } 149