This is the mail archive of the
newlib@sourceware.org
mailing list for the newlib project.
[PATCH] mbsnrtowcs/wcsnrtombs
- From: Corinna Vinschen <vinschen at redhat dot com>
- To: newlib at sourceware dot org
- Date: Fri, 13 Feb 2009 19:35:07 +0100
- Subject: [PATCH] mbsnrtowcs/wcsnrtombs
- Reply-to: newlib at sourceware dot org
Hi,
the below patch adds the two functions mbsnrtowcs and wcsnrtombs, as
defined in BSD and POSIX.1-2008, as well as their reentrant siblings.
Actually, the functions are just copies of the functions mbsrtowcs and
wcsrtombs, just with the additional parameter. The extra handling for
the new parameter is really a minor change. The old 'r' functions are
now simply implemented by calling the new 'nr' functions.
Corinna
* libc/include/wchar.h (mbsnrtowcs): Declare.
(_mbsnrtowcs_r): Declare.
(wcsnrtombs): Declare.
(_wcsnrtombs_r): Declare.
* libc/stdlib/Makefile.am (ELIX_2_SOURCES): Add mbsnrtowcs.c
and wcsnrtombs.c.
* libc/stdlib/Makefile.in: Regenerate.
* libc/stdlib/mbsnrtowcs.c: New file, implementing _mbsnrtowcs_r
and mbsnrtowcs.
* libc/stdlib/mbsrtowcs.c (_mbsrtowcs_r): Just call _mbsnrtowcs_r.
(mbsrtowcs): Ditto.
* libc/stdlib/wcsnrtombs.c: New file, implementing _wcsnrtombs_r
and wcsnrtombs.
* libc/stdlib/wcsrtombs.c (_wcsrtombs_r): Just call _wcsnrtombs_r.
(wcsrtombs): Ditto.
Index: libc/include/wchar.h
===================================================================
RCS file: /cvs/src/src/newlib/libc/include/wchar.h,v
retrieving revision 1.20
diff -u -p -r1.20 wchar.h
--- libc/include/wchar.h 12 Feb 2009 23:10:01 -0000 1.20
+++ libc/include/wchar.h 13 Feb 2009 18:29:42 -0000
@@ -47,10 +47,18 @@ size_t _EXFUN(mbrtowc, (wchar_t * , cons
size_t _EXFUN(_mbrtowc_r, (struct _reent *, wchar_t * , const char * ,
size_t, mbstate_t *));
int _EXFUN(mbsinit, (const mbstate_t *));
+size_t _EXFUN(mbsnrtowcs, (wchar_t * , const char ** , size_t, size_t,
+ mbstate_t *));
+size_t _EXFUN(_mbsnrtowcs_r, (struct _reent *, wchar_t * , const char ** ,
+ size_t, size_t, mbstate_t *));
size_t _EXFUN(mbsrtowcs, (wchar_t * , const char ** , size_t, mbstate_t *));
size_t _EXFUN(_mbsrtowcs_r, (struct _reent *, wchar_t * , const char ** , size_t, mbstate_t *));
size_t _EXFUN(wcrtomb, (char * , wchar_t, mbstate_t *));
size_t _EXFUN(_wcrtomb_r, (struct _reent *, char * , wchar_t, mbstate_t *));
+size_t _EXFUN(wcsnrtombs, (char * , const wchar_t ** , size_t, size_t,
+ mbstate_t *));
+size_t _EXFUN(_wcsnrtombs_r, (struct _reent *, char * , const wchar_t ** ,
+ size_t, size_t, mbstate_t *));
size_t _EXFUN(wcsrtombs, (char * , const wchar_t ** , size_t, mbstate_t *));
size_t _EXFUN(_wcsrtombs_r, (struct _reent *, char * , const wchar_t ** ,
size_t, mbstate_t *));
Index: libc/stdlib/Makefile.am
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdlib/Makefile.am,v
retrieving revision 1.26
diff -u -p -r1.26 Makefile.am
--- libc/stdlib/Makefile.am 12 Feb 2009 23:10:01 -0000 1.26
+++ libc/stdlib/Makefile.am 13 Feb 2009 18:29:42 -0000
@@ -98,10 +98,12 @@ ELIX_2_SOURCES = \
mbrlen.c \
mbrtowc.c \
mbsinit.c \
+ mbsnrtowcs.c \
mbsrtowcs.c \
on_exit.c \
valloc.c \
wcrtomb.c \
+ wcsnrtombs.c \
wcsrtombs.c \
wctob.c
Index: libc/stdlib/mbsnrtowcs.c
===================================================================
RCS file: libc/stdlib/mbsnrtowcs.c
diff -N libc/stdlib/mbsnrtowcs.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ libc/stdlib/mbsnrtowcs.c 13 Feb 2009 18:29:42 -0000
@@ -0,0 +1,81 @@
+#include <reent.h>
+#include <newlib.h>
+#include <wchar.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+
+size_t
+_DEFUN (_mbsnrtowcs_r, (r, dst, src, nms, len, ps),
+ struct _reent *r _AND
+ wchar_t *dst _AND
+ const char **src _AND
+ size_t nms _AND
+ size_t len _AND
+ mbstate_t *ps)
+{
+ wchar_t *ptr = dst;
+ const char *tmp_src;
+ size_t max;
+ size_t count = 0;
+ int bytes;
+
+#ifdef _MB_CAPABLE
+ if (ps == NULL)
+ {
+ _REENT_CHECK_MISC(r);
+ ps = &(_REENT_MBSRTOWCS_STATE(r));
+ }
+#endif
+
+ if (dst == NULL)
+ {
+ /* Ignore original len value and do not alter src pointer if the
+ dst pointer is NULL. */
+ len = (size_t)-1;
+ tmp_src = *src;
+ src = &tmp_src;
+ }
+
+ max = len;
+ while (len > 0)
+ {
+ bytes = _mbrtowc_r (r, ptr, *src, nms, ps);
+ if (bytes > 0)
+ {
+ *src += bytes;
+ nms -= bytes;
+ ++count;
+ ptr = (dst == NULL) ? NULL : ptr + 1;
+ --len;
+ }
+ else if (bytes == -2)
+ return count;
+ else if (bytes == 0)
+ {
+ *src = NULL;
+ return count;
+ }
+ else
+ {
+ ps->__count = 0;
+ r->_errno = EILSEQ;
+ return (size_t)-1;
+ }
+ }
+
+ return (size_t)max;
+}
+
+#ifndef _REENT_ONLY
+size_t
+_DEFUN (mbsnrtowcs, (dst, src, nms, len, ps),
+ wchar_t *dst _AND
+ const char **src _AND
+ size_t nms _AND
+ size_t len _AND
+ mbstate_t *ps)
+{
+ return _mbsnrtowcs_r (_REENT, dst, src, nms, len, ps);
+}
+#endif /* !_REENT_ONLY */
Index: libc/stdlib/mbsrtowcs.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdlib/mbsrtowcs.c,v
retrieving revision 1.5
diff -u -p -r1.5 mbsrtowcs.c
--- libc/stdlib/mbsrtowcs.c 23 Apr 2004 21:44:22 -0000 1.5
+++ libc/stdlib/mbsrtowcs.c 13 Feb 2009 18:29:42 -0000
@@ -6,65 +6,14 @@
#include <errno.h>
size_t
-_DEFUN (_mbsrtowcs_r, (r, dst, src, n, ps),
+_DEFUN (_mbsrtowcs_r, (r, dst, src, len, ps),
struct _reent *r _AND
wchar_t *dst _AND
const char **src _AND
- size_t n _AND
+ size_t len _AND
mbstate_t *ps)
{
- wchar_t *ptr = dst;
- const char *tmp_src;
- size_t max;
- size_t count = 0;
- int bytes;
-
-#ifdef _MB_CAPABLE
- if (ps == NULL)
- {
- _REENT_CHECK_MISC(r);
- ps = &(_REENT_MBSRTOWCS_STATE(r));
- }
-#endif
-
- if (dst == NULL)
- {
- /* Ignore original n value and do not alter src pointer if the
- dst pointer is NULL. */
- n = (size_t)-1;
- tmp_src = *src;
- src = &tmp_src;
- }
-
- max = n;
- while (n > 0)
- {
- bytes = _mbrtowc_r (r, ptr, *src, MB_CUR_MAX, ps);
- if (bytes > 0)
- {
- *src += bytes;
- ++count;
- ptr = (dst == NULL) ? NULL : ptr + 1;
- --n;
- }
- else if (bytes == -2)
- {
- *src += MB_CUR_MAX;
- }
- else if (bytes == 0)
- {
- *src = NULL;
- return count;
- }
- else
- {
- ps->__count = 0;
- r->_errno = EILSEQ;
- return (size_t)-1;
- }
- }
-
- return (size_t)max;
+ return _mbsnrtowcs_r (r, dst, src, (size_t) -1, len, ps);
}
#ifndef _REENT_ONLY
@@ -75,6 +24,6 @@ _DEFUN (mbsrtowcs, (dst, src, len, ps),
size_t len _AND
mbstate_t *ps)
{
- return _mbsrtowcs_r (_REENT, dst, src, len, ps);
+ return _mbsnrtowcs_r (_REENT, dst, src, (size_t) -1, len, ps);
}
#endif /* !_REENT_ONLY */
Index: libc/stdlib/wcsnrtombs.c
===================================================================
RCS file: libc/stdlib/wcsnrtombs.c
diff -N libc/stdlib/wcsnrtombs.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ libc/stdlib/wcsnrtombs.c 13 Feb 2009 18:29:42 -0000
@@ -0,0 +1,89 @@
+#include <reent.h>
+#include <newlib.h>
+#include <wchar.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+
+size_t
+_DEFUN (_wcsnrtombs_r, (r, dst, src, nwc, len, ps),
+ struct _reent *r _AND
+ char *dst _AND
+ const wchar_t **src _AND
+ size_t nwc _AND
+ size_t len _AND
+ mbstate_t *ps)
+{
+ char *ptr = dst;
+ char buff[10];
+ wchar_t *pwcs;
+ size_t n;
+ int i;
+
+#ifdef _MB_CAPABLE
+ if (ps == NULL)
+ {
+ _REENT_CHECK_MISC(r);
+ ps = &(_REENT_WCSRTOMBS_STATE(r));
+ }
+#endif
+
+ /* If no dst pointer, treat len as maximum possible value. */
+ if (dst == NULL)
+ len = (size_t)-1;
+
+ n = 0;
+ pwcs = (wchar_t *)(*src);
+
+ while (n < len && nwc-- > 0)
+ {
+ int count = ps->__count;
+ wint_t wch = ps->__value.__wch;
+ int bytes = _wcrtomb_r (r, buff, *pwcs, ps);
+ if (bytes == -1)
+ {
+ r->_errno = EILSEQ;
+ ps->__count = 0;
+ return (size_t)-1;
+ }
+ if (n + bytes <= len)
+ {
+ n += bytes;
+ if (dst)
+ {
+ for (i = 0; i < bytes; ++i)
+ *ptr++ = buff[i];
+ ++(*src);
+ }
+ if (*pwcs++ == 0x00)
+ {
+ if (dst)
+ *src = NULL;
+ ps->__count = 0;
+ return n - 1;
+ }
+ }
+ else
+ {
+ /* not enough room, we must back up state to before _wctomb_r call */
+ ps->__count = count;
+ ps->__value.__wch = wch;
+ len = 0;
+ }
+ }
+
+ return n;
+}
+
+#ifndef _REENT_ONLY
+size_t
+_DEFUN (wcsnrtombs, (dst, src, nwc, len, ps),
+ char *dst _AND
+ const wchar_t **src _AND
+ size_t nwc _AND
+ size_t len _AND
+ mbstate_t *ps)
+{
+ return _wcsnrtombs_r (_REENT, dst, src, nwc, len, ps);
+}
+#endif /* !_REENT_ONLY */
Index: libc/stdlib/wcsrtombs.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdlib/wcsrtombs.c,v
retrieving revision 1.8
diff -u -p -r1.8 wcsrtombs.c
--- libc/stdlib/wcsrtombs.c 28 Aug 2008 17:36:49 -0000 1.8
+++ libc/stdlib/wcsrtombs.c 13 Feb 2009 18:29:42 -0000
@@ -1,9 +1,6 @@
#include <reent.h>
#include <newlib.h>
#include <wchar.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <errno.h>
size_t
_DEFUN (_wcsrtombs_r, (r, dst, src, len, ps),
@@ -13,65 +10,7 @@ _DEFUN (_wcsrtombs_r, (r, dst, src, len,
size_t len _AND
mbstate_t *ps)
{
- char *ptr = dst;
- char buff[10];
- wchar_t *pwcs;
- size_t n;
- int i;
-
-#ifdef _MB_CAPABLE
- if (ps == NULL)
- {
- _REENT_CHECK_MISC(r);
- ps = &(_REENT_WCSRTOMBS_STATE(r));
- }
-#endif
-
- /* If no dst pointer, treat len as maximum possible value. */
- if (dst == NULL)
- len = (size_t)-1;
-
- n = 0;
- pwcs = (wchar_t *)(*src);
-
- while (n < len)
- {
- int count = ps->__count;
- wint_t wch = ps->__value.__wch;
- int bytes = _wcrtomb_r (r, buff, *pwcs, ps);
- if (bytes == -1)
- {
- r->_errno = EILSEQ;
- ps->__count = 0;
- return (size_t)-1;
- }
- if (n + bytes <= len)
- {
- n += bytes;
- if (dst)
- {
- for (i = 0; i < bytes; ++i)
- *ptr++ = buff[i];
- ++(*src);
- }
- if (*pwcs++ == 0x00)
- {
- if (dst)
- *src = NULL;
- ps->__count = 0;
- return n - 1;
- }
- }
- else
- {
- /* not enough room, we must back up state to before _wctomb_r call */
- ps->__count = count;
- ps->__value.__wch = wch;
- len = 0;
- }
- }
-
- return n;
+ return _wcsnrtombs_r (r, dst, src, (size_t) -1, len, ps);
}
#ifndef _REENT_ONLY
@@ -82,6 +21,6 @@ _DEFUN (wcsrtombs, (dst, src, len, ps),
size_t len _AND
mbstate_t *ps)
{
- return _wcsrtombs_r (_REENT, dst, src, len, ps);
+ return _wcsnrtombs_r (_REENT, dst, src, (size_t) -1, len, ps);
}
#endif /* !_REENT_ONLY */
--
Corinna Vinschen
Cygwin Project Co-Leader
Red Hat