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 fa059a4e 2005-12-17 devnull #ifdef PLAN9PORT
6 fa059a4e 2005-12-17 devnull #include <errno.h>
8 fa059a4e 2005-12-17 devnull extern int errno;
11 a31db67d 2004-04-21 devnull #include <sys/types.h>
12 a31db67d 2004-04-21 devnull #include <stdio.h>
13 a31db67d 2004-04-21 devnull #include <stdlib.h>
14 a31db67d 2004-04-21 devnull #include <string.h>
15 a31db67d 2004-04-21 devnull #include <unistd.h>
16 a31db67d 2004-04-21 devnull #include <errno.h>
17 a31db67d 2004-04-21 devnull #include "plan9.h"
19 a31db67d 2004-04-21 devnull #include "hdr.h"
20 35d26aa3 2005-12-26 devnull #ifndef EILSEQ
21 35d26aa3 2005-12-26 devnull #define EILSEQ 9998
25 a31db67d 2004-04-21 devnull the our_* routines are implementations for the corresponding library
26 a31db67d 2004-04-21 devnull routines. for a while, i tried to actually name them wctomb etc
27 a31db67d 2004-04-21 devnull but stopped that after i found a system which made wchar_t an
28 a31db67d 2004-04-21 devnull unsigned char.
31 a31db67d 2004-04-21 devnull int our_wctomb(char *s, unsigned long wc);
32 a31db67d 2004-04-21 devnull int our_mbtowc(unsigned long *p, char *s, unsigned n);
33 a31db67d 2004-04-21 devnull int runetoisoutf(char *str, Rune *rune);
34 a31db67d 2004-04-21 devnull int fullisorune(char *str, int n);
35 a31db67d 2004-04-21 devnull int isochartorune(Rune *rune, char *str);
38 a31db67d 2004-04-21 devnull utf_in(int fd, long *notused, struct convert *out)
40 7551b2ec 2005-03-09 devnull char buf[N];
41 7551b2ec 2005-03-09 devnull int i, j, c, n, tot;
44 a31db67d 2004-04-21 devnull USED(notused);
46 7551b2ec 2005-03-09 devnull while((n = read(fd, buf+tot, N-tot)) >= 0){
47 7551b2ec 2005-03-09 devnull tot += n;
48 7551b2ec 2005-03-09 devnull for(i=j=0; i<tot; ){
49 7551b2ec 2005-03-09 devnull c = our_mbtowc(&l, buf+i, tot-i);
50 7f0d675d 2005-09-13 devnull if(c == -2)
52 7f0d675d 2005-09-13 devnull if(c == -1){
53 7551b2ec 2005-03-09 devnull if(squawk)
54 7551b2ec 2005-03-09 devnull EPR "%s: bad UTF sequence near byte %ld in input\n", argv0, ninput+i);
55 7551b2ec 2005-03-09 devnull if(clean)
56 7551b2ec 2005-03-09 devnull continue;
57 7551b2ec 2005-03-09 devnull nerrors++;
58 7551b2ec 2005-03-09 devnull l = Runeerror;
61 7551b2ec 2005-03-09 devnull runes[j++] = l;
64 7551b2ec 2005-03-09 devnull OUT(out, runes, j);
65 7551b2ec 2005-03-09 devnull tot -= i;
66 7551b2ec 2005-03-09 devnull ninput += i;
68 7551b2ec 2005-03-09 devnull memmove(buf, buf+i, tot);
69 7551b2ec 2005-03-09 devnull if(n == 0)
75 a31db67d 2004-04-21 devnull utf_out(Rune *base, int n, long *notused)
80 a31db67d 2004-04-21 devnull USED(notused);
81 a31db67d 2004-04-21 devnull nrunes += n;
82 a31db67d 2004-04-21 devnull for(r = base, p = obuf; n-- > 0; r++){
83 a31db67d 2004-04-21 devnull p += our_wctomb(p, *r);
85 a31db67d 2004-04-21 devnull noutput += p-obuf;
86 a31db67d 2004-04-21 devnull write(1, obuf, p-obuf);
90 a31db67d 2004-04-21 devnull isoutf_in(int fd, long *notused, struct convert *out)
92 7551b2ec 2005-03-09 devnull char buf[N];
93 7551b2ec 2005-03-09 devnull int i, j, c, n, tot;
95 a31db67d 2004-04-21 devnull USED(notused);
97 7551b2ec 2005-03-09 devnull while((n = read(fd, buf+tot, N-tot)) >= 0){
98 7551b2ec 2005-03-09 devnull tot += n;
99 7551b2ec 2005-03-09 devnull for(i=j=0; i<tot; ){
100 7551b2ec 2005-03-09 devnull if(!fullisorune(buf+i, tot-i))
102 7551b2ec 2005-03-09 devnull c = isochartorune(&runes[j], buf+i);
103 7551b2ec 2005-03-09 devnull if(runes[j] == Runeerror){
104 7551b2ec 2005-03-09 devnull if(squawk)
105 7551b2ec 2005-03-09 devnull EPR "%s: bad UTF sequence near byte %ld in input\n", argv0, ninput+i);
106 7551b2ec 2005-03-09 devnull if(clean)
107 7551b2ec 2005-03-09 devnull continue;
108 7551b2ec 2005-03-09 devnull nerrors++;
113 7551b2ec 2005-03-09 devnull OUT(out, runes, j);
114 7551b2ec 2005-03-09 devnull tot -= i;
115 7551b2ec 2005-03-09 devnull ninput += i;
117 7551b2ec 2005-03-09 devnull memmove(buf, buf+i, tot);
118 7551b2ec 2005-03-09 devnull if(n == 0)
124 a31db67d 2004-04-21 devnull isoutf_out(Rune *base, int n, long *notused)
126 a31db67d 2004-04-21 devnull char *p;
127 a31db67d 2004-04-21 devnull Rune *r;
129 a31db67d 2004-04-21 devnull USED(notused);
130 a31db67d 2004-04-21 devnull nrunes += n;
131 a31db67d 2004-04-21 devnull for(r = base, p = obuf; n-- > 0; r++)
132 a31db67d 2004-04-21 devnull p += runetoisoutf(p, r);
133 a31db67d 2004-04-21 devnull noutput += p-obuf;
134 a31db67d 2004-04-21 devnull write(1, obuf, p-obuf);
140 a31db67d 2004-04-21 devnull Char1 = Runeself, Rune1 = Runeself,
141 a31db67d 2004-04-21 devnull Char21 = 0xA1, Rune21 = 0x0100,
142 a31db67d 2004-04-21 devnull Char22 = 0xF6, Rune22 = 0x4016,
143 a31db67d 2004-04-21 devnull Char3 = 0xFC, Rune3 = 0x10000, /* really 0x38E2E */
144 a31db67d 2004-04-21 devnull Esc = 0xBE, Bad = Runeerror
147 a31db67d 2004-04-21 devnull static uchar U[256];
148 a31db67d 2004-04-21 devnull static uchar T[256];
152 a31db67d 2004-04-21 devnull mktable(void)
154 a31db67d 2004-04-21 devnull int i, u;
156 a31db67d 2004-04-21 devnull for(i=0; i<256; i++) {
157 a31db67d 2004-04-21 devnull u = i + (0x5E - 0xA0);
158 a31db67d 2004-04-21 devnull if(i < 0xA0)
159 a31db67d 2004-04-21 devnull u = i + (0xDF - 0x7F);
160 a31db67d 2004-04-21 devnull if(i < 0x7F)
161 a31db67d 2004-04-21 devnull u = i + (0x00 - 0x21);
162 a31db67d 2004-04-21 devnull if(i < 0x21)
163 a31db67d 2004-04-21 devnull u = i + (0xBE - 0x00);
164 a31db67d 2004-04-21 devnull U[i] = u;
165 a31db67d 2004-04-21 devnull T[u] = i;
170 a31db67d 2004-04-21 devnull isochartorune(Rune *rune, char *str)
172 a31db67d 2004-04-21 devnull int c, c1, c2;
175 a31db67d 2004-04-21 devnull if(U[0] == 0)
176 a31db67d 2004-04-21 devnull mktable();
179 a31db67d 2004-04-21 devnull * one character sequence
180 a31db67d 2004-04-21 devnull * 00000-0009F => 00-9F
182 a31db67d 2004-04-21 devnull c = *(uchar*)str;
183 a31db67d 2004-04-21 devnull if(c < Char1) {
184 a31db67d 2004-04-21 devnull *rune = c;
185 a31db67d 2004-04-21 devnull return 1;
189 a31db67d 2004-04-21 devnull * two character sequence
190 a31db67d 2004-04-21 devnull * 000A0-000FF => A0; A0-FF
192 a31db67d 2004-04-21 devnull c1 = *(uchar*)(str+1);
193 a31db67d 2004-04-21 devnull if(c < Char21) {
194 a31db67d 2004-04-21 devnull if(c1 >= Rune1 && c1 < Rune21) {
195 a31db67d 2004-04-21 devnull *rune = c1;
196 a31db67d 2004-04-21 devnull return 2;
198 a31db67d 2004-04-21 devnull goto bad;
202 a31db67d 2004-04-21 devnull * two character sequence
203 a31db67d 2004-04-21 devnull * 00100-04015 => A1-F5; 21-7E/A0-FF
205 a31db67d 2004-04-21 devnull c1 = U[c1];
206 a31db67d 2004-04-21 devnull if(c1 >= Esc)
207 a31db67d 2004-04-21 devnull goto bad;
208 a31db67d 2004-04-21 devnull if(c < Char22) {
209 a31db67d 2004-04-21 devnull *rune = (c-Char21)*Esc + c1 + Rune21;
210 a31db67d 2004-04-21 devnull return 2;
214 a31db67d 2004-04-21 devnull * three character sequence
215 a31db67d 2004-04-21 devnull * 04016-38E2D => A6-FB; 21-7E/A0-FF
217 a31db67d 2004-04-21 devnull c2 = U[*(uchar*)(str+2)];
218 a31db67d 2004-04-21 devnull if(c2 >= Esc)
219 a31db67d 2004-04-21 devnull goto bad;
220 a31db67d 2004-04-21 devnull if(c < Char3) {
221 a31db67d 2004-04-21 devnull l = (c-Char22)*Esc*Esc + c1*Esc + c2 + Rune22;
222 a31db67d 2004-04-21 devnull if(l >= Rune3)
223 a31db67d 2004-04-21 devnull goto bad;
224 a31db67d 2004-04-21 devnull *rune = l;
225 a31db67d 2004-04-21 devnull return 3;
229 a31db67d 2004-04-21 devnull * bad decoding
232 a31db67d 2004-04-21 devnull *rune = Bad;
233 a31db67d 2004-04-21 devnull return 1;
237 a31db67d 2004-04-21 devnull runetoisoutf(char *str, Rune *rune)
241 a31db67d 2004-04-21 devnull if(T[0] == 0)
242 a31db67d 2004-04-21 devnull mktable();
245 a31db67d 2004-04-21 devnull * one character sequence
246 a31db67d 2004-04-21 devnull * 00000-0009F => 00-9F
248 a31db67d 2004-04-21 devnull c = *rune;
249 a31db67d 2004-04-21 devnull if(c < Rune1) {
250 a31db67d 2004-04-21 devnull str[0] = c;
251 a31db67d 2004-04-21 devnull return 1;
255 a31db67d 2004-04-21 devnull * two character sequence
256 a31db67d 2004-04-21 devnull * 000A0-000FF => A0; A0-FF
258 a31db67d 2004-04-21 devnull if(c < Rune21) {
259 b5932d3d 2005-03-18 devnull str[0] = (char)Char1;
260 a31db67d 2004-04-21 devnull str[1] = c;
261 a31db67d 2004-04-21 devnull return 2;
265 a31db67d 2004-04-21 devnull * two character sequence
266 a31db67d 2004-04-21 devnull * 00100-04015 => A1-F5; 21-7E/A0-FF
268 a31db67d 2004-04-21 devnull if(c < Rune22) {
269 a31db67d 2004-04-21 devnull c -= Rune21;
270 a31db67d 2004-04-21 devnull str[0] = c/Esc + Char21;
271 a31db67d 2004-04-21 devnull str[1] = T[c%Esc];
272 a31db67d 2004-04-21 devnull return 2;
276 a31db67d 2004-04-21 devnull * three character sequence
277 a31db67d 2004-04-21 devnull * 04016-38E2D => A6-FB; 21-7E/A0-FF
279 a31db67d 2004-04-21 devnull c -= Rune22;
280 a31db67d 2004-04-21 devnull str[0] = c/(Esc*Esc) + Char22;
281 a31db67d 2004-04-21 devnull str[1] = T[c/Esc%Esc];
282 a31db67d 2004-04-21 devnull str[2] = T[c%Esc];
283 a31db67d 2004-04-21 devnull return 3;
287 a31db67d 2004-04-21 devnull fullisorune(char *str, int n)
291 a31db67d 2004-04-21 devnull if(n > 0) {
292 a31db67d 2004-04-21 devnull c = *(uchar*)str;
293 a31db67d 2004-04-21 devnull if(c < Char1)
294 a31db67d 2004-04-21 devnull return 1;
295 a31db67d 2004-04-21 devnull if(n > 1)
296 a31db67d 2004-04-21 devnull if(c < Char22 || n > 2)
297 a31db67d 2004-04-21 devnull return 1;
299 a31db67d 2004-04-21 devnull return 0;
304 a31db67d 2004-04-21 devnull T1 = 0x00,
305 a31db67d 2004-04-21 devnull Tx = 0x80,
306 a31db67d 2004-04-21 devnull T2 = 0xC0,
307 a31db67d 2004-04-21 devnull T3 = 0xE0,
308 a31db67d 2004-04-21 devnull T4 = 0xF0,
309 a31db67d 2004-04-21 devnull T5 = 0xF8,
310 a31db67d 2004-04-21 devnull T6 = 0xFC,
312 a31db67d 2004-04-21 devnull Bit1 = 7,
313 a31db67d 2004-04-21 devnull Bitx = 6,
314 a31db67d 2004-04-21 devnull Bit2 = 5,
315 a31db67d 2004-04-21 devnull Bit3 = 4,
316 a31db67d 2004-04-21 devnull Bit4 = 3,
317 a31db67d 2004-04-21 devnull Bit5 = 2,
318 a31db67d 2004-04-21 devnull Bit6 = 2,
320 a31db67d 2004-04-21 devnull Mask1 = (1<<Bit1)-1,
321 a31db67d 2004-04-21 devnull Maskx = (1<<Bitx)-1,
322 a31db67d 2004-04-21 devnull Mask2 = (1<<Bit2)-1,
323 a31db67d 2004-04-21 devnull Mask3 = (1<<Bit3)-1,
324 a31db67d 2004-04-21 devnull Mask4 = (1<<Bit4)-1,
325 a31db67d 2004-04-21 devnull Mask5 = (1<<Bit5)-1,
326 a31db67d 2004-04-21 devnull Mask6 = (1<<Bit6)-1,
328 a31db67d 2004-04-21 devnull Wchar1 = (1UL<<Bit1)-1,
329 a31db67d 2004-04-21 devnull Wchar2 = (1UL<<(Bit2+Bitx))-1,
330 a31db67d 2004-04-21 devnull Wchar3 = (1UL<<(Bit3+2*Bitx))-1,
331 a31db67d 2004-04-21 devnull Wchar4 = (1UL<<(Bit4+3*Bitx))-1,
332 a31db67d 2004-04-21 devnull Wchar5 = (1UL<<(Bit5+4*Bitx))-1
336 a31db67d 2004-04-21 devnull our_wctomb(char *s, unsigned long wc)
338 a31db67d 2004-04-21 devnull if(s == 0)
339 a31db67d 2004-04-21 devnull return 0; /* no shift states */
340 a31db67d 2004-04-21 devnull if(wc & ~Wchar2) {
341 a31db67d 2004-04-21 devnull if(wc & ~Wchar4) {
342 a31db67d 2004-04-21 devnull if(wc & ~Wchar5) {
343 a31db67d 2004-04-21 devnull /* 6 bytes */
344 a31db67d 2004-04-21 devnull s[0] = T6 | ((wc >> 5*Bitx) & Mask6);
345 a31db67d 2004-04-21 devnull s[1] = Tx | ((wc >> 4*Bitx) & Maskx);
346 a31db67d 2004-04-21 devnull s[2] = Tx | ((wc >> 3*Bitx) & Maskx);
347 a31db67d 2004-04-21 devnull s[3] = Tx | ((wc >> 2*Bitx) & Maskx);
348 a31db67d 2004-04-21 devnull s[4] = Tx | ((wc >> 1*Bitx) & Maskx);
349 a31db67d 2004-04-21 devnull s[5] = Tx | (wc & Maskx);
350 a31db67d 2004-04-21 devnull return 6;
352 a31db67d 2004-04-21 devnull /* 5 bytes */
353 a31db67d 2004-04-21 devnull s[0] = T5 | (wc >> 4*Bitx);
354 a31db67d 2004-04-21 devnull s[1] = Tx | ((wc >> 3*Bitx) & Maskx);
355 a31db67d 2004-04-21 devnull s[2] = Tx | ((wc >> 2*Bitx) & Maskx);
356 a31db67d 2004-04-21 devnull s[3] = Tx | ((wc >> 1*Bitx) & Maskx);
357 a31db67d 2004-04-21 devnull s[4] = Tx | (wc & Maskx);
358 a31db67d 2004-04-21 devnull return 5;
360 a31db67d 2004-04-21 devnull if(wc & ~Wchar3) {
361 a31db67d 2004-04-21 devnull /* 4 bytes */
362 a31db67d 2004-04-21 devnull s[0] = T4 | (wc >> 3*Bitx);
363 a31db67d 2004-04-21 devnull s[1] = Tx | ((wc >> 2*Bitx) & Maskx);
364 a31db67d 2004-04-21 devnull s[2] = Tx | ((wc >> 1*Bitx) & Maskx);
365 a31db67d 2004-04-21 devnull s[3] = Tx | (wc & Maskx);
366 a31db67d 2004-04-21 devnull return 4;
368 a31db67d 2004-04-21 devnull /* 3 bytes */
369 a31db67d 2004-04-21 devnull s[0] = T3 | (wc >> 2*Bitx);
370 a31db67d 2004-04-21 devnull s[1] = Tx | ((wc >> 1*Bitx) & Maskx);
371 a31db67d 2004-04-21 devnull s[2] = Tx | (wc & Maskx);
372 a31db67d 2004-04-21 devnull return 3;
374 a31db67d 2004-04-21 devnull if(wc & ~Wchar1) {
375 a31db67d 2004-04-21 devnull /* 2 bytes */
376 a31db67d 2004-04-21 devnull s[0] = T2 | (wc >> 1*Bitx);
377 a31db67d 2004-04-21 devnull s[1] = Tx | (wc & Maskx);
378 a31db67d 2004-04-21 devnull return 2;
380 a31db67d 2004-04-21 devnull /* 1 byte */
381 a31db67d 2004-04-21 devnull s[0] = T1 | wc;
382 a31db67d 2004-04-21 devnull return 1;
386 a31db67d 2004-04-21 devnull our_mbtowc(unsigned long *p, char *s, unsigned n)
388 a31db67d 2004-04-21 devnull uchar *us;
389 a31db67d 2004-04-21 devnull int c0, c1, c2, c3, c4, c5;
390 a31db67d 2004-04-21 devnull unsigned long wc;
392 a31db67d 2004-04-21 devnull if(s == 0)
393 a31db67d 2004-04-21 devnull return 0; /* no shift states */
395 a31db67d 2004-04-21 devnull if(n < 1)
396 a31db67d 2004-04-21 devnull goto badlen;
397 a31db67d 2004-04-21 devnull us = (uchar*)s;
398 a31db67d 2004-04-21 devnull c0 = us[0];
399 a31db67d 2004-04-21 devnull if(c0 >= T3) {
400 a31db67d 2004-04-21 devnull if(n < 3)
401 a31db67d 2004-04-21 devnull goto badlen;
402 a31db67d 2004-04-21 devnull c1 = us[1] ^ Tx;
403 a31db67d 2004-04-21 devnull c2 = us[2] ^ Tx;
404 a31db67d 2004-04-21 devnull if((c1|c2) & T2)
405 a31db67d 2004-04-21 devnull goto bad;
406 a31db67d 2004-04-21 devnull if(c0 >= T5) {
407 a31db67d 2004-04-21 devnull if(n < 5)
408 a31db67d 2004-04-21 devnull goto badlen;
409 a31db67d 2004-04-21 devnull c3 = us[3] ^ Tx;
410 a31db67d 2004-04-21 devnull c4 = us[4] ^ Tx;
411 a31db67d 2004-04-21 devnull if((c3|c4) & T2)
412 a31db67d 2004-04-21 devnull goto bad;
413 a31db67d 2004-04-21 devnull if(c0 >= T6) {
414 a31db67d 2004-04-21 devnull /* 6 bytes */
415 a31db67d 2004-04-21 devnull if(n < 6)
416 a31db67d 2004-04-21 devnull goto badlen;
417 a31db67d 2004-04-21 devnull c5 = us[5] ^ Tx;
418 a31db67d 2004-04-21 devnull if(c5 & T2)
419 a31db67d 2004-04-21 devnull goto bad;
420 a31db67d 2004-04-21 devnull wc = ((((((((((c0 & Mask6) << Bitx) |
421 a31db67d 2004-04-21 devnull c1) << Bitx) | c2) << Bitx) |
422 a31db67d 2004-04-21 devnull c3) << Bitx) | c4) << Bitx) | c5;
423 a31db67d 2004-04-21 devnull if(wc <= Wchar5)
424 a31db67d 2004-04-21 devnull goto bad;
425 a31db67d 2004-04-21 devnull *p = wc;
426 a31db67d 2004-04-21 devnull return 6;
428 a31db67d 2004-04-21 devnull /* 5 bytes */
429 a31db67d 2004-04-21 devnull wc = ((((((((c0 & Mask5) << Bitx) |
430 a31db67d 2004-04-21 devnull c1) << Bitx) | c2) << Bitx) |
431 a31db67d 2004-04-21 devnull c3) << Bitx) | c4;
432 a31db67d 2004-04-21 devnull if(wc <= Wchar4)
433 a31db67d 2004-04-21 devnull goto bad;
434 a31db67d 2004-04-21 devnull *p = wc;
435 a31db67d 2004-04-21 devnull return 5;
437 a31db67d 2004-04-21 devnull if(c0 >= T4) {
438 a31db67d 2004-04-21 devnull /* 4 bytes */
439 a31db67d 2004-04-21 devnull if(n < 4)
440 a31db67d 2004-04-21 devnull goto badlen;
441 a31db67d 2004-04-21 devnull c3 = us[3] ^ Tx;
442 a31db67d 2004-04-21 devnull if(c3 & T2)
443 a31db67d 2004-04-21 devnull goto bad;
444 a31db67d 2004-04-21 devnull wc = ((((((c0 & Mask4) << Bitx) |
445 a31db67d 2004-04-21 devnull c1) << Bitx) | c2) << Bitx) |
447 a31db67d 2004-04-21 devnull if(wc <= Wchar3)
448 a31db67d 2004-04-21 devnull goto bad;
449 a31db67d 2004-04-21 devnull *p = wc;
450 a31db67d 2004-04-21 devnull return 4;
452 a31db67d 2004-04-21 devnull /* 3 bytes */
453 a31db67d 2004-04-21 devnull wc = ((((c0 & Mask3) << Bitx) |
454 a31db67d 2004-04-21 devnull c1) << Bitx) | c2;
455 a31db67d 2004-04-21 devnull if(wc <= Wchar2)
456 a31db67d 2004-04-21 devnull goto bad;
457 a31db67d 2004-04-21 devnull *p = wc;
458 a31db67d 2004-04-21 devnull return 3;
460 a31db67d 2004-04-21 devnull if(c0 >= T2) {
461 a31db67d 2004-04-21 devnull /* 2 bytes */
462 a31db67d 2004-04-21 devnull if(n < 2)
463 a31db67d 2004-04-21 devnull goto badlen;
464 a31db67d 2004-04-21 devnull c1 = us[1] ^ Tx;
465 a31db67d 2004-04-21 devnull if(c1 & T2)
466 a31db67d 2004-04-21 devnull goto bad;
467 a31db67d 2004-04-21 devnull wc = ((c0 & Mask2) << Bitx) |
469 a31db67d 2004-04-21 devnull if(wc <= Wchar1)
470 a31db67d 2004-04-21 devnull goto bad;
471 a31db67d 2004-04-21 devnull *p = wc;
472 a31db67d 2004-04-21 devnull return 2;
474 a31db67d 2004-04-21 devnull /* 1 byte */
475 a31db67d 2004-04-21 devnull if(c0 >= Tx)
476 a31db67d 2004-04-21 devnull goto bad;
477 a31db67d 2004-04-21 devnull *p = c0;
478 a31db67d 2004-04-21 devnull return 1;
481 a31db67d 2004-04-21 devnull errno = EILSEQ;
482 a31db67d 2004-04-21 devnull return -1;
484 a31db67d 2004-04-21 devnull return -2;