This is the mail archive of the newlib@sourceware.org mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] mbsnrtowcs/wcsnrtombs


On Feb 13 19:35, Corinna Vinschen wrote:
> 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.

I added the code for the new mbsnrtowcs.c file to this mail again.  The
change to the former version is the handling of incomplete MB sequences
per the discussion starting at
http://sources.redhat.com/ml/newlib/2009/msg00131.html.  It now skips src
by nms bytes.  Since nms is 0 afterwards anyway, we can simply return
the current count.


Corinna


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	14 Feb 2009 09:16:04 -0000
@@ -0,0 +1,84 @@
+#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)
+	{
+	  *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 */

-- 
Corinna Vinschen
Cygwin Project Co-Leader
Red Hat


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]