diff --git a/deps/build.jl b/deps/build.jl index b668d03..a0e9503 100644 --- a/deps/build.jl +++ b/deps/build.jl @@ -2,9 +2,34 @@ 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. glibc, GNU libiconv and win_iconv behave that way. +function validate_iconv(n, h) + Libdl.dlsym_e(h, "iconv_open") == C_NULL && return false + + cd = ccall((:iconv_open, h), 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((:iconv, h), Csize_t, + (Ptr{Void}, Ptr{Ptr{UInt8}}, Ref{Csize_t}, Ptr{Ptr{UInt8}}, Ref{Csize_t}), + cd, inbufptr, inbytesleft, outbufptr, outbytesleft) + ccall((:iconv_close, h), Void, (Ptr{Void},), cd) == -1 && return false + + return ret == -1 % Csize_t && Base.Libc.errno() == Base.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