- do_final_flush2 = false;
- incremented2 = true;
- }
-
- length = out2ptr - result;
- grow = (length + extra_alloc > allocated / 2);
- if (res2 == (size_t)(-1))
- {
- if (errno == E2BIG)
- grow = true;
- else if (errno == EINVAL)
- break;
- else if (errno == EILSEQ && handler != iconveh_error)
- {
- /* Error handling can produce up to 10 bytes of ASCII
- output. But TO_CODESET may be UCS-2, UTF-16 or
- UCS-4, so use CD2 here as well. */
- char scratchbuf[10];
- size_t scratchlen;
- ucs4_t uc;
- const char *inptr;
- size_t insize;
- size_t res;
-
- if (incremented2)
- {
- if (u8_prev (&uc, (const uint8_t *) in2ptr,
- (const uint8_t *) utf8buf)
- == NULL)
- abort ();
- }
- else
- {
- int n;
- if (in2size == 0)
- abort ();
- n = u8_mbtouc_unsafe (&uc, (const uint8_t *) in2ptr,
- in2size);
- in2ptr += n;
- in2size -= n;
- }
-
- if (handler == iconveh_escape_sequence)
- {
- static char hex[16] = "0123456789ABCDEF";
- scratchlen = 0;
- scratchbuf[scratchlen++] = '\\';
- if (uc < 0x10000)
- scratchbuf[scratchlen++] = 'u';
- else
- {
- scratchbuf[scratchlen++] = 'U';
- scratchbuf[scratchlen++] = hex[(uc>>28) & 15];
- scratchbuf[scratchlen++] = hex[(uc>>24) & 15];
- scratchbuf[scratchlen++] = hex[(uc>>20) & 15];
- scratchbuf[scratchlen++] = hex[(uc>>16) & 15];
- }
- scratchbuf[scratchlen++] = hex[(uc>>12) & 15];
- scratchbuf[scratchlen++] = hex[(uc>>8) & 15];
- scratchbuf[scratchlen++] = hex[(uc>>4) & 15];
- scratchbuf[scratchlen++] = hex[uc & 15];
- }
- else
- {
- scratchbuf[0] = '?';
- scratchlen = 1;
- }
-
- inptr = scratchbuf;
- insize = scratchlen;
- res = iconv (cd2,
- (ICONV_CONST char **) &inptr, &insize,
- &out2ptr, &out2size);
- length = out2ptr - result;
- if (res == (size_t)(-1) && errno == E2BIG)
- {
- char *memory;
-
- allocated = 2 * allocated;
- if (length + 1 + extra_alloc > allocated)
- abort ();
- if (result == initial_result)
- memory = (char *) malloc (allocated);
- else
- memory = (char *) realloc (result, allocated);
- if (memory == NULL)
- {
- if (result != initial_result)
- free (result);
- errno = ENOMEM;
- return -1;
- }
- if (result == initial_result)
- memcpy (memory, initial_result, length);
- result = memory;
- grow = false;
-
- out2ptr = result + length;
- out2size = allocated - extra_alloc - length;
- res = iconv (cd2,
- (ICONV_CONST char **) &inptr, &insize,
- &out2ptr, &out2size);
- length = out2ptr - result;
- }
+ res2 = 0;
+ do_final_flush2 = false;
+ incremented2 = true;
+ }
+
+ length = out2ptr - result;
+ grow = (length + extra_alloc > allocated / 2);
+ if (res2 == (size_t)(-1))
+ {
+ if (errno == E2BIG)
+ grow = true;
+ else if (errno == EINVAL)
+ break;
+ else if (errno == EILSEQ && handler != iconveh_error)
+ {
+ /* Error handling can produce up to 10 bytes of ASCII
+ output. But TO_CODESET may be UCS-2, UTF-16 or
+ UCS-4, so use CD2 here as well. */
+ char scratchbuf[10];
+ size_t scratchlen;
+ ucs4_t uc;
+ const char *inptr;
+ size_t insize;
+ size_t res;
+
+ if (incremented2)
+ {
+ if (u8_prev (&uc, (const uint8_t *) in2ptr,
+ (const uint8_t *) utf8buf)
+ == NULL)
+ abort ();
+ }
+ else
+ {
+ int n;
+ if (in2size == 0)
+ abort ();
+ n = u8_mbtouc_unsafe (&uc, (const uint8_t *) in2ptr,
+ in2size);
+ in2ptr += n;
+ in2size -= n;
+ }
+
+ if (handler == iconveh_escape_sequence)
+ {
+ static char hex[16] = "0123456789ABCDEF";
+ scratchlen = 0;
+ scratchbuf[scratchlen++] = '\\';
+ if (uc < 0x10000)
+ scratchbuf[scratchlen++] = 'u';
+ else
+ {
+ scratchbuf[scratchlen++] = 'U';
+ scratchbuf[scratchlen++] = hex[(uc>>28) & 15];
+ scratchbuf[scratchlen++] = hex[(uc>>24) & 15];
+ scratchbuf[scratchlen++] = hex[(uc>>20) & 15];
+ scratchbuf[scratchlen++] = hex[(uc>>16) & 15];
+ }
+ scratchbuf[scratchlen++] = hex[(uc>>12) & 15];
+ scratchbuf[scratchlen++] = hex[(uc>>8) & 15];
+ scratchbuf[scratchlen++] = hex[(uc>>4) & 15];
+ scratchbuf[scratchlen++] = hex[uc & 15];
+ }
+ else
+ {
+ scratchbuf[0] = '?';
+ scratchlen = 1;
+ }
+
+ inptr = scratchbuf;
+ insize = scratchlen;
+ if (cd2 != (iconv_t)(-1))
+ res = iconv (cd2,
+ (ICONV_CONST char **) &inptr, &insize,
+ &out2ptr, &out2size);
+ else
+ {
+ /* TO_CODESET is UTF-8. */
+ if (out2size >= insize)
+ {
+ memcpy (out2ptr, inptr, insize);
+ out2ptr += insize;
+ out2size -= insize;
+ inptr += insize;
+ insize = 0;
+ res = 0;
+ }
+ else
+ {
+ errno = E2BIG;
+ res = (size_t)(-1);
+ }
+ }
+ length = out2ptr - result;
+ if (res == (size_t)(-1) && errno == E2BIG)
+ {
+ char *memory;
+
+ allocated = 2 * allocated;
+ if (length + 1 + extra_alloc > allocated)
+ abort ();
+ if (result == initial_result)
+ memory = (char *) malloc (allocated);
+ else
+ memory = (char *) realloc (result, allocated);
+ if (memory == NULL)
+ {
+ if (result != initial_result)
+ free (result);
+ errno = ENOMEM;
+ return -1;
+ }
+ if (result == initial_result)
+ memcpy (memory, initial_result, length);
+ result = memory;
+ grow = false;
+
+ out2ptr = result + length;
+ out2size = allocated - extra_alloc - length;
+ if (cd2 != (iconv_t)(-1))
+ res = iconv (cd2,
+ (ICONV_CONST char **) &inptr,
+ &insize,
+ &out2ptr, &out2size);
+ else
+ {
+ /* TO_CODESET is UTF-8. */
+ if (!(out2size >= insize))
+ abort ();
+ memcpy (out2ptr, inptr, insize);
+ out2ptr += insize;
+ out2size -= insize;
+ inptr += insize;
+ insize = 0;
+ res = 0;
+ }
+ length = out2ptr - result;
+ }