summary refs log tree commit diff stats
path: root/tests/stdlib
diff options
context:
space:
mode:
Diffstat (limited to 'tests/stdlib')
-rw-r--r--tests/stdlib/nre/captures.nim59
-rw-r--r--tests/stdlib/nre/escape.nim7
-rw-r--r--tests/stdlib/nre/find.nim25
-rw-r--r--tests/stdlib/nre/init.nim36
-rw-r--r--tests/stdlib/nre/match.nim18
-rw-r--r--tests/stdlib/nre/misc.nim16
-rw-r--r--tests/stdlib/nre/optional_nonstrict.nim3
-rw-r--r--tests/stdlib/nre/replace.nim20
-rw-r--r--tests/stdlib/nre/split.nim53
-rw-r--r--tests/stdlib/talgorithm.nim2
-rw-r--r--tests/stdlib/tcritbits.nim2
-rw-r--r--tests/stdlib/tdialogs.nim17
-rw-r--r--tests/stdlib/tformat.nim12
-rw-r--r--tests/stdlib/thtmlparser2813.nim45
-rw-r--r--tests/stdlib/tio.nim14
-rw-r--r--tests/stdlib/tlists.nim12
-rw-r--r--tests/stdlib/tmarshal.nim2
-rw-r--r--tests/stdlib/tmath.nim6
-rw-r--r--tests/stdlib/tmath2.nim170
-rw-r--r--tests/stdlib/tmemfiles1.nim12
-rw-r--r--tests/stdlib/tmemfiles2.nim39
-rw-r--r--tests/stdlib/tmemlines.nim5
-rw-r--r--tests/stdlib/tmemlinesBuf.nim6
-rw-r--r--tests/stdlib/tmemslices.nim6
-rw-r--r--tests/stdlib/tmitems.nim4
-rw-r--r--tests/stdlib/tnre.nim9
-rw-r--r--tests/stdlib/tos.nim4
-rw-r--r--tests/stdlib/tosprocterminate.nim2
-rw-r--r--tests/stdlib/tparscfg.nim4
-rw-r--r--tests/stdlib/tparsopt.nim16
-rw-r--r--tests/stdlib/tpegs.nim346
-rw-r--r--tests/stdlib/tposix.nim8
-rw-r--r--tests/stdlib/tquit.nim12
-rw-r--r--tests/stdlib/tregex.nim40
-rw-r--r--tests/stdlib/treguse.nim42
-rw-r--r--tests/stdlib/treloop.nim9
-rw-r--r--tests/stdlib/trepr.nim4
-rw-r--r--tests/stdlib/trepr2.nim64
-rw-r--r--tests/stdlib/tsplit.nim2
-rw-r--r--tests/stdlib/tstreams2.nim13
-rw-r--r--tests/stdlib/tstrset.nim6
-rw-r--r--tests/stdlib/tstrtabs.nim10
-rw-r--r--tests/stdlib/tstrutil.nim48
-rw-r--r--tests/stdlib/ttime.nim12
-rw-r--r--tests/stdlib/tunittest.nim85
-rw-r--r--tests/stdlib/twalker.nim26
-rw-r--r--tests/stdlib/twchartoutf8.nim110
47 files changed, 1031 insertions, 432 deletions
diff --git a/tests/stdlib/nre/captures.nim b/tests/stdlib/nre/captures.nim
new file mode 100644
index 000000000..19c344a8d
--- /dev/null
+++ b/tests/stdlib/nre/captures.nim
@@ -0,0 +1,59 @@
+import unittest, optional_nonstrict
+include nre
+
+suite "captures":
+  test "map capture names to numbers":
+    check(getNameToNumberTable(re("(?<v1>1(?<v2>2(?<v3>3))(?'v4'4))()")) ==
+      { "v1" : 0, "v2" : 1, "v3" : 2, "v4" : 3 }.toTable())
+
+  test "capture bounds are correct":
+    let ex1 = re("([0-9])")
+    check("1 23".find(ex1).matchBounds == 0 .. 0)
+    check("1 23".find(ex1).captureBounds[0].get == 0 .. 0)
+    check("1 23".find(ex1, 1).matchBounds == 2 .. 2)
+    check("1 23".find(ex1, 3).matchBounds == 3 .. 3)
+
+    let ex2 = re("()()()()()()()()()()([0-9])")
+    check("824".find(ex2).captureBounds[0].get == 0 .. -1)
+    check("824".find(ex2).captureBounds[10].get == 0 .. 0)
+
+    let ex3 = re("([0-9]+)")
+    check("824".find(ex3).captureBounds[0].get == 0 .. 2)
+
+  test "named captures":
+    let ex1 = "foobar".find(re("(?<foo>foo)(?<bar>bar)"))
+    check(ex1.captures["foo"] == "foo")
+    check(ex1.captures["bar"] == "bar")
+
+    let ex2 = "foo".find(re("(?<foo>foo)(?<bar>bar)?"))
+    check(ex2.captures["foo"] == "foo")
+    check(ex2.captures["bar"] == nil)
+
+  test "named capture bounds":
+    let ex1 = "foo".find(re("(?<foo>foo)(?<bar>bar)?"))
+    check(ex1.captureBounds["foo"] == some(0..2))
+    check(ex1.captureBounds["bar"] == none(Slice[int]))
+
+  test "capture count":
+    let ex1 = re("(?<foo>foo)(?<bar>bar)?")
+    check(ex1.captureCount == 2)
+    check(ex1.captureNameId == {"foo" : 0, "bar" : 1}.toTable())
+
+  test "named capture table":
+    let ex1 = "foo".find(re("(?<foo>foo)(?<bar>bar)?"))
+    check(ex1.captures.toTable == {"foo" : "foo", "bar" : nil}.toTable())
+    check(ex1.captureBounds.toTable == {"foo" : some(0..2), "bar" : none(Slice[int])}.toTable())
+    check(ex1.captures.toTable("") == {"foo" : "foo", "bar" : ""}.toTable())
+
+    let ex2 = "foobar".find(re("(?<foo>foo)(?<bar>bar)?"))
+    check(ex2.captures.toTable == {"foo" : "foo", "bar" : "bar"}.toTable())
+
+  test "capture sequence":
+    let ex1 = "foo".find(re("(?<foo>foo)(?<bar>bar)?"))
+    check(ex1.captures.toSeq == @["foo", nil])
+    check(ex1.captureBounds.toSeq == @[some(0..2), none(Slice[int])])
+    check(ex1.captures.toSeq("") == @["foo", ""])
+
+    let ex2 = "foobar".find(re("(?<foo>foo)(?<bar>bar)?"))
+    check(ex2.captures.toSeq == @["foo", "bar"])
+
diff --git a/tests/stdlib/nre/escape.nim b/tests/stdlib/nre/escape.nim
new file mode 100644
index 000000000..db5e8a001
--- /dev/null
+++ b/tests/stdlib/nre/escape.nim
@@ -0,0 +1,7 @@
+import nre, unittest
+
+suite "escape strings":
+  test "escape strings":
+    check("123".escapeRe() == "123")
+    check("[]".escapeRe() == r"\[\]")
+    check("()".escapeRe() == r"\(\)")
diff --git a/tests/stdlib/nre/find.nim b/tests/stdlib/nre/find.nim
new file mode 100644
index 000000000..05bfb848a
--- /dev/null
+++ b/tests/stdlib/nre/find.nim
@@ -0,0 +1,25 @@
+import unittest, sequtils, nre, optional_nonstrict
+
+suite "find":
+  test "find text":
+    check("3213a".find(re"[a-z]").match == "a")
+    check(toSeq(findIter("1 2 3 4 5 6 7 8 ", re" ")).map(
+      proc (a: RegexMatch): string = a.match
+    ) == @[" ", " ", " ", " ", " ", " ", " ", " "])
+
+  test "find bounds":
+    check(toSeq(findIter("1 2 3 4 5 ", re" ")).map(
+      proc (a: RegexMatch): Slice[int] = a.matchBounds
+    ) == @[1..1, 3..3, 5..5, 7..7, 9..9])
+
+  test "overlapping find":
+    check("222".findAll(re"22") == @["22"])
+    check("2222".findAll(re"22") == @["22", "22"])
+
+  test "len 0 find":
+    check("".findAll(re"\ ") == newSeq[string]())
+    check("".findAll(re"") == @[""])
+    check("abc".findAll(re"") == @["", "", "", ""])
+    check("word word".findAll(re"\b") == @["", "", "", ""])
+    check("word\r\lword".findAll(re"(*ANYCRLF)(?m)$") == @["", ""])
+    check("слово слово".findAll(re"(*U)\b") == @["", "", "", ""])
diff --git a/tests/stdlib/nre/init.nim b/tests/stdlib/nre/init.nim
new file mode 100644
index 000000000..1a1470842
--- /dev/null
+++ b/tests/stdlib/nre/init.nim
@@ -0,0 +1,36 @@
+import unittest
+include nre
+
+suite "Test NRE initialization":
+  test "correct intialization":
+    check(re("[0-9]+") != nil)
+    check(re("(?i)[0-9]+") != nil)
+
+  test "options":
+    check(extractOptions("(*NEVER_UTF)") ==
+          ("", pcre.NEVER_UTF, true))
+    check(extractOptions("(*UTF8)(*ANCHORED)(*UCP)z") ==
+          ("(*UTF8)(*UCP)z", pcre.ANCHORED, true))
+    check(extractOptions("(*ANCHORED)(*UTF8)(*JAVASCRIPT_COMPAT)z") ==
+          ("(*UTF8)z", pcre.ANCHORED or pcre.JAVASCRIPT_COMPAT, true))
+
+    check(extractOptions("(*NO_STUDY)(") == ("(", 0, false))
+
+    check(extractOptions("(*LIMIT_MATCH=6)(*ANCHORED)z") ==
+          ("(*LIMIT_MATCH=6)z", pcre.ANCHORED, true))
+
+  test "incorrect options":
+    for s in ["CR", "(CR", "(*CR", "(*abc)", "(*abc)CR",
+              "(?i)",
+              "(*LIMIT_MATCH=5", "(*NO_AUTO_POSSESS=5)"]:
+      let ss = s & "(*NEVER_UTF)"
+      check(extractOptions(ss) == (ss, 0, true))
+
+  test "invalid regex":
+    expect(SyntaxError): discard re("[0-9")
+    try:
+      discard re("[0-9")
+    except SyntaxError:
+      let ex = SyntaxError(getCurrentException())
+      check(ex.pos == 4)
+      check(ex.pattern == "[0-9")
diff --git a/tests/stdlib/nre/match.nim b/tests/stdlib/nre/match.nim
new file mode 100644
index 000000000..38ee5214b
--- /dev/null
+++ b/tests/stdlib/nre/match.nim
@@ -0,0 +1,18 @@
+include nre, unittest, optional_nonstrict
+
+suite "match":
+  test "upper bound must be inclusive":
+    check("abc".match(re"abc", endpos = -1) == none(RegexMatch))
+    check("abc".match(re"abc", endpos = 1) == none(RegexMatch))
+    check("abc".match(re"abc", endpos = 2) != none(RegexMatch))
+
+  test "match examples":
+    check("abc".match(re"(\w)").captures[0] == "a")
+    check("abc".match(re"(?<letter>\w)").captures["letter"] == "a")
+    check("abc".match(re"(\w)\w").captures[-1] == "ab")
+    check("abc".match(re"(\w)").captureBounds[0].get == 0 .. 0)
+    check("abc".match(re"").captureBounds[-1].get == 0 .. -1)
+    check("abc".match(re"abc").captureBounds[-1].get == 0 .. 2)
+
+  test "match test cases":
+    check("123".match(re"").matchBounds == 0 .. -1)
diff --git a/tests/stdlib/nre/misc.nim b/tests/stdlib/nre/misc.nim
new file mode 100644
index 000000000..f4a88b639
--- /dev/null
+++ b/tests/stdlib/nre/misc.nim
@@ -0,0 +1,16 @@
+import unittest, nre, strutils, optional_nonstrict
+
+suite "Misc tests":
+  test "unicode":
+    check("".find(re"(*UTF8)").match == "")
+    check("перевірка".replace(re"(*U)\w", "") == "")
+
+  test "empty or non-empty match":
+    check("abc".findall(re"|.").join(":") == ":a::b::c:")
+    check("abc".findall(re".|").join(":") == "a:b:c:")
+
+    check("abc".replace(re"|.", "x") == "xxxxxxx")
+    check("abc".replace(re".|", "x") == "xxxx")
+
+    check("abc".split(re"|.").join(":") == ":::::")
+    check("abc".split(re".|").join(":") == ":::")
diff --git a/tests/stdlib/nre/optional_nonstrict.nim b/tests/stdlib/nre/optional_nonstrict.nim
new file mode 100644
index 000000000..d13f4fab7
--- /dev/null
+++ b/tests/stdlib/nre/optional_nonstrict.nim
@@ -0,0 +1,3 @@
+import options
+converter option2val*[T](val: Option[T]): T =
+  return val.get()
diff --git a/tests/stdlib/nre/replace.nim b/tests/stdlib/nre/replace.nim
new file mode 100644
index 000000000..516fd4328
--- /dev/null
+++ b/tests/stdlib/nre/replace.nim
@@ -0,0 +1,20 @@
+include nre
+import unittest
+
+suite "replace":
+  test "replace with 0-length strings":
+    check("".replace(re"1", proc (v: RegexMatch): string = "1") == "")
+    check(" ".replace(re"", proc (v: RegexMatch): string = "1") == "1 1")
+    check("".replace(re"", proc (v: RegexMatch): string = "1") == "1")
+
+  test "regular replace":
+    check("123".replace(re"\d", "foo") == "foofoofoo")
+    check("123".replace(re"(\d)", "$1$1") == "112233")
+    check("123".replace(re"(\d)(\d)", "$1$2") == "123")
+    check("123".replace(re"(\d)(\d)", "$#$#") == "123")
+    check("123".replace(re"(?<foo>\d)(\d)", "$foo$#$#") == "1123")
+    check("123".replace(re"(?<foo>\d)(\d)", "${foo}$#$#") == "1123")
+
+  test "replacing missing captures should throw instead of segfaulting":
+    expect ValueError: discard "ab".replace(re"(a)|(b)", "$1$2")
+    expect ValueError: discard "b".replace(re"(a)?(b)", "$1$2")
diff --git a/tests/stdlib/nre/split.nim b/tests/stdlib/nre/split.nim
new file mode 100644
index 000000000..9d57ea7d8
--- /dev/null
+++ b/tests/stdlib/nre/split.nim
@@ -0,0 +1,53 @@
+import unittest, strutils
+include nre
+
+suite "string splitting":
+  test "splitting strings":
+    check("1 2 3 4 5 6 ".split(re" ") == @["1", "2", "3", "4", "5", "6", ""])
+    check("1  2  ".split(re(" ")) == @["1", "", "2", "", ""])
+    check("1 2".split(re(" ")) == @["1", "2"])
+    check("foo".split(re("foo")) == @["", ""])
+    check("".split(re"foo") == @[""])
+    check("9".split(re"\son\s") == @["9"])
+
+  test "captured patterns":
+    check("12".split(re"(\d)") == @["", "1", "", "2", ""])
+
+  test "maxsplit":
+    check("123".split(re"", maxsplit = 2) == @["1", "23"])
+    check("123".split(re"", maxsplit = 1) == @["123"])
+    check("123".split(re"", maxsplit = -1) == @["1", "2", "3"])
+
+  test "split with 0-length match":
+    check("12345".split(re("")) == @["1", "2", "3", "4", "5"])
+    check("".split(re"") == newSeq[string]())
+    check("word word".split(re"\b") == @["word", " ", "word"])
+    check("word\r\lword".split(re"(*ANYCRLF)(?m)$") == @["word", "\r\lword"])
+    check("слово слово".split(re"(*U)(\b)") == @["", "слово", "", " ", "", "слово", ""])
+
+  test "perl split tests":
+    check("forty-two"                    .split(re"")      .join(",") == "f,o,r,t,y,-,t,w,o")
+    check("forty-two"                    .split(re"", 3)   .join(",") == "f,o,rty-two")
+    check("split this string"            .split(re" ")     .join(",") == "split,this,string")
+    check("split this string"            .split(re" ", 2)  .join(",") == "split,this string")
+    check("try$this$string"              .split(re"\$")    .join(",") == "try,this,string")
+    check("try$this$string"              .split(re"\$", 2) .join(",") == "try,this$string")
+    check("comma, separated, values"     .split(re", ")    .join("|") == "comma|separated|values")
+    check("comma, separated, values"     .split(re", ", 2) .join("|") == "comma|separated, values")
+    check("Perl6::Camelia::Test"         .split(re"::")    .join(",") == "Perl6,Camelia,Test")
+    check("Perl6::Camelia::Test"         .split(re"::", 2) .join(",") == "Perl6,Camelia::Test")
+    check("split,me,please"              .split(re",")     .join("|") == "split|me|please")
+    check("split,me,please"              .split(re",", 2)  .join("|") == "split|me,please")
+    check("Hello World    Goodbye   Mars".split(re"\s+")   .join(",") == "Hello,World,Goodbye,Mars")
+    check("Hello World    Goodbye   Mars".split(re"\s+", 3).join(",") == "Hello,World,Goodbye   Mars")
+    check("Hello test"                   .split(re"(\s+)") .join(",") == "Hello, ,test")
+    check("this will be split"           .split(re" ")     .join(",") == "this,will,be,split")
+    check("this will be split"           .split(re" ", 3)  .join(",") == "this,will,be split")
+    check("a.b"                          .split(re"\.")    .join(",") == "a,b")
+    check(""                             .split(re"")      .len       == 0)
+    check(":"                            .split(re"")      .len       == 1)
+
+  test "start position":
+    check("abc".split(re"", start = 1) == @["b", "c"])
+    check("abc".split(re"", start = 2) == @["c"])
+    check("abc".split(re"", start = 3) == newSeq[string]())
diff --git a/tests/stdlib/talgorithm.nim b/tests/stdlib/talgorithm.nim
index 3ca425fbc..f200e54c5 100644
--- a/tests/stdlib/talgorithm.nim
+++ b/tests/stdlib/talgorithm.nim
@@ -8,4 +8,4 @@ doAssert product(@[@[1,2], @[3,4], @[5,6]]) == @[@[2,4,6],@[1,4,6],@[2,3,6],@[1,
 doAssert product(@[@[1,2], @[]]) == newSeq[seq[int]](), "two elements, but one empty"
 doAssert lowerBound([1,2,4], 3, system.cmp[int]) == 2
 doAssert lowerBound([1,2,2,3], 4, system.cmp[int]) == 4
-doAssert lowerBound([1,2,3,10], 11) == 4
\ No newline at end of file
+doAssert lowerBound([1,2,3,10], 11) == 4
diff --git a/tests/stdlib/tcritbits.nim b/tests/stdlib/tcritbits.nim
index fb447b80b..8280ec881 100644
--- a/tests/stdlib/tcritbits.nim
+++ b/tests/stdlib/tcritbits.nim
@@ -22,7 +22,7 @@ when isMainModule:
 
   for w in r.items:
     echo w
-    
+
   for w in r.itemsWithPrefix("de"):
     echo w
 
diff --git a/tests/stdlib/tdialogs.nim b/tests/stdlib/tdialogs.nim
deleted file mode 100644
index f0203d319..000000000
--- a/tests/stdlib/tdialogs.nim
+++ /dev/null
@@ -1,17 +0,0 @@
-# Test the dialogs module
-
-import dialogs, gtk2
-
-gtk2.nimrod_init()
-
-var x = chooseFilesToOpen(nil)
-for a in items(x):
-  writeln(stdout, a)
-
-info(nil, "start with an info box")
-warning(nil, "now a warning ...")
-error(nil, "... and an error!")
-
-writeln(stdout, chooseFileToOpen(nil))
-writeln(stdout, chooseFileToSave(nil))
-writeln(stdout, chooseDir(nil))
diff --git a/tests/stdlib/tformat.nim b/tests/stdlib/tformat.nim
index 92c0c16f5..160ab0fd5 100644
--- a/tests/stdlib/tformat.nim
+++ b/tests/stdlib/tformat.nim
@@ -2,11 +2,11 @@ discard """
   file: "tformat.nim"
   output: "Hi Andreas! How do you feel, Rumpf?"
 """
-# Tests the new format proc (including the & and &= operators)

-

-import strutils

-

-echo("Hi $1! How do you feel, $2?\n" % ["Andreas", "Rumpf"])

-#OUT Hi Andreas! How do you feel, Rumpf?

+# Tests the new format proc (including the & and &= operators)
+
+import strutils
+
+echo("Hi $1! How do you feel, $2?\n" % ["Andreas", "Rumpf"])
+#OUT Hi Andreas! How do you feel, Rumpf?
 
 
diff --git a/tests/stdlib/thtmlparser2813.nim b/tests/stdlib/thtmlparser2813.nim
new file mode 100644
index 000000000..4b04bc3f0
--- /dev/null
+++ b/tests/stdlib/thtmlparser2813.nim
@@ -0,0 +1,45 @@
+discard """
+  output: "@[]"
+"""
+import htmlparser
+import xmltree
+from streams import newStringStream
+
+const
+  html = """
+  <html>
+    <head>
+      <title>Test</title>
+    </head>
+    <body>
+      <table>
+        <thead>
+          <tr><td>A</td></tr>
+          <tr><td>B</td></tr>
+        </thead>
+        <tbody>
+          <tr><td></td>A<td></td></tr>
+          <tr><td></td>B<td></td></tr>
+          <tr><td></td>C<td></td></tr>
+        </tbody>
+        <tfoot>
+          <tr><td>A</td></tr>
+        </tfoot>
+      </table>
+    </body>
+  </html>
+  """
+var errors: seq[string] = @[]
+
+let tree = parseHtml(newStringStream(html), "test.html", errors)
+
+echo errors # Errors: </thead> expected,...
+
+var len = tree.findAll("tr").len # len = 6
+
+var rows: seq[XmlNode] = @[]
+for n in tree.findAll("table"):
+  n.findAll("tr", rows)  # len = 2
+  break
+
+assert tree.findAll("tr").len == rows.len
diff --git a/tests/stdlib/tio.nim b/tests/stdlib/tio.nim
index 5ae119f77..ebf2d70f3 100644
--- a/tests/stdlib/tio.nim
+++ b/tests/stdlib/tio.nim
@@ -1,7 +1,7 @@
-# test the file-IO

-

-proc main() =

-  for line in lines("thello.nim"):

-    writeln(stdout, line)

-

-main()

+# test the file-IO
+
+proc main() =
+  for line in lines("thello.nim"):
+    writeLine(stdout, line)
+
+main()
diff --git a/tests/stdlib/tlists.nim b/tests/stdlib/tlists.nim
index 7d5379945..4caa05c90 100644
--- a/tests/stdlib/tlists.nim
+++ b/tests/stdlib/tlists.nim
@@ -11,14 +11,14 @@ block SinglyLinkedListTest1:
   var L: TSinglyLinkedList[int]
   for d in items(data): L.prepend(d)
   assert($L == "[6, 5, 4, 3, 2, 1]")
-  
+
   assert(4 in L)
 
 block SinglyLinkedListTest2:
   var L: TSinglyLinkedList[string]
   for d in items(data): L.prepend($d)
   assert($L == "[6, 5, 4, 3, 2, 1]")
-  
+
   assert("4" in L)
 
 
@@ -28,7 +28,7 @@ block DoublyLinkedListTest1:
   for d in items(data): L.append(d)
   L.remove(L.find(1))
   assert($L == "[6, 5, 4, 3, 2, 1, 2, 3, 4, 5, 6]")
-  
+
   assert(4 in L)
 
 block SinglyLinkedRingTest1:
@@ -39,7 +39,7 @@ block SinglyLinkedRingTest1:
 
   assert($L == "[4, 4]")
   assert(4 in L)
-  
+
 
 block DoublyLinkedRingTest1:
   var L: TDoublyLinkedRing[int]
@@ -49,7 +49,7 @@ block DoublyLinkedRingTest1:
 
   assert($L == "[4, 4]")
   assert(4 in L)
-  
+
   L.append(3)
   L.append(5)
   assert($L == "[4, 4, 3, 5]")
@@ -60,7 +60,7 @@ block DoublyLinkedRingTest1:
   L.remove(L.find(4))
   assert($L == "[]")
   assert(4 notin L)
-  
+
 
 echo "true"
 
diff --git a/tests/stdlib/tmarshal.nim b/tests/stdlib/tmarshal.nim
index a778d2f77..4c0c10360 100644
--- a/tests/stdlib/tmarshal.nim
+++ b/tests/stdlib/tmarshal.nim
@@ -25,7 +25,7 @@ type
       help: string
     else:
       discard
-      
+
   PNode = ref TNode
   TNode = object
     next, prev: PNode
diff --git a/tests/stdlib/tmath.nim b/tests/stdlib/tmath.nim
index fc9486093..1ac9c8092 100644
--- a/tests/stdlib/tmath.nim
+++ b/tests/stdlib/tmath.nim
@@ -23,13 +23,13 @@ suite "random int":
       rand = random(100..1000)
       check rand < 1000
       check rand >= 100
-  test "randomize() again gives new numbers":      
+  test "randomize() again gives new numbers":
     randomize()
     var rand1 = random(1000000)
     randomize()
     var rand2 = random(1000000)
     check rand1 != rand2
-    
+
 
 suite "random float":
   test "there might be some randomness":
@@ -52,7 +52,7 @@ suite "random float":
       rand = random(100.0..1000.0)
       check rand < 1000.0
       check rand >= 100.0
-  test "randomize() again gives new numbers":      
+  test "randomize() again gives new numbers":
     randomize()
     var rand1:float = random(1000000.0)
     randomize()
diff --git a/tests/stdlib/tmath2.nim b/tests/stdlib/tmath2.nim
index 88d96c80a..84a49efa9 100644
--- a/tests/stdlib/tmath2.nim
+++ b/tests/stdlib/tmath2.nim
@@ -1,85 +1,85 @@
-# tests for the interpreter

-

-proc loops(a: var int) =

-  discard

-  #var

-  #  b: int

-  #b = glob

-  #while b != 0:

-  #  b = b + 1

-  #a = b

-

-proc mymax(a, b: int): int =

-  #loops(result)

-  result = a

-  if b > a: result = b

-

-proc test(a, b: int) =

-  var

-    x, y: int

-  x = 0

-  y = 7

-  if x == a + b * 3 - 7 or

-      x == 8 or

-      x == y and y > -56 and y < 699:

-    y = 0

-  elif y == 78 and x == 0:

-    y = 1

-  elif y == 0 and x == 0:

-    y = 2

-  else:

-    y = 3

-

-type

-  TTokType = enum

-    tkNil, tkType, tkConst, tkVar, tkSymbol, tkIf,

-    tkWhile, tkFor, tkLoop, tkCase, tkLabel, tkGoto

-

-proc testCase(t: TTokType): int =

-  case t

-  of tkNil, tkType, tkConst: result = 0

-  of tkVar: result = 1

-  of tkSymbol: result = 2

-  of tkIf..tkFor: result = 3

-  of tkLoop: result = 56

-  else: result = -1

-  test(0, 9) # test the call

-

-proc TestLoops() =

-  var

-    i, j: int

-

-  while i >= 0:

-    if i mod 3 == 0:

-      break

-    i = i + 1

-    while j == 13:

-      j = 13

-      break

-    break

-

-  while true:

-    break

-

-

-var

-  glob: int

-  a: array [0..5, int]

-

-proc main() =

-  #glob = 0

-  #loops( glob )

-  var

-    res: int

-    s: string

-  #write(stdout, mymax(23, 45))

-  write(stdout, "Hallo! Wie heisst du? ")

-  s = readLine(stdin)

-  # test the case statement

-  case s

-  of "Andreas": write(stdout, "Du bist mein Meister!\n")

-  of "Rumpf": write(stdout, "Du bist in der Familie meines Meisters!\n")

-  else: write(stdout, "ich kenne dich nicht!\n")

-  write(stdout, "Du heisst " & s & "\n")

-

-main()

+# tests for the interpreter
+
+proc loops(a: var int) =
+  discard
+  #var
+  #  b: int
+  #b = glob
+  #while b != 0:
+  #  b = b + 1
+  #a = b
+
+proc mymax(a, b: int): int =
+  #loops(result)
+  result = a
+  if b > a: result = b
+
+proc test(a, b: int) =
+  var
+    x, y: int
+  x = 0
+  y = 7
+  if x == a + b * 3 - 7 or
+      x == 8 or
+      x == y and y > -56 and y < 699:
+    y = 0
+  elif y == 78 and x == 0:
+    y = 1
+  elif y == 0 and x == 0:
+    y = 2
+  else:
+    y = 3
+
+type
+  TTokType = enum
+    tkNil, tkType, tkConst, tkVar, tkSymbol, tkIf,
+    tkWhile, tkFor, tkLoop, tkCase, tkLabel, tkGoto
+
+proc testCase(t: TTokType): int =
+  case t
+  of tkNil, tkType, tkConst: result = 0
+  of tkVar: result = 1
+  of tkSymbol: result = 2
+  of tkIf..tkFor: result = 3
+  of tkLoop: result = 56
+  else: result = -1
+  test(0, 9) # test the call
+
+proc TestLoops() =
+  var
+    i, j: int
+
+  while i >= 0:
+    if i mod 3 == 0:
+      break
+    i = i + 1
+    while j == 13:
+      j = 13
+      break
+    break
+
+  while true:
+    break
+
+
+var
+  glob: int
+  a: array [0..5, int]
+
+proc main() =
+  #glob = 0
+  #loops( glob )
+  var
+    res: int
+    s: string
+  #write(stdout, mymax(23, 45))
+  write(stdout, "Hallo! Wie heisst du? ")
+  s = readLine(stdin)
+  # test the case statement
+  case s
+  of "Andreas": write(stdout, "Du bist mein Meister!\n")
+  of "Rumpf": write(stdout, "Du bist in der Familie meines Meisters!\n")
+  else: write(stdout, "ich kenne dich nicht!\n")
+  write(stdout, "Du heisst " & s & "\n")
+
+main()
diff --git a/tests/stdlib/tmemfiles1.nim b/tests/stdlib/tmemfiles1.nim
new file mode 100644
index 000000000..8b66dfcc1
--- /dev/null
+++ b/tests/stdlib/tmemfiles1.nim
@@ -0,0 +1,12 @@
+discard """
+  file: "tmemfiles1.nim"
+"""
+import memfiles, os
+var
+  mm: MemFile
+  fn = "test.mmap"
+# Create a new file
+mm = memfiles.open(fn, mode = fmReadWrite, newFileSize = 20)
+mm.close()
+mm.close()
+if fileExists(fn): removeFile(fn)
diff --git a/tests/stdlib/tmemfiles2.nim b/tests/stdlib/tmemfiles2.nim
new file mode 100644
index 000000000..026443e93
--- /dev/null
+++ b/tests/stdlib/tmemfiles2.nim
@@ -0,0 +1,39 @@
+discard """
+  file: "tmemfiles2.nim"
+  disabled: true
+  output: '''Full read size: 20
+Half read size: 10 Data: Hello'''
+"""
+# doesn't work on windows. fmReadWrite doesn't create a file.
+import memfiles, os
+var
+  mm, mm_full, mm_half: MemFile
+  fn = "test.mmap"
+  p: pointer
+
+if fileExists(fn): removeFile(fn)
+
+# Create a new file, data all zeros
+mm = memfiles.open(fn, mode = fmReadWrite, newFileSize = 20)
+mm.close()
+
+# read, change
+mm_full = memfiles.open(fn, mode = fmWrite, mappedSize = -1)
+echo "Full read size: ",mm_full.size
+p = mm_full.mapMem(fmReadWrite, 20, 0)
+var p2 = cast[cstring](p)
+p2[0] = 'H'
+p2[1] = 'e'
+p2[2] = 'l'
+p2[3] = 'l'
+p2[4] = 'o'
+p2[5] = '\0'
+mm_full.unmapMem(p, 20)
+mm_full.close()
+
+# read half, and verify data change
+mm_half = memfiles.open(fn, mode = fmRead, mappedSize = 10)
+echo "Half read size: ",mm_half.size, " Data: ", cast[cstring](mm_half.mem)
+mm_half.close()
+
+if fileExists(fn): removeFile(fn)
diff --git a/tests/stdlib/tmemlines.nim b/tests/stdlib/tmemlines.nim
new file mode 100644
index 000000000..19821ea26
--- /dev/null
+++ b/tests/stdlib/tmemlines.nim
@@ -0,0 +1,5 @@
+import memfiles
+var inp = memfiles.open("readme.txt")
+for line in lines(inp):
+  echo("#" & line & "#")
+close(inp)
diff --git a/tests/stdlib/tmemlinesBuf.nim b/tests/stdlib/tmemlinesBuf.nim
new file mode 100644
index 000000000..21edc2322
--- /dev/null
+++ b/tests/stdlib/tmemlinesBuf.nim
@@ -0,0 +1,6 @@
+import memfiles
+var inp = memfiles.open("readme.txt")
+var buffer: TaintedString = ""
+for line in lines(inp, buffer):
+  echo("#" & line & "#")
+close(inp)
diff --git a/tests/stdlib/tmemslices.nim b/tests/stdlib/tmemslices.nim
new file mode 100644
index 000000000..951807cc4
--- /dev/null
+++ b/tests/stdlib/tmemslices.nim
@@ -0,0 +1,6 @@
+import memfiles
+var inp = memfiles.open("readme.txt")
+for mem in memSlices(inp):
+  if mem.size > 3:
+    echo("#" & $mem & "#")
+close(inp)
diff --git a/tests/stdlib/tmitems.nim b/tests/stdlib/tmitems.nim
index f2307aeb3..27ff344e5 100644
--- a/tests/stdlib/tmitems.nim
+++ b/tests/stdlib/tmitems.nim
@@ -11,8 +11,8 @@ fpqeew
 [11, 12, 13]
 [11, 12, 13]
 [11, 12, 13]
-{"key1": 11, "key2": 12, "key3": 13}
-[11, 12, 13]
+{"key1":11,"key2":12,"key3":13}
+[11,12,13]
 <Students>
   <Student Name="Aprilfoo" />
   <Student Name="bar" />
diff --git a/tests/stdlib/tnre.nim b/tests/stdlib/tnre.nim
new file mode 100644
index 000000000..85792b81e
--- /dev/null
+++ b/tests/stdlib/tnre.nim
@@ -0,0 +1,9 @@
+import nre
+import nre.init
+import nre.captures
+import nre.find
+import nre.split
+import nre.match
+import nre.replace
+import nre.escape
+import nre.misc
diff --git a/tests/stdlib/tos.nim b/tests/stdlib/tos.nim
index ebe577b00..cae388792 100644
--- a/tests/stdlib/tos.nim
+++ b/tests/stdlib/tos.nim
@@ -2,9 +2,9 @@
 
 import os
 
-proc walkDirTree(root: string) = 
+proc walkDirTree(root: string) =
   for k, f in walkDir(root):
-    case k 
+    case k
     of pcFile, pcLinkToFile: echo(f)
     of pcDir: walkDirTree(f)
     of pcLinkToDir: discard
diff --git a/tests/stdlib/tosprocterminate.nim b/tests/stdlib/tosprocterminate.nim
index fd044414c..7fc6c5d85 100644
--- a/tests/stdlib/tosprocterminate.nim
+++ b/tests/stdlib/tosprocterminate.nim
@@ -14,7 +14,7 @@ var TimeToWait = 5000
 while process.running() and TimeToWait > 0:
   sleep(100)
   TimeToWait = TimeToWait - 100
-  
+
 if process.running():
   echo("FAILED")
 else:
diff --git a/tests/stdlib/tparscfg.nim b/tests/stdlib/tparscfg.nim
index 618ecadd6..4c11ccf61 100644
--- a/tests/stdlib/tparscfg.nim
+++ b/tests/stdlib/tparscfg.nim
@@ -1,7 +1,7 @@
 
 import
   os, parsecfg, strutils, streams
-  
+
 var f = newFileStream(paramStr(1), fmRead)
 if f != nil:
   var p: TCfgParser
@@ -9,7 +9,7 @@ if f != nil:
   while true:
     var e = next(p)
     case e.kind
-    of cfgEof: 
+    of cfgEof:
       echo("EOF!")
       break
     of cfgSectionStart:   ## a ``[section]`` has been parsed
diff --git a/tests/stdlib/tparsopt.nim b/tests/stdlib/tparsopt.nim
index 2b2da7e51..848fba2da 100644
--- a/tests/stdlib/tparsopt.nim
+++ b/tests/stdlib/tparsopt.nim
@@ -3,24 +3,24 @@
 import
   parseopt
 
-proc writeHelp() = 
-  writeln(stdout, "Usage: tparsopt [options] filename [options]")
+proc writeHelp() =
+  writeLine(stdout, "Usage: tparsopt [options] filename [options]")
+
+proc writeVersion() =
+  writeLine(stdout, "Version: 1.0.0")
 
-proc writeVersion() = 
-  writeln(stdout, "Version: 1.0.0")
-  
 var
   filename = ""
 for kind, key, val in getopt():
   case kind
-  of cmdArgument: 
+  of cmdArgument:
     filename = key
   of cmdLongOption, cmdShortOption:
     case key
     of "help", "h": writeHelp()
     of "version", "v": writeVersion()
-    else: 
-      writeln(stdout, "Unknown command line option: ", key, ": ", val)
+    else:
+      writeLine(stdout, "Unknown command line option: ", key, ": ", val)
   of cmdEnd: assert(false) # cannot happen
 if filename == "":
   # no filename has been given, so we show the help:
diff --git a/tests/stdlib/tpegs.nim b/tests/stdlib/tpegs.nim
index cceea1693..3fe964d82 100644
--- a/tests/stdlib/tpegs.nim
+++ b/tests/stdlib/tpegs.nim
@@ -24,7 +24,7 @@ when useUnicode:
 const
   InlineThreshold = 5  ## number of leaves; -1 to disable inlining
   MaxSubpatterns* = 10 ## defines the maximum number of subpatterns that
-                       ## can be captured. More subpatterns cannot be captured! 
+                       ## can be captured. More subpatterns cannot be captured!
 
 type
   TPegKind = enum
@@ -80,12 +80,12 @@ type
     of pkBackRef..pkBackRefIgnoreStyle: index: range[0..MaxSubpatterns]
     else: sons: seq[TNode]
   PNonTerminal* = ref TNonTerminal
-  
+
   TPeg* = TNode ## type that represents a PEG
 
 proc term*(t: string): TPeg {.rtl, extern: "npegs$1Str".} =
   ## constructs a PEG from a terminal string
-  if t.len != 1:  
+  if t.len != 1:
     result.kind = pkTerminal
     result.term = t
   else:
@@ -109,7 +109,7 @@ proc term*(t: char): TPeg {.rtl, extern: "npegs$1Char".} =
   assert t != '\0'
   result.kind = pkChar
   result.ch = t
-  
+
 proc charSet*(s: set[char]): TPeg {.rtl, extern: "npegs$1".} =
   ## constructs a PEG from a character set `s`
   assert '\0' notin s
@@ -120,31 +120,31 @@ proc charSet*(s: set[char]): TPeg {.rtl, extern: "npegs$1".} =
 proc len(a: TPeg): int {.inline.} = return a.sons.len
 proc add(d: var TPeg, s: TPeg) {.inline.} = add(d.sons, s)
 
-proc copyPeg(a: TPeg): TPeg = 
+proc copyPeg(a: TPeg): TPeg =
   result.kind = a.kind
   case a.kind
   of pkEmpty..pkWhitespace: discard
-  of pkTerminal, pkTerminalIgnoreCase, pkTerminalIgnoreStyle: 
+  of pkTerminal, pkTerminalIgnoreCase, pkTerminalIgnoreStyle:
     result.term = a.term
-  of pkChar, pkGreedyRepChar: 
+  of pkChar, pkGreedyRepChar:
     result.ch = a.ch
-  of pkCharChoice, pkGreedyRepSet: 
+  of pkCharChoice, pkGreedyRepSet:
     new(result.charChoice)
     result.charChoice[] = a.charChoice[]
   of pkNonTerminal: result.nt = a.nt
-  of pkBackRef..pkBackRefIgnoreStyle: 
+  of pkBackRef..pkBackRefIgnoreStyle:
     result.index = a.index
-  else: 
+  else:
     result.sons = a.sons
 
 proc addChoice(dest: var TPeg, elem: TPeg) =
   var L = dest.len-1
-  if L >= 0 and dest.sons[L].kind == pkCharChoice: 
+  if L >= 0 and dest.sons[L].kind == pkCharChoice:
     # caution! Do not introduce false aliasing here!
     case elem.kind
     of pkCharChoice:
       dest.sons[L] = charSet(dest.sons[L].charChoice[] + elem.charChoice[])
-    of pkChar: 
+    of pkChar:
       dest.sons[L] = charSet(dest.sons[L].charChoice[] + {elem.ch})
     else: add(dest, elem)
   else: add(dest, elem)
@@ -168,12 +168,12 @@ proc `/`*(a: varargs[TPeg]): TPeg {.
 
 proc addSequence(dest: var TPeg, elem: TPeg) =
   var L = dest.len-1
-  if L >= 0 and dest.sons[L].kind == pkTerminal: 
+  if L >= 0 and dest.sons[L].kind == pkTerminal:
     # caution! Do not introduce false aliasing here!
     case elem.kind
-    of pkTerminal: 
+    of pkTerminal:
       dest.sons[L] = term(dest.sons[L].term & elem.term)
-    of pkChar: 
+    of pkChar:
       dest.sons[L] = term(dest.sons[L].term & elem.ch)
     else: add(dest, elem)
   else: add(dest, elem)
@@ -182,7 +182,7 @@ proc sequence*(a: varargs[TPeg]): TPeg {.
   rtl, extern: "npegs$1".} =
   ## constructs a sequence with all the PEGs from `a`
   multipleOp(pkSequence, addSequence)
- 
+
 proc `?`*(a: TPeg): TPeg {.rtl, extern: "npegsOptional".} =
   ## constructs an optional for the PEG `a`
   if a.kind in {pkOption, pkGreedyRep, pkGreedyAny, pkGreedyRepChar,
@@ -217,12 +217,12 @@ proc `!*`*(a: TPeg): TPeg {.rtl, extern: "npegsSearch".} =
   result.kind = pkSearch
   result.sons = @[a]
 
-proc `!*\`*(a: TPeg): TPeg {.rtl, 
+proc `!*\`*(a: TPeg): TPeg {.rtl,
                              extern: "npgegsCapturedSearch".} =
   ## constructs a "captured search" for the PEG `a`
   result.kind = pkCapturedSearch
   result.sons = @[a]
-  
+
 when false:
   proc contains(a: TPeg, k: TPegKind): bool =
     if a.kind == k: return true
@@ -238,7 +238,7 @@ when false:
 proc `+`*(a: TPeg): TPeg {.rtl, extern: "npegsGreedyPosRep".} =
   ## constructs a "greedy positive repetition" with the PEG `a`
   return sequence(a, *a)
-  
+
 proc `&`*(a: TPeg): TPeg {.rtl, extern: "npegsAndPredicate".} =
   ## constructs an "and predicate" with the PEG `a`
   result.kind = pkAndPredicate
@@ -261,33 +261,33 @@ proc newLine*: TPeg {.inline.} =
   ## constructs the PEG `newline`:idx: (``\n``)
   result.kind = pkNewline
 
-proc UnicodeLetter*: TPeg {.inline.} = 
+proc UnicodeLetter*: TPeg {.inline.} =
   ## constructs the PEG ``\letter`` which matches any Unicode letter.
   result.kind = pkLetter
-  
-proc UnicodeLower*: TPeg {.inline.} = 
+
+proc UnicodeLower*: TPeg {.inline.} =
   ## constructs the PEG ``\lower`` which matches any Unicode lowercase letter.
-  result.kind = pkLower 
+  result.kind = pkLower
 
-proc UnicodeUpper*: TPeg {.inline.} = 
+proc UnicodeUpper*: TPeg {.inline.} =
   ## constructs the PEG ``\upper`` which matches any Unicode lowercase letter.
-  result.kind = pkUpper 
-  
-proc UnicodeTitle*: TPeg {.inline.} = 
+  result.kind = pkUpper
+
+proc UnicodeTitle*: TPeg {.inline.} =
   ## constructs the PEG ``\title`` which matches any Unicode title letter.
   result.kind = pkTitle
 
-proc UnicodeWhitespace*: TPeg {.inline.} = 
-  ## constructs the PEG ``\white`` which matches any Unicode 
+proc UnicodeWhitespace*: TPeg {.inline.} =
+  ## constructs the PEG ``\white`` which matches any Unicode
   ## whitespace character.
   result.kind = pkWhitespace
 
-proc startAnchor*: TPeg {.inline.} = 
-  ## constructs the PEG ``^`` which matches the start of the input.  
+proc startAnchor*: TPeg {.inline.} =
+  ## constructs the PEG ``^`` which matches the start of the input.
   result.kind = pkStartAnchor
 
-proc endAnchor*: TPeg {.inline.} = 
-  ## constructs the PEG ``$`` which matches the end of the input.  
+proc endAnchor*: TPeg {.inline.} =
+  ## constructs the PEG ``$`` which matches the end of the input.
   result = !any()
 
 proc capture*(a: TPeg): TPeg {.rtl, extern: "npegsCapture".} =
@@ -296,21 +296,21 @@ proc capture*(a: TPeg): TPeg {.rtl, extern: "npegsCapture".} =
   result.sons = @[a]
 
 proc backref*(index: range[1..MaxSubPatterns]): TPeg {.
-  rtl, extern: "npegs$1".} = 
+  rtl, extern: "npegs$1".} =
   ## constructs a back reference of the given `index`. `index` starts counting
   ## from 1.
   result.kind = pkBackRef
   result.index = index-1
 
 proc backrefIgnoreCase*(index: range[1..MaxSubPatterns]): TPeg {.
-  rtl, extern: "npegs$1".} = 
+  rtl, extern: "npegs$1".} =
   ## constructs a back reference of the given `index`. `index` starts counting
   ## from 1. Ignores case for matching.
   result.kind = pkBackRefIgnoreCase
   result.index = index-1
 
 proc backrefIgnoreStyle*(index: range[1..MaxSubPatterns]): TPeg {.
-  rtl, extern: "npegs$1".}= 
+  rtl, extern: "npegs$1".}=
   ## constructs a back reference of the given `index`. `index` starts counting
   ## from 1. Ignores style for matching.
   result.kind = pkBackRefIgnoreStyle
@@ -320,7 +320,7 @@ proc spaceCost(n: TPeg): int =
   case n.kind
   of pkEmpty: discard
   of pkTerminal, pkTerminalIgnoreCase, pkTerminalIgnoreStyle, pkChar,
-     pkGreedyRepChar, pkCharChoice, pkGreedyRepSet, 
+     pkGreedyRepChar, pkCharChoice, pkGreedyRepSet,
      pkAny..pkWhitespace, pkGreedyAny:
     result = 1
   of pkNonTerminal:
@@ -332,7 +332,7 @@ proc spaceCost(n: TPeg): int =
       if result >= InlineThreshold: break
 
 proc nonterminal*(n: PNonTerminal): TPeg {.
-  rtl, extern: "npegs$1".} = 
+  rtl, extern: "npegs$1".} =
   ## constructs a PEG that consists of the nonterminal symbol
   assert n != nil
   if ntDeclared in n.flags and spaceCost(n.rule) < InlineThreshold:
@@ -353,7 +353,7 @@ proc newNonTerminal*(name: string, line, column: int): PNonTerminal {.
 template letters*: expr =
   ## expands to ``charset({'A'..'Z', 'a'..'z'})``
   charset({'A'..'Z', 'a'..'z'})
-  
+
 template digits*: expr =
   ## expands to ``charset({'0'..'9'})``
   charset({'0'..'9'})
@@ -361,11 +361,11 @@ template digits*: expr =
 template whitespace*: expr =
   ## expands to ``charset({' ', '\9'..'\13'})``
   charset({' ', '\9'..'\13'})
-  
+
 template identChars*: expr =
   ## expands to ``charset({'a'..'z', 'A'..'Z', '0'..'9', '_'})``
   charset({'a'..'z', 'A'..'Z', '0'..'9', '_'})
-  
+
 template identStartChars*: expr =
   ## expands to ``charset({'A'..'Z', 'a'..'z', '_'})``
   charset({'a'..'z', 'A'..'Z', '_'})
@@ -374,14 +374,14 @@ template ident*: expr =
   ## same as ``[a-zA-Z_][a-zA-z_0-9]*``; standard identifier
   sequence(charset({'a'..'z', 'A'..'Z', '_'}),
            *charset({'a'..'z', 'A'..'Z', '0'..'9', '_'}))
-  
+
 template natural*: expr =
   ## same as ``\d+``
   +digits
 
 # ------------------------- debugging -----------------------------------------
 
-proc esc(c: char, reserved = {'\0'..'\255'}): string = 
+proc esc(c: char, reserved = {'\0'..'\255'}): string =
   case c
   of '\b': result = "\\b"
   of '\t': result = "\\t"
@@ -396,38 +396,38 @@ proc esc(c: char, reserved = {'\0'..'\255'}): string =
   elif c < ' ' or c >= '\128': result = '\\' & $ord(c)
   elif c in reserved: result = '\\' & c
   else: result = $c
-  
+
 proc singleQuoteEsc(c: char): string = return "'" & esc(c, {'\''}) & "'"
 
-proc singleQuoteEsc(str: string): string = 
+proc singleQuoteEsc(str: string): string =
   result = "'"
   for c in items(str): add result, esc(c, {'\''})
   add result, '\''
-  
-proc charSetEscAux(cc: set[char]): string = 
+
+proc charSetEscAux(cc: set[char]): string =
   const reserved = {'^', '-', ']'}
   result = ""
   var c1 = 0
-  while c1 <= 0xff: 
-    if chr(c1) in cc: 
+  while c1 <= 0xff:
+    if chr(c1) in cc:
       var c2 = c1
       while c2 < 0xff and chr(succ(c2)) in cc: inc(c2)
-      if c1 == c2: 
+      if c1 == c2:
         add result, esc(chr(c1), reserved)
-      elif c2 == succ(c1): 
+      elif c2 == succ(c1):
         add result, esc(chr(c1), reserved) & esc(chr(c2), reserved)
-      else: 
+      else:
         add result, esc(chr(c1), reserved) & '-' & esc(chr(c2), reserved)
       c1 = c2
     inc(c1)
-  
+
 proc charSetEsc(cc: set[char]): string =
-  if card(cc) >= 128+64: 
+  if card(cc) >= 128+64:
     result = "[^" & charSetEscAux({'\1'..'\xFF'} - cc) & ']'
-  else: 
+  else:
     result = '[' & charSetEscAux(cc) & ']'
-  
-proc toStrAux(r: TPeg, res: var string) = 
+
+proc toStrAux(r: TPeg, res: var string) =
   case r.kind
   of pkEmpty: add(res, "()")
   of pkAny: add(res, '.')
@@ -491,25 +491,25 @@ proc toStrAux(r: TPeg, res: var string) =
     toStrAux(r.sons[0], res)
   of pkCapture:
     add(res, '{')
-    toStrAux(r.sons[0], res)    
+    toStrAux(r.sons[0], res)
     add(res, '}')
-  of pkBackRef: 
+  of pkBackRef:
     add(res, '$')
     add(res, $r.index)
-  of pkBackRefIgnoreCase: 
+  of pkBackRefIgnoreCase:
     add(res, "i$")
     add(res, $r.index)
-  of pkBackRefIgnoreStyle: 
+  of pkBackRefIgnoreStyle:
     add(res, "y$")
     add(res, $r.index)
   of pkRule:
-    toStrAux(r.sons[0], res)    
+    toStrAux(r.sons[0], res)
     add(res, " <- ")
     toStrAux(r.sons[1], res)
   of pkList:
     for i in 0 .. high(r.sons):
       toStrAux(r.sons[i], res)
-      add(res, "\n")  
+      add(res, "\n")
   of pkStartAnchor:
     add(res, '^')
 
@@ -526,8 +526,8 @@ type
     ml: int
     origStart: int
 
-proc bounds*(c: TCaptures, 
-             i: range[0..MaxSubpatterns-1]): tuple[first, last: int] = 
+proc bounds*(c: TCaptures,
+             i: range[0..MaxSubpatterns-1]): tuple[first, last: int] =
   ## returns the bounds ``[first..last]`` of the `i`'th capture.
   result = c.matches[i]
 
@@ -547,7 +547,7 @@ when not useUnicode:
 
 proc rawMatch*(s: string, p: TPeg, start: int, c: var TCaptures): int {.
                rtl, extern: "npegs$1".} =
-  ## low-level matching proc that implements the PEG interpreter. Use this 
+  ## low-level matching proc that implements the PEG interpreter. Use this
   ## for maximum efficiency (every other PEG operation ends up calling this
   ## proc).
   ## Returns -1 if it does not match, else the length of the match
@@ -561,7 +561,7 @@ proc rawMatch*(s: string, p: TPeg, start: int, c: var TCaptures): int {.
       result = runeLenAt(s, start)
     else:
       result = -1
-  of pkLetter: 
+  of pkLetter:
     if s[start] != '\0':
       var a: Rune
       result = start
@@ -570,7 +570,7 @@ proc rawMatch*(s: string, p: TPeg, start: int, c: var TCaptures): int {.
       else: result = -1
     else:
       result = -1
-  of pkLower: 
+  of pkLower:
     if s[start] != '\0':
       var a: Rune
       result = start
@@ -579,7 +579,7 @@ proc rawMatch*(s: string, p: TPeg, start: int, c: var TCaptures): int {.
       else: result = -1
     else:
       result = -1
-  of pkUpper: 
+  of pkUpper:
     if s[start] != '\0':
       var a: Rune
       result = start
@@ -588,16 +588,16 @@ proc rawMatch*(s: string, p: TPeg, start: int, c: var TCaptures): int {.
       else: result = -1
     else:
       result = -1
-  of pkTitle: 
+  of pkTitle:
     if s[start] != '\0':
       var a: Rune
       result = start
       fastRuneAt(s, result, a)
-      if isTitle(a): dec(result, start) 
+      if isTitle(a): dec(result, start)
       else: result = -1
     else:
       result = -1
-  of pkWhitespace: 
+  of pkWhitespace:
     if s[start] != '\0':
       var a: Rune
       result = start
@@ -661,7 +661,7 @@ proc rawMatch*(s: string, p: TPeg, start: int, c: var TCaptures): int {.
     when false: echo "leave: ", p.nt.name
     if result < 0: c.ml = oldMl
   of pkSequence:
-    var oldMl = c.ml  
+    var oldMl = c.ml
     result = 0
     assert(not isNil(p.sons))
     for i in 0..high(p.sons):
@@ -744,11 +744,11 @@ proc rawMatch*(s: string, p: TPeg, start: int, c: var TCaptures): int {.
       #else: silently ignore the capture
     else:
       c.ml = idx
-  of pkBackRef..pkBackRefIgnoreStyle: 
+  of pkBackRef..pkBackRefIgnoreStyle:
     if p.index >= c.ml: return -1
     var (a, b) = c.matches[p.index]
     var n: TPeg
-    n.kind = succ(pkTerminal, ord(p.kind)-ord(pkBackRef)) 
+    n.kind = succ(pkTerminal, ord(p.kind)-ord(pkBackRef))
     n.term = s.substr(a, b)
     result = rawMatch(s, n, start, c)
   of pkStartAnchor:
@@ -769,7 +769,7 @@ proc match*(s: string, pattern: TPeg, matches: var openarray[string],
     for i in 0..c.ml-1:
       matches[i] = substr(s, c.matches[i][0], c.matches[i][1])
 
-proc match*(s: string, pattern: TPeg, 
+proc match*(s: string, pattern: TPeg,
             start = 0): bool {.rtl, extern: "npegs$1".} =
   ## returns ``true`` if ``s`` matches the ``pattern`` beginning from ``start``.
   var c: TCaptures
@@ -789,7 +789,7 @@ proc matchLen*(s: string, pattern: TPeg, matches: var openarray[string],
     for i in 0..c.ml-1:
       matches[i] = substr(s, c.matches[i][0], c.matches[i][1])
 
-proc matchLen*(s: string, pattern: TPeg, 
+proc matchLen*(s: string, pattern: TPeg,
                start = 0): int {.rtl, extern: "npegs$1".} =
   ## the same as ``match``, but it returns the length of the match,
   ## if there is no match, -1 is returned. Note that a match length
@@ -808,11 +808,11 @@ proc find*(s: string, pattern: TPeg, matches: var openarray[string],
     if matchLen(s, pattern, matches, i) >= 0: return i
   return -1
   # could also use the pattern here: (!P .)* P
-  
+
 proc findBounds*(s: string, pattern: TPeg, matches: var openarray[string],
                  start = 0): tuple[first, last: int] {.
                  rtl, extern: "npegs$1Capture".} =
-  ## returns the starting position and end position of ``pattern`` in ``s`` 
+  ## returns the starting position and end position of ``pattern`` in ``s``
   ## and the captured
   ## substrings in the array ``matches``. If it does not match, nothing
   ## is written into ``matches`` and (-1,0) is returned.
@@ -820,40 +820,40 @@ proc findBounds*(s: string, pattern: TPeg, matches: var openarray[string],
     var L = matchLen(s, pattern, matches, i)
     if L >= 0: return (i, i+L-1)
   return (-1, 0)
-  
-proc find*(s: string, pattern: TPeg, 
+
+proc find*(s: string, pattern: TPeg,
            start = 0): int {.rtl, extern: "npegs$1".} =
   ## returns the starting position of ``pattern`` in ``s``. If it does not
   ## match, -1 is returned.
   for i in start .. s.len-1:
     if matchLen(s, pattern, i) >= 0: return i
   return -1
-  
-iterator findAll*(s: string, pattern: TPeg, start = 0): string = 
+
+iterator findAll*(s: string, pattern: TPeg, start = 0): string =
   ## yields all matching captures of pattern in `s`.
   var matches: array[0..MaxSubpatterns-1, string]
   var i = start
   while i < s.len:
     var L = matchLen(s, pattern, matches, i)
     if L < 0: break
-    for k in 0..MaxSubPatterns-1: 
+    for k in 0..MaxSubPatterns-1:
       if isNil(matches[k]): break
       yield matches[k]
     inc(i, L)
-    
+
 proc findAll*(s: string, pattern: TPeg, start = 0): seq[string] {.
-  rtl, extern: "npegs$1".} = 
+  rtl, extern: "npegs$1".} =
   ## returns all matching captures of pattern in `s`.
   ## If it does not match, @[] is returned.
   accumulateResult(findAll(s, pattern, start))
-  
+
 template `=~`*(s: string, pattern: TPeg): expr =
-  ## This calls ``match`` with an implicit declared ``matches`` array that 
-  ## can be used in the scope of the ``=~`` call: 
-  ## 
+  ## This calls ``match`` with an implicit declared ``matches`` array that
+  ## can be used in the scope of the ``=~`` call:
+  ##
   ## .. code-block:: nim
   ##
-  ##   if line =~ peg"\s* {\w+} \s* '=' \s* {\w+}": 
+  ##   if line =~ peg"\s* {\w+} \s* '=' \s* {\w+}":
   ##     # matches a key=value pair:
   ##     echo("Key: ", matches[0])
   ##     echo("Value: ", matches[1])
@@ -864,7 +864,7 @@ template `=~`*(s: string, pattern: TPeg): expr =
   ##     echo("comment: ", matches[0])
   ##   else:
   ##     echo("syntax error")
-  ##  
+  ##
   when not declaredInScope(matches):
     var matches {.inject.}: array[0..MaxSubpatterns-1, string]
   match(s, pattern, matches)
@@ -934,10 +934,10 @@ proc replace*(s: string, sub: TPeg, by = ""): string {.
       addf(result, by, caps)
       inc(i, x)
   add(result, substr(s, i))
-  
+
 proc parallelReplace*(s: string, subs: varargs[
                       tuple[pattern: TPeg, repl: string]]): string {.
-                      rtl, extern: "npegs$1".} = 
+                      rtl, extern: "npegs$1".} =
   ## Returns a modified copy of `s` with the substitutions in `subs`
   ## applied in parallel.
   result = ""
@@ -954,8 +954,8 @@ proc parallelReplace*(s: string, subs: varargs[
       add(result, s[i])
       inc(i)
   # copy the rest:
-  add(result, substr(s, i))  
-  
+  add(result, substr(s, i))
+
 proc transformFile*(infile, outfile: string,
                     subs: varargs[tuple[pattern: TPeg, repl: string]]) {.
                     rtl, extern: "npegs$1".} =
@@ -972,7 +972,7 @@ proc transformFile*(infile, outfile: string,
       quit("cannot open for writing: " & outfile)
   else:
     quit("cannot open for reading: " & infile)
-  
+
 iterator split*(s: string, sep: TPeg): string =
   ## Splits the string `s` into substrings.
   ##
@@ -981,7 +981,7 @@ iterator split*(s: string, sep: TPeg): string =
   ##
   ## .. code-block:: nim
   ##   for word in split("00232this02939is39an22example111", peg"\d+"):
-  ##     writeln(stdout, word)
+  ##     writeLine(stdout, word)
   ##
   ## Results in:
   ##
@@ -1044,14 +1044,14 @@ type
     tkBackref,          ## '$'
     tkDollar,           ## '$'
     tkHat               ## '^'
-  
+
   TToken {.final.} = object  ## a token
     kind: TTokKind           ## the type of the token
     modifier: TModifier
     literal: string          ## the parsed (string) literal
     charset: set[char]       ## if kind == tkCharSet
     index: int               ## if kind == tkBackref
-  
+
   TPegLexer {.inheritable.} = object          ## the lexer object.
     bufpos: int               ## the current position within the buffer
     buf: cstring              ## the buffer itself
@@ -1081,7 +1081,7 @@ proc HandleLF(L: var TPegLexer, pos: int): int =
   result = pos+1
   L.lineStart = result
 
-proc init(L: var TPegLexer, input, filename: string, line = 1, col = 0) = 
+proc init(L: var TPegLexer, input, filename: string, line = 1, col = 0) =
   L.buf = input
   L.bufpos = 0
   L.lineNumber = line
@@ -1089,69 +1089,69 @@ proc init(L: var TPegLexer, input, filename: string, line = 1, col = 0) =
   L.lineStart = 0
   L.filename = filename
 
-proc getColumn(L: TPegLexer): int {.inline.} = 
+proc getColumn(L: TPegLexer): int {.inline.} =
   result = abs(L.bufpos - L.lineStart) + L.colOffset
 
-proc getLine(L: TPegLexer): int {.inline.} = 
+proc getLine(L: TPegLexer): int {.inline.} =
   result = L.linenumber
-  
+
 proc errorStr(L: TPegLexer, msg: string, line = -1, col = -1): string =
   var line = if line < 0: getLine(L) else: line
   var col = if col < 0: getColumn(L) else: col
   result = "$1($2, $3) Error: $4" % [L.filename, $line, $col, msg]
 
-proc handleHexChar(c: var TPegLexer, xi: var int) = 
+proc handleHexChar(c: var TPegLexer, xi: var int) =
   case c.buf[c.bufpos]
-  of '0'..'9': 
+  of '0'..'9':
     xi = (xi shl 4) or (ord(c.buf[c.bufpos]) - ord('0'))
     inc(c.bufpos)
-  of 'a'..'f': 
+  of 'a'..'f':
     xi = (xi shl 4) or (ord(c.buf[c.bufpos]) - ord('a') + 10)
     inc(c.bufpos)
-  of 'A'..'F': 
+  of 'A'..'F':
     xi = (xi shl 4) or (ord(c.buf[c.bufpos]) - ord('A') + 10)
     inc(c.bufpos)
   else: discard
 
-proc getEscapedChar(c: var TPegLexer, tok: var TToken) = 
+proc getEscapedChar(c: var TPegLexer, tok: var TToken) =
   inc(c.bufpos)
   case c.buf[c.bufpos]
-  of 'r', 'R', 'c', 'C': 
+  of 'r', 'R', 'c', 'C':
     add(tok.literal, '\c')
     inc(c.bufpos)
-  of 'l', 'L': 
+  of 'l', 'L':
     add(tok.literal, '\L')
     inc(c.bufpos)
-  of 'f', 'F': 
+  of 'f', 'F':
     add(tok.literal, '\f')
     inc(c.bufpos)
-  of 'e', 'E': 
+  of 'e', 'E':
     add(tok.literal, '\e')
     inc(c.bufpos)
-  of 'a', 'A': 
+  of 'a', 'A':
     add(tok.literal, '\a')
     inc(c.bufpos)
-  of 'b', 'B': 
+  of 'b', 'B':
     add(tok.literal, '\b')
     inc(c.bufpos)
-  of 'v', 'V': 
+  of 'v', 'V':
     add(tok.literal, '\v')
     inc(c.bufpos)
-  of 't', 'T': 
+  of 't', 'T':
     add(tok.literal, '\t')
     inc(c.bufpos)
-  of 'x', 'X': 
+  of 'x', 'X':
     inc(c.bufpos)
     var xi = 0
     handleHexChar(c, xi)
     handleHexChar(c, xi)
     if xi == 0: tok.kind = tkInvalid
     else: add(tok.literal, chr(xi))
-  of '0'..'9': 
+  of '0'..'9':
     var val = ord(c.buf[c.bufpos]) - ord('0')
     inc(c.bufpos)
     var i = 1
-    while (i <= 3) and (c.buf[c.bufpos] in {'0'..'9'}): 
+    while (i <= 3) and (c.buf[c.bufpos] in {'0'..'9'}):
       val = val * 10 + ord(c.buf[c.bufpos]) - ord('0')
       inc(c.bufpos)
       inc(i)
@@ -1164,32 +1164,32 @@ proc getEscapedChar(c: var TPegLexer, tok: var TToken) =
   else:
     add(tok.literal, c.buf[c.bufpos])
     inc(c.bufpos)
-  
-proc skip(c: var TPegLexer) = 
+
+proc skip(c: var TPegLexer) =
   var pos = c.bufpos
   var buf = c.buf
-  while true: 
+  while true:
     case buf[pos]
-    of ' ', '\t': 
+    of ' ', '\t':
       inc(pos)
     of '#':
       while not (buf[pos] in {'\c', '\L', '\0'}): inc(pos)
     of '\c':
       pos = HandleCR(c, pos)
       buf = c.buf
-    of '\L': 
+    of '\L':
       pos = HandleLF(c, pos)
       buf = c.buf
-    else: 
+    else:
       break                   # EndOfFile also leaves the loop
   c.bufpos = pos
-  
-proc getString(c: var TPegLexer, tok: var TToken) = 
+
+proc getString(c: var TPegLexer, tok: var TToken) =
   tok.kind = tkStringLit
   var pos = c.bufPos + 1
   var buf = c.buf
   var quote = buf[pos-1]
-  while true: 
+  while true:
     case buf[pos]
     of '\\':
       c.bufpos = pos
@@ -1200,13 +1200,13 @@ proc getString(c: var TPegLexer, tok: var TToken) =
       break
     elif buf[pos] == quote:
       inc(pos)
-      break      
+      break
     else:
       add(tok.literal, buf[pos])
       inc(pos)
   c.bufpos = pos
-  
-proc getDollar(c: var TPegLexer, tok: var TToken) = 
+
+proc getDollar(c: var TPegLexer, tok: var TToken) =
   var pos = c.bufPos + 1
   var buf = c.buf
   if buf[pos] in {'0'..'9'}:
@@ -1218,8 +1218,8 @@ proc getDollar(c: var TPegLexer, tok: var TToken) =
   else:
     tok.kind = tkDollar
   c.bufpos = pos
-  
-proc getCharSet(c: var TPegLexer, tok: var TToken) = 
+
+proc getCharSet(c: var TPegLexer, tok: var TToken) =
   tok.kind = tkCharSet
   tok.charset = {}
   var pos = c.bufPos + 1
@@ -1242,7 +1242,7 @@ proc getCharSet(c: var TPegLexer, tok: var TToken) =
     of '\C', '\L', '\0':
       tok.kind = tkInvalid
       break
-    else: 
+    else:
       ch = buf[pos]
       inc(pos)
     incl(tok.charset, ch)
@@ -1262,18 +1262,18 @@ proc getCharSet(c: var TPegLexer, tok: var TToken) =
         of '\C', '\L', '\0':
           tok.kind = tkInvalid
           break
-        else: 
+        else:
           ch2 = buf[pos]
           inc(pos)
         for i in ord(ch)+1 .. ord(ch2):
           incl(tok.charset, chr(i))
   c.bufpos = pos
   if caret: tok.charset = {'\1'..'\xFF'} - tok.charset
-  
-proc getSymbol(c: var TPegLexer, tok: var TToken) = 
+
+proc getSymbol(c: var TPegLexer, tok: var TToken) =
   var pos = c.bufpos
   var buf = c.buf
-  while true: 
+  while true:
     add(tok.literal, buf[pos])
     inc(pos)
     if buf[pos] notin strutils.IdentChars: break
@@ -1289,7 +1289,7 @@ proc getBuiltin(c: var TPegLexer, tok: var TToken) =
     tok.kind = tkEscaped
     getEscapedChar(c, tok) # may set tok.kind to tkInvalid
 
-proc getTok(c: var TPegLexer, tok: var TToken) = 
+proc getTok(c: var TPegLexer, tok: var TToken) =
   tok.kind = tkInvalid
   tok.modifier = modNone
   setlen(tok.literal, 0)
@@ -1304,11 +1304,11 @@ proc getTok(c: var TPegLexer, tok: var TToken) =
     else:
       tok.kind = tkCurlyLe
       add(tok.literal, '{')
-  of '}': 
+  of '}':
     tok.kind = tkCurlyRi
     inc(c.bufpos)
     add(tok.literal, '}')
-  of '[': 
+  of '[':
     getCharset(c, tok)
   of '(':
     tok.kind = tkParLe
@@ -1318,7 +1318,7 @@ proc getTok(c: var TPegLexer, tok: var TToken) =
     tok.kind = tkParRi
     inc(c.bufpos)
     add(tok.literal, ')')
-  of '.': 
+  of '.':
     tok.kind = tkAny
     inc(c.bufpos)
     add(tok.literal, '.')
@@ -1326,16 +1326,16 @@ proc getTok(c: var TPegLexer, tok: var TToken) =
     tok.kind = tkAnyRune
     inc(c.bufpos)
     add(tok.literal, '_')
-  of '\\': 
+  of '\\':
     getBuiltin(c, tok)
   of '\'', '"': getString(c, tok)
   of '$': getDollar(c, tok)
-  of '\0': 
+  of '\0':
     tok.kind = tkEof
     tok.literal = "[EOF]"
   of 'a'..'z', 'A'..'Z', '\128'..'\255':
     getSymbol(c, tok)
-    if c.buf[c.bufpos] in {'\'', '"'} or 
+    if c.buf[c.bufpos] in {'\'', '"'} or
         c.buf[c.bufpos] == '$' and c.buf[c.bufpos+1] in {'0'..'9'}:
       case tok.literal
       of "i": tok.modifier = modIgnoreCase
@@ -1383,7 +1383,7 @@ proc getTok(c: var TPegLexer, tok: var TToken) =
     tok.kind = tkAt
     inc(c.bufpos)
     add(tok.literal, '@')
-    if c.buf[c.bufpos] == '@': 
+    if c.buf[c.bufpos] == '@':
       tok.kind = tkCurlyAt
       inc(c.bufpos)
       add(tok.literal, '@')
@@ -1402,7 +1402,7 @@ proc arrowIsNextTok(c: TPegLexer): bool =
   result = c.buf[pos] == '<' and c.buf[pos+1] == '-'
 
 # ----------------------------- parser ----------------------------------------
-    
+
 type
   EInvalidPeg* = object of ValueError ## raised if an invalid
                                       ## PEG has been detected
@@ -1420,7 +1420,7 @@ proc pegError(p: TPegParser, msg: string, line = -1, col = -1) =
   e.msg = errorStr(p, msg, line, col)
   raise e
 
-proc getTok(p: var TPegParser) = 
+proc getTok(p: var TPegParser) =
   getTok(p, p.tok)
   if p.tok.kind == tkInvalid: pegError(p, "invalid token")
 
@@ -1470,7 +1470,7 @@ proc builtin(p: var TPegParser): TPeg =
   of "white": result = UnicodeWhitespace()
   else: pegError(p, "unknown built-in: " & p.tok.literal)
 
-proc token(terminal: TPeg, p: TPegParser): TPeg = 
+proc token(terminal: TPeg, p: TPegParser): TPeg =
   if p.skip.kind == pkEmpty: result = terminal
   else: result = sequence(p.skip, terminal)
 
@@ -1491,7 +1491,7 @@ proc primary(p: var TPegParser): TPeg =
   else: discard
   case p.tok.kind
   of tkIdentifier:
-    if p.identIsVerbatim: 
+    if p.identIsVerbatim:
       var m = p.tok.modifier
       if m == modNone: m = p.modifier
       result = modifiedTerm(p.tok.literal, m).token(p)
@@ -1534,17 +1534,17 @@ proc primary(p: var TPegParser): TPeg =
   of tkEscaped:
     result = term(p.tok.literal[0]).token(p)
     getTok(p)
-  of tkDollar: 
+  of tkDollar:
     result = endAnchor()
     getTok(p)
-  of tkHat: 
+  of tkHat:
     result = startAnchor()
     getTok(p)
   of tkBackref:
     var m = p.tok.modifier
     if m == modNone: m = p.modifier
     result = modifiedBackRef(p.tok.index, m).token(p)
-    if p.tok.index < 0 or p.tok.index > p.captures: 
+    if p.tok.index < 0 or p.tok.index > p.captures:
       pegError(p, "invalid back reference index: " & $p.tok.index)
     getTok(p)
   else:
@@ -1568,7 +1568,7 @@ proc seqExpr(p: var TPegParser): TPeg =
   while true:
     case p.tok.kind
     of tkAmp, tkNot, tkAt, tkStringLit, tkCharset, tkParLe, tkCurlyLe,
-       tkAny, tkAnyRune, tkBuiltin, tkEscaped, tkDollar, tkBackref, 
+       tkAny, tkAnyRune, tkBuiltin, tkEscaped, tkDollar, tkBackref,
        tkHat, tkCurlyAt:
       result = sequence(result, primary(p))
     of tkIdentifier:
@@ -1582,7 +1582,7 @@ proc parseExpr(p: var TPegParser): TPeg =
   while p.tok.kind == tkBar:
     getTok(p)
     result = result / seqExpr(p)
-  
+
 proc parseRule(p: var TPegParser): PNonTerminal =
   if p.tok.kind == tkIdentifier and arrowIsNextTok(p):
     result = getNonTerminal(p, p.tok.literal)
@@ -1596,7 +1596,7 @@ proc parseRule(p: var TPegParser): PNonTerminal =
     incl(result.flags, ntDeclared) # NOW inlining may be attempted
   else:
     pegError(p, "rule expected, but found: " & p.tok.literal)
-  
+
 proc rawParse(p: var TPegParser): TPeg =
   ## parses a rule or a PEG expression
   while p.tok.kind == tkBuiltin:
@@ -1649,20 +1649,20 @@ proc peg*(pattern: string): TPeg =
   ##   peg"{\ident} \s* '=' \s* {.*}"
   result = parsePeg(pattern, "pattern")
 
-proc escapePeg*(s: string): string = 
+proc escapePeg*(s: string): string =
   ## escapes `s` so that it is matched verbatim when used as a peg.
   result = ""
   var inQuote = false
-  for c in items(s):  
+  for c in items(s):
     case c
-    of '\0'..'\31', '\'', '"', '\\': 
-      if inQuote: 
+    of '\0'..'\31', '\'', '"', '\\':
+      if inQuote:
         result.add('\'')
         inQuote = false
       result.add("\\x")
       result.add(toHex(ord(c), 2))
     else:
-      if not inQuote: 
+      if not inQuote:
         result.add('\'')
         inQuote = true
       result.add(c)
@@ -1675,27 +1675,27 @@ when isMainModule:
   doAssert(not match("W_HI_L", peg"\y 'while'"))
   doAssert(not match("W_HI_Le", peg"\y v'while'"))
   doAssert match("W_HI_Le", peg"y'while'")
-  
+
   doAssert($ +digits == $peg"\d+")
   doAssert "0158787".match(peg"\d+")
   doAssert "ABC 0232".match(peg"\w+\s+\d+")
   doAssert "ABC".match(peg"\d+ / \w+")
 
   for word in split("00232this02939is39an22example111", peg"\d+"):
-    writeln(stdout, word)
+    writeLine(stdout, word)
 
   doAssert matchLen("key", ident) == 3
 
   var pattern = sequence(ident, *whitespace, term('='), *whitespace, ident)
   doAssert matchLen("key1=  cal9", pattern) == 11
-  
+
   var ws = newNonTerminal("ws", 1, 1)
   ws.rule = *whitespace
-  
+
   var expr = newNonTerminal("expr", 1, 1)
   expr.rule = sequence(capture(ident), *sequence(
                 nonterminal(ws), term('+'), nonterminal(ws), nonterminal(expr)))
-  
+
   var c: TCaptures
   var s = "a+b +  c +d+e+f"
   doAssert rawMatch(s, expr.rule, 0, c) == len(s)
@@ -1716,7 +1716,7 @@ when isMainModule:
     doAssert matches[0] == "abc"
   else:
     doAssert false
-  
+
   var g2 = peg"""S <- A B / C D
                  A <- 'a'+
                  B <- 'b'+
@@ -1733,10 +1733,10 @@ when isMainModule:
     doAssert matches[0] == "a"
   else:
     doAssert false
-  
+
   block:
     var matches: array[0..2, string]
-    if match("abcdefg", peg"c {d} ef {g}", matches, 2): 
+    if match("abcdefg", peg"c {d} ef {g}", matches, 2):
       doAssert matches[0] == "d"
       doAssert matches[1] == "g"
     else:
@@ -1744,13 +1744,13 @@ when isMainModule:
 
   for x in findAll("abcdef", peg"{.}", 3):
     echo x
-    
+
   if "f(a, b)" =~ peg"{[0-9]+} / ({\ident} '(' {@} ')')":
     doAssert matches[0] == "f"
     doAssert matches[1] == "a, b"
   else:
     doAssert false
-  
+
   doAssert match("eine übersicht und außerdem", peg"(\letter \white*)+")
   # ß is not a lower cased letter?!
   doAssert match("eine übersicht und auerdem", peg"(\lower \white*)+")
@@ -1762,7 +1762,7 @@ when isMainModule:
          "var1<-keykey;var2<-key2key2")
 
   doAssert match("prefix/start", peg"^start$", 7)
-  
+
   # tricky test to check for false aliasing:
   block:
     var a = term"key"
diff --git a/tests/stdlib/tposix.nim b/tests/stdlib/tposix.nim
index bf0b49586..229035d22 100644
--- a/tests/stdlib/tposix.nim
+++ b/tests/stdlib/tposix.nim
@@ -9,8 +9,8 @@ when not defined(windows):
 
   discard uname(u)
 
-  writeln(stdout, u.sysname)
-  writeln(stdout, u.nodename)
-  writeln(stdout, u.release)
-  writeln(stdout, u.machine)
+  writeLine(stdout, u.sysname)
+  writeLine(stdout, u.nodename)
+  writeLine(stdout, u.release)
+  writeLine(stdout, u.machine)
 
diff --git a/tests/stdlib/tquit.nim b/tests/stdlib/tquit.nim
index d4dc1522d..d18b468c8 100644
--- a/tests/stdlib/tquit.nim
+++ b/tests/stdlib/tquit.nim
@@ -1,6 +1,6 @@
-# Test the new beforeQuit variable: 

-

-proc myExit() {.noconv.} = 

-  write(stdout, "just exiting...\n")

-

-addQuitProc(myExit)

+# Test the new beforeQuit variable:
+
+proc myExit() {.noconv.} =
+  write(stdout, "just exiting...\n")
+
+addQuitProc(myExit)
diff --git a/tests/stdlib/tregex.nim b/tests/stdlib/tregex.nim
index bb4695f02..ae6714de1 100644
--- a/tests/stdlib/tregex.nim
+++ b/tests/stdlib/tregex.nim
@@ -2,30 +2,30 @@ discard """
   file: "tregex.nim"
   output: "key: keyAYes!"
 """
-# Test the new regular expression module

-# which is based on the PCRE library

+# Test the new regular expression module
+# which is based on the PCRE library
 
 when defined(powerpc64):
   # cheat as our powerpc test machine has no PCRE installed:
   echo "key: keyAYes!"
 
-else:

-  import

-    re

-

-  if "keyA = valueA" =~ re"\s*(\w+)\s*\=\s*(\w+)":

-    write(stdout, "key: ", matches[0])

-  elif "# comment!" =~ re.re"\s*(\#.*)": 

-    # test re.re"" syntax

-    echo("comment: ", matches[0])

-  else: 

-    echo("Bug!")

-

-  if "Username".match(re"[A-Za-z]+"):

-    echo("Yes!")

-  else:

-    echo("Bug!")

-

-  #OUT key: keyAYes!

+else:
+  import
+    re
+
+  if "keyA = valueA" =~ re"\s*(\w+)\s*\=\s*(\w+)":
+    write(stdout, "key: ", matches[0])
+  elif "# comment!" =~ re.re"\s*(\#.*)":
+    # test re.re"" syntax
+    echo("comment: ", matches[0])
+  else:
+    echo("Bug!")
+
+  if "Username".match(re"[A-Za-z]+"):
+    echo("Yes!")
+  else:
+    echo("Bug!")
+
+  #OUT key: keyAYes!
 
 
diff --git a/tests/stdlib/treguse.nim b/tests/stdlib/treguse.nim
index a610ad725..3d09eb731 100644
--- a/tests/stdlib/treguse.nim
+++ b/tests/stdlib/treguse.nim
@@ -2,26 +2,26 @@ discard """
   file: "treguse.nim"
   output: "055this should be the casehugh"
 """
-# Test the register usage of the virtual machine and

-# the blocks in var statements

-

-proc main(a, b: int) =

-  var x = 0

-  write(stdout, x)

-  if x == 0:

-    var y = 55

-    write(stdout, y)

-    write(stdout, "this should be the case")

-    var input = "<no input>"

-    if input == "Andreas":

-      write(stdout, "wow")

-    else:

-      write(stdout, "hugh")

-  else:

-    var z = 66

-    write(stdout, z) # "bug!")

-

-main(45, 1000)

-#OUT 055this should be the casehugh

+# Test the register usage of the virtual machine and
+# the blocks in var statements
+
+proc main(a, b: int) =
+  var x = 0
+  write(stdout, x)
+  if x == 0:
+    var y = 55
+    write(stdout, y)
+    write(stdout, "this should be the case")
+    var input = "<no input>"
+    if input == "Andreas":
+      write(stdout, "wow")
+    else:
+      write(stdout, "hugh")
+  else:
+    var z = 66
+    write(stdout, z) # "bug!")
+
+main(45, 1000)
+#OUT 055this should be the casehugh
 
 
diff --git a/tests/stdlib/treloop.nim b/tests/stdlib/treloop.nim
new file mode 100644
index 000000000..35236708c
--- /dev/null
+++ b/tests/stdlib/treloop.nim
@@ -0,0 +1,9 @@
+discard """
+  output: "@[(, +,  1,  2, )]"
+"""
+
+import re
+
+let str = "(+ 1 2)"
+var tokenRE = re"""[\s,]*(~@|[\[\]{}()'`~^@]|"(?:\\.|[^\\"])*"|;.*|[^\s\[\]{}('"`,;)]*)"""
+echo str.findAll(tokenRE)
diff --git a/tests/stdlib/trepr.nim b/tests/stdlib/trepr.nim
index 41c830621..18fe7e054 100644
--- a/tests/stdlib/trepr.nim
+++ b/tests/stdlib/trepr.nim
@@ -6,10 +6,10 @@ discard """
 type
   TEnum = enum
     a, b
-    
+
 var val = {a, b}
 stdout.write(repr(val))
-stdout.writeln(repr({'a'..'z', 'A'..'Z'}))
+stdout.writeLine(repr({'a'..'z', 'A'..'Z'}))
 
 type
   TObj {.pure, inheritable.} = object
diff --git a/tests/stdlib/trepr2.nim b/tests/stdlib/trepr2.nim
index b15081e48..a92024851 100644
--- a/tests/stdlib/trepr2.nim
+++ b/tests/stdlib/trepr2.nim
@@ -1,32 +1,32 @@
-# test the new "repr" built-in proc

-

-type

-  TEnum = enum

-    en1, en2, en3, en4, en5, en6

-

-  TPoint {.final.} = object

-    x, y, z: int

-    s: array [0..1, string]

-    e: TEnum

-

-var

-  p: TPoint

-  q: ref TPoint

-  s: seq[ref TPoint]

-

-p.x = 0

-p.y = 13

-p.z = 45

-p.s[0] = "abc"

-p.s[1] = "xyz"

-p.e = en6

-

-new(q)

-q[] = p

-

-s = @[q, q, q, q]

-

-writeln(stdout, repr(p))

-writeln(stdout, repr(q))

-writeln(stdout, repr(s))

-writeln(stdout, repr(en4))

+# test the new "repr" built-in proc
+
+type
+  TEnum = enum
+    en1, en2, en3, en4, en5, en6
+
+  TPoint {.final.} = object
+    x, y, z: int
+    s: array [0..1, string]
+    e: TEnum
+
+var
+  p: TPoint
+  q: ref TPoint
+  s: seq[ref TPoint]
+
+p.x = 0
+p.y = 13
+p.z = 45
+p.s[0] = "abc"
+p.s[1] = "xyz"
+p.e = en6
+
+new(q)
+q[] = p
+
+s = @[q, q, q, q]
+
+writeLine(stdout, repr(p))
+writeLine(stdout, repr(q))
+writeLine(stdout, repr(s))
+writeLine(stdout, repr(en4))
diff --git a/tests/stdlib/tsplit.nim b/tests/stdlib/tsplit.nim
index 25bad33e2..5a1cd2f5f 100644
--- a/tests/stdlib/tsplit.nim
+++ b/tests/stdlib/tsplit.nim
@@ -13,7 +13,7 @@ if s == "#abc#xy#z":
   echo "true"
 else:
   echo "false"
-  
+
 #OUT true
 
 
diff --git a/tests/stdlib/tstreams2.nim b/tests/stdlib/tstreams2.nim
new file mode 100644
index 000000000..90102d8e3
--- /dev/null
+++ b/tests/stdlib/tstreams2.nim
@@ -0,0 +1,13 @@
+discard """
+  file: "tstreams2.nim"
+  output: '''fs is: nil'''
+"""
+import streams
+var
+  fs = newFileStream("amissingfile.txt")
+  line = ""
+echo "fs is: ",repr(fs)
+if not isNil(fs):
+  while fs.readLine(line):
+    echo line
+  fs.close()
diff --git a/tests/stdlib/tstrset.nim b/tests/stdlib/tstrset.nim
index 9cdb5ed35..15024c3f1 100644
--- a/tests/stdlib/tstrset.nim
+++ b/tests/stdlib/tstrset.nim
@@ -8,7 +8,7 @@ type
   TRadixNodeLinear = object of TRadixNode
     len: int8
     keys: array [0..31, char]
-    vals: array [0..31, PRadixNode]  
+    vals: array [0..31, PRadixNode]
   TRadixNodeFull = object of TRadixNode
     b: array [char, PRadixNode]
   TRadixNodeLeaf = object of TRadixNode
@@ -16,7 +16,7 @@ type
   PRadixNodeLinear = ref TRadixNodeLinear
   PRadixNodeFull = ref TRadixNodeFull
   PRadixNodeLeaf = ref TRadixNodeLeaf
-    
+
 proc search(r: PRadixNode, s: string): PRadixNode =
   var r = r
   var i = 0
@@ -52,7 +52,7 @@ proc contains*(r: PRadixNode, s: string): bool =
 
 proc testOrincl*(r: var PRadixNode, s: string): bool =
   nil
-    
+
 proc incl*(r: var PRadixNode, s: string) = discard testOrIncl(r, s)
 
 proc excl*(r: var PRadixNode, s: string) =
diff --git a/tests/stdlib/tstrtabs.nim b/tests/stdlib/tstrtabs.nim
index 251ec77ef..a248cc3b2 100644
--- a/tests/stdlib/tstrtabs.nim
+++ b/tests/stdlib/tstrtabs.nim
@@ -1,12 +1,12 @@
 import strtabs
 
-var tab = newStringTable({"key1": "val1", "key2": "val2"}, 
+var tab = newStringTable({"key1": "val1", "key2": "val2"},
                          modeStyleInsensitive)
 for i in 0..80:
   tab["key_" & $i] = "value" & $i
-  
+
 for key, val in pairs(tab):
-  writeln(stdout, key, ": ", val)
-writeln(stdout, "length of table ", $tab.len)
+  writeLine(stdout, key, ": ", val)
+writeLine(stdout, "length of table ", $tab.len)
 
-writeln(stdout, `%`("$key1 = $key2; ${PATH}", tab, {useEnvironment}))
+writeLine(stdout, `%`("$key1 = $key2; ${PATH}", tab, {useEnvironment}))
diff --git a/tests/stdlib/tstrutil.nim b/tests/stdlib/tstrutil.nim
index 3db484faa..b15bf0e68 100644
--- a/tests/stdlib/tstrutil.nim
+++ b/tests/stdlib/tstrutil.nim
@@ -10,12 +10,52 @@ import
 proc testStrip() =
   write(stdout, strip("  ha  "))
 
-proc main() = 
+proc testRemoveSuffix =
+  var s = "hello\n\r"
+  s.removeSuffix
+  assert s == "hello\n"
+  s.removeSuffix
+  assert s == "hello"
+  s.removeSuffix
+  assert s == "hello"
+
+  s = "hello\n\n"
+  s.removeSuffix
+  assert s == "hello\n"
+
+  s = "hello\r"
+  s.removeSuffix
+  assert s == "hello"
+
+  s = "hello \n there"
+  s.removeSuffix
+  assert s == "hello \n there"
+
+  s = "hello"
+  s.removeSuffix("llo")
+  assert s == "he"
+  s.removeSuffix('e')
+  assert s == "h"
+
+  s = "hellos"
+  s.removeSuffix({'s','z'})
+  assert s == "hello"
+  s.removeSuffix({'l','o'})
+  assert s == "hell"
+
+  # Contrary to Chomp in other languages
+  # empty string does not change behaviour
+  s = "hello\r\n\r\n"
+  s.removeSuffix("")
+  assert s == "hello\r\n\r\n"
+
+proc main() =
   testStrip()
+  testRemoveSuffix()
   for p in split("/home/a1:xyz:/usr/bin", {':'}):
     write(stdout, p)
 
-proc testDelete = 
+proc testDelete =
   var s = "0123456789ABCDEFGH"
   delete(s, 4, 5)
   assert s == "01236789ABCDEFGH"
@@ -24,8 +64,8 @@ proc testDelete =
   delete(s, 0, 0)
   assert s == "1236789ABCDEFG"
 
-testDelete()  
-    
+testDelete()
+
 assert(insertSep($1000_000) == "1_000_000")
 assert(insertSep($232) == "232")
 assert(insertSep($12345, ',') == "12,345")
diff --git a/tests/stdlib/ttime.nim b/tests/stdlib/ttime.nim
index bad818816..859f0abdd 100644
--- a/tests/stdlib/ttime.nim
+++ b/tests/stdlib/ttime.nim
@@ -1,6 +1,6 @@
-# test the new time module

-

-import

-  times

-

-write(stdout, $getTime())

+# test the new time module
+
+import
+  times
+
+write(stdout, $getTime())
diff --git a/tests/stdlib/tunittest.nim b/tests/stdlib/tunittest.nim
new file mode 100644
index 000000000..4b210c23b
--- /dev/null
+++ b/tests/stdlib/tunittest.nim
@@ -0,0 +1,85 @@
+import unittest, sequtils
+
+
+proc doThings(spuds: var int): int =
+  spuds = 24
+  return 99
+test "#964":
+  var spuds = 0
+  check doThings(spuds) == 99
+  check spuds == 24
+
+
+from strutils import toUpper
+test "#1384":
+  check(@["hello", "world"].map(toUpper) == @["HELLO", "WORLD"])
+
+
+import options
+test "unittest typedescs":
+  check(none(int) == none(int))
+  check(none(int) != some(1))
+
+
+test "unittest multiple requires":
+  require(true)
+  require(true)
+
+
+import math
+from strutils import parseInt
+proc defectiveRobot() =
+  randomize()
+  case random(1..4)
+  of 1: raise newException(OSError, "CANNOT COMPUTE!")
+  of 2: discard parseInt("Hello World!")
+  of 3: raise newException(IOError, "I can't do that Dave.")
+  else: assert 2 + 2 == 5
+test "unittest expect":
+  expect IOError, OSError, ValueError, AssertionError:
+    defectiveRobot()
+
+var
+  a = 1
+  b = -1
+  c = 1
+
+#unittests are sequential right now
+suite "suite with only teardown":
+  teardown:
+    b = 2
+
+  test "unittest with only teardown 1":
+    check a == c
+
+  test "unittest with only teardown 2":
+    check b > a
+
+suite "suite with only setup":
+  setup:
+    var testVar = "from setup"
+
+  test "unittest with only setup 1":
+    check testVar == "from setup"
+    check b > a
+    b = -1
+
+  test "unittest with only setup 2":
+    check b < a
+
+suite "suite with none":
+  test "unittest with none":
+    check b < a
+
+suite "suite with both":
+  setup:
+    a = -2
+
+  teardown:
+    c = 2
+
+  test "unittest with both 1":
+    check b > a
+
+  test "unittest with both 2":
+    check c == 2
diff --git a/tests/stdlib/twalker.nim b/tests/stdlib/twalker.nim
index 89e6c2b9d..91c97df01 100644
--- a/tests/stdlib/twalker.nim
+++ b/tests/stdlib/twalker.nim
@@ -1,13 +1,13 @@
-# iterate over all files with a given filter:

-

-import

-  "../../lib/pure/os.nim", ../../ lib / pure / times

-

-proc main(filter: string) =

-  for filename in walkFiles(filter):

-    writeln(stdout, filename)

-

-  for key, val in envPairs():

-    writeln(stdout, key & '=' & val)

-

-main("*.nim")

+# iterate over all files with a given filter:
+
+import
+  "../../lib/pure/os.nim", ../../ lib / pure / times
+
+proc main(filter: string) =
+  for filename in walkFiles(filter):
+    writeLine(stdout, filename)
+
+  for key, val in envPairs():
+    writeLine(stdout, key & '=' & val)
+
+main("*.nim")
diff --git a/tests/stdlib/twchartoutf8.nim b/tests/stdlib/twchartoutf8.nim
new file mode 100644
index 000000000..b2f68ee32
--- /dev/null
+++ b/tests/stdlib/twchartoutf8.nim
@@ -0,0 +1,110 @@
+discard """
+  output: '''OK'''
+"""
+
+#assume WideCharToMultiByte always produce correct result
+#windows only
+
+when not defined(windows):
+  echo "OK"
+else:
+  {.push gcsafe.}
+
+  const CP_UTF8 = 65001'i32
+
+  type
+    LPBOOL = ptr int32
+    LPWCSTR = ptr uint16
+
+  proc WideCharToMultiByte*(CodePage: int32, dwFlags: int32,
+                            lpWideCharStr: LPWCSTR, cchWideChar: int32,
+                            lpMultiByteStr: cstring, cchMultiByte: int32,
+                            lpDefaultChar: cstring, lpUsedDefaultChar: LPBOOL): int32{.
+      stdcall, dynlib: "kernel32", importc: "WideCharToMultiByte".}
+
+  {.pop.}
+
+  proc convertToUTF8(wc: WideCString, wclen: int32): string =
+    let size = WideCharToMultiByte(CP_UTF8, 0'i32, cast[LPWCSTR](addr(wc[0])), wclen,
+      cstring(nil), 0'i32, cstring(nil), LPBOOL(nil))
+    result = newString(size)
+    let res = WideCharToMultiByte(CP_UTF8, 0'i32, cast[LPWCSTR](addr(wc[0])), wclen,
+      cstring(result), size, cstring(nil), LPBOOL(nil))
+    result[size] = chr(0)
+    doAssert size == res
+
+  proc testCP(wc: WideCString, lo, hi: int) =
+    var x = 0
+    let chunk = 1024
+    for i in lo..hi:
+      wc[x] = cast[Utf16Char](i)
+      if (x >= chunk) or (i >= hi):
+        wc[x] = Utf16Char(0)
+        var a = convertToUTF8(wc, int32(x))
+        var b = wc $ chunk
+        doAssert a == b
+        x = 0
+      inc x
+
+  proc testCP2(wc: WideCString, lo, hi: int) =
+    doAssert((lo >= 0x10000) and (hi <= 0x10FFFF))
+    var x = 0
+    let chunk = 1024
+    for i in lo..hi:
+      let ch = i - 0x10000
+      let W1 = 0xD800 or (ch shr 10)
+      let W2 = 0xDC00 or (0x3FF and ch)
+      wc[x] = cast[Utf16Char](W1)
+      wc[x+1] = cast[Utf16Char](W2)
+      inc(x, 2)
+
+      if (x >= chunk) or (i >= hi):
+        wc[x] = Utf16Char(0)
+        var a = convertToUTF8(wc, int32(x))
+        var b = wc $ chunk
+        doAssert a == b
+        x = 0
+
+  #RFC-2781 "UTF-16, an encoding of ISO 10646"
+
+  var wc: WideCString
+  unsafeNew(wc, 1024 * 4 + 2)
+
+  #U+0000 to U+D7FF
+  #skip the U+0000
+  wc.testCP(1, 0xD7FF)
+
+  #U+E000 to U+FFFF
+  wc.testCP(0xE000, 0xFFFF)
+
+  #U+10000 to U+10FFFF
+  wc.testCP2(0x10000, 0x10FFFF)
+
+  #invalid UTF-16
+  const
+    b = "\xEF\xBF\xBD"
+    c = "\xEF\xBF\xBF"
+
+  wc[0] = cast[Utf16Char](0xDC00)
+  wc[1] = Utf16Char(0)
+  var a = $wc
+  doAssert a == b
+
+  wc[0] = cast[Utf16Char](0xFFFF)
+  wc[1] = cast[Utf16Char](0xDC00)
+  wc[2] = Utf16Char(0)
+  a = $wc
+  doAssert a == c & b
+
+  wc[0] = cast[Utf16Char](0xD800)
+  wc[1] = Utf16Char(0)
+  a = $wc
+  doAssert a == b
+
+  wc[0] = cast[Utf16Char](0xD800)
+  wc[1] = cast[Utf16Char](0xFFFF)
+  wc[2] = Utf16Char(0)
+  a = $wc
+  doAssert a == b & c
+
+  echo "OK"