diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/core/macros.nim | 6 | ||||
-rw-r--r-- | lib/pure/marshal.nim | 11 | ||||
-rw-r--r-- | lib/pure/parsecfg.nim | 35 | ||||
-rw-r--r-- | lib/pure/parsexml.nim | 140 | ||||
-rw-r--r-- | lib/system.nim | 22 |
5 files changed, 182 insertions, 32 deletions
diff --git a/lib/core/macros.nim b/lib/core/macros.nim index 5b29d5e94..4d76d60c2 100644 --- a/lib/core/macros.nim +++ b/lib/core/macros.nim @@ -237,6 +237,12 @@ else: # bootstrapping substitute else: n.strValOld +when defined(nimHasSymOwnerInMacro): + proc owner*(sym: NimNode): NimNode {.magic: "SymOwner", noSideEffect.} + ## accepts node of kind nnkSym and returns its owner's symbol. + ## result is also mnde of kind nnkSym if owner exists otherwise + ## nnkNilLit is returned + proc getType*(n: NimNode): NimNode {.magic: "NGetType", noSideEffect.} ## with 'getType' you can access the node's `type`:idx:. A Nim type is ## mapped to a Nim AST too, so it's slightly confusing but it means the same diff --git a/lib/pure/marshal.nim b/lib/pure/marshal.nim index 980439759..b0bcfe535 100644 --- a/lib/pure/marshal.nim +++ b/lib/pure/marshal.nim @@ -280,6 +280,17 @@ proc `$$`*[T](x: T): string = proc to*[T](data: string): T = ## reads data and transforms it to a ``T``. + runnableExamples: + type + Foo = object + id: int + bar: string + + let x = Foo(id: 1, bar: "baz") + # serialize + let y = ($$x) + # deserialize back to type 'Foo': + let z = y.to[:Foo] var tab = initTable[BiggestInt, pointer]() loadAny(newStringStream(data), toAny(result), tab) diff --git a/lib/pure/parsecfg.nim b/lib/pure/parsecfg.nim index 5fa2d8dc3..b991dd57f 100644 --- a/lib/pure/parsecfg.nim +++ b/lib/pure/parsecfg.nim @@ -17,12 +17,37 @@ ## ## .. include:: ../../doc/mytest.cfg ## :literal: -## The file ``examples/parsecfgex.nim`` demonstrates how to use the -## configuration file parser: -## -## .. code-block:: nim -## :file: ../../examples/parsecfgex.nim ## + +##[ Here is an example of how to use the configuration file parser: + +.. code-block:: nim + + import + os, parsecfg, strutils, streams + + var f = newFileStream(paramStr(1), fmRead) + if f != nil: + var p: CfgParser + open(p, f, paramStr(1)) + while true: + var e = next(p) + case e.kind + of cfgEof: break + of cfgSectionStart: ## a ``[section]`` has been parsed + echo("new section: " & e.section) + of cfgKeyValuePair: + echo("key-value-pair: " & e.key & ": " & e.value) + of cfgOption: + echo("command: " & e.key & ": " & e.value) + of cfgError: + echo(e.msg) + close(p) + else: + echo("cannot open: " & paramStr(1)) + +]## + ## Examples ## -------- ## diff --git a/lib/pure/parsexml.nim b/lib/pure/parsexml.nim index fe933fb79..d8d5a7a2d 100644 --- a/lib/pure/parsexml.nim +++ b/lib/pure/parsexml.nim @@ -26,27 +26,125 @@ ## creates. ## ## -## Example 1: Retrieve HTML title -## ============================== -## -## The file ``examples/htmltitle.nim`` demonstrates how to use the -## XML parser to accomplish a simple task: To determine the title of an HTML -## document. -## -## .. code-block:: nim -## :file: ../../examples/htmltitle.nim -## -## -## Example 2: Retrieve all HTML links -## ================================== -## -## The file ``examples/htmlrefs.nim`` demonstrates how to use the -## XML parser to accomplish another simple task: To determine all the links -## an HTML document contains. -## -## .. code-block:: nim -## :file: ../../examples/htmlrefs.nim -## + +##[ + +Example 1: Retrieve HTML title +============================== + +The file ``examples/htmltitle.nim`` demonstrates how to use the +XML parser to accomplish a simple task: To determine the title of an HTML +document. + +.. code-block:: nim + + # Example program to show the parsexml module + # This program reads an HTML file and writes its title to stdout. + # Errors and whitespace are ignored. + + import os, streams, parsexml, strutils + + if paramCount() < 1: + quit("Usage: htmltitle filename[.html]") + + var filename = addFileExt(paramStr(1), "html") + var s = newFileStream(filename, fmRead) + if s == nil: quit("cannot open the file " & filename) + var x: XmlParser + open(x, s, filename) + while true: + x.next() + case x.kind + of xmlElementStart: + if cmpIgnoreCase(x.elementName, "title") == 0: + var title = "" + x.next() # skip "<title>" + while x.kind == xmlCharData: + title.add(x.charData) + x.next() + if x.kind == xmlElementEnd and cmpIgnoreCase(x.elementName, "title") == 0: + echo("Title: " & title) + quit(0) # Success! + else: + echo(x.errorMsgExpected("/title")) + + of xmlEof: break # end of file reached + else: discard # ignore other events + + x.close() + quit("Could not determine title!") + +]## + +##[ + +Example 2: Retrieve all HTML links +================================== + +The file ``examples/htmlrefs.nim`` demonstrates how to use the +XML parser to accomplish another simple task: To determine all the links +an HTML document contains. + +.. code-block:: nim + + # Example program to show the new parsexml module + # This program reads an HTML file and writes all its used links to stdout. + # Errors and whitespace are ignored. + + import os, streams, parsexml, strutils + + proc `=?=` (a, b: string): bool = + # little trick: define our own comparator that ignores case + return cmpIgnoreCase(a, b) == 0 + + if paramCount() < 1: + quit("Usage: htmlrefs filename[.html]") + + var links = 0 # count the number of links + var filename = addFileExt(paramStr(1), "html") + var s = newFileStream(filename, fmRead) + if s == nil: quit("cannot open the file " & filename) + var x: XmlParser + open(x, s, filename) + next(x) # get first event + block mainLoop: + while true: + case x.kind + of xmlElementOpen: + # the <a href = "xyz"> tag we are interested in always has an attribute, + # thus we search for ``xmlElementOpen`` and not for ``xmlElementStart`` + if x.elementName =?= "a": + x.next() + if x.kind == xmlAttribute: + if x.attrKey =?= "href": + var link = x.attrValue + inc(links) + # skip until we have an ``xmlElementClose`` event + while true: + x.next() + case x.kind + of xmlEof: break mainLoop + of xmlElementClose: break + else: discard + x.next() # skip ``xmlElementClose`` + # now we have the description for the ``a`` element + var desc = "" + while x.kind == xmlCharData: + desc.add(x.charData) + x.next() + echo(desc & ": " & link) + else: + x.next() + of xmlEof: break # end of file reached + of xmlError: + echo(errorMsg(x)) + x.next() + else: x.next() # skip other events + + echo($links & " link(s) found!") + x.close() + +]## import hashes, strutils, lexbase, streams, unicode diff --git a/lib/system.nim b/lib/system.nim index 92f51fe7e..3a18a715c 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -2195,10 +2195,17 @@ iterator items*[T](a: set[T]): T {.inline.} = iterator items*(a: cstring): char {.inline.} = ## iterates over each item of `a`. - var i = 0 - while a[i] != '\0': - yield a[i] - inc(i) + when defined(js): + var i = 0 + var L = len(a) + while i < L: + yield a[i] + inc(i) + else: + var i = 0 + while a[i] != '\0': + yield a[i] + inc(i) iterator mitems*(a: var cstring): var char {.inline.} = ## iterates over each item of `a` so that you can modify the yielded value. @@ -3386,12 +3393,15 @@ when not defined(JS): #and not defined(nimscript): var e = getCurrentException() return if e == nil: "" else: e.msg - proc onRaise*(action: proc(e: ref Exception): bool{.closure.}) = + proc onRaise*(action: proc(e: ref Exception): bool{.closure.}) {.deprecated.} = ## can be used in a ``try`` statement to setup a Lisp-like ## `condition system`:idx:\: This prevents the 'raise' statement to ## raise an exception but instead calls ``action``. ## If ``action`` returns false, the exception has been handled and ## does not propagate further through the call stack. + ## + ## *Deprecated since version 0.18.1*: No good usages of this + ## feature are known. if not isNil(excHandler): excHandler.hasRaiseAction = true excHandler.raiseAction = action @@ -3972,7 +3982,7 @@ proc addQuoted*[T](s: var string, x: T) = ## tmp.add(", ") ## tmp.addQuoted('c') ## assert(tmp == """1, "string", 'c'""") - when T is string: + when T is string or T is cstring: s.add("\"") for c in x: # Only ASCII chars are escaped to avoid butchering |