]> pd.if.org Git - pdclib/blob - functions/wchar/mbrtowc.c
91fefebc1cc063639ac796e91653f576ab017d60
[pdclib] / functions / wchar / mbrtowc.c
1 /* mbrtowc(
2     wchar_t *restrict pwc, 
3     const char *restrict s, 
4     size_t n, 
5     mbstate_t *restrict ps);
6
7    This file is part of the Public Domain C Library (PDCLib).
8    Permission is granted to use, modify, and / or redistribute at will.
9 */
10
11 #include <wchar.h>
12 #ifndef REGTEST
13 #include <errno.h>
14 #include <stdint.h>
15 #include <assert.h>
16 #include <_PDCLIB_encoding.h>
17 #include <_PDCLIB_locale.h>
18
19 size_t mbrtowc_l(
20     wchar_t    *restrict    pwc, 
21     const char *restrict    s, 
22     size_t                  n, 
23     mbstate_t  *restrict    ps,
24     locale_t    restrict    l
25 )
26 {
27     size_t res;
28
29     if(s == NULL) {
30         s = "";
31         n = 1;
32     }
33
34     if(ps->_PendState == _PendPrefix) {
35         res = _PDCLIB_mbrtocwc_l(pwc, &ps->_PendChar, 1, ps, l);
36         switch(res) {
37             case 0:
38                 // Converted the NUL character
39                 ps->_PendState = _PendClear;
40                 return 0;
41
42             case 1:
43                 // Successful conversion
44                 ps->_PendChar = *s;
45                 return 1;
46
47             case (size_t) -1:
48                 // Illegal sequence. mbrtocwc has already set errno.
49                 return (size_t) -1;
50
51             case (size_t) -3:
52                 assert(!"Codec had buffered two characters");
53                 _PDCLIB_UNREACHABLE;
54                 return 0;
55
56             case (size_t) -2:
57                 // Incomplete character, continue
58                 break;
59         }
60     }
61
62     // _PendClear state
63     res = _PDCLIB_mbrtocwc_l(pwc, s, n, ps, l);
64     switch(res) {
65         case (size_t) -3:
66             // Converted entirely from internal state
67             ps->_PendChar  = *s;
68             ps->_PendState = _PendPrefix;
69             return 1;
70         default:
71             return res;
72     }
73 }
74
75 size_t mbrtowc(
76     wchar_t *restrict pwc, 
77     const char *restrict s, 
78     size_t n, 
79     mbstate_t *restrict ps
80 )
81 {
82     static mbstate_t st;
83     return mbrtowc_l(pwc, s, n, ps ? ps : &st, _PDCLIB_threadlocale());
84 }
85
86 #endif
87
88 #ifdef TEST
89 #include <_PDCLIB_test.h>
90
91 int main( void )
92 {
93     TESTCASE( NO_TESTDRIVER );
94     return TEST_RESULTS;
95 }
96 #endif