Blame


1 a31db67d 2004-04-21 devnull #ifdef PLAN9
2 a31db67d 2004-04-21 devnull #include <u.h>
3 a31db67d 2004-04-21 devnull #include <libc.h>
4 a31db67d 2004-04-21 devnull #include <bio.h>
5 a31db67d 2004-04-21 devnull #else
6 a31db67d 2004-04-21 devnull #include <sys/types.h>
7 a31db67d 2004-04-21 devnull #include <stdio.h>
8 a31db67d 2004-04-21 devnull #include <stdlib.h>
9 a31db67d 2004-04-21 devnull #include <string.h>
10 a31db67d 2004-04-21 devnull #include <unistd.h>
11 a31db67d 2004-04-21 devnull #include <errno.h>
12 a31db67d 2004-04-21 devnull #include "plan9.h"
13 a31db67d 2004-04-21 devnull #endif
14 a31db67d 2004-04-21 devnull #include "hdr.h"
15 a31db67d 2004-04-21 devnull
16 a31db67d 2004-04-21 devnull /*
17 a31db67d 2004-04-21 devnull the our_* routines are implementations for the corresponding library
18 a31db67d 2004-04-21 devnull routines. for a while, i tried to actually name them wctomb etc
19 a31db67d 2004-04-21 devnull but stopped that after i found a system which made wchar_t an
20 a31db67d 2004-04-21 devnull unsigned char.
21 a31db67d 2004-04-21 devnull */
22 a31db67d 2004-04-21 devnull
23 a31db67d 2004-04-21 devnull #ifdef PLAN9
24 a31db67d 2004-04-21 devnull long getrune(Biobuf *);
25 a31db67d 2004-04-21 devnull long getisorune(Biobuf *);
26 a31db67d 2004-04-21 devnull #else
27 a31db67d 2004-04-21 devnull long getrune(FILE *);
28 a31db67d 2004-04-21 devnull long getisorune(FILE *);
29 a31db67d 2004-04-21 devnull #endif
30 a31db67d 2004-04-21 devnull int our_wctomb(char *s, unsigned long wc);
31 a31db67d 2004-04-21 devnull int our_mbtowc(unsigned long *p, char *s, unsigned n);
32 a31db67d 2004-04-21 devnull int runetoisoutf(char *str, Rune *rune);
33 a31db67d 2004-04-21 devnull int fullisorune(char *str, int n);
34 a31db67d 2004-04-21 devnull int isochartorune(Rune *rune, char *str);
35 a31db67d 2004-04-21 devnull
36 a31db67d 2004-04-21 devnull void
37 a31db67d 2004-04-21 devnull utf_in(int fd, long *notused, struct convert *out)
38 a31db67d 2004-04-21 devnull {
39 a31db67d 2004-04-21 devnull #ifndef PLAN9
40 a31db67d 2004-04-21 devnull FILE *fp;
41 a31db67d 2004-04-21 devnull #else /* PLAN9 */
42 a31db67d 2004-04-21 devnull Biobuf b;
43 a31db67d 2004-04-21 devnull #endif /* PLAN9 */
44 a31db67d 2004-04-21 devnull Rune *r;
45 a31db67d 2004-04-21 devnull long l;
46 a31db67d 2004-04-21 devnull
47 a31db67d 2004-04-21 devnull USED(notused);
48 a31db67d 2004-04-21 devnull #ifndef PLAN9
49 a31db67d 2004-04-21 devnull if((fp = fdopen(fd, "r")) == NULL){
50 a31db67d 2004-04-21 devnull EPR "%s: input setup error: %s\n", argv0, strerror(errno));
51 a31db67d 2004-04-21 devnull #else /* PLAN9 */
52 a31db67d 2004-04-21 devnull if(Binit(&b, fd, OREAD) < 0){
53 a31db67d 2004-04-21 devnull EPR "%s: input setup error: %r\n", argv0);
54 a31db67d 2004-04-21 devnull #endif /* PLAN9 */
55 a31db67d 2004-04-21 devnull EXIT(1, "input error");
56 a31db67d 2004-04-21 devnull }
57 a31db67d 2004-04-21 devnull r = runes;
58 a31db67d 2004-04-21 devnull for(;;)
59 a31db67d 2004-04-21 devnull #ifndef PLAN9
60 a31db67d 2004-04-21 devnull switch(l = getrune(fp))
61 a31db67d 2004-04-21 devnull #else /* PLAN9 */
62 a31db67d 2004-04-21 devnull switch(l = getrune(&b))
63 a31db67d 2004-04-21 devnull #endif /* PLAN9 */
64 a31db67d 2004-04-21 devnull {
65 a31db67d 2004-04-21 devnull case -1:
66 a31db67d 2004-04-21 devnull goto done;
67 a31db67d 2004-04-21 devnull case -2:
68 a31db67d 2004-04-21 devnull if(squawk)
69 a31db67d 2004-04-21 devnull EPR "%s: bad UTF sequence near byte %ld in input\n", argv0, ninput);
70 a31db67d 2004-04-21 devnull if(clean)
71 a31db67d 2004-04-21 devnull continue;
72 a31db67d 2004-04-21 devnull nerrors++;
73 a31db67d 2004-04-21 devnull l = Runeerror;
74 a31db67d 2004-04-21 devnull default:
75 a31db67d 2004-04-21 devnull *r++ = l;
76 a31db67d 2004-04-21 devnull if(r >= &runes[N]){
77 a31db67d 2004-04-21 devnull OUT(out, runes, r-runes);
78 a31db67d 2004-04-21 devnull r = runes;
79 a31db67d 2004-04-21 devnull }
80 a31db67d 2004-04-21 devnull }
81 a31db67d 2004-04-21 devnull done:
82 a31db67d 2004-04-21 devnull if(r > runes)
83 a31db67d 2004-04-21 devnull OUT(out, runes, r-runes);
84 a31db67d 2004-04-21 devnull }
85 a31db67d 2004-04-21 devnull
86 a31db67d 2004-04-21 devnull void
87 a31db67d 2004-04-21 devnull utf_out(Rune *base, int n, long *notused)
88 a31db67d 2004-04-21 devnull {
89 a31db67d 2004-04-21 devnull char *p;
90 a31db67d 2004-04-21 devnull Rune *r;
91 a31db67d 2004-04-21 devnull
92 a31db67d 2004-04-21 devnull USED(notused);
93 a31db67d 2004-04-21 devnull nrunes += n;
94 a31db67d 2004-04-21 devnull for(r = base, p = obuf; n-- > 0; r++){
95 a31db67d 2004-04-21 devnull p += our_wctomb(p, *r);
96 a31db67d 2004-04-21 devnull }
97 a31db67d 2004-04-21 devnull noutput += p-obuf;
98 a31db67d 2004-04-21 devnull write(1, obuf, p-obuf);
99 a31db67d 2004-04-21 devnull }
100 a31db67d 2004-04-21 devnull
101 a31db67d 2004-04-21 devnull void
102 a31db67d 2004-04-21 devnull isoutf_in(int fd, long *notused, struct convert *out)
103 a31db67d 2004-04-21 devnull {
104 a31db67d 2004-04-21 devnull #ifndef PLAN9
105 a31db67d 2004-04-21 devnull FILE *fp;
106 a31db67d 2004-04-21 devnull #else /* PLAN9 */
107 a31db67d 2004-04-21 devnull Biobuf b;
108 a31db67d 2004-04-21 devnull #endif /* PLAN9 */
109 a31db67d 2004-04-21 devnull Rune *r;
110 a31db67d 2004-04-21 devnull long l;
111 a31db67d 2004-04-21 devnull
112 a31db67d 2004-04-21 devnull USED(notused);
113 a31db67d 2004-04-21 devnull #ifndef PLAN9
114 a31db67d 2004-04-21 devnull if((fp = fdopen(fd, "r")) == 0){
115 a31db67d 2004-04-21 devnull EPR "%s: input setup error: %s\n", argv0, strerror(errno));
116 a31db67d 2004-04-21 devnull #else /* PLAN9 */
117 a31db67d 2004-04-21 devnull if(Binit(&b, fd, OREAD) < 0){
118 a31db67d 2004-04-21 devnull EPR "%s: input setup error: %r\n", argv0);
119 a31db67d 2004-04-21 devnull #endif /* PLAN9 */
120 a31db67d 2004-04-21 devnull EXIT(1, "input error");
121 a31db67d 2004-04-21 devnull }
122 a31db67d 2004-04-21 devnull r = runes;
123 a31db67d 2004-04-21 devnull for(;;)
124 a31db67d 2004-04-21 devnull #ifndef PLAN9
125 a31db67d 2004-04-21 devnull switch(l = getisorune(fp))
126 a31db67d 2004-04-21 devnull #else /* PLAN9 */
127 a31db67d 2004-04-21 devnull switch(l = getisorune(&b))
128 a31db67d 2004-04-21 devnull #endif /* PLAN9 */
129 a31db67d 2004-04-21 devnull {
130 a31db67d 2004-04-21 devnull case -1:
131 a31db67d 2004-04-21 devnull goto done;
132 a31db67d 2004-04-21 devnull case -2:
133 a31db67d 2004-04-21 devnull if(squawk)
134 a31db67d 2004-04-21 devnull EPR "%s: bad UTF sequence near byte %ld in input\n", argv0, ninput);
135 a31db67d 2004-04-21 devnull if(clean)
136 a31db67d 2004-04-21 devnull continue;
137 a31db67d 2004-04-21 devnull nerrors++;
138 a31db67d 2004-04-21 devnull l = Runeerror;
139 a31db67d 2004-04-21 devnull default:
140 a31db67d 2004-04-21 devnull *r++ = l;
141 a31db67d 2004-04-21 devnull if(r >= &runes[N]){
142 a31db67d 2004-04-21 devnull OUT(out, runes, r-runes);
143 a31db67d 2004-04-21 devnull r = runes;
144 a31db67d 2004-04-21 devnull }
145 a31db67d 2004-04-21 devnull }
146 a31db67d 2004-04-21 devnull done:
147 a31db67d 2004-04-21 devnull if(r > runes)
148 a31db67d 2004-04-21 devnull OUT(out, runes, r-runes);
149 a31db67d 2004-04-21 devnull }
150 a31db67d 2004-04-21 devnull
151 a31db67d 2004-04-21 devnull void
152 a31db67d 2004-04-21 devnull isoutf_out(Rune *base, int n, long *notused)
153 a31db67d 2004-04-21 devnull {
154 a31db67d 2004-04-21 devnull char *p;
155 a31db67d 2004-04-21 devnull Rune *r;
156 a31db67d 2004-04-21 devnull
157 a31db67d 2004-04-21 devnull USED(notused);
158 a31db67d 2004-04-21 devnull nrunes += n;
159 a31db67d 2004-04-21 devnull for(r = base, p = obuf; n-- > 0; r++)
160 a31db67d 2004-04-21 devnull p += runetoisoutf(p, r);
161 a31db67d 2004-04-21 devnull noutput += p-obuf;
162 a31db67d 2004-04-21 devnull write(1, obuf, p-obuf);
163 a31db67d 2004-04-21 devnull }
164 a31db67d 2004-04-21 devnull
165 a31db67d 2004-04-21 devnull long
166 a31db67d 2004-04-21 devnull #ifndef PLAN9
167 a31db67d 2004-04-21 devnull getrune(FILE *fp)
168 a31db67d 2004-04-21 devnull #else /* PLAN9 */
169 a31db67d 2004-04-21 devnull getrune(Biobuf *bp)
170 a31db67d 2004-04-21 devnull #endif /* PLAN9 */
171 a31db67d 2004-04-21 devnull {
172 a31db67d 2004-04-21 devnull int c, i;
173 a31db67d 2004-04-21 devnull char str[UTFmax]; /* MB_LEN_MAX really */
174 a31db67d 2004-04-21 devnull unsigned long l;
175 a31db67d 2004-04-21 devnull int n;
176 a31db67d 2004-04-21 devnull
177 a31db67d 2004-04-21 devnull for(i = 0;;){
178 a31db67d 2004-04-21 devnull #ifndef PLAN9
179 a31db67d 2004-04-21 devnull c = getc(fp);
180 a31db67d 2004-04-21 devnull #else /* PLAN9 */
181 a31db67d 2004-04-21 devnull c = Bgetc(bp);
182 a31db67d 2004-04-21 devnull #endif /* PLAN9 */
183 a31db67d 2004-04-21 devnull if(c < 0)
184 a31db67d 2004-04-21 devnull return(c);
185 a31db67d 2004-04-21 devnull ninput++;
186 a31db67d 2004-04-21 devnull str[i++] = c;
187 a31db67d 2004-04-21 devnull n = our_mbtowc(&l, str, i);
188 a31db67d 2004-04-21 devnull if(n == -1)
189 a31db67d 2004-04-21 devnull return(-2);
190 a31db67d 2004-04-21 devnull if(n > 0)
191 a31db67d 2004-04-21 devnull return(l);
192 a31db67d 2004-04-21 devnull }
193 a31db67d 2004-04-21 devnull }
194 a31db67d 2004-04-21 devnull
195 a31db67d 2004-04-21 devnull long
196 a31db67d 2004-04-21 devnull #ifndef PLAN9
197 a31db67d 2004-04-21 devnull getisorune(FILE *fp)
198 a31db67d 2004-04-21 devnull #else /* PLAN9 */
199 a31db67d 2004-04-21 devnull getisorune(Biobuf *bp)
200 a31db67d 2004-04-21 devnull #endif /* PLAN9 */
201 a31db67d 2004-04-21 devnull {
202 a31db67d 2004-04-21 devnull int c, i;
203 a31db67d 2004-04-21 devnull Rune rune;
204 a31db67d 2004-04-21 devnull char str[UTFmax]; /* MB_LEN_MAX really */
205 a31db67d 2004-04-21 devnull
206 a31db67d 2004-04-21 devnull for(i = 0;;){
207 a31db67d 2004-04-21 devnull #ifndef PLAN9
208 a31db67d 2004-04-21 devnull c = getc(fp);
209 a31db67d 2004-04-21 devnull #else /* PLAN9 */
210 a31db67d 2004-04-21 devnull c = Bgetc(bp);
211 a31db67d 2004-04-21 devnull #endif /* PLAN9 */
212 a31db67d 2004-04-21 devnull if(c < 0)
213 a31db67d 2004-04-21 devnull return(c);
214 a31db67d 2004-04-21 devnull ninput++;
215 a31db67d 2004-04-21 devnull str[i++] = c;
216 a31db67d 2004-04-21 devnull if(fullisorune(str, i))
217 a31db67d 2004-04-21 devnull break;
218 a31db67d 2004-04-21 devnull }
219 a31db67d 2004-04-21 devnull isochartorune(&rune, str);
220 a31db67d 2004-04-21 devnull if(rune == Runeerror)
221 a31db67d 2004-04-21 devnull return -2;
222 a31db67d 2004-04-21 devnull return(rune);
223 a31db67d 2004-04-21 devnull }
224 a31db67d 2004-04-21 devnull
225 a31db67d 2004-04-21 devnull enum
226 a31db67d 2004-04-21 devnull {
227 a31db67d 2004-04-21 devnull Char1 = Runeself, Rune1 = Runeself,
228 a31db67d 2004-04-21 devnull Char21 = 0xA1, Rune21 = 0x0100,
229 a31db67d 2004-04-21 devnull Char22 = 0xF6, Rune22 = 0x4016,
230 a31db67d 2004-04-21 devnull Char3 = 0xFC, Rune3 = 0x10000, /* really 0x38E2E */
231 a31db67d 2004-04-21 devnull Esc = 0xBE, Bad = Runeerror
232 a31db67d 2004-04-21 devnull };
233 a31db67d 2004-04-21 devnull
234 a31db67d 2004-04-21 devnull static uchar U[256];
235 a31db67d 2004-04-21 devnull static uchar T[256];
236 a31db67d 2004-04-21 devnull
237 a31db67d 2004-04-21 devnull static
238 a31db67d 2004-04-21 devnull void
239 a31db67d 2004-04-21 devnull mktable(void)
240 a31db67d 2004-04-21 devnull {
241 a31db67d 2004-04-21 devnull int i, u;
242 a31db67d 2004-04-21 devnull
243 a31db67d 2004-04-21 devnull for(i=0; i<256; i++) {
244 a31db67d 2004-04-21 devnull u = i + (0x5E - 0xA0);
245 a31db67d 2004-04-21 devnull if(i < 0xA0)
246 a31db67d 2004-04-21 devnull u = i + (0xDF - 0x7F);
247 a31db67d 2004-04-21 devnull if(i < 0x7F)
248 a31db67d 2004-04-21 devnull u = i + (0x00 - 0x21);
249 a31db67d 2004-04-21 devnull if(i < 0x21)
250 a31db67d 2004-04-21 devnull u = i + (0xBE - 0x00);
251 a31db67d 2004-04-21 devnull U[i] = u;
252 a31db67d 2004-04-21 devnull T[u] = i;
253 a31db67d 2004-04-21 devnull }
254 a31db67d 2004-04-21 devnull }
255 a31db67d 2004-04-21 devnull
256 a31db67d 2004-04-21 devnull int
257 a31db67d 2004-04-21 devnull isochartorune(Rune *rune, char *str)
258 a31db67d 2004-04-21 devnull {
259 a31db67d 2004-04-21 devnull int c, c1, c2;
260 a31db67d 2004-04-21 devnull long l;
261 a31db67d 2004-04-21 devnull
262 a31db67d 2004-04-21 devnull if(U[0] == 0)
263 a31db67d 2004-04-21 devnull mktable();
264 a31db67d 2004-04-21 devnull
265 a31db67d 2004-04-21 devnull /*
266 a31db67d 2004-04-21 devnull * one character sequence
267 a31db67d 2004-04-21 devnull * 00000-0009F => 00-9F
268 a31db67d 2004-04-21 devnull */
269 a31db67d 2004-04-21 devnull c = *(uchar*)str;
270 a31db67d 2004-04-21 devnull if(c < Char1) {
271 a31db67d 2004-04-21 devnull *rune = c;
272 a31db67d 2004-04-21 devnull return 1;
273 a31db67d 2004-04-21 devnull }
274 a31db67d 2004-04-21 devnull
275 a31db67d 2004-04-21 devnull /*
276 a31db67d 2004-04-21 devnull * two character sequence
277 a31db67d 2004-04-21 devnull * 000A0-000FF => A0; A0-FF
278 a31db67d 2004-04-21 devnull */
279 a31db67d 2004-04-21 devnull c1 = *(uchar*)(str+1);
280 a31db67d 2004-04-21 devnull if(c < Char21) {
281 a31db67d 2004-04-21 devnull if(c1 >= Rune1 && c1 < Rune21) {
282 a31db67d 2004-04-21 devnull *rune = c1;
283 a31db67d 2004-04-21 devnull return 2;
284 a31db67d 2004-04-21 devnull }
285 a31db67d 2004-04-21 devnull goto bad;
286 a31db67d 2004-04-21 devnull }
287 a31db67d 2004-04-21 devnull
288 a31db67d 2004-04-21 devnull /*
289 a31db67d 2004-04-21 devnull * two character sequence
290 a31db67d 2004-04-21 devnull * 00100-04015 => A1-F5; 21-7E/A0-FF
291 a31db67d 2004-04-21 devnull */
292 a31db67d 2004-04-21 devnull c1 = U[c1];
293 a31db67d 2004-04-21 devnull if(c1 >= Esc)
294 a31db67d 2004-04-21 devnull goto bad;
295 a31db67d 2004-04-21 devnull if(c < Char22) {
296 a31db67d 2004-04-21 devnull *rune = (c-Char21)*Esc + c1 + Rune21;
297 a31db67d 2004-04-21 devnull return 2;
298 a31db67d 2004-04-21 devnull }
299 a31db67d 2004-04-21 devnull
300 a31db67d 2004-04-21 devnull /*
301 a31db67d 2004-04-21 devnull * three character sequence
302 a31db67d 2004-04-21 devnull * 04016-38E2D => A6-FB; 21-7E/A0-FF
303 a31db67d 2004-04-21 devnull */
304 a31db67d 2004-04-21 devnull c2 = U[*(uchar*)(str+2)];
305 a31db67d 2004-04-21 devnull if(c2 >= Esc)
306 a31db67d 2004-04-21 devnull goto bad;
307 a31db67d 2004-04-21 devnull if(c < Char3) {
308 a31db67d 2004-04-21 devnull l = (c-Char22)*Esc*Esc + c1*Esc + c2 + Rune22;
309 a31db67d 2004-04-21 devnull if(l >= Rune3)
310 a31db67d 2004-04-21 devnull goto bad;
311 a31db67d 2004-04-21 devnull *rune = l;
312 a31db67d 2004-04-21 devnull return 3;
313 a31db67d 2004-04-21 devnull }
314 a31db67d 2004-04-21 devnull
315 a31db67d 2004-04-21 devnull /*
316 a31db67d 2004-04-21 devnull * bad decoding
317 a31db67d 2004-04-21 devnull */
318 a31db67d 2004-04-21 devnull bad:
319 a31db67d 2004-04-21 devnull *rune = Bad;
320 a31db67d 2004-04-21 devnull return 1;
321 a31db67d 2004-04-21 devnull }
322 a31db67d 2004-04-21 devnull
323 a31db67d 2004-04-21 devnull int
324 a31db67d 2004-04-21 devnull runetoisoutf(char *str, Rune *rune)
325 a31db67d 2004-04-21 devnull {
326 a31db67d 2004-04-21 devnull long c;
327 a31db67d 2004-04-21 devnull
328 a31db67d 2004-04-21 devnull if(T[0] == 0)
329 a31db67d 2004-04-21 devnull mktable();
330 a31db67d 2004-04-21 devnull
331 a31db67d 2004-04-21 devnull /*
332 a31db67d 2004-04-21 devnull * one character sequence
333 a31db67d 2004-04-21 devnull * 00000-0009F => 00-9F
334 a31db67d 2004-04-21 devnull */
335 a31db67d 2004-04-21 devnull c = *rune;
336 a31db67d 2004-04-21 devnull if(c < Rune1) {
337 a31db67d 2004-04-21 devnull str[0] = c;
338 a31db67d 2004-04-21 devnull return 1;
339 a31db67d 2004-04-21 devnull }
340 a31db67d 2004-04-21 devnull
341 a31db67d 2004-04-21 devnull /*
342 a31db67d 2004-04-21 devnull * two character sequence
343 a31db67d 2004-04-21 devnull * 000A0-000FF => A0; A0-FF
344 a31db67d 2004-04-21 devnull */
345 a31db67d 2004-04-21 devnull if(c < Rune21) {
346 a31db67d 2004-04-21 devnull str[0] = (uchar)Char1;
347 a31db67d 2004-04-21 devnull str[1] = c;
348 a31db67d 2004-04-21 devnull return 2;
349 a31db67d 2004-04-21 devnull }
350 a31db67d 2004-04-21 devnull
351 a31db67d 2004-04-21 devnull /*
352 a31db67d 2004-04-21 devnull * two character sequence
353 a31db67d 2004-04-21 devnull * 00100-04015 => A1-F5; 21-7E/A0-FF
354 a31db67d 2004-04-21 devnull */
355 a31db67d 2004-04-21 devnull if(c < Rune22) {
356 a31db67d 2004-04-21 devnull c -= Rune21;
357 a31db67d 2004-04-21 devnull str[0] = c/Esc + Char21;
358 a31db67d 2004-04-21 devnull str[1] = T[c%Esc];
359 a31db67d 2004-04-21 devnull return 2;
360 a31db67d 2004-04-21 devnull }
361 a31db67d 2004-04-21 devnull
362 a31db67d 2004-04-21 devnull /*
363 a31db67d 2004-04-21 devnull * three character sequence
364 a31db67d 2004-04-21 devnull * 04016-38E2D => A6-FB; 21-7E/A0-FF
365 a31db67d 2004-04-21 devnull */
366 a31db67d 2004-04-21 devnull c -= Rune22;
367 a31db67d 2004-04-21 devnull str[0] = c/(Esc*Esc) + Char22;
368 a31db67d 2004-04-21 devnull str[1] = T[c/Esc%Esc];
369 a31db67d 2004-04-21 devnull str[2] = T[c%Esc];
370 a31db67d 2004-04-21 devnull return 3;
371 a31db67d 2004-04-21 devnull }
372 a31db67d 2004-04-21 devnull
373 a31db67d 2004-04-21 devnull int
374 a31db67d 2004-04-21 devnull fullisorune(char *str, int n)
375 a31db67d 2004-04-21 devnull {
376 a31db67d 2004-04-21 devnull int c;
377 a31db67d 2004-04-21 devnull
378 a31db67d 2004-04-21 devnull if(n > 0) {
379 a31db67d 2004-04-21 devnull c = *(uchar*)str;
380 a31db67d 2004-04-21 devnull if(c < Char1)
381 a31db67d 2004-04-21 devnull return 1;
382 a31db67d 2004-04-21 devnull if(n > 1)
383 a31db67d 2004-04-21 devnull if(c < Char22 || n > 2)
384 a31db67d 2004-04-21 devnull return 1;
385 a31db67d 2004-04-21 devnull }
386 a31db67d 2004-04-21 devnull return 0;
387 a31db67d 2004-04-21 devnull }
388 a31db67d 2004-04-21 devnull
389 a31db67d 2004-04-21 devnull #ifdef PLAN9
390 a31db67d 2004-04-21 devnull int errno;
391 a31db67d 2004-04-21 devnull #endif
392 a31db67d 2004-04-21 devnull
393 a31db67d 2004-04-21 devnull enum
394 a31db67d 2004-04-21 devnull {
395 a31db67d 2004-04-21 devnull T1 = 0x00,
396 a31db67d 2004-04-21 devnull Tx = 0x80,
397 a31db67d 2004-04-21 devnull T2 = 0xC0,
398 a31db67d 2004-04-21 devnull T3 = 0xE0,
399 a31db67d 2004-04-21 devnull T4 = 0xF0,
400 a31db67d 2004-04-21 devnull T5 = 0xF8,
401 a31db67d 2004-04-21 devnull T6 = 0xFC,
402 a31db67d 2004-04-21 devnull
403 a31db67d 2004-04-21 devnull Bit1 = 7,
404 a31db67d 2004-04-21 devnull Bitx = 6,
405 a31db67d 2004-04-21 devnull Bit2 = 5,
406 a31db67d 2004-04-21 devnull Bit3 = 4,
407 a31db67d 2004-04-21 devnull Bit4 = 3,
408 a31db67d 2004-04-21 devnull Bit5 = 2,
409 a31db67d 2004-04-21 devnull Bit6 = 2,
410 a31db67d 2004-04-21 devnull
411 a31db67d 2004-04-21 devnull Mask1 = (1<<Bit1)-1,
412 a31db67d 2004-04-21 devnull Maskx = (1<<Bitx)-1,
413 a31db67d 2004-04-21 devnull Mask2 = (1<<Bit2)-1,
414 a31db67d 2004-04-21 devnull Mask3 = (1<<Bit3)-1,
415 a31db67d 2004-04-21 devnull Mask4 = (1<<Bit4)-1,
416 a31db67d 2004-04-21 devnull Mask5 = (1<<Bit5)-1,
417 a31db67d 2004-04-21 devnull Mask6 = (1<<Bit6)-1,
418 a31db67d 2004-04-21 devnull
419 a31db67d 2004-04-21 devnull Wchar1 = (1UL<<Bit1)-1,
420 a31db67d 2004-04-21 devnull Wchar2 = (1UL<<(Bit2+Bitx))-1,
421 a31db67d 2004-04-21 devnull Wchar3 = (1UL<<(Bit3+2*Bitx))-1,
422 a31db67d 2004-04-21 devnull Wchar4 = (1UL<<(Bit4+3*Bitx))-1,
423 a31db67d 2004-04-21 devnull Wchar5 = (1UL<<(Bit5+4*Bitx))-1
424 a31db67d 2004-04-21 devnull
425 a31db67d 2004-04-21 devnull #ifndef EILSEQ
426 a31db67d 2004-04-21 devnull , /* we hate ansi c's comma rules */
427 a31db67d 2004-04-21 devnull EILSEQ = 123
428 a31db67d 2004-04-21 devnull #endif /* PLAN9 */
429 a31db67d 2004-04-21 devnull };
430 a31db67d 2004-04-21 devnull
431 a31db67d 2004-04-21 devnull int
432 a31db67d 2004-04-21 devnull our_wctomb(char *s, unsigned long wc)
433 a31db67d 2004-04-21 devnull {
434 a31db67d 2004-04-21 devnull if(s == 0)
435 a31db67d 2004-04-21 devnull return 0; /* no shift states */
436 a31db67d 2004-04-21 devnull if(wc & ~Wchar2) {
437 a31db67d 2004-04-21 devnull if(wc & ~Wchar4) {
438 a31db67d 2004-04-21 devnull if(wc & ~Wchar5) {
439 a31db67d 2004-04-21 devnull /* 6 bytes */
440 a31db67d 2004-04-21 devnull s[0] = T6 | ((wc >> 5*Bitx) & Mask6);
441 a31db67d 2004-04-21 devnull s[1] = Tx | ((wc >> 4*Bitx) & Maskx);
442 a31db67d 2004-04-21 devnull s[2] = Tx | ((wc >> 3*Bitx) & Maskx);
443 a31db67d 2004-04-21 devnull s[3] = Tx | ((wc >> 2*Bitx) & Maskx);
444 a31db67d 2004-04-21 devnull s[4] = Tx | ((wc >> 1*Bitx) & Maskx);
445 a31db67d 2004-04-21 devnull s[5] = Tx | (wc & Maskx);
446 a31db67d 2004-04-21 devnull return 6;
447 a31db67d 2004-04-21 devnull }
448 a31db67d 2004-04-21 devnull /* 5 bytes */
449 a31db67d 2004-04-21 devnull s[0] = T5 | (wc >> 4*Bitx);
450 a31db67d 2004-04-21 devnull s[1] = Tx | ((wc >> 3*Bitx) & Maskx);
451 a31db67d 2004-04-21 devnull s[2] = Tx | ((wc >> 2*Bitx) & Maskx);
452 a31db67d 2004-04-21 devnull s[3] = Tx | ((wc >> 1*Bitx) & Maskx);
453 a31db67d 2004-04-21 devnull s[4] = Tx | (wc & Maskx);
454 a31db67d 2004-04-21 devnull return 5;
455 a31db67d 2004-04-21 devnull }
456 a31db67d 2004-04-21 devnull if(wc & ~Wchar3) {
457 a31db67d 2004-04-21 devnull /* 4 bytes */
458 a31db67d 2004-04-21 devnull s[0] = T4 | (wc >> 3*Bitx);
459 a31db67d 2004-04-21 devnull s[1] = Tx | ((wc >> 2*Bitx) & Maskx);
460 a31db67d 2004-04-21 devnull s[2] = Tx | ((wc >> 1*Bitx) & Maskx);
461 a31db67d 2004-04-21 devnull s[3] = Tx | (wc & Maskx);
462 a31db67d 2004-04-21 devnull return 4;
463 a31db67d 2004-04-21 devnull }
464 a31db67d 2004-04-21 devnull /* 3 bytes */
465 a31db67d 2004-04-21 devnull s[0] = T3 | (wc >> 2*Bitx);
466 a31db67d 2004-04-21 devnull s[1] = Tx | ((wc >> 1*Bitx) & Maskx);
467 a31db67d 2004-04-21 devnull s[2] = Tx | (wc & Maskx);
468 a31db67d 2004-04-21 devnull return 3;
469 a31db67d 2004-04-21 devnull }
470 a31db67d 2004-04-21 devnull if(wc & ~Wchar1) {
471 a31db67d 2004-04-21 devnull /* 2 bytes */
472 a31db67d 2004-04-21 devnull s[0] = T2 | (wc >> 1*Bitx);
473 a31db67d 2004-04-21 devnull s[1] = Tx | (wc & Maskx);
474 a31db67d 2004-04-21 devnull return 2;
475 a31db67d 2004-04-21 devnull }
476 a31db67d 2004-04-21 devnull /* 1 byte */
477 a31db67d 2004-04-21 devnull s[0] = T1 | wc;
478 a31db67d 2004-04-21 devnull return 1;
479 a31db67d 2004-04-21 devnull }
480 a31db67d 2004-04-21 devnull
481 a31db67d 2004-04-21 devnull int
482 a31db67d 2004-04-21 devnull our_mbtowc(unsigned long *p, char *s, unsigned n)
483 a31db67d 2004-04-21 devnull {
484 a31db67d 2004-04-21 devnull uchar *us;
485 a31db67d 2004-04-21 devnull int c0, c1, c2, c3, c4, c5;
486 a31db67d 2004-04-21 devnull unsigned long wc;
487 a31db67d 2004-04-21 devnull
488 a31db67d 2004-04-21 devnull if(s == 0)
489 a31db67d 2004-04-21 devnull return 0; /* no shift states */
490 a31db67d 2004-04-21 devnull
491 a31db67d 2004-04-21 devnull if(n < 1)
492 a31db67d 2004-04-21 devnull goto badlen;
493 a31db67d 2004-04-21 devnull us = (uchar*)s;
494 a31db67d 2004-04-21 devnull c0 = us[0];
495 a31db67d 2004-04-21 devnull if(c0 >= T3) {
496 a31db67d 2004-04-21 devnull if(n < 3)
497 a31db67d 2004-04-21 devnull goto badlen;
498 a31db67d 2004-04-21 devnull c1 = us[1] ^ Tx;
499 a31db67d 2004-04-21 devnull c2 = us[2] ^ Tx;
500 a31db67d 2004-04-21 devnull if((c1|c2) & T2)
501 a31db67d 2004-04-21 devnull goto bad;
502 a31db67d 2004-04-21 devnull if(c0 >= T5) {
503 a31db67d 2004-04-21 devnull if(n < 5)
504 a31db67d 2004-04-21 devnull goto badlen;
505 a31db67d 2004-04-21 devnull c3 = us[3] ^ Tx;
506 a31db67d 2004-04-21 devnull c4 = us[4] ^ Tx;
507 a31db67d 2004-04-21 devnull if((c3|c4) & T2)
508 a31db67d 2004-04-21 devnull goto bad;
509 a31db67d 2004-04-21 devnull if(c0 >= T6) {
510 a31db67d 2004-04-21 devnull /* 6 bytes */
511 a31db67d 2004-04-21 devnull if(n < 6)
512 a31db67d 2004-04-21 devnull goto badlen;
513 a31db67d 2004-04-21 devnull c5 = us[5] ^ Tx;
514 a31db67d 2004-04-21 devnull if(c5 & T2)
515 a31db67d 2004-04-21 devnull goto bad;
516 a31db67d 2004-04-21 devnull wc = ((((((((((c0 & Mask6) << Bitx) |
517 a31db67d 2004-04-21 devnull c1) << Bitx) | c2) << Bitx) |
518 a31db67d 2004-04-21 devnull c3) << Bitx) | c4) << Bitx) | c5;
519 a31db67d 2004-04-21 devnull if(wc <= Wchar5)
520 a31db67d 2004-04-21 devnull goto bad;
521 a31db67d 2004-04-21 devnull *p = wc;
522 a31db67d 2004-04-21 devnull return 6;
523 a31db67d 2004-04-21 devnull }
524 a31db67d 2004-04-21 devnull /* 5 bytes */
525 a31db67d 2004-04-21 devnull wc = ((((((((c0 & Mask5) << Bitx) |
526 a31db67d 2004-04-21 devnull c1) << Bitx) | c2) << Bitx) |
527 a31db67d 2004-04-21 devnull c3) << Bitx) | c4;
528 a31db67d 2004-04-21 devnull if(wc <= Wchar4)
529 a31db67d 2004-04-21 devnull goto bad;
530 a31db67d 2004-04-21 devnull *p = wc;
531 a31db67d 2004-04-21 devnull return 5;
532 a31db67d 2004-04-21 devnull }
533 a31db67d 2004-04-21 devnull if(c0 >= T4) {
534 a31db67d 2004-04-21 devnull /* 4 bytes */
535 a31db67d 2004-04-21 devnull if(n < 4)
536 a31db67d 2004-04-21 devnull goto badlen;
537 a31db67d 2004-04-21 devnull c3 = us[3] ^ Tx;
538 a31db67d 2004-04-21 devnull if(c3 & T2)
539 a31db67d 2004-04-21 devnull goto bad;
540 a31db67d 2004-04-21 devnull wc = ((((((c0 & Mask4) << Bitx) |
541 a31db67d 2004-04-21 devnull c1) << Bitx) | c2) << Bitx) |
542 a31db67d 2004-04-21 devnull c3;
543 a31db67d 2004-04-21 devnull if(wc <= Wchar3)
544 a31db67d 2004-04-21 devnull goto bad;
545 a31db67d 2004-04-21 devnull *p = wc;
546 a31db67d 2004-04-21 devnull return 4;
547 a31db67d 2004-04-21 devnull }
548 a31db67d 2004-04-21 devnull /* 3 bytes */
549 a31db67d 2004-04-21 devnull wc = ((((c0 & Mask3) << Bitx) |
550 a31db67d 2004-04-21 devnull c1) << Bitx) | c2;
551 a31db67d 2004-04-21 devnull if(wc <= Wchar2)
552 a31db67d 2004-04-21 devnull goto bad;
553 a31db67d 2004-04-21 devnull *p = wc;
554 a31db67d 2004-04-21 devnull return 3;
555 a31db67d 2004-04-21 devnull }
556 a31db67d 2004-04-21 devnull if(c0 >= T2) {
557 a31db67d 2004-04-21 devnull /* 2 bytes */
558 a31db67d 2004-04-21 devnull if(n < 2)
559 a31db67d 2004-04-21 devnull goto badlen;
560 a31db67d 2004-04-21 devnull c1 = us[1] ^ Tx;
561 a31db67d 2004-04-21 devnull if(c1 & T2)
562 a31db67d 2004-04-21 devnull goto bad;
563 a31db67d 2004-04-21 devnull wc = ((c0 & Mask2) << Bitx) |
564 a31db67d 2004-04-21 devnull c1;
565 a31db67d 2004-04-21 devnull if(wc <= Wchar1)
566 a31db67d 2004-04-21 devnull goto bad;
567 a31db67d 2004-04-21 devnull *p = wc;
568 a31db67d 2004-04-21 devnull return 2;
569 a31db67d 2004-04-21 devnull }
570 a31db67d 2004-04-21 devnull /* 1 byte */
571 a31db67d 2004-04-21 devnull if(c0 >= Tx)
572 a31db67d 2004-04-21 devnull goto bad;
573 a31db67d 2004-04-21 devnull *p = c0;
574 a31db67d 2004-04-21 devnull return 1;
575 a31db67d 2004-04-21 devnull
576 a31db67d 2004-04-21 devnull bad:
577 a31db67d 2004-04-21 devnull errno = EILSEQ;
578 a31db67d 2004-04-21 devnull return -1;
579 a31db67d 2004-04-21 devnull badlen:
580 a31db67d 2004-04-21 devnull return -2;
581 a31db67d 2004-04-21 devnull }