1 /*
2 Copyright (c) 1990 Regents of the University of California.
3 All rights reserved.
4 */
5 /*
6 FUNCTION
7 <<mbstowcs>>---minimal multibyte string to wide char converter
8
9 INDEX
10 mbstowcs
11
12 SYNOPSIS
13 #include <stdlib.h>
14 int mbstowcs(wchar_t *restrict <[pwc]>, const char *restrict <[s]>, size_t <[n]>);
15
16 DESCRIPTION
17 When _MB_CAPABLE is not defined, this is a minimal ANSI-conforming
18 implementation of <<mbstowcs>>. In this case, the
19 only ``multi-byte character sequences'' recognized are single bytes,
20 and they are ``converted'' to wide-char versions simply by byte
21 extension.
22
23 When _MB_CAPABLE is defined, this uses a state variable to allow state
24 dependent decoding. The result is based on the locale setting which
25 may be restricted to a defined set of locales.
26
27 RETURNS
28 This implementation of <<mbstowcs>> returns <<0>> if
29 <[s]> is <<NULL>> or is the empty string;
30 it returns <<-1>> if _MB_CAPABLE and one of the
31 multi-byte characters is invalid or incomplete;
32 otherwise it returns the minimum of: <<n>> or the
33 number of multi-byte characters in <<s>> plus 1 (to
34 compensate for the nul character).
35 If the return value is -1, the state of the <<pwc>> string is
36 indeterminate. If the input has a length of 0, the output
37 string will be modified to contain a wchar_t nul terminator.
38
39 PORTABILITY
40 <<mbstowcs>> is required in the ANSI C standard. However, the precise
41 effects vary with the locale.
42
43 <<mbstowcs>> requires no supporting OS subroutines.
44 */
45
46 #include <stdlib.h>
47 #include <wchar.h>
48 #include "local.h"
49
50 size_t
mbstowcs(wchar_t * __restrict pwcs,const char * __restrict s,size_t n)51 mbstowcs (wchar_t *__restrict pwcs,
52 const char *__restrict s,
53 size_t n)
54 {
55 #ifdef _MB_CAPABLE
56 mbstate_t state;
57 state.__count = 0;
58
59 size_t ret = 0;
60 char *t = (char *)s;
61 int bytes;
62
63 if (!pwcs)
64 n = (size_t) 1; /* Value doesn't matter as long as it's not 0. */
65 while (n > 0)
66 {
67 bytes = __MBTOWC (pwcs, t, MB_CUR_MAX, &state);
68 if (bytes < 0)
69 {
70 state.__count = 0;
71 return -1;
72 }
73 else if (bytes == 0)
74 break;
75 t += bytes;
76 ++ret;
77 if (pwcs)
78 {
79 ++pwcs;
80 --n;
81 }
82 }
83 return ret;
84 #else /* not _MB_CAPABLE */
85
86 int count = 0;
87
88 if (n != 0) {
89 do {
90 if ((*pwcs++ = (wchar_t) *s++) == 0)
91 break;
92 count++;
93 } while (--n != 0);
94 }
95
96 return count;
97 #endif /* not _MB_CAPABLE */
98 }
99