Cygwin: mmap: allow remapping part of an existing anonymous mapping
[newlib-cygwin.git] / newlib / libc / stdlib / wctomb_r.c
blob5ea1e13e48a3b81b82c5b63c22448a7c616b8cdd
1 #include <errno.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <wchar.h>
5 #include <locale.h>
6 #include "mbctype.h"
7 #include "local.h"
9 int
10 _wctomb_r (struct _reent *r,
11 char *s,
12 wchar_t _wchar,
13 mbstate_t *state)
15 return __WCTOMB (r, s, _wchar, state);
18 int
19 __ascii_wctomb (struct _reent *r,
20 char *s,
21 wchar_t _wchar,
22 mbstate_t *state)
24 /* Avoids compiler warnings about comparisons that are always false
25 due to limited range when sizeof(wchar_t) is 2 but sizeof(wint_t)
26 is 4, as is the case on cygwin. */
27 wint_t wchar = _wchar;
29 if (s == NULL)
30 return 0;
32 if ((size_t)wchar >= 0x100)
34 _REENT_ERRNO(r) = EILSEQ;
35 return -1;
38 *s = (char) wchar;
39 return 1;
42 #ifdef _MB_CAPABLE
43 /* for some conversions, we use the __count field as a place to store a state value */
44 #define __state __count
46 int
47 __utf8_wctomb (struct _reent *r,
48 char *s,
49 wchar_t _wchar,
50 mbstate_t *state)
52 wint_t wchar = _wchar;
53 int ret = 0;
55 if (s == NULL)
56 return 0; /* UTF-8 encoding is not state-dependent */
58 if (sizeof (wchar_t) == 2 && state->__count == -4
59 && (wchar < 0xdc00 || wchar > 0xdfff))
61 /* There's a leftover lone high surrogate. Write out the CESU-8 value
62 of the surrogate and proceed to convert the given character. Note
63 to return extra 3 bytes. */
64 wchar_t tmp;
65 tmp = (state->__value.__wchb[0] << 16 | state->__value.__wchb[1] << 8)
66 - (0x10000 >> 10 | 0xd80d);
67 *s++ = 0xe0 | ((tmp & 0xf000) >> 12);
68 *s++ = 0x80 | ((tmp & 0xfc0) >> 6);
69 *s++ = 0x80 | (tmp & 0x3f);
70 state->__count = 0;
71 ret = 3;
73 if (wchar <= 0x7f)
75 *s = wchar;
76 return ret + 1;
78 if (wchar >= 0x80 && wchar <= 0x7ff)
80 *s++ = 0xc0 | ((wchar & 0x7c0) >> 6);
81 *s = 0x80 | (wchar & 0x3f);
82 return ret + 2;
84 if (wchar >= 0x800 && wchar <= 0xffff)
86 /* No UTF-16 surrogate handling in UCS-4 */
87 if (sizeof (wchar_t) == 2 && wchar >= 0xd800 && wchar <= 0xdfff)
89 wint_t tmp;
90 if (wchar <= 0xdbff)
92 /* First half of a surrogate pair. Store the state and
93 return ret + 0. */
94 tmp = ((wchar & 0x3ff) << 10) + 0x10000;
95 state->__value.__wchb[0] = (tmp >> 16) & 0xff;
96 state->__value.__wchb[1] = (tmp >> 8) & 0xff;
97 state->__count = -4;
98 *s = (0xf0 | ((tmp & 0x1c0000) >> 18));
99 return ret;
101 if (state->__count == -4)
103 /* Second half of a surrogate pair. Reconstruct the full
104 Unicode value and return the trailing three bytes of the
105 UTF-8 character. */
106 tmp = (state->__value.__wchb[0] << 16)
107 | (state->__value.__wchb[1] << 8)
108 | (wchar & 0x3ff);
109 state->__count = 0;
110 *s++ = 0xf0 | ((tmp & 0x1c0000) >> 18);
111 *s++ = 0x80 | ((tmp & 0x3f000) >> 12);
112 *s++ = 0x80 | ((tmp & 0xfc0) >> 6);
113 *s = 0x80 | (tmp & 0x3f);
114 return 4;
116 /* Otherwise translate into CESU-8 value. */
118 *s++ = 0xe0 | ((wchar & 0xf000) >> 12);
119 *s++ = 0x80 | ((wchar & 0xfc0) >> 6);
120 *s = 0x80 | (wchar & 0x3f);
121 return ret + 3;
123 if (wchar >= 0x10000 && wchar <= 0x10ffff)
125 *s++ = 0xf0 | ((wchar & 0x1c0000) >> 18);
126 *s++ = 0x80 | ((wchar & 0x3f000) >> 12);
127 *s++ = 0x80 | ((wchar & 0xfc0) >> 6);
128 *s = 0x80 | (wchar & 0x3f);
129 return 4;
132 _REENT_ERRNO(r) = EILSEQ;
133 return -1;
136 /* Cygwin defines its own doublebyte charset conversion functions
137 because the underlying OS requires wchar_t == UTF-16. */
138 #ifndef __CYGWIN__
140 __sjis_wctomb (struct _reent *r,
141 char *s,
142 wchar_t _wchar,
143 mbstate_t *state)
145 wint_t wchar = _wchar;
147 unsigned char char2 = (unsigned char)wchar;
148 unsigned char char1 = (unsigned char)(wchar >> 8);
150 if (s == NULL)
151 return 0; /* not state-dependent */
153 if (char1 != 0x00)
155 /* first byte is non-zero..validate multi-byte char */
156 if (_issjis1(char1) && _issjis2(char2))
158 *s++ = (char)char1;
159 *s = (char)char2;
160 return 2;
162 else
164 _REENT_ERRNO(r) = EILSEQ;
165 return -1;
168 *s = (char) wchar;
169 return 1;
173 __eucjp_wctomb (struct _reent *r,
174 char *s,
175 wchar_t _wchar,
176 mbstate_t *state)
178 wint_t wchar = _wchar;
179 unsigned char char2 = (unsigned char)wchar;
180 unsigned char char1 = (unsigned char)(wchar >> 8);
182 if (s == NULL)
183 return 0; /* not state-dependent */
185 if (char1 != 0x00)
187 /* first byte is non-zero..validate multi-byte char */
188 if (_iseucjp1 (char1) && _iseucjp2 (char2))
190 *s++ = (char)char1;
191 *s = (char)char2;
192 return 2;
194 else if (_iseucjp2 (char1) && _iseucjp2 (char2 | 0x80))
196 *s++ = (char)0x8f;
197 *s++ = (char)char1;
198 *s = (char)(char2 | 0x80);
199 return 3;
201 else
203 _REENT_ERRNO(r) = EILSEQ;
204 return -1;
207 *s = (char) wchar;
208 return 1;
212 __jis_wctomb (struct _reent *r,
213 char *s,
214 wchar_t _wchar,
215 mbstate_t *state)
217 wint_t wchar = _wchar;
218 int cnt = 0;
219 unsigned char char2 = (unsigned char)wchar;
220 unsigned char char1 = (unsigned char)(wchar >> 8);
222 if (s == NULL)
223 return 1; /* state-dependent */
225 if (char1 != 0x00)
227 /* first byte is non-zero..validate multi-byte char */
228 if (_isjis (char1) && _isjis (char2))
230 if (state->__state == 0)
232 /* must switch from ASCII to JIS state */
233 state->__state = 1;
234 *s++ = ESC_CHAR;
235 *s++ = '$';
236 *s++ = 'B';
237 cnt = 3;
239 *s++ = (char)char1;
240 *s = (char)char2;
241 return cnt + 2;
243 _REENT_ERRNO(r) = EILSEQ;
244 return -1;
246 if (state->__state != 0)
248 /* must switch from JIS to ASCII state */
249 state->__state = 0;
250 *s++ = ESC_CHAR;
251 *s++ = '(';
252 *s++ = 'B';
253 cnt = 3;
255 *s = (char)char2;
256 return cnt + 1;
258 #endif /* !__CYGWIN__ */
260 #ifdef _MB_EXTENDED_CHARSETS_ISO
261 static int
262 ___iso_wctomb (struct _reent *r, char *s, wchar_t _wchar, int iso_idx,
263 mbstate_t *state)
265 wint_t wchar = _wchar;
267 if (s == NULL)
268 return 0;
270 /* wchars <= 0x9f translate to all ISO charsets directly. */
271 if (wchar >= 0xa0)
273 if (iso_idx >= 0)
275 unsigned char mb;
277 for (mb = 0; mb < 0x60; ++mb)
278 if (__iso_8859_conv[iso_idx][mb] == wchar)
280 *s = (char) (mb + 0xa0);
281 return 1;
283 _REENT_ERRNO(r) = EILSEQ;
284 return -1;
288 if ((size_t)wchar >= 0x100)
290 _REENT_ERRNO(r) = EILSEQ;
291 return -1;
294 *s = (char) wchar;
295 return 1;
298 int __iso_8859_1_wctomb (struct _reent *r, char *s, wchar_t _wchar,
299 mbstate_t *state)
301 return ___iso_wctomb (r, s, _wchar, -1, state);
304 int __iso_8859_2_wctomb (struct _reent *r, char *s, wchar_t _wchar,
305 mbstate_t *state)
307 return ___iso_wctomb (r, s, _wchar, 0, state);
310 int __iso_8859_3_wctomb (struct _reent *r, char *s, wchar_t _wchar,
311 mbstate_t *state)
313 return ___iso_wctomb (r, s, _wchar, 1, state);
316 int __iso_8859_4_wctomb (struct _reent *r, char *s, wchar_t _wchar,
317 mbstate_t *state)
319 return ___iso_wctomb (r, s, _wchar, 2, state);
322 int __iso_8859_5_wctomb (struct _reent *r, char *s, wchar_t _wchar,
323 mbstate_t *state)
325 return ___iso_wctomb (r, s, _wchar, 3, state);
328 int __iso_8859_6_wctomb (struct _reent *r, char *s, wchar_t _wchar,
329 mbstate_t *state)
331 return ___iso_wctomb (r, s, _wchar, 4, state);
334 int __iso_8859_7_wctomb (struct _reent *r, char *s, wchar_t _wchar,
335 mbstate_t *state)
337 return ___iso_wctomb (r, s, _wchar, 5, state);
340 int __iso_8859_8_wctomb (struct _reent *r, char *s, wchar_t _wchar,
341 mbstate_t *state)
343 return ___iso_wctomb (r, s, _wchar, 6, state);
346 int __iso_8859_9_wctomb (struct _reent *r, char *s, wchar_t _wchar,
347 mbstate_t *state)
349 return ___iso_wctomb (r, s, _wchar, 7, state);
352 int __iso_8859_10_wctomb (struct _reent *r, char *s, wchar_t _wchar,
353 mbstate_t *state)
355 return ___iso_wctomb (r, s, _wchar, 8, state);
358 int __iso_8859_11_wctomb (struct _reent *r, char *s, wchar_t _wchar,
359 mbstate_t *state)
361 return ___iso_wctomb (r, s, _wchar, 9, state);
364 int __iso_8859_13_wctomb (struct _reent *r, char *s, wchar_t _wchar,
365 mbstate_t *state)
367 return ___iso_wctomb (r, s, _wchar, 10, state);
370 int __iso_8859_14_wctomb (struct _reent *r, char *s, wchar_t _wchar,
371 mbstate_t *state)
373 return ___iso_wctomb (r, s, _wchar, 11, state);
376 int __iso_8859_15_wctomb (struct _reent *r, char *s, wchar_t _wchar,
377 mbstate_t *state)
379 return ___iso_wctomb (r, s, _wchar, 12, state);
382 int __iso_8859_16_wctomb (struct _reent *r, char *s, wchar_t _wchar,
383 mbstate_t *state)
385 return ___iso_wctomb (r, s, _wchar, 13, state);
388 static wctomb_p __iso_8859_wctomb[17] = {
389 NULL,
390 __iso_8859_1_wctomb,
391 __iso_8859_2_wctomb,
392 __iso_8859_3_wctomb,
393 __iso_8859_4_wctomb,
394 __iso_8859_5_wctomb,
395 __iso_8859_6_wctomb,
396 __iso_8859_7_wctomb,
397 __iso_8859_8_wctomb,
398 __iso_8859_9_wctomb,
399 __iso_8859_10_wctomb,
400 __iso_8859_11_wctomb,
401 NULL, /* No ISO 8859-12 */
402 __iso_8859_13_wctomb,
403 __iso_8859_14_wctomb,
404 __iso_8859_15_wctomb,
405 __iso_8859_16_wctomb
408 /* val *MUST* be valid! All checks for validity are supposed to be
409 performed before calling this function. */
410 wctomb_p
411 __iso_wctomb (int val)
413 return __iso_8859_wctomb[val];
415 #endif /* _MB_EXTENDED_CHARSETS_ISO */
417 #ifdef _MB_EXTENDED_CHARSETS_WINDOWS
418 static int
419 ___cp_wctomb (struct _reent *r, char *s, wchar_t _wchar, int cp_idx,
420 mbstate_t *state)
422 wint_t wchar = _wchar;
424 if (s == NULL)
425 return 0;
427 if (wchar >= 0x80)
429 if (cp_idx >= 0)
431 unsigned char mb;
433 for (mb = 0; mb < 0x80; ++mb)
434 if (__cp_conv[cp_idx][mb] == wchar)
436 *s = (char) (mb + 0x80);
437 return 1;
439 _REENT_ERRNO(r) = EILSEQ;
440 return -1;
444 if ((size_t)wchar >= 0x100)
446 _REENT_ERRNO(r) = EILSEQ;
447 return -1;
450 *s = (char) wchar;
451 return 1;
454 static int
455 __cp_437_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
457 return ___cp_wctomb (r, s, _wchar, 0, state);
460 static int
461 __cp_720_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
463 return ___cp_wctomb (r, s, _wchar, 1, state);
466 static int
467 __cp_737_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
469 return ___cp_wctomb (r, s, _wchar, 2, state);
472 static int
473 __cp_775_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
475 return ___cp_wctomb (r, s, _wchar, 3, state);
478 static int
479 __cp_850_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
481 return ___cp_wctomb (r, s, _wchar, 4, state);
484 static int
485 __cp_852_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
487 return ___cp_wctomb (r, s, _wchar, 5, state);
490 static int
491 __cp_855_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
493 return ___cp_wctomb (r, s, _wchar, 6, state);
496 static int
497 __cp_857_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
499 return ___cp_wctomb (r, s, _wchar, 7, state);
502 static int
503 __cp_858_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
505 return ___cp_wctomb (r, s, _wchar, 8, state);
508 static int
509 __cp_862_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
511 return ___cp_wctomb (r, s, _wchar, 9, state);
514 static int
515 __cp_866_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
517 return ___cp_wctomb (r, s, _wchar, 10, state);
520 static int
521 __cp_874_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
523 return ___cp_wctomb (r, s, _wchar, 11, state);
526 static int
527 __cp_1125_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
529 return ___cp_wctomb (r, s, _wchar, 12, state);
532 static int
533 __cp_1250_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
535 return ___cp_wctomb (r, s, _wchar, 13, state);
538 static int
539 __cp_1251_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
541 return ___cp_wctomb (r, s, _wchar, 14, state);
544 static int
545 __cp_1252_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
547 return ___cp_wctomb (r, s, _wchar, 15, state);
550 static int
551 __cp_1253_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
553 return ___cp_wctomb (r, s, _wchar, 16, state);
556 static int
557 __cp_1254_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
559 return ___cp_wctomb (r, s, _wchar, 17, state);
562 static int
563 __cp_1255_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
565 return ___cp_wctomb (r, s, _wchar, 18, state);
568 static int
569 __cp_1256_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
571 return ___cp_wctomb (r, s, _wchar, 19, state);
574 static int
575 __cp_1257_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
577 return ___cp_wctomb (r, s, _wchar, 20, state);
580 static int
581 __cp_1258_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
583 return ___cp_wctomb (r, s, _wchar, 21, state);
586 static int
587 __cp_20866_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
589 return ___cp_wctomb (r, s, _wchar, 22, state);
592 static int
593 __cp_21866_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
595 return ___cp_wctomb (r, s, _wchar, 23, state);
598 static int
599 __cp_101_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
601 return ___cp_wctomb (r, s, _wchar, 24, state);
604 static int
605 __cp_102_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
607 return ___cp_wctomb (r, s, _wchar, 25, state);
610 static int
611 __cp_103_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
613 return ___cp_wctomb (r, s, _wchar, 26, state);
616 static wctomb_p __cp_xxx_wctomb[27] = {
617 __cp_437_wctomb,
618 __cp_720_wctomb,
619 __cp_737_wctomb,
620 __cp_775_wctomb,
621 __cp_850_wctomb,
622 __cp_852_wctomb,
623 __cp_855_wctomb,
624 __cp_857_wctomb,
625 __cp_858_wctomb,
626 __cp_862_wctomb,
627 __cp_866_wctomb,
628 __cp_874_wctomb,
629 __cp_1125_wctomb,
630 __cp_1250_wctomb,
631 __cp_1251_wctomb,
632 __cp_1252_wctomb,
633 __cp_1253_wctomb,
634 __cp_1254_wctomb,
635 __cp_1255_wctomb,
636 __cp_1256_wctomb,
637 __cp_1257_wctomb,
638 __cp_1258_wctomb,
639 __cp_20866_wctomb,
640 __cp_21866_wctomb,
641 __cp_101_wctomb,
642 __cp_102_wctomb,
643 __cp_103_wctomb,
646 /* val *MUST* be valid! All checks for validity are supposed to be
647 performed before calling this function. */
648 wctomb_p
649 __cp_wctomb (int val)
651 return __cp_xxx_wctomb[__cp_val_index (val)];
653 #endif /* _MB_EXTENDED_CHARSETS_WINDOWS */
654 #endif /* _MB_CAPABLE */