+2024-02-14 Bruno Haible <bruno@clisp.org>
+
+ Don't treat Apple's new Citrus/FreeBSD-based iconv like GNU libiconv.
+ * m4/iconv_open.m4 (gl_FUNC_ICONV_OPEN): Don't treat the bastard Apple
+ iconv like GNU libiconv.
+ * lib/striconv.c (mem_cd_iconv, str_cd_iconv): Likewise.
+ * lib/striconveh.c (iconv_carefully, iconv_carefully_1,
+ mem_cd_iconveh_internal): Likewise.
+ * lib/propername.c (proper_name_utf8): Likewise.
+ * lib/unicodeio.c (unicode_to_mb): Likewise.
+ * lib/uniconv/u16-conv-from-enc.c (UTF16_NAME): Likewise.
+ * lib/uniconv/u16-conv-to-enc.c (UTF16_NAME): Likewise.
+ * lib/uniconv/u16-strconv-to-enc.c (UTF16_NAME): Likewise.
+ * lib/uniconv/u32-conv-from-enc.c (UTF32_NAME): Likewise.
+ * lib/uniconv/u32-conv-to-enc.c (UTF32_NAME): Likewise.
+ * lib/uniconv/u32-strconv-to-enc.c (UTF32_NAME): Likewise.
+ * tests/test-striconveh.c (main): Likewise.
+ * tests/test-striconveha.c (main): Likewise.
+ * tests/uniconv/test-u8-conv-from-enc.c (main): Likewise.
+ * tests/uniconv/test-u8-strconv-from-enc.c (main): Likewise.
+ * tests/uniconv/test-u16-conv-from-enc.c (main): Likewise.
+ * tests/uniconv/test-u16-strconv-from-enc.c (main): Likewise.
+ * tests/uniconv/test-u32-conv-from-enc.c (main): Likewise.
+ * tests/uniconv/test-u32-strconv-from-enc.c (main): Likewise.
+
2024-02-14 Bruno Haible <bruno@clisp.org>
Improve support of Citrus/FreeBSD iconv.
if (converted_translit != NULL)
{
-# if !_LIBICONV_VERSION
+# if !_LIBICONV_VERSION || (_LIBICONV_VERSION == 0x10b && defined __APPLE__)
/* Don't use the transliteration if it added question marks.
glibc's transliteration falls back to question marks; libiconv's
transliteration does not.
else
return -1;
}
-# if !defined _LIBICONV_VERSION && !(defined __GLIBC__ && !defined __UCLIBC__)
+# if !(defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)) \
+ && !(defined __GLIBC__ && !defined __UCLIBC__)
/* 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. */
+ Only GNU libiconv (excluding the bastard Apple iconv) and GNU libc
+ are known to prefer to fail rather than doing a lossy conversion. */
else if (res > 0)
{
errno = EILSEQ;
else
goto fail;
}
-# if !defined _LIBICONV_VERSION && !(defined __GLIBC__ && !defined __UCLIBC__)
+# if !(defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)) \
+ && !(defined __GLIBC__ && !defined __UCLIBC__)
/* 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. */
+ Only GNU libiconv (excluding the bastard Apple iconv) and GNU libc
+ are known to prefer to fail rather than doing a lossy conversion. */
else if (res > 0)
{
errno = EILSEQ;
to a trailing NUL byte in the output. But not for UTF-7. So that this
function is usable for UTF-7, we have to exclude the NUL byte from the
conversion and add it by hand afterwards. */
-# if !defined _LIBICONV_VERSION && !(defined __GLIBC__ && !defined __UCLIBC__)
+# if !(defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)) \
+ && !(defined __GLIBC__ && !defined __UCLIBC__)
/* 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. For other iconv() implementations,
- we have to look at the number of irreversible conversions returned;
- but this information is lost when iconv() returns for an E2BIG reason.
- Therefore we cannot use the second, faster algorithm. */
+ Only GNU libiconv (excluding the bastard Apple iconv) and GNU libc are
+ known to prefer to fail rather than doing a lossy conversion. For other
+ iconv() implementations, we have to look at the number of irreversible
+ conversions returned; but this information is lost when iconv() returns
+ for an E2BIG reason. Therefore we cannot use the second, faster
+ algorithm. */
char *result = NULL;
size_t length = 0;
/* iconv_carefully is like iconv, except that it stops as soon as it encounters
a conversion error, and it returns in *INCREMENTED a boolean telling whether
it has incremented the input pointers past the error location. */
-# if !defined _LIBICONV_VERSION && !(defined __GLIBC__ && !defined __UCLIBC__)
+# if !(defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)) \
+ && !(defined __GLIBC__ && !defined __UCLIBC__)
/* 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. */
+ Only GNU libiconv (excluding the bastard Apple iconv) and GNU libc are
+ known to prefer to fail rather than doing a lossy conversion. */
static size_t
iconv_carefully (iconv_t cd,
const char **inbuf, size_t *inbytesleft,
*inbuf = inptr;
*inbytesleft = inptr_end - inptr;
-# if !defined _LIBICONV_VERSION && !(defined __GLIBC__ && !defined __UCLIBC__)
+# if !(defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)) \
+ && !(defined __GLIBC__ && !defined __UCLIBC__)
/* 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. */
+ Only GNU libiconv (excluding the bastard Apple iconv) and GNU libc are
+ known to prefer to fail rather than doing a lossy conversion. */
if (res != (size_t)(-1) && res > 0)
{
/* iconv() has already incremented INPTR. We cannot go back to a
}
length = out2ptr - result;
}
-# if !defined _LIBICONV_VERSION && !(defined __GLIBC__ && !defined __UCLIBC__)
+# if !(defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)) \
+ && !(defined __GLIBC__ && !defined __UCLIBC__)
/* IRIX iconv() inserts a NUL byte if it cannot convert.
FreeBSD iconv(), NetBSD iconv(), and Solaris 11
iconv() insert a '?' if they cannot convert.
musl libc iconv() inserts a '*' if it cannot convert.
- Only GNU libiconv and GNU libc are known to prefer
- to fail rather than doing a lossy conversion. */
+ Only GNU libiconv (excluding the bastard Apple iconv)
+ and GNU libc are known to prefer to fail rather than
+ doing a lossy conversion. */
if (res != (size_t)(-1) && res > 0)
{
errno = EILSEQ;
# endif
/* FreeBSD iconv(), NetBSD iconv(), and Solaris 11 iconv() insert
a '?' if they cannot convert. */
-# if !defined _LIBICONV_VERSION
+# if !defined _LIBICONV_VERSION || (_LIBICONV_VERSION == 0x10b && defined __APPLE__)
|| (res > 0 && outptr - outbuf == 1 && *outbuf == '?')
# endif
/* musl libc iconv() inserts a '*' if it cannot convert. */
#include "unistr.h"
/* Name of UTF-16 encoding with machine dependent endianness and alignment. */
-#if defined _LIBICONV_VERSION || (((__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2)) && !defined __UCLIBC__)
+#if (defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)) \
+ || (((__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2)) && !defined __UCLIBC__)
# ifdef WORDS_BIGENDIAN
# define UTF16_NAME "UTF-16BE"
# else
#define SIZEOF(array) (sizeof (array) / sizeof (array[0]))
/* Name of UTF-16 encoding with machine dependent endianness and alignment. */
-#if defined _LIBICONV_VERSION || (((__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2)) && !defined __UCLIBC__)
+#if (defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)) \
+ || (((__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2)) && !defined __UCLIBC__)
# ifdef WORDS_BIGENDIAN
# define UTF16_NAME "UTF-16BE"
# else
#define SIZEOF(array) (sizeof (array) / sizeof (array[0]))
/* Name of UTF-16 encoding with machine dependent endianness and alignment. */
-#if defined _LIBICONV_VERSION || (((__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2)) && !defined __UCLIBC__)
+#if (defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)) \
+ || (((__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2)) && !defined __UCLIBC__)
# ifdef WORDS_BIGENDIAN
# define UTF16_NAME "UTF-16BE"
# else
/* Name of UTF-32 or UCS-4 encoding with machine dependent endianness and
alignment. */
-#if defined _LIBICONV_VERSION
+#if defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)
# define UTF32_NAME "UCS-4-INTERNAL"
#elif ((__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2)) && !defined __UCLIBC__
# define UTF32_NAME "WCHAR_T"
/* Name of UTF-32 or UCS-4 encoding with machine dependent endianness and
alignment. */
-#if defined _LIBICONV_VERSION
+#if defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)
# define UTF32_NAME "UCS-4-INTERNAL"
#elif ((__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2)) && !defined __UCLIBC__
# define UTF32_NAME "WCHAR_T"
/* Name of UTF-32 or UCS-4 encoding with machine dependent endianness and
alignment. */
-#if defined _LIBICONV_VERSION
+#if defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)
# define UTF32_NAME "UCS-4-INTERNAL"
#elif ((__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2)) && !defined __UCLIBC__
# define UTF32_NAME "WCHAR_T"
-# iconv_open.m4 serial 16
+# iconv_open.m4 serial 17
dnl Copyright (C) 2007-2024 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl We know that GNU libiconv and GNU libc do.
AC_EGREP_CPP([gnu_iconv], [
#include <iconv.h>
- #if defined _LIBICONV_VERSION || (defined __GLIBC__ && !defined __UCLIBC__)
+ #if (defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)) \
+ || (defined __GLIBC__ && !defined __UCLIBC__)
gnu_iconv
#endif
], [gl_func_iconv_gnu=yes], [gl_func_iconv_gnu=no])
iconv_t cd_88592_to_utf8 = iconv_open ("UTF-8", "ISO-8859-2");
iconv_t cd_utf8_to_88592 = iconv_open ("ISO-8859-2", "UTF-8");
iconv_t cd_utf7_to_utf8 = iconv_open ("UTF-8", "UTF-7");
-# if defined _LIBICONV_VERSION || (defined __GLIBC__ && !defined __UCLIBC__)
+# if (defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)) || (defined __GLIBC__ && !defined __UCLIBC__)
iconv_t cd_ascii_to_gb18030 = iconv_open ("GB18030", "ASCII");
iconv_t cd_utf8_to_gb18030 = iconv_open ("GB18030", "UTF-8");
iconv_t cd_88591_to_gb18030 = iconv_open ("GB18030", "ISO-8859-1");
iconveh_t cdeh_88591_to_utf8;
iconveh_t cdeh_utf8_to_88591;
iconveh_t cdeh_utf7_to_utf8;
-# if defined _LIBICONV_VERSION || (defined __GLIBC__ && !defined __UCLIBC__)
+# if (defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)) || (defined __GLIBC__ && !defined __UCLIBC__)
iconveh_t cdeh_ascii_to_gb18030;
iconveh_t cdeh_88591_to_gb18030;
iconveh_t cdeh_utf7_to_gb18030;
ASSERT (cd_utf8_to_88591 != (iconv_t)(-1));
ASSERT (cd_88592_to_utf8 != (iconv_t)(-1));
ASSERT (cd_utf8_to_88592 != (iconv_t)(-1));
-# if defined _LIBICONV_VERSION || (defined __GLIBC__ && !defined __UCLIBC__)
+# if (defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)) || (defined __GLIBC__ && !defined __UCLIBC__)
ASSERT (cd_ascii_to_gb18030 != (iconv_t)(-1));
ASSERT (cd_utf8_to_gb18030 != (iconv_t)(-1));
# endif
cdeh_utf7_to_utf8.cd1 = cd_utf7_to_utf8;
cdeh_utf7_to_utf8.cd2 = (iconv_t)(-1);
-# if defined _LIBICONV_VERSION || (defined __GLIBC__ && !defined __UCLIBC__)
+# if (defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)) || (defined __GLIBC__ && !defined __UCLIBC__)
cdeh_ascii_to_gb18030.cd = cd_ascii_to_gb18030;
cdeh_ascii_to_gb18030.cd1 = cd_ascii_to_utf8;
cdeh_ascii_to_gb18030.cd2 = cd_utf8_to_gb18030;
}
}
-# if defined _LIBICONV_VERSION || (defined __GLIBC__ && !defined __UCLIBC__)
+# if (defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)) || (defined __GLIBC__ && !defined __UCLIBC__)
/* Test conversion from ISO-8859-1 to GB18030 with no errors. */
for (h = 0; h < SIZEOF (handlers); h++)
{
}
}
-# if defined _LIBICONV_VERSION || ((__GLIBC__ + (__GLIBC_MINOR__ >= 16) > 2) && !defined __UCLIBC__)
+# if (defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)) || ((__GLIBC__ + (__GLIBC_MINOR__ >= 16) > 2) && !defined __UCLIBC__)
/* Test conversion from ASCII to GB18030 with invalid input (EILSEQ).
Note: glibc's GB18030 converter was buggy in glibc-2.15; fixed by
Andreas Schwab on 2012-02-06. */
free (result);
}
-# if defined _LIBICONV_VERSION || (defined __GLIBC__ && !defined __UCLIBC__)
+# if (defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)) || (defined __GLIBC__ && !defined __UCLIBC__)
/* Test conversion from UTF-7 to GB18030 with EINVAL. */
for (h = 0; h < SIZEOF (handlers); h++)
{
}
}
-# if defined _LIBICONV_VERSION || ((__GLIBC__ + (__GLIBC_MINOR__ >= 16) > 2) && !defined __UCLIBC__)
+# if (defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)) || ((__GLIBC__ + (__GLIBC_MINOR__ >= 16) > 2) && !defined __UCLIBC__)
/* Test conversion from UTF-7 to GB18030 with EILSEQ.
Note: glibc's GB18030 converter was buggy in glibc-2.15; fixed by
Andreas Schwab on 2012-02-06. */
free (result);
}
-# if defined _LIBICONV_VERSION || (defined __GLIBC__ && !defined __UCLIBC__)
+# if (defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)) || (defined __GLIBC__ && !defined __UCLIBC__)
/* Test conversion from ISO-8859-1 to GB18030 with no errors. */
for (h = 0; h < SIZEOF (handlers); h++)
{
}
}
-# if defined _LIBICONV_VERSION || ((__GLIBC__ + (__GLIBC_MINOR__ >= 16) > 2) && !defined __UCLIBC__)
+# if (defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)) || ((__GLIBC__ + (__GLIBC_MINOR__ >= 16) > 2) && !defined __UCLIBC__)
/* Test conversion from ASCII to GB18030 with invalid input (EILSEQ).
Note: glibc's GB18030 converter was buggy in glibc-2.15; fixed by
Andreas Schwab on 2012-02-06. */
}
}
-# if defined _LIBICONV_VERSION || (defined __GLIBC__ && !defined __UCLIBC__)
+# if (defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)) || (defined __GLIBC__ && !defined __UCLIBC__)
/* Test conversion from ISO-8859-1 to GB18030 with no errors. */
for (h = 0; h < SIZEOF (handlers); h++)
{
free (result);
}
-# if defined _LIBICONV_VERSION || (defined __GLIBC__ && !defined __UCLIBC__)
+# if (defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)) || (defined __GLIBC__ && !defined __UCLIBC__)
/* Test conversion from ISO-8859-1 to GB18030 with no errors. */
for (h = 0; h < SIZEOF (handlers); h++)
{
}
/* autodetect_jp is only supported when iconv() support ISO-2022-JP-2. */
-# if defined _LIBICONV_VERSION || !(defined _AIX || defined __sgi || defined __hpux || defined __osf__ || defined __sun)
+# if (defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)) \
+ || !(defined _AIX || defined __sgi || defined __hpux || defined __osf__ || defined __sun)
if (iconv_supports_encoding ("ISO-2022-JP-2"))
{
/* Test conversions from autodetect_jp to UTF-8. */
}
/* autodetect_jp is only supported when iconv() support ISO-2022-JP-2. */
-# if defined _LIBICONV_VERSION || !(defined _AIX || defined __sgi || defined __hpux || defined __osf__ || defined __sun)
+# if (defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)) \
+ || !(defined _AIX || defined __sgi || defined __hpux || defined __osf__ || defined __sun)
if (iconv_supports_encoding ("ISO-2022-JP-2"))
{
/* Test conversions from autodetect_jp to UTF-8. */
}
/* autodetect_jp is only supported when iconv() support ISO-2022-JP-2. */
-# if defined _LIBICONV_VERSION || !(defined _AIX || defined __sgi || defined __hpux || defined __osf__ || defined __sun)
+# if (defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)) \
+ || !(defined _AIX || defined __sgi || defined __hpux || defined __osf__ || defined __sun)
if (iconv_supports_encoding ("ISO-2022-JP-2"))
{
/* Test conversions from autodetect_jp to UTF-16. */
}
/* autodetect_jp is only supported when iconv() support ISO-2022-JP-2. */
-# if defined _LIBICONV_VERSION || !(defined _AIX || defined __sgi || defined __hpux || defined __osf__ || defined __sun)
+# if (defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)) \
+ || !(defined _AIX || defined __sgi || defined __hpux || defined __osf__ || defined __sun)
if (iconv_supports_encoding ("ISO-2022-JP-2"))
{
/* Test conversions from autodetect_jp to UTF-16. */
}
/* autodetect_jp is only supported when iconv() support ISO-2022-JP-2. */
-# if defined _LIBICONV_VERSION || !(defined _AIX || defined __sgi || defined __hpux || defined __osf__ || defined __sun)
+# if (defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)) \
+ || !(defined _AIX || defined __sgi || defined __hpux || defined __osf__ || defined __sun)
if (iconv_supports_encoding ("ISO-2022-JP-2"))
{
/* Test conversions from autodetect_jp to UTF-16. */
}
/* autodetect_jp is only supported when iconv() support ISO-2022-JP-2. */
-# if defined _LIBICONV_VERSION || !(defined _AIX || defined __sgi || defined __hpux || defined __osf__ || defined __sun)
+# if (defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)) \
+ || !(defined _AIX || defined __sgi || defined __hpux || defined __osf__ || defined __sun)
if (iconv_supports_encoding ("ISO-2022-JP-2"))
{
/* Test conversions from autodetect_jp to UTF-16. */
}
/* autodetect_jp is only supported when iconv() support ISO-2022-JP-2. */
-# if defined _LIBICONV_VERSION || !(defined _AIX || defined __sgi || defined __hpux || defined __osf__ || defined __sun)
+# if (defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)) \
+ || !(defined _AIX || defined __sgi || defined __hpux || defined __osf__ || defined __sun)
if (iconv_supports_encoding ("ISO-2022-JP-2"))
{
/* Test conversions from autodetect_jp to UTF-8. */
}
/* autodetect_jp is only supported when iconv() support ISO-2022-JP-2. */
-# if defined _LIBICONV_VERSION || !(defined _AIX || defined __sgi || defined __hpux || defined __osf__ || defined __sun)
+# if (defined _LIBICONV_VERSION && !(_LIBICONV_VERSION == 0x10b && defined __APPLE__)) \
+ || !(defined _AIX || defined __sgi || defined __hpux || defined __osf__ || defined __sun)
if (iconv_supports_encoding ("ISO-2022-JP-2"))
{
/* Test conversions from autodetect_jp to UTF-8. */