Cygwin: mmap: allow remapping part of an existing anonymous mapping
[newlib-cygwin.git] / newlib / libc / stdlib / wcsnrtombs.c
blobabef7ac36b78c27630e3e7ac215bcc7bdc2838b4
1 /*
2 FUNCTION
3 <<wcsrtombs>>, <<wcsnrtombs>>---convert a wide-character string to a character string
5 INDEX
6 wcsrtombs
7 INDEX
8 _wcsrtombs_r
9 INDEX
10 wcsnrtombs
11 INDEX
12 _wcsnrtombs_r
14 SYNOPSIS
15 #include <wchar.h>
16 size_t wcsrtombs(char *__restrict <[dst]>,
17 const wchar_t **__restrict <[src]>, size_t <[len]>,
18 mbstate_t *__restrict <[ps]>);
20 #include <wchar.h>
21 size_t _wcsrtombs_r(struct _reent *<[ptr]>, char *<[dst]>,
22 const wchar_t **<[src]>, size_t <[len]>,
23 mbstate_t *<[ps]>);
25 #include <wchar.h>
26 size_t wcsnrtombs(char *__restrict <[dst]>,
27 const wchar_t **__restrict <[src]>,
28 size_t <[nwc]>, size_t <[len]>,
29 mbstate_t *__restrict <[ps]>);
31 #include <wchar.h>
32 size_t _wcsnrtombs_r(struct _reent *<[ptr]>, char *<[dst]>,
33 const wchar_t **<[src]>, size_t <[nwc]>,
34 size_t <[len]>, mbstate_t *<[ps]>);
36 DESCRIPTION
37 The <<wcsrtombs>> function converts a string of wide characters indirectly
38 pointed to by <[src]> to a corresponding multibyte character string stored in
39 the array pointed to by <[dst]>. No more than <[len]> bytes are written to
40 <[dst]>.
42 If <[dst]> is NULL, no characters are stored.
44 If <[dst]> is not NULL, the pointer pointed to by <[src]> is updated to point
45 to the character after the one that conversion stopped at. If conversion
46 stops because a null character is encountered, *<[src]> is set to NULL.
48 The mbstate_t argument, <[ps]>, is used to keep track of the shift state. If
49 it is NULL, <<wcsrtombs>> uses an internal, static mbstate_t object, which
50 is initialized to the initial conversion state at program startup.
52 The <<wcsnrtombs>> function behaves identically to <<wcsrtombs>>, except that
53 conversion stops after reading at most <[nwc]> characters from the buffer
54 pointed to by <[src]>.
56 RETURNS
57 The <<wcsrtombs>> and <<wcsnrtombs>> functions return the number of bytes
58 stored in the array pointed to by <[dst]> (not including any terminating
59 null), if successful, otherwise it returns (size_t)-1.
61 PORTABILITY
62 <<wcsrtombs>> is defined by C99 standard.
63 <<wcsnrtombs>> is defined by the POSIX.1-2008 standard.
66 #include <reent.h>
67 #include <newlib.h>
68 #include <wchar.h>
69 #include <stdlib.h>
70 #include <stdio.h>
71 #include <errno.h>
72 #include "local.h"
73 #include "../locale/setlocale.h"
75 #ifdef _REENT_THREAD_LOCAL
76 _Thread_local _mbstate_t _tls_wcsrtombs_state;
77 #endif
79 size_t
80 _wcsnrtombs_l (struct _reent *r, char *dst, const wchar_t **src, size_t nwc,
81 size_t len, mbstate_t *ps, struct __locale_t *loc)
83 char *ptr = dst;
84 char buff[10];
85 wchar_t *pwcs;
86 size_t n;
87 int i;
89 #ifdef _MB_CAPABLE
90 if (ps == NULL)
92 _REENT_CHECK_MISC(r);
93 ps = &(_REENT_WCSRTOMBS_STATE(r));
95 #endif
97 /* If no dst pointer, treat len as maximum possible value. */
98 if (dst == NULL)
99 len = (size_t)-1;
101 n = 0;
102 pwcs = (wchar_t *)(*src);
104 while (n < len && nwc-- > 0)
106 int count = ps->__count;
107 wint_t wch = ps->__value.__wch;
108 int bytes = loc->wctomb (r, buff, *pwcs, ps);
109 if (bytes == -1)
111 _REENT_ERRNO(r) = EILSEQ;
112 ps->__count = 0;
113 return (size_t)-1;
115 if (n + bytes <= len)
117 n += bytes;
118 if (dst)
120 for (i = 0; i < bytes; ++i)
121 *ptr++ = buff[i];
122 ++(*src);
124 if (*pwcs++ == 0x00)
126 if (dst)
127 *src = NULL;
128 ps->__count = 0;
129 return n - 1;
132 else
134 /* not enough room, we must back up state to before __WCTOMB call */
135 ps->__count = count;
136 ps->__value.__wch = wch;
137 len = 0;
141 return n;
144 size_t
145 _wcsnrtombs_r (struct _reent *r,
146 char *dst,
147 const wchar_t **src,
148 size_t nwc,
149 size_t len,
150 mbstate_t *ps)
152 return _wcsnrtombs_l (_REENT, dst, src, nwc, len, ps,
153 __get_current_locale ());
156 #ifndef _REENT_ONLY
157 size_t
158 wcsnrtombs (char *__restrict dst,
159 const wchar_t **__restrict src,
160 size_t nwc,
161 size_t len,
162 mbstate_t *__restrict ps)
164 return _wcsnrtombs_l (_REENT, dst, src, nwc, len, ps,
165 __get_current_locale ());
167 #endif /* !_REENT_ONLY */