diff options
Diffstat (limited to 'tests/stdlib/tstrscans.nim')
-rw-r--r-- | tests/stdlib/tstrscans.nim | 288 |
1 files changed, 288 insertions, 0 deletions
diff --git a/tests/stdlib/tstrscans.nim b/tests/stdlib/tstrscans.nim new file mode 100644 index 000000000..ae7fd98ca --- /dev/null +++ b/tests/stdlib/tstrscans.nim @@ -0,0 +1,288 @@ +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("<abcd> a", "<$+> $+", nick1, msg1) + doAssert nick1 == "abcd" + doAssert msg1 == "a" + + var nick2, msg2: string + doAssert(not scanf("<abcd> ", "<$+> $+", nick2, msg2)) + + var nick3, msg3: string + doAssert scanf("<abcd> ", "<$+> $*", 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 |