diff options
Diffstat (limited to 'iconv')
-rw-r--r-- | iconv/gconv.h | 6 | ||||
-rw-r--r-- | iconv/gconv_open.c | 34 | ||||
-rw-r--r-- | iconv/skeleton.c | 11 |
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); |