Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'newlib/libc/stdlib/wcsrtombs.c')
-rw-r--r--newlib/libc/stdlib/wcsrtombs.c74
1 files changed, 65 insertions, 9 deletions
diff --git a/newlib/libc/stdlib/wcsrtombs.c b/newlib/libc/stdlib/wcsrtombs.c
index 22512c0b4..431347866 100644
--- a/newlib/libc/stdlib/wcsrtombs.c
+++ b/newlib/libc/stdlib/wcsrtombs.c
@@ -5,18 +5,74 @@
#include <errno.h>
size_t
-wcsrtombs (char *dst, const wchar_t **src, size_t len, mbstate_t *ps)
+_DEFUN (_wcsrtombs_r, (r, dst, src, len, ps),
+ struct _reent *r _AND
+ char *dst _AND
+ const wchar_t **src _AND
+ size_t len _AND
+ mbstate_t *ps)
{
- int retval = 0;
- _REENT_CHECK_MISC(_REENT);
+ char *ptr = dst;
+ char buff[10];
+ int i, n;
+ int count;
+ wint_t wch;
- retval = _wcstombs_r (_REENT, dst, *src, len, ps);
+#ifdef MB_CAPABLE
+ if (ps == NULL)
+ {
+ _REENT_CHECK_MISC(r);
+ ps = &(_REENT_WCSRTOMBS_STATE(r));
+ }
+#endif
- if (retval == -1)
+ n = (int)len;
+
+ while (n > 0)
{
- _REENT->_errno = EILSEQ;
- return (size_t)(-1);
+ wchar_t *pwcs = (wchar_t *)(*src);
+ int count = ps->__count;
+ wint_t wch = ps->__value.__wch;
+ int bytes = _wctomb_r (r, buff, *pwcs, ps);
+ if (bytes == -1)
+ {
+ r->_errno = EILSEQ;
+ ps->__count = 0;
+ return (size_t)-1;
+ }
+ if (bytes <= n)
+ {
+ for (i = 0; i < bytes; ++i)
+ *ptr++ = buff[i];
+
+ if (*pwcs == 0x00)
+ {
+ *src = NULL;
+ ps->__count = 0;
+ return (size_t)(ptr - dst - 1);
+ }
+ ++(*src);
+ }
+ else
+ {
+ /* not enough room, we must back up state to before _wctomb_r call */
+ ps->__count = count;
+ ps->__value.__wch = wch;
+ }
+ n -= bytes;
}
- else
- return (size_t)retval;
+
+ return (size_t)(ptr - dst);
+}
+
+#ifndef _REENT_ONLY
+size_t
+_DEFUN (wcsrtombs, (dst, src, len, ps),
+ char *dst _AND
+ const wchar_t **src _AND
+ size_t len _AND
+ mbstate_t *ps)
+{
+ return _wcsrtombs_r (_REENT, dst, src, len, ps);
}
+#endif /* !_REENT_ONLY */