Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions lib/pure/parseutils.nim
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,23 @@ proc parseOct*(s: string, number: var int, start = 0): int {.
inc(i)
if foundDigit: result = i-start

proc parseBin*(s: string, number: var int, start = 0): int {.
rtl, extern: "npuParseBin", noSideEffect.} =
## parses an binary number and stores its value in ``number``. Returns
## the number of the parsed characters or 0 in case of an error.
var i = start
var foundDigit = false
if s[i] == '0' and (s[i+1] == 'b' or s[i+1] == 'B'): inc(i, 2)
while true:
case s[i]
of '_': discard
of '0'..'1':
number = number shl 1 or (ord(s[i]) - ord('0'))
foundDigit = true
else: break
inc(i)
if foundDigit: result = i-start

proc parseIdent*(s: string, ident: var string, start = 0): int =
## parses an identifier and stores it in ``ident``. Returns
## the number of the parsed characters or 0 in case of an error.
Expand Down
33 changes: 31 additions & 2 deletions lib/pure/strscans.nim
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,10 @@ As can be seen from the examples, strings are matched verbatim except for
substrings starting with ``$``. These constructions are available:

================= ========================================================
``$i`` Matches an integer. This uses ``parseutils.parseInt``.
``$b`` Matches an decimal integer. This uses ``parseutils.parseBin``.
``$o`` Matches an octal integer. This uses ``parseutils.parseOct``.
``$i`` Matches an decimal integer. This uses ``parseutils.parseInt``.
``$h`` Matches an hex integer. This uses ``parseutils.parseHex``.
``$f`` Matches a floating pointer number. Uses ``parseFloat``.
``$w`` Matches an ASCII identifier: ``[A-Z-a-z_][A-Za-z_0-9]*``.
``$s`` Skips optional whitespace.
Expand Down Expand Up @@ -335,11 +338,29 @@ macro scanf*(input: string; pattern: static[string]; results: varargs[typed]): b
else:
error("no string var given for $w")
inc i
of 'b':
if i < results.len or getType(results[i]).typeKind != ntyInt:
matchBind "parseBin"
else:
error("no int var given for $b")
inc i
of 'o':
if i < results.len or getType(results[i]).typeKind != ntyInt:
matchBind "parseOct"
else:
error("no int var given for $o")
inc i
of 'i':
if i < results.len or getType(results[i]).typeKind != ntyInt:
matchBind "parseInt"
else:
error("no int var given for $d")
error("no int var given for $i")
inc i
of 'h':
if i < results.len or getType(results[i]).typeKind != ntyInt:
matchBind "parseHex"
else:
error("no int var given for $h")
inc i
of 'f':
if i < results.len or getType(results[i]).typeKind != ntyFloat:
Expand Down Expand Up @@ -645,6 +666,14 @@ when isMainModule:
doAssert intval == 89
doAssert floatVal == 33.25

var binval: int
var octval: int
var hexval: int
doAssert scanf("0b0101 0o1234 0xabcd", "$b$s$o$s$h", binval, octval, hexval)
doAssert binval == 0b0101
doAssert octval == 0o1234
doAssert hexval == 0xabcd

let xx = scanf("$abc", "$$$i", intval)
doAssert xx == false

Expand Down