2016-09-20 19:53:38 +00:00
|
|
|
# NimYAML - YAML implementation in Nim
|
|
|
|
# (c) Copyright 2016 Felix Krause
|
|
|
|
#
|
|
|
|
# See the file "copying.txt", included in this
|
|
|
|
# distribution, for details about the copyright.
|
|
|
|
|
2020-11-10 18:07:46 +00:00
|
|
|
import tables
|
|
|
|
import ../data
|
|
|
|
|
2016-09-20 19:53:38 +00:00
|
|
|
template internalError*(s: string) =
|
2018-10-09 16:25:55 +00:00
|
|
|
# Note: to get the internal stacktrace that caused the error
|
|
|
|
# compile with the `d:debug` flag.
|
2016-09-20 19:53:38 +00:00
|
|
|
when not defined(release):
|
|
|
|
let ii = instantiationInfo()
|
|
|
|
echo "[NimYAML] Error in file ", ii.filename, " at line ", ii.line, ":"
|
|
|
|
echo s
|
|
|
|
when not defined(JS):
|
|
|
|
echo "[NimYAML] Stacktrace:"
|
2018-10-09 16:25:55 +00:00
|
|
|
try:
|
|
|
|
writeStackTrace()
|
2018-10-11 12:21:12 +00:00
|
|
|
let exc = getCurrentException()
|
|
|
|
if not isNil(exc.parent):
|
2018-10-12 07:01:20 +00:00
|
|
|
echo "Internal stacktrace:"
|
2018-10-09 16:25:55 +00:00
|
|
|
echo getStackTrace(exc.parent)
|
2016-09-20 19:53:38 +00:00
|
|
|
except: discard
|
|
|
|
echo "[NimYAML] Please report this bug."
|
|
|
|
quit 1
|
2018-10-09 16:25:55 +00:00
|
|
|
|
2016-09-20 19:53:38 +00:00
|
|
|
template yAssert*(e: typed) =
|
|
|
|
when not defined(release):
|
|
|
|
if not e:
|
|
|
|
let ii = instantiationInfo()
|
|
|
|
echo "[NimYAML] Error in file ", ii.filename, " at line ", ii.line, ":"
|
|
|
|
echo "assertion failed!"
|
|
|
|
when not defined(JS):
|
|
|
|
echo "[NimYAML] Stacktrace:"
|
2018-10-09 16:25:55 +00:00
|
|
|
try:
|
|
|
|
writeStackTrace()
|
2018-10-11 12:21:12 +00:00
|
|
|
let exc = getCurrentException()
|
|
|
|
if not isNil(exc.parent):
|
2018-10-12 07:01:20 +00:00
|
|
|
echo "Internal stacktrace:"
|
2018-10-09 16:25:55 +00:00
|
|
|
echo getStackTrace(exc.parent)
|
2016-09-20 19:53:38 +00:00
|
|
|
except: discard
|
|
|
|
echo "[NimYAML] Please report this bug."
|
2017-02-14 18:40:40 +00:00
|
|
|
quit 1
|
|
|
|
|
2020-11-03 21:08:21 +00:00
|
|
|
proc nextAnchor*(s: var string, i: int) =
|
|
|
|
if s[i] == 'z':
|
|
|
|
s[i] = 'a'
|
|
|
|
if i == 0:
|
|
|
|
s.add('a')
|
|
|
|
else:
|
|
|
|
s[i] = 'a'
|
|
|
|
nextAnchor(s, i - 1)
|
|
|
|
else:
|
2021-05-17 21:51:35 +00:00
|
|
|
s[i] = char(int(s[i]) + 1)
|
2020-11-06 20:39:50 +00:00
|
|
|
|
|
|
|
template resetHandles*(handles: var seq[tuple[handle, uriPrefix: string]]) {.dirty.} =
|
|
|
|
handles.setLen(0)
|
|
|
|
handles.add(("!", "!"))
|
|
|
|
handles.add(("!!", yamlTagRepositoryPrefix))
|
|
|
|
|
|
|
|
proc registerHandle*(handles: var seq[tuple[handle, uriPrefix: string]], handle, uriPrefix: string): bool =
|
|
|
|
for i in countup(0, len(handles)-1):
|
|
|
|
if handles[i].handle == handle:
|
|
|
|
handles[i].uriPrefix = uriPrefix
|
|
|
|
return false
|
|
|
|
handles.add((handle, uriPrefix))
|
2020-11-10 18:07:46 +00:00
|
|
|
return false
|
|
|
|
|
|
|
|
type
|
|
|
|
AnchorContext* = object
|
|
|
|
nextAnchorId: string
|
|
|
|
mapping: Table[Anchor, Anchor]
|
|
|
|
|
|
|
|
proc initAnchorContext*(): AnchorContext =
|
|
|
|
return AnchorContext(nextAnchorId: "a", mapping: initTable[Anchor, Anchor]())
|
|
|
|
|
|
|
|
proc process*(context: var AnchorContext,
|
|
|
|
target: var Properties, refs: Table[pointer, tuple[a: Anchor, referenced: bool]]) =
|
|
|
|
if target.anchor == yAnchorNone: return
|
|
|
|
for key, val in refs:
|
|
|
|
if val.a == target.anchor:
|
|
|
|
if not val.referenced:
|
|
|
|
target.anchor = yAnchorNone
|
|
|
|
return
|
|
|
|
break
|
|
|
|
if context.mapping.hasKey(target.anchor):
|
|
|
|
target.anchor = context.mapping.getOrDefault(target.anchor)
|
|
|
|
else:
|
|
|
|
let old = move(target.anchor)
|
|
|
|
target.anchor = context.nextAnchorId.Anchor
|
|
|
|
nextAnchor(context.nextAnchorId, len(context.nextAnchorId)-1)
|
|
|
|
context.mapping[old] = target.anchor
|
|
|
|
|
|
|
|
proc map*(context: AnchorContext, anchor: Anchor): Anchor =
|
|
|
|
return context.mapping.getOrDefault(anchor)
|