discard """ matrix: "--mm:refc; --mm:orc" """ import std/[strscans, strutils, assertions] block ParsePasswd: proc parsePasswd(content: string): seq[string] = result = @[] var idx = 0 while true: var entry = "" if scanp(content, idx, +(~{'\L', '\0'} -> entry.add($_)), '\L'): result.add entry else: break const etcPasswd = """root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/bin/sh bin:x:2:2:bin:/bin:/bin/sh sys:x:3:3:sys:/dev:/bin/sh nobody:x:65534:65534:nobody:/nonexistent:/bin/sh messagebus:x:103:107::/var/run/dbus:/bin/false """ const parsedEtcPasswd = @[ "root:x:0:0:root:/root:/bin/bash", "daemon:x:1:1:daemon:/usr/sbin:/bin/sh", "bin:x:2:2:bin:/bin:/bin/sh", "sys:x:3:3:sys:/dev:/bin/sh", "nobody:x:65534:65534:nobody:/nonexistent:/bin/sh", "messagebus:x:103:107::/var/run/dbus:/bin/false", ] doAssert etcPasswd.parsePasswd == parsedEtcPasswd block LastNot: var idx : int idx = 0 doAssert scanp("foo", idx, 'f', 'o', ~'a') idx = 0 doAssert scanp("foo", idx, 'f', 'o', ~'o') == false idx = 0 doAssert scanp("foox", idx, 'f', 'o', ~'o') == false idx = 0 doAssert scanp("foox", idx, 'f', 'o', ~'a') block LastOptional: var idx = 0 doAssert scanp("foo", idx, 'f', 'o', 'o', ?'o') block Tuple: var idx = 0 doAssert scanp("foo", idx, ('f', 'o', 'o')) block NotWithOptional: var idx : int idx = 0 doAssert scanp("bc", idx, ~(?'b', 'c')) == false idx = 0 doAssert scanp("c", idx, ~(?'b', 'c')) == false idx = 0 doAssert scanp("b", idx, ~(?'b', 'c')) block NotEmpty: var idx = 0 doAssert scanp("", idx, ~()) == false block EmptyTuple: var idx = 0 doAssert scanp("ab", idx, 'a', (), 'b') block Arrow: let text = "foo;bar;baz;" var idx = 0 doAssert scanp(text, idx, +(~{';','\0'} -> (discard $_)), ';') doAssert scanp(text, idx, +(~{';','\0'} -> (discard $_)), ';') doAssert scanp(text, idx, +(~{';','\0'} -> (discard $_)), ';') doAssert scanp(text, idx, +(~{';','\0'} -> (discard $_)), ';') == false block issue15064: var nick1, msg1: string doAssert scanf(" a", "<$+> $+", nick1, msg1) doAssert nick1 == "abcd" doAssert msg1 == "a" var nick2, msg2: string doAssert(not scanf(" ", "<$+> $+", nick2, msg2)) var nick3, msg3: string doAssert scanf(" ", "<$+> $*", nick3, msg3) doAssert nick3 == "abcd" doAssert msg3 == "" block: proc twoDigits(input: string; x: var int; start: int): int = if start+1 < input.len and input[start] == '0' and input[start+1] == '0': result = 2 x = 13 else: result = 0 proc someSep(input: string; start: int; seps: set[char] = {';', ',', '-', '.'}): int = result = 0 while start+result < input.len and input[start+result] in seps: inc result proc demangle(s: string; res: var string; start: int): int = while result+start < s.len and s[result+start] in {'_', '@'}: inc result res = "" while result+start < s.len and s[result+start] > ' ' and s[result+start] != '_': res.add s[result+start] inc result while result+start < s.len and s[result+start] > ' ': inc result proc parseGDB(resp: string): seq[string] = const digits = {'0'..'9'} hexdigits = digits + {'a'..'f', 'A'..'F'} whites = {' ', '\t', '\C', '\L'} result = @[] var idx = 0 while true: var prc = "" var info = "" if scanp(resp, idx, *`whites`, '#', *`digits`, +`whites`, ?("0x", *`hexdigits`, " in "), demangle($input, prc, $index), *`whites`, '(', * ~ ')', ')', *`whites`, "at ", +(~{'\C', '\L'} -> info.add($_))): result.add prc & " " & info else: break var key, val: string var intVal: int var floatVal: float doAssert scanf("abc:: xyz 89 33.25", "$w$s::$s$w$s$i $f", key, val, intVal, floatVal) doAssert key == "abc" doAssert val == "xyz" 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 let xx2 = scanf("$1234", "$$$i", intVal) doAssert xx2 let yy = scanf(";.--Breakpoint00 [output]", "$[someSep]Breakpoint${twoDigits}$[someSep({';','.','-'})] [$+]$.", intVal, key) doAssert yy doAssert key == "output" doAssert intVal == 13 var ident = "" var idx = 0 let zz = scanp("foobar x x x xWZ", idx, +{'a'..'z'} -> add(ident, $_), *(*{ ' ', '\t'}, "x"), ~'U', "Z") doAssert zz doAssert ident == "foobar" const digits = {'0'..'9'} var year = 0 var idx2 = 0 if scanp("201655-8-9", idx2, `digits`{4, 6} -> (year = year * 10 + ord($_) - ord('0')), "-8", "-9"): doAssert year == 201655 const gdbOut = """ #0 @foo_96013_1208911747@8 (x0=...) at c:/users/anwender/projects/nim/temp.nim:11 #1 0x00417754 in tempInit000 () at c:/users/anwender/projects/nim/temp.nim:13 #2 0x0041768d in NimMainInner () at c:/users/anwender/projects/nim/lib/system.nim:2605 #3 0x004176b1 in NimMain () at c:/users/anwender/projects/nim/lib/system.nim:2613 #4 0x004176db in main (argc=1, args=0x712cc8, env=0x711ca8) at c:/users/anwender/projects/nim/lib/system.nim:2620""" const result = @["foo c:/users/anwender/projects/nim/temp.nim:11", "tempInit000 c:/users/anwender/projects/nim/temp.nim:13", "NimMainInner c:/users/anwender/projects/nim/lib/system.nim:2605", "NimMain c:/users/anwender/projects/nim/lib/system.nim:2613", "main c:/users/anwender/projects/nim/lib/system.nim:2620"] doAssert parseGDB(gdbOut) == result # bug #6487 var count = 0 proc test(): string = inc count result = ",123123" var a: int discard scanf(test(), ",$i", a) 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 block: #whenscanf testing let input = """1-3 s: abc 15-18 9: def 15-18 A: ghi 15-18 _: jkl """ proc twoDigits(input: string; x: var int; start: int): int = if start+1 < input.len and input[start] == '0' and input[start+1] == '0': result = 2 x = 13 else: result = 0 proc someSep(input: string; start: int; seps: set[char] = {';', ',', '-', '.'}): int = result = 0 while start+result < input.len and input[start+result] in seps: inc result type ScanRetType = tuple success: bool lo: int hi: int ch: char word: string var res = 0 for line in input.splitLines: let ret: ScanRetType = scanTuple(line, "$i-$i $c: $w") if ret.success: inc res doAssert res == 4 let (_, key, val, intVal, floatVal) = scanTuple("abc:: xyz 89 33.25", "$w$s::$s$w$s$i $f") doAssert key == "abc" doAssert val == "xyz" doAssert intVal == 89 doAssert floatVal == 33.25 let (_, binVal, octVal, hexVal) = scanTuple("0b0101 0o1234 0xabcd", "$b$s$o$s$h", binVal, octVal, hexVal) doAssert binVal == 0b0101 doAssert octVal == 0o1234 doAssert hexVal == 0xabcd var (xx,_) = scanTuple("$abc", "$$$i") doAssert xx == false let (xx2, _) = block: scanTuple("$1234", "$$$i") doAssert xx2 var (yy, intVal2, key2) = scanTuple(";.--Breakpoint00 [output]", "$[someSep]Breakpoint${twoDigits}$[someSep({';','.','-'})] [$+]$.", int) doAssert yy doAssert key2 == "output" doAssert intVal2 == 13