Explain the different license terms for module descriptions,
[gnulib.git] / lib / striconv.c
index 4ca9839..3e5782d 100644 (file)
@@ -1,5 +1,5 @@
 /* Charset conversion.
-   Copyright (C) 2001-2006 Free Software Foundation, Inc.
+   Copyright (C) 2001-2007 Free Software Foundation, Inc.
    Written by Bruno Haible and Simon Josefsson.
 
    This program is free software; you can redistribute it and/or modify
@@ -16,9 +16,7 @@
    along with this program; if not, write to the Free Software Foundation,
    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
 
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
+#include <config.h>
 
 /* Specification.  */
 #include "striconv.h"
@@ -53,7 +51,7 @@ mem_cd_iconv (const char *src, size_t srclen, iconv_t cd,
 
   /* 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)
+     || !((__GLIBC__ - 0 == 2 && __GLIBC_MINOR__ - 0 <= 1) || defined __sun)
   /* Set to the initial state.  */
   iconv (cd, NULL, NULL, NULL, NULL);
 # endif
@@ -61,7 +59,10 @@ mem_cd_iconv (const char *src, size_t srclen, iconv_t cd,
   /* Determine the length we need.  */
   {
     size_t count = 0;
-    char tmpbuf[tmpbufsize];
+    /* The alignment is needed when converting e.g. to glibc's WCHAR_T or
+       libiconv's UCS-4-INTERNAL encoding.  */
+    union { unsigned int align; char buf[tmpbufsize]; } tmp;
+# define tmpbuf tmp.buf
     const char *inptr = src;
     size_t insize = srclen;
 
@@ -82,8 +83,11 @@ mem_cd_iconv (const char *src, size_t srclen, iconv_t cd,
            else
              return -1;
          }
-# if !defined _LIBICONV_VERSION && (defined sgi || defined __sgi)
-       /* Irix iconv() inserts a NUL byte if it cannot convert.  */
+# if !defined _LIBICONV_VERSION && !defined __GLIBC__
+       /* Irix iconv() inserts a NUL byte if it cannot convert.
+          NetBSD iconv() inserts a question mark if it cannot convert.
+          Only GNU libiconv and GNU libc are known to prefer to fail rather
+          than doing a lossy conversion.  */
        else if (res > 0)
          {
            errno = EILSEQ;
@@ -94,7 +98,7 @@ mem_cd_iconv (const char *src, size_t srclen, iconv_t cd,
       }
     /* Avoid glibc-2.1 bug and Solaris 2.7 bug.  */
 # if defined _LIBICONV_VERSION \
-    || !((__GLIBC__ - 0 == 2 && __GLIBC_MINOR__ - 0 <= 1) || defined __sun)
+     || !((__GLIBC__ - 0 == 2 && __GLIBC_MINOR__ - 0 <= 1) || defined __sun)
     {
       char *outptr = tmpbuf;
       size_t outsize = tmpbufsize;
@@ -106,6 +110,7 @@ mem_cd_iconv (const char *src, size_t srclen, iconv_t cd,
     }
 # endif
     length = count;
+# undef tmpbuf
   }
 
   if (length == 0)
@@ -113,7 +118,8 @@ mem_cd_iconv (const char *src, size_t srclen, iconv_t cd,
       *lengthp = 0;
       return 0;
     }
-  result = (*resultp != NULL ? realloc (*resultp, length) : malloc (length));
+  result =
+    (char *) (*resultp != NULL ? realloc (*resultp, length) : malloc (length));
   if (result == NULL)
     {
       errno = ENOMEM;
@@ -124,7 +130,7 @@ mem_cd_iconv (const char *src, size_t srclen, iconv_t cd,
 
   /* 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)
+     || !((__GLIBC__ - 0 == 2 && __GLIBC_MINOR__ - 0 <= 1) || defined __sun)
   /* Return to the initial state.  */
   iconv (cd, NULL, NULL, NULL, NULL);
 # endif
@@ -149,8 +155,11 @@ mem_cd_iconv (const char *src, size_t srclen, iconv_t cd,
            else
              return -1;
          }
-# if !defined _LIBICONV_VERSION && (defined sgi || defined __sgi)
-       /* Irix iconv() inserts a NUL byte if it cannot convert.  */
+# if !defined _LIBICONV_VERSION && !defined __GLIBC__
+       /* Irix iconv() inserts a NUL byte if it cannot convert.
+          NetBSD iconv() inserts a question mark if it cannot convert.
+          Only GNU libiconv and GNU libc are known to prefer to fail rather
+          than doing a lossy conversion.  */
        else if (res > 0)
          {
            errno = EILSEQ;
@@ -160,7 +169,7 @@ mem_cd_iconv (const char *src, size_t srclen, iconv_t cd,
       }
     /* Avoid glibc-2.1 bug and Solaris 2.7 bug.  */
 # if defined _LIBICONV_VERSION \
-    || !((__GLIBC__ - 0 == 2 && __GLIBC_MINOR__ - 0 <= 1) || defined __sun)
+     || !((__GLIBC__ - 0 == 2 && __GLIBC_MINOR__ - 0 <= 1) || defined __sun)
     {
       size_t res = iconv (cd, NULL, NULL, &outptr, &outsize);
 
@@ -243,7 +252,7 @@ str_cd_iconv (const char *src, iconv_t cd)
 
   /* 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)
+     || !((__GLIBC__ - 0 == 2 && __GLIBC_MINOR__ - 0 <= 1) || defined __sun)
   /* Set to the initial state.  */
   iconv (cd, NULL, NULL, NULL, NULL);
 # endif
@@ -290,8 +299,11 @@ str_cd_iconv (const char *src, iconv_t cd)
            else
              goto failed;
          }
-# if !defined _LIBICONV_VERSION && (defined sgi || defined __sgi)
-       /* Irix iconv() inserts a NUL byte if it cannot convert.  */
+# if !defined _LIBICONV_VERSION && !defined __GLIBC__
+       /* Irix iconv() inserts a NUL byte if it cannot convert.
+          NetBSD iconv() inserts a question mark if it cannot convert.
+          Only GNU libiconv and GNU libc are known to prefer to fail rather
+          than doing a lossy conversion.  */
        else if (res > 0)
          {
            errno = EILSEQ;
@@ -303,7 +315,7 @@ str_cd_iconv (const char *src, iconv_t cd)
       }
     /* Avoid glibc-2.1 bug and Solaris 2.7 bug.  */
 # if defined _LIBICONV_VERSION \
-    || !((__GLIBC__ - 0 == 2 && __GLIBC_MINOR__ - 0 <= 1) || defined __sun)
+     || !((__GLIBC__ - 0 == 2 && __GLIBC_MINOR__ - 0 <= 1) || defined __sun)
     for (;;)
       {
        /* Here outptr + outbytes_remaining = result + result_size - 1.  */