1 #define UNICODE 2 #define Unknown win_Unknown 3 #include <windows.h> 4 #include <winbase.h> 5 #undef Unknown 6 #undef Sleep 7 #include "dat.h" 8 #include "fns.h" 9 #include "error.h" 10 #include "r16.h" 11 12 #define Bit(i) (7-(i)) 13 /* N 0's preceded by i 1's, T(Bit(2)) is 1100 0000 */ 14 #define T(i) (((1 << (Bit(i)+1))-1) ^ 0xFF) 15 /* 0000 0000 0000 0111 1111 1111 */ 16 #define RuneX(i) ((1 << (Bit(i) + ((i)-1)*Bitx))-1) 17 18 enum 19 { 20 Bitx = Bit(1), 21 22 Tx = T(1), /* 1000 0000 */ 23 Rune1 = (1<<(Bit(0)+0*Bitx))-1, /* 0000 0000 0000 0000 0111 1111 */ 24 25 Maskx = (1<<Bitx)-1, /* 0011 1111 */ 26 Testx = Maskx ^ 0xFF, /* 1100 0000 */ 27 28 SurrogateMin = 0xD800, 29 SurrogateMax = 0xDFFF, 30 31 Bad = Runeerror, 32 }; 33 34 Rune16* 35 runes16dup(Rune16 *r) 36 { 37 int n; 38 Rune16 *s; 39 40 n = runes16len(r) + 1; 41 s = malloc(n * sizeof(Rune16)); 42 if(s == nil) 43 error(Enomem); 44 memmove(s, r, n * sizeof(Rune16)); 45 return s; 46 } 47 48 int 49 runes16len(Rune16 *r) 50 { 51 int n; 52 53 n = 0; 54 while(*r++ != 0) 55 n++; 56 return n; 57 } 58 59 char* 60 runes16toutf(char *p, Rune16 *r, int nc) 61 { 62 char *op, *ep; 63 int n, c; 64 Rune rc; 65 66 op = p; 67 ep = p + nc; 68 while(c = *r++) { 69 n = 1; 70 if(c >= Runeself) 71 n = runelen(c); 72 if(p + n >= ep) 73 break; 74 rc = c; 75 if(c < Runeself) 76 *p++ = c; 77 else 78 p += runetochar(p, &rc); 79 } 80 *p = '\0'; 81 return op; 82 } 83 84 int 85 rune16nlen(Rune16 *r, int nrune) 86 { 87 int nb, i; 88 Rune c; 89 90 nb = 0; 91 while(nrune--) { 92 c = *r++; 93 if(c <= Rune1){ 94 nb++; 95 } else { 96 for(i = 2; i < UTFmax + 1; i++) 97 if(c <= RuneX(i) || i == UTFmax){ 98 nb += i; 99 break; 100 } 101 } 102 } 103 return nb; 104 } 105 106 Rune16* 107 utftorunes16(Rune16 *r, char *p, int nc) 108 { 109 Rune16 *or, *er; 110 Rune rc; 111 112 or = r; 113 er = r + nc; 114 while(*p != '\0' && r + 1 < er){ 115 p += chartorune(&rc, p); 116 *r++ = rc; /* we'll ignore surrogate pairs */ 117 } 118 *r = '\0'; 119 return or; 120 } 121 122 int 123 runes16cmp(Rune16 *s1, Rune16 *s2) 124 { 125 Rune16 r1, r2; 126 127 for(;;) { 128 r1 = *s1++; 129 r2 = *s2++; 130 if(r1 != r2) { 131 if(r1 > r2) 132 return 1; 133 return -1; 134 } 135 if(r1 == 0) 136 return 0; 137 } 138 } 139 140 wchar_t * 141 widen(char *s) 142 { 143 int n; 144 wchar_t *ws; 145 146 n = utflen(s) + 1; 147 ws = smalloc(n*sizeof(wchar_t)); 148 utftorunes16(ws, s, n); 149 return ws; 150 } 151 152 153 char * 154 narrowen(wchar_t *ws) 155 { 156 char *s; 157 int n; 158 159 n = widebytes(ws); 160 s = smalloc(n); 161 runes16toutf(s, ws, n); 162 return s; 163 } 164 165 166 int 167 widebytes(wchar_t *ws) 168 { 169 int n = 0; 170 171 while (*ws) 172 n += runelen(*ws++); 173 return n+1; 174 } 175