about summary refs log tree commit diff
path: root/iconv
diff options
context:
space:
mode:
Diffstat (limited to 'iconv')
-rw-r--r--iconv/gconv.h6
-rw-r--r--iconv/gconv_open.c34
-rw-r--r--iconv/skeleton.c11
3 files changed, 30 insertions, 21 deletions
diff --git a/iconv/gconv.h b/iconv/gconv.h
index 4d7022feb5..85b9a3a0e0 100644
--- a/iconv/gconv.h
+++ b/iconv/gconv.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
+/* Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -100,7 +100,7 @@ struct __gconv_step_data
 {
   unsigned char *__outbuf;    /* Output buffer for this step.  */
   unsigned char *__outbufend; /* Address of first byte after the output
-				 buffer.*/
+				 buffer.  */
 
   /* Is this the last module in the chain.  */
   int __is_last;
@@ -114,7 +114,7 @@ struct __gconv_step_data
   int __internal_use;
 
   __mbstate_t *__statep;
-  __mbstate_t __state;	/* This element should not be used directly by
+  __mbstate_t __state;	/* This element must not be used directly by
 			   any module; always use STATEP!  */
 };
 
diff --git a/iconv/gconv_open.c b/iconv/gconv_open.c
index 4a42a84bc8..35ea4782ac 100644
--- a/iconv/gconv_open.c
+++ b/iconv/gconv_open.c
@@ -1,5 +1,5 @@
 /* Find matching transformation algorithms and initialize steps.
-   Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
+   Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
 
@@ -57,11 +57,13 @@ __gconv_open (const char *toset, const char *fromset, __gconv_t *handle,
 
 	  /* Call all initialization functions for the transformation
 	     step implementations.  */
-	  for (cnt = 0; cnt < nsteps; ++cnt)
+	  for (cnt = 0; cnt < nsteps - 1; ++cnt)
 	    {
+	      size_t size;
+
 	      /* If this is the last step we must not allocate an
 		 output buffer.  */
-	      result->__data[cnt].__is_last = cnt == nsteps - 1;
+	      result->__data[cnt].__is_last = 0;
 
 	      /* Reset the counter.  */
 	      result->__data[cnt].__invocation_counter = 0;
@@ -73,21 +75,23 @@ __gconv_open (const char *toset, const char *fromset, __gconv_t *handle,
 	      result->__data[cnt].__statep = &result->__data[cnt].__state;
 
 	      /* Allocate the buffer.  */
-	      if (!result->__data[cnt].__is_last)
+	      size = (GCONV_NCHAR_GOAL * steps[cnt].__max_needed_to);
+
+	      result->__data[cnt].__outbuf = (char *) malloc (size);
+	      if (result->__data[cnt].__outbuf == NULL)
 		{
-		  size_t size = (GCONV_NCHAR_GOAL
-				 * steps[cnt].__max_needed_to);
-
-		  result->__data[cnt].__outbuf = (char *) malloc (size);
-		  if (result->__data[cnt].__outbuf == NULL)
-		    {
-		      res = __GCONV_NOMEM;
-		      break;
-		    }
-		  result->__data[cnt].__outbufend =
-		    result->__data[cnt].__outbuf + size;
+		  res = __GCONV_NOMEM;
+		  break;
 		}
+	      result->__data[cnt].__outbufend =
+		result->__data[cnt].__outbuf + size;
 	    }
+
+	  /* Now handle the last entry.  */
+	  result->__data[cnt].__is_last = 1;
+	  result->__data[cnt].__invocation_counter = 0;
+	  result->__data[cnt].__internal_use = 0;
+	  result->__data[cnt].__statep = &result->__data[cnt].__state;
 	}
     }
 
diff --git a/iconv/skeleton.c b/iconv/skeleton.c
index 350b532e3a..726a76f00e 100644
--- a/iconv/skeleton.c
+++ b/iconv/skeleton.c
@@ -261,6 +261,9 @@ FUNCTION_NAME (struct __gconv_step *step, struct __gconv_step_data *data,
 			      data->__statep, step->__data, &converted
 			      EXTRA_LOOP_ARGS);
 
+	  /* We finished one use of the loops.  */
+	  ++data->__invocation_counter;
+
 	  /* If this is the last step leave the loop, there is nothing
              we can do.  */
 	  if (data->__is_last)
@@ -324,6 +327,11 @@ FUNCTION_NAME (struct __gconv_step *step, struct __gconv_step_data *data,
 			 rerun.  */
 		      assert (outbuf == outerr);
 		      assert (nstatus == __GCONV_FULL_OUTPUT);
+
+		      /* If we haven't consumed a single byte decrement
+			 the invocation counter.  */
+		      if (outbuf == outstart)
+			--data->__invocation_counter;
 #endif	/* reset input buffer */
 		    }
 
@@ -336,9 +344,6 @@ FUNCTION_NAME (struct __gconv_step *step, struct __gconv_step_data *data,
 		if (status == __GCONV_FULL_OUTPUT)
 		  status = __GCONV_OK;
 	    }
-
-	  /* We finished one use of the loops.  */
-	  ++data->__invocation_counter;
 	}
       while (status == __GCONV_OK);