about summary refs log tree commit diff
path: root/iconv/loop.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2000-04-27 05:42:19 +0000
committerUlrich Drepper <drepper@redhat.com>2000-04-27 05:42:19 +0000
commit316518d610789256841f929e3c5757d1e385fcd5 (patch)
treecf53931201515683b375870c359e5ec81ffe6088 /iconv/loop.c
parentcd201e387c261f9684a76a51e63f194bf49faa3f (diff)
downloadglibc-316518d610789256841f929e3c5757d1e385fcd5.tar.gz
glibc-316518d610789256841f929e3c5757d1e385fcd5.tar.xz
glibc-316518d610789256841f929e3c5757d1e385fcd5.zip
Update.
2000-04-26  Ulrich Drepper  <drepper@redhat.com>

	* iconv/gconv_simple.c (utf8_internal_loop): Correctly reconstruct
	stored character in state in UNPACK_BYTES macro.
	* iconv/loop.c (SINGLE(LOOPFCT)): Make it actually work.  Correct
	test for available characters, handle result of BODY code correctly.
	* localedata/Makefile (test-srcs): Add tst-mbswcs1.
	(distribute): Add tst-mbswcs.sh.
	Add rule to run tst-mbswcs.sh.
	* localedata/tst-mbswcs.sh: New file.
	* localedata/tst-mbswcs1.c: New file.

2000-04-26  Jakub Jelinek  <jakub@redhat.com>

	* nis/nis_callback.c (__nis_create_callback): Do failed memory
	allocation fixups centrally, fix __builtin_expect call, return NULL
	on failure, not NIS_NOMEMORY.

2000-04-27  Bruno Haible  <haible@clisp.cons.org>
Diffstat (limited to 'iconv/loop.c')
-rw-r--r--iconv/loop.c39
1 files changed, 32 insertions, 7 deletions
diff --git a/iconv/loop.c b/iconv/loop.c
index c8f893406a..9c5dbfca77 100644
--- a/iconv/loop.c
+++ b/iconv/loop.c
@@ -307,10 +307,10 @@ SINGLE(LOOPFCT) (const unsigned char **inptrp, const unsigned char *inend,
 #endif
 
   /* Are there enough bytes in the input buffer?  */
-  if (__builtin_expect (inptr + (MAX_NEEDED_INPUT - inlen) > inend, 0))
+  if (__builtin_expect (inptr + (MIN_NEEDED_INPUT - inlen) > inend, 0))
     {
-#ifdef STORE_REST
       *inptrp = inend;
+#ifdef STORE_REST
       inptr = bytebuf;
       inptrp = &inptr;
       inend = &bytebuf[inlen];
@@ -335,28 +335,53 @@ SINGLE(LOOPFCT) (const unsigned char **inptrp, const unsigned char *inend,
   /*  Now add characters from the normal input buffer.  */
   do
     bytebuf[inlen++] = *inptr++;
-  while (inlen < MAX_NEEDED_INPUT);
+  while (inlen < MAX_NEEDED_INPUT && inptr < inend);
 
   inptr = bytebuf;
-  inend = &inptr[MAX_NEEDED_INPUT];
+  inend = &bytebuf[inlen];
+#undef NEED_LENGTH_TEST
+#define NEED_LENGTH_TEST	1
   do
     {
       BODY
     }
   while (0);
 
-  if (result == __GCONV_OK)
+  /* Now we either have produced an output character and consumed all the
+     bytes from the state and at least one more, or the character is still
+     incomplete, or we have some other error (like illegal input character,
+     no space in output buffer).  */
+  if (inptr != bytebuf)
     {
-      /* We successfully converted the character (maybe even more).
-	 Update the pointers passed in.  */
+      /* We found a new character.  */
       assert (inptr - bytebuf > (state->__count & 7));
 
       *inptrp += inptr - bytebuf - (state->__count & 7);
       *outptrp = outptr;
 
+      result = __GCONV_OK;
+
       /* Clear the state buffer.  */
       state->__count &= ~7;
     }
+  else if (result == __GCONV_INCOMPLETE_INPUT)
+    {
+      /* This can only happen if we have less than MAX_NEEDED_INPUT bytes
+	 available.  */
+      assert (inend != &bytebuf[MAX_NEEDED_INPUT]);
+
+      *inptrp += inend - bytebuf - (state->__count & 7);
+#ifdef STORE_REST
+      inptrp = &inptr;
+
+      STORE_REST
+#else
+      /* We don't have enough input for another complete input
+	 character.  */
+      while (inptr < inend)
+	state->__value.__wchb[inlen++] = *inptr++;
+#endif
+    }
 
   return result;
 }