From: Tim Kientzle Date: Fri, 11 Mar 2011 06:25:11 +0000 (-0500) Subject: Do a more extensive test for iconv() support: X-Git-Tag: v3.0.0a~664 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5289fb9bb9ba4010690e882948cd1679aa9239fb;p=thirdparty%2Flibarchive.git Do a more extensive test for iconv() support: * Check both POSIX-conforming (second argument is const) and non-POSIX * Check in libc and libiconv The configuration script sets three flags: * HAVE_ICONV_H * HAVE_ICONV * ICONV_IS_POSIX and also adds libiconv to the compile if necessary. SVN-Revision: 3007 --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 8df070893..caeeddf97 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -265,10 +265,6 @@ LA_CHECK_INCLUDE_FILE("windows.h" HAVE_WINDOWS_H) LA_CHECK_INCLUDE_FILE("winioctl.h" HAVE_WINIOCTL_H) -# -# Some headers require extra includes when they're available. -# - # # Find OpenSSL # @@ -443,22 +439,66 @@ CHECK_HASH_WIN("MD5;SHA1;SHA256;SHA384;SHA512") # # Find iconv +# POSIX defines the second arg as const char ** +# and requires it to be in libc. But we can accept +# a non-const argument here and can support iconv() +# being in libiconv. # LA_CHECK_INCLUDE_FILE("iconv.h" HAVE_ICONV_H) IF(HAVE_ICONV_H) FIND_PATH(ICONV_INCLUDE_DIR iconv.h) + + # Try POSIX-conforming iconv() in libc + CHECK_C_SOURCE_COMPILES( + "#include + int main() {const char *ccp; iconv_t cd; + iconv(cd, &ccp, (size_t *)0, (char **)0, (size_t *)0); + return 0;}" + HAVE_POSIX_ICONV_IN_LIBC) + IF(HAVE_POSIX_ICONV_IN_LIBC) + SET(HAVE_ICONV true) + SET(ICONV_IS_POSIX true) + ELSE(HAVE_POSIX_ICONV_IN_LIBC) + + # Try non-POSIX-conforming iconv() in libc + CHECK_C_SOURCE_COMPILES( + "#include + int main() {char *ccp; iconv_t cd; + iconv(cd, &ccp, (size_t *)0, (char **)0, (size_t *)0); + return 0;}" + HAVE_NONPOSIX_ICONV_IN_LIBC) + IF(HAVE_NONPOSIX_ICONV_IN_LIBC) + SET(HAVE_ICONV true) + ELSE(HAVE_NONPOSIX_ICONV_IN_LIBC) + + # iconv isn't in libc, try libiconv + SET(CMAKE_REQUIRED_LIBRARIES "iconv") + CHECK_C_SOURCE_COMPILES( + "#include + int main() {const char *ccp; iconv_t cd; + iconv(cd, &ccp, (size_t *)0, (char **)0, (size_t *)0); + return 0;}" + HAVE_POSIX_ICONV_IN_LIBICONV) + IF(HAVE_POSIX_ICONV_IN_LIBICONV) + SET(HAVE_ICONV true) + SET(ICONV_IS_POSIX true) + LIST(APPEND ADDITIONAL_LIBS "iconv") + ELSE(HAVE_POSIX_ICONV_IN_LIBICONV) + + CHECK_C_SOURCE_COMPILES( + "#include + int main() {char *ccp; iconv_t cd; + iconv(cd, &ccp, (size_t *)0, (char **)0, (size_t *)0); + return 0;}" + HAVE_NONPOSIX_ICONV_IN_LIBICONV) + IF(HAVE_NONPOSIX_ICONV_IN_LIBICONV) + SET(HAVE_ICONV true) + LIST(APPEND ADDITIONAL_LIBS "iconv") + ENDIF(HAVE_NONPOSIX_ICONV_IN_LIBICONV) + ENDIF(HAVE_POSIX_ICONV_IN_LIBICONV) + ENDIF(HAVE_NONPOSIX_ICONV_IN_LIBC) + ENDIF(HAVE_POSIX_ICONV_IN_LIBC) ENDIF(HAVE_ICONV_H) -CHECK_FUNCTION_EXISTS(iconv HAVE_ICONV_IN_LIBC) -IF(HAVE_ICONV_IN_LIBC) - SET(HAVE_ICONV true) -ELSE(HAVE_ICONV_IN_LIBC) - # iconv isn't in libc, try libiconv - CHECK_LIBRARY_EXISTS(iconv iconv "" HAVE_ICONV_IN_LIBICONV) - IF(HAVE_ICONV_IN_LIBICONV) - SET(HAVE_ICONV true) - LIST(APPEND ADDITIONAL_LIBS "iconv") - ENDIF(HAVE_ICONV_IN_LIBICONV) -ENDIF(HAVE_ICONV_IN_LIBC) # # Find Libxml2 diff --git a/build/cmake/config.h.in b/build/cmake/config.h.in index 0d1159032..5df98c547 100644 --- a/build/cmake/config.h.in +++ b/build/cmake/config.h.in @@ -495,6 +495,9 @@ typedef uint64_t uintmax_t; /* Define to 1 if you have the `iconv' function. */ #cmakedefine HAVE_ICONV 1 +/* Define to 1 if the 'iconv' function follows POSIX. */ +#cmakedefine ICONV_IS_POSIX 1 + /* Define to 1 if you have the header file. */ #cmakedefine HAVE_ICONV_H 1 diff --git a/libarchive/archive_string.c b/libarchive/archive_string.c index f2df5f578..98640db2b 100644 --- a/libarchive/archive_string.c +++ b/libarchive/archive_string.c @@ -503,7 +503,11 @@ int archive_wstring_append_from_mbs(struct archive *a, struct archive_wstring *dest, const char *p, size_t len) { char buff[256]; +#if ICONV_IS_POSIX + const char *inp; +#else char *inp; +#endif size_t remaining; iconv_t cd; int return_value = 0; /* success */ @@ -640,7 +644,11 @@ int archive_string_append_from_unicode_to_mbs(struct archive *a, struct archive_string *as, const wchar_t *w, size_t len) { char buff[256]; +#if ICONV_IS_POSIX + const char *inp; +#else char *inp; +#endif size_t remaining; iconv_t cd; int return_value = 0; /* success */