1 | #include <stdbool.h> |
2 | #include <stdlib.h> |
3 | #include <string.h> |
4 | #include <wchar.h> |
5 | |
6 | /* Do not include the above headers in the example. |
7 | */ |
8 | wchar_t * |
9 | mbstouwcs (const char *s) |
10 | { |
11 | /* Include the null terminator in the conversion. */ |
12 | size_t len = strlen (s) + 1; |
13 | wchar_t *result = reallocarray (NULL, nmemb: len, size: sizeof (wchar_t)); |
14 | if (result == NULL) |
15 | return NULL; |
16 | |
17 | wchar_t *wcp = result; |
18 | mbstate_t state; |
19 | memset (&state, '\0', sizeof (state)); |
20 | |
21 | while (true) |
22 | { |
23 | wchar_t wc; |
24 | size_t nbytes = mbrtowc (&wc, s, len, &state); |
25 | if (nbytes == 0) |
26 | { |
27 | /* Terminate the result string. */ |
28 | *wcp = L'\0'; |
29 | break; |
30 | } |
31 | else if (nbytes == (size_t) -2) |
32 | { |
33 | /* Truncated input string. */ |
34 | errno = EILSEQ; |
35 | free (ptr: result); |
36 | return NULL; |
37 | } |
38 | else if (nbytes == (size_t) -1) |
39 | { |
40 | /* Some other error (including EILSEQ). */ |
41 | free (ptr: result); |
42 | return NULL; |
43 | } |
44 | else |
45 | { |
46 | /* A character was converted. */ |
47 | *wcp++ = towupper (wc); |
48 | len -= nbytes; |
49 | s += nbytes; |
50 | } |
51 | } |
52 | return result; |
53 | } |
54 | |