Add push raises (#101)
* Add push raises * Fix gcsafe violation * remove debug code
This commit is contained in:
parent
7340359702
commit
57ff0b8555
|
@ -26,7 +26,7 @@ const
|
||||||
|
|
||||||
when not defined(nimscript):
|
when not defined(nimscript):
|
||||||
import
|
import
|
||||||
os, terminal,
|
terminal,
|
||||||
confutils/shell_completion
|
confutils/shell_completion
|
||||||
|
|
||||||
type
|
type
|
||||||
|
@ -70,6 +70,8 @@ const
|
||||||
confutils_description_width {.intdefine.} = 80
|
confutils_description_width {.intdefine.} = 80
|
||||||
confutils_narrow_terminal_width {.intdefine.} = 36
|
confutils_narrow_terminal_width {.intdefine.} = 36
|
||||||
|
|
||||||
|
{.push gcsafe, raises: [].}
|
||||||
|
|
||||||
func getFieldName(caseField: NimNode): NimNode =
|
func getFieldName(caseField: NimNode): NimNode =
|
||||||
result = caseField
|
result = caseField
|
||||||
if result.kind == nnkIdentDefs: result = result[0]
|
if result.kind == nnkIdentDefs: result = result[0]
|
||||||
|
@ -565,7 +567,10 @@ proc parseCmdArgAux(T: type, s: string): T {.raises: [ValueError].} =
|
||||||
# If you have provided your own specializations, please handle
|
# If you have provided your own specializations, please handle
|
||||||
# all other exception types.
|
# all other exception types.
|
||||||
mixin parseCmdArg
|
mixin parseCmdArg
|
||||||
|
try:
|
||||||
parseCmdArg(T, s)
|
parseCmdArg(T, s)
|
||||||
|
except CatchableError as exc:
|
||||||
|
raise newException(ValueError, exc.msg)
|
||||||
|
|
||||||
func completeCmdArg*(T: type enum, val: string): seq[string] =
|
func completeCmdArg*(T: type enum, val: string): seq[string] =
|
||||||
for e in low(T)..high(T):
|
for e in low(T)..high(T):
|
||||||
|
@ -1291,3 +1296,5 @@ func load*(f: TypedInputFile): f.ContentType =
|
||||||
else:
|
else:
|
||||||
mixin loadFile
|
mixin loadFile
|
||||||
loadFile(f.Format, f.string, f.ContentType)
|
loadFile(f.Format, f.string, f.ContentType)
|
||||||
|
|
||||||
|
{.pop.}
|
||||||
|
|
|
@ -29,6 +29,8 @@ type
|
||||||
## or the argument, and the value is not "" if
|
## or the argument, and the value is not "" if
|
||||||
## the option was given a value
|
## the option was given a value
|
||||||
|
|
||||||
|
{.push gcsafe, raises: [].}
|
||||||
|
|
||||||
func parseWord(s: string, i: int, w: var string,
|
func parseWord(s: string, i: int, w: var string,
|
||||||
delim: set[char] = {'\t', ' '}): int =
|
delim: set[char] = {'\t', ' '}): int =
|
||||||
result = i
|
result = i
|
||||||
|
@ -161,3 +163,4 @@ iterator getopt*(cmds: seq[string],
|
||||||
if p.kind == cmdEnd: break
|
if p.kind == cmdEnd: break
|
||||||
yield (p.kind, p.key, p.val)
|
yield (p.kind, p.key, p.val)
|
||||||
|
|
||||||
|
{.pop.}
|
||||||
|
|
|
@ -12,6 +12,8 @@ import
|
||||||
stew/byteutils, testutils/fuzzing,
|
stew/byteutils, testutils/fuzzing,
|
||||||
../confutils
|
../confutils
|
||||||
|
|
||||||
|
{.push gcsafe, raises: [].}
|
||||||
|
|
||||||
template fuzzCliParsing*(Conf: type) =
|
template fuzzCliParsing*(Conf: type) =
|
||||||
test:
|
test:
|
||||||
block:
|
block:
|
||||||
|
@ -22,3 +24,4 @@ template fuzzCliParsing*(Conf: type) =
|
||||||
except ConfigurationError as err:
|
except ConfigurationError as err:
|
||||||
discard
|
discard
|
||||||
|
|
||||||
|
{.pop.}
|
||||||
|
|
|
@ -45,6 +45,8 @@ type
|
||||||
|
|
||||||
OriginalToGeneratedFields = OrderedTable[string, GeneratedFieldInfo]
|
OriginalToGeneratedFields = OrderedTable[string, GeneratedFieldInfo]
|
||||||
|
|
||||||
|
{.push gcsafe, raises: [].}
|
||||||
|
|
||||||
func isOption(n: NimNode): bool =
|
func isOption(n: NimNode): bool =
|
||||||
if n.kind != nnkBracketExpr: return false
|
if n.kind != nnkBracketExpr: return false
|
||||||
eqIdent(n[0], "Option")
|
eqIdent(n[0], "Option")
|
||||||
|
@ -248,19 +250,20 @@ proc generateTypes(root: ConfFileSection): seq[NimNode] =
|
||||||
recList.add generateOptionalField(child.getRenamedName.ident, child.typ)
|
recList.add generateOptionalField(child.getRenamedName.ident, child.typ)
|
||||||
result[index].putRecList(recList)
|
result[index].putRecList(recList)
|
||||||
|
|
||||||
proc generateSettersPaths(node: ConfFileSection, result: var OriginalToGeneratedFields) =
|
proc generateSettersPaths(node: ConfFileSection,
|
||||||
var path {.global.}: seq[string]
|
result: var OriginalToGeneratedFields,
|
||||||
path.add node.getRenamedName
|
pathsCache: var seq[string]) =
|
||||||
|
pathsCache.add node.getRenamedName
|
||||||
if node.children.len == 0:
|
if node.children.len == 0:
|
||||||
result[node.fieldName] = (node.isCommandOrArgument, path)
|
result[node.fieldName] = (node.isCommandOrArgument, pathsCache)
|
||||||
else:
|
else:
|
||||||
for child in node.children:
|
for child in node.children:
|
||||||
generateSettersPaths(child, result)
|
generateSettersPaths(child, result, pathsCache)
|
||||||
path.del path.len - 1
|
pathsCache.del pathsCache.len - 1
|
||||||
|
|
||||||
proc generateSettersPaths(root: ConfFileSection): OriginalToGeneratedFields =
|
proc generateSettersPaths(root: ConfFileSection, pathsCache: var seq[string]): OriginalToGeneratedFields =
|
||||||
for child in root.children:
|
for child in root.children:
|
||||||
generateSettersPaths(child, result)
|
generateSettersPaths(child, result, pathsCache)
|
||||||
|
|
||||||
template cfSetter(a, b: untyped): untyped =
|
template cfSetter(a, b: untyped): untyped =
|
||||||
when a is Option:
|
when a is Option:
|
||||||
|
@ -346,9 +349,13 @@ macro generateSecondarySources*(ConfType: type): untyped =
|
||||||
let
|
let
|
||||||
model = generateConfigFileModel(ConfType)
|
model = generateConfigFileModel(ConfType)
|
||||||
modelType = generateTypes(model)
|
modelType = generateTypes(model)
|
||||||
|
var
|
||||||
|
pathsCache: seq[string]
|
||||||
|
|
||||||
result = newTree(nnkStmtList)
|
result = newTree(nnkStmtList)
|
||||||
result.add newTree(nnkTypeSection, modelType)
|
result.add newTree(nnkTypeSection, modelType)
|
||||||
|
|
||||||
let settersPaths = model.generateSettersPaths
|
let settersPaths = model.generateSettersPaths(pathsCache)
|
||||||
result.add generateConfigFileSetters(ConfType, result[^1], settersPaths)
|
result.add generateConfigFileSetters(ConfType, result[^1], settersPaths)
|
||||||
|
|
||||||
|
{.pop.}
|
||||||
|
|
|
@ -45,6 +45,8 @@ type
|
||||||
|
|
||||||
SomeDistinctString = InputFile|InputDir|OutPath|OutDir|OutFile
|
SomeDistinctString = InputFile|InputDir|OutPath|OutDir|OutFile
|
||||||
|
|
||||||
|
{.push gcsafe, raises: [].}
|
||||||
|
|
||||||
template `/`*(dir: InputDir|OutDir, path: string): auto =
|
template `/`*(dir: InputDir|OutDir, path: string): auto =
|
||||||
string(dir) / path
|
string(dir) / path
|
||||||
|
|
||||||
|
@ -70,3 +72,5 @@ template implicitlySelectable* {.pragma.}
|
||||||
## to allow the value of the discriminator to be determined
|
## to allow the value of the discriminator to be determined
|
||||||
## implicitly when the user specifies any of the sub-options
|
## implicitly when the user specifies any of the sub-options
|
||||||
## that depend on the disciminator value.
|
## that depend on the disciminator value.
|
||||||
|
|
||||||
|
{.pop.}
|
||||||
|
|
|
@ -24,13 +24,21 @@ const
|
||||||
WORDBREAKS = "\"'@><=;|&(:"
|
WORDBREAKS = "\"'@><=;|&(:"
|
||||||
SAFE_CHARS = {'a'..'z', 'A'..'Z', '0'..'9', '@', '%', '+', '=', ':', ',', '.', '/', '-'}
|
SAFE_CHARS = {'a'..'z', 'A'..'Z', '0'..'9', '@', '%', '+', '=', ':', ',', '.', '/', '-'}
|
||||||
|
|
||||||
proc open(l: var ShellLexer, input: Stream, wordBreakChars: string = WORDBREAKS, preserveTrailingWs = true) =
|
{.push gcsafe, raises: [].}
|
||||||
|
|
||||||
|
proc open(l: var ShellLexer,
|
||||||
|
input: Stream,
|
||||||
|
wordBreakChars: string = WORDBREAKS,
|
||||||
|
preserveTrailingWs = true) {.gcsafe, raises: [IOError, OSError].} =
|
||||||
lexbase.open(l, input)
|
lexbase.open(l, input)
|
||||||
l.preserveTrailingWs = preserveTrailingWs
|
l.preserveTrailingWs = preserveTrailingWs
|
||||||
l.mergeWordBreaks = false
|
l.mergeWordBreaks = false
|
||||||
l.wordBreakChars = wordBreakChars
|
l.wordBreakChars = wordBreakChars
|
||||||
|
|
||||||
proc parseQuoted(l: var ShellLexer, pos: int, isSingle: bool, output: var string): int =
|
proc parseQuoted(l: var ShellLexer,
|
||||||
|
pos: int,
|
||||||
|
isSingle: bool,
|
||||||
|
output: var string): int {.gcsafe, raises: [IOError, OSError].} =
|
||||||
var pos = pos
|
var pos = pos
|
||||||
while true:
|
while true:
|
||||||
case l.buf[pos]:
|
case l.buf[pos]:
|
||||||
|
@ -62,7 +70,7 @@ proc parseQuoted(l: var ShellLexer, pos: int, isSingle: bool, output: var string
|
||||||
inc(pos)
|
inc(pos)
|
||||||
return pos
|
return pos
|
||||||
|
|
||||||
proc getTok(l: var ShellLexer): Option[string] =
|
proc getTok(l: var ShellLexer): Option[string] {.gcsafe, raises: [IOError, OSError].} =
|
||||||
var pos = l.bufpos
|
var pos = l.bufpos
|
||||||
|
|
||||||
# Skip the initial whitespace
|
# Skip the initial whitespace
|
||||||
|
@ -179,6 +187,8 @@ proc shellPathEscape*(path: string): string =
|
||||||
result.add('\\')
|
result.add('\\')
|
||||||
result.add(ch)
|
result.add(ch)
|
||||||
|
|
||||||
|
{.pop.}
|
||||||
|
|
||||||
when isMainModule:
|
when isMainModule:
|
||||||
# Test data lifted from python's shlex unit-tests
|
# Test data lifted from python's shlex unit-tests
|
||||||
const data = """
|
const data = """
|
||||||
|
@ -265,9 +275,9 @@ foo\ bar|foo bar|
|
||||||
echo "expected ", expected
|
echo "expected ", expected
|
||||||
doAssert(false)
|
doAssert(false)
|
||||||
|
|
||||||
doAssert(quoteWord("") == "''")
|
doAssert(shellQuote("") == "''")
|
||||||
doAssert(quoteWord("\\\"") == "'\\\"'")
|
doAssert(shellQuote("\\\"") == "'\\\"'")
|
||||||
doAssert(quoteWord("foobar") == "foobar")
|
doAssert(shellQuote("foobar") == "foobar")
|
||||||
doAssert(quoteWord("foo$bar") == "'foo$bar'")
|
doAssert(shellQuote("foo$bar") == "'foo$bar'")
|
||||||
doAssert(quoteWord("foo bar") == "'foo bar'")
|
doAssert(shellQuote("foo bar") == "'foo bar'")
|
||||||
doAssert(quoteWord("foo'bar") == "'foo\\'bar'")
|
doAssert(shellQuote("foo'bar") == "'foo\\'bar'")
|
||||||
|
|
|
@ -11,14 +11,16 @@ import std/net
|
||||||
from std/parseutils import parseInt
|
from std/parseutils import parseInt
|
||||||
export net
|
export net
|
||||||
|
|
||||||
func parseCmdArg*(T: type IpAddress, s: string): T =
|
{.push gcsafe, raises: [].}
|
||||||
|
|
||||||
|
func parseCmdArg*(T: type IpAddress, s: string): T {.gcsafe, raises: [ValueError].} =
|
||||||
parseIpAddress(s)
|
parseIpAddress(s)
|
||||||
|
|
||||||
func completeCmdArg*(T: type IpAddress, val: string): seq[string] =
|
func completeCmdArg*(T: type IpAddress, val: string): seq[string] =
|
||||||
# TODO: Maybe complete the local IP address?
|
# TODO: Maybe complete the local IP address?
|
||||||
@[]
|
@[]
|
||||||
|
|
||||||
func parseCmdArg*(T: type Port, s: string): T =
|
func parseCmdArg*(T: type Port, s: string): T {.gcsafe, raises: [ValueError].} =
|
||||||
template fail =
|
template fail =
|
||||||
raise newException(ValueError,
|
raise newException(ValueError,
|
||||||
"The supplied port must be an integer value in the range 1-65535")
|
"The supplied port must be an integer value in the range 1-65535")
|
||||||
|
@ -34,3 +36,5 @@ func parseCmdArg*(T: type Port, s: string): T =
|
||||||
|
|
||||||
func completeCmdArg*(T: type Port, val: string): seq[string] =
|
func completeCmdArg*(T: type Port, val: string): seq[string] =
|
||||||
@[]
|
@[]
|
||||||
|
|
||||||
|
{.pop.}
|
||||||
|
|
|
@ -13,6 +13,8 @@ import
|
||||||
export
|
export
|
||||||
toml_serialization, confutilsDefs
|
toml_serialization, confutilsDefs
|
||||||
|
|
||||||
|
{.push gcsafe, raises: [].}
|
||||||
|
|
||||||
template readConfutilsType(T: type) =
|
template readConfutilsType(T: type) =
|
||||||
template readValue*(r: var TomlReader, val: var T) =
|
template readValue*(r: var TomlReader, val: var T) =
|
||||||
val = T r.readValue(string)
|
val = T r.readValue(string)
|
||||||
|
@ -22,3 +24,5 @@ readConfutilsType InputDir
|
||||||
readConfutilsType OutPath
|
readConfutilsType OutPath
|
||||||
readConfutilsType OutDir
|
readConfutilsType OutDir
|
||||||
readConfutilsType OutFile
|
readConfutilsType OutFile
|
||||||
|
|
||||||
|
{.pop.}
|
||||||
|
|
|
@ -14,16 +14,20 @@ import
|
||||||
export
|
export
|
||||||
net, toml_serialization
|
net, toml_serialization
|
||||||
|
|
||||||
|
{.push gcsafe, raises: [].}
|
||||||
|
|
||||||
proc readValue*(r: var TomlReader, val: var IpAddress)
|
proc readValue*(r: var TomlReader, val: var IpAddress)
|
||||||
{.raises: [SerializationError, IOError, Defect].} =
|
{.raises: [SerializationError, IOError].} =
|
||||||
val = try: parseIpAddress(r.readValue(string))
|
val = try: parseIpAddress(r.readValue(string))
|
||||||
except ValueError as err:
|
except ValueError as err:
|
||||||
r.lex.raiseUnexpectedValue("IP address")
|
r.lex.raiseUnexpectedValue("IP address " & err.msg)
|
||||||
|
|
||||||
proc readValue*(r: var TomlReader, val: var Port)
|
proc readValue*(r: var TomlReader, val: var Port)
|
||||||
{.raises: [SerializationError, IOError, Defect].} =
|
{.raises: [SerializationError, IOError].} =
|
||||||
let port = try: r.readValue(uint16)
|
let port = try: r.readValue(uint16)
|
||||||
except ValueError:
|
except ValueError as exc:
|
||||||
r.lex.raiseUnexpectedValue("Port")
|
r.lex.raiseUnexpectedValue("Port " & exc.msg)
|
||||||
|
|
||||||
val = Port port
|
val = Port port
|
||||||
|
|
||||||
|
{.pop.}
|
||||||
|
|
|
@ -14,9 +14,12 @@ import
|
||||||
export
|
export
|
||||||
uri, toml_serialization
|
uri, toml_serialization
|
||||||
|
|
||||||
|
{.push gcsafe, raises: [].}
|
||||||
|
|
||||||
proc readValue*(r: var TomlReader, val: var Uri)
|
proc readValue*(r: var TomlReader, val: var Uri)
|
||||||
{.raises: [SerializationError, IOError, Defect].} =
|
{.raises: [SerializationError, IOError].} =
|
||||||
val = try: parseUri(r.readValue(string))
|
val = try: parseUri(r.readValue(string))
|
||||||
except ValueError as err:
|
except ValueError as err:
|
||||||
r.lex.raiseUnexpectedValue("URI")
|
r.lex.raiseUnexpectedValue("URI " & err.msg)
|
||||||
|
|
||||||
|
{.pop.}
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
import
|
import
|
||||||
tables, typetraits, options,
|
tables, typetraits, options,
|
||||||
serialization/[object_serialization],
|
serialization/[object_serialization, errors],
|
||||||
./utils, ./types
|
./utils, ./types
|
||||||
|
|
||||||
type
|
type
|
||||||
|
@ -24,11 +24,13 @@ type
|
||||||
deserializedField*: string
|
deserializedField*: string
|
||||||
innerException*: ref CatchableError
|
innerException*: ref CatchableError
|
||||||
|
|
||||||
|
{.push gcsafe, raises: [].}
|
||||||
|
|
||||||
proc handleReadException*(r: WinregReader,
|
proc handleReadException*(r: WinregReader,
|
||||||
Record: type,
|
Record: type,
|
||||||
fieldName: string,
|
fieldName: string,
|
||||||
field: auto,
|
field: auto,
|
||||||
err: ref CatchableError) =
|
err: ref CatchableError) {.gcsafe, raises: [WinregError].} =
|
||||||
var ex = new GenericWinregReaderError
|
var ex = new GenericWinregReaderError
|
||||||
ex.deserializedField = fieldName
|
ex.deserializedField = fieldName
|
||||||
ex.innerException = err
|
ex.innerException = err
|
||||||
|
@ -39,7 +41,8 @@ proc init*(T: type WinregReader,
|
||||||
result.hKey = hKey
|
result.hKey = hKey
|
||||||
result.path = path
|
result.path = path
|
||||||
|
|
||||||
proc readValue*[T](r: var WinregReader, value: var T) =
|
proc readValue*[T](r: var WinregReader, value: var T)
|
||||||
|
{.gcsafe, raises: [SerializationError, IOError].} =
|
||||||
mixin readValue
|
mixin readValue
|
||||||
# TODO: reduce allocation
|
# TODO: reduce allocation
|
||||||
|
|
||||||
|
@ -88,3 +91,5 @@ proc readValue*[T](r: var WinregReader, value: var T) =
|
||||||
else:
|
else:
|
||||||
const typeName = typetraits.name(T)
|
const typeName = typetraits.name(T)
|
||||||
{.fatal: "Failed to convert from Winreg an unsupported type: " & typeName.}
|
{.fatal: "Failed to convert from Winreg an unsupported type: " & typeName.}
|
||||||
|
|
||||||
|
{.pop.}
|
||||||
|
|
|
@ -26,5 +26,9 @@ const
|
||||||
HKCR* = HKEY_CLASSES_ROOT
|
HKCR* = HKEY_CLASSES_ROOT
|
||||||
HKU* = HKEY_USERS
|
HKU* = HKEY_USERS
|
||||||
|
|
||||||
|
{.push gcsafe, raises: [].}
|
||||||
|
|
||||||
proc `==`*(a, b: HKEY): bool {.borrow.}
|
proc `==`*(a, b: HKEY): bool {.borrow.}
|
||||||
proc `==`*(a, b: RegType): bool {.borrow.}
|
proc `==`*(a, b: RegType): bool {.borrow.}
|
||||||
|
|
||||||
|
{.pop.}
|
||||||
|
|
|
@ -26,6 +26,8 @@ const
|
||||||
RT_QWORD* = 0x00000040
|
RT_QWORD* = 0x00000040
|
||||||
RT_ANY* = 0x0000ffff
|
RT_ANY* = 0x0000ffff
|
||||||
|
|
||||||
|
{.push gcsafe, raises: [].}
|
||||||
|
|
||||||
proc regGetValue(hKey: HKEY, lpSubKey, lpValue: cstring,
|
proc regGetValue(hKey: HKEY, lpSubKey, lpValue: cstring,
|
||||||
dwFlags: int32, pdwType: ptr RegType,
|
dwFlags: int32, pdwType: ptr RegType,
|
||||||
pvData: pointer, pcbData: ptr int32): int32 {.
|
pvData: pointer, pcbData: ptr int32): int32 {.
|
||||||
|
@ -39,12 +41,18 @@ template call(f) =
|
||||||
if f != 0:
|
if f != 0:
|
||||||
return false
|
return false
|
||||||
|
|
||||||
|
template safeCast(destType: type, src: typed): auto =
|
||||||
|
when sizeof(src) < sizeof(destType):
|
||||||
|
destType(src)
|
||||||
|
else:
|
||||||
|
cast[destType](src)
|
||||||
|
|
||||||
proc setValue*(hKey: HKEY, path, key: string, val: SomePrimitives): bool =
|
proc setValue*(hKey: HKEY, path, key: string, val: SomePrimitives): bool =
|
||||||
when sizeof(val) < 8:
|
when sizeof(val) < 8:
|
||||||
var dw = cast[int32](val)
|
var dw = int32.safeCast(val)
|
||||||
call regSetValue(hKey, path, key, REG_DWORD, dw.addr, sizeof(dw).int32)
|
call regSetValue(hKey, path, key, REG_DWORD, dw.addr, sizeof(dw).int32)
|
||||||
else:
|
else:
|
||||||
var dw = cast[int64](val)
|
var dw = int64.safeCast(val)
|
||||||
call regSetValue(hKey, path, key, REG_QWORD, dw.addr, sizeof(dw).int32)
|
call regSetValue(hKey, path, key, REG_QWORD, dw.addr, sizeof(dw).int32)
|
||||||
result = true
|
result = true
|
||||||
|
|
||||||
|
@ -160,3 +168,5 @@ func constructPath*(root: string, keys: openArray[string]): string =
|
||||||
result.add keys[i]
|
result.add keys[i]
|
||||||
if i < keys.len-2:
|
if i < keys.len-2:
|
||||||
result. add '\\'
|
result. add '\\'
|
||||||
|
|
||||||
|
{.pop.}
|
||||||
|
|
|
@ -14,6 +14,8 @@ import
|
||||||
export
|
export
|
||||||
serialization, reader, writer, types
|
serialization, reader, writer, types
|
||||||
|
|
||||||
|
{.push gcsafe, raises: [].}
|
||||||
|
|
||||||
serializationFormat Winreg
|
serializationFormat Winreg
|
||||||
|
|
||||||
Winreg.setReader WinregReader
|
Winreg.setReader WinregReader
|
||||||
|
@ -65,3 +67,5 @@ template saveFile*(_: type Winreg, filename: string, value: auto, params: vararg
|
||||||
let (hKey, path) = parseWinregPath(filename)
|
let (hKey, path) = parseWinregPath(filename)
|
||||||
var writer = unpackArgs(init, [WinregWriter, hKey, path, params])
|
var writer = unpackArgs(init, [WinregWriter, hKey, path, params])
|
||||||
writer.writeValue(value)
|
writer.writeValue(value)
|
||||||
|
|
||||||
|
{.pop.}
|
||||||
|
|
|
@ -18,6 +18,8 @@ type
|
||||||
path: string
|
path: string
|
||||||
key: seq[string]
|
key: seq[string]
|
||||||
|
|
||||||
|
{.push gcsafe, raises: [].}
|
||||||
|
|
||||||
proc init*(T: type WinregWriter,
|
proc init*(T: type WinregWriter,
|
||||||
hKey: HKEY, path: string): T =
|
hKey: HKEY, path: string): T =
|
||||||
result.hKey = hKey
|
result.hKey = hKey
|
||||||
|
@ -55,3 +57,5 @@ proc writeValue*(w: var WinregWriter, value: auto) {.raises: [IOError].} =
|
||||||
else:
|
else:
|
||||||
const typeName = typetraits.name(value.type)
|
const typeName = typetraits.name(value.type)
|
||||||
{.fatal: "Failed to convert to Winreg an unsupported type: " & typeName.}
|
{.fatal: "Failed to convert to Winreg an unsupported type: " & typeName.}
|
||||||
|
|
||||||
|
{.pop.}
|
||||||
|
|
|
@ -20,10 +20,7 @@ type
|
||||||
field_a: int
|
field_a: int
|
||||||
field_b: string
|
field_b: string
|
||||||
|
|
||||||
CheckPoint = int
|
|
||||||
RuntimePreset = int
|
|
||||||
GraffitiBytes = array[16, byte]
|
GraffitiBytes = array[16, byte]
|
||||||
WalletName = string
|
|
||||||
|
|
||||||
VCStartUpCmd = enum
|
VCStartUpCmd = enum
|
||||||
VCNoCommand
|
VCNoCommand
|
||||||
|
|
|
@ -34,10 +34,6 @@ type
|
||||||
abbr: "d"
|
abbr: "d"
|
||||||
name: "data-dir" }: OutDir
|
name: "data-dir" }: OutDir
|
||||||
|
|
||||||
func defaultObject(conf: TestConf): SomeObject =
|
|
||||||
discard
|
|
||||||
|
|
||||||
|
|
||||||
func completeCmdArg(T: type SomeObject, val: string): seq[string] =
|
func completeCmdArg(T: type SomeObject, val: string): seq[string] =
|
||||||
@[]
|
@[]
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ import
|
||||||
std/[strutils],
|
std/[strutils],
|
||||||
unittest2,
|
unittest2,
|
||||||
../confutils,
|
../confutils,
|
||||||
./specialint
|
./private/specialint
|
||||||
|
|
||||||
type
|
type
|
||||||
TestConf* = object
|
TestConf* = object
|
||||||
|
|
Loading…
Reference in New Issue