mirror of
https://github.com/nim-lang/Nim.git
synced 2026-07-19 07:21:19 +00:00
breaking change: arrays of char do not convert to cstring; ptr to array of char does
This commit is contained in:
@@ -5,3 +5,6 @@
|
||||
- Removed basic2d/basic3d out of the stdlib and into Nimble packages.
|
||||
These packages deprecated however, use the ``glm``, ``arraymancer``, ``neo``
|
||||
or another package.
|
||||
- Arrays of char cannot be converted to ``cstring`` anymore, pointers to
|
||||
arrays of char can! This means ``$`` for arrays can finally exist
|
||||
in ``system.nim`` and do the right thing.
|
||||
|
||||
@@ -108,3 +108,4 @@ proc initDefines*() =
|
||||
defineSymbol("nimHasCppDefine")
|
||||
defineSymbol("nimGenericInOutFlags")
|
||||
when false: defineSymbol("nimHasOpt")
|
||||
defineSymbol("nimNoArrayToCstringConversion")
|
||||
|
||||
@@ -21,9 +21,14 @@ proc toStrMaxPrecision*(f: BiggestFloat, literalPostfix = ""): string =
|
||||
if f > 0.0: result = "INF"
|
||||
else: result = "-INF"
|
||||
else:
|
||||
var buf: array[0..80, char]
|
||||
discard c_snprintf(buf.cstring, buf.len.uint, "%#.16e%s", f, literalPostfix.cstring)
|
||||
result = $buf.cstring
|
||||
when defined(nimNoArrayToCstringConversion):
|
||||
result = newString(81)
|
||||
let n = c_snprintf(result.cstring, result.len.uint, "%#.16e%s", f, literalPostfix.cstring)
|
||||
setLen(result, n)
|
||||
else:
|
||||
var buf: array[0..80, char]
|
||||
discard c_snprintf(buf.cstring, buf.len.uint, "%#.16e%s", f, literalPostfix.cstring)
|
||||
result = $buf.cstring
|
||||
|
||||
proc encodeStr*(s: string, result: var string) =
|
||||
for i in countup(0, len(s) - 1):
|
||||
|
||||
@@ -1288,12 +1288,13 @@ proc typeRelImpl(c: var TCandidate, f, aOrig: PType,
|
||||
of tyString: result = isConvertible
|
||||
of tyPtr:
|
||||
# ptr[Tag, char] is not convertible to 'cstring' for now:
|
||||
if a.len == 1 and a.sons[0].kind == tyChar: result = isConvertible
|
||||
of tyArray:
|
||||
if (firstOrd(a.sons[0]) == 0) and
|
||||
(skipTypes(a.sons[0], {tyRange}).kind in {tyInt..tyInt64}) and
|
||||
(a.sons[1].kind == tyChar):
|
||||
result = isConvertible
|
||||
if a.len == 1:
|
||||
let pointsTo = a.sons[0].skipTypes(abstractInst)
|
||||
if pointsTo.kind == tyChar: result = isConvertible
|
||||
elif pointsTo.kind == tyArray and firstOrd(pointsTo.sons[0]) == 0 and
|
||||
skipTypes(pointsTo.sons[0], {tyRange}).kind in {tyInt..tyInt64} and
|
||||
pointsTo.sons[1].kind == tyChar:
|
||||
result = isConvertible
|
||||
else: discard
|
||||
|
||||
of tyEmpty, tyVoid:
|
||||
|
||||
@@ -667,14 +667,6 @@ proc lengthOrd*(t: PType): BiggestInt =
|
||||
else:
|
||||
result = lastOrd(t) - firstOrd(t) + 1
|
||||
|
||||
proc isCompatibleToCString*(a: PType): bool =
|
||||
if a.kind == tyArray:
|
||||
if (firstOrd(a.sons[0]) == 0) and
|
||||
(skipTypes(a.sons[0], {tyRange, tyGenericInst, tyAlias}).kind in
|
||||
{tyInt..tyInt64, tyUInt..tyUInt64}) and
|
||||
(a.sons[1].kind == tyChar):
|
||||
result = true
|
||||
|
||||
# -------------- type equality -----------------------------------------------
|
||||
|
||||
type
|
||||
|
||||
@@ -496,11 +496,12 @@ proc getLocalAddr*(socket: SocketHandle, domain: Domain): (string, Port) =
|
||||
addr(namelen)) == -1'i32:
|
||||
raiseOSError(osLastError())
|
||||
# Cannot use INET6_ADDRSTRLEN here, because it's a C define.
|
||||
var buf: array[64, char]
|
||||
result[0] = newString(64)
|
||||
if inet_ntop(name.sin6_family.cint,
|
||||
addr name.sin6_addr, buf.cstring, sizeof(buf).int32).isNil:
|
||||
addr name.sin6_addr, addr result[0][0], (result[0].len+1).int32).isNil:
|
||||
raiseOSError(osLastError())
|
||||
result = ($buf.cstring, Port(nativesockets.ntohs(name.sin6_port)))
|
||||
setLen(result[0], result[0].cstring.len)
|
||||
result[1] = Port(nativesockets.ntohs(name.sin6_port))
|
||||
else:
|
||||
raiseOSError(OSErrorCode(-1), "invalid socket family in getLocalAddr")
|
||||
|
||||
@@ -532,11 +533,12 @@ proc getPeerAddr*(socket: SocketHandle, domain: Domain): (string, Port) =
|
||||
addr(namelen)) == -1'i32:
|
||||
raiseOSError(osLastError())
|
||||
# Cannot use INET6_ADDRSTRLEN here, because it's a C define.
|
||||
var buf: array[64, char]
|
||||
result[0] = newString(64)
|
||||
if inet_ntop(name.sin6_family.cint,
|
||||
addr name.sin6_addr, buf.cstring, sizeof(buf).int32).isNil:
|
||||
addr name.sin6_addr, addr result[0][0], (result[0].len+1).int32).isNil:
|
||||
raiseOSError(osLastError())
|
||||
result = ($buf.cstring, Port(nativesockets.ntohs(name.sin6_port)))
|
||||
setLen(result[0], result[0].cstring.len)
|
||||
result[1] = Port(nativesockets.ntohs(name.sin6_port))
|
||||
else:
|
||||
raiseOSError(OSErrorCode(-1), "invalid socket family in getLocalAddr")
|
||||
|
||||
|
||||
@@ -790,7 +790,10 @@ iterator walkDir*(dir: string; relative=false): tuple[kind: PathComponent, path:
|
||||
while true:
|
||||
var x = readdir(d)
|
||||
if x == nil: break
|
||||
var y = $x.d_name.cstring
|
||||
when defined(nimNoArrayToCstringConversion):
|
||||
var y = $cstring(addr x.d_name)
|
||||
else:
|
||||
var y = $x.d_name.cstring
|
||||
if y != "." and y != "..":
|
||||
var s: Stat
|
||||
if not relative:
|
||||
|
||||
@@ -1890,11 +1890,17 @@ proc formatBiggestFloat*(f: BiggestFloat, format: FloatFormatMode = ffDefault,
|
||||
frmtstr[3] = '*'
|
||||
frmtstr[4] = floatFormatToChar[format]
|
||||
frmtstr[5] = '\0'
|
||||
L = c_sprintf(buf, frmtstr, precision, f)
|
||||
when defined(nimNoArrayToCstringConversion):
|
||||
L = c_sprintf(addr buf, addr frmtstr, precision, f)
|
||||
else:
|
||||
L = c_sprintf(buf, frmtstr, precision, f)
|
||||
else:
|
||||
frmtstr[1] = floatFormatToChar[format]
|
||||
frmtstr[2] = '\0'
|
||||
L = c_sprintf(buf, frmtstr, f)
|
||||
when defined(nimNoArrayToCstringConversion):
|
||||
L = c_sprintf(addr buf, addr frmtstr, f)
|
||||
else:
|
||||
L = c_sprintf(buf, frmtstr, f)
|
||||
result = newString(L)
|
||||
for i in 0 ..< L:
|
||||
# Depending on the locale either dot or comma is produced,
|
||||
|
||||
@@ -142,7 +142,10 @@ elif defined(windows) or defined(dos):
|
||||
dec(m)
|
||||
k = k div 10
|
||||
if k == 0: break
|
||||
result = getProcAddress(cast[THINSTANCE](lib), decorated)
|
||||
when defined(nimNoArrayToCstringConversion):
|
||||
result = getProcAddress(cast[THINSTANCE](lib), addr decorated)
|
||||
else:
|
||||
result = getProcAddress(cast[THINSTANCE](lib), decorated)
|
||||
if result != nil: return
|
||||
procAddrError(name)
|
||||
|
||||
|
||||
@@ -289,8 +289,12 @@ proc raiseExceptionAux(e: ref Exception) =
|
||||
add(buf, " [")
|
||||
xadd(buf, e.name, e.name.len)
|
||||
add(buf, "]\n")
|
||||
unhandled(buf):
|
||||
showErrorMessage(buf)
|
||||
when defined(nimNoArrayToCstringConversion):
|
||||
template tbuf(): untyped = addr buf
|
||||
else:
|
||||
template tbuf(): untyped = buf
|
||||
unhandled(tbuf()):
|
||||
showErrorMessage(tbuf())
|
||||
quitOrDebug()
|
||||
|
||||
proc raiseException(e: ref Exception, ename: cstring) {.compilerRtl.} =
|
||||
|
||||
@@ -16,9 +16,14 @@ proc reprInt(x: int64): string {.compilerproc.} = return $x
|
||||
proc reprFloat(x: float): string {.compilerproc.} = return $x
|
||||
|
||||
proc reprPointer(x: pointer): string {.compilerproc.} =
|
||||
var buf: array[60, char]
|
||||
discard c_sprintf(buf.cstring, "%p", x)
|
||||
result = $buf.cstring
|
||||
when defined(nimNoArrayToCstringConversion):
|
||||
result = newString(60)
|
||||
let n = c_sprintf(addr result[0], "%p", x)
|
||||
setLen(result, n)
|
||||
else:
|
||||
var buf: array[0..59, char]
|
||||
discard c_sprintf(buf, "%p", x)
|
||||
return $buf
|
||||
|
||||
proc `$`(x: uint64): string =
|
||||
if x == 0:
|
||||
|
||||
@@ -24,7 +24,10 @@ proc cmpStrings(a, b: NimString): int {.inline, compilerProc.} =
|
||||
if a == b: return 0
|
||||
if a == nil: return -1
|
||||
if b == nil: return 1
|
||||
return c_strcmp(a.data, b.data)
|
||||
when defined(nimNoArrayToCstringConversion):
|
||||
return c_strcmp(addr a.data, addr b.data)
|
||||
else:
|
||||
return c_strcmp(a.data, b.data)
|
||||
|
||||
proc eqStrings(a, b: NimString): bool {.inline, compilerProc.} =
|
||||
if a == b: return true
|
||||
@@ -320,7 +323,10 @@ proc nimIntToStr(x: int): string {.compilerRtl.} =
|
||||
|
||||
proc add*(result: var string; x: float) =
|
||||
var buf: array[0..64, char]
|
||||
var n: int = c_sprintf(buf, "%.16g", x)
|
||||
when defined(nimNoArrayToCstringConversion):
|
||||
var n: int = c_sprintf(addr buf, "%.16g", x)
|
||||
else:
|
||||
var n: int = c_sprintf(buf, "%.16g", x)
|
||||
var hasDot = false
|
||||
for i in 0..n-1:
|
||||
if buf[i] == ',':
|
||||
@@ -342,7 +348,10 @@ proc add*(result: var string; x: float) =
|
||||
else:
|
||||
result.add "inf"
|
||||
else:
|
||||
result.add buf
|
||||
var i = 0
|
||||
while buf[i] != '\0':
|
||||
result.add buf[i]
|
||||
inc i
|
||||
|
||||
proc nimFloatToStr(f: float): string {.compilerproc.} =
|
||||
result = newStringOfCap(8)
|
||||
@@ -507,7 +516,10 @@ proc nimParseBiggestFloat(s: string, number: var BiggestFloat,
|
||||
t[ti-2] = ('0'.ord + abs_exponent mod 10).char; abs_exponent = abs_exponent div 10
|
||||
t[ti-3] = ('0'.ord + abs_exponent mod 10).char
|
||||
|
||||
number = c_strtod(t, nil)
|
||||
when defined(nimNoArrayToCstringConversion):
|
||||
number = c_strtod(addr t, nil)
|
||||
else:
|
||||
number = c_strtod(t, nil)
|
||||
|
||||
proc nimInt64ToStr(x: int64): string {.compilerRtl.} =
|
||||
result = newStringOfCap(sizeof(x)*4)
|
||||
|
||||
Reference in New Issue
Block a user