source: trunk/libs/newlib/src/newlib/libc/stdlib/wctomb_r.c @ 577

Last change on this file since 577 was 444, checked in by satin@…, 6 years ago

add newlib,libalmos-mkh, restructure shared_syscalls.h and mini-libc

File size: 14.4 KB
Line 
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"
8
9int
10_wctomb_r (struct _reent *r,
11        char          *s,
12        wchar_t        _wchar,
13        mbstate_t     *state)
14{
15  return __WCTOMB (r, s, _wchar, state);
16}
17
18int
19__ascii_wctomb (struct _reent *r,
20        char          *s,
21        wchar_t        _wchar,
22        mbstate_t     *state)
23{
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;
28
29  if (s == NULL)
30    return 0;
31 
32#ifdef __CYGWIN__
33  if ((size_t)wchar >= 0x80)
34#else
35  if ((size_t)wchar >= 0x100)
36#endif
37    {
38      r->_errno = EILSEQ;
39      return -1;
40    }
41
42  *s = (char) wchar;
43  return 1;
44}
45
46#ifdef _MB_CAPABLE
47/* for some conversions, we use the __count field as a place to store a state value */
48#define __state __count
49
50int
51__utf8_wctomb (struct _reent *r,
52        char          *s,
53        wchar_t        _wchar,
54        mbstate_t     *state)
55{
56  wint_t wchar = _wchar;
57  int ret = 0;
58
59  if (s == NULL)
60    return 0; /* UTF-8 encoding is not state-dependent */
61
62  if (sizeof (wchar_t) == 2 && state->__count == -4
63      && (wchar < 0xdc00 || wchar > 0xdfff))
64    {
65      /* There's a leftover lone high surrogate.  Write out the CESU-8 value
66         of the surrogate and proceed to convert the given character.  Note
67         to return extra 3 bytes. */
68      wchar_t tmp;
69      tmp = (state->__value.__wchb[0] << 16 | state->__value.__wchb[1] << 8)
70            - (0x10000 >> 10 | 0xd80d);
71      *s++ = 0xe0 | ((tmp & 0xf000) >> 12);
72      *s++ = 0x80 | ((tmp &  0xfc0) >> 6);
73      *s++ = 0x80 |  (tmp &   0x3f);
74      state->__count = 0;
75      ret = 3;
76    }
77  if (wchar <= 0x7f)
78    {
79      *s = wchar;
80      return ret + 1;
81    }
82  if (wchar >= 0x80 && wchar <= 0x7ff)
83    {
84      *s++ = 0xc0 | ((wchar & 0x7c0) >> 6);
85      *s   = 0x80 |  (wchar &  0x3f);
86      return ret + 2;
87    }
88  if (wchar >= 0x800 && wchar <= 0xffff)
89    {
90      /* No UTF-16 surrogate handling in UCS-4 */
91      if (sizeof (wchar_t) == 2 && wchar >= 0xd800 && wchar <= 0xdfff)
92        {
93          wint_t tmp;
94          if (wchar <= 0xdbff)
95            {
96              /* First half of a surrogate pair.  Store the state and
97                 return ret + 0. */
98              tmp = ((wchar & 0x3ff) << 10) + 0x10000;
99              state->__value.__wchb[0] = (tmp >> 16) & 0xff;
100              state->__value.__wchb[1] = (tmp >> 8) & 0xff;
101              state->__count = -4;
102              *s = (0xf0 | ((tmp & 0x1c0000) >> 18));
103              return ret;
104            }
105          if (state->__count == -4)
106            {
107              /* Second half of a surrogate pair.  Reconstruct the full
108                 Unicode value and return the trailing three bytes of the
109                 UTF-8 character. */
110              tmp = (state->__value.__wchb[0] << 16)
111                    | (state->__value.__wchb[1] << 8)
112                    | (wchar & 0x3ff);
113              state->__count = 0;
114              *s++ = 0xf0 | ((tmp & 0x1c0000) >> 18);
115              *s++ = 0x80 | ((tmp &  0x3f000) >> 12);
116              *s++ = 0x80 | ((tmp &    0xfc0) >> 6);
117              *s   = 0x80 |  (tmp &     0x3f);
118              return 4;
119            }
120          /* Otherwise translate into CESU-8 value. */
121        }
122      *s++ = 0xe0 | ((wchar & 0xf000) >> 12);
123      *s++ = 0x80 | ((wchar &  0xfc0) >> 6);
124      *s   = 0x80 |  (wchar &   0x3f);
125      return ret + 3;
126    }
127  if (wchar >= 0x10000 && wchar <= 0x10ffff)
128    {
129      *s++ = 0xf0 | ((wchar & 0x1c0000) >> 18);
130      *s++ = 0x80 | ((wchar &  0x3f000) >> 12);
131      *s++ = 0x80 | ((wchar &    0xfc0) >> 6);
132      *s   = 0x80 |  (wchar &     0x3f);
133      return 4;
134    }
135
136  r->_errno = EILSEQ;
137  return -1;
138}
139
140/* Cygwin defines its own doublebyte charset conversion functions
141   because the underlying OS requires wchar_t == UTF-16. */
142#ifndef __CYGWIN__
143int
144__sjis_wctomb (struct _reent *r,
145        char          *s,
146        wchar_t        _wchar,
147        mbstate_t     *state)
148{
149  wint_t wchar = _wchar;
150
151  unsigned char char2 = (unsigned char)wchar;
152  unsigned char char1 = (unsigned char)(wchar >> 8);
153
154  if (s == NULL)
155    return 0;  /* not state-dependent */
156
157  if (char1 != 0x00)
158    {
159    /* first byte is non-zero..validate multi-byte char */
160      if (_issjis1(char1) && _issjis2(char2)) 
161        {
162          *s++ = (char)char1;
163          *s = (char)char2;
164          return 2;
165        }
166      else
167        {
168          r->_errno = EILSEQ;
169          return -1;
170        }
171    }
172  *s = (char) wchar;
173  return 1;
174}
175
176int
177__eucjp_wctomb (struct _reent *r,
178        char          *s,
179        wchar_t        _wchar,
180        mbstate_t     *state)
181{
182  wint_t wchar = _wchar;
183  unsigned char char2 = (unsigned char)wchar;
184  unsigned char char1 = (unsigned char)(wchar >> 8);
185
186  if (s == NULL)
187    return 0;  /* not state-dependent */
188
189  if (char1 != 0x00)
190    {
191    /* first byte is non-zero..validate multi-byte char */
192      if (_iseucjp1 (char1) && _iseucjp2 (char2)) 
193        {
194          *s++ = (char)char1;
195          *s = (char)char2;
196          return 2;
197        }
198      else if (_iseucjp2 (char1) && _iseucjp2 (char2 | 0x80))
199        {
200          *s++ = (char)0x8f;
201          *s++ = (char)char1;
202          *s = (char)(char2 | 0x80);
203          return 3;
204        }
205      else
206        {
207          r->_errno = EILSEQ;
208          return -1;
209        }
210    }
211  *s = (char) wchar;
212  return 1;
213}
214
215int
216__jis_wctomb (struct _reent *r,
217        char          *s,
218        wchar_t        _wchar,
219        mbstate_t     *state)
220{
221  wint_t wchar = _wchar;
222  int cnt = 0; 
223  unsigned char char2 = (unsigned char)wchar;
224  unsigned char char1 = (unsigned char)(wchar >> 8);
225
226  if (s == NULL)
227    return 1;  /* state-dependent */
228
229  if (char1 != 0x00)
230    {
231    /* first byte is non-zero..validate multi-byte char */
232      if (_isjis (char1) && _isjis (char2)) 
233        {
234          if (state->__state == 0)
235            {
236              /* must switch from ASCII to JIS state */
237              state->__state = 1;
238              *s++ = ESC_CHAR;
239              *s++ = '$';
240              *s++ = 'B';
241              cnt = 3;
242            }
243          *s++ = (char)char1;
244          *s = (char)char2;
245          return cnt + 2;
246        }
247      r->_errno = EILSEQ;
248      return -1;
249    }
250  if (state->__state != 0)
251    {
252      /* must switch from JIS to ASCII state */
253      state->__state = 0;
254      *s++ = ESC_CHAR;
255      *s++ = '(';
256      *s++ = 'B';
257      cnt = 3;
258    }
259  *s = (char)char2;
260  return cnt + 1;
261}
262#endif /* !__CYGWIN__ */
263
264#ifdef _MB_EXTENDED_CHARSETS_ISO
265static int
266___iso_wctomb (struct _reent *r, char *s, wchar_t _wchar, int iso_idx,
267               mbstate_t *state)
268{
269  wint_t wchar = _wchar;
270
271  if (s == NULL)
272    return 0;
273
274  /* wchars <= 0x9f translate to all ISO charsets directly. */
275  if (wchar >= 0xa0)
276    {
277      if (iso_idx >= 0)
278        {
279          unsigned char mb;
280
281          for (mb = 0; mb < 0x60; ++mb)
282            if (__iso_8859_conv[iso_idx][mb] == wchar)
283              {
284                *s = (char) (mb + 0xa0);
285                return 1;
286              }
287          r->_errno = EILSEQ;
288          return -1;
289        }
290    }
291 
292  if ((size_t)wchar >= 0x100)
293    {
294      r->_errno = EILSEQ;
295      return -1;
296    }
297
298  *s = (char) wchar;
299  return 1;
300}
301
302int __iso_8859_1_wctomb (struct _reent *r, char *s, wchar_t _wchar,
303                         mbstate_t *state)
304{
305  return ___iso_wctomb (r, s, _wchar, -1, state);
306}
307
308int __iso_8859_2_wctomb (struct _reent *r, char *s, wchar_t _wchar,
309                         mbstate_t *state)
310{
311  return ___iso_wctomb (r, s, _wchar, 0, state);
312}
313
314int __iso_8859_3_wctomb (struct _reent *r, char *s, wchar_t _wchar,
315                         mbstate_t *state)
316{
317  return ___iso_wctomb (r, s, _wchar, 1, state);
318}
319
320int __iso_8859_4_wctomb (struct _reent *r, char *s, wchar_t _wchar,
321                         mbstate_t *state)
322{
323  return ___iso_wctomb (r, s, _wchar, 2, state);
324}
325
326int __iso_8859_5_wctomb (struct _reent *r, char *s, wchar_t _wchar,
327                         mbstate_t *state)
328{
329  return ___iso_wctomb (r, s, _wchar, 3, state);
330}
331
332int __iso_8859_6_wctomb (struct _reent *r, char *s, wchar_t _wchar,
333                         mbstate_t *state)
334{
335  return ___iso_wctomb (r, s, _wchar, 4, state);
336}
337
338int __iso_8859_7_wctomb (struct _reent *r, char *s, wchar_t _wchar,
339                         mbstate_t *state)
340{
341  return ___iso_wctomb (r, s, _wchar, 5, state);
342}
343
344int __iso_8859_8_wctomb (struct _reent *r, char *s, wchar_t _wchar,
345                         mbstate_t *state)
346{
347  return ___iso_wctomb (r, s, _wchar, 6, state);
348}
349
350int __iso_8859_9_wctomb (struct _reent *r, char *s, wchar_t _wchar,
351                         mbstate_t *state)
352{
353  return ___iso_wctomb (r, s, _wchar, 7, state);
354}
355
356int __iso_8859_10_wctomb (struct _reent *r, char *s, wchar_t _wchar,
357                          mbstate_t *state)
358{
359  return ___iso_wctomb (r, s, _wchar, 8, state);
360}
361
362int __iso_8859_11_wctomb (struct _reent *r, char *s, wchar_t _wchar,
363                          mbstate_t *state)
364{
365  return ___iso_wctomb (r, s, _wchar, 9, state);
366}
367
368int __iso_8859_13_wctomb (struct _reent *r, char *s, wchar_t _wchar,
369                          mbstate_t *state)
370{
371  return ___iso_wctomb (r, s, _wchar, 10, state);
372}
373
374int __iso_8859_14_wctomb (struct _reent *r, char *s, wchar_t _wchar,
375                          mbstate_t *state)
376{
377  return ___iso_wctomb (r, s, _wchar, 11, state);
378}
379
380int __iso_8859_15_wctomb (struct _reent *r, char *s, wchar_t _wchar,
381                          mbstate_t *state)
382{
383  return ___iso_wctomb (r, s, _wchar, 12, state);
384}
385
386int __iso_8859_16_wctomb (struct _reent *r, char *s, wchar_t _wchar,
387                          mbstate_t *state)
388{
389  return ___iso_wctomb (r, s, _wchar, 13, state);
390}
391
392static wctomb_p __iso_8859_wctomb[17] = {
393  NULL,
394  __iso_8859_1_wctomb,
395  __iso_8859_2_wctomb,
396  __iso_8859_3_wctomb,
397  __iso_8859_4_wctomb,
398  __iso_8859_5_wctomb,
399  __iso_8859_6_wctomb,
400  __iso_8859_7_wctomb,
401  __iso_8859_8_wctomb,
402  __iso_8859_9_wctomb,
403  __iso_8859_10_wctomb,
404  __iso_8859_11_wctomb,
405  NULL,                 /* No ISO 8859-12 */
406  __iso_8859_13_wctomb,
407  __iso_8859_14_wctomb,
408  __iso_8859_15_wctomb,
409  __iso_8859_16_wctomb
410};
411
412/* val *MUST* be valid!  All checks for validity are supposed to be
413   performed before calling this function. */
414wctomb_p
415__iso_wctomb (int val)
416{
417  return __iso_8859_wctomb[val];
418}
419#endif /* _MB_EXTENDED_CHARSETS_ISO */
420
421#ifdef _MB_EXTENDED_CHARSETS_WINDOWS
422static int
423___cp_wctomb (struct _reent *r, char *s, wchar_t _wchar, int cp_idx,
424              mbstate_t *state)
425{
426  wint_t wchar = _wchar;
427
428  if (s == NULL)
429    return 0;
430
431  if (wchar >= 0x80)
432    {
433      if (cp_idx >= 0)
434        {
435          unsigned char mb;
436
437          for (mb = 0; mb < 0x80; ++mb)
438            if (__cp_conv[cp_idx][mb] == wchar)
439              {
440                *s = (char) (mb + 0x80);
441                return 1;
442              }
443          r->_errno = EILSEQ;
444          return -1;
445        }
446    }
447
448  if ((size_t)wchar >= 0x100)
449    {
450      r->_errno = EILSEQ;
451      return -1;
452    }
453
454  *s = (char) wchar;
455  return 1;
456}
457
458static int
459__cp_437_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
460{
461  return ___cp_wctomb (r, s, _wchar, 0, state);
462}
463
464static int
465__cp_720_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
466{
467  return ___cp_wctomb (r, s, _wchar, 1, state);
468}
469
470static int
471__cp_737_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
472{
473  return ___cp_wctomb (r, s, _wchar, 2, state);
474}
475
476static int
477__cp_775_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
478{
479  return ___cp_wctomb (r, s, _wchar, 3, state);
480}
481
482static int
483__cp_850_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
484{
485  return ___cp_wctomb (r, s, _wchar, 4, state);
486}
487
488static int
489__cp_852_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
490{
491  return ___cp_wctomb (r, s, _wchar, 5, state);
492}
493
494static int
495__cp_855_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
496{
497  return ___cp_wctomb (r, s, _wchar, 6, state);
498}
499
500static int
501__cp_857_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
502{
503  return ___cp_wctomb (r, s, _wchar, 7, state);
504}
505
506static int
507__cp_858_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
508{
509  return ___cp_wctomb (r, s, _wchar, 8, state);
510}
511
512static int
513__cp_862_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
514{
515  return ___cp_wctomb (r, s, _wchar, 9, state);
516}
517
518static int
519__cp_866_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
520{
521  return ___cp_wctomb (r, s, _wchar, 10, state);
522}
523
524static int
525__cp_874_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
526{
527  return ___cp_wctomb (r, s, _wchar, 11, state);
528}
529
530static int
531__cp_1125_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
532{
533  return ___cp_wctomb (r, s, _wchar, 12, state);
534}
535
536static int
537__cp_1250_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
538{
539  return ___cp_wctomb (r, s, _wchar, 13, state);
540}
541
542static int
543__cp_1251_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
544{
545  return ___cp_wctomb (r, s, _wchar, 14, state);
546}
547
548static int
549__cp_1252_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
550{
551  return ___cp_wctomb (r, s, _wchar, 15, state);
552}
553
554static int
555__cp_1253_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
556{
557  return ___cp_wctomb (r, s, _wchar, 16, state);
558}
559
560static int
561__cp_1254_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
562{
563  return ___cp_wctomb (r, s, _wchar, 17, state);
564}
565
566static int
567__cp_1255_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
568{
569  return ___cp_wctomb (r, s, _wchar, 18, state);
570}
571
572static int
573__cp_1256_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
574{
575  return ___cp_wctomb (r, s, _wchar, 19, state);
576}
577
578static int
579__cp_1257_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
580{
581  return ___cp_wctomb (r, s, _wchar, 20, state);
582}
583
584static int
585__cp_1258_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
586{
587  return ___cp_wctomb (r, s, _wchar, 21, state);
588}
589
590static int
591__cp_20866_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
592{
593  return ___cp_wctomb (r, s, _wchar, 22, state);
594}
595
596static int
597__cp_21866_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
598{
599  return ___cp_wctomb (r, s, _wchar, 23, state);
600}
601
602static int
603__cp_101_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
604{
605  return ___cp_wctomb (r, s, _wchar, 24, state);
606}
607
608static int
609__cp_102_wctomb (struct _reent *r, char *s, wchar_t _wchar, mbstate_t *state)
610{
611  return ___cp_wctomb (r, s, _wchar, 25, state);
612}
613
614static wctomb_p __cp_xxx_wctomb[26] = {
615  __cp_437_wctomb,
616  __cp_720_wctomb,
617  __cp_737_wctomb,
618  __cp_775_wctomb,
619  __cp_850_wctomb,
620  __cp_852_wctomb,
621  __cp_855_wctomb,
622  __cp_857_wctomb,
623  __cp_858_wctomb,
624  __cp_862_wctomb,
625  __cp_866_wctomb,
626  __cp_874_wctomb,
627  __cp_1125_wctomb,
628  __cp_1250_wctomb,
629  __cp_1251_wctomb,
630  __cp_1252_wctomb,
631  __cp_1253_wctomb,
632  __cp_1254_wctomb,
633  __cp_1255_wctomb,
634  __cp_1256_wctomb,
635  __cp_1257_wctomb,
636  __cp_1258_wctomb,
637  __cp_20866_wctomb,
638  __cp_21866_wctomb,
639  __cp_101_wctomb,
640  __cp_102_wctomb
641};
642
643/* val *MUST* be valid!  All checks for validity are supposed to be
644   performed before calling this function. */
645wctomb_p
646__cp_wctomb (int val)
647{
648  return __cp_xxx_wctomb[__cp_val_index (val)];
649}
650#endif /* _MB_EXTENDED_CHARSETS_WINDOWS */
651#endif /* _MB_CAPABLE */
Note: See TracBrowser for help on using the repository browser.