cleanup: E_Base should not be used for inheriting exceptions; documentation generator generates dependencies section

This commit is contained in:
Araq
2011-01-15 23:57:19 +01:00
parent 25d41f2f9a
commit fa111b9067
17 changed files with 60 additions and 370 deletions

View File

@@ -1,5 +1,5 @@
# This is the config file for the documentation generator.
# (c) 2010 Andreas Rumpf
# (c) 2011 Andreas Rumpf
# Feel free to edit the templates as you need.
split.item.toc = "20"
@@ -45,12 +45,16 @@ doc.body_toc = """
$tableofcontents
<div class="content" id="content">
$moduledesc
<h1>Dependencies</h1>
$deps
$content
</div>
"""
doc.body_no_toc = """
$moduledesc
<h1>Dependencies</h1>
$deps
$content
"""

View File

@@ -1,6 +1,6 @@
# This is the config file for the documentation generator that produces TeX
# output.
# (c) 2009 Andreas Rumpf
# (c) 2011 Andreas Rumpf
# Feel free to edit the templates as you need.
split.item.toc = "20"
@@ -30,11 +30,17 @@ doc.toc = r"\tableofcontents \newpage"
doc.body_toc = """
$tableofcontents
$moduledesc
Dependencies: $deps
$content
"""
doc.body_no_toc = """
$moduledesc
Dependencies: $deps
$content
"""

View File

@@ -34,6 +34,10 @@ Core
* `macros <macros.html>`_
Contains the AST API and documentation of Nimrod for writing macros.
* `marshal <marshal.html>`_
Contains procs for serialization and deseralization of arbitrary Nimrod
data structures.
String handling
---------------

View File

@@ -24,7 +24,7 @@ type
w, h: int
s: sdl.PSurface
EGraphics* = object of EBase
EGraphics* = object of EIO
TFont {.pure, final.} = object
f: sdl_ttf.PFont

View File

@@ -1,163 +0,0 @@
#
#
# Nimrod's Runtime Library
# (c) Copyright 2009 Andreas Rumpf
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
#
## The ``hashtabs`` module implements an efficient generic hash
## table/dictionary data type.
import
hashes
const
growthFactor = 2
startSize = 8
sham = sizeof(THash)*8-2 # shift amount
mask = 0b11 shl sham
usedSlot = 0b10 shl sham
delSlot = 0b01 shl sham
emptySlot = 0
type
TTable*[TKey, TValue] = object
counter: int
data: seq[tuple[key: TKey, val: TValue, h: THash]]
proc init*(t: var TTable, size = startSize) =
t.counter = 0
newSeq(t.data, size)
proc markUsed(h: THash): THash {.inline.} =
return h and not mask or usedSlot
proc len*(t: TTable): int {.inline.} =
## returns the number of keys in `t`.
result = t.counter
proc mustRehash(length, counter: int): bool =
assert(length > counter)
result = (length * 2 < counter * 3) or (length - counter < 4)
proc nextTry(h, maxHash: THash): THash {.inline.} =
result = ((5 * h) + 1) and maxHash
template eq(a, b: expr): expr = a == b
proc rawGet(t: TTable, key: TKey, fullhash: THash): int =
var h = fullhash and high(t.data)
while (t.data[h].h and mask) != 0:
# If it is a deleted entry, the comparison with ``markUsed(fullhash)``
# fails, so there is no need to check for this explicitely.
if t.data[h].h == markUsed(fullhash) and eq(t.data[h].key, key): return h
h = nextTry(h, high(t.data))
result = - 1
proc `[]`*(t: TTable, key: TKey): TValue =
## retrieves the value at ``t[key]``. If `key` is not in `t`,
## `EInvalidValue` is raised.
var index = rawGet(t, key, hash(key))
if index >= 0: result = t.data[index].val
else:
var e: ref EInvalidValue
new(e)
e.msg = "invalid key: " & $key
raise e
proc hasKey*(t: TTable, key: TKey): bool =
## returns true iff `key` is in the table `t`.
result = rawGet(t, key) >= 0
proc rawInsert[TKey, TValue](
data: var seq[tuple[key: TKey, val: TValue, h: THash]],
tup: tuple[key: TKey, val: TValue, h: THash]) =
var h = tup.h and high(data)
while (data[h].h and mask) == usedSlot: h = nextTry(h, high(data))
data[h] = tup
proc enlarge(t: var TTable) =
var n: seq[tuple[key: TKey, val: TValue, h: THash]]
newSeq(n, len(t.data) * growthFactor)
for i in 0..high(t.data):
if (t.data[i].h and mask) == usedSlot: rawInsert(n, t.data[i])
swap(t.data, n)
proc `[]=`*(t: var TTable, key: TKey, val: TValue) =
## puts a (key, value)-pair into `t`.
var fullhash = hash(key)
var index = rawGet(t, key, fullhash)
if index >= 0:
t.data[index].val = val
else:
if mustRehash(len(t.data), t.counter): enlarge(t)
rawInsert(t.data, (key, val, markUsed(fullhash)))
inc(t.counter)
proc add*(t: var TTable, key: TKey, val: TValue) =
## puts a (key, value)-pair into `t`, but does not check if key already
## exists.
if mustRehash(len(t.data), t.counter): enlarge(t)
rawInsert(t.data, (key, val, markUsed(hash(key))))
inc(t.counter)
proc del*(t: var TTable, key: TKey) =
## deletes a (key, val)-pair in `t`.
var index = rawGet(t, key)
if index >= 0:
t.data[index].h = delSlot
proc delAll*(t: var TTable, key: TKey) =
## deletes all (key, val)-pairs in `t`.
while true:
var index = rawGet(t, key)
if index < 0: break
t.data[index].h = delSlot
iterator pairs*(t: TTable): tuple[key: TKey, value: TValue] =
## iterates over any (key, value) pair in the table `t`.
for h in 0..high(t.data):
if (t.data[h].h and mask) == usedSlot:
yield (t.data[h].key, t.data[h].val)
iterator keys*(t: TTable): TKey =
## iterate over any key in the table `t`. If key occurs multiple times, it
## is yielded multiple times.
for h in 0..high(t.data):
if (t.data[h].h and mask) == usedSlot:
yield t.data[h].key
iterator values*(t: TTable): TValue =
## iterate over any value in the table `t`.
for h in 0..high(t.data):
if (t.data[h].h and mask) == usedSlot:
yield t.data[h].val
iterator values*(t: TTable, key: TKey): TValue =
## iterate over any value associated with `key` in `t`.
var fullhash = hash(key)
var h = fullhash and high(t.data)
while (t.data[h].h and mask) != 0:
# If it is a deleted entry, the comparison with ``markUsed(fullhash)``
# fails, so there is no need to check for this explicitely.
if t.data[h].h == markUsed(fullhash) and eq(t.data[h].key, key):
yield t.data[h].val
h = nextTry(h, high(t.data))
proc `$`*[KeyToStr=`$`, ValueToStr=`$`](t: TTable): string =
## turns the table into its string representation. `$` must be available
## for TKey and TValue for this to work.
if t.len == 0:
result = "{:}"
else:
result = "{"
var i = 0
for k, v in pairs(t):
if i > 0: add(result, ", ")
add(result, KeyToStr(k))
add(result, ": ")
add(result, ValueToStr(v))
inc(i)
add(result, "}")

View File

@@ -52,13 +52,13 @@ type
headers: PStringTable,
body: string]
EInvalidProtocol* = object of EBase ## exception that is raised when server
## does not conform to the implemented
## protocol
EInvalidProtocol* = object of ESynch ## exception that is raised when server
## does not conform to the implemented
## protocol
EHttpRequestErr* = object of EBase ## Thrown in the ``getContent`` proc
## and ``postContent`` proc,
## when the server returns an error
EHttpRequestErr* = object of ESynch ## Thrown in the ``getContent`` proc
## and ``postContent`` proc,
## when the server returns an error
proc httpError(msg: string) =
var e: ref EInvalidProtocol

View File

@@ -498,7 +498,7 @@ type
of JArray:
elems*: seq[PJsonNode]
EJsonParsingError* = object of EBase
EJsonParsingError* = object of EInvalidValue
proc raiseParseErr(p: TJsonParser, msg: string) =
raise newException(EJsonParsingError, errorMsgExpected(p, msg))

View File

@@ -8,7 +8,7 @@
#
## This module implements a simple logger. It is based on the following design:
## * Runtime log formating is a bug: Sooner or later ever log file is parsed.
## * Runtime log formating is a bug: Sooner or later every log file is parsed.
## * Keep it simple: If this library does not fullfill your needs, write your
## own. Trying to support every logging feature just leads to bloat.
##

View File

@@ -536,7 +536,7 @@ type
nkEnumDef
type
EInvalidSql* = object of EBase ## Invalid SQL encountered
EInvalidSql* = object of EInvalidValue ## Invalid SQL encountered
PSqlNode* = ref TSqlNode ## an SQL abstract syntax tree node
TSqlNode* = object ## an SQL abstract syntax tree node
case kind*: TSqlNodeKind ## kind of syntax tree

View File

@@ -1344,7 +1344,8 @@ proc arrowIsNextTok(c: TPegLexer): bool =
# ----------------------------- parser ----------------------------------------
type
EInvalidPeg* = object of EBase ## raised if an invalid PEG has been detected
EInvalidPeg* = object of EInvalidValue ## raised if an invalid
## PEG has been detected
TPegParser = object of TPegLexer ## the PEG parser object
tok: TToken
nonterms: seq[PNonTerminal]

View File

@@ -48,7 +48,7 @@ type
msgOtherHeaders: PStringTable
msgBody: string
EInvalidReply* = object of EBase
EInvalidReply* = object of EIO
proc debugSend(smtp: TSMTP, cmd: string) =
if smtp.debug:

View File

@@ -1,181 +0,0 @@
#
#
# Nimrod's Runtime Library
# (c) Copyright 2010 Andreas Rumpf
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
#
## This module implements Nimrod's support for the ``variant`` datatype.
## `TVariant` shows how the flexibility of dynamic typing is achieved
## within a static type system.
type
TVarType* = enum
vtNone,
vtBool,
vtChar,
vtEnum,
vtInt,
vtFloat,
vtString,
vtSet,
vtSeq,
vtDict
TVariant* {.final.} = object of TObject
case vtype: TVarType
of vtNone: nil
of vtBool, vtChar, vtEnum, vtInt: vint: int64
of vtFloat: vfloat: float64
of vtString: vstring: string
of vtSet, vtSeq: q: seq[TVariant]
of vtDict: d: seq[tuple[key, val: TVariant]]
iterator objectFields*[T](x: T, skipInherited: bool): tuple[
key: string, val: TVariant] {.magic: "ObjectFields"}
proc `?`*(x: ordinal): TVariant =
result.kind = vtEnum
result.vint = x
proc `?`*(x: biggestInt): TVariant =
result.kind = vtInt
result.vint = x
proc `?`*(x: char): TVariant =
result.kind = vtChar
result.vint = ord(x)
proc `?`*(x: bool): TVariant =
result.kind = vtBool
result.vint = ord(x)
proc `?`*(x: biggestFloat): TVariant =
result.kind = vtFloat
result.vfloat = x
proc `?`*(x: string): TVariant =
result.kind = vtString
result.vstring = x
proc `?`*[T](x: openArray[T]): TVariant =
result.kind = vtSeq
newSeq(result.q, x.len)
for i in 0..x.len-1: result.q[i] = <>x[i]
proc `?`*[T](x: set[T]): TVariant =
result.kind = vtSet
result.q = @[]
for a in items(x): result.q.add(<>a)
proc `?`* [T: object](x: T): TVariant {.magic: "ToVariant".}
## this converts a value to a variant ("boxing")
proc `><`*[T](v: TVariant, typ: T): T {.magic: "FromVariant".}
?[?5, ?67, ?"hello"]
myVar?int
proc `==`* (x, y: TVariant): bool =
if x.vtype == y.vtype:
case x.vtype
of vtNone: result = true
of vtBool, vtChar, vtEnum, vtInt: result = x.vint == y.vint
of vtFloat: result = x.vfloat == y.vfloat
of vtString: result = x.vstring == y.vstring
of vtSet:
# complicated! We check that each a in x also occurs in y and that the
# counts are identical:
if x.q.len == y.q.len:
for a in items(x.q):
block inner:
for b in items(y.q):
if a == b: break inner
return false
result = true
of vtSeq:
if x.q.len == y.q.len:
for i in 0..x.q.len-1:
if x.q[i] != y.q[i]: return false
result = true
of vtDict:
# it is an ordered dict:
if x.d.len == y.d.len:
for i in 0..x.d.len-1:
if x.d[i].key != y.d[i].key: return false
if x.d[i].val != y.d[i].val: return false
result = true
proc `[]`* (a, b: TVariant): TVariant =
case a.vtype
of vtSeq:
if b.vtype in {vtBool, vtChar, vtEnum, vtInt}:
result = a.q[b.vint]
else:
variantError()
of vtDict:
for i in 0..a.d.len-1:
if a.d[i].key == b: return a.d[i].val
if b.vtype in {vtBool, vtChar, vtEnum, vtInt}:
result = a.d[b.vint].val
variantError()
else: variantError()
proc `[]=`* (a, b, c: TVariant) =
case a.vtype
of vtSeq:
if b.vtype in {vtBool, vtChar, vtEnum, vtInt}:
a.q[b.vint] = b
else:
variantError()
of vtDict:
for i in 0..a.d.len-1:
if a.d[i].key == b:
a.d[i].val = c
return
if b.vtype in {vtBool, vtChar, vtEnum, vtInt}:
a.d[b.vint].val = c
variantError()
else: variantError()
proc `[]`* (a: TVariant, b: int): TVariant {.inline} = return a[?b]
proc `[]`* (a: TVariant, b: string): TVariant {.inline} = return a[?b]
proc `[]=`* (a: TVariant, b: int, c: TVariant) {.inline} = a[?b] = c
proc `[]=`* (a: TVariant, b: string, c: TVariant) {.inline} = a[?b] = c
proc `+`* (x, y: TVariant): TVariant =
case x.vtype
of vtBool, vtChar, vtEnum, vtInt:
if y.vtype == x.vtype:
result.vtype = x.vtype
result.vint = x.vint + y.vint
else:
case y.vtype
of vtBool, vtChar, vtEnum, vtInt:
vint: int64
of vtFloat: vfloat: float64
of vtString: vstring: string
of vtSet, vtSeq: q: seq[TVariant]
of vtDict: d: seq[tuple[key, val: TVariant]]
proc `-`* (x, y: TVariant): TVariant
proc `*`* (x, y: TVariant): TVariant
proc `/`* (x, y: TVariant): TVariant
proc `div`* (x, y: TVariant): TVariant
proc `mod`* (x, y: TVariant): TVariant
proc `&`* (x, y: TVariant): TVariant
proc `$`* (x: TVariant): string =
# uses JS notation
proc parseVariant*(s: string): TVariant
proc `<`* (x, y: TVariant): bool
proc `<=`* (x, y: TVariant): bool
proc hash*(x: TVariant): int =

View File

@@ -16,7 +16,7 @@ import strutils
#Exceptions
type
EDOMException* = object of E_Base ## Base exception object for all DOM Exceptions
EDOMException* = object of EInvalidValue ## Base exception object for all DOM Exceptions
EDOMStringSizeErr* = object of EDOMException ## If the specified range of text does not fit into a DOMString
## Currently not used(Since DOMString is just string)
EHierarchyRequestErr* = object of EDOMException ## If any node is inserted somewhere it doesn't belong

View File

@@ -15,8 +15,8 @@ import xmldom, os, streams, parsexml, strutils
type
# Parsing errors
EMismatchedTag* = object of E_Base ## Raised when a tag is not properly closed
EParserError* = object of E_Base ## Raised when an unexpected XML Parser event occurs
EMismatchedTag* = object of EInvalidValue ## Raised when a tag is not properly closed
EParserError* = object of EInvalidValue ## Raised when an unexpected XML Parser event occurs
# For namespaces
xmlnsAttr = tuple[name, value: string, ownerElement: PElement]

View File

@@ -12,8 +12,9 @@
import streams, parsexml, strtabs, xmltree
type
EInvalidXml* = object of E_Base ## exception that is raised for invalid XML
errors*: seq[string] ## all detected parsing errors
EInvalidXml* = object of EInvalidValue ## exception that is raised
## for invalid XML
errors*: seq[string] ## all detected parsing errors
proc raiseInvalidXml(errors: seq[string]) =
var e: ref EInvalidXml

View File

@@ -244,7 +244,7 @@ proc nimIntToStr(x: int): string {.compilerRtl.} =
proc nimFloatToStr(x: float): string {.compilerproc.} =
var buf: array [0..59, char]
c_sprintf(buf, "%#g", x)
c_sprintf(buf, "%#.16e", x)
return $buf
proc nimInt64ToStr(x: int64): string {.compilerRtl.} =

View File

@@ -32,7 +32,7 @@ type
filename*: string # filename of the source file; without extension
basedir*: string # base directory (where to put the documentation)
modDesc*: PRope # module description
dependsOn*: PRope # dependencies
deps*: PRope # dependencies
id*: int # for generating IDs
splitAfter*: int # split too long entries in the TOC
tocPart*: seq[TTocEntry]
@@ -755,6 +755,19 @@ proc renderRstToOut(d: PDoc, n: PRstNode): PRope =
proc checkForFalse(n: PNode): bool =
result = n.kind == nkIdent and IdentEq(n.ident, "false")
proc getModuleFile(n: PNode): string =
case n.kind
of nkStrLit, nkRStrLit, nkTripleStrLit: result = n.strVal
of nkIdent: result = n.ident.s
of nkSym: result = n.sym.name.s
else:
internalError(n.info, "getModuleFile()")
result = ""
proc traceDeps(d: PDoc, n: PNode) =
if d.deps != nil: app(d.deps, ", ")
app(d.deps, getModuleFile(n))
proc generateDoc(d: PDoc, n: PNode) =
if n == nil: return
case n.kind
@@ -783,6 +796,9 @@ proc generateDoc(d: PDoc, n: PNode) =
# generate documentation for the first branch only:
if not checkForFalse(n.sons[0].sons[0]):
generateDoc(d, lastSon(n.sons[0]))
of nkImportStmt:
for i in 0 .. sonsLen(n)-1: traceDeps(d, n.sons[i])
of nkFromStmt: traceDeps(d, n.sons[0])
else: nil
proc genSection(d: PDoc, kind: TSymKind) =
@@ -817,12 +833,14 @@ proc genOutFile(d: PDoc): PRope =
if d.hasToc: bodyname = "doc.body_toc"
else: bodyname = "doc.body_no_toc"
content = ropeFormatNamedVars(getConfigVar(bodyname), ["title",
"tableofcontents", "moduledesc", "date", "time", "content"], [title, toc,
d.modDesc, toRope(getDateStr()), toRope(getClockStr()), code])
if not (optCompileOnly in gGlobalOptions):
"tableofcontents", "moduledesc", "deps", "date", "time", "content"],
[title, toc, d.modDesc, d.deps, toRope(getDateStr()),
toRope(getClockStr()), code])
if optCompileOnly notin gGlobalOptions:
code = ropeFormatNamedVars(getConfigVar("doc.file"), ["title",
"tableofcontents", "moduledesc", "date", "time", "content", "author",
"version"], [title, toc, d.modDesc, toRope(getDateStr()),
"tableofcontents", "moduledesc", "deps", "date", "time",
"content", "author", "version"],
[title, toc, d.modDesc, d.deps, toRope(getDateStr()),
toRope(getClockStr()), content, d.meta[metaAuthor],
d.meta[metaVersion]])
else: