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).
This commit is contained in:
alaviss 2020-06-21 17:28:03 +00:00 • committed by GitHub
commit c7dee55b87
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -290,11 +290,8 @@ else:
importc: "iconv_open", importIconv.} importc: "iconv_open", importIconv.}
proc iconvClose(c: EncodingConverter) {. proc iconvClose(c: EncodingConverter) {.
importc: "iconv_close", importIconv.} importc: "iconv_close", importIconv.}
proc iconv(c: EncodingConverter, inbuf: var cstring, inbytesLeft: var int, proc iconv(c: EncodingConverter, inbuf: ptr cstring, inbytesLeft: ptr csize_t,
outbuf: var cstring, outbytesLeft: var int): int {. outbuf: ptr cstring, outbytesLeft: ptr csize_t): csize_t {.
importc: "iconv", importIconv.}
proc iconv(c: EncodingConverter, inbuf: pointer, inbytesLeft: pointer,
outbuf: var cstring, outbytesLeft: var int): int {.
importc: "iconv", importIconv.} importc: "iconv", importIconv.}
proc getCurrentEncoding*(uiApp = false): string = proc getCurrentEncoding*(uiApp = false): string =
@ -428,14 +425,14 @@ when defined(windows):
else: else:
proc convert*(c: EncodingConverter, s: string): string = proc convert*(c: EncodingConverter, s: string): string =
result = newString(s.len) result = newString(s.len)
var inLen = len(s) var inLen = csize_t len(s)
var outLen = len(result) var outLen = csize_t len(result)
var src = cstring(s) var src = cstring(s)
var dst = cstring(result) var dst = cstring(result)
var iconvres: int var iconvres: csize_t
while inLen > 0: while inLen > 0:
iconvres = iconv(c, src, inLen, dst, outLen) iconvres = iconv(c, addr src, addr inLen, addr dst, addr outLen)
if iconvres == -1: if iconvres == high(csize_t):
var lerr = errno var lerr = errno
if lerr == EILSEQ or lerr == EINVAL: if lerr == EILSEQ or lerr == EINVAL:
# unknown char, skip # unknown char, skip
@ -446,24 +443,24 @@ else:
dec(outLen) dec(outLen)
elif lerr == E2BIG: elif lerr == E2BIG:
var offset = cast[int](dst) - cast[int](cstring(result)) 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 # 5 is minimally one utf-8 char
dst = cast[cstring](cast[int](cstring(result)) + offset) dst = cast[cstring](cast[int](cstring(result)) + offset)
outLen = len(result) - offset outLen = csize_t(len(result) - offset)
else: else:
raiseOSError(lerr.OSErrorCode) raiseOSError(lerr.OSErrorCode)
# iconv has a buffer that needs flushing, specially if the last char is # iconv has a buffer that needs flushing, specially if the last char is
# not '\0' # not '\0'
discard iconv(c, nil, nil, dst, outLen) discard iconv(c, nil, nil, addr dst, addr outLen)
if iconvres == cint(-1) and errno == E2BIG: if iconvres == high(csize_t) and errno == E2BIG:
var offset = cast[int](dst) - cast[int](cstring(result)) 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 # 5 is minimally one utf-8 char
dst = cast[cstring](cast[int](cstring(result)) + offset) dst = cast[cstring](cast[int](cstring(result)) + offset)
outLen = len(result) - offset outLen = csize_t(len(result) - offset)
discard iconv(c, nil, nil, dst, outLen) discard iconv(c, nil, nil, addr dst, addr outLen)
# trim output buffer # trim output buffer
setLen(result, len(result) - outLen) setLen(result, len(result) - outLen.int)
proc convert*(s: string, destEncoding = "UTF-8", proc convert*(s: string, destEncoding = "UTF-8",
srcEncoding = "CP1252"): string = srcEncoding = "CP1252"): string =