[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [bug-gnu-libiconv] iconv.h differs on Mac OS X 10.4 and 10.5
From: |
Bruno Haible |
Subject: |
Re: [bug-gnu-libiconv] iconv.h differs on Mac OS X 10.4 and 10.5 |
Date: |
Tue, 3 Jun 2008 02:14:38 +0200 |
User-agent: |
KMail/1.5.4 |
Hi,
Ryan Schmidt wrote:
> I have a problem with iconv.h from libiconv 1.12 and the
> fact that it differs depending on whether it's installed on Mac OS X
> 10.4 or 10.5.
>
> On Mac OS X 10.4 with Xcode 2.4.1 (or Xcode 2.5), and libiconv 1.12
> installed by MacPorts, iconv.h defines the iconv() function this way:
>
> extern size_t iconv (iconv_t cd, const char* * inbuf, size_t
> *inbytesleft, char* * outbuf, size_t *outbytesleft);
>
> On Mac OS X 10.5 with Xcode 3.0 (or Xcode 3.1 from iPhone SDK beta
> 6), the same version of libiconv defines the second parameter of iconv
> () differently:
>
> extern size_t iconv (iconv_t cd, char* * inbuf, size_t *inbytesleft,
> char* * outbuf, size_t *outbytesleft);
libiconv, installed from source, uses 'const' or not here, depending whether
the system header uses 'const' or not. And in MacOS X 10.5, Apple changed
their headers for POSIX compliance (so as to get the UNIX 2003 branding).
And POSIX happens to specify 'char **' for iconv's inbuf parameter.
See the diff between the 10.4 and 10.5 headers at the end of this mail.
> This causes problems for software that wants to work on both Mac OS X
> 10.4 and 10.5. See:
>
> http://trac.macports.org/changeset?new=trunk%2Fdports%2Fdevel%2Fice-
> cpp%2FPortfile%4037235&old=trunk%2Fdports%2Fdevel%2Fice-cpp%2FPortfile
> %4037182
>
> And:
>
> http://trac.macports.org/ticket/15297
>
> The developer of the pure language feels this is a bug in libiconv.
This incompatible change is under Apple's responsibility, since they changed
the system header.
You can blame libiconv for having used 'const' by default in the past, but
this is "corrected" in libiconv 1.12.
As a way out, the iconv.m4 macro from gnulib
<http://www.gnu.org/software/gnulib/MODULES.html#module=iconv>
detects the presence or absence of 'const' and defines ICONV_CONST
accordingly. So that you can cast the argument to (ICONV_CONST char **)
and be safe in all cases. It is documented here:
<http://www.gnu.org/software/gettext/manual/html_node/AM_005fICONV.html>
Bruno
$ diff -c /Developer/SDKs/MacOSX10.4u.sdk/usr/include/iconv.h
/Developer/SDKs/MacOSX10.5.sdk/usr/include/iconv.h
*** /Developer/SDKs/MacOSX10.4u.sdk/usr/include/iconv.h Sat Jul 1 21:20:07 2006
--- /Developer/SDKs/MacOSX10.5.sdk/usr/include/iconv.h Mon Sep 24 00:08:35 2007
***************
*** 66,100 ****
/* Allocates descriptor for code conversion from encoding `fromcode' to
encoding `tocode'. */
! #ifndef LIBICONV_PLUG
! #define iconv_open libiconv_open
! #endif
! extern iconv_t iconv_open (const char* tocode, const char* fromcode);
/* Converts, using conversion descriptor `cd', at most `*inbytesleft' bytes
starting at `*inbuf', writing at most `*outbytesleft' bytes starting at
`*outbuf'.
Decrements `*inbytesleft' and increments `*inbuf' by the same amount.
Decrements `*outbytesleft' and increments `*outbuf' by the same amount. */
! #ifndef LIBICONV_PLUG
! #define iconv libiconv
! #endif
! extern size_t iconv (iconv_t cd, const char* * inbuf, size_t *inbytesleft,
char* * outbuf, size_t *outbytesleft);
/* Frees resources allocated for conversion descriptor `cd'. */
! #ifndef LIBICONV_PLUG
! #define iconv_close libiconv_close
! #endif
! extern int iconv_close (iconv_t cd);
!
! #ifndef LIBICONV_PLUG
/* Nonstandard extensions. */
/* Control of attributes. */
! #define iconvctl libiconvctl
! extern int iconvctl (iconv_t cd, int request, void* argument);
/* Requests for iconvctl. */
#define ICONV_TRIVIALP 0 /* int *argument */
--- 62,161 ----
/* Allocates descriptor for code conversion from encoding `fromcode' to
encoding `tocode'. */
! iconv_t iconv_open (const char* /*tocode*/, const char* /*fromcode*/);
/* Converts, using conversion descriptor `cd', at most `*inbytesleft' bytes
starting at `*inbuf', writing at most `*outbytesleft' bytes starting at
`*outbuf'.
Decrements `*inbytesleft' and increments `*inbuf' by the same amount.
Decrements `*outbytesleft' and increments `*outbuf' by the same amount. */
! size_t iconv (iconv_t /*cd*/,
! char ** __restrict /*inbuf*/, size_t * __restrict /*inbytesleft*/,
! char ** __restrict /*outbuf*/, size_t * __restrict /*outbytesleft*/);
/* Frees resources allocated for conversion descriptor `cd'. */
! int iconv_close (iconv_t /*cd*/);
! #if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)
/* Nonstandard extensions. */
+ #ifndef __cplusplus
+ #ifndef _WCHAR_T
+ #define _WCHAR_T
+ typedef __darwin_wchar_t wchar_t;
+ #endif /* _WCHAR_T */
+ #endif /* __cplusplus */
+
/* Control of attributes. */
! int iconvctl (iconv_t /*cd*/, int /*request*/, void* /*argument*/);
!
! /* Hook performed after every successful conversion of a Unicode character. */
! typedef void (*iconv_unicode_char_hook) (unsigned int uc, void* data);
! /* Hook performed after every successful conversion of a wide character. */
! typedef void (*iconv_wide_char_hook) (wchar_t wc, void* data);
! /* Set of hooks. */
! struct iconv_hooks {
! iconv_unicode_char_hook uc_hook;
! iconv_wide_char_hook wc_hook;
! void* data;
! };
!
! /* Fallback function. Invoked when a small number of bytes could not be
! converted to a Unicode character. This function should process all
! bytes from inbuf and may produce replacement Unicode characters by calling
! the write_replacement callback repeatedly. */
! typedef void (*iconv_unicode_mb_to_uc_fallback)
! (const char* inbuf, size_t inbufsize,
! void (*write_replacement) (const unsigned int *buf, size_t
buflen,
! void* callback_arg),
! void* callback_arg,
! void* data);
! /* Fallback function. Invoked when a Unicode character could not be converted
! to the target encoding. This function should process the character and
! may produce replacement bytes (in the target encoding) by calling the
! write_replacement callback repeatedly. */
! typedef void (*iconv_unicode_uc_to_mb_fallback)
! (unsigned int code,
! void (*write_replacement) (const char *buf, size_t buflen,
! void* callback_arg),
! void* callback_arg,
! void* data);
! #if 1
! /* Fallback function. Invoked when a number of bytes could not be converted
to
! a wide character. This function should process all bytes from inbuf and
may
! produce replacement wide characters by calling the write_replacement
! callback repeatedly. */
! typedef void (*iconv_wchar_mb_to_wc_fallback)
! (const char* inbuf, size_t inbufsize,
! void (*write_replacement) (const wchar_t *buf, size_t buflen,
! void* callback_arg),
! void* callback_arg,
! void* data);
! /* Fallback function. Invoked when a wide character could not be converted to
! the target encoding. This function should process the character and may
! produce replacement bytes (in the target encoding) by calling the
! write_replacement callback repeatedly. */
! typedef void (*iconv_wchar_wc_to_mb_fallback)
! (wchar_t code,
! void (*write_replacement) (const char *buf, size_t buflen,
! void* callback_arg),
! void* callback_arg,
! void* data);
! #else
! /* If the wchar_t type does not exist, these two fallback functions are never
! invoked. Their argument list therefore does not matter. */
! typedef void (*iconv_wchar_mb_to_wc_fallback) ();
! typedef void (*iconv_wchar_wc_to_mb_fallback) ();
! #endif
! /* Set of fallbacks. */
! struct iconv_fallbacks {
! iconv_unicode_mb_to_uc_fallback mb_to_uc_fallback;
! iconv_unicode_uc_to_mb_fallback uc_to_mb_fallback;
! iconv_wchar_mb_to_wc_fallback mb_to_wc_fallback;
! iconv_wchar_wc_to_mb_fallback wc_to_mb_fallback;
! void* data;
! };
/* Requests for iconvctl. */
#define ICONV_TRIVIALP 0 /* int *argument */