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