add support for parsing chars in scanf macro (#16240)
This commit is contained in:
parent
545c406cbe
commit
2220aaeaef
4 changed files with 33 additions and 1 deletions
|
|
@ -52,6 +52,9 @@
|
||||||
|
|
||||||
- `writeStackTrace` is available in JS backend now.
|
- `writeStackTrace` is available in JS backend now.
|
||||||
|
|
||||||
|
- `strscans.scanf` now supports parsing single characters.
|
||||||
|
|
||||||
|
|
||||||
## Language changes
|
## Language changes
|
||||||
|
|
||||||
- `nimscript` now handles `except Exception as e`.
|
- `nimscript` now handles `except Exception as e`.
|
||||||
|
|
@ -60,6 +63,7 @@
|
||||||
|
|
||||||
- nil dereference is not allowed at compile time. `cast[ptr int](nil)[]` is rejected at compile time.
|
- nil dereference is not allowed at compile time. `cast[ptr int](nil)[]` is rejected at compile time.
|
||||||
|
|
||||||
|
|
||||||
## Compiler changes
|
## Compiler changes
|
||||||
|
|
||||||
- Added `--declaredlocs` to show symbol declaration location in messages.
|
- Added `--declaredlocs` to show symbol declaration location in messages.
|
||||||
|
|
|
||||||
|
|
@ -241,6 +241,10 @@ proc parseIdent*(s: string, start = 0): string =
|
||||||
while i < s.len and s[i] in IdentChars: inc(i)
|
while i < s.len and s[i] in IdentChars: inc(i)
|
||||||
result = substr(s, start, i-1)
|
result = substr(s, start, i-1)
|
||||||
|
|
||||||
|
proc parseChar*(s: string, ident: var char, start = 0): int =
|
||||||
|
ident = s[start]
|
||||||
|
result = 1
|
||||||
|
|
||||||
proc skipWhitespace*(s: string, start = 0): int {.inline.} =
|
proc skipWhitespace*(s: string, start = 0): int {.inline.} =
|
||||||
## Skips the whitespace starting at ``s[start]``. Returns the number of
|
## Skips the whitespace starting at ``s[start]``. Returns the number of
|
||||||
## skipped characters.
|
## skipped characters.
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ substrings starting with ``$``. These constructions are available:
|
||||||
``$h`` Matches a hex integer. This uses ``parseutils.parseHex``.
|
``$h`` Matches a hex integer. This uses ``parseutils.parseHex``.
|
||||||
``$f`` Matches a floating pointer number. Uses ``parseFloat``.
|
``$f`` Matches a floating pointer number. Uses ``parseFloat``.
|
||||||
``$w`` Matches an ASCII identifier: ``[A-Za-z_][A-Za-z_0-9]*``.
|
``$w`` Matches an ASCII identifier: ``[A-Za-z_][A-Za-z_0-9]*``.
|
||||||
|
``$c`` Matches a single ASCII character.
|
||||||
``$s`` Skips optional whitespace.
|
``$s`` Skips optional whitespace.
|
||||||
``$$`` Matches a single dollar sign.
|
``$$`` Matches a single dollar sign.
|
||||||
``$.`` Matches if the end of the input string has been reached.
|
``$.`` Matches if the end of the input string has been reached.
|
||||||
|
|
@ -345,6 +346,12 @@ macro scanf*(input: string; pattern: static[string]; results: varargs[typed]): b
|
||||||
else:
|
else:
|
||||||
matchError
|
matchError
|
||||||
inc i
|
inc i
|
||||||
|
of 'c':
|
||||||
|
if i < results.len and getType(results[i]).typeKind == ntyChar:
|
||||||
|
matchBind "parseChar"
|
||||||
|
else:
|
||||||
|
matchError
|
||||||
|
inc i
|
||||||
of 'b':
|
of 'b':
|
||||||
if i < results.len and getType(results[i]).typeKind == ntyInt:
|
if i < results.len and getType(results[i]).typeKind == ntyInt:
|
||||||
matchBind "parseBin"
|
matchBind "parseBin"
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ discard """
|
||||||
output: ""
|
output: ""
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import strscans
|
import strscans, strutils
|
||||||
|
|
||||||
block ParsePasswd:
|
block ParsePasswd:
|
||||||
proc parsePasswd(content: string): seq[string] =
|
proc parsePasswd(content: string): seq[string] =
|
||||||
|
|
@ -210,3 +210,20 @@ block:
|
||||||
var a: int
|
var a: int
|
||||||
discard scanf(test(), ",$i", a)
|
discard scanf(test(), ",$i", a)
|
||||||
doAssert count == 1
|
doAssert count == 1
|
||||||
|
|
||||||
|
|
||||||
|
block:
|
||||||
|
let input = """1-3 s: abc
|
||||||
|
15-18 9: def
|
||||||
|
15-18 A: ghi
|
||||||
|
15-18 _: jkl
|
||||||
|
"""
|
||||||
|
var
|
||||||
|
lo, hi: int
|
||||||
|
w: string
|
||||||
|
c: char
|
||||||
|
res: int
|
||||||
|
for line in input.splitLines:
|
||||||
|
if line.scanf("$i-$i $c: $w", lo, hi, c, w):
|
||||||
|
inc res
|
||||||
|
doAssert res == 4
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue