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:
parent
ca71a60ff6
commit
c7dee55b87
1 changed files with 15 additions and 18 deletions
|
|
@ -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 =
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue