From 32504b520b371315439c6e013557f397563bb220 Mon Sep 17 00:00:00 2001 From: Milan Bouchet-Valat Date: Sat, 6 Feb 2016 18:23:34 +0100 Subject: [PATCH] Only accept iconv implementations with the GNU behavior --- deps/build.jl | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/deps/build.jl b/deps/build.jl index b668d03..84b2482 100644 --- a/deps/build.jl +++ b/deps/build.jl @@ -2,9 +2,37 @@ using BinDeps @BinDeps.setup +# Check for an iconv implementation with the GNU (non-POSIX) behavior: +# EILSEQ is returned when a sequence cannot be converted to target encoding, +# instead of succeeding and only returning the number of invalid conversions +# This non-standard behavior is required to allow replacing invalid sequences +# with a user-defined character. +# Implementations with this behavior include glibc, GNU libiconv (on which Mac +# OS X's is based) and win_iconv. +function validate_iconv(n, h) + # Needed to check libc + f = Libdl.dlsym_e(h, "iconv_open") + f == C_NULL && return false + + cd = ccall(f, Ptr{Void}, (Cstring, Cstring), "ASCII", "UTF-8") + cd == Ptr{Void}(-1) && return false + + s = "café" + a = similar(s.data) + inbufptr = Ref{Ptr{UInt8}}(pointer(s.data)) + inbytesleft = Ref{Csize_t}(length(s.data)) + outbufptr = Ref{Ptr{UInt8}}(pointer(a)) + outbytesleft = Ref{Csize_t}(length(a)) + ret = ccall(Libdl.dlsym_e(h, "iconv"), Csize_t, + (Ptr{Void}, Ptr{Ptr{UInt8}}, Ref{Csize_t}, Ptr{Ptr{UInt8}}, Ref{Csize_t}), + cd, inbufptr, inbytesleft, outbufptr, outbytesleft) + ccall(Libdl.dlsym_e(h, "iconv_close"), Void, (Ptr{Void},), cd) == -1 && return false + + return ret == -1 % Csize_t && Libc.errno() == Libc.EILSEQ +end + libiconv = library_dependency("libiconv", aliases = ["libc", "iconv"], - # Check whether libc provides iconv_open (as on Linux) - validate = (n, h) -> Libdl.dlsym_e(h, "iconv_open") != C_NULL) + validate = validate_iconv) @windows_only begin using WinRPM