From 8083a1fd2fe2ba5728c3a53204b03f3e36ccf9a7 Mon Sep 17 00:00:00 2001 From: alaviss Date: Sun, 21 Jun 2020 17:28:03 +0000 Subject: [PATCH] encodings: use only one iconv definition [backport:1.2] (#14741) Fix an issue reported on IRC: using encodings with --dynlibOverrideAll result in duplicated iconv definitions, causing compile errors. This commit remove the `var` wrapper of iconv and go all out on pointers, as it should due to how the API accepts nil. Also corrected the API to resemble iconv(3p). (cherry picked from commit c7dee55b87fe0f35a411b4ec48f833be5537a231) --- lib/pure/encodings.nim | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/lib/pure/encodings.nim b/lib/pure/encodings.nim index ff9c3889af..1d8512018e 100644 --- a/lib/pure/encodings.nim +++ b/lib/pure/encodings.nim @@ -290,11 +290,8 @@ else: importc: "iconv_open", importIconv.} proc iconvClose(c: EncodingConverter) {. importc: "iconv_close", importIconv.} - proc iconv(c: EncodingConverter, inbuf: var cstring, inbytesLeft: var int, - outbuf: var cstring, outbytesLeft: var int): int {. - importc: "iconv", importIconv.} - proc iconv(c: EncodingConverter, inbuf: pointer, inbytesLeft: pointer, - outbuf: var cstring, outbytesLeft: var int): int {. + proc iconv(c: EncodingConverter, inbuf: ptr cstring, inbytesLeft: ptr csize_t, + outbuf: ptr cstring, outbytesLeft: ptr csize_t): csize_t {. importc: "iconv", importIconv.} proc getCurrentEncoding*(uiApp = false): string = @@ -428,14 +425,14 @@ when defined(windows): else: proc convert*(c: EncodingConverter, s: string): string = result = newString(s.len) - var inLen = len(s) - var outLen = len(result) + var inLen = csize_t len(s) + var outLen = csize_t len(result) var src = cstring(s) var dst = cstring(result) - var iconvres: int + var iconvres: csize_t while inLen > 0: - iconvres = iconv(c, src, inLen, dst, outLen) - if iconvres == -1: + iconvres = iconv(c, addr src, addr inLen, addr dst, addr outLen) + if iconvres == high(csize_t): var lerr = errno if lerr == EILSEQ or lerr == EINVAL: # unknown char, skip @@ -446,24 +443,24 @@ else: dec(outLen) elif lerr == E2BIG: var offset = cast[int](dst) - cast[int](cstring(result)) - setLen(result, len(result)+inLen*2+5) + setLen(result, len(result) + inLen.int * 2 + 5) # 5 is minimally one utf-8 char dst = cast[cstring](cast[int](cstring(result)) + offset) - outLen = len(result) - offset + outLen = csize_t(len(result) - offset) else: raiseOSError(lerr.OSErrorCode) # iconv has a buffer that needs flushing, specially if the last char is # not '\0' - discard iconv(c, nil, nil, dst, outLen) - if iconvres == cint(-1) and errno == E2BIG: + discard iconv(c, nil, nil, addr dst, addr outLen) + if iconvres == high(csize_t) and errno == E2BIG: var offset = cast[int](dst) - cast[int](cstring(result)) - setLen(result, len(result)+inLen*2+5) + setLen(result, len(result) + inLen.int * 2 + 5) # 5 is minimally one utf-8 char dst = cast[cstring](cast[int](cstring(result)) + offset) - outLen = len(result) - offset - discard iconv(c, nil, nil, dst, outLen) + outLen = csize_t(len(result) - offset) + discard iconv(c, nil, nil, addr dst, addr outLen) # trim output buffer - setLen(result, len(result) - outLen) + setLen(result, len(result) - outLen.int) proc convert*(s: string, destEncoding = "UTF-8", srcEncoding = "CP1252"): string =