bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: iconv modules


From: Bruno Haible
Subject: Re: iconv modules
Date: Tue, 12 Dec 2006 13:46:54 +0100
User-agent: KMail/1.9.1

Simon Josefsson wrote on 2006-09-06:
> > What do you think about them?
> > Acceptable?
> 
> It looks good to me.

I applied these changes.

Let us know when we can remove the iconvme module. Remember the migration
path:
  iconvme::iconv_string -> str_iconv
  iconvme::iconv_alloc -> str_cd_iconv (with reversed arguments)

Bruno


2006-12-12  Bruno Haible  <address@hidden>

        Merge these changes.
        2006-09-05  Bruno Haible  <address@hidden>
        * lib/iconvme.c (iconv_string): No need to save and restore errno when
        iconv_alloc succeeded.
        (iconv_alloc): Don't assume that malloc() or realloc(), when failing,
        sets errno to ENOMEM. (malloc on GNU/kFreeBSD doesn't.) No need to
        test for " && dest " at the end - dest is always != NULL there. Call
        iconv with 4xNULL arguments initially, to reset the state. Call iconv
        with 2xNULL arguments, also to flush the state storage. Handle the
        IRIX iconv behaviour. Realloc the final result, to throw away unused
        memory.

*** lib/iconvme.c       29 Oct 2006 21:52:55 -0000      1.7
--- lib/iconvme.c       12 Dec 2006 12:40:51 -0000
***************
*** 73,93 ****
  
    dest = iconv_alloc (cd, str);
  
!   {
!     int save_errno = errno;
! 
!     if (iconv_close (cd) < 0 && dest)
!       {
!       int save_errno2 = errno;
!       /* If we didn't have a real error before, make sure we restore
!          the iconv_close error below. */
!       free (dest);
!       dest = NULL;
!       errno = save_errno2;
!       }
!     else
!       errno = save_errno;
!   }
  #else
    errno = ENOSYS;
  #endif
--- 73,96 ----
  
    dest = iconv_alloc (cd, str);
  
!   if (dest == NULL)
!     {
!       int saved_errno = errno;
!       iconv_close (cd);
!       errno = saved_errno;
!     }
!   else
!     {
!       if (iconv_close (cd) < 0)
!       {
!         int saved_errno2 = errno;
!         /* If we didn't have a real error before, make sure we restore
!            the iconv_close error below. */
!         free (dest);
!         dest = NULL;
!         errno = saved_errno2;
!       }
!     }
  #else
    errno = ENOSYS;
  #endif
***************
*** 126,132 ****
  
    outp = dest = (char *) malloc (outbuf_size);
    if (dest == NULL)
!     return NULL;
  
  again:
    err = iconv (cd, &p, &inbytes_remaining, &outp, &outbytes_remaining);
--- 129,145 ----
  
    outp = dest = (char *) malloc (outbuf_size);
    if (dest == NULL)
!     {
!       errno = ENOMEM;
!       return NULL;
!     }
! 
!   /* Avoid glibc-2.1 bug and Solaris 2.7-2.9 bug.  */
! # if defined _LIBICONV_VERSION \
!     || !((__GLIBC__ - 0 == 2 && __GLIBC_MINOR__ - 0 <= 1) || defined __sun)
!   /* Set to the initial state.  */
!   iconv (cd, NULL, NULL, NULL, NULL);
! # endif
  
  again:
    err = iconv (cd, &p, &inbytes_remaining, &outp, &outbytes_remaining);
***************
*** 154,159 ****
--- 167,173 ----
            newdest = (char *) realloc (dest, newsize);
            if (newdest == NULL)
              {
+               errno = ENOMEM;
                have_error = 1;
                goto out;
              }
***************
*** 176,186 ****
          break;
        }
      }
  
!   *outp = '\0';
  
  out:
!   if (have_error && dest)
      {
        int save_errno = errno;
        free (dest);
--- 190,269 ----
          break;
        }
      }
+ # if !defined _LIBICONV_VERSION && (defined sgi || defined __sgi)
+   /* Irix iconv() inserts a NUL byte if it cannot convert.  */
+   else if (err > 0)
+     {
+       errno = EILSEQ;
+       have_error = 1;
+       goto out;
+     }
+ # endif
+ 
+ again2:
+   err = iconv (cd, NULL, NULL, &outp, &outbytes_remaining);
+ 
+   if (err == (size_t) -1)
+     {
+       switch (errno)
+       {
+       case E2BIG:
+         {
+           size_t used = outp - dest;
+           size_t newsize = outbuf_size * 2;
+           char *newdest;
+ 
+           if (newsize <= outbuf_size)
+             {
+               errno = ENOMEM;
+               have_error = 1;
+               goto out;
+             }
+           newdest = (char *) realloc (dest, newsize);
+           if (newdest == NULL)
+             {
+               errno = ENOMEM;
+               have_error = 1;
+               goto out;
+             }
+           dest = newdest;
+           outbuf_size = newsize;
+ 
+           outp = dest + used;
+           outbytes_remaining = outbuf_size - used - 1;        /* -1 for NUL */
+ 
+           goto again2;
+         }
+         break;
+ 
+       default:
+         have_error = 1;
+         break;
+       }
+     }
+ # if !defined _LIBICONV_VERSION && (defined sgi || defined __sgi)
+   /* Irix iconv() inserts a NUL byte if it cannot convert.  */
+   else if (err > 0)
+     {
+       errno = EILSEQ;
+       have_error = 1;
+       goto out;
+     }
+ # endif
+ 
+   *outp++ = '\0';
  
!   /* Give away unused memory.  */
!   if (outp - dest < outbuf_size)
!     {
!       char *newdest = (char *) realloc (dest, outp - dest);
! 
!       if (newdest != NULL)
!       dest = newdest;
!     }
  
  out:
!   if (have_error)
      {
        int save_errno = errno;
        free (dest);




reply via email to

[Prev in Thread] Current Thread [Next in Thread]