mirror of
https://github.com/nim-lang/Nim.git
synced 2026-07-21 08:21:32 +00:00
Improved collection-to-string behavior (#6825)
This commit is contained in:
committed by
Andreas Rumpf
parent
bc1123536e
commit
6df6ec27ec
@@ -141,8 +141,8 @@ proc excl*[T](c: var CritBitTree[T], key: string) =
|
||||
|
||||
proc missingOrExcl*[T](c: var CritBitTree[T], key: string): bool =
|
||||
## Returns true iff `c` does not contain the given `key`. If the key
|
||||
## does exist, c.excl(key) is performed.
|
||||
let oldCount = c.count
|
||||
## does exist, c.excl(key) is performed.
|
||||
let oldCount = c.count
|
||||
var n = exclImpl(c, key)
|
||||
result = c.count == oldCount
|
||||
|
||||
@@ -326,7 +326,7 @@ proc `$`*[T](c: CritBitTree[T]): string =
|
||||
result.add($key)
|
||||
when T isnot void:
|
||||
result.add(": ")
|
||||
result.add($val)
|
||||
result.addQuoted(val)
|
||||
result.add("}")
|
||||
|
||||
when isMainModule:
|
||||
|
||||
@@ -185,7 +185,7 @@ proc `$`*[T](deq: Deque[T]): string =
|
||||
result = "["
|
||||
for x in deq:
|
||||
if result.len > 1: result.add(", ")
|
||||
result.add($x)
|
||||
result.addQuoted(x)
|
||||
result.add("]")
|
||||
|
||||
when isMainModule:
|
||||
|
||||
@@ -135,7 +135,7 @@ proc `$`*[T](L: SomeLinkedCollection[T]): string =
|
||||
result = "["
|
||||
for x in nodes(L):
|
||||
if result.len > 1: result.add(", ")
|
||||
result.add($x.value)
|
||||
result.addQuoted(x.value)
|
||||
result.add("]")
|
||||
|
||||
proc find*[T](L: SomeLinkedCollection[T], value: T): SomeLinkedNode[T] =
|
||||
|
||||
@@ -406,7 +406,7 @@ template dollarImpl() {.dirty.} =
|
||||
result = "{"
|
||||
for key in items(s):
|
||||
if result.len > 1: result.add(", ")
|
||||
result.add($key)
|
||||
result.addQuoted(key)
|
||||
result.add("}")
|
||||
|
||||
proc `$`*[A](s: HashSet[A]): string =
|
||||
|
||||
@@ -338,9 +338,9 @@ template dollarImpl(): untyped {.dirty.} =
|
||||
result = "{"
|
||||
for key, val in pairs(t):
|
||||
if result.len > 1: result.add(", ")
|
||||
result.add($key)
|
||||
result.addQuoted(key)
|
||||
result.add(": ")
|
||||
result.add($val)
|
||||
result.addQuoted(val)
|
||||
result.add("}")
|
||||
|
||||
proc `$`*[A, B](t: Table[A, B]): string =
|
||||
|
||||
@@ -1761,29 +1761,15 @@ proc insertSep*(s: string, sep = '_', digits = 3): string {.noSideEffect,
|
||||
|
||||
proc escape*(s: string, prefix = "\"", suffix = "\""): string {.noSideEffect,
|
||||
rtl, extern: "nsuEscape".} =
|
||||
## Escapes a string `s`.
|
||||
## Escapes a string `s`. See `system.addEscapedChar <system.html#addEscapedChar>`_
|
||||
## for the escaping scheme.
|
||||
##
|
||||
## This does these operations (at the same time):
|
||||
## * replaces any ``\`` by ``\\``
|
||||
## * replaces any ``'`` by ``\'``
|
||||
## * replaces any ``"`` by ``\"``
|
||||
## * replaces any other character in the set ``{'\0'..'\31', '\127'..'\255'}``
|
||||
## by ``\xHH`` where ``HH`` is its hexadecimal value.
|
||||
## The procedure has been designed so that its output is usable for many
|
||||
## different common syntaxes. The resulting string is prefixed with
|
||||
## `prefix` and suffixed with `suffix`. Both may be empty strings.
|
||||
## **Note**: This is not correct for producing Ansi C code!
|
||||
## The resulting string is prefixed with `prefix` and suffixed with `suffix`.
|
||||
## Both may be empty strings.
|
||||
result = newStringOfCap(s.len + s.len shr 2)
|
||||
result.add(prefix)
|
||||
for c in items(s):
|
||||
case c
|
||||
of '\0'..'\31', '\127'..'\255':
|
||||
add(result, "\\x")
|
||||
add(result, toHex(ord(c), 2))
|
||||
of '\\': add(result, "\\\\")
|
||||
of '\'': add(result, "\\'")
|
||||
of '\"': add(result, "\\\"")
|
||||
else: add(result, c)
|
||||
result.addEscapedChar(c)
|
||||
add(result, suffix)
|
||||
|
||||
proc unescape*(s: string, prefix = "\"", suffix = "\""): string {.noSideEffect,
|
||||
|
||||
@@ -1325,6 +1325,7 @@ proc add*(x: var string, y: string) {.magic: "AppendStrStr", noSideEffect.}
|
||||
## tmp.add("cd")
|
||||
## assert(tmp == "abcd")
|
||||
|
||||
|
||||
type
|
||||
Endianness* = enum ## is a type describing the endianness of a processor.
|
||||
littleEndian, bigEndian
|
||||
@@ -2503,9 +2504,9 @@ proc `$`*[T: tuple|object](x: T): string =
|
||||
when compiles($value):
|
||||
when compiles(value.isNil):
|
||||
if value.isNil: result.add "nil"
|
||||
else: result.add($value)
|
||||
else: result.addQuoted(value)
|
||||
else:
|
||||
result.add($value)
|
||||
result.addQuoted(value)
|
||||
firstElement = false
|
||||
else:
|
||||
result.add("...")
|
||||
@@ -2525,12 +2526,9 @@ proc collectionToString[T](x: T, prefix, separator, suffix: string): string =
|
||||
if value.isNil:
|
||||
result.add "nil"
|
||||
else:
|
||||
result.add($value)
|
||||
# prevent temporary string allocation
|
||||
elif compiles(result.add(value)):
|
||||
result.add(value)
|
||||
result.addQuoted(value)
|
||||
else:
|
||||
result.add($value)
|
||||
result.addQuoted(value)
|
||||
|
||||
result.add(suffix)
|
||||
|
||||
@@ -3893,6 +3891,65 @@ proc compiles*(x: untyped): bool {.magic: "Compiles", noSideEffect, compileTime.
|
||||
when declared(initDebugger):
|
||||
initDebugger()
|
||||
|
||||
proc addEscapedChar*(s: var string, c: char) {.noSideEffect, inline.} =
|
||||
## Adds a char to string `s` and applies the following escaping:
|
||||
##
|
||||
## * replaces any ``\`` by ``\\``
|
||||
## * replaces any ``'`` by ``\'``
|
||||
## * replaces any ``"`` by ``\"``
|
||||
## * replaces any other character in the set ``{'\0'..'\31', '\127'..'\255'}``
|
||||
## by ``\xHH`` where ``HH`` is its hexadecimal value.
|
||||
##
|
||||
## The procedure has been designed so that its output is usable for many
|
||||
## different common syntaxes.
|
||||
## **Note**: This is not correct for producing Ansi C code!
|
||||
case c
|
||||
of '\0'..'\31', '\127'..'\255':
|
||||
add(s, "\\x")
|
||||
const HexChars = "0123456789ABCDEF"
|
||||
let n = ord(c)
|
||||
s.add(HexChars[int((n and 0xF0) shr 4)])
|
||||
s.add(HexChars[int(n and 0xF)])
|
||||
of '\\': add(s, "\\\\")
|
||||
of '\'': add(s, "\\'")
|
||||
of '\"': add(s, "\\\"")
|
||||
else: add(s, c)
|
||||
|
||||
proc addQuoted*[T](s: var string, x: T) =
|
||||
## Appends `x` to string `s` in place, applying quoting and escaping
|
||||
## if `x` is a string or char. See
|
||||
## `addEscapedChar <system.html#addEscapedChar>`_
|
||||
## for the escaping scheme.
|
||||
##
|
||||
## The Nim standard library uses this function on the elements of
|
||||
## collections when producing a string representation of a collection.
|
||||
## It is recommended to use this function as well for user-side collections.
|
||||
## Users may overload `addQuoted` for custom (string-like) types if
|
||||
## they want to implement a customized element representation.
|
||||
##
|
||||
## .. code-block:: Nim
|
||||
## var tmp = ""
|
||||
## tmp.addQuoted(1)
|
||||
## tmp.add(", ")
|
||||
## tmp.addQuoted("string")
|
||||
## tmp.add(", ")
|
||||
## tmp.addQuoted('c')
|
||||
## assert(tmp == """1, "string", 'c'""")
|
||||
when T is string:
|
||||
s.add("\"")
|
||||
for c in x:
|
||||
s.addEscapedChar(c)
|
||||
s.add("\"")
|
||||
elif T is char:
|
||||
s.add("'")
|
||||
s.addEscapedChar(x)
|
||||
s.add("'")
|
||||
# prevent temporary string allocation
|
||||
elif compiles(s.add(x)):
|
||||
s.add(x)
|
||||
else:
|
||||
s.add($x)
|
||||
|
||||
when hasAlloc:
|
||||
# XXX: make these the default (or implement the NilObject optimization)
|
||||
proc safeAdd*[T](x: var seq[T], y: T) {.noSideEffect.} =
|
||||
@@ -4034,4 +4091,4 @@ template doAssertRaises*(exception, code: untyped): typed =
|
||||
except Exception as exc:
|
||||
raiseAssert(astToStr(exception) &
|
||||
" wasn't raised, another error was raised instead by:\n"&
|
||||
astToStr(code))
|
||||
astToStr(code))
|
||||
|
||||
Reference in New Issue
Block a user