From 17ce01c3e1268a6bdcc4504aa2d0591e6047bd7f Mon Sep 17 00:00:00 2001 From: Araq Date: Wed, 17 Sep 2014 10:04:36 +0200 Subject: some progress on documentation building --- koch.nim | 13 ++-- lib/impure/ssl.nim | 32 ++++---- lib/wrappers/openssl.nim | 4 +- tests/metatype/ttypeclasses.nim | 15 ++++ tools/nimweb.nim | 164 ++++++++++++++++++++-------------------- web/news.txt | 4 +- 6 files changed, 121 insertions(+), 111 deletions(-) diff --git a/koch.nim b/koch.nim index ad1a4b910..b7a32a1b4 100644 --- a/koch.nim +++ b/koch.nim @@ -40,7 +40,7 @@ Possible Commands: boot [options] bootstraps with given command line options install [dir] installs to given directory clean cleans Nimrod project; removes generated files - web generates the website + web [options] generates the website csource [options] builds the C sources for installation zip builds the installation ZIP package inno [options] builds the Inno Setup installer (for Windows) @@ -105,8 +105,8 @@ proc install(args: string) = exec("sh ./install.sh $#" % args) proc web(args: string) = - exec("$# cc -r tools/nimweb.nim web/nim --putenv:nimversion=$#" % - [findNim(), NimVersion]) + exec("$# cc -r tools/nimweb.nim $# web/nim --putenv:nimversion=$#" % + [findNim(), args, NimVersion]) # -------------- boot --------------------------------------------------------- @@ -298,7 +298,7 @@ proc temp(args: string) = if args.len > 0: exec(finalDest & " " & args) proc showHelp() = - quit(HelpText % [NimrodVersion & repeatChar(44-len(NimrodVersion)), + quit(HelpText % [NimVersion & repeatChar(44-len(NimVersion)), CompileDate, CompileTime]) var op = initOptParser() @@ -306,7 +306,7 @@ op.next() case op.kind of cmdLongOption, cmdShortOption: showHelp() of cmdArgument: - case normalize(op.key) + case normalize(op.key) of "boot": boot(op.cmdLineRest) of "clean": clean(op.cmdLineRest) of "web": web(op.cmdLineRest) @@ -315,7 +315,7 @@ of cmdArgument: of "inno": inno(op.cmdLineRest) of "install": install(op.cmdLineRest) of "test", "tests": tests(op.cmdLineRest) - of "update": + of "update": when defined(withUpdate): update(op.cmdLineRest) else: @@ -323,4 +323,3 @@ of cmdArgument: of "temp": temp(op.cmdLineRest) else: showHelp() of cmdEnd: showHelp() - diff --git a/lib/impure/ssl.nim b/lib/impure/ssl.nim index cae9990b9..bb7cfc0d3 100644 --- a/lib/impure/ssl.nim +++ b/lib/impure/ssl.nim @@ -15,24 +15,24 @@ import openssl, strutils, os type - TSecureSocket* {.final.} = object - ssl: PSSL - bio: PBIO + TSecureSocket* = object + ssl: SslPtr + bio: BIO proc connect*(sock: var TSecureSocket, address: string, - port: int): Int = + port: int): int = ## Connects to the specified `address` on the specified `port`. ## Returns the result of the certificate validation. SslLoadErrorStrings() ERR_load_BIO_strings() if SSL_library_init() != 1: - OSError() + raiseOSError(osLastError()) var ctx = SSL_CTX_new(SSLv23_client_method()) if ctx == nil: ERR_print_errors_fp(stderr) - OSError() + raiseOSError(osLastError()) #if SSL_CTX_load_verify_locations(ctx, # "/tmp/openssl-0.9.8e/certs/vsign1.pem", NIL) == 0: @@ -41,14 +41,14 @@ proc connect*(sock: var TSecureSocket, address: string, sock.bio = BIO_new_ssl_connect(ctx) if BIO_get_ssl(sock.bio, addr(sock.ssl)) == 0: - OSError() + raiseOSError(osLastError()) if BIO_set_conn_hostname(sock.bio, address & ":" & $port) != 1: - OSError() + raiseOSError(osLastError()) if BIO_do_connect(sock.bio) <= 0: ERR_print_errors_fp(stderr) - OSError() + raiseOSError(osLastError()) result = SSL_get_verify_result(sock.ssl) @@ -57,30 +57,30 @@ proc recvLine*(sock: TSecureSocket, line: var TaintedString): bool = ## Returns false when no data is available to be read. ## `Line` must be initialized and not nil! setLen(line.string, 0) - while True: + while true: var c: array[0..0, char] var n = BIO_read(sock.bio, c, c.len.cint) - if n <= 0: return False + if n <= 0: return false if c[0] == '\r': n = BIO_read(sock.bio, c, c.len.cint) if n > 0 and c[0] == '\L': - return True + return true elif n <= 0: - return False - elif c[0] == '\L': return True + return false + elif c[0] == '\L': return true add(line.string, c) proc send*(sock: TSecureSocket, data: string) = ## Writes `data` to the socket. if BIO_write(sock.bio, data, data.len.cint) <= 0: - OSError() + raiseOSError(osLastError()) proc close*(sock: TSecureSocket) = ## Closes the socket if BIO_free(sock.bio) <= 0: ERR_print_errors_fp(stderr) - OSError() + raiseOSError(osLastError()) when isMainModule: var s: TSecureSocket diff --git a/lib/wrappers/openssl.nim b/lib/wrappers/openssl.nim index 7f24507ba..a668f3526 100644 --- a/lib/wrappers/openssl.nim +++ b/lib/wrappers/openssl.nim @@ -480,7 +480,7 @@ proc hexStr (buf:cstring): string = for i in 0 .. <16: result.add toHex(buf[i].ord, 2).toLower -proc md5_File* (file: string): string {.raises:[EIO,Ebase].} = +proc md5_File* (file: string): string {.raises: [IOError,Exception].} = ## Generate MD5 hash for a file. Result is a 32 character # hex string with lowercase characters (like the output # of `md5sum` @@ -500,7 +500,7 @@ proc md5_File* (file: string): string {.raises:[EIO,Ebase].} = result = hexStr(buf) -proc md5_Str* (str:string): string {.raises:[EIO].} = +proc md5_Str* (str:string): string {.raises:[IOError].} = ##Generate MD5 hash for a string. Result is a 32 character #hex string with lowercase characters var diff --git a/tests/metatype/ttypeclasses.nim b/tests/metatype/ttypeclasses.nim index 677229868..db9db7713 100644 --- a/tests/metatype/ttypeclasses.nim +++ b/tests/metatype/ttypeclasses.nim @@ -1,3 +1,18 @@ +discard """ + output: '''12 +1xxx +true0 +12 +testtest +1010 +11string +testtest1 +seq +seq +seq +foo seq +foo of numeric'''""" + type TFoo[T] = object val: T diff --git a/tools/nimweb.nim b/tools/nimweb.nim index 8744a250e..a98a27a13 100644 --- a/tools/nimweb.nim +++ b/tools/nimweb.nim @@ -1,7 +1,7 @@ # # # Nim Website Generator -# (c) Copyright 2012 Andreas Rumpf +# (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -13,14 +13,14 @@ import type TKeyValPair = tuple[key, id, val: string] - TConfigData = object of TObject + TConfigData = object of RootObj tabs, links: seq[TKeyValPair] doc, srcdoc, srcdoc2, webdoc, pdf: seq[string] authors, projectName, projectTitle, logo, infile, outdir, ticker: string - vars: PStringTable - nimrodArgs: string + vars: StringTableRef + nimArgs: string gitCommit: string - quotations: TTable[string, tuple[quote, author: string]] + quotations: Table[string, tuple[quote, author: string]] numProcessors: int # Set by parallelBuild:n, only works for values > 0. TRssItem = object year, month, day, title: string @@ -35,7 +35,7 @@ proc initConfigData(c: var TConfigData) = c.pdf = @[] c.infile = "" c.outdir = "" - c.nimrodArgs = "--hint[Conf]:off " + c.nimArgs = "--hint[Conf]:off " c.authors = "" c.projectTitle = "" c.projectName = "" @@ -58,7 +58,7 @@ const version = "0.7" usage = "nimweb - Nim Website Generator Version " & version & """ - (c) 2012 Andreas Rumpf + (c) 2014 Andreas Rumpf Usage: nimweb [options] ini-file[.ini] [compile_options] Options: @@ -112,7 +112,7 @@ proc parseCmdLine(c: var TConfigData) = case kind of cmdArgument: c.infile = addFileExt(key, "ini") - c.nimrodArgs.add(cmdLineRest(p)) + c.nimArgs.add(cmdLineRest(p)) break of cmdLongOption, cmdShortOption: case normalize(key) @@ -127,7 +127,7 @@ proc parseCmdLine(c: var TConfigData) = try: let num = parseInt(val) if num != 0: c.numProcessors = num - except EInvalidValue: + except ValueError: quit("invalid numeric value for --parallelBuild") of "var": var idx = val.find('=') @@ -155,68 +155,65 @@ proc addFiles(s: var seq[string], dir, ext: string, patterns: seq[string]) = proc parseIniFile(c: var TConfigData) = var - p: TCfgParser + p: CfgParser section: string # current section var input = newFileStream(c.infile, fmRead) - if input != nil: - open(p, input, c.infile) - while true: - var k = next(p) - case k.kind - of cfgEof: break - of cfgSectionStart: - section = normalize(k.section) - case section - of "project", "links", "tabs", "ticker", "documentation", "var": discard - else: echo("[Warning] Skipping unknown section: " & section) - - of cfgKeyValuePair: - var v = k.value % c.vars - c.vars[k.key] = v - - case section - of "project": - case normalize(k.key) - of "name": c.projectName = v - of "title": c.projectTitle = v - of "logo": c.logo = v - of "authors": c.authors = v - else: quit(errorStr(p, "unknown variable: " & k.key)) - of "var": discard - of "links": - let valID = v.split(';') - add(c.links, (k.key.replace('_', ' '), valID[1], valID[0])) - of "tabs": add(c.tabs, (k.key, "", v)) - of "ticker": c.ticker = v - of "documentation": - case normalize(k.key) - of "doc": addFiles(c.doc, "doc", ".txt", split(v, {';'})) - of "pdf": addFiles(c.pdf, "doc", ".txt", split(v, {';'})) - of "srcdoc": addFiles(c.srcdoc, "lib", ".nim", split(v, {';'})) - of "srcdoc2": addFiles(c.srcdoc2, "lib", ".nim", split(v, {';'})) - of "webdoc": addFiles(c.webdoc, "lib", ".nim", split(v, {';'})) - of "parallelbuild": - try: - let num = parseInt(v) - if num != 0: c.numProcessors = num - except EInvalidValue: - quit("invalid numeric value for --parallelBuild in config") - else: quit(errorStr(p, "unknown variable: " & k.key)) - of "quotations": - let vSplit = v.split('-') - doAssert vSplit.len == 2 - c.quotations[k.key.normalize] = (vSplit[0], vSplit[1]) - else: discard - - of cfgOption: quit(errorStr(p, "syntax error")) - of cfgError: quit(errorStr(p, k.msg)) - close(p) - if c.projectName.len == 0: - c.projectName = changeFileExt(extractFilename(c.infile), "") - if c.outdir.len == 0: - c.outdir = splitFile(c.infile).dir - else: - quit("cannot open: " & c.infile) + if input == nil: quit("cannot open: " & c.infile) + open(p, input, c.infile) + while true: + var k = next(p) + case k.kind + of cfgEof: break + of cfgSectionStart: + section = normalize(k.section) + case section + of "project", "links", "tabs", "ticker", "documentation", "var": discard + else: echo("[Warning] Skipping unknown section: " & section) + + of cfgKeyValuePair: + var v = k.value % c.vars + c.vars[k.key] = v + + case section + of "project": + case normalize(k.key) + of "name": c.projectName = v + of "title": c.projectTitle = v + of "logo": c.logo = v + of "authors": c.authors = v + else: quit(errorStr(p, "unknown variable: " & k.key)) + of "var": discard + of "links": + let valID = v.split(';') + add(c.links, (k.key.replace('_', ' '), valID[1], valID[0])) + of "tabs": add(c.tabs, (k.key, "", v)) + of "ticker": c.ticker = v + of "documentation": + case normalize(k.key) + of "doc": addFiles(c.doc, "doc", ".txt", split(v, {';'})) + of "pdf": addFiles(c.pdf, "doc", ".txt", split(v, {';'})) + of "srcdoc": addFiles(c.srcdoc, "lib", ".nim", split(v, {';'})) + of "srcdoc2": addFiles(c.srcdoc2, "lib", ".nim", split(v, {';'})) + of "webdoc": addFiles(c.webdoc, "lib", ".nim", split(v, {';'})) + of "parallelbuild": + try: + let num = parseInt(v) + if num != 0: c.numProcessors = num + except ValueError: + quit("invalid numeric value for --parallelBuild in config") + else: quit(errorStr(p, "unknown variable: " & k.key)) + of "quotations": + let vSplit = v.split('-') + doAssert vSplit.len == 2 + c.quotations[k.key.normalize] = (vSplit[0], vSplit[1]) + else: discard + of cfgOption: quit(errorStr(p, "syntax error")) + of cfgError: quit(errorStr(p, k.msg)) + close(p) + if c.projectName.len == 0: + c.projectName = changeFileExt(extractFilename(c.infile), "") + if c.outdir.len == 0: + c.outdir = splitFile(c.infile).dir # Ugly hack to override git command output when building private repo. if c.vars.hasKey("githash"): let githash = c.vars["githash"].strip @@ -238,8 +235,7 @@ proc mexec(cmds: openarray[string], processors: int) = if processors < 2: sexec(cmds) return - - if 0 != execProcesses(cmds, {poStdErrToStdOut, poParentStreams, poEchoCmd}): + if execProcesses(cmds, {poStdErrToStdOut, poParentStreams, poEchoCmd}) != 0: echo "external program failed, retrying serial work queue for logs!" sexec(cmds) @@ -251,9 +247,9 @@ proc buildDocSamples(c: var TConfigData, destPath: string) = ## documentation builders. const src = "doc"/"docgen_sample.nim" exec("nim doc $# -o:$# $#" % - [c.nimrodArgs, destPath / "docgen_sample.html", src]) + [c.nimArgs, destPath / "docgen_sample.html", src]) exec("nim doc2 $# -o:$# $#" % - [c.nimrodArgs, destPath / "docgen_sample2.html", src]) + [c.nimArgs, destPath / "docgen_sample2.html", src]) proc buildDoc(c: var TConfigData, destPath: string) = # call nim for the documentation: @@ -262,17 +258,17 @@ proc buildDoc(c: var TConfigData, destPath: string) = i = 0 for d in items(c.doc): commands[i] = "nim rst2html $# --docSeeSrcUrl:$# -o:$# --index:on $#" % - [c.nimrodArgs, c.gitCommit, + [c.nimArgs, c.gitCommit, destPath / changeFileExt(splitFile(d).name, "html"), d] i.inc for d in items(c.srcdoc): commands[i] = "nim doc $# --docSeeSrcUrl:$# -o:$# --index:on $#" % - [c.nimrodArgs, c.gitCommit, + [c.nimArgs, c.gitCommit, destPath / changeFileExt(splitFile(d).name, "html"), d] i.inc for d in items(c.srcdoc2): commands[i] = "nim doc2 $# --docSeeSrcUrl:$# -o:$# --index:on $#" % - [c.nimrodArgs, c.gitCommit, + [c.nimArgs, c.gitCommit, destPath / changeFileExt(splitFile(d).name, "html"), d] i.inc @@ -284,7 +280,7 @@ proc buildPdfDoc(c: var TConfigData, destPath: string) = echo "pdflatex not found; no PDF documentation generated" else: for d in items(c.pdf): - exec("nim rst2tex $# $#" % [c.nimrodArgs, d]) + exec("nim rst2tex $# $#" % [c.nimArgs, d]) # call LaTeX twice to get cross references right: exec("pdflatex " & changeFileExt(d, "tex")) exec("pdflatex " & changeFileExt(d, "tex")) @@ -303,7 +299,7 @@ proc buildAddDoc(c: var TConfigData, destPath: string) = var commands = newSeq[string](c.webdoc.len) for i, doc in pairs(c.webdoc): commands[i] = "nim doc $# --docSeeSrcUrl:$# -o:$# $#" % - [c.nimrodArgs, c.gitCommit, + [c.nimArgs, c.gitCommit, destPath / changeFileExt(splitFile(doc).name, "html"), doc] mexec(commands, c.numProcessors) @@ -311,7 +307,7 @@ proc parseNewsTitles(inputFilename: string): seq[TRssItem] = # parses the file for titles and returns them as TRssItem blocks. let reYearMonthDayTitle = re(rYearMonthDayTitle) var - input: TFile + input: File line = "" result = @[] @@ -347,7 +343,7 @@ proc genNewsLink(title: string): string = proc generateRss(outputFilename: string, news: seq[TRssItem]) = # Given a list of rss items generates an rss overwriting destination. var - output: TFile + output: File if not open(output, outputFilename, mode = fmWrite): quit("Could not write to $1 for rss generation" % [outputFilename]) @@ -396,19 +392,19 @@ proc main(c: var TConfigData) = if c.ticker.len > 0: try: c.ticker = readFile("web" / c.ticker) - except EIO: + except IOError: quit("[Error] cannot open: " & c.ticker) for i in 0..c.tabs.len-1: var file = c.tabs[i].val let rss = if file in ["news", "index"]: extractFilename(rssUrl) else: "" - exec(cmd % [c.nimrodArgs, file]) + exec(cmd % [c.nimArgs, file]) var temp = "web" / changeFileExt(file, "temp") var content: string try: content = readFile(temp) - except EIO: + except IOError: quit("[Error] cannot open: " & temp) - var f: TFile + var f: File var outfile = "web/upload/$#.html" % file if not existsDir("web/upload"): createDir("web/upload") diff --git a/web/news.txt b/web/news.txt index 2c6ef4196..93cb71f94 100644 --- a/web/news.txt +++ b/web/news.txt @@ -104,7 +104,7 @@ the use of an ``await`` macro which behaves similar to C#'s await. The following is a very simple chat server demonstrating Nimrod's new async capabilities. -.. code-block::nimrod +.. code-block::nim import asyncnet, asyncdispatch var clients: seq[PAsyncSocket] = @[] @@ -137,7 +137,7 @@ Syntactic sugar for anonymous procedures has also been introduced. It too has been implemented as a macro. The following shows some simple usage of the new syntax: -.. code-block::nimrod +.. code-block::nim import future var s = @[1, 2, 3, 4, 5] -- cgit 1.4.1-2-gfad0