tstrscans.nim 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. discard """
  2. output: ""
  3. """
  4. import strscans, strutils
  5. block ParsePasswd:
  6. proc parsePasswd(content: string): seq[string] =
  7. result = @[]
  8. var idx = 0
  9. while true:
  10. var entry = ""
  11. if scanp(content, idx, +(~{'\L', '\0'} -> entry.add($_)), '\L'):
  12. result.add entry
  13. else:
  14. break
  15. const etc_passwd = """root:x:0:0:root:/root:/bin/bash
  16. daemon:x:1:1:daemon:/usr/sbin:/bin/sh
  17. bin:x:2:2:bin:/bin:/bin/sh
  18. sys:x:3:3:sys:/dev:/bin/sh
  19. nobody:x:65534:65534:nobody:/nonexistent:/bin/sh
  20. messagebus:x:103:107::/var/run/dbus:/bin/false
  21. """
  22. const parsed_etc_passwd = @[
  23. "root:x:0:0:root:/root:/bin/bash",
  24. "daemon:x:1:1:daemon:/usr/sbin:/bin/sh",
  25. "bin:x:2:2:bin:/bin:/bin/sh",
  26. "sys:x:3:3:sys:/dev:/bin/sh",
  27. "nobody:x:65534:65534:nobody:/nonexistent:/bin/sh",
  28. "messagebus:x:103:107::/var/run/dbus:/bin/false",
  29. ]
  30. doAssert etc_passwd.parsePasswd == parsed_etc_passwd
  31. block LastNot:
  32. var idx : int
  33. idx = 0
  34. doAssert scanp("foo", idx, 'f', 'o', ~'a')
  35. idx = 0
  36. doAssert scanp("foo", idx, 'f', 'o', ~'o') == false
  37. idx = 0
  38. doAssert scanp("foox", idx, 'f', 'o', ~'o') == false
  39. idx = 0
  40. doAssert scanp("foox", idx, 'f', 'o', ~'a')
  41. block LastOptional:
  42. var idx = 0
  43. doAssert scanp("foo", idx, 'f', 'o', 'o', ?'o')
  44. block Tuple:
  45. var idx = 0
  46. doAssert scanp("foo", idx, ('f', 'o', 'o'))
  47. block NotWithOptional:
  48. var idx : int
  49. idx = 0
  50. doAssert scanp("bc", idx, ~(?'b', 'c')) == false
  51. idx = 0
  52. doAssert scanp("c", idx, ~(?'b', 'c')) == false
  53. idx = 0
  54. doAssert scanp("b", idx, ~(?'b', 'c'))
  55. block NotEmpty:
  56. var idx = 0
  57. doAssert scanp("", idx, ~()) == false
  58. block EmptyTuple:
  59. var idx = 0
  60. doAssert scanp("ab", idx, 'a', (), 'b')
  61. block Arrow:
  62. let text = "foo;bar;baz;"
  63. var idx = 0
  64. doAssert scanp(text, idx, +(~{';','\0'} -> (discard $_)), ';')
  65. doAssert scanp(text, idx, +(~{';','\0'} -> (discard $_)), ';')
  66. doAssert scanp(text, idx, +(~{';','\0'} -> (discard $_)), ';')
  67. doAssert scanp(text, idx, +(~{';','\0'} -> (discard $_)), ';') == false
  68. block issue15064:
  69. var nick1, msg1: string
  70. doAssert scanf("<abcd> a", "<$+> $+", nick1, msg1)
  71. doAssert nick1 == "abcd"
  72. doAssert msg1 == "a"
  73. var nick2, msg2: string
  74. doAssert(not scanf("<abcd> ", "<$+> $+", nick2, msg2))
  75. var nick3, msg3: string
  76. doAssert scanf("<abcd> ", "<$+> $*", nick3, msg3)
  77. doAssert nick3 == "abcd"
  78. doAssert msg3 == ""
  79. block:
  80. proc twoDigits(input: string; x: var int; start: int): int =
  81. if start+1 < input.len and input[start] == '0' and input[start+1] == '0':
  82. result = 2
  83. x = 13
  84. else:
  85. result = 0
  86. proc someSep(input: string; start: int; seps: set[char] = {';', ',', '-', '.'}): int =
  87. result = 0
  88. while start+result < input.len and input[start+result] in seps: inc result
  89. proc demangle(s: string; res: var string; start: int): int =
  90. while result+start < s.len and s[result+start] in {'_', '@'}: inc result
  91. res = ""
  92. while result+start < s.len and s[result+start] > ' ' and s[result+start] != '_':
  93. res.add s[result+start]
  94. inc result
  95. while result+start < s.len and s[result+start] > ' ':
  96. inc result
  97. proc parseGDB(resp: string): seq[string] =
  98. const
  99. digits = {'0'..'9'}
  100. hexdigits = digits + {'a'..'f', 'A'..'F'}
  101. whites = {' ', '\t', '\C', '\L'}
  102. result = @[]
  103. var idx = 0
  104. while true:
  105. var prc = ""
  106. var info = ""
  107. if scanp(resp, idx, *`whites`, '#', *`digits`, +`whites`, ?("0x", *`hexdigits`, " in "),
  108. demangle($input, prc, $index), *`whites`, '(', * ~ ')', ')',
  109. *`whites`, "at ", +(~{'\C', '\L'} -> info.add($_))):
  110. result.add prc & " " & info
  111. else:
  112. break
  113. var key, val: string
  114. var intval: int
  115. var floatval: float
  116. doAssert scanf("abc:: xyz 89 33.25", "$w$s::$s$w$s$i $f", key, val, intval, floatVal)
  117. doAssert key == "abc"
  118. doAssert val == "xyz"
  119. doAssert intval == 89
  120. doAssert floatVal == 33.25
  121. var binval: int
  122. var octval: int
  123. var hexval: int
  124. doAssert scanf("0b0101 0o1234 0xabcd", "$b$s$o$s$h", binval, octval, hexval)
  125. doAssert binval == 0b0101
  126. doAssert octval == 0o1234
  127. doAssert hexval == 0xabcd
  128. let xx = scanf("$abc", "$$$i", intval)
  129. doAssert xx == false
  130. let xx2 = scanf("$1234", "$$$i", intval)
  131. doAssert xx2
  132. let yy = scanf(";.--Breakpoint00 [output]",
  133. "$[someSep]Breakpoint${twoDigits}$[someSep({';','.','-'})] [$+]$.",
  134. intVal, key)
  135. doAssert yy
  136. doAssert key == "output"
  137. doAssert intVal == 13
  138. var ident = ""
  139. var idx = 0
  140. let zz = scanp("foobar x x x xWZ", idx, +{'a'..'z'} -> add(ident, $_), *(*{
  141. ' ', '\t'}, "x"), ~'U', "Z")
  142. doAssert zz
  143. doAssert ident == "foobar"
  144. const digits = {'0'..'9'}
  145. var year = 0
  146. var idx2 = 0
  147. if scanp("201655-8-9", idx2, `digits`{4, 6} -> (year = year * 10 + ord($_) -
  148. ord('0')), "-8", "-9"):
  149. doAssert year == 201655
  150. const gdbOut = """
  151. #0 @foo_96013_1208911747@8 (x0=...)
  152. at c:/users/anwender/projects/nim/temp.nim:11
  153. #1 0x00417754 in tempInit000 () at c:/users/anwender/projects/nim/temp.nim:13
  154. #2 0x0041768d in NimMainInner ()
  155. at c:/users/anwender/projects/nim/lib/system.nim:2605
  156. #3 0x004176b1 in NimMain ()
  157. at c:/users/anwender/projects/nim/lib/system.nim:2613
  158. #4 0x004176db in main (argc=1, args=0x712cc8, env=0x711ca8)
  159. at c:/users/anwender/projects/nim/lib/system.nim:2620"""
  160. const result = @["foo c:/users/anwender/projects/nim/temp.nim:11",
  161. "tempInit000 c:/users/anwender/projects/nim/temp.nim:13",
  162. "NimMainInner c:/users/anwender/projects/nim/lib/system.nim:2605",
  163. "NimMain c:/users/anwender/projects/nim/lib/system.nim:2613",
  164. "main c:/users/anwender/projects/nim/lib/system.nim:2620"]
  165. doAssert parseGDB(gdbOut) == result
  166. # bug #6487
  167. var count = 0
  168. proc test(): string =
  169. inc count
  170. result = ",123123"
  171. var a: int
  172. discard scanf(test(), ",$i", a)
  173. doAssert count == 1
  174. block:
  175. let input = """1-3 s: abc
  176. 15-18 9: def
  177. 15-18 A: ghi
  178. 15-18 _: jkl
  179. """
  180. var
  181. lo, hi: int
  182. w: string
  183. c: char
  184. res: int
  185. for line in input.splitLines:
  186. if line.scanf("$i-$i $c: $w", lo, hi, c, w):
  187. inc res
  188. doAssert res == 4
  189. block:
  190. #whenscanf testing
  191. let input = """1-3 s: abc
  192. 15-18 9: def
  193. 15-18 A: ghi
  194. 15-18 _: jkl
  195. """
  196. proc twoDigits(input: string; x: var int; start: int): int =
  197. if start+1 < input.len and input[start] == '0' and input[start+1] == '0':
  198. result = 2
  199. x = 13
  200. else:
  201. result = 0
  202. proc someSep(input: string; start: int; seps: set[char] = {';', ',', '-', '.'}): int =
  203. result = 0
  204. while start+result < input.len and input[start+result] in seps: inc result
  205. var res = 0
  206. for line in input.splitLines:
  207. let (success, lo, hi, c ,w) = scanTuple(line, "$i-$i $c: $w")
  208. if success:
  209. inc res
  210. doAssert res == 4
  211. let (_, key, val, intval, floatVal) = scanTuple("abc:: xyz 89 33.25", "$w$s::$s$w$s$i $f")
  212. doAssert key == "abc"
  213. doAssert val == "xyz"
  214. doAssert intval == 89
  215. doAssert floatVal == 33.25
  216. let (_, binVal, octVal, hexVal) = scanTuple("0b0101 0o1234 0xabcd", "$b$s$o$s$h", binval, octval, hexval)
  217. doAssert binval == 0b0101
  218. doAssert octval == 0o1234
  219. doAssert hexval == 0xabcd
  220. var (xx,_) = scanTuple("$abc", "$$$i")
  221. doAssert xx == false
  222. let (xx2, _) = block: scanTuple("$1234", "$$$i")
  223. doAssert xx2
  224. var (yy, intval2, key2) = scanTuple(";.--Breakpoint00 [output]",
  225. "$[someSep]Breakpoint${twoDigits}$[someSep({';','.','-'})] [$+]$.",
  226. int)
  227. doAssert yy
  228. doAssert key2 == "output"
  229. doAssert intVal2 == 13