From 2e10d61ccb8311e75df612a028873f212020057a Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Thu, 19 Feb 2009 09:19:42 +0000 Subject: [PATCH] * 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. Document mbsnrtowcs and mbsrtowcs. * libc/stdlib/mbsrtowcs.c (_mbsrtowcs_r): Just call _mbsnrtowcs_r. (mbsrtowcs): Ditto. * libc/stdlib/wcsnrtombs.c: New file, implementing _wcsnrtombs_r and wcsnrtombs. Document wcsrtombs and wcsnrtombs. * libc/stdlib/wcsrtombs.c (_wcsrtombs_r): Just call _wcsnrtombs_r. (wcsrtombs): Ditto. * libc/stdlib/stdlib.tex: Accommodate new documentation. --- newlib/ChangeLog | 19 ++++ newlib/libc/include/wchar.h | 8 ++ newlib/libc/stdlib/Makefile.am | 2 + newlib/libc/stdlib/Makefile.in | 26 ++++- newlib/libc/stdlib/mbsnrtowcs.c | 179 +++++++++++++++++++++++++++++++ newlib/libc/stdlib/mbsrtowcs.c | 59 +--------- newlib/libc/stdlib/stdlib.tex | 8 ++ newlib/libc/stdlib/wcsnrtombs.c | 184 ++++++++++++++++++++++++++++++++ newlib/libc/stdlib/wcsrtombs.c | 65 +---------- 9 files changed, 427 insertions(+), 123 deletions(-) create mode 100644 newlib/libc/stdlib/mbsnrtowcs.c create mode 100644 newlib/libc/stdlib/wcsnrtombs.c diff --git a/newlib/ChangeLog b/newlib/ChangeLog index 525548a09..b96d46d6b 100644 --- a/newlib/ChangeLog +++ b/newlib/ChangeLog @@ -1,3 +1,22 @@ +2009-02-19 Corinna Vinschen + + * 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. Document mbsnrtowcs and mbsrtowcs. + * libc/stdlib/mbsrtowcs.c (_mbsrtowcs_r): Just call _mbsnrtowcs_r. + (mbsrtowcs): Ditto. + * libc/stdlib/wcsnrtombs.c: New file, implementing _wcsnrtombs_r + and wcsnrtombs. Document wcsrtombs and wcsnrtombs. + * libc/stdlib/wcsrtombs.c (_wcsrtombs_r): Just call _wcsnrtombs_r. + (wcsrtombs): Ditto. + * libc/stdlib/stdlib.tex: Accommodate new documentation. + 2009-02-18 Jeff Johnston * libc/stdio/open_memstream.c (internal_open_memstream_r): Fix max diff --git a/newlib/libc/include/wchar.h b/newlib/libc/include/wchar.h index 4cec3ce95..ad905e2bf 100644 --- a/newlib/libc/include/wchar.h +++ b/newlib/libc/include/wchar.h @@ -47,10 +47,18 @@ size_t _EXFUN(mbrtowc, (wchar_t * , const char * , size_t, mbstate_t *)); 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 *)); diff --git a/newlib/libc/stdlib/Makefile.am b/newlib/libc/stdlib/Makefile.am index 9a9c013d7..6a9296e62 100644 --- a/newlib/libc/stdlib/Makefile.am +++ b/newlib/libc/stdlib/Makefile.am @@ -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 diff --git a/newlib/libc/stdlib/Makefile.in b/newlib/libc/stdlib/Makefile.in index 2dfbfed8f..ab06a0ef3 100644 --- a/newlib/libc/stdlib/Makefile.in +++ b/newlib/libc/stdlib/Makefile.in @@ -111,9 +111,10 @@ am__objects_3 = lib_a-a64l.$(OBJEXT) lib_a-btowc.$(OBJEXT) \ lib_a-getopt.$(OBJEXT) lib_a-getsubopt.$(OBJEXT) \ lib_a-l64a.$(OBJEXT) lib_a-malign.$(OBJEXT) \ lib_a-mbrlen.$(OBJEXT) lib_a-mbrtowc.$(OBJEXT) \ - lib_a-mbsinit.$(OBJEXT) lib_a-mbsrtowcs.$(OBJEXT) \ - lib_a-on_exit.$(OBJEXT) lib_a-valloc.$(OBJEXT) \ - lib_a-wcrtomb.$(OBJEXT) lib_a-wcsrtombs.$(OBJEXT) \ + lib_a-mbsinit.$(OBJEXT) lib_a-mbsnrtowcs.$(OBJEXT) \ + lib_a-mbsrtowcs.$(OBJEXT) lib_a-on_exit.$(OBJEXT) \ + lib_a-valloc.$(OBJEXT) lib_a-wcrtomb.$(OBJEXT) \ + lib_a-wcsnrtombs.$(OBJEXT) lib_a-wcsrtombs.$(OBJEXT) \ lib_a-wctob.$(OBJEXT) am__objects_4 = lib_a-putenv.$(OBJEXT) lib_a-putenv_r.$(OBJEXT) \ lib_a-setenv.$(OBJEXT) lib_a-setenv_r.$(OBJEXT) @@ -146,8 +147,9 @@ am__objects_8 = cxa_atexit.lo cxa_finalize.lo drand48.lo ecvtbuf.lo \ wcstoll.lo wcstoll_r.lo wcstoull.lo wcstoull_r.lo atoll.lo \ llabs.lo lldiv.lo am__objects_9 = a64l.lo btowc.lo getopt.lo getsubopt.lo l64a.lo \ - malign.lo mbrlen.lo mbrtowc.lo mbsinit.lo mbsrtowcs.lo \ - on_exit.lo valloc.lo wcrtomb.lo wcsrtombs.lo wctob.lo + malign.lo mbrlen.lo mbrtowc.lo mbsinit.lo mbsnrtowcs.lo \ + mbsrtowcs.lo on_exit.lo valloc.lo wcrtomb.lo wcsnrtombs.lo \ + wcsrtombs.lo wctob.lo am__objects_10 = putenv.lo putenv_r.lo setenv.lo setenv_r.lo am__objects_11 = system.lo @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@am__objects_12 = $(am__objects_9) \ @@ -440,10 +442,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 @@ -1142,6 +1146,12 @@ lib_a-mbsinit.o: mbsinit.c lib_a-mbsinit.obj: mbsinit.c $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-mbsinit.obj `if test -f 'mbsinit.c'; then $(CYGPATH_W) 'mbsinit.c'; else $(CYGPATH_W) '$(srcdir)/mbsinit.c'; fi` +lib_a-mbsnrtowcs.o: mbsnrtowcs.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-mbsnrtowcs.o `test -f 'mbsnrtowcs.c' || echo '$(srcdir)/'`mbsnrtowcs.c + +lib_a-mbsnrtowcs.obj: mbsnrtowcs.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-mbsnrtowcs.obj `if test -f 'mbsnrtowcs.c'; then $(CYGPATH_W) 'mbsnrtowcs.c'; else $(CYGPATH_W) '$(srcdir)/mbsnrtowcs.c'; fi` + lib_a-mbsrtowcs.o: mbsrtowcs.c $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-mbsrtowcs.o `test -f 'mbsrtowcs.c' || echo '$(srcdir)/'`mbsrtowcs.c @@ -1166,6 +1176,12 @@ lib_a-wcrtomb.o: wcrtomb.c lib_a-wcrtomb.obj: wcrtomb.c $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-wcrtomb.obj `if test -f 'wcrtomb.c'; then $(CYGPATH_W) 'wcrtomb.c'; else $(CYGPATH_W) '$(srcdir)/wcrtomb.c'; fi` +lib_a-wcsnrtombs.o: wcsnrtombs.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-wcsnrtombs.o `test -f 'wcsnrtombs.c' || echo '$(srcdir)/'`wcsnrtombs.c + +lib_a-wcsnrtombs.obj: wcsnrtombs.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-wcsnrtombs.obj `if test -f 'wcsnrtombs.c'; then $(CYGPATH_W) 'wcsnrtombs.c'; else $(CYGPATH_W) '$(srcdir)/wcsnrtombs.c'; fi` + lib_a-wcsrtombs.o: wcsrtombs.c $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-wcsrtombs.o `test -f 'wcsrtombs.c' || echo '$(srcdir)/'`wcsrtombs.c diff --git a/newlib/libc/stdlib/mbsnrtowcs.c b/newlib/libc/stdlib/mbsnrtowcs.c new file mode 100644 index 000000000..6729df951 --- /dev/null +++ b/newlib/libc/stdlib/mbsnrtowcs.c @@ -0,0 +1,179 @@ +/* +FUNCTION +<>, <>---convert a character string to a wide-character string + +INDEX + mbsrtowcs +INDEX + _mbsrtowcs_r +INDEX + mbsnrtowcs +INDEX + _mbsnrtowcs_r + +ANSI_SYNOPSIS + #include + size_t mbsrtowcs(wchar_t *<[dst]>, const char **<[src]>, size_t <[len]>, + mbstate_t *<[ps]>); + + #include + size_t _mbsrtowcs_r(struct _reent *<[ptr]>, wchar_t *<[dst]>, + const char **<[src]>, size_t <[len]>, + mbstate_t *<[ps]>); + + #include + size_t mbsnrtowcs(wchar_t *<[dst]>, const char **<[src]>, + size_t <[nms]>, size_t <[len]>, mbstate_t *<[ps]>); + + #include + size_t _mbsnrtowcs_r(struct _reent *<[ptr]>, wchar_t *<[dst]>, + const char **<[src]>, size_t <[nms]>, + size_t <[len]>, mbstate_t *<[ps]>); + +TRAD_SYNOPSIS + #include + size_t mbsrtowcs(<[dst]>, <[src]>, <[len]>, <[ps]>) + wchar_t *<[dst]>; + const char **<[src]>; + size_t <[len]>; + mbstate_t *<[ps]>; + + #include + size_t _mbsrtowcs_r(<[ptr]>, <[dst]>, <[src]>, <[len]>, <[ps]>) + struct _reent *<[ptr]>; + wchar_t *<[dst]>; + const char **<[src]>; + size_t <[len]>; + mbstate_t *<[ps]>; + + #include + size_t mbsnrtowcs(<[dst]>, <[src]>, <[nms]>, <[len]>, <[ps]>) + wchar_t *<[dst]>; + const char **<[src]>; + size_t <[nms]>; + size_t <[len]>; + mbstate_t *<[ps]>; + + #include + size_t _mbsnrtowcs_r(<[ptr]>, <[dst]>, <[src]>, <[nms]>, <[len]>, <[ps]>) + struct _reent *<[ptr]>; + wchar_t *<[dst]>; + const char **<[src]>; + size_t <[nms]>; + size_t <[len]>; + mbstate_t *<[ps]>; + +DESCRIPTION +The <> function converts a sequence of multibyte characters +pointed to indirectly by <[src]> into a sequence of corresponding wide +characters and stores at most <[len]> of them in the wchar_t array pointed +to by <[dst]>, until it encounters a terminating null character ('\0'). + +If <[dst]> is NULL, no characters are stored. + +If <[dst]> is not NULL, the pointer pointed to by <[src]> is updated to point +to the character after the one that conversion stopped at. If conversion +stops because a null character is encountered, *<[src]> is set to NULL. + +The mbstate_t argument, <[ps]>, is used to keep track of the shift state. If +it is NULL, <> uses an internal, static mbstate_t object, which +is initialized to the initial conversion state at program startup. + +The <> function behaves identically to <>, except that +conversion stops after reading at most <[nms]> bytes from the buffer pointed +to by <[src]>. + +RETURNS +The <> and <> functions return the number of wide +characters stored in the array pointed to by <[dst]> if successful, otherwise +it returns (size_t)-1. + +PORTABILITY +<> is defined by the C99 standard. +<> is defined by the POSIX.1-2008 standard. +*/ + +#include +#include +#include +#include +#include +#include + +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) + { + *src += nms; + 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 */ diff --git a/newlib/libc/stdlib/mbsrtowcs.c b/newlib/libc/stdlib/mbsrtowcs.c index 2eaa0fe56..d5137d144 100644 --- a/newlib/libc/stdlib/mbsrtowcs.c +++ b/newlib/libc/stdlib/mbsrtowcs.c @@ -6,65 +6,14 @@ #include 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 */ diff --git a/newlib/libc/stdlib/stdlib.tex b/newlib/libc/stdlib/stdlib.tex index d91b3f8d3..9242246db 100644 --- a/newlib/libc/stdlib/stdlib.tex +++ b/newlib/libc/stdlib/stdlib.tex @@ -29,6 +29,7 @@ The corresponding declarations are in the header file @file{stdlib.h}. * malloc:: Allocate and manage memory (malloc, realloc, free) * mallinfo:: Get information about allocated memory * __malloc_lock:: Lock memory pool for malloc and free +* mbsnrtowcs:: Convert a character string to a wide-character string * mbstowcs:: Minimal multibyte string to wide string converter * mblen:: Minimal multibyte length * mbtowc:: Minimal multibyte to wide character converter @@ -40,6 +41,7 @@ The corresponding declarations are in the header file @file{stdlib.h}. * strtoll:: String to long long * strtoul:: String to unsigned long * strtoull:: String to unsigned long long +* wcsnrtombs:: Convert a wide-character string to a character string * wcstod:: Wide string to double or float * wcstol:: Wide string to long * wcstoll:: Wide string to long long @@ -122,6 +124,9 @@ The corresponding declarations are in the header file @file{stdlib.h}. @page @include stdlib/mblen.def +@page +@include stdlib/mbsnrtowcs.def + @page @include stdlib/mbstowcs.def @@ -152,6 +157,9 @@ The corresponding declarations are in the header file @file{stdlib.h}. @page @include stdlib/strtoull.def +@page +@include stdlib/wcsnrtombs.def + @page @include stdlib/wcstod.def diff --git a/newlib/libc/stdlib/wcsnrtombs.c b/newlib/libc/stdlib/wcsnrtombs.c new file mode 100644 index 000000000..a8e6901a3 --- /dev/null +++ b/newlib/libc/stdlib/wcsnrtombs.c @@ -0,0 +1,184 @@ +/* +FUNCTION +<>, <>---convert a wide-character string to a character string + +INDEX + wcsrtombs +INDEX + _wcsrtombs_r +INDEX + wcsnrtombs +INDEX + _wcsnrtombs_r + +ANSI_SYNOPSIS + #include + size_t wcsrtombs(char *<[dst]>, const wchar_t **<[src]>, size_t <[len]>, + mbstate_t *<[ps]>); + + #include + size_t _wcsrtombs_r(struct _reent *<[ptr]>, char *<[dst]>, + const wchar_t **<[src]>, size_t <[len]>, + mbstate_t *<[ps]>); + + #include + size_t wcsnrtombs(char *<[dst]>, const wchar_t **<[src]>, + size_t <[nwc]>, size_t <[len]>, mbstate_t *<[ps]>); + + #include + size_t _wcsnrtombs_r(struct _reent *<[ptr]>, char *<[dst]>, + const wchar_t **<[src]>, size_t <[nwc]>, + size_t <[len]>, mbstate_t *<[ps]>); + +TRAD_SYNOPSIS + #include + size_t wcsrtombs(<[dst]>, <[src]>, <[len]>, <[ps]>) + char *<[dst]>; + const wchar_t **<[src]>; + size_t <[len]>; + mbstate_t *<[ps]>; + + #include + size_t _wcsrtombs_r(<[ptr]>, <[dst]>, <[src]>, <[len]>, <[ps]>) + struct _rent *<[ptr]>; + char *<[dst]>; + const wchar_t **<[src]>; + size_t <[len]>; + mbstate_t *<[ps]>; + + #include + size_t wcsnrtombs(<[dst]>, <[src]>, <[nwc]>, <[len]>, <[ps]>) + char *<[dst]>; + const wchar_t **<[src]>; + size_t <[nwc]>; + size_t <[len]>; + mbstate_t *<[ps]>; + + #include + size_t _wcsnrtombs_r(<[ptr]>, <[dst]>, <[src]>, <[nwc]>, <[len]>, <[ps]>) + struct _rent *<[ptr]>; + char *<[dst]>; + const wchar_t **<[src]>; + size_t <[nwc]>; + size_t <[len]>; + mbstate_t *<[ps]>; + +DESCRIPTION +The <> function converts a string of wide characters indirectly +pointed to by <[src]> to a corresponding multibyte character string stored in +the array pointed to by <[dst}>. No more than <[len]> bytes are written to +<[dst}>. + +If <[dst}> is NULL, no characters are stored. + +If <[dst}> is not NULL, the pointer pointed to by <[src]> is updated to point +to the character after the one that conversion stopped at. If conversion +stops because a null character is encountered, *<[src]> is set to NULL. + +The mbstate_t argument, <[ps]>, is used to keep track of the shift state. If +it is NULL, <> uses an internal, static mbstate_t object, which +is initialized to the initial conversion state at program startup. + +The <> function behaves identically to <>, except that +conversion stops after reading at most <[nwc]> characters from the buffer +pointed to by <[src]>. + +RETURNS +The <> and <> functions return the number of bytes +stored in the array pointed to by <[dst]> (not including any terminating +null), if successful, otherwise it returns (size_t)-1. + +PORTABILITY +<> is defined by C99 standard. +<> is defined by the POSIX.1-2008 standard. +*/ + +#include +#include +#include +#include +#include +#include + +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 */ diff --git a/newlib/libc/stdlib/wcsrtombs.c b/newlib/libc/stdlib/wcsrtombs.c index a16d36cf6..ea6bd9d43 100644 --- a/newlib/libc/stdlib/wcsrtombs.c +++ b/newlib/libc/stdlib/wcsrtombs.c @@ -1,9 +1,6 @@ #include #include #include -#include -#include -#include size_t _DEFUN (_wcsrtombs_r, (r, dst, src, len, ps), @@ -13,65 +10,7 @@ _DEFUN (_wcsrtombs_r, (r, dst, src, len, ps), 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 */