Cygwin: mmap: allow remapping part of an existing anonymous mapping
[newlib-cygwin.git] / newlib / libc / stdlib / mbtowc_r.c
blobcab8333d70df96c3d3d7741badedf9a1cc57001e
1 #include <newlib.h>
2 #include <stdlib.h>
3 #include <locale.h>
4 #include "mbctype.h"
5 #include <wchar.h>
6 #include <string.h>
7 #include <errno.h>
8 #include "local.h"
10 int
11 _mbtowc_r (struct _reent *r,
12 wchar_t *__restrict pwc,
13 const char *__restrict s,
14 size_t n,
15 mbstate_t *state)
17 return __MBTOWC (r, pwc, s, n, state);
20 int
21 __ascii_mbtowc (struct _reent *r,
22 wchar_t *pwc,
23 const char *s,
24 size_t n,
25 mbstate_t *state)
27 wchar_t dummy;
28 unsigned char *t = (unsigned char *)s;
30 if (pwc == NULL)
31 pwc = &dummy;
33 if (s == NULL)
34 return 0;
36 if (n == 0)
37 return -2;
39 *pwc = (wchar_t)*t;
41 if (*t == '\0')
42 return 0;
44 return 1;
47 #ifdef _MB_CAPABLE
48 typedef enum __packed { ESCAPE, DOLLAR, BRACKET, AT, B, J,
49 NUL, JIS_CHAR, OTHER, JIS_C_NUM } JIS_CHAR_TYPE;
50 typedef enum __packed { ASCII, JIS, A_ESC, A_ESC_DL, JIS_1, J_ESC, J_ESC_BR,
51 INV, JIS_S_NUM } JIS_STATE;
52 typedef enum __packed { COPY_A, COPY_J1, COPY_J2, MAKE_A, NOOP, EMPTY, ERROR } JIS_ACTION;
54 /**************************************************************************************
55 * state/action tables for processing JIS encoding
56 * Where possible, switches to JIS are grouped with proceding JIS characters and switches
57 * to ASCII are grouped with preceding JIS characters. Thus, maximum returned length
58 * is 2 (switch to JIS) + 2 (JIS characters) + 2 (switch back to ASCII) = 6.
59 *************************************************************************************/
61 #ifndef __CYGWIN__
62 static JIS_STATE JIS_state_table[JIS_S_NUM][JIS_C_NUM] = {
63 /* ESCAPE DOLLAR BRACKET AT B J NUL JIS_CHAR OTHER */
64 /* ASCII */ { A_ESC, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII },
65 /* JIS */ { J_ESC, JIS_1, JIS_1, JIS_1, JIS_1, JIS_1, INV, JIS_1, INV },
66 /* A_ESC */ { ASCII, A_ESC_DL, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII },
67 /* A_ESC_DL */{ ASCII, ASCII, ASCII, JIS, JIS, ASCII, ASCII, ASCII, ASCII },
68 /* JIS_1 */ { INV, JIS, JIS, JIS, JIS, JIS, INV, JIS, INV },
69 /* J_ESC */ { INV, INV, J_ESC_BR, INV, INV, INV, INV, INV, INV },
70 /* J_ESC_BR */{ INV, INV, INV, INV, ASCII, ASCII, INV, INV, INV },
73 static JIS_ACTION JIS_action_table[JIS_S_NUM][JIS_C_NUM] = {
74 /* ESCAPE DOLLAR BRACKET AT B J NUL JIS_CHAR OTHER */
75 /* ASCII */ { NOOP, COPY_A, COPY_A, COPY_A, COPY_A, COPY_A, EMPTY, COPY_A, COPY_A},
76 /* JIS */ { NOOP, COPY_J1, COPY_J1, COPY_J1, COPY_J1, COPY_J1, ERROR, COPY_J1, ERROR },
77 /* A_ESC */ { COPY_A, NOOP, COPY_A, COPY_A, COPY_A, COPY_A, COPY_A, COPY_A, COPY_A},
78 /* A_ESC_DL */{ COPY_A, COPY_A, COPY_A, NOOP, NOOP, COPY_A, COPY_A, COPY_A, COPY_A},
79 /* JIS_1 */ { ERROR, COPY_J2, COPY_J2, COPY_J2, COPY_J2, COPY_J2, ERROR, COPY_J2, ERROR },
80 /* J_ESC */ { ERROR, ERROR, NOOP, ERROR, ERROR, ERROR, ERROR, ERROR, ERROR },
81 /* J_ESC_BR */{ ERROR, ERROR, ERROR, ERROR, MAKE_A, MAKE_A, ERROR, ERROR, ERROR },
83 #endif /* !__CYGWIN__ */
85 /* we override the mbstate_t __count field for more complex encodings and use it store a state value */
86 #define __state __count
88 #ifdef _MB_EXTENDED_CHARSETS_ISO
89 static int
90 ___iso_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
91 int iso_idx, mbstate_t *state)
93 wchar_t dummy;
94 unsigned char *t = (unsigned char *)s;
96 if (pwc == NULL)
97 pwc = &dummy;
99 if (s == NULL)
100 return 0;
102 if (n == 0)
103 return -2;
105 if (*t >= 0xa0)
107 if (iso_idx >= 0)
109 *pwc = __iso_8859_conv[iso_idx][*t - 0xa0];
110 if (*pwc == 0) /* Invalid character */
112 _REENT_ERRNO(r) = EILSEQ;
113 return -1;
115 return 1;
119 *pwc = (wchar_t) *t;
121 if (*t == '\0')
122 return 0;
124 return 1;
127 static int
128 __iso_8859_1_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
129 mbstate_t *state)
131 return ___iso_mbtowc (r, pwc, s, n, -1, state);
134 static int
135 __iso_8859_2_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
136 mbstate_t *state)
138 return ___iso_mbtowc (r, pwc, s, n, 0, state);
141 static int
142 __iso_8859_3_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
143 mbstate_t *state)
145 return ___iso_mbtowc (r, pwc, s, n, 1, state);
148 static int
149 __iso_8859_4_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
150 mbstate_t *state)
152 return ___iso_mbtowc (r, pwc, s, n, 2, state);
155 static int
156 __iso_8859_5_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
157 mbstate_t *state)
159 return ___iso_mbtowc (r, pwc, s, n, 3, state);
162 static int
163 __iso_8859_6_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
164 mbstate_t *state)
166 return ___iso_mbtowc (r, pwc, s, n, 4, state);
169 static int
170 __iso_8859_7_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
171 mbstate_t *state)
173 return ___iso_mbtowc (r, pwc, s, n, 5, state);
176 static int
177 __iso_8859_8_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
178 mbstate_t *state)
180 return ___iso_mbtowc (r, pwc, s, n, 6, state);
183 static int
184 __iso_8859_9_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
185 mbstate_t *state)
187 return ___iso_mbtowc (r, pwc, s, n, 7, state);
190 static int
191 __iso_8859_10_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
192 mbstate_t *state)
194 return ___iso_mbtowc (r, pwc, s, n, 8, state);
197 static int
198 __iso_8859_11_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
199 mbstate_t *state)
201 return ___iso_mbtowc (r, pwc, s, n, 9, state);
204 static int
205 __iso_8859_13_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
206 mbstate_t *state)
208 return ___iso_mbtowc (r, pwc, s, n, 10, state);
211 static int
212 __iso_8859_14_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
213 mbstate_t *state)
215 return ___iso_mbtowc (r, pwc, s, n, 11, state);
218 static int
219 __iso_8859_15_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
220 mbstate_t *state)
222 return ___iso_mbtowc (r, pwc, s, n, 12, state);
225 static int
226 __iso_8859_16_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
227 mbstate_t *state)
229 return ___iso_mbtowc (r, pwc, s, n, 13, state);
232 static mbtowc_p __iso_8859_mbtowc[17] = {
233 NULL,
234 __iso_8859_1_mbtowc,
235 __iso_8859_2_mbtowc,
236 __iso_8859_3_mbtowc,
237 __iso_8859_4_mbtowc,
238 __iso_8859_5_mbtowc,
239 __iso_8859_6_mbtowc,
240 __iso_8859_7_mbtowc,
241 __iso_8859_8_mbtowc,
242 __iso_8859_9_mbtowc,
243 __iso_8859_10_mbtowc,
244 __iso_8859_11_mbtowc,
245 NULL, /* No ISO 8859-12 */
246 __iso_8859_13_mbtowc,
247 __iso_8859_14_mbtowc,
248 __iso_8859_15_mbtowc,
249 __iso_8859_16_mbtowc
252 /* val *MUST* be valid! All checks for validity are supposed to be
253 performed before calling this function. */
254 mbtowc_p
255 __iso_mbtowc (int val)
257 return __iso_8859_mbtowc[val];
259 #endif /* _MB_EXTENDED_CHARSETS_ISO */
261 #ifdef _MB_EXTENDED_CHARSETS_WINDOWS
262 static int
263 ___cp_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
264 int cp_idx, mbstate_t *state)
266 wchar_t dummy;
267 unsigned char *t = (unsigned char *)s;
269 if (pwc == NULL)
270 pwc = &dummy;
272 if (s == NULL)
273 return 0;
275 if (n == 0)
276 return -2;
278 if (*t >= 0x80)
280 if (cp_idx >= 0)
282 *pwc = __cp_conv[cp_idx][*t - 0x80];
283 if (*pwc == 0) /* Invalid character */
285 _REENT_ERRNO(r) = EILSEQ;
286 return -1;
288 return 1;
292 *pwc = (wchar_t)*t;
294 if (*t == '\0')
295 return 0;
297 return 1;
300 static int
301 __cp_437_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
302 mbstate_t *state)
304 return ___cp_mbtowc (r, pwc, s, n, 0, state);
307 static int
308 __cp_720_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
309 mbstate_t *state)
311 return ___cp_mbtowc (r, pwc, s, n, 1, state);
314 static int
315 __cp_737_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
316 mbstate_t *state)
318 return ___cp_mbtowc (r, pwc, s, n, 2, state);
321 static int
322 __cp_775_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
323 mbstate_t *state)
325 return ___cp_mbtowc (r, pwc, s, n, 3, state);
328 static int
329 __cp_850_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
330 mbstate_t *state)
332 return ___cp_mbtowc (r, pwc, s, n, 4, state);
335 static int
336 __cp_852_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
337 mbstate_t *state)
339 return ___cp_mbtowc (r, pwc, s, n, 5, state);
342 static int
343 __cp_855_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
344 mbstate_t *state)
346 return ___cp_mbtowc (r, pwc, s, n, 6, state);
349 static int
350 __cp_857_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
351 mbstate_t *state)
353 return ___cp_mbtowc (r, pwc, s, n, 7, state);
356 static int
357 __cp_858_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
358 mbstate_t *state)
360 return ___cp_mbtowc (r, pwc, s, n, 8, state);
363 static int
364 __cp_862_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
365 mbstate_t *state)
367 return ___cp_mbtowc (r, pwc, s, n, 9, state);
370 static int
371 __cp_866_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
372 mbstate_t *state)
374 return ___cp_mbtowc (r, pwc, s, n, 10, state);
377 static int
378 __cp_874_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
379 mbstate_t *state)
381 return ___cp_mbtowc (r, pwc, s, n, 11, state);
384 static int
385 __cp_1125_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
386 mbstate_t *state)
388 return ___cp_mbtowc (r, pwc, s, n, 12, state);
391 static int
392 __cp_1250_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
393 mbstate_t *state)
395 return ___cp_mbtowc (r, pwc, s, n, 13, state);
398 static int
399 __cp_1251_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
400 mbstate_t *state)
402 return ___cp_mbtowc (r, pwc, s, n, 14, state);
405 static int
406 __cp_1252_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
407 mbstate_t *state)
409 return ___cp_mbtowc (r, pwc, s, n, 15, state);
412 static int
413 __cp_1253_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
414 mbstate_t *state)
416 return ___cp_mbtowc (r, pwc, s, n, 16, state);
419 static int
420 __cp_1254_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
421 mbstate_t *state)
423 return ___cp_mbtowc (r, pwc, s, n, 17, state);
426 static int
427 __cp_1255_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
428 mbstate_t *state)
430 return ___cp_mbtowc (r, pwc, s, n, 18, state);
433 static int
434 __cp_1256_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
435 mbstate_t *state)
437 return ___cp_mbtowc (r, pwc, s, n, 19, state);
440 static int
441 __cp_1257_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
442 mbstate_t *state)
444 return ___cp_mbtowc (r, pwc, s, n, 20, state);
447 static int
448 __cp_1258_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
449 mbstate_t *state)
451 return ___cp_mbtowc (r, pwc, s, n, 21, state);
454 static int
455 __cp_20866_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
456 mbstate_t *state)
458 return ___cp_mbtowc (r, pwc, s, n, 22, state);
461 static int
462 __cp_21866_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
463 mbstate_t *state)
465 return ___cp_mbtowc (r, pwc, s, n, 23, state);
468 static int
469 __cp_101_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
470 mbstate_t *state)
472 return ___cp_mbtowc (r, pwc, s, n, 24, state);
475 static int
476 __cp_102_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
477 mbstate_t *state)
479 return ___cp_mbtowc (r, pwc, s, n, 25, state);
482 static int
483 __cp_103_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
484 mbstate_t *state)
486 return ___cp_mbtowc (r, pwc, s, n, 26, state);
489 static mbtowc_p __cp_xxx_mbtowc[27] = {
490 __cp_437_mbtowc,
491 __cp_720_mbtowc,
492 __cp_737_mbtowc,
493 __cp_775_mbtowc,
494 __cp_850_mbtowc,
495 __cp_852_mbtowc,
496 __cp_855_mbtowc,
497 __cp_857_mbtowc,
498 __cp_858_mbtowc,
499 __cp_862_mbtowc,
500 __cp_866_mbtowc,
501 __cp_874_mbtowc,
502 __cp_1125_mbtowc,
503 __cp_1250_mbtowc,
504 __cp_1251_mbtowc,
505 __cp_1252_mbtowc,
506 __cp_1253_mbtowc,
507 __cp_1254_mbtowc,
508 __cp_1255_mbtowc,
509 __cp_1256_mbtowc,
510 __cp_1257_mbtowc,
511 __cp_1258_mbtowc,
512 __cp_20866_mbtowc,
513 __cp_21866_mbtowc,
514 __cp_101_mbtowc,
515 __cp_102_mbtowc,
516 __cp_103_mbtowc,
519 /* val *MUST* be valid! All checks for validity are supposed to be
520 performed before calling this function. */
521 mbtowc_p
522 __cp_mbtowc (int val)
524 return __cp_xxx_mbtowc[__cp_val_index (val)];
526 #endif /* _MB_EXTENDED_CHARSETS_WINDOWS */
529 __utf8_mbtowc (struct _reent *r,
530 wchar_t *pwc,
531 const char *s,
532 size_t n,
533 mbstate_t *state)
535 wchar_t dummy;
536 unsigned char *t = (unsigned char *)s;
537 int ch;
538 int i = 0;
540 if (pwc == NULL)
541 pwc = &dummy;
543 if (s == NULL)
544 return 0;
546 if (n == 0)
547 return -2;
549 if (state->__count == 0)
550 ch = t[i++];
551 else
552 ch = state->__value.__wchb[0];
554 if (ch == '\0')
556 *pwc = 0;
557 state->__count = 0;
558 return 0; /* s points to the null character */
561 if (ch <= 0x7f)
563 /* single-byte sequence */
564 state->__count = 0;
565 *pwc = ch;
566 return 1;
568 if (ch >= 0xc0 && ch <= 0xdf)
570 /* two-byte sequence */
571 state->__value.__wchb[0] = ch;
572 if (state->__count == 0)
573 state->__count = 1;
574 else if (n < (size_t)-1)
575 ++n;
576 if (n < 2)
577 return -2;
578 ch = t[i++];
579 if (ch < 0x80 || ch > 0xbf)
581 _REENT_ERRNO(r) = EILSEQ;
582 return -1;
584 if (state->__value.__wchb[0] < 0xc2)
586 /* overlong UTF-8 sequence */
587 _REENT_ERRNO(r) = EILSEQ;
588 return -1;
590 state->__count = 0;
591 *pwc = (wchar_t)((state->__value.__wchb[0] & 0x1f) << 6)
592 | (wchar_t)(ch & 0x3f);
593 return i;
595 if (ch >= 0xe0 && ch <= 0xef)
597 /* three-byte sequence */
598 wchar_t tmp;
599 state->__value.__wchb[0] = ch;
600 if (state->__count == 0)
601 state->__count = 1;
602 else if (n < (size_t)-1)
603 ++n;
604 if (n < 2)
605 return -2;
606 ch = (state->__count == 1) ? t[i++] : state->__value.__wchb[1];
607 if (state->__value.__wchb[0] == 0xe0 && ch < 0xa0)
609 /* overlong UTF-8 sequence */
610 _REENT_ERRNO(r) = EILSEQ;
611 return -1;
613 if (ch < 0x80 || ch > 0xbf)
615 _REENT_ERRNO(r) = EILSEQ;
616 return -1;
618 state->__value.__wchb[1] = ch;
619 if (state->__count == 1)
620 state->__count = 2;
621 else if (n < (size_t)-1)
622 ++n;
623 if (n < 3)
624 return -2;
625 ch = t[i++];
626 if (ch < 0x80 || ch > 0xbf)
628 _REENT_ERRNO(r) = EILSEQ;
629 return -1;
631 state->__count = 0;
632 tmp = (wchar_t)((state->__value.__wchb[0] & 0x0f) << 12)
633 | (wchar_t)((state->__value.__wchb[1] & 0x3f) << 6)
634 | (wchar_t)(ch & 0x3f);
635 *pwc = tmp;
636 return i;
638 if (ch >= 0xf0 && ch <= 0xf4)
640 /* four-byte sequence */
641 wint_t tmp;
642 state->__value.__wchb[0] = ch;
643 if (state->__count == 0)
644 state->__count = 1;
645 else if (n < (size_t)-1)
646 ++n;
647 if (n < 2)
648 return -2;
649 ch = (state->__count == 1) ? t[i++] : state->__value.__wchb[1];
650 if ((state->__value.__wchb[0] == 0xf0 && ch < 0x90)
651 || (state->__value.__wchb[0] == 0xf4 && ch >= 0x90))
653 /* overlong UTF-8 sequence or result is > 0x10ffff */
654 _REENT_ERRNO(r) = EILSEQ;
655 return -1;
657 if (ch < 0x80 || ch > 0xbf)
659 _REENT_ERRNO(r) = EILSEQ;
660 return -1;
662 state->__value.__wchb[1] = ch;
663 if (state->__count == 1)
664 state->__count = 2;
665 else if (n < (size_t)-1)
666 ++n;
667 if (n < 3)
668 return -2;
669 ch = (state->__count == 2) ? t[i++] : state->__value.__wchb[2];
670 if (ch < 0x80 || ch > 0xbf)
672 _REENT_ERRNO(r) = EILSEQ;
673 return -1;
675 state->__value.__wchb[2] = ch;
676 if (state->__count == 2)
677 state->__count = 3;
678 else if (n < (size_t)-1)
679 ++n;
680 if (state->__count == 3 && sizeof(wchar_t) == 2)
682 /* On systems which have wchar_t being UTF-16 values, the value
683 doesn't fit into a single wchar_t in this case. So what we
684 do here is to store the state with a special value of __count
685 and return the first half of a surrogate pair. The first
686 three bytes of a UTF-8 sequence are enough to generate the
687 first half of a UTF-16 surrogate pair. As return value we
688 choose to return the number of bytes actually read up to
689 here.
690 The second half of the surrogate pair is returned in case we
691 recognize the special __count value of four, and the next
692 byte is actually a valid value. See below. */
693 tmp = (wint_t)((state->__value.__wchb[0] & 0x07) << 18)
694 | (wint_t)((state->__value.__wchb[1] & 0x3f) << 12)
695 | (wint_t)((state->__value.__wchb[2] & 0x3f) << 6);
696 state->__count = 4;
697 *pwc = 0xd800 | ((tmp - 0x10000) >> 10);
698 return i;
700 if (n < 4)
701 return -2;
702 ch = t[i++];
703 if (ch < 0x80 || ch > 0xbf)
705 _REENT_ERRNO(r) = EILSEQ;
706 return -1;
708 tmp = (wint_t)((state->__value.__wchb[0] & 0x07) << 18)
709 | (wint_t)((state->__value.__wchb[1] & 0x3f) << 12)
710 | (wint_t)((state->__value.__wchb[2] & 0x3f) << 6)
711 | (wint_t)(ch & 0x3f);
712 if (state->__count == 4 && sizeof(wchar_t) == 2)
713 /* Create the second half of the surrogate pair for systems with
714 wchar_t == UTF-16 . */
715 *pwc = 0xdc00 | (tmp & 0x3ff);
716 else
717 *pwc = tmp;
718 state->__count = 0;
719 return i;
722 _REENT_ERRNO(r) = EILSEQ;
723 return -1;
726 /* Cygwin defines its own doublebyte charset conversion functions
727 because the underlying OS requires wchar_t == UTF-16. */
728 #ifndef __CYGWIN__
730 __sjis_mbtowc (struct _reent *r,
731 wchar_t *pwc,
732 const char *s,
733 size_t n,
734 mbstate_t *state)
736 wchar_t dummy;
737 unsigned char *t = (unsigned char *)s;
738 int ch;
739 int i = 0;
741 if (pwc == NULL)
742 pwc = &dummy;
744 if (s == NULL)
745 return 0; /* not state-dependent */
747 if (n == 0)
748 return -2;
750 ch = t[i++];
751 if (state->__count == 0)
753 if (_issjis1 (ch))
755 state->__value.__wchb[0] = ch;
756 state->__count = 1;
757 if (n <= 1)
758 return -2;
759 ch = t[i++];
762 if (state->__count == 1)
764 if (_issjis2 (ch))
766 *pwc = (((wchar_t)state->__value.__wchb[0]) << 8) + (wchar_t)ch;
767 state->__count = 0;
768 return i;
770 else
772 _REENT_ERRNO(r) = EILSEQ;
773 return -1;
777 *pwc = (wchar_t)*t;
779 if (*t == '\0')
780 return 0;
782 return 1;
786 __eucjp_mbtowc (struct _reent *r,
787 wchar_t *pwc,
788 const char *s,
789 size_t n,
790 mbstate_t *state)
792 wchar_t dummy;
793 unsigned char *t = (unsigned char *)s;
794 int ch;
795 int i = 0;
797 if (pwc == NULL)
798 pwc = &dummy;
800 if (s == NULL)
801 return 0;
803 if (n == 0)
804 return -2;
806 ch = t[i++];
807 if (state->__count == 0)
809 if (_iseucjp1 (ch))
811 state->__value.__wchb[0] = ch;
812 state->__count = 1;
813 if (n <= 1)
814 return -2;
815 ch = t[i++];
818 if (state->__count == 1)
820 if (_iseucjp2 (ch))
822 if (state->__value.__wchb[0] == 0x8f)
824 state->__value.__wchb[1] = ch;
825 state->__count = 2;
826 if (n <= i)
827 return -2;
828 ch = t[i++];
830 else
832 *pwc = (((wchar_t)state->__value.__wchb[0]) << 8) + (wchar_t)ch;
833 state->__count = 0;
834 return i;
837 else
839 _REENT_ERRNO(r) = EILSEQ;
840 return -1;
843 if (state->__count == 2)
845 if (_iseucjp2 (ch))
847 *pwc = (((wchar_t)state->__value.__wchb[1]) << 8)
848 + (wchar_t)(ch & 0x7f);
849 state->__count = 0;
850 return i;
852 else
854 _REENT_ERRNO(r) = EILSEQ;
855 return -1;
859 *pwc = (wchar_t)*t;
861 if (*t == '\0')
862 return 0;
864 return 1;
868 __jis_mbtowc (struct _reent *r,
869 wchar_t *pwc,
870 const char *s,
871 size_t n,
872 mbstate_t *state)
874 wchar_t dummy;
875 unsigned char *t = (unsigned char *)s;
876 JIS_STATE curr_state;
877 JIS_ACTION action;
878 JIS_CHAR_TYPE ch;
879 unsigned char *ptr;
880 unsigned int i;
881 int curr_ch;
883 if (pwc == NULL)
884 pwc = &dummy;
886 if (s == NULL)
888 state->__state = ASCII;
889 return 1; /* state-dependent */
892 if (n == 0)
893 return -2;
895 curr_state = state->__state;
896 ptr = t;
898 for (i = 0; i < n; ++i)
900 curr_ch = t[i];
901 switch (curr_ch)
903 case ESC_CHAR:
904 ch = ESCAPE;
905 break;
906 case '$':
907 ch = DOLLAR;
908 break;
909 case '@':
910 ch = AT;
911 break;
912 case '(':
913 ch = BRACKET;
914 break;
915 case 'B':
916 ch = B;
917 break;
918 case 'J':
919 ch = J;
920 break;
921 case '\0':
922 ch = NUL;
923 break;
924 default:
925 if (_isjis (curr_ch))
926 ch = JIS_CHAR;
927 else
928 ch = OTHER;
931 action = JIS_action_table[curr_state][ch];
932 curr_state = JIS_state_table[curr_state][ch];
934 switch (action)
936 case NOOP:
937 break;
938 case EMPTY:
939 state->__state = ASCII;
940 *pwc = (wchar_t)0;
941 return 0;
942 case COPY_A:
943 state->__state = ASCII;
944 *pwc = (wchar_t)*ptr;
945 return (i + 1);
946 case COPY_J1:
947 state->__value.__wchb[0] = t[i];
948 break;
949 case COPY_J2:
950 state->__state = JIS;
951 *pwc = (((wchar_t)state->__value.__wchb[0]) << 8) + (wchar_t)(t[i]);
952 return (i + 1);
953 case MAKE_A:
954 ptr = (unsigned char *)(t + i + 1);
955 break;
956 case ERROR:
957 default:
958 _REENT_ERRNO(r) = EILSEQ;
959 return -1;
964 state->__state = curr_state;
965 return -2; /* n < bytes needed */
967 #endif /* !__CYGWIN__*/
968 #endif /* _MB_CAPABLE */