From 9787797d15d281ce1dd792d247fac043c72dc769 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 20 Nov 2018 03:01:04 -0600 Subject: [PATCH 001/593] Initial version --- .gitignore | 5 + LICENSE | 21 +++++ README.md | 73 +++++++++++++++ config.nims | 1 + nimterop.nimble | 16 ++++ nimterop/ast.nim | 218 +++++++++++++++++++++++++++++++++++++++++++ nimterop/cimport.nim | 149 +++++++++++++++++++++++++++++ nimterop/getters.nim | 39 ++++++++ nimterop/globals.nim | 28 ++++++ nimterop/lisp.nim | 69 ++++++++++++++ tests/include/test.c | 33 +++++++ tests/include/test.h | 36 +++++++ tests/tnimterop.nim | 39 ++++++++ toast.nim | 99 ++++++++++++++++++++ 14 files changed, 826 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md create mode 100644 config.nims create mode 100644 nimterop.nimble create mode 100644 nimterop/ast.nim create mode 100644 nimterop/cimport.nim create mode 100644 nimterop/getters.nim create mode 100644 nimterop/globals.nim create mode 100644 nimterop/lisp.nim create mode 100644 tests/include/test.c create mode 100644 tests/include/test.h create mode 100644 tests/tnimterop.nim create mode 100644 toast.nim diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..04d0b79 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +nimcache +*.exe +*.swp +test* +toast diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..69dd3a7 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 Ganesh Viswanathan + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..b82ba54 --- /dev/null +++ b/README.md @@ -0,0 +1,73 @@ +Nimterop is a [Nim](https://nim-lang.org/) package that aims to make C/C++ interop seamless + +Nim has one of the best FFI you can find - importing C/C++ is supported out of the box. All you need to provide is type and proc definitions for Nim to interop with C/C++ binaries. Generation of these wrappers is easy for simple libraries but quickly gets out of hand. [c2nim](https://github.com/nim-lang/c2nim) greatly helps here by parsing and converting C/C++ into Nim but is limited due to the complex and constantly evolving C/C++ grammar. [nimgen](https://github.com/genotrance/nimgen) mainly focuses on automating the wrapping process and fills some holes but is again limited to c2nim's capabilities. + +The goal of nimterop is to leverage the [tree-sitter](http://tree-sitter.github.io/tree-sitter/) engine to parse C/C++ code and then convert relevant portions of the AST into Nim definitions using compile-time macros. [tree-sitter](https://github.com/tree-sitter) is a Github sponsored project that can parse a variety of languages into an AST which is then leveraged by the [Atom](https://atom.io/) editor for syntax highlighting and code folding. The advantages of this approach are multifold: +- Benefit from the tree-sitter community's investment into language parsing +- Leverage Nim macros which are a user API and relatively stable +- Avoid depending on Nim compiler API which is evolving constantly + +The nimterop feature set is still limited when compared with c2nim. Supported language constructs include: +- `#define NAME VALUE` where `VALUE` is a number (int, float, hex) +- `struct X`, `typedef struct`, `enum X`, `typedef enum` +- Functions with primitive types, structs, enums and typedef structs/enums as params and return values + +Given the simplicity and success of this approach so far, it seems feasible to continue on for more complex code. The goal is to make interop seamless so nimterop will focus on wrapping headers and not the outright conversion of C/C++ implementation. + +C++ constructs are still TBD depending on the results of the C interop. + +__Installation__ + +Nimterop can be installed via [Nimble](https://github.com/nim-lang/nimble): + +``` +> nimble install http://github.com/genotrance/nimtreesitter?subdir=treesitter +> nimble install http://github.com/genotrance/nimtreesitter?subdir=treesitter_c +> nimble install http://github.com/genotrance/nimtreesitter?subdir=treesitter_cpp + +> nimble install http://github.com/genotrance/nimterop +``` + +This will download and install nimterop in the standard Nimble package location, typically ~/.nimble. Once installed, it can be imported into any Nim program. + +__Usage__ + +```nim +import nimterop/cimport + +cDebug() +cDefine("HAS_ABC") +cDefine("HAS_ABC", "DEF") +cIncludeDir("clib/include") +cImport("clib.h") + +cCompile("clib/src/*.c") +``` + +__Documentation__ + +Detailed documentation is still forthcoming. + +`cDebug()` - enable debug messages + +`cDefine()` - `#define` an identifer that is forwarded to the compiler using `{.passC: "-DXXX".}` as well as _eventually_ used in processing `#ifdef` statements + +`cIncludeDir()` - add an include directory that is forwarded to the compiler using `{.passC: "-IXXX".}` as well as searched for files included using `cImport()` statements and following `cIncludeDir()` statements + +`cImport()` - import all supported definitions from specific import header file + +__Implementation Details__ + +In order to use the tree-sitter C library at compile-time, it has to be compiled into a separate binary called `toast` (to AST) since the Nim VM doesn't yet support FFI. `toast` takes a C/C++ file and runs it through the tree-sitter API which returns an AST data structure. This is then printed out to stdout in a Lisp S-Expression format. + +The `cImport()` proc runs `toast` on the specified header file and parses the resulting S-Expression back into an AST data structure at compile time. This AST is then processed to generate the relevant Nim definitions to interop with the code accordingly. A few other helper procs are provided to influence this process. + +The tree-sitter library is limited as well - it may fail on some advanced language constructs but is designed to handle them gracefully since it is expected to have bad code while actively typing in an editor. When an error is detected, tree-sitter includes an ERROR node at that location in the AST. At this time, `cImport()` will complain and continue if it encounters any errors. Depending on how severe the errors are, compilation may succeed or fail. Glaring issues will be communicated to the tree-sitter team but their goals may not always align with those of this project. + +__Credits__ + +Nimterop depends on [tree-sitter](http://tree-sitter.github.io/tree-sitter/) and all licensing terms of [tree-sitter](https://github.com/tree-sitter/tree-sitter/blob/master/LICENSE) apply to the usage of this package. Interestingly, the tree-sitter functionality is [wrapped](https://github.com/genotrance/nimtreesitter) using c2nim and nimgen at this time. Depending on the success of this project, those could perhaps be bootstrapped using nimterop eventually. + +__Feedback__ + +Nimterop is a work in progress and any feedback or suggestions are welcome. It is hosted on [GitHub](https://github.com/genotrance/nimterop) with an MIT license so issues, forks and PRs are most appreciated. diff --git a/config.nims b/config.nims new file mode 100644 index 0000000..8c8044e --- /dev/null +++ b/config.nims @@ -0,0 +1 @@ +switch("gcc.linkerexe", "g++") \ No newline at end of file diff --git a/nimterop.nimble b/nimterop.nimble new file mode 100644 index 0000000..6ec3afa --- /dev/null +++ b/nimterop.nimble @@ -0,0 +1,16 @@ +# Package + +version = "0.1.0" +author = "genotrance" +description = "C/C++ interop for Nim" +license = "MIT" + +bin = @["toast"] +installDirs = @["nimterop"] + +# Dependencies + +requires "nim >= 0.19.0", "treesitter >= 0.1.0", "treesitter_c >= 0.1.0", "treesitter_cpp >= 0.1.0", "regex >= 0.10.0" + +task test, "Test": + exec "nim c -r tests/tnimterop" diff --git a/nimterop/ast.nim b/nimterop/ast.nim new file mode 100644 index 0000000..7f977a7 --- /dev/null +++ b/nimterop/ast.nim @@ -0,0 +1,218 @@ +import macros, os, strformat + +import regex + +import getters, globals + +proc addReorder*(): NimNode = + result = newNimNode(nnkStmtList) + if not gReorder: + gReorder = true + result.add parseStmt( + "{.experimental: \"codeReordering\".}" + ) + +proc addHeader*(fullpath: string) = + gCurrentHeader = ("header" & fullpath.splitFile().name.replace(re"[-.]+", "")) + gConstStr &= &" {gCurrentHeader} = \"{fullpath}\" # addHeader()\n" + +# +# Preprocessor +# + +proc preprocDef(node: Ast) = + if node.children.len() == 2: + let + name = getNodeValIf(node.children[0], "identifier") + val = getNodeValIf(node.children[1], "preproc_arg") + + if name.nBl and val.nBl and name notin gConsts: + gConsts.add(name) + if val.getType().nBl: + # #define NAME VALUE + gConstStr &= &" {name.getIdentifier()}* = {val} # preprocDef()\n" + +# +# Types +# + +proc typeScan(node: Ast, sym, identifier, offset: string): string = + if node.sym != sym or node.children.len() != 2: + return + + let + pname = getNodeValIf(node.children[1], identifier) + ptyp = getNodeValIf(node.children[0], "primitive_type") + ttyp = getNodeValIf(node.children[0], "type_identifier") + + if pname.len() == 0: + return + elif ptyp.nBl: + result = &"{offset}{pname.getIdentifier()}: {ptyp.getType()}" + elif ttyp.nBl: + result = &"{offset}{pname.getIdentifier()}: {ttyp}" + elif node.children[0].sym in ["struct_specifier", "enum_specifier"] and node.children[0].children.len() == 1: + let styp = getNodeValIf(node.children[0].children[0], "type_identifier") + if styp.nBl: + result = &"{offset}{pname.getIdentifier()}: {styp}" + else: + return + +proc structSpecifier(node: Ast, name = "") = + var stmt: string + if node.children.len() == 1 and name notin gTypes: + case node.children[0].sym: + of "type_identifier": + let typ = getNodeValIf(node.children[0], "type_identifier") + if typ.nBl: + # typedef struct X Y + gTypes.add(name) + gTypeStr &= &" {name}* = {typ} #1 structSpecifier()\n" + + of "field_declaration_list": + # typedef struct { fields } X + stmt = &" {name}* {{.importc: \"{name}\", header: {gCurrentHeader}, bycopy.}} = object #2 structSpecifier()\n" + + for field in node.children[0].children: + let ts = typeScan(field, "field_declaration", "field_identifier", " ") + if ts.len() == 0: + return + stmt &= ts & "\n" + + gTypes.add(name) + gTypeStr &= stmt + elif name.len() == 0 and node.children.len() == 2 and node.children[1].sym == "field_declaration_list": + let ename = getNodeValIf(node.children[0], "type_identifier") + if ename.nBl and ename notin gTypes: + # struct X { fields } + stmt &= &" {ename}* {{.importc: \"struct {ename}\", header: {gCurrentHeader}, bycopy.}} = object #3 structSpecifier()\n" + + for field in node.children[1].children: + let ts = typeScan(field, "field_declaration", "field_identifier", " ") + if ts.len() == 0: + return + stmt &= ts & "\n" + + gTypes.add(name) + gTypeStr &= stmt + +proc enumSpecifier(node: Ast, name = "") = + var + ename: string + elid: int + stmt: string + + if node.children.len() == 1 and node.children[0].sym == "enumerator_list": + # typedef enum { fields } X + ename = name + elid = 0 + stmt = &" {name}* = enum #1 enumSpecifier()\n" + elif name.len() == 0 and node.children.len() == 2 and node.children[1].sym == "enumerator_list": + ename = getNodeValIf(node.children[0], "type_identifier") + elid = 1 + if ename.nBl: + # enum X { fields } + stmt = &" {ename}* = enum #2 enumSpecifier()\n" + else: + return + + for field in node.children[elid].children: + if field.sym == "enumerator": + let fname = getNodeValIf(field.children[0], "identifier") + if field.children.len() == 1: + stmt &= &" {fname}\n" + elif field.children.len() == 2 and field.children[1].sym == "number_literal": + let num = getNodeValIf(field.children[1], "number_literal") + stmt &= &" {fname} = {num}\n" + else: + return + + if ename notin gTypes: + gTypes.add(name) + gTypeStr &= stmt + +proc typeDefinition(node: Ast) = + if node.children.len() == 2: + let + name = getNodeValIf(node.children[1], "type_identifier") + ptyp = getNodeValIf(node.children[0], "primitive_type") + ttyp = getNodeValIf(node.children[0], "type_identifier") + + if name.nBl and name notin gTypes: + if ptyp.nBl: + # typedef int X + gTypes.add(name) + gTypeStr &= &" {name}* = {ptyp.getType()} #1 typeDefinition()\n" + elif ttyp.nBl: + # typedef X Y + gTypes.add(name) + gTypeStr &= &" {name}* = {ttyp} #2 typeDefinition()\n" + else: + case node.children[0].sym: + of "struct_specifier": + structSpecifier(node.children[0], name) + of "enum_specifier": + enumSpecifier(node.children[0], name) + +proc functionDeclarator(node: Ast, typ: string) = + if node.children.len() == 2: + let + name = getNodeValIf(node.children[0], "identifier") + + if name.nBl and name notin gProcs and node.children[1].sym == "parameter_list": + # typ function(typ param1, ...) + var stmt = &"# functionDeclarator()\nproc {name}*(" + + for i in 0 .. node.children[1].children.len()-1: + let ts = typeScan(node.children[1].children[i], "parameter_declaration", "identifier", "") + if ts.len() == 0: + return + stmt &= ts + if i != node.children[1].children.len()-1: + stmt &= ", " + + if typ != "void": + stmt &= &"): {typ.getType()} " + else: + stmt &= ") " + + stmt &= &"{{.importc: \"{name}\", header: {gCurrentHeader}.}}\n" + + gProcs.add(name) + gProcStr &= stmt + +proc declaration*(node: Ast) = + if node.children.len() == 2 and node.children[1].sym == "function_declarator": + let + ptyp = getNodeValIf(node.children[0], "primitive_type") + ttyp = getNodeValIf(node.children[0], "type_identifier") + + if ptyp.nBl: + functionDeclarator(node.children[1], ptyp.getType()) + elif ttyp.nBl: + functionDeclarator(node.children[1], ttyp) + elif node.children[0].sym == "struct_specifier" and node.children[0].children.len() == 1: + let styp = getNodeValIf(node.children[0].children[0], "type_identifier") + if styp.nBl: + functionDeclarator(node.children[1], styp) + +proc genNimAst*(node: Ast) = + case node.sym: + of "ERROR": + let (line, col) = getLineCol(node) + echo &"Potentially invalid syntax at line {line} column {col}" + of "preproc_def": + preprocDef(node) + of "type_definition": + typeDefinition(node) + of "declaration": + declaration(node) + of "struct_specifier": + if node.parent.sym notin ["type_definition", "declaration"]: + structSpecifier(node) + of "enum_specifier": + if node.parent.sym notin ["type_definition", "declaration"]: + enumSpecifier(node) + + for child in node.children: + genNimAst(child) diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim new file mode 100644 index 0000000..8a1f299 --- /dev/null +++ b/nimterop/cimport.nim @@ -0,0 +1,149 @@ +import macros, os, strformat, strutils + +import ast, getters, globals, lisp + +proc search(path: string): string = + result = joinPath(getProjectPath(), path).replace("\\", "/") + if not fileExists(result) and not dirExists(result): + result = path + if not fileExists(result) and not dirExists(result): + var found = false + for inc in gIncludeDirs: + result = inc & "/" & path + if fileExists(result) or dirExists(result): + found = true + break + if not found: + echo "File or directory not found: " & path + quit(1) + +macro cDebug*(): untyped = + gDebug = true + +macro cDefine*(name: static[string], val: static[string] = ""): untyped = + result = newNimNode(nnkStmtList) + + var str = "-D" & name + if val.nBl: + str &= "=\"" & val & "\"" + + result.add(quote do: + {.passC: `str`.} + ) + + if gDebug: + echo result.repr + +macro cIncludeDir*(dir: static[string]): untyped = + result = newNimNode(nnkStmtList) + + let fullpath = search(dir) + gIncludeDirs.add(fullpath) + + let str = "-I\"" & fullpath & "\"" + result.add(quote do: + {.passC: `str`.} + ) + + if gDebug: + echo result.repr + +macro cIncludeC*(): untyped = + result = newNimNode(nnkStmtList) + + var + inc = false + for line in getGccPaths().splitLines(): + if "#include <...> search starts here" in line: + inc = true + continue + elif "End of search list" in line: + break + + if inc: + if gDebug: + echo "Including " & line.strip() + gIncludeDirs.add(line.strip()) + +macro cCompile*(path: static[string]): untyped = + result = newNimNode(nnkStmtList) + + var + stmt = "" + flags = "" + + proc fcompile(file: string): string = + let fn = file.splitFile().name + var + ufn = fn + uniq = 1 + while ufn in gCompile: + ufn = fn & $uniq + uniq += 1 + + gCompile.add(ufn) + if fn == ufn: + return "{.compile: \"$#\".}" % file.replace("\\", "/") + else: + return "{.compile: (\"../$#\", \"$#.o\").}" % [file.replace("\\", "/"), ufn] + + proc dcompile(dir: string) = + for f in walkFiles(dir): + stmt &= fcompile(f) & "\n" + + if path.contains("*") or path.contains("?"): + dcompile(path) + else: + let fpath = search(path) + if fileExists(fpath): + stmt &= fcompile(fpath) & "\n" + elif dirExists(fpath): + if flags.contains("cpp"): + for i in @["*.C", "*.cpp", "*.c++", "*.cc", "*.cxx"]: + dcompile(fpath / i) + else: + dcompile(fpath / "*.c") + + result.add stmt.parseStmt() + + if gDebug: + echo result.repr + +macro cImport*(filename: static[string]): untyped = + result = newNimNode(nnkStmtList) + result.add addReorder() + + let + fullpath = search(filename) + root = parseLisp(fullpath) + + echo "Importing " & fullpath + + gCode = staticRead(fullpath) + gConstStr = "" + gTypeStr = "" + + addHeader(fullpath) + genNimAst(root) + + if gConstStr.nBl: + if gDebug: + echo "const\n" & gConstStr + result.add parseStmt( + "const\n" & gConstStr + ) + + if gTypeStr.nBl: + if gDebug: + echo "type\n" & gTypeStr + result.add parseStmt( + "type\n" & gTypeStr + ) + + if gProcStr.nBl: + if gDebug: + echo gProcStr + result.add gProcStr.parseStmt() + + if gDebug: + echo result.repr \ No newline at end of file diff --git a/nimterop/getters.nim b/nimterop/getters.nim new file mode 100644 index 0000000..b65d800 --- /dev/null +++ b/nimterop/getters.nim @@ -0,0 +1,39 @@ +import macros, strutils + +import regex + +import globals + +proc getIdentifier*(str: string): string = + result = str.strip(chars={'_'}) + +proc getType*(str: string): string = + result = str.strip(chars={'_'}).replace(re"([u]?int[\d]+)_t", "$1") + +proc getLit*(str: string): string = + if str.contains(re"^[\-]?[\d]+$") or + str.contains(re"^[\-]?[\d]*\.[\d]+$") or + str.contains(re"^0x[\d]+$"): + return str + +proc getNodeValIf*(node: Ast, esym: string): string = + if esym != node.sym: + return + + return gCode[node.start .. node.stop-1].strip() + +proc getGccPaths*(mode = "c"): string = + let + nul = when defined(Windows): "nul" else: "/dev/null" + + return staticExec("gcc -Wp,-v -x" & mode & " " & nul) + +proc getLineCol*(node: Ast): tuple[line, col: int] = + result.line = 1 + result.col = 1 + echo gCode[node.start .. node.stop-1] + for i in 0 .. node.start-1: + if gCode[i] == '\n': + result.col = 0 + result.line += 1 + result.col += 1 \ No newline at end of file diff --git a/nimterop/globals.nim b/nimterop/globals.nim new file mode 100644 index 0000000..bc113af --- /dev/null +++ b/nimterop/globals.nim @@ -0,0 +1,28 @@ +import macros + +type + Ast* = object + sym*: string + start*, stop*: int + parent*: ptr Ast + children*: seq[Ast] + +var + gDefines* {.compiletime.}: seq[string] + gCompile* {.compiletime.}: seq[string] + gConsts* {.compiletime.}: seq[string] + gHeaders* {.compiletime.}: seq[string] + gIncludeDirs* {.compiletime.}: seq[string] + gProcs* {.compiletime.}: seq[string] + gTypes* {.compiletime.}: seq[string] + + gCode* {.compiletime.}: string + gConstStr* {.compiletime.}: string + gCurrentHeader* {.compiletime.}: string + gDebug* {.compiletime.}: bool + gReorder* {.compiletime.}: bool + gProcStr* {.compiletime.}: string + gTypeStr* {.compiletime.}: string + +template nBl*(s: untyped): untyped = + (s.len() != 0) \ No newline at end of file diff --git a/nimterop/lisp.nim b/nimterop/lisp.nim new file mode 100644 index 0000000..a472a54 --- /dev/null +++ b/nimterop/lisp.nim @@ -0,0 +1,69 @@ +import strutils + +import regex + +import globals + +var + gTokens {.compiletime.}: seq[string] + idx {.compiletime.} = 0 + +proc tokenize(fullpath: string) = + var collect = "" + + gTokens = @[] + idx = 0 + for i in staticExec("toast " & fullpath): + case i: + of ' ', '\n', '\r', ')': + if collect.nBl: + gTokens.add(collect) + collect = "" + if i == ')': + gTokens.add(")") + of '(': + gTokens.add("(") + else: + collect &= $i + +proc readFromTokens(): Ast = + if idx == gTokens.len(): + echo "Bad AST" + quit(1) + + if gTokens[idx] == "(": + if gTokens.len() - idx < 2: + echo "Corrupt AST" + quit(1) + result.sym = gTokens[idx+1] + result.start = gTokens[idx+2].parseInt() + result.stop = gTokens[idx+3].parseInt() + idx += 4 + result.children = @[] + while gTokens[idx] != ")": + var res = readFromTokens() + if res.sym.nBl: + res.parent = addr result + result.children.add(res) + idx += 1 + return + elif gTokens[idx] == ")": + echo "Poor AST" + quit(1) + + idx += 1 + +proc printAst*(node: Ast, offset=""): string = + result = offset & "(" & node.sym & " " & $node.start & " " & $node.stop + if node.children.len() != 0: + result &= "\n" + for child in node.children: + result &= printAst(child, offset & " ") + result &= offset & ")\n" + else: + result &= ")\n" + +proc parseLisp*(fullpath: string): Ast = + tokenize(fullpath) + + return readFromTokens() diff --git a/tests/include/test.c b/tests/include/test.c new file mode 100644 index 0000000..8d801b7 --- /dev/null +++ b/tests/include/test.c @@ -0,0 +1,33 @@ +#include "test.h" + +int test_call_int() { + return 5; +} + +struct STRUCT1 test_call_int_param(int param1) { + struct STRUCT1 s; + + s.field1 = param1; + + return s; +} + +STRUCT2 test_call_int_param2(int param1, STRUCT2 param2) { + STRUCT2 s; + + s.field1 = param1 + param2.field1; + + return s; +} + +STRUCT2 test_call_int_param3(int param1, struct STRUCT1 param2) { + STRUCT2 s; + + s.field1 = param1 + param2.field1; + + return s; +} + +ENUM2 test_call_int_param4(enum ENUM param1) { + return enum4; +} \ No newline at end of file diff --git a/tests/include/test.h b/tests/include/test.h new file mode 100644 index 0000000..60d1660 --- /dev/null +++ b/tests/include/test.h @@ -0,0 +1,36 @@ +#include + +#define TEST_INT 512 +#define TEST_FLOAT 5.12 +#define TEST_HEX 0x512 + +typedef uint8_t PRIMTYPE; +typedef PRIMTYPE CUSTTYPE; + +struct STRUCT1 { + int field1; +}; + +typedef struct STRUCT1 STRUCT2; + +typedef struct { + int field1; +} STRUCT3; + +enum ENUM { + enum1, + enum2, + enum3 +}; + +typedef enum { + enum4 = 3, + enum5, + enum6 +} ENUM2; + +int test_call_int(); +struct STRUCT1 test_call_int_param(int param1); +STRUCT2 test_call_int_param2(int param1, STRUCT2 param2); +STRUCT2 test_call_int_param3(int param1, struct STRUCT1 param2); +ENUM2 test_call_int_param4(enum ENUM param1); \ No newline at end of file diff --git a/tests/tnimterop.nim b/tests/tnimterop.nim new file mode 100644 index 0000000..77419ea --- /dev/null +++ b/tests/tnimterop.nim @@ -0,0 +1,39 @@ +import nimterop/cimport +import macros + +cDebug() + +cIncludeDir("include") +cCompile("test.c") +cImport("test.h") + +assert TEST_INT == 512 +assert TEST_FLOAT == 5.12 +assert TEST_HEX == 0x512 + +var + pt: PRIMTYPE + ct: CUSTTYPE + + s: STRUCT1 + s2: STRUCT2 + s3: STRUCT3 + + e: ENUM + e2: ENUM2 = enum5 + +pt = 3 +ct = 4 + +s.field1 = 5 +s2.field1 = 6 +s3.field1 = 7 + +e = enum1 +e2 = enum4 + +assert test_call_int() == 5 +assert test_call_int_param(5).field1 == 5 +assert test_call_int_param2(5, s2).field1 == 11 +assert test_call_int_param3(5, s).field1 == 10 +assert test_call_int_param4(e) == e2 \ No newline at end of file diff --git a/toast.nim b/toast.nim new file mode 100644 index 0000000..c2f2a3b --- /dev/null +++ b/toast.nim @@ -0,0 +1,99 @@ +import os, strutils + +import regex + +import treesitter/[runtime, c, cpp] + +const HELP = """ +> toast header.h +""" + +proc printLisp(root: TSNode, data: var string) = + var + node = root + nextnode: TSNode + depth = 0 + + while true: + if not node.tsNodeIsNull(): + stdout.write spaces(depth) & "(" & $node.tsNodeType() & " " & $node.tsNodeStartByte() & " " & $node.tsNodeEndByte() + + if node.tsNodeNamedChildCount() != 0: + echo "" + nextnode = node.tsNodeNamedChild(0) + depth += 1 + else: + echo ")" + nextnode = node.tsNodeNextNamedSibling() + + if nextnode.tsNodeIsNull(): + while true: + node = node.tsNodeParent() + depth -= 1 + echo spaces(depth) & ")" + if node == root: + break + if not node.tsNodeNextNamedSibling().tsNodeIsNull(): + node = node.tsNodeNextNamedSibling() + break + else: + node = nextnode + + if node == root: + break + +proc process(path: string, mode="") = + if not existsFile(path): + echo "Invalid path " & path + return + + var + parser = tsParserNew() + ext = path.splitFile().ext + pmode = "" + data = readFile(path) + + defer: + parser.tsParserDelete() + + if mode.len() != 0: + pmode = mode + elif ext in [".h", ".c"]: + pmode = "c" + elif ext in [".hxx", ".hpp", ".hh", ".H", ".h++", ".cpp", ".cxx", ".cc", ".C", ".c++"]: + pmode = "cpp" + + if "cplusplus" in data or "extern \"C\"" in data: + pmode = "cpp" + + if pmode == "c": + if not parser.tsParserSetLanguage(treeSitterC()): + echo "Failed to load C parser" + quit() + elif pmode == "cpp": + if not parser.tsParserSetLanguage(treeSitterCpp()): + echo "Failed to load C++ parser" + quit() + else: + echo "Invalid parser " & mode + quit() + + var + tree = parser.tsParserParseString(nil, data.cstring, data.len().uint32) + root = tree.tsTreeRootNode() + + defer: + tree.tsTreeDelete() + + printLisp(root, data) + +proc parseCli() = + let params = commandLineParams() + for param in params: + if param in ["-h", "--help", "-?", "/?", "/h"]: + echo HELP + quit() + else: + process(param) + +parseCli() \ No newline at end of file From 4ace90476b77e08bb54414ec5131f11f894eca78 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 20 Nov 2018 03:08:23 -0600 Subject: [PATCH 002/593] Tests directory reference --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index b82ba54..95d4207 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,8 @@ cImport("clib.h") cCompile("clib/src/*.c") ``` +Refer to the ```tests``` directory for examples on how the library can be used. + __Documentation__ Detailed documentation is still forthcoming. From b6ca0a815a5a651ed90b2150fdda5ecf1bac9632 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 20 Nov 2018 16:49:14 -0600 Subject: [PATCH 003/593] Use references, reduce RAM usage --- nimterop.nimble | 3 +++ nimterop/ast.nim | 18 ++++++++++-------- nimterop/getters.nim | 4 ++-- nimterop/globals.nim | 4 ++-- nimterop/lisp.nim | 13 ++++++------- 5 files changed, 23 insertions(+), 19 deletions(-) diff --git a/nimterop.nimble b/nimterop.nimble index 6ec3afa..b3def89 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -14,3 +14,6 @@ requires "nim >= 0.19.0", "treesitter >= 0.1.0", "treesitter_c >= 0.1.0", "trees task test, "Test": exec "nim c -r tests/tnimterop" + +task testext, "Test": + exec "nim c -r tests/tnimteropext" diff --git a/nimterop/ast.nim b/nimterop/ast.nim index 7f977a7..1a30ad7 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -20,7 +20,7 @@ proc addHeader*(fullpath: string) = # Preprocessor # -proc preprocDef(node: Ast) = +proc preprocDef(node: ref Ast) = if node.children.len() == 2: let name = getNodeValIf(node.children[0], "identifier") @@ -36,7 +36,7 @@ proc preprocDef(node: Ast) = # Types # -proc typeScan(node: Ast, sym, identifier, offset: string): string = +proc typeScan(node: ref Ast, sym, identifier, offset: string): string = if node.sym != sym or node.children.len() != 2: return @@ -58,7 +58,7 @@ proc typeScan(node: Ast, sym, identifier, offset: string): string = else: return -proc structSpecifier(node: Ast, name = "") = +proc structSpecifier(node: ref Ast, name = "") = var stmt: string if node.children.len() == 1 and name notin gTypes: case node.children[0].sym: @@ -96,7 +96,7 @@ proc structSpecifier(node: Ast, name = "") = gTypes.add(name) gTypeStr &= stmt -proc enumSpecifier(node: Ast, name = "") = +proc enumSpecifier(node: ref Ast, name = "") = var ename: string elid: int @@ -131,7 +131,7 @@ proc enumSpecifier(node: Ast, name = "") = gTypes.add(name) gTypeStr &= stmt -proc typeDefinition(node: Ast) = +proc typeDefinition(node: ref Ast) = if node.children.len() == 2: let name = getNodeValIf(node.children[1], "type_identifier") @@ -154,7 +154,7 @@ proc typeDefinition(node: Ast) = of "enum_specifier": enumSpecifier(node.children[0], name) -proc functionDeclarator(node: Ast, typ: string) = +proc functionDeclarator(node: ref Ast, typ: string) = if node.children.len() == 2: let name = getNodeValIf(node.children[0], "identifier") @@ -181,7 +181,7 @@ proc functionDeclarator(node: Ast, typ: string) = gProcs.add(name) gProcStr &= stmt -proc declaration*(node: Ast) = +proc declaration*(node: ref Ast) = if node.children.len() == 2 and node.children[1].sym == "function_declarator": let ptyp = getNodeValIf(node.children[0], "primitive_type") @@ -196,7 +196,7 @@ proc declaration*(node: Ast) = if styp.nBl: functionDeclarator(node.children[1], styp) -proc genNimAst*(node: Ast) = +proc genNimAst*(node: ref Ast) = case node.sym: of "ERROR": let (line, col) = getLineCol(node) @@ -213,6 +213,8 @@ proc genNimAst*(node: Ast) = of "enum_specifier": if node.parent.sym notin ["type_definition", "declaration"]: enumSpecifier(node) + of "": + return for child in node.children: genNimAst(child) diff --git a/nimterop/getters.nim b/nimterop/getters.nim index b65d800..dd6ca40 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -16,7 +16,7 @@ proc getLit*(str: string): string = str.contains(re"^0x[\d]+$"): return str -proc getNodeValIf*(node: Ast, esym: string): string = +proc getNodeValIf*(node: ref Ast, esym: string): string = if esym != node.sym: return @@ -28,7 +28,7 @@ proc getGccPaths*(mode = "c"): string = return staticExec("gcc -Wp,-v -x" & mode & " " & nul) -proc getLineCol*(node: Ast): tuple[line, col: int] = +proc getLineCol*(node: ref Ast): tuple[line, col: int] = result.line = 1 result.col = 1 echo gCode[node.start .. node.stop-1] diff --git a/nimterop/globals.nim b/nimterop/globals.nim index bc113af..9802417 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -4,8 +4,8 @@ type Ast* = object sym*: string start*, stop*: int - parent*: ptr Ast - children*: seq[Ast] + parent*: ref Ast + children*: seq[ref Ast] var gDefines* {.compiletime.}: seq[string] diff --git a/nimterop/lisp.nim b/nimterop/lisp.nim index a472a54..83f9e4f 100644 --- a/nimterop/lisp.nim +++ b/nimterop/lisp.nim @@ -26,7 +26,7 @@ proc tokenize(fullpath: string) = else: collect &= $i -proc readFromTokens(): Ast = +proc readFromTokens(): ref Ast = if idx == gTokens.len(): echo "Bad AST" quit(1) @@ -35,6 +35,7 @@ proc readFromTokens(): Ast = if gTokens.len() - idx < 2: echo "Corrupt AST" quit(1) + result = new(Ast) result.sym = gTokens[idx+1] result.start = gTokens[idx+2].parseInt() result.stop = gTokens[idx+3].parseInt() @@ -42,18 +43,16 @@ proc readFromTokens(): Ast = result.children = @[] while gTokens[idx] != ")": var res = readFromTokens() - if res.sym.nBl: - res.parent = addr result + if not res.isNil() and res.sym.nBl: + res.parent = result result.children.add(res) - idx += 1 - return elif gTokens[idx] == ")": echo "Poor AST" quit(1) idx += 1 -proc printAst*(node: Ast, offset=""): string = +proc printAst*(node: ref Ast, offset=""): string = result = offset & "(" & node.sym & " " & $node.start & " " & $node.stop if node.children.len() != 0: result &= "\n" @@ -63,7 +62,7 @@ proc printAst*(node: Ast, offset=""): string = else: result &= ")\n" -proc parseLisp*(fullpath: string): Ast = +proc parseLisp*(fullpath: string): ref Ast = tokenize(fullpath) return readFromTokens() From 882b38f4f642b4d351836f1f1f9645a46b3e7610 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 20 Nov 2018 17:02:37 -0600 Subject: [PATCH 004/593] Fix typedef struct X X --- nimterop/ast.nim | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/nimterop/ast.nim b/nimterop/ast.nim index 1a30ad7..474c918 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -28,7 +28,7 @@ proc preprocDef(node: ref Ast) = if name.nBl and val.nBl and name notin gConsts: gConsts.add(name) - if val.getType().nBl: + if val.getLit().nBl: # #define NAME VALUE gConstStr &= &" {name.getIdentifier()}* = {val} # preprocDef()\n" @@ -65,13 +65,17 @@ proc structSpecifier(node: ref Ast, name = "") = of "type_identifier": let typ = getNodeValIf(node.children[0], "type_identifier") if typ.nBl: - # typedef struct X Y gTypes.add(name) - gTypeStr &= &" {name}* = {typ} #1 structSpecifier()\n" + if name != typ: + # typedef struct X Y + gTypeStr &= &" {name}* = {typ} #1 structSpecifier()\n" + else: + # typedef struct X X + gTypeStr &= &" {name}* {{.importc: \"{name}\", header: {gCurrentHeader}, bycopy.}} = object #2 structSpecifier()\n" of "field_declaration_list": # typedef struct { fields } X - stmt = &" {name}* {{.importc: \"{name}\", header: {gCurrentHeader}, bycopy.}} = object #2 structSpecifier()\n" + stmt = &" {name}* {{.importc: \"{name}\", header: {gCurrentHeader}, bycopy.}} = object #3 structSpecifier()\n" for field in node.children[0].children: let ts = typeScan(field, "field_declaration", "field_identifier", " ") @@ -85,7 +89,7 @@ proc structSpecifier(node: ref Ast, name = "") = let ename = getNodeValIf(node.children[0], "type_identifier") if ename.nBl and ename notin gTypes: # struct X { fields } - stmt &= &" {ename}* {{.importc: \"struct {ename}\", header: {gCurrentHeader}, bycopy.}} = object #3 structSpecifier()\n" + stmt &= &" {ename}* {{.importc: \"struct {ename}\", header: {gCurrentHeader}, bycopy.}} = object #4 structSpecifier()\n" for field in node.children[1].children: let ts = typeScan(field, "field_declaration", "field_identifier", " ") From 63585e889ecfaf6f99148696986a1ac1fa85f60d Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 20 Nov 2018 22:56:30 -0600 Subject: [PATCH 005/593] Add git support --- README.md | 2 + nimterop/getters.nim | 1 - nimterop/git.nim | 94 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 nimterop/git.nim diff --git a/README.md b/README.md index 95d4207..4df46fc 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,8 @@ Detailed documentation is still forthcoming. `cImport()` - import all supported definitions from specific import header file +`gitPull()` - pull a git repository prior to C/C++ interop + __Implementation Details__ In order to use the tree-sitter C library at compile-time, it has to be compiled into a separate binary called `toast` (to AST) since the Nim VM doesn't yet support FFI. `toast` takes a C/C++ file and runs it through the tree-sitter API which returns an AST data structure. This is then printed out to stdout in a Lisp S-Expression format. diff --git a/nimterop/getters.nim b/nimterop/getters.nim index dd6ca40..d31034a 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -31,7 +31,6 @@ proc getGccPaths*(mode = "c"): string = proc getLineCol*(node: ref Ast): tuple[line, col: int] = result.line = 1 result.col = 1 - echo gCode[node.start .. node.stop-1] for i in 0 .. node.start-1: if gCode[i] == '\n': result.col = 0 diff --git a/nimterop/git.nim b/nimterop/git.nim new file mode 100644 index 0000000..f06e9ba --- /dev/null +++ b/nimterop/git.nim @@ -0,0 +1,94 @@ +import macros, os, regex, strformat, strutils + +import globals + +proc execAction*(cmd: string): string = + var + ccmd = "" + ret = 0 + when defined(Windows): + ccmd = "cmd /c " & cmd + when defined(Linux) or defined(MacOSX): + ccmd = "bash -c '" & cmd & "'" + + (result, ret) = gorgeEx(ccmd) + if ret != 0: + echo "Command failed: " & $ret + echo ccmd + echo result + quit(1) + +macro extractZip*(zipfile, outdir: static[string]): untyped = + var cmd = "unzip -o $#" + if defined(Windows): + cmd = "powershell -nologo -noprofile -command \"& { Add-Type -A " & + "'System.IO.Compression.FileSystem'; " & + "[IO.Compression.ZipFile]::ExtractToDirectory('$#', '.'); }\"" + + echo "Extracting " & zipfile + discard execAction(&"cd \"{getProjectPath()/outdir}\" && " & cmd % zipfile) + +macro downloadUrl*(url, outdir: static[string]): untyped = + let + file = url.extractFilename() + ext = file.splitFile().ext.toLowerAscii() + + var cmd = "curl $# -o $#" + if defined(Windows): + cmd = "powershell wget $# -OutFile $#" + + if not (ext == ".zip" and fileExists(getProjectPath()/outdir/file)): + echo "Downloading " & file + discard execAction(cmd % [url, getProjectPath()/outdir/file]) + + if ext == ".zip": + discard quote do: + extractZip(`file`, `outdir`) + +macro gitReset*(outdir: static[string]): untyped = + echo "Resetting " & outdir + + let cmd = &"cd \"{getProjectPath()/outdir}\" && git reset --hard" + while execAction(cmd).contains("Permission denied"): + sleep(1000) + echo " Retrying ..." + +macro gitCheckout*(file, outdir: static[string]): untyped = + echo "Resetting " & file + + let cmd = &"cd \"{getProjectPath()/outdir}\" && git checkout $#" % file.replace(outdir & "/", "") + while execAction(cmd).contains("Permission denied"): + sleep(500) + echo " Retrying ..." + +macro gitPull*(url: static[string], outdirN = "", plistN = "", checkoutN = ""): untyped = + let + outdir = getProjectPath()/outdirN.strVal() + plist = plistN.strVal() + checkout = checkoutN.strVal() + + if dirExists(outdir/".git"): + discard quote do: + gitReset(`outdirN`) + return + else: + echo execAction(&"mkdir \"{outdir}\"") + + echo "Setting up Git repo: " & url + discard execAction(&"cd \"{outdir}\" && git init .") + discard execAction(&"cd \"{outdir}\" && git remote add origin " & url) + + if plist.len() != 0: + let sparsefile = &"{outdir}/.git/info/sparse-checkout" + + discard execAction(&"cd \"{outdir}\" && git config core.sparsecheckout true") + writeFile(sparsefile, plist) + echo "Wrote" + + if checkout.len() != 0: + echo "Checking out " & checkout + discard execAction(&"cd \"{outdir}\" && git pull --tags origin master") + discard execAction(&"cd \"{outdir}\" && git checkout {checkout}") + else: + echo "Pulling repository" + discard execAction(&"cd \"{outdir}\" && git pull --depth=1 origin master") From 047e33868f4523516b4b88742d29905dbe702e45 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 21 Nov 2018 11:41:47 -0600 Subject: [PATCH 006/593] Filter out comment nodes --- nimterop/lisp.nim | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/nimterop/lisp.nim b/nimterop/lisp.nim index 83f9e4f..4a0b71d 100644 --- a/nimterop/lisp.nim +++ b/nimterop/lisp.nim @@ -35,12 +35,13 @@ proc readFromTokens(): ref Ast = if gTokens.len() - idx < 2: echo "Corrupt AST" quit(1) - result = new(Ast) - result.sym = gTokens[idx+1] - result.start = gTokens[idx+2].parseInt() - result.stop = gTokens[idx+3].parseInt() + if gTokens[idx+1] != "comment": + result = new(Ast) + result.sym = gTokens[idx+1] + result.start = gTokens[idx+2].parseInt() + result.stop = gTokens[idx+3].parseInt() + result.children = @[] idx += 4 - result.children = @[] while gTokens[idx] != ")": var res = readFromTokens() if not res.isNil() and res.sym.nBl: From 01c295a41c6f80e8999db07f9b07d29943f98040 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 21 Nov 2018 14:14:18 -0600 Subject: [PATCH 007/593] Initial pointer support, ugly toast --- nimterop/ast.nim | 54 +++++++++++++++++++++++--------------------- nimterop/getters.nim | 2 +- nimterop/lisp.nim | 10 ++++---- toast.nim | 22 ++++++++++++++---- 4 files changed, 51 insertions(+), 37 deletions(-) diff --git a/nimterop/ast.nim b/nimterop/ast.nim index 474c918..71ae9d1 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -14,12 +14,12 @@ proc addReorder*(): NimNode = proc addHeader*(fullpath: string) = gCurrentHeader = ("header" & fullpath.splitFile().name.replace(re"[-.]+", "")) - gConstStr &= &" {gCurrentHeader} = \"{fullpath}\" # addHeader()\n" + gConstStr &= &" {gCurrentHeader} = \"{fullpath}\" # addHeader()\n" # # Preprocessor # - + proc preprocDef(node: ref Ast) = if node.children.len() == 2: let @@ -30,7 +30,7 @@ proc preprocDef(node: ref Ast) = gConsts.add(name) if val.getLit().nBl: # #define NAME VALUE - gConstStr &= &" {name.getIdentifier()}* = {val} # preprocDef()\n" + gConstStr &= &" {name.getIdentifier()}* = {val} # preprocDef()\n" # # Types @@ -44,7 +44,7 @@ proc typeScan(node: ref Ast, sym, identifier, offset: string): string = pname = getNodeValIf(node.children[1], identifier) ptyp = getNodeValIf(node.children[0], "primitive_type") ttyp = getNodeValIf(node.children[0], "type_identifier") - + if pname.len() == 0: return elif ptyp.nBl: @@ -68,28 +68,28 @@ proc structSpecifier(node: ref Ast, name = "") = gTypes.add(name) if name != typ: # typedef struct X Y - gTypeStr &= &" {name}* = {typ} #1 structSpecifier()\n" + gTypeStr &= &" {name}* = {typ} #1 structSpecifier()\n" else: # typedef struct X X - gTypeStr &= &" {name}* {{.importc: \"{name}\", header: {gCurrentHeader}, bycopy.}} = object #2 structSpecifier()\n" + gTypeStr &= &" {name}* {{.importc: \"{name}\", header: {gCurrentHeader}, bycopy.}} = object #2 structSpecifier()\n" of "field_declaration_list": # typedef struct { fields } X - stmt = &" {name}* {{.importc: \"{name}\", header: {gCurrentHeader}, bycopy.}} = object #3 structSpecifier()\n" - + stmt = &" {name}* {{.importc: \"{name}\", header: {gCurrentHeader}, bycopy.}} = object #3 structSpecifier()\n" + for field in node.children[0].children: let ts = typeScan(field, "field_declaration", "field_identifier", " ") if ts.len() == 0: return stmt &= ts & "\n" - + gTypes.add(name) gTypeStr &= stmt elif name.len() == 0 and node.children.len() == 2 and node.children[1].sym == "field_declaration_list": let ename = getNodeValIf(node.children[0], "type_identifier") if ename.nBl and ename notin gTypes: # struct X { fields } - stmt &= &" {ename}* {{.importc: \"struct {ename}\", header: {gCurrentHeader}, bycopy.}} = object #4 structSpecifier()\n" + stmt &= &" {ename}* {{.importc: \"struct {ename}\", header: {gCurrentHeader}, bycopy.}} = object #4 structSpecifier()\n" for field in node.children[1].children: let ts = typeScan(field, "field_declaration", "field_identifier", " ") @@ -105,18 +105,18 @@ proc enumSpecifier(node: ref Ast, name = "") = ename: string elid: int stmt: string - + if node.children.len() == 1 and node.children[0].sym == "enumerator_list": # typedef enum { fields } X ename = name elid = 0 - stmt = &" {name}* = enum #1 enumSpecifier()\n" + stmt = &" {name}* = enum #1 enumSpecifier()\n" elif name.len() == 0 and node.children.len() == 2 and node.children[1].sym == "enumerator_list": ename = getNodeValIf(node.children[0], "type_identifier") elid = 1 if ename.nBl: # enum X { fields } - stmt = &" {ename}* = enum #2 enumSpecifier()\n" + stmt = &" {ename}* = enum #2 enumSpecifier()\n" else: return @@ -130,27 +130,31 @@ proc enumSpecifier(node: ref Ast, name = "") = stmt &= &" {fname} = {num}\n" else: return - + if ename notin gTypes: gTypes.add(name) gTypeStr &= stmt proc typeDefinition(node: ref Ast) = if node.children.len() == 2: - let + var name = getNodeValIf(node.children[1], "type_identifier") + pname = getNodeValIf(node.children[1], "pointer_declarator") ptyp = getNodeValIf(node.children[0], "primitive_type") ttyp = getNodeValIf(node.children[0], "type_identifier") - + + if name.len() == 0 and node.children[1].sym == "pointer_declarator" and node.children[1].children.len() == 1: + name = getNodeValIf(node.children[1].children[0], "type_identifier") + if name.nBl and name notin gTypes: if ptyp.nBl: # typedef int X gTypes.add(name) - gTypeStr &= &" {name}* = {ptyp.getType()} #1 typeDefinition()\n" + gTypeStr &= &" {name}* = {ptyp.getType()} #1 typeDefinition()\n" elif ttyp.nBl: # typedef X Y gTypes.add(name) - gTypeStr &= &" {name}* = {ttyp} #2 typeDefinition()\n" + gTypeStr &= &" {name}* = {ttyp} #2 typeDefinition()\n" else: case node.children[0].sym: of "struct_specifier": @@ -162,11 +166,11 @@ proc functionDeclarator(node: ref Ast, typ: string) = if node.children.len() == 2: let name = getNodeValIf(node.children[0], "identifier") - + if name.nBl and name notin gProcs and node.children[1].sym == "parameter_list": # typ function(typ param1, ...) var stmt = &"# functionDeclarator()\nproc {name}*(" - + for i in 0 .. node.children[1].children.len()-1: let ts = typeScan(node.children[1].children[i], "parameter_declaration", "identifier", "") if ts.len() == 0: @@ -174,17 +178,17 @@ proc functionDeclarator(node: ref Ast, typ: string) = stmt &= ts if i != node.children[1].children.len()-1: stmt &= ", " - + if typ != "void": stmt &= &"): {typ.getType()} " else: stmt &= ") " - + stmt &= &"{{.importc: \"{name}\", header: {gCurrentHeader}.}}\n" gProcs.add(name) gProcStr &= stmt - + proc declaration*(node: ref Ast) = if node.children.len() == 2 and node.children[1].sym == "function_declarator": let @@ -199,7 +203,7 @@ proc declaration*(node: ref Ast) = let styp = getNodeValIf(node.children[0].children[0], "type_identifier") if styp.nBl: functionDeclarator(node.children[1], styp) - + proc genNimAst*(node: ref Ast) = case node.sym: of "ERROR": @@ -217,8 +221,6 @@ proc genNimAst*(node: ref Ast) = of "enum_specifier": if node.parent.sym notin ["type_definition", "declaration"]: enumSpecifier(node) - of "": - return for child in node.children: genNimAst(child) diff --git a/nimterop/getters.nim b/nimterop/getters.nim index d31034a..1ad4733 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -8,7 +8,7 @@ proc getIdentifier*(str: string): string = result = str.strip(chars={'_'}) proc getType*(str: string): string = - result = str.strip(chars={'_'}).replace(re"([u]?int[\d]+)_t", "$1") + result = str.strip(chars={'_'}).replace(re"([u]?int[\d]+)_t", "$1").replace(re"^void$", "object") proc getLit*(str: string): string = if str.contains(re"^[\-]?[\d]+$") or diff --git a/nimterop/lisp.nim b/nimterop/lisp.nim index 4a0b71d..6e49197 100644 --- a/nimterop/lisp.nim +++ b/nimterop/lisp.nim @@ -13,16 +13,14 @@ proc tokenize(fullpath: string) = gTokens = @[] idx = 0 - for i in staticExec("toast " & fullpath): + for i in staticExec("toast -u " & fullpath): case i: - of ' ', '\n', '\r', ')': + of ' ', '\n', '\r', '(', ')': if collect.nBl: gTokens.add(collect) collect = "" - if i == ')': - gTokens.add(")") - of '(': - gTokens.add("(") + if i in ['(', ')']: + gTokens.add($i) else: collect &= $i diff --git a/toast.nim b/toast.nim index c2f2a3b..60f92d8 100644 --- a/toast.nim +++ b/toast.nim @@ -8,6 +8,9 @@ const HELP = """ > toast header.h """ +var + gPretty = true + proc printLisp(root: TSNode, data: var string) = var node = root @@ -16,21 +19,30 @@ proc printLisp(root: TSNode, data: var string) = while true: if not node.tsNodeIsNull(): - stdout.write spaces(depth) & "(" & $node.tsNodeType() & " " & $node.tsNodeStartByte() & " " & $node.tsNodeEndByte() + if gPretty: + stdout.write spaces(depth) + stdout.write "(" & $node.tsNodeType() & " " & $node.tsNodeStartByte() & " " & $node.tsNodeEndByte() if node.tsNodeNamedChildCount() != 0: - echo "" + if gPretty: + echo "" nextnode = node.tsNodeNamedChild(0) depth += 1 else: - echo ")" + if gPretty: + echo ")" + else: + stdout.write ")" nextnode = node.tsNodeNextNamedSibling() if nextnode.tsNodeIsNull(): while true: node = node.tsNodeParent() depth -= 1 - echo spaces(depth) & ")" + if gPretty: + echo spaces(depth) & ")" + else: + stdout.write ")" if node == root: break if not node.tsNodeNextNamedSibling().tsNodeIsNull(): @@ -93,6 +105,8 @@ proc parseCli() = if param in ["-h", "--help", "-?", "/?", "/h"]: echo HELP quit() + elif param == "-u": + gPretty = false else: process(param) From dc14ceca4c58383bd693bdf0e912fed7c0e3f4e6 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Wed, 21 Nov 2018 14:44:33 -0800 Subject: [PATCH 008/593] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 4df46fc..2ea23e9 100644 --- a/README.md +++ b/README.md @@ -21,9 +21,9 @@ __Installation__ Nimterop can be installed via [Nimble](https://github.com/nim-lang/nimble): ``` -> nimble install http://github.com/genotrance/nimtreesitter?subdir=treesitter -> nimble install http://github.com/genotrance/nimtreesitter?subdir=treesitter_c -> nimble install http://github.com/genotrance/nimtreesitter?subdir=treesitter_cpp +> nimble install "http://github.com/genotrance/nimtreesitter?subdir=treesitter" +> nimble install "http://github.com/genotrance/nimtreesitter?subdir=treesitter_c" +> nimble install "http://github.com/genotrance/nimtreesitter?subdir=treesitter_cpp" > nimble install http://github.com/genotrance/nimterop ``` From d0a6ca68338b69898e434d02e42ded7f0aa06719 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Wed, 21 Nov 2018 14:45:32 -0800 Subject: [PATCH 009/593] Update README.md --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 2ea23e9..db0d1fd 100644 --- a/README.md +++ b/README.md @@ -20,12 +20,12 @@ __Installation__ Nimterop can be installed via [Nimble](https://github.com/nim-lang/nimble): -``` -> nimble install "http://github.com/genotrance/nimtreesitter?subdir=treesitter" -> nimble install "http://github.com/genotrance/nimtreesitter?subdir=treesitter_c" -> nimble install "http://github.com/genotrance/nimtreesitter?subdir=treesitter_cpp" +```bash +nimble install "http://github.com/genotrance/nimtreesitter?subdir=treesitter" +nimble install "http://github.com/genotrance/nimtreesitter?subdir=treesitter_c" +nimble install "http://github.com/genotrance/nimtreesitter?subdir=treesitter_cpp" -> nimble install http://github.com/genotrance/nimterop +nimble install http://github.com/genotrance/nimterop ``` This will download and install nimterop in the standard Nimble package location, typically ~/.nimble. Once installed, it can be imported into any Nim program. From 8dad6c8b312b474b42fc71e4c8506b33b07b5ab0 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 21 Nov 2018 17:13:36 -0600 Subject: [PATCH 010/593] Mac support --- config.nims | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/config.nims b/config.nims index 8c8044e..32bbe5e 100644 --- a/config.nims +++ b/config.nims @@ -1 +1,4 @@ -switch("gcc.linkerexe", "g++") \ No newline at end of file +when defined(MacOSX): + switch("clang.linkerexe", "g++") +else: + switch("gcc.linkerexe", "g++") From c0481ac41c84bb34326058ad8db7cf74b35fcb82 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 21 Nov 2018 17:24:13 -0600 Subject: [PATCH 011/593] Use enums for sym, fail if no toast --- nimterop/ast.nim | 151 ++++++++++++++++++++++--------------------- nimterop/getters.nim | 2 +- nimterop/globals.nim | 15 ++++- nimterop/lisp.nim | 17 +++-- 4 files changed, 105 insertions(+), 80 deletions(-) diff --git a/nimterop/ast.nim b/nimterop/ast.nim index 71ae9d1..b825efe 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -20,30 +20,30 @@ proc addHeader*(fullpath: string) = # Preprocessor # -proc preprocDef(node: ref Ast) = +proc pPreprocDef(node: ref Ast) = if node.children.len() == 2: let - name = getNodeValIf(node.children[0], "identifier") - val = getNodeValIf(node.children[1], "preproc_arg") + name = getNodeValIf(node.children[0], identifier) + val = getNodeValIf(node.children[1], preproc_arg) if name.nBl and val.nBl and name notin gConsts: gConsts.add(name) if val.getLit().nBl: # #define NAME VALUE - gConstStr &= &" {name.getIdentifier()}* = {val} # preprocDef()\n" + gConstStr &= &" {name.getIdentifier()}* = {val} # pPreprocDef()\n" # # Types # -proc typeScan(node: ref Ast, sym, identifier, offset: string): string = +proc typeScan(node: ref Ast, sym, id: Sym, offset: string): string = if node.sym != sym or node.children.len() != 2: return let - pname = getNodeValIf(node.children[1], identifier) - ptyp = getNodeValIf(node.children[0], "primitive_type") - ttyp = getNodeValIf(node.children[0], "type_identifier") + pname = getNodeValIf(node.children[1], id) + ptyp = getNodeValIf(node.children[0], primitive_type) + ttyp = getNodeValIf(node.children[0], type_identifier) if pname.len() == 0: return @@ -51,48 +51,51 @@ proc typeScan(node: ref Ast, sym, identifier, offset: string): string = result = &"{offset}{pname.getIdentifier()}: {ptyp.getType()}" elif ttyp.nBl: result = &"{offset}{pname.getIdentifier()}: {ttyp}" - elif node.children[0].sym in ["struct_specifier", "enum_specifier"] and node.children[0].children.len() == 1: - let styp = getNodeValIf(node.children[0].children[0], "type_identifier") + elif node.children[0].sym in [struct_specifier, enum_specifier] and node.children[0].children.len() == 1: + let styp = getNodeValIf(node.children[0].children[0], type_identifier) if styp.nBl: result = &"{offset}{pname.getIdentifier()}: {styp}" else: return -proc structSpecifier(node: ref Ast, name = "") = +proc pStructSpecifier(node: ref Ast, name = "") = var stmt: string if node.children.len() == 1 and name notin gTypes: case node.children[0].sym: - of "type_identifier": - let typ = getNodeValIf(node.children[0], "type_identifier") + of type_identifier: + let typ = getNodeValIf(node.children[0], type_identifier) if typ.nBl: gTypes.add(name) if name != typ: # typedef struct X Y - gTypeStr &= &" {name}* = {typ} #1 structSpecifier()\n" + gTypeStr &= &" {name}* = {typ} #1 pStructSpecifier()\n" else: # typedef struct X X - gTypeStr &= &" {name}* {{.importc: \"{name}\", header: {gCurrentHeader}, bycopy.}} = object #2 structSpecifier()\n" + gTypeStr &= &" {name}* {{.importc: \"{name}\", header: {gCurrentHeader}, bycopy.}} = object #2 pStructSpecifier()\n" - of "field_declaration_list": + of field_declaration_list: # typedef struct { fields } X - stmt = &" {name}* {{.importc: \"{name}\", header: {gCurrentHeader}, bycopy.}} = object #3 structSpecifier()\n" + stmt = &" {name}* {{.importc: \"{name}\", header: {gCurrentHeader}, bycopy.}} = object #3 pStructSpecifier()\n" for field in node.children[0].children: - let ts = typeScan(field, "field_declaration", "field_identifier", " ") + let ts = typeScan(field, field_declaration, field_identifier, " ") if ts.len() == 0: return stmt &= ts & "\n" gTypes.add(name) gTypeStr &= stmt - elif name.len() == 0 and node.children.len() == 2 and node.children[1].sym == "field_declaration_list": - let ename = getNodeValIf(node.children[0], "type_identifier") + else: + discard + + elif name.len() == 0 and node.children.len() == 2 and node.children[1].sym == field_declaration_list: + let ename = getNodeValIf(node.children[0], type_identifier) if ename.nBl and ename notin gTypes: # struct X { fields } - stmt &= &" {ename}* {{.importc: \"struct {ename}\", header: {gCurrentHeader}, bycopy.}} = object #4 structSpecifier()\n" + stmt &= &" {ename}* {{.importc: \"struct {ename}\", header: {gCurrentHeader}, bycopy.}} = object #4 pStructSpecifier()\n" for field in node.children[1].children: - let ts = typeScan(field, "field_declaration", "field_identifier", " ") + let ts = typeScan(field, field_declaration, field_identifier, " ") if ts.len() == 0: return stmt &= ts & "\n" @@ -100,33 +103,33 @@ proc structSpecifier(node: ref Ast, name = "") = gTypes.add(name) gTypeStr &= stmt -proc enumSpecifier(node: ref Ast, name = "") = +proc pEnumSpecifier(node: ref Ast, name = "") = var ename: string elid: int stmt: string - if node.children.len() == 1 and node.children[0].sym == "enumerator_list": + if node.children.len() == 1 and node.children[0].sym == enumerator_list: # typedef enum { fields } X ename = name elid = 0 - stmt = &" {name}* = enum #1 enumSpecifier()\n" - elif name.len() == 0 and node.children.len() == 2 and node.children[1].sym == "enumerator_list": - ename = getNodeValIf(node.children[0], "type_identifier") + stmt = &" {name}* = enum #1 pEnumSpecifier()\n" + elif name.len() == 0 and node.children.len() == 2 and node.children[1].sym == enumerator_list: + ename = getNodeValIf(node.children[0], type_identifier) elid = 1 if ename.nBl: # enum X { fields } - stmt = &" {ename}* = enum #2 enumSpecifier()\n" + stmt = &" {ename}* = enum #2 pEnumSpecifier()\n" else: return for field in node.children[elid].children: - if field.sym == "enumerator": - let fname = getNodeValIf(field.children[0], "identifier") + if field.sym == enumerator: + let fname = getNodeValIf(field.children[0], identifier) if field.children.len() == 1: stmt &= &" {fname}\n" - elif field.children.len() == 2 and field.children[1].sym == "number_literal": - let num = getNodeValIf(field.children[1], "number_literal") + elif field.children.len() == 2 and field.children[1].sym == number_literal: + let num = getNodeValIf(field.children[1], number_literal) stmt &= &" {fname} = {num}\n" else: return @@ -135,44 +138,46 @@ proc enumSpecifier(node: ref Ast, name = "") = gTypes.add(name) gTypeStr &= stmt -proc typeDefinition(node: ref Ast) = +proc pTypeDefinition(node: ref Ast) = if node.children.len() == 2: var - name = getNodeValIf(node.children[1], "type_identifier") - pname = getNodeValIf(node.children[1], "pointer_declarator") - ptyp = getNodeValIf(node.children[0], "primitive_type") - ttyp = getNodeValIf(node.children[0], "type_identifier") + name = getNodeValIf(node.children[1], type_identifier) + pname = getNodeValIf(node.children[1], pointer_declarator) + ptyp = getNodeValIf(node.children[0], primitive_type) + ttyp = getNodeValIf(node.children[0], type_identifier) - if name.len() == 0 and node.children[1].sym == "pointer_declarator" and node.children[1].children.len() == 1: - name = getNodeValIf(node.children[1].children[0], "type_identifier") + if name.len() == 0 and node.children[1].sym == pointer_declarator and node.children[1].children.len() == 1: + name = getNodeValIf(node.children[1].children[0], type_identifier) if name.nBl and name notin gTypes: if ptyp.nBl: # typedef int X gTypes.add(name) - gTypeStr &= &" {name}* = {ptyp.getType()} #1 typeDefinition()\n" + gTypeStr &= &" {name}* = {ptyp.getType()} #1 pTypeDefinition()\n" elif ttyp.nBl: # typedef X Y gTypes.add(name) - gTypeStr &= &" {name}* = {ttyp} #2 typeDefinition()\n" + gTypeStr &= &" {name}* = {ttyp} #2 pTypeDefinition()\n" else: case node.children[0].sym: - of "struct_specifier": - structSpecifier(node.children[0], name) - of "enum_specifier": - enumSpecifier(node.children[0], name) + of struct_specifier: + pStructSpecifier(node.children[0], name) + of enum_specifier: + pEnumSpecifier(node.children[0], name) + else: + discard -proc functionDeclarator(node: ref Ast, typ: string) = +proc pFunctionDeclarator(node: ref Ast, typ: string) = if node.children.len() == 2: let - name = getNodeValIf(node.children[0], "identifier") + name = getNodeValIf(node.children[0], identifier) - if name.nBl and name notin gProcs and node.children[1].sym == "parameter_list": + if name.nBl and name notin gProcs and node.children[1].sym == parameter_list: # typ function(typ param1, ...) - var stmt = &"# functionDeclarator()\nproc {name}*(" + var stmt = &"# pFunctionDeclarator()\nproc {name}*(" for i in 0 .. node.children[1].children.len()-1: - let ts = typeScan(node.children[1].children[i], "parameter_declaration", "identifier", "") + let ts = typeScan(node.children[1].children[i], parameter_declaration, identifier, "") if ts.len() == 0: return stmt &= ts @@ -189,38 +194,40 @@ proc functionDeclarator(node: ref Ast, typ: string) = gProcs.add(name) gProcStr &= stmt -proc declaration*(node: ref Ast) = - if node.children.len() == 2 and node.children[1].sym == "function_declarator": +proc pDeclaration*(node: ref Ast) = + if node.children.len() == 2 and node.children[1].sym == function_declarator: let - ptyp = getNodeValIf(node.children[0], "primitive_type") - ttyp = getNodeValIf(node.children[0], "type_identifier") + ptyp = getNodeValIf(node.children[0], primitive_type) + ttyp = getNodeValIf(node.children[0], type_identifier) if ptyp.nBl: - functionDeclarator(node.children[1], ptyp.getType()) + pFunctionDeclarator(node.children[1], ptyp.getType()) elif ttyp.nBl: - functionDeclarator(node.children[1], ttyp) - elif node.children[0].sym == "struct_specifier" and node.children[0].children.len() == 1: - let styp = getNodeValIf(node.children[0].children[0], "type_identifier") + pFunctionDeclarator(node.children[1], ttyp) + elif node.children[0].sym == struct_specifier and node.children[0].children.len() == 1: + let styp = getNodeValIf(node.children[0].children[0], type_identifier) if styp.nBl: - functionDeclarator(node.children[1], styp) + pFunctionDeclarator(node.children[1], styp) proc genNimAst*(node: ref Ast) = case node.sym: - of "ERROR": + of ERROR: let (line, col) = getLineCol(node) echo &"Potentially invalid syntax at line {line} column {col}" - of "preproc_def": - preprocDef(node) - of "type_definition": - typeDefinition(node) - of "declaration": - declaration(node) - of "struct_specifier": - if node.parent.sym notin ["type_definition", "declaration"]: - structSpecifier(node) - of "enum_specifier": - if node.parent.sym notin ["type_definition", "declaration"]: - enumSpecifier(node) + of preproc_def: + pPreprocDef(node) + of type_definition: + pTypeDefinition(node) + of declaration: + pDeclaration(node) + of struct_specifier: + if node.parent.sym notin [type_definition, declaration]: + pStructSpecifier(node) + of enum_specifier: + if node.parent.sym notin [type_definition, declaration]: + pEnumSpecifier(node) + else: + discard for child in node.children: genNimAst(child) diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 1ad4733..b4f9df6 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -16,7 +16,7 @@ proc getLit*(str: string): string = str.contains(re"^0x[\d]+$"): return str -proc getNodeValIf*(node: ref Ast, esym: string): string = +proc getNodeValIf*(node: ref Ast, esym: Sym): string = if esym != node.sym: return diff --git a/nimterop/globals.nim b/nimterop/globals.nim index 9802417..6ace9f5 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -1,9 +1,20 @@ import macros type + Sym* = enum + ERROR, IGNORED, + enumerator, enumerator_list, enum_specifier, + declaration, + field_declaration, field_declaration_list, field_identifier, function_declarator, + identifier, + number_literal, + parameter_declaration, parameter_list, pointer_declarator, preproc_arg, preproc_def, primitive_type, + struct_specifier, + type_definition, type_identifier + Ast* = object - sym*: string - start*, stop*: int + sym*: Sym + start*, stop*: uint32 parent*: ref Ast children*: seq[ref Ast] diff --git a/nimterop/lisp.nim b/nimterop/lisp.nim index 6e49197..cf723b7 100644 --- a/nimterop/lisp.nim +++ b/nimterop/lisp.nim @@ -24,6 +24,10 @@ proc tokenize(fullpath: string) = else: collect &= $i + if gTokens.len() == 0: + echo "toast binary not installed - nimble install nimterop to force build" + quit(1) + proc readFromTokens(): ref Ast = if idx == gTokens.len(): echo "Bad AST" @@ -35,14 +39,17 @@ proc readFromTokens(): ref Ast = quit(1) if gTokens[idx+1] != "comment": result = new(Ast) - result.sym = gTokens[idx+1] - result.start = gTokens[idx+2].parseInt() - result.stop = gTokens[idx+3].parseInt() + try: + result.sym = parseEnum[Sym](gTokens[idx+1]) + except: + result.sym = IGNORED + result.start = gTokens[idx+2].parseInt().uint32 + result.stop = gTokens[idx+3].parseInt().uint32 result.children = @[] idx += 4 while gTokens[idx] != ")": var res = readFromTokens() - if not res.isNil() and res.sym.nBl: + if not res.isNil(): res.parent = result result.children.add(res) elif gTokens[idx] == ")": @@ -52,7 +59,7 @@ proc readFromTokens(): ref Ast = idx += 1 proc printAst*(node: ref Ast, offset=""): string = - result = offset & "(" & node.sym & " " & $node.start & " " & $node.stop + result = offset & "(" & $node.sym & " " & $node.start & " " & $node.stop if node.children.len() != 0: result &= "\n" for child in node.children: From ca7b37bb056a6413bfb8ed342a19941b3b3cfd81 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Wed, 21 Nov 2018 15:25:51 -0800 Subject: [PATCH 012/593] simplify install --- README.md | 5 +++++ nimterop.nimble | 15 +++++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index db0d1fd..f77debe 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,11 @@ nimble install "http://github.com/genotrance/nimtreesitter?subdir=treesitter_cpp nimble install http://github.com/genotrance/nimterop ``` +or: +```bash +git clone http://github.com/genotrance/nimterop && cd nimterop +nimble installWithDeps +``` This will download and install nimterop in the standard Nimble package location, typically ~/.nimble. Once installed, it can be imported into any Nim program. diff --git a/nimterop.nimble b/nimterop.nimble index b3def89..128e2a6 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -12,8 +12,19 @@ installDirs = @["nimterop"] requires "nim >= 0.19.0", "treesitter >= 0.1.0", "treesitter_c >= 0.1.0", "treesitter_cpp >= 0.1.0", "regex >= 0.10.0" +proc execCmd(cmd:string)= + echo cmd + exec cmd + task test, "Test": - exec "nim c -r tests/tnimterop" + execCmd "nim c -r tests/tnimterop" task testext, "Test": - exec "nim c -r tests/tnimteropext" + execCmd "nim c -r tests/tnimteropext" + +task installWithDeps, "install dependencies": + for a in ["http://github.com/genotrance/nimtreesitter?subdir=treesitter", + "http://github.com/genotrance/nimtreesitter?subdir=treesitter_c", + "http://github.com/genotrance/nimtreesitter?subdir=treesitter_cpp",]: + execCmd "nimble install -y " & a + execCmd "nimble install" From abc5bda9a0c219a661710c5811933faac0167541 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 21 Nov 2018 18:08:07 -0600 Subject: [PATCH 013/593] Fix #6 --- nimterop.nimble | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/nimterop.nimble b/nimterop.nimble index 128e2a6..553b308 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -19,12 +19,9 @@ proc execCmd(cmd:string)= task test, "Test": execCmd "nim c -r tests/tnimterop" -task testext, "Test": - execCmd "nim c -r tests/tnimteropext" - task installWithDeps, "install dependencies": for a in ["http://github.com/genotrance/nimtreesitter?subdir=treesitter", "http://github.com/genotrance/nimtreesitter?subdir=treesitter_c", "http://github.com/genotrance/nimtreesitter?subdir=treesitter_cpp",]: execCmd "nimble install -y " & a - execCmd "nimble install" + execCmd "nimble install -y" From db15588cbc609c33b2ffa210f7c92899785e53ab Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Wed, 21 Nov 2018 16:27:22 -0800 Subject: [PATCH 014/593] always use assert=>doAssert for tests --- tests/tnimterop.nim | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/tnimterop.nim b/tests/tnimterop.nim index 77419ea..e61580b 100644 --- a/tests/tnimterop.nim +++ b/tests/tnimterop.nim @@ -7,9 +7,9 @@ cIncludeDir("include") cCompile("test.c") cImport("test.h") -assert TEST_INT == 512 -assert TEST_FLOAT == 5.12 -assert TEST_HEX == 0x512 +doAssert TEST_INT == 512 +doAssert TEST_FLOAT == 5.12 +doAssert TEST_HEX == 0x512 var pt: PRIMTYPE @@ -32,8 +32,8 @@ s3.field1 = 7 e = enum1 e2 = enum4 -assert test_call_int() == 5 -assert test_call_int_param(5).field1 == 5 -assert test_call_int_param2(5, s2).field1 == 11 -assert test_call_int_param3(5, s).field1 == 10 -assert test_call_int_param4(e) == e2 \ No newline at end of file +doAssert test_call_int() == 5 +doAssert test_call_int_param(5).field1 == 5 +doAssert test_call_int_param2(5, s2).field1 == 11 +doAssert test_call_int_param3(5, s).field1 == 10 +doAssert test_call_int_param4(e) == e2 \ No newline at end of file From 6b68a71069830256501cf059f9558fbe2ecd777f Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Wed, 21 Nov 2018 16:34:29 -0800 Subject: [PATCH 015/593] fixup --- tests/tnimterop.nim | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/tnimterop.nim b/tests/tnimterop.nim index e61580b..9c5db77 100644 --- a/tests/tnimterop.nim +++ b/tests/tnimterop.nim @@ -1,5 +1,4 @@ import nimterop/cimport -import macros cDebug() @@ -36,4 +35,4 @@ doAssert test_call_int() == 5 doAssert test_call_int_param(5).field1 == 5 doAssert test_call_int_param2(5, s2).field1 == 11 doAssert test_call_int_param3(5, s).field1 == 10 -doAssert test_call_int_param4(e) == e2 \ No newline at end of file +doAssert test_call_int_param4(e) == e2 From a8bb2dc01f99a2866f586f6e1491a512ce9b3cfa Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 21 Nov 2018 21:53:40 -0600 Subject: [PATCH 016/593] Fix #7 - separate file searching from include dirs --- README.md | 10 +++++--- nimterop/cimport.nim | 58 +++++++++++++++++++++++++++++--------------- nimterop/globals.nim | 1 + tests/tnimterop.nim | 7 +++--- 4 files changed, 51 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index f77debe..062ac16 100644 --- a/README.md +++ b/README.md @@ -57,11 +57,15 @@ Detailed documentation is still forthcoming. `cDebug()` - enable debug messages -`cDefine()` - `#define` an identifer that is forwarded to the compiler using `{.passC: "-DXXX".}` as well as _eventually_ used in processing `#ifdef` statements +`cDefine("XXX")` - `#define` an identifer that is forwarded to the C/C++ compiler using `{.passC: "-DXXX".}` as well as _eventually_ used in processing `#ifdef` statements -`cIncludeDir()` - add an include directory that is forwarded to the compiler using `{.passC: "-IXXX".}` as well as searched for files included using `cImport()` statements and following `cIncludeDir()` statements +`cIncludeDir("XXX")` - add an include directory that is forwarded to the compiler using `{.passC: "-IXXX".}` -`cImport()` - import all supported definitions from specific import header file +`cImport("header.h")` - import all supported definitions from header file + +`cAddSearchDir("XXX")` - add directory XXX to search path in calls to `cSearchPath()` + +`cSearchPath("header.h")` - return a file or directory found in search path configured using `cSearchPath()` - can be used in `cCompile()`, `cIncludeDir()` and `cImport()` calls `gitPull()` - pull a git repository prior to C/C++ interop diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index 8a1f299..91dd404 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -2,20 +2,31 @@ import macros, os, strformat, strutils import ast, getters, globals, lisp -proc search(path: string): string = - result = joinPath(getProjectPath(), path).replace("\\", "/") +proc findPath(path: string, fail = true): string = + # As is + result = path.replace("\\", "/") if not fileExists(result) and not dirExists(result): - result = path + # Relative to project path + result = joinPath(getProjectPath(), path).replace("\\", "/") if not fileExists(result) and not dirExists(result): - var found = false - for inc in gIncludeDirs: - result = inc & "/" & path - if fileExists(result) or dirExists(result): - found = true - break - if not found: + if fail: echo "File or directory not found: " & path quit(1) + else: + return "" + +proc cSearchPath*(path: string): string = + result = findPath(path, fail = false) + if result.len() == 0: + var found = false + for inc in gSearchDirs: + result = (inc & "/" & path).replace("\\", "/") + if fileExists(result) or dirExists(result): + found = true + break + if not found: + echo "File or directory not found: " & path + quit(1) macro cDebug*(): untyped = gDebug = true @@ -34,13 +45,23 @@ macro cDefine*(name: static[string], val: static[string] = ""): untyped = if gDebug: echo result.repr +macro cAddSearchDir*(dir: static[string]): untyped = + result = newNimNode(nnkStmtList) + + let fullpath = cSearchPath(dir) + if fullpath notin gSearchDirs: + gSearchDirs.add(fullpath) + macro cIncludeDir*(dir: static[string]): untyped = result = newNimNode(nnkStmtList) - let fullpath = search(dir) - gIncludeDirs.add(fullpath) - - let str = "-I\"" & fullpath & "\"" + let + fullpath = findPath(dir) + str = "-I\"" & fullpath & "\"" + + if fullpath notin gIncludeDirs: + gIncludeDirs.add(fullpath) + result.add(quote do: {.passC: `str`.} ) @@ -61,9 +82,8 @@ macro cIncludeC*(): untyped = break if inc: - if gDebug: - echo "Including " & line.strip() - gIncludeDirs.add(line.strip()) + result = quote do: + cIncludeDir(line) macro cCompile*(path: static[string]): untyped = result = newNimNode(nnkStmtList) @@ -94,7 +114,7 @@ macro cCompile*(path: static[string]): untyped = if path.contains("*") or path.contains("?"): dcompile(path) else: - let fpath = search(path) + let fpath = findPath(path) if fileExists(fpath): stmt &= fcompile(fpath) & "\n" elif dirExists(fpath): @@ -114,7 +134,7 @@ macro cImport*(filename: static[string]): untyped = result.add addReorder() let - fullpath = search(filename) + fullpath = findPath(filename) root = parseLisp(fullpath) echo "Importing " & fullpath diff --git a/nimterop/globals.nim b/nimterop/globals.nim index 6ace9f5..e2e155d 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -25,6 +25,7 @@ var gHeaders* {.compiletime.}: seq[string] gIncludeDirs* {.compiletime.}: seq[string] gProcs* {.compiletime.}: seq[string] + gSearchDirs* {.compiletime.}: seq[string] gTypes* {.compiletime.}: seq[string] gCode* {.compiletime.}: string diff --git a/tests/tnimterop.nim b/tests/tnimterop.nim index 9c5db77..a05cecd 100644 --- a/tests/tnimterop.nim +++ b/tests/tnimterop.nim @@ -2,9 +2,10 @@ import nimterop/cimport cDebug() -cIncludeDir("include") -cCompile("test.c") -cImport("test.h") +cIncludeDir "include" +cAddSearchDir "include" +cCompile cSearchPath("test.c") +cImport cSearchPath "test.h" doAssert TEST_INT == 512 doAssert TEST_FLOAT == 5.12 From b9b5174759b6dd1f94404b2f63637d406aec4983 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 21 Nov 2018 23:45:12 -0600 Subject: [PATCH 017/593] More pointer support, cpp mode default in toast, cleanup --- README.md | 2 ++ nimterop/ast.nim | 86 ++++++++++++++++++++++++++------------------ nimterop/cimport.nim | 32 +++++++++-------- nimterop/getters.nim | 5 +-- nimterop/git.nim | 14 ++++---- nimterop/globals.nim | 2 +- nimterop/lisp.nim | 10 +++--- tests/include/test.c | 4 ++- tests/include/test.h | 9 ++++- tests/tnimterop.nim | 9 ++++- toast.nim | 48 +++++++++++++------------ 11 files changed, 132 insertions(+), 89 deletions(-) diff --git a/README.md b/README.md index 062ac16..8aa6dfa 100644 --- a/README.md +++ b/README.md @@ -65,6 +65,8 @@ Detailed documentation is still forthcoming. `cAddSearchDir("XXX")` - add directory XXX to search path in calls to `cSearchPath()` +`cAddStdDir("XXX")` - add standard "c" [default] or "cpp" include paths to search path + `cSearchPath("header.h")` - return a file or directory found in search path configured using `cSearchPath()` - can be used in `cCompile()`, `cIncludeDir()` and `cImport()` calls `gitPull()` - pull a git repository prior to C/C++ interop diff --git a/nimterop/ast.nim b/nimterop/ast.nim index b825efe..a84f503 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -21,7 +21,7 @@ proc addHeader*(fullpath: string) = # proc pPreprocDef(node: ref Ast) = - if node.children.len() == 2: + if node.children.len == 2: let name = getNodeValIf(node.children[0], identifier) val = getNodeValIf(node.children[1], preproc_arg) @@ -37,30 +37,42 @@ proc pPreprocDef(node: ref Ast) = # proc typeScan(node: ref Ast, sym, id: Sym, offset: string): string = - if node.sym != sym or node.children.len() != 2: + if node.sym != sym or node.children.len != 2: return - let - pname = getNodeValIf(node.children[1], id) + var + name = getNodeValIf(node.children[1], id) ptyp = getNodeValIf(node.children[0], primitive_type) ttyp = getNodeValIf(node.children[0], type_identifier) + ptrname = false - if pname.len() == 0: + if name.len == 0 and node.children[1].sym == pointer_declarator and node.children[1].children.len == 1: + name = getNodeValIf(node.children[1].children[0], id) + ptrname = true + + if name.len == 0: return elif ptyp.nBl: - result = &"{offset}{pname.getIdentifier()}: {ptyp.getType()}" + ptyp = ptyp.getType() + if ptyp != "object" and ptrname: + ptyp = &"ptr {ptyp}" + result = &"{offset}{name.getIdentifier()}: {ptyp}" elif ttyp.nBl: - result = &"{offset}{pname.getIdentifier()}: {ttyp}" - elif node.children[0].sym in [struct_specifier, enum_specifier] and node.children[0].children.len() == 1: - let styp = getNodeValIf(node.children[0].children[0], type_identifier) + if ptrname: + ttyp = &"ptr {ttyp}" + result = &"{offset}{name.getIdentifier()}: {ttyp}" + elif node.children[0].sym in [struct_specifier, enum_specifier] and node.children[0].children.len == 1: + var styp = getNodeValIf(node.children[0].children[0], type_identifier) if styp.nBl: - result = &"{offset}{pname.getIdentifier()}: {styp}" + if ptrname: + styp = &"ptr {styp}" + result = &"{offset}{name.getIdentifier()}: {styp}" else: return proc pStructSpecifier(node: ref Ast, name = "") = var stmt: string - if node.children.len() == 1 and name notin gTypes: + if node.children.len == 1 and name notin gTypes: case node.children[0].sym: of type_identifier: let typ = getNodeValIf(node.children[0], type_identifier) @@ -68,18 +80,18 @@ proc pStructSpecifier(node: ref Ast, name = "") = gTypes.add(name) if name != typ: # typedef struct X Y - gTypeStr &= &" {name}* = {typ} #1 pStructSpecifier()\n" + gTypeStr &= &" {name.getIdentifier()}* = {typ} #1 pStructSpecifier()\n" else: # typedef struct X X - gTypeStr &= &" {name}* {{.importc: \"{name}\", header: {gCurrentHeader}, bycopy.}} = object #2 pStructSpecifier()\n" + gTypeStr &= &" {name.getIdentifier()}* {{.importc: \"{name}\", header: {gCurrentHeader}, bycopy.}} = object #2 pStructSpecifier()\n" of field_declaration_list: # typedef struct { fields } X - stmt = &" {name}* {{.importc: \"{name}\", header: {gCurrentHeader}, bycopy.}} = object #3 pStructSpecifier()\n" + stmt = &" {name.getIdentifier()}* {{.importc: \"{name}\", header: {gCurrentHeader}, bycopy.}} = object #3 pStructSpecifier()\n" for field in node.children[0].children: let ts = typeScan(field, field_declaration, field_identifier, " ") - if ts.len() == 0: + if ts.len == 0: return stmt &= ts & "\n" @@ -88,7 +100,7 @@ proc pStructSpecifier(node: ref Ast, name = "") = else: discard - elif name.len() == 0 and node.children.len() == 2 and node.children[1].sym == field_declaration_list: + elif name.len == 0 and node.children.len == 2 and node.children[1].sym == field_declaration_list: let ename = getNodeValIf(node.children[0], type_identifier) if ename.nBl and ename notin gTypes: # struct X { fields } @@ -96,7 +108,7 @@ proc pStructSpecifier(node: ref Ast, name = "") = for field in node.children[1].children: let ts = typeScan(field, field_declaration, field_identifier, " ") - if ts.len() == 0: + if ts.len == 0: return stmt &= ts & "\n" @@ -109,12 +121,12 @@ proc pEnumSpecifier(node: ref Ast, name = "") = elid: int stmt: string - if node.children.len() == 1 and node.children[0].sym == enumerator_list: + if node.children.len == 1 and node.children[0].sym == enumerator_list: # typedef enum { fields } X ename = name elid = 0 - stmt = &" {name}* = enum #1 pEnumSpecifier()\n" - elif name.len() == 0 and node.children.len() == 2 and node.children[1].sym == enumerator_list: + stmt = &" {name.getIdentifier()}* = enum #1 pEnumSpecifier()\n" + elif name.len == 0 and node.children.len == 2 and node.children[1].sym == enumerator_list: ename = getNodeValIf(node.children[0], type_identifier) elid = 1 if ename.nBl: @@ -126,9 +138,9 @@ proc pEnumSpecifier(node: ref Ast, name = "") = for field in node.children[elid].children: if field.sym == enumerator: let fname = getNodeValIf(field.children[0], identifier) - if field.children.len() == 1: + if field.children.len == 1: stmt &= &" {fname}\n" - elif field.children.len() == 2 and field.children[1].sym == number_literal: + elif field.children.len == 2 and field.children[1].sym == number_literal: let num = getNodeValIf(field.children[1], number_literal) stmt &= &" {fname} = {num}\n" else: @@ -139,25 +151,31 @@ proc pEnumSpecifier(node: ref Ast, name = "") = gTypeStr &= stmt proc pTypeDefinition(node: ref Ast) = - if node.children.len() == 2: + if node.children.len == 2: var name = getNodeValIf(node.children[1], type_identifier) - pname = getNodeValIf(node.children[1], pointer_declarator) ptyp = getNodeValIf(node.children[0], primitive_type) ttyp = getNodeValIf(node.children[0], type_identifier) + ptrname = false - if name.len() == 0 and node.children[1].sym == pointer_declarator and node.children[1].children.len() == 1: + if name.len == 0 and node.children[1].sym == pointer_declarator and node.children[1].children.len == 1: name = getNodeValIf(node.children[1].children[0], type_identifier) + ptrname = true if name.nBl and name notin gTypes: if ptyp.nBl: # typedef int X gTypes.add(name) - gTypeStr &= &" {name}* = {ptyp.getType()} #1 pTypeDefinition()\n" + ptyp = ptyp.getType() + if ptyp != "object" and ptrname: + ptyp = &"ptr {ptyp}" + gTypeStr &= &" {name.getIdentifier()}* = {ptyp} #1 pTypeDefinition()\n" elif ttyp.nBl: # typedef X Y gTypes.add(name) - gTypeStr &= &" {name}* = {ttyp} #2 pTypeDefinition()\n" + if ptrname: + ttyp = &"ptr {ttyp}" + gTypeStr &= &" {name.getIdentifier()}* = {ttyp} #2 pTypeDefinition()\n" else: case node.children[0].sym: of struct_specifier: @@ -168,20 +186,20 @@ proc pTypeDefinition(node: ref Ast) = discard proc pFunctionDeclarator(node: ref Ast, typ: string) = - if node.children.len() == 2: + if node.children.len == 2: let name = getNodeValIf(node.children[0], identifier) if name.nBl and name notin gProcs and node.children[1].sym == parameter_list: # typ function(typ param1, ...) - var stmt = &"# pFunctionDeclarator()\nproc {name}*(" + var stmt = &"# pFunctionDeclarator()\nproc {name.getIdentifier()}*(" - for i in 0 .. node.children[1].children.len()-1: + for i in 0 .. node.children[1].children.len-1: let ts = typeScan(node.children[1].children[i], parameter_declaration, identifier, "") - if ts.len() == 0: + if ts.len == 0: return stmt &= ts - if i != node.children[1].children.len()-1: + if i != node.children[1].children.len-1: stmt &= ", " if typ != "void": @@ -195,7 +213,7 @@ proc pFunctionDeclarator(node: ref Ast, typ: string) = gProcStr &= stmt proc pDeclaration*(node: ref Ast) = - if node.children.len() == 2 and node.children[1].sym == function_declarator: + if node.children.len == 2 and node.children[1].sym == function_declarator: let ptyp = getNodeValIf(node.children[0], primitive_type) ttyp = getNodeValIf(node.children[0], type_identifier) @@ -204,7 +222,7 @@ proc pDeclaration*(node: ref Ast) = pFunctionDeclarator(node.children[1], ptyp.getType()) elif ttyp.nBl: pFunctionDeclarator(node.children[1], ttyp) - elif node.children[0].sym == struct_specifier and node.children[0].children.len() == 1: + elif node.children[0].sym == struct_specifier and node.children[0].children.len == 1: let styp = getNodeValIf(node.children[0].children[0], type_identifier) if styp.nBl: pFunctionDeclarator(node.children[1], styp) diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index 91dd404..a47443c 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -17,7 +17,7 @@ proc findPath(path: string, fail = true): string = proc cSearchPath*(path: string): string = result = findPath(path, fail = false) - if result.len() == 0: + if result.len == 0: var found = false for inc in gSearchDirs: result = (inc & "/" & path).replace("\\", "/") @@ -31,12 +31,12 @@ proc cSearchPath*(path: string): string = macro cDebug*(): untyped = gDebug = true -macro cDefine*(name: static[string], val: static[string] = ""): untyped = +macro cDefine*(name: static string, val: static string = ""): untyped = result = newNimNode(nnkStmtList) var str = "-D" & name if val.nBl: - str &= "=\"" & val & "\"" + str &= &"=\"{val}\"" result.add(quote do: {.passC: `str`.} @@ -45,36 +45,37 @@ macro cDefine*(name: static[string], val: static[string] = ""): untyped = if gDebug: echo result.repr -macro cAddSearchDir*(dir: static[string]): untyped = +macro cAddSearchDir*(dir: static string): untyped = result = newNimNode(nnkStmtList) let fullpath = cSearchPath(dir) if fullpath notin gSearchDirs: gSearchDirs.add(fullpath) -macro cIncludeDir*(dir: static[string]): untyped = +macro cIncludeDir*(dir: static string): untyped = result = newNimNode(nnkStmtList) let fullpath = findPath(dir) - str = "-I\"" & fullpath & "\"" + str = &"-I\"{fullpath}\"" if fullpath notin gIncludeDirs: gIncludeDirs.add(fullpath) - result.add(quote do: - {.passC: `str`.} - ) + result.add(quote do: + {.passC: `str`.} + ) if gDebug: echo result.repr -macro cIncludeC*(): untyped = +macro cAddStdDir*(mode = "c"): untyped = result = newNimNode(nnkStmtList) var inc = false - for line in getGccPaths().splitLines(): + + for line in getGccPaths(mode.strVal()).splitLines(): if "#include <...> search starts here" in line: inc = true continue @@ -82,10 +83,11 @@ macro cIncludeC*(): untyped = break if inc: - result = quote do: - cIncludeDir(line) + let sline = line.strip() + result.add quote do: + cAddSearchDir(`sline`) -macro cCompile*(path: static[string]): untyped = +macro cCompile*(path: static string): untyped = result = newNimNode(nnkStmtList) var @@ -129,7 +131,7 @@ macro cCompile*(path: static[string]): untyped = if gDebug: echo result.repr -macro cImport*(filename: static[string]): untyped = +macro cImport*(filename: static string): untyped = result = newNimNode(nnkStmtList) result.add addReorder() diff --git a/nimterop/getters.nim b/nimterop/getters.nim index b4f9df6..0412522 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -23,10 +23,11 @@ proc getNodeValIf*(node: ref Ast, esym: Sym): string = return gCode[node.start .. node.stop-1].strip() proc getGccPaths*(mode = "c"): string = - let + var nul = when defined(Windows): "nul" else: "/dev/null" + mmode = if mode == "cpp": "c++" else: mode - return staticExec("gcc -Wp,-v -x" & mode & " " & nul) + return staticExec("gcc -Wp,-v -x" & mmode & " " & nul) proc getLineCol*(node: ref Ast): tuple[line, col: int] = result.line = 1 diff --git a/nimterop/git.nim b/nimterop/git.nim index f06e9ba..b55b365 100644 --- a/nimterop/git.nim +++ b/nimterop/git.nim @@ -18,7 +18,7 @@ proc execAction*(cmd: string): string = echo result quit(1) -macro extractZip*(zipfile, outdir: static[string]): untyped = +macro extractZip*(zipfile, outdir: static string): untyped = var cmd = "unzip -o $#" if defined(Windows): cmd = "powershell -nologo -noprofile -command \"& { Add-Type -A " & @@ -28,7 +28,7 @@ macro extractZip*(zipfile, outdir: static[string]): untyped = echo "Extracting " & zipfile discard execAction(&"cd \"{getProjectPath()/outdir}\" && " & cmd % zipfile) -macro downloadUrl*(url, outdir: static[string]): untyped = +macro downloadUrl*(url, outdir: static string): untyped = let file = url.extractFilename() ext = file.splitFile().ext.toLowerAscii() @@ -45,7 +45,7 @@ macro downloadUrl*(url, outdir: static[string]): untyped = discard quote do: extractZip(`file`, `outdir`) -macro gitReset*(outdir: static[string]): untyped = +macro gitReset*(outdir: static string): untyped = echo "Resetting " & outdir let cmd = &"cd \"{getProjectPath()/outdir}\" && git reset --hard" @@ -53,7 +53,7 @@ macro gitReset*(outdir: static[string]): untyped = sleep(1000) echo " Retrying ..." -macro gitCheckout*(file, outdir: static[string]): untyped = +macro gitCheckout*(file, outdir: static string): untyped = echo "Resetting " & file let cmd = &"cd \"{getProjectPath()/outdir}\" && git checkout $#" % file.replace(outdir & "/", "") @@ -61,7 +61,7 @@ macro gitCheckout*(file, outdir: static[string]): untyped = sleep(500) echo " Retrying ..." -macro gitPull*(url: static[string], outdirN = "", plistN = "", checkoutN = ""): untyped = +macro gitPull*(url: static string, outdirN = "", plistN = "", checkoutN = ""): untyped = let outdir = getProjectPath()/outdirN.strVal() plist = plistN.strVal() @@ -78,14 +78,14 @@ macro gitPull*(url: static[string], outdirN = "", plistN = "", checkoutN = ""): discard execAction(&"cd \"{outdir}\" && git init .") discard execAction(&"cd \"{outdir}\" && git remote add origin " & url) - if plist.len() != 0: + if plist.len != 0: let sparsefile = &"{outdir}/.git/info/sparse-checkout" discard execAction(&"cd \"{outdir}\" && git config core.sparsecheckout true") writeFile(sparsefile, plist) echo "Wrote" - if checkout.len() != 0: + if checkout.len != 0: echo "Checking out " & checkout discard execAction(&"cd \"{outdir}\" && git pull --tags origin master") discard execAction(&"cd \"{outdir}\" && git checkout {checkout}") diff --git a/nimterop/globals.nim b/nimterop/globals.nim index e2e155d..ccc4ec2 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -37,4 +37,4 @@ var gTypeStr* {.compiletime.}: string template nBl*(s: untyped): untyped = - (s.len() != 0) \ No newline at end of file + (s.len != 0) \ No newline at end of file diff --git a/nimterop/lisp.nim b/nimterop/lisp.nim index cf723b7..2727c18 100644 --- a/nimterop/lisp.nim +++ b/nimterop/lisp.nim @@ -13,7 +13,7 @@ proc tokenize(fullpath: string) = gTokens = @[] idx = 0 - for i in staticExec("toast -u " & fullpath): + for i in staticExec("toast -m " & fullpath): case i: of ' ', '\n', '\r', '(', ')': if collect.nBl: @@ -24,17 +24,17 @@ proc tokenize(fullpath: string) = else: collect &= $i - if gTokens.len() == 0: + if gTokens.len == 0: echo "toast binary not installed - nimble install nimterop to force build" quit(1) proc readFromTokens(): ref Ast = - if idx == gTokens.len(): + if idx == gTokens.len: echo "Bad AST" quit(1) if gTokens[idx] == "(": - if gTokens.len() - idx < 2: + if gTokens.len - idx < 2: echo "Corrupt AST" quit(1) if gTokens[idx+1] != "comment": @@ -60,7 +60,7 @@ proc readFromTokens(): ref Ast = proc printAst*(node: ref Ast, offset=""): string = result = offset & "(" & $node.sym & " " & $node.start & " " & $node.stop - if node.children.len() != 0: + if node.children.len != 0: result &= "\n" for child in node.children: result &= printAst(child, offset & " ") diff --git a/tests/include/test.c b/tests/include/test.c index 8d801b7..885723e 100644 --- a/tests/include/test.c +++ b/tests/include/test.c @@ -4,13 +4,15 @@ int test_call_int() { return 5; } -struct STRUCT1 test_call_int_param(int param1) { +#ifdef FORCE +struct STRUCT1 _test_call_int_param_(int param1) { struct STRUCT1 s; s.field1 = param1; return s; } +#endif STRUCT2 test_call_int_param2(int param1, STRUCT2 param2) { STRUCT2 s; diff --git a/tests/include/test.h b/tests/include/test.h index 60d1660..7de6eed 100644 --- a/tests/include/test.h +++ b/tests/include/test.h @@ -29,8 +29,15 @@ typedef enum { enum6 } ENUM2; +typedef void * VOIDPTR; +typedef int * INTPTR; + +typedef struct { + int *field; +} STRUCT4; + int test_call_int(); -struct STRUCT1 test_call_int_param(int param1); +struct STRUCT1 _test_call_int_param_(int param1); STRUCT2 test_call_int_param2(int param1, STRUCT2 param2); STRUCT2 test_call_int_param3(int param1, struct STRUCT1 param2); ENUM2 test_call_int_param4(enum ENUM param1); \ No newline at end of file diff --git a/tests/tnimterop.nim b/tests/tnimterop.nim index a05cecd..dd822cb 100644 --- a/tests/tnimterop.nim +++ b/tests/tnimterop.nim @@ -2,6 +2,7 @@ import nimterop/cimport cDebug() +cDefine("FORCE") cIncludeDir "include" cAddSearchDir "include" cCompile cSearchPath("test.c") @@ -18,10 +19,14 @@ var s: STRUCT1 s2: STRUCT2 s3: STRUCT3 + s4: STRUCT4 e: ENUM e2: ENUM2 = enum5 + vptr: VOIDPTR + iptr: INTPTR + pt = 3 ct = 4 @@ -31,9 +36,11 @@ s3.field1 = 7 e = enum1 e2 = enum4 - + doAssert test_call_int() == 5 doAssert test_call_int_param(5).field1 == 5 doAssert test_call_int_param2(5, s2).field1 == 11 doAssert test_call_int_param3(5, s).field1 == 10 doAssert test_call_int_param4(e) == e2 + +cAddStdDir() diff --git a/toast.nim b/toast.nim index 60f92d8..b117f05 100644 --- a/toast.nim +++ b/toast.nim @@ -6,30 +6,28 @@ import treesitter/[runtime, c, cpp] const HELP = """ > toast header.h -""" +-m minimized output - non-pretty +-c C mode - CPP is default""" -var - gPretty = true - -proc printLisp(root: TSNode, data: var string) = +proc printLisp(root: TSNode, data: var string, pretty = true) = var node = root nextnode: TSNode depth = 0 - + while true: if not node.tsNodeIsNull(): - if gPretty: + if pretty: stdout.write spaces(depth) stdout.write "(" & $node.tsNodeType() & " " & $node.tsNodeStartByte() & " " & $node.tsNodeEndByte() if node.tsNodeNamedChildCount() != 0: - if gPretty: + if pretty: echo "" nextnode = node.tsNodeNamedChild(0) depth += 1 else: - if gPretty: + if pretty: echo ")" else: stdout.write ")" @@ -39,7 +37,7 @@ proc printLisp(root: TSNode, data: var string) = while true: node = node.tsNodeParent() depth -= 1 - if gPretty: + if pretty: echo spaces(depth) & ")" else: stdout.write ")" @@ -54,11 +52,11 @@ proc printLisp(root: TSNode, data: var string) = if node == root: break -proc process(path: string, mode="") = +proc process(path: string, mode="cpp", pretty = true) = if not existsFile(path): echo "Invalid path " & path return - + var parser = tsParserNew() ext = path.splitFile().ext @@ -67,14 +65,14 @@ proc process(path: string, mode="") = defer: parser.tsParserDelete() - - if mode.len() != 0: + + if mode.len != 0: pmode = mode elif ext in [".h", ".c"]: pmode = "c" elif ext in [".hxx", ".hpp", ".hh", ".H", ".h++", ".cpp", ".cxx", ".cc", ".C", ".c++"]: pmode = "cpp" - + if "cplusplus" in data or "extern \"C\"" in data: pmode = "cpp" @@ -91,23 +89,29 @@ proc process(path: string, mode="") = quit() var - tree = parser.tsParserParseString(nil, data.cstring, data.len().uint32) + tree = parser.tsParserParseString(nil, data.cstring, data.len.uint32) root = tree.tsTreeRootNode() defer: tree.tsTreeDelete() - - printLisp(root, data) + + printLisp(root, data, pretty) proc parseCli() = - let params = commandLineParams() + var + mode = "cpp" + params = commandLineParams() + pretty = true + for param in params: if param in ["-h", "--help", "-?", "/?", "/h"]: echo HELP quit() - elif param == "-u": - gPretty = false + elif param == "-c": + mode = "c" + elif param == "-m": + pretty = false else: - process(param) + process(param, mode, pretty) parseCli() \ No newline at end of file From 88692bce071b4feb46f4ef4c26b4b0010579281b Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Sat, 24 Nov 2018 18:05:40 -0500 Subject: [PATCH 018/593] fix gitignore --- .gitignore | 4 +++- tests/.gitignore | 5 +++++ 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 tests/.gitignore diff --git a/.gitignore b/.gitignore index 04d0b79..2048a22 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,7 @@ nimcache + +.DS_Store + *.exe *.swp -test* toast diff --git a/tests/.gitignore b/tests/.gitignore new file mode 100644 index 0000000..7df3c8d --- /dev/null +++ b/tests/.gitignore @@ -0,0 +1,5 @@ +/* +!*.nim +!.gitignore +!/include/ + From 50eba9a485691f984947af70ff3b94556825a7ee Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Sun, 25 Nov 2018 12:27:28 -0600 Subject: [PATCH 019/593] Minor changes --- nimterop/cimport.nim | 16 ++++++++++------ nimterop/getters.nim | 38 ++++++++++++++++++++++++++------------ 2 files changed, 36 insertions(+), 18 deletions(-) diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index a47443c..8a85145 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -34,16 +34,20 @@ macro cDebug*(): untyped = macro cDefine*(name: static string, val: static string = ""): untyped = result = newNimNode(nnkStmtList) - var str = "-D" & name + var str = name if val.nBl: str &= &"=\"{val}\"" - result.add(quote do: - {.passC: `str`.} - ) + if str notin gDefines: + gDefines.add(str) + str = "-D" & str - if gDebug: - echo result.repr + result.add(quote do: + {.passC: `str`.} + ) + + if gDebug: + echo result.repr macro cAddSearchDir*(dir: static string): untyped = result = newNimNode(nnkStmtList) diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 0412522..6ba83e8 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -1,15 +1,15 @@ -import macros, strutils +import macros, strformat, strutils import regex -import globals +import git, globals proc getIdentifier*(str: string): string = result = str.strip(chars={'_'}) proc getType*(str: string): string = result = str.strip(chars={'_'}).replace(re"([u]?int[\d]+)_t", "$1").replace(re"^void$", "object") - + proc getLit*(str: string): string = if str.contains(re"^[\-]?[\d]+$") or str.contains(re"^[\-]?[\d]*\.[\d]+$") or @@ -19,15 +19,8 @@ proc getLit*(str: string): string = proc getNodeValIf*(node: ref Ast, esym: Sym): string = if esym != node.sym: return - - return gCode[node.start .. node.stop-1].strip() -proc getGccPaths*(mode = "c"): string = - var - nul = when defined(Windows): "nul" else: "/dev/null" - mmode = if mode == "cpp": "c++" else: mode - - return staticExec("gcc -Wp,-v -x" & mmode & " " & nul) + return gCode[node.start .. node.stop-1].strip() proc getLineCol*(node: ref Ast): tuple[line, col: int] = result.line = 1 @@ -36,4 +29,25 @@ proc getLineCol*(node: ref Ast): tuple[line, col: int] = if gCode[i] == '\n': result.col = 0 result.line += 1 - result.col += 1 \ No newline at end of file + result.col += 1 + +proc getGccPaths*(mode = "c"): string = + var + nul = when defined(Windows): "nul" else: "/dev/null" + mmode = if mode == "cpp": "c++" else: mode + + return staticExec("gcc -Wp,-v -x" & mmode & " " & nul) + +proc getPreprocessor*(fullpath: string, mode = "cpp"): string = + var + mmode = if mode == "cpp": "c++" else: mode + cmd = &"gcc -E -dD -x{mmode} " + + for inc in gIncludeDirs: + cmd &= &"-I\"{inc}\" " + + for def in gDefines: + cmd &= &"-D{def} " + + cmd &= &"\"{fullpath}\"" + return staticExec(cmd) \ No newline at end of file From 9ee67da1c254db70b84712a96c33389f5f3feb9b Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 27 Nov 2018 14:56:47 -0600 Subject: [PATCH 020/593] Add preprocessor step in toast --- nimterop/getters.nim | 41 +++++++++++++++++++++++++++++++---- nimterop/git.nim | 9 +++++--- nimterop/globals.nim | 2 ++ nimterop/lisp.nim | 2 -- toast.nim | 51 +++++++++++++++++++++++++++++++++----------- 5 files changed, 83 insertions(+), 22 deletions(-) diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 6ba83e8..c9ac3b9 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -1,9 +1,12 @@ -import macros, strformat, strutils +import macros, ospaths, strformat, strutils import regex import git, globals +proc sanitizePath*(path: string): string = + path.multiReplace([("\\\\", $DirSep), ("\\", $DirSep), ("//", $DirSep)]) + proc getIdentifier*(str: string): string = result = str.strip(chars={'_'}) @@ -42,12 +45,42 @@ proc getPreprocessor*(fullpath: string, mode = "cpp"): string = var mmode = if mode == "cpp": "c++" else: mode cmd = &"gcc -E -dD -x{mmode} " + gdef, gdir: seq[string] - for inc in gIncludeDirs: + rdata: seq[string] = @[] + start = false + sfile = fullpath.sanitizePath + + when nimvm: + gdef = gDefines + gdir = gIncludeDirs + else: + gdef = gDefinesRT + gdir = gIncludeDirsRT + + for inc in gdir: cmd &= &"-I\"{inc}\" " - for def in gDefines: + for def in gdef: cmd &= &"-D{def} " cmd &= &"\"{fullpath}\"" - return staticExec(cmd) \ No newline at end of file + + # Include content only from file + for line in execAction(cmd).splitLines(): + if line.strip() != "": + if line[0] == '#' and not line.contains("#pragma") and not line.contains("define"): + start = false + if sfile in line.sanitizePath: + start = true + if not ("\\" in line) and not ("/" in line) and extractFilename(sfile) in line: + start = true + else: + if start: + rdata.add( + line.multiReplace([("_Noreturn", ""), ("(())", ""), ("WINAPI", ""), + ("__attribute__", ""), ("extern \"C\"", "")]) + .replace(re"\(\([_a-z]+?\)\)", "") + .replace(re"\(\(__format__[\s]*\(__[gnu_]*printf__, [\d]+, [\d]+\)\)\);", ";") + ) + return rdata.join("\n") diff --git a/nimterop/git.nim b/nimterop/git.nim index b55b365..51ea756 100644 --- a/nimterop/git.nim +++ b/nimterop/git.nim @@ -1,4 +1,4 @@ -import macros, os, regex, strformat, strutils +import macros, os, osproc, regex, strformat, strutils import globals @@ -11,7 +11,10 @@ proc execAction*(cmd: string): string = when defined(Linux) or defined(MacOSX): ccmd = "bash -c '" & cmd & "'" - (result, ret) = gorgeEx(ccmd) + when nimvm: + (result, ret) = gorgeEx(ccmd) + else: + (result, ret) = execCmdEx(ccmd) if ret != 0: echo "Command failed: " & $ret echo ccmd @@ -66,7 +69,7 @@ macro gitPull*(url: static string, outdirN = "", plistN = "", checkoutN = ""): u outdir = getProjectPath()/outdirN.strVal() plist = plistN.strVal() checkout = checkoutN.strVal() - + if dirExists(outdir/".git"): discard quote do: gitReset(`outdirN`) diff --git a/nimterop/globals.nim b/nimterop/globals.nim index ccc4ec2..ae3d03b 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -20,10 +20,12 @@ type var gDefines* {.compiletime.}: seq[string] + gDefinesRT*: seq[string] gCompile* {.compiletime.}: seq[string] gConsts* {.compiletime.}: seq[string] gHeaders* {.compiletime.}: seq[string] gIncludeDirs* {.compiletime.}: seq[string] + gIncludeDirsRT*: seq[string] gProcs* {.compiletime.}: seq[string] gSearchDirs* {.compiletime.}: seq[string] gTypes* {.compiletime.}: seq[string] diff --git a/nimterop/lisp.nim b/nimterop/lisp.nim index 2727c18..c4a3b54 100644 --- a/nimterop/lisp.nim +++ b/nimterop/lisp.nim @@ -1,7 +1,5 @@ import strutils -import regex - import globals var diff --git a/toast.nim b/toast.nim index b117f05..4e01de7 100644 --- a/toast.nim +++ b/toast.nim @@ -1,13 +1,17 @@ import os, strutils -import regex - import treesitter/[runtime, c, cpp] +import nimterop/[globals, getters] + const HELP = """ > toast header.h --m minimized output - non-pretty --c C mode - CPP is default""" +-a print AST output +-c C mode - CPP is default +-m print minimized AST output - non-pretty (implies -a) +-p run preprocessor on header +-D definitions to pass to preprocessor +-I include directory to pass to preprocessor""" proc printLisp(root: TSNode, data: var string, pretty = true) = var @@ -20,6 +24,8 @@ proc printLisp(root: TSNode, data: var string, pretty = true) = if pretty: stdout.write spaces(depth) stdout.write "(" & $node.tsNodeType() & " " & $node.tsNodeStartByte() & " " & $node.tsNodeEndByte() + else: + return if node.tsNodeNamedChildCount() != 0: if pretty: @@ -37,6 +43,8 @@ proc printLisp(root: TSNode, data: var string, pretty = true) = while true: node = node.tsNodeParent() depth -= 1 + if depth == -1: + break if pretty: echo spaces(depth) & ")" else: @@ -52,7 +60,7 @@ proc printLisp(root: TSNode, data: var string, pretty = true) = if node == root: break -proc process(path: string, mode="cpp", pretty = true) = +proc process(path: string, mode="cpp", past, pretty, preprocess: bool) = if not existsFile(path): echo "Invalid path " & path return @@ -61,7 +69,7 @@ proc process(path: string, mode="cpp", pretty = true) = parser = tsParserNew() ext = path.splitFile().ext pmode = "" - data = readFile(path) + data = "" defer: parser.tsParserDelete() @@ -73,8 +81,10 @@ proc process(path: string, mode="cpp", pretty = true) = elif ext in [".hxx", ".hpp", ".hh", ".H", ".h++", ".cpp", ".cxx", ".cc", ".C", ".c++"]: pmode = "cpp" - if "cplusplus" in data or "extern \"C\"" in data: - pmode = "cpp" + if preprocess: + data = getPreprocessor(path) + else: + data = readFile(path) if pmode == "c": if not parser.tsParserSetLanguage(treeSitterC()): @@ -95,23 +105,38 @@ proc process(path: string, mode="cpp", pretty = true) = defer: tree.tsTreeDelete() - printLisp(root, data, pretty) + if past: + printLisp(root, data, pretty) proc parseCli() = var mode = "cpp" params = commandLineParams() + + past = false pretty = true + preprocess = false for param in params: - if param in ["-h", "--help", "-?", "/?", "/h"]: + let flag = if param.len() <= 2: param else: param[0..<2] + + if flag in ["-h", "--help", "-?", "/?", "/h"]: echo HELP quit() - elif param == "-c": + elif flag == "-a": + past = true + elif flag == "-c": mode = "c" - elif param == "-m": + elif flag == "-m": + past = true pretty = false + elif flag == "-p": + preprocess = true + elif flag == "-D": + gDefinesRT.add(param[2..^1]) + elif flag == "-I": + gIncludeDirsRT.add(param[2..^1]) else: - process(param, mode, pretty) + process(param, mode, past, pretty, preprocess) parseCli() \ No newline at end of file From fb053dd81eca9a45a813a7d7b0de868c28203976 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 27 Nov 2018 16:58:11 -0600 Subject: [PATCH 021/593] Cleanup --- nimterop/ast.nim | 3 +++ nimterop/cimport.nim | 20 ++++++++++---------- nimterop/lisp.nim | 6 +++--- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/nimterop/ast.nim b/nimterop/ast.nim index a84f503..cc1cd61 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -228,6 +228,9 @@ proc pDeclaration*(node: ref Ast) = pFunctionDeclarator(node.children[1], styp) proc genNimAst*(node: ref Ast) = + if node.isNil: + return + case node.sym: of ERROR: let (line, col) = getLineCol(node) diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index 8a85145..9c63665 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -33,11 +33,11 @@ macro cDebug*(): untyped = macro cDefine*(name: static string, val: static string = ""): untyped = result = newNimNode(nnkStmtList) - + var str = name if val.nBl: str &= &"=\"{val}\"" - + if str notin gDefines: gDefines.add(str) str = "-D" & str @@ -69,7 +69,7 @@ macro cIncludeDir*(dir: static string): untyped = result.add(quote do: {.passC: `str`.} ) - + if gDebug: echo result.repr @@ -85,7 +85,7 @@ macro cAddStdDir*(mode = "c"): untyped = continue elif "End of search list" in line: break - + if inc: let sline = line.strip() result.add quote do: @@ -131,7 +131,7 @@ macro cCompile*(path: static string): untyped = dcompile(fpath / "*.c") result.add stmt.parseStmt() - + if gDebug: echo result.repr @@ -144,14 +144,14 @@ macro cImport*(filename: static string): untyped = root = parseLisp(fullpath) echo "Importing " & fullpath - + gCode = staticRead(fullpath) gConstStr = "" gTypeStr = "" - + addHeader(fullpath) genNimAst(root) - + if gConstStr.nBl: if gDebug: echo "const\n" & gConstStr @@ -170,6 +170,6 @@ macro cImport*(filename: static string): untyped = if gDebug: echo gProcStr result.add gProcStr.parseStmt() - + if gDebug: - echo result.repr \ No newline at end of file + echo result.repr diff --git a/nimterop/lisp.nim b/nimterop/lisp.nim index c4a3b54..36c810a 100644 --- a/nimterop/lisp.nim +++ b/nimterop/lisp.nim @@ -8,7 +8,7 @@ var proc tokenize(fullpath: string) = var collect = "" - + gTokens = @[] idx = 0 for i in staticExec("toast -m " & fullpath): @@ -53,7 +53,7 @@ proc readFromTokens(): ref Ast = elif gTokens[idx] == ")": echo "Poor AST" quit(1) - + idx += 1 proc printAst*(node: ref Ast, offset=""): string = @@ -68,5 +68,5 @@ proc printAst*(node: ref Ast, offset=""): string = proc parseLisp*(fullpath: string): ref Ast = tokenize(fullpath) - + return readFromTokens() From d00aeeafdd54134ff294dc4459a6b8cbaa560f8d Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Tue, 27 Nov 2018 18:06:17 -0500 Subject: [PATCH 022/593] add syntax cIncludeDir "$projpath/include"; do not use recursive search paths; add test tests/tnimterop_cpp.nim --- nimterop.nimble | 3 +- nimterop/cimport.nim | 30 +++++++++------ tests/include/test2.cpp | 8 ++++ tests/include/test2.hpp | 20 ++++++++++ tests/{tnimterop.nim => tnimterop_c.nim} | 4 +- tests/tnimterop_cpp.nim | 49 ++++++++++++++++++++++++ 6 files changed, 99 insertions(+), 15 deletions(-) create mode 100644 tests/include/test2.cpp create mode 100644 tests/include/test2.hpp rename tests/{tnimterop.nim => tnimterop_c.nim} (90%) create mode 100644 tests/tnimterop_cpp.nim diff --git a/nimterop.nimble b/nimterop.nimble index 553b308..52241a3 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -17,7 +17,8 @@ proc execCmd(cmd:string)= exec cmd task test, "Test": - execCmd "nim c -r tests/tnimterop" + execCmd "nim c -r tests/tnimterop_c.nim" + execCmd "nim c -r tests/tnimterop_cpp.nim" task installWithDeps, "install dependencies": for a in ["http://github.com/genotrance/nimtreesitter?subdir=treesitter", diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index 9c63665..0317787 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -2,20 +2,29 @@ import macros, os, strformat, strutils import ast, getters, globals, lisp +proc interpPath(dir: string): string= + # TODO: more robust: needs a DirSep after "$projpath" + result = dir.replace("$projpath", getProjectPath()) + +proc joinPathIfRel(path1: string, path2: string): string = + if path2.isAbsolute: + result = path2 + else: + result = joinPath(path1, path2) + proc findPath(path: string, fail = true): string = # As is result = path.replace("\\", "/") if not fileExists(result) and not dirExists(result): # Relative to project path - result = joinPath(getProjectPath(), path).replace("\\", "/") + result = joinPathIfRel(getProjectPath(), path).replace("\\", "/") if not fileExists(result) and not dirExists(result): if fail: - echo "File or directory not found: " & path - quit(1) + doAssert false, "File or directory not found: " & path else: return "" -proc cSearchPath*(path: string): string = +proc cSearchPath*(path: string): string {.compileTime.}= result = findPath(path, fail = false) if result.len == 0: var found = false @@ -24,9 +33,7 @@ proc cSearchPath*(path: string): string = if fileExists(result) or dirExists(result): found = true break - if not found: - echo "File or directory not found: " & path - quit(1) + doAssert found, "File or directory not found: " & path & " gSearchDirs: " & $gSearchDirs macro cDebug*(): untyped = gDebug = true @@ -50,13 +57,12 @@ macro cDefine*(name: static string, val: static string = ""): untyped = echo result.repr macro cAddSearchDir*(dir: static string): untyped = - result = newNimNode(nnkStmtList) - - let fullpath = cSearchPath(dir) - if fullpath notin gSearchDirs: - gSearchDirs.add(fullpath) + var dir = interpPath(dir) + if dir notin gSearchDirs: + gSearchDirs.add(dir) macro cIncludeDir*(dir: static string): untyped = + var dir = interpPath(dir) result = newNimNode(nnkStmtList) let diff --git a/tests/include/test2.cpp b/tests/include/test2.cpp new file mode 100644 index 0000000..4a40e90 --- /dev/null +++ b/tests/include/test2.cpp @@ -0,0 +1,8 @@ +#include "test2.hpp" + +// BUG: should complain +// # include test2.h + +int test_call_int() { + return 5; +} diff --git a/tests/include/test2.hpp b/tests/include/test2.hpp new file mode 100644 index 0000000..1ba9a8d --- /dev/null +++ b/tests/include/test2.hpp @@ -0,0 +1,20 @@ +#define TEST_INT 512 + +int test_call_int(); + +struct Foo{ + int bar; +}; + +class Foo1{ + int bar1; +}; + +template +struct Foo2{ + int bar2; +}; + +typedef Foo2 Foo2_int; + + diff --git a/tests/tnimterop.nim b/tests/tnimterop_c.nim similarity index 90% rename from tests/tnimterop.nim rename to tests/tnimterop_c.nim index dd822cb..1f2aaab 100644 --- a/tests/tnimterop.nim +++ b/tests/tnimterop_c.nim @@ -3,8 +3,8 @@ import nimterop/cimport cDebug() cDefine("FORCE") -cIncludeDir "include" -cAddSearchDir "include" +cIncludeDir "$projpath/include" +cAddSearchDir "$projpath/include" cCompile cSearchPath("test.c") cImport cSearchPath "test.h" diff --git a/tests/tnimterop_cpp.nim b/tests/tnimterop_cpp.nim new file mode 100644 index 0000000..b3d62f5 --- /dev/null +++ b/tests/tnimterop_cpp.nim @@ -0,0 +1,49 @@ +import nimterop/cimport +import unittest + +cDebug() + +cIncludeDir "$projpath/include" +cAddSearchDir "$projpath/include" +cCompile cSearchPath "test2.cpp" +# TODO: allow this to have correct language: cImport("test2.h") +cImport cSearchPath "test2.hpp" + +check TEST_INT == 512 +check test_call_int() == 5 + +var foo: Foo +check foo.bar == 2 + +# var foo2: Foo2[int] +# var foo2: Foo2Int + +when false: + doAssert TEST_FLOAT == 5.12 + doAssert TEST_HEX == 0x512 + + var + pt: PRIMTYPE + ct: CUSTTYPE + + s: STRUCT1 + s2: STRUCT2 + s3: STRUCT3 + + e: ENUM + e2: ENUM2 = enum5 + + pt = 3 + ct = 4 + + s.field1 = 5 + s2.field1 = 6 + s3.field1 = 7 + + e = enum1 + e2 = enum4 + + doAssert test_call_int_param(5).field1 == 5 + doAssert test_call_int_param2(5, s2).field1 == 11 + doAssert test_call_int_param3(5, s).field1 == 10 + doAssert test_call_int_param4(e) == e2 From 6a4158dab4ee36214678a92a1e5605a00402f01c Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Tue, 27 Nov 2018 18:25:34 -0500 Subject: [PATCH 023/593] fixup --- nimterop.nimble | 2 +- tests/include/test.h | 2 +- tests/include/test2.cpp | 3 --- tests/include/test2.hpp | 4 ++++ tests/tnimterop_cpp.nim | 38 +++----------------------------------- 5 files changed, 9 insertions(+), 40 deletions(-) diff --git a/nimterop.nimble b/nimterop.nimble index 52241a3..aef56fc 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -18,7 +18,7 @@ proc execCmd(cmd:string)= task test, "Test": execCmd "nim c -r tests/tnimterop_c.nim" - execCmd "nim c -r tests/tnimterop_cpp.nim" + execCmd "nim cpp -r tests/tnimterop_cpp.nim" task installWithDeps, "install dependencies": for a in ["http://github.com/genotrance/nimtreesitter?subdir=treesitter", diff --git a/tests/include/test.h b/tests/include/test.h index 7de6eed..6138ca3 100644 --- a/tests/include/test.h +++ b/tests/include/test.h @@ -40,4 +40,4 @@ int test_call_int(); struct STRUCT1 _test_call_int_param_(int param1); STRUCT2 test_call_int_param2(int param1, STRUCT2 param2); STRUCT2 test_call_int_param3(int param1, struct STRUCT1 param2); -ENUM2 test_call_int_param4(enum ENUM param1); \ No newline at end of file +ENUM2 test_call_int_param4(enum ENUM param1); diff --git a/tests/include/test2.cpp b/tests/include/test2.cpp index 4a40e90..7039cde 100644 --- a/tests/include/test2.cpp +++ b/tests/include/test2.cpp @@ -1,8 +1,5 @@ #include "test2.hpp" -// BUG: should complain -// # include test2.h - int test_call_int() { return 5; } diff --git a/tests/include/test2.hpp b/tests/include/test2.hpp index 1ba9a8d..0fd90ee 100644 --- a/tests/include/test2.hpp +++ b/tests/include/test2.hpp @@ -1,4 +1,8 @@ +#include + #define TEST_INT 512 +#define TEST_FLOAT 5.12 +#define TEST_HEX 0x512 int test_call_int(); diff --git a/tests/tnimterop_cpp.nim b/tests/tnimterop_cpp.nim index b3d62f5..bed052c 100644 --- a/tests/tnimterop_cpp.nim +++ b/tests/tnimterop_cpp.nim @@ -6,44 +6,12 @@ cDebug() cIncludeDir "$projpath/include" cAddSearchDir "$projpath/include" cCompile cSearchPath "test2.cpp" -# TODO: allow this to have correct language: cImport("test2.h") cImport cSearchPath "test2.hpp" check TEST_INT == 512 +check TEST_FLOAT == 5.12 +check TEST_HEX == 0x512 check test_call_int() == 5 var foo: Foo -check foo.bar == 2 - -# var foo2: Foo2[int] -# var foo2: Foo2Int - -when false: - doAssert TEST_FLOAT == 5.12 - doAssert TEST_HEX == 0x512 - - var - pt: PRIMTYPE - ct: CUSTTYPE - - s: STRUCT1 - s2: STRUCT2 - s3: STRUCT3 - - e: ENUM - e2: ENUM2 = enum5 - - pt = 3 - ct = 4 - - s.field1 = 5 - s2.field1 = 6 - s3.field1 = 7 - - e = enum1 - e2 = enum4 - - doAssert test_call_int_param(5).field1 == 5 - doAssert test_call_int_param2(5, s2).field1 == 11 - doAssert test_call_int_param3(5, s).field1 == 10 - doAssert test_call_int_param4(e) == e2 +check foo.bar == 0 From c1ea14c0d3c80e401aabeb2d99431d41c4347fe1 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Tue, 27 Nov 2018 18:27:59 -0500 Subject: [PATCH 024/593] doAssert => check --- tests/tnimterop_c.nim | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/tests/tnimterop_c.nim b/tests/tnimterop_c.nim index 1f2aaab..eff7039 100644 --- a/tests/tnimterop_c.nim +++ b/tests/tnimterop_c.nim @@ -1,3 +1,4 @@ +import std/unittest import nimterop/cimport cDebug() @@ -8,9 +9,9 @@ cAddSearchDir "$projpath/include" cCompile cSearchPath("test.c") cImport cSearchPath "test.h" -doAssert TEST_INT == 512 -doAssert TEST_FLOAT == 5.12 -doAssert TEST_HEX == 0x512 +check TEST_INT == 512 +check TEST_FLOAT == 5.12 +check TEST_HEX == 0x512 var pt: PRIMTYPE @@ -37,10 +38,10 @@ s3.field1 = 7 e = enum1 e2 = enum4 -doAssert test_call_int() == 5 -doAssert test_call_int_param(5).field1 == 5 -doAssert test_call_int_param2(5, s2).field1 == 11 -doAssert test_call_int_param3(5, s).field1 == 10 -doAssert test_call_int_param4(e) == e2 +check test_call_int() == 5 +check test_call_int_param(5).field1 == 5 +check test_call_int_param2(5, s2).field1 == 11 +check test_call_int_param3(5, s).field1 == 10 +check test_call_int_param4(e) == e2 cAddStdDir() From b8cddadfd0d62826b8e9fd2ff4e9e704732e5e5b Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 27 Nov 2018 18:01:38 -0600 Subject: [PATCH 025/593] Add CI --- .travis.yml | 26 ++++++++++++++++ appveyor.yml | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 112 insertions(+) create mode 100644 .travis.yml create mode 100644 appveyor.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..ca42600 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,26 @@ +sudo: false +language: c +os: + - linux + - osx +dist: trusty + +before_script: + - curl -u $TOKEN -o latest.json --silent https://api.github.com/repos/nim-lang/nightlies/releases/latest + - export RELEASE=`cat latest.json | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/'` + - export TXZ=`cat latest.json | grep '"name":' | sed -E 's/.*"([^"]+)".*/\1/' | grep linux | tail -n 1` + - export VERSION=`echo $TXZ | cut -d"-" -f 2,2` + - echo "RELEASE = $RELEASE, TXZ = $TXZ, VERSION = $VERSION" + - curl -L --silent -o $TXZ "https://github.com/nim-lang/nightlies/releases/download/$RELEASE/$TXZ" + - tar xf $TXZ + - cd nim-$VERSION + - sh build.sh + - bin/nim c koch + - ./koch boot -d:release + - ./koch nimble + - export PATH=$(pwd)/bin:~/.nimble/bin:$PATH + - cd .. + +script: + - nimble installWithDeps + - nimble test diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 0000000..b4bbcd9 --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,86 @@ +version: '{build}' + +image: + - Ubuntu + - Visual Studio 2017 + +matrix: + fast_finish: true + +environment: + matrix: + - NIM_VERSION: 0.19.0 + +for: +- + matrix: + only: + - image: Visual Studio 2017 + + environment: + ARCH: 32 + MINGW_URL: https://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win32/Personal%20Builds/mingw-builds/8.1.0/threads-posix/dwarf + MINGW_ARCHIVE: i686-8.1.0-release-posix-dwarf-rt_v6-rev0.7z + SFNET_URL: https://sourceforge.net/projects/msys2/files/REPOS/MINGW/i686 + + install: + - CD c:\ + - IF not exist "binaries" ( + echo %NIM_VERSION% && + MKDIR binaries && + CD binaries && + appveyor DownloadFile "%MINGW_URL%/%MINGW_ARCHIVE%/download" -FileName "%MINGW_ARCHIVE%" && + 7z x -y "%MINGW_ARCHIVE%"> nul && + del "%MINGW_ARCHIVE%" && + appveyor DownloadFile "https://nim-lang.org/download/nim-%NIM_VERSION%_x%ARCH%.zip" -FileName "nim-%NIM_VERSION%_x%ARCH%.zip" && + 7z x -y "nim-%NIM_VERSION%_x%ARCH%.zip"> nul && + del "nim-%NIM_VERSION%_x%ARCH%.zip") + - SET PATH=c:\binaries\mingw%ARCH%\bin;c:\binaries\nim-%NIM_VERSION%\bin;%USERPROFILE%\.nimble\bin;%PATH% + - CD c:\projects\nimterop + + on_finish: + - 7z a -r buildlogs-win-pkgs.zip %USERPROFILE%\.nimble\pkgs + - appveyor PushArtifact buildlogs-win-pkgs.zip + - 7z a -r buildlogs-win-projects.zip c:\projects\* + - appveyor PushArtifact buildlogs-win-projects.zip + + cache: + - c:\binaries + +- + matrix: + only: + - image: Ubuntu + + install: + - if [ ! -e /home/appveyor/binaries ]; then + echo $NIM_VERSION && + mkdir /home/appveyor/binaries && + cd /home/appveyor/binaries && + curl -s -o nim-$NIM_VERSION.tar.xz https://nim-lang.org/download/nim-$NIM_VERSION.tar.xz && + tar xJf nim-$NIM_VERSION.tar.xz && + cd nim-$NIM_VERSION && + sh build.sh && + bin/nim c -d:release koch && + ./koch boot -d:release && + ./koch nimble -d:release; + fi + - export PATH=/home/appveyor/binaries/nim-$NIM_VERSION/bin:~/.nimble/bin:$PATH + - cd /home/appveyor/projects/nimterop + + on_finish: + - zip -r -q buildlogs-lin-pkgs.zip ~/.nimble/pkgs + - appveyor PushArtifact buildlogs-lin-pkgs.zip + - zip -r -q buildlogs-lin-projects.zip /home/appveyor/projects + - appveyor PushArtifact buildlogs-lin-projects.zip + + cache: + - /home/appveyor/binaries + +build_script: + - nimble installWithDeps + +test_script: + - nimble test + +deploy: off From 51180f63738ad6cb1a3b621b1ad35de5a3f19fc5 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 27 Nov 2018 18:09:42 -0600 Subject: [PATCH 026/593] Build status on Github --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 8aa6dfa..c9625ba 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,7 @@ +[![Chat on Gitter](https://badges.gitter.im/gitterHQ/gitter.png)](https://gitter.im/nimgen/Lobby) +[![Build status](https://ci.appveyor.com/api/projects/status/nsaar5foexk9adan/branch/master?svg=true)](https://ci.appveyor.com/project/genotrance/nimterop/branch/master) +[![Build Status](https://travis-ci.org/genotrance/nimterop.svg?branch=master)](https://travis-ci.org/genotrance/nimterop) + Nimterop is a [Nim](https://nim-lang.org/) package that aims to make C/C++ interop seamless Nim has one of the best FFI you can find - importing C/C++ is supported out of the box. All you need to provide is type and proc definitions for Nim to interop with C/C++ binaries. Generation of these wrappers is easy for simple libraries but quickly gets out of hand. [c2nim](https://github.com/nim-lang/c2nim) greatly helps here by parsing and converting C/C++ into Nim but is limited due to the complex and constantly evolving C/C++ grammar. [nimgen](https://github.com/genotrance/nimgen) mainly focuses on automating the wrapping process and fills some holes but is again limited to c2nim's capabilities. From 3a3c1f5e57781af29b433c1f320849e3fbb1ade3 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Tue, 27 Nov 2018 19:51:04 -0500 Subject: [PATCH 027/593] fix 32bit builds --- nimterop/globals.nim | 2 +- nimterop/lisp.nim | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/nimterop/globals.nim b/nimterop/globals.nim index ae3d03b..8797af8 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -14,7 +14,7 @@ type Ast* = object sym*: Sym - start*, stop*: uint32 + start*, stop*: int parent*: ref Ast children*: seq[ref Ast] diff --git a/nimterop/lisp.nim b/nimterop/lisp.nim index 36c810a..44d609f 100644 --- a/nimterop/lisp.nim +++ b/nimterop/lisp.nim @@ -41,8 +41,8 @@ proc readFromTokens(): ref Ast = result.sym = parseEnum[Sym](gTokens[idx+1]) except: result.sym = IGNORED - result.start = gTokens[idx+2].parseInt().uint32 - result.stop = gTokens[idx+3].parseInt().uint32 + result.start = gTokens[idx+2].parseInt() + result.stop = gTokens[idx+3].parseInt() result.children = @[] idx += 4 while gTokens[idx] != ")": From e7f58adc4963de57efc617a1cc11b22f6563bdf2 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Tue, 27 Nov 2018 20:19:24 -0500 Subject: [PATCH 028/593] simplift travis --- .travis.yml | 42 ++++++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/.travis.yml b/.travis.yml index ca42600..60eabe7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,25 +1,31 @@ -sudo: false -language: c os: - linux - osx -dist: trusty -before_script: - - curl -u $TOKEN -o latest.json --silent https://api.github.com/repos/nim-lang/nightlies/releases/latest - - export RELEASE=`cat latest.json | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/'` - - export TXZ=`cat latest.json | grep '"name":' | sed -E 's/.*"([^"]+)".*/\1/' | grep linux | tail -n 1` - - export VERSION=`echo $TXZ | cut -d"-" -f 2,2` - - echo "RELEASE = $RELEASE, TXZ = $TXZ, VERSION = $VERSION" - - curl -L --silent -o $TXZ "https://github.com/nim-lang/nightlies/releases/download/$RELEASE/$TXZ" - - tar xf $TXZ - - cd nim-$VERSION - - sh build.sh - - bin/nim c koch - - ./koch boot -d:release - - ./koch nimble - - export PATH=$(pwd)/bin:~/.nimble/bin:$PATH - - cd .. +language: c + +env: + # test against both stable & devel + - BRANCH=stable + - BRANCH=devel + +cache: + directories: + - "$HOME/.nimble" + - "$HOME/.choosenim" + +matrix: + allow_failures: + - env: BRANCH=devel + fast_finish: true + +install: + - export CHOOSENIM_CHOOSE_VERSION=$BRANCH + - | + curl https://nim-lang.org/choosenim/init.sh -sSf > init.sh + sh init.sh -y + - export PATH=$HOME/.nimble/bin:$PATH + - nimble refresh -y script: - nimble installWithDeps From d7ca43f49fb544d1d1299a445ad519874ec63f3a Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 27 Nov 2018 20:14:32 -0600 Subject: [PATCH 029/593] Fix toast on Linux --- toast.nim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/toast.nim b/toast.nim index 4e01de7..409b293 100644 --- a/toast.nim +++ b/toast.nim @@ -120,7 +120,7 @@ proc parseCli() = for param in params: let flag = if param.len() <= 2: param else: param[0..<2] - if flag in ["-h", "--help", "-?", "/?", "/h"]: + if flag in ["-h", "-?"]: echo HELP quit() elif flag == "-a": @@ -139,4 +139,4 @@ proc parseCli() = else: process(param, mode, past, pretty, preprocess) -parseCli() \ No newline at end of file +parseCli() From 7344042029bf6319219c11b318372f55904c6491 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 28 Nov 2018 11:08:45 -0600 Subject: [PATCH 030/593] Move AST to Nim processing into toast --- nimterop/ast.nim | 318 ++++++++++++++++++++++++------------------- nimterop/cimport.nim | 72 ++++------ nimterop/getters.nim | 29 ++-- nimterop/globals.nim | 44 ++---- toast.nim | 78 ++++++----- 5 files changed, 267 insertions(+), 274 deletions(-) diff --git a/nimterop/ast.nim b/nimterop/ast.nim index cc1cd61..4cee1db 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -1,53 +1,41 @@ -import macros, os, strformat +import macros, os, strformat, strutils -import regex +import treesitter/runtime import getters, globals -proc addReorder*(): NimNode = - result = newNimNode(nnkStmtList) - if not gReorder: - gReorder = true - result.add parseStmt( - "{.experimental: \"codeReordering\".}" - ) - -proc addHeader*(fullpath: string) = - gCurrentHeader = ("header" & fullpath.splitFile().name.replace(re"[-.]+", "")) - gConstStr &= &" {gCurrentHeader} = \"{fullpath}\" # addHeader()\n" - # # Preprocessor # -proc pPreprocDef(node: ref Ast) = - if node.children.len == 2: +proc pPreprocDef(node: TSNode) = + if node.tsNodeNamedChildCount() == 2: let - name = getNodeValIf(node.children[0], identifier) - val = getNodeValIf(node.children[1], preproc_arg) + name = getNodeValIf(node.tsNodeNamedChild(0), "identifier") + val = getNodeValIf(node.tsNodeNamedChild(1), "preproc_arg") - if name.nBl and val.nBl and name notin gConsts: - gConsts.add(name) + if name.nBl and val.nBl and name notin gStateRT.consts: + gStateRT.consts.add(name) if val.getLit().nBl: # #define NAME VALUE - gConstStr &= &" {name.getIdentifier()}* = {val} # pPreprocDef()\n" + gStateRT.constStr &= &" {name.getIdentifier()}* = {val} # pPreprocDef()\n" # # Types # -proc typeScan(node: ref Ast, sym, id: Sym, offset: string): string = - if node.sym != sym or node.children.len != 2: +proc typeScan(node: TSNode, sym, id: string, offset: string): string = + if node.tsNodeIsNull() or $node.tsNodeType() != sym or node.tsNodeNamedChildCount() != 2: return var - name = getNodeValIf(node.children[1], id) - ptyp = getNodeValIf(node.children[0], primitive_type) - ttyp = getNodeValIf(node.children[0], type_identifier) + name = getNodeValIf(node.tsNodeNamedChild(1), id) + ptyp = getNodeValIf(node.tsNodeNamedChild(0), "primitive_type") + ttyp = getNodeValIf(node.tsNodeNamedChild(0), "type_identifier") ptrname = false - if name.len == 0 and node.children[1].sym == pointer_declarator and node.children[1].children.len == 1: - name = getNodeValIf(node.children[1].children[0], id) + if name.len == 0 and $node.tsNodeNamedChild(1).tsNodeType() == "pointer_declarator" and node.tsNodeNamedChild(1).tsNodeNamedChildCount() == 1: + name = getNodeValIf(node.tsNodeNamedChild(1).tsNodeNamedChild(0), id) ptrname = true if name.len == 0: @@ -61,194 +49,238 @@ proc typeScan(node: ref Ast, sym, id: Sym, offset: string): string = if ptrname: ttyp = &"ptr {ttyp}" result = &"{offset}{name.getIdentifier()}: {ttyp}" - elif node.children[0].sym in [struct_specifier, enum_specifier] and node.children[0].children.len == 1: - var styp = getNodeValIf(node.children[0].children[0], type_identifier) + elif $node.tsNodeNamedChild(0).tsNodeType() in ["struct_specifier", "enum_specifier"] and node.tsNodeNamedChild(0).tsNodeNamedChildCount() == 1: + var styp = getNodeValIf(node.tsNodeNamedChild(0).tsNodeNamedChild(0), "type_identifier") if styp.nBl: if ptrname: styp = &"ptr {styp}" result = &"{offset}{name.getIdentifier()}: {styp}" - else: - return -proc pStructSpecifier(node: ref Ast, name = "") = +proc pStructSpecifier(node: TSNode, name = "") = var stmt: string - if node.children.len == 1 and name notin gTypes: - case node.children[0].sym: - of type_identifier: - let typ = getNodeValIf(node.children[0], type_identifier) + if node.tsNodeNamedChildCount() == 1 and name notin gStateRT.types: + case $node.tsNodeNamedChild(0).tsNodeType(): + of "type_identifier": + let typ = getNodeValIf(node.tsNodeNamedChild(0), "type_identifier") if typ.nBl: - gTypes.add(name) + gStateRT.types.add(name) if name != typ: # typedef struct X Y - gTypeStr &= &" {name.getIdentifier()}* = {typ} #1 pStructSpecifier()\n" + gStateRT.typeStr &= &" {name.getIdentifier()}* = {typ} #1 pStructSpecifier()\n" else: # typedef struct X X - gTypeStr &= &" {name.getIdentifier()}* {{.importc: \"{name}\", header: {gCurrentHeader}, bycopy.}} = object #2 pStructSpecifier()\n" + gStateRT.typeStr &= &" {name.getIdentifier()}* {{.importc: \"{name}\", header: {gStateRT.currentHeader}, bycopy.}} = object #2 pStructSpecifier()\n" - of field_declaration_list: + of "field_declaration_list": # typedef struct { fields } X - stmt = &" {name.getIdentifier()}* {{.importc: \"{name}\", header: {gCurrentHeader}, bycopy.}} = object #3 pStructSpecifier()\n" + stmt = &" {name.getIdentifier()}* {{.importc: \"{name}\", header: {gStateRT.currentHeader}, bycopy.}} = object #3 pStructSpecifier()\n" - for field in node.children[0].children: - let ts = typeScan(field, field_declaration, field_identifier, " ") + if node.tsNodeNamedChild(0).tsNodeNamedChildCount() != 0: + for i in 0 .. node.tsNodeNamedChild(0).tsNodeNamedChildCount()-1: + let ts = typeScan(node.tsNodeNamedChild(0).tsNodeNamedChild(i), "field_declaration", "field_identifier", " ") + if ts.len == 0: + return + stmt &= ts & "\n" + + gStateRT.types.add(name) + gStateRT.typeStr &= stmt + else: + discard + + elif name.len == 0 and node.tsNodeNamedChildCount() == 2 and $node.tsNodeNamedChild(1).tsNodeType() == "field_declaration_list": + let ename = getNodeValIf(node.tsNodeNamedChild(0), "type_identifier") + if ename.nBl and ename notin gStateRT.types: + # struct X { fields } + stmt &= &" {ename}* {{.importc: \"struct {ename}\", header: {gStateRT.currentHeader}, bycopy.}} = object #4 pStructSpecifier()\n" + + if node.tsNodeNamedChild(1).tsNodeNamedChildCount() != 0: + for i in 0 .. node.tsNodeNamedChild(1).tsNodeNamedChildCount()-1: + let ts = typeScan(node.tsNodeNamedChild(1).tsNodeNamedChild(i), "field_declaration", "field_identifier", " ") if ts.len == 0: return stmt &= ts & "\n" - gTypes.add(name) - gTypeStr &= stmt - else: - discard + gStateRT.types.add(name) + gStateRT.typeStr &= stmt - elif name.len == 0 and node.children.len == 2 and node.children[1].sym == field_declaration_list: - let ename = getNodeValIf(node.children[0], type_identifier) - if ename.nBl and ename notin gTypes: - # struct X { fields } - stmt &= &" {ename}* {{.importc: \"struct {ename}\", header: {gCurrentHeader}, bycopy.}} = object #4 pStructSpecifier()\n" - - for field in node.children[1].children: - let ts = typeScan(field, field_declaration, field_identifier, " ") - if ts.len == 0: - return - stmt &= ts & "\n" - - gTypes.add(name) - gTypeStr &= stmt - -proc pEnumSpecifier(node: ref Ast, name = "") = +proc pEnumSpecifier(node: TSNode, name = "") = var ename: string - elid: int + elid: uint32 stmt: string - if node.children.len == 1 and node.children[0].sym == enumerator_list: + if node.tsNodeNamedChildCount() == 1 and $node.tsNodeNamedChild(0).tsNodeType() == "enumerator_list": # typedef enum { fields } X ename = name elid = 0 stmt = &" {name.getIdentifier()}* = enum #1 pEnumSpecifier()\n" - elif name.len == 0 and node.children.len == 2 and node.children[1].sym == enumerator_list: - ename = getNodeValIf(node.children[0], type_identifier) + elif name.len == 0 and node.tsNodeNamedChildCount() == 2 and $node.tsNodeNamedChild(1).tsNodeType() == "enumerator_list": + ename = getNodeValIf(node.tsNodeNamedChild(0), "type_identifier") elid = 1 if ename.nBl: # enum X { fields } stmt = &" {ename}* = enum #2 pEnumSpecifier()\n" else: return + else: + return - for field in node.children[elid].children: - if field.sym == enumerator: - let fname = getNodeValIf(field.children[0], identifier) - if field.children.len == 1: - stmt &= &" {fname}\n" - elif field.children.len == 2 and field.children[1].sym == number_literal: - let num = getNodeValIf(field.children[1], number_literal) - stmt &= &" {fname} = {num}\n" - else: - return + if node.tsNodeNamedChild(elid).tsNodeNamedChildCount() != 0: + for i in 0 .. node.tsNodeNamedChild(elid).tsNodeNamedChildCount()-1: + let field = node.tsNodeNamedChild(elid).tsNodeNamedChild(i) + if not field.tsNodeIsNull() and $field.tsNodeType() == "enumerator": + let fname = getNodeValIf(field.tsNodeNamedChild(0), "identifier") + if field.tsNodeNamedChildCount() == 1: + stmt &= &" {fname}\n" + elif field.tsNodeNamedChildCount() == 2 and $field.tsNodeNamedChild(1).tsNodeType() == "number_literal": + let num = getNodeValIf(field.tsNodeNamedChild(1), "number_literal") + stmt &= &" {fname} = {num}\n" + else: + return - if ename notin gTypes: - gTypes.add(name) - gTypeStr &= stmt + if ename notin gStateRT.types: + gStateRT.types.add(name) + gStateRT.typeStr &= stmt -proc pTypeDefinition(node: ref Ast) = - if node.children.len == 2: +proc pTypeDefinition(node: TSNode) = + if node.tsNodeNamedChildCount() == 2: var - name = getNodeValIf(node.children[1], type_identifier) - ptyp = getNodeValIf(node.children[0], primitive_type) - ttyp = getNodeValIf(node.children[0], type_identifier) + name = getNodeValIf(node.tsNodeNamedChild(1), "type_identifier") + ptyp = getNodeValIf(node.tsNodeNamedChild(0), "primitive_type") + ttyp = getNodeValIf(node.tsNodeNamedChild(0), "type_identifier") ptrname = false - if name.len == 0 and node.children[1].sym == pointer_declarator and node.children[1].children.len == 1: - name = getNodeValIf(node.children[1].children[0], type_identifier) + if name.len == 0 and $node.tsNodeNamedChild(1).tsNodeType() == "pointer_declarator" and node.tsNodeNamedChild(1).tsNodeNamedChildCount() == 1: + name = getNodeValIf(node.tsNodeNamedChild(1).tsNodeNamedChild(0), "type_identifier") ptrname = true - if name.nBl and name notin gTypes: + if name.nBl and name notin gStateRT.types: if ptyp.nBl: # typedef int X - gTypes.add(name) + gStateRT.types.add(name) ptyp = ptyp.getType() if ptyp != "object" and ptrname: ptyp = &"ptr {ptyp}" - gTypeStr &= &" {name.getIdentifier()}* = {ptyp} #1 pTypeDefinition()\n" + gStateRT.typeStr &= &" {name.getIdentifier()}* = {ptyp} #1 pTypeDefinition()\n" elif ttyp.nBl: # typedef X Y - gTypes.add(name) + gStateRT.types.add(name) if ptrname: ttyp = &"ptr {ttyp}" - gTypeStr &= &" {name.getIdentifier()}* = {ttyp} #2 pTypeDefinition()\n" + gStateRT.typeStr &= &" {name.getIdentifier()}* = {ttyp} #2 pTypeDefinition()\n" else: - case node.children[0].sym: - of struct_specifier: - pStructSpecifier(node.children[0], name) - of enum_specifier: - pEnumSpecifier(node.children[0], name) + case $node.tsNodeNamedChild(0).tsNodeType(): + of "struct_specifier": + pStructSpecifier(node.tsNodeNamedChild(0), name) + of "enum_specifier": + pEnumSpecifier(node.tsNodeNamedChild(0), name) else: discard -proc pFunctionDeclarator(node: ref Ast, typ: string) = - if node.children.len == 2: +proc pFunctionDeclarator(node: TSNode, typ: string) = + if node.tsNodeNamedChildCount() == 2: let - name = getNodeValIf(node.children[0], identifier) + name = getNodeValIf(node.tsNodeNamedChild(0), "identifier") - if name.nBl and name notin gProcs and node.children[1].sym == parameter_list: + if name.nBl and name notin gStateRT.procs and $node.tsNodeNamedChild(1).tsNodeType() == "parameter_list": # typ function(typ param1, ...) var stmt = &"# pFunctionDeclarator()\nproc {name.getIdentifier()}*(" - for i in 0 .. node.children[1].children.len-1: - let ts = typeScan(node.children[1].children[i], parameter_declaration, identifier, "") - if ts.len == 0: - return - stmt &= ts - if i != node.children[1].children.len-1: - stmt &= ", " + if node.tsNodeNamedChild(1).tsNodeNamedChildCount() != 0: + for i in 0 .. node.tsNodeNamedChild(1).tsNodeNamedChildCount()-1: + let ts = typeScan(node.tsNodeNamedChild(1).tsNodeNamedChild(i), "parameter_declaration", "identifier", "") + if ts.len == 0: + return + stmt &= ts + if i != node.tsNodeNamedChild(1).tsNodeNamedChildCount()-1: + stmt &= ", " if typ != "void": stmt &= &"): {typ.getType()} " else: stmt &= ") " - stmt &= &"{{.importc: \"{name}\", header: {gCurrentHeader}.}}\n" + stmt &= &"{{.importc: \"{name}\", header: {gStateRT.currentHeader}.}}\n" - gProcs.add(name) - gProcStr &= stmt + gStateRT.procs.add(name) + gStateRT.procStr &= stmt -proc pDeclaration*(node: ref Ast) = - if node.children.len == 2 and node.children[1].sym == function_declarator: +proc pDeclaration*(node: TSNode) = + if node.tsNodeNamedChildCount() == 2 and $node.tsNodeNamedChild(1).tsNodeType() == "function_declarator": let - ptyp = getNodeValIf(node.children[0], primitive_type) - ttyp = getNodeValIf(node.children[0], type_identifier) + ptyp = getNodeValIf(node.tsNodeNamedChild(0), "primitive_type") + ttyp = getNodeValIf(node.tsNodeNamedChild(0), "type_identifier") if ptyp.nBl: - pFunctionDeclarator(node.children[1], ptyp.getType()) + pFunctionDeclarator(node.tsNodeNamedChild(1), ptyp.getType()) elif ttyp.nBl: - pFunctionDeclarator(node.children[1], ttyp) - elif node.children[0].sym == struct_specifier and node.children[0].children.len == 1: - let styp = getNodeValIf(node.children[0].children[0], type_identifier) + pFunctionDeclarator(node.tsNodeNamedChild(1), ttyp) + elif $node.tsNodeNamedChild(0).tsNodeType() == "struct_specifier" and node.tsNodeNamedChild(0).tsNodeNamedChildCount() == 1: + let styp = getNodeValIf(node.tsNodeNamedChild(0).tsNodeNamedChild(0), "type_identifier") if styp.nBl: - pFunctionDeclarator(node.children[1], styp) + pFunctionDeclarator(node.tsNodeNamedChild(1), styp) -proc genNimAst*(node: ref Ast) = - if node.isNil: - return +proc genNimAst(root: TSNode) = + var + node = root + nextnode: TSNode - case node.sym: - of ERROR: - let (line, col) = getLineCol(node) - echo &"Potentially invalid syntax at line {line} column {col}" - of preproc_def: - pPreprocDef(node) - of type_definition: - pTypeDefinition(node) - of declaration: - pDeclaration(node) - of struct_specifier: - if node.parent.sym notin [type_definition, declaration]: - pStructSpecifier(node) - of enum_specifier: - if node.parent.sym notin [type_definition, declaration]: - pEnumSpecifier(node) + while true: + if not node.tsNodeIsNull(): + case $node.tsNodeType(): + of "ERROR": + let (line, col) = getLineCol(node) + echo &"Potentially invalid syntax at line {line} column {col}" + of "preproc_def": + pPreprocDef(node) + of "type_definition": + pTypeDefinition(node) + of "declaration": + pDeclaration(node) + of "struct_specifier": + if $node.tsNodeParent().tsNodeType() notin ["type_definition", "declaration"]: + pStructSpecifier(node) + of "enum_specifier": + if $node.tsNodeParent.tsNodeType() notin ["type_definition", "declaration"]: + pEnumSpecifier(node) + else: + discard else: - discard + return - for child in node.children: - genNimAst(child) + if node.tsNodeNamedChildCount() != 0: + nextnode = node.tsNodeNamedChild(0) + else: + nextnode = node.tsNodeNextNamedSibling() + + if nextnode.tsNodeIsNull(): + while true: + node = node.tsNodeParent() + if node == root: + break + if not node.tsNodeNextNamedSibling().tsNodeIsNull(): + node = node.tsNodeNextNamedSibling() + break + else: + node = nextnode + + if node == root: + break + +proc printNim*(fullpath: string, root: TSNode) = + echo "{.experimental: \"codeReordering\".}" + + var fp = fullpath.replace("\\", "/") + gStateRT.currentHeader = getCurrentHeader(fullpath) + gStateRT.constStr &= &" {gStateRT.currentHeader} = \"{fp}\"\n" + + genNimAst(root) + + if gStateRT.constStr.nBl: + echo "const\n" & gStateRT.constStr + + if gStateRT.typeStr.nBl: + echo "type\n" & gStateRT.typeStr + + if gStateRT.procStr.nBl: + echo gStateRT.procStr diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index 0317787..fc0d057 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -1,6 +1,6 @@ import macros, os, strformat, strutils -import ast, getters, globals, lisp +import getters, globals proc interpPath(dir: string): string= # TODO: more robust: needs a DirSep after "$projpath" @@ -24,19 +24,31 @@ proc findPath(path: string, fail = true): string = else: return "" +proc getToast(fullpath: string): string = + var + cmd = "toast -n -p " + + for i in gStateCT.defines: + cmd &= &"-D\"{i}\" " + + for i in gStateCT.includeDirs: + cmd &= &"-I\"{i}\" " + + result = staticExec(cmd & fullpath) + proc cSearchPath*(path: string): string {.compileTime.}= result = findPath(path, fail = false) if result.len == 0: var found = false - for inc in gSearchDirs: + for inc in gStateCT.searchDirs: result = (inc & "/" & path).replace("\\", "/") if fileExists(result) or dirExists(result): found = true break - doAssert found, "File or directory not found: " & path & " gSearchDirs: " & $gSearchDirs + doAssert found, "File or directory not found: " & path & " gStateCT.searchDirs: " & $gStateCT.searchDirs macro cDebug*(): untyped = - gDebug = true + gStateCT.debug = true macro cDefine*(name: static string, val: static string = ""): untyped = result = newNimNode(nnkStmtList) @@ -45,21 +57,21 @@ macro cDefine*(name: static string, val: static string = ""): untyped = if val.nBl: str &= &"=\"{val}\"" - if str notin gDefines: - gDefines.add(str) + if str notin gStateCT.defines: + gStateCT.defines.add(str) str = "-D" & str result.add(quote do: {.passC: `str`.} ) - if gDebug: + if gStateCT.debug: echo result.repr macro cAddSearchDir*(dir: static string): untyped = var dir = interpPath(dir) - if dir notin gSearchDirs: - gSearchDirs.add(dir) + if dir notin gStateCT.searchDirs: + gStateCT.searchDirs.add(dir) macro cIncludeDir*(dir: static string): untyped = var dir = interpPath(dir) @@ -69,14 +81,14 @@ macro cIncludeDir*(dir: static string): untyped = fullpath = findPath(dir) str = &"-I\"{fullpath}\"" - if fullpath notin gIncludeDirs: - gIncludeDirs.add(fullpath) + if fullpath notin gStateCT.includeDirs: + gStateCT.includeDirs.add(fullpath) result.add(quote do: {.passC: `str`.} ) - if gDebug: + if gStateCT.debug: echo result.repr macro cAddStdDir*(mode = "c"): untyped = @@ -109,11 +121,11 @@ macro cCompile*(path: static string): untyped = var ufn = fn uniq = 1 - while ufn in gCompile: + while ufn in gStateCT.compile: ufn = fn & $uniq uniq += 1 - gCompile.add(ufn) + gStateCT.compile.add(ufn) if fn == ufn: return "{.compile: \"$#\".}" % file.replace("\\", "/") else: @@ -138,44 +150,18 @@ macro cCompile*(path: static string): untyped = result.add stmt.parseStmt() - if gDebug: + if gStateCT.debug: echo result.repr macro cImport*(filename: static string): untyped = result = newNimNode(nnkStmtList) - result.add addReorder() let fullpath = findPath(filename) - root = parseLisp(fullpath) echo "Importing " & fullpath - gCode = staticRead(fullpath) - gConstStr = "" - gTypeStr = "" + result.add parseStmt(getToast(fullpath)) - addHeader(fullpath) - genNimAst(root) - - if gConstStr.nBl: - if gDebug: - echo "const\n" & gConstStr - result.add parseStmt( - "const\n" & gConstStr - ) - - if gTypeStr.nBl: - if gDebug: - echo "type\n" & gTypeStr - result.add parseStmt( - "type\n" & gTypeStr - ) - - if gProcStr.nBl: - if gDebug: - echo gProcStr - result.add gProcStr.parseStmt() - - if gDebug: + if gStateCT.debug: echo result.repr diff --git a/nimterop/getters.nim b/nimterop/getters.nim index c9ac3b9..a402610 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -2,6 +2,8 @@ import macros, ospaths, strformat, strutils import regex +import treesitter/runtime + import git, globals proc sanitizePath*(path: string): string = @@ -19,21 +21,24 @@ proc getLit*(str: string): string = str.contains(re"^0x[\d]+$"): return str -proc getNodeValIf*(node: ref Ast, esym: Sym): string = - if esym != node.sym: +proc getNodeValIf*(node: TSNode, esym: string): string = + if esym != $node.tsNodeType(): return - return gCode[node.start .. node.stop-1].strip() + return gStateRT.code[node.tsNodeStartByte() .. node.tsNodeEndByte()-1].strip() -proc getLineCol*(node: ref Ast): tuple[line, col: int] = +proc getLineCol*(node: TSNode): tuple[line, col: int] = result.line = 1 result.col = 1 - for i in 0 .. node.start-1: - if gCode[i] == '\n': + for i in 0 .. node.tsNodeStartByte()-1: + if gStateRT.code[i] == '\n': result.col = 0 result.line += 1 result.col += 1 +proc getCurrentHeader*(fullpath: string): string = + ("header" & fullpath.splitFile().name.replace(re"[-.]+", "")) + proc getGccPaths*(mode = "c"): string = var nul = when defined(Windows): "nul" else: "/dev/null" @@ -45,23 +50,15 @@ proc getPreprocessor*(fullpath: string, mode = "cpp"): string = var mmode = if mode == "cpp": "c++" else: mode cmd = &"gcc -E -dD -x{mmode} " - gdef, gdir: seq[string] rdata: seq[string] = @[] start = false sfile = fullpath.sanitizePath - when nimvm: - gdef = gDefines - gdir = gIncludeDirs - else: - gdef = gDefinesRT - gdir = gIncludeDirsRT - - for inc in gdir: + for inc in gStateRT.includeDirs: cmd &= &"-I\"{inc}\" " - for def in gdef: + for def in gStateRT.defines: cmd &= &"-D{def} " cmd &= &"\"{fullpath}\"" diff --git a/nimterop/globals.nim b/nimterop/globals.nim index 8797af8..98e4249 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -1,42 +1,16 @@ -import macros - type - Sym* = enum - ERROR, IGNORED, - enumerator, enumerator_list, enum_specifier, - declaration, - field_declaration, field_declaration_list, field_identifier, function_declarator, - identifier, - number_literal, - parameter_declaration, parameter_list, pointer_declarator, preproc_arg, preproc_def, primitive_type, - struct_specifier, - type_definition, type_identifier + State* = object + compile*, defines*, headers*, includeDirs*, searchDirs*: seq[string] - Ast* = object - sym*: Sym - start*, stop*: int - parent*: ref Ast - children*: seq[ref Ast] + debug*, past*, preprocess*, pnim*, pretty*: bool + + consts*, procs*, types*: seq[string] + + code*, constStr*, currentHeader*, mode*, procStr*, typeStr*: string var - gDefines* {.compiletime.}: seq[string] - gDefinesRT*: seq[string] - gCompile* {.compiletime.}: seq[string] - gConsts* {.compiletime.}: seq[string] - gHeaders* {.compiletime.}: seq[string] - gIncludeDirs* {.compiletime.}: seq[string] - gIncludeDirsRT*: seq[string] - gProcs* {.compiletime.}: seq[string] - gSearchDirs* {.compiletime.}: seq[string] - gTypes* {.compiletime.}: seq[string] - - gCode* {.compiletime.}: string - gConstStr* {.compiletime.}: string - gCurrentHeader* {.compiletime.}: string - gDebug* {.compiletime.}: bool - gReorder* {.compiletime.}: bool - gProcStr* {.compiletime.}: string - gTypeStr* {.compiletime.}: string + gStateCT* {.compiletime.}: State + gStateRT*: State template nBl*(s: untyped): untyped = (s.len != 0) \ No newline at end of file diff --git a/toast.nim b/toast.nim index 409b293..4877c50 100644 --- a/toast.nim +++ b/toast.nim @@ -2,18 +2,20 @@ import os, strutils import treesitter/[runtime, c, cpp] -import nimterop/[globals, getters] +import nimterop/[ast, globals, getters] const HELP = """ > toast header.h -a print AST output --c C mode - CPP is default -m print minimized AST output - non-pretty (implies -a) +-n print Nim output + +-c C mode - CPP is default -p run preprocessor on header -D definitions to pass to preprocessor -I include directory to pass to preprocessor""" -proc printLisp(root: TSNode, data: var string, pretty = true) = +proc printLisp(root: TSNode) = var node = root nextnode: TSNode @@ -21,19 +23,19 @@ proc printLisp(root: TSNode, data: var string, pretty = true) = while true: if not node.tsNodeIsNull(): - if pretty: + if gStateRT.pretty: stdout.write spaces(depth) stdout.write "(" & $node.tsNodeType() & " " & $node.tsNodeStartByte() & " " & $node.tsNodeEndByte() else: return if node.tsNodeNamedChildCount() != 0: - if pretty: + if gStateRT.pretty: echo "" nextnode = node.tsNodeNamedChild(0) depth += 1 else: - if pretty: + if gStateRT.pretty: echo ")" else: stdout.write ")" @@ -45,7 +47,7 @@ proc printLisp(root: TSNode, data: var string, pretty = true) = depth -= 1 if depth == -1: break - if pretty: + if gStateRT.pretty: echo spaces(depth) & ")" else: stdout.write ")" @@ -60,7 +62,7 @@ proc printLisp(root: TSNode, data: var string, pretty = true) = if node == root: break -proc process(path: string, mode="cpp", past, pretty, preprocess: bool) = +proc process(path: string) = if not existsFile(path): echo "Invalid path " & path return @@ -68,54 +70,54 @@ proc process(path: string, mode="cpp", past, pretty, preprocess: bool) = var parser = tsParserNew() ext = path.splitFile().ext - pmode = "" - data = "" defer: parser.tsParserDelete() - if mode.len != 0: - pmode = mode + if gStateRT.mode.len != 0: + gStateRT.mode = "cpp" elif ext in [".h", ".c"]: - pmode = "c" + gStateRT.mode = "c" elif ext in [".hxx", ".hpp", ".hh", ".H", ".h++", ".cpp", ".cxx", ".cc", ".C", ".c++"]: - pmode = "cpp" + gStateRT.mode = "cpp" - if preprocess: - data = getPreprocessor(path) + if gStateRT.preprocess: + gStateRT.code = getPreprocessor(path) else: - data = readFile(path) + gStateRT.code = readFile(path) - if pmode == "c": + if gStateRT.mode == "c": if not parser.tsParserSetLanguage(treeSitterC()): echo "Failed to load C parser" quit() - elif pmode == "cpp": + elif gStateRT.mode == "cpp": if not parser.tsParserSetLanguage(treeSitterCpp()): echo "Failed to load C++ parser" quit() else: - echo "Invalid parser " & mode + echo "Invalid parser " & gStateRT.mode quit() var - tree = parser.tsParserParseString(nil, data.cstring, data.len.uint32) + tree = parser.tsParserParseString(nil, gStateRT.code.cstring, gStateRT.code.len.uint32) root = tree.tsTreeRootNode() defer: tree.tsTreeDelete() - if past: - printLisp(root, data, pretty) + if gStateRT.past: + printLisp(root) + elif gStateRT.pnim: + printNim(path, root) proc parseCli() = - var - mode = "cpp" - params = commandLineParams() + var params = commandLineParams() - past = false - pretty = true - preprocess = false + gStateRT.mode = "cpp" + gStateRT.past = false + gStateRT.pnim = false + gStateRT.pretty = true + gStateRT.preprocess = false for param in params: let flag = if param.len() <= 2: param else: param[0..<2] @@ -124,19 +126,21 @@ proc parseCli() = echo HELP quit() elif flag == "-a": - past = true + gStateRT.past = true elif flag == "-c": - mode = "c" + gStateRT.mode = "c" elif flag == "-m": - past = true - pretty = false + gStateRT.past = true + gStateRT.pretty = false + elif flag == "-n": + gStateRT.pnim = true elif flag == "-p": - preprocess = true + gStateRT.preprocess = true elif flag == "-D": - gDefinesRT.add(param[2..^1]) + gStateRT.defines.add(param[2..^1].strip(chars={'"'})) elif flag == "-I": - gIncludeDirsRT.add(param[2..^1]) + gStateRT.includeDirs.add(param[2..^1].strip(chars={'"'})) else: - process(param, mode, past, pretty, preprocess) + process(param) parseCli() From 691e7d80e5c5c7c099859d240633fe6bbe91f9f5 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 28 Nov 2018 11:37:53 -0600 Subject: [PATCH 031/593] Fix uint32 --- nimterop/getters.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimterop/getters.nim b/nimterop/getters.nim index a402610..f638edc 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -30,7 +30,7 @@ proc getNodeValIf*(node: TSNode, esym: string): string = proc getLineCol*(node: TSNode): tuple[line, col: int] = result.line = 1 result.col = 1 - for i in 0 .. node.tsNodeStartByte()-1: + for i in 0 .. node.tsNodeStartByte().int-1: if gStateRT.code[i] == '\n': result.col = 0 result.line += 1 From 4a6973c14de892970cddd952677fc7e578806479 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Wed, 28 Nov 2018 16:30:56 -0500 Subject: [PATCH 032/593] use cligen; fix bugs; some cleanups --- nimterop.nimble | 2 +- nimterop/cimport.nim | 12 ++++--- nimterop/getters.nim | 2 +- nimterop/globals.nim | 12 +++++-- nimterop/lisp.nim | 7 +++- toast.nim | 81 ++++++++++++++++++++------------------------ 6 files changed, 62 insertions(+), 54 deletions(-) diff --git a/nimterop.nimble b/nimterop.nimble index aef56fc..3bfd982 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -10,7 +10,7 @@ installDirs = @["nimterop"] # Dependencies -requires "nim >= 0.19.0", "treesitter >= 0.1.0", "treesitter_c >= 0.1.0", "treesitter_cpp >= 0.1.0", "regex >= 0.10.0" +requires "nim >= 0.19.0", "treesitter >= 0.1.0", "treesitter_c >= 0.1.0", "treesitter_cpp >= 0.1.0", "regex >= 0.10.0", "cligen >= 0.9.17" proc execCmd(cmd:string)= echo cmd diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index fc0d057..758237b 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -26,15 +26,19 @@ proc findPath(path: string, fail = true): string = proc getToast(fullpath: string): string = var - cmd = "toast -n -p " + cmd = "toast --pnim --preprocess " for i in gStateCT.defines: - cmd &= &"-D\"{i}\" " + cmd.add &"--defines+={i.quoteShell} " for i in gStateCT.includeDirs: - cmd &= &"-I\"{i}\" " + cmd.add &"--includeDirs+={i.quoteShell} " - result = staticExec(cmd & fullpath) + cmd.add &"--source:{fullpath.quoteShell}" + echo cmd + var (output, exitCode) = gorgeEx(cmd) + doAssert exitCode == 0, $exitCode + result = output proc cSearchPath*(path: string): string {.compileTime.}= result = findPath(path, fail = false) diff --git a/nimterop/getters.nim b/nimterop/getters.nim index f638edc..daf01ef 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -1,4 +1,4 @@ -import macros, ospaths, strformat, strutils +import macros, os, strformat, strutils import regex diff --git a/nimterop/globals.nim b/nimterop/globals.nim index 98e4249..1e3a83c 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -12,5 +12,13 @@ var gStateCT* {.compiletime.}: State gStateRT*: State -template nBl*(s: untyped): untyped = - (s.len != 0) \ No newline at end of file +template nBl*(s: typed): untyped = + (s.len != 0) + + +type CompileMode* = enum + c, + cpp, + +# TODO: can cligen accept enum instead of string? +const modeDefault* = $cpp # TODO: USE this everywhere relevant diff --git a/nimterop/lisp.nim b/nimterop/lisp.nim index 44d609f..8fa73e0 100644 --- a/nimterop/lisp.nim +++ b/nimterop/lisp.nim @@ -1,4 +1,5 @@ import strutils +import strformat import globals @@ -11,7 +12,11 @@ proc tokenize(fullpath: string) = gTokens = @[] idx = 0 - for i in staticExec("toast -m " & fullpath): + # TODO: consider calling API directly + const cmd = &"toast --past --pretty:false --source:{fullpath.quoteShell}" + var (output, exitCode) = gorgeEx cmd + doAssert exitCode == 0, $exitCode + for i in output: case i: of ' ', '\n', '\r', '(', ')': if collect.nBl: diff --git a/toast.nim b/toast.nim index 4877c50..b418308 100644 --- a/toast.nim +++ b/toast.nim @@ -4,17 +4,6 @@ import treesitter/[runtime, c, cpp] import nimterop/[ast, globals, getters] -const HELP = """ -> toast header.h --a print AST output --m print minimized AST output - non-pretty (implies -a) --n print Nim output - --c C mode - CPP is default --p run preprocessor on header --D definitions to pass to preprocessor --I include directory to pass to preprocessor""" - proc printLisp(root: TSNode) = var node = root @@ -74,8 +63,8 @@ proc process(path: string) = defer: parser.tsParserDelete() - if gStateRT.mode.len != 0: - gStateRT.mode = "cpp" + if gStateRT.mode.len == 0: + gStateRT.mode = modeDefault elif ext in [".h", ".c"]: gStateRT.mode = "c" elif ext in [".hxx", ".hpp", ".hh", ".H", ".h++", ".cpp", ".cxx", ".cc", ".C", ".c++"]: @@ -110,37 +99,39 @@ proc process(path: string) = elif gStateRT.pnim: printNim(path, root) -proc parseCli() = - var params = commandLineParams() +proc main( + mode = modeDefault, + past = false, + pnim = false, + pretty = true, + preprocess = false, + defines: seq[string] = @[], + includeDirs: seq[string] = @[], + # defines.add(param[2..^1].strip(chars={'"'})) + source: string, + ) = + # TODO: should we add back `-m` param? meaning was: print minimized AST output - non-pretty (implies -a) - gStateRT.mode = "cpp" - gStateRT.past = false - gStateRT.pnim = false - gStateRT.pretty = true - gStateRT.preprocess = false + gStateRT = State( + mode: mode, + past: past, + pnim: pnim, + pretty: pretty, + preprocess: preprocess, + # Note: was: strip(chars={'"'} but that seemed buggy (the shell should remove these already) + defines: defines, + includeDirs: includeDirs, + ) + process(source) - for param in params: - let flag = if param.len() <= 2: param else: param[0..<2] - - if flag in ["-h", "-?"]: - echo HELP - quit() - elif flag == "-a": - gStateRT.past = true - elif flag == "-c": - gStateRT.mode = "c" - elif flag == "-m": - gStateRT.past = true - gStateRT.pretty = false - elif flag == "-n": - gStateRT.pnim = true - elif flag == "-p": - gStateRT.preprocess = true - elif flag == "-D": - gStateRT.defines.add(param[2..^1].strip(chars={'"'})) - elif flag == "-I": - gStateRT.includeDirs.add(param[2..^1].strip(chars={'"'})) - else: - process(param) - -parseCli() +when isMainModule: + import cligen + dispatch(main, help = { + "past": "print AST output", + "mode": "language; see CompileMode", # TODO: auto-generate valid choices + "pnim": "run preprocessor on header", + "defines": "definitions to pass to preprocessor", + "includeDirs": "include directory to pass to preprocessor", + "preprocess": "print Nim output", + "source" : "C/C++ source/header", + }) From a2ff8ea64c5ff4cd54157ce3c35cbeef59d3187e Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 28 Nov 2018 16:06:15 -0600 Subject: [PATCH 033/593] Update README [ci skip] --- README.md | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index c9625ba..38b2f1d 100644 --- a/README.md +++ b/README.md @@ -6,19 +6,21 @@ Nimterop is a [Nim](https://nim-lang.org/) package that aims to make C/C++ inter Nim has one of the best FFI you can find - importing C/C++ is supported out of the box. All you need to provide is type and proc definitions for Nim to interop with C/C++ binaries. Generation of these wrappers is easy for simple libraries but quickly gets out of hand. [c2nim](https://github.com/nim-lang/c2nim) greatly helps here by parsing and converting C/C++ into Nim but is limited due to the complex and constantly evolving C/C++ grammar. [nimgen](https://github.com/genotrance/nimgen) mainly focuses on automating the wrapping process and fills some holes but is again limited to c2nim's capabilities. -The goal of nimterop is to leverage the [tree-sitter](http://tree-sitter.github.io/tree-sitter/) engine to parse C/C++ code and then convert relevant portions of the AST into Nim definitions using compile-time macros. [tree-sitter](https://github.com/tree-sitter) is a Github sponsored project that can parse a variety of languages into an AST which is then leveraged by the [Atom](https://atom.io/) editor for syntax highlighting and code folding. The advantages of this approach are multifold: +The goal of nimterop is to leverage the [tree-sitter](http://tree-sitter.github.io/tree-sitter/) engine to parse C/C++ code and then convert relevant portions of the AST into Nim definitions. [tree-sitter](https://github.com/tree-sitter) is a Github sponsored project that can parse a variety of languages into an AST which is then leveraged by the [Atom](https://atom.io/) editor for syntax highlighting and code folding. The advantages of this approach are multifold: - Benefit from the tree-sitter community's investment into language parsing -- Leverage Nim macros which are a user API and relatively stable -- Avoid depending on Nim compiler API which is evolving constantly +- Avoid depending on Nim compiler API which is evolving constantly and makes backwards compatibility a bit challenging + +Most of the functionality is contained within the `toast` binary that is built when nimterop is installed and can be used standalone similar to how c2nim can be used today. In addition, nimterop also offers an API to pull in the generated Nim content directly into an application. The nimterop feature set is still limited when compared with c2nim. Supported language constructs include: - `#define NAME VALUE` where `VALUE` is a number (int, float, hex) - `struct X`, `typedef struct`, `enum X`, `typedef enum` - Functions with primitive types, structs, enums and typedef structs/enums as params and return values +- Pointers to data types Given the simplicity and success of this approach so far, it seems feasible to continue on for more complex code. The goal is to make interop seamless so nimterop will focus on wrapping headers and not the outright conversion of C/C++ implementation. -C++ constructs are still TBD depending on the results of the C interop. +C++ constructs such as classes and templats are still TBD depending on the results of the C interop. __Installation__ @@ -37,7 +39,7 @@ git clone http://github.com/genotrance/nimterop && cd nimterop nimble installWithDeps ``` -This will download and install nimterop in the standard Nimble package location, typically ~/.nimble. Once installed, it can be imported into any Nim program. +This will download and install nimterop in the standard Nimble package location, typically `~/.nimble`. Once installed, it can be imported into any Nim program. Note that the `~/.nimble/bin` directory needs to be added to the `PATH` for nimterop to work. __Usage__ @@ -55,6 +57,8 @@ cCompile("clib/src/*.c") Refer to the ```tests``` directory for examples on how the library can be used. +The `toast` binary can also be used directly on the CLI. The `--help` flag provides more details. + __Documentation__ Detailed documentation is still forthcoming. @@ -77,9 +81,9 @@ Detailed documentation is still forthcoming. __Implementation Details__ -In order to use the tree-sitter C library at compile-time, it has to be compiled into a separate binary called `toast` (to AST) since the Nim VM doesn't yet support FFI. `toast` takes a C/C++ file and runs it through the tree-sitter API which returns an AST data structure. This is then printed out to stdout in a Lisp S-Expression format. +In order to use the tree-sitter C library at compile-time, it has to be compiled into a separate binary called `toast` (to AST) since the Nim VM doesn't yet support FFI. `toast` takes a C/C++ file and runs it through the tree-sitter API which returns an AST data structure. This can then be printed out to stdout in a Lisp S-Expression format or the relevant Nim wrapper output. This content can be saved to a `.nim` file and imported if so desired. -The `cImport()` proc runs `toast` on the specified header file and parses the resulting S-Expression back into an AST data structure at compile time. This AST is then processed to generate the relevant Nim definitions to interop with the code accordingly. A few other helper procs are provided to influence this process. +Alternatively, the `cImport()` macro allows easier creation of wrappers in code. It runs `toast` on the specified header file and injects the generated wrapper content into the application at compile time. A few other helper procs are provided to influence this process. The tree-sitter library is limited as well - it may fail on some advanced language constructs but is designed to handle them gracefully since it is expected to have bad code while actively typing in an editor. When an error is detected, tree-sitter includes an ERROR node at that location in the AST. At this time, `cImport()` will complain and continue if it encounters any errors. Depending on how severe the errors are, compilation may succeed or fail. Glaring issues will be communicated to the tree-sitter team but their goals may not always align with those of this project. From c9b57c567cf065ca4ff5dcb4f4a5ee2eb1f01a52 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 28 Nov 2018 16:51:32 -0600 Subject: [PATCH 034/593] Fix #23 - handle inline comments, handle typedef enum X {} Y; --- nimterop/ast.nim | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/nimterop/ast.nim b/nimterop/ast.nim index 4cee1db..fe0111f 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -77,6 +77,8 @@ proc pStructSpecifier(node: TSNode, name = "") = if node.tsNodeNamedChild(0).tsNodeNamedChildCount() != 0: for i in 0 .. node.tsNodeNamedChild(0).tsNodeNamedChildCount()-1: + if $node.tsNodeNamedChild(0).tsNodeNamedChild(i).tsNodeType() == "comment": + continue let ts = typeScan(node.tsNodeNamedChild(0).tsNodeNamedChild(i), "field_declaration", "field_identifier", " ") if ts.len == 0: return @@ -95,6 +97,8 @@ proc pStructSpecifier(node: TSNode, name = "") = if node.tsNodeNamedChild(1).tsNodeNamedChildCount() != 0: for i in 0 .. node.tsNodeNamedChild(1).tsNodeNamedChildCount()-1: + if $node.tsNodeNamedChild(1).tsNodeNamedChild(i).tsNodeType() == "comment": + continue let ts = typeScan(node.tsNodeNamedChild(1).tsNodeNamedChild(i), "field_declaration", "field_identifier", " ") if ts.len == 0: return @@ -114,8 +118,11 @@ proc pEnumSpecifier(node: TSNode, name = "") = ename = name elid = 0 stmt = &" {name.getIdentifier()}* = enum #1 pEnumSpecifier()\n" - elif name.len == 0 and node.tsNodeNamedChildCount() == 2 and $node.tsNodeNamedChild(1).tsNodeType() == "enumerator_list": - ename = getNodeValIf(node.tsNodeNamedChild(0), "type_identifier") + elif node.tsNodeNamedChildCount() == 2 and $node.tsNodeNamedChild(1).tsNodeType() == "enumerator_list": + if name.len == 0: + ename = getNodeValIf(node.tsNodeNamedChild(0), "type_identifier") + else: + ename = name elid = 1 if ename.nBl: # enum X { fields } @@ -128,6 +135,8 @@ proc pEnumSpecifier(node: TSNode, name = "") = if node.tsNodeNamedChild(elid).tsNodeNamedChildCount() != 0: for i in 0 .. node.tsNodeNamedChild(elid).tsNodeNamedChildCount()-1: let field = node.tsNodeNamedChild(elid).tsNodeNamedChild(i) + if $field.tsNodeType() == "comment": + continue if not field.tsNodeIsNull() and $field.tsNodeType() == "enumerator": let fname = getNodeValIf(field.tsNodeNamedChild(0), "identifier") if field.tsNodeNamedChildCount() == 1: From b1c5407ff3fbf79c8d9318b789c9f4a638e43f83 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 28 Nov 2018 22:21:34 -0600 Subject: [PATCH 035/593] Fix #22 - print parse errors as comments --- nimterop/ast.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimterop/ast.nim b/nimterop/ast.nim index fe0111f..4d20482 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -239,7 +239,7 @@ proc genNimAst(root: TSNode) = case $node.tsNodeType(): of "ERROR": let (line, col) = getLineCol(node) - echo &"Potentially invalid syntax at line {line} column {col}" + echo &"# Potentially invalid syntax at line {line} column {col}" of "preproc_def": pPreprocDef(node) of "type_definition": From 7dd8fff8a7cf518cbc663b72598477b622ae1822 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Thu, 29 Nov 2018 15:13:25 -0800 Subject: [PATCH 036/593] fix #8 ; keep track of source file; display in standard sublime format file:line:col --- nimterop/ast.nim | 4 +++- nimterop/globals.nim | 1 + toast.nim | 2 ++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/nimterop/ast.nim b/nimterop/ast.nim index fe0111f..069ecba 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -239,7 +239,8 @@ proc genNimAst(root: TSNode) = case $node.tsNodeType(): of "ERROR": let (line, col) = getLineCol(node) - echo &"Potentially invalid syntax at line {line} column {col}" + let file = gStateRT.sourceFile + echo &"# [toast] Potentially invalid syntax at {file}:{line}:{col}" of "preproc_def": pPreprocDef(node) of "type_definition": @@ -253,6 +254,7 @@ proc genNimAst(root: TSNode) = if $node.tsNodeParent.tsNodeType() notin ["type_definition", "declaration"]: pEnumSpecifier(node) else: + # TODO: log discard else: return diff --git a/nimterop/globals.nim b/nimterop/globals.nim index 1e3a83c..f1ba151 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -7,6 +7,7 @@ type consts*, procs*, types*: seq[string] code*, constStr*, currentHeader*, mode*, procStr*, typeStr*: string + sourceFile*: string # eg, C or C++ source or header file var gStateCT* {.compiletime.}: State diff --git a/toast.nim b/toast.nim index b418308..f743264 100644 --- a/toast.nim +++ b/toast.nim @@ -63,6 +63,8 @@ proc process(path: string) = defer: parser.tsParserDelete() + gStateRT.sourceFile = path + if gStateRT.mode.len == 0: gStateRT.mode = modeDefault elif ext in [".h", ".c"]: From 33956c36ee837603ed94f94b528a3bbb6bd51890 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 3 Dec 2018 14:58:27 -0600 Subject: [PATCH 037/593] Switch to simpler grammar engine --- nimterop/ast.nim | 300 +++++++++---------------------------------- nimterop/astold.nim | 297 ++++++++++++++++++++++++++++++++++++++++++ nimterop/getters.nim | 61 ++++++++- nimterop/globals.nim | 19 ++- nimterop/grammar.nim | 244 +++++++++++++++++++++++++++++++++++ nimterop/lisp.nim | 35 ++--- 6 files changed, 690 insertions(+), 266 deletions(-) create mode 100644 nimterop/astold.nim create mode 100644 nimterop/grammar.nim diff --git a/nimterop/ast.nim b/nimterop/ast.nim index 069ecba..cce07c3 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -1,265 +1,83 @@ -import macros, os, strformat, strutils +import strformat, strutils, tables + +import regex import treesitter/runtime -import getters, globals +import "."/[getters, globals, grammar] -# -# Preprocessor -# +const gAtoms = @[ + "field_identifier", + "identifier", + "number_literal", + "preproc_arg", + "primitive_type", + "type_identifier" +] -proc pPreprocDef(node: TSNode) = - if node.tsNodeNamedChildCount() == 2: - let - name = getNodeValIf(node.tsNodeNamedChild(0), "identifier") - val = getNodeValIf(node.tsNodeNamedChild(1), "preproc_arg") - - if name.nBl and val.nBl and name notin gStateRT.consts: - gStateRT.consts.add(name) - if val.getLit().nBl: - # #define NAME VALUE - gStateRT.constStr &= &" {name.getIdentifier()}* = {val} # pPreprocDef()\n" - -# -# Types -# - -proc typeScan(node: TSNode, sym, id: string, offset: string): string = - if node.tsNodeIsNull() or $node.tsNodeType() != sym or node.tsNodeNamedChildCount() != 2: - return - - var - name = getNodeValIf(node.tsNodeNamedChild(1), id) - ptyp = getNodeValIf(node.tsNodeNamedChild(0), "primitive_type") - ttyp = getNodeValIf(node.tsNodeNamedChild(0), "type_identifier") - ptrname = false - - if name.len == 0 and $node.tsNodeNamedChild(1).tsNodeType() == "pointer_declarator" and node.tsNodeNamedChild(1).tsNodeNamedChildCount() == 1: - name = getNodeValIf(node.tsNodeNamedChild(1).tsNodeNamedChild(0), id) - ptrname = true - - if name.len == 0: - return - elif ptyp.nBl: - ptyp = ptyp.getType() - if ptyp != "object" and ptrname: - ptyp = &"ptr {ptyp}" - result = &"{offset}{name.getIdentifier()}: {ptyp}" - elif ttyp.nBl: - if ptrname: - ttyp = &"ptr {ttyp}" - result = &"{offset}{name.getIdentifier()}: {ttyp}" - elif $node.tsNodeNamedChild(0).tsNodeType() in ["struct_specifier", "enum_specifier"] and node.tsNodeNamedChild(0).tsNodeNamedChildCount() == 1: - var styp = getNodeValIf(node.tsNodeNamedChild(0).tsNodeNamedChild(0), "type_identifier") - if styp.nBl: - if ptrname: - styp = &"ptr {styp}" - result = &"{offset}{name.getIdentifier()}: {styp}" - -proc pStructSpecifier(node: TSNode, name = "") = - var stmt: string - if node.tsNodeNamedChildCount() == 1 and name notin gStateRT.types: - case $node.tsNodeNamedChild(0).tsNodeType(): - of "type_identifier": - let typ = getNodeValIf(node.tsNodeNamedChild(0), "type_identifier") - if typ.nBl: - gStateRT.types.add(name) - if name != typ: - # typedef struct X Y - gStateRT.typeStr &= &" {name.getIdentifier()}* = {typ} #1 pStructSpecifier()\n" - else: - # typedef struct X X - gStateRT.typeStr &= &" {name.getIdentifier()}* {{.importc: \"{name}\", header: {gStateRT.currentHeader}, bycopy.}} = object #2 pStructSpecifier()\n" - - of "field_declaration_list": - # typedef struct { fields } X - stmt = &" {name.getIdentifier()}* {{.importc: \"{name}\", header: {gStateRT.currentHeader}, bycopy.}} = object #3 pStructSpecifier()\n" - - if node.tsNodeNamedChild(0).tsNodeNamedChildCount() != 0: - for i in 0 .. node.tsNodeNamedChild(0).tsNodeNamedChildCount()-1: - if $node.tsNodeNamedChild(0).tsNodeNamedChild(i).tsNodeType() == "comment": - continue - let ts = typeScan(node.tsNodeNamedChild(0).tsNodeNamedChild(i), "field_declaration", "field_identifier", " ") - if ts.len == 0: - return - stmt &= ts & "\n" - - gStateRT.types.add(name) - gStateRT.typeStr &= stmt - else: - discard - - elif name.len == 0 and node.tsNodeNamedChildCount() == 2 and $node.tsNodeNamedChild(1).tsNodeType() == "field_declaration_list": - let ename = getNodeValIf(node.tsNodeNamedChild(0), "type_identifier") - if ename.nBl and ename notin gStateRT.types: - # struct X { fields } - stmt &= &" {ename}* {{.importc: \"struct {ename}\", header: {gStateRT.currentHeader}, bycopy.}} = object #4 pStructSpecifier()\n" - - if node.tsNodeNamedChild(1).tsNodeNamedChildCount() != 0: - for i in 0 .. node.tsNodeNamedChild(1).tsNodeNamedChildCount()-1: - if $node.tsNodeNamedChild(1).tsNodeNamedChild(i).tsNodeType() == "comment": - continue - let ts = typeScan(node.tsNodeNamedChild(1).tsNodeNamedChild(i), "field_declaration", "field_identifier", " ") - if ts.len == 0: - return - stmt &= ts & "\n" - - gStateRT.types.add(name) - gStateRT.typeStr &= stmt - -proc pEnumSpecifier(node: TSNode, name = "") = - var - ename: string - elid: uint32 - stmt: string - - if node.tsNodeNamedChildCount() == 1 and $node.tsNodeNamedChild(0).tsNodeType() == "enumerator_list": - # typedef enum { fields } X - ename = name - elid = 0 - stmt = &" {name.getIdentifier()}* = enum #1 pEnumSpecifier()\n" - elif node.tsNodeNamedChildCount() == 2 and $node.tsNodeNamedChild(1).tsNodeType() == "enumerator_list": - if name.len == 0: - ename = getNodeValIf(node.tsNodeNamedChild(0), "type_identifier") - else: - ename = name - elid = 1 - if ename.nBl: - # enum X { fields } - stmt = &" {ename}* = enum #2 pEnumSpecifier()\n" - else: - return - else: - return - - if node.tsNodeNamedChild(elid).tsNodeNamedChildCount() != 0: - for i in 0 .. node.tsNodeNamedChild(elid).tsNodeNamedChildCount()-1: - let field = node.tsNodeNamedChild(elid).tsNodeNamedChild(i) - if $field.tsNodeType() == "comment": - continue - if not field.tsNodeIsNull() and $field.tsNodeType() == "enumerator": - let fname = getNodeValIf(field.tsNodeNamedChild(0), "identifier") - if field.tsNodeNamedChildCount() == 1: - stmt &= &" {fname}\n" - elif field.tsNodeNamedChildCount() == 2 and $field.tsNodeNamedChild(1).tsNodeType() == "number_literal": - let num = getNodeValIf(field.tsNodeNamedChild(1), "number_literal") - stmt &= &" {fname} = {num}\n" - else: - return - - if ename notin gStateRT.types: - gStateRT.types.add(name) - gStateRT.typeStr &= stmt - -proc pTypeDefinition(node: TSNode) = - if node.tsNodeNamedChildCount() == 2: +proc saveNodeData(node: TSNode): bool = + let name = $node.tsNodeType() + if name in gAtoms: var - name = getNodeValIf(node.tsNodeNamedChild(1), "type_identifier") - ptyp = getNodeValIf(node.tsNodeNamedChild(0), "primitive_type") - ttyp = getNodeValIf(node.tsNodeNamedChild(0), "type_identifier") - ptrname = false + val = node.getNodeVal() - if name.len == 0 and $node.tsNodeNamedChild(1).tsNodeType() == "pointer_declarator" and node.tsNodeNamedChild(1).tsNodeNamedChildCount() == 1: - name = getNodeValIf(node.tsNodeNamedChild(1).tsNodeNamedChild(0), "type_identifier") - ptrname = true + if name == "primitive_type": + val = val.getType() - if name.nBl and name notin gStateRT.types: - if ptyp.nBl: - # typedef int X - gStateRT.types.add(name) - ptyp = ptyp.getType() - if ptyp != "object" and ptrname: - ptyp = &"ptr {ptyp}" - gStateRT.typeStr &= &" {name.getIdentifier()}* = {ptyp} #1 pTypeDefinition()\n" - elif ttyp.nBl: - # typedef X Y - gStateRT.types.add(name) - if ptrname: - ttyp = &"ptr {ttyp}" - gStateRT.typeStr &= &" {name.getIdentifier()}* = {ttyp} #2 pTypeDefinition()\n" - else: - case $node.tsNodeNamedChild(0).tsNodeType(): - of "struct_specifier": - pStructSpecifier(node.tsNodeNamedChild(0), name) - of "enum_specifier": - pEnumSpecifier(node.tsNodeNamedChild(0), name) - else: - discard + if node.tsNodeParent().tsNodeType() == "pointer_declarator": + if gStateRT.data[^1].val != "object": + gStateRT.data[^1].val = "ptr " & gStateRT.data[^1].val -proc pFunctionDeclarator(node: TSNode, typ: string) = - if node.tsNodeNamedChildCount() == 2: + gStateRT.data.add((name, val)) + + return true + +proc searchAstForNode(ast: ref Ast, node: TSNode): bool = + let + childNames = node.getTSNodeNamedChildNames().join() + + if ast.children.len != 0: let - name = getNodeValIf(node.tsNodeNamedChild(0), "identifier") + rstr = ast.getRegexForAstChildren() - if name.nBl and name notin gStateRT.procs and $node.tsNodeNamedChild(1).tsNodeType() == "parameter_list": - # typ function(typ param1, ...) - var stmt = &"# pFunctionDeclarator()\nproc {name.getIdentifier()}*(" + if childNames.contains(rstr.toPattern): + if node.getTSNodeNamedChildCountSansComments() != 0: + var flag = true + for i in 0 .. node.tsNodeNamedChildCount()-1: + if node.tsNodeType() != "comment": + let + nodeChild = node.tsNodeNamedChild(i) + astChild = ast.getAstChildByName($nodeChild.tsNodeType()) + if not searchAstForNode(astChild, nodeChild): + flag = false + break - if node.tsNodeNamedChild(1).tsNodeNamedChildCount() != 0: - for i in 0 .. node.tsNodeNamedChild(1).tsNodeNamedChildCount()-1: - let ts = typeScan(node.tsNodeNamedChild(1).tsNodeNamedChild(i), "parameter_declaration", "identifier", "") - if ts.len == 0: - return - stmt &= ts - if i != node.tsNodeNamedChild(1).tsNodeNamedChildCount()-1: - stmt &= ", " - - if typ != "void": - stmt &= &"): {typ.getType()} " + if flag: + return node.saveNodeData() else: - stmt &= ") " + return node.saveNodeData() + elif node.getTSNodeNamedChildCountSansComments() == 0: + return node.saveNodeData() - stmt &= &"{{.importc: \"{name}\", header: {gStateRT.currentHeader}.}}\n" - - gStateRT.procs.add(name) - gStateRT.procStr &= stmt - -proc pDeclaration*(node: TSNode) = - if node.tsNodeNamedChildCount() == 2 and $node.tsNodeNamedChild(1).tsNodeType() == "function_declarator": - let - ptyp = getNodeValIf(node.tsNodeNamedChild(0), "primitive_type") - ttyp = getNodeValIf(node.tsNodeNamedChild(0), "type_identifier") - - if ptyp.nBl: - pFunctionDeclarator(node.tsNodeNamedChild(1), ptyp.getType()) - elif ttyp.nBl: - pFunctionDeclarator(node.tsNodeNamedChild(1), ttyp) - elif $node.tsNodeNamedChild(0).tsNodeType() == "struct_specifier" and node.tsNodeNamedChild(0).tsNodeNamedChildCount() == 1: - let styp = getNodeValIf(node.tsNodeNamedChild(0).tsNodeNamedChild(0), "type_identifier") - if styp.nBl: - pFunctionDeclarator(node.tsNodeNamedChild(1), styp) - -proc genNimAst(root: TSNode) = +proc searchAst(root: TSNode) = var node = root nextnode: TSNode while true: if not node.tsNodeIsNull(): - case $node.tsNodeType(): - of "ERROR": - let (line, col) = getLineCol(node) - let file = gStateRT.sourceFile - echo &"# [toast] Potentially invalid syntax at {file}:{line}:{col}" - of "preproc_def": - pPreprocDef(node) - of "type_definition": - pTypeDefinition(node) - of "declaration": - pDeclaration(node) - of "struct_specifier": - if $node.tsNodeParent().tsNodeType() notin ["type_definition", "declaration"]: - pStructSpecifier(node) - of "enum_specifier": - if $node.tsNodeParent.tsNodeType() notin ["type_definition", "declaration"]: - pEnumSpecifier(node) - else: - # TODO: log - discard + let + name = $node.tsNodeType() + if name in gStateRT.ast: + for ast in gStateRT.ast[name]: + if searchAstForNode(ast, node): + ast.tonim() + break + gStateRT.data = @[] else: return - if node.tsNodeNamedChildCount() != 0: + if $node.tsNodeType() notin gStateRT.ast and node.tsNodeNamedChildCount() != 0: nextnode = node.tsNodeNamedChild(0) else: nextnode = node.tsNodeNextNamedSibling() @@ -279,13 +97,15 @@ proc genNimAst(root: TSNode) = break proc printNim*(fullpath: string, root: TSNode) = + parseGrammar() + echo "{.experimental: \"codeReordering\".}" var fp = fullpath.replace("\\", "/") gStateRT.currentHeader = getCurrentHeader(fullpath) gStateRT.constStr &= &" {gStateRT.currentHeader} = \"{fp}\"\n" - genNimAst(root) + root.searchAst() if gStateRT.constStr.nBl: echo "const\n" & gStateRT.constStr diff --git a/nimterop/astold.nim b/nimterop/astold.nim new file mode 100644 index 0000000..069ecba --- /dev/null +++ b/nimterop/astold.nim @@ -0,0 +1,297 @@ +import macros, os, strformat, strutils + +import treesitter/runtime + +import getters, globals + +# +# Preprocessor +# + +proc pPreprocDef(node: TSNode) = + if node.tsNodeNamedChildCount() == 2: + let + name = getNodeValIf(node.tsNodeNamedChild(0), "identifier") + val = getNodeValIf(node.tsNodeNamedChild(1), "preproc_arg") + + if name.nBl and val.nBl and name notin gStateRT.consts: + gStateRT.consts.add(name) + if val.getLit().nBl: + # #define NAME VALUE + gStateRT.constStr &= &" {name.getIdentifier()}* = {val} # pPreprocDef()\n" + +# +# Types +# + +proc typeScan(node: TSNode, sym, id: string, offset: string): string = + if node.tsNodeIsNull() or $node.tsNodeType() != sym or node.tsNodeNamedChildCount() != 2: + return + + var + name = getNodeValIf(node.tsNodeNamedChild(1), id) + ptyp = getNodeValIf(node.tsNodeNamedChild(0), "primitive_type") + ttyp = getNodeValIf(node.tsNodeNamedChild(0), "type_identifier") + ptrname = false + + if name.len == 0 and $node.tsNodeNamedChild(1).tsNodeType() == "pointer_declarator" and node.tsNodeNamedChild(1).tsNodeNamedChildCount() == 1: + name = getNodeValIf(node.tsNodeNamedChild(1).tsNodeNamedChild(0), id) + ptrname = true + + if name.len == 0: + return + elif ptyp.nBl: + ptyp = ptyp.getType() + if ptyp != "object" and ptrname: + ptyp = &"ptr {ptyp}" + result = &"{offset}{name.getIdentifier()}: {ptyp}" + elif ttyp.nBl: + if ptrname: + ttyp = &"ptr {ttyp}" + result = &"{offset}{name.getIdentifier()}: {ttyp}" + elif $node.tsNodeNamedChild(0).tsNodeType() in ["struct_specifier", "enum_specifier"] and node.tsNodeNamedChild(0).tsNodeNamedChildCount() == 1: + var styp = getNodeValIf(node.tsNodeNamedChild(0).tsNodeNamedChild(0), "type_identifier") + if styp.nBl: + if ptrname: + styp = &"ptr {styp}" + result = &"{offset}{name.getIdentifier()}: {styp}" + +proc pStructSpecifier(node: TSNode, name = "") = + var stmt: string + if node.tsNodeNamedChildCount() == 1 and name notin gStateRT.types: + case $node.tsNodeNamedChild(0).tsNodeType(): + of "type_identifier": + let typ = getNodeValIf(node.tsNodeNamedChild(0), "type_identifier") + if typ.nBl: + gStateRT.types.add(name) + if name != typ: + # typedef struct X Y + gStateRT.typeStr &= &" {name.getIdentifier()}* = {typ} #1 pStructSpecifier()\n" + else: + # typedef struct X X + gStateRT.typeStr &= &" {name.getIdentifier()}* {{.importc: \"{name}\", header: {gStateRT.currentHeader}, bycopy.}} = object #2 pStructSpecifier()\n" + + of "field_declaration_list": + # typedef struct { fields } X + stmt = &" {name.getIdentifier()}* {{.importc: \"{name}\", header: {gStateRT.currentHeader}, bycopy.}} = object #3 pStructSpecifier()\n" + + if node.tsNodeNamedChild(0).tsNodeNamedChildCount() != 0: + for i in 0 .. node.tsNodeNamedChild(0).tsNodeNamedChildCount()-1: + if $node.tsNodeNamedChild(0).tsNodeNamedChild(i).tsNodeType() == "comment": + continue + let ts = typeScan(node.tsNodeNamedChild(0).tsNodeNamedChild(i), "field_declaration", "field_identifier", " ") + if ts.len == 0: + return + stmt &= ts & "\n" + + gStateRT.types.add(name) + gStateRT.typeStr &= stmt + else: + discard + + elif name.len == 0 and node.tsNodeNamedChildCount() == 2 and $node.tsNodeNamedChild(1).tsNodeType() == "field_declaration_list": + let ename = getNodeValIf(node.tsNodeNamedChild(0), "type_identifier") + if ename.nBl and ename notin gStateRT.types: + # struct X { fields } + stmt &= &" {ename}* {{.importc: \"struct {ename}\", header: {gStateRT.currentHeader}, bycopy.}} = object #4 pStructSpecifier()\n" + + if node.tsNodeNamedChild(1).tsNodeNamedChildCount() != 0: + for i in 0 .. node.tsNodeNamedChild(1).tsNodeNamedChildCount()-1: + if $node.tsNodeNamedChild(1).tsNodeNamedChild(i).tsNodeType() == "comment": + continue + let ts = typeScan(node.tsNodeNamedChild(1).tsNodeNamedChild(i), "field_declaration", "field_identifier", " ") + if ts.len == 0: + return + stmt &= ts & "\n" + + gStateRT.types.add(name) + gStateRT.typeStr &= stmt + +proc pEnumSpecifier(node: TSNode, name = "") = + var + ename: string + elid: uint32 + stmt: string + + if node.tsNodeNamedChildCount() == 1 and $node.tsNodeNamedChild(0).tsNodeType() == "enumerator_list": + # typedef enum { fields } X + ename = name + elid = 0 + stmt = &" {name.getIdentifier()}* = enum #1 pEnumSpecifier()\n" + elif node.tsNodeNamedChildCount() == 2 and $node.tsNodeNamedChild(1).tsNodeType() == "enumerator_list": + if name.len == 0: + ename = getNodeValIf(node.tsNodeNamedChild(0), "type_identifier") + else: + ename = name + elid = 1 + if ename.nBl: + # enum X { fields } + stmt = &" {ename}* = enum #2 pEnumSpecifier()\n" + else: + return + else: + return + + if node.tsNodeNamedChild(elid).tsNodeNamedChildCount() != 0: + for i in 0 .. node.tsNodeNamedChild(elid).tsNodeNamedChildCount()-1: + let field = node.tsNodeNamedChild(elid).tsNodeNamedChild(i) + if $field.tsNodeType() == "comment": + continue + if not field.tsNodeIsNull() and $field.tsNodeType() == "enumerator": + let fname = getNodeValIf(field.tsNodeNamedChild(0), "identifier") + if field.tsNodeNamedChildCount() == 1: + stmt &= &" {fname}\n" + elif field.tsNodeNamedChildCount() == 2 and $field.tsNodeNamedChild(1).tsNodeType() == "number_literal": + let num = getNodeValIf(field.tsNodeNamedChild(1), "number_literal") + stmt &= &" {fname} = {num}\n" + else: + return + + if ename notin gStateRT.types: + gStateRT.types.add(name) + gStateRT.typeStr &= stmt + +proc pTypeDefinition(node: TSNode) = + if node.tsNodeNamedChildCount() == 2: + var + name = getNodeValIf(node.tsNodeNamedChild(1), "type_identifier") + ptyp = getNodeValIf(node.tsNodeNamedChild(0), "primitive_type") + ttyp = getNodeValIf(node.tsNodeNamedChild(0), "type_identifier") + ptrname = false + + if name.len == 0 and $node.tsNodeNamedChild(1).tsNodeType() == "pointer_declarator" and node.tsNodeNamedChild(1).tsNodeNamedChildCount() == 1: + name = getNodeValIf(node.tsNodeNamedChild(1).tsNodeNamedChild(0), "type_identifier") + ptrname = true + + if name.nBl and name notin gStateRT.types: + if ptyp.nBl: + # typedef int X + gStateRT.types.add(name) + ptyp = ptyp.getType() + if ptyp != "object" and ptrname: + ptyp = &"ptr {ptyp}" + gStateRT.typeStr &= &" {name.getIdentifier()}* = {ptyp} #1 pTypeDefinition()\n" + elif ttyp.nBl: + # typedef X Y + gStateRT.types.add(name) + if ptrname: + ttyp = &"ptr {ttyp}" + gStateRT.typeStr &= &" {name.getIdentifier()}* = {ttyp} #2 pTypeDefinition()\n" + else: + case $node.tsNodeNamedChild(0).tsNodeType(): + of "struct_specifier": + pStructSpecifier(node.tsNodeNamedChild(0), name) + of "enum_specifier": + pEnumSpecifier(node.tsNodeNamedChild(0), name) + else: + discard + +proc pFunctionDeclarator(node: TSNode, typ: string) = + if node.tsNodeNamedChildCount() == 2: + let + name = getNodeValIf(node.tsNodeNamedChild(0), "identifier") + + if name.nBl and name notin gStateRT.procs and $node.tsNodeNamedChild(1).tsNodeType() == "parameter_list": + # typ function(typ param1, ...) + var stmt = &"# pFunctionDeclarator()\nproc {name.getIdentifier()}*(" + + if node.tsNodeNamedChild(1).tsNodeNamedChildCount() != 0: + for i in 0 .. node.tsNodeNamedChild(1).tsNodeNamedChildCount()-1: + let ts = typeScan(node.tsNodeNamedChild(1).tsNodeNamedChild(i), "parameter_declaration", "identifier", "") + if ts.len == 0: + return + stmt &= ts + if i != node.tsNodeNamedChild(1).tsNodeNamedChildCount()-1: + stmt &= ", " + + if typ != "void": + stmt &= &"): {typ.getType()} " + else: + stmt &= ") " + + stmt &= &"{{.importc: \"{name}\", header: {gStateRT.currentHeader}.}}\n" + + gStateRT.procs.add(name) + gStateRT.procStr &= stmt + +proc pDeclaration*(node: TSNode) = + if node.tsNodeNamedChildCount() == 2 and $node.tsNodeNamedChild(1).tsNodeType() == "function_declarator": + let + ptyp = getNodeValIf(node.tsNodeNamedChild(0), "primitive_type") + ttyp = getNodeValIf(node.tsNodeNamedChild(0), "type_identifier") + + if ptyp.nBl: + pFunctionDeclarator(node.tsNodeNamedChild(1), ptyp.getType()) + elif ttyp.nBl: + pFunctionDeclarator(node.tsNodeNamedChild(1), ttyp) + elif $node.tsNodeNamedChild(0).tsNodeType() == "struct_specifier" and node.tsNodeNamedChild(0).tsNodeNamedChildCount() == 1: + let styp = getNodeValIf(node.tsNodeNamedChild(0).tsNodeNamedChild(0), "type_identifier") + if styp.nBl: + pFunctionDeclarator(node.tsNodeNamedChild(1), styp) + +proc genNimAst(root: TSNode) = + var + node = root + nextnode: TSNode + + while true: + if not node.tsNodeIsNull(): + case $node.tsNodeType(): + of "ERROR": + let (line, col) = getLineCol(node) + let file = gStateRT.sourceFile + echo &"# [toast] Potentially invalid syntax at {file}:{line}:{col}" + of "preproc_def": + pPreprocDef(node) + of "type_definition": + pTypeDefinition(node) + of "declaration": + pDeclaration(node) + of "struct_specifier": + if $node.tsNodeParent().tsNodeType() notin ["type_definition", "declaration"]: + pStructSpecifier(node) + of "enum_specifier": + if $node.tsNodeParent.tsNodeType() notin ["type_definition", "declaration"]: + pEnumSpecifier(node) + else: + # TODO: log + discard + else: + return + + if node.tsNodeNamedChildCount() != 0: + nextnode = node.tsNodeNamedChild(0) + else: + nextnode = node.tsNodeNextNamedSibling() + + if nextnode.tsNodeIsNull(): + while true: + node = node.tsNodeParent() + if node == root: + break + if not node.tsNodeNextNamedSibling().tsNodeIsNull(): + node = node.tsNodeNextNamedSibling() + break + else: + node = nextnode + + if node == root: + break + +proc printNim*(fullpath: string, root: TSNode) = + echo "{.experimental: \"codeReordering\".}" + + var fp = fullpath.replace("\\", "/") + gStateRT.currentHeader = getCurrentHeader(fullpath) + gStateRT.constStr &= &" {gStateRT.currentHeader} = \"{fp}\"\n" + + genNimAst(root) + + if gStateRT.constStr.nBl: + echo "const\n" & gStateRT.constStr + + if gStateRT.typeStr.nBl: + echo "type\n" & gStateRT.typeStr + + if gStateRT.procStr.nBl: + echo gStateRT.procStr diff --git a/nimterop/getters.nim b/nimterop/getters.nim index daf01ef..ff8a361 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -21,11 +21,14 @@ proc getLit*(str: string): string = str.contains(re"^0x[\d]+$"): return str +proc getNodeVal*(node: TSNode): string = + return gStateRT.code[node.tsNodeStartByte() .. node.tsNodeEndByte()-1].strip() + proc getNodeValIf*(node: TSNode, esym: string): string = if esym != $node.tsNodeType(): return - return gStateRT.code[node.tsNodeStartByte() .. node.tsNodeEndByte()-1].strip() + return node.getNodeVal() proc getLineCol*(node: TSNode): tuple[line, col: int] = result.line = 1 @@ -81,3 +84,59 @@ proc getPreprocessor*(fullpath: string, mode = "cpp"): string = .replace(re"\(\(__format__[\s]*\(__[gnu_]*printf__, [\d]+, [\d]+\)\)\);", ";") ) return rdata.join("\n") + +converter toString*(kind: Kind): string = + return case kind: + of exactlyOne: + "" + of oneOrMore: + "+" + of zeroOrMore: + "*" + of zeroOrOne: + "?" + +converter toKind*(kind: string): Kind = + return case kind: + of "+": + oneOrMore + of "*": + zeroOrMore + of "?": + zeroOrOne + else: + exactlyOne + +proc getNameKind*(name: string): tuple[name: string, kind: Kind] = + result.name = name + result.kind = $name[^1] + + if result.kind != exactlyOne: + result.name = name[0 .. ^2] + +proc getTSNodeNamedChildCountSansComments*(node: TSNode): int = + if node.tsNodeNamedChildCount() != 0: + for i in 0 .. node.tsNodeNamedChildCount()-1: + if $node.tsNodeType() != "comment": + result += 1 + +proc getTSNodeNamedChildNames*(node: TSNode): seq[string] = + if node.tsNodeNamedChildCount() != 0: + for i in 0 .. node.tsNodeNamedChildCount()-1: + let + name = $node.tsNodeNamedChild(i).tsNodeType() + + if name != "comment": + result.add(name) + +proc getRegexForAstChildren*(ast: ref Ast): string = + result = "^" + for i in 0 .. ast.children.len-1: + let kind: string = ast.children[i].kind + result &= &"(?:{ast.children[i].name}){kind}" + result &= "$" + +proc getAstChildByName*(ast: ref Ast, name: string): ref Ast = + for i in 0 .. ast.children.len-1: + if name in ast.children[i].name.split("|"): + return ast.children[i] diff --git a/nimterop/globals.nim b/nimterop/globals.nim index f1ba151..39969bc 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -1,4 +1,18 @@ +import tables + type + Kind* = enum + exactlyOne + oneOrMore # + + zeroOrMore # * + zeroOrOne # ? + + Ast* = object + name*: string + kind*: Kind + children*: seq[ref Ast] + tonim*: proc () {.closure, locks: 0.} + State* = object compile*, defines*, headers*, includeDirs*, searchDirs*: seq[string] @@ -9,6 +23,10 @@ type code*, constStr*, currentHeader*, mode*, procStr*, typeStr*: string sourceFile*: string # eg, C or C++ source or header file + ast*: Table[string, seq[ref Ast]] + data*: seq[tuple[name, val: string]] + grammar*: seq[tuple[grammar: string, call: proc() {.locks: 0.}]] + var gStateCT* {.compiletime.}: State gStateRT*: State @@ -16,7 +34,6 @@ var template nBl*(s: typed): untyped = (s.len != 0) - type CompileMode* = enum c, cpp, diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim new file mode 100644 index 0000000..4e819d9 --- /dev/null +++ b/nimterop/grammar.nim @@ -0,0 +1,244 @@ +import strformat, tables + +import "."/[getters, globals, lisp] + +proc initGrammar() = + # #define X Y + gStateRT.grammar.add((""" + (preproc_def + (identifier) + (preproc_arg) + ) + """, + proc () {.closure, locks: 0.} = + let + name = gStateRT.data[0].val.getIdentifier() + val = gStateRT.data[1].val + + if name notin gStateRT.consts: + gStateRT.consts.add(name) + gStateRT.constStr &= &" {name}* = {val}\n" + )) + + # typedef int X + # typedef X Y + # typedef struct X Y + # typedef ?* Y + gStateRT.grammar.add((""" + (type_definition + (primitive_type|type_identifier?) + (struct_specifier? + (type_identifier) + ) + (type_identifier?) + (pointer_declarator? + (type_identifier) + ) + ) + """, + proc () {.closure, locks: 0.} = + var + name = gStateRT.data[1].val.getIdentifier() + typ = gStateRT.data[0].val + + if name notin gStateRT.types: + gStateRT.types.add(name) + gStateRT.typeStr &= &" {name}* = {typ}\n" + )) + + proc pStructCommon(name: string, fstart, fend: int, prefix="") = + let + nname = name.getIdentifier() + if nname notin gStateRT.types: + gStateRT.types.add(nname) + gStateRT.typeStr &= &" {nname}* {{.importc: \"{prefix}{name}\", header: {gStateRT.currentHeader}, bycopy.}} = object\n" + + for i in fstart .. gStateRT.data.len-fend: + let + ftyp = gStateRT.data[i].val + fname = gStateRT.data[i+1].val.getIdentifier() + gStateRT.typeStr &= &" {fname}*: {ftyp}\n" + + # struct X {} + gStateRT.grammar.add((""" + (struct_specifier + (type_identifier) + (field_declaration_list + (field_declaration+ + (primitive_type|type_identifier?) + (struct_specifier? + (type_identifier) + ) + (field_identifier?) + (pointer_declarator? + (field_identifier) + ) + ) + ) + ) + """, + proc () {.closure, locks: 0.} = + pStructCommon(gStateRT.data[0].val, 1, 2, "struct ") + )) + + # typedef struct X {} + gStateRT.grammar.add((""" + (type_definition + (struct_specifier + (field_declaration_list + (field_declaration+ + (primitive_type|type_identifier?) + (struct_specifier? + (type_identifier) + ) + (field_identifier?) + (pointer_declarator? + (field_identifier) + ) + ) + ) + ) + (type_identifier) + ) + """, + proc () {.closure, locks: 0.} = + pStructCommon(gStateRT.data[^1].val, 0, 3) + )) + + proc pEnumCommon(name: string, fstart, fend: int, prefix="") = + let + nname = name.getIdentifier() + if nname notin gStateRT.types: + gStateRT.types.add(nname) + gStateRT.typeStr &= &" {nname}* = enum\n" + + var + i = fstart + while i < gStateRT.data.len-fend: + let + fname = gStateRT.data[i].val.getIdentifier() + + if i+1 < gStateRT.data.len-fend and gStateRT.data[i+1].name == "number_literal": + gStateRT.typeStr &= &" {fname} = {gStateRT.data[i+1].val}\n" + i += 2 + else: + gStateRT.typeStr &= &" {fname}\n" + i += 1 + + # enum X {} + gStateRT.grammar.add((""" + (enum_specifier + (type_identifier) + (enumerator_list + (enumerator+ + (identifier) + (number_literal?) + ) + ) + ) + """, + proc () {.closure, locks: 0.} = + pEnumCommon(gStateRT.data[0].val, 1, 0) + )) + + # typedef enum {} X + gStateRT.grammar.add((""" + (type_definition + (enum_specifier + (enumerator_list + (enumerator+ + (identifier) + (number_literal?) + ) + ) + ) + (type_identifier) + ) + """, + proc () {.closure, locks: 0.} = + pEnumCommon(gStateRT.data[^1].val, 0, 1) + )) + + # typ function(typ param1, ...) + gStateRT.grammar.add((""" + (declaration + (primitive_type|type_identifier?) + (struct_specifier? + (type_identifier) + ) + (function_declarator? + (identifier) + (parameter_list + (parameter_declaration* + (primitive_type|type_identifier?) + (struct_specifier? + (type_identifier) + ) + (enum_specifier? + (type_identifier) + ) + (identifier) + ) + ) + ) + (pointer_declarator? + (function_declarator? + (identifier) + (parameter_list + (parameter_declaration* + (primitive_type|type_identifier?) + (struct_specifier? + (type_identifier) + ) + (enum_specifier? + (type_identifier) + ) + (identifier) + ) + ) + ) + ) + ) + """, + proc () {.closure, locks: 0.} = + let + ftyp = gStateRT.data[0].val + fname = gStateRT.data[1].val + fnname = fname.getIdentifier() + + if fnname notin gStateRT.procs: + var + pout = "" + i = 2 + if gStateRT.data.len > 2: + while i < gStateRT.data.len-1: + let + ptyp = gStateRT.data[i].val + pname = gStateRT.data[i+1].val.getIdentifier() + pout &= &"{pname}: {ptyp}," + i += 2 + if pout.len != 0 and pout[^1] == ',': + pout = pout[0 .. ^2] + + gStateRT.procStr &= &"proc {fnname}({pout}): {ftyp} {{.importc: \"{fname}\", header: {gStateRT.currentHeader}.}}\n" + + )) + +proc parseGrammar*() = + initGrammar() + + gStateRT.ast = initTable[string, seq[ref Ast]]() + for i in 0 .. gStateRT.grammar.len-1: + var + ast = gStateRT.grammar[i].grammar.parseLisp() + + ast.tonim = gStateRT.grammar[i].call + if ast.name notin gStateRT.ast: + gStateRT.ast[ast.name] = @[ast] + else: + gStateRT.ast[ast.name].add(ast) + +proc printGrammar*() = + for name in gStateRT.ast.keys(): + for ast in gStateRT.ast[name]: + echo ast.printAst() diff --git a/nimterop/lisp.nim b/nimterop/lisp.nim index 8fa73e0..3d3c34e 100644 --- a/nimterop/lisp.nim +++ b/nimterop/lisp.nim @@ -1,22 +1,18 @@ import strutils import strformat -import globals +import "."/[getters, globals] var - gTokens {.compiletime.}: seq[string] - idx {.compiletime.} = 0 + gTokens: seq[string] + idx = 0 -proc tokenize(fullpath: string) = +proc tokenize(tree: string) = var collect = "" gTokens = @[] idx = 0 - # TODO: consider calling API directly - const cmd = &"toast --past --pretty:false --source:{fullpath.quoteShell}" - var (output, exitCode) = gorgeEx cmd - doAssert exitCode == 0, $exitCode - for i in output: + for i in tree: case i: of ' ', '\n', '\r', '(', ')': if collect.nBl: @@ -27,10 +23,6 @@ proc tokenize(fullpath: string) = else: collect &= $i - if gTokens.len == 0: - echo "toast binary not installed - nimble install nimterop to force build" - quit(1) - proc readFromTokens(): ref Ast = if idx == gTokens.len: echo "Bad AST" @@ -42,18 +34,12 @@ proc readFromTokens(): ref Ast = quit(1) if gTokens[idx+1] != "comment": result = new(Ast) - try: - result.sym = parseEnum[Sym](gTokens[idx+1]) - except: - result.sym = IGNORED - result.start = gTokens[idx+2].parseInt() - result.stop = gTokens[idx+3].parseInt() + (result.name, result.kind) = gTokens[idx+1].getNameKind() result.children = @[] - idx += 4 + idx += 2 while gTokens[idx] != ")": var res = readFromTokens() if not res.isNil(): - res.parent = result result.children.add(res) elif gTokens[idx] == ")": echo "Poor AST" @@ -62,7 +48,8 @@ proc readFromTokens(): ref Ast = idx += 1 proc printAst*(node: ref Ast, offset=""): string = - result = offset & "(" & $node.sym & " " & $node.start & " " & $node.stop + result = offset & "(" & node.name & node.kind.toString() + if node.children.len != 0: result &= "\n" for child in node.children: @@ -71,7 +58,7 @@ proc printAst*(node: ref Ast, offset=""): string = else: result &= ")\n" -proc parseLisp*(fullpath: string): ref Ast = - tokenize(fullpath) +proc parseLisp*(tree: string): ref Ast = + tokenize(tree) return readFromTokens() From ba8c57984bc2e947c1f8a1c22c3df398188959a5 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 3 Dec 2018 16:17:13 -0600 Subject: [PATCH 038/593] Support for unsigned, function params with pointers --- nimterop/ast.nim | 8 +++++++- nimterop/getters.nim | 7 ++++++- nimterop/grammar.nim | 35 +++++++++++++++++++++++++++++++---- 3 files changed, 44 insertions(+), 6 deletions(-) diff --git a/nimterop/ast.nim b/nimterop/ast.nim index cce07c3..ca4a563 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -12,6 +12,7 @@ const gAtoms = @[ "number_literal", "preproc_arg", "primitive_type", + "sized_type_specifier", "type_identifier" ] @@ -21,7 +22,10 @@ proc saveNodeData(node: TSNode): bool = var val = node.getNodeVal() - if name == "primitive_type": + if name == "primitive_type" and node.tsNodeParent.tsNodeType() == "sized_type_specifier": + return true + + if name in ["primitive_type", "sized_type_specifier"]: val = val.getType() if node.tsNodeParent().tsNodeType() == "pointer_declarator": @@ -36,6 +40,8 @@ proc searchAstForNode(ast: ref Ast, node: TSNode): bool = let childNames = node.getTSNodeNamedChildNames().join() + if ast.isNil: + return if ast.children.len != 0: let rstr = ast.getRegexForAstChildren() diff --git a/nimterop/getters.nim b/nimterop/getters.nim index ff8a361..02732e5 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -13,7 +13,12 @@ proc getIdentifier*(str: string): string = result = str.strip(chars={'_'}) proc getType*(str: string): string = - result = str.strip(chars={'_'}).replace(re"([u]?int[\d]+)_t", "$1").replace(re"^void$", "object") + if str == "void": + return "object" + + result = str.strip(chars={'_'}). + replace("unsigned ", "u"). + replace(re"([u]?int[\d]+)_t", "$1") proc getLit*(str: string): string = if str.contains(re"^[\-]?[\d]+$") or diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index 4e819d9..1fc45c2 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -15,7 +15,7 @@ proc initGrammar() = name = gStateRT.data[0].val.getIdentifier() val = gStateRT.data[1].val - if name notin gStateRT.consts: + if name notin gStateRT.consts and val.nBl: gStateRT.consts.add(name) gStateRT.constStr &= &" {name}* = {val}\n" )) @@ -27,6 +27,9 @@ proc initGrammar() = gStateRT.grammar.add((""" (type_definition (primitive_type|type_identifier?) + (sized_type_specifier? + (primitive_type) + ) (struct_specifier? (type_identifier) ) @@ -66,6 +69,9 @@ proc initGrammar() = (field_declaration_list (field_declaration+ (primitive_type|type_identifier?) + (sized_type_specifier? + (primitive_type) + ) (struct_specifier? (type_identifier) ) @@ -88,6 +94,9 @@ proc initGrammar() = (field_declaration_list (field_declaration+ (primitive_type|type_identifier?) + (sized_type_specifier? + (primitive_type) + ) (struct_specifier? (type_identifier) ) @@ -163,6 +172,9 @@ proc initGrammar() = gStateRT.grammar.add((""" (declaration (primitive_type|type_identifier?) + (sized_type_specifier? + (primitive_type) + ) (struct_specifier? (type_identifier) ) @@ -171,13 +183,19 @@ proc initGrammar() = (parameter_list (parameter_declaration* (primitive_type|type_identifier?) + (sized_type_specifier? + (primitive_type) + ) (struct_specifier? (type_identifier) ) (enum_specifier? (type_identifier) ) - (identifier) + (identifier?) + (pointer_declarator? + (identifier) + ) ) ) ) @@ -187,13 +205,19 @@ proc initGrammar() = (parameter_list (parameter_declaration* (primitive_type|type_identifier?) + (sized_type_specifier? + (primitive_type) + ) (struct_specifier? (type_identifier) ) (enum_specifier? (type_identifier) ) - (identifier) + (identifier?) + (pointer_declarator? + (identifier) + ) ) ) ) @@ -220,7 +244,10 @@ proc initGrammar() = if pout.len != 0 and pout[^1] == ',': pout = pout[0 .. ^2] - gStateRT.procStr &= &"proc {fnname}({pout}): {ftyp} {{.importc: \"{fname}\", header: {gStateRT.currentHeader}.}}\n" + if ftyp != "object": + gStateRT.procStr &= &"proc {fnname}({pout}): {ftyp} {{.importc: \"{fname}\", header: {gStateRT.currentHeader}.}}\n" + else: + gStateRT.procStr &= &"proc {fnname}({pout}) {{.importc: \"{fname}\", header: {gStateRT.currentHeader}.}}\n" )) From 007f3aa1913dca798f73ee55ca9cbe507b36fef6 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 3 Dec 2018 16:25:44 -0600 Subject: [PATCH 039/593] Fix for uchar and double --- nimterop/getters.nim | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 02732e5..1e76429 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -20,6 +20,11 @@ proc getType*(str: string): string = replace("unsigned ", "u"). replace(re"([u]?int[\d]+)_t", "$1") + if result == "uchar": + result = "cuchar" + elif result == "double": + result = "cdouble" + proc getLit*(str: string): string = if str.contains(re"^[\-]?[\d]+$") or str.contains(re"^[\-]?[\d]*\.[\d]+$") or From d3340d51e2d15a93fef46e4cf5be67ac69413cd9 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 3 Dec 2018 21:15:02 -0600 Subject: [PATCH 040/593] Fix inline comments breaking search --- nimterop/ast.nim | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nimterop/ast.nim b/nimterop/ast.nim index ca4a563..1f397c1 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -42,6 +42,7 @@ proc searchAstForNode(ast: ref Ast, node: TSNode): bool = if ast.isNil: return + if ast.children.len != 0: let rstr = ast.getRegexForAstChildren() @@ -50,7 +51,7 @@ proc searchAstForNode(ast: ref Ast, node: TSNode): bool = if node.getTSNodeNamedChildCountSansComments() != 0: var flag = true for i in 0 .. node.tsNodeNamedChildCount()-1: - if node.tsNodeType() != "comment": + if $node.tsNodeNamedChild(i).tsNodeType() != "comment": let nodeChild = node.tsNodeNamedChild(i) astChild = ast.getAstChildByName($nodeChild.tsNodeType()) From 4fe3b0380ccf14ebb8a241c51d0e0355ff4bb2d6 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 3 Dec 2018 22:29:39 -0600 Subject: [PATCH 041/593] Fixes for const, short and function returning pointer --- nimterop/ast.nim | 15 ++++++++++++--- nimterop/grammar.nim | 15 +++++++++------ 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/nimterop/ast.nim b/nimterop/ast.nim index 1f397c1..ba7561e 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -28,9 +28,18 @@ proc saveNodeData(node: TSNode): bool = if name in ["primitive_type", "sized_type_specifier"]: val = val.getType() - if node.tsNodeParent().tsNodeType() == "pointer_declarator": - if gStateRT.data[^1].val != "object": - gStateRT.data[^1].val = "ptr " & gStateRT.data[^1].val + let + nparent = node.tsNodeParent() + if not nparent.tsNodeIsNull(): + let + npname = nparent.tsNodeType() + npparent = nparent.tsNodeParent() + if npname == "pointer_declarator" or + (npname == "function_declarator" and + not npparent.tsNodeIsNull() and npparent.tsNodeType() == "pointer_declarator"): + + if gStateRT.data[^1].val != "object": + gStateRT.data[^1].val = "ptr " & gStateRT.data[^1].val gStateRT.data.add((name, val)) diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index 1fc45c2..a07ad84 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -28,7 +28,7 @@ proc initGrammar() = (type_definition (primitive_type|type_identifier?) (sized_type_specifier? - (primitive_type) + (primitive_type?) ) (struct_specifier? (type_identifier) @@ -95,7 +95,7 @@ proc initGrammar() = (field_declaration+ (primitive_type|type_identifier?) (sized_type_specifier? - (primitive_type) + (primitive_type?) ) (struct_specifier? (type_identifier) @@ -171,9 +171,10 @@ proc initGrammar() = # typ function(typ param1, ...) gStateRT.grammar.add((""" (declaration + (type_qualifier?) (primitive_type|type_identifier?) (sized_type_specifier? - (primitive_type) + (primitive_type?) ) (struct_specifier? (type_identifier) @@ -182,9 +183,10 @@ proc initGrammar() = (identifier) (parameter_list (parameter_declaration* + (type_qualifier?) (primitive_type|type_identifier?) (sized_type_specifier? - (primitive_type) + (primitive_type?) ) (struct_specifier? (type_identifier) @@ -200,13 +202,14 @@ proc initGrammar() = ) ) (pointer_declarator? - (function_declarator? + (function_declarator (identifier) (parameter_list (parameter_declaration* + (type_qualifier?) (primitive_type|type_identifier?) (sized_type_specifier? - (primitive_type) + (primitive_type?) ) (struct_specifier? (type_identifier) From cb100ca5717ecc34112f1e5c5aac09439676c4ba Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 4 Dec 2018 11:11:34 -0600 Subject: [PATCH 042/593] Add short CLI flags, --source= not required --- nimterop/cimport.nim | 2 +- toast.nim | 13 ++++++++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index 758237b..d671ee4 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -34,7 +34,7 @@ proc getToast(fullpath: string): string = for i in gStateCT.includeDirs: cmd.add &"--includeDirs+={i.quoteShell} " - cmd.add &"--source:{fullpath.quoteShell}" + cmd.add &"{fullpath.quoteShell}" echo cmd var (output, exitCode) = gorgeEx(cmd) doAssert exitCode == 0, $exitCode diff --git a/toast.nim b/toast.nim index f743264..948a517 100644 --- a/toast.nim +++ b/toast.nim @@ -109,10 +109,8 @@ proc main( preprocess = false, defines: seq[string] = @[], includeDirs: seq[string] = @[], - # defines.add(param[2..^1].strip(chars={'"'})) - source: string, + source: seq[string], ) = - # TODO: should we add back `-m` param? meaning was: print minimized AST output - non-pretty (implies -a) gStateRT = State( mode: mode, @@ -120,11 +118,10 @@ proc main( pnim: pnim, pretty: pretty, preprocess: preprocess, - # Note: was: strip(chars={'"'} but that seemed buggy (the shell should remove these already) defines: defines, includeDirs: includeDirs, ) - process(source) + process(source[0]) when isMainModule: import cligen @@ -136,4 +133,10 @@ when isMainModule: "includeDirs": "include directory to pass to preprocessor", "preprocess": "print Nim output", "source" : "C/C++ source/header", + }, short = { + "past": 'a', + "pnim": 'n', + "defines": 'D', + "includeDirs": 'I', + "preprocess": 'p' }) From cf2f200a16203311a3ac7595eb547b37fab5df82 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 4 Dec 2018 13:24:49 -0600 Subject: [PATCH 043/593] Fix performance issues with regex --- nimterop/ast.nim | 5 +---- nimterop/globals.nim | 3 +++ nimterop/grammar.nim | 10 ++++++++++ 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/nimterop/ast.nim b/nimterop/ast.nim index ba7561e..df973b9 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -53,10 +53,7 @@ proc searchAstForNode(ast: ref Ast, node: TSNode): bool = return if ast.children.len != 0: - let - rstr = ast.getRegexForAstChildren() - - if childNames.contains(rstr.toPattern): + if childNames.contains(ast.regex): if node.getTSNodeNamedChildCountSansComments() != 0: var flag = true for i in 0 .. node.tsNodeNamedChildCount()-1: diff --git a/nimterop/globals.nim b/nimterop/globals.nim index 39969bc..e65a4b9 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -1,5 +1,7 @@ import tables +import regex + type Kind* = enum exactlyOne @@ -12,6 +14,7 @@ type kind*: Kind children*: seq[ref Ast] tonim*: proc () {.closure, locks: 0.} + regex*: Regex State* = object compile*, defines*, headers*, includeDirs*, searchDirs*: seq[string] diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index a07ad84..7876ca3 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -1,5 +1,7 @@ import strformat, tables +import regex + import "."/[getters, globals, lisp] proc initGrammar() = @@ -254,6 +256,13 @@ proc initGrammar() = )) +proc initRegex(ast: ref Ast) = + if ast.children.len != 0: + for child in ast.children: + child.initRegex() + + ast.regex = ast.getRegexForAstChildren().re() + proc parseGrammar*() = initGrammar() @@ -263,6 +272,7 @@ proc parseGrammar*() = ast = gStateRT.grammar[i].grammar.parseLisp() ast.tonim = gStateRT.grammar[i].call + ast.initRegex() if ast.name notin gStateRT.ast: gStateRT.ast[ast.name] = @[ast] else: From e77792ceb71cd85c2615d2f5136810bbd3cb302c Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 4 Dec 2018 14:59:00 -0600 Subject: [PATCH 044/593] Fix crash if no arguments --- toast.nim | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/toast.nim b/toast.nim index 948a517..a4181d0 100644 --- a/toast.nim +++ b/toast.nim @@ -121,7 +121,8 @@ proc main( defines: defines, includeDirs: includeDirs, ) - process(source[0]) + if source.len != 0: + process(source[0]) when isMainModule: import cligen From 8d9bc5adbd9c3368295c7e7c920fb0c166f29c29 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 4 Dec 2018 16:46:16 -0600 Subject: [PATCH 045/593] Fix qualifiers, preproc only literals, remove _, struct field issue, print preproc output --- nimterop.nimble | 3 +++ nimterop/getters.nim | 15 ++++++++++----- nimterop/grammar.nim | 20 ++++++++++++-------- toast.nim | 2 ++ 4 files changed, 27 insertions(+), 13 deletions(-) diff --git a/nimterop.nimble b/nimterop.nimble index 3bfd982..a504ffc 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -19,6 +19,9 @@ proc execCmd(cmd:string)= task test, "Test": execCmd "nim c -r tests/tnimterop_c.nim" execCmd "nim cpp -r tests/tnimterop_cpp.nim" + when defined(windows): + execCmd "nim c -r tests/tmath.nim" + execCmd "nim cpp -r tests/tmath.nim" task installWithDeps, "install dependencies": for a in ["http://github.com/genotrance/nimtreesitter?subdir=treesitter", diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 1e76429..e3e00c2 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -17,13 +17,18 @@ proc getType*(str: string): string = return "object" result = str.strip(chars={'_'}). - replace("unsigned ", "u"). + multiReplace([ + ("unsigned ", "cu"), + ("double ", "cdouble"), + ("long ", "clong"), + ]). replace(re"([u]?int[\d]+)_t", "$1") - if result == "uchar": - result = "cuchar" - elif result == "double": - result = "cdouble" + case result: + of "long": + result = "clong" + of "double": + result = "cdouble" proc getLit*(str: string): string = if str.contains(re"^[\-]?[\d]+$") or diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index 7876ca3..2233609 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -15,7 +15,7 @@ proc initGrammar() = proc () {.closure, locks: 0.} = let name = gStateRT.data[0].val.getIdentifier() - val = gStateRT.data[1].val + val = gStateRT.data[1].val.getLit() if name notin gStateRT.consts and val.nBl: gStateRT.consts.add(name) @@ -44,7 +44,7 @@ proc initGrammar() = proc () {.closure, locks: 0.} = var name = gStateRT.data[1].val.getIdentifier() - typ = gStateRT.data[0].val + typ = gStateRT.data[0].val.getIdentifier() if name notin gStateRT.types: gStateRT.types.add(name) @@ -58,11 +58,14 @@ proc initGrammar() = gStateRT.types.add(nname) gStateRT.typeStr &= &" {nname}* {{.importc: \"{prefix}{name}\", header: {gStateRT.currentHeader}, bycopy.}} = object\n" - for i in fstart .. gStateRT.data.len-fend: + var + i = fstart + while i < gStateRT.data.len-fend: let - ftyp = gStateRT.data[i].val + ftyp = gStateRT.data[i].val.getIdentifier() fname = gStateRT.data[i+1].val.getIdentifier() gStateRT.typeStr &= &" {fname}*: {ftyp}\n" + i += 2 # struct X {} gStateRT.grammar.add((""" @@ -86,7 +89,7 @@ proc initGrammar() = ) """, proc () {.closure, locks: 0.} = - pStructCommon(gStateRT.data[0].val, 1, 2, "struct ") + pStructCommon(gStateRT.data[0].val, 1, 0, "struct ") )) # typedef struct X {} @@ -113,7 +116,7 @@ proc initGrammar() = ) """, proc () {.closure, locks: 0.} = - pStructCommon(gStateRT.data[^1].val, 0, 3) + pStructCommon(gStateRT.data[^1].val, 0, 1) )) proc pEnumCommon(name: string, fstart, fend: int, prefix="") = @@ -231,7 +234,7 @@ proc initGrammar() = """, proc () {.closure, locks: 0.} = let - ftyp = gStateRT.data[0].val + ftyp = gStateRT.data[0].val.getIdentifier() fname = gStateRT.data[1].val fnname = fname.getIdentifier() @@ -242,13 +245,14 @@ proc initGrammar() = if gStateRT.data.len > 2: while i < gStateRT.data.len-1: let - ptyp = gStateRT.data[i].val + ptyp = gStateRT.data[i].val.getIdentifier() pname = gStateRT.data[i+1].val.getIdentifier() pout &= &"{pname}: {ptyp}," i += 2 if pout.len != 0 and pout[^1] == ',': pout = pout[0 .. ^2] + gStateRT.procs.add(fnname) if ftyp != "object": gStateRT.procStr &= &"proc {fnname}({pout}): {ftyp} {{.importc: \"{fname}\", header: {gStateRT.currentHeader}.}}\n" else: diff --git a/toast.nim b/toast.nim index a4181d0..7511d8d 100644 --- a/toast.nim +++ b/toast.nim @@ -100,6 +100,8 @@ proc process(path: string) = printLisp(root) elif gStateRT.pnim: printNim(path, root) + elif gStateRT.preprocess: + echo gStateRT.code proc main( mode = modeDefault, From cb1c7f28cbff8ac4e588266b8aa953a6f7f44563 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 4 Dec 2018 17:14:50 -0600 Subject: [PATCH 046/593] Add math test for Windows --- tests/tmath.nim | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 tests/tmath.nim diff --git a/tests/tmath.nim b/tests/tmath.nim new file mode 100644 index 0000000..0479dda --- /dev/null +++ b/tests/tmath.nim @@ -0,0 +1,12 @@ +import nimterop/cimport +import unittest + +type + locale_t = object + +cAddStdDir() +cImport cSearchPath("math.h") + +check sin(5) == -0.9589242746631385 +check abs(-5) == 5 +check sqrt(4.00) == 2.0 \ No newline at end of file From dfe06fd9d474c368cb6c724902dd20369d68f1b6 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 4 Dec 2018 23:37:08 -0600 Subject: [PATCH 047/593] Support for unions --- README.md | 4 +-- nimterop/ast.nim | 2 +- nimterop/globals.nim | 6 ++-- nimterop/grammar.nim | 74 ++++++++++++++++++++++++++++--------------- tests/include/test.c | 38 +++++++++++++++------- tests/include/test.h | 21 +++++++++--- tests/tnimterop_c.nim | 17 +++++++--- 7 files changed, 112 insertions(+), 50 deletions(-) diff --git a/README.md b/README.md index 38b2f1d..5bb725f 100644 --- a/README.md +++ b/README.md @@ -14,8 +14,8 @@ Most of the functionality is contained within the `toast` binary that is built w The nimterop feature set is still limited when compared with c2nim. Supported language constructs include: - `#define NAME VALUE` where `VALUE` is a number (int, float, hex) -- `struct X`, `typedef struct`, `enum X`, `typedef enum` -- Functions with primitive types, structs, enums and typedef structs/enums as params and return values +- `struct X`, `typedef struct`, `enum X`, `typedef enum`, `union X`, `typedef union` +- Functions with primitive types, structs, enums, unions and typedef structs/enums/unions as params and return values - Pointers to data types Given the simplicity and success of this approach so far, it seems feasible to continue on for more complex code. The goal is to make interop seamless so nimterop will focus on wrapping headers and not the outright conversion of C/C++ implementation. diff --git a/nimterop/ast.nim b/nimterop/ast.nim index df973b9..9a2ee3c 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -84,7 +84,7 @@ proc searchAst(root: TSNode) = if name in gStateRT.ast: for ast in gStateRT.ast[name]: if searchAstForNode(ast, node): - ast.tonim() + ast.tonim(ast, node) break gStateRT.data = @[] else: diff --git a/nimterop/globals.nim b/nimterop/globals.nim index e65a4b9..c4fe8ad 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -2,6 +2,8 @@ import tables import regex +import treesitter/runtime + type Kind* = enum exactlyOne @@ -13,7 +15,7 @@ type name*: string kind*: Kind children*: seq[ref Ast] - tonim*: proc () {.closure, locks: 0.} + tonim*: proc (ast: ref Ast, node: TSNode) {.closure, locks: 0.} regex*: Regex State* = object @@ -28,7 +30,7 @@ type ast*: Table[string, seq[ref Ast]] data*: seq[tuple[name, val: string]] - grammar*: seq[tuple[grammar: string, call: proc() {.locks: 0.}]] + grammar*: seq[tuple[grammar: string, call: proc(ast: ref Ast, node: TSNode) {.locks: 0.}]] var gStateCT* {.compiletime.}: State diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index 2233609..455d2e8 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -1,7 +1,9 @@ -import strformat, tables +import strformat, strutils, tables import regex +import treesitter/runtime + import "."/[getters, globals, lisp] proc initGrammar() = @@ -12,7 +14,7 @@ proc initGrammar() = (preproc_arg) ) """, - proc () {.closure, locks: 0.} = + proc (ast: ref Ast, node: TSNode) {.closure, locks: 0.} = let name = gStateRT.data[0].val.getIdentifier() val = gStateRT.data[1].val.getLit() @@ -41,7 +43,7 @@ proc initGrammar() = ) ) """, - proc () {.closure, locks: 0.} = + proc (ast: ref Ast, node: TSNode) {.closure, locks: 0.} = var name = gStateRT.data[1].val.getIdentifier() typ = gStateRT.data[0].val.getIdentifier() @@ -51,12 +53,31 @@ proc initGrammar() = gStateRT.typeStr &= &" {name}* = {typ}\n" )) - proc pStructCommon(name: string, fstart, fend: int, prefix="") = - let + proc pStructCommon(ast: ref Ast, node: TSNode, name: string, fstart, fend: int) = + var nname = name.getIdentifier() + prefix = "" + union = "" + + case $node.tsNodeType(): + of "struct_specifier": + prefix = "struct " + of "union_specifier": + prefix = "union " + union = " {.union.}" + of "type_definition": + if node.getTSNodeNamedChildCountSansComments() != 0: + for i in 0 .. node.tsNodeNamedChildCount()-1: + let + nchild = $node.tsNodeNamedChild(i).tsNodeType() + if nchild != "comment": + if nchild == "union_specifier": + union = " {.union.}" + break + if nname notin gStateRT.types: gStateRT.types.add(nname) - gStateRT.typeStr &= &" {nname}* {{.importc: \"{prefix}{name}\", header: {gStateRT.currentHeader}, bycopy.}} = object\n" + gStateRT.typeStr &= &" {nname}* {{.importc: \"{prefix}{name}\", header: {gStateRT.currentHeader}, bycopy.}} = object{union}\n" var i = fstart @@ -69,13 +90,13 @@ proc initGrammar() = # struct X {} gStateRT.grammar.add((""" - (struct_specifier + (struct_specifier|union_specifier (type_identifier) (field_declaration_list (field_declaration+ (primitive_type|type_identifier?) (sized_type_specifier? - (primitive_type) + (primitive_type?) ) (struct_specifier? (type_identifier) @@ -88,14 +109,14 @@ proc initGrammar() = ) ) """, - proc () {.closure, locks: 0.} = - pStructCommon(gStateRT.data[0].val, 1, 0, "struct ") + proc (ast: ref Ast, node: TSNode) {.closure, locks: 0.} = + pStructCommon(ast, node, gStateRT.data[0].val, 1, 1) )) # typedef struct X {} gStateRT.grammar.add((""" (type_definition - (struct_specifier + (struct_specifier|union_specifier (field_declaration_list (field_declaration+ (primitive_type|type_identifier?) @@ -115,11 +136,11 @@ proc initGrammar() = (type_identifier) ) """, - proc () {.closure, locks: 0.} = - pStructCommon(gStateRT.data[^1].val, 0, 1) + proc (ast: ref Ast, node: TSNode) {.closure, locks: 0.} = + pStructCommon(ast, node, gStateRT.data[^1].val, 0, 1) )) - proc pEnumCommon(name: string, fstart, fend: int, prefix="") = + proc pEnumCommon(ast: ref Ast, node: TSNode, name: string, fstart, fend: int) = let nname = name.getIdentifier() if nname notin gStateRT.types: @@ -151,8 +172,8 @@ proc initGrammar() = ) ) """, - proc () {.closure, locks: 0.} = - pEnumCommon(gStateRT.data[0].val, 1, 0) + proc (ast: ref Ast, node: TSNode) {.closure, locks: 0.} = + pEnumCommon(ast, node, gStateRT.data[0].val, 1, 0) )) # typedef enum {} X @@ -169,8 +190,8 @@ proc initGrammar() = (type_identifier) ) """, - proc () {.closure, locks: 0.} = - pEnumCommon(gStateRT.data[^1].val, 0, 1) + proc (ast: ref Ast, node: TSNode) {.closure, locks: 0.} = + pEnumCommon(ast, node, gStateRT.data[^1].val, 0, 1) )) # typ function(typ param1, ...) @@ -181,7 +202,7 @@ proc initGrammar() = (sized_type_specifier? (primitive_type?) ) - (struct_specifier? + (struct_specifier|union_specifier? (type_identifier) ) (function_declarator? @@ -193,7 +214,7 @@ proc initGrammar() = (sized_type_specifier? (primitive_type?) ) - (struct_specifier? + (struct_specifier|union_specifier? (type_identifier) ) (enum_specifier? @@ -216,7 +237,7 @@ proc initGrammar() = (sized_type_specifier? (primitive_type?) ) - (struct_specifier? + (struct_specifier|union_specifier? (type_identifier) ) (enum_specifier? @@ -232,7 +253,7 @@ proc initGrammar() = ) ) """, - proc () {.closure, locks: 0.} = + proc (ast: ref Ast, node: TSNode) {.closure, locks: 0.} = let ftyp = gStateRT.data[0].val.getIdentifier() fname = gStateRT.data[1].val @@ -277,10 +298,11 @@ proc parseGrammar*() = ast.tonim = gStateRT.grammar[i].call ast.initRegex() - if ast.name notin gStateRT.ast: - gStateRT.ast[ast.name] = @[ast] - else: - gStateRT.ast[ast.name].add(ast) + for n in ast.name.split("|"): + if n notin gStateRT.ast: + gStateRT.ast[n] = @[ast] + else: + gStateRT.ast[n].add(ast) proc printGrammar*() = for name in gStateRT.ast.keys(): diff --git a/tests/include/test.c b/tests/include/test.c index 885723e..d63c974 100644 --- a/tests/include/test.c +++ b/tests/include/test.c @@ -1,35 +1,51 @@ #include "test.h" int test_call_int() { - return 5; + return 5; } #ifdef FORCE -struct STRUCT1 _test_call_int_param_(int param1) { +struct STRUCT1 _test_call_param_(int param1) { struct STRUCT1 s; - + s.field1 = param1; - + return s; } #endif -STRUCT2 test_call_int_param2(int param1, STRUCT2 param2) { +STRUCT2 test_call_param2(int param1, STRUCT2 param2) { STRUCT2 s; - + s.field1 = param1 + param2.field1; - + return s; } -STRUCT2 test_call_int_param3(int param1, struct STRUCT1 param2) { +STRUCT2 test_call_param3(int param1, struct STRUCT1 param2) { STRUCT2 s; - + s.field1 = param1 + param2.field1; - + return s; } -ENUM2 test_call_int_param4(enum ENUM param1) { +ENUM2 test_call_param4(enum ENUM param1) { return enum4; +} + +union UNION1 test_call_param5(float param1) { + union UNION1 u; + + u.field2 = param1; + + return u; +} + +unsigned char test_call_param6(UNION2 param1) { + return param1.field2; +} + +int test_call_param7(union UNION1 param1) { + return param1.field1; } \ No newline at end of file diff --git a/tests/include/test.h b/tests/include/test.h index 6138ca3..af7eeb8 100644 --- a/tests/include/test.h +++ b/tests/include/test.h @@ -36,8 +36,21 @@ typedef struct { int *field; } STRUCT4; +union UNION1 { + int field1; + float field2; +}; + +typedef union { + double field1; + unsigned char field2; +} UNION2; + int test_call_int(); -struct STRUCT1 _test_call_int_param_(int param1); -STRUCT2 test_call_int_param2(int param1, STRUCT2 param2); -STRUCT2 test_call_int_param3(int param1, struct STRUCT1 param2); -ENUM2 test_call_int_param4(enum ENUM param1); +struct STRUCT1 _test_call_param_(int param1); +STRUCT2 test_call_param2(int param1, STRUCT2 param2); +STRUCT2 test_call_param3(int param1, struct STRUCT1 param2); +ENUM2 test_call_param4(enum ENUM param1); +union UNION1 test_call_param5(float param1); +unsigned char test_call_param6(UNION2 param1); +int test_call_param7(union UNION1 param1); \ No newline at end of file diff --git a/tests/tnimterop_c.nim b/tests/tnimterop_c.nim index eff7039..2477e61 100644 --- a/tests/tnimterop_c.nim +++ b/tests/tnimterop_c.nim @@ -28,6 +28,9 @@ var vptr: VOIDPTR iptr: INTPTR + u: UNION1 + u2: UNION2 + pt = 3 ct = 4 @@ -38,10 +41,16 @@ s3.field1 = 7 e = enum1 e2 = enum4 +u2.field2 = 'c' + check test_call_int() == 5 -check test_call_int_param(5).field1 == 5 -check test_call_int_param2(5, s2).field1 == 11 -check test_call_int_param3(5, s).field1 == 10 -check test_call_int_param4(e) == e2 +check test_call_param(5).field1 == 5 +check test_call_param2(5, s2).field1 == 11 +check test_call_param3(5, s).field1 == 10 +check test_call_param4(e) == e2 +check test_call_param5(5.0).field2 == 5.0 +check test_call_param6(u2) == 'c' +u.field1 = 4 +check test_call_param7(u) == 4 cAddStdDir() From 7c8afa19975517b18553f2eb3007c0e279360299 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 5 Dec 2018 00:14:38 -0600 Subject: [PATCH 048/593] Fix default cpp mode, print row col length in AST output --- toast.nim | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/toast.nim b/toast.nim index 7511d8d..5885bc2 100644 --- a/toast.nim +++ b/toast.nim @@ -1,4 +1,4 @@ -import os, strutils +import os, strformat, strutils import treesitter/[runtime, c, cpp] @@ -14,7 +14,9 @@ proc printLisp(root: TSNode) = if not node.tsNodeIsNull(): if gStateRT.pretty: stdout.write spaces(depth) - stdout.write "(" & $node.tsNodeType() & " " & $node.tsNodeStartByte() & " " & $node.tsNodeEndByte() + let + (line, col) = node.getLineCol() + stdout.write &"({$node.tsNodeType()} {line} {col} {node.tsNodeEndByte() - node.tsNodeStartByte()}" else: return @@ -66,11 +68,10 @@ proc process(path: string) = gStateRT.sourceFile = path if gStateRT.mode.len == 0: - gStateRT.mode = modeDefault - elif ext in [".h", ".c"]: - gStateRT.mode = "c" - elif ext in [".hxx", ".hpp", ".hh", ".H", ".h++", ".cpp", ".cxx", ".cc", ".C", ".c++"]: - gStateRT.mode = "cpp" + if ext in [".h", ".c"]: + gStateRT.mode = "c" + elif ext in [".hxx", ".hpp", ".hh", ".H", ".h++", ".cpp", ".cxx", ".cc", ".C", ".c++"]: + gStateRT.mode = "cpp" if gStateRT.preprocess: gStateRT.code = getPreprocessor(path) From d835d29e3ec1260569bb98866679110b2d193daa Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 5 Dec 2018 00:35:15 -0600 Subject: [PATCH 049/593] Fix recursion in type --- nimterop/grammar.nim | 2 ++ 1 file changed, 2 insertions(+) diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index 455d2e8..4a949cb 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -50,6 +50,8 @@ proc initGrammar() = if name notin gStateRT.types: gStateRT.types.add(name) + if name == typ: + typ = "object" gStateRT.typeStr &= &" {name}* = {typ}\n" )) From f90b00446e930f7695a709800561950894a854d5 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 10 Dec 2018 09:52:18 -0600 Subject: [PATCH 050/593] No caching of binaries on Travis --- .travis.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.travis.yml b/.travis.yml index 60eabe7..2e316a2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,15 +9,15 @@ env: - BRANCH=stable - BRANCH=devel -cache: - directories: - - "$HOME/.nimble" - - "$HOME/.choosenim" +# cache: + # directories: + # - "$HOME/.nimble" + # - "$HOME/.choosenim" -matrix: - allow_failures: - - env: BRANCH=devel - fast_finish: true +# matrix: + # allow_failures: + # - env: BRANCH=devel + # fast_finish: true install: - export CHOOSENIM_CHOOSE_VERSION=$BRANCH @@ -25,7 +25,7 @@ install: curl https://nim-lang.org/choosenim/init.sh -sSf > init.sh sh init.sh -y - export PATH=$HOME/.nimble/bin:$PATH - - nimble refresh -y + # - nimble refresh -y script: - nimble installWithDeps From 0697feed0f79cdb1aceac0c4dfc04c170208e40c Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Sat, 15 Dec 2018 22:35:56 -0600 Subject: [PATCH 051/593] Fix treesitter namespace issue --- toast.nim | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/toast.nim b/toast.nim index 5885bc2..3481832 100644 --- a/toast.nim +++ b/toast.nim @@ -1,6 +1,8 @@ import os, strformat, strutils -import treesitter/[runtime, c, cpp] +import treesitter/runtime +import treesitter_c/c +import treesitter_cpp/cpp import nimterop/[ast, globals, getters] From 34cb1715b876ac9dd09b97b938638f6beaff926b Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 26 Dec 2018 13:25:45 -0600 Subject: [PATCH 052/593] Support for math expressions, nameless enums, uintptr, redundant typedef naming --- nimterop.nimble | 6 +++--- nimterop/ast.nim | 8 ++++++-- nimterop/getters.nim | 13 ++++++++++++- nimterop/grammar.nim | 46 +++++++++++++++++++++++++++++++++++++------- tests/tmath.nim | 2 ++ 5 files changed, 62 insertions(+), 13 deletions(-) diff --git a/nimterop.nimble b/nimterop.nimble index a504ffc..b1ee584 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -19,9 +19,9 @@ proc execCmd(cmd:string)= task test, "Test": execCmd "nim c -r tests/tnimterop_c.nim" execCmd "nim cpp -r tests/tnimterop_cpp.nim" - when defined(windows): - execCmd "nim c -r tests/tmath.nim" - execCmd "nim cpp -r tests/tmath.nim" + # when defined(windows): + # execCmd "nim c -r tests/tmath.nim" + # execCmd "nim cpp -r tests/tmath.nim" task installWithDeps, "install dependencies": for a in ["http://github.com/genotrance/nimtreesitter?subdir=treesitter", diff --git a/nimterop/ast.nim b/nimterop/ast.nim index 9a2ee3c..ff7dbcb 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -9,6 +9,7 @@ import "."/[getters, globals, grammar] const gAtoms = @[ "field_identifier", "identifier", + "math_expression", "number_literal", "preproc_arg", "primitive_type", @@ -25,7 +26,10 @@ proc saveNodeData(node: TSNode): bool = if name == "primitive_type" and node.tsNodeParent.tsNodeType() == "sized_type_specifier": return true - if name in ["primitive_type", "sized_type_specifier"]: + if name == "number_literal" and node.tsNodeParent.tsNodeType() == "math_expression": + return true + + if name in ["math_expression", "primitive_type", "sized_type_specifier"]: val = val.getType() let @@ -39,7 +43,7 @@ proc saveNodeData(node: TSNode): bool = not npparent.tsNodeIsNull() and npparent.tsNodeType() == "pointer_declarator"): if gStateRT.data[^1].val != "object": - gStateRT.data[^1].val = "ptr " & gStateRT.data[^1].val + gStateRT.data[^1].val = "ptr " & gStateRT.data[^1].val.getIdentifier() gStateRT.data.add((name, val)) diff --git a/nimterop/getters.nim b/nimterop/getters.nim index e3e00c2..b03f931 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -12,6 +12,16 @@ proc sanitizePath*(path: string): string = proc getIdentifier*(str: string): string = result = str.strip(chars={'_'}) +proc getUniqueIdentifier*(exists: seq[string]): string = + var + name = gStateRT.sourceFile.extractFilename().multiReplace([(".", ""), ("-", "")]) + count = 1 + + while (name & $count) in exists: + count += 1 + + return name & $count + proc getType*(str: string): string = if str == "void": return "object" @@ -22,7 +32,8 @@ proc getType*(str: string): string = ("double ", "cdouble"), ("long ", "clong"), ]). - replace(re"([u]?int[\d]+)_t", "$1") + replace(re"([u]?int[\d]+)_t", "$1"). + replace(re"([u]?int)ptr_t", "ptr $1") case result: of "long": diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index 4a949cb..e86f907 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -119,6 +119,7 @@ proc initGrammar() = gStateRT.grammar.add((""" (type_definition (struct_specifier|union_specifier + (type_identifier?) (field_declaration_list (field_declaration+ (primitive_type|type_identifier?) @@ -139,12 +140,22 @@ proc initGrammar() = ) """, proc (ast: ref Ast, node: TSNode) {.closure, locks: 0.} = - pStructCommon(ast, node, gStateRT.data[^1].val, 0, 1) + var + offset = 0 + + if gStateRT.data[0].name == "type_identifier": + offset = 1 + + pStructCommon(ast, node, gStateRT.data[^1].val, offset, 1) )) proc pEnumCommon(ast: ref Ast, node: TSNode, name: string, fstart, fend: int) = - let + var nname = name.getIdentifier() + + if nname.len == 0: + nname = getUniqueIdentifier(gStateRT.types) + if nname notin gStateRT.types: gStateRT.types.add(nname) gStateRT.typeStr &= &" {nname}* = enum\n" @@ -155,7 +166,7 @@ proc initGrammar() = let fname = gStateRT.data[i].val.getIdentifier() - if i+1 < gStateRT.data.len-fend and gStateRT.data[i+1].name == "number_literal": + if i+1 < gStateRT.data.len-fend and gStateRT.data[i+1].name in ["math_expression", "number_literal"]: gStateRT.typeStr &= &" {fname} = {gStateRT.data[i+1].val}\n" i += 2 else: @@ -165,27 +176,42 @@ proc initGrammar() = # enum X {} gStateRT.grammar.add((""" (enum_specifier - (type_identifier) + (type_identifier?) (enumerator_list (enumerator+ (identifier) (number_literal?) + (math_expression? + (number_literal) + ) ) ) ) """, proc (ast: ref Ast, node: TSNode) {.closure, locks: 0.} = - pEnumCommon(ast, node, gStateRT.data[0].val, 1, 0) + var + name = "" + offset = 0 + + if gStateRT.data[0].name == "type_identifier": + name = gStateRT.data[0].val + offset = 1 + + pEnumCommon(ast, node, name, offset, 0) )) # typedef enum {} X gStateRT.grammar.add((""" (type_definition (enum_specifier + (type_identifier?) (enumerator_list (enumerator+ (identifier) (number_literal?) + (math_expression? + (number_literal) + ) ) ) ) @@ -193,13 +219,19 @@ proc initGrammar() = ) """, proc (ast: ref Ast, node: TSNode) {.closure, locks: 0.} = - pEnumCommon(ast, node, gStateRT.data[^1].val, 0, 1) + var + offset = 0 + + if gStateRT.data[0].name == "type_identifier": + offset = 1 + + pEnumCommon(ast, node, gStateRT.data[^1].val, offset, 1) )) # typ function(typ param1, ...) gStateRT.grammar.add((""" (declaration - (type_qualifier?) + (type_qualifier|storage_class_specifier?) (primitive_type|type_identifier?) (sized_type_specifier? (primitive_type?) diff --git a/tests/tmath.nim b/tests/tmath.nim index 0479dda..bee2f29 100644 --- a/tests/tmath.nim +++ b/tests/tmath.nim @@ -4,6 +4,8 @@ import unittest type locale_t = object +cDebug() + cAddStdDir() cImport cSearchPath("math.h") From 1684e773ad51612ea1034834662049e1228ddad9 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 26 Dec 2018 17:42:13 -0600 Subject: [PATCH 053/593] Tests for enhancements --- nimterop/getters.nim | 4 ++-- nimterop/grammar.nim | 2 +- tests/include/test.h | 14 +++++++++++++- tests/tnimterop_c.nim | 5 +++++ 4 files changed, 21 insertions(+), 4 deletions(-) diff --git a/nimterop/getters.nim b/nimterop/getters.nim index b03f931..28e1bd1 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -12,9 +12,9 @@ proc sanitizePath*(path: string): string = proc getIdentifier*(str: string): string = result = str.strip(chars={'_'}) -proc getUniqueIdentifier*(exists: seq[string]): string = +proc getUniqueIdentifier*(exists: seq[string], prefix = ""): string = var - name = gStateRT.sourceFile.extractFilename().multiReplace([(".", ""), ("-", "")]) + name = prefix & "_" & gStateRT.sourceFile.extractFilename().multiReplace([(".", ""), ("-", "")]) count = 1 while (name & $count) in exists: diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index e86f907..a8d8eed 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -154,7 +154,7 @@ proc initGrammar() = nname = name.getIdentifier() if nname.len == 0: - nname = getUniqueIdentifier(gStateRT.types) + nname = getUniqueIdentifier(gStateRT.types, "Enum") if nname notin gStateRT.types: gStateRT.types.add(nname) diff --git a/tests/include/test.h b/tests/include/test.h index af7eeb8..bf4f70d 100644 --- a/tests/include/test.h +++ b/tests/include/test.h @@ -29,6 +29,18 @@ typedef enum { enum6 } ENUM2; +enum { + enum7, + enum8, + enum9 +}; + +typedef enum ENUM4 { + enum10, + enum11, + enum12 +} ENUM4; + typedef void * VOIDPTR; typedef int * INTPTR; @@ -41,7 +53,7 @@ union UNION1 { float field2; }; -typedef union { +typedef union UNION2 { double field1; unsigned char field2; } UNION2; diff --git a/tests/tnimterop_c.nim b/tests/tnimterop_c.nim index 2477e61..45e94d6 100644 --- a/tests/tnimterop_c.nim +++ b/tests/tnimterop_c.nim @@ -24,6 +24,8 @@ var e: ENUM e2: ENUM2 = enum5 + e3: Enum_testh1 = enum7 + e4: ENUM4 = enum11 vptr: VOIDPTR iptr: INTPTR @@ -53,4 +55,7 @@ check test_call_param6(u2) == 'c' u.field1 = 4 check test_call_param7(u) == 4 +check e3 == enum7 +check e4 == enum11 + cAddStdDir() From 373e9decf333ec65c14d7c36a0d1d33e9eb2a803 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 26 Dec 2018 18:49:46 -0600 Subject: [PATCH 054/593] Support arrays in structs --- nimterop/grammar.nim | 26 ++++++++++++++++++++++++-- toast.nim | 4 ++-- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index a8d8eed..c72e29b 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -87,8 +87,14 @@ proc initGrammar() = let ftyp = gStateRT.data[i].val.getIdentifier() fname = gStateRT.data[i+1].val.getIdentifier() - gStateRT.typeStr &= &" {fname}*: {ftyp}\n" - i += 2 + if i+2 < gStateRT.data.len-fend and gStateRT.data[i+2].name == "identifier": + let + flen = gStateRT.data[i+2].val.getIdentifier() + gStateRT.typeStr &= &" {fname}*: array[{flen}, {ftyp}]\n" + i += 3 + else: + gStateRT.typeStr &= &" {fname}*: {ftyp}\n" + i += 2 # struct X {} gStateRT.grammar.add((""" @@ -105,7 +111,15 @@ proc initGrammar() = ) (field_identifier?) (pointer_declarator? + (field_identifier?) + (array_declarator? + (field_identifier) + (identifier) + ) + ) + (array_declarator? (field_identifier) + (identifier) ) ) ) @@ -131,7 +145,15 @@ proc initGrammar() = ) (field_identifier?) (pointer_declarator? + (field_identifier?) + (array_declarator? + (field_identifier) + (identifier) + ) + ) + (array_declarator? (field_identifier) + (identifier) ) ) ) diff --git a/toast.nim b/toast.nim index 3481832..ced3047 100644 --- a/toast.nim +++ b/toast.nim @@ -134,10 +134,10 @@ when isMainModule: dispatch(main, help = { "past": "print AST output", "mode": "language; see CompileMode", # TODO: auto-generate valid choices - "pnim": "run preprocessor on header", + "pnim": "print Nim output", "defines": "definitions to pass to preprocessor", "includeDirs": "include directory to pass to preprocessor", - "preprocess": "print Nim output", + "preprocess": "run preprocessor on header", "source" : "C/C++ source/header", }, short = { "past": 'a', From e59e34a7be12c7f84099d8b56b038d3c3ab9c15c Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 26 Dec 2018 20:18:38 -0600 Subject: [PATCH 055/593] Array ptr, numeric length, tests --- nimterop/ast.nim | 4 ++-- nimterop/grammar.nim | 16 ++++++++-------- tests/include/test.h | 4 ++++ tests/tnimterop_c.nim | 2 ++ 4 files changed, 16 insertions(+), 10 deletions(-) diff --git a/nimterop/ast.nim b/nimterop/ast.nim index ff7dbcb..105d543 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -34,12 +34,12 @@ proc saveNodeData(node: TSNode): bool = let nparent = node.tsNodeParent() - if not nparent.tsNodeIsNull(): + if not nparent.tsNodeIsNull() and node.tsNodePrevNamedSibling().tsNodeIsNull(): let npname = nparent.tsNodeType() npparent = nparent.tsNodeParent() if npname == "pointer_declarator" or - (npname == "function_declarator" and + ($npname in ["function_declarator", "array_declarator"] and not npparent.tsNodeIsNull() and npparent.tsNodeType() == "pointer_declarator"): if gStateRT.data[^1].val != "object": diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index c72e29b..90aff2f 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -34,7 +34,7 @@ proc initGrammar() = (sized_type_specifier? (primitive_type?) ) - (struct_specifier? + (struct_specifier|union_specifier|enum_specifier? (type_identifier) ) (type_identifier?) @@ -87,7 +87,7 @@ proc initGrammar() = let ftyp = gStateRT.data[i].val.getIdentifier() fname = gStateRT.data[i+1].val.getIdentifier() - if i+2 < gStateRT.data.len-fend and gStateRT.data[i+2].name == "identifier": + if i+2 < gStateRT.data.len-fend and gStateRT.data[i+2].name in ["identifier", "number_literal"]: let flen = gStateRT.data[i+2].val.getIdentifier() gStateRT.typeStr &= &" {fname}*: array[{flen}, {ftyp}]\n" @@ -106,7 +106,7 @@ proc initGrammar() = (sized_type_specifier? (primitive_type?) ) - (struct_specifier? + (struct_specifier|union_specifier|enum_specifier? (type_identifier) ) (field_identifier?) @@ -114,12 +114,12 @@ proc initGrammar() = (field_identifier?) (array_declarator? (field_identifier) - (identifier) + (identifier|number_literal) ) ) (array_declarator? (field_identifier) - (identifier) + (identifier|number_literal) ) ) ) @@ -140,7 +140,7 @@ proc initGrammar() = (sized_type_specifier? (primitive_type?) ) - (struct_specifier? + (struct_specifier|union_specifier|enum_specifier? (type_identifier) ) (field_identifier?) @@ -148,12 +148,12 @@ proc initGrammar() = (field_identifier?) (array_declarator? (field_identifier) - (identifier) + (identifier|number_literal) ) ) (array_declarator? (field_identifier) - (identifier) + (identifier|number_literal) ) ) ) diff --git a/tests/include/test.h b/tests/include/test.h index bf4f70d..e040d7f 100644 --- a/tests/include/test.h +++ b/tests/include/test.h @@ -46,6 +46,10 @@ typedef int * INTPTR; typedef struct { int *field; + int field2[TEST_INT]; + enum ENUM field3[TEST_INT]; + int *field4[TEST_INT]; + ENUM4 *field5[TEST_INT]; } STRUCT4; union UNION1 { diff --git a/tests/tnimterop_c.nim b/tests/tnimterop_c.nim index 45e94d6..deef7d2 100644 --- a/tests/tnimterop_c.nim +++ b/tests/tnimterop_c.nim @@ -39,6 +39,8 @@ ct = 4 s.field1 = 5 s2.field1 = 6 s3.field1 = 7 +s4.field2[2] = 5 +s4.field3[3] = enum1 e = enum1 e2 = enum4 From 9cddef831de594ebc9f72babcdfdf45a4fba87f5 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 26 Dec 2018 20:24:17 -0600 Subject: [PATCH 056/593] Remove closure pragmas --- nimterop/globals.nim | 4 ++-- nimterop/grammar.nim | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/nimterop/globals.nim b/nimterop/globals.nim index c4fe8ad..9ad2b99 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -15,7 +15,7 @@ type name*: string kind*: Kind children*: seq[ref Ast] - tonim*: proc (ast: ref Ast, node: TSNode) {.closure, locks: 0.} + tonim*: proc (ast: ref Ast, node: TSNode) regex*: Regex State* = object @@ -30,7 +30,7 @@ type ast*: Table[string, seq[ref Ast]] data*: seq[tuple[name, val: string]] - grammar*: seq[tuple[grammar: string, call: proc(ast: ref Ast, node: TSNode) {.locks: 0.}]] + grammar*: seq[tuple[grammar: string, call: proc(ast: ref Ast, node: TSNode) {.nimcall.}]] var gStateCT* {.compiletime.}: State diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index 90aff2f..26ce7f0 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -14,7 +14,7 @@ proc initGrammar() = (preproc_arg) ) """, - proc (ast: ref Ast, node: TSNode) {.closure, locks: 0.} = + proc (ast: ref Ast, node: TSNode) = let name = gStateRT.data[0].val.getIdentifier() val = gStateRT.data[1].val.getLit() @@ -43,7 +43,7 @@ proc initGrammar() = ) ) """, - proc (ast: ref Ast, node: TSNode) {.closure, locks: 0.} = + proc (ast: ref Ast, node: TSNode) = var name = gStateRT.data[1].val.getIdentifier() typ = gStateRT.data[0].val.getIdentifier() @@ -125,7 +125,7 @@ proc initGrammar() = ) ) """, - proc (ast: ref Ast, node: TSNode) {.closure, locks: 0.} = + proc (ast: ref Ast, node: TSNode) = pStructCommon(ast, node, gStateRT.data[0].val, 1, 1) )) @@ -161,7 +161,7 @@ proc initGrammar() = (type_identifier) ) """, - proc (ast: ref Ast, node: TSNode) {.closure, locks: 0.} = + proc (ast: ref Ast, node: TSNode) = var offset = 0 @@ -210,7 +210,7 @@ proc initGrammar() = ) ) """, - proc (ast: ref Ast, node: TSNode) {.closure, locks: 0.} = + proc (ast: ref Ast, node: TSNode) = var name = "" offset = 0 @@ -240,7 +240,7 @@ proc initGrammar() = (type_identifier) ) """, - proc (ast: ref Ast, node: TSNode) {.closure, locks: 0.} = + proc (ast: ref Ast, node: TSNode) = var offset = 0 @@ -309,7 +309,7 @@ proc initGrammar() = ) ) """, - proc (ast: ref Ast, node: TSNode) {.closure, locks: 0.} = + proc (ast: ref Ast, node: TSNode) = let ftyp = gStateRT.data[0].val.getIdentifier() fname = gStateRT.data[1].val From c3744c0034d6b13081be26b13ed46014a9b0a036 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 26 Dec 2018 21:24:05 -0600 Subject: [PATCH 057/593] Enums as distinct int, always relative to project path, cmd /c for toast, escape reserved words --- nimterop/ast.nim | 3 +++ nimterop/cimport.nim | 19 +++++++++---------- nimterop/getters.nim | 25 +++++++++++++++++++++++++ nimterop/globals.nim | 4 ++-- nimterop/grammar.nim | 28 ++++++++++++++++++---------- 5 files changed, 57 insertions(+), 22 deletions(-) diff --git a/nimterop/ast.nim b/nimterop/ast.nim index 105d543..dd05227 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -124,6 +124,9 @@ proc printNim*(fullpath: string, root: TSNode) = root.searchAst() + if gStateRT.enumStr.nBl: + echo gStateRT.enumStr + if gStateRT.constStr.nBl: echo "const\n" & gStateRT.constStr diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index d671ee4..dd51166 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -13,20 +13,19 @@ proc joinPathIfRel(path1: string, path2: string): string = result = joinPath(path1, path2) proc findPath(path: string, fail = true): string = - # As is - result = path.replace("\\", "/") + # Relative to project path + result = joinPathIfRel(getProjectPath(), path).replace("\\", "/") if not fileExists(result) and not dirExists(result): - # Relative to project path - result = joinPathIfRel(getProjectPath(), path).replace("\\", "/") - if not fileExists(result) and not dirExists(result): - if fail: - doAssert false, "File or directory not found: " & path - else: - return "" + if fail: + doAssert false, "File or directory not found: " & path + else: + return "" proc getToast(fullpath: string): string = var - cmd = "toast --pnim --preprocess " + cmd = when defined(Windows): "cmd /c " else: "" + + cmd &= "toast --pnim --preprocess " for i in gStateCT.defines: cmd.add &"--defines+={i.quoteShell} " diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 28e1bd1..7ce16bd 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -6,12 +6,37 @@ import treesitter/runtime import git, globals +const gReserved = """ +addr and as asm +bind block break +case cast concept const continue converter +defer discard distinct div do +elif else end enum except export +finally for from func +if import in include interface is isnot iterator +let +macro method mixin mod +nil not notin +of or out +proc ptr +raise ref return +shl shr static +template try tuple type +using +var +when while +xor +yield""".split(Whitespace) + proc sanitizePath*(path: string): string = path.multiReplace([("\\\\", $DirSep), ("\\", $DirSep), ("//", $DirSep)]) proc getIdentifier*(str: string): string = result = str.strip(chars={'_'}) + if result in gReserved: + result = &"`{result}`" + proc getUniqueIdentifier*(exists: seq[string], prefix = ""): string = var name = prefix & "_" & gStateRT.sourceFile.extractFilename().multiReplace([(".", ""), ("-", "")]) diff --git a/nimterop/globals.nim b/nimterop/globals.nim index 9ad2b99..771987e 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -23,9 +23,9 @@ type debug*, past*, preprocess*, pnim*, pretty*: bool - consts*, procs*, types*: seq[string] + consts*, enums*, procs*, types*: seq[string] - code*, constStr*, currentHeader*, mode*, procStr*, typeStr*: string + code*, constStr*, currentHeader*, enumStr*, mode*, procStr*, typeStr*: string sourceFile*: string # eg, C or C++ source or header file ast*: Table[string, seq[ref Ast]] diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index 26ce7f0..3da4cc4 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -176,24 +176,32 @@ proc initGrammar() = nname = name.getIdentifier() if nname.len == 0: - nname = getUniqueIdentifier(gStateRT.types, "Enum") + nname = getUniqueIdentifier(gStateRT.enums, "Enum") - if nname notin gStateRT.types: - gStateRT.types.add(nname) - gStateRT.typeStr &= &" {nname}* = enum\n" + if nname notin gStateRT.enums: + gStateRT.enums.add(nname) + gStateRT.enumStr &= &"\ntype {nname}* = distinct int" + gStateRT.enumStr &= &"\nconverter enumToInt(en: {nname}): int = en.int\n" var i = fstart + count = 0 while i < gStateRT.data.len-fend: let fname = gStateRT.data[i].val.getIdentifier() - if i+1 < gStateRT.data.len-fend and gStateRT.data[i+1].name in ["math_expression", "number_literal"]: - gStateRT.typeStr &= &" {fname} = {gStateRT.data[i+1].val}\n" - i += 2 - else: - gStateRT.typeStr &= &" {fname}\n" - i += 1 + if fname notin gStateRT.consts: + if i+1 < gStateRT.data.len-fend and gStateRT.data[i+1].name in ["math_expression", "number_literal"]: + gStateRT.constStr &= &" {fname} = {gStateRT.data[i+1].val}.{nname}\n" + try: + count = gStateRT.data[i+1].val.parseInt() + 1 + except: + count += 1 + i += 2 + else: + gStateRT.constStr &= &" {fname} = {count}.{nname}\n" + i += 1 + count += 1 # enum X {} gStateRT.grammar.add((""" From 33a3f6fc8b159340f2b29d0ba4aff3fe6c839f66 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 26 Dec 2018 21:33:50 -0600 Subject: [PATCH 058/593] Fix for const void * proc --- nimterop/ast.nim | 2 ++ nimterop/grammar.nim | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/nimterop/ast.nim b/nimterop/ast.nim index dd05227..4c8e253 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -44,6 +44,8 @@ proc saveNodeData(node: TSNode): bool = if gStateRT.data[^1].val != "object": gStateRT.data[^1].val = "ptr " & gStateRT.data[^1].val.getIdentifier() + else: + gStateRT.data[^1].val = "pointer" gStateRT.data.add((name, val)) diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index 3da4cc4..66f7ee1 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -261,7 +261,8 @@ proc initGrammar() = # typ function(typ param1, ...) gStateRT.grammar.add((""" (declaration - (type_qualifier|storage_class_specifier?) + (storage_class_specifier?) + (type_qualifier?) (primitive_type|type_identifier?) (sized_type_specifier? (primitive_type?) From 9b93fb6561ff5b170b73979e18626e78c770b78c Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 26 Dec 2018 23:46:09 -0600 Subject: [PATCH 059/593] Reduce redundancy in grammar --- nimterop/grammar.nim | 146 +++++++++++-------------------------------- 1 file changed, 38 insertions(+), 108 deletions(-) diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index 66f7ee1..aa364b1 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -24,12 +24,7 @@ proc initGrammar() = gStateRT.constStr &= &" {name}* = {val}\n" )) - # typedef int X - # typedef X Y - # typedef struct X Y - # typedef ?* Y - gStateRT.grammar.add((""" - (type_definition + let typeGrammar = """ (primitive_type|type_identifier?) (sized_type_specifier? (primitive_type?) @@ -37,6 +32,15 @@ proc initGrammar() = (struct_specifier|union_specifier|enum_specifier? (type_identifier) ) + """ + + # typedef int X + # typedef X Y + # typedef struct X Y + # typedef ?* Y + gStateRT.grammar.add((&""" + (type_definition + {typeGrammar} (type_identifier?) (pointer_declarator? (type_identifier) @@ -96,30 +100,24 @@ proc initGrammar() = gStateRT.typeStr &= &" {fname}*: {ftyp}\n" i += 2 + let fieldGrammar = """ + (field_identifier?) + (array_declarator? + (field_identifier) + (identifier|number_literal) + ) + """ + # struct X {} - gStateRT.grammar.add((""" + gStateRT.grammar.add((&""" (struct_specifier|union_specifier (type_identifier) (field_declaration_list (field_declaration+ - (primitive_type|type_identifier?) - (sized_type_specifier? - (primitive_type?) - ) - (struct_specifier|union_specifier|enum_specifier? - (type_identifier) - ) - (field_identifier?) + {typeGrammar} + {fieldGrammar} (pointer_declarator? - (field_identifier?) - (array_declarator? - (field_identifier) - (identifier|number_literal) - ) - ) - (array_declarator? - (field_identifier) - (identifier|number_literal) + {fieldGrammar} ) ) ) @@ -130,34 +128,9 @@ proc initGrammar() = )) # typedef struct X {} - gStateRT.grammar.add((""" + gStateRT.grammar.add((&""" (type_definition - (struct_specifier|union_specifier - (type_identifier?) - (field_declaration_list - (field_declaration+ - (primitive_type|type_identifier?) - (sized_type_specifier? - (primitive_type?) - ) - (struct_specifier|union_specifier|enum_specifier? - (type_identifier) - ) - (field_identifier?) - (pointer_declarator? - (field_identifier?) - (array_declarator? - (field_identifier) - (identifier|number_literal) - ) - ) - (array_declarator? - (field_identifier) - (identifier|number_literal) - ) - ) - ) - ) + {gStateRT.grammar[^1].grammar} (type_identifier) ) """, @@ -231,20 +204,9 @@ proc initGrammar() = )) # typedef enum {} X - gStateRT.grammar.add((""" + gStateRT.grammar.add((&""" (type_definition - (enum_specifier - (type_identifier?) - (enumerator_list - (enumerator+ - (identifier) - (number_literal?) - (math_expression? - (number_literal) - ) - ) - ) - ) + {gStateRT.grammar[^1].grammar} (type_identifier) ) """, @@ -258,33 +220,13 @@ proc initGrammar() = pEnumCommon(ast, node, gStateRT.data[^1].val, offset, 1) )) - # typ function(typ param1, ...) - gStateRT.grammar.add((""" - (declaration - (storage_class_specifier?) - (type_qualifier?) - (primitive_type|type_identifier?) - (sized_type_specifier? - (primitive_type?) - ) - (struct_specifier|union_specifier? - (type_identifier) - ) + let funcGrammar = &""" (function_declarator? (identifier) (parameter_list (parameter_declaration* (type_qualifier?) - (primitive_type|type_identifier?) - (sized_type_specifier? - (primitive_type?) - ) - (struct_specifier|union_specifier? - (type_identifier) - ) - (enum_specifier? - (type_identifier) - ) + {typeGrammar} (identifier?) (pointer_declarator? (identifier) @@ -292,29 +234,17 @@ proc initGrammar() = ) ) ) + """ + + # typ function(typ param1, ...) + gStateRT.grammar.add((&""" + (declaration + (storage_class_specifier?) + (type_qualifier?) + {typeGrammar} + {funcGrammar} (pointer_declarator? - (function_declarator - (identifier) - (parameter_list - (parameter_declaration* - (type_qualifier?) - (primitive_type|type_identifier?) - (sized_type_specifier? - (primitive_type?) - ) - (struct_specifier|union_specifier? - (type_identifier) - ) - (enum_specifier? - (type_identifier) - ) - (identifier?) - (pointer_declarator? - (identifier) - ) - ) - ) - ) + {funcGrammar} ) ) """, From c7a3c7b7d606b00fa1c676e244c39002b8fc1609 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 27 Dec 2018 00:38:29 -0600 Subject: [PATCH 060/593] Fix typedef struct bug --- nimterop/grammar.nim | 42 +++++++++++++++++++++++++----------------- toast.nim | 13 ++++++++++--- 2 files changed, 35 insertions(+), 20 deletions(-) diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index aa364b1..bb789bc 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -100,27 +100,32 @@ proc initGrammar() = gStateRT.typeStr &= &" {fname}*: {ftyp}\n" i += 2 - let fieldGrammar = """ - (field_identifier?) - (array_declarator? - (field_identifier) - (identifier|number_literal) - ) - """ + let + fieldGrammar = """ + (field_identifier?) + (array_declarator? + (field_identifier) + (identifier|number_literal) + ) + """ + + fieldListGrammar = &""" + (field_declaration_list + (field_declaration+ + {typeGrammar} + {fieldGrammar} + (pointer_declarator? + {fieldGrammar} + ) + ) + ) + """ # struct X {} gStateRT.grammar.add((&""" (struct_specifier|union_specifier (type_identifier) - (field_declaration_list - (field_declaration+ - {typeGrammar} - {fieldGrammar} - (pointer_declarator? - {fieldGrammar} - ) - ) - ) + {fieldListGrammar} ) """, proc (ast: ref Ast, node: TSNode) = @@ -130,7 +135,10 @@ proc initGrammar() = # typedef struct X {} gStateRT.grammar.add((&""" (type_definition - {gStateRT.grammar[^1].grammar} + (struct_specifier|union_specifier + (type_identifier?) + {fieldListGrammar} + ) (type_identifier) ) """, diff --git a/toast.nim b/toast.nim index ced3047..f9edd89 100644 --- a/toast.nim +++ b/toast.nim @@ -4,7 +4,7 @@ import treesitter/runtime import treesitter_c/c import treesitter_cpp/cpp -import nimterop/[ast, globals, getters] +import nimterop/[ast, globals, getters, grammar] proc printLisp(root: TSNode) = var @@ -112,6 +112,7 @@ proc main( pnim = false, pretty = true, preprocess = false, + pgrammar = false, defines: seq[string] = @[], includeDirs: seq[string] = @[], source: seq[string], @@ -126,7 +127,11 @@ proc main( defines: defines, includeDirs: includeDirs, ) - if source.len != 0: + + if pgrammar: + parseGrammar() + printGrammar() + elif source.len != 0: process(source[0]) when isMainModule: @@ -138,11 +143,13 @@ when isMainModule: "defines": "definitions to pass to preprocessor", "includeDirs": "include directory to pass to preprocessor", "preprocess": "run preprocessor on header", + "pgrammar": "print grammar", "source" : "C/C++ source/header", }, short = { "past": 'a', "pnim": 'n', "defines": 'D', "includeDirs": 'I', - "preprocess": 'p' + "preprocess": 'p', + "pgrammar": 'g' }) From 21bd2d4112e5bf40d3fe52435cc15ccd5d4ad71a Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 27 Dec 2018 22:42:55 -0600 Subject: [PATCH 061/593] Struct field function pointers, cstring, show toast error in cimport --- nimterop/ast.nim | 33 +++++++++++++--------- nimterop/cimport.nim | 10 ++++++- nimterop/getters.nim | 14 +++++++++ nimterop/grammar.nim | 66 +++++++++++++++++++++++++++++++++++-------- tests/include/test.c | 6 ++++ tests/include/test.h | 9 +++++- tests/tnimterop_c.nim | 11 ++++++++ 7 files changed, 121 insertions(+), 28 deletions(-) diff --git a/nimterop/ast.nim b/nimterop/ast.nim index 4c8e253..ea50b1d 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -32,23 +32,28 @@ proc saveNodeData(node: TSNode): bool = if name in ["math_expression", "primitive_type", "sized_type_specifier"]: val = val.getType() - let - nparent = node.tsNodeParent() - if not nparent.tsNodeIsNull() and node.tsNodePrevNamedSibling().tsNodeIsNull(): - let - npname = nparent.tsNodeType() - npparent = nparent.tsNodeParent() - if npname == "pointer_declarator" or - ($npname in ["function_declarator", "array_declarator"] and - not npparent.tsNodeIsNull() and npparent.tsNodeType() == "pointer_declarator"): - - if gStateRT.data[^1].val != "object": - gStateRT.data[^1].val = "ptr " & gStateRT.data[^1].val.getIdentifier() - else: - gStateRT.data[^1].val = "pointer" + if node.tsNodePrevNamedSibling().tsNodeIsNull() and + ((node.isPName("pointer_declarator") and not node.isPPName("function_declarator")) or + (node.getPName() in ["function_declarator", "array_declarator"] and node.isPPName("pointer_declarator"))): + if gStateRT.data[^1].val != "object": + gStateRT.data[^1].val = "ptr " & gStateRT.data[^1].val.getIdentifier() + if gStateRT.data[^1].val == "ptr char": + gStateRT.data[^1].val = "cstring" + else: + gStateRT.data[^1].val = "pointer" gStateRT.data.add((name, val)) + if node.isPName("pointer_declarator") and node.isPPName("function_declarator"): + gStateRT.data.add(("function_declarator", "")) + + elif name in ["abstract_pointer_declarator"]: + gStateRT.data[^1].val = "ptr " & gStateRT.data[^1].val.getIdentifier() + if gStateRT.data[^1].val == "ptr char": + gStateRT.data[^1].val = "cstring" + elif name == "field_declaration": + gStateRT.data.add(("field_declaration", "")) + return true proc searchAstForNode(ast: ref Ast, node: TSNode): bool = diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index dd51166..2d29e6c 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -164,7 +164,15 @@ macro cImport*(filename: static string): untyped = echo "Importing " & fullpath - result.add parseStmt(getToast(fullpath)) + let + output = getToast(fullpath) + + try: + result.add parseStmt(output) + except: + echo output + echo "Failed to import generated nim" + result.add parseStmt(output) if gStateCT.debug: echo result.repr diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 7ce16bd..df1c3d7 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -191,3 +191,17 @@ proc getAstChildByName*(ast: ref Ast, name: string): ref Ast = for i in 0 .. ast.children.len-1: if name in ast.children[i].name.split("|"): return ast.children[i] + +proc getPName*(node: TSNode): string = + if not node.tsNodeIsNull(): + let + nparent = node.tsNodeParent() + if not nparent.tsNodeIsNull(): + return $nparent.tsNodeType() + +proc isPName*(node: TSNode, name: string): bool = + return node.getPName() == name + +proc isPPName*(node: TSNode, name: string): bool = + if node.getPName().len != 0: + return node.tsNodeParent().isPName(name) diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index bb789bc..b278872 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -25,6 +25,7 @@ proc initGrammar() = )) let typeGrammar = """ + (type_qualifier?) (primitive_type|type_identifier?) (sized_type_specifier? (primitive_type?) @@ -88,6 +89,10 @@ proc initGrammar() = var i = fstart while i < gStateRT.data.len-fend: + if gStateRT.data[i].name == "field_declaration": + i += 1 + continue + let ftyp = gStateRT.data[i].val.getIdentifier() fname = gStateRT.data[i+1].val.getIdentifier() @@ -96,17 +101,64 @@ proc initGrammar() = flen = gStateRT.data[i+2].val.getIdentifier() gStateRT.typeStr &= &" {fname}*: array[{flen}, {ftyp}]\n" i += 3 + elif i+2 < gStateRT.data.len-fend and gStateRT.data[i+2].name == "function_declarator": + var + pout, pname, ptyp = "" + count = 1 + + i += 3 + while i < gStateRT.data.len-fend: + if gStateRT.data[i].name == "field_declaration": + break + + ptyp = gStateRT.data[i].val.getIdentifier() + if gStateRT.data[i+1].name == "identifier": + pname = gStateRT.data[i+1].val.getIdentifier() + i += 2 + else: + pname = "a" & $count + count += 1 + i += 1 + if ptyp != "object": + pout &= &"{pname}: {ptyp}," + + if pout.len != 0 and pout[^1] == ',': + pout = pout[0 .. ^2] + if ftyp != "object": + gStateRT.typeStr &= &" {fname}*: proc({pout}): {ftyp} {{.nimcall.}}\n" + else: + gStateRT.typeStr &= &" {fname}*: proc({pout}) {{.nimcall.}}\n" + i += 1 else: gStateRT.typeStr &= &" {fname}*: {ftyp}\n" i += 2 let - fieldGrammar = """ + paramListGrammar = &""" + (parameter_list + (parameter_declaration* + {typeGrammar} + (identifier?) + (pointer_declarator? + (identifier) + ) + (abstract_pointer_declarator?) + ) + ) + """ + + fieldGrammar = &""" (field_identifier?) (array_declarator? (field_identifier) (identifier|number_literal) ) + (function_declarator? + (pointer_declarator + (field_identifier) + ) + {paramListGrammar} + ) """ fieldListGrammar = &""" @@ -231,16 +283,7 @@ proc initGrammar() = let funcGrammar = &""" (function_declarator? (identifier) - (parameter_list - (parameter_declaration* - (type_qualifier?) - {typeGrammar} - (identifier?) - (pointer_declarator? - (identifier) - ) - ) - ) + {paramListGrammar} ) """ @@ -248,7 +291,6 @@ proc initGrammar() = gStateRT.grammar.add((&""" (declaration (storage_class_specifier?) - (type_qualifier?) {typeGrammar} {funcGrammar} (pointer_declarator? diff --git a/tests/include/test.c b/tests/include/test.c index d63c974..3a59ffc 100644 --- a/tests/include/test.c +++ b/tests/include/test.c @@ -48,4 +48,10 @@ unsigned char test_call_param6(UNION2 param1) { int test_call_param7(union UNION1 param1) { return param1.field1; +} + +float test_call_param8(int *param1) { + *param1 = 5 * *param1; + + return 1.0 * *param1; } \ No newline at end of file diff --git a/tests/include/test.h b/tests/include/test.h index e040d7f..29181c5 100644 --- a/tests/include/test.h +++ b/tests/include/test.h @@ -52,6 +52,12 @@ typedef struct { ENUM4 *field5[TEST_INT]; } STRUCT4; +typedef struct STRUCT5 { + int (*tci)(); + struct STRUCT1 (*tcp)(int); + float (*tcp8)(int *i); +} STRUCT5; + union UNION1 { int field1; float field2; @@ -69,4 +75,5 @@ STRUCT2 test_call_param3(int param1, struct STRUCT1 param2); ENUM2 test_call_param4(enum ENUM param1); union UNION1 test_call_param5(float param1); unsigned char test_call_param6(UNION2 param1); -int test_call_param7(union UNION1 param1); \ No newline at end of file +int test_call_param7(union UNION1 param1); +float test_call_param8(int *param1); \ No newline at end of file diff --git a/tests/tnimterop_c.nim b/tests/tnimterop_c.nim index deef7d2..69f8105 100644 --- a/tests/tnimterop_c.nim +++ b/tests/tnimterop_c.nim @@ -21,6 +21,7 @@ var s2: STRUCT2 s3: STRUCT3 s4: STRUCT4 + s5: STRUCT5 e: ENUM e2: ENUM2 = enum5 @@ -33,6 +34,8 @@ var u: UNION1 u2: UNION2 + i: int + pt = 3 ct = 4 @@ -41,12 +44,18 @@ s2.field1 = 6 s3.field1 = 7 s4.field2[2] = 5 s4.field3[3] = enum1 +s5.tci = test_call_int +s5.tcp = test_call_param +s5.tcp8 = test_call_param8 +check s5.tci() == 5 e = enum1 e2 = enum4 u2.field2 = 'c' +i = 5 + check test_call_int() == 5 check test_call_param(5).field1 == 5 check test_call_param2(5, s2).field1 == 11 @@ -56,6 +65,8 @@ check test_call_param5(5.0).field2 == 5.0 check test_call_param6(u2) == 'c' u.field1 = 4 check test_call_param7(u) == 4 +check test_call_param8(addr i) == 25.0 +check i == 25 check e3 == enum7 check e4 == enum11 From e2430cf40c95d33c2987c21c76557d444bca0d27 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 27 Dec 2018 23:38:02 -0600 Subject: [PATCH 062/593] Fix #15, fix #20 --- nimterop.nimble | 1 + nimterop/getters.nim | 3 ++- tests/include/test.h | 10 +++++++++- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/nimterop.nimble b/nimterop.nimble index b1ee584..c3c87a7 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -18,6 +18,7 @@ proc execCmd(cmd:string)= task test, "Test": execCmd "nim c -r tests/tnimterop_c.nim" + execCmd "nim cpp -r tests/tnimterop_c.nim" execCmd "nim cpp -r tests/tnimterop_cpp.nim" # when defined(windows): # execCmd "nim c -r tests/tmath.nim" diff --git a/nimterop/getters.nim b/nimterop/getters.nim index df1c3d7..1ff4d49 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -95,10 +95,11 @@ proc getCurrentHeader*(fullpath: string): string = proc getGccPaths*(mode = "c"): string = var + ret = 0 nul = when defined(Windows): "nul" else: "/dev/null" mmode = if mode == "cpp": "c++" else: mode - return staticExec("gcc -Wp,-v -x" & mmode & " " & nul) + (result, ret) = gorgeEx("gcc -Wp,-v -x" & mmode & " " & nul) proc getPreprocessor*(fullpath: string, mode = "cpp"): string = var diff --git a/tests/include/test.h b/tests/include/test.h index 29181c5..6a3d9a4 100644 --- a/tests/include/test.h +++ b/tests/include/test.h @@ -1,3 +1,7 @@ +#ifdef __cplusplus +extern "C" { +#endif + #include #define TEST_INT 512 @@ -76,4 +80,8 @@ ENUM2 test_call_param4(enum ENUM param1); union UNION1 test_call_param5(float param1); unsigned char test_call_param6(UNION2 param1); int test_call_param7(union UNION1 param1); -float test_call_param8(int *param1); \ No newline at end of file +float test_call_param8(int *param1); + +#ifdef __cplusplus +} +#endif \ No newline at end of file From 1e086d59595c24ee8ec3f1dcc02b55d97fe9e2ec Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Fri, 28 Dec 2018 00:33:09 -0600 Subject: [PATCH 063/593] Implement PR #17 --- nimterop.nimble | 2 +- tests/include/test.h | 12 ++++++++++++ tests/tnimterop_c.nim | 9 ++++++++- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/nimterop.nimble b/nimterop.nimble index c3c87a7..13bafae 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -18,7 +18,7 @@ proc execCmd(cmd:string)= task test, "Test": execCmd "nim c -r tests/tnimterop_c.nim" - execCmd "nim cpp -r tests/tnimterop_c.nim" + #execCmd "nim cpp -r tests/tnimterop_c.nim" execCmd "nim cpp -r tests/tnimterop_cpp.nim" # when defined(windows): # execCmd "nim c -r tests/tmath.nim" diff --git a/tests/include/test.h b/tests/include/test.h index 6a3d9a4..741fa97 100644 --- a/tests/include/test.h +++ b/tests/include/test.h @@ -8,6 +8,18 @@ extern "C" { #define TEST_FLOAT 5.12 #define TEST_HEX 0x512 +#ifdef __APPLE__ +#define OSDEF 10 +#endif + +#ifdef _WIN32 +#define OSDEF 20 +#endif + +#ifdef __linux__ +#define OSDEF 30 +#endif + typedef uint8_t PRIMTYPE; typedef PRIMTYPE CUSTTYPE; diff --git a/tests/tnimterop_c.nim b/tests/tnimterop_c.nim index 69f8105..74e1afa 100644 --- a/tests/tnimterop_c.nim +++ b/tests/tnimterop_c.nim @@ -13,6 +13,13 @@ check TEST_INT == 512 check TEST_FLOAT == 5.12 check TEST_HEX == 0x512 +when defined(osx): + check OSDEF == 10 +elif defined(windows): + check OSDEF == 20 +else: + check OSDEF == 30 + var pt: PRIMTYPE ct: CUSTTYPE @@ -34,7 +41,7 @@ var u: UNION1 u2: UNION2 - i: int + i: cint pt = 3 ct = 4 From 9f7d2ca95637e6026336c9b1e264b321784737f4 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Sat, 29 Dec 2018 14:02:04 -0800 Subject: [PATCH 064/593] add failing tests; add a test at CT --- nimterop.nimble | 2 +- tests/include/test.h | 3 +++ tests/tnimterop_c.nim | 11 +++++++++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/nimterop.nimble b/nimterop.nimble index 13bafae..0510abf 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -18,7 +18,7 @@ proc execCmd(cmd:string)= task test, "Test": execCmd "nim c -r tests/tnimterop_c.nim" - #execCmd "nim cpp -r tests/tnimterop_c.nim" + # execCmd "nim cpp -r tests/tnimterop_c.nim" execCmd "nim cpp -r tests/tnimterop_cpp.nim" # when defined(windows): # execCmd "nim c -r tests/tmath.nim" diff --git a/tests/include/test.h b/tests/include/test.h index 741fa97..8a8c579 100644 --- a/tests/include/test.h +++ b/tests/include/test.h @@ -20,6 +20,9 @@ extern "C" { #define OSDEF 30 #endif +#define foobar1(x) OSDEF * x +#define foobar2(x) x + 1 + typedef uint8_t PRIMTYPE; typedef PRIMTYPE CUSTTYPE; diff --git a/tests/tnimterop_c.nim b/tests/tnimterop_c.nim index 74e1afa..1fd92b5 100644 --- a/tests/tnimterop_c.nim +++ b/tests/tnimterop_c.nim @@ -20,6 +20,10 @@ elif defined(windows): else: check OSDEF == 30 +block: + # workaround for https://github.com/nim-lang/Nim/issues/10129 + const ok = OSDEF + var pt: PRIMTYPE ct: CUSTTYPE @@ -79,3 +83,10 @@ check e3 == enum7 check e4 == enum11 cAddStdDir() + +## failing tests +when false: + static: # Error: undeclared identifier: 'foobar1' + doAssert foobar1(3) == OSDEF * 3 +when false: # Error: undeclared identifier: 'foobar2' + doAssert foobar2(3) == 3 + 1 From 6cc1e66ee20d081403faeacb10761a33747ea64f Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Sat, 29 Dec 2018 14:49:01 -0800 Subject: [PATCH 065/593] fix #15 by re-enabling nim cpp on c file and selectively disabling failing things --- nimterop.nimble | 2 +- tests/tnimterop_c.nim | 23 +++++++++++++++++++---- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/nimterop.nimble b/nimterop.nimble index 0510abf..c3c87a7 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -18,7 +18,7 @@ proc execCmd(cmd:string)= task test, "Test": execCmd "nim c -r tests/tnimterop_c.nim" - # execCmd "nim cpp -r tests/tnimterop_c.nim" + execCmd "nim cpp -r tests/tnimterop_c.nim" execCmd "nim cpp -r tests/tnimterop_cpp.nim" # when defined(windows): # execCmd "nim c -r tests/tmath.nim" diff --git a/tests/tnimterop_c.nim b/tests/tnimterop_c.nim index 1fd92b5..0f53556 100644 --- a/tests/tnimterop_c.nim +++ b/tests/tnimterop_c.nim @@ -54,7 +54,11 @@ s.field1 = 5 s2.field1 = 6 s3.field1 = 7 s4.field2[2] = 5 -s4.field3[3] = enum1 +when defined(cpp): + discard # TODO +else: # TODO: what's `defined(cpp)` for c ? + s4.field3[3] = enum1 + s5.tci = test_call_int s5.tcp = test_call_param s5.tcp8 = test_call_param8 @@ -71,13 +75,24 @@ check test_call_int() == 5 check test_call_param(5).field1 == 5 check test_call_param2(5, s2).field1 == 11 check test_call_param3(5, s).field1 == 10 -check test_call_param4(e) == e2 +# error: assigning to 'enum ENUM' from incompatible type 'NI' (aka 'long long') +when defined(cpp): + discard # TODO +else: + check test_call_param4(e) == e2 check test_call_param5(5.0).field2 == 5.0 check test_call_param6(u2) == 'c' u.field1 = 4 check test_call_param7(u) == 4 -check test_call_param8(addr i) == 25.0 -check i == 25 + +when defined(cpp): + # TODO + # note: candidate function not viable: no known conversion from 'NI *' (aka 'long long *') to 'int *' for 1st argument + # check test_call_param8(cast[ptr int](addr i)) == 25.0 + discard +else: + check test_call_param8(addr i) == 25.0 + check i == 25 check e3 == enum7 check e4 == enum11 From 48ae6bad7dc004242e25c684acd6df40ff450926 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 31 Dec 2018 12:35:49 -0600 Subject: [PATCH 066/593] Update appveyor to 0.19.2 --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index b4bbcd9..d10a96e 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -9,7 +9,7 @@ matrix: environment: matrix: - - NIM_VERSION: 0.19.0 + - NIM_VERSION: 0.19.2 for: - From d21017ac5bfade2194a50952e40257e80bd018dd Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 9 Jan 2019 14:18:31 -0600 Subject: [PATCH 067/593] Support for nameless function params, unused enums --- nimterop/grammar.nim | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index b278872..9abbf87 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -60,6 +60,18 @@ proc initGrammar() = gStateRT.typeStr &= &" {name}* = {typ}\n" )) + template funcParamCommon(pname, ptyp, pout, count, i: untyped): untyped = + ptyp = gStateRT.data[i].val.getIdentifier() + if i+1 < gStateRT.data.len and gStateRT.data[i+1].name == "identifier": + pname = gStateRT.data[i+1].val.getIdentifier() + i += 2 + else: + pname = "a" & $count + count += 1 + i += 1 + if ptyp != "object": + pout &= &"{pname}: {ptyp}," + proc pStructCommon(ast: ref Ast, node: TSNode, name: string, fstart, fend: int) = var nname = name.getIdentifier() @@ -111,16 +123,7 @@ proc initGrammar() = if gStateRT.data[i].name == "field_declaration": break - ptyp = gStateRT.data[i].val.getIdentifier() - if gStateRT.data[i+1].name == "identifier": - pname = gStateRT.data[i+1].val.getIdentifier() - i += 2 - else: - pname = "a" & $count - count += 1 - i += 1 - if ptyp != "object": - pout &= &"{pname}: {ptyp}," + funcParamCommon(pname, ptyp, pout, count, i) if pout.len != 0 and pout[^1] == ',': pout = pout[0 .. ^2] @@ -214,7 +217,7 @@ proc initGrammar() = if nname notin gStateRT.enums: gStateRT.enums.add(nname) gStateRT.enumStr &= &"\ntype {nname}* = distinct int" - gStateRT.enumStr &= &"\nconverter enumToInt(en: {nname}): int = en.int\n" + gStateRT.enumStr &= &"\nconverter enumToInt(en: {nname}): int {{.used.}} = en.int\n" var i = fstart @@ -306,15 +309,14 @@ proc initGrammar() = if fnname notin gStateRT.procs: var - pout = "" + pout, pname, ptyp = "" i = 2 + count = 1 + if gStateRT.data.len > 2: - while i < gStateRT.data.len-1: - let - ptyp = gStateRT.data[i].val.getIdentifier() - pname = gStateRT.data[i+1].val.getIdentifier() - pout &= &"{pname}: {ptyp}," - i += 2 + while i < gStateRT.data.len: + funcParamCommon(pname, ptyp, pout, count, i) + if pout.len != 0 and pout[^1] == ',': pout = pout[0 .. ^2] From 4d57be55ac5e0be8870bd7479e08448a079da2be Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 9 Jan 2019 17:08:04 -0600 Subject: [PATCH 068/593] Support for multiple functions in declarator, size_t fixes --- nimterop/ast.nim | 4 ++-- nimterop/getters.nim | 2 ++ nimterop/grammar.nim | 45 ++++++++++++++++++++++++++++++-------------- 3 files changed, 35 insertions(+), 16 deletions(-) diff --git a/nimterop/ast.nim b/nimterop/ast.nim index ea50b1d..5f6ad8d 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -51,8 +51,8 @@ proc saveNodeData(node: TSNode): bool = gStateRT.data[^1].val = "ptr " & gStateRT.data[^1].val.getIdentifier() if gStateRT.data[^1].val == "ptr char": gStateRT.data[^1].val = "cstring" - elif name == "field_declaration": - gStateRT.data.add(("field_declaration", "")) + elif name in ["field_declaration", "function_declarator"]: + gStateRT.data.add((name, "")) return true diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 1ff4d49..db15991 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -56,6 +56,8 @@ proc getType*(str: string): string = ("unsigned ", "cu"), ("double ", "cdouble"), ("long ", "clong"), + ("ssize_t", "int"), + ("size_t", "uint") ]). replace(re"([u]?int[\d]+)_t", "$1"). replace(re"([u]?int)ptr_t", "ptr $1") diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index 9abbf87..ef5cbb4 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -120,6 +120,10 @@ proc initGrammar() = i += 3 while i < gStateRT.data.len-fend: + if gStateRT.data[i].name == "function_declarator": + i += 1 + continue + if gStateRT.data[i].name == "field_declaration": break @@ -284,7 +288,7 @@ proc initGrammar() = )) let funcGrammar = &""" - (function_declarator? + (function_declarator* (identifier) {paramListGrammar} ) @@ -296,7 +300,11 @@ proc initGrammar() = (storage_class_specifier?) {typeGrammar} {funcGrammar} - (pointer_declarator? + (pointer_declarator* + {funcGrammar} + ) + {funcGrammar} + (pointer_declarator* {funcGrammar} ) ) @@ -304,27 +312,36 @@ proc initGrammar() = proc (ast: ref Ast, node: TSNode) = let ftyp = gStateRT.data[0].val.getIdentifier() - fname = gStateRT.data[1].val - fnname = fname.getIdentifier() - if fnname notin gStateRT.procs: + var + i = 1 + while i < gStateRT.data.len: + if gStateRT.data[i].name == "function_declarator": + i += 1 + continue + var + fname = gStateRT.data[i].val + fnname = fname.getIdentifier() pout, pname, ptyp = "" - i = 2 count = 1 - if gStateRT.data.len > 2: - while i < gStateRT.data.len: - funcParamCommon(pname, ptyp, pout, count, i) + i += 1 + while i < gStateRT.data.len: + if gStateRT.data[i].name == "function_declarator": + break + + funcParamCommon(pname, ptyp, pout, count, i) if pout.len != 0 and pout[^1] == ',': pout = pout[0 .. ^2] - gStateRT.procs.add(fnname) - if ftyp != "object": - gStateRT.procStr &= &"proc {fnname}({pout}): {ftyp} {{.importc: \"{fname}\", header: {gStateRT.currentHeader}.}}\n" - else: - gStateRT.procStr &= &"proc {fnname}({pout}) {{.importc: \"{fname}\", header: {gStateRT.currentHeader}.}}\n" + if fnname notin gStateRT.procs: + gStateRT.procs.add(fnname) + if ftyp != "object": + gStateRT.procStr &= &"proc {fnname}({pout}): {ftyp} {{.importc: \"{fname}\", header: {gStateRT.currentHeader}.}}\n" + else: + gStateRT.procStr &= &"proc {fnname}({pout}) {{.importc: \"{fname}\", header: {gStateRT.currentHeader}.}}\n" )) From 51ae21f8d5240a670e1bc8e94d92dfd833ea864b Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 10 Jan 2019 10:25:19 -0600 Subject: [PATCH 069/593] Export enums and procs --- nimterop/grammar.nim | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index ef5cbb4..f5c0237 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -232,14 +232,14 @@ proc initGrammar() = if fname notin gStateRT.consts: if i+1 < gStateRT.data.len-fend and gStateRT.data[i+1].name in ["math_expression", "number_literal"]: - gStateRT.constStr &= &" {fname} = {gStateRT.data[i+1].val}.{nname}\n" + gStateRT.constStr &= &" {fname}* = {gStateRT.data[i+1].val}.{nname}\n" try: count = gStateRT.data[i+1].val.parseInt() + 1 except: count += 1 i += 2 else: - gStateRT.constStr &= &" {fname} = {count}.{nname}\n" + gStateRT.constStr &= &" {fname}* = {count}.{nname}\n" i += 1 count += 1 @@ -339,9 +339,9 @@ proc initGrammar() = if fnname notin gStateRT.procs: gStateRT.procs.add(fnname) if ftyp != "object": - gStateRT.procStr &= &"proc {fnname}({pout}): {ftyp} {{.importc: \"{fname}\", header: {gStateRT.currentHeader}.}}\n" + gStateRT.procStr &= &"proc {fnname}*({pout}): {ftyp} {{.importc: \"{fname}\", header: {gStateRT.currentHeader}.}}\n" else: - gStateRT.procStr &= &"proc {fnname}({pout}) {{.importc: \"{fname}\", header: {gStateRT.currentHeader}.}}\n" + gStateRT.procStr &= &"proc {fnname}*({pout}) {{.importc: \"{fname}\", header: {gStateRT.currentHeader}.}}\n" )) From ac7231a882b5cd0d30110bae74480314d4ded939 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 10 Jan 2019 11:25:29 -0600 Subject: [PATCH 070/593] Fix cuclonglong issue #32 --- nimterop/getters.nim | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/nimterop/getters.nim b/nimterop/getters.nim index db15991..b4eb13b 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -1,4 +1,4 @@ -import macros, os, strformat, strutils +import macros, os, strformat, strutils, tables import regex @@ -28,6 +28,25 @@ when while xor yield""".split(Whitespace) +const gTypeMap = { + "long": "clong", + "unsigned long": "culong", + "char": "cchar", + "signed char": "cschar", + "short": "cshort", + "int": "cint", + "size_t": "uint", + "ssize_t": "int", + "long long": "clonglong", + "float": "cfloat", + "double": "cdouble", + "long double": "clongdouble", + "unsigned char": "cuchar", + "unsigned short": "cushort", + "unsigned int": "cuint", + "unsigned long long": "culonglong" +}.toTable() + proc sanitizePath*(path: string): string = path.multiReplace([("\\\\", $DirSep), ("\\", $DirSep), ("//", $DirSep)]) @@ -52,21 +71,11 @@ proc getType*(str: string): string = return "object" result = str.strip(chars={'_'}). - multiReplace([ - ("unsigned ", "cu"), - ("double ", "cdouble"), - ("long ", "clong"), - ("ssize_t", "int"), - ("size_t", "uint") - ]). replace(re"([u]?int[\d]+)_t", "$1"). replace(re"([u]?int)ptr_t", "ptr $1") - case result: - of "long": - result = "clong" - of "double": - result = "cdouble" + if gTypeMap.hasKey(result): + result = gTypeMap[result] proc getLit*(str: string): string = if str.contains(re"^[\-]?[\d]+$") or From c65c566e09faf11f374429e3dbe573cc09f5aba9 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 10 Jan 2019 13:07:55 -0600 Subject: [PATCH 071/593] Filter out gcc attributes --- nimterop/getters.nim | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/nimterop/getters.nim b/nimterop/getters.nim index b4eb13b..4d217a7 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -141,10 +141,7 @@ proc getPreprocessor*(fullpath: string, mode = "cpp"): string = else: if start: rdata.add( - line.multiReplace([("_Noreturn", ""), ("(())", ""), ("WINAPI", ""), - ("__attribute__", ""), ("extern \"C\"", "")]) - .replace(re"\(\([_a-z]+?\)\)", "") - .replace(re"\(\(__format__[\s]*\(__[gnu_]*printf__, [\d]+, [\d]+\)\)\);", ";") + line.replace(re"__attribute__[ ]*\(\(.*?\)\) ", "") ) return rdata.join("\n") From 88005fa9841ca74c25cc54699ee7b0968dd495ef Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Fri, 11 Jan 2019 12:22:49 -0600 Subject: [PATCH 072/593] #include file, static line, nostderr, improve preprocessing --- README.md | 14 ++++++-------- nimterop/cimport.nim | 9 ++++++--- nimterop/getters.nim | 42 ++++++++++++++++++++++++++++++++++++------ nimterop/git.nim | 9 ++++++--- nimterop/globals.nim | 2 +- toast.nim | 4 ++++ 6 files changed, 59 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 5bb725f..cc51f4e 100644 --- a/README.md +++ b/README.md @@ -12,16 +12,10 @@ The goal of nimterop is to leverage the [tree-sitter](http://tree-sitter.github. Most of the functionality is contained within the `toast` binary that is built when nimterop is installed and can be used standalone similar to how c2nim can be used today. In addition, nimterop also offers an API to pull in the generated Nim content directly into an application. -The nimterop feature set is still limited when compared with c2nim. Supported language constructs include: -- `#define NAME VALUE` where `VALUE` is a number (int, float, hex) -- `struct X`, `typedef struct`, `enum X`, `typedef enum`, `union X`, `typedef union` -- Functions with primitive types, structs, enums, unions and typedef structs/enums/unions as params and return values -- Pointers to data types +The nimterop feature set is still limited to C but is expanding rapidly. C++ support will be added once most popular C libraries can be wrapped seamlessly. Given the simplicity and success of this approach so far, it seems feasible to continue on for more complex code. The goal is to make interop seamless so nimterop will focus on wrapping headers and not the outright conversion of C/C++ implementation. -C++ constructs such as classes and templats are still TBD depending on the results of the C interop. - __Installation__ Nimterop can be installed via [Nimble](https://github.com/nim-lang/nimble): @@ -71,6 +65,8 @@ Detailed documentation is still forthcoming. `cImport("header.h")` - import all supported definitions from header file +`cImport("header.h", recurse=true)` - import all supported definitions from header file and #includes + `cAddSearchDir("XXX")` - add directory XXX to search path in calls to `cSearchPath()` `cAddStdDir("XXX")` - add standard "c" [default] or "cpp" include paths to search path @@ -81,10 +77,12 @@ Detailed documentation is still forthcoming. __Implementation Details__ -In order to use the tree-sitter C library at compile-time, it has to be compiled into a separate binary called `toast` (to AST) since the Nim VM doesn't yet support FFI. `toast` takes a C/C++ file and runs it through the tree-sitter API which returns an AST data structure. This can then be printed out to stdout in a Lisp S-Expression format or the relevant Nim wrapper output. This content can be saved to a `.nim` file and imported if so desired. +In order to use the tree-sitter C library, it has to be compiled into a separate binary called `toast` (to AST) since the Nim VM doesn't yet support FFI. `toast` takes a C/C++ file and runs it through the tree-sitter API which returns an AST data structure. This can then be printed out to stdout in a Lisp S-Expression format or the relevant Nim wrapper output. This content can be saved to a `.nim` file and imported if so desired. Alternatively, the `cImport()` macro allows easier creation of wrappers in code. It runs `toast` on the specified header file and injects the generated wrapper content into the application at compile time. A few other helper procs are provided to influence this process. +`toast` can also be used to run the header through the preprocessor which cleans up the code considerably. Along with the recursion capability which runs through all #include files, one large simpler header file can be created which can then be processed with c2nim if so desired. + The tree-sitter library is limited as well - it may fail on some advanced language constructs but is designed to handle them gracefully since it is expected to have bad code while actively typing in an editor. When an error is detected, tree-sitter includes an ERROR node at that location in the AST. At this time, `cImport()` will complain and continue if it encounters any errors. Depending on how severe the errors are, compilation may succeed or fail. Glaring issues will be communicated to the tree-sitter team but their goals may not always align with those of this project. __Credits__ diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index 2d29e6c..5b8935b 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -21,12 +21,15 @@ proc findPath(path: string, fail = true): string = else: return "" -proc getToast(fullpath: string): string = +proc getToast(fullpath: string, recurse: bool = false): string = var cmd = when defined(Windows): "cmd /c " else: "" cmd &= "toast --pnim --preprocess " + if recurse: + cmd.add "--recurse " + for i in gStateCT.defines: cmd.add &"--defines+={i.quoteShell} " @@ -156,7 +159,7 @@ macro cCompile*(path: static string): untyped = if gStateCT.debug: echo result.repr -macro cImport*(filename: static string): untyped = +macro cImport*(filename: static string, recurse: static bool = false): untyped = result = newNimNode(nnkStmtList) let @@ -165,7 +168,7 @@ macro cImport*(filename: static string): untyped = echo "Importing " & fullpath let - output = getToast(fullpath) + output = getToast(fullpath, recurse) try: result.add parseStmt(output) diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 4d217a7..d0fa49c 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -112,6 +112,20 @@ proc getGccPaths*(mode = "c"): string = (result, ret) = gorgeEx("gcc -Wp,-v -x" & mmode & " " & nul) +proc removeStatic*(content: string): string = + ## Replace static function bodies with a semicolon and commented + ## out body + return content.replace( + re"(?ms)static inline(.*?\))(\s*\{(\s*?.*?$)*?[\n\r]\})", + proc (m: RegexMatch, s: string): string = + let funcDecl = s[m.group(0)[0]] + let body = s[m.group(1)[0]].strip() + result = "" + + result.add("$#;" % [funcDecl]) + result.add(body.replace(re"(?m)^(.*\n?)", "//$1")) + ) + proc getPreprocessor*(fullpath: string, mode = "cpp"): string = var mmode = if mode == "cpp": "c++" else: mode @@ -130,20 +144,36 @@ proc getPreprocessor*(fullpath: string, mode = "cpp"): string = cmd &= &"\"{fullpath}\"" # Include content only from file - for line in execAction(cmd).splitLines(): + for line in execAction(cmd, true).splitLines(): if line.strip() != "": - if line[0] == '#' and not line.contains("#pragma") and not line.contains("define"): + if line.len > 1 and line[0 .. 1] == "# ": start = false - if sfile in line.sanitizePath: + let + saniLine = line.sanitizePath + if sfile in saniLine: start = true - if not ("\\" in line) and not ("/" in line) and extractFilename(sfile) in line: + elif not ("\\" in line) and not ("/" in line) and extractFilename(sfile) in line: start = true + elif gStateRT.recurse: + if sfile.parentDir() in saniLine: + start = true + else: + for inc in gStateRT.includeDirs: + if inc.absolutePath().sanitizePath in saniLine: + start = true + break + if start: + rdata.add(&"// {line}") else: if start: + if "#undef" in line: + continue rdata.add( - line.replace(re"__attribute__[ ]*\(\(.*?\)\) ", "") + line. + replace("__restrict", ""). + replace(re"__attribute__[ ]*\(\(.*?\)\)([ ,;])", "$1") ) - return rdata.join("\n") + return rdata.join("\n").removeStatic() converter toString*(kind: Kind): string = return case kind: diff --git a/nimterop/git.nim b/nimterop/git.nim index 51ea756..f4412ce 100644 --- a/nimterop/git.nim +++ b/nimterop/git.nim @@ -2,7 +2,7 @@ import macros, os, osproc, regex, strformat, strutils import globals -proc execAction*(cmd: string): string = +proc execAction*(cmd: string, nostderr=false): string = var ccmd = "" ret = 0 @@ -14,7 +14,10 @@ proc execAction*(cmd: string): string = when nimvm: (result, ret) = gorgeEx(ccmd) else: - (result, ret) = execCmdEx(ccmd) + if nostderr: + (result, ret) = execCmdEx(ccmd, {poUsePath}) + else: + (result, ret) = execCmdEx(ccmd) if ret != 0: echo "Command failed: " & $ret echo ccmd @@ -66,7 +69,7 @@ macro gitCheckout*(file, outdir: static string): untyped = macro gitPull*(url: static string, outdirN = "", plistN = "", checkoutN = ""): untyped = let - outdir = getProjectPath()/outdirN.strVal() + outdir = if outdirN.strVal().isAbsolute(): outdirN.strVal() else: getProjectPath()/outdirN.strVal() plist = plistN.strVal() checkout = checkoutN.strVal() diff --git a/nimterop/globals.nim b/nimterop/globals.nim index 771987e..7b2375c 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -21,7 +21,7 @@ type State* = object compile*, defines*, headers*, includeDirs*, searchDirs*: seq[string] - debug*, past*, preprocess*, pnim*, pretty*: bool + debug*, past*, preprocess*, pnim*, pretty*, recurse*: bool consts*, enums*, procs*, types*: seq[string] diff --git a/toast.nim b/toast.nim index f9edd89..d4a40c9 100644 --- a/toast.nim +++ b/toast.nim @@ -113,6 +113,7 @@ proc main( pretty = true, preprocess = false, pgrammar = false, + recurse = false, defines: seq[string] = @[], includeDirs: seq[string] = @[], source: seq[string], @@ -124,6 +125,7 @@ proc main( pnim: pnim, pretty: pretty, preprocess: preprocess, + recurse: recurse, defines: defines, includeDirs: includeDirs, ) @@ -144,6 +146,7 @@ when isMainModule: "includeDirs": "include directory to pass to preprocessor", "preprocess": "run preprocessor on header", "pgrammar": "print grammar", + "recurse": "process #include files", "source" : "C/C++ source/header", }, short = { "past": 'a', @@ -151,5 +154,6 @@ when isMainModule: "defines": 'D', "includeDirs": 'I', "preprocess": 'p', + "recurse": 'r', "pgrammar": 'g' }) From bc282938125fbb60ce04338d9d276cca18dd2aaa Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Fri, 11 Jan 2019 13:00:03 -0600 Subject: [PATCH 073/593] Shift/math expressions in enum --- nimterop/ast.nim | 3 ++- nimterop/getters.nim | 2 +- nimterop/grammar.nim | 13 ++++++++++--- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/nimterop/ast.nim b/nimterop/ast.nim index 5f6ad8d..df3f626 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -9,6 +9,7 @@ import "."/[getters, globals, grammar] const gAtoms = @[ "field_identifier", "identifier", + "shift_expression", "math_expression", "number_literal", "preproc_arg", @@ -26,7 +27,7 @@ proc saveNodeData(node: TSNode): bool = if name == "primitive_type" and node.tsNodeParent.tsNodeType() == "sized_type_specifier": return true - if name == "number_literal" and node.tsNodeParent.tsNodeType() == "math_expression": + if name == "number_literal" and $node.tsNodeParent.tsNodeType() in ["shift_expression", "math_expression"]: return true if name in ["math_expression", "primitive_type", "sized_type_specifier"]: diff --git a/nimterop/getters.nim b/nimterop/getters.nim index d0fa49c..77243f6 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -51,7 +51,7 @@ proc sanitizePath*(path: string): string = path.multiReplace([("\\\\", $DirSep), ("\\", $DirSep), ("//", $DirSep)]) proc getIdentifier*(str: string): string = - result = str.strip(chars={'_'}) + result = str.strip(chars={'_'}).replace(re"_+", "_") if result in gReserved: result = &"`{result}`" diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index f5c0237..13fab13 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -231,7 +231,14 @@ proc initGrammar() = fname = gStateRT.data[i].val.getIdentifier() if fname notin gStateRT.consts: - if i+1 < gStateRT.data.len-fend and gStateRT.data[i+1].name in ["math_expression", "number_literal"]: + if i+1 < gStateRT.data.len-fend and + gStateRT.data[i+1].name in ["shift_expression", "math_expression", "number_literal"]: + if " " in gStateRT.data[i+1].val: + gStateRT.data[i+1].val = "(" & gStateRT.data[i+1].val.replace(" ", "") & ")" + gStateRT.data[i+1].val = gStateRT.data[i+1].val.multiReplace([ + ("<<", " shl "), (">>", " shr ") + ]) + gStateRT.constStr &= &" {fname}* = {gStateRT.data[i+1].val}.{nname}\n" try: count = gStateRT.data[i+1].val.parseInt() + 1 @@ -251,8 +258,8 @@ proc initGrammar() = (enumerator+ (identifier) (number_literal?) - (math_expression? - (number_literal) + (shift_expression|math_expression? + (number_literal+) ) ) ) From a1d920bc6ab1b9b398dac9b8cf3b02c226cb2512 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Fri, 11 Jan 2019 19:36:38 -0600 Subject: [PATCH 074/593] orWithNext, pointer cleanup --- nimterop/ast.nim | 7 +-- nimterop/getters.nim | 11 ++++- nimterop/globals.nim | 1 + nimterop/grammar.nim | 111 ++++++++++++++++++++++++++++--------------- 4 files changed, 84 insertions(+), 46 deletions(-) diff --git a/nimterop/ast.nim b/nimterop/ast.nim index df3f626..35817a2 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -36,12 +36,7 @@ proc saveNodeData(node: TSNode): bool = if node.tsNodePrevNamedSibling().tsNodeIsNull() and ((node.isPName("pointer_declarator") and not node.isPPName("function_declarator")) or (node.getPName() in ["function_declarator", "array_declarator"] and node.isPPName("pointer_declarator"))): - if gStateRT.data[^1].val != "object": - gStateRT.data[^1].val = "ptr " & gStateRT.data[^1].val.getIdentifier() - if gStateRT.data[^1].val == "ptr char": - gStateRT.data[^1].val = "cstring" - else: - gStateRT.data[^1].val = "pointer" + gStateRT.data.add(("pointer_declarator", "")) gStateRT.data.add((name, val)) diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 77243f6..19d32ea 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -185,6 +185,8 @@ converter toString*(kind: Kind): string = "*" of zeroOrOne: "?" + of orWithNext: + "!" converter toKind*(kind: string): Kind = return case kind: @@ -194,6 +196,8 @@ converter toKind*(kind: string): Kind = zeroOrMore of "?": zeroOrOne + of "!": + orWithNext else: exactlyOne @@ -223,7 +227,12 @@ proc getRegexForAstChildren*(ast: ref Ast): string = result = "^" for i in 0 .. ast.children.len-1: let kind: string = ast.children[i].kind - result &= &"(?:{ast.children[i].name}){kind}" + let begin = if result[^1] == '|': "" else: "(?:" + case kind: + of "!": + result &= &"{begin}{ast.children[i].name}|" + else: + result &= &"{begin}{ast.children[i].name}){kind}" result &= "$" proc getAstChildByName*(ast: ref Ast, name: string): ref Ast = diff --git a/nimterop/globals.nim b/nimterop/globals.nim index 7b2375c..e5bb6ac 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -10,6 +10,7 @@ type oneOrMore # + zeroOrMore # * zeroOrOne # ? + orWithNext # ! Ast* = object name*: string diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index 13fab13..8210cd3 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -50,18 +50,35 @@ proc initGrammar() = """, proc (ast: ref Ast, node: TSNode) = var - name = gStateRT.data[1].val.getIdentifier() - typ = gStateRT.data[0].val.getIdentifier() + i = 0 + typ = gStateRT.data[i].val.getIdentifier() + name = "" + tptr = "" + + i += 1 + if i < gStateRT.data.len: + if gStateRT.data[i].name == "pointer_declarator": + tptr = "ptr " + i += 1 + + name = gStateRT.data[i].val.getIdentifier() if name notin gStateRT.types: gStateRT.types.add(name) - if name == typ: - typ = "object" - gStateRT.typeStr &= &" {name}* = {typ}\n" + if name == typ or typ == "object": + gStateRT.typeStr &= &" {name}* = object\n" + else: + gStateRT.typeStr &= &" {name}* = {tptr}{typ}\n" )) - template funcParamCommon(pname, ptyp, pout, count, i: untyped): untyped = + template funcParamCommon(pname, ptyp, pptr, pout, count, i: untyped): untyped = ptyp = gStateRT.data[i].val.getIdentifier() + if i+1 < gStateRT.data.len and gStateRT.data[i+1].name == "pointer_declarator": + pptr = "ptr " + i += 1 + else: + pptr = "" + if i+1 < gStateRT.data.len and gStateRT.data[i+1].name == "identifier": pname = gStateRT.data[i+1].val.getIdentifier() i += 2 @@ -70,7 +87,7 @@ proc initGrammar() = count += 1 i += 1 if ptyp != "object": - pout &= &"{pname}: {ptyp}," + pout &= &"{pname}: {pptr}{ptyp}," proc pStructCommon(ast: ref Ast, node: TSNode, name: string, fstart, fend: int) = var @@ -100,25 +117,34 @@ proc initGrammar() = var i = fstart + ftyp, fname: string + fptr = "" while i < gStateRT.data.len-fend: + fptr = "" if gStateRT.data[i].name == "field_declaration": i += 1 continue - let + if gStateRT.data[i].name notin ["field_identifier", "pointer_declarator"]: ftyp = gStateRT.data[i].val.getIdentifier() - fname = gStateRT.data[i+1].val.getIdentifier() - if i+2 < gStateRT.data.len-fend and gStateRT.data[i+2].name in ["identifier", "number_literal"]: + i += 1 + + if gStateRT.data[i].name == "pointer_declarator": + fptr = "ptr " + i += 1 + + fname = gStateRT.data[i].val.getIdentifier() + if i+1 < gStateRT.data.len-fend and gStateRT.data[i+1].name in ["identifier", "number_literal"]: let - flen = gStateRT.data[i+2].val.getIdentifier() - gStateRT.typeStr &= &" {fname}*: array[{flen}, {ftyp}]\n" - i += 3 - elif i+2 < gStateRT.data.len-fend and gStateRT.data[i+2].name == "function_declarator": + flen = gStateRT.data[i+1].val.getIdentifier() + gStateRT.typeStr &= &" {fname}*: array[{flen}, {fptr}{ftyp}]\n" + i += 2 + elif i+1 < gStateRT.data.len-fend and gStateRT.data[i+1].name == "function_declarator": var - pout, pname, ptyp = "" + pout, pname, ptyp, pptr = "" count = 1 - i += 3 + i += 2 while i < gStateRT.data.len-fend: if gStateRT.data[i].name == "function_declarator": i += 1 @@ -127,18 +153,18 @@ proc initGrammar() = if gStateRT.data[i].name == "field_declaration": break - funcParamCommon(pname, ptyp, pout, count, i) + funcParamCommon(pname, ptyp, pptr, pout, count, i) if pout.len != 0 and pout[^1] == ',': pout = pout[0 .. ^2] if ftyp != "object": - gStateRT.typeStr &= &" {fname}*: proc({pout}): {ftyp} {{.nimcall.}}\n" + gStateRT.typeStr &= &" {fname}*: proc({pout}): {fptr}{ftyp} {{.nimcall.}}\n" else: gStateRT.typeStr &= &" {fname}*: proc({pout}) {{.nimcall.}}\n" - i += 1 + i += 1 else: - gStateRT.typeStr &= &" {fname}*: {ftyp}\n" - i += 2 + gStateRT.typeStr &= &" {fname}*: {fptr}{ftyp}\n" + i += 1 let paramListGrammar = &""" @@ -155,12 +181,12 @@ proc initGrammar() = """ fieldGrammar = &""" - (field_identifier?) - (array_declarator? + (field_identifier!) + (array_declarator! (field_identifier) (identifier|number_literal) ) - (function_declarator? + (function_declarator+ (pointer_declarator (field_identifier) ) @@ -172,10 +198,10 @@ proc initGrammar() = (field_declaration_list (field_declaration+ {typeGrammar} - {fieldGrammar} - (pointer_declarator? + (pointer_declarator! {fieldGrammar} ) + {fieldGrammar} ) ) """ @@ -295,7 +321,7 @@ proc initGrammar() = )) let funcGrammar = &""" - (function_declarator* + (function_declarator+ (identifier) {paramListGrammar} ) @@ -306,31 +332,31 @@ proc initGrammar() = (declaration (storage_class_specifier?) {typeGrammar} - {funcGrammar} - (pointer_declarator* + (pointer_declarator! {funcGrammar} ) {funcGrammar} - (pointer_declarator* - {funcGrammar} - ) ) """, proc (ast: ref Ast, node: TSNode) = - let - ftyp = gStateRT.data[0].val.getIdentifier() - var + ftyp = gStateRT.data[0].val.getIdentifier() + fptr = "" i = 1 + while i < gStateRT.data.len: if gStateRT.data[i].name == "function_declarator": i += 1 continue + if gStateRT.data[i].name == "pointer_declarator": + fptr = "ptr " + i += 1 + var fname = gStateRT.data[i].val fnname = fname.getIdentifier() - pout, pname, ptyp = "" + pout, pname, ptyp, pptr = "" count = 1 i += 1 @@ -338,7 +364,7 @@ proc initGrammar() = if gStateRT.data[i].name == "function_declarator": break - funcParamCommon(pname, ptyp, pout, count, i) + funcParamCommon(pname, ptyp, pptr, pout, count, i) if pout.len != 0 and pout[^1] == ',': pout = pout[0 .. ^2] @@ -346,7 +372,7 @@ proc initGrammar() = if fnname notin gStateRT.procs: gStateRT.procs.add(fnname) if ftyp != "object": - gStateRT.procStr &= &"proc {fnname}*({pout}): {ftyp} {{.importc: \"{fname}\", header: {gStateRT.currentHeader}.}}\n" + gStateRT.procStr &= &"proc {fnname}*({pout}): {fptr}{ftyp} {{.importc: \"{fname}\", header: {gStateRT.currentHeader}.}}\n" else: gStateRT.procStr &= &"proc {fnname}*({pout}) {{.importc: \"{fname}\", header: {gStateRT.currentHeader}.}}\n" @@ -357,7 +383,14 @@ proc initRegex(ast: ref Ast) = for child in ast.children: child.initRegex() - ast.regex = ast.getRegexForAstChildren().re() + var + reg: string + try: + reg = ast.getRegexForAstChildren() + ast.regex = reg.re() + except: + echo reg + raise newException(Exception, getCurrentExceptionMsg()) proc parseGrammar*() = initGrammar() From 8c644e814ca676ce2e126bc85497eba7877cc94f Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Fri, 11 Jan 2019 22:14:05 -0600 Subject: [PATCH 075/593] Cleanup abstract pointers, typedef function support --- nimterop/ast.nim | 4 +- nimterop/grammar.nim | 156 +++++++++++++++++++++++++------------------ 2 files changed, 92 insertions(+), 68 deletions(-) diff --git a/nimterop/ast.nim b/nimterop/ast.nim index 35817a2..73c602c 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -44,9 +44,7 @@ proc saveNodeData(node: TSNode): bool = gStateRT.data.add(("function_declarator", "")) elif name in ["abstract_pointer_declarator"]: - gStateRT.data[^1].val = "ptr " & gStateRT.data[^1].val.getIdentifier() - if gStateRT.data[^1].val == "ptr char": - gStateRT.data[^1].val = "cstring" + gStateRT.data.add(("pointer_declarator", "")) elif name in ["field_declaration", "function_declarator"]: gStateRT.data.add((name, "")) diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index 8210cd3..7b12477 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -24,52 +24,37 @@ proc initGrammar() = gStateRT.constStr &= &" {name}* = {val}\n" )) - let typeGrammar = """ - (type_qualifier?) - (primitive_type|type_identifier?) - (sized_type_specifier? - (primitive_type?) - ) - (struct_specifier|union_specifier|enum_specifier? - (type_identifier) - ) - """ + let + typeGrammar = """ + (type_qualifier?) + (primitive_type|type_identifier?) + (sized_type_specifier? + (primitive_type?) + ) + (struct_specifier|union_specifier|enum_specifier? + (type_identifier) + ) + """ - # typedef int X - # typedef X Y - # typedef struct X Y - # typedef ?* Y - gStateRT.grammar.add((&""" - (type_definition - {typeGrammar} - (type_identifier?) - (pointer_declarator? - (type_identifier) - ) - ) - """, - proc (ast: ref Ast, node: TSNode) = - var - i = 0 - typ = gStateRT.data[i].val.getIdentifier() - name = "" - tptr = "" + paramListGrammar = &""" + (parameter_list + (parameter_declaration* + {typeGrammar} + (identifier|type_identifier?) + (pointer_declarator? + (identifier|type_identifier) + ) + (abstract_pointer_declarator?) + ) + ) + """ - i += 1 - if i < gStateRT.data.len: - if gStateRT.data[i].name == "pointer_declarator": - tptr = "ptr " - i += 1 - - name = gStateRT.data[i].val.getIdentifier() - - if name notin gStateRT.types: - gStateRT.types.add(name) - if name == typ or typ == "object": - gStateRT.typeStr &= &" {name}* = object\n" - else: - gStateRT.typeStr &= &" {name}* = {tptr}{typ}\n" - )) + funcGrammar = &""" + (function_declarator* + (identifier|type_identifier) + {paramListGrammar} + ) + """ template funcParamCommon(pname, ptyp, pptr, pout, count, i: untyped): untyped = ptyp = gStateRT.data[i].val.getIdentifier() @@ -89,6 +74,64 @@ proc initGrammar() = if ptyp != "object": pout &= &"{pname}: {pptr}{ptyp}," + # typedef int X + # typedef X Y + # typedef struct X Y + # typedef ?* Y + gStateRT.grammar.add((&""" + (type_definition + {typeGrammar} + (type_identifier?) + (pointer_declarator? + (type_identifier!) + {funcGrammar} + ) + {funcGrammar} + ) + """, + proc (ast: ref Ast, node: TSNode) = + var + i = 0 + typ = gStateRT.data[i].val.getIdentifier() + name = "" + tptr = "" + + i += 1 + if i < gStateRT.data.len: + if gStateRT.data[i].name == "pointer_declarator": + tptr = "ptr " + i += 1 + + if i < gStateRT.data.len: + name = gStateRT.data[i].val.getIdentifier() + i += 1 + + if name notin gStateRT.types: + if i < gStateRT.data.len and gStateRT.data[^1].name == "function_declarator": + var + pout, pname, ptyp, pptr = "" + count = 1 + + while i < gStateRT.data.len: + if gStateRT.data[i].name == "function_declarator": + break + + funcParamCommon(pname, ptyp, pptr, pout, count, i) + + if pout.len != 0 and pout[^1] == ',': + pout = pout[0 .. ^2] + if typ != "object": + gStateRT.typeStr &= &" {name}* = proc({pout}): {tptr}{typ} {{.nimcall.}}\n" + else: + gStateRT.typeStr &= &" {name}*: proc({pout}) {{.nimcall.}}\n" + else: + gStateRT.types.add(name) + if name == typ or typ == "object": + gStateRT.typeStr &= &" {name}* = object\n" + else: + gStateRT.typeStr &= &" {name}* = {tptr}{typ}\n" + )) + proc pStructCommon(ast: ref Ast, node: TSNode, name: string, fstart, fend: int) = var nname = name.getIdentifier() @@ -163,23 +206,13 @@ proc initGrammar() = gStateRT.typeStr &= &" {fname}*: proc({pout}) {{.nimcall.}}\n" i += 1 else: - gStateRT.typeStr &= &" {fname}*: {fptr}{ftyp}\n" + if ftyp == "object": + gStateRT.typeStr &= &" {fname}*: pointer\n" + else: + gStateRT.typeStr &= &" {fname}*: {fptr}{ftyp}\n" i += 1 let - paramListGrammar = &""" - (parameter_list - (parameter_declaration* - {typeGrammar} - (identifier?) - (pointer_declarator? - (identifier) - ) - (abstract_pointer_declarator?) - ) - ) - """ - fieldGrammar = &""" (field_identifier!) (array_declarator! @@ -320,13 +353,6 @@ proc initGrammar() = pEnumCommon(ast, node, gStateRT.data[^1].val, offset, 1) )) - let funcGrammar = &""" - (function_declarator+ - (identifier) - {paramListGrammar} - ) - """ - # typ function(typ param1, ...) gStateRT.grammar.add((&""" (declaration From 75dc6dc56e787daf55363c2ef4f8195c0c5fae9a Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Sat, 12 Jan 2019 00:46:44 -0600 Subject: [PATCH 076/593] Identifiers in enums --- nimterop/ast.nim | 9 ++++----- nimterop/grammar.nim | 17 ++++++++++++----- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/nimterop/ast.nim b/nimterop/ast.nim index 73c602c..8f880da 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -40,13 +40,12 @@ proc saveNodeData(node: TSNode): bool = gStateRT.data.add((name, val)) - if node.isPName("pointer_declarator") and node.isPPName("function_declarator"): + if node.tsNodeType() == "field_identifier" and node.isPName("pointer_declarator") and + node.isPPName("function_declarator"): gStateRT.data.add(("function_declarator", "")) - elif name in ["abstract_pointer_declarator"]: - gStateRT.data.add(("pointer_declarator", "")) - elif name in ["field_declaration", "function_declarator"]: - gStateRT.data.add((name, "")) + elif name in ["abstract_pointer_declarator", "enumerator", "field_declaration", "function_declarator"]: + gStateRT.data.add((name.replace("abstract_", ""), "")) return true diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index 7b12477..693b365 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -51,7 +51,10 @@ proc initGrammar() = funcGrammar = &""" (function_declarator* - (identifier|type_identifier) + (identifier|type_identifier!) + (pointer_declarator + (type_identifier) + ) {paramListGrammar} ) """ @@ -123,7 +126,7 @@ proc initGrammar() = if typ != "object": gStateRT.typeStr &= &" {name}* = proc({pout}): {tptr}{typ} {{.nimcall.}}\n" else: - gStateRT.typeStr &= &" {name}*: proc({pout}) {{.nimcall.}}\n" + gStateRT.typeStr &= &" {name}* = proc({pout}) {{.nimcall.}}\n" else: gStateRT.types.add(name) if name == typ or typ == "object": @@ -169,7 +172,7 @@ proc initGrammar() = continue if gStateRT.data[i].name notin ["field_identifier", "pointer_declarator"]: - ftyp = gStateRT.data[i].val.getIdentifier() + ftyp = gStateRT.data[i].val.getType() i += 1 if gStateRT.data[i].name == "pointer_declarator": @@ -289,9 +292,13 @@ proc initGrammar() = let fname = gStateRT.data[i].val.getIdentifier() + if gStateRT.data[i].name == "enumerator": + i += 1 + continue + if fname notin gStateRT.consts: if i+1 < gStateRT.data.len-fend and - gStateRT.data[i+1].name in ["shift_expression", "math_expression", "number_literal"]: + gStateRT.data[i+1].name in ["identifier", "shift_expression", "math_expression", "number_literal"]: if " " in gStateRT.data[i+1].val: gStateRT.data[i+1].val = "(" & gStateRT.data[i+1].val.replace(" ", "") & ")" gStateRT.data[i+1].val = gStateRT.data[i+1].val.multiReplace([ @@ -315,7 +322,7 @@ proc initGrammar() = (type_identifier?) (enumerator_list (enumerator+ - (identifier) + (identifier+) (number_literal?) (shift_expression|math_expression? (number_literal+) From 04d01a5f6ebf85f846ab54bd86011f733b42879c Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 15 Jan 2019 16:20:52 -0600 Subject: [PATCH 077/593] Fix missing array type, suppress gcc warnings --- nimterop/getters.nim | 4 ++-- nimterop/grammar.nim | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 19d32ea..abc292b 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -129,7 +129,7 @@ proc removeStatic*(content: string): string = proc getPreprocessor*(fullpath: string, mode = "cpp"): string = var mmode = if mode == "cpp": "c++" else: mode - cmd = &"gcc -E -dD -x{mmode} " + cmd = &"gcc -E -dD -x{mmode} -w " rdata: seq[string] = @[] start = false @@ -144,7 +144,7 @@ proc getPreprocessor*(fullpath: string, mode = "cpp"): string = cmd &= &"\"{fullpath}\"" # Include content only from file - for line in execAction(cmd, true).splitLines(): + for line in execAction(cmd).splitLines(): if line.strip() != "": if line.len > 1 and line[0 .. 1] == "# ": start = false diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index 693b365..ab80356 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -267,7 +267,9 @@ proc initGrammar() = var offset = 0 - if gStateRT.data[0].name == "type_identifier": + if gStateRT.data.len > 1 and + gStateRT.data[0].name == "type_identifier" and + gStateRT.data[1].name != "field_identifier": offset = 1 pStructCommon(ast, node, gStateRT.data[^1].val, offset, 1) From 11c896f82e00fce82e159d781243c2036346cc58 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 15 Jan 2019 17:55:38 -0600 Subject: [PATCH 078/593] Support array pointer in struct --- nimterop/ast.nim | 22 ++++++++++++++++------ nimterop/grammar.nim | 21 +++++++++++++++------ 2 files changed, 31 insertions(+), 12 deletions(-) diff --git a/nimterop/ast.nim b/nimterop/ast.nim index 8f880da..8a61fe0 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -33,15 +33,25 @@ proc saveNodeData(node: TSNode): bool = if name in ["math_expression", "primitive_type", "sized_type_specifier"]: val = val.getType() - if node.tsNodePrevNamedSibling().tsNodeIsNull() and - ((node.isPName("pointer_declarator") and not node.isPPName("function_declarator")) or - (node.getPName() in ["function_declarator", "array_declarator"] and node.isPPName("pointer_declarator"))): - gStateRT.data.add(("pointer_declarator", "")) + let + pname = node.getPName() + ppname = node.tsNodeParent().getPName() + + if node.tsNodePrevNamedSibling().tsNodeIsNull(): + if pname == "pointer_declarator": + if ppname notin ["function_declarator", "array_declarator"]: + gStateRT.data.add(("pointer_declarator", "")) + elif ppname == "array_declarator": + gStateRT.data.add(("array_pointer_declarator", "")) + elif pname in ["function_declarator", "array_declarator"]: + if ppname == "pointer_declarator": + gStateRT.data.add(("pointer_declarator", "")) gStateRT.data.add((name, val)) - if node.tsNodeType() == "field_identifier" and node.isPName("pointer_declarator") and - node.isPPName("function_declarator"): + if node.tsNodeType() == "field_identifier" and + pname == "pointer_declarator" and + ppname == "function_declarator": gStateRT.data.add(("function_declarator", "")) elif name in ["abstract_pointer_declarator", "enumerator", "field_declaration", "function_declarator"]: diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index ab80356..a72df53 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -165,25 +165,31 @@ proc initGrammar() = i = fstart ftyp, fname: string fptr = "" + aptr = "" while i < gStateRT.data.len-fend: fptr = "" + aptr = "" if gStateRT.data[i].name == "field_declaration": i += 1 continue - if gStateRT.data[i].name notin ["field_identifier", "pointer_declarator"]: + if gStateRT.data[i].name notin ["field_identifier", "pointer_declarator", "array_pointer_declarator"]: ftyp = gStateRT.data[i].val.getType() i += 1 - if gStateRT.data[i].name == "pointer_declarator": - fptr = "ptr " - i += 1 + case gStateRT.data[i].name: + of "pointer_declarator": + fptr = "ptr " + i += 1 + of "array_pointer_declarator": + aptr = "ptr " + i += 1 fname = gStateRT.data[i].val.getIdentifier() if i+1 < gStateRT.data.len-fend and gStateRT.data[i+1].name in ["identifier", "number_literal"]: let flen = gStateRT.data[i+1].val.getIdentifier() - gStateRT.typeStr &= &" {fname}*: array[{flen}, {fptr}{ftyp}]\n" + gStateRT.typeStr &= &" {fname}*: {aptr}array[{flen}, {fptr}{ftyp}]\n" i += 2 elif i+1 < gStateRT.data.len-fend and gStateRT.data[i+1].name == "function_declarator": var @@ -219,7 +225,10 @@ proc initGrammar() = fieldGrammar = &""" (field_identifier!) (array_declarator! - (field_identifier) + (field_identifier!) + (pointer_declarator + (field_identifier) + ) (identifier|number_literal) ) (function_declarator+ From da06be80d1a3b00cf5b380aa9529d403ca8aab9b Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 15 Jan 2019 20:17:10 -0600 Subject: [PATCH 079/593] typedef arrays, debug output --- nimterop/ast.nim | 5 +++++ nimterop/globals.nim | 2 +- nimterop/grammar.nim | 38 ++++++++++++++++++++++++++++++-------- toast.nim | 4 ++++ 4 files changed, 40 insertions(+), 9 deletions(-) diff --git a/nimterop/ast.nim b/nimterop/ast.nim index 8a61fe0..6c5ab71 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -99,6 +99,8 @@ proc searchAst(root: TSNode) = for ast in gStateRT.ast[name]: if searchAstForNode(ast, node): ast.tonim(ast, node) + if gStateRT.debug: + gStateRT.debugStr &= "\n\n# " & gStateRT.data.join("\n# ") break gStateRT.data = @[] else: @@ -145,3 +147,6 @@ proc printNim*(fullpath: string, root: TSNode) = if gStateRT.procStr.nBl: echo gStateRT.procStr + + if gStateRT.debug and gStateRT.debugStr.nBl: + echo gStateRT.debugStr \ No newline at end of file diff --git a/nimterop/globals.nim b/nimterop/globals.nim index e5bb6ac..e6a1d55 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -26,7 +26,7 @@ type consts*, enums*, procs*, types*: seq[string] - code*, constStr*, currentHeader*, enumStr*, mode*, procStr*, typeStr*: string + code*, constStr*, currentHeader*, debugStr*, enumStr*, mode*, procStr*, typeStr*: string sourceFile*: string # eg, C or C++ source or header file ast*: Table[string, seq[ref Ast]] diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index a72df53..3caeb3d 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -59,6 +59,16 @@ proc initGrammar() = ) """ + arrGrammar = &""" + (array_declarator! + (pointer_declarator! + (type_identifier) + ) + (type_identifier) + (identifier|number_literal) + ) + """ + template funcParamCommon(pname, ptyp, pptr, pout, count, i: untyped): untyped = ptyp = gStateRT.data[i].val.getIdentifier() if i+1 < gStateRT.data.len and gStateRT.data[i+1].name == "pointer_declarator": @@ -84,9 +94,11 @@ proc initGrammar() = gStateRT.grammar.add((&""" (type_definition {typeGrammar} - (type_identifier?) - (pointer_declarator? + (type_identifier!) + {arrGrammar} + (pointer_declarator! (type_identifier!) + {arrGrammar} {funcGrammar} ) {funcGrammar} @@ -98,12 +110,17 @@ proc initGrammar() = typ = gStateRT.data[i].val.getIdentifier() name = "" tptr = "" + aptr = "" i += 1 if i < gStateRT.data.len: - if gStateRT.data[i].name == "pointer_declarator": - tptr = "ptr " - i += 1 + case gStateRT.data[i].name: + of "pointer_declarator": + tptr = "ptr " + i += 1 + of "array_pointer_declarator": + aptr = "ptr " + i += 1 if i < gStateRT.data.len: name = gStateRT.data[i].val.getIdentifier() @@ -129,10 +146,15 @@ proc initGrammar() = gStateRT.typeStr &= &" {name}* = proc({pout}) {{.nimcall.}}\n" else: gStateRT.types.add(name) - if name == typ or typ == "object": - gStateRT.typeStr &= &" {name}* = object\n" + if i < gStateRT.data.len and gStateRT.data[i].name in ["identifier", "number_literal"]: + let + flen = gStateRT.data[i].val.getIdentifier() + gStateRT.typeStr &= &" {name}*: = {aptr}array[{flen}, {tptr}{typ}]\n" else: - gStateRT.typeStr &= &" {name}* = {tptr}{typ}\n" + if name == typ or typ == "object": + gStateRT.typeStr &= &" {name}* = object\n" + else: + gStateRT.typeStr &= &" {name}* = {tptr}{typ}\n" )) proc pStructCommon(ast: ref Ast, node: TSNode, name: string, fstart, fend: int) = diff --git a/toast.nim b/toast.nim index d4a40c9..28f6067 100644 --- a/toast.nim +++ b/toast.nim @@ -114,6 +114,7 @@ proc main( preprocess = false, pgrammar = false, recurse = false, + debug = false, defines: seq[string] = @[], includeDirs: seq[string] = @[], source: seq[string], @@ -126,6 +127,7 @@ proc main( pretty: pretty, preprocess: preprocess, recurse: recurse, + debug: debug, defines: defines, includeDirs: includeDirs, ) @@ -147,6 +149,7 @@ when isMainModule: "preprocess": "run preprocessor on header", "pgrammar": "print grammar", "recurse": "process #include files", + "debug": "enable debug output", "source" : "C/C++ source/header", }, short = { "past": 'a', @@ -155,5 +158,6 @@ when isMainModule: "includeDirs": 'I', "preprocess": 'p', "recurse": 'r', + "debug": 'd', "pgrammar": 'g' }) From f81b2a89894298fa06a2d3c7d7e3bdc17581469c Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 15 Jan 2019 20:18:42 -0600 Subject: [PATCH 080/593] Minor output fix --- nimterop/grammar.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index 3caeb3d..f767ce6 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -149,7 +149,7 @@ proc initGrammar() = if i < gStateRT.data.len and gStateRT.data[i].name in ["identifier", "number_literal"]: let flen = gStateRT.data[i].val.getIdentifier() - gStateRT.typeStr &= &" {name}*: = {aptr}array[{flen}, {tptr}{typ}]\n" + gStateRT.typeStr &= &" {name}* = {aptr}array[{flen}, {tptr}{typ}]\n" else: if name == typ or typ == "object": gStateRT.typeStr &= &" {name}* = object\n" From 80b47c9d4edad831302cc543ce8a8cc5513d72ab Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 15 Jan 2019 23:54:25 -0600 Subject: [PATCH 081/593] Support for time_t --- nimterop/getters.nim | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/nimterop/getters.nim b/nimterop/getters.nim index abc292b..bdf92f2 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -1,3 +1,5 @@ +{.experimental: "codeReordering".} + import macros, os, strformat, strutils, tables import regex @@ -44,14 +46,15 @@ const gTypeMap = { "unsigned char": "cuchar", "unsigned short": "cushort", "unsigned int": "cuint", - "unsigned long long": "culonglong" + "unsigned long long": "culonglong", + "time_t": "int32" }.toTable() proc sanitizePath*(path: string): string = path.multiReplace([("\\\\", $DirSep), ("\\", $DirSep), ("//", $DirSep)]) proc getIdentifier*(str: string): string = - result = str.strip(chars={'_'}).replace(re"_+", "_") + result = str.strip(chars={'_'}).replace(re"_+", "_").getType() if result in gReserved: result = &"`{result}`" From e9a5ccc007207c89dfb6086dccb816f72fe492ee Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 16 Jan 2019 00:11:53 -0600 Subject: [PATCH 082/593] cstring support --- nimterop/getters.nim | 9 +++++++++ nimterop/grammar.nim | 16 ++++++++-------- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/nimterop/getters.nim b/nimterop/getters.nim index bdf92f2..e25f7a9 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -80,6 +80,15 @@ proc getType*(str: string): string = if gTypeMap.hasKey(result): result = gTypeMap[result] +proc getPtrType*(str: string): string = + result = case str: + of "ptr cchar": + "cstring" + of "ptr object": + "pointer" + else: + str + proc getLit*(str: string): string = if str.contains(re"^[\-]?[\d]+$") or str.contains(re"^[\-]?[\d]*\.[\d]+$") or diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index f767ce6..0144073 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -85,7 +85,7 @@ proc initGrammar() = count += 1 i += 1 if ptyp != "object": - pout &= &"{pname}: {pptr}{ptyp}," + pout &= &"{pname}: {getPtrType(pptr&ptyp)}," # typedef int X # typedef X Y @@ -141,7 +141,7 @@ proc initGrammar() = if pout.len != 0 and pout[^1] == ',': pout = pout[0 .. ^2] if typ != "object": - gStateRT.typeStr &= &" {name}* = proc({pout}): {tptr}{typ} {{.nimcall.}}\n" + gStateRT.typeStr &= &" {name}* = proc({pout}): {getPtrType(tptr&typ)} {{.nimcall.}}\n" else: gStateRT.typeStr &= &" {name}* = proc({pout}) {{.nimcall.}}\n" else: @@ -149,12 +149,12 @@ proc initGrammar() = if i < gStateRT.data.len and gStateRT.data[i].name in ["identifier", "number_literal"]: let flen = gStateRT.data[i].val.getIdentifier() - gStateRT.typeStr &= &" {name}* = {aptr}array[{flen}, {tptr}{typ}]\n" + gStateRT.typeStr &= &" {name}* = {aptr}array[{flen}, {getPtrType(tptr&typ)}]\n" else: if name == typ or typ == "object": gStateRT.typeStr &= &" {name}* = object\n" else: - gStateRT.typeStr &= &" {name}* = {tptr}{typ}\n" + gStateRT.typeStr &= &" {name}* = {getPtrType(tptr&typ)}\n" )) proc pStructCommon(ast: ref Ast, node: TSNode, name: string, fstart, fend: int) = @@ -211,7 +211,7 @@ proc initGrammar() = if i+1 < gStateRT.data.len-fend and gStateRT.data[i+1].name in ["identifier", "number_literal"]: let flen = gStateRT.data[i+1].val.getIdentifier() - gStateRT.typeStr &= &" {fname}*: {aptr}array[{flen}, {fptr}{ftyp}]\n" + gStateRT.typeStr &= &" {fname}*: {aptr}array[{flen}, {getPtrType(fptr&ftyp)}]\n" i += 2 elif i+1 < gStateRT.data.len-fend and gStateRT.data[i+1].name == "function_declarator": var @@ -232,7 +232,7 @@ proc initGrammar() = if pout.len != 0 and pout[^1] == ',': pout = pout[0 .. ^2] if ftyp != "object": - gStateRT.typeStr &= &" {fname}*: proc({pout}): {fptr}{ftyp} {{.nimcall.}}\n" + gStateRT.typeStr &= &" {fname}*: proc({pout}): {getPtrType(fptr&ftyp)} {{.nimcall.}}\n" else: gStateRT.typeStr &= &" {fname}*: proc({pout}) {{.nimcall.}}\n" i += 1 @@ -240,7 +240,7 @@ proc initGrammar() = if ftyp == "object": gStateRT.typeStr &= &" {fname}*: pointer\n" else: - gStateRT.typeStr &= &" {fname}*: {fptr}{ftyp}\n" + gStateRT.typeStr &= &" {fname}*: {getPtrType(fptr&ftyp)}\n" i += 1 let @@ -438,7 +438,7 @@ proc initGrammar() = if fnname notin gStateRT.procs: gStateRT.procs.add(fnname) if ftyp != "object": - gStateRT.procStr &= &"proc {fnname}*({pout}): {fptr}{ftyp} {{.importc: \"{fname}\", header: {gStateRT.currentHeader}.}}\n" + gStateRT.procStr &= &"proc {fnname}*({pout}): {getPtrType(fptr&ftyp)} {{.importc: \"{fname}\", header: {gStateRT.currentHeader}.}}\n" else: gStateRT.procStr &= &"proc {fnname}*({pout}) {{.importc: \"{fname}\", header: {gStateRT.currentHeader}.}}\n" From 114d502f13b721b55ff297074121d2f4cfeb014e Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 16 Jan 2019 17:13:15 -0600 Subject: [PATCH 083/593] Remove nimgen dependency, enable tmath test --- .gitignore | 2 + .travis.yml | 3 +- appveyor.yml | 2 +- nimterop.nimble | 15 +--- nimterop/ast.nim | 4 +- nimterop/cimport.nim | 10 ++- nimterop/getters.nim | 38 ++++----- nimterop/git.nim | 3 +- nimterop/globals.nim | 9 ++- nimterop/grammar.nim | 4 +- nimterop/setup.nim | 43 +++++++++++ nimterop/treesitter/c.nim | 5 ++ nimterop/treesitter/cpp.nim | 6 ++ nimterop/treesitter/runtime.nim | 132 ++++++++++++++++++++++++++++++++ tests/tmath.nim | 2 + toast.nim | 6 +- toast.nims | 1 + 17 files changed, 231 insertions(+), 54 deletions(-) create mode 100644 nimterop/setup.nim create mode 100644 nimterop/treesitter/c.nim create mode 100644 nimterop/treesitter/cpp.nim create mode 100644 nimterop/treesitter/runtime.nim create mode 100644 toast.nims diff --git a/.gitignore b/.gitignore index 2048a22..7969ea3 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,5 @@ nimcache *.exe *.swp toast +inc +tests \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 2e316a2..6d86766 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,8 +25,7 @@ install: curl https://nim-lang.org/choosenim/init.sh -sSf > init.sh sh init.sh -y - export PATH=$HOME/.nimble/bin:$PATH - # - nimble refresh -y script: - - nimble installWithDeps + - nimble install - nimble test diff --git a/appveyor.yml b/appveyor.yml index d10a96e..59a0b62 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -78,7 +78,7 @@ for: - /home/appveyor/binaries build_script: - - nimble installWithDeps + - nimble install test_script: - nimble test diff --git a/nimterop.nimble b/nimterop.nimble index c3c87a7..ca9040e 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -10,7 +10,7 @@ installDirs = @["nimterop"] # Dependencies -requires "nim >= 0.19.0", "treesitter >= 0.1.0", "treesitter_c >= 0.1.0", "treesitter_cpp >= 0.1.0", "regex >= 0.10.0", "cligen >= 0.9.17" +requires "nim >= 0.19.0", "regex >= 0.10.0", "cligen >= 0.9.17" proc execCmd(cmd:string)= echo cmd @@ -20,13 +20,6 @@ task test, "Test": execCmd "nim c -r tests/tnimterop_c.nim" execCmd "nim cpp -r tests/tnimterop_c.nim" execCmd "nim cpp -r tests/tnimterop_cpp.nim" - # when defined(windows): - # execCmd "nim c -r tests/tmath.nim" - # execCmd "nim cpp -r tests/tmath.nim" - -task installWithDeps, "install dependencies": - for a in ["http://github.com/genotrance/nimtreesitter?subdir=treesitter", - "http://github.com/genotrance/nimtreesitter?subdir=treesitter_c", - "http://github.com/genotrance/nimtreesitter?subdir=treesitter_cpp",]: - execCmd "nimble install -y " & a - execCmd "nimble install -y" + when defined(windows): + execCmd "nim c -r tests/tmath.nim" + execCmd "nim cpp -r tests/tmath.nim" diff --git a/nimterop/ast.nim b/nimterop/ast.nim index 6c5ab71..13dcf2c 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -2,9 +2,7 @@ import strformat, strutils, tables import regex -import treesitter/runtime - -import "."/[getters, globals, grammar] +import "."/[getters, globals, grammar, treesitter/runtime] const gAtoms = @[ "field_identifier", diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index 5b8935b..14c689d 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -1,6 +1,6 @@ import macros, os, strformat, strutils -import getters, globals +import "."/globals proc interpPath(dir: string): string= # TODO: more robust: needs a DirSep after "$projpath" @@ -42,6 +42,14 @@ proc getToast(fullpath: string, recurse: bool = false): string = doAssert exitCode == 0, $exitCode result = output +proc getGccPaths*(mode = "c"): string = + var + ret = 0 + nul = when defined(Windows): "nul" else: "/dev/null" + mmode = if mode == "cpp": "c++" else: mode + + (result, ret) = gorgeEx("gcc -Wp,-v -x" & mmode & " " & nul) + proc cSearchPath*(path: string): string {.compileTime.}= result = findPath(path, fail = false) if result.len == 0: diff --git a/nimterop/getters.nim b/nimterop/getters.nim index e25f7a9..ede88fc 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -1,12 +1,8 @@ -{.experimental: "codeReordering".} - import macros, os, strformat, strutils, tables import regex -import treesitter/runtime - -import git, globals +import "."/[git, globals, treesitter/runtime] const gReserved = """ addr and as asm @@ -53,6 +49,17 @@ const gTypeMap = { proc sanitizePath*(path: string): string = path.multiReplace([("\\\\", $DirSep), ("\\", $DirSep), ("//", $DirSep)]) +proc getType*(str: string): string = + if str == "void": + return "object" + + result = str.strip(chars={'_'}). + replace(re"([u]?int[\d]+)_t", "$1"). + replace(re"([u]?int)ptr_t", "ptr $1") + + if gTypeMap.hasKey(result): + result = gTypeMap[result] + proc getIdentifier*(str: string): string = result = str.strip(chars={'_'}).replace(re"_+", "_").getType() @@ -69,17 +76,6 @@ proc getUniqueIdentifier*(exists: seq[string], prefix = ""): string = return name & $count -proc getType*(str: string): string = - if str == "void": - return "object" - - result = str.strip(chars={'_'}). - replace(re"([u]?int[\d]+)_t", "$1"). - replace(re"([u]?int)ptr_t", "ptr $1") - - if gTypeMap.hasKey(result): - result = gTypeMap[result] - proc getPtrType*(str: string): string = result = case str: of "ptr cchar": @@ -116,15 +112,7 @@ proc getLineCol*(node: TSNode): tuple[line, col: int] = proc getCurrentHeader*(fullpath: string): string = ("header" & fullpath.splitFile().name.replace(re"[-.]+", "")) -proc getGccPaths*(mode = "c"): string = - var - ret = 0 - nul = when defined(Windows): "nul" else: "/dev/null" - mmode = if mode == "cpp": "c++" else: mode - - (result, ret) = gorgeEx("gcc -Wp,-v -x" & mmode & " " & nul) - -proc removeStatic*(content: string): string = +proc removeStatic(content: string): string = ## Replace static function bodies with a semicolon and commented ## out body return content.replace( diff --git a/nimterop/git.nim b/nimterop/git.nim index f4412ce..bebf75e 100644 --- a/nimterop/git.nim +++ b/nimterop/git.nim @@ -1,6 +1,6 @@ import macros, os, osproc, regex, strformat, strutils -import globals +import "."/globals proc execAction*(cmd: string, nostderr=false): string = var @@ -89,7 +89,6 @@ macro gitPull*(url: static string, outdirN = "", plistN = "", checkoutN = ""): u discard execAction(&"cd \"{outdir}\" && git config core.sparsecheckout true") writeFile(sparsefile, plist) - echo "Wrote" if checkout.len != 0: echo "Checking out " & checkout diff --git a/nimterop/globals.nim b/nimterop/globals.nim index e6a1d55..6ba64c1 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -2,7 +2,8 @@ import tables import regex -import treesitter/runtime +when defined(NIMTEROP): + import "."/treesitter/runtime type Kind* = enum @@ -16,7 +17,8 @@ type name*: string kind*: Kind children*: seq[ref Ast] - tonim*: proc (ast: ref Ast, node: TSNode) + when defined(NIMTEROP): + tonim*: proc (ast: ref Ast, node: TSNode) regex*: Regex State* = object @@ -31,7 +33,8 @@ type ast*: Table[string, seq[ref Ast]] data*: seq[tuple[name, val: string]] - grammar*: seq[tuple[grammar: string, call: proc(ast: ref Ast, node: TSNode) {.nimcall.}]] + when defined(NIMTEROP): + grammar*: seq[tuple[grammar: string, call: proc(ast: ref Ast, node: TSNode) {.nimcall.}]] var gStateCT* {.compiletime.}: State diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index 0144073..e6a0fe2 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -2,9 +2,7 @@ import strformat, strutils, tables import regex -import treesitter/runtime - -import "."/[getters, globals, lisp] +import "."/[getters, globals, lisp, treesitter/runtime] proc initGrammar() = # #define X Y diff --git a/nimterop/setup.nim b/nimterop/setup.nim new file mode 100644 index 0000000..baa9ecb --- /dev/null +++ b/nimterop/setup.nim @@ -0,0 +1,43 @@ +import os, strutils + +import "."/git + +static: + gitPull("https://github.com/tree-sitter/tree-sitter/", "inc/treesitter", """ +include/* +src/runtime/* +""") + + gitPull("https://github.com/JuliaStrings/utf8proc", "inc/utf8proc", """ +*.c +*.h +""") + + gitPull("https://github.com/tree-sitter/tree-sitter-c", "inc/treesitter_c", """ +src/*.h +src/*.c +src/*.cc +""") + + gitPull("https://github.com/tree-sitter/tree-sitter-cpp", "inc/treesitter_cpp", """ +src/*.h +src/*.c +src/*.cc +""") + + let + stack = "inc/treesitter/src/runtime/stack.c" + headerc = "inc/treesitter_c/src/parser.h" + headercpp = "inc/treesitter_cpp/src/parser.h" + + stack.writeFile(stack.readFile().replace("inline Stack", "Stack")) + + headerc.writeFile(""" + typedef struct TSLanguage TSLanguage; + const TSLanguage *tree_sitter_c(); + """) + + headercpp.writeFile(""" + typedef struct TSLanguage TSLanguage; + const TSLanguage *tree_sitter_cpp(); + """) \ No newline at end of file diff --git a/nimterop/treesitter/c.nim b/nimterop/treesitter/c.nim new file mode 100644 index 0000000..a60d072 --- /dev/null +++ b/nimterop/treesitter/c.nim @@ -0,0 +1,5 @@ +import "."/runtime + +{.compile: ("../../inc/treesitter_c/src/parser.c", "parserc.o").} + +proc treeSitterC*(): ptr TSLanguage {.importc: "tree_sitter_c", header: "inc/treesitter_c/src/parser.h".} diff --git a/nimterop/treesitter/cpp.nim b/nimterop/treesitter/cpp.nim new file mode 100644 index 0000000..9509139 --- /dev/null +++ b/nimterop/treesitter/cpp.nim @@ -0,0 +1,6 @@ +import "."/runtime + +{.compile: ("../../inc/treesitter_cpp/src/parser.c", "parsercpp.o").} +{.compile: ("../../inc/treesitter_cpp/src/scanner.cc", "scannercpp.o").} + +proc treeSitterCpp*(): ptr TSLanguage {.importc: "tree_sitter_cpp", header: "inc/treesitter_cpp/src/parser.h".} diff --git a/nimterop/treesitter/runtime.nim b/nimterop/treesitter/runtime.nim new file mode 100644 index 0000000..34ce237 --- /dev/null +++ b/nimterop/treesitter/runtime.nim @@ -0,0 +1,132 @@ +{.experimental: "codeReordering".} + +{.passC: "-std=c11 -DUTF8PROC_STATIC".} +{.passC: "-Iinc/treesitter/include".} +{.passC: "-Iinc/treesitter/src".} +{.passC: "-Iinc/utf8proc".} +{.compile: "../../inc/treesitter/src/runtime/runtime.c".} + +type TSInputEncoding* = distinct int +converter enumToInt(en: TSInputEncoding): int {.used.} = en.int + +type TSSymbolType* = distinct int +converter enumToInt(en: TSSymbolType): int {.used.} = en.int + +type TSLogType* = distinct int +converter enumToInt(en: TSLogType): int {.used.} = en.int + +const + headerruntime = "inc/treesitter/include/tree_sitter/runtime.h" + TREE_SITTER_LANGUAGE_VERSION* = 9 + TSInputEncodingUTF8* = 0.TSInputEncoding + TSInputEncodingUTF16* = 1.TSInputEncoding + TSSymbolTypeRegular* = 0.TSSymbolType + TSSymbolTypeAnonymous* = 1.TSSymbolType + TSSymbolTypeAuxiliary* = 2.TSSymbolType + TSLogTypeParse* = 0.TSLogType + TSLogTypeLex* = 1.TSLogType + +type + TSSymbol* = uint16 + TSLanguage* = object + TSParser* = object + TSTree* = object + TSPoint* {.importc: "TSPoint", header: headerruntime, bycopy.} = object + row*: uint32 + column*: uint32 + TSRange* {.importc: "TSRange", header: headerruntime, bycopy.} = object + start_point*: TSPoint + end_point*: TSPoint + start_byte*: uint32 + end_byte*: uint32 + TSInput* {.importc: "TSInput", header: headerruntime, bycopy.} = object + payload*: pointer + read*: proc(byte_index: uint32,position: TSPoint,bytes_read: ptr uint32): cchar {.nimcall.} + encoding*: TSInputEncoding + TSLogger* {.importc: "TSLogger", header: headerruntime, bycopy.} = object + payload*: pointer + log*: proc(a1: TSLogType,a2: cstring) {.nimcall.} + TSInputEdit* {.importc: "TSInputEdit", header: headerruntime, bycopy.} = object + start_byte*: uint32 + old_end_byte*: uint32 + new_end_byte*: uint32 + start_point*: TSPoint + old_end_point*: TSPoint + new_end_point*: TSPoint + TSNode* {.importc: "TSNode", header: headerruntime, bycopy.} = object + context*: array[4, uint32] + id*: pointer + tree*: ptr TSTree + TSTreeCursor* {.importc: "TSTreeCursor", header: headerruntime, bycopy.} = object + tree*: pointer + id*: pointer + context*: array[2, uint32] + +proc ts_parser_new*(): ptr TSParser {.importc: "ts_parser_new", header: headerruntime.} +proc ts_parser_delete*(a1: ptr TSParser) {.importc: "ts_parser_delete", header: headerruntime.} +proc ts_parser_language*(a1: ptr TSParser): ptr TSLanguage {.importc: "ts_parser_language", header: headerruntime.} +proc ts_parser_set_language*(a1: ptr TSParser,a2: ptr TSLanguage): bool {.importc: "ts_parser_set_language", header: headerruntime.} +proc ts_parser_logger*(a1: ptr TSParser): TSLogger {.importc: "ts_parser_logger", header: headerruntime.} +proc ts_parser_set_logger*(a1: ptr TSParser,a2: TSLogger) {.importc: "ts_parser_set_logger", header: headerruntime.} +proc ts_parser_print_dot_graphs*(a1: ptr TSParser,a2: ptr FILE) {.importc: "ts_parser_print_dot_graphs", header: headerruntime.} +proc ts_parser_halt_on_error*(a1: ptr TSParser,a2: bool) {.importc: "ts_parser_halt_on_error", header: headerruntime.} +proc ts_parser_parse*(a1: ptr TSParser,a2: ptr TSTree,a3: TSInput): ptr TSTree {.importc: "ts_parser_parse", header: headerruntime.} +proc ts_parser_parse_string*(a1: ptr TSParser,a2: ptr TSTree,a3: cstring,a4: uint32): ptr TSTree {.importc: "ts_parser_parse_string", header: headerruntime.} +proc ts_parser_parse_string_encoding*(a1: ptr TSParser,a2: ptr TSTree,a3: cstring,a4: uint32,a5: TSInputEncoding): ptr TSTree {.importc: "ts_parser_parse_string_encoding", header: headerruntime.} +proc ts_parser_enabled*(a1: ptr TSParser): bool {.importc: "ts_parser_enabled", header: headerruntime.} +proc ts_parser_set_enabled*(a1: ptr TSParser,a2: bool) {.importc: "ts_parser_set_enabled", header: headerruntime.} +proc ts_parser_operation_limit*(a1: ptr TSParser): uint {.importc: "ts_parser_operation_limit", header: headerruntime.} +proc ts_parser_set_operation_limit*(a1: ptr TSParser,a2: uint) {.importc: "ts_parser_set_operation_limit", header: headerruntime.} +proc ts_parser_reset*(a1: ptr TSParser) {.importc: "ts_parser_reset", header: headerruntime.} +proc ts_parser_set_included_ranges*(a1: ptr TSParser,a2: ptr TSRange,a3: uint32) {.importc: "ts_parser_set_included_ranges", header: headerruntime.} +proc ts_parser_included_ranges*(a1: ptr TSParser,a2: ptr uint32): ptr TSRange {.importc: "ts_parser_included_ranges", header: headerruntime.} +proc ts_tree_copy*(a1: ptr TSTree): ptr TSTree {.importc: "ts_tree_copy", header: headerruntime.} +proc ts_tree_delete*(a1: ptr TSTree) {.importc: "ts_tree_delete", header: headerruntime.} +proc ts_tree_root_node*(a1: ptr TSTree): TSNode {.importc: "ts_tree_root_node", header: headerruntime.} +proc ts_tree_edit*(a1: ptr TSTree,a2: ptr TSInputEdit) {.importc: "ts_tree_edit", header: headerruntime.} +proc ts_tree_get_changed_ranges*(a1: ptr TSTree,a2: ptr TSTree,a3: ptr uint32): ptr TSRange {.importc: "ts_tree_get_changed_ranges", header: headerruntime.} +proc ts_tree_print_dot_graph*(a1: ptr TSTree,a2: ptr FILE) {.importc: "ts_tree_print_dot_graph", header: headerruntime.} +proc ts_tree_language*(a1: ptr TSTree): ptr TSLanguage {.importc: "ts_tree_language", header: headerruntime.} +proc ts_node_start_byte*(a1: TSNode): uint32 {.importc: "ts_node_start_byte", header: headerruntime.} +proc ts_node_start_point*(a1: TSNode): TSPoint {.importc: "ts_node_start_point", header: headerruntime.} +proc ts_node_end_byte*(a1: TSNode): uint32 {.importc: "ts_node_end_byte", header: headerruntime.} +proc ts_node_end_point*(a1: TSNode): TSPoint {.importc: "ts_node_end_point", header: headerruntime.} +proc ts_node_symbol*(a1: TSNode): TSSymbol {.importc: "ts_node_symbol", header: headerruntime.} +proc ts_node_type*(a1: TSNode): cstring {.importc: "ts_node_type", header: headerruntime.} +proc ts_node_string*(a1: TSNode): cstring {.importc: "ts_node_string", header: headerruntime.} +proc ts_node_eq*(a1: TSNode,a2: TSNode): bool {.importc: "ts_node_eq", header: headerruntime.} +proc ts_node_is_null*(a1: TSNode): bool {.importc: "ts_node_is_null", header: headerruntime.} +proc ts_node_is_named*(a1: TSNode): bool {.importc: "ts_node_is_named", header: headerruntime.} +proc ts_node_is_missing*(a1: TSNode): bool {.importc: "ts_node_is_missing", header: headerruntime.} +proc ts_node_has_changes*(a1: TSNode): bool {.importc: "ts_node_has_changes", header: headerruntime.} +proc ts_node_has_error*(a1: TSNode): bool {.importc: "ts_node_has_error", header: headerruntime.} +proc ts_node_parent*(a1: TSNode): TSNode {.importc: "ts_node_parent", header: headerruntime.} +proc ts_node_child*(a1: TSNode,a2: uint32): TSNode {.importc: "ts_node_child", header: headerruntime.} +proc ts_node_named_child*(a1: TSNode,a2: uint32): TSNode {.importc: "ts_node_named_child", header: headerruntime.} +proc ts_node_child_count*(a1: TSNode): uint32 {.importc: "ts_node_child_count", header: headerruntime.} +proc ts_node_named_child_count*(a1: TSNode): uint32 {.importc: "ts_node_named_child_count", header: headerruntime.} +proc ts_node_next_sibling*(a1: TSNode): TSNode {.importc: "ts_node_next_sibling", header: headerruntime.} +proc ts_node_next_named_sibling*(a1: TSNode): TSNode {.importc: "ts_node_next_named_sibling", header: headerruntime.} +proc ts_node_prev_sibling*(a1: TSNode): TSNode {.importc: "ts_node_prev_sibling", header: headerruntime.} +proc ts_node_prev_named_sibling*(a1: TSNode): TSNode {.importc: "ts_node_prev_named_sibling", header: headerruntime.} +proc ts_node_first_child_for_byte*(a1: TSNode,a2: uint32): TSNode {.importc: "ts_node_first_child_for_byte", header: headerruntime.} +proc ts_node_first_named_child_for_byte*(a1: TSNode,a2: uint32): TSNode {.importc: "ts_node_first_named_child_for_byte", header: headerruntime.} +proc ts_node_descendant_for_byte_range*(a1: TSNode,a2: uint32,a3: uint32): TSNode {.importc: "ts_node_descendant_for_byte_range", header: headerruntime.} +proc ts_node_named_descendant_for_byte_range*(a1: TSNode,a2: uint32,a3: uint32): TSNode {.importc: "ts_node_named_descendant_for_byte_range", header: headerruntime.} +proc ts_node_descendant_for_point_range*(a1: TSNode,a2: TSPoint,a3: TSPoint): TSNode {.importc: "ts_node_descendant_for_point_range", header: headerruntime.} +proc ts_node_named_descendant_for_point_range*(a1: TSNode,a2: TSPoint,a3: TSPoint): TSNode {.importc: "ts_node_named_descendant_for_point_range", header: headerruntime.} +proc ts_node_edit*(a1: ptr TSNode,a2: ptr TSInputEdit) {.importc: "ts_node_edit", header: headerruntime.} +proc ts_tree_cursor_new*(a1: TSNode): TSTreeCursor {.importc: "ts_tree_cursor_new", header: headerruntime.} +proc ts_tree_cursor_delete*(a1: ptr TSTreeCursor) {.importc: "ts_tree_cursor_delete", header: headerruntime.} +proc ts_tree_cursor_reset*(a1: ptr TSTreeCursor,a2: TSNode) {.importc: "ts_tree_cursor_reset", header: headerruntime.} +proc ts_tree_cursor_current_node*(a1: ptr TSTreeCursor): TSNode {.importc: "ts_tree_cursor_current_node", header: headerruntime.} +proc ts_tree_cursor_goto_parent*(a1: ptr TSTreeCursor): bool {.importc: "ts_tree_cursor_goto_parent", header: headerruntime.} +proc ts_tree_cursor_goto_next_sibling*(a1: ptr TSTreeCursor): bool {.importc: "ts_tree_cursor_goto_next_sibling", header: headerruntime.} +proc ts_tree_cursor_goto_first_child*(a1: ptr TSTreeCursor): bool {.importc: "ts_tree_cursor_goto_first_child", header: headerruntime.} +proc ts_tree_cursor_goto_first_child_for_byte*(a1: ptr TSTreeCursor,a2: uint32): int64 {.importc: "ts_tree_cursor_goto_first_child_for_byte", header: headerruntime.} +proc ts_language_symbol_count*(a1: ptr TSLanguage): uint32 {.importc: "ts_language_symbol_count", header: headerruntime.} +proc ts_language_symbol_name*(a1: ptr TSLanguage,a2: TSSymbol): cstring {.importc: "ts_language_symbol_name", header: headerruntime.} +proc ts_language_symbol_for_name*(a1: ptr TSLanguage,a2: cstring): TSSymbol {.importc: "ts_language_symbol_for_name", header: headerruntime.} +proc ts_language_symbol_type*(a1: ptr TSLanguage,a2: TSSymbol): TSSymbolType {.importc: "ts_language_symbol_type", header: headerruntime.} +proc ts_language_version*(a1: ptr TSLanguage): uint32 {.importc: "ts_language_version", header: headerruntime.} + diff --git a/tests/tmath.nim b/tests/tmath.nim index bee2f29..d5a7166 100644 --- a/tests/tmath.nim +++ b/tests/tmath.nim @@ -3,6 +3,8 @@ import unittest type locale_t = object + mingw_ldbl_type_t = object + mingw_dbl_type_t = object cDebug() diff --git a/toast.nim b/toast.nim index 28f6067..29fb2b1 100644 --- a/toast.nim +++ b/toast.nim @@ -1,8 +1,8 @@ +import nimterop/setup + import os, strformat, strutils -import treesitter/runtime -import treesitter_c/c -import treesitter_cpp/cpp +import nimterop/treesitter/[runtime, c, cpp] import nimterop/[ast, globals, getters, grammar] diff --git a/toast.nims b/toast.nims new file mode 100644 index 0000000..9c2ddac --- /dev/null +++ b/toast.nims @@ -0,0 +1 @@ +switch("d", "NIMTEROP") \ No newline at end of file From d2bd1f7dad18524d74429566bbe73e3d3adeb232 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 16 Jan 2019 17:30:17 -0600 Subject: [PATCH 084/593] Yes to nimble --- .travis.yml | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 6d86766..dbec88d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -27,5 +27,5 @@ install: - export PATH=$HOME/.nimble/bin:$PATH script: - - nimble install + - nimble install -y - nimble test diff --git a/appveyor.yml b/appveyor.yml index 59a0b62..b089567 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -78,7 +78,7 @@ for: - /home/appveyor/binaries build_script: - - nimble install + - nimble install -y test_script: - nimble test From 0e3588d258ed5a2e8eb5e2535fc33056fd43ab53 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 16 Jan 2019 21:28:04 -0600 Subject: [PATCH 085/593] Fix source paths --- nimterop/treesitter/c.nim | 5 ++++- nimterop/treesitter/cpp.nim | 5 ++++- nimterop/treesitter/runtime.nim | 14 +++++++++----- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/nimterop/treesitter/c.nim b/nimterop/treesitter/c.nim index a60d072..9310f97 100644 --- a/nimterop/treesitter/c.nim +++ b/nimterop/treesitter/c.nim @@ -1,5 +1,8 @@ +import strutils + import "."/runtime {.compile: ("../../inc/treesitter_c/src/parser.c", "parserc.o").} -proc treeSitterC*(): ptr TSLanguage {.importc: "tree_sitter_c", header: "inc/treesitter_c/src/parser.h".} +const sourcePath = currentSourcePath().split({'\\', '/'})[0..^4].join("/") +proc treeSitterC*(): ptr TSLanguage {.importc: "tree_sitter_c", header: sourcePath & "/inc/treesitter_c/src/parser.h".} diff --git a/nimterop/treesitter/cpp.nim b/nimterop/treesitter/cpp.nim index 9509139..794d6c0 100644 --- a/nimterop/treesitter/cpp.nim +++ b/nimterop/treesitter/cpp.nim @@ -1,6 +1,9 @@ +import strutils + import "."/runtime {.compile: ("../../inc/treesitter_cpp/src/parser.c", "parsercpp.o").} {.compile: ("../../inc/treesitter_cpp/src/scanner.cc", "scannercpp.o").} -proc treeSitterCpp*(): ptr TSLanguage {.importc: "tree_sitter_cpp", header: "inc/treesitter_cpp/src/parser.h".} +const sourcePath = currentSourcePath().split({'\\', '/'})[0..^4].join("/") & "/inc/treesitter_cpp/src/" +proc treeSitterCpp*(): ptr TSLanguage {.importc: "tree_sitter_cpp", header: sourcePath & "parser.h".} diff --git a/nimterop/treesitter/runtime.nim b/nimterop/treesitter/runtime.nim index 34ce237..6650aaf 100644 --- a/nimterop/treesitter/runtime.nim +++ b/nimterop/treesitter/runtime.nim @@ -1,10 +1,14 @@ {.experimental: "codeReordering".} +import strutils + +const sourcePath = currentSourcePath().split({'\\', '/'})[0..^4].join("/") & "/inc/treesitter" + {.passC: "-std=c11 -DUTF8PROC_STATIC".} -{.passC: "-Iinc/treesitter/include".} -{.passC: "-Iinc/treesitter/src".} -{.passC: "-Iinc/utf8proc".} -{.compile: "../../inc/treesitter/src/runtime/runtime.c".} +{.passC: "-I$1/include" % sourcePath.} +{.passC: "-I$1/src" % sourcePath.} +{.passC: "-I$1/../utf8proc" % sourcePath.} +{.compile: sourcePath & "/src/runtime/runtime.c".} type TSInputEncoding* = distinct int converter enumToInt(en: TSInputEncoding): int {.used.} = en.int @@ -16,7 +20,7 @@ type TSLogType* = distinct int converter enumToInt(en: TSLogType): int {.used.} = en.int const - headerruntime = "inc/treesitter/include/tree_sitter/runtime.h" + headerruntime = sourcePath & "/include/tree_sitter/runtime.h" TREE_SITTER_LANGUAGE_VERSION* = 9 TSInputEncodingUTF8* = 0.TSInputEncoding TSInputEncodingUTF16* = 1.TSInputEncoding From ab3543cbdaed38fa4f79ce5479e2db37110a53ee Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 16 Jan 2019 21:49:17 -0600 Subject: [PATCH 086/593] Workaround 0.19.2 crash --- nimterop/cimport.nim | 4 +++- nimterop/globals.nim | 6 +++--- nimterop/treesitter/runtime.nim | 2 +- toast.nims | 1 - 4 files changed, 7 insertions(+), 6 deletions(-) delete mode 100644 toast.nims diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index 14c689d..91de727 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -1,6 +1,8 @@ import macros, os, strformat, strutils -import "."/globals +const CIMPORT = 1 + +include "."/globals proc interpPath(dir: string): string= # TODO: more robust: needs a DirSep after "$projpath" diff --git a/nimterop/globals.nim b/nimterop/globals.nim index 6ba64c1..5fb100c 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -2,7 +2,7 @@ import tables import regex -when defined(NIMTEROP): +when not defined(CIMPORT): import "."/treesitter/runtime type @@ -17,7 +17,7 @@ type name*: string kind*: Kind children*: seq[ref Ast] - when defined(NIMTEROP): + when not defined(CIMPORT): tonim*: proc (ast: ref Ast, node: TSNode) regex*: Regex @@ -33,7 +33,7 @@ type ast*: Table[string, seq[ref Ast]] data*: seq[tuple[name, val: string]] - when defined(NIMTEROP): + when not defined(CIMPORT): grammar*: seq[tuple[grammar: string, call: proc(ast: ref Ast, node: TSNode) {.nimcall.}]] var diff --git a/nimterop/treesitter/runtime.nim b/nimterop/treesitter/runtime.nim index 6650aaf..ca93fd4 100644 --- a/nimterop/treesitter/runtime.nim +++ b/nimterop/treesitter/runtime.nim @@ -2,7 +2,7 @@ import strutils -const sourcePath = currentSourcePath().split({'\\', '/'})[0..^4].join("/") & "/inc/treesitter" +const sourcePath = currentSourcePath().split({'\\', '/'})[0..^4].join("/") & "/inc/treesitter" {.passC: "-std=c11 -DUTF8PROC_STATIC".} {.passC: "-I$1/include" % sourcePath.} diff --git a/toast.nims b/toast.nims deleted file mode 100644 index 9c2ddac..0000000 --- a/toast.nims +++ /dev/null @@ -1 +0,0 @@ -switch("d", "NIMTEROP") \ No newline at end of file From a491201bb2508c48bfb3ef34164c4dc3845fb1cb Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 17 Jan 2019 08:28:57 -0600 Subject: [PATCH 087/593] Call setup on per wrapper basis --- nimterop/git.nim | 6 +++--- nimterop/globals.nim | 6 +++--- nimterop/setup.nim | 26 ++++++++++++++++---------- nimterop/treesitter/c.nim | 5 +++++ nimterop/treesitter/cpp.nim | 5 +++++ nimterop/treesitter/runtime.nim | 5 +++++ toast.nim | 2 -- 7 files changed, 37 insertions(+), 18 deletions(-) diff --git a/nimterop/git.nim b/nimterop/git.nim index bebf75e..8617b8b 100644 --- a/nimterop/git.nim +++ b/nimterop/git.nim @@ -1,7 +1,5 @@ import macros, os, osproc, regex, strformat, strutils -import "."/globals - proc execAction*(cmd: string, nostderr=false): string = var ccmd = "" @@ -78,7 +76,9 @@ macro gitPull*(url: static string, outdirN = "", plistN = "", checkoutN = ""): u gitReset(`outdirN`) return else: - echo execAction(&"mkdir \"{outdir}\"") + let + flag = when not defined(Windows): "-p" else: "" + echo execAction(&"mkdir {flag} \"{outdir}\"") echo "Setting up Git repo: " & url discard execAction(&"cd \"{outdir}\" && git init .") diff --git a/nimterop/globals.nim b/nimterop/globals.nim index 5fb100c..121b799 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -2,7 +2,7 @@ import tables import regex -when not defined(CIMPORT): +when not declared(CIMPORT): import "."/treesitter/runtime type @@ -17,7 +17,7 @@ type name*: string kind*: Kind children*: seq[ref Ast] - when not defined(CIMPORT): + when not declared(CIMPORT): tonim*: proc (ast: ref Ast, node: TSNode) regex*: Regex @@ -33,7 +33,7 @@ type ast*: Table[string, seq[ref Ast]] data*: seq[tuple[name, val: string]] - when not defined(CIMPORT): + when not declared(CIMPORT): grammar*: seq[tuple[grammar: string, call: proc(ast: ref Ast, node: TSNode) {.nimcall.}]] var diff --git a/nimterop/setup.nim b/nimterop/setup.nim index baa9ecb..c3edb99 100644 --- a/nimterop/setup.nim +++ b/nimterop/setup.nim @@ -2,7 +2,7 @@ import os, strutils import "."/git -static: +proc treesitterSetup*() = gitPull("https://github.com/tree-sitter/tree-sitter/", "inc/treesitter", """ include/* src/runtime/* @@ -13,12 +13,27 @@ src/runtime/* *.h """) + let + stack = "inc/treesitter/src/runtime/stack.c" + + stack.writeFile(stack.readFile().replace("inline Stack", "Stack")) + +proc treesitterCSetup*() = gitPull("https://github.com/tree-sitter/tree-sitter-c", "inc/treesitter_c", """ src/*.h src/*.c src/*.cc """) + let + headerc = "inc/treesitter_c/src/parser.h" + + headerc.writeFile(""" + typedef struct TSLanguage TSLanguage; + const TSLanguage *tree_sitter_c(); + """) + +proc treesitterCppSetup*() = gitPull("https://github.com/tree-sitter/tree-sitter-cpp", "inc/treesitter_cpp", """ src/*.h src/*.c @@ -26,17 +41,8 @@ src/*.cc """) let - stack = "inc/treesitter/src/runtime/stack.c" - headerc = "inc/treesitter_c/src/parser.h" headercpp = "inc/treesitter_cpp/src/parser.h" - stack.writeFile(stack.readFile().replace("inline Stack", "Stack")) - - headerc.writeFile(""" - typedef struct TSLanguage TSLanguage; - const TSLanguage *tree_sitter_c(); - """) - headercpp.writeFile(""" typedef struct TSLanguage TSLanguage; const TSLanguage *tree_sitter_cpp(); diff --git a/nimterop/treesitter/c.nim b/nimterop/treesitter/c.nim index 9310f97..da13f2e 100644 --- a/nimterop/treesitter/c.nim +++ b/nimterop/treesitter/c.nim @@ -1,5 +1,10 @@ import strutils +import ".."/setup + +static: + treesitterCSetup() + import "."/runtime {.compile: ("../../inc/treesitter_c/src/parser.c", "parserc.o").} diff --git a/nimterop/treesitter/cpp.nim b/nimterop/treesitter/cpp.nim index 794d6c0..ec6cf2c 100644 --- a/nimterop/treesitter/cpp.nim +++ b/nimterop/treesitter/cpp.nim @@ -1,5 +1,10 @@ import strutils +import ".."/setup + +static: + treesitterCppSetup() + import "."/runtime {.compile: ("../../inc/treesitter_cpp/src/parser.c", "parsercpp.o").} diff --git a/nimterop/treesitter/runtime.nim b/nimterop/treesitter/runtime.nim index ca93fd4..b255eba 100644 --- a/nimterop/treesitter/runtime.nim +++ b/nimterop/treesitter/runtime.nim @@ -2,6 +2,11 @@ import strutils +import ".."/setup + +static: + treesitterSetup() + const sourcePath = currentSourcePath().split({'\\', '/'})[0..^4].join("/") & "/inc/treesitter" {.passC: "-std=c11 -DUTF8PROC_STATIC".} diff --git a/toast.nim b/toast.nim index 29fb2b1..712d1a7 100644 --- a/toast.nim +++ b/toast.nim @@ -1,5 +1,3 @@ -import nimterop/setup - import os, strformat, strutils import nimterop/treesitter/[runtime, c, cpp] From f2b3ffc862b6e7cf768111b04aabdb191d9c87be Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 17 Jan 2019 08:45:04 -0600 Subject: [PATCH 088/593] OSX fix, test 0.19.0 as well --- .travis.yml | 17 ++++++----------- appveyor.yml | 1 + nimterop/treesitter/runtime.nim | 4 +++- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/.travis.yml b/.travis.yml index dbec88d..347263a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,19 +5,14 @@ os: language: c env: - # test against both stable & devel - - BRANCH=stable + - BRANCH=0.19.0 + - BRANCH=0.19.2 - BRANCH=devel -# cache: - # directories: - # - "$HOME/.nimble" - # - "$HOME/.choosenim" - -# matrix: - # allow_failures: - # - env: BRANCH=devel - # fast_finish: true +cache: + directories: + - "$HOME/.choosenim/toolchains/nim-0.19.0" + - "$HOME/.choosenim/toolchains/nim-0.19.2" install: - export CHOOSENIM_CHOOSE_VERSION=$BRANCH diff --git a/appveyor.yml b/appveyor.yml index b089567..72c2033 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -9,6 +9,7 @@ matrix: environment: matrix: + - NIM_VERSION: 0.19.0 - NIM_VERSION: 0.19.2 for: diff --git a/nimterop/treesitter/runtime.nim b/nimterop/treesitter/runtime.nim index b255eba..d5fbed5 100644 --- a/nimterop/treesitter/runtime.nim +++ b/nimterop/treesitter/runtime.nim @@ -9,7 +9,9 @@ static: const sourcePath = currentSourcePath().split({'\\', '/'})[0..^4].join("/") & "/inc/treesitter" -{.passC: "-std=c11 -DUTF8PROC_STATIC".} +when defined(Linux): + {.passC: "-std=c11".} +{.passC: "-DUTF8PROC_STATIC".} {.passC: "-I$1/include" % sourcePath.} {.passC: "-I$1/src" % sourcePath.} {.passC: "-I$1/../utf8proc" % sourcePath.} From 4883780f8fe5fec4b2b436192f388a5e81fa4cb8 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 17 Jan 2019 09:38:05 -0600 Subject: [PATCH 089/593] Update install instructions --- README.md | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index cc51f4e..457903f 100644 --- a/README.md +++ b/README.md @@ -21,16 +21,12 @@ __Installation__ Nimterop can be installed via [Nimble](https://github.com/nim-lang/nimble): ```bash -nimble install "http://github.com/genotrance/nimtreesitter?subdir=treesitter" -nimble install "http://github.com/genotrance/nimtreesitter?subdir=treesitter_c" -nimble install "http://github.com/genotrance/nimtreesitter?subdir=treesitter_cpp" - -nimble install http://github.com/genotrance/nimterop +nimble install nimterop -y ``` or: ```bash git clone http://github.com/genotrance/nimterop && cd nimterop -nimble installWithDeps +nimble install -y ``` This will download and install nimterop in the standard Nimble package location, typically `~/.nimble`. Once installed, it can be imported into any Nim program. Note that the `~/.nimble/bin` directory needs to be added to the `PATH` for nimterop to work. From 3d9cf10f8a7f5c779af110faf47211feff029581 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 17 Jan 2019 09:49:42 -0600 Subject: [PATCH 090/593] Fix nimble install --- nimterop/setup.nim | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/nimterop/setup.nim b/nimterop/setup.nim index c3edb99..06f15d4 100644 --- a/nimterop/setup.nim +++ b/nimterop/setup.nim @@ -2,6 +2,8 @@ import os, strutils import "."/git +const sourcePath = currentSourcePath().split({'\\', '/'})[0..^3].join("/") & "/inc" + proc treesitterSetup*() = gitPull("https://github.com/tree-sitter/tree-sitter/", "inc/treesitter", """ include/* @@ -14,7 +16,7 @@ src/runtime/* """) let - stack = "inc/treesitter/src/runtime/stack.c" + stack = sourcePath & "/treesitter/src/runtime/stack.c" stack.writeFile(stack.readFile().replace("inline Stack", "Stack")) @@ -26,7 +28,7 @@ src/*.cc """) let - headerc = "inc/treesitter_c/src/parser.h" + headerc = sourcePath & "/treesitter_c/src/parser.h" headerc.writeFile(""" typedef struct TSLanguage TSLanguage; @@ -41,9 +43,9 @@ src/*.cc """) let - headercpp = "inc/treesitter_cpp/src/parser.h" + headercpp = sourcePath & "/treesitter_cpp/src/parser.h" headercpp.writeFile(""" typedef struct TSLanguage TSLanguage; const TSLanguage *tree_sitter_cpp(); - """) \ No newline at end of file + """) From 43193f59500e69c2ce9257ad890d924680df6e97 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 17 Jan 2019 10:30:52 -0600 Subject: [PATCH 091/593] Fix C data types --- nimterop/getters.nim | 46 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 38 insertions(+), 8 deletions(-) diff --git a/nimterop/getters.nim b/nimterop/getters.nim index ede88fc..e066858 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -27,22 +27,52 @@ xor yield""".split(Whitespace) const gTypeMap = { - "long": "clong", - "unsigned long": "culong", + # char "char": "cchar", "signed char": "cschar", + "unsigned char": "cuchar", + + # short "short": "cshort", + "short int": "cshort", + "signed short": "cshort", + "signed short int": "cshort", + "unsigned short": "cushort", + "unsigned short int": "cushort", + + # int "int": "cint", - "size_t": "uint", - "ssize_t": "int", + "signed": "cint", + "signed int": "cint", + "ssize_t": "cint", + "unsigned": "cuint", + "unsigned int": "cuint", + "size_t": "cuint", + + # long + "long": "clong", + "long int": "clong", + "signed long": "clong", + "signed long int": "clong", + "off_t": "clong", + "unsigned long": "culong", + "unsigned long int": "culong", + + # long long "long long": "clonglong", + "long long int": "clonglong", + "signed long long": "clonglong", + "signed long long int": "clonglong", + "off64_t": "clonglong", + "unsigned long long": "culonglong", + "unsigned long long int": "culonglong", + + # floating point "float": "cfloat", "double": "cdouble", "long double": "clongdouble", - "unsigned char": "cuchar", - "unsigned short": "cushort", - "unsigned int": "cuint", - "unsigned long long": "culonglong", + + # misc "time_t": "int32" }.toTable() From 09d9794bb648ed2e0eb94bce1cebdbb66adf1c0f Mon Sep 17 00:00:00 2001 From: genotrance Date: Thu, 17 Jan 2019 20:26:51 -0600 Subject: [PATCH 092/593] Walkdir (#43) * Fix walkDir, cCompile mode, add tsoloud, fix void * * No tsoloud on Travis Linux --- README.md | 6 +++++ nimterop.nimble | 12 +++++++++- nimterop/cimport.nim | 53 +++++++++++++++++++++++++++++++++++--------- nimterop/grammar.nim | 5 ++--- tests/tsoloud.nim | 37 +++++++++++++++++++++++++++++++ 5 files changed, 99 insertions(+), 14 deletions(-) create mode 100644 tests/tsoloud.nim diff --git a/README.md b/README.md index 457903f..a4d3098 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,12 @@ Detailed documentation is still forthcoming. `cImport("header.h", recurse=true)` - import all supported definitions from header file and #includes +`cCompile("file.c")` - compile C/C++ implementation into binary + +`cCompile("path/to/*.c")` - compile in all files matching wildcard + +`cCompile("path/to/dir", "cpp")` - compile in all C++ files found recursively + `cAddSearchDir("XXX")` - add directory XXX to search path in calls to `cSearchPath()` `cAddStdDir("XXX")` - add standard "c" [default] or "cpp" include paths to search path diff --git a/nimterop.nimble b/nimterop.nimble index ca9040e..11d8342 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -12,10 +12,14 @@ installDirs = @["nimterop"] requires "nim >= 0.19.0", "regex >= 0.10.0", "cligen >= 0.9.17" -proc execCmd(cmd:string)= +proc execCmd(cmd: string) = echo cmd exec cmd +proc tsoloud() = + execCmd "nim c -r tests/tsoloud.nim" + execCmd "nim cpp -r tests/tsoloud.nim" + task test, "Test": execCmd "nim c -r tests/tnimterop_c.nim" execCmd "nim cpp -r tests/tnimterop_c.nim" @@ -23,3 +27,9 @@ task test, "Test": when defined(windows): execCmd "nim c -r tests/tmath.nim" execCmd "nim cpp -r tests/tmath.nim" + when not defined(OSX): + when defined(Windows): + tsoloud() + else: + if not existsEnv("TRAVIS"): + tsoloud() \ No newline at end of file diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index 91de727..2ff6251 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -1,6 +1,6 @@ import macros, os, strformat, strutils -const CIMPORT = 1 +const CIMPORT {.used.} = 1 include "."/globals @@ -23,6 +23,36 @@ proc findPath(path: string, fail = true): string = else: return "" +proc walkDirImpl(indir, inext: string, file=true): seq[string] = + let + dir = joinPathIfRel(getProjectPath(), indir) + ext = + if inext.len != 0: + when not defined(Windows): + "-name " & inext + else: + "\\" & inext + else: + "" + + let + cmd = + when defined(Windows): + if file: + "cmd /c dir /s/b/a-d " & dir.replace("/", "\\") & ext + else: + "cmd /c dir /s/b/ad " & dir.replace("/", "\\") + else: + if file: + "find $1 -type f $2" % [dir, ext] + else: + "find $1 -type d" % dir + + (output, ret) = gorgeEx(cmd) + + if ret == 0: + result = output.splitLines() + proc getToast(fullpath: string, recurse: bool = false): string = var cmd = when defined(Windows): "cmd /c " else: "" @@ -125,12 +155,11 @@ macro cAddStdDir*(mode = "c"): untyped = result.add quote do: cAddSearchDir(`sline`) -macro cCompile*(path: static string): untyped = +macro cCompile*(path: static string, mode = "c"): untyped = result = newNimNode(nnkStmtList) var stmt = "" - flags = "" proc fcompile(file: string): string = let fn = file.splitFile().name @@ -147,22 +176,26 @@ macro cCompile*(path: static string): untyped = else: return "{.compile: (\"../$#\", \"$#.o\").}" % [file.replace("\\", "/"), ufn] - proc dcompile(dir: string) = - for f in walkFiles(dir): - stmt &= fcompile(f) & "\n" + proc dcompile(dir: string, ext=""): string = + let + files = walkDirImpl(dir, ext) + + for f in files: + if f.len != 0: + result &= fcompile(f) & "\n" if path.contains("*") or path.contains("?"): - dcompile(path) + stmt &= dcompile(path) else: let fpath = findPath(path) if fileExists(fpath): stmt &= fcompile(fpath) & "\n" elif dirExists(fpath): - if flags.contains("cpp"): + if mode.strVal().contains("cpp"): for i in @["*.C", "*.cpp", "*.c++", "*.cc", "*.cxx"]: - dcompile(fpath / i) + stmt &= dcompile(fpath, i) else: - dcompile(fpath / "*.c") + stmt &= dcompile(fpath, "*.c") result.add stmt.parseStmt() diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index e6a0fe2..d2632b8 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -82,8 +82,7 @@ proc initGrammar() = pname = "a" & $count count += 1 i += 1 - if ptyp != "object": - pout &= &"{pname}: {getPtrType(pptr&ptyp)}," + pout &= &"{pname}: {getPtrType(pptr&ptyp)}," # typedef int X # typedef X Y @@ -149,7 +148,7 @@ proc initGrammar() = flen = gStateRT.data[i].val.getIdentifier() gStateRT.typeStr &= &" {name}* = {aptr}array[{flen}, {getPtrType(tptr&typ)}]\n" else: - if name == typ or typ == "object": + if name == typ: gStateRT.typeStr &= &" {name}* = object\n" else: gStateRT.typeStr &= &" {name}* = {getPtrType(tptr&typ)}\n" diff --git a/tests/tsoloud.nim b/tests/tsoloud.nim new file mode 100644 index 0000000..544c1af --- /dev/null +++ b/tests/tsoloud.nim @@ -0,0 +1,37 @@ +import os, nimterop/[cimport, git] + +gitPull("https://github.com/jarikomppa/soloud", "soloud", "include/*\nsrc/*\n") + +cDebug() + +const + inc = "soloud/include" + src = "soloud/src" + +cIncludeDir(inc) + +when defined(Linux): + {.passL: "-lpthread".} + cDefine("WITH_OSS") + cCompile(src/"backend/oss/*.cpp") + +when defined(Windows): + {.passC: "-msse".} + {.passL: "-lwinmm".} + cDefine("WITH_WINMM") + cCompile(src/"backend/winmm/*.cpp") + +cCompile(src/"c_api/soloud_c.cpp") +cCompile(src/"core/*.cpp") +cCompile(src/"audiosource", "cpp") +cCompile(src/"audiosource", "c") +cCompile(src/"filter/*.cpp") + +cImport(inc/"soloud_c.h") + +var + s = Soloud_create() + +echo s.Soloud_init() + +s.Soloud_destroy() \ No newline at end of file From 8a09f3e290a7d36c9a7b8dc3795e993a8fe3a94b Mon Sep 17 00:00:00 2001 From: Ico Doornekamp Date: Fri, 18 Jan 2019 03:40:56 +0100 Subject: [PATCH 093/593] Added ptrdiff_t (#38) --- nimterop/getters.nim | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nimterop/getters.nim b/nimterop/getters.nim index e066858..d6f17c6 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -73,7 +73,8 @@ const gTypeMap = { "long double": "clongdouble", # misc - "time_t": "int32" + "time_t": "int32", + "ptrdiff_t": "ByteAddress" }.toTable() proc sanitizePath*(path: string): string = From 287980c9edbb1f037b1827b62ca8cc3453b2203a Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 17 Jan 2019 22:19:26 -0600 Subject: [PATCH 094/593] Use HashSet, fix #40, compare nimNames --- nimterop/ast.nim | 4 ++-- nimterop/getters.nim | 14 +++++++++----- nimterop/globals.nim | 4 ++-- nimterop/grammar.nim | 27 ++++++++++++++------------- 4 files changed, 27 insertions(+), 22 deletions(-) diff --git a/nimterop/ast.nim b/nimterop/ast.nim index 13dcf2c..6981deb 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -1,4 +1,4 @@ -import strformat, strutils, tables +import sets, strformat, strutils, tables import regex @@ -14,7 +14,7 @@ const gAtoms = @[ "primitive_type", "sized_type_specifier", "type_identifier" -] +].toSet() proc saveNodeData(node: TSNode): bool = let name = $node.tsNodeType() diff --git a/nimterop/getters.nim b/nimterop/getters.nim index d6f17c6..59dbb15 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -1,4 +1,4 @@ -import macros, os, strformat, strutils, tables +import macros, os, sets, strformat, strutils, tables import regex @@ -24,7 +24,7 @@ using var when while xor -yield""".split(Whitespace) +yield""".split(Whitespace).toSet() const gTypeMap = { # char @@ -92,21 +92,25 @@ proc getType*(str: string): string = result = gTypeMap[result] proc getIdentifier*(str: string): string = - result = str.strip(chars={'_'}).replace(re"_+", "_").getType() + result = str.strip(chars={'_'}).replace(re"_+", "_") if result in gReserved: result = &"`{result}`" -proc getUniqueIdentifier*(exists: seq[string], prefix = ""): string = +proc getUniqueIdentifier*(existing: HashSet[string], prefix = ""): string = var name = prefix & "_" & gStateRT.sourceFile.extractFilename().multiReplace([(".", ""), ("-", "")]) + nimName = name.replace("_", "").toLowerAscii count = 1 - while (name & $count) in exists: + while (nimName & $count) in existing: count += 1 return name & $count +proc addNewIdentifer*(existing: var HashSet[string], name: string): bool = + return not existing.containsOrIncl(name.replace("_", "").toLowerAscii) + proc getPtrType*(str: string): string = result = case str: of "ptr cchar": diff --git a/nimterop/globals.nim b/nimterop/globals.nim index 121b799..ed69ff5 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -1,4 +1,4 @@ -import tables +import sets, tables import regex @@ -26,7 +26,7 @@ type debug*, past*, preprocess*, pnim*, pretty*, recurse*: bool - consts*, enums*, procs*, types*: seq[string] + consts*, enums*, procs*, types*: HashSet[string] code*, constStr*, currentHeader*, debugStr*, enumStr*, mode*, procStr*, typeStr*: string sourceFile*: string # eg, C or C++ source or header file diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index d2632b8..ae46404 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -1,4 +1,4 @@ -import strformat, strutils, tables +import sets, strformat, strutils, tables import regex @@ -17,8 +17,7 @@ proc initGrammar() = name = gStateRT.data[0].val.getIdentifier() val = gStateRT.data[1].val.getLit() - if name notin gStateRT.consts and val.nBl: - gStateRT.consts.add(name) + if val.nBl and gStateRT.consts.addNewIdentifer(name): gStateRT.constStr &= &" {name}* = {val}\n" )) @@ -82,7 +81,8 @@ proc initGrammar() = pname = "a" & $count count += 1 i += 1 - pout &= &"{pname}: {getPtrType(pptr&ptyp)}," + if pptr == "ptr " or ptyp != "object": + pout &= &"{pname}: {getPtrType(pptr&ptyp)}," # typedef int X # typedef X Y @@ -123,7 +123,7 @@ proc initGrammar() = name = gStateRT.data[i].val.getIdentifier() i += 1 - if name notin gStateRT.types: + if gStateRT.types.addNewIdentifer(name): if i < gStateRT.data.len and gStateRT.data[^1].name == "function_declarator": var pout, pname, ptyp, pptr = "" @@ -142,7 +142,6 @@ proc initGrammar() = else: gStateRT.typeStr &= &" {name}* = proc({pout}) {{.nimcall.}}\n" else: - gStateRT.types.add(name) if i < gStateRT.data.len and gStateRT.data[i].name in ["identifier", "number_literal"]: let flen = gStateRT.data[i].val.getIdentifier() @@ -176,8 +175,7 @@ proc initGrammar() = union = " {.union.}" break - if nname notin gStateRT.types: - gStateRT.types.add(nname) + if gStateRT.types.addNewIdentifer(nname): gStateRT.typeStr &= &" {nname}* {{.importc: \"{prefix}{name}\", header: {gStateRT.currentHeader}, bycopy.}} = object{union}\n" var @@ -310,8 +308,7 @@ proc initGrammar() = if nname.len == 0: nname = getUniqueIdentifier(gStateRT.enums, "Enum") - if nname notin gStateRT.enums: - gStateRT.enums.add(nname) + if gStateRT.enums.addNewIdentifer(nname): gStateRT.enumStr &= &"\ntype {nname}* = distinct int" gStateRT.enumStr &= &"\nconverter enumToInt(en: {nname}): int {{.used.}} = en.int\n" @@ -326,7 +323,7 @@ proc initGrammar() = i += 1 continue - if fname notin gStateRT.consts: + if gStateRT.consts.addNewIdentifer(fname): if i+1 < gStateRT.data.len-fend and gStateRT.data[i+1].name in ["identifier", "shift_expression", "math_expression", "number_literal"]: if " " in gStateRT.data[i+1].val: @@ -432,8 +429,7 @@ proc initGrammar() = if pout.len != 0 and pout[^1] == ',': pout = pout[0 .. ^2] - if fnname notin gStateRT.procs: - gStateRT.procs.add(fnname) + if gStateRT.procs.addNewIdentifer(fnname): if ftyp != "object": gStateRT.procStr &= &"proc {fnname}*({pout}): {getPtrType(fptr&ftyp)} {{.importc: \"{fname}\", header: {gStateRT.currentHeader}.}}\n" else: @@ -456,6 +452,11 @@ proc initRegex(ast: ref Ast) = raise newException(Exception, getCurrentExceptionMsg()) proc parseGrammar*() = + gStateRT.consts.init() + gStateRT.enums.init() + gStateRT.procs.init() + gStateRT.types.init() + initGrammar() gStateRT.ast = initTable[string, seq[ref Ast]]() From dd234ab7eff217d9d14df7d0fe16ff44466f5be9 Mon Sep 17 00:00:00 2001 From: genotrance Date: Fri, 18 Jan 2019 22:39:22 -0600 Subject: [PATCH 095/593] Recursive node support, enum expressions, or/and/not (#45) --- nimterop/ast.nim | 29 +++++++++++++---------------- nimterop/getters.nim | 15 ++++++++++----- nimterop/globals.nim | 26 +++++++++++++++++++++++++- nimterop/grammar.nim | 25 ++++++++++++------------- nimterop/lisp.nim | 8 +++++--- tests/include/test.h | 6 ++++++ tests/tnimterop_c.nim | 4 ++++ 7 files changed, 75 insertions(+), 38 deletions(-) diff --git a/nimterop/ast.nim b/nimterop/ast.nim index 6981deb..6498c93 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -4,18 +4,6 @@ import regex import "."/[getters, globals, grammar, treesitter/runtime] -const gAtoms = @[ - "field_identifier", - "identifier", - "shift_expression", - "math_expression", - "number_literal", - "preproc_arg", - "primitive_type", - "sized_type_specifier", - "type_identifier" -].toSet() - proc saveNodeData(node: TSNode): bool = let name = $node.tsNodeType() if name in gAtoms: @@ -25,10 +13,10 @@ proc saveNodeData(node: TSNode): bool = if name == "primitive_type" and node.tsNodeParent.tsNodeType() == "sized_type_specifier": return true - if name == "number_literal" and $node.tsNodeParent.tsNodeType() in ["shift_expression", "math_expression"]: + if name == "number_literal" and $node.tsNodeParent.tsNodeType() in gExpressions: return true - if name in ["math_expression", "primitive_type", "sized_type_specifier"]: + if name in ["primitive_type", "sized_type_specifier"]: val = val.getType() let @@ -52,6 +40,10 @@ proc saveNodeData(node: TSNode): bool = ppname == "function_declarator": gStateRT.data.add(("function_declarator", "")) + elif name in gExpressions: + if $node.tsNodeParent.tsNodeType() notin gExpressions: + gStateRT.data.add((name, node.getNodeVal())) + elif name in ["abstract_pointer_declarator", "enumerator", "field_declaration", "function_declarator"]: gStateRT.data.add((name.replace("abstract_", ""), "")) @@ -65,14 +57,19 @@ proc searchAstForNode(ast: ref Ast, node: TSNode): bool = return if ast.children.len != 0: - if childNames.contains(ast.regex): + if childNames.contains(ast.regex) or + (childNames.len == 0 and ast.recursive): if node.getTSNodeNamedChildCountSansComments() != 0: var flag = true for i in 0 .. node.tsNodeNamedChildCount()-1: if $node.tsNodeNamedChild(i).tsNodeType() != "comment": let nodeChild = node.tsNodeNamedChild(i) - astChild = ast.getAstChildByName($nodeChild.tsNodeType()) + astChild = + if not ast.recursive: + ast.getAstChildByName($nodeChild.tsNodeType()) + else: + ast if not searchAstForNode(astChild, nodeChild): flag = false break diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 59dbb15..1b39247 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -236,12 +236,16 @@ converter toKind*(kind: string): Kind = else: exactlyOne -proc getNameKind*(name: string): tuple[name: string, kind: Kind] = - result.name = name +proc getNameKind*(name: string): tuple[name: string, kind: Kind, recursive: bool] = + if name[0] == '^': + result.recursive = true + result.name = name[1 .. ^1] + else: + result.name = name result.kind = $name[^1] if result.kind != exactlyOne: - result.name = name[0 .. ^2] + result.name = result.name[0 .. ^2] proc getTSNodeNamedChildCountSansComments*(node: TSNode): int = if node.tsNodeNamedChildCount() != 0: @@ -261,8 +265,9 @@ proc getTSNodeNamedChildNames*(node: TSNode): seq[string] = proc getRegexForAstChildren*(ast: ref Ast): string = result = "^" for i in 0 .. ast.children.len-1: - let kind: string = ast.children[i].kind - let begin = if result[^1] == '|': "" else: "(?:" + let + kind: string = ast.children[i].kind + begin = if result[^1] == '|': "" else: "(?:" case kind: of "!": result &= &"{begin}{ast.children[i].name}|" diff --git a/nimterop/globals.nim b/nimterop/globals.nim index ed69ff5..0c81e27 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -1,10 +1,33 @@ -import sets, tables +import sequtils, sets, tables import regex when not declared(CIMPORT): import "."/treesitter/runtime +const + gAtoms* = @[ + "field_identifier", + "identifier", + "number_literal", + "preproc_arg", + "primitive_type", + "sized_type_specifier", + "type_identifier" + ].toSet() + + gExpressions* = @[ + "parenthesized_expression", + "bitwise_expression", + "shift_expression", + "math_expression" + ].toSet() + + gEnumVals* = @[ + "identifier", + "number_literal" + ].concat(toSeq(gExpressions.items)) + type Kind* = enum exactlyOne @@ -16,6 +39,7 @@ type Ast* = object name*: string kind*: Kind + recursive*: bool children*: seq[ref Ast] when not declared(CIMPORT): tonim*: proc (ast: ref Ast, node: TSNode) diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index ae46404..ee42825 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -325,14 +325,15 @@ proc initGrammar() = if gStateRT.consts.addNewIdentifer(fname): if i+1 < gStateRT.data.len-fend and - gStateRT.data[i+1].name in ["identifier", "shift_expression", "math_expression", "number_literal"]: - if " " in gStateRT.data[i+1].val: - gStateRT.data[i+1].val = "(" & gStateRT.data[i+1].val.replace(" ", "") & ")" + gStateRT.data[i+1].name in gEnumVals: gStateRT.data[i+1].val = gStateRT.data[i+1].val.multiReplace([ - ("<<", " shl "), (">>", " shr ") + (" ", ""), + ("<<", " shl "), (">>", " shr "), + ("^", " xor "), ("&", " and "), ("|", " or "), + ("~", " not ") ]) - gStateRT.constStr &= &" {fname}* = {gStateRT.data[i+1].val}.{nname}\n" + gStateRT.constStr &= &" {fname}* = ({gStateRT.data[i+1].val}).{nname}\n" try: count = gStateRT.data[i+1].val.parseInt() + 1 except: @@ -349,15 +350,12 @@ proc initGrammar() = (type_identifier?) (enumerator_list (enumerator+ - (identifier+) - (number_literal?) - (shift_expression|math_expression? - (number_literal+) - ) + (identifier?) + (^$1+) ) ) ) - """, + """ % gEnumVals.join("|"), proc (ast: ref Ast, node: TSNode) = var name = "" @@ -439,8 +437,9 @@ proc initGrammar() = proc initRegex(ast: ref Ast) = if ast.children.len != 0: - for child in ast.children: - child.initRegex() + if not ast.recursive: + for child in ast.children: + child.initRegex() var reg: string diff --git a/nimterop/lisp.nim b/nimterop/lisp.nim index 3d3c34e..c21c3be 100644 --- a/nimterop/lisp.nim +++ b/nimterop/lisp.nim @@ -34,8 +34,10 @@ proc readFromTokens(): ref Ast = quit(1) if gTokens[idx+1] != "comment": result = new(Ast) - (result.name, result.kind) = gTokens[idx+1].getNameKind() + (result.name, result.kind, result.recursive) = gTokens[idx+1].getNameKind() result.children = @[] + if result.recursive: + result.children.add(result) idx += 2 while gTokens[idx] != ")": var res = readFromTokens() @@ -48,9 +50,9 @@ proc readFromTokens(): ref Ast = idx += 1 proc printAst*(node: ref Ast, offset=""): string = - result = offset & "(" & node.name & node.kind.toString() + result = offset & "(" & (if node.recursive: "^" else: "") & node.name & node.kind.toString() - if node.children.len != 0: + if node.children.len != 0 and not node.recursive: result &= "\n" for child in node.children: result &= printAst(child, offset & " ") diff --git a/tests/include/test.h b/tests/include/test.h index 8a8c579..64bdbb2 100644 --- a/tests/include/test.h +++ b/tests/include/test.h @@ -60,6 +60,12 @@ typedef enum ENUM4 { enum12 } ENUM4; +enum ENUM5 { + enum13 = (1 << 2), + enum14 = ((1 << 3) | 1), + enum15 = (1 << (1 & 1)) +}; + typedef void * VOIDPTR; typedef int * INTPTR; diff --git a/tests/tnimterop_c.nim b/tests/tnimterop_c.nim index 0f53556..86526c1 100644 --- a/tests/tnimterop_c.nim +++ b/tests/tnimterop_c.nim @@ -97,6 +97,10 @@ else: check e3 == enum7 check e4 == enum11 +check enum13 == 4 +check enum14 == 9 +check enum15 == 2 + cAddStdDir() ## failing tests From 47bc610c9ac321c69b4919b9c339e9e390a806a7 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Sat, 19 Jan 2019 00:23:26 -0600 Subject: [PATCH 096/593] Fix #41 --- nimterop/getters.nim | 9 ++++++++- nimterop/grammar.nim | 25 +++++++++++++++++++++---- tests/include/test.h | 2 +- tests/tnimterop_c.nim | 3 +++ 4 files changed, 33 insertions(+), 6 deletions(-) diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 1b39247..06688a9 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -109,7 +109,14 @@ proc getUniqueIdentifier*(existing: HashSet[string], prefix = ""): string = return name & $count proc addNewIdentifer*(existing: var HashSet[string], name: string): bool = - return not existing.containsOrIncl(name.replace("_", "").toLowerAscii) + let + nimName = + if existing == gStateRT.types: + name[0] & name[1 .. ^1].replace("_", "").toLowerAscii + else: + name.replace("_", "").toLowerAscii + + return not existing.containsOrIncl(nimName) proc getPtrType*(str: string): string = result = case str: diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index ee42825..5e37393 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -171,8 +171,14 @@ proc initGrammar() = let nchild = $node.tsNodeNamedChild(i).tsNodeType() if nchild != "comment": - if nchild == "union_specifier": - union = " {.union.}" + case nchild: + of "struct_specifier": + if fstart == 1: + prefix = "struct " + of "union_specifier": + if fstart == 1: + prefix = "union " + union = " {.union.}" break if gStateRT.types.addNewIdentifer(nname): @@ -238,6 +244,15 @@ proc initGrammar() = gStateRT.typeStr &= &" {fname}*: {getPtrType(fptr&ftyp)}\n" i += 1 + if node.tsNodeType() == "type_definition" and + gStateRT.data[^1].name == "type_identifier": + let + dname = gStateRT.data[^1].val + ndname = gStateRT.data[^1].val.getIdentifier() + + if gStateRT.types.addNewIdentifer(ndname): + gStateRT.typeStr &= &" {ndname}* {{.importc: \"{dname}\", header: {gStateRT.currentHeader}, bycopy.}} = {nname}\n" + let fieldGrammar = &""" (field_identifier!) @@ -296,9 +311,11 @@ proc initGrammar() = if gStateRT.data.len > 1 and gStateRT.data[0].name == "type_identifier" and gStateRT.data[1].name != "field_identifier": - offset = 1 - pStructCommon(ast, node, gStateRT.data[^1].val, offset, 1) + offset = 1 + pStructCommon(ast, node, gStateRT.data[0].val, offset, 1) + else: + pStructCommon(ast, node, gStateRT.data[^1].val, offset, 1) )) proc pEnumCommon(ast: ref Ast, node: TSNode, name: string, fstart, fend: int) = diff --git a/tests/include/test.h b/tests/include/test.h index 64bdbb2..f450814 100644 --- a/tests/include/test.h +++ b/tests/include/test.h @@ -77,7 +77,7 @@ typedef struct { ENUM4 *field5[TEST_INT]; } STRUCT4; -typedef struct STRUCT5 { +typedef struct struct5 { int (*tci)(); struct STRUCT1 (*tcp)(int); float (*tcp8)(int *i); diff --git a/tests/tnimterop_c.nim b/tests/tnimterop_c.nim index 86526c1..e848950 100644 --- a/tests/tnimterop_c.nim +++ b/tests/tnimterop_c.nim @@ -33,6 +33,7 @@ var s3: STRUCT3 s4: STRUCT4 s5: STRUCT5 + s51: struct5 e: ENUM e2: ENUM2 = enum5 @@ -62,7 +63,9 @@ else: # TODO: what's `defined(cpp)` for c ? s5.tci = test_call_int s5.tcp = test_call_param s5.tcp8 = test_call_param8 +s51.tci = test_call_int check s5.tci() == 5 +check s51.tci() == 5 e = enum1 e2 = enum4 From abbd08d6de602d0d66457509a1c1714e5a529dd2 Mon Sep 17 00:00:00 2001 From: genotrance Date: Sat, 19 Jan 2019 01:50:55 -0600 Subject: [PATCH 097/593] Nimble install test (#46) --- .travis.yml | 1 + appveyor.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 347263a..8632daf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,3 +24,4 @@ install: script: - nimble install -y - nimble test + - nimble --nimbleDir:`pwd`/test install nimterop -y \ No newline at end of file diff --git a/appveyor.yml b/appveyor.yml index 72c2033..5768382 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -83,5 +83,6 @@ build_script: test_script: - nimble test + - nimble --nimbleDir:test install nimterop -y deploy: off From 7bc53080e8c2d185dd7e0289ec2829e65643f6b9 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Sat, 19 Jan 2019 02:03:14 -0600 Subject: [PATCH 098/593] Caching cImport content --- README.md | 2 +- nimterop/cimport.nim | 16 +++++++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a4d3098..147daf1 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,7 @@ Detailed documentation is still forthcoming. `cIncludeDir("XXX")` - add an include directory that is forwarded to the compiler using `{.passC: "-IXXX".}` -`cImport("header.h")` - import all supported definitions from header file +`cImport("header.h")` - import all supported definitions from header file. Output is cached in nimcache unless header.h changes or by using `nim -f` `cImport("header.h", recurse=true)` - import all supported definitions from header file and #includes diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index 2ff6251..ce21af2 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -53,6 +53,20 @@ proc walkDirImpl(indir, inext: string, file=true): seq[string] = if ret == 0: result = output.splitLines() +proc getFileDate(fullpath: string): string = + var + ret = 0 + cmd = + when defined(Windows): + &"cmd /c for %a in ({fullpath.quoteShell}) do echo %~ta" + else: + &"stat -c %y {fullpath.quoteShell}" + + (result, ret) = gorgeEx(cmd) + + if ret != 0: + doAssert false, "File date error: " & fullpath & "\n" & result + proc getToast(fullpath: string, recurse: bool = false): string = var cmd = when defined(Windows): "cmd /c " else: "" @@ -70,7 +84,7 @@ proc getToast(fullpath: string, recurse: bool = false): string = cmd.add &"{fullpath.quoteShell}" echo cmd - var (output, exitCode) = gorgeEx(cmd) + var (output, exitCode) = gorgeEx(cmd, cache=getFileDate(fullpath)) doAssert exitCode == 0, $exitCode result = output From 1748279553e7a693e6bcf3aa5857cf7d65e7fc30 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Sat, 19 Jan 2019 02:19:28 -0600 Subject: [PATCH 099/593] Caching fix for OSX --- nimterop/cimport.nim | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index ce21af2..3d337c7 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -59,8 +59,10 @@ proc getFileDate(fullpath: string): string = cmd = when defined(Windows): &"cmd /c for %a in ({fullpath.quoteShell}) do echo %~ta" - else: + elif defined(Linux): &"stat -c %y {fullpath.quoteShell}" + elif defined(OSX): + &"stat -f %m {fullpath.quoteShell}" (result, ret) = gorgeEx(cmd) From 3d7682c61130101270828582e60ff87a858b3c82 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Sat, 19 Jan 2019 15:02:49 -0600 Subject: [PATCH 100/593] Better error handling - fix #39, #47 --- nimterop/cimport.nim | 25 ++++++++++++++++--------- toast.nim | 13 +++++-------- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index 3d337c7..2bad012 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -18,10 +18,8 @@ proc findPath(path: string, fail = true): string = # Relative to project path result = joinPathIfRel(getProjectPath(), path).replace("\\", "/") if not fileExists(result) and not dirExists(result): - if fail: - doAssert false, "File or directory not found: " & path - else: - return "" + doAssert not fail, "File or directory not found: " & path + result = "" proc walkDirImpl(indir, inext: string, file=true): seq[string] = let @@ -66,11 +64,21 @@ proc getFileDate(fullpath: string): string = (result, ret) = gorgeEx(cmd) - if ret != 0: - doAssert false, "File date error: " & fullpath & "\n" & result + doAssert ret == 0, "File date error: " & fullpath & "\n" & result + +proc getToastError(output: string): string = + # Filter out preprocessor errors + for line in output.splitLines(): + if "fatal error:" in line.toLowerAscii: + result &= &"\nERROR: {line.split(\"fatal error\")[1]}\n" + + # Toast error + if result.len == 0: + result = output proc getToast(fullpath: string, recurse: bool = false): string = var + ret = 0 cmd = when defined(Windows): "cmd /c " else: "" cmd &= "toast --pnim --preprocess " @@ -86,9 +94,8 @@ proc getToast(fullpath: string, recurse: bool = false): string = cmd.add &"{fullpath.quoteShell}" echo cmd - var (output, exitCode) = gorgeEx(cmd, cache=getFileDate(fullpath)) - doAssert exitCode == 0, $exitCode - result = output + (result, ret) = gorgeEx(cmd, cache=getFileDate(fullpath)) + doAssert ret == 0, getToastError(result) proc getGccPaths*(mode = "c"): string = var diff --git a/toast.nim b/toast.nim index 712d1a7..7781369 100644 --- a/toast.nim +++ b/toast.nim @@ -78,17 +78,14 @@ proc process(path: string) = else: gStateRT.code = readFile(path) + doAssert gStateRT.code.len != 0, "Empty file or preprocessor error" + if gStateRT.mode == "c": - if not parser.tsParserSetLanguage(treeSitterC()): - echo "Failed to load C parser" - quit() + doAssert parser.tsParserSetLanguage(treeSitterC()), "Failed to load C parser" elif gStateRT.mode == "cpp": - if not parser.tsParserSetLanguage(treeSitterCpp()): - echo "Failed to load C++ parser" - quit() + doAssert parser.tsParserSetLanguage(treeSitterCpp()), "Failed to load C++ parser" else: - echo "Invalid parser " & gStateRT.mode - quit() + doAssert false, "Invalid parser " & gStateRT.mode var tree = parser.tsParserParseString(nil, gStateRT.code.cstring, gStateRT.code.len.uint32) From be1fe6495cbd1649a03ce6ee5bcca18e49da9ae1 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Sat, 19 Jan 2019 15:05:51 -0600 Subject: [PATCH 101/593] Fix not fail --- nimterop/cimport.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index 2bad012..c5955c6 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -18,7 +18,7 @@ proc findPath(path: string, fail = true): string = # Relative to project path result = joinPathIfRel(getProjectPath(), path).replace("\\", "/") if not fileExists(result) and not dirExists(result): - doAssert not fail, "File or directory not found: " & path + doAssert (not fail), "File or directory not found: " & path result = "" proc walkDirImpl(indir, inext: string, file=true): seq[string] = From 65111455134774bd965bc52b22556d9942e1888f Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Sun, 20 Jan 2019 14:41:50 -0600 Subject: [PATCH 102/593] Fix #36 - va_list and time_t --- nimterop/cimport.nim | 3 +++ nimterop/getters.nim | 6 +----- nimterop/types.nim | 4 ++++ 3 files changed, 8 insertions(+), 5 deletions(-) create mode 100644 nimterop/types.nim diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index c5955c6..bb2217c 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -4,6 +4,9 @@ const CIMPORT {.used.} = 1 include "."/globals +import "."/types +export types + proc interpPath(dir: string): string= # TODO: more robust: needs a DirSep after "$projpath" result = dir.replace("$projpath", getProjectPath()) diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 06688a9..cc5b0a2 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -70,11 +70,7 @@ const gTypeMap = { # floating point "float": "cfloat", "double": "cdouble", - "long double": "clongdouble", - - # misc - "time_t": "int32", - "ptrdiff_t": "ByteAddress" + "long double": "clongdouble" }.toTable() proc sanitizePath*(path: string): string = diff --git a/nimterop/types.nim b/nimterop/types.nim new file mode 100644 index 0000000..80ba603 --- /dev/null +++ b/nimterop/types.nim @@ -0,0 +1,4 @@ +type + time_t* = int32 + ptrdiff_t* = ByteAddress + va_list* {.importc: "va_list", header:"".} = object \ No newline at end of file From 8a4fb0facac95351b266c8424bb864d34dde8446 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Sun, 20 Jan 2019 15:53:14 -0600 Subject: [PATCH 103/593] Add documentation --- README.md | 10 +++---- nimterop/cimport.nim | 66 ++++++++++++++++++++++++++++++++++++++++++-- nimterop/globals.nim | 25 +++++++++-------- 3 files changed, 82 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 147daf1..60e9eb5 100644 --- a/README.md +++ b/README.md @@ -55,11 +55,11 @@ Detailed documentation is still forthcoming. `cDebug()` - enable debug messages -`cDefine("XXX")` - `#define` an identifer that is forwarded to the C/C++ compiler using `{.passC: "-DXXX".}` as well as _eventually_ used in processing `#ifdef` statements +`cDefine("XXX")` - `#define` an identifer that is forwarded to the C/C++ compiler using `{.passC: "-DXXX".}` -`cIncludeDir("XXX")` - add an include directory that is forwarded to the compiler using `{.passC: "-IXXX".}` +`cIncludeDir("XXX")` - add an include directory that is forwarded to the C/C++ compiler using `{.passC: "-IXXX".}` -`cImport("header.h")` - import all supported definitions from header file. Output is cached in nimcache unless header.h changes or by using `nim -f` +`cImport("header.h")` - Import all supported definitions from specified header file. Generated content is cached in `nimcache` until `header.h` changes. If files imported by `header.h` change and affect the generated content, use `nim -f` to force regeneration of Nim code. `cImport("header.h", recurse=true)` - import all supported definitions from header file and #includes @@ -69,9 +69,9 @@ Detailed documentation is still forthcoming. `cCompile("path/to/dir", "cpp")` - compile in all C++ files found recursively -`cAddSearchDir("XXX")` - add directory XXX to search path in calls to `cSearchPath()` +`cAddSearchDir("XXX")` - add directory XXX to the search path used in calls to `cSearchPath()` -`cAddStdDir("XXX")` - add standard "c" [default] or "cpp" include paths to search path +`cAddStdDir("XXX")` - add standard "c" [default] or "cpp" include paths to search path used in calls to `cSearchPath()` `cSearchPath("header.h")` - return a file or directory found in search path configured using `cSearchPath()` - can be used in `cCompile()`, `cIncludeDir()` and `cImport()` calls diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index bb2217c..af66953 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -73,7 +73,7 @@ proc getToastError(output: string): string = # Filter out preprocessor errors for line in output.splitLines(): if "fatal error:" in line.toLowerAscii: - result &= &"\nERROR: {line.split(\"fatal error\")[1]}\n" + result &= "\nERROR:$1\n" % line.split("fatal error:")[1] # Toast error if result.len == 0: @@ -100,7 +100,7 @@ proc getToast(fullpath: string, recurse: bool = false): string = (result, ret) = gorgeEx(cmd, cache=getFileDate(fullpath)) doAssert ret == 0, getToastError(result) -proc getGccPaths*(mode = "c"): string = +proc getGccPaths(mode = "c"): string = var ret = 0 nul = when defined(Windows): "nul" else: "/dev/null" @@ -109,6 +109,12 @@ proc getGccPaths*(mode = "c"): string = (result, ret) = gorgeEx("gcc -Wp,-v -x" & mmode & " " & nul) proc cSearchPath*(path: string): string {.compileTime.}= + ## Return a file or directory found in search path configured using + ## ``cSearchPath()`` + ## + ## This proc can be used to locate files or directories in calls to + ## ``cCompile()``, ``cIncludeDir()`` and ``cImport()``. + result = findPath(path, fail = false) if result.len == 0: var found = false @@ -117,12 +123,18 @@ proc cSearchPath*(path: string): string {.compileTime.}= if fileExists(result) or dirExists(result): found = true break - doAssert found, "File or directory not found: " & path & " gStateCT.searchDirs: " & $gStateCT.searchDirs + doAssert found, "File or directory not found: " & path & + " gStateCT.searchDirs: " & $gStateCT.searchDirs macro cDebug*(): untyped = + ## Enable debug messages and display the generated Nim code + gStateCT.debug = true macro cDefine*(name: static string, val: static string = ""): untyped = + ## ``#define`` an identifer that is forwarded to the C/C++ compiler + ## using ``{.passC: "-DXXX".}`` + result = newNimNode(nnkStmtList) var str = name @@ -141,11 +153,24 @@ macro cDefine*(name: static string, val: static string = ""): untyped = echo result.repr macro cAddSearchDir*(dir: static string): untyped = + ## Add directory ``dir`` to the search path used in calls to + ## ``cSearchPath()`` + ## + ## This allows something like this: + ## + ## .. code-block:: nim + ## + ## cAddSearchDir("path/to/includes") + ## cImport cSearchPath("file.h") + var dir = interpPath(dir) if dir notin gStateCT.searchDirs: gStateCT.searchDirs.add(dir) macro cIncludeDir*(dir: static string): untyped = + ## Add an include directory that is forwarded to the C/C++ compiler + ## using ``{.passC: "-IXXX".}`` + var dir = interpPath(dir) result = newNimNode(nnkStmtList) @@ -164,6 +189,16 @@ macro cIncludeDir*(dir: static string): untyped = echo result.repr macro cAddStdDir*(mode = "c"): untyped = + ## Add the standard ``c`` [default] or ``cpp`` include paths to search + ## path used in calls to ``cSearchPath()`` + ## + ## This allows something like this: + ## + ## .. code-block:: nim + ## + ## cAddStdDir() + ## cImport cSearchPath("math.h") + result = newNimNode(nnkStmtList) var @@ -182,6 +217,22 @@ macro cAddStdDir*(mode = "c"): untyped = cAddSearchDir(`sline`) macro cCompile*(path: static string, mode = "c"): untyped = + ## Compile and link C/C++ implementation into resulting binary using ``{.compile.}`` + ## + ## ``path`` can be a specific file or contain wildcards: + ## + ## .. code-block:: nim + ## + ## cCompile("file.c") + ## cCompile("path/to/*.c") + ## + ## ``mode`` can be ``c`` or ``cpp`` and recursively searches for code files in + ## specified path. ``c`` = ``*.c``, ``cpp`` = ``*.C``, ``*.cpp``, ``*.c++``, ``*.cc``, ``*.cxx`` + ## + ## .. code-block:: nim + ## + ## cCompile("path/to/dir", "cpp") + result = newNimNode(nnkStmtList) var @@ -229,6 +280,15 @@ macro cCompile*(path: static string, mode = "c"): untyped = echo result.repr macro cImport*(filename: static string, recurse: static bool = false): untyped = + ## Import all supported definitions from specified header file. Generated + ## content is cached in ``nimcache`` until ``filename`` changes. If files + ## imported by ``filename`` change and affect the generated content, use + ## ``nim -f`` to force regeneration of Nim code. + ## + ## ``recurse`` can be used to generate Nim wrappers from ``#include`` files + ## referenced in ``filename``. This is only done for files in the same + ## directory as ``filename`` or in a directory added using ``cIncludeDir()``. + result = newNimNode(nnkStmtList) let diff --git a/nimterop/globals.nim b/nimterop/globals.nim index 0c81e27..11882a7 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -6,7 +6,7 @@ when not declared(CIMPORT): import "."/treesitter/runtime const - gAtoms* = @[ + gAtoms {.used.} = @[ "field_identifier", "identifier", "number_literal", @@ -16,27 +16,27 @@ const "type_identifier" ].toSet() - gExpressions* = @[ + gExpressions {.used.} = @[ "parenthesized_expression", "bitwise_expression", "shift_expression", "math_expression" ].toSet() - gEnumVals* = @[ + gEnumVals {.used.} = @[ "identifier", "number_literal" ].concat(toSeq(gExpressions.items)) type - Kind* = enum + Kind = enum exactlyOne oneOrMore # + zeroOrMore # * zeroOrOne # ? orWithNext # ! - Ast* = object + Ast = object name*: string kind*: Kind recursive*: bool @@ -45,7 +45,7 @@ type tonim*: proc (ast: ref Ast, node: TSNode) regex*: Regex - State* = object + State = object compile*, defines*, headers*, includeDirs*, searchDirs*: seq[string] debug*, past*, preprocess*, pnim*, pretty*, recurse*: bool @@ -61,15 +61,18 @@ type grammar*: seq[tuple[grammar: string, call: proc(ast: ref Ast, node: TSNode) {.nimcall.}]] var - gStateCT* {.compiletime.}: State - gStateRT*: State + gStateCT {.compiletime, used.}: State + gStateRT {.used.}: State -template nBl*(s: typed): untyped = +template nBl(s: typed): untyped {.used.} = (s.len != 0) -type CompileMode* = enum +type CompileMode = enum c, cpp, # TODO: can cligen accept enum instead of string? -const modeDefault* = $cpp # TODO: USE this everywhere relevant +const modeDefault {.used.} = $cpp # TODO: USE this everywhere relevant + +when not declared(CIMPORT): + export gAtoms, gExpressions, gEnumVals, Kind, Ast, State, gStateRT, nBl, CompileMode, modeDefault \ No newline at end of file From 186e78f8c68bcb9e96a33721e7c310b4d791c95d Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Sun, 20 Jan 2019 16:12:51 -0600 Subject: [PATCH 104/593] Docs fix --- nimterop/cimport.nim | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index af66953..bb8ce03 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -226,8 +226,9 @@ macro cCompile*(path: static string, mode = "c"): untyped = ## cCompile("file.c") ## cCompile("path/to/*.c") ## - ## ``mode`` can be ``c`` or ``cpp`` and recursively searches for code files in - ## specified path. ``c`` = ``*.c``, ``cpp`` = ``*.C``, ``*.cpp``, ``*.c++``, ``*.cc``, ``*.cxx`` + ## ``mode`` recursively searches for code files in ``path``. + ## + ## ``c`` searches for ``*.c`` whereas ``cpp`` searches for ``*.C *.cpp *.c++ *.cc *.cxx`` ## ## .. code-block:: nim ## From 65133ff9e93628931f1deadfc87a188f3fc039b1 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Sun, 20 Jan 2019 16:17:08 -0600 Subject: [PATCH 105/593] Update documentation --- .nojekyll | 0 cimport.html | 1386 ++++++++++++++++++++++++++++++++++++++++++++++++++ cimport.idx | 8 + types.html | 1298 ++++++++++++++++++++++++++++++++++++++++++++++ types.idx | 3 + 5 files changed, 2695 insertions(+) create mode 100644 .nojekyll create mode 100644 cimport.html create mode 100644 cimport.idx create mode 100644 types.html create mode 100644 types.idx diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/cimport.html b/cimport.html new file mode 100644 index 0000000..5f22587 --- /dev/null +++ b/cimport.html @@ -0,0 +1,1386 @@ + + + + + + + + + + + + + + + + + +cimport + + + + + + + + +
+
+

cimport

+
+
+ +
+ Search: +
+
+ Group by: + +
+ + +
+
+
+

+ +
+

Imports

+
+types +
+
+

Procs

+
+ +
proc cSearchPath(path: string): string {...}{.compileTime, raises: [], tags: [ReadDirEffect].}
+
+

Return a file or directory found in search path configured using cSearchPath()

+

This proc can be used to locate files or directories in calls to cCompile(), cIncludeDir() and cImport().

+ + +
+ +
+
+

Macros

+
+ +
macro cDebug(): untyped
+
+Enable debug messages and display the generated Nim code + +
+ +
macro cDefine(name: static string; val: static string = ""): untyped
+
+#define an identifer that is forwarded to the C/C++ compiler using {.passC: "-DXXX".} + +
+ +
macro cAddSearchDir(dir: static string): untyped
+
+

Add directory dir to the search path used in calls to cSearchPath()

+

This allows something like this:

+
cAddSearchDir("path/to/includes")
+cImport cSearchPath("file.h")
+ +
+ +
macro cIncludeDir(dir: static string): untyped
+
+Add an include directory that is forwarded to the C/C++ compiler using {.passC: "-IXXX".} + +
+ +
macro cAddStdDir(mode = "c"): untyped
+
+

Add the standard c [default] or cpp include paths to search path used in calls to cSearchPath()

+

This allows something like this:

+
cAddStdDir()
+cImport cSearchPath("math.h")
+ +
+ +
macro cCompile(path: static string; mode = "c"): untyped
+
+

Compile and link C/C++ implementation into resulting binary using {.compile.}

+

path can be a specific file or contain wildcards:

+
cCompile("file.c")
+cCompile("path/to/*.c")

mode recursively searches for code files in path.

+

c searches for *.c whereas cpp searches for *.C *.cpp *.c++ *.cc *.cxx

+
cCompile("path/to/dir", "cpp")
+ +
+ +
macro cImport(filename: static string; recurse: static bool = false): untyped
+
+

Import all supported definitions from specified header file. Generated content is cached in nimcache until filename changes. If files imported by filename change and affect the generated content, use nim -f to force regeneration of Nim code.

+

recurse can be used to generate Nim wrappers from #include files referenced in filename. This is only done for files in the same directory as filename or in a directory added using cIncludeDir().

+ + +
+ +
+ +
+
+ +
+ +
+
+
+ + + diff --git a/cimport.idx b/cimport.idx new file mode 100644 index 0000000..f9daf49 --- /dev/null +++ b/cimport.idx @@ -0,0 +1,8 @@ +cSearchPath cimport.html#cSearchPath,string cimport: cSearchPath(path: string): string +cDebug cimport.html#cDebug.m, cimport: cDebug(): untyped +cDefine cimport.html#cDefine.m,,string cimport: cDefine(name: static string; val: static string = ""): untyped +cAddSearchDir cimport.html#cAddSearchDir.m, cimport: cAddSearchDir(dir: static string): untyped +cIncludeDir cimport.html#cIncludeDir.m, cimport: cIncludeDir(dir: static string): untyped +cAddStdDir cimport.html#cAddStdDir.m,string cimport: cAddStdDir(mode = "c"): untyped +cCompile cimport.html#cCompile.m,,string cimport: cCompile(path: static string; mode = "c"): untyped +cImport cimport.html#cImport.m, cimport: cImport(filename: static string; recurse: static bool = false): untyped diff --git a/types.html b/types.html new file mode 100644 index 0000000..03d8438 --- /dev/null +++ b/types.html @@ -0,0 +1,1298 @@ + + + + + + + + + + + + + + + + + +types + + + + + + + + +
+
+

types

+
+
+ +
+ Search: +
+
+ Group by: + +
+ + +
+
+
+

+
+

Types

+
+ +
time_t = int32
+
+ + +
+ +
ptrdiff_t = ByteAddress
+
+ + +
+ +
va_list {...}{.importc: "va_list", header: "<stdarg.h>".} = object
+
+ + +
+ +
+ +
+
+ +
+ +
+
+
+ + + diff --git a/types.idx b/types.idx new file mode 100644 index 0000000..d641285 --- /dev/null +++ b/types.idx @@ -0,0 +1,3 @@ +time_t types.html#time_t types: time_t +ptrdiff_t types.html#ptrdiff_t types: ptrdiff_t +va_list types.html#va_list types: va_list From 783cf70fbf0ac036289bc6d96294a916c1b063a3 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Sun, 20 Jan 2019 16:22:12 -0600 Subject: [PATCH 106/593] Generate and post documentation --- README.md | 2 +- nimterop.nimble | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 60e9eb5..74b5848 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,7 @@ The `toast` binary can also be used directly on the CLI. The `--help` flag provi __Documentation__ -Detailed documentation is still forthcoming. +Documentation can be found [here](https://genotrance.github.io/nimterop/cimport.html). `cDebug()` - enable debug messages diff --git a/nimterop.nimble b/nimterop.nimble index 11d8342..d72ab8d 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -32,4 +32,10 @@ task test, "Test": tsoloud() else: if not existsEnv("TRAVIS"): - tsoloud() \ No newline at end of file + tsoloud() + +task docs, "Generate docs": + # Uses: pip install ghp-import + execCmd "nim doc --project --index:on nimterop/cimport" + execCmd "nim doc --project --index:on nimterop/git" + execCmd "ghp-import --no-jekyll -fp nimterop/htmldocs" \ No newline at end of file From 0f090797d5c95a5e270ac7177ba539d6434977a7 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Sun, 20 Jan 2019 16:22:21 -0600 Subject: [PATCH 107/593] Update documentation --- cimport.html | 2 +- git.html | 1334 ++++++++++++++++++++++++++++++++++++++++++++++++++ git.idx | 6 + types.html | 2 +- 4 files changed, 1342 insertions(+), 2 deletions(-) create mode 100644 git.html create mode 100644 git.idx diff --git a/cimport.html b/cimport.html index 5f22587..fa702cc 100644 --- a/cimport.html +++ b/cimport.html @@ -1376,7 +1376,7 @@ Add an include directory that is forwarded to the C/C++ compiler using
- Made with Nim. Generated: 2019-01-20 22:17:08 UTC + Made with Nim. Generated: 2019-01-20 22:22:20 UTC diff --git a/git.html b/git.html new file mode 100644 index 0000000..5d009fc --- /dev/null +++ b/git.html @@ -0,0 +1,1334 @@ + + + + + + + + + + + + + + + + + +git + + + + + + + + +
+
+

git

+
+
+ +
+ Search: +
+
+ Group by: + +
+ + +
+
+
+

+
+

Procs

+
+ +
proc execAction(cmd: string; nostderr = false): string {...}{.raises: [OSError, Exception],
+    tags: [ExecIOEffect, ReadIOEffect, RootEffect].}
+
+ + +
+ +
+
+

Macros

+
+ +
macro extractZip(zipfile, outdir: static string): untyped
+
+ + +
+ +
macro downloadUrl(url, outdir: static string): untyped
+
+ + +
+ +
macro gitReset(outdir: static string): untyped
+
+ + +
+ +
macro gitCheckout(file, outdir: static string): untyped
+
+ + +
+ +
macro gitPull(url: static string; outdirN = ""; plistN = ""; checkoutN = ""): untyped
+
+ + +
+ +
+ +
+
+ +
+ +
+
+
+ + + diff --git a/git.idx b/git.idx new file mode 100644 index 0000000..486b012 --- /dev/null +++ b/git.idx @@ -0,0 +1,6 @@ +execAction git.html#execAction,string git: execAction(cmd: string; nostderr = false): string +extractZip git.html#extractZip.m,, git: extractZip(zipfile, outdir: static string): untyped +downloadUrl git.html#downloadUrl.m,, git: downloadUrl(url, outdir: static string): untyped +gitReset git.html#gitReset.m, git: gitReset(outdir: static string): untyped +gitCheckout git.html#gitCheckout.m,, git: gitCheckout(file, outdir: static string): untyped +gitPull git.html#gitPull.m,,string,string,string git: gitPull(url: static string; outdirN = ""; plistN = ""; checkoutN = ""): untyped diff --git a/types.html b/types.html index 03d8438..05fb09d 100644 --- a/types.html +++ b/types.html @@ -1288,7 +1288,7 @@ function main() { From 22d8181073621102cf32c56b08a29bd4dc4f459a Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 21 Jan 2019 00:17:44 -0600 Subject: [PATCH 108/593] Fix #50 - ptr object to pointer --- nimterop/ast.nim | 12 +++++++----- nimterop/getters.nim | 20 +++++++++----------- nimterop/grammar.nim | 7 ++++--- tests/include/test.c | 4 ++++ tests/include/test.h | 4 ++++ tests/tnimterop_c.nim | 4 ++++ 6 files changed, 32 insertions(+), 19 deletions(-) diff --git a/nimterop/ast.nim b/nimterop/ast.nim index 6498c93..8191ac6 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -1,4 +1,4 @@ -import sets, strformat, strutils, tables +import sequtils, sets, strformat, strutils, tables import regex @@ -20,8 +20,9 @@ proc saveNodeData(node: TSNode): bool = val = val.getType() let - pname = node.getPName() - ppname = node.tsNodeParent().getPName() + pname = node.getPxName(1) + ppname = node.getPxName(2) + pppname = node.getPxName(3) if node.tsNodePrevNamedSibling().tsNodeIsNull(): if pname == "pointer_declarator": @@ -37,8 +38,9 @@ proc saveNodeData(node: TSNode): bool = if node.tsNodeType() == "field_identifier" and pname == "pointer_declarator" and - ppname == "function_declarator": - gStateRT.data.add(("function_declarator", "")) + ppname == "function_declarator" and + pppname == "pointer_declarator": + gStateRT.data.insert(("pointer_declarator", ""), gStateRT.data.len-1) elif name in gExpressions: if $node.tsNodeParent.tsNodeType() notin gExpressions: diff --git a/nimterop/getters.nim b/nimterop/getters.nim index cc5b0a2..921467e 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -283,16 +283,14 @@ proc getAstChildByName*(ast: ref Ast, name: string): ref Ast = if name in ast.children[i].name.split("|"): return ast.children[i] -proc getPName*(node: TSNode): string = - if not node.tsNodeIsNull(): - let - nparent = node.tsNodeParent() - if not nparent.tsNodeIsNull(): - return $nparent.tsNodeType() +proc getPxName*(node: TSNode, offset: int): string = + var + np = node + count = 0 -proc isPName*(node: TSNode, name: string): bool = - return node.getPName() == name + while not np.tsNodeIsNull() and count < offset: + np = np.tsNodeParent() + count += 1 -proc isPPName*(node: TSNode, name: string): bool = - if node.getPName().len != 0: - return node.tsNodeParent().isPName(name) + if count == offset and not np.tsNodeIsNull(): + return $np.tsNodeType() diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index 5e37393..692be01 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -137,7 +137,8 @@ proc initGrammar() = if pout.len != 0 and pout[^1] == ',': pout = pout[0 .. ^2] - if typ != "object": + + if tptr == "ptr " or typ != "object": gStateRT.typeStr &= &" {name}* = proc({pout}): {getPtrType(tptr&typ)} {{.nimcall.}}\n" else: gStateRT.typeStr &= &" {name}* = proc({pout}) {{.nimcall.}}\n" @@ -232,7 +233,7 @@ proc initGrammar() = if pout.len != 0 and pout[^1] == ',': pout = pout[0 .. ^2] - if ftyp != "object": + if fptr == "ptr " or ftyp != "object": gStateRT.typeStr &= &" {fname}*: proc({pout}): {getPtrType(fptr&ftyp)} {{.nimcall.}}\n" else: gStateRT.typeStr &= &" {fname}*: proc({pout}) {{.nimcall.}}\n" @@ -445,7 +446,7 @@ proc initGrammar() = pout = pout[0 .. ^2] if gStateRT.procs.addNewIdentifer(fnname): - if ftyp != "object": + if fptr == "ptr " or ftyp != "object": gStateRT.procStr &= &"proc {fnname}*({pout}): {getPtrType(fptr&ftyp)} {{.importc: \"{fname}\", header: {gStateRT.currentHeader}.}}\n" else: gStateRT.procStr &= &"proc {fnname}*({pout}) {{.importc: \"{fname}\", header: {gStateRT.currentHeader}.}}\n" diff --git a/tests/include/test.c b/tests/include/test.c index 3a59ffc..162645c 100644 --- a/tests/include/test.c +++ b/tests/include/test.c @@ -54,4 +54,8 @@ float test_call_param8(int *param1) { *param1 = 5 * *param1; return 1.0 * *param1; +} + +void *test_call9() { + return NULL; } \ No newline at end of file diff --git a/tests/include/test.h b/tests/include/test.h index f450814..6c62e2f 100644 --- a/tests/include/test.h +++ b/tests/include/test.h @@ -1,3 +1,5 @@ +#include + #ifdef __cplusplus extern "C" { #endif @@ -81,6 +83,7 @@ typedef struct struct5 { int (*tci)(); struct STRUCT1 (*tcp)(int); float (*tcp8)(int *i); + void *(*tcv)(); } STRUCT5; union UNION1 { @@ -102,6 +105,7 @@ union UNION1 test_call_param5(float param1); unsigned char test_call_param6(UNION2 param1); int test_call_param7(union UNION1 param1); float test_call_param8(int *param1); +void *test_call9(); #ifdef __cplusplus } diff --git a/tests/tnimterop_c.nim b/tests/tnimterop_c.nim index e848950..2218256 100644 --- a/tests/tnimterop_c.nim +++ b/tests/tnimterop_c.nim @@ -64,8 +64,10 @@ s5.tci = test_call_int s5.tcp = test_call_param s5.tcp8 = test_call_param8 s51.tci = test_call_int +s51.tcv = test_call9 check s5.tci() == 5 check s51.tci() == 5 +check s51.tcv() == nil e = enum1 e2 = enum4 @@ -97,6 +99,8 @@ else: check test_call_param8(addr i) == 25.0 check i == 25 +check test_call9() == nil + check e3 == enum7 check e4 == enum11 From 23a93e1d4266ee7982f629be00b8fa0390d79dce Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 21 Jan 2019 00:47:25 -0600 Subject: [PATCH 109/593] Fix build break --- nimterop.nimble | 8 ++++---- nimterop/ast.nim | 5 +++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/nimterop.nimble b/nimterop.nimble index d72ab8d..16a7100 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -17,15 +17,15 @@ proc execCmd(cmd: string) = exec cmd proc tsoloud() = - execCmd "nim c -r tests/tsoloud.nim" + execCmd "nim c --forceBuild -r tests/tsoloud.nim" execCmd "nim cpp -r tests/tsoloud.nim" task test, "Test": - execCmd "nim c -r tests/tnimterop_c.nim" + execCmd "nim c -f -r tests/tnimterop_c.nim" execCmd "nim cpp -r tests/tnimterop_c.nim" - execCmd "nim cpp -r tests/tnimterop_cpp.nim" + execCmd "nim cpp -f -r tests/tnimterop_cpp.nim" when defined(windows): - execCmd "nim c -r tests/tmath.nim" + execCmd "nim c -f -r tests/tmath.nim" execCmd "nim cpp -r tests/tmath.nim" when not defined(OSX): when defined(Windows): diff --git a/nimterop/ast.nim b/nimterop/ast.nim index 8191ac6..62cf05e 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -38,9 +38,10 @@ proc saveNodeData(node: TSNode): bool = if node.tsNodeType() == "field_identifier" and pname == "pointer_declarator" and - ppname == "function_declarator" and - pppname == "pointer_declarator": + ppname == "function_declarator": + if pppname == "pointer_declarator": gStateRT.data.insert(("pointer_declarator", ""), gStateRT.data.len-1) + gStateRT.data.add(("function_declarator", "")) elif name in gExpressions: if $node.tsNodeParent.tsNodeType() notin gExpressions: From c89a741095a4ed4858ea41eee6c412c3fea2e68e Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 21 Jan 2019 01:35:42 -0600 Subject: [PATCH 110/593] Support cache disabling --- README.md | 4 +++- nimterop.nimble | 8 ++++---- nimterop/cimport.nim | 22 ++++++++++++++++++---- nimterop/globals.nim | 2 +- tests/tmath.nim | 1 + tests/tnimterop_c.nim | 1 + tests/tnimterop_cpp.nim | 1 + tests/tsoloud.nim | 1 + 8 files changed, 30 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 74b5848..07a6ec5 100644 --- a/README.md +++ b/README.md @@ -55,11 +55,13 @@ Documentation can be found [here](https://genotrance.github.io/nimterop/cimport. `cDebug()` - enable debug messages +`cDisableCaching()` - disable caching of generated Nim content from `cImport()` + `cDefine("XXX")` - `#define` an identifer that is forwarded to the C/C++ compiler using `{.passC: "-DXXX".}` `cIncludeDir("XXX")` - add an include directory that is forwarded to the C/C++ compiler using `{.passC: "-IXXX".}` -`cImport("header.h")` - Import all supported definitions from specified header file. Generated content is cached in `nimcache` until `header.h` changes. If files imported by `header.h` change and affect the generated content, use `nim -f` to force regeneration of Nim code. +`cImport("header.h")` - Import all supported definitions from specified header file. Generated content is cached in `nimcache` until `header.h` changes `cImport("header.h", recurse=true)` - import all supported definitions from header file and #includes diff --git a/nimterop.nimble b/nimterop.nimble index 16a7100..d72ab8d 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -17,15 +17,15 @@ proc execCmd(cmd: string) = exec cmd proc tsoloud() = - execCmd "nim c --forceBuild -r tests/tsoloud.nim" + execCmd "nim c -r tests/tsoloud.nim" execCmd "nim cpp -r tests/tsoloud.nim" task test, "Test": - execCmd "nim c -f -r tests/tnimterop_c.nim" + execCmd "nim c -r tests/tnimterop_c.nim" execCmd "nim cpp -r tests/tnimterop_c.nim" - execCmd "nim cpp -f -r tests/tnimterop_cpp.nim" + execCmd "nim cpp -r tests/tnimterop_cpp.nim" when defined(windows): - execCmd "nim c -f -r tests/tmath.nim" + execCmd "nim c -r tests/tmath.nim" execCmd "nim cpp -r tests/tmath.nim" when not defined(OSX): when defined(Windows): diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index bb8ce03..beaaeb2 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -69,6 +69,10 @@ proc getFileDate(fullpath: string): string = doAssert ret == 0, "File date error: " & fullpath & "\n" & result +proc getCacheValue(fullpath: string): string = + if not gStateCT.nocache: + result = fullpath.getFileDate() + proc getToastError(output: string): string = # Filter out preprocessor errors for line in output.splitLines(): @@ -97,7 +101,7 @@ proc getToast(fullpath: string, recurse: bool = false): string = cmd.add &"{fullpath.quoteShell}" echo cmd - (result, ret) = gorgeEx(cmd, cache=getFileDate(fullpath)) + (result, ret) = gorgeEx(cmd, cache=getCacheValue(fullpath)) doAssert ret == 0, getToastError(result) proc getGccPaths(mode = "c"): string = @@ -131,6 +135,17 @@ macro cDebug*(): untyped = gStateCT.debug = true +macro cDisableCaching*(): untyped = + ## Disable caching of generated Nim code - useful during wrapper development + ## + ## If files included by header bring processed by ``cImport()`` change and affect + ## the generated content, ``cImport()`` won't detect the change and use the cached + ## value. Use ``cDisableCaching()`` to avoid this scenario. + ## + ## ``nim -f`` is currently broken but will eventually allow forcing regeneration. + + gStateCT.nocache = true + macro cDefine*(name: static string, val: static string = ""): untyped = ## ``#define`` an identifer that is forwarded to the C/C++ compiler ## using ``{.passC: "-DXXX".}`` @@ -282,9 +297,8 @@ macro cCompile*(path: static string, mode = "c"): untyped = macro cImport*(filename: static string, recurse: static bool = false): untyped = ## Import all supported definitions from specified header file. Generated - ## content is cached in ``nimcache`` until ``filename`` changes. If files - ## imported by ``filename`` change and affect the generated content, use - ## ``nim -f`` to force regeneration of Nim code. + ## content is cached in ``nimcache`` until ``filename`` changes unless + ## ``cDisableCaching()`` is set. ## ## ``recurse`` can be used to generate Nim wrappers from ``#include`` files ## referenced in ``filename``. This is only done for files in the same diff --git a/nimterop/globals.nim b/nimterop/globals.nim index 11882a7..1a96aa3 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -48,7 +48,7 @@ type State = object compile*, defines*, headers*, includeDirs*, searchDirs*: seq[string] - debug*, past*, preprocess*, pnim*, pretty*, recurse*: bool + nocache*, debug*, past*, preprocess*, pnim*, pretty*, recurse*: bool consts*, enums*, procs*, types*: HashSet[string] diff --git a/tests/tmath.nim b/tests/tmath.nim index d5a7166..f32a1f5 100644 --- a/tests/tmath.nim +++ b/tests/tmath.nim @@ -7,6 +7,7 @@ type mingw_dbl_type_t = object cDebug() +cDisableCaching() cAddStdDir() cImport cSearchPath("math.h") diff --git a/tests/tnimterop_c.nim b/tests/tnimterop_c.nim index 2218256..7123c80 100644 --- a/tests/tnimterop_c.nim +++ b/tests/tnimterop_c.nim @@ -2,6 +2,7 @@ import std/unittest import nimterop/cimport cDebug() +cDisableCaching() cDefine("FORCE") cIncludeDir "$projpath/include" diff --git a/tests/tnimterop_cpp.nim b/tests/tnimterop_cpp.nim index bed052c..a556818 100644 --- a/tests/tnimterop_cpp.nim +++ b/tests/tnimterop_cpp.nim @@ -2,6 +2,7 @@ import nimterop/cimport import unittest cDebug() +cDisableCaching() cIncludeDir "$projpath/include" cAddSearchDir "$projpath/include" diff --git a/tests/tsoloud.nim b/tests/tsoloud.nim index 544c1af..6d3028d 100644 --- a/tests/tsoloud.nim +++ b/tests/tsoloud.nim @@ -3,6 +3,7 @@ import os, nimterop/[cimport, git] gitPull("https://github.com/jarikomppa/soloud", "soloud", "include/*\nsrc/*\n") cDebug() +cDisableCaching() const inc = "soloud/include" From 3736ea8083d25e06f7519f90ab9bd9a42a1549fd Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 21 Jan 2019 11:06:39 -0600 Subject: [PATCH 111/593] Update documentation --- cimport.html | 60 +++++++++++++++++++++++++++------------------------- cimport.idx | 1 + git.html | 42 ++++++++++++++++-------------------- types.html | 17 ++++++--------- 4 files changed, 57 insertions(+), 63 deletions(-) diff --git a/cimport.html b/cimport.html index fa702cc..ae4e586 100644 --- a/cimport.html +++ b/cimport.html @@ -16,7 +16,7 @@ -cimport +Module cimport - + + + + + + + + + + + +
+
+

plugin

+
+
+ +
+ Search: +
+
+ Group by: + +
+ + +
+
+
+

+
+

Types

+
+ +
Symbol = object
+  name*: string
+  parent*: string
+  kind*: NimSymKind
+
+
+ + +
+ +
OnSymbol = proc (sym: var Symbol) {...}{.cdecl.}
+
+ + +
+ +
+ +
+
+ +
+ +
+
+
+ + + diff --git a/plugin.idx b/plugin.idx new file mode 100644 index 0000000..c5ac576 --- /dev/null +++ b/plugin.idx @@ -0,0 +1,2 @@ +Symbol plugin.html#Symbol plugin: Symbol +OnSymbol plugin.html#OnSymbol plugin: OnSymbol diff --git a/types.html b/types.html index e31f9cb..6f4d337 100644 --- a/types.html +++ b/types.html @@ -1288,7 +1288,7 @@ function main() { From 2bdb99c8fbb1cbc7b297f31c74a9ae6da46bf2ec Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 28 Jan 2019 10:57:47 -0600 Subject: [PATCH 141/593] Update documentation --- cimport.html | 2 +- plugin.html | 2 +- types.html | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cimport.html b/cimport.html index 3e05dde..73210ba 100644 --- a/cimport.html +++ b/cimport.html @@ -1440,7 +1440,7 @@ Add an include directory that is forwarded to the C/C++ compiler using
- Made with Nim. Generated: 2019-01-28 16:53:06 UTC + Made with Nim. Generated: 2019-01-28 16:57:12 UTC diff --git a/plugin.html b/plugin.html index 4f1cf32..d17a993 100644 --- a/plugin.html +++ b/plugin.html @@ -1287,7 +1287,7 @@ function main() { diff --git a/types.html b/types.html index 6f4d337..8695734 100644 --- a/types.html +++ b/types.html @@ -1288,7 +1288,7 @@ function main() { From 31ec7987dbb7df21fa36e7aeb5fb2f4a93cb1cb3 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 28 Jan 2019 16:14:58 -0600 Subject: [PATCH 142/593] Better context in _ error msg, gitPull fix for path, allow suppress of #define _X --- nimterop/getters.nim | 10 +++++++--- nimterop/git.nim | 8 +++----- nimterop/globals.nim | 4 ++-- nimterop/grammar.nim | 9 ++++++--- 4 files changed, 18 insertions(+), 13 deletions(-) diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 8b6b15d..42dc9f9 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -94,6 +94,9 @@ template checkUnderscores(name, errmsg: string): untyped = proc getIdentifier*(name: string, kind: NimSymKind, parent=""): string = doAssert name.len != 0, "Blank identifier error" + let + parentStr = if parent.nBl: parent & ":" else: "" + if name notin gStateRT.symOverride or parent.nBl: if gStateRT.onSymbol != nil: var @@ -101,12 +104,13 @@ proc getIdentifier*(name: string, kind: NimSymKind, parent=""): string = gStateRT.onSymbol(sym) result = sym.name - checkUnderscores(result, &"Identifier '{name}' still contains leading/trailing underscores '_' after 'cPlugin:onSymbol()': result '{result}'") + checkUnderscores(result, &"Identifier '{parentStr}{name}' ({kind}) still contains leading/trailing underscores '_' after 'cPlugin:onSymbol()': result '{result}'") - doAssert result.nBl, &"Blank {kind} '{result}', originally '{name}', child of '{parent}' so cannot be empty" + if parent.nBl: + doAssert result.nBl, &"Blank identifier, originally '{parentStr}{name}' ({kind}), cannot be empty" else: result = name - checkUnderscores(result, &"Identifier '{result}' contains unsupported leading/trailing underscores '_': use 'cPlugin:onSymbol()' to remove") + checkUnderscores(result, &"Identifier '{parentStr}{result}' ({kind}) contains unsupported leading/trailing underscores '_': use 'cPlugin:onSymbol()' to remove") if result in gReserved: result = &"`{result}`" diff --git a/nimterop/git.nim b/nimterop/git.nim index 8617b8b..7961385 100644 --- a/nimterop/git.nim +++ b/nimterop/git.nim @@ -65,15 +65,13 @@ macro gitCheckout*(file, outdir: static string): untyped = sleep(500) echo " Retrying ..." -macro gitPull*(url: static string, outdirN = "", plistN = "", checkoutN = ""): untyped = +macro gitPull*(url: static string, outdirN: static string = "", plist: static string = "", checkout: static string = ""): untyped = let - outdir = if outdirN.strVal().isAbsolute(): outdirN.strVal() else: getProjectPath()/outdirN.strVal() - plist = plistN.strVal() - checkout = checkoutN.strVal() + outdir = if outdirN.isAbsolute(): outdirN else: getProjectPath()/outdirN if dirExists(outdir/".git"): discard quote do: - gitReset(`outdirN`) + gitReset(`outdir`) return else: let diff --git a/nimterop/globals.nim b/nimterop/globals.nim index cfbefdb..b959958 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -47,7 +47,7 @@ type tonim*: proc (ast: ref Ast, node: TSNode, nimState: NimState) regex*: Regex - AstTable = TableRef[string, seq[ref Ast]] + AstTable {.used.} = TableRef[string, seq[ref Ast]] State = object compile*, defines*, headers*, includeDirs*, searchDirs*, symOverride*: seq[string] @@ -58,7 +58,7 @@ type onSymbol*: OnSymbol - NimState = ref object + NimState {.used.} = ref object identifiers*: TableRef[string, string] constStr*, debugStr*, enumStr*, procStr*, typeStr*: string diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index aae3b17..ad7ad9e 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -17,11 +17,14 @@ proc initGrammar(): Grammar = """, proc (ast: ref Ast, node: TSNode, nimState: NimState) = let - name = nimState.data[0].val.getIdentifier(nskConst) val = nimState.data[1].val.getLit() - if name.nBl and val.nBl and nimState.identifiers.addNewIdentifer(name): - nimState.constStr &= &" {name}* = {val}\n" + if val.nBl: + let + name = nimState.data[0].val.getIdentifier(nskConst) + + if name.nBl and nimState.identifiers.addNewIdentifer(name): + nimState.constStr &= &" {name}* = {val}\n" )) let From 343024738a57dc0c201d54068b79e24e873f00c7 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Sun, 27 Jan 2019 16:21:45 -0800 Subject: [PATCH 143/593] fix #71; bug fixes in types.nim --- nimterop/types.nim | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/nimterop/types.nim b/nimterop/types.nim index 80ba603..d9ffdcd 100644 --- a/nimterop/types.nim +++ b/nimterop/types.nim @@ -1,4 +1,33 @@ +#[ +TODO: +this should pull as few dependencies as needed by the wrapper, one option is, for the types that carry a dependency, wrap the type declaration inside something like: +``` +when defined(nimteropNeeds_va_list): + type + va_list* {.importc, header:"".} = object +``` + +TODO: +nimterop should replace the generated wrappers with the nim-idiomatic version, eg: +``` +proc mylib(a: ptrdiff_t) => proc mylib(a: ByteAddress) +``` +]# + +from std/time_t import nil # for time_t + +export time_t + type - time_t* = int32 ptrdiff_t* = ByteAddress - va_list* {.importc: "va_list", header:"".} = object \ No newline at end of file + +type + va_list* {.importc, header:"".} = object + +when defined(c): + # http://www.cplusplus.com/reference/cwchar/wchar_t/ In C++, wchar_t is a distinct fundamental type (and thus it is not defined in nor any other header). + type + wchar_t* {.importc, header:"".} = object +elif defined(cpp): + type + wchar_t* {.importc.} = object From ecb2d545088a65eb681f9a181bc39b854d39f057 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Mon, 28 Jan 2019 01:43:31 -0800 Subject: [PATCH 144/593] fix for 0.19.2 --- nimterop/types.nim | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/nimterop/types.nim b/nimterop/types.nim index d9ffdcd..c9168d0 100644 --- a/nimterop/types.nim +++ b/nimterop/types.nim @@ -1,5 +1,5 @@ #[ -TODO: +note: this should pull as few dependencies as needed by the wrapper, one option is, for the types that carry a dependency, wrap the type declaration inside something like: ``` when defined(nimteropNeeds_va_list): @@ -7,16 +7,34 @@ when defined(nimteropNeeds_va_list): va_list* {.importc, header:"".} = object ``` -TODO: +note: nimterop should replace the generated wrappers with the nim-idiomatic version, eg: ``` proc mylib(a: ptrdiff_t) => proc mylib(a: ByteAddress) ``` + +note: +as needed, provide (platform specific) nim aliases which can be used eg to compute sizeof, eg: +type foo_t* {.importc, header: "".} = distinct int32 ]# -from std/time_t import nil # for time_t - -export time_t +when (NimMajor, NimMinor, NimPatch) < (0, 19, 9): + # clean this up once upgraded; adapted from std/time_t + when defined(nimdoc): + type + impl = distinct int64 + Time = impl + elif defined(windows): + when defined(i386) and defined(gcc): + type Time {.importc: "time_t", header: "".} = distinct int32 + else: + type Time {.importc: "time_t", header: "".} = distinct int64 + elif defined(posix): + import posix + type time_t* = Time +else: + import std/time_t as time_t_temp + type time_t* = time_t_temp.Time type ptrdiff_t* = ByteAddress From 70deda95b795f7fbc9002cf3bf08d4ad8b0a5aa2 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Mon, 28 Jan 2019 14:21:50 -0800 Subject: [PATCH 145/593] address comments --- nimterop/types.nim | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/nimterop/types.nim b/nimterop/types.nim index c9168d0..c90f2e4 100644 --- a/nimterop/types.nim +++ b/nimterop/types.nim @@ -1,22 +1,4 @@ -#[ -note: -this should pull as few dependencies as needed by the wrapper, one option is, for the types that carry a dependency, wrap the type declaration inside something like: -``` -when defined(nimteropNeeds_va_list): - type - va_list* {.importc, header:"".} = object -``` - -note: -nimterop should replace the generated wrappers with the nim-idiomatic version, eg: -``` -proc mylib(a: ptrdiff_t) => proc mylib(a: ByteAddress) -``` - -note: -as needed, provide (platform specific) nim aliases which can be used eg to compute sizeof, eg: -type foo_t* {.importc, header: "".} = distinct int32 -]# +# see https://github.com/genotrance/nimterop/issues/79 when (NimMajor, NimMinor, NimPatch) < (0, 19, 9): # clean this up once upgraded; adapted from std/time_t From 839c4007f6a9e2b820be152df64f5f602535e18f Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Tue, 29 Jan 2019 21:06:26 -0800 Subject: [PATCH 146/593] fix #62 (toast now addressed relatively); macros=>procs + other fixes (#70) * fixes https://github.com/genotrance/nimterop/issues/62 * toast is now automatically built on demand, and doesn't depend on PATH - [ ] todo: need to track its deps properly to trigger rebuilding it; using same algo as shown here https://github.com/genotrance/nimterop/issues/69 but using nim deps instead of c deps * many other fixes * trying to follow https://github.com/timotheecour/vitanim/wiki/Nim-best-practices --- .gitignore | 10 +++-- build/.gitignore | 4 -- config.nims | 5 +++ nimterop.nimble | 42 ++++++++++++------- nimterop/cimport.nim | 14 ++++--- nimterop/git.nim | 73 ++++++++++++++++++--------------- nimterop/globals.nim | 2 +- nimterop/paths.nim | 17 ++++++++ nimterop/setup.nim | 33 ++++++++------- toast.nim => nimterop/toast.nim | 4 +- nimterop/treesitter/c.nim | 9 ++-- nimterop/treesitter/cpp.nim | 32 ++++++++++++--- nimterop/treesitter/runtime.nim | 13 +++--- tests/tnimterop_c.nim | 11 ++--- tests/tsoloud.nim | 12 +++--- 15 files changed, 173 insertions(+), 108 deletions(-) delete mode 100644 build/.gitignore create mode 100644 nimterop/paths.nim rename toast.nim => nimterop/toast.nim (97%) diff --git a/.gitignore b/.gitignore index df228b3..61390ef 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,12 @@ !/**/ !*.* -# TODO: all generated stuff should go inside `build/` + +# Notes: +# all generated files should go inside `build/` +# use absolute paths to refer to a path assumed to be at a fixed level in the hierarchy +/build + nimcache @@ -12,6 +17,3 @@ nimcache *.exe *.swp -# Note: use absolute paths to refer to a path assumed to be at a fixed dir level - -inc diff --git a/build/.gitignore b/build/.gitignore deleted file mode 100644 index f72369d..0000000 --- a/build/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -# everything generated should go in this dir -* -!/.gitignore - diff --git a/config.nims b/config.nims index 32bbe5e..5aac628 100644 --- a/config.nims +++ b/config.nims @@ -1,3 +1,8 @@ +#[ +see D20190127T231316 workaround for fact that toast needs to build scanner.cc, which would otherwise result in link erros such as: +"std::terminate()", referenced from: + ___clang_call_terminate in scanner.cc.o +]# when defined(MacOSX): switch("clang.linkerexe", "g++") else: diff --git a/nimterop.nimble b/nimterop.nimble index 77853a5..ec034f0 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -5,13 +5,17 @@ author = "genotrance" description = "C/C++ interop for Nim" license = "MIT" -bin = @["toast"] +# this gives Warning: Binary 'nimterop/toast' was already installed from source directory +# when running `nimble install --verbose -y` +bin = @["nimterop/toast"] installDirs = @["nimterop"] +installFiles = @["config.nims"] # Dependencies - requires "nim >= 0.19.2", "regex >= 0.10.0", "cligen >= 0.9.17" +import strformat + proc execCmd(cmd: string) = echo "execCmd:" & cmd exec cmd @@ -20,26 +24,34 @@ proc tsoloud() = execCmd "nim c -r tests/tsoloud.nim" execCmd "nim cpp -r tests/tsoloud.nim" -proc testall() = +proc buildToast(options: string) = + execCmd(&"nim c {options} nimterop/toast.nim") + +task rebuildToast, "rebuild toast": + # If need to manually rebuild (automatically built on 1st need) + buildToast("-d:release") + +proc testAll() = execCmd "nim c -r tests/tnimterop_c.nim" execCmd "nim cpp -r tests/tnimterop_c.nim" execCmd "nim cpp -r tests/tnimterop_cpp.nim" - when defined(windows): + + ## platform specific tests + when defined(Windows): execCmd "nim c -r tests/tmath.nim" execCmd "nim cpp -r tests/tmath.nim" - when not defined(OSX): - when defined(Windows): - tsoloud() - else: - if not existsEnv("TRAVIS"): - tsoloud() + tsoloud() + elif defined(osx): + discard + elif existsEnv("TRAVIS"): + discard + else: + tsoloud() task test, "Test": - execCmd "nim c toast" - testAll() - - execCmd "nim c -d:release toast" - testAll() + for options in ["", "-d:release"]: + buildToast(options) + testAll() task docs, "Generate docs": # Uses: pip install ghp-import diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index 7e9cd65..7fcd14d 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -2,9 +2,7 @@ import hashes, macros, os, strformat, strutils const CIMPORT {.used.} = 1 -include "."/globals - -import "."/types +import "." / [globals,types,paths] export types proc interpPath(dir: string): string= @@ -88,7 +86,10 @@ proc getToast(fullpath: string, recurse: bool = false): string = ret = 0 cmd = when defined(Windows): "cmd /c " else: "" - cmd &= "toast --pnim --preprocess" + let toastExe = toastExePath() + doAssert fileExists(toastExe), "toast not compiled: " & toastExe.quoteShell & + " make sure 'nimble build' or 'nimble install' built it" + cmd &= &"{toastExe} --pnim --preprocess" if recurse: cmd.add " --recurse" @@ -107,6 +108,7 @@ proc getToast(fullpath: string, recurse: bool = false): string = cmd.add &" {fullpath.quoteShell}" echo cmd + # see https://github.com/genotrance/nimterop/issues/69 (result, ret) = gorgeEx(cmd, cache=getCacheValue(fullpath)) doAssert ret == 0, getToastError(result) @@ -264,7 +266,7 @@ macro cDefine*(name: static string, val: static string = ""): untyped = var str = name if val.nBl: - str &= &"=\"{val}\"" + str &= &"={val.quoteShell}" if str notin gStateCT.defines: gStateCT.defines.add(str) @@ -302,7 +304,7 @@ macro cIncludeDir*(dir: static string): untyped = let fullpath = findPath(dir) - str = &"-I\"{fullpath}\"" + str = &"-I{fullpath.quoteShell}" if fullpath notin gStateCT.includeDirs: gStateCT.includeDirs.add(fullpath) diff --git a/nimterop/git.nim b/nimterop/git.nim index 7961385..edd2156 100644 --- a/nimterop/git.nim +++ b/nimterop/git.nim @@ -1,5 +1,7 @@ import macros, os, osproc, regex, strformat, strutils +import "."/paths + proc execAction*(cmd: string, nostderr=false): string = var ccmd = "" @@ -22,7 +24,7 @@ proc execAction*(cmd: string, nostderr=false): string = echo result quit(1) -macro extractZip*(zipfile, outdir: static string): untyped = +proc extractZip*(zipfile, outdir: string) = var cmd = "unzip -o $#" if defined(Windows): cmd = "powershell -nologo -noprofile -command \"& { Add-Type -A " & @@ -30,68 +32,73 @@ macro extractZip*(zipfile, outdir: static string): untyped = "[IO.Compression.ZipFile]::ExtractToDirectory('$#', '.'); }\"" echo "Extracting " & zipfile - discard execAction(&"cd \"{getProjectPath()/outdir}\" && " & cmd % zipfile) + discard execAction(&"cd {outdir.quoteShell} && {cmd % zipfile}") -macro downloadUrl*(url, outdir: static string): untyped = +proc downloadUrl*(url, outdir: string) = let file = url.extractFilename() ext = file.splitFile().ext.toLowerAscii() - var cmd = "curl $# -o $#" - if defined(Windows): - cmd = "powershell wget $# -OutFile $#" - - if not (ext == ".zip" and fileExists(getProjectPath()/outdir/file)): + if not (ext == ".zip" and fileExists(outdir/file)): echo "Downloading " & file - discard execAction(cmd % [url, getProjectPath()/outdir/file]) + var cmd = if defined(Windows): + "powershell wget $# -OutFile $#" + else: + "curl $# -o $#" + discard execAction(cmd % [url, outdir/file]) if ext == ".zip": - discard quote do: - extractZip(`file`, `outdir`) + extractZip(file, outdir) -macro gitReset*(outdir: static string): untyped = +proc gitReset*(outdir: string) = echo "Resetting " & outdir - let cmd = &"cd \"{getProjectPath()/outdir}\" && git reset --hard" + let cmd = &"cd {outdir.quoteShell} && git reset --hard" while execAction(cmd).contains("Permission denied"): sleep(1000) echo " Retrying ..." -macro gitCheckout*(file, outdir: static string): untyped = - echo "Resetting " & file +proc relativePathNaive*(file, base: string): string = + ## naive version of `os.relativePath` ; remove after nim >= 0.19.9 + runnableExamples: + doAssert "/foo/bar/baz/log.txt".relativePathNaive("/foo/bar") == "baz/log.txt" + var base = base + if not base.endsWith "/": base.add "/" + doAssert file.startsWith base + result = file[base.len .. ^1] - let cmd = &"cd \"{getProjectPath()/outdir}\" && git checkout $#" % file.replace(outdir & "/", "") +proc gitCheckout*(file, outdir: string) = + echo "Resetting " & file + let file2 = file.relativePathNaive outdir + let cmd = &"cd {outdir.quoteShell} && git checkout {file2.quoteShell}" while execAction(cmd).contains("Permission denied"): sleep(500) echo " Retrying ..." -macro gitPull*(url: static string, outdirN: static string = "", plist: static string = "", checkout: static string = ""): untyped = - let - outdir = if outdirN.isAbsolute(): outdirN else: getProjectPath()/outdirN - +proc gitPull*(url: string, outdir = "", plist = "", checkout = "") = if dirExists(outdir/".git"): - discard quote do: - gitReset(`outdir`) + gitReset(outdir) return - else: - let - flag = when not defined(Windows): "-p" else: "" - echo execAction(&"mkdir {flag} \"{outdir}\"") + let + outdir2 = outdir.quoteShell + flag = when not defined(Windows): "-p" else: "" + echo execAction(&"mkdir {flag} {outdir2}") echo "Setting up Git repo: " & url - discard execAction(&"cd \"{outdir}\" && git init .") - discard execAction(&"cd \"{outdir}\" && git remote add origin " & url) + discard execAction(&"cd {outdir2} && git init .") + discard execAction(&"cd {outdir2} && git remote add origin {url}") if plist.len != 0: - let sparsefile = &"{outdir}/.git/info/sparse-checkout" + # TODO: document this, it's not clear + let sparsefile = outdir / ".git/info/sparse-checkout" - discard execAction(&"cd \"{outdir}\" && git config core.sparsecheckout true") + discard execAction(&"cd {outdir2} && git config core.sparsecheckout true") writeFile(sparsefile, plist) if checkout.len != 0: echo "Checking out " & checkout - discard execAction(&"cd \"{outdir}\" && git pull --tags origin master") - discard execAction(&"cd \"{outdir}\" && git checkout {checkout}") + discard execAction(&"cd {outdir2} && git pull --tags origin master") + discard execAction(&"cd {outdir2} && git checkout {checkout}") else: echo "Pulling repository" - discard execAction(&"cd \"{outdir}\" && git pull --depth=1 origin master") + discard execAction(&"cd {outdir2} && git pull --depth=1 origin master") diff --git a/nimterop/globals.nim b/nimterop/globals.nim index b959958..bf9a0ef 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -68,7 +68,7 @@ type data*: seq[tuple[name, val: string]] var - gStateCT {.compiletime, used.}: State + gStateCT* {.compiletime, used.}: State gStateRT {.used.}: State template nBl(s: typed): untyped {.used.} = diff --git a/nimterop/paths.nim b/nimterop/paths.nim new file mode 100644 index 0000000..64879a4 --- /dev/null +++ b/nimterop/paths.nim @@ -0,0 +1,17 @@ +import os + +proc nimteropRoot*(): string = + currentSourcePath.parentDir.parentDir + +proc nimteropBuildDir*(): string = + ## all nimterop generated files go under here (gitignored) + nimteropRoot() / "build" + +proc nimteropSrcDir*(): string = + nimteropRoot() / "nimterop" + +proc toastExePath*(): string = + nimteropSrcDir() / ("toast".addFileExt ExeExt) + +proc incDir*(): string = + nimteropBuildDir() / "inc" diff --git a/nimterop/setup.nim b/nimterop/setup.nim index 06f15d4..2c1c7c0 100644 --- a/nimterop/setup.nim +++ b/nimterop/setup.nim @@ -1,51 +1,50 @@ import os, strutils -import "."/git - -const sourcePath = currentSourcePath().split({'\\', '/'})[0..^3].join("/") & "/inc" +import "."/[git,paths] proc treesitterSetup*() = - gitPull("https://github.com/tree-sitter/tree-sitter/", "inc/treesitter", """ + gitPull("https://github.com/tree-sitter/tree-sitter/", incDir() / "treesitter", """ include/* src/runtime/* """) - gitPull("https://github.com/JuliaStrings/utf8proc", "inc/utf8proc", """ + gitPull("https://github.com/JuliaStrings/utf8proc", incDir() / "utf8proc", """ *.c *.h """) - + + # TODO: does this work on windows? if not use `os.unixToNativePath` let - stack = sourcePath & "/treesitter/src/runtime/stack.c" + stack = incDir() / "treesitter/src/runtime/stack.c" stack.writeFile(stack.readFile().replace("inline Stack", "Stack")) proc treesitterCSetup*() = - gitPull("https://github.com/tree-sitter/tree-sitter-c", "inc/treesitter_c", """ + gitPull("https://github.com/tree-sitter/tree-sitter-c", incDir() / "treesitter_c", """ src/*.h src/*.c src/*.cc """) let - headerc = sourcePath & "/treesitter_c/src/parser.h" + headerc = incDir() / "treesitter_c/src/parser.h" headerc.writeFile(""" - typedef struct TSLanguage TSLanguage; - const TSLanguage *tree_sitter_c(); - """) +typedef struct TSLanguage TSLanguage; +const TSLanguage *tree_sitter_c(); +""") proc treesitterCppSetup*() = - gitPull("https://github.com/tree-sitter/tree-sitter-cpp", "inc/treesitter_cpp", """ + gitPull("https://github.com/tree-sitter/tree-sitter-cpp", incDir() / "treesitter_cpp", """ src/*.h src/*.c src/*.cc """) let - headercpp = sourcePath & "/treesitter_cpp/src/parser.h" + headercpp = incDir() / "treesitter_cpp/src/parser.h" headercpp.writeFile(""" - typedef struct TSLanguage TSLanguage; - const TSLanguage *tree_sitter_cpp(); - """) +typedef struct TSLanguage TSLanguage; +const TSLanguage *tree_sitter_cpp(); +""") diff --git a/toast.nim b/nimterop/toast.nim similarity index 97% rename from toast.nim rename to nimterop/toast.nim index 13295af..9221802 100644 --- a/toast.nim +++ b/nimterop/toast.nim @@ -1,8 +1,8 @@ import os, strformat, strutils -import nimterop/treesitter/[runtime, c, cpp] +import "."/treesitter/[runtime, c, cpp] -import nimterop/[ast, globals, getters, grammar] +import "."/[ast, globals, getters, grammar] proc printLisp(root: TSNode) = var diff --git a/nimterop/treesitter/c.nim b/nimterop/treesitter/c.nim index da13f2e..b4a8228 100644 --- a/nimterop/treesitter/c.nim +++ b/nimterop/treesitter/c.nim @@ -1,13 +1,12 @@ -import strutils +import strutils, os -import ".."/setup +import ".."/[setup,paths] static: treesitterCSetup() import "."/runtime -{.compile: ("../../inc/treesitter_c/src/parser.c", "parserc.o").} +{.compile: incDir() / "treesitter_c/src/parser.c".} -const sourcePath = currentSourcePath().split({'\\', '/'})[0..^4].join("/") -proc treeSitterC*(): ptr TSLanguage {.importc: "tree_sitter_c", header: sourcePath & "/inc/treesitter_c/src/parser.h".} +proc treeSitterC*(): ptr TSLanguage {.importc: "tree_sitter_c", header: incDir() / "treesitter_c/src/parser.h".} diff --git a/nimterop/treesitter/cpp.nim b/nimterop/treesitter/cpp.nim index ec6cf2c..c0eca0c 100644 --- a/nimterop/treesitter/cpp.nim +++ b/nimterop/treesitter/cpp.nim @@ -1,14 +1,34 @@ -import strutils +import strutils, os -import ".."/setup +import ".."/[setup,paths] static: treesitterCppSetup() import "."/runtime -{.compile: ("../../inc/treesitter_cpp/src/parser.c", "parsercpp.o").} -{.compile: ("../../inc/treesitter_cpp/src/scanner.cc", "scannercpp.o").} +const srcDir = incDir() / "treesitter_cpp/src" -const sourcePath = currentSourcePath().split({'\\', '/'})[0..^4].join("/") & "/inc/treesitter_cpp/src/" -proc treeSitterCpp*(): ptr TSLanguage {.importc: "tree_sitter_cpp", header: sourcePath & "parser.h".} +when (NimMajor, NimMinor, NimPatch) < (0, 19, 9): + const srcDirRel = "../../build/inc/treesitter_cpp/src" +else: + const srcDirRel = srcDir.relativePath(currentSourcePath.parentDir) + +# pending https://github.com/nim-lang/Nim/issues/9370 we need srcDirRel instead +# of srcDir +{.compile: (srcDirRel / "parser.c", "nimtero_cpp_parser.c.o").} + +#[ +D20190127T231316:here note: this will be compiled as a C++ file even with +`nim c`, thanks to the extension (which clang/gcc understands); +however, in `nim c` mode this will fail in link phase +(which by default would use `clang/gcc`) +unless linker is overridden, see D20190127T231316. + +cleaner alternative: compile `scanner.cc` into a shared library +that we link against, which avoids the linker hack. +]# + +{.compile: srcDir / "scanner.cc".} + +proc treeSitterCpp*(): ptr TSLanguage {.importc: "tree_sitter_cpp", header: srcDir / "parser.h".} diff --git a/nimterop/treesitter/runtime.nim b/nimterop/treesitter/runtime.nim index d5fbed5..acb2289 100644 --- a/nimterop/treesitter/runtime.nim +++ b/nimterop/treesitter/runtime.nim @@ -1,13 +1,13 @@ {.experimental: "codeReordering".} -import strutils +import strutils, os -import ".."/setup +import ".."/[setup,paths] static: treesitterSetup() -const sourcePath = currentSourcePath().split({'\\', '/'})[0..^4].join("/") & "/inc/treesitter" +const sourcePath = incDir() / "treesitter" when defined(Linux): {.passC: "-std=c11".} @@ -15,7 +15,10 @@ when defined(Linux): {.passC: "-I$1/include" % sourcePath.} {.passC: "-I$1/src" % sourcePath.} {.passC: "-I$1/../utf8proc" % sourcePath.} -{.compile: sourcePath & "/src/runtime/runtime.c".} +# pending https://github.com/nim-lang/Nim/issues/10299 we need to rename the +# object files (via compile:(foo,bar)) to avoid name collisions, here +# and everywhere `compile` is used +{.compile: sourcePath / "src/runtime/runtime.c".} type TSInputEncoding* = distinct int converter enumToInt(en: TSInputEncoding): int {.used.} = en.int @@ -27,7 +30,7 @@ type TSLogType* = distinct int converter enumToInt(en: TSLogType): int {.used.} = en.int const - headerruntime = sourcePath & "/include/tree_sitter/runtime.h" + headerruntime = sourcePath / "include/tree_sitter/runtime.h" TREE_SITTER_LANGUAGE_VERSION* = 9 TSInputEncodingUTF8* = 0.TSInputEncoding TSInputEncodingUTF16* = 1.TSInputEncoding diff --git a/tests/tnimterop_c.nim b/tests/tnimterop_c.nim index ece78db..eca3324 100644 --- a/tests/tnimterop_c.nim +++ b/tests/tnimterop_c.nim @@ -67,9 +67,11 @@ s1.field1 = 5 s2.field1 = 6 s3.field1 = 7 s4.field2[2] = 5 + +# note: simplify with `defined(c)` for nim >= 0.19.9 when defined(cpp): - discard # TODO -else: # TODO: what's `defined(cpp)` for c ? + discard +else: s4.field3[3] = enum1 s5.tci = test_call_int @@ -92,9 +94,9 @@ check test_call_int() == 5 check test_call_param(5).field1 == 5 check test_call_param2(5, s2).field1 == 11 check test_call_param3(5, s1).field1 == 10 -# error: assigning to 'enum ENUM' from incompatible type 'NI' (aka 'long long') when defined(cpp): - discard # TODO + # error: assigning to 'enum ENUM' from incompatible type 'NI' (aka 'long long') + discard else: check test_call_param4(e) == e2 check test_call_param5(5.0).field2 == 5.0 @@ -103,7 +105,6 @@ u.field1 = 4 check test_call_param7(u) == 4 when defined(cpp): - # TODO # note: candidate function not viable: no known conversion from 'NI *' (aka 'long long *') to 'int *' for 1st argument # check test_call_param8(cast[ptr int](addr i)) == 25.0 discard diff --git a/tests/tsoloud.nim b/tests/tsoloud.nim index 8d2143b..2d1c40d 100644 --- a/tests/tsoloud.nim +++ b/tests/tsoloud.nim @@ -1,10 +1,12 @@ -import os, nimterop/[cimport, git] +import os, nimterop/[cimport, git, paths] const - incl = "soloud/include" - src = "soloud/src" + baseDir = nimteropBuildDir()/"soloud" + incl = baseDir/"include" + src = baseDir/"src" -gitPull("https://github.com/jarikomppa/soloud", "soloud", "include/*\nsrc/*\n") +static: + gitPull("https://github.com/jarikomppa/soloud", baseDir, "include/*\nsrc/*\n") cDebug() cDisableCaching() @@ -50,4 +52,4 @@ when declared(WavStream_stop): assert "WavStream_stop() not skipped" when declared(WavStream_setFilter): - assert "WavStream_setFilter not skipped" \ No newline at end of file + assert "WavStream_setFilter not skipped" From 69aaa8725362b04eebe1ae1ddf57f3c9cd4d7a6d Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Tue, 29 Jan 2019 21:45:19 -0800 Subject: [PATCH 147/593] `quit => doAssert` to show backtrace + relevant context + exception friendly (#85) --- nimterop/git.nim | 6 ++---- nimterop/lisp.nim | 9 +++------ 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/nimterop/git.nim b/nimterop/git.nim index edd2156..2315204 100644 --- a/nimterop/git.nim +++ b/nimterop/git.nim @@ -19,10 +19,8 @@ proc execAction*(cmd: string, nostderr=false): string = else: (result, ret) = execCmdEx(ccmd) if ret != 0: - echo "Command failed: " & $ret - echo ccmd - echo result - quit(1) + let msg = "Command failed: " & $ret & "\nccmd: " & ccmd & "\nresult:\n" & result + doAssert false, msg proc extractZip*(zipfile, outdir: string) = var cmd = "unzip -o $#" diff --git a/nimterop/lisp.nim b/nimterop/lisp.nim index c21c3be..119de36 100644 --- a/nimterop/lisp.nim +++ b/nimterop/lisp.nim @@ -25,13 +25,11 @@ proc tokenize(tree: string) = proc readFromTokens(): ref Ast = if idx == gTokens.len: - echo "Bad AST" - quit(1) + doAssert false, "Bad AST " & $(idx: idx) if gTokens[idx] == "(": if gTokens.len - idx < 2: - echo "Corrupt AST" - quit(1) + doAssert false, "Corrupt AST " & $(gTokensLen: gTokens.len, idx: idx) if gTokens[idx+1] != "comment": result = new(Ast) (result.name, result.kind, result.recursive) = gTokens[idx+1].getNameKind() @@ -44,8 +42,7 @@ proc readFromTokens(): ref Ast = if not res.isNil(): result.children.add(res) elif gTokens[idx] == ")": - echo "Poor AST" - quit(1) + doAssert false, "Poor AST " & $(idx: idx) idx += 1 From ef8149778cc0a9c99b2f9904e16913f5be70e5b4 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Tue, 29 Jan 2019 21:47:53 -0800 Subject: [PATCH 148/593] make tsoloud work on OSX (#84) --- nimterop.nimble | 9 ++------- tests/tsoloud.nim | 11 ++++++++--- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/nimterop.nimble b/nimterop.nimble index ec034f0..bcdd78d 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -40,13 +40,8 @@ proc testAll() = when defined(Windows): execCmd "nim c -r tests/tmath.nim" execCmd "nim cpp -r tests/tmath.nim" - tsoloud() - elif defined(osx): - discard - elif existsEnv("TRAVIS"): - discard - else: - tsoloud() + if defined(OSX) or defined(Windows) or not existsEnv("TRAVIS"): + tsoloud() # requires some libraries on linux, need them installed in TRAVIS task test, "Test": for options in ["", "-d:release"]: diff --git a/tests/tsoloud.nim b/tests/tsoloud.nim index 2d1c40d..ea7bbb2 100644 --- a/tests/tsoloud.nim +++ b/tests/tsoloud.nim @@ -22,16 +22,21 @@ cSkipSymbol("WavStream_stop", "WavStream_setFilter") cIncludeDir(incl) -when defined(Linux): +when defined(osx): + cDefine("WITH_COREAUDIO") + {.passL: "-framework CoreAudio -framework AudioToolbox".} + cCompile(src/"backend/coreaudio/*.cpp") +elif defined(Linux): {.passL: "-lpthread".} cDefine("WITH_OSS") cCompile(src/"backend/oss/*.cpp") - -when defined(Windows): +elif defined(Windows): {.passC: "-msse".} {.passL: "-lwinmm".} cDefine("WITH_WINMM") cCompile(src/"backend/winmm/*.cpp") +else: + static: doAssert false cCompile(src/"c_api/soloud_c.cpp") cCompile(src/"core/*.cpp") From 3709628b6627cdf5cfb2931b1b8e88a86c9b5dec Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Wed, 30 Jan 2019 04:34:17 -0800 Subject: [PATCH 149/593] rm tests/.gitignore now that top-level .gitignore ignores exe and that generated includes go under ./build (#92) --- tests/.gitignore | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 tests/.gitignore diff --git a/tests/.gitignore b/tests/.gitignore deleted file mode 100644 index 7df3c8d..0000000 --- a/tests/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -/* -!*.nim -!.gitignore -!/include/ - From 731398c98860ca0cdf671a38539e48283be04d4d Mon Sep 17 00:00:00 2001 From: genotrance Date: Wed, 30 Jan 2019 22:52:49 -0600 Subject: [PATCH 150/593] Fix #72 (#97) * Remove enum converter - #72 * Workaround gc crash on Windows * Suppress hint, import types in toast --- config.nims | 7 +++++- nimterop/ast.nim | 13 +++++++---- nimterop/cimport.nim | 2 +- nimterop/grammar.nim | 41 ++++++++++++++++----------------- nimterop/setup.nim | 4 ++-- nimterop/treesitter/c.nim | 2 +- nimterop/treesitter/cpp.nim | 2 +- nimterop/treesitter/runtime.nim | 4 ++-- nimterop/types.nim | 28 ++++++++++++++++++++++ 9 files changed, 69 insertions(+), 34 deletions(-) diff --git a/config.nims b/config.nims index 5aac628..d43b04f 100644 --- a/config.nims +++ b/config.nims @@ -1,5 +1,6 @@ #[ -see D20190127T231316 workaround for fact that toast needs to build scanner.cc, which would otherwise result in link erros such as: +see D20190127T231316 workaround for fact that toast needs to build +scanner.cc, which would otherwise result in link errors such as: "std::terminate()", referenced from: ___clang_call_terminate in scanner.cc.o ]# @@ -7,3 +8,7 @@ when defined(MacOSX): switch("clang.linkerexe", "g++") else: switch("gcc.linkerexe", "g++") + +# Workaround for NilAccessError crash on Windows #98 +when defined(Windows): + switch("gc", "markAndSweep") \ No newline at end of file diff --git a/nimterop/ast.nim b/nimterop/ast.nim index 0c5c4bc..1cc2c6c 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -99,7 +99,7 @@ proc searchAst(root: TSNode, astTable: AstTable, nimState: NimState) = if searchAstForNode(ast, node, nimState): ast.tonim(ast, node, nimState) if gStateRT.debug: - nimState.debugStr &= "\n\n# " & nimState.data.join("\n# ") + nimState.debugStr &= "\n# " & nimState.data.join("\n# ") break nimState.data = @[] else: @@ -134,6 +134,9 @@ proc printNimHeader*() = # $2 $3 {.experimental: "codeReordering".} +{.hint[ConvFromXtoItselfNotNeeded]: off.} + +import nimterop/types """ % [$now(), getAppFilename(), commandLineParams().join(" ")] proc printNim*(fullpath: string, root: TSNode, astTable: AstTable) = @@ -143,7 +146,7 @@ proc printNim*(fullpath: string, root: TSNode, astTable: AstTable) = nimState.identifiers = newTable[string, string]() nimState.currentHeader = getCurrentHeader(fullpath) - nimState.constStr &= &" {nimState.currentHeader} = \"{fp}\"\n" + nimState.constStr &= &"\n {nimState.currentHeader} = \"{fp}\"" root.searchAst(astTable, nimState) @@ -151,13 +154,13 @@ proc printNim*(fullpath: string, root: TSNode, astTable: AstTable) = echo nimState.enumStr if nimState.constStr.nBl: - echo "const\n" & nimState.constStr + echo &"const {nimState.constStr}\n" if nimState.typeStr.nBl: - echo "type\n" & nimState.typeStr + echo &"type {nimState.typeStr}\n" if nimState.procStr.nBl: - echo nimState.procStr + echo &"{nimState.procStr}\n" if gStateRT.debug and nimState.debugStr.nBl: echo nimState.debugStr \ No newline at end of file diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index 7fcd14d..298c8a2 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -2,7 +2,7 @@ import hashes, macros, os, strformat, strutils const CIMPORT {.used.} = 1 -import "." / [globals,types,paths] +import "." / [globals, types, paths] export types proc interpPath(dir: string): string= diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index ad7ad9e..6b1e051 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -24,7 +24,7 @@ proc initGrammar(): Grammar = name = nimState.data[0].val.getIdentifier(nskConst) if name.nBl and nimState.identifiers.addNewIdentifer(name): - nimState.constStr &= &" {name}* = {val}\n" + nimState.constStr &= &"\n {name}* = {val}" )) let @@ -148,9 +148,9 @@ proc initGrammar(): Grammar = pout = pout[0 .. ^2] if tptr == "ptr " or typ != "object": - nimState.typeStr &= &" {name}* = proc({pout}): {getPtrType(tptr&typ)} {{.nimcall.}}\n" + nimState.typeStr &= &"\n {name}* = proc({pout}): {getPtrType(tptr&typ)} {{.nimcall.}}" else: - nimState.typeStr &= &" {name}* = proc({pout}) {{.nimcall.}}\n" + nimState.typeStr &= &"\n {name}* = proc({pout}) {{.nimcall.}}" else: if i < nimState.data.len and nimState.data[i].name in ["identifier", "number_literal"]: var @@ -158,12 +158,12 @@ proc initGrammar(): Grammar = if nimState.data[i].name == "identifier": flen = flen.getIdentifier(nskConst, name) - nimState.typeStr &= &" {name}* = {aptr}array[{flen}, {getPtrType(tptr&typ)}]\n" + nimState.typeStr &= &"\n {name}* = {aptr}array[{flen}, {getPtrType(tptr&typ)}]" else: if name == typ: - nimState.typeStr &= &" {name}* = object\n" + nimState.typeStr &= &"\n {name}* = object" else: - nimState.typeStr &= &" {name}* = {getPtrType(tptr&typ)}\n" + nimState.typeStr &= &"\n {name}* = {getPtrType(tptr&typ)}" )) proc pDupTypeCommon(nname: string, fend: int, nimState: NimState, isEnum=false) = @@ -179,11 +179,11 @@ proc initGrammar(): Grammar = if ndname.nBl and ndname != nname: if isEnum: if nimState.identifiers.addNewIdentifer(ndname): - nimState.enumStr &= &"type {ndname}* = {dptr}{nname}\n" + nimState.enumStr &= &"\ntype {ndname}* = {dptr}{nname}" else: if nimState.identifiers.addNewIdentifer(ndname): nimState.typeStr &= - &" {ndname}* {{.importc: \"{dname}\", header: {nimState.currentHeader}, bycopy.}} = {dptr}{nname}\n" + &"\n {ndname}* {{.importc: \"{dname}\", header: {nimState.currentHeader}, bycopy.}} = {dptr}{nname}" proc pStructCommon(ast: ref Ast, node: TSNode, name: string, fstart, fend: int, nimState: NimState) = var @@ -215,9 +215,9 @@ proc initGrammar(): Grammar = if nname.nBl and nimState.identifiers.addNewIdentifer(nname): if nimState.data.len == 1: - nimState.typeStr &= &" {nname}* {{.bycopy.}} = object{union}\n" + nimState.typeStr &= &"\n {nname}* {{.bycopy.}} = object{union}" else: - nimState.typeStr &= &" {nname}* {{.importc: \"{prefix}{name}\", header: {nimState.currentHeader}, bycopy.}} = object{union}\n" + nimState.typeStr &= &"\n {nname}* {{.importc: \"{prefix}{name}\", header: {nimState.currentHeader}, bycopy.}} = object{union}" var i = fstart @@ -248,7 +248,7 @@ proc initGrammar(): Grammar = if i+1 < nimState.data.len-fend and nimState.data[i+1].name in gEnumVals: let flen = nimState.data[i+1].val.getNimExpression() - nimState.typeStr &= &" {fname}*: {aptr}array[{flen}, {getPtrType(fptr&ftyp)}]\n" + nimState.typeStr &= &"\n {fname}*: {aptr}array[{flen}, {getPtrType(fptr&ftyp)}]" i += 2 elif i+1 < nimState.data.len-fend and nimState.data[i+1].name == "function_declarator": var @@ -269,15 +269,15 @@ proc initGrammar(): Grammar = if pout.len != 0 and pout[^1] == ',': pout = pout[0 .. ^2] if fptr == "ptr " or ftyp != "object": - nimState.typeStr &= &" {fname}*: proc({pout}): {getPtrType(fptr&ftyp)} {{.nimcall.}}\n" + nimState.typeStr &= &"\n {fname}*: proc({pout}): {getPtrType(fptr&ftyp)} {{.nimcall.}}" else: - nimState.typeStr &= &" {fname}*: proc({pout}) {{.nimcall.}}\n" + nimState.typeStr &= &"\n {fname}*: proc({pout}) {{.nimcall.}}" i += 1 else: if ftyp == "object": - nimState.typeStr &= &" {fname}*: pointer\n" + nimState.typeStr &= &"\n {fname}*: pointer" else: - nimState.typeStr &= &" {fname}*: {getPtrType(fptr&ftyp)}\n" + nimState.typeStr &= &"\n {fname}*: {getPtrType(fptr&ftyp)}" i += 1 if node.tsNodeType() == "type_definition" and @@ -364,8 +364,7 @@ proc initGrammar(): Grammar = name.getIdentifier(nskType) if nname.nBl and nimState.identifiers.addNewIdentifer(nname): - nimState.enumStr &= &"\ntype {nname}* = distinct int" - nimState.enumStr &= &"\nconverter enumToInt(en: {nname}): int {{.used.}} = en.int\n" + nimState.enumStr &= &"\ndefineEnum({nname})" var i = fstart @@ -381,7 +380,7 @@ proc initGrammar(): Grammar = if i+1 < nimState.data.len-fend and nimState.data[i+1].name in gEnumVals: if fname.nBl and nimState.identifiers.addNewIdentifer(fname): - nimState.constStr &= &" {fname}* = ({nimState.data[i+1].val.getNimExpression()}).{nname}\n" + nimState.constStr &= &"\n {fname}* = ({nimState.data[i+1].val.getNimExpression()}).{nname}" try: count = nimState.data[i+1].val.parseInt() + 1 except: @@ -389,7 +388,7 @@ proc initGrammar(): Grammar = i += 2 else: if fname.nBl and nimState.identifiers.addNewIdentifer(fname): - nimState.constStr &= &" {fname}* = {count}.{nname}\n" + nimState.constStr &= &"\n {fname}* = {count}.{nname}" i += 1 count += 1 @@ -494,9 +493,9 @@ proc initGrammar(): Grammar = let ftyp = nimState.data[0].val.getIdentifier(nskType, fnname) if fptr == "ptr " or ftyp != "object": - nimState.procStr &= &"proc {fnname}*({pout}): {getPtrType(fptr&ftyp)} {{.importc: \"{fname}\", header: {nimState.currentHeader}.}}\n" + nimState.procStr &= &"\nproc {fnname}*({pout}): {getPtrType(fptr&ftyp)} {{.importc: \"{fname}\", header: {nimState.currentHeader}.}}" else: - nimState.procStr &= &"proc {fnname}*({pout}) {{.importc: \"{fname}\", header: {nimState.currentHeader}.}}\n" + nimState.procStr &= &"\nproc {fnname}*({pout}) {{.importc: \"{fname}\", header: {nimState.currentHeader}.}}" )) diff --git a/nimterop/setup.nim b/nimterop/setup.nim index 2c1c7c0..3c7afac 100644 --- a/nimterop/setup.nim +++ b/nimterop/setup.nim @@ -1,6 +1,6 @@ import os, strutils -import "."/[git,paths] +import "."/[git, paths] proc treesitterSetup*() = gitPull("https://github.com/tree-sitter/tree-sitter/", incDir() / "treesitter", """ @@ -12,7 +12,7 @@ src/runtime/* *.c *.h """) - + # TODO: does this work on windows? if not use `os.unixToNativePath` let stack = incDir() / "treesitter/src/runtime/stack.c" diff --git a/nimterop/treesitter/c.nim b/nimterop/treesitter/c.nim index b4a8228..f34eaf9 100644 --- a/nimterop/treesitter/c.nim +++ b/nimterop/treesitter/c.nim @@ -1,6 +1,6 @@ import strutils, os -import ".."/[setup,paths] +import ".."/[setup, paths] static: treesitterCSetup() diff --git a/nimterop/treesitter/cpp.nim b/nimterop/treesitter/cpp.nim index c0eca0c..7fc0b13 100644 --- a/nimterop/treesitter/cpp.nim +++ b/nimterop/treesitter/cpp.nim @@ -1,6 +1,6 @@ import strutils, os -import ".."/[setup,paths] +import ".."/[setup, paths] static: treesitterCppSetup() diff --git a/nimterop/treesitter/runtime.nim b/nimterop/treesitter/runtime.nim index acb2289..8885400 100644 --- a/nimterop/treesitter/runtime.nim +++ b/nimterop/treesitter/runtime.nim @@ -2,7 +2,7 @@ import strutils, os -import ".."/[setup,paths] +import ".."/[setup, paths] static: treesitterSetup() @@ -16,7 +16,7 @@ when defined(Linux): {.passC: "-I$1/src" % sourcePath.} {.passC: "-I$1/../utf8proc" % sourcePath.} # pending https://github.com/nim-lang/Nim/issues/10299 we need to rename the -# object files (via compile:(foo,bar)) to avoid name collisions, here +# object files (via compile:(foo,bar)) to avoid name collisions, here # and everywhere `compile` is used {.compile: sourcePath / "src/runtime/runtime.c".} diff --git a/nimterop/types.nim b/nimterop/types.nim index c90f2e4..ecc5345 100644 --- a/nimterop/types.nim +++ b/nimterop/types.nim @@ -31,3 +31,31 @@ when defined(c): elif defined(cpp): type wchar_t* {.importc.} = object + +template enumOp*(op, typ, typout) = + proc op*(x: typ, y: int): typout {.borrow.} + proc op*(x: int, y: typ): typout {.borrow.} + proc op*(x, y: typ): typout {.borrow.} + +template defineEnum*(typ) = + type + typ* = distinct int + + enumOp(`+`, typ, typ) + enumOp(`-`, typ, typ) + enumOp(`*`, typ, typ) + enumOp(`<`, typ, bool) + enumOp(`<=`, typ, bool) + enumOp(`==`, typ, bool) + enumOp(`div`, typ, typ) + enumOp(`mod`, typ, typ) + + proc `shl`*(x: typ, y: int): typ {.borrow.} + proc `shl`*(x: int, y: typ): typ {.borrow.} + proc `shl`*(x, y: typ): typ {.borrow.} + + proc `shr`*(x: typ, y: int): typ {.borrow.} + proc `shr`*(x: int, y: typ): typ {.borrow.} + proc `shr`*(x, y: typ): typ {.borrow.} + + proc `$` *(x: typ): string {.borrow.} \ No newline at end of file From 5f70b01302169d1f5f970597c67893a79d18a989 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Wed, 30 Jan 2019 21:50:43 -0800 Subject: [PATCH 151/593] refs #60 importc is now DRY (#88) --- nimterop/grammar.nim | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index 6b1e051..510cc7c 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -7,6 +7,11 @@ import "."/[getters, globals, lisp, treesitter/runtime] type Grammar = seq[tuple[grammar: string, call: proc(ast: ref Ast, node: TSNode, nimState: NimState) {.nimcall.}]] +proc genImportC(origName, nimName: string): string = + result = "importc" + if nimName != origName: + result.add &": \"{origName}\"" # used as {.importc: "foo".} + proc initGrammar(): Grammar = # #define X Y result.add((""" @@ -166,6 +171,7 @@ proc initGrammar(): Grammar = nimState.typeStr &= &"\n {name}* = {getPtrType(tptr&typ)}" )) + proc pDupTypeCommon(nname: string, fend: int, nimState: NimState, isEnum=false) = var dname = nimState.data[^1].val @@ -183,7 +189,7 @@ proc initGrammar(): Grammar = else: if nimState.identifiers.addNewIdentifer(ndname): nimState.typeStr &= - &"\n {ndname}* {{.importc: \"{dname}\", header: {nimState.currentHeader}, bycopy.}} = {dptr}{nname}" + &"\n {ndname}* {{.{genImportC(dname, ndname)}, header: {nimState.currentHeader}, bycopy.}} = {dptr}{nname}" proc pStructCommon(ast: ref Ast, node: TSNode, name: string, fstart, fend: int, nimState: NimState) = var @@ -217,7 +223,8 @@ proc initGrammar(): Grammar = if nimState.data.len == 1: nimState.typeStr &= &"\n {nname}* {{.bycopy.}} = object{union}" else: - nimState.typeStr &= &"\n {nname}* {{.importc: \"{prefix}{name}\", header: {nimState.currentHeader}, bycopy.}} = object{union}" + let importCDecl = genImportC(prefix & name, nname) + nimState.typeStr &= &"\n {nname}* {{.{importCDecl}, header: {nimState.currentHeader}, bycopy.}} = object{union}" var i = fstart @@ -491,12 +498,10 @@ proc initGrammar(): Grammar = if fnname.nBl and nimState.identifiers.addNewIdentifer(fnname): let ftyp = nimState.data[0].val.getIdentifier(nskType, fnname) - if fptr == "ptr " or ftyp != "object": - nimState.procStr &= &"\nproc {fnname}*({pout}): {getPtrType(fptr&ftyp)} {{.importc: \"{fname}\", header: {nimState.currentHeader}.}}" + nimState.procStr &= &"\nproc {fnname}*({pout}): {getPtrType(fptr&ftyp)} {{.{genImportC(fname, fnname)}, header: {nimState.currentHeader}.}}" else: - nimState.procStr &= &"\nproc {fnname}*({pout}) {{.importc: \"{fname}\", header: {nimState.currentHeader}.}}" - + nimState.procStr &= &"\nproc {fnname}*({pout}) {{.{genImportC(fname, fnname)}, header: {nimState.currentHeader}.}}" )) proc initRegex(ast: ref Ast) = From abaac4d1bf6ce018a8244c1bb7a130bb8f93207d Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 31 Jan 2019 09:14:56 -0600 Subject: [PATCH 152/593] Fix cOverride crash on pragmas --- nimterop/cimport.nim | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index 298c8a2..6a78b5e 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -149,15 +149,17 @@ macro cOverride*(body): untyped = ## can be instructed to skip over ``svGetCallerInfo()``. This works for procs, ## consts and types. + proc recFindIdent(node: NimNode): seq[string] = + if node.kind != nnkIdent: + for child in node: + result.add recFindIdent(child) + if result.len != 0 and node.kind notin [nnkTypeSection, nnkConstSection]: + break + elif $node != "*": + result.add $node + for sym in body: - case sym.kind: - of nnkProcDef: - gStateCT.symOverride.add ($sym[0]).strip(chars={'*'}) - of nnkConstSection, nnkTypeSection: - for ssym in sym: - gStateCT.symOverride.add ($ssym[0]).strip(chars={'*'}) - else: - discard + gStateCT.symOverride.add recFindIdent(sym) result = body From ada2ac0244b9ca8f9e365c31444cbf61cc372788 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 31 Jan 2019 09:20:28 -0600 Subject: [PATCH 153/593] Fix #101 - include globals in cimport --- nimterop/cimport.nim | 4 +++- nimterop/globals.nim | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index 6a78b5e..1dd97aa 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -2,7 +2,9 @@ import hashes, macros, os, strformat, strutils const CIMPORT {.used.} = 1 -import "." / [globals, types, paths] +include "." / globals + +import "." / [types, paths] export types proc interpPath(dir: string): string= diff --git a/nimterop/globals.nim b/nimterop/globals.nim index bf9a0ef..b959958 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -68,7 +68,7 @@ type data*: seq[tuple[name, val: string]] var - gStateCT* {.compiletime, used.}: State + gStateCT {.compiletime, used.}: State gStateRT {.used.}: State template nBl(s: typed): untyped {.used.} = From 240f745dcea36ab1ac63fcdc5b25c3079cae4f27 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 31 Jan 2019 09:20:56 -0600 Subject: [PATCH 154/593] Update documentation --- cimport.html | 6 +- git.html | 82 ++-- git.idx | 11 +- paths.html | 1314 ++++++++++++++++++++++++++++++++++++++++++++++++++ paths.idx | 5 + plugin.html | 2 +- types.html | 37 +- types.idx | 2 + 8 files changed, 1412 insertions(+), 47 deletions(-) create mode 100644 paths.html create mode 100644 paths.idx diff --git a/cimport.html b/cimport.html index 73210ba..1d35872 100644 --- a/cimport.html +++ b/cimport.html @@ -1296,12 +1296,12 @@ function main() {

Procs

@@ -1440,7 +1440,7 @@ Add an include directory that is forwarded to the C/C++ compiler using
- Made with Nim. Generated: 2019-01-28 16:57:12 UTC + Made with Nim. Generated: 2019-01-31 15:20:53 UTC
diff --git a/git.html b/git.html index 536004f..bb605f2 100644 --- a/git.html +++ b/git.html @@ -1238,27 +1238,29 @@ function main() {
    +
  • + Imports +
      + +
    +
  • Procs -
  • -
  • - Macros -
  • @@ -1269,7 +1271,12 @@ function main() {

    -
    +
    +

    Imports

    +
    +paths +
    +

    Procs

    @@ -1279,37 +1286,46 @@ function main() { - -
    -
    -

    Macros

    -
    - -
    macro extractZip(zipfile, outdir: static string): untyped
    + +
    proc extractZip(zipfile, outdir: string) {...}{.raises: [OSError, Exception, ValueError], tags: [
    +    ExecIOEffect, ReadIOEffect, RootEffect].}
    - -
    macro downloadUrl(url, outdir: static string): untyped
    + +
    proc downloadUrl(url, outdir: string) {...}{.raises: [OSError, Exception, ValueError], tags: [
    +    ReadDirEffect, ExecIOEffect, ReadIOEffect, RootEffect].}
    - -
    macro gitReset(outdir: static string): untyped
    + +
    proc gitReset(outdir: string) {...}{.raises: [OSError, Exception], tags: [ExecIOEffect,
    +    ReadIOEffect, RootEffect, TimeEffect].}
    - -
    macro gitCheckout(file, outdir: static string): untyped
    + +
    proc relativePathNaive(file, base: string): string {...}{.raises: [], tags: [].}
    +
    +naive version of os.relativePath ; remove after nim >= 0.19.9 +

    Examples:

    +
    doAssert "/foo/bar/baz/log.txt".relativePathNaive("/foo/bar") == "baz/log.txt"
    + +
    + +
    proc gitCheckout(file, outdir: string) {...}{.raises: [OSError, Exception], tags: [
    +    ExecIOEffect, ReadIOEffect, RootEffect, TimeEffect].}
    - -
    macro gitPull(url: static string; outdirN = ""; plistN = ""; checkoutN = ""): untyped
    + +
    proc gitPull(url: string; outdir = ""; plist = ""; checkout = "") {...}{.
    +    raises: [OSError, Exception, IOError], tags: [ReadDirEffect, ExecIOEffect,
    +    ReadIOEffect, RootEffect, TimeEffect, WriteIOEffect].}
    @@ -1324,7 +1340,7 @@ function main() {
    diff --git a/git.idx b/git.idx index 486b012..ae9f083 100644 --- a/git.idx +++ b/git.idx @@ -1,6 +1,7 @@ execAction git.html#execAction,string git: execAction(cmd: string; nostderr = false): string -extractZip git.html#extractZip.m,, git: extractZip(zipfile, outdir: static string): untyped -downloadUrl git.html#downloadUrl.m,, git: downloadUrl(url, outdir: static string): untyped -gitReset git.html#gitReset.m, git: gitReset(outdir: static string): untyped -gitCheckout git.html#gitCheckout.m,, git: gitCheckout(file, outdir: static string): untyped -gitPull git.html#gitPull.m,,string,string,string git: gitPull(url: static string; outdirN = ""; plistN = ""; checkoutN = ""): untyped +extractZip git.html#extractZip,string,string git: extractZip(zipfile, outdir: string) +downloadUrl git.html#downloadUrl,string,string git: downloadUrl(url, outdir: string) +gitReset git.html#gitReset,string git: gitReset(outdir: string) +relativePathNaive git.html#relativePathNaive,string,string git: relativePathNaive(file, base: string): string +gitCheckout git.html#gitCheckout,string,string git: gitCheckout(file, outdir: string) +gitPull git.html#gitPull,string,string,string,string git: gitPull(url: string; outdir = ""; plist = ""; checkout = "") diff --git a/paths.html b/paths.html new file mode 100644 index 0000000..56fad4e --- /dev/null +++ b/paths.html @@ -0,0 +1,1314 @@ + + + + + + + + + + + + + + + + + +paths + + + + + + + + +
    +
    +

    paths

    +
    +
    + +
    + Search: +
    +
    + Group by: + +
    + + +
    +
    +
    +

    +
    +

    Procs

    +
    + +
    proc nimteropRoot(): string {...}{.raises: [], tags: [].}
    +
    + + +
    + +
    proc nimteropBuildDir(): string {...}{.raises: [], tags: [].}
    +
    +all nimterop generated files go under here (gitignored) + +
    + +
    proc nimteropSrcDir(): string {...}{.raises: [], tags: [].}
    +
    + + +
    + +
    proc toastExePath(): string {...}{.raises: [], tags: [].}
    +
    + + +
    + +
    proc incDir(): string {...}{.raises: [], tags: [].}
    +
    + + +
    + +
    + +
    +
    + +
    + +
    +
    +
    + + + diff --git a/paths.idx b/paths.idx new file mode 100644 index 0000000..7239d08 --- /dev/null +++ b/paths.idx @@ -0,0 +1,5 @@ +nimteropRoot paths.html#nimteropRoot, paths: nimteropRoot(): string +nimteropBuildDir paths.html#nimteropBuildDir, paths: nimteropBuildDir(): string +nimteropSrcDir paths.html#nimteropSrcDir, paths: nimteropSrcDir(): string +toastExePath paths.html#toastExePath, paths: toastExePath(): string +incDir paths.html#incDir, paths: incDir(): string diff --git a/plugin.html b/plugin.html index d17a993..491c58a 100644 --- a/plugin.html +++ b/plugin.html @@ -1287,7 +1287,7 @@ function main() {
    diff --git a/types.html b/types.html index 8695734..9914a3f 100644 --- a/types.html +++ b/types.html @@ -1242,11 +1242,21 @@ function main() { Types
    • time_t
    • + title="time_t = Time">time_t
    • ptrdiff_t
    • va_list
    • + title="va_list {.importc, header: "<stdarg.h>".} = object">va_list + +
    + +
  • + Templates +
  • @@ -1261,7 +1271,7 @@ function main() {

    Types

    -
    time_t = int32
    +
    time_t = Time
    @@ -1273,7 +1283,24 @@ function main() {
    -
    va_list {...}{.importc: "va_list", header: "<stdarg.h>".} = object
    +
    va_list {...}{.importc, header: "<stdarg.h>".} = object
    +
    + + +
    + +
    +
    +

    Templates

    +
    + +
    template enumOp(op, typ, typout)
    +
    + + +
    + +
    template defineEnum(typ)
    @@ -1288,7 +1315,7 @@ function main() {
    diff --git a/types.idx b/types.idx index d641285..d4ab217 100644 --- a/types.idx +++ b/types.idx @@ -1,3 +1,5 @@ time_t types.html#time_t types: time_t ptrdiff_t types.html#ptrdiff_t types: ptrdiff_t va_list types.html#va_list types: va_list +enumOp types.html#enumOp.t,,, types: enumOp(op, typ, typout) +defineEnum types.html#defineEnum.t, types: defineEnum(typ) From 013c925490fa0a524169e557d2bf5936360e5ee9 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 31 Jan 2019 16:20:28 -0600 Subject: [PATCH 155/593] Fix appveyor path, badges --- README.md | 4 ++-- appveyor.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index ca180c1..9bcc3ad 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ [![Chat on Gitter](https://badges.gitter.im/gitterHQ/gitter.png)](https://gitter.im/nimgen/Lobby) -[![Build status](https://ci.appveyor.com/api/projects/status/nsaar5foexk9adan/branch/master?svg=true)](https://ci.appveyor.com/project/genotrance/nimterop/branch/master) -[![Build Status](https://travis-ci.org/genotrance/nimterop.svg?branch=master)](https://travis-ci.org/genotrance/nimterop) +[![Build status](https://ci.appveyor.com/api/projects/status/hol1yvqbp6hq4ao8/branch/master?svg=true)](https://ci.appveyor.com/project/genotrance/nimterop-8jcj7/branch/master) +[![Build Status](https://travis-ci.org/nimterop/nimterop.svg?branch=master)](https://travis-ci.org/nimterop/nimterop) Nimterop is a [Nim](https://nim-lang.org/) package that aims to make C/C++ interop seamless diff --git a/appveyor.yml b/appveyor.yml index f8f45d7..b7f97f3 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -36,7 +36,7 @@ for: 7z x -y "nim-%NIM_VERSION%_x%ARCH%.zip"> nul && del "nim-%NIM_VERSION%_x%ARCH%.zip") - SET PATH=c:\binaries\mingw%ARCH%\bin;c:\binaries\nim-%NIM_VERSION%\bin;%USERPROFILE%\.nimble\bin;%PATH% - - CD c:\projects\nimterop + - CD %APPVEYOR_BUILD_FOLDER% on_finish: - 7z a -r buildlogs-win-pkgs.zip %USERPROFILE%\.nimble\pkgs @@ -66,7 +66,7 @@ for: ./koch nimble -d:release; fi - export PATH=/home/appveyor/binaries/nim-$NIM_VERSION/bin:~/.nimble/bin:$PATH - - cd /home/appveyor/projects/nimterop + - cd $APPVEYOR_BUILD_FOLDER on_finish: - zip -r -q buildlogs-lin-pkgs.zip ~/.nimble/pkgs From 4152564b398d1cc9214281d274e332d8e4d48012 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 31 Jan 2019 19:43:32 -0600 Subject: [PATCH 156/593] Fix #95 - error for multiple underscores --- nimterop/getters.nim | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 42dc9f9..9d8da6e 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -87,16 +87,25 @@ proc getType*(str: string): string = if gTypeMap.hasKey(result): result = gTypeMap[result] -template checkUnderscores(name, errmsg: string): untyped = +proc checkIdentifier(name, kind, parent, origName: string) = + let + parentStr = if parent.nBl: parent & ":" else: "" + if name.len != 0: - doAssert name[0] != '_' and name[^1] != '_', errmsg + let + origStr = if name != origName: ", originally '{origName}' before 'cPlugin:onSymbol()', still" else: "" + errmsg = &"Identifier '{parentStr}{name}' ({kind}){origStr} contains" + + doAssert name[0] != '_' and name[^1] != '_', errmsg & " leading/trailing underscores '_'" + + doAssert (not name.contains(re"_[_]+")): errmsg & " more than one consecutive underscore '_'" + + if parent.nBl: + doAssert name.nBl, &"Blank identifier, originally '{parentStr}{name}' ({kind}), cannot be empty" proc getIdentifier*(name: string, kind: NimSymKind, parent=""): string = doAssert name.len != 0, "Blank identifier error" - let - parentStr = if parent.nBl: parent & ":" else: "" - if name notin gStateRT.symOverride or parent.nBl: if gStateRT.onSymbol != nil: var @@ -104,13 +113,10 @@ proc getIdentifier*(name: string, kind: NimSymKind, parent=""): string = gStateRT.onSymbol(sym) result = sym.name - checkUnderscores(result, &"Identifier '{parentStr}{name}' ({kind}) still contains leading/trailing underscores '_' after 'cPlugin:onSymbol()': result '{result}'") - - if parent.nBl: - doAssert result.nBl, &"Blank identifier, originally '{parentStr}{name}' ({kind}), cannot be empty" else: result = name - checkUnderscores(result, &"Identifier '{parentStr}{result}' ({kind}) contains unsupported leading/trailing underscores '_': use 'cPlugin:onSymbol()' to remove") + + checkIdentifier(result, $kind, parent, name) if result in gReserved: result = &"`{result}`" From 1807580c71b28f76ded313bb3227833bc6081d22 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 31 Jan 2019 21:15:05 -0600 Subject: [PATCH 157/593] Fix #96 - run nim check on bad codegen --- nimterop/cimport.nim | 37 ++++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index 1dd97aa..60e0781 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -77,11 +77,27 @@ proc getToastError(output: string): string = # Filter out preprocessor errors for line in output.splitLines(): if "fatal error:" in line.toLowerAscii: - result &= "\nERROR:$1\n" % line.split("fatal error:")[1] + result &= "\n\nERROR:$1\n" % line.split("fatal error:")[1] # Toast error if result.len == 0: - result = output + result = "\n\n" & output + +proc getNimCheckError(output: string): tuple[tmpFile, errors: string] = + let + hash = output.hash().abs() + + result.tmpFile = getTempDir() / "nimterop_" & $hash & ".nim" + + if not fileExists(result.tmpFile) or gStateCT.nocache or compileOption("forceBuild"): + writeFile(result.tmpFile, output) + + doAssert fileExists(result.tmpFile), "Bad codegen - unable to write to TEMP: " & result.tmpFile + + let + (check, ret) = gorgeEx("nim check " & result.tmpFile) + + result.errors = "\n\n" & check proc getToast(fullpath: string, recurse: bool = false): string = var @@ -433,11 +449,14 @@ macro cImport*(filename: static string, recurse: static bool = false): untyped = output = getToast(fullpath, recurse) try: - result.add parseStmt(output) - except: - echo output - echo "Failed to import generated nim" - result.add parseStmt(output) + let body = parseStmt(output) + + result.add body + + if gStateCT.debug: + echo result.repr + except: + let + (tmpFile, errors) = getNimCheckError(output) + doAssert false, errors & "Nimterop codegen limitation or error - review 'nim check' output above generated for " & tmpFile - if gStateCT.debug: - echo result.repr From d6932247a9af7fe3eb83363c42c99c7e6f6d13b5 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 31 Jan 2019 22:10:43 -0600 Subject: [PATCH 158/593] Remove preprocessor file lines, clean whitespace in types --- nimterop/cimport.nim | 2 +- nimterop/getters.nim | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index 60e0781..6a258f8 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -458,5 +458,5 @@ macro cImport*(filename: static string, recurse: static bool = false): untyped = except: let (tmpFile, errors) = getNimCheckError(output) - doAssert false, errors & "Nimterop codegen limitation or error - review 'nim check' output above generated for " & tmpFile + doAssert false, errors & "\n\nNimterop codegen limitation or error - review 'nim check' output above generated for " & tmpFile diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 9d8da6e..7c42583 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -81,6 +81,7 @@ proc getType*(str: string): string = return "object" result = str.strip(chars={'_'}). + replace(re"\s+", " "). replace(re"([u]?int[\d]+)_t", "$1"). replace(re"([u]?int)ptr_t", "ptr $1") @@ -232,8 +233,6 @@ proc getPreprocessor*(fullpath: string, mode = "cpp"): string = if inc.absolutePath().sanitizePath in saniLine: start = true break - if start: - rdata.add(&"// {line}") else: if start: if "#undef" in line: From 74f4485ecdf09a6446bcdeefcae17f5020324172 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Sat, 2 Feb 2019 00:38:18 -0600 Subject: [PATCH 159/593] Add mkdir to git, use in downloadUrl --- nimterop/git.nim | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/nimterop/git.nim b/nimterop/git.nim index 2315204..ee170b2 100644 --- a/nimterop/git.nim +++ b/nimterop/git.nim @@ -22,6 +22,11 @@ proc execAction*(cmd: string, nostderr=false): string = let msg = "Command failed: " & $ret & "\nccmd: " & ccmd & "\nresult:\n" & result doAssert false, msg +proc mkDir*(dir: string) = + let + flag = when not defined(Windows): "-p" else: "" + discard execAction(&"mkdir {flag} {dir.quoteShell}") + proc extractZip*(zipfile, outdir: string) = var cmd = "unzip -o $#" if defined(Windows): @@ -39,14 +44,15 @@ proc downloadUrl*(url, outdir: string) = if not (ext == ".zip" and fileExists(outdir/file)): echo "Downloading " & file + mkDir(outdir) var cmd = if defined(Windows): "powershell wget $# -OutFile $#" else: "curl $# -o $#" discard execAction(cmd % [url, outdir/file]) - if ext == ".zip": - extractZip(file, outdir) + if ext == ".zip": + extractZip(file, outdir) proc gitReset*(outdir: string) = echo "Resetting " & outdir @@ -77,10 +83,11 @@ proc gitPull*(url: string, outdir = "", plist = "", checkout = "") = if dirExists(outdir/".git"): gitReset(outdir) return + let outdir2 = outdir.quoteShell - flag = when not defined(Windows): "-p" else: "" - echo execAction(&"mkdir {flag} {outdir2}") + + mkDir(outdir2) echo "Setting up Git repo: " & url discard execAction(&"cd {outdir2} && git init .") From 9fe45ac32b9c79ca2265accfdb89e37e91166d68 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Sat, 2 Feb 2019 16:03:46 -0800 Subject: [PATCH 160/593] refs #68; turn some macros to CT procs; fix #112 (doc fixes) (#102) * refs #68 macro=>proc cSkipSymbol * refs #68 macro=>proc cDebug * refs #68 macro=>proc cDisableCaching * refs #68 notes for cDefine * refs #68 macro=>proc cAddSearchDir ; improve some runnableExamples * refs #68 macro=>proc cAddStdDir * $projpath/include => testsIncludeDir() everywhere * disable $projpath interpolation (error prone) * fix tests * make nim doc part of test suite; fix for 0.19.2 --- README.md | 3 +- nimterop.nimble | 12 +++-- nimterop/all.nim | 7 +++ nimterop/cimport.nim | 98 ++++++++++++++++++-------------------- nimterop/paths.nim | 4 ++ tests/config.nims.disabled | 7 +++ tests/nim.cfg | 2 + tests/tmath.nim | 12 ++--- tests/tnimterop_c.nim | 12 ++--- tests/tnimterop_cpp.nim | 12 +++-- tests/tsoloud.nim | 7 ++- 11 files changed, 99 insertions(+), 77 deletions(-) create mode 100644 nimterop/all.nim create mode 100644 tests/config.nims.disabled create mode 100644 tests/nim.cfg diff --git a/README.md b/README.md index 9bcc3ad..320cbd2 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,8 @@ __Usage__ ```nim import nimterop/cimport -cDebug() +static: + cDebug() cDefine("HAS_ABC") cDefine("HAS_ABC", "DEF") cIncludeDir("clib/include") diff --git a/nimterop.nimble b/nimterop.nimble index bcdd78d..5f69daa 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -43,14 +43,18 @@ proc testAll() = if defined(OSX) or defined(Windows) or not existsEnv("TRAVIS"): tsoloud() # requires some libraries on linux, need them installed in TRAVIS +const htmldocsDir = "build/htmldocs" + +proc runNimDoc() = + execCmd &"nim doc -o:{htmldocsDir} --project --index:on nimterop/all.nim" + task test, "Test": for options in ["", "-d:release"]: buildToast(options) testAll() + runNimDoc() task docs, "Generate docs": # Uses: pip install ghp-import - execCmd "nim doc --project --index:on nimterop/cimport" - execCmd "nim doc --project --index:on nimterop/git" - execCmd "nim doc --project --index:on nimterop/plugin" - execCmd "ghp-import --no-jekyll -fp nimterop/htmldocs" + runNimDoc() + execCmd &"ghp-import --no-jekyll -fp {htmldocsDir}" diff --git a/nimterop/all.nim b/nimterop/all.nim new file mode 100644 index 0000000..87564e0 --- /dev/null +++ b/nimterop/all.nim @@ -0,0 +1,7 @@ +##[ +Module that should import everything so that `nim doc --project nimtero/all` runs docs on everything. +]## + +# TODO: make sure it does import everything. + +import "."/[cimport,git,plugin] diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index 6a258f8..714cc93 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -1,3 +1,13 @@ +##[ +Main import file to write wrappers. +Each `compileTime` proc must be used in a compile time context, eg using: + +``` +static: + cAddStdDir() +``` +]## + import hashes, macros, os, strformat, strutils const CIMPORT {.used.} = 1 @@ -9,7 +19,10 @@ export types proc interpPath(dir: string): string= # TODO: more robust: needs a DirSep after "$projpath" - result = dir.replace("$projpath", getProjectPath()) + # disabling this interpolation as this is error prone, but other less + # interpolations can be added, eg see https://github.com/nim-lang/Nim/pull/10530 + # result = dir.replace("$projpath", getProjectPath()) + result = dir proc joinPathIfRel(path1: string, path2: string): string = if path2.isAbsolute: @@ -184,18 +197,15 @@ macro cOverride*(body): untyped = if gStateCT.debug: echo "Overriding " & gStateCT.symOverride.join(" ") -macro cSkipSymbol*(skips: varargs[string]): untyped = +proc cSkipSymbol*(skips: seq[string]) {.compileTime.} = ## Similar to `cOverride() `_, this macro allows ## filtering out symbols not of interest from the generated output. - ## runnableExamples: - cSkipSymbol "proc1", "Type2" - - for skip in skips: - gStateCT.symOverride.add skip.strVal + static: cSkipSymbol @["proc1", "Type2"] + gStateCT.symOverride.add skips macro cPlugin*(body): untyped = - ## When `cOverride() `_ and `cSkipSymbol() `_ + ## When `cOverride() `_ and `cSkipSymbol() `_ ## are not adequate, the `cPlugin() `_ macro can be used ## to customize the generated Nim output. The following callbacks are available at ## this time. @@ -242,8 +252,8 @@ macro cPlugin*(body): untyped = proc cSearchPath*(path: string): string {.compileTime.}= ## Get full path to file or directory ``path`` in search path configured - ## using `cAddSearchDir() `_ and - ## `cAddStdDir() `_. + ## using `cAddSearchDir() `_ and + ## `cAddStdDir() `_. ## ## This can be used to locate files or directories that can be passed onto ## `cCompile() `_, @@ -261,23 +271,25 @@ proc cSearchPath*(path: string): string {.compileTime.}= doAssert found, "File or directory not found: " & path & " gStateCT.searchDirs: " & $gStateCT.searchDirs -macro cDebug*(): untyped = +proc cDebug*() {.compileTime.} = ## Enable debug messages and display the generated Nim code - gStateCT.debug = true -macro cDisableCaching*(): untyped = +proc cDisableCaching*() {.compileTime.} = ## Disable caching of generated Nim code - useful during wrapper development ## ## If files included by header being processed by `cImport() `_ ## change and affect the generated content, they will be ignored and the cached - ## value will continue to be used . Use `cDisableCaching() `_ + ## value will continue to be used . Use `cDisableCaching() `_ ## to avoid this scenario during development. ## ## ``nim -f`` was broken prior to 0.19.4 but can also be used to flush the cached content. gStateCT.nocache = true +# TODO: `passC` should be delayed and inserted inside `cImport`, `cCompile` +# and this should be made a proc: +# proc cDefine*(name: string, val = "") {.compileTime.} = macro cDefine*(name: static string, val: static string = ""): untyped = ## ``#define`` an identifer that is forwarded to the C/C++ compiler ## using ``{.passC: "-DXXX".}`` @@ -285,6 +297,8 @@ macro cDefine*(name: static string, val: static string = ""): untyped = result = newNimNode(nnkStmtList) var str = name + # todo: see https://github.com/genotrance/nimterop/issues/100 for + # edge case of empty strings if val.nBl: str &= &"={val.quoteShell}" @@ -292,24 +306,20 @@ macro cDefine*(name: static string, val: static string = ""): untyped = gStateCT.defines.add(str) str = "-D" & str - result.add(quote do: + result.add quote do: {.passC: `str`.} - ) if gStateCT.debug: echo result.repr -macro cAddSearchDir*(dir: static string): untyped = +proc cAddSearchDir*(dir: string) {.compileTime.} = ## Add directory ``dir`` to the search path used in calls to ## `cSearchPath() `_. - ## - ## This allows something like this: - ## - ## .. code-block:: nim - ## - ## cAddSearchDir("path/to/includes") - ## cImport cSearchPath("file.h") - + runnableExamples: + import paths, os + static: + cAddSearchDir testsIncludeDir() + doAssert cSearchPath("test.h").existsFile var dir = interpPath(dir) if dir notin gStateCT.searchDirs: gStateCT.searchDirs.add(dir) @@ -322,46 +332,32 @@ macro cIncludeDir*(dir: static string): untyped = var dir = interpPath(dir) result = newNimNode(nnkStmtList) - let - fullpath = findPath(dir) - str = &"-I{fullpath.quoteShell}" - + let fullpath = findPath(dir) if fullpath notin gStateCT.includeDirs: gStateCT.includeDirs.add(fullpath) - - result.add(quote do: + let str = &"-I{fullpath.quoteShell}" + result.add quote do: {.passC: `str`.} - ) + if gStateCT.debug: + echo result.repr - if gStateCT.debug: - echo result.repr - -macro cAddStdDir*(mode = "c"): untyped = +proc cAddStdDir*(mode = "c") {.compileTime.} = ## Add the standard ``c`` [default] or ``cpp`` include paths to search ## path used in calls to `cSearchPath() `_ - ## - ## This allows something like this: - ## runnableExamples: - cAddStdDir() - echo cSearchPath("math.h") - - result = newNimNode(nnkStmtList) - + static: cAddStdDir() + import os + doAssert cSearchPath("math.h").existsFile var inc = false - - for line in getGccPaths(mode.strVal()).splitLines(): + for line in getGccPaths(mode).splitLines(): if "#include <...> search starts here" in line: inc = true continue elif "End of search list" in line: break - if inc: - let sline = line.strip() - result.add quote do: - cAddSearchDir(`sline`) + cAddSearchDir line.strip() macro cCompile*(path: static string, mode = "c"): untyped = ## Compile and link C/C++ implementation into resulting binary using ``{.compile.}`` @@ -430,7 +426,7 @@ macro cCompile*(path: static string, mode = "c"): untyped = macro cImport*(filename: static string, recurse: static bool = false): untyped = ## Import all supported definitions from specified header file. Generated ## content is cached in ``nimcache`` until ``filename`` changes unless - ## `cDisableCaching() `_ is set. ``nim -f`` + ## `cDisableCaching() `_ is set. ``nim -f`` ## can also be used after Nim v0.19.4 to flush the cache. ## ## ``recurse`` can be used to generate Nim wrappers from ``#include`` files diff --git a/nimterop/paths.nim b/nimterop/paths.nim index 64879a4..5a2bb73 100644 --- a/nimterop/paths.nim +++ b/nimterop/paths.nim @@ -15,3 +15,7 @@ proc toastExePath*(): string = proc incDir*(): string = nimteropBuildDir() / "inc" + +proc testsIncludeDir*(): string = + nimteropRoot() / "tests" / "include" + diff --git a/tests/config.nims.disabled b/tests/config.nims.disabled new file mode 100644 index 0000000..06a791e --- /dev/null +++ b/tests/config.nims.disabled @@ -0,0 +1,7 @@ +#[ +pending https://github.com/nim-lang/Nim/pull/10530 +note: nimble init installs something like this (maybe without src in this case) +switch("path", "$projectDir/../src") +but it doesn't seem robust in case tests have subdirs, so, changing to ../ seems better +]# +switch("path", "..") diff --git a/tests/nim.cfg b/tests/nim.cfg new file mode 100644 index 0000000..3936716 --- /dev/null +++ b/tests/nim.cfg @@ -0,0 +1,2 @@ +# TODO: pending https://github.com/nimterop/nimterop/issues/110 remove in favor of config.nims +--path:".." diff --git a/tests/tmath.nim b/tests/tmath.nim index 63f1786..95fc086 100644 --- a/tests/tmath.nim +++ b/tests/tmath.nim @@ -1,15 +1,15 @@ -import nimterop/cimport import unittest +import nimterop/cimport type locale_t = object mingw_ldbl_type_t = object mingw_dbl_type_t = object -cDebug() -cDisableCaching() - -cAddStdDir() +static: + cDebug() + cDisableCaching() + cAddStdDir() cPlugin: import strutils @@ -21,4 +21,4 @@ cImport cSearchPath("math.h") check sin(5) == -0.9589242746631385 check abs(-5) == 5 -check sqrt(4.00) == 2.0 \ No newline at end of file +check sqrt(4.00) == 2.0 diff --git a/tests/tnimterop_c.nim b/tests/tnimterop_c.nim index eca3324..86ac0fd 100644 --- a/tests/tnimterop_c.nim +++ b/tests/tnimterop_c.nim @@ -1,12 +1,14 @@ import std/unittest import nimterop/cimport +import nimterop/paths -cDebug() -cDisableCaching() +static: + cDebug() + cDisableCaching() + cAddSearchDir testsIncludeDir() cDefine("FORCE") -cIncludeDir "$projpath/include" -cAddSearchDir "$projpath/include" +cIncludeDir testsIncludeDir() cCompile cSearchPath("test.c") cPlugin: @@ -137,8 +139,6 @@ var k: uKernel kp: Kernel -cAddStdDir() - ## failing tests when false: static: # Error: undeclared identifier: 'foobar1' diff --git a/tests/tnimterop_cpp.nim b/tests/tnimterop_cpp.nim index a556818..14c8c8f 100644 --- a/tests/tnimterop_cpp.nim +++ b/tests/tnimterop_cpp.nim @@ -1,11 +1,13 @@ -import nimterop/cimport import unittest +import nimterop/cimport +import nimterop/paths -cDebug() -cDisableCaching() +static: + cDebug() + cDisableCaching() + cAddSearchDir testsIncludeDir() -cIncludeDir "$projpath/include" -cAddSearchDir "$projpath/include" +cIncludeDir testsIncludeDir() cCompile cSearchPath "test2.cpp" cImport cSearchPath "test2.hpp" diff --git a/tests/tsoloud.nim b/tests/tsoloud.nim index ea7bbb2..f46dd10 100644 --- a/tests/tsoloud.nim +++ b/tests/tsoloud.nim @@ -7,9 +7,8 @@ const static: gitPull("https://github.com/jarikomppa/soloud", baseDir, "include/*\nsrc/*\n") - -cDebug() -cDisableCaching() + cDebug() + cDisableCaching() cOverride: type @@ -18,7 +17,7 @@ cOverride: proc Soloud_destroy*(aSoloud: ptr Soloud) {.importc: "Soloud_destroy", header: cSearchPath(incl/"soloud_c.h").} -cSkipSymbol("WavStream_stop", "WavStream_setFilter") +static: cSkipSymbol @["WavStream_stop", "WavStream_setFilter"] cIncludeDir(incl) From 61eb0457441a8cc7d45a6cad53ebac8a7cc0d4f9 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Sun, 3 Feb 2019 00:02:13 -0600 Subject: [PATCH 161/593] Fix quoteShell issue --- nimterop/git.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimterop/git.nim b/nimterop/git.nim index ee170b2..f7de472 100644 --- a/nimterop/git.nim +++ b/nimterop/git.nim @@ -9,7 +9,7 @@ proc execAction*(cmd: string, nostderr=false): string = when defined(Windows): ccmd = "cmd /c " & cmd when defined(Linux) or defined(MacOSX): - ccmd = "bash -c '" & cmd & "'" + ccmd = "bash -c \"" & cmd & "\"" when nimvm: (result, ret) = gorgeEx(ccmd) From 10aef55dadfbb9a4a1b4cab5ce64242cc1a63d66 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 6 Feb 2019 14:47:09 -0600 Subject: [PATCH 162/593] Add exclude to cCompile, fix duplicate filename compilation, mkDir fix, cp/mvFile, full relativePath --- nimterop/ast.nim | 2 +- nimterop/cimport.nim | 59 +++++++++++++++++++++++++--------- nimterop/git.nim | 76 +++++++++++++++++++++++++++++++++++++------- 3 files changed, 109 insertions(+), 28 deletions(-) diff --git a/nimterop/ast.nim b/nimterop/ast.nim index 1cc2c6c..94465a7 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -146,7 +146,7 @@ proc printNim*(fullpath: string, root: TSNode, astTable: AstTable) = nimState.identifiers = newTable[string, string]() nimState.currentHeader = getCurrentHeader(fullpath) - nimState.constStr &= &"\n {nimState.currentHeader} = \"{fp}\"" + nimState.constStr &= &"\n {nimState.currentHeader} {{.used.}} = \"{fp}\"" root.searchAst(astTable, nimState) diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index 714cc93..443eca3 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -12,9 +12,9 @@ import hashes, macros, os, strformat, strutils const CIMPORT {.used.} = 1 -include "." / globals +include "."/globals -import "." / [types, paths] +import "."/[git, paths, types] export types proc interpPath(dir: string): string= @@ -359,7 +359,7 @@ proc cAddStdDir*(mode = "c") {.compileTime.} = if inc: cAddSearchDir line.strip() -macro cCompile*(path: static string, mode = "c"): untyped = +macro cCompile*(path: static string, mode = "c", exclude = ""): untyped = ## Compile and link C/C++ implementation into resulting binary using ``{.compile.}`` ## ## ``path`` can be a specific file or contain wildcards: @@ -376,6 +376,13 @@ macro cCompile*(path: static string, mode = "c"): untyped = ## .. code-block:: nim ## ## cCompile("path/to/dir", "cpp") + ## + ## ``exclude`` can be used to exclude files by partial string match. Comma separated to + ## specify multiple exclude strings + ## + ## .. code-block:: nim + ## + ## cCompile("path/to/dir", exclude="test2.c") result = newNimNode(nnkStmtList) @@ -383,7 +390,8 @@ macro cCompile*(path: static string, mode = "c"): untyped = stmt = "" proc fcompile(file: string): string = - let fn = file.splitFile().name + let + (_, fn, ext) = file.splitFile() var ufn = fn uniq = 1 @@ -391,32 +399,53 @@ macro cCompile*(path: static string, mode = "c"): untyped = ufn = fn & $uniq uniq += 1 + # - https://github.com/nim-lang/Nim/issues/10299 + # - https://github.com/nim-lang/Nim/issues/10486 gStateCT.compile.add(ufn) if fn == ufn: - return "{.compile: \"$#\".}" % file.replace("\\", "/") + return "{.compile: \"$#\".}\n" % file.replace("\\", "/") else: - return "{.compile: (\"../$#\", \"$#.o\").}" % [file.replace("\\", "/"), ufn] + # - https://github.com/nim-lang/Nim/issues/9370 + let + hash = file.hash().abs() + tmpFile = file.parentDir() / &"_nimterop_{$hash}_{ufn}{ext}" + if not tmpFile.fileExists() or file.getFileDate() > tmpFile.getFileDate(): + cpFile(file, tmpFile) + return "{.compile: \"$#\".}\n" % tmpFile.replace("\\", "/") - proc dcompile(dir: string, ext=""): string = + # Due to https://github.com/nim-lang/Nim/issues/9863 + # cannot use seq[string] for excludes + proc notExcluded(file, exclude: string): bool = + result = true + if "_nimterop_" in file: + result = false + elif exclude.len != 0: + for excl in exclude.split(","): + if excl in file: + result = false + + proc dcompile(dir, exclude: string, ext=""): string = let files = walkDirImpl(dir, ext) for f in files: - if f.len != 0: - result &= fcompile(f) & "\n" + if f.len != 0 and f.notExcluded(exclude): + result &= fcompile(f) if path.contains("*") or path.contains("?"): - stmt &= dcompile(path) + stmt &= dcompile(path, exclude.strVal()) else: let fpath = findPath(path) - if fileExists(fpath): - stmt &= fcompile(fpath) & "\n" + if fileExists(fpath) and fpath.notExcluded(exclude.strVal()): + stmt &= fcompile(fpath) elif dirExists(fpath): if mode.strVal().contains("cpp"): - for i in @["*.C", "*.cpp", "*.c++", "*.cc", "*.cxx"]: - stmt &= dcompile(fpath, i) + for i in @["*.cpp", "*.c++", "*.cc", "*.cxx"]: + stmt &= dcompile(fpath, exclude.strVal(), i) + when not defined(Windows): + stmt &= dcompile(fpath, exclude.strVal(), "*.C") else: - stmt &= dcompile(fpath, "*.c") + stmt &= dcompile(fpath, exclude.strVal(), "*.c") result.add stmt.parseStmt() diff --git a/nimterop/git.nim b/nimterop/git.nim index f7de472..5b657b9 100644 --- a/nimterop/git.nim +++ b/nimterop/git.nim @@ -23,9 +23,70 @@ proc execAction*(cmd: string, nostderr=false): string = doAssert false, msg proc mkDir*(dir: string) = + if not dirExists(dir): + let + flag = when not defined(Windows): "-p" else: "" + discard execAction(&"mkdir {flag} {dir.quoteShell}") + +proc cpFile*(source, dest: string, move=false) = let - flag = when not defined(Windows): "-p" else: "" - discard execAction(&"mkdir {flag} {dir.quoteShell}") + source = source.replace("/", $DirSep) + dest = dest.replace("/", $DirSep) + cmd = + when defined(Windows): + if move: + "move /y" + else: + "copy /y" + else: + if move: + "mv -f" + else: + "cp -f" + + discard execAction(&"{cmd} {source.quoteShell} {dest.quoteShell}") + +proc mvFile*(source, dest: string) = + cpFile(source, dest, move=true) + +when (NimMajor, NimMinor, NimPatch) < (0, 19, 9): + proc relativePath*(path, base: string; sep = DirSep): string = + ## Copied from `os.relativePath` ; remove after nim >= 0.19.9 + if path.len == 0: return "" + var f, b: PathIter + var ff = (0, -1) + var bb = (0, -1) # (int, int) + result = newStringOfCap(path.len) + while f.hasNext(path) and b.hasNext(base): + ff = next(f, path) + bb = next(b, base) + let diff = ff[1] - ff[0] + if diff != bb[1] - bb[0]: break + var same = true + for i in 0..diff: + if path[i + ff[0]] !=? base[i + bb[0]]: + same = false + break + if not same: break + ff = (0, -1) + bb = (0, -1) + + while true: + if bb[1] >= bb[0]: + if result.len > 0 and result[^1] != sep: + result.add sep + result.add ".." + if not b.hasNext(base): break + bb = b.next(base) + + while true: + if ff[1] >= ff[0]: + if result.len > 0 and result[^1] != sep: + result.add sep + for i in 0..ff[1] - ff[0]: + result.add path[i + ff[0]] + if not f.hasNext(path): break + ff = f.next(path) proc extractZip*(zipfile, outdir: string) = var cmd = "unzip -o $#" @@ -62,18 +123,9 @@ proc gitReset*(outdir: string) = sleep(1000) echo " Retrying ..." -proc relativePathNaive*(file, base: string): string = - ## naive version of `os.relativePath` ; remove after nim >= 0.19.9 - runnableExamples: - doAssert "/foo/bar/baz/log.txt".relativePathNaive("/foo/bar") == "baz/log.txt" - var base = base - if not base.endsWith "/": base.add "/" - doAssert file.startsWith base - result = file[base.len .. ^1] - proc gitCheckout*(file, outdir: string) = echo "Resetting " & file - let file2 = file.relativePathNaive outdir + let file2 = file.relativePath outdir let cmd = &"cd {outdir.quoteShell} && git checkout {file2.quoteShell}" while execAction(cmd).contains("Permission denied"): sleep(500) From e3b3750ef0b2e36ac0fa046f59f02f637ca46c77 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 6 Feb 2019 15:10:19 -0600 Subject: [PATCH 163/593] Revert relativePath --- nimterop/git.nim | 45 ++++++++------------------------------------- 1 file changed, 8 insertions(+), 37 deletions(-) diff --git a/nimterop/git.nim b/nimterop/git.nim index 5b657b9..86a042e 100644 --- a/nimterop/git.nim +++ b/nimterop/git.nim @@ -50,43 +50,14 @@ proc mvFile*(source, dest: string) = cpFile(source, dest, move=true) when (NimMajor, NimMinor, NimPatch) < (0, 19, 9): - proc relativePath*(path, base: string; sep = DirSep): string = - ## Copied from `os.relativePath` ; remove after nim >= 0.19.9 - if path.len == 0: return "" - var f, b: PathIter - var ff = (0, -1) - var bb = (0, -1) # (int, int) - result = newStringOfCap(path.len) - while f.hasNext(path) and b.hasNext(base): - ff = next(f, path) - bb = next(b, base) - let diff = ff[1] - ff[0] - if diff != bb[1] - bb[0]: break - var same = true - for i in 0..diff: - if path[i + ff[0]] !=? base[i + bb[0]]: - same = false - break - if not same: break - ff = (0, -1) - bb = (0, -1) - - while true: - if bb[1] >= bb[0]: - if result.len > 0 and result[^1] != sep: - result.add sep - result.add ".." - if not b.hasNext(base): break - bb = b.next(base) - - while true: - if ff[1] >= ff[0]: - if result.len > 0 and result[^1] != sep: - result.add sep - for i in 0..ff[1] - ff[0]: - result.add path[i + ff[0]] - if not f.hasNext(path): break - ff = f.next(path) + proc relativePath*(file, base: string): string = + ## naive version of `os.relativePath` ; remove after nim >= 0.19.9 + runnableExamples: + doAssert "/foo/bar/baz/log.txt".relativePath("/foo/bar") == "baz/log.txt" + var base = base + if not base.endsWith "/": base.add "/" + doAssert file.startsWith base + result = file[base.len .. ^1] proc extractZip*(zipfile, outdir: string) = var cmd = "unzip -o $#" From b2d68ba84cb024b5577af3823359c51e771b294c Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 6 Feb 2019 16:02:08 -0600 Subject: [PATCH 164/593] Fix to accommodate tree-sitter upstream changes --- nimterop/cimport.nim | 2 +- nimterop/setup.nim | 6 +- nimterop/treesitter/runtime.nim | 212 ++++++++++++++++++-------------- 3 files changed, 124 insertions(+), 96 deletions(-) diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index 443eca3..4950d7b 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -108,7 +108,7 @@ proc getNimCheckError(output: string): tuple[tmpFile, errors: string] = doAssert fileExists(result.tmpFile), "Bad codegen - unable to write to TEMP: " & result.tmpFile let - (check, ret) = gorgeEx("nim check " & result.tmpFile) + (check, _) = gorgeEx("nim check " & result.tmpFile) result.errors = "\n\n" & check diff --git a/nimterop/setup.nim b/nimterop/setup.nim index 3c7afac..fceac88 100644 --- a/nimterop/setup.nim +++ b/nimterop/setup.nim @@ -4,8 +4,8 @@ import "."/[git, paths] proc treesitterSetup*() = gitPull("https://github.com/tree-sitter/tree-sitter/", incDir() / "treesitter", """ -include/* -src/runtime/* +lib/include/* +lib/src/* """) gitPull("https://github.com/JuliaStrings/utf8proc", incDir() / "utf8proc", """ @@ -15,7 +15,7 @@ src/runtime/* # TODO: does this work on windows? if not use `os.unixToNativePath` let - stack = incDir() / "treesitter/src/runtime/stack.c" + stack = incDir() / "treesitter/lib/src/stack.c" stack.writeFile(stack.readFile().replace("inline Stack", "Stack")) diff --git a/nimterop/treesitter/runtime.nim b/nimterop/treesitter/runtime.nim index 8885400..62ebe3b 100644 --- a/nimterop/treesitter/runtime.nim +++ b/nimterop/treesitter/runtime.nim @@ -2,35 +2,32 @@ import strutils, os -import ".."/[setup, paths] +import ".."/[setup, paths, types] static: treesitterSetup() -const sourcePath = incDir() / "treesitter" +const sourcePath = incDir() / "treesitter/lib" when defined(Linux): {.passC: "-std=c11".} + {.passC: "-DUTF8PROC_STATIC".} {.passC: "-I$1/include" % sourcePath.} {.passC: "-I$1/src" % sourcePath.} -{.passC: "-I$1/../utf8proc" % sourcePath.} -# pending https://github.com/nim-lang/Nim/issues/10299 we need to rename the -# object files (via compile:(foo,bar)) to avoid name collisions, here -# and everywhere `compile` is used -{.compile: sourcePath / "src/runtime/runtime.c".} +{.passC: "-I$1/../../utf8proc" % sourcePath.} -type TSInputEncoding* = distinct int -converter enumToInt(en: TSInputEncoding): int {.used.} = en.int +{.compile: sourcePath / "src/lib.c".} -type TSSymbolType* = distinct int -converter enumToInt(en: TSSymbolType): int {.used.} = en.int +### Generated below -type TSLogType* = distinct int -converter enumToInt(en: TSLogType): int {.used.} = en.int +{.hint[ConvFromXtoItselfNotNeeded]: off.} +defineEnum(TSInputEncoding) +defineEnum(TSSymbolType) +defineEnum(TSLogType) const - headerruntime = sourcePath / "include/tree_sitter/runtime.h" + headerapi {.used.} = sourcePath / "include/tree_sitter/api.h" TREE_SITTER_LANGUAGE_VERSION* = 9 TSInputEncodingUTF8* = 0.TSInputEncoding TSInputEncodingUTF16* = 1.TSInputEncoding @@ -39,108 +36,139 @@ const TSSymbolTypeAuxiliary* = 2.TSSymbolType TSLogTypeParse* = 0.TSLogType TSLogTypeLex* = 1.TSLogType - type TSSymbol* = uint16 TSLanguage* = object TSParser* = object TSTree* = object - TSPoint* {.importc: "TSPoint", header: headerruntime, bycopy.} = object + TSPoint* {.importc, header: headerapi, bycopy.} = object row*: uint32 column*: uint32 - TSRange* {.importc: "TSRange", header: headerruntime, bycopy.} = object + + TSRange* {.importc, header: headerapi, bycopy.} = object start_point*: TSPoint end_point*: TSPoint start_byte*: uint32 end_byte*: uint32 - TSInput* {.importc: "TSInput", header: headerruntime, bycopy.} = object + + TSInput* {.importc, header: headerapi, bycopy.} = object payload*: pointer - read*: proc(byte_index: uint32,position: TSPoint,bytes_read: ptr uint32): cchar {.nimcall.} + read*: proc (payload: pointer; byte_index: uint32; position: TSPoint; + bytes_read: ptr uint32): cstring {.nimcall.} encoding*: TSInputEncoding - TSLogger* {.importc: "TSLogger", header: headerruntime, bycopy.} = object + + TSLogger* {.importc, header: headerapi, bycopy.} = object payload*: pointer - log*: proc(a1: TSLogType,a2: cstring) {.nimcall.} - TSInputEdit* {.importc: "TSInputEdit", header: headerruntime, bycopy.} = object + log*: proc (payload: pointer; a1: TSLogType; a2: cstring) {.nimcall.} + + TSInputEdit* {.importc, header: headerapi, bycopy.} = object start_byte*: uint32 old_end_byte*: uint32 new_end_byte*: uint32 start_point*: TSPoint old_end_point*: TSPoint new_end_point*: TSPoint - TSNode* {.importc: "TSNode", header: headerruntime, bycopy.} = object + + TSNode* {.importc, header: headerapi, bycopy.} = object context*: array[4, uint32] id*: pointer tree*: ptr TSTree - TSTreeCursor* {.importc: "TSTreeCursor", header: headerruntime, bycopy.} = object + + TSTreeCursor* {.importc, header: headerapi, bycopy.} = object tree*: pointer id*: pointer context*: array[2, uint32] -proc ts_parser_new*(): ptr TSParser {.importc: "ts_parser_new", header: headerruntime.} -proc ts_parser_delete*(a1: ptr TSParser) {.importc: "ts_parser_delete", header: headerruntime.} -proc ts_parser_language*(a1: ptr TSParser): ptr TSLanguage {.importc: "ts_parser_language", header: headerruntime.} -proc ts_parser_set_language*(a1: ptr TSParser,a2: ptr TSLanguage): bool {.importc: "ts_parser_set_language", header: headerruntime.} -proc ts_parser_logger*(a1: ptr TSParser): TSLogger {.importc: "ts_parser_logger", header: headerruntime.} -proc ts_parser_set_logger*(a1: ptr TSParser,a2: TSLogger) {.importc: "ts_parser_set_logger", header: headerruntime.} -proc ts_parser_print_dot_graphs*(a1: ptr TSParser,a2: ptr FILE) {.importc: "ts_parser_print_dot_graphs", header: headerruntime.} -proc ts_parser_halt_on_error*(a1: ptr TSParser,a2: bool) {.importc: "ts_parser_halt_on_error", header: headerruntime.} -proc ts_parser_parse*(a1: ptr TSParser,a2: ptr TSTree,a3: TSInput): ptr TSTree {.importc: "ts_parser_parse", header: headerruntime.} -proc ts_parser_parse_string*(a1: ptr TSParser,a2: ptr TSTree,a3: cstring,a4: uint32): ptr TSTree {.importc: "ts_parser_parse_string", header: headerruntime.} -proc ts_parser_parse_string_encoding*(a1: ptr TSParser,a2: ptr TSTree,a3: cstring,a4: uint32,a5: TSInputEncoding): ptr TSTree {.importc: "ts_parser_parse_string_encoding", header: headerruntime.} -proc ts_parser_enabled*(a1: ptr TSParser): bool {.importc: "ts_parser_enabled", header: headerruntime.} -proc ts_parser_set_enabled*(a1: ptr TSParser,a2: bool) {.importc: "ts_parser_set_enabled", header: headerruntime.} -proc ts_parser_operation_limit*(a1: ptr TSParser): uint {.importc: "ts_parser_operation_limit", header: headerruntime.} -proc ts_parser_set_operation_limit*(a1: ptr TSParser,a2: uint) {.importc: "ts_parser_set_operation_limit", header: headerruntime.} -proc ts_parser_reset*(a1: ptr TSParser) {.importc: "ts_parser_reset", header: headerruntime.} -proc ts_parser_set_included_ranges*(a1: ptr TSParser,a2: ptr TSRange,a3: uint32) {.importc: "ts_parser_set_included_ranges", header: headerruntime.} -proc ts_parser_included_ranges*(a1: ptr TSParser,a2: ptr uint32): ptr TSRange {.importc: "ts_parser_included_ranges", header: headerruntime.} -proc ts_tree_copy*(a1: ptr TSTree): ptr TSTree {.importc: "ts_tree_copy", header: headerruntime.} -proc ts_tree_delete*(a1: ptr TSTree) {.importc: "ts_tree_delete", header: headerruntime.} -proc ts_tree_root_node*(a1: ptr TSTree): TSNode {.importc: "ts_tree_root_node", header: headerruntime.} -proc ts_tree_edit*(a1: ptr TSTree,a2: ptr TSInputEdit) {.importc: "ts_tree_edit", header: headerruntime.} -proc ts_tree_get_changed_ranges*(a1: ptr TSTree,a2: ptr TSTree,a3: ptr uint32): ptr TSRange {.importc: "ts_tree_get_changed_ranges", header: headerruntime.} -proc ts_tree_print_dot_graph*(a1: ptr TSTree,a2: ptr FILE) {.importc: "ts_tree_print_dot_graph", header: headerruntime.} -proc ts_tree_language*(a1: ptr TSTree): ptr TSLanguage {.importc: "ts_tree_language", header: headerruntime.} -proc ts_node_start_byte*(a1: TSNode): uint32 {.importc: "ts_node_start_byte", header: headerruntime.} -proc ts_node_start_point*(a1: TSNode): TSPoint {.importc: "ts_node_start_point", header: headerruntime.} -proc ts_node_end_byte*(a1: TSNode): uint32 {.importc: "ts_node_end_byte", header: headerruntime.} -proc ts_node_end_point*(a1: TSNode): TSPoint {.importc: "ts_node_end_point", header: headerruntime.} -proc ts_node_symbol*(a1: TSNode): TSSymbol {.importc: "ts_node_symbol", header: headerruntime.} -proc ts_node_type*(a1: TSNode): cstring {.importc: "ts_node_type", header: headerruntime.} -proc ts_node_string*(a1: TSNode): cstring {.importc: "ts_node_string", header: headerruntime.} -proc ts_node_eq*(a1: TSNode,a2: TSNode): bool {.importc: "ts_node_eq", header: headerruntime.} -proc ts_node_is_null*(a1: TSNode): bool {.importc: "ts_node_is_null", header: headerruntime.} -proc ts_node_is_named*(a1: TSNode): bool {.importc: "ts_node_is_named", header: headerruntime.} -proc ts_node_is_missing*(a1: TSNode): bool {.importc: "ts_node_is_missing", header: headerruntime.} -proc ts_node_has_changes*(a1: TSNode): bool {.importc: "ts_node_has_changes", header: headerruntime.} -proc ts_node_has_error*(a1: TSNode): bool {.importc: "ts_node_has_error", header: headerruntime.} -proc ts_node_parent*(a1: TSNode): TSNode {.importc: "ts_node_parent", header: headerruntime.} -proc ts_node_child*(a1: TSNode,a2: uint32): TSNode {.importc: "ts_node_child", header: headerruntime.} -proc ts_node_named_child*(a1: TSNode,a2: uint32): TSNode {.importc: "ts_node_named_child", header: headerruntime.} -proc ts_node_child_count*(a1: TSNode): uint32 {.importc: "ts_node_child_count", header: headerruntime.} -proc ts_node_named_child_count*(a1: TSNode): uint32 {.importc: "ts_node_named_child_count", header: headerruntime.} -proc ts_node_next_sibling*(a1: TSNode): TSNode {.importc: "ts_node_next_sibling", header: headerruntime.} -proc ts_node_next_named_sibling*(a1: TSNode): TSNode {.importc: "ts_node_next_named_sibling", header: headerruntime.} -proc ts_node_prev_sibling*(a1: TSNode): TSNode {.importc: "ts_node_prev_sibling", header: headerruntime.} -proc ts_node_prev_named_sibling*(a1: TSNode): TSNode {.importc: "ts_node_prev_named_sibling", header: headerruntime.} -proc ts_node_first_child_for_byte*(a1: TSNode,a2: uint32): TSNode {.importc: "ts_node_first_child_for_byte", header: headerruntime.} -proc ts_node_first_named_child_for_byte*(a1: TSNode,a2: uint32): TSNode {.importc: "ts_node_first_named_child_for_byte", header: headerruntime.} -proc ts_node_descendant_for_byte_range*(a1: TSNode,a2: uint32,a3: uint32): TSNode {.importc: "ts_node_descendant_for_byte_range", header: headerruntime.} -proc ts_node_named_descendant_for_byte_range*(a1: TSNode,a2: uint32,a3: uint32): TSNode {.importc: "ts_node_named_descendant_for_byte_range", header: headerruntime.} -proc ts_node_descendant_for_point_range*(a1: TSNode,a2: TSPoint,a3: TSPoint): TSNode {.importc: "ts_node_descendant_for_point_range", header: headerruntime.} -proc ts_node_named_descendant_for_point_range*(a1: TSNode,a2: TSPoint,a3: TSPoint): TSNode {.importc: "ts_node_named_descendant_for_point_range", header: headerruntime.} -proc ts_node_edit*(a1: ptr TSNode,a2: ptr TSInputEdit) {.importc: "ts_node_edit", header: headerruntime.} -proc ts_tree_cursor_new*(a1: TSNode): TSTreeCursor {.importc: "ts_tree_cursor_new", header: headerruntime.} -proc ts_tree_cursor_delete*(a1: ptr TSTreeCursor) {.importc: "ts_tree_cursor_delete", header: headerruntime.} -proc ts_tree_cursor_reset*(a1: ptr TSTreeCursor,a2: TSNode) {.importc: "ts_tree_cursor_reset", header: headerruntime.} -proc ts_tree_cursor_current_node*(a1: ptr TSTreeCursor): TSNode {.importc: "ts_tree_cursor_current_node", header: headerruntime.} -proc ts_tree_cursor_goto_parent*(a1: ptr TSTreeCursor): bool {.importc: "ts_tree_cursor_goto_parent", header: headerruntime.} -proc ts_tree_cursor_goto_next_sibling*(a1: ptr TSTreeCursor): bool {.importc: "ts_tree_cursor_goto_next_sibling", header: headerruntime.} -proc ts_tree_cursor_goto_first_child*(a1: ptr TSTreeCursor): bool {.importc: "ts_tree_cursor_goto_first_child", header: headerruntime.} -proc ts_tree_cursor_goto_first_child_for_byte*(a1: ptr TSTreeCursor,a2: uint32): int64 {.importc: "ts_tree_cursor_goto_first_child_for_byte", header: headerruntime.} -proc ts_language_symbol_count*(a1: ptr TSLanguage): uint32 {.importc: "ts_language_symbol_count", header: headerruntime.} -proc ts_language_symbol_name*(a1: ptr TSLanguage,a2: TSSymbol): cstring {.importc: "ts_language_symbol_name", header: headerruntime.} -proc ts_language_symbol_for_name*(a1: ptr TSLanguage,a2: cstring): TSSymbol {.importc: "ts_language_symbol_for_name", header: headerruntime.} -proc ts_language_symbol_type*(a1: ptr TSLanguage,a2: TSSymbol): TSSymbolType {.importc: "ts_language_symbol_type", header: headerruntime.} -proc ts_language_version*(a1: ptr TSLanguage): uint32 {.importc: "ts_language_version", header: headerruntime.} - +proc ts_parser_new*(): ptr TSParser {.importc, header: headerapi.} +proc ts_parser_delete*(a1: ptr TSParser) {.importc, header: headerapi.} +proc ts_parser_language*(a1: ptr TSParser): ptr TSLanguage {.importc, header: headerapi.} +proc ts_parser_set_language*(a1: ptr TSParser; a2: ptr TSLanguage): bool {.importc, + header: headerapi.} +proc ts_parser_logger*(a1: ptr TSParser): TSLogger {.importc, header: headerapi.} +proc ts_parser_set_logger*(a1: ptr TSParser; a2: TSLogger) {.importc, header: headerapi.} +proc ts_parser_print_dot_graphs*(a1: ptr TSParser; a2: cint) {.importc, + header: headerapi.} +proc ts_parser_halt_on_error*(a1: ptr TSParser; a2: bool) {.importc, header: headerapi.} +proc ts_parser_parse*(a1: ptr TSParser; a2: ptr TSTree; a3: TSInput): ptr TSTree {.importc, + header: headerapi.} +proc ts_parser_parse_string*(a1: ptr TSParser; a2: ptr TSTree; a3: cstring; a4: uint32): ptr TSTree {. + importc, header: headerapi.} +proc ts_parser_parse_string_encoding*(a1: ptr TSParser; a2: ptr TSTree; a3: cstring; + a4: uint32; a5: TSInputEncoding): ptr TSTree {. + importc, header: headerapi.} +proc ts_parser_enabled*(a1: ptr TSParser): bool {.importc, header: headerapi.} +proc ts_parser_set_enabled*(a1: ptr TSParser; a2: bool) {.importc, header: headerapi.} +proc ts_parser_operation_limit*(a1: ptr TSParser): cuint {.importc, header: headerapi.} +proc ts_parser_set_operation_limit*(a1: ptr TSParser; a2: cuint) {.importc, + header: headerapi.} +proc ts_parser_reset*(a1: ptr TSParser) {.importc, header: headerapi.} +proc ts_parser_set_included_ranges*(a1: ptr TSParser; a2: ptr TSRange; a3: uint32) {. + importc, header: headerapi.} +proc ts_parser_included_ranges*(a1: ptr TSParser; a2: ptr uint32): ptr TSRange {.importc, + header: headerapi.} +proc ts_tree_copy*(a1: ptr TSTree): ptr TSTree {.importc, header: headerapi.} +proc ts_tree_delete*(a1: ptr TSTree) {.importc, header: headerapi.} +proc ts_tree_root_node*(a1: ptr TSTree): TSNode {.importc, header: headerapi.} +proc ts_tree_edit*(a1: ptr TSTree; a2: ptr TSInputEdit) {.importc, header: headerapi.} +proc ts_tree_get_changed_ranges*(a1: ptr TSTree; a2: ptr TSTree; a3: ptr uint32): ptr TSRange {. + importc, header: headerapi.} +proc ts_tree_print_dot_graph*(a1: ptr TSTree; a2: ptr FILE) {.importc, header: headerapi.} +proc ts_tree_language*(a1: ptr TSTree): ptr TSLanguage {.importc, header: headerapi.} +proc ts_node_start_byte*(a1: TSNode): uint32 {.importc, header: headerapi.} +proc ts_node_start_point*(a1: TSNode): TSPoint {.importc, header: headerapi.} +proc ts_node_end_byte*(a1: TSNode): uint32 {.importc, header: headerapi.} +proc ts_node_end_point*(a1: TSNode): TSPoint {.importc, header: headerapi.} +proc ts_node_symbol*(a1: TSNode): TSSymbol {.importc, header: headerapi.} +proc ts_node_type*(a1: TSNode): cstring {.importc, header: headerapi.} +proc ts_node_string*(a1: TSNode): cstring {.importc, header: headerapi.} +proc ts_node_eq*(a1: TSNode; a2: TSNode): bool {.importc, header: headerapi.} +proc ts_node_is_null*(a1: TSNode): bool {.importc, header: headerapi.} +proc ts_node_is_named*(a1: TSNode): bool {.importc, header: headerapi.} +proc ts_node_is_missing*(a1: TSNode): bool {.importc, header: headerapi.} +proc ts_node_has_changes*(a1: TSNode): bool {.importc, header: headerapi.} +proc ts_node_has_error*(a1: TSNode): bool {.importc, header: headerapi.} +proc ts_node_parent*(a1: TSNode): TSNode {.importc, header: headerapi.} +proc ts_node_child*(a1: TSNode; a2: uint32): TSNode {.importc, header: headerapi.} +proc ts_node_named_child*(a1: TSNode; a2: uint32): TSNode {.importc, header: headerapi.} +proc ts_node_child_count*(a1: TSNode): uint32 {.importc, header: headerapi.} +proc ts_node_named_child_count*(a1: TSNode): uint32 {.importc, header: headerapi.} +proc ts_node_next_sibling*(a1: TSNode): TSNode {.importc, header: headerapi.} +proc ts_node_next_named_sibling*(a1: TSNode): TSNode {.importc, header: headerapi.} +proc ts_node_prev_sibling*(a1: TSNode): TSNode {.importc, header: headerapi.} +proc ts_node_prev_named_sibling*(a1: TSNode): TSNode {.importc, header: headerapi.} +proc ts_node_first_child_for_byte*(a1: TSNode; a2: uint32): TSNode {.importc, + header: headerapi.} +proc ts_node_first_named_child_for_byte*(a1: TSNode; a2: uint32): TSNode {.importc, + header: headerapi.} +proc ts_node_descendant_for_byte_range*(a1: TSNode; a2: uint32; a3: uint32): TSNode {. + importc, header: headerapi.} +proc ts_node_named_descendant_for_byte_range*(a1: TSNode; a2: uint32; a3: uint32): TSNode {. + importc, header: headerapi.} +proc ts_node_descendant_for_point_range*(a1: TSNode; a2: TSPoint; a3: TSPoint): TSNode {. + importc, header: headerapi.} +proc ts_node_named_descendant_for_point_range*(a1: TSNode; a2: TSPoint; a3: TSPoint): TSNode {. + importc, header: headerapi.} +proc ts_node_edit*(a1: ptr TSNode; a2: ptr TSInputEdit) {.importc, header: headerapi.} +proc ts_tree_cursor_new*(a1: TSNode): TSTreeCursor {.importc, header: headerapi.} +proc ts_tree_cursor_delete*(a1: ptr TSTreeCursor) {.importc, header: headerapi.} +proc ts_tree_cursor_reset*(a1: ptr TSTreeCursor; a2: TSNode) {.importc, + header: headerapi.} +proc ts_tree_cursor_current_node*(a1: ptr TSTreeCursor): TSNode {.importc, + header: headerapi.} +proc ts_tree_cursor_goto_parent*(a1: ptr TSTreeCursor): bool {.importc, + header: headerapi.} +proc ts_tree_cursor_goto_next_sibling*(a1: ptr TSTreeCursor): bool {.importc, + header: headerapi.} +proc ts_tree_cursor_goto_first_child*(a1: ptr TSTreeCursor): bool {.importc, + header: headerapi.} +proc ts_tree_cursor_goto_first_child_for_byte*(a1: ptr TSTreeCursor; a2: uint32): int64 {. + importc, header: headerapi.} +proc ts_language_symbol_count*(a1: ptr TSLanguage): uint32 {.importc, + header: headerapi.} +proc ts_language_symbol_name*(a1: ptr TSLanguage; a2: TSSymbol): cstring {.importc, + header: headerapi.} +proc ts_language_symbol_for_name*(a1: ptr TSLanguage; a2: cstring): TSSymbol {.importc, + header: headerapi.} +proc ts_language_symbol_type*(a1: ptr TSLanguage; a2: TSSymbol): TSSymbolType {. + importc, header: headerapi.} +proc ts_language_version*(a1: ptr TSLanguage): uint32 {.importc, header: headerapi.} From 7bc619e79dbe751c037c3d61983baed3a7bc64d9 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 6 Feb 2019 18:13:58 -0600 Subject: [PATCH 165/593] Rename tree-sitter runtime to api, add tsgen --- nimterop/all.nim | 2 +- nimterop/ast.nim | 2 +- nimterop/astold.nim | 2 +- nimterop/getters.nim | 2 +- nimterop/globals.nim | 2 +- nimterop/grammar.nim | 2 +- nimterop/toast.nim | 2 +- nimterop/treesitter/{runtime.nim => api.nim} | 0 nimterop/treesitter/c.nim | 2 +- nimterop/treesitter/cpp.nim | 2 +- nimterop/treesitter/tsgen.nim | 18 ++++++++++++++++++ 11 files changed, 27 insertions(+), 9 deletions(-) rename nimterop/treesitter/{runtime.nim => api.nim} (100%) create mode 100644 nimterop/treesitter/tsgen.nim diff --git a/nimterop/all.nim b/nimterop/all.nim index 87564e0..dd42c03 100644 --- a/nimterop/all.nim +++ b/nimterop/all.nim @@ -4,4 +4,4 @@ Module that should import everything so that `nim doc --project nimtero/all` run # TODO: make sure it does import everything. -import "."/[cimport,git,plugin] +import "."/[cimport, git, types, plugin] diff --git a/nimterop/ast.nim b/nimterop/ast.nim index 94465a7..aede004 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -2,7 +2,7 @@ import os, sequtils, sets, strformat, strutils, tables, times import regex -import "."/[getters, globals, grammar, treesitter/runtime] +import "."/[getters, globals, grammar, treesitter/api] proc saveNodeData(node: TSNode, nimState: NimState): bool = let name = $node.tsNodeType() diff --git a/nimterop/astold.nim b/nimterop/astold.nim index 069ecba..a0c5b93 100644 --- a/nimterop/astold.nim +++ b/nimterop/astold.nim @@ -1,6 +1,6 @@ import macros, os, strformat, strutils -import treesitter/runtime +import treesitter/api import getters, globals diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 7c42583..63836e3 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -2,7 +2,7 @@ import dynlib, macros, os, sequtils, sets, strformat, strutils, tables, times import regex -import "."/[git, globals, plugin, treesitter/runtime] +import "."/[git, globals, plugin, treesitter/api] const gReserved = """ addr and as asm diff --git a/nimterop/globals.nim b/nimterop/globals.nim index b959958..bdb29dc 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -5,7 +5,7 @@ import regex import "."/plugin when not declared(CIMPORT): - import "."/treesitter/runtime + import "."/treesitter/api const gAtoms {.used.} = @[ diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index 510cc7c..3895aa1 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -2,7 +2,7 @@ import macros, sets, strformat, strutils, tables import regex -import "."/[getters, globals, lisp, treesitter/runtime] +import "."/[getters, globals, lisp, treesitter/api] type Grammar = seq[tuple[grammar: string, call: proc(ast: ref Ast, node: TSNode, nimState: NimState) {.nimcall.}]] diff --git a/nimterop/toast.nim b/nimterop/toast.nim index 9221802..e3651a0 100644 --- a/nimterop/toast.nim +++ b/nimterop/toast.nim @@ -1,6 +1,6 @@ import os, strformat, strutils -import "."/treesitter/[runtime, c, cpp] +import "."/treesitter/[api, c, cpp] import "."/[ast, globals, getters, grammar] diff --git a/nimterop/treesitter/runtime.nim b/nimterop/treesitter/api.nim similarity index 100% rename from nimterop/treesitter/runtime.nim rename to nimterop/treesitter/api.nim diff --git a/nimterop/treesitter/c.nim b/nimterop/treesitter/c.nim index f34eaf9..0170a5d 100644 --- a/nimterop/treesitter/c.nim +++ b/nimterop/treesitter/c.nim @@ -5,7 +5,7 @@ import ".."/[setup, paths] static: treesitterCSetup() -import "."/runtime +import "."/api {.compile: incDir() / "treesitter_c/src/parser.c".} diff --git a/nimterop/treesitter/cpp.nim b/nimterop/treesitter/cpp.nim index 7fc0b13..296929f 100644 --- a/nimterop/treesitter/cpp.nim +++ b/nimterop/treesitter/cpp.nim @@ -5,7 +5,7 @@ import ".."/[setup, paths] static: treesitterCppSetup() -import "."/runtime +import "."/api const srcDir = incDir() / "treesitter_cpp/src" diff --git a/nimterop/treesitter/tsgen.nim b/nimterop/treesitter/tsgen.nim new file mode 100644 index 0000000..335f28f --- /dev/null +++ b/nimterop/treesitter/tsgen.nim @@ -0,0 +1,18 @@ +# nim c tsgen.nim > temp.nim +# Move temp.nim contents to api.nim below generated line + minor adjustments + +import os + +import nimterop/[cimport, paths] + +cPlugin: + import strutils + + proc onSymbol*(sym: var Symbol) {.exportc, dynlib.} = + if "_CRT" in sym.name: + sym.name = sym.name.strip(chars={'_'}) + +static: + cDebug() + +cImport(incDir()/"treesitter/lib/include/tree_sitter/api.h") \ No newline at end of file From 1251d9e200e46367353675d1caed4606126d38e5 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 6 Feb 2019 18:19:20 -0600 Subject: [PATCH 166/593] Fix issue #90 based on PR #91 --- nimterop.nimble | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/nimterop.nimble b/nimterop.nimble index 5f69daa..d0074ba 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -20,26 +20,27 @@ proc execCmd(cmd: string) = echo "execCmd:" & cmd exec cmd -proc tsoloud() = - execCmd "nim c -r tests/tsoloud.nim" - execCmd "nim cpp -r tests/tsoloud.nim" +proc execTest(test: string) = + execCmd "nim c -r " & test + execCmd "nim cpp -r " & test -proc buildToast(options: string) = - execCmd(&"nim c {options} nimterop/toast.nim") +proc tsoloud() = + execTest "tests/tsoloud.nim" + +proc buildToast() = + execCmd(&"nim c -d:release nimterop/toast.nim") task rebuildToast, "rebuild toast": # If need to manually rebuild (automatically built on 1st need) - buildToast("-d:release") + buildToast() proc testAll() = - execCmd "nim c -r tests/tnimterop_c.nim" - execCmd "nim cpp -r tests/tnimterop_c.nim" + execTest "tests/tnimterop_c.nim" execCmd "nim cpp -r tests/tnimterop_cpp.nim" ## platform specific tests when defined(Windows): - execCmd "nim c -r tests/tmath.nim" - execCmd "nim cpp -r tests/tmath.nim" + execTest "tests/tmath.nim" if defined(OSX) or defined(Windows) or not existsEnv("TRAVIS"): tsoloud() # requires some libraries on linux, need them installed in TRAVIS @@ -49,9 +50,8 @@ proc runNimDoc() = execCmd &"nim doc -o:{htmldocsDir} --project --index:on nimterop/all.nim" task test, "Test": - for options in ["", "-d:release"]: - buildToast(options) - testAll() + buildToast() + testAll() runNimDoc() task docs, "Generate docs": From 0ef310b7d9a3bf02b6caf54ba20982640e48156a Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 7 Feb 2019 20:48:16 -0600 Subject: [PATCH 167/593] And/or/xor for enums --- nimterop/types.nim | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/nimterop/types.nim b/nimterop/types.nim index ecc5345..17b4795 100644 --- a/nimterop/types.nim +++ b/nimterop/types.nim @@ -58,4 +58,16 @@ template defineEnum*(typ) = proc `shr`*(x: int, y: typ): typ {.borrow.} proc `shr`*(x, y: typ): typ {.borrow.} + proc `or`*(x: typ, y: int): typ {.borrow.} + proc `or`*(x: int, y: typ): typ {.borrow.} + proc `or`*(x, y: typ): typ {.borrow.} + + proc `and`*(x: typ, y: int): typ {.borrow.} + proc `and`*(x: int, y: typ): typ {.borrow.} + proc `and`*(x, y: typ): typ {.borrow.} + + proc `xor`*(x: typ, y: int): typ {.borrow.} + proc `xor`*(x: int, y: typ): typ {.borrow.} + proc `xor`*(x, y: typ): typ {.borrow.} + proc `$` *(x: typ): string {.borrow.} \ No newline at end of file From 52264204749a2159153113b4ffb6545d2eccc2e4 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Fri, 8 Feb 2019 13:59:41 -0800 Subject: [PATCH 168/593] execAction: quoting was not robust (in case cmd had quotes) and bash -c was redundant on posix (#117) --- nimterop/git.nim | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/nimterop/git.nim b/nimterop/git.nim index 86a042e..1d28179 100644 --- a/nimterop/git.nim +++ b/nimterop/git.nim @@ -8,18 +8,18 @@ proc execAction*(cmd: string, nostderr=false): string = ret = 0 when defined(Windows): ccmd = "cmd /c " & cmd - when defined(Linux) or defined(MacOSX): - ccmd = "bash -c \"" & cmd & "\"" + elif defined(posix): + ccmd = cmd + else: + doAssert false when nimvm: (result, ret) = gorgeEx(ccmd) else: - if nostderr: - (result, ret) = execCmdEx(ccmd, {poUsePath}) - else: - (result, ret) = execCmdEx(ccmd) + let opt = if nostderr: {poUsePath} else: {poStdErrToStdOut, poUsePath} + (result, ret) = execCmdEx(ccmd, opt) if ret != 0: - let msg = "Command failed: " & $ret & "\nccmd: " & ccmd & "\nresult:\n" & result + let msg = "Command failed: " & $(ret, nostderr) & "\nccmd: " & ccmd & "\nresult:\n" & result doAssert false, msg proc mkDir*(dir: string) = From bed87aa2d897368f9c0afcb25ee20bbfd20032b4 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Fri, 8 Feb 2019 14:32:06 -0800 Subject: [PATCH 169/593] docs now include theindex.html (w all procs) + search (#116) * nim docs now generates theindex.html * doc: enable doc search * fixup --- nimterop.nimble | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/nimterop.nimble b/nimterop.nimble index d0074ba..c53e4dc 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -46,8 +46,27 @@ proc testAll() = const htmldocsDir = "build/htmldocs" +when (NimMajor, NimMinor, NimPatch) >= (0, 19, 9): + import os + proc getNimRootDir(): string = + #[ + hack, but works + alternatively (but more complex), use (from a nim file, not nims otherwise + you get Error: ambiguous call; both system.fileExists): + import "$nim/testament/lib/stdtest/specialpaths.nim" + nimRootDir + ]# + fmt"{currentSourcePath}".parentDir.parentDir.parentDir + proc runNimDoc() = execCmd &"nim doc -o:{htmldocsDir} --project --index:on nimterop/all.nim" + execCmd &"nim buildIndex -o:{htmldocsDir}/theindex.html {htmldocsDir}" + when declared(getNimRootDir): + #[ + this enables doc search, works at least locally with: + cd {htmldocsDir} && python -m SimpleHTTPServer 9009 + ]# + execCmd &"nim js -o:{htmldocsDir}/dochack.js {getNimRootDir()}/tools/dochack/dochack.nim" task test, "Test": buildToast() @@ -55,6 +74,9 @@ task test, "Test": runNimDoc() task docs, "Generate docs": + runNimDoc() + +task docsPublish, "Generate and publish docs": # Uses: pip install ghp-import runNimDoc() execCmd &"ghp-import --no-jekyll -fp {htmldocsDir}" From 7f299d18e418b2135eed86c62048ab4b29152ff3 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Fri, 8 Feb 2019 16:36:23 -0600 Subject: [PATCH 170/593] Update documentation --- all.html | 838 +++++++++++++++++++++ cimport.html | 1157 +++++++++-------------------- cimport.idx | 20 +- dochack.js | 1970 +++++++++++++++++++++++++++++++++++++++++++++++++ git.html | 1050 ++++++++------------------ git.idx | 4 +- paths.html | 1006 ++++++++----------------- paths.idx | 11 +- plugin.html | 968 +++++++----------------- plugin.idx | 0 theindex.html | 936 +++++++++++++++++++++++ types.html | 980 +++++++----------------- types.idx | 2 +- 13 files changed, 5275 insertions(+), 3667 deletions(-) create mode 100755 all.html mode change 100644 => 100755 cimport.html mode change 100644 => 100755 cimport.idx create mode 100755 dochack.js mode change 100644 => 100755 git.html mode change 100644 => 100755 git.idx mode change 100644 => 100755 paths.html mode change 100644 => 100755 paths.idx mode change 100644 => 100755 plugin.html mode change 100644 => 100755 plugin.idx create mode 100755 theindex.html mode change 100644 => 100755 types.html mode change 100644 => 100755 types.idx diff --git a/all.html b/all.html new file mode 100755 index 0000000..82d847d --- /dev/null +++ b/all.html @@ -0,0 +1,838 @@ + + + + + + + + + + + + + + + + + +all + + + + + + + + +
    +
    +

    all

    +
    +
    + +
    + Search: +
    +
    + Group by: + +
    + + +
    +
    +
    +

    Module that should import everything so that nim doc --project nimtero/all runs docs on everything.

    + + +
    +
    + +
    + +
    +
    +
    + + + diff --git a/cimport.html b/cimport.html old mode 100644 new mode 100755 index 1d35872..ef6a06c --- a/cimport.html +++ b/cimport.html @@ -27,232 +27,113 @@ customize this style sheet. Modified from Chad Skeeters' rst2html-style https://bitbucket.org/cskeeters/rst2html-style/ -Modified by Boyd Greenfield +Modified by Boyd Greenfield and narimiran */ -/* SCSS variables */ -/* Text weights */ -/* Body colors */ -/* Text colors */ -/* Link colors */ -/* Syntax highlighting colors */ -/* Pct changes */ -/* Mixins */ -/* Body/layout */ + html { font-size: 100%; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; } -/* Where we want fancier font if available */ -h1, h2, h3, h4, h5, h6, p.module-desc, table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; } - -h1.title { - font-weight: 900; } - body { font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: 400; - font-size: 16px; - line-height: 20px; - color: #444; - letter-spacing: 0.15px; - background-color: #FDFBFA; } + font-size: 1.125em; + line-height: 1.5; + color: #222; + background-color: #FCFCFC; } /* Skeleton grid */ .container { position: relative; width: 100%; - max-width: 960px; + max-width: 1050px; margin: 0 auto; - padding: 0 20px; + padding: 0; box-sizing: border-box; } .column, .columns { width: 100%; float: left; - box-sizing: border-box; } + box-sizing: border-box; + margin-left: 1%; +} -/* For devices larger than 400px */ -@media (min-width: 400px) { - .container { - width: 100%; - padding: 0; } } -/* For devices larger than 650px */ -@media (min-width: 650px) { - .container { - width: 100%; } +.column:first-child, +.columns:first-child { + margin-left: 0; } - .column, - .columns { - margin-left: 4%; } +.three.columns { + width: 19%; } - .column:first-child, - .columns:first-child { - margin-left: 0; } +.nine.columns { + width: 80.0%; } - .one.column, - .one.columns { - width: 4.66666666667%; } - - .two.columns { - width: 13.3333333333%; } +.twelve.columns { + width: 100%; + margin-left: 0; } +@media screen and (max-width: 860px) { .three.columns { - width: 22%; } - - .four.columns { - width: 30.6666666667%; } - - .five.columns { - width: 39.3333333333%; } - - .six.columns { - width: 48%; } - - .seven.columns { - width: 56.6666666667%; } - - .eight.columns { - width: 65.3333333333%; } - + display: none; + } .nine.columns { - width: 74.0%; } - - .ten.columns { - width: 82.6666666667%; } - - .eleven.columns { - width: 91.3333333333%; } - - .twelve.columns { - width: 100%; - margin-left: 0; } - - .one-third.column { - width: 30.6666666667%; } - - .two-thirds.column { - width: 65.3333333333%; } } -/* Customer Overrides */ -.footer { - text-align: center; - color: #969696; - padding-top: 10%; } - -p.module-desc { - font-size: 1.1em; - color: #666666; } - -a.link-seesrc { - color: #aec7d2; - font-style: italic; } - -a.link-seesrc:hover { - color: #6c9aae; } - -#toc-list { - word-wrap: break-word; } - -ul.simple-toc { - list-style: none; } - -ul.simple-toc a.reference-toplevel { - font-weight: bold; - color: #0077b3; } - -ul.simple-toc-section { - list-style-type: circle; - color: #6c9aae; } - -ul.simple-toc-section a.reference { - color: #0077b3; } + width: 98.0%; + } + body { + font-size: 1em; + line-height: 1.35; + } +} cite { font-style: italic !important; } -dt > pre { - border-color: rgba(0, 0, 0, 0.1); - background-color: rgba(255, 255, 255, 0.3); - margin: 15px 0px 5px; } - -dd > pre { - border-color: rgba(0, 0, 0, 0.1); - background-color: whitesmoke; - margin-top: 8px; } - -.item > dd { - margin-left: 10px; - margin-bottom: 30px; } - -/* Nim line-numbered tables */ -.line-nums-table { - width: 100%; - table-layout: fixed; } /* Nim search input */ div#searchInputDiv { - margin-bottom: 8px; + margin-bottom: 1em; } -div#searchInputDiv input#searchInput { - width: 10em; -} -div.search-groupby { - margin-bottom: 8px; +input#searchInput { + width: 80%; } -table.line-nums-table { - border-radius: 4px; - border: 1px solid #cccccc; - background-color: whitesmoke; - border-collapse: separate; - margin-top: 15px; - margin-bottom: 25px; } - -.line-nums-table tbody { - border: none; } - -.line-nums-table td pre { - border: none; - background-color: transparent; } - -.line-nums-table td.blob-line-nums { - width: 28px; } - -.line-nums-table td.blob-line-nums pre { - color: #b0b0b0; - -webkit-filter: opacity(75%); - text-align: right; - border-color: transparent; - background-color: transparent; - padding-left: 0px; - margin-left: 0px; - padding-right: 0px; - margin-right: 0px; } /* Docgen styles */ /* Links */ a { - color: #0077b3; - text-decoration: none; } + color: #07b; + text-decoration: none; +} + +a span.Identifier { + text-decoration: underline; + text-decoration-color: #aab; +} + +a.reference-toplevel { + font-weight: bold; +} + +a.toc-backref { + text-decoration: none; + color: #222; } + +a.link-seesrc { + color: #607c9f; + font-size: 0.9em; + font-style: italic; } a:hover, a:focus { - color: #00334d; + color: #607c9f; text-decoration: underline; } -a:visited { - color: #00334d; } +a:hover span.Identifier { + color: #607c9f; +} -a:focus { - outline: thin dotted #2d2d2d; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; } - -a:hover, -a:active { - outline: 0; } sub, sup { @@ -329,379 +210,258 @@ img { h2, h3 { - page-break-after: avoid; } } -.img-rounded { - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; } + page-break-after: avoid; } +} -.img-polaroid { - padding: 4px; - background-color: rgba(252, 248, 244, 0.75); - border: 1px solid #ccc; - border: 1px solid rgba(0, 0, 0, 0.2); - -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); - -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); } p { - margin: 0 0 8px; } + margin-top: 0.5em; + margin-bottom: 0.5em; +} small { font-size: 85%; } strong { - font-weight: 600; } + font-weight: 600; + font-size: 0.95em; + color: #3c3c3c; +} em { font-style: italic; } -cite { - font-style: normal; } - -h1, -h2, -h3, -h4, -h5, -h6 { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-weight: 600; - line-height: 20px; - color: inherit; - text-rendering: optimizelegibility; } - h1 { - font-size: 2em; + font-size: 1.8em; font-weight: 400; - padding-bottom: .15em; - border-bottom: 1px solid #aaaaaa; - margin-top: 1.0em; + padding-bottom: .25em; + border-bottom: 1px solid #aaa; + margin-top: 2.5em; + margin-bottom: 1em; line-height: 1.2em; } h1.title { padding-bottom: 1em; border-bottom: 0px; - font-size: 2.75em; } + font-size: 2.5em; + text-align: center; + font-weight: 900; + margin-top: 0.75em; + margin-bottom: 0em; +} h2 { - font-size: 1.5em; - margin-top: 1.5em; } + font-size: 1.3em; + margin-top: 2em; } + +h2.subtitle { + text-align: center; } h3 { - font-size: 1.3em; + font-size: 1.125em; font-style: italic; - margin-top: 0.75em; } + margin-top: 1.5em; } h4 { - font-size: 1.3em; - margin-top: 0.5em; } + font-size: 1.125em; + margin-top: 1em; } h5 { - font-size: 1.2em; - margin-top: 0.25em; } + font-size: 1.125em; + margin-top: 0.75em; } h6 { font-size: 1.1em; } + ul, ol { padding: 0; - margin: 0 0 0px 15px; } + margin-top: 0.5em; + margin-left: 0.75em; } ul ul, ul ol, ol ol, ol ul { - margin-bottom: 0; } + margin-bottom: 0; + margin-left: 1.25em; } li { - line-height: 20px; } - -dl { - margin-bottom: 20px; } - -dt, -dd { - line-height: 20px; } - -dt { - font-weight: bold; } - -dd { - margin-left: 10px; - margin-bottom: 26px; } - -hr { - margin: 20px 0; - border: 0; - border-top: 1px solid #eeeeee; - border-bottom: 1px solid #ffffff; } - -abbr[title], -abbr[data-original-title] { - cursor: help; - border-bottom: 1px dotted #999999; } - -abbr.initialism { - font-size: 90%; - text-transform: uppercase; } - -blockquote { - padding: 0 0 0 15px; - margin: 0 0 20px; - border-left: 5px solid #EFEBE0; } - -table.docinfo + blockquote, table.docinfo blockquote, h1 + blockquote { - border-left: 5px solid #c9c9c9; + list-style-type: circle; } -table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { - margin-bottom: 0; - font-size: 15px; - font-weight: 200; - line-height: 1.5; - font-style: italic; } +ul.simple-boot li { + list-style-type: none; + margin-left: 0em; + margin-bottom: 0.5em; +} -q:before, -q:after, -blockquote:before, -blockquote:after { - content: ""; } +ol.simple > li, ul.simple > li { + margin-bottom: 0.25em; + margin-left: 0.4em } -address { - display: block; - margin-bottom: 20px; - font-style: normal; - line-height: 20px; } +ul.simple.simple-toc > li { + margin-top: 1em; +} -code, -pre { - font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - padding: 0 3px 2px; - font-weight: 500; - font-size: 12px; - color: #444444; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; } +ul.simple-toc { + list-style: none; + font-size: 0.9em; + margin-left: -0.3em; + margin-top: 1em; } + +ul.simple-toc > li { + list-style-type: none; +} + +ul.simple-toc-section { + list-style-type: circle; + margin-left: 1em; + color: #6c9aae; } + + +ol.arabic { + list-style: decimal; } + +ol.loweralpha { + list-style: lower-alpha; } + +ol.upperalpha { + list-style: upper-alpha; } + +ol.lowerroman { + list-style: lower-roman; } + +ol.upperroman { + list-style: upper-roman; } + +ul.auto-toc { + list-style-type: none; } + + +dl { + margin-bottom: 1.5em; } + +dt { + margin-bottom: -0.5em; + margin-left: 0.5em; } + +dd { + margin-left: 0.5em; + margin-bottom: 2.5em; + margin-top: 0.5em; } + + +hr { + margin: 2em 0; + border: 0; + border-top: 1px solid #aaa; } + +blockquote { + font-size: 0.9em; + font-style: italic; + padding-left: 0.5em; + margin-left: 0; + border-left: 5px solid #bbc; +} .pre { font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - font-weight: 600; - /*color: #504da6;*/ + font-weight: 500; + font-size: 0.85em; + background-color: #f0f3ff; + padding-left: 3px; + padding-right: 3px; + border-radius: 4px; } -code { - padding: 2px 4px; - color: #444444; - white-space: nowrap; - background-color: white; - border: 1px solid #777777; } - pre { + font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; + color: #222; + font-weight: 500; display: inline-block; box-sizing: border-box; - min-width: calc(100% - 19.5px); - padding: 9.5px; - margin: 0.25em 10px 10px 10px; - font-size: 15px; - line-height: 20px; + min-width: 100%; + padding: 0.5em; + margin-top: 0.5em; + margin-bottom: 0.5em; + font-size: 0.85em; white-space: pre !important; overflow-y: hidden; overflow-x: visible; - background-color: rgba(0, 0, 0, 0.01); - border: 1px solid #cccccc; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; } - -pre.prettyprint { - margin-bottom: 20px; } - -pre code { - padding: 0; - color: inherit; - white-space: pre; - overflow-x: visible; - background-color: transparent; - border: 0; } + background-color: ghostwhite; + border: 1px solid #dde; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; } .pre-scrollable { max-height: 340px; overflow-y: scroll; } + +/* Nim line-numbered tables */ +.line-nums-table { + width: 100%; + table-layout: fixed; } + +table.line-nums-table { + border-radius: 4px; + border: 1px solid #cccccc; + background-color: ghostwhite; + border-collapse: separate; + margin-top: 15px; + margin-bottom: 25px; } + +.line-nums-table tbody { + border: none; } + +.line-nums-table td pre { + border: none; + background-color: transparent; } + +.line-nums-table td.blob-line-nums { + width: 28px; } + +.line-nums-table td.blob-line-nums pre { + color: #b0b0b0; + -webkit-filter: opacity(75%); + text-align: right; + border-color: transparent; + background-color: transparent; + padding-left: 0px; + margin-left: 0px; + padding-right: 0px; + margin-right: 0px; } + + table { max-width: 100%; background-color: transparent; + margin-top: 0.5em; + margin-bottom: 1.5em; border-collapse: collapse; - border-spacing: 0; } - -table th, table td { - padding: 0px 8px 0px; + border-color: #ccc; + border-spacing: 0; + font-size: 0.9em; } -.table { - width: 100%; - margin-bottom: 20px; } +table th, table td { + padding: 0px 0.5em 0px; +} -.table th, -.table td { - padding: 8px; - line-height: 20px; - text-align: left; - vertical-align: top; - border-top: 1px solid #444444; } - -.table th { +table th { + background-color: #e8e8e8; font-weight: bold; } -.table thead th { - vertical-align: bottom; } +table th.docinfo-name { + background-color: transparent; +} -.table caption + thead tr:first-child th, -.table caption + thead tr:first-child td, -.table colgroup + thead tr:first-child th, -.table colgroup + thead tr:first-child td, -.table thead:first-child tr:first-child th, -.table thead:first-child tr:first-child td { - border-top: 0; } +table tr:hover { + background-color: ghostwhite; } -.table tbody + tbody { - border-top: 2px solid #444444; } - -.table .table { - background-color: rgba(252, 248, 244, 0.75); } - -.table-condensed th, -.table-condensed td { - padding: 4px 5px; } - -.table-bordered { - border: 1px solid #444444; - border-collapse: separate; - *border-collapse: collapse; - border-left: 0; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; } - -.table-bordered th, -.table-bordered td { - border-left: 1px solid #444444; } - -.table-bordered caption + thead tr:first-child th, -.table-bordered caption + tbody tr:first-child th, -.table-bordered caption + tbody tr:first-child td, -.table-bordered colgroup + thead tr:first-child th, -.table-bordered colgroup + tbody tr:first-child th, -.table-bordered colgroup + tbody tr:first-child td, -.table-bordered thead:first-child tr:first-child th, -.table-bordered tbody:first-child tr:first-child th, -.table-bordered tbody:first-child tr:first-child td { - border-top: 0; } - -.table-bordered thead:first-child tr:first-child > th:first-child, -.table-bordered tbody:first-child tr:first-child > td:first-child, -.table-bordered tbody:first-child tr:first-child > th:first-child { - -webkit-border-top-left-radius: 4px; - border-top-left-radius: 4px; - -moz-border-radius-topleft: 4px; } - -.table-bordered thead:first-child tr:first-child > th:last-child, -.table-bordered tbody:first-child tr:first-child > td:last-child, -.table-bordered tbody:first-child tr:first-child > th:last-child { - -webkit-border-top-right-radius: 4px; - border-top-right-radius: 4px; - -moz-border-radius-topright: 4px; } - -.table-bordered thead:last-child tr:last-child > th:first-child, -.table-bordered tbody:last-child tr:last-child > td:first-child, -.table-bordered tbody:last-child tr:last-child > th:first-child, -.table-bordered tfoot:last-child tr:last-child > td:first-child, -.table-bordered tfoot:last-child tr:last-child > th:first-child { - -webkit-border-bottom-left-radius: 4px; - border-bottom-left-radius: 4px; - -moz-border-radius-bottomleft: 4px; } - -.table-bordered thead:last-child tr:last-child > th:last-child, -.table-bordered tbody:last-child tr:last-child > td:last-child, -.table-bordered tbody:last-child tr:last-child > th:last-child, -.table-bordered tfoot:last-child tr:last-child > td:last-child, -.table-bordered tfoot:last-child tr:last-child > th:last-child { - -webkit-border-bottom-right-radius: 4px; - border-bottom-right-radius: 4px; - -moz-border-radius-bottomright: 4px; } - -.table-bordered tfoot + tbody:last-child tr:last-child td:first-child { - -webkit-border-bottom-left-radius: 0; - border-bottom-left-radius: 0; - -moz-border-radius-bottomleft: 0; } - -.table-bordered tfoot + tbody:last-child tr:last-child td:last-child { - -webkit-border-bottom-right-radius: 0; - border-bottom-right-radius: 0; - -moz-border-radius-bottomright: 0; } - -.table-bordered caption + thead tr:first-child th:first-child, -.table-bordered caption + tbody tr:first-child td:first-child, -.table-bordered colgroup + thead tr:first-child th:first-child, -.table-bordered colgroup + tbody tr:first-child td:first-child { - -webkit-border-top-left-radius: 4px; - border-top-left-radius: 4px; - -moz-border-radius-topleft: 4px; } - -.table-bordered caption + thead tr:first-child th:last-child, -.table-bordered caption + tbody tr:first-child td:last-child, -.table-bordered colgroup + thead tr:first-child th:last-child, -.table-bordered colgroup + tbody tr:first-child td:last-child { - -webkit-border-top-right-radius: 4px; - border-top-right-radius: 4px; - -moz-border-radius-topright: 4px; } - -table.docutils th { - background-color: #e8e8e8; } - -table.docutils tr:hover { - background-color: whitesmoke; } - -.table-striped tbody > tr:nth-child(odd) > td, -.table-striped tbody > tr:nth-child(odd) > th { - background-color: rgba(252, 248, 244, 0.75); } - -.table-hover tbody tr:hover > td, -.table-hover tbody tr:hover > th { - background-color: rgba(241, 222, 204, 0.75); } - -table td[class*="span"], -table th[class*="span"], -.row-fluid table td[class*="span"], -.row-fluid table th[class*="span"] { - display: table-cell; - float: none; - margin-left: 0; } - -.hero-unit { - padding: 60px; - margin-bottom: 30px; - font-size: 18px; - font-weight: 200; - line-height: 30px; - color: inherit; - background-color: rgba(230, 197, 164, 0.75); - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; } - -.hero-unit h1 { - margin-bottom: 0; - font-size: 60px; - line-height: 1; - letter-spacing: -1px; - color: inherit; } - -.hero-unit li { - line-height: 30px; } /* rst2html default used to remove borders from tables and images */ .borderless, table.borderless td, table.borderless th { @@ -722,10 +482,6 @@ table.borderless td, table.borderless th { .hidden { display: none; } -a.toc-backref { - text-decoration: none; - color: #444444; } - blockquote.epigraph { margin: 2em 5em; } @@ -735,85 +491,6 @@ dl.docutils dd { object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] { overflow: hidden; } -/* Uncomment (and remove this text!) to get bold-faced definition list terms -dl.docutils dt { - font-weight: bold } -*/ -div.abstract { - margin: 2em 5em; } - -div.abstract p.topic-title { - font-weight: bold; - text-align: center; } - -div.admonition, div.attention, div.caution, div.danger, div.error, -div.hint, div.important, div.note, div.tip, div.warning { - margin: 2em; - border: medium outset; - padding: 1em; } - -div.note, div.warning { - margin: 1.5em 0px; - border: none; } - -div.note p.admonition-title, -div.warning p.admonition-title { - display: none; } - -/* Clearfix - * http://css-tricks.com/snippets/css/clear-fix/ - */ -div.note:after, -div.warning:after { - content: ""; - display: table; - clear: both; } - -div.note p:before, -div.warning p:before { - display: block; - float: left; - font-size: 4em; - line-height: 1em; - margin-right: 20px; - margin-left: 0em; - margin-top: -10px; - content: '\0270D'; - /*handwriting*/ } - -div.warning p:before { - content: '\026A0'; - /*warning*/ } - -div.admonition p.admonition-title, div.hint p.admonition-title, -div.important p.admonition-title, div.note p.admonition-title, -div.tip p.admonition-title { - font-weight: bold; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } - -div.attention p.admonition-title, div.caution p.admonition-title, -div.danger p.admonition-title, div.error p.admonition-title, -div.warning p.admonition-title, .code .error { - color: #b30000; - font-weight: bold; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } - -/* Uncomment (and remove this text!) to get reduced vertical space in - compound paragraphs. -div.compound .compound-first, div.compound .compound-middle { - margin-bottom: 0.5em } - -div.compound .compound-last, div.compound .compound-middle { - margin-top: 0.5em } -*/ -div.dedication { - margin: 2em 5em; - text-align: center; - font-style: italic; } - -div.dedication p.topic-title { - font-weight: bold; - font-style: normal; } div.figure { margin-left: 2em; @@ -821,8 +498,14 @@ div.figure { div.footer, div.header { clear: both; + text-align: center; + color: #666; font-size: smaller; } +div.footer { + padding-top: 5em; +} + div.line-block { display: block; margin-top: 1em; @@ -833,45 +516,24 @@ div.line-block div.line-block { margin-bottom: 0; margin-left: 1.5em; } -div.sidebar { - margin: 0 0 0.5em 1em; - border: medium outset; - padding: 1em; - background-color: rgba(252, 248, 244, 0.75); - width: 40%; - float: right; - clear: right; } - -div.sidebar p.rubric { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-size: medium; } - -div.system-messages { - margin: 5em; } - -div.system-messages h1 { - color: #b30000; } - -div.system-message { - border: medium outset; - padding: 1em; } - -div.system-message p.system-message-title { - color: #b30000; - font-weight: bold; } - div.topic { margin: 2em; } -h1.section-subtitle, h2.section-subtitle, h3.section-subtitle, -h4.section-subtitle, h5.section-subtitle, h6.section-subtitle { - margin-top: 0.4em; } +div.search_results { + background-color: antiquewhite; + margin: 3em; + padding: 1em; + border: 1px solid #4d4d4d; +} -h1.title { - text-align: center; } +div#global-links ul { + margin-left: 0; + list-style-type: none; +} -h2.subtitle { - text-align: center; } +div#global-links > simple-boot { + margin-left: 3em; +} hr.docutils { width: 75%; } @@ -905,30 +567,6 @@ img.align-center, .figure.align-center, object.align-center { div.align-right { text-align: inherit; } -/* div.align-center * { */ -/* text-align: left } */ - -ul.simple > li { - margin-bottom: 0.5em } - -ol.simple, ul.simple { - margin-bottom: 1em; } - -ol.arabic { - list-style: decimal; } - -ol.loweralpha { - list-style: lower-alpha; } - -ol.upperalpha { - list-style: upper-alpha; } - -ol.lowerroman { - list-style: lower-roman; } - -ol.upperroman { - list-style: upper-roman; } - p.attribution { text-align: right; margin-left: 50%; } @@ -949,15 +587,6 @@ p.rubric { color: maroon; text-align: center; } -p.sidebar-title { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-weight: bold; - font-size: larger; } - -p.sidebar-subtitle { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-weight: bold; } - p.topic-title { font-weight: bold; } @@ -997,22 +626,14 @@ pre.code .inserted, code .inserted { background-color: #A3D289; } span.classifier { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-style: oblique; } span.classifier-delimiter { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: bold; } -span.interpreted { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } - span.option { white-space: nowrap; } -span.pre { - white-space: pre; } - span.problematic { color: #b30000; } @@ -1020,44 +641,6 @@ span.section-subtitle { /* font-size relative to parent (h1..h6 element) */ font-size: 80%; } -table.citation { - border-left: solid 1px #666666; - margin-left: 1px; } - -table.docinfo { - margin: 0em; - margin-top: 2em; - margin-bottom: 2em; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; - color: #444444; } - -table.docutils { - margin-top: 0.5em; - margin-bottom: 0.5em; } - -table.footnote { - border-left: solid 1px #2d2d2d; - margin-left: 1px; } - -table.docutils td, table.docutils th, -table.docinfo td, table.docinfo th { - padding-left: 0.5em; - padding-right: 0.5em; - vertical-align: top; } - -table.docutils th.field-name, table.docinfo th.docinfo-name { - font-weight: 700; - text-align: left; - white-space: nowrap; - padding-left: 0; } - -h1 tt.docutils, h2 tt.docutils, h3 tt.docutils, -h4 tt.docutils, h5 tt.docutils, h6 tt.docutils { - font-size: 100%; } - -ul.auto-toc { - list-style-type: none; } - span.DecNumber { color: #252dbe; } @@ -1074,7 +657,7 @@ span.FloatNumber { color: #252dbe; } span.Identifier { - color: #3b3b3b; } + color: #222; } span.Keyword { font-weight: 600; @@ -1139,38 +722,23 @@ dt pre > span.Identifier, dt pre > span.Operator { color: #155da4; font-weight: 700; } -dt pre > span.Identifier ~ span.Identifier, dt pre > span.Operator ~ span.Identifier { - color: inherit; - font-weight: inherit; } - -dt pre > span.Operator ~ span.Identifier { +dt pre > span.Keyword ~ span.Identifier, dt pre > span.Identifier ~ span.Identifier, +dt pre > span.Operator ~ span.Identifier, dt pre > span.Other ~ span.Identifier { color: inherit; font-weight: inherit; } /* Nim sprite for the footer (taken from main page favicon) */ .nim-sprite { display: inline-block; - height: 12px; - width: 12px; + height: 16px; + width: 16px; background-position: 0 0; - background-size: 12px 12px; + background-size: 16px 16px; -webkit-filter: opacity(50%); background-repeat: no-repeat; background-image: url("data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="); margin-bottom: -5px; } -div.search_results { - background-color: antiquewhite; - margin: 3em; - padding: 1em; - border: 1px solid #4d4d4d; -} - -div#global-links ul { - margin-left: 0; - list-style-type: none; -} - span.pragmadots { /* Position: relative frees us up to make the dots look really nice without fucking up the layout and @@ -1178,18 +746,14 @@ span.pragmadots { position: relative; /* 1px down looks slightly nicer */ top: 1px; - padding: 2px; - background-color: #D3D3D3; + background-color: #e8e8e8; border-radius: 4px; margin: 0 2px; cursor: pointer; - - /* For some reason on Chrome, making the font size - smaller than 1em is causing the parent container to - bulge slightly. So, we're stuck with inheriting 1em, - which is sad, because 0.8em looks better... */ + font-size: 0.8em; } + span.pragmadots:hover { background-color: #DBDBDB; } @@ -1253,35 +817,35 @@ function main() {
  • Procs
  • Macros @@ -1292,35 +856,90 @@ function main() {
    -

    +

    Main import file to write wrappers. Each compileTime proc must be used in a compile time context, eg using:

    +

    +static:
    +  cAddStdDir()
    +

    +

    Procs

    - -
    proc cSearchPath(path: string): string {...}{.compileTime, raises: [], tags: [ReadDirEffect].}
    + +
    proc cSkipSymbol(skips: seq[string]) {...}{.compileTime, raises: [], tags: [].}
    -

    Get full path to file or directory path in search path configured using cAddSearchDir() and cAddStdDir().

    +Similar to cOverride(), this macro allows filtering out symbols not of interest from the generated output. +

    Examples:

    +
    static :
    +  cSkipSymbol @["proc1", "Type2"]
    + +
    + +
    proc cSearchPath(path: string): string {...}{.compileTime, raises: [], tags: [ReadDirEffect].}
    +
    +

    Get full path to file or directory path in search path configured using cAddSearchDir() and cAddStdDir().

    This can be used to locate files or directories that can be passed onto cCompile(), cIncludeDir() and cImport().

    +
    + +
    proc cDebug() {...}{.compileTime, raises: [], tags: [].}
    +
    +Enable debug messages and display the generated Nim code + +
    + +
    proc cDisableCaching() {...}{.compileTime, raises: [], tags: [].}
    +
    +

    Disable caching of generated Nim code - useful during wrapper development

    +

    If files included by header being processed by cImport() change and affect the generated content, they will be ignored and the cached value will continue to be used . Use cDisableCaching() to avoid this scenario during development.

    +

    nim -f was broken prior to 0.19.4 but can also be used to flush the cached content.

    + + +
    + +
    proc cAddSearchDir(dir: string) {...}{.compileTime, raises: [], tags: [].}
    +
    +Add directory dir to the search path used in calls to cSearchPath(). +

    Examples:

    +
    import
    +  paths, os
    +
    +static :
    +  cAddSearchDir testsIncludeDir()
    +doAssert cSearchPath("test.h").existsFile
    + +
    + +
    proc cAddStdDir(mode = "c") {...}{.compileTime, raises: [], tags: [].}
    +
    +Add the standard c [default] or cpp include paths to search path used in calls to cSearchPath() +

    Examples:

    +
    static :
    +  cAddStdDir()
    +import
    +  os
    +
    +doAssert cSearchPath("math.h").existsFile
    +

    Macros

    - -
    macro cOverride(body): untyped
    + +
    macro cOverride(body): untyped

    When the wrapper code generated by nimterop is missing certain symbols or not accurate, it may be required to hand wrap them. Define them in a cOverride() macro block so that Nimterop no longer defines these symbols.

    For example:

    @@ -1331,28 +950,20 @@ function main() {
    - -
    macro cSkipSymbol(skips: varargs[string]): untyped
    + +
    macro cPlugin(body): untyped
    -Similar to cOverride(), this macro allows filtering out symbols not of interest from the generated output. -

    Examples:

    -
    cSkipSymbol "proc1", "Type2"
    - -
    - -
    macro cPlugin(body): untyped
    -
    -When cOverride() and cSkipSymbol() are not adequate, the cPlugin() macro can be used to customize the generated Nim output. The following callbacks are available at this time.
    proc onSymbol(sym: var Symbol) {.exportc, dynlib.}

    onSymbol() can be used to handle symbol name modifications required due to invalid characters like leading/trailing _ or rename symbols that would clash due to Nim's style insensitivity. It can also be used to remove prefixes and suffixes like SDL_. The symbol name and type is provided to the callback and the name can be modified.

    -

    Returning a blank name will result in the symbol being skipped. This will fail for nskParam and nskField since the generated Nim code will be wrong.

    +When cOverride() and cSkipSymbol() are not adequate, the cPlugin() macro can be used to customize the generated Nim output. The following callbacks are available at this time.
    proc onSymbol(sym: var Symbol) {.exportc, dynlib.}

    onSymbol() can be used to handle symbol name modifications required due to invalid characters like leading/trailing _ or rename symbols that would clash due to Nim's style insensitivity. It can also be used to remove prefixes and suffixes like SDL_. The symbol name and type is provided to the callback and the name can be modified.

    +

    Returning a blank name will result in the symbol being skipped. This will fail for nskParam and nskField since the generated Nim code will be wrong.

    Symbol types can be any of the following:

    -
    • nskConst for constants
    • -
    • nskType for type identifiers, including primitive
    • -
    • nskParam for param names
    • -
    • nskField for struct field names
    • -
    • nskEnumField for enum (field) names, though they are in the global namespace as nskConst
    • -
    • nskProc - for proc names
    • +
      • nskConst for constants
      • +
      • nskType for type identifiers, including primitive
      • +
      • nskParam for param names
      • +
      • nskField for struct field names
      • +
      • nskEnumField for enum (field) names, though they are in the global namespace as nskConst
      • +
      • nskProc - for proc names
      -

      nimterop/plugins is implicitly imported to provide access to standard plugin facilities.

      +

      nimterop/plugins is implicitly imported to provide access to standard plugin facilities.

      Examples:

      cPlugin:
      @@ -1363,69 +974,35 @@ When cOverride()<
           sym.name = sym.name.strip(chars = {'_'})
       
      -
    - -
    macro cDebug(): untyped
    -
    -Enable debug messages and display the generated Nim code - -
    - -
    macro cDisableCaching(): untyped
    -
    -

    Disable caching of generated Nim code - useful during wrapper development

    -

    If files included by header being processed by cImport() change and affect the generated content, they will be ignored and the cached value will continue to be used . Use cDisableCaching() to avoid this scenario during development.

    -

    nim -f was broken prior to 0.19.4 but can also be used to flush the cached content.

    - -
    -
    macro cDefine(name: static string; val: static string = ""): untyped
    +
    macro cDefine(name: static string; val: static string = ""): untyped
    #define an identifer that is forwarded to the C/C++ compiler using {.passC: "-DXXX".}
    - -
    macro cAddSearchDir(dir: static string): untyped
    -
    -

    Add directory dir to the search path used in calls to cSearchPath().

    -

    This allows something like this:

    -
    cAddSearchDir("path/to/includes")
    -cImport cSearchPath("file.h")
    - -
    - -
    macro cIncludeDir(dir: static string): untyped
    + +
    macro cIncludeDir(dir: static string): untyped
    Add an include directory that is forwarded to the C/C++ compiler using {.passC: "-IXXX".}. This is also provided to the preprocessor during Nim code generation.
    - -
    macro cAddStdDir(mode = "c"): untyped
    -
    -

    Add the standard c [default] or cpp include paths to search path used in calls to cSearchPath()

    -

    This allows something like this:

    - -

    Examples:

    -
    cAddStdDir()
    -echo cSearchPath("math.h")
    - -
    - -
    macro cCompile(path: static string; mode = "c"): untyped
    + +
    macro cCompile(path: static string; mode = "c"; exclude = ""): untyped

    Compile and link C/C++ implementation into resulting binary using {.compile.}

    path can be a specific file or contain wildcards:

    cCompile("file.c")
     cCompile("path/to/*.c")

    mode recursively searches for code files in path.

    c searches for *.c whereas cpp searches for *.C *.cpp *.c++ *.cc *.cxx

    -
    cCompile("path/to/dir", "cpp")
    +
    cCompile("path/to/dir", "cpp")

    exclude can be used to exclude files by partial string match. Comma separated to specify multiple exclude strings

    +
    cCompile("path/to/dir", exclude="test2.c")
    - -
    macro cImport(filename: static string; recurse: static bool = false): untyped
    + +
    macro cImport(filename: static string; recurse: static bool = false): untyped
    -

    Import all supported definitions from specified header file. Generated content is cached in nimcache until filename changes unless cDisableCaching() is set. nim -f can also be used after Nim v0.19.4 to flush the cache.

    +

    Import all supported definitions from specified header file. Generated content is cached in nimcache until filename changes unless cDisableCaching() is set. nim -f can also be used after Nim v0.19.4 to flush the cache.

    recurse can be used to generate Nim wrappers from #include files referenced in filename. This is only done for files in the same directory as filename or in a directory added using cIncludeDir()

    @@ -1440,7 +1017,7 @@ Add an include directory that is forwarded to the C/C++ compiler using
    - Made with Nim. Generated: 2019-01-31 15:20:53 UTC + Made with Nim. Generated: 2019-02-08 22:35:14 UTC
    diff --git a/cimport.idx b/cimport.idx old mode 100644 new mode 100755 index 87ea44f..6358c57 --- a/cimport.idx +++ b/cimport.idx @@ -1,12 +1,12 @@ -cOverride cimport.html#cOverride.m, cimport: cOverride(body): untyped -cSkipSymbol cimport.html#cSkipSymbol.m,varargs[string] cimport: cSkipSymbol(skips: varargs[string]): untyped -cPlugin cimport.html#cPlugin.m, cimport: cPlugin(body): untyped +cOverride cimport.html#cOverride.m cimport: cOverride(body): untyped +cSkipSymbol cimport.html#cSkipSymbol,seq[string] cimport: cSkipSymbol(skips: seq[string]) +cPlugin cimport.html#cPlugin.m cimport: cPlugin(body): untyped cSearchPath cimport.html#cSearchPath,string cimport: cSearchPath(path: string): string -cDebug cimport.html#cDebug.m, cimport: cDebug(): untyped -cDisableCaching cimport.html#cDisableCaching.m, cimport: cDisableCaching(): untyped +cDebug cimport.html#cDebug cimport: cDebug() +cDisableCaching cimport.html#cDisableCaching cimport: cDisableCaching() cDefine cimport.html#cDefine.m,,string cimport: cDefine(name: static string; val: static string = ""): untyped -cAddSearchDir cimport.html#cAddSearchDir.m, cimport: cAddSearchDir(dir: static string): untyped -cIncludeDir cimport.html#cIncludeDir.m, cimport: cIncludeDir(dir: static string): untyped -cAddStdDir cimport.html#cAddStdDir.m,string cimport: cAddStdDir(mode = "c"): untyped -cCompile cimport.html#cCompile.m,,string cimport: cCompile(path: static string; mode = "c"): untyped -cImport cimport.html#cImport.m, cimport: cImport(filename: static string; recurse: static bool = false): untyped +cAddSearchDir cimport.html#cAddSearchDir,string cimport: cAddSearchDir(dir: string) +cIncludeDir cimport.html#cIncludeDir.m cimport: cIncludeDir(dir: static string): untyped +cAddStdDir cimport.html#cAddStdDir,string cimport: cAddStdDir(mode = "c") +cCompile cimport.html#cCompile.m,,string,string cimport: cCompile(path: static string; mode = "c"; exclude = ""): untyped +cImport cimport.html#cImport.m cimport: cImport(filename: static string; recurse: static bool = false): untyped diff --git a/dochack.js b/dochack.js new file mode 100755 index 0000000..e23a822 --- /dev/null +++ b/dochack.js @@ -0,0 +1,1970 @@ +/* Generated by the Nim Compiler v0.19.9 */ +/* (c) 2018 Andreas Rumpf */ + +var framePtr = null; +var excHandler = 0; +var lastJSError = null; +if (typeof Int8Array === 'undefined') Int8Array = Array; +if (typeof Int16Array === 'undefined') Int16Array = Array; +if (typeof Int32Array === 'undefined') Int32Array = Array; +if (typeof Uint8Array === 'undefined') Uint8Array = Array; +if (typeof Uint16Array === 'undefined') Uint16Array = Array; +if (typeof Uint32Array === 'undefined') Uint32Array = Array; +if (typeof Float32Array === 'undefined') Float32Array = Array; +if (typeof Float64Array === 'undefined') Float64Array = Array; +var NTI37032 = {size: 0,kind: 1,base: null,node: null,finalizer: null}; +var NTI180074 = {size: 0, kind: 18, base: null, node: null, finalizer: null}; +var NTI41262 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI182526 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; +var NTI71442 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI71438 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI71434 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI71430 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI71426 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI71422 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI71418 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI71414 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI71410 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI71406 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI71402 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI71398 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI71394 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI71390 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI71386 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI71382 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI71378 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI71374 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI71370 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI71366 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI71205 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI71277 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI71275 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; +var NTI71221 = {size: 0, kind: 14, base: null, node: null, finalizer: null}; +var NTI71520 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; +var NTI71518 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; +var NTI71516 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; +var NTI71225 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI71223 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; +var NTI73045 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; +var NTI41250 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI41258 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI37006 = {size: 0,kind: 31,base: null,node: null,finalizer: null}; +var NTI53541 = {size: 0, kind: 18, base: null, node: null, finalizer: null}; +var NTI41208 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI41314 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; +var NTI37016 = {size: 0,kind: 40,base: null,node: null,finalizer: null}; +var NTI37040 = {size: 0,kind: 28,base: null,node: null,finalizer: null}; +var NTI37042 = {size: 0,kind: 29,base: null,node: null,finalizer: null}; +var NTI41308 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; +var NTI41226 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI41228 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI41242 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI41246 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NNI41246 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI41246.node = NNI41246; +var NNI41242 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI41242.node = NNI41242; +var NNI41228 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI41228.node = NNI41228; +NTI41308.base = NTI41226; +NTI41314.base = NTI41226; +var NNI41226 = {kind: 2, len: 6, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "parent", len: 0, typ: NTI41308, name: "parent", sons: null}, +{kind: 1, offset: "name", len: 0, typ: NTI37042, name: "name", sons: null}, +{kind: 1, offset: "message", len: 0, typ: NTI37040, name: "msg", sons: null}, +{kind: 1, offset: "trace", len: 0, typ: NTI37040, name: "trace", sons: null}, +{kind: 1, offset: "raiseId", len: 0, typ: NTI37016, name: "raiseId", sons: null}, +{kind: 1, offset: "up", len: 0, typ: NTI41314, name: "up", sons: null}]}; +NTI41226.node = NNI41226; +var NNI41208 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI41208.node = NNI41208; +NTI41226.base = NTI41208; +NTI41228.base = NTI41226; +NTI41242.base = NTI41228; +NTI41246.base = NTI41242; +var NNI53541 = {kind: 2, len: 2, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "Field0", len: 0, typ: NTI37042, name: "Field0", sons: null}, +{kind: 1, offset: "Field1", len: 0, typ: NTI37006, name: "Field1", sons: null}]}; +NTI53541.node = NNI53541; +var NNI41258 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI41258.node = NNI41258; +NTI41258.base = NTI41228; +var NNI41250 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI41250.node = NNI41250; +NTI41250.base = NTI41228; +NTI71516.base = NTI71223; +NTI71518.base = NTI71223; +NTI71520.base = NTI71223; +var NNI71221 = {kind: 2, offset: 0, typ: null, name: null, len: 12, sons: {"1": {kind: 1, offset: 1, typ: NTI71221, name: "ElementNode", len: 0, sons: null}, +"2": {kind: 1, offset: 2, typ: NTI71221, name: "AttributeNode", len: 0, sons: null}, +"3": {kind: 1, offset: 3, typ: NTI71221, name: "TextNode", len: 0, sons: null}, +"4": {kind: 1, offset: 4, typ: NTI71221, name: "CDATANode", len: 0, sons: null}, +"5": {kind: 1, offset: 5, typ: NTI71221, name: "EntityRefNode", len: 0, sons: null}, +"6": {kind: 1, offset: 6, typ: NTI71221, name: "EntityNode", len: 0, sons: null}, +"7": {kind: 1, offset: 7, typ: NTI71221, name: "ProcessingInstructionNode", len: 0, sons: null}, +"8": {kind: 1, offset: 8, typ: NTI71221, name: "CommentNode", len: 0, sons: null}, +"9": {kind: 1, offset: 9, typ: NTI71221, name: "DocumentNode", len: 0, sons: null}, +"10": {kind: 1, offset: 10, typ: NTI71221, name: "DocumentTypeNode", len: 0, sons: null}, +"11": {kind: 1, offset: 11, typ: NTI71221, name: "DocumentFragmentNode", len: 0, sons: null}, +"12": {kind: 1, offset: 12, typ: NTI71221, name: "NotationNode", len: 0, sons: null}}}; +NTI71221.node = NNI71221; +var NNI71277 = {kind: 2, len: 91, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "background", len: 0, typ: NTI37042, name: "background", sons: null}, +{kind: 1, offset: "backgroundAttachment", len: 0, typ: NTI37042, name: "backgroundAttachment", sons: null}, +{kind: 1, offset: "backgroundColor", len: 0, typ: NTI37042, name: "backgroundColor", sons: null}, +{kind: 1, offset: "backgroundImage", len: 0, typ: NTI37042, name: "backgroundImage", sons: null}, +{kind: 1, offset: "backgroundPosition", len: 0, typ: NTI37042, name: "backgroundPosition", sons: null}, +{kind: 1, offset: "backgroundRepeat", len: 0, typ: NTI37042, name: "backgroundRepeat", sons: null}, +{kind: 1, offset: "border", len: 0, typ: NTI37042, name: "border", sons: null}, +{kind: 1, offset: "borderBottom", len: 0, typ: NTI37042, name: "borderBottom", sons: null}, +{kind: 1, offset: "borderBottomColor", len: 0, typ: NTI37042, name: "borderBottomColor", sons: null}, +{kind: 1, offset: "borderBottomStyle", len: 0, typ: NTI37042, name: "borderBottomStyle", sons: null}, +{kind: 1, offset: "borderBottomWidth", len: 0, typ: NTI37042, name: "borderBottomWidth", sons: null}, +{kind: 1, offset: "borderColor", len: 0, typ: NTI37042, name: "borderColor", sons: null}, +{kind: 1, offset: "borderLeft", len: 0, typ: NTI37042, name: "borderLeft", sons: null}, +{kind: 1, offset: "borderLeftColor", len: 0, typ: NTI37042, name: "borderLeftColor", sons: null}, +{kind: 1, offset: "borderLeftStyle", len: 0, typ: NTI37042, name: "borderLeftStyle", sons: null}, +{kind: 1, offset: "borderLeftWidth", len: 0, typ: NTI37042, name: "borderLeftWidth", sons: null}, +{kind: 1, offset: "borderRight", len: 0, typ: NTI37042, name: "borderRight", sons: null}, +{kind: 1, offset: "borderRightColor", len: 0, typ: NTI37042, name: "borderRightColor", sons: null}, +{kind: 1, offset: "borderRightStyle", len: 0, typ: NTI37042, name: "borderRightStyle", sons: null}, +{kind: 1, offset: "borderRightWidth", len: 0, typ: NTI37042, name: "borderRightWidth", sons: null}, +{kind: 1, offset: "borderStyle", len: 0, typ: NTI37042, name: "borderStyle", sons: null}, +{kind: 1, offset: "borderTop", len: 0, typ: NTI37042, name: "borderTop", sons: null}, +{kind: 1, offset: "borderTopColor", len: 0, typ: NTI37042, name: "borderTopColor", sons: null}, +{kind: 1, offset: "borderTopStyle", len: 0, typ: NTI37042, name: "borderTopStyle", sons: null}, +{kind: 1, offset: "borderTopWidth", len: 0, typ: NTI37042, name: "borderTopWidth", sons: null}, +{kind: 1, offset: "borderWidth", len: 0, typ: NTI37042, name: "borderWidth", sons: null}, +{kind: 1, offset: "bottom", len: 0, typ: NTI37042, name: "bottom", sons: null}, +{kind: 1, offset: "captionSide", len: 0, typ: NTI37042, name: "captionSide", sons: null}, +{kind: 1, offset: "clear", len: 0, typ: NTI37042, name: "clear", sons: null}, +{kind: 1, offset: "clip", len: 0, typ: NTI37042, name: "clip", sons: null}, +{kind: 1, offset: "color", len: 0, typ: NTI37042, name: "color", sons: null}, +{kind: 1, offset: "cursor", len: 0, typ: NTI37042, name: "cursor", sons: null}, +{kind: 1, offset: "direction", len: 0, typ: NTI37042, name: "direction", sons: null}, +{kind: 1, offset: "display", len: 0, typ: NTI37042, name: "display", sons: null}, +{kind: 1, offset: "emptyCells", len: 0, typ: NTI37042, name: "emptyCells", sons: null}, +{kind: 1, offset: "cssFloat", len: 0, typ: NTI37042, name: "cssFloat", sons: null}, +{kind: 1, offset: "font", len: 0, typ: NTI37042, name: "font", sons: null}, +{kind: 1, offset: "fontFamily", len: 0, typ: NTI37042, name: "fontFamily", sons: null}, +{kind: 1, offset: "fontSize", len: 0, typ: NTI37042, name: "fontSize", sons: null}, +{kind: 1, offset: "fontStretch", len: 0, typ: NTI37042, name: "fontStretch", sons: null}, +{kind: 1, offset: "fontStyle", len: 0, typ: NTI37042, name: "fontStyle", sons: null}, +{kind: 1, offset: "fontVariant", len: 0, typ: NTI37042, name: "fontVariant", sons: null}, +{kind: 1, offset: "fontWeight", len: 0, typ: NTI37042, name: "fontWeight", sons: null}, +{kind: 1, offset: "height", len: 0, typ: NTI37042, name: "height", sons: null}, +{kind: 1, offset: "left", len: 0, typ: NTI37042, name: "left", sons: null}, +{kind: 1, offset: "letterSpacing", len: 0, typ: NTI37042, name: "letterSpacing", sons: null}, +{kind: 1, offset: "lineHeight", len: 0, typ: NTI37042, name: "lineHeight", sons: null}, +{kind: 1, offset: "listStyle", len: 0, typ: NTI37042, name: "listStyle", sons: null}, +{kind: 1, offset: "listStyleImage", len: 0, typ: NTI37042, name: "listStyleImage", sons: null}, +{kind: 1, offset: "listStylePosition", len: 0, typ: NTI37042, name: "listStylePosition", sons: null}, +{kind: 1, offset: "listStyleType", len: 0, typ: NTI37042, name: "listStyleType", sons: null}, +{kind: 1, offset: "margin", len: 0, typ: NTI37042, name: "margin", sons: null}, +{kind: 1, offset: "marginBottom", len: 0, typ: NTI37042, name: "marginBottom", sons: null}, +{kind: 1, offset: "marginLeft", len: 0, typ: NTI37042, name: "marginLeft", sons: null}, +{kind: 1, offset: "marginRight", len: 0, typ: NTI37042, name: "marginRight", sons: null}, +{kind: 1, offset: "marginTop", len: 0, typ: NTI37042, name: "marginTop", sons: null}, +{kind: 1, offset: "maxHeight", len: 0, typ: NTI37042, name: "maxHeight", sons: null}, +{kind: 1, offset: "maxWidth", len: 0, typ: NTI37042, name: "maxWidth", sons: null}, +{kind: 1, offset: "minHeight", len: 0, typ: NTI37042, name: "minHeight", sons: null}, +{kind: 1, offset: "minWidth", len: 0, typ: NTI37042, name: "minWidth", sons: null}, +{kind: 1, offset: "overflow", len: 0, typ: NTI37042, name: "overflow", sons: null}, +{kind: 1, offset: "padding", len: 0, typ: NTI37042, name: "padding", sons: null}, +{kind: 1, offset: "paddingBottom", len: 0, typ: NTI37042, name: "paddingBottom", sons: null}, +{kind: 1, offset: "paddingLeft", len: 0, typ: NTI37042, name: "paddingLeft", sons: null}, +{kind: 1, offset: "paddingRight", len: 0, typ: NTI37042, name: "paddingRight", sons: null}, +{kind: 1, offset: "paddingTop", len: 0, typ: NTI37042, name: "paddingTop", sons: null}, +{kind: 1, offset: "pageBreakAfter", len: 0, typ: NTI37042, name: "pageBreakAfter", sons: null}, +{kind: 1, offset: "pageBreakBefore", len: 0, typ: NTI37042, name: "pageBreakBefore", sons: null}, +{kind: 1, offset: "pointerEvents", len: 0, typ: NTI37042, name: "pointerEvents", sons: null}, +{kind: 1, offset: "position", len: 0, typ: NTI37042, name: "position", sons: null}, +{kind: 1, offset: "right", len: 0, typ: NTI37042, name: "right", sons: null}, +{kind: 1, offset: "scrollbar3dLightColor", len: 0, typ: NTI37042, name: "scrollbar3dLightColor", sons: null}, +{kind: 1, offset: "scrollbarArrowColor", len: 0, typ: NTI37042, name: "scrollbarArrowColor", sons: null}, +{kind: 1, offset: "scrollbarBaseColor", len: 0, typ: NTI37042, name: "scrollbarBaseColor", sons: null}, +{kind: 1, offset: "scrollbarDarkshadowColor", len: 0, typ: NTI37042, name: "scrollbarDarkshadowColor", sons: null}, +{kind: 1, offset: "scrollbarFaceColor", len: 0, typ: NTI37042, name: "scrollbarFaceColor", sons: null}, +{kind: 1, offset: "scrollbarHighlightColor", len: 0, typ: NTI37042, name: "scrollbarHighlightColor", sons: null}, +{kind: 1, offset: "scrollbarShadowColor", len: 0, typ: NTI37042, name: "scrollbarShadowColor", sons: null}, +{kind: 1, offset: "scrollbarTrackColor", len: 0, typ: NTI37042, name: "scrollbarTrackColor", sons: null}, +{kind: 1, offset: "tableLayout", len: 0, typ: NTI37042, name: "tableLayout", sons: null}, +{kind: 1, offset: "textAlign", len: 0, typ: NTI37042, name: "textAlign", sons: null}, +{kind: 1, offset: "textDecoration", len: 0, typ: NTI37042, name: "textDecoration", sons: null}, +{kind: 1, offset: "textIndent", len: 0, typ: NTI37042, name: "textIndent", sons: null}, +{kind: 1, offset: "textTransform", len: 0, typ: NTI37042, name: "textTransform", sons: null}, +{kind: 1, offset: "transform", len: 0, typ: NTI37042, name: "transform", sons: null}, +{kind: 1, offset: "top", len: 0, typ: NTI37042, name: "top", sons: null}, +{kind: 1, offset: "verticalAlign", len: 0, typ: NTI37042, name: "verticalAlign", sons: null}, +{kind: 1, offset: "visibility", len: 0, typ: NTI37042, name: "visibility", sons: null}, +{kind: 1, offset: "width", len: 0, typ: NTI37042, name: "width", sons: null}, +{kind: 1, offset: "wordSpacing", len: 0, typ: NTI37042, name: "wordSpacing", sons: null}, +{kind: 1, offset: "zIndex", len: 0, typ: NTI37006, name: "zIndex", sons: null}]}; +NTI71277.node = NNI71277; +NTI71277.base = NTI41208; +NTI71275.base = NTI71277; +var NNI71225 = {kind: 2, len: 14, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "attributes", len: 0, typ: NTI71516, name: "attributes", sons: null}, +{kind: 1, offset: "childNodes", len: 0, typ: NTI71518, name: "childNodes", sons: null}, +{kind: 1, offset: "children", len: 0, typ: NTI71520, name: "children", sons: null}, +{kind: 1, offset: "data", len: 0, typ: NTI37042, name: "data", sons: null}, +{kind: 1, offset: "firstChild", len: 0, typ: NTI71223, name: "firstChild", sons: null}, +{kind: 1, offset: "lastChild", len: 0, typ: NTI71223, name: "lastChild", sons: null}, +{kind: 1, offset: "nextSibling", len: 0, typ: NTI71223, name: "nextSibling", sons: null}, +{kind: 1, offset: "nodeName", len: 0, typ: NTI37042, name: "nodeName", sons: null}, +{kind: 1, offset: "nodeType", len: 0, typ: NTI71221, name: "nodeType", sons: null}, +{kind: 1, offset: "nodeValue", len: 0, typ: NTI37042, name: "nodeValue", sons: null}, +{kind: 1, offset: "parentNode", len: 0, typ: NTI71223, name: "parentNode", sons: null}, +{kind: 1, offset: "previousSibling", len: 0, typ: NTI71223, name: "previousSibling", sons: null}, +{kind: 1, offset: "innerHTML", len: 0, typ: NTI37042, name: "innerHTML", sons: null}, +{kind: 1, offset: "style", len: 0, typ: NTI71275, name: "style", sons: null}]}; +NTI71225.node = NNI71225; +var NNI71205 = {kind: 2, len: 20, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "onabort", len: 0, typ: NTI71366, name: "onabort", sons: null}, +{kind: 1, offset: "onblur", len: 0, typ: NTI71370, name: "onblur", sons: null}, +{kind: 1, offset: "onchange", len: 0, typ: NTI71374, name: "onchange", sons: null}, +{kind: 1, offset: "onclick", len: 0, typ: NTI71378, name: "onclick", sons: null}, +{kind: 1, offset: "ondblclick", len: 0, typ: NTI71382, name: "ondblclick", sons: null}, +{kind: 1, offset: "onerror", len: 0, typ: NTI71386, name: "onerror", sons: null}, +{kind: 1, offset: "onfocus", len: 0, typ: NTI71390, name: "onfocus", sons: null}, +{kind: 1, offset: "onkeydown", len: 0, typ: NTI71394, name: "onkeydown", sons: null}, +{kind: 1, offset: "onkeypress", len: 0, typ: NTI71398, name: "onkeypress", sons: null}, +{kind: 1, offset: "onkeyup", len: 0, typ: NTI71402, name: "onkeyup", sons: null}, +{kind: 1, offset: "onload", len: 0, typ: NTI71406, name: "onload", sons: null}, +{kind: 1, offset: "onmousedown", len: 0, typ: NTI71410, name: "onmousedown", sons: null}, +{kind: 1, offset: "onmousemove", len: 0, typ: NTI71414, name: "onmousemove", sons: null}, +{kind: 1, offset: "onmouseout", len: 0, typ: NTI71418, name: "onmouseout", sons: null}, +{kind: 1, offset: "onmouseover", len: 0, typ: NTI71422, name: "onmouseover", sons: null}, +{kind: 1, offset: "onmouseup", len: 0, typ: NTI71426, name: "onmouseup", sons: null}, +{kind: 1, offset: "onreset", len: 0, typ: NTI71430, name: "onreset", sons: null}, +{kind: 1, offset: "onselect", len: 0, typ: NTI71434, name: "onselect", sons: null}, +{kind: 1, offset: "onsubmit", len: 0, typ: NTI71438, name: "onsubmit", sons: null}, +{kind: 1, offset: "onunload", len: 0, typ: NTI71442, name: "onunload", sons: null}]}; +NTI71205.node = NNI71205; +NTI71205.base = NTI41208; +NTI71225.base = NTI71205; +NTI71223.base = NTI71225; +NTI73045.base = NTI71223; +NTI182526.base = NTI37042; +var NNI41262 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI41262.node = NNI41262; +NTI41262.base = NTI41228; +var NNI180074 = {kind: 2, len: 2, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "Field0", len: 0, typ: NTI37006, name: "Field0", sons: null}, +{kind: 1, offset: "Field1", len: 0, typ: NTI37032, name: "Field1", sons: null}]}; +NTI180074.node = NNI180074; + +function makeNimstrLit(c_54391) { + var ln = c_54391.length; + var result = new Array(ln); + for (var i = 0; i < ln; ++i) { + result[i] = c_54391.charCodeAt(i); + } + return result; + + + +} + +function setConstr() { + var result = {}; + for (var i = 0; i < arguments.length; ++i) { + var x = arguments[i]; + if (typeof(x) == "object") { + for (var j = x[0]; j <= x[1]; ++j) { + result[j] = true; + } + } else { + result[x] = true; + } + } + return result; + + + +} +var ConstSet1 = setConstr(17, 16, 4, 18, 27, 19, 23, 22, 21); + +function nimCopy(dest_55427, src_55428, ti_55429) { + var result_55619 = null; + + switch (ti_55429.kind) { + case 21: + case 22: + case 23: + case 5: + if (!(is_fat_pointer_55401(ti_55429))) { + result_55619 = src_55428; + } + else { + result_55619 = [src_55428[0], src_55428[1]]; + } + + break; + case 19: + if (dest_55427 === null || dest_55427 === undefined) { + dest_55427 = {}; + } + else { + for (var key in dest_55427) { delete dest_55427[key]; } + } + for (var key in src_55428) { dest_55427[key] = src_55428[key]; } + result_55619 = dest_55427; + + break; + case 18: + case 17: + if (!((ti_55429.base == null))) { + result_55619 = nimCopy(dest_55427, src_55428, ti_55429.base); + } + else { + if ((ti_55429.kind == 17)) { + result_55619 = (dest_55427 === null || dest_55427 === undefined) ? {m_type: ti_55429} : dest_55427; + } + else { + result_55619 = (dest_55427 === null || dest_55427 === undefined) ? {} : dest_55427; + } + } + nimCopyAux(result_55619, src_55428, ti_55429.node); + break; + case 24: + case 4: + case 27: + case 16: + if (src_55428 === null) { + result_55619 = null; + } + else { + if (dest_55427 === null || dest_55427 === undefined) { + dest_55427 = new Array(src_55428.length); + } + else { + dest_55427.length = src_55428.length; + } + result_55619 = dest_55427; + for (var i = 0; i < src_55428.length; ++i) { + result_55619[i] = nimCopy(result_55619[i], src_55428[i], ti_55429.base); + } + } + + break; + case 28: + if (src_55428 !== null) { + result_55619 = src_55428.slice(0); + } + + break; + default: + result_55619 = src_55428; + break; + } + + return result_55619; + +} + +function arrayConstr(len_55671, value_55672, typ_55673) { + var result = new Array(len_55671); + for (var i = 0; i < len_55671; ++i) result[i] = nimCopy(null, value_55672, typ_55673); + return result; + + + +} + +function cstrToNimstr(c_54408) { + var ln = c_54408.length; + var result = new Array(ln); + var r = 0; + for (var i = 0; i < ln; ++i) { + var ch = c_54408.charCodeAt(i); + + if (ch < 128) { + result[r] = ch; + } + else { + if (ch < 2048) { + result[r] = (ch >> 6) | 192; + } + else { + if (ch < 55296 || ch >= 57344) { + result[r] = (ch >> 12) | 224; + } + else { + ++i; + ch = 65536 + (((ch & 1023) << 10) | (c_54408.charCodeAt(i) & 1023)); + result[r] = (ch >> 18) | 240; + ++r; + result[r] = ((ch >> 12) & 63) | 128; + } + ++r; + result[r] = ((ch >> 6) & 63) | 128; + } + ++r; + result[r] = (ch & 63) | 128; + } + ++r; + } + return result; + + + +} + +function toJSStr(s_54425) { + if (s_54425 === null) return ""; + var len = s_54425.length; + var asciiPart = new Array(len); + var fcc = String.fromCharCode; + var nonAsciiPart = null; + var nonAsciiOffset = 0; + for (var i = 0; i < len; ++i) { + if (nonAsciiPart !== null) { + var offset = (i - nonAsciiOffset) * 2; + var code = s_54425[i].toString(16); + if (code.length == 1) { + code = "0"+code; + } + nonAsciiPart[offset] = "%"; + nonAsciiPart[offset + 1] = code; + } + else if (s_54425[i] < 128) + asciiPart[i] = fcc(s_54425[i]); + else { + asciiPart.length = i; + nonAsciiOffset = i; + nonAsciiPart = new Array((len - i) * 2); + --i; + } + } + asciiPart = asciiPart.join(""); + return (nonAsciiPart === null) ? + asciiPart : asciiPart + decodeURIComponent(nonAsciiPart.join("")); + + + +} + +function raiseException(e_54018, ename_54019) { + e_54018.name = ename_54019; + if ((excHandler == 0)) { + unhandledException(e_54018); + } + + e_54018.trace = nimCopy(null, raw_write_stack_trace_53838(), NTI37040); + throw e_54018; + + +} + +function addInt(a_54803, b_54804) { + var result = a_54803 + b_54804; + if (result > 2147483647 || result < -2147483648) raiseOverflow(); + return result; + + + +} + +function chckIndx(i_55690, a_55691, b_55692) { + var Tmp1; + + var result_55693 = 0; + + BeforeRet: do { + if (!(a_55691 <= i_55690)) Tmp1 = false; else { Tmp1 = (i_55690 <= b_55692); } if (Tmp1) { + result_55693 = i_55690; + break BeforeRet; + } + else { + raiseIndexError(); + } + + } while (false); + + return result_55693; + +} + +function subInt(a_54821, b_54822) { + var result = a_54821 - b_54822; + if (result > 2147483647 || result < -2147483648) raiseOverflow(); + return result; + + + +} +var ConstSet2 = setConstr([65, 90]); + +function chckRange(i_55709, a_55710, b_55711) { + var Tmp1; + + var result_55712 = 0; + + BeforeRet: do { + if (!(a_55710 <= i_55709)) Tmp1 = false; else { Tmp1 = (i_55709 <= b_55711); } if (Tmp1) { + result_55712 = i_55709; + break BeforeRet; + } + else { + raiseRangeError(); + } + + } while (false); + + return result_55712; + +} +var ConstSet3 = setConstr(95, 32, 46); +var ConstSet4 = setConstr(95, 32, 46); + +function mulInt(a_54839, b_54840) { + var result = a_54839 * b_54840; + if (result > 2147483647 || result < -2147483648) raiseOverflow(); + return result; + + + +} +var ConstSet5 = setConstr([97, 122]); +var ConstSet6 = setConstr([65, 90], [97, 122]); +var ConstSet7 = setConstr([97, 122]); +var ConstSet8 = setConstr([65, 90]); + +function nimMax(a_55158, b_55159) { + var Tmp1; + + var result_55160 = 0; + + BeforeRet: do { + if ((b_55159 <= a_55158)) { + Tmp1 = a_55158; + } + else { + Tmp1 = b_55159; + } + + result_55160 = Tmp1; + break BeforeRet; + } while (false); + + return result_55160; + +} + +function nimMin(a_55140, b_55141) { + var Tmp1; + + var result_55142 = 0; + + BeforeRet: do { + if ((a_55140 <= b_55141)) { + Tmp1 = a_55140; + } + else { + Tmp1 = b_55141; + } + + result_55142 = Tmp1; + break BeforeRet; + } while (false); + + return result_55142; + +} +var nim_program_result = 0; +var global_raise_hook_51418 = [null]; +var local_raise_hook_51423 = [null]; +var out_of_mem_hook_51426 = [null]; + if (!Math.trunc) { + Math.trunc = function(v) { + v = +v; + if (!isFinite(v)) return v; + + return (v - v % 1) || (v < 0 ? -0 : v === 0 ? v : 0); + }; + } +var alternative_182285 = [null]; + +function is_fat_pointer_55401(ti_55403) { + var result_55404 = false; + + BeforeRet: do { + result_55404 = !((ConstSet1[ti_55403.base.kind] != undefined)); + break BeforeRet; + } while (false); + + return result_55404; + +} + +function nimCopyAux(dest_55432, src_55433, n_55435) { + switch (n_55435.kind) { + case 0: + break; + case 1: + dest_55432[n_55435.offset] = nimCopy(dest_55432[n_55435.offset], src_55433[n_55435.offset], n_55435.typ); + + break; + case 2: + for (var i = 0; i < n_55435.sons.length; i++) { + nimCopyAux(dest_55432, src_55433, n_55435.sons[i]); + } + + break; + case 3: + dest_55432[n_55435.offset] = nimCopy(dest_55432[n_55435.offset], src_55433[n_55435.offset], n_55435.typ); + for (var i = 0; i < n_55435.sons.length; ++i) { + nimCopyAux(dest_55432, src_55433, n_55435.sons[i][1]); + } + + break; + } + + +} + +function add_51438(x_51441, x_51441_Idx, y_51442) { + if (x_51441[x_51441_Idx] === null) { x_51441[x_51441_Idx] = []; } + var off = x_51441[x_51441_Idx].length; + x_51441[x_51441_Idx].length += y_51442.length; + for (var i = 0; i < y_51442.length; ++i) { + x_51441[x_51441_Idx][off+i] = y_51442.charCodeAt(i); + } + + + +} + +function aux_write_stack_trace_53536(f_53538) { + var Tmp3; + + var result_53539 = [null]; + + var it_53547 = f_53538; + var i_53549 = 0; + var total_53551 = 0; + var temp_frames_53558 = arrayConstr(64, {Field0: null, Field1: 0}, NTI53541); + L1: do { + L2: while (true) { + if (!!((it_53547 == null))) Tmp3 = false; else { Tmp3 = (i_53549 <= 63); } if (!Tmp3) break L2; + temp_frames_53558[i_53549].Field0 = it_53547.procname; + temp_frames_53558[i_53549].Field1 = it_53547.line; + i_53549 += 1; + total_53551 += 1; + it_53547 = it_53547.prev; + } + } while(false); + L4: do { + L5: while (true) { + if (!!((it_53547 == null))) break L5; + total_53551 += 1; + it_53547 = it_53547.prev; + } + } while(false); + result_53539[0] = nimCopy(null, [], NTI37040); + if (!((total_53551 == i_53549))) { + if (result_53539[0] != null) { result_53539[0] = (result_53539[0]).concat(makeNimstrLit("(")); } else { result_53539[0] = makeNimstrLit("("); }; + if (result_53539[0] != null) { result_53539[0] = (result_53539[0]).concat(cstrToNimstr(((total_53551 - i_53549))+"")); } else { result_53539[0] = cstrToNimstr(((total_53551 - i_53549))+"").slice(); }; + if (result_53539[0] != null) { result_53539[0] = (result_53539[0]).concat(makeNimstrLit(" calls omitted) ...\x0A")); } else { result_53539[0] = makeNimstrLit(" calls omitted) ...\x0A"); }; + } + + L6: do { + var j_53821 = 0; + var colontmp__182426 = 0; + colontmp__182426 = (i_53549 - 1); + var res_182431 = colontmp__182426; + L7: do { + L8: while (true) { + if (!(0 <= res_182431)) break L8; + j_53821 = res_182431; + add_51438(result_53539, 0, temp_frames_53558[j_53821].Field0); + if ((0 < temp_frames_53558[j_53821].Field1)) { + if (result_53539[0] != null) { result_53539[0] = (result_53539[0]).concat(makeNimstrLit(", line: ")); } else { result_53539[0] = makeNimstrLit(", line: "); }; + if (result_53539[0] != null) { result_53539[0] = (result_53539[0]).concat(cstrToNimstr((temp_frames_53558[j_53821].Field1)+"")); } else { result_53539[0] = cstrToNimstr((temp_frames_53558[j_53821].Field1)+"").slice(); }; + } + + if (result_53539[0] != null) { result_53539[0] = (result_53539[0]).concat(makeNimstrLit("\x0A")); } else { result_53539[0] = makeNimstrLit("\x0A"); }; + res_182431 -= 1; + } + } while(false); + } while(false); + + return result_53539[0]; + +} + +function raw_write_stack_trace_53838() { + var result_53840 = null; + + if (!((framePtr == null))) { + result_53840 = nimCopy(null, (makeNimstrLit("Traceback (most recent call last)\x0A") || []).concat(aux_write_stack_trace_53536(framePtr) || []), NTI37040); + } + else { + result_53840 = nimCopy(null, makeNimstrLit("No stack traceback available\x0A"), NTI37040); + } + + + return result_53840; + +} + +function unhandledException(e_53899) { + var buf_53900 = [[]]; + if (!(((e_53899.message != null ? e_53899.message.length : 0) == 0))) { + if (buf_53900[0] != null) { buf_53900[0] = (buf_53900[0]).concat(makeNimstrLit("Error: unhandled exception: ")); } else { buf_53900[0] = makeNimstrLit("Error: unhandled exception: "); }; + if (buf_53900[0] != null) { buf_53900[0] = (buf_53900[0]).concat(e_53899.message); } else { buf_53900[0] = e_53899.message.slice(); }; + } + else { + if (buf_53900[0] != null) { buf_53900[0] = (buf_53900[0]).concat(makeNimstrLit("Error: unhandled exception")); } else { buf_53900[0] = makeNimstrLit("Error: unhandled exception"); }; + } + + if (buf_53900[0] != null) { buf_53900[0] = (buf_53900[0]).concat(makeNimstrLit(" [")); } else { buf_53900[0] = makeNimstrLit(" ["); }; + add_51438(buf_53900, 0, e_53899.name); + if (buf_53900[0] != null) { buf_53900[0] = (buf_53900[0]).concat(makeNimstrLit("]\x0A")); } else { buf_53900[0] = makeNimstrLit("]\x0A"); }; + if (buf_53900[0] != null) { buf_53900[0] = (buf_53900[0]).concat(raw_write_stack_trace_53838()); } else { buf_53900[0] = raw_write_stack_trace_53838().slice(); }; + var cbuf_54001 = toJSStr(buf_53900[0]); + framePtr = null; + if (typeof(Error) !== "undefined") { + throw new Error(cbuf_54001); + } + else { + throw cbuf_54001; + } + + + +} + +function raiseOverflow() { + var e_54252 = null; + e_54252 = {m_type: NTI41246, parent: null, name: null, message: null, trace: null, raiseId: 0, up: null}; + e_54252.message = nimCopy(null, makeNimstrLit("over- or underflow"), NTI37040); + e_54252.parent = null; + raiseException(e_54252, "OverflowError"); + + +} + +function is_whitespace_181639(text_181641) { + return !/[^\s]/.test(text_181641); + + + +} + +function is_whitespace_181656(x_181658) { + var Tmp1; + var Tmp2; + + var result_181659 = false; + + var F={procname:"dochack.isWhitespace",prev:framePtr,filename:"dochack.nim",line:0}; + framePtr = F; + F.line = 134; + if (!(x_181658.nodeName == "#text")) Tmp2 = false; else { Tmp2 = is_whitespace_181639(x_181658.textContent); } if (Tmp2) Tmp1 = true; else { Tmp1 = (x_181658.nodeName == "#comment"); } result_181659 = Tmp1; + framePtr = F.prev; + + return result_181659; + +} + +function raiseIndexError() { + var e_54327 = null; + e_54327 = {m_type: NTI41258, parent: null, name: null, message: null, trace: null, raiseId: 0, up: null}; + e_54327.message = nimCopy(null, makeNimstrLit("index out of bounds"), NTI37040); + e_54327.parent = null; + raiseException(e_54327, "IndexError"); + + +} + +function to_toc_181673(x_181675, father_181676) { + var Tmp5; + var Tmp6; + var Tmp7; + var Tmp8; + var Tmp15; + + var F={procname:"dochack.toToc",prev:framePtr,filename:"dochack.nim",line:0}; + framePtr = F; + if ((x_181675.nodeName == "UL")) { + F.line = 139; + var f_181695 = {heading: null, kids: [], sortId: (father_181676.kids != null ? father_181676.kids.length : 0), doSort: false}; + F.line = 140; + var i_181697 = 0; + L1: do { + F.line = 141; + L2: while (true) { + if (!(i_181697 < x_181675.childNodes.length)) break L2; + F.line = 142; + var nxt_181698 = addInt(i_181697, 1); + L3: do { + F.line = 143; + L4: while (true) { + if (!(nxt_181698 < x_181675.childNodes.length)) Tmp5 = false; else { Tmp5 = is_whitespace_181656(x_181675.childNodes[nxt_181698]); } if (!Tmp5) break L4; + F.line = 144; + nxt_181698 = addInt(nxt_181698, 1); + } + } while(false); + if (!(nxt_181698 < x_181675.childNodes.length)) Tmp8 = false; else { Tmp8 = (x_181675.childNodes[i_181697].nodeName == "LI"); } if (!Tmp8) Tmp7 = false; else { Tmp7 = (x_181675.childNodes[i_181697].childNodes.length == 1); } if (!Tmp7) Tmp6 = false; else { Tmp6 = (x_181675.childNodes[nxt_181698].nodeName == "UL"); } if (Tmp6) { + F.line = 147; + var e_181723 = {heading: x_181675.childNodes[i_181697].childNodes[0], kids: [], sortId: (f_181695.kids != null ? f_181695.kids.length : 0), doSort: false}; + F.line = 148; + var it_181724 = x_181675.childNodes[nxt_181698]; + L9: do { + F.line = 149; + var j_181731 = 0; + F.line = 3055; + var colontmp__182402 = 0; + F.line = 149; + colontmp__182402 = it_181724.childNodes.length; + F.line = 3056; + var i_182403 = 0; + L10: do { + F.line = 3057; + L11: while (true) { + if (!(i_182403 < colontmp__182402)) break L11; + F.line = 149; + j_181731 = i_182403; + F.line = 150; + to_toc_181673(it_181724.childNodes[j_181731], e_181723); + F.line = 3059; + i_182403 = addInt(i_182403, 1); + } + } while(false); + } while(false); + F.line = 151; + if (f_181695.kids != null) { f_181695.kids.push(e_181723); } else { f_181695.kids = [e_181723]; }; + F.line = 152; + i_181697 = addInt(nxt_181698, 1); + } + else { + F.line = 154; + to_toc_181673(x_181675.childNodes[i_181697], f_181695); + F.line = 155; + i_181697 = addInt(i_181697, 1); + } + + } + } while(false); + F.line = 156; + if (father_181676.kids != null) { father_181676.kids.push(f_181695); } else { father_181676.kids = [f_181695]; }; + } + else { + if (is_whitespace_181656(x_181675)) { + } + else { + if ((x_181675.nodeName == "LI")) { + F.line = 160; + var idx_181766 = []; + L12: do { + F.line = 161; + var i_181773 = 0; + F.line = 3055; + var colontmp__182407 = 0; + F.line = 161; + colontmp__182407 = x_181675.childNodes.length; + F.line = 3056; + var i_182408 = 0; + L13: do { + F.line = 3057; + L14: while (true) { + if (!(i_182408 < colontmp__182407)) break L14; + F.line = 161; + i_181773 = i_182408; + if (!(is_whitespace_181656(x_181675.childNodes[i_181773]))) { + F.line = 162; + if (idx_181766 != null) { idx_181766.push(i_181773); } else { idx_181766 = [i_181773]; }; + } + + F.line = 3059; + i_182408 = addInt(i_182408, 1); + } + } while(false); + } while(false); + if (!((idx_181766 != null ? idx_181766.length : 0) == 2)) Tmp15 = false; else { Tmp15 = (x_181675.childNodes[idx_181766[chckIndx(1, 0, idx_181766.length+0-1)-0]].nodeName == "UL"); } if (Tmp15) { + F.line = 164; + var e_181804 = {heading: x_181675.childNodes[idx_181766[chckIndx(0, 0, idx_181766.length+0-1)-0]], kids: [], sortId: (father_181676.kids != null ? father_181676.kids.length : 0), doSort: false}; + F.line = 166; + var it_181805 = x_181675.childNodes[idx_181766[chckIndx(1, 0, idx_181766.length+0-1)-0]]; + L16: do { + F.line = 167; + var j_181812 = 0; + F.line = 3055; + var colontmp__182413 = 0; + F.line = 167; + colontmp__182413 = it_181805.childNodes.length; + F.line = 3056; + var i_182414 = 0; + L17: do { + F.line = 3057; + L18: while (true) { + if (!(i_182414 < colontmp__182413)) break L18; + F.line = 167; + j_181812 = i_182414; + F.line = 168; + to_toc_181673(it_181805.childNodes[j_181812], e_181804); + F.line = 3059; + i_182414 = addInt(i_182414, 1); + } + } while(false); + } while(false); + F.line = 169; + if (father_181676.kids != null) { father_181676.kids.push(e_181804); } else { father_181676.kids = [e_181804]; }; + } + else { + L19: do { + F.line = 171; + var i_181826 = 0; + F.line = 3055; + var colontmp__182418 = 0; + F.line = 171; + colontmp__182418 = x_181675.childNodes.length; + F.line = 3056; + var i_182419 = 0; + L20: do { + F.line = 3057; + L21: while (true) { + if (!(i_182419 < colontmp__182418)) break L21; + F.line = 171; + i_181826 = i_182419; + F.line = 172; + to_toc_181673(x_181675.childNodes[i_181826], father_181676); + F.line = 3059; + i_182419 = addInt(i_182419, 1); + } + } while(false); + } while(false); + } + + } + else { + F.line = 174; + if (father_181676.kids != null) { father_181676.kids.push({heading: x_181675, kids: [], sortId: (father_181676.kids != null ? father_181676.kids.length : 0), doSort: false}); } else { father_181676.kids = [{heading: x_181675, kids: [], sortId: (father_181676.kids != null ? father_181676.kids.length : 0), doSort: false}]; }; + } + }} + framePtr = F.prev; + + +} + +function extract_items_181307(x_181309, heading_181310, items_181313, items_181313_Idx) { + var Tmp1; + + var F={procname:"dochack.extractItems",prev:framePtr,filename:"dochack.nim",line:0}; + framePtr = F; + BeforeRet: do { + if ((x_181309 == null)) { + F.line = 81; + break BeforeRet; + } + + if (!!((x_181309.heading == null))) Tmp1 = false; else { Tmp1 = (x_181309.heading.textContent == heading_181310); } if (Tmp1) { + L2: do { + F.line = 83; + var i_181341 = 0; + F.line = 3055; + var colontmp__182437 = 0; + F.line = 83; + colontmp__182437 = (x_181309.kids != null ? x_181309.kids.length : 0); + F.line = 3056; + var i_182438 = 0; + L3: do { + F.line = 3057; + L4: while (true) { + if (!(i_182438 < colontmp__182437)) break L4; + F.line = 83; + i_181341 = i_182438; + F.line = 84; + if (items_181313[items_181313_Idx] != null) { items_181313[items_181313_Idx].push(x_181309.kids[chckIndx(i_181341, 0, x_181309.kids.length+0-1)-0].heading); } else { items_181313[items_181313_Idx] = [x_181309.kids[chckIndx(i_181341, 0, x_181309.kids.length+0-1)-0].heading]; }; + F.line = 3059; + i_182438 = addInt(i_182438, 1); + } + } while(false); + } while(false); + } + else { + L5: do { + F.line = 86; + var i_181360 = 0; + F.line = 3055; + var colontmp__182442 = 0; + F.line = 86; + colontmp__182442 = (x_181309.kids != null ? x_181309.kids.length : 0); + F.line = 3056; + var i_182443 = 0; + L6: do { + F.line = 3057; + L7: while (true) { + if (!(i_182443 < colontmp__182442)) break L7; + F.line = 86; + i_181360 = i_182443; + F.line = 87; + var it_181361 = x_181309.kids[chckIndx(i_181360, 0, x_181309.kids.length+0-1)-0]; + F.line = 88; + extract_items_181307(it_181361, heading_181310, items_181313, items_181313_Idx); + F.line = 3059; + i_182443 = addInt(i_182443, 1); + } + } while(false); + } while(false); + } + + } while (false); + framePtr = F.prev; + + +} + +function tree_181020(tag_181022, kids_181024) { + var result_181025 = null; + + var F={procname:"dochack.tree",prev:framePtr,filename:"dochack.nim",line:0}; + framePtr = F; + F.line = 11; + result_181025 = document.createElement(toJSStr(tag_181022)); + L1: do { + F.line = 12; + var k_181056 = null; + F.line = 2309; + var i_182460 = 0; + L2: do { + F.line = 2310; + L3: while (true) { + if (!(i_182460 < (kids_181024 != null ? kids_181024.length : 0))) break L3; + F.line = 12; + k_181056 = kids_181024[chckIndx(i_182460, 0, kids_181024.length+0-1)-0]; + F.line = 13; + result_181025.appendChild(k_181056); + F.line = 2312; + i_182460 = addInt(i_182460, 1); + } + } while(false); + } while(false); + framePtr = F.prev; + + return result_181025; + +} + +function text_181122(s_181124) { + var result_181125 = null; + + var F={procname:"dochack.text",prev:framePtr,filename:"dochack.nim",line:0}; + framePtr = F; + F.line = 27; + result_181125 = document.createTextNode(s_181124); + framePtr = F.prev; + + return result_181125; + +} + +function sys_fatal_58236(message_58240) { + var F={procname:"sysFatal.sysFatal",prev:framePtr,filename:"..\\..\\lib\\system.nim",line:0}; + framePtr = F; + F.line = 3015; + var e_58242 = null; + F.line = 3016; + e_58242 = {m_type: NTI41250, parent: null, name: null, message: null, trace: null, raiseId: 0, up: null}; + F.line = 3017; + e_58242.message = nimCopy(null, message_58240, NTI37040); + F.line = 3018; + raiseException(e_58242, "AssertionError"); + framePtr = F.prev; + + +} + +function raise_assert_58232(msg_58234) { + var F={procname:"system.raiseAssert",prev:framePtr,filename:"..\\..\\lib\\system.nim",line:0}; + framePtr = F; + F.line = 3734; + sys_fatal_58236(msg_58234); + framePtr = F.prev; + + +} + +function failed_assert_impl_58275(msg_58277) { + var F={procname:"system.failedAssertImpl",prev:framePtr,filename:"..\\..\\lib\\system.nim",line:0}; + framePtr = F; + F.line = 3741; + raise_assert_58232(msg_58277); + framePtr = F.prev; + + +} + +function uncovered_181920(x_181922) { + var Tmp1; + var Tmp2; + + var result_181923 = null; + + var F={procname:"dochack.uncovered",prev:framePtr,filename:"dochack.nim",line:0}; + framePtr = F; + BeforeRet: do { + if (!((x_181922.kids != null ? x_181922.kids.length : 0) == 0)) Tmp1 = false; else { Tmp1 = !((x_181922.heading == null)); } if (Tmp1) { + F.line = 194; + if (!(x_181922.heading.hasOwnProperty('__karaxMarker__'))) { + Tmp2 = x_181922; + } + else { + Tmp2 = null; + } + + result_181923 = Tmp2; + break BeforeRet; + } + + F.line = 195; + result_181923 = {heading: x_181922.heading, kids: [], sortId: x_181922.sortId, doSort: x_181922.doSort}; + L3: do { + F.line = 197; + var i_181961 = 0; + F.line = 3055; + var colontmp__182472 = 0; + F.line = 197; + colontmp__182472 = (x_181922.kids != null ? x_181922.kids.length : 0); + F.line = 3056; + var i_182473 = 0; + L4: do { + F.line = 3057; + L5: while (true) { + if (!(i_182473 < colontmp__182472)) break L5; + F.line = 197; + i_181961 = i_182473; + F.line = 198; + var y_181962 = uncovered_181920(x_181922.kids[chckIndx(i_181961, 0, x_181922.kids.length+0-1)-0]); + if (!((y_181962 == null))) { + F.line = 199; + if (result_181923.kids != null) { result_181923.kids.push(y_181962); } else { result_181923.kids = [y_181962]; }; + } + + F.line = 3059; + i_182473 = addInt(i_182473, 1); + } + } while(false); + } while(false); + if (((result_181923.kids != null ? result_181923.kids.length : 0) == 0)) { + F.line = 200; + result_181923 = null; + } + + } while (false); + framePtr = F.prev; + + return result_181923; + +} + +function merge_tocs_181996(orig_181998, news_181999) { + var result_182000 = null; + + var F={procname:"dochack.mergeTocs",prev:framePtr,filename:"dochack.nim",line:0}; + framePtr = F; + F.line = 203; + result_182000 = uncovered_181920(orig_181998); + if ((result_182000 == null)) { + F.line = 205; + result_182000 = news_181999; + } + else { + L1: do { + F.line = 207; + var i_182020 = 0; + F.line = 3055; + var colontmp__182466 = 0; + F.line = 207; + colontmp__182466 = (news_181999.kids != null ? news_181999.kids.length : 0); + F.line = 3056; + var i_182467 = 0; + L2: do { + F.line = 3057; + L3: while (true) { + if (!(i_182467 < colontmp__182466)) break L3; + F.line = 207; + i_182020 = i_182467; + F.line = 208; + if (result_182000.kids != null) { result_182000.kids.push(news_181999.kids[chckIndx(i_182020, 0, news_181999.kids.length+0-1)-0]); } else { result_182000.kids = [news_181999.kids[chckIndx(i_182020, 0, news_181999.kids.length+0-1)-0]]; }; + F.line = 3059; + i_182467 = addInt(i_182467, 1); + } + } while(false); + } while(false); + } + + framePtr = F.prev; + + return result_182000; + +} + +function build_toc_182041(orig_182043, types_182045, procs_182046) { + var result_182047 = null; + + var F={procname:"dochack.buildToc",prev:framePtr,filename:"dochack.nim",line:0}; + framePtr = F; + F.line = 211; + var new_stuff_182061 = {heading: null, kids: [], doSort: true, sortId: 0}; + L1: do { + F.line = 212; + var t_182214 = null; + F.line = 3773; + var i_182455 = 0; + F.line = 3774; + var l_182456 = (types_182045 != null ? types_182045.length : 0); + L2: do { + F.line = 3775; + L3: while (true) { + if (!(i_182455 < l_182456)) break L3; + F.line = 212; + t_182214 = types_182045[chckIndx(i_182455, 0, types_182045.length+0-1)-0]; + F.line = 213; + var c_182228 = {heading: t_182214.cloneNode(true), kids: [], doSort: true, sortId: 0}; + F.line = 214; + t_182214.__karaxMarker__ = true; + L4: do { + F.line = 215; + var p_182235 = null; + F.line = 3773; + var i_182452 = 0; + F.line = 3774; + var l_182453 = (procs_182046 != null ? procs_182046.length : 0); + L5: do { + F.line = 3775; + L6: while (true) { + if (!(i_182452 < l_182453)) break L6; + F.line = 215; + p_182235 = procs_182046[chckIndx(i_182452, 0, procs_182046.length+0-1)-0]; + if (!(p_182235.hasOwnProperty('__karaxMarker__'))) { + F.line = 217; + var xx_182236 = p_182235.parentNode.getElementsByClassName("attachedType"); + if ((((xx_182236 != null ? xx_182236.length : 0) == 1) && (xx_182236[chckIndx(0, 0, xx_182236.length+0-1)-0].textContent == t_182214.textContent))) { + F.line = 220; + var q_182244 = tree_181020(makeNimstrLit("A"), [text_181122(p_182235.title)]); + F.line = 221; + q_182244.setAttribute("href", p_182235.getAttribute("href")); + F.line = 222; + if (c_182228.kids != null) { c_182228.kids.push({heading: q_182244, kids: [], sortId: 0, doSort: false}); } else { c_182228.kids = [{heading: q_182244, kids: [], sortId: 0, doSort: false}]; }; + F.line = 223; + p_182235.__karaxMarker__ = true; + } + + } + + F.line = 3777; + i_182452 = addInt(i_182452, 1); + if (!(((procs_182046 != null ? procs_182046.length : 0) == l_182453))) { + F.line = 3778; + failed_assert_impl_58275(makeNimstrLit("c:\\Users\\gt\\Desktop\\dl\\programming\\nimdevel\\lib\\system.nim(3778, 11) `len(a) == L` seq modified while iterating over it")); + } + + } + } while(false); + } while(false); + F.line = 224; + if (new_stuff_182061.kids != null) { new_stuff_182061.kids.push(c_182228); } else { new_stuff_182061.kids = [c_182228]; }; + F.line = 3777; + i_182455 = addInt(i_182455, 1); + if (!(((types_182045 != null ? types_182045.length : 0) == l_182456))) { + F.line = 3778; + failed_assert_impl_58275(makeNimstrLit("c:\\Users\\gt\\Desktop\\dl\\programming\\nimdevel\\lib\\system.nim(3778, 11) `len(a) == L` seq modified while iterating over it")); + } + + } + } while(false); + } while(false); + F.line = 225; + result_182047 = merge_tocs_181996(orig_182043, new_stuff_182061); + framePtr = F.prev; + + return result_182047; + +} + +function add_181070(parent_181072, kid_181073) { + var Tmp1; + var Tmp2; + + var F={procname:"dochack.add",prev:framePtr,filename:"dochack.nim",line:0}; + framePtr = F; + if (!(parent_181072.nodeName == "TR")) Tmp1 = false; else { if ((kid_181073.nodeName == "TD")) Tmp2 = true; else { Tmp2 = (kid_181073.nodeName == "TH"); } Tmp1 = Tmp2; } if (Tmp1) { + F.line = 18; + var k_181074 = document.createElement("TD"); + F.line = 19; + k_181074.appendChild(kid_181073); + F.line = 20; + parent_181072.appendChild(k_181074); + } + else { + F.line = 22; + parent_181072.appendChild(kid_181073); + } + + framePtr = F.prev; + + +} + +function set_class_181088(e_181090, value_181091) { + var F={procname:"dochack.setClass",prev:framePtr,filename:"dochack.nim",line:0}; + framePtr = F; + F.line = 25; + e_181090.setAttribute("class", toJSStr(value_181091)); + framePtr = F.prev; + + +} + +function to_html_181375(x_181377, is_root_181378) { + var Tmp1; + + function HEX3Aanonymous_181418(a_181420, b_181421) { + var Tmp1; + + var result_181422 = 0; + + var F={procname:"toHtml.:anonymous",prev:framePtr,filename:"dochack.nim",line:0}; + framePtr = F; + BeforeRet: do { + if (!!((a_181420.heading == null))) Tmp1 = false; else { Tmp1 = !((b_181421.heading == null)); } if (Tmp1) { + F.line = 106; + var x_181439 = a_181420.heading.textContent; + F.line = 107; + var y_181440 = b_181421.heading.textContent; + if ((x_181439 < y_181440)) { + F.line = 108; + result_181422 = -1; + break BeforeRet; + } + + if ((y_181440 < x_181439)) { + F.line = 109; + result_181422 = 1; + break BeforeRet; + } + + F.line = 110; + result_181422 = 0; + break BeforeRet; + } + else { + F.line = 113; + result_181422 = subInt(a_181420.sortId, b_181421.sortId); + break BeforeRet; + } + + } while (false); + framePtr = F.prev; + + return result_181422; + + } + + var result_181379 = null; + + var F={procname:"dochack.toHtml",prev:framePtr,filename:"dochack.nim",line:0}; + framePtr = F; + BeforeRet: do { + if ((x_181377 == null)) { + F.line = 91; + result_181379 = null; + break BeforeRet; + } + + if (((x_181377.kids != null ? x_181377.kids.length : 0) == 0)) { + if ((x_181377.heading == null)) { + F.line = 93; + result_181379 = null; + break BeforeRet; + } + + F.line = 94; + result_181379 = x_181377.heading.cloneNode(true); + break BeforeRet; + } + + F.line = 95; + result_181379 = tree_181020(makeNimstrLit("DIV"), []); + if (!!((x_181377.heading == null))) Tmp1 = false; else { Tmp1 = !(x_181377.heading.hasOwnProperty('__karaxMarker__')); } if (Tmp1) { + F.line = 97; + add_181070(result_181379, x_181377.heading.cloneNode(true)); + } + + F.line = 98; + var ul_181415 = tree_181020(makeNimstrLit("UL"), []); + if (is_root_181378) { + F.line = 100; + set_class_181088(ul_181415, makeNimstrLit("simple simple-toc")); + } + else { + F.line = 102; + set_class_181088(ul_181415, makeNimstrLit("simple")); + } + + if (x_181377.doSort) { + F.line = 104; + x_181377.kids.sort(HEX3Aanonymous_181418); + } + + L2: do { + F.line = 115; + var k_181614 = null; + F.line = 3771; + var colontmp__182479 = null; + F.line = 115; + colontmp__182479 = x_181377.kids; + F.line = 3773; + var i_182481 = 0; + F.line = 3774; + var l_182482 = (colontmp__182479 != null ? colontmp__182479.length : 0); + L3: do { + F.line = 3775; + L4: while (true) { + if (!(i_182481 < l_182482)) break L4; + F.line = 115; + k_181614 = colontmp__182479[chckIndx(i_182481, 0, colontmp__182479.length+0-1)-0]; + F.line = 116; + var y_181615 = to_html_181375(k_181614, false); + if (!((y_181615 == null))) { + F.line = 118; + add_181070(ul_181415, tree_181020(makeNimstrLit("LI"), [y_181615])); + } + + F.line = 3777; + i_182481 = addInt(i_182481, 1); + if (!(((colontmp__182479 != null ? colontmp__182479.length : 0) == l_182482))) { + F.line = 3778; + failed_assert_impl_58275(makeNimstrLit("c:\\Users\\gt\\Desktop\\dl\\programming\\nimdevel\\lib\\system.nim(3778, 11) `len(a) == L` seq modified while iterating over it")); + } + + } + } while(false); + } while(false); + if (!((ul_181415.childNodes.length == 0))) { + F.line = 119; + add_181070(result_181379, ul_181415); + } + + if ((result_181379.childNodes.length == 0)) { + F.line = 120; + result_181379 = null; + } + + } while (false); + framePtr = F.prev; + + return result_181379; + +} + +function replace_by_id_181142(id_181144, new_tree_181145) { + var F={procname:"dochack.replaceById",prev:framePtr,filename:"dochack.nim",line:0}; + framePtr = F; + F.line = 32; + var x_181146 = document.getElementById(id_181144); + F.line = 33; + x_181146.parentNode.replaceChild(new_tree_181145, x_181146); + F.line = 34; + new_tree_181145.id = id_181144; + framePtr = F.prev; + + +} + +function togglevis_182299(d_182301) { + var F={procname:"dochack.togglevis",prev:framePtr,filename:"dochack.nim",line:0}; + framePtr = F; + F.line = 230; + if (d_182301.style.display == 'none') + d_182301.style.display = 'inline'; + else + d_182301.style.display = 'none'; + + framePtr = F.prev; + + +} + +function groupBy(value_182317) { + var F={procname:"dochack.groupBy",prev:framePtr,filename:"dochack.nim",line:0}; + framePtr = F; + F.line = 238; + var toc_182318 = document.getElementById("toc-list"); + if ((alternative_182285[0] == null)) { + F.line = 240; + var tt_182337 = {heading: null, kids: [], sortId: 0, doSort: false}; + F.line = 241; + to_toc_181673(toc_182318, tt_182337); + F.line = 242; + tt_182337 = tt_182337.kids[chckIndx(0, 0, tt_182337.kids.length+0-1)-0]; + F.line = 244; + var types_182352 = [[]]; + F.line = 245; + var procs_182367 = [[]]; + F.line = 247; + extract_items_181307(tt_182337, "Types", types_182352, 0); + F.line = 248; + extract_items_181307(tt_182337, "Procs", procs_182367, 0); + F.line = 249; + extract_items_181307(tt_182337, "Converters", procs_182367, 0); + F.line = 250; + extract_items_181307(tt_182337, "Methods", procs_182367, 0); + F.line = 251; + extract_items_181307(tt_182337, "Templates", procs_182367, 0); + F.line = 252; + extract_items_181307(tt_182337, "Macros", procs_182367, 0); + F.line = 253; + extract_items_181307(tt_182337, "Iterators", procs_182367, 0); + F.line = 255; + var ntoc_182375 = build_toc_182041(tt_182337, types_182352[0], procs_182367[0]); + F.line = 256; + var x_182376 = to_html_181375(ntoc_182375, true); + F.line = 257; + alternative_182285[0] = tree_181020(makeNimstrLit("DIV"), [x_182376]); + } + + if ((value_182317 == "type")) { + F.line = 259; + replace_by_id_181142("tocRoot", alternative_182285[0]); + } + else { + F.line = 261; + replace_by_id_181142("tocRoot", tree_181020(makeNimstrLit("DIV"), [])); + } + + F.line = 262; + togglevis_182299(document.getElementById("toc-list")); + framePtr = F.prev; + + +} +var db_182485 = [null]; +var contents_182487 = [null]; +var oldtoc_182742 = [null]; +var timer_182743 = [null]; + +function raiseRangeError() { + var e_54302 = null; + e_54302 = {m_type: NTI41262, parent: null, name: null, message: null, trace: null, raiseId: 0, up: null}; + e_54302.message = nimCopy(null, makeNimstrLit("value out of range"), NTI37040); + e_54302.parent = null; + raiseException(e_54302, "RangeError"); + + +} + +function nsuToLowerAsciiChar(c_171980) { + var result_171981 = 0; + + var F={procname:"strutils.toLowerAscii",prev:framePtr,filename:"..\\..\\lib\\pure\\strutils.nim",line:0}; + framePtr = F; + if ((ConstSet2[c_171980] != undefined)) { + F.line = 222; + result_171981 = chckRange(addInt(c_171980, 32), 0, 255); + } + else { + F.line = 224; + result_171981 = c_171980; + } + + framePtr = F.prev; + + return result_171981; + +} + +function fuzzy_match_180070(pattern_180072, str_180073) { + var Tmp4; + var Tmp5; + var Tmp6; + + var result_180077 = {Field0: 0, Field1: false}; + + var F={procname:"fuzzysearch.fuzzyMatch",prev:framePtr,filename:"fuzzysearch.nim",line:0}; + framePtr = F; + F.line = 37; + var score_state_180078 = -100; + F.line = 38; + var header_matched_180079 = false; + F.line = 39; + var unmatched_leading_char_count_180081 = 0; + F.line = 40; + var consecutive_match_count_180083 = 0; + F.line = 41; + var str_index_180085 = 0; + F.line = 42; + var pat_index_180087 = 0; + F.line = 43; + var score_180089 = 0; + L1: do { + F.line = 49; + L2: while (true) { + if (!((str_index_180085 < (str_180073 != null ? str_180073.length : 0)) && (pat_index_180087 < (pattern_180072 != null ? pattern_180072.length : 0)))) break L2; + L3: do { + F.line = 51; + var pattern_char_180096 = nsuToLowerAsciiChar(pattern_180072.charCodeAt(chckIndx(pat_index_180087, 0, pattern_180072.length+0-1)-0)); + F.line = 52; + var str_char_180097 = nsuToLowerAsciiChar(str_180073.charCodeAt(chckIndx(str_index_180085, 0, str_180073.length+0-1)-0)); + if ((ConstSet3[pattern_char_180096] != undefined)) { + F.line = 56; + pat_index_180087 = addInt(pat_index_180087, 1); + F.line = 57; + break L3; + } + + if ((ConstSet4[str_char_180097] != undefined)) { + F.line = 59; + str_index_180085 = addInt(str_index_180085, 1); + F.line = 60; + break L3; + } + + if ((!(header_matched_180079) && (str_char_180097 == 58))) { + F.line = 65; + header_matched_180079 = true; + F.line = 66; + score_state_180078 = -100; + F.line = 67; + score_180089 = Math.trunc(Math.floor((5.0000000000000000e-001 * score_180089))); + F.line = 68; + pat_index_180087 = 0; + F.line = 69; + str_index_180085 = addInt(str_index_180085, 1); + F.line = 70; + break L3; + } + + if ((str_char_180097 == pattern_char_180096)) { + F.line = 73; + switch (score_state_180078) { + case -100: + case 20: + F.line = 75; + score_state_180078 = 10; + break; + case 0: + F.line = 78; + score_state_180078 = 5; + F.line = 78; + score_180089 = addInt(score_180089, score_state_180078); + break; + case 10: + case 5: + F.line = 81; + consecutive_match_count_180083 = addInt(consecutive_match_count_180083, 1); + F.line = 82; + score_state_180078 = 5; + F.line = 83; + score_180089 = addInt(score_180089, mulInt(5, consecutive_match_count_180083)); + if ((score_state_180078 == 10)) { + F.line = 86; + score_180089 = addInt(score_180089, 10); + } + + F.line = 88; + var on_boundary_180172 = (pat_index_180087 == (pattern_180072 != null ? (pattern_180072.length-1) : -1)); + if ((!(on_boundary_180172) && (str_index_180085 < (str_180073 != null ? (str_180073.length-1) : -1)))) { + F.line = 91; + var next_pattern_char_180173 = nsuToLowerAsciiChar(pattern_180072.charCodeAt(chckIndx(addInt(pat_index_180087, 1), 0, pattern_180072.length+0-1)-0)); + F.line = 92; + var next_str_char_180174 = nsuToLowerAsciiChar(str_180073.charCodeAt(chckIndx(addInt(str_index_180085, 1), 0, str_180073.length+0-1)-0)); + F.line = 95; + if (!!((ConstSet5[next_str_char_180174] != undefined))) Tmp4 = false; else { Tmp4 = !((next_str_char_180174 == next_pattern_char_180173)); } on_boundary_180172 = Tmp4; + } + + if (on_boundary_180172) { + F.line = 100; + score_state_180078 = 20; + F.line = 100; + score_180089 = addInt(score_180089, score_state_180078); + } + + break; + case -1: + case -3: + F.line = 103; + if (!((ConstSet6[str_180073.charCodeAt(chckIndx(subInt(str_index_180085, 1), 0, str_180073.length+0-1)-0)] != undefined))) Tmp5 = true; else { if (!(ConstSet7[str_180073.charCodeAt(chckIndx(subInt(str_index_180085, 1), 0, str_180073.length+0-1)-0)] != undefined)) Tmp6 = false; else { Tmp6 = (ConstSet8[str_180073.charCodeAt(chckIndx(str_index_180085, 0, str_180073.length+0-1)-0)] != undefined); } Tmp5 = Tmp6; } var is_leading_char_180212 = Tmp5; + if (is_leading_char_180212) { + F.line = 110; + score_state_180078 = 10; + } + else { + F.line = 114; + score_state_180078 = 0; + F.line = 114; + score_180089 = addInt(score_180089, score_state_180078); + } + + break; + } + F.line = 115; + pat_index_180087 = addInt(pat_index_180087, 1); + } + else { + F.line = 118; + switch (score_state_180078) { + case -100: + F.line = 120; + score_state_180078 = -3; + F.line = 120; + score_180089 = addInt(score_180089, score_state_180078); + break; + case 5: + F.line = 123; + score_state_180078 = -1; + F.line = 123; + score_180089 = addInt(score_180089, score_state_180078); + F.line = 124; + consecutive_match_count_180083 = 0; + break; + case -3: + if ((unmatched_leading_char_count_180081 < 3)) { + F.line = 128; + score_state_180078 = -3; + F.line = 128; + score_180089 = addInt(score_180089, score_state_180078); + } + + F.line = 129; + unmatched_leading_char_count_180081 = addInt(unmatched_leading_char_count_180081, 1); + break; + default: + F.line = 132; + score_state_180078 = -1; + F.line = 132; + score_180089 = addInt(score_180089, score_state_180078); + break; + } + } + + F.line = 134; + str_index_180085 = addInt(str_index_180085, 1); + } while(false); + } + } while(false); + F.line = 136; + nimCopy(result_180077, {Field0: nimMax(0, score_180089), Field1: (0 < score_180089)}, NTI180074); + framePtr = F.prev; + + return result_180077; + +} + +function text_181105(s_181107) { + var result_181108 = null; + + var F={procname:"dochack.text",prev:framePtr,filename:"dochack.nim",line:0}; + framePtr = F; + F.line = 26; + result_181108 = document.createTextNode(toJSStr(s_181107)); + framePtr = F.prev; + + return result_181108; + +} + +function dosearch_182504(value_182506) { + + function HEX3Aanonymous_182670(a_182679, b_182680) { + var result_182684 = 0; + + var F={procname:"dosearch.:anonymous",prev:framePtr,filename:"dochack.nim",line:0}; + framePtr = F; + F.line = 305; + result_182684 = subInt(b_182680["Field1"], a_182679["Field1"]); + framePtr = F.prev; + + return result_182684; + + } + + var result_182507 = null; + + var F={procname:"dochack.dosearch",prev:framePtr,filename:"dochack.nim",line:0}; + framePtr = F; + if (((db_182485[0] != null ? db_182485[0].length : 0) == 0)) { + F.line = 272; + var stuff_182513 = null; + F.line = 273; + var request = new XMLHttpRequest(); + request.open("GET", "theindex.html", false); + request.send(null); + + var doc = document.implementation.createHTMLDocument("theindex"); + doc.documentElement.innerHTML = request.responseText; + + //parser=new DOMParser(); + //doc=parser.parseFromString("", "text/html"); + + stuff_182513 = doc.documentElement; + + F.line = 286; + db_182485[0] = nimCopy(null, stuff_182513.getElementsByClassName("reference"), NTI73045); + F.line = 287; + contents_182487[0] = nimCopy(null, [], NTI182526); + L1: do { + F.line = 288; + var ahref_182614 = null; + F.line = 3773; + var i_182811 = 0; + F.line = 3774; + var l_182812 = (db_182485[0] != null ? db_182485[0].length : 0); + L2: do { + F.line = 3775; + L3: while (true) { + if (!(i_182811 < l_182812)) break L3; + F.line = 288; + ahref_182614 = db_182485[0][chckIndx(i_182811, 0, db_182485[0].length+0-1)-0]; + F.line = 289; + if (contents_182487[0] != null) { contents_182487[0].push(ahref_182614.getAttribute("data-doc-search-tag")); } else { contents_182487[0] = [ahref_182614.getAttribute("data-doc-search-tag")]; }; + F.line = 3777; + i_182811 = addInt(i_182811, 1); + if (!(((db_182485[0] != null ? db_182485[0].length : 0) == l_182812))) { + F.line = 3778; + failed_assert_impl_58275(makeNimstrLit("c:\\Users\\gt\\Desktop\\dl\\programming\\nimdevel\\lib\\system.nim(3778, 11) `len(a) == L` seq modified while iterating over it")); + } + + } + } while(false); + } while(false); + } + + F.line = 290; + var ul_182625 = tree_181020(makeNimstrLit("UL"), []); + F.line = 291; + result_182507 = tree_181020(makeNimstrLit("DIV"), []); + F.line = 292; + set_class_181088(result_182507, makeNimstrLit("search_results")); + F.line = 293; + var matches_182644 = []; + L4: do { + F.line = 294; + var i_182656 = 0; + F.line = 3055; + var colontmp__182818 = 0; + F.line = 294; + colontmp__182818 = (db_182485[0] != null ? db_182485[0].length : 0); + F.line = 3056; + var i_182819 = 0; + L5: do { + F.line = 3057; + L6: while (true) { + if (!(i_182819 < colontmp__182818)) break L6; + F.line = 294; + i_182656 = i_182819; + L7: do { + F.line = 295; + var c_182657 = contents_182487[0][chckIndx(i_182656, 0, contents_182487[0].length+0-1)-0]; + if (((c_182657 == "Examples") || (c_182657 == "PEG construction"))) { + F.line = 300; + break L7; + } + + F.line = 301; + var colontmp__182828 = {Field0: 0, Field1: false}; + F.line = 301; + var score_182658 = 0; + F.line = 301; + var matched_182659 = false; + F.line = 301; + nimCopy(colontmp__182828, fuzzy_match_180070(value_182506, c_182657), NTI180074); + F.line = 301; + score_182658 = colontmp__182828["Field0"]; + F.line = 301; + matched_182659 = colontmp__182828["Field1"]; + if (matched_182659) { + F.line = 303; + if (matches_182644 != null) { matches_182644.push({Field0: db_182485[0][chckIndx(i_182656, 0, db_182485[0].length+0-1)-0], Field1: score_182658}); } else { matches_182644 = [{Field0: db_182485[0][chckIndx(i_182656, 0, db_182485[0].length+0-1)-0], Field1: score_182658}]; }; + } + + } while(false); + F.line = 3059; + i_182819 = addInt(i_182819, 1); + } + } while(false); + } while(false); + F.line = 305; + matches_182644.sort(HEX3Aanonymous_182670); + L8: do { + F.line = 306; + var i_182722 = 0; + F.line = 3055; + var colontmp__182824 = 0; + F.line = 306; + colontmp__182824 = nimMin((matches_182644 != null ? matches_182644.length : 0), 19); + F.line = 3056; + var i_182825 = 0; + L9: do { + F.line = 3057; + L10: while (true) { + if (!(i_182825 < colontmp__182824)) break L10; + F.line = 306; + i_182722 = i_182825; + F.line = 307; + matches_182644[chckIndx(i_182722, 0, matches_182644.length+0-1)-0]["Field0"].innerHTML = matches_182644[chckIndx(i_182722, 0, matches_182644.length+0-1)-0]["Field0"].getAttribute("data-doc-search-tag"); + F.line = 308; + add_181070(ul_182625, tree_181020(makeNimstrLit("LI"), [matches_182644[chckIndx(i_182722, 0, matches_182644.length+0-1)-0]["Field0"]])); + F.line = 3059; + i_182825 = addInt(i_182825, 1); + } + } while(false); + } while(false); + if ((ul_182625.childNodes.length == 0)) { + F.line = 310; + add_181070(result_182507, tree_181020(makeNimstrLit("B"), [text_181105(makeNimstrLit("no search results"))])); + } + else { + F.line = 312; + add_181070(result_182507, tree_181020(makeNimstrLit("B"), [text_181105(makeNimstrLit("search results"))])); + F.line = 313; + add_181070(result_182507, ul_182625); + } + + framePtr = F.prev; + + return result_182507; + +} + +function search() { + + function wrapper_182759() { + var F={procname:"search.wrapper",prev:framePtr,filename:"dochack.nim",line:0}; + framePtr = F; + F.line = 320; + var elem_182761 = document.getElementById("searchInput"); + F.line = 321; + var value_182762 = elem_182761.value; + if (!(((value_182762 != null ? value_182762.length : 0) == 0))) { + if ((oldtoc_182742[0] == null)) { + F.line = 324; + oldtoc_182742[0] = document.getElementById("tocRoot"); + } + + F.line = 325; + var results_182768 = dosearch_182504(value_182762); + F.line = 326; + replace_by_id_181142("tocRoot", results_182768); + } + else { + if (!((oldtoc_182742[0] == null))) { + F.line = 328; + replace_by_id_181142("tocRoot", oldtoc_182742[0]); + } + } + framePtr = F.prev; + + + } + + var F={procname:"dochack.search",prev:framePtr,filename:"dochack.nim",line:0}; + framePtr = F; + if (!((timer_182743[0] == null))) { + F.line = 330; + clearTimeout(timer_182743[0]); + } + + F.line = 331; + timer_182743[0] = setTimeout(wrapper_182759, 400); + framePtr = F.prev; + + +} diff --git a/git.html b/git.html old mode 100644 new mode 100755 index bb605f2..bb96fef --- a/git.html +++ b/git.html @@ -27,232 +27,113 @@ customize this style sheet. Modified from Chad Skeeters' rst2html-style https://bitbucket.org/cskeeters/rst2html-style/ -Modified by Boyd Greenfield +Modified by Boyd Greenfield and narimiran */ -/* SCSS variables */ -/* Text weights */ -/* Body colors */ -/* Text colors */ -/* Link colors */ -/* Syntax highlighting colors */ -/* Pct changes */ -/* Mixins */ -/* Body/layout */ + html { font-size: 100%; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; } -/* Where we want fancier font if available */ -h1, h2, h3, h4, h5, h6, p.module-desc, table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; } - -h1.title { - font-weight: 900; } - body { font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: 400; - font-size: 16px; - line-height: 20px; - color: #444; - letter-spacing: 0.15px; - background-color: #FDFBFA; } + font-size: 1.125em; + line-height: 1.5; + color: #222; + background-color: #FCFCFC; } /* Skeleton grid */ .container { position: relative; width: 100%; - max-width: 960px; + max-width: 1050px; margin: 0 auto; - padding: 0 20px; + padding: 0; box-sizing: border-box; } .column, .columns { width: 100%; float: left; - box-sizing: border-box; } + box-sizing: border-box; + margin-left: 1%; +} -/* For devices larger than 400px */ -@media (min-width: 400px) { - .container { - width: 100%; - padding: 0; } } -/* For devices larger than 650px */ -@media (min-width: 650px) { - .container { - width: 100%; } +.column:first-child, +.columns:first-child { + margin-left: 0; } - .column, - .columns { - margin-left: 4%; } +.three.columns { + width: 19%; } - .column:first-child, - .columns:first-child { - margin-left: 0; } +.nine.columns { + width: 80.0%; } - .one.column, - .one.columns { - width: 4.66666666667%; } - - .two.columns { - width: 13.3333333333%; } +.twelve.columns { + width: 100%; + margin-left: 0; } +@media screen and (max-width: 860px) { .three.columns { - width: 22%; } - - .four.columns { - width: 30.6666666667%; } - - .five.columns { - width: 39.3333333333%; } - - .six.columns { - width: 48%; } - - .seven.columns { - width: 56.6666666667%; } - - .eight.columns { - width: 65.3333333333%; } - + display: none; + } .nine.columns { - width: 74.0%; } - - .ten.columns { - width: 82.6666666667%; } - - .eleven.columns { - width: 91.3333333333%; } - - .twelve.columns { - width: 100%; - margin-left: 0; } - - .one-third.column { - width: 30.6666666667%; } - - .two-thirds.column { - width: 65.3333333333%; } } -/* Customer Overrides */ -.footer { - text-align: center; - color: #969696; - padding-top: 10%; } - -p.module-desc { - font-size: 1.1em; - color: #666666; } - -a.link-seesrc { - color: #aec7d2; - font-style: italic; } - -a.link-seesrc:hover { - color: #6c9aae; } - -#toc-list { - word-wrap: break-word; } - -ul.simple-toc { - list-style: none; } - -ul.simple-toc a.reference-toplevel { - font-weight: bold; - color: #0077b3; } - -ul.simple-toc-section { - list-style-type: circle; - color: #6c9aae; } - -ul.simple-toc-section a.reference { - color: #0077b3; } + width: 98.0%; + } + body { + font-size: 1em; + line-height: 1.35; + } +} cite { font-style: italic !important; } -dt > pre { - border-color: rgba(0, 0, 0, 0.1); - background-color: rgba(255, 255, 255, 0.3); - margin: 15px 0px 5px; } - -dd > pre { - border-color: rgba(0, 0, 0, 0.1); - background-color: whitesmoke; - margin-top: 8px; } - -.item > dd { - margin-left: 10px; - margin-bottom: 30px; } - -/* Nim line-numbered tables */ -.line-nums-table { - width: 100%; - table-layout: fixed; } /* Nim search input */ div#searchInputDiv { - margin-bottom: 8px; + margin-bottom: 1em; } -div#searchInputDiv input#searchInput { - width: 10em; -} -div.search-groupby { - margin-bottom: 8px; +input#searchInput { + width: 80%; } -table.line-nums-table { - border-radius: 4px; - border: 1px solid #cccccc; - background-color: whitesmoke; - border-collapse: separate; - margin-top: 15px; - margin-bottom: 25px; } - -.line-nums-table tbody { - border: none; } - -.line-nums-table td pre { - border: none; - background-color: transparent; } - -.line-nums-table td.blob-line-nums { - width: 28px; } - -.line-nums-table td.blob-line-nums pre { - color: #b0b0b0; - -webkit-filter: opacity(75%); - text-align: right; - border-color: transparent; - background-color: transparent; - padding-left: 0px; - margin-left: 0px; - padding-right: 0px; - margin-right: 0px; } /* Docgen styles */ /* Links */ a { - color: #0077b3; - text-decoration: none; } + color: #07b; + text-decoration: none; +} + +a span.Identifier { + text-decoration: underline; + text-decoration-color: #aab; +} + +a.reference-toplevel { + font-weight: bold; +} + +a.toc-backref { + text-decoration: none; + color: #222; } + +a.link-seesrc { + color: #607c9f; + font-size: 0.9em; + font-style: italic; } a:hover, a:focus { - color: #00334d; + color: #607c9f; text-decoration: underline; } -a:visited { - color: #00334d; } +a:hover span.Identifier { + color: #607c9f; +} -a:focus { - outline: thin dotted #2d2d2d; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; } - -a:hover, -a:active { - outline: 0; } sub, sup { @@ -329,379 +210,258 @@ img { h2, h3 { - page-break-after: avoid; } } -.img-rounded { - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; } + page-break-after: avoid; } +} -.img-polaroid { - padding: 4px; - background-color: rgba(252, 248, 244, 0.75); - border: 1px solid #ccc; - border: 1px solid rgba(0, 0, 0, 0.2); - -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); - -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); } p { - margin: 0 0 8px; } + margin-top: 0.5em; + margin-bottom: 0.5em; +} small { font-size: 85%; } strong { - font-weight: 600; } + font-weight: 600; + font-size: 0.95em; + color: #3c3c3c; +} em { font-style: italic; } -cite { - font-style: normal; } - -h1, -h2, -h3, -h4, -h5, -h6 { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-weight: 600; - line-height: 20px; - color: inherit; - text-rendering: optimizelegibility; } - h1 { - font-size: 2em; + font-size: 1.8em; font-weight: 400; - padding-bottom: .15em; - border-bottom: 1px solid #aaaaaa; - margin-top: 1.0em; + padding-bottom: .25em; + border-bottom: 1px solid #aaa; + margin-top: 2.5em; + margin-bottom: 1em; line-height: 1.2em; } h1.title { padding-bottom: 1em; border-bottom: 0px; - font-size: 2.75em; } + font-size: 2.5em; + text-align: center; + font-weight: 900; + margin-top: 0.75em; + margin-bottom: 0em; +} h2 { - font-size: 1.5em; - margin-top: 1.5em; } + font-size: 1.3em; + margin-top: 2em; } + +h2.subtitle { + text-align: center; } h3 { - font-size: 1.3em; + font-size: 1.125em; font-style: italic; - margin-top: 0.75em; } + margin-top: 1.5em; } h4 { - font-size: 1.3em; - margin-top: 0.5em; } + font-size: 1.125em; + margin-top: 1em; } h5 { - font-size: 1.2em; - margin-top: 0.25em; } + font-size: 1.125em; + margin-top: 0.75em; } h6 { font-size: 1.1em; } + ul, ol { padding: 0; - margin: 0 0 0px 15px; } + margin-top: 0.5em; + margin-left: 0.75em; } ul ul, ul ol, ol ol, ol ul { - margin-bottom: 0; } + margin-bottom: 0; + margin-left: 1.25em; } li { - line-height: 20px; } - -dl { - margin-bottom: 20px; } - -dt, -dd { - line-height: 20px; } - -dt { - font-weight: bold; } - -dd { - margin-left: 10px; - margin-bottom: 26px; } - -hr { - margin: 20px 0; - border: 0; - border-top: 1px solid #eeeeee; - border-bottom: 1px solid #ffffff; } - -abbr[title], -abbr[data-original-title] { - cursor: help; - border-bottom: 1px dotted #999999; } - -abbr.initialism { - font-size: 90%; - text-transform: uppercase; } - -blockquote { - padding: 0 0 0 15px; - margin: 0 0 20px; - border-left: 5px solid #EFEBE0; } - -table.docinfo + blockquote, table.docinfo blockquote, h1 + blockquote { - border-left: 5px solid #c9c9c9; + list-style-type: circle; } -table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { - margin-bottom: 0; - font-size: 15px; - font-weight: 200; - line-height: 1.5; - font-style: italic; } +ul.simple-boot li { + list-style-type: none; + margin-left: 0em; + margin-bottom: 0.5em; +} -q:before, -q:after, -blockquote:before, -blockquote:after { - content: ""; } +ol.simple > li, ul.simple > li { + margin-bottom: 0.25em; + margin-left: 0.4em } -address { - display: block; - margin-bottom: 20px; - font-style: normal; - line-height: 20px; } +ul.simple.simple-toc > li { + margin-top: 1em; +} -code, -pre { - font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - padding: 0 3px 2px; - font-weight: 500; - font-size: 12px; - color: #444444; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; } +ul.simple-toc { + list-style: none; + font-size: 0.9em; + margin-left: -0.3em; + margin-top: 1em; } + +ul.simple-toc > li { + list-style-type: none; +} + +ul.simple-toc-section { + list-style-type: circle; + margin-left: 1em; + color: #6c9aae; } + + +ol.arabic { + list-style: decimal; } + +ol.loweralpha { + list-style: lower-alpha; } + +ol.upperalpha { + list-style: upper-alpha; } + +ol.lowerroman { + list-style: lower-roman; } + +ol.upperroman { + list-style: upper-roman; } + +ul.auto-toc { + list-style-type: none; } + + +dl { + margin-bottom: 1.5em; } + +dt { + margin-bottom: -0.5em; + margin-left: 0.5em; } + +dd { + margin-left: 0.5em; + margin-bottom: 2.5em; + margin-top: 0.5em; } + + +hr { + margin: 2em 0; + border: 0; + border-top: 1px solid #aaa; } + +blockquote { + font-size: 0.9em; + font-style: italic; + padding-left: 0.5em; + margin-left: 0; + border-left: 5px solid #bbc; +} .pre { font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - font-weight: 600; - /*color: #504da6;*/ + font-weight: 500; + font-size: 0.85em; + background-color: #f0f3ff; + padding-left: 3px; + padding-right: 3px; + border-radius: 4px; } -code { - padding: 2px 4px; - color: #444444; - white-space: nowrap; - background-color: white; - border: 1px solid #777777; } - pre { + font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; + color: #222; + font-weight: 500; display: inline-block; box-sizing: border-box; - min-width: calc(100% - 19.5px); - padding: 9.5px; - margin: 0.25em 10px 10px 10px; - font-size: 15px; - line-height: 20px; + min-width: 100%; + padding: 0.5em; + margin-top: 0.5em; + margin-bottom: 0.5em; + font-size: 0.85em; white-space: pre !important; overflow-y: hidden; overflow-x: visible; - background-color: rgba(0, 0, 0, 0.01); - border: 1px solid #cccccc; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; } - -pre.prettyprint { - margin-bottom: 20px; } - -pre code { - padding: 0; - color: inherit; - white-space: pre; - overflow-x: visible; - background-color: transparent; - border: 0; } + background-color: ghostwhite; + border: 1px solid #dde; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; } .pre-scrollable { max-height: 340px; overflow-y: scroll; } + +/* Nim line-numbered tables */ +.line-nums-table { + width: 100%; + table-layout: fixed; } + +table.line-nums-table { + border-radius: 4px; + border: 1px solid #cccccc; + background-color: ghostwhite; + border-collapse: separate; + margin-top: 15px; + margin-bottom: 25px; } + +.line-nums-table tbody { + border: none; } + +.line-nums-table td pre { + border: none; + background-color: transparent; } + +.line-nums-table td.blob-line-nums { + width: 28px; } + +.line-nums-table td.blob-line-nums pre { + color: #b0b0b0; + -webkit-filter: opacity(75%); + text-align: right; + border-color: transparent; + background-color: transparent; + padding-left: 0px; + margin-left: 0px; + padding-right: 0px; + margin-right: 0px; } + + table { max-width: 100%; background-color: transparent; + margin-top: 0.5em; + margin-bottom: 1.5em; border-collapse: collapse; - border-spacing: 0; } - -table th, table td { - padding: 0px 8px 0px; + border-color: #ccc; + border-spacing: 0; + font-size: 0.9em; } -.table { - width: 100%; - margin-bottom: 20px; } +table th, table td { + padding: 0px 0.5em 0px; +} -.table th, -.table td { - padding: 8px; - line-height: 20px; - text-align: left; - vertical-align: top; - border-top: 1px solid #444444; } - -.table th { +table th { + background-color: #e8e8e8; font-weight: bold; } -.table thead th { - vertical-align: bottom; } +table th.docinfo-name { + background-color: transparent; +} -.table caption + thead tr:first-child th, -.table caption + thead tr:first-child td, -.table colgroup + thead tr:first-child th, -.table colgroup + thead tr:first-child td, -.table thead:first-child tr:first-child th, -.table thead:first-child tr:first-child td { - border-top: 0; } +table tr:hover { + background-color: ghostwhite; } -.table tbody + tbody { - border-top: 2px solid #444444; } - -.table .table { - background-color: rgba(252, 248, 244, 0.75); } - -.table-condensed th, -.table-condensed td { - padding: 4px 5px; } - -.table-bordered { - border: 1px solid #444444; - border-collapse: separate; - *border-collapse: collapse; - border-left: 0; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; } - -.table-bordered th, -.table-bordered td { - border-left: 1px solid #444444; } - -.table-bordered caption + thead tr:first-child th, -.table-bordered caption + tbody tr:first-child th, -.table-bordered caption + tbody tr:first-child td, -.table-bordered colgroup + thead tr:first-child th, -.table-bordered colgroup + tbody tr:first-child th, -.table-bordered colgroup + tbody tr:first-child td, -.table-bordered thead:first-child tr:first-child th, -.table-bordered tbody:first-child tr:first-child th, -.table-bordered tbody:first-child tr:first-child td { - border-top: 0; } - -.table-bordered thead:first-child tr:first-child > th:first-child, -.table-bordered tbody:first-child tr:first-child > td:first-child, -.table-bordered tbody:first-child tr:first-child > th:first-child { - -webkit-border-top-left-radius: 4px; - border-top-left-radius: 4px; - -moz-border-radius-topleft: 4px; } - -.table-bordered thead:first-child tr:first-child > th:last-child, -.table-bordered tbody:first-child tr:first-child > td:last-child, -.table-bordered tbody:first-child tr:first-child > th:last-child { - -webkit-border-top-right-radius: 4px; - border-top-right-radius: 4px; - -moz-border-radius-topright: 4px; } - -.table-bordered thead:last-child tr:last-child > th:first-child, -.table-bordered tbody:last-child tr:last-child > td:first-child, -.table-bordered tbody:last-child tr:last-child > th:first-child, -.table-bordered tfoot:last-child tr:last-child > td:first-child, -.table-bordered tfoot:last-child tr:last-child > th:first-child { - -webkit-border-bottom-left-radius: 4px; - border-bottom-left-radius: 4px; - -moz-border-radius-bottomleft: 4px; } - -.table-bordered thead:last-child tr:last-child > th:last-child, -.table-bordered tbody:last-child tr:last-child > td:last-child, -.table-bordered tbody:last-child tr:last-child > th:last-child, -.table-bordered tfoot:last-child tr:last-child > td:last-child, -.table-bordered tfoot:last-child tr:last-child > th:last-child { - -webkit-border-bottom-right-radius: 4px; - border-bottom-right-radius: 4px; - -moz-border-radius-bottomright: 4px; } - -.table-bordered tfoot + tbody:last-child tr:last-child td:first-child { - -webkit-border-bottom-left-radius: 0; - border-bottom-left-radius: 0; - -moz-border-radius-bottomleft: 0; } - -.table-bordered tfoot + tbody:last-child tr:last-child td:last-child { - -webkit-border-bottom-right-radius: 0; - border-bottom-right-radius: 0; - -moz-border-radius-bottomright: 0; } - -.table-bordered caption + thead tr:first-child th:first-child, -.table-bordered caption + tbody tr:first-child td:first-child, -.table-bordered colgroup + thead tr:first-child th:first-child, -.table-bordered colgroup + tbody tr:first-child td:first-child { - -webkit-border-top-left-radius: 4px; - border-top-left-radius: 4px; - -moz-border-radius-topleft: 4px; } - -.table-bordered caption + thead tr:first-child th:last-child, -.table-bordered caption + tbody tr:first-child td:last-child, -.table-bordered colgroup + thead tr:first-child th:last-child, -.table-bordered colgroup + tbody tr:first-child td:last-child { - -webkit-border-top-right-radius: 4px; - border-top-right-radius: 4px; - -moz-border-radius-topright: 4px; } - -table.docutils th { - background-color: #e8e8e8; } - -table.docutils tr:hover { - background-color: whitesmoke; } - -.table-striped tbody > tr:nth-child(odd) > td, -.table-striped tbody > tr:nth-child(odd) > th { - background-color: rgba(252, 248, 244, 0.75); } - -.table-hover tbody tr:hover > td, -.table-hover tbody tr:hover > th { - background-color: rgba(241, 222, 204, 0.75); } - -table td[class*="span"], -table th[class*="span"], -.row-fluid table td[class*="span"], -.row-fluid table th[class*="span"] { - display: table-cell; - float: none; - margin-left: 0; } - -.hero-unit { - padding: 60px; - margin-bottom: 30px; - font-size: 18px; - font-weight: 200; - line-height: 30px; - color: inherit; - background-color: rgba(230, 197, 164, 0.75); - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; } - -.hero-unit h1 { - margin-bottom: 0; - font-size: 60px; - line-height: 1; - letter-spacing: -1px; - color: inherit; } - -.hero-unit li { - line-height: 30px; } /* rst2html default used to remove borders from tables and images */ .borderless, table.borderless td, table.borderless th { @@ -722,10 +482,6 @@ table.borderless td, table.borderless th { .hidden { display: none; } -a.toc-backref { - text-decoration: none; - color: #444444; } - blockquote.epigraph { margin: 2em 5em; } @@ -735,85 +491,6 @@ dl.docutils dd { object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] { overflow: hidden; } -/* Uncomment (and remove this text!) to get bold-faced definition list terms -dl.docutils dt { - font-weight: bold } -*/ -div.abstract { - margin: 2em 5em; } - -div.abstract p.topic-title { - font-weight: bold; - text-align: center; } - -div.admonition, div.attention, div.caution, div.danger, div.error, -div.hint, div.important, div.note, div.tip, div.warning { - margin: 2em; - border: medium outset; - padding: 1em; } - -div.note, div.warning { - margin: 1.5em 0px; - border: none; } - -div.note p.admonition-title, -div.warning p.admonition-title { - display: none; } - -/* Clearfix - * http://css-tricks.com/snippets/css/clear-fix/ - */ -div.note:after, -div.warning:after { - content: ""; - display: table; - clear: both; } - -div.note p:before, -div.warning p:before { - display: block; - float: left; - font-size: 4em; - line-height: 1em; - margin-right: 20px; - margin-left: 0em; - margin-top: -10px; - content: '\0270D'; - /*handwriting*/ } - -div.warning p:before { - content: '\026A0'; - /*warning*/ } - -div.admonition p.admonition-title, div.hint p.admonition-title, -div.important p.admonition-title, div.note p.admonition-title, -div.tip p.admonition-title { - font-weight: bold; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } - -div.attention p.admonition-title, div.caution p.admonition-title, -div.danger p.admonition-title, div.error p.admonition-title, -div.warning p.admonition-title, .code .error { - color: #b30000; - font-weight: bold; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } - -/* Uncomment (and remove this text!) to get reduced vertical space in - compound paragraphs. -div.compound .compound-first, div.compound .compound-middle { - margin-bottom: 0.5em } - -div.compound .compound-last, div.compound .compound-middle { - margin-top: 0.5em } -*/ -div.dedication { - margin: 2em 5em; - text-align: center; - font-style: italic; } - -div.dedication p.topic-title { - font-weight: bold; - font-style: normal; } div.figure { margin-left: 2em; @@ -821,8 +498,14 @@ div.figure { div.footer, div.header { clear: both; + text-align: center; + color: #666; font-size: smaller; } +div.footer { + padding-top: 5em; +} + div.line-block { display: block; margin-top: 1em; @@ -833,45 +516,24 @@ div.line-block div.line-block { margin-bottom: 0; margin-left: 1.5em; } -div.sidebar { - margin: 0 0 0.5em 1em; - border: medium outset; - padding: 1em; - background-color: rgba(252, 248, 244, 0.75); - width: 40%; - float: right; - clear: right; } - -div.sidebar p.rubric { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-size: medium; } - -div.system-messages { - margin: 5em; } - -div.system-messages h1 { - color: #b30000; } - -div.system-message { - border: medium outset; - padding: 1em; } - -div.system-message p.system-message-title { - color: #b30000; - font-weight: bold; } - div.topic { margin: 2em; } -h1.section-subtitle, h2.section-subtitle, h3.section-subtitle, -h4.section-subtitle, h5.section-subtitle, h6.section-subtitle { - margin-top: 0.4em; } +div.search_results { + background-color: antiquewhite; + margin: 3em; + padding: 1em; + border: 1px solid #4d4d4d; +} -h1.title { - text-align: center; } +div#global-links ul { + margin-left: 0; + list-style-type: none; +} -h2.subtitle { - text-align: center; } +div#global-links > simple-boot { + margin-left: 3em; +} hr.docutils { width: 75%; } @@ -905,30 +567,6 @@ img.align-center, .figure.align-center, object.align-center { div.align-right { text-align: inherit; } -/* div.align-center * { */ -/* text-align: left } */ - -ul.simple > li { - margin-bottom: 0.5em } - -ol.simple, ul.simple { - margin-bottom: 1em; } - -ol.arabic { - list-style: decimal; } - -ol.loweralpha { - list-style: lower-alpha; } - -ol.upperalpha { - list-style: upper-alpha; } - -ol.lowerroman { - list-style: lower-roman; } - -ol.upperroman { - list-style: upper-roman; } - p.attribution { text-align: right; margin-left: 50%; } @@ -949,15 +587,6 @@ p.rubric { color: maroon; text-align: center; } -p.sidebar-title { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-weight: bold; - font-size: larger; } - -p.sidebar-subtitle { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-weight: bold; } - p.topic-title { font-weight: bold; } @@ -997,22 +626,14 @@ pre.code .inserted, code .inserted { background-color: #A3D289; } span.classifier { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-style: oblique; } span.classifier-delimiter { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: bold; } -span.interpreted { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } - span.option { white-space: nowrap; } -span.pre { - white-space: pre; } - span.problematic { color: #b30000; } @@ -1020,44 +641,6 @@ span.section-subtitle { /* font-size relative to parent (h1..h6 element) */ font-size: 80%; } -table.citation { - border-left: solid 1px #666666; - margin-left: 1px; } - -table.docinfo { - margin: 0em; - margin-top: 2em; - margin-bottom: 2em; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; - color: #444444; } - -table.docutils { - margin-top: 0.5em; - margin-bottom: 0.5em; } - -table.footnote { - border-left: solid 1px #2d2d2d; - margin-left: 1px; } - -table.docutils td, table.docutils th, -table.docinfo td, table.docinfo th { - padding-left: 0.5em; - padding-right: 0.5em; - vertical-align: top; } - -table.docutils th.field-name, table.docinfo th.docinfo-name { - font-weight: 700; - text-align: left; - white-space: nowrap; - padding-left: 0; } - -h1 tt.docutils, h2 tt.docutils, h3 tt.docutils, -h4 tt.docutils, h5 tt.docutils, h6 tt.docutils { - font-size: 100%; } - -ul.auto-toc { - list-style-type: none; } - span.DecNumber { color: #252dbe; } @@ -1074,7 +657,7 @@ span.FloatNumber { color: #252dbe; } span.Identifier { - color: #3b3b3b; } + color: #222; } span.Keyword { font-weight: 600; @@ -1139,38 +722,23 @@ dt pre > span.Identifier, dt pre > span.Operator { color: #155da4; font-weight: 700; } -dt pre > span.Identifier ~ span.Identifier, dt pre > span.Operator ~ span.Identifier { - color: inherit; - font-weight: inherit; } - -dt pre > span.Operator ~ span.Identifier { +dt pre > span.Keyword ~ span.Identifier, dt pre > span.Identifier ~ span.Identifier, +dt pre > span.Operator ~ span.Identifier, dt pre > span.Other ~ span.Identifier { color: inherit; font-weight: inherit; } /* Nim sprite for the footer (taken from main page favicon) */ .nim-sprite { display: inline-block; - height: 12px; - width: 12px; + height: 16px; + width: 16px; background-position: 0 0; - background-size: 12px 12px; + background-size: 16px 16px; -webkit-filter: opacity(50%); background-repeat: no-repeat; background-image: url("data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="); margin-bottom: -5px; } -div.search_results { - background-color: antiquewhite; - margin: 3em; - padding: 1em; - border: 1px solid #4d4d4d; -} - -div#global-links ul { - margin-left: 0; - list-style-type: none; -} - span.pragmadots { /* Position: relative frees us up to make the dots look really nice without fucking up the layout and @@ -1178,18 +746,14 @@ span.pragmadots { position: relative; /* 1px down looks slightly nicer */ top: 1px; - padding: 2px; - background-color: #D3D3D3; + background-color: #e8e8e8; border-radius: 4px; margin: 0 2px; cursor: pointer; - - /* For some reason on Chrome, making the font size - smaller than 1em is causing the parent container to - bulge slightly. So, we're stuck with inheriting 1em, - which is sad, because 0.8em looks better... */ + font-size: 0.8em; } + span.pragmadots:hover { background-color: #DBDBDB; } @@ -1249,14 +813,18 @@ function main() {
    • execAction
    • +
    • mkDir
    • +
    • cpFile
    • +
    • mvFile
    • extractZip
    • downloadUrl
    • gitReset
    • -
    • relativePathNaive
    • gitCheckout
    • Procs
      -
      proc execAction(cmd: string; nostderr = false): string {...}{.raises: [OSError, Exception],
      +
      proc execAction(cmd: string; nostderr = false): string {...}{.
      +    raises: [OSError, Exception, ValueError, IOError, Defect],
           tags: [ExecIOEffect, ReadIOEffect, RootEffect].}
      - -
      proc extractZip(zipfile, outdir: string) {...}{.raises: [OSError, Exception, ValueError], tags: [
      -    ExecIOEffect, ReadIOEffect, RootEffect].}
      -
      - - -
      - -
      proc downloadUrl(url, outdir: string) {...}{.raises: [OSError, Exception, ValueError], tags: [
      +
      +
      proc mkDir(dir: string) {...}{.raises: [OSError, Exception, ValueError, IOError, Defect], tags: [
           ReadDirEffect, ExecIOEffect, ReadIOEffect, RootEffect].}
      +
      + +
      proc cpFile(source, dest: string; move = false) {...}{.
      +    raises: [OSError, Exception, ValueError, IOError, Defect],
      +    tags: [ExecIOEffect, ReadIOEffect, RootEffect].}
      +
      + + +
      + +
      proc mvFile(source, dest: string) {...}{.raises: [OSError, Exception, ValueError, IOError,
      +                                        Defect],
      +                                tags: [ExecIOEffect, ReadIOEffect, RootEffect].}
      +
      + + +
      + +
      proc extractZip(zipfile, outdir: string) {...}{.raises: [OSError, Exception, ValueError,
      +    IOError, Defect], tags: [ExecIOEffect, ReadIOEffect, RootEffect].}
      +
      + + +
      + +
      proc downloadUrl(url, outdir: string) {...}{.raises: [OSError, Exception, ValueError,
      +    IOError, Defect], tags: [ReadDirEffect, ExecIOEffect, ReadIOEffect, RootEffect].}
      +
      + +
      -
      proc gitReset(outdir: string) {...}{.raises: [OSError, Exception], tags: [ExecIOEffect,
      -    ReadIOEffect, RootEffect, TimeEffect].}
      -
      - - -
      - -
      proc relativePathNaive(file, base: string): string {...}{.raises: [], tags: [].}
      -
      -naive version of os.relativePath ; remove after nim >= 0.19.9 -

      Examples:

      -
      doAssert "/foo/bar/baz/log.txt".relativePathNaive("/foo/bar") == "baz/log.txt"
      - -
      - -
      proc gitCheckout(file, outdir: string) {...}{.raises: [OSError, Exception], tags: [
      +
      proc gitReset(outdir: string) {...}{.raises: [OSError, Exception, ValueError, IOError, Defect], tags: [
           ExecIOEffect, ReadIOEffect, RootEffect, TimeEffect].}
      +
      + +
      proc gitCheckout(file, outdir: string) {...}{.raises: [OSError, Exception, ValueError,
      +    IOError, Defect], tags: [ExecIOEffect, ReadIOEffect, RootEffect, TimeEffect].}
      +
      + +
      -
      proc gitPull(url: string; outdir = ""; plist = ""; checkout = "") {...}{.
      -    raises: [OSError, Exception, IOError], tags: [ReadDirEffect, ExecIOEffect,
      -    ReadIOEffect, RootEffect, TimeEffect, WriteIOEffect].}
      +
      proc gitPull(url: string; outdir = ""; plist = ""; checkout = "") {...}{.
      +    raises: [OSError, Exception, ValueError, IOError, Defect], tags: [ReadDirEffect,
      +    ExecIOEffect, ReadIOEffect, RootEffect, TimeEffect, WriteIOEffect].}
      @@ -1340,7 +924,7 @@ naive version of os.relativePath ; remove after nim >= 0.19.9 diff --git a/git.idx b/git.idx old mode 100644 new mode 100755 index ae9f083..ac1d642 --- a/git.idx +++ b/git.idx @@ -1,7 +1,9 @@ execAction git.html#execAction,string git: execAction(cmd: string; nostderr = false): string +mkDir git.html#mkDir,string git: mkDir(dir: string) +cpFile git.html#cpFile,string,string git: cpFile(source, dest: string; move = false) +mvFile git.html#mvFile,string,string git: mvFile(source, dest: string) extractZip git.html#extractZip,string,string git: extractZip(zipfile, outdir: string) downloadUrl git.html#downloadUrl,string,string git: downloadUrl(url, outdir: string) gitReset git.html#gitReset,string git: gitReset(outdir: string) -relativePathNaive git.html#relativePathNaive,string,string git: relativePathNaive(file, base: string): string gitCheckout git.html#gitCheckout,string,string git: gitCheckout(file, outdir: string) gitPull git.html#gitPull,string,string,string,string git: gitPull(url: string; outdir = ""; plist = ""; checkout = "") diff --git a/paths.html b/paths.html old mode 100644 new mode 100755 index 56fad4e..474bcf5 --- a/paths.html +++ b/paths.html @@ -27,232 +27,113 @@ customize this style sheet. Modified from Chad Skeeters' rst2html-style https://bitbucket.org/cskeeters/rst2html-style/ -Modified by Boyd Greenfield +Modified by Boyd Greenfield and narimiran */ -/* SCSS variables */ -/* Text weights */ -/* Body colors */ -/* Text colors */ -/* Link colors */ -/* Syntax highlighting colors */ -/* Pct changes */ -/* Mixins */ -/* Body/layout */ + html { font-size: 100%; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; } -/* Where we want fancier font if available */ -h1, h2, h3, h4, h5, h6, p.module-desc, table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; } - -h1.title { - font-weight: 900; } - body { font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: 400; - font-size: 16px; - line-height: 20px; - color: #444; - letter-spacing: 0.15px; - background-color: #FDFBFA; } + font-size: 1.125em; + line-height: 1.5; + color: #222; + background-color: #FCFCFC; } /* Skeleton grid */ .container { position: relative; width: 100%; - max-width: 960px; + max-width: 1050px; margin: 0 auto; - padding: 0 20px; + padding: 0; box-sizing: border-box; } .column, .columns { width: 100%; float: left; - box-sizing: border-box; } + box-sizing: border-box; + margin-left: 1%; +} -/* For devices larger than 400px */ -@media (min-width: 400px) { - .container { - width: 100%; - padding: 0; } } -/* For devices larger than 650px */ -@media (min-width: 650px) { - .container { - width: 100%; } +.column:first-child, +.columns:first-child { + margin-left: 0; } - .column, - .columns { - margin-left: 4%; } +.three.columns { + width: 19%; } - .column:first-child, - .columns:first-child { - margin-left: 0; } +.nine.columns { + width: 80.0%; } - .one.column, - .one.columns { - width: 4.66666666667%; } - - .two.columns { - width: 13.3333333333%; } +.twelve.columns { + width: 100%; + margin-left: 0; } +@media screen and (max-width: 860px) { .three.columns { - width: 22%; } - - .four.columns { - width: 30.6666666667%; } - - .five.columns { - width: 39.3333333333%; } - - .six.columns { - width: 48%; } - - .seven.columns { - width: 56.6666666667%; } - - .eight.columns { - width: 65.3333333333%; } - + display: none; + } .nine.columns { - width: 74.0%; } - - .ten.columns { - width: 82.6666666667%; } - - .eleven.columns { - width: 91.3333333333%; } - - .twelve.columns { - width: 100%; - margin-left: 0; } - - .one-third.column { - width: 30.6666666667%; } - - .two-thirds.column { - width: 65.3333333333%; } } -/* Customer Overrides */ -.footer { - text-align: center; - color: #969696; - padding-top: 10%; } - -p.module-desc { - font-size: 1.1em; - color: #666666; } - -a.link-seesrc { - color: #aec7d2; - font-style: italic; } - -a.link-seesrc:hover { - color: #6c9aae; } - -#toc-list { - word-wrap: break-word; } - -ul.simple-toc { - list-style: none; } - -ul.simple-toc a.reference-toplevel { - font-weight: bold; - color: #0077b3; } - -ul.simple-toc-section { - list-style-type: circle; - color: #6c9aae; } - -ul.simple-toc-section a.reference { - color: #0077b3; } + width: 98.0%; + } + body { + font-size: 1em; + line-height: 1.35; + } +} cite { font-style: italic !important; } -dt > pre { - border-color: rgba(0, 0, 0, 0.1); - background-color: rgba(255, 255, 255, 0.3); - margin: 15px 0px 5px; } - -dd > pre { - border-color: rgba(0, 0, 0, 0.1); - background-color: whitesmoke; - margin-top: 8px; } - -.item > dd { - margin-left: 10px; - margin-bottom: 30px; } - -/* Nim line-numbered tables */ -.line-nums-table { - width: 100%; - table-layout: fixed; } /* Nim search input */ div#searchInputDiv { - margin-bottom: 8px; + margin-bottom: 1em; } -div#searchInputDiv input#searchInput { - width: 10em; -} -div.search-groupby { - margin-bottom: 8px; +input#searchInput { + width: 80%; } -table.line-nums-table { - border-radius: 4px; - border: 1px solid #cccccc; - background-color: whitesmoke; - border-collapse: separate; - margin-top: 15px; - margin-bottom: 25px; } - -.line-nums-table tbody { - border: none; } - -.line-nums-table td pre { - border: none; - background-color: transparent; } - -.line-nums-table td.blob-line-nums { - width: 28px; } - -.line-nums-table td.blob-line-nums pre { - color: #b0b0b0; - -webkit-filter: opacity(75%); - text-align: right; - border-color: transparent; - background-color: transparent; - padding-left: 0px; - margin-left: 0px; - padding-right: 0px; - margin-right: 0px; } /* Docgen styles */ /* Links */ a { - color: #0077b3; - text-decoration: none; } + color: #07b; + text-decoration: none; +} + +a span.Identifier { + text-decoration: underline; + text-decoration-color: #aab; +} + +a.reference-toplevel { + font-weight: bold; +} + +a.toc-backref { + text-decoration: none; + color: #222; } + +a.link-seesrc { + color: #607c9f; + font-size: 0.9em; + font-style: italic; } a:hover, a:focus { - color: #00334d; + color: #607c9f; text-decoration: underline; } -a:visited { - color: #00334d; } +a:hover span.Identifier { + color: #607c9f; +} -a:focus { - outline: thin dotted #2d2d2d; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; } - -a:hover, -a:active { - outline: 0; } sub, sup { @@ -329,379 +210,258 @@ img { h2, h3 { - page-break-after: avoid; } } -.img-rounded { - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; } + page-break-after: avoid; } +} -.img-polaroid { - padding: 4px; - background-color: rgba(252, 248, 244, 0.75); - border: 1px solid #ccc; - border: 1px solid rgba(0, 0, 0, 0.2); - -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); - -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); } p { - margin: 0 0 8px; } + margin-top: 0.5em; + margin-bottom: 0.5em; +} small { font-size: 85%; } strong { - font-weight: 600; } + font-weight: 600; + font-size: 0.95em; + color: #3c3c3c; +} em { font-style: italic; } -cite { - font-style: normal; } - -h1, -h2, -h3, -h4, -h5, -h6 { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-weight: 600; - line-height: 20px; - color: inherit; - text-rendering: optimizelegibility; } - h1 { - font-size: 2em; + font-size: 1.8em; font-weight: 400; - padding-bottom: .15em; - border-bottom: 1px solid #aaaaaa; - margin-top: 1.0em; + padding-bottom: .25em; + border-bottom: 1px solid #aaa; + margin-top: 2.5em; + margin-bottom: 1em; line-height: 1.2em; } h1.title { padding-bottom: 1em; border-bottom: 0px; - font-size: 2.75em; } + font-size: 2.5em; + text-align: center; + font-weight: 900; + margin-top: 0.75em; + margin-bottom: 0em; +} h2 { - font-size: 1.5em; - margin-top: 1.5em; } + font-size: 1.3em; + margin-top: 2em; } + +h2.subtitle { + text-align: center; } h3 { - font-size: 1.3em; + font-size: 1.125em; font-style: italic; - margin-top: 0.75em; } + margin-top: 1.5em; } h4 { - font-size: 1.3em; - margin-top: 0.5em; } + font-size: 1.125em; + margin-top: 1em; } h5 { - font-size: 1.2em; - margin-top: 0.25em; } + font-size: 1.125em; + margin-top: 0.75em; } h6 { font-size: 1.1em; } + ul, ol { padding: 0; - margin: 0 0 0px 15px; } + margin-top: 0.5em; + margin-left: 0.75em; } ul ul, ul ol, ol ol, ol ul { - margin-bottom: 0; } + margin-bottom: 0; + margin-left: 1.25em; } li { - line-height: 20px; } - -dl { - margin-bottom: 20px; } - -dt, -dd { - line-height: 20px; } - -dt { - font-weight: bold; } - -dd { - margin-left: 10px; - margin-bottom: 26px; } - -hr { - margin: 20px 0; - border: 0; - border-top: 1px solid #eeeeee; - border-bottom: 1px solid #ffffff; } - -abbr[title], -abbr[data-original-title] { - cursor: help; - border-bottom: 1px dotted #999999; } - -abbr.initialism { - font-size: 90%; - text-transform: uppercase; } - -blockquote { - padding: 0 0 0 15px; - margin: 0 0 20px; - border-left: 5px solid #EFEBE0; } - -table.docinfo + blockquote, table.docinfo blockquote, h1 + blockquote { - border-left: 5px solid #c9c9c9; + list-style-type: circle; } -table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { - margin-bottom: 0; - font-size: 15px; - font-weight: 200; - line-height: 1.5; - font-style: italic; } +ul.simple-boot li { + list-style-type: none; + margin-left: 0em; + margin-bottom: 0.5em; +} -q:before, -q:after, -blockquote:before, -blockquote:after { - content: ""; } +ol.simple > li, ul.simple > li { + margin-bottom: 0.25em; + margin-left: 0.4em } -address { - display: block; - margin-bottom: 20px; - font-style: normal; - line-height: 20px; } +ul.simple.simple-toc > li { + margin-top: 1em; +} -code, -pre { - font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - padding: 0 3px 2px; - font-weight: 500; - font-size: 12px; - color: #444444; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; } +ul.simple-toc { + list-style: none; + font-size: 0.9em; + margin-left: -0.3em; + margin-top: 1em; } + +ul.simple-toc > li { + list-style-type: none; +} + +ul.simple-toc-section { + list-style-type: circle; + margin-left: 1em; + color: #6c9aae; } + + +ol.arabic { + list-style: decimal; } + +ol.loweralpha { + list-style: lower-alpha; } + +ol.upperalpha { + list-style: upper-alpha; } + +ol.lowerroman { + list-style: lower-roman; } + +ol.upperroman { + list-style: upper-roman; } + +ul.auto-toc { + list-style-type: none; } + + +dl { + margin-bottom: 1.5em; } + +dt { + margin-bottom: -0.5em; + margin-left: 0.5em; } + +dd { + margin-left: 0.5em; + margin-bottom: 2.5em; + margin-top: 0.5em; } + + +hr { + margin: 2em 0; + border: 0; + border-top: 1px solid #aaa; } + +blockquote { + font-size: 0.9em; + font-style: italic; + padding-left: 0.5em; + margin-left: 0; + border-left: 5px solid #bbc; +} .pre { font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - font-weight: 600; - /*color: #504da6;*/ + font-weight: 500; + font-size: 0.85em; + background-color: #f0f3ff; + padding-left: 3px; + padding-right: 3px; + border-radius: 4px; } -code { - padding: 2px 4px; - color: #444444; - white-space: nowrap; - background-color: white; - border: 1px solid #777777; } - pre { + font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; + color: #222; + font-weight: 500; display: inline-block; box-sizing: border-box; - min-width: calc(100% - 19.5px); - padding: 9.5px; - margin: 0.25em 10px 10px 10px; - font-size: 15px; - line-height: 20px; + min-width: 100%; + padding: 0.5em; + margin-top: 0.5em; + margin-bottom: 0.5em; + font-size: 0.85em; white-space: pre !important; overflow-y: hidden; overflow-x: visible; - background-color: rgba(0, 0, 0, 0.01); - border: 1px solid #cccccc; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; } - -pre.prettyprint { - margin-bottom: 20px; } - -pre code { - padding: 0; - color: inherit; - white-space: pre; - overflow-x: visible; - background-color: transparent; - border: 0; } + background-color: ghostwhite; + border: 1px solid #dde; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; } .pre-scrollable { max-height: 340px; overflow-y: scroll; } + +/* Nim line-numbered tables */ +.line-nums-table { + width: 100%; + table-layout: fixed; } + +table.line-nums-table { + border-radius: 4px; + border: 1px solid #cccccc; + background-color: ghostwhite; + border-collapse: separate; + margin-top: 15px; + margin-bottom: 25px; } + +.line-nums-table tbody { + border: none; } + +.line-nums-table td pre { + border: none; + background-color: transparent; } + +.line-nums-table td.blob-line-nums { + width: 28px; } + +.line-nums-table td.blob-line-nums pre { + color: #b0b0b0; + -webkit-filter: opacity(75%); + text-align: right; + border-color: transparent; + background-color: transparent; + padding-left: 0px; + margin-left: 0px; + padding-right: 0px; + margin-right: 0px; } + + table { max-width: 100%; background-color: transparent; + margin-top: 0.5em; + margin-bottom: 1.5em; border-collapse: collapse; - border-spacing: 0; } - -table th, table td { - padding: 0px 8px 0px; + border-color: #ccc; + border-spacing: 0; + font-size: 0.9em; } -.table { - width: 100%; - margin-bottom: 20px; } +table th, table td { + padding: 0px 0.5em 0px; +} -.table th, -.table td { - padding: 8px; - line-height: 20px; - text-align: left; - vertical-align: top; - border-top: 1px solid #444444; } - -.table th { +table th { + background-color: #e8e8e8; font-weight: bold; } -.table thead th { - vertical-align: bottom; } +table th.docinfo-name { + background-color: transparent; +} -.table caption + thead tr:first-child th, -.table caption + thead tr:first-child td, -.table colgroup + thead tr:first-child th, -.table colgroup + thead tr:first-child td, -.table thead:first-child tr:first-child th, -.table thead:first-child tr:first-child td { - border-top: 0; } +table tr:hover { + background-color: ghostwhite; } -.table tbody + tbody { - border-top: 2px solid #444444; } - -.table .table { - background-color: rgba(252, 248, 244, 0.75); } - -.table-condensed th, -.table-condensed td { - padding: 4px 5px; } - -.table-bordered { - border: 1px solid #444444; - border-collapse: separate; - *border-collapse: collapse; - border-left: 0; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; } - -.table-bordered th, -.table-bordered td { - border-left: 1px solid #444444; } - -.table-bordered caption + thead tr:first-child th, -.table-bordered caption + tbody tr:first-child th, -.table-bordered caption + tbody tr:first-child td, -.table-bordered colgroup + thead tr:first-child th, -.table-bordered colgroup + tbody tr:first-child th, -.table-bordered colgroup + tbody tr:first-child td, -.table-bordered thead:first-child tr:first-child th, -.table-bordered tbody:first-child tr:first-child th, -.table-bordered tbody:first-child tr:first-child td { - border-top: 0; } - -.table-bordered thead:first-child tr:first-child > th:first-child, -.table-bordered tbody:first-child tr:first-child > td:first-child, -.table-bordered tbody:first-child tr:first-child > th:first-child { - -webkit-border-top-left-radius: 4px; - border-top-left-radius: 4px; - -moz-border-radius-topleft: 4px; } - -.table-bordered thead:first-child tr:first-child > th:last-child, -.table-bordered tbody:first-child tr:first-child > td:last-child, -.table-bordered tbody:first-child tr:first-child > th:last-child { - -webkit-border-top-right-radius: 4px; - border-top-right-radius: 4px; - -moz-border-radius-topright: 4px; } - -.table-bordered thead:last-child tr:last-child > th:first-child, -.table-bordered tbody:last-child tr:last-child > td:first-child, -.table-bordered tbody:last-child tr:last-child > th:first-child, -.table-bordered tfoot:last-child tr:last-child > td:first-child, -.table-bordered tfoot:last-child tr:last-child > th:first-child { - -webkit-border-bottom-left-radius: 4px; - border-bottom-left-radius: 4px; - -moz-border-radius-bottomleft: 4px; } - -.table-bordered thead:last-child tr:last-child > th:last-child, -.table-bordered tbody:last-child tr:last-child > td:last-child, -.table-bordered tbody:last-child tr:last-child > th:last-child, -.table-bordered tfoot:last-child tr:last-child > td:last-child, -.table-bordered tfoot:last-child tr:last-child > th:last-child { - -webkit-border-bottom-right-radius: 4px; - border-bottom-right-radius: 4px; - -moz-border-radius-bottomright: 4px; } - -.table-bordered tfoot + tbody:last-child tr:last-child td:first-child { - -webkit-border-bottom-left-radius: 0; - border-bottom-left-radius: 0; - -moz-border-radius-bottomleft: 0; } - -.table-bordered tfoot + tbody:last-child tr:last-child td:last-child { - -webkit-border-bottom-right-radius: 0; - border-bottom-right-radius: 0; - -moz-border-radius-bottomright: 0; } - -.table-bordered caption + thead tr:first-child th:first-child, -.table-bordered caption + tbody tr:first-child td:first-child, -.table-bordered colgroup + thead tr:first-child th:first-child, -.table-bordered colgroup + tbody tr:first-child td:first-child { - -webkit-border-top-left-radius: 4px; - border-top-left-radius: 4px; - -moz-border-radius-topleft: 4px; } - -.table-bordered caption + thead tr:first-child th:last-child, -.table-bordered caption + tbody tr:first-child td:last-child, -.table-bordered colgroup + thead tr:first-child th:last-child, -.table-bordered colgroup + tbody tr:first-child td:last-child { - -webkit-border-top-right-radius: 4px; - border-top-right-radius: 4px; - -moz-border-radius-topright: 4px; } - -table.docutils th { - background-color: #e8e8e8; } - -table.docutils tr:hover { - background-color: whitesmoke; } - -.table-striped tbody > tr:nth-child(odd) > td, -.table-striped tbody > tr:nth-child(odd) > th { - background-color: rgba(252, 248, 244, 0.75); } - -.table-hover tbody tr:hover > td, -.table-hover tbody tr:hover > th { - background-color: rgba(241, 222, 204, 0.75); } - -table td[class*="span"], -table th[class*="span"], -.row-fluid table td[class*="span"], -.row-fluid table th[class*="span"] { - display: table-cell; - float: none; - margin-left: 0; } - -.hero-unit { - padding: 60px; - margin-bottom: 30px; - font-size: 18px; - font-weight: 200; - line-height: 30px; - color: inherit; - background-color: rgba(230, 197, 164, 0.75); - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; } - -.hero-unit h1 { - margin-bottom: 0; - font-size: 60px; - line-height: 1; - letter-spacing: -1px; - color: inherit; } - -.hero-unit li { - line-height: 30px; } /* rst2html default used to remove borders from tables and images */ .borderless, table.borderless td, table.borderless th { @@ -722,10 +482,6 @@ table.borderless td, table.borderless th { .hidden { display: none; } -a.toc-backref { - text-decoration: none; - color: #444444; } - blockquote.epigraph { margin: 2em 5em; } @@ -735,85 +491,6 @@ dl.docutils dd { object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] { overflow: hidden; } -/* Uncomment (and remove this text!) to get bold-faced definition list terms -dl.docutils dt { - font-weight: bold } -*/ -div.abstract { - margin: 2em 5em; } - -div.abstract p.topic-title { - font-weight: bold; - text-align: center; } - -div.admonition, div.attention, div.caution, div.danger, div.error, -div.hint, div.important, div.note, div.tip, div.warning { - margin: 2em; - border: medium outset; - padding: 1em; } - -div.note, div.warning { - margin: 1.5em 0px; - border: none; } - -div.note p.admonition-title, -div.warning p.admonition-title { - display: none; } - -/* Clearfix - * http://css-tricks.com/snippets/css/clear-fix/ - */ -div.note:after, -div.warning:after { - content: ""; - display: table; - clear: both; } - -div.note p:before, -div.warning p:before { - display: block; - float: left; - font-size: 4em; - line-height: 1em; - margin-right: 20px; - margin-left: 0em; - margin-top: -10px; - content: '\0270D'; - /*handwriting*/ } - -div.warning p:before { - content: '\026A0'; - /*warning*/ } - -div.admonition p.admonition-title, div.hint p.admonition-title, -div.important p.admonition-title, div.note p.admonition-title, -div.tip p.admonition-title { - font-weight: bold; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } - -div.attention p.admonition-title, div.caution p.admonition-title, -div.danger p.admonition-title, div.error p.admonition-title, -div.warning p.admonition-title, .code .error { - color: #b30000; - font-weight: bold; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } - -/* Uncomment (and remove this text!) to get reduced vertical space in - compound paragraphs. -div.compound .compound-first, div.compound .compound-middle { - margin-bottom: 0.5em } - -div.compound .compound-last, div.compound .compound-middle { - margin-top: 0.5em } -*/ -div.dedication { - margin: 2em 5em; - text-align: center; - font-style: italic; } - -div.dedication p.topic-title { - font-weight: bold; - font-style: normal; } div.figure { margin-left: 2em; @@ -821,8 +498,14 @@ div.figure { div.footer, div.header { clear: both; + text-align: center; + color: #666; font-size: smaller; } +div.footer { + padding-top: 5em; +} + div.line-block { display: block; margin-top: 1em; @@ -833,45 +516,24 @@ div.line-block div.line-block { margin-bottom: 0; margin-left: 1.5em; } -div.sidebar { - margin: 0 0 0.5em 1em; - border: medium outset; - padding: 1em; - background-color: rgba(252, 248, 244, 0.75); - width: 40%; - float: right; - clear: right; } - -div.sidebar p.rubric { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-size: medium; } - -div.system-messages { - margin: 5em; } - -div.system-messages h1 { - color: #b30000; } - -div.system-message { - border: medium outset; - padding: 1em; } - -div.system-message p.system-message-title { - color: #b30000; - font-weight: bold; } - div.topic { margin: 2em; } -h1.section-subtitle, h2.section-subtitle, h3.section-subtitle, -h4.section-subtitle, h5.section-subtitle, h6.section-subtitle { - margin-top: 0.4em; } +div.search_results { + background-color: antiquewhite; + margin: 3em; + padding: 1em; + border: 1px solid #4d4d4d; +} -h1.title { - text-align: center; } +div#global-links ul { + margin-left: 0; + list-style-type: none; +} -h2.subtitle { - text-align: center; } +div#global-links > simple-boot { + margin-left: 3em; +} hr.docutils { width: 75%; } @@ -905,30 +567,6 @@ img.align-center, .figure.align-center, object.align-center { div.align-right { text-align: inherit; } -/* div.align-center * { */ -/* text-align: left } */ - -ul.simple > li { - margin-bottom: 0.5em } - -ol.simple, ul.simple { - margin-bottom: 1em; } - -ol.arabic { - list-style: decimal; } - -ol.loweralpha { - list-style: lower-alpha; } - -ol.upperalpha { - list-style: upper-alpha; } - -ol.lowerroman { - list-style: lower-roman; } - -ol.upperroman { - list-style: upper-roman; } - p.attribution { text-align: right; margin-left: 50%; } @@ -949,15 +587,6 @@ p.rubric { color: maroon; text-align: center; } -p.sidebar-title { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-weight: bold; - font-size: larger; } - -p.sidebar-subtitle { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-weight: bold; } - p.topic-title { font-weight: bold; } @@ -997,22 +626,14 @@ pre.code .inserted, code .inserted { background-color: #A3D289; } span.classifier { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-style: oblique; } span.classifier-delimiter { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: bold; } -span.interpreted { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } - span.option { white-space: nowrap; } -span.pre { - white-space: pre; } - span.problematic { color: #b30000; } @@ -1020,44 +641,6 @@ span.section-subtitle { /* font-size relative to parent (h1..h6 element) */ font-size: 80%; } -table.citation { - border-left: solid 1px #666666; - margin-left: 1px; } - -table.docinfo { - margin: 0em; - margin-top: 2em; - margin-bottom: 2em; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; - color: #444444; } - -table.docutils { - margin-top: 0.5em; - margin-bottom: 0.5em; } - -table.footnote { - border-left: solid 1px #2d2d2d; - margin-left: 1px; } - -table.docutils td, table.docutils th, -table.docinfo td, table.docinfo th { - padding-left: 0.5em; - padding-right: 0.5em; - vertical-align: top; } - -table.docutils th.field-name, table.docinfo th.docinfo-name { - font-weight: 700; - text-align: left; - white-space: nowrap; - padding-left: 0; } - -h1 tt.docutils, h2 tt.docutils, h3 tt.docutils, -h4 tt.docutils, h5 tt.docutils, h6 tt.docutils { - font-size: 100%; } - -ul.auto-toc { - list-style-type: none; } - span.DecNumber { color: #252dbe; } @@ -1074,7 +657,7 @@ span.FloatNumber { color: #252dbe; } span.Identifier { - color: #3b3b3b; } + color: #222; } span.Keyword { font-weight: 600; @@ -1139,38 +722,23 @@ dt pre > span.Identifier, dt pre > span.Operator { color: #155da4; font-weight: 700; } -dt pre > span.Identifier ~ span.Identifier, dt pre > span.Operator ~ span.Identifier { - color: inherit; - font-weight: inherit; } - -dt pre > span.Operator ~ span.Identifier { +dt pre > span.Keyword ~ span.Identifier, dt pre > span.Identifier ~ span.Identifier, +dt pre > span.Operator ~ span.Identifier, dt pre > span.Other ~ span.Identifier { color: inherit; font-weight: inherit; } /* Nim sprite for the footer (taken from main page favicon) */ .nim-sprite { display: inline-block; - height: 12px; - width: 12px; + height: 16px; + width: 16px; background-position: 0 0; - background-size: 12px 12px; + background-size: 16px 16px; -webkit-filter: opacity(50%); background-repeat: no-repeat; background-image: url("data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="); margin-bottom: -5px; } -div.search_results { - background-color: antiquewhite; - margin: 3em; - padding: 1em; - border: 1px solid #4d4d4d; -} - -div#global-links ul { - margin-left: 0; - list-style-type: none; -} - span.pragmadots { /* Position: relative frees us up to make the dots look really nice without fucking up the layout and @@ -1178,18 +746,14 @@ span.pragmadots { position: relative; /* 1px down looks slightly nicer */ top: 1px; - padding: 2px; - background-color: #D3D3D3; + background-color: #e8e8e8; border-radius: 4px; margin: 0 2px; cursor: pointer; - - /* For some reason on Chrome, making the font size - smaller than 1em is causing the parent container to - bulge slightly. So, we're stuck with inheriting 1em, - which is sad, because 0.8em looks better... */ + font-size: 0.8em; } + span.pragmadots:hover { background-color: #DBDBDB; } @@ -1241,16 +805,18 @@ function main() {
    • Procs
    • @@ -1264,32 +830,38 @@ function main() {

      Procs

      - -
      proc nimteropRoot(): string {...}{.raises: [], tags: [].}
      + +
      proc nimteropRoot(): string {...}{.raises: [], tags: [].}
      - -
      proc nimteropBuildDir(): string {...}{.raises: [], tags: [].}
      + +
      proc nimteropBuildDir(): string {...}{.raises: [], tags: [].}
      all nimterop generated files go under here (gitignored)
      - -
      proc nimteropSrcDir(): string {...}{.raises: [], tags: [].}
      + +
      proc nimteropSrcDir(): string {...}{.raises: [], tags: [].}
      - -
      proc toastExePath(): string {...}{.raises: [], tags: [].}
      + +
      proc toastExePath(): string {...}{.raises: [], tags: [].}
      - -
      proc incDir(): string {...}{.raises: [], tags: [].}
      + +
      proc incDir(): string {...}{.raises: [], tags: [].}
      +
      + + +
      + +
      proc testsIncludeDir(): string {...}{.raises: [], tags: [].}
      @@ -1304,7 +876,7 @@ all nimterop generated files go under here (gitignored)
      diff --git a/paths.idx b/paths.idx old mode 100644 new mode 100755 index 7239d08..8a688d4 --- a/paths.idx +++ b/paths.idx @@ -1,5 +1,6 @@ -nimteropRoot paths.html#nimteropRoot, paths: nimteropRoot(): string -nimteropBuildDir paths.html#nimteropBuildDir, paths: nimteropBuildDir(): string -nimteropSrcDir paths.html#nimteropSrcDir, paths: nimteropSrcDir(): string -toastExePath paths.html#toastExePath, paths: toastExePath(): string -incDir paths.html#incDir, paths: incDir(): string +nimteropRoot paths.html#nimteropRoot paths: nimteropRoot(): string +nimteropBuildDir paths.html#nimteropBuildDir paths: nimteropBuildDir(): string +nimteropSrcDir paths.html#nimteropSrcDir paths: nimteropSrcDir(): string +toastExePath paths.html#toastExePath paths: toastExePath(): string +incDir paths.html#incDir paths: incDir(): string +testsIncludeDir paths.html#testsIncludeDir paths: testsIncludeDir(): string diff --git a/plugin.html b/plugin.html old mode 100644 new mode 100755 index 491c58a..5e00f23 --- a/plugin.html +++ b/plugin.html @@ -27,232 +27,113 @@ customize this style sheet. Modified from Chad Skeeters' rst2html-style https://bitbucket.org/cskeeters/rst2html-style/ -Modified by Boyd Greenfield +Modified by Boyd Greenfield and narimiran */ -/* SCSS variables */ -/* Text weights */ -/* Body colors */ -/* Text colors */ -/* Link colors */ -/* Syntax highlighting colors */ -/* Pct changes */ -/* Mixins */ -/* Body/layout */ + html { font-size: 100%; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; } -/* Where we want fancier font if available */ -h1, h2, h3, h4, h5, h6, p.module-desc, table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; } - -h1.title { - font-weight: 900; } - body { font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: 400; - font-size: 16px; - line-height: 20px; - color: #444; - letter-spacing: 0.15px; - background-color: #FDFBFA; } + font-size: 1.125em; + line-height: 1.5; + color: #222; + background-color: #FCFCFC; } /* Skeleton grid */ .container { position: relative; width: 100%; - max-width: 960px; + max-width: 1050px; margin: 0 auto; - padding: 0 20px; + padding: 0; box-sizing: border-box; } .column, .columns { width: 100%; float: left; - box-sizing: border-box; } + box-sizing: border-box; + margin-left: 1%; +} -/* For devices larger than 400px */ -@media (min-width: 400px) { - .container { - width: 100%; - padding: 0; } } -/* For devices larger than 650px */ -@media (min-width: 650px) { - .container { - width: 100%; } +.column:first-child, +.columns:first-child { + margin-left: 0; } - .column, - .columns { - margin-left: 4%; } +.three.columns { + width: 19%; } - .column:first-child, - .columns:first-child { - margin-left: 0; } +.nine.columns { + width: 80.0%; } - .one.column, - .one.columns { - width: 4.66666666667%; } - - .two.columns { - width: 13.3333333333%; } +.twelve.columns { + width: 100%; + margin-left: 0; } +@media screen and (max-width: 860px) { .three.columns { - width: 22%; } - - .four.columns { - width: 30.6666666667%; } - - .five.columns { - width: 39.3333333333%; } - - .six.columns { - width: 48%; } - - .seven.columns { - width: 56.6666666667%; } - - .eight.columns { - width: 65.3333333333%; } - + display: none; + } .nine.columns { - width: 74.0%; } - - .ten.columns { - width: 82.6666666667%; } - - .eleven.columns { - width: 91.3333333333%; } - - .twelve.columns { - width: 100%; - margin-left: 0; } - - .one-third.column { - width: 30.6666666667%; } - - .two-thirds.column { - width: 65.3333333333%; } } -/* Customer Overrides */ -.footer { - text-align: center; - color: #969696; - padding-top: 10%; } - -p.module-desc { - font-size: 1.1em; - color: #666666; } - -a.link-seesrc { - color: #aec7d2; - font-style: italic; } - -a.link-seesrc:hover { - color: #6c9aae; } - -#toc-list { - word-wrap: break-word; } - -ul.simple-toc { - list-style: none; } - -ul.simple-toc a.reference-toplevel { - font-weight: bold; - color: #0077b3; } - -ul.simple-toc-section { - list-style-type: circle; - color: #6c9aae; } - -ul.simple-toc-section a.reference { - color: #0077b3; } + width: 98.0%; + } + body { + font-size: 1em; + line-height: 1.35; + } +} cite { font-style: italic !important; } -dt > pre { - border-color: rgba(0, 0, 0, 0.1); - background-color: rgba(255, 255, 255, 0.3); - margin: 15px 0px 5px; } - -dd > pre { - border-color: rgba(0, 0, 0, 0.1); - background-color: whitesmoke; - margin-top: 8px; } - -.item > dd { - margin-left: 10px; - margin-bottom: 30px; } - -/* Nim line-numbered tables */ -.line-nums-table { - width: 100%; - table-layout: fixed; } /* Nim search input */ div#searchInputDiv { - margin-bottom: 8px; + margin-bottom: 1em; } -div#searchInputDiv input#searchInput { - width: 10em; -} -div.search-groupby { - margin-bottom: 8px; +input#searchInput { + width: 80%; } -table.line-nums-table { - border-radius: 4px; - border: 1px solid #cccccc; - background-color: whitesmoke; - border-collapse: separate; - margin-top: 15px; - margin-bottom: 25px; } - -.line-nums-table tbody { - border: none; } - -.line-nums-table td pre { - border: none; - background-color: transparent; } - -.line-nums-table td.blob-line-nums { - width: 28px; } - -.line-nums-table td.blob-line-nums pre { - color: #b0b0b0; - -webkit-filter: opacity(75%); - text-align: right; - border-color: transparent; - background-color: transparent; - padding-left: 0px; - margin-left: 0px; - padding-right: 0px; - margin-right: 0px; } /* Docgen styles */ /* Links */ a { - color: #0077b3; - text-decoration: none; } + color: #07b; + text-decoration: none; +} + +a span.Identifier { + text-decoration: underline; + text-decoration-color: #aab; +} + +a.reference-toplevel { + font-weight: bold; +} + +a.toc-backref { + text-decoration: none; + color: #222; } + +a.link-seesrc { + color: #607c9f; + font-size: 0.9em; + font-style: italic; } a:hover, a:focus { - color: #00334d; + color: #607c9f; text-decoration: underline; } -a:visited { - color: #00334d; } +a:hover span.Identifier { + color: #607c9f; +} -a:focus { - outline: thin dotted #2d2d2d; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; } - -a:hover, -a:active { - outline: 0; } sub, sup { @@ -329,379 +210,258 @@ img { h2, h3 { - page-break-after: avoid; } } -.img-rounded { - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; } + page-break-after: avoid; } +} -.img-polaroid { - padding: 4px; - background-color: rgba(252, 248, 244, 0.75); - border: 1px solid #ccc; - border: 1px solid rgba(0, 0, 0, 0.2); - -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); - -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); } p { - margin: 0 0 8px; } + margin-top: 0.5em; + margin-bottom: 0.5em; +} small { font-size: 85%; } strong { - font-weight: 600; } + font-weight: 600; + font-size: 0.95em; + color: #3c3c3c; +} em { font-style: italic; } -cite { - font-style: normal; } - -h1, -h2, -h3, -h4, -h5, -h6 { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-weight: 600; - line-height: 20px; - color: inherit; - text-rendering: optimizelegibility; } - h1 { - font-size: 2em; + font-size: 1.8em; font-weight: 400; - padding-bottom: .15em; - border-bottom: 1px solid #aaaaaa; - margin-top: 1.0em; + padding-bottom: .25em; + border-bottom: 1px solid #aaa; + margin-top: 2.5em; + margin-bottom: 1em; line-height: 1.2em; } h1.title { padding-bottom: 1em; border-bottom: 0px; - font-size: 2.75em; } + font-size: 2.5em; + text-align: center; + font-weight: 900; + margin-top: 0.75em; + margin-bottom: 0em; +} h2 { - font-size: 1.5em; - margin-top: 1.5em; } + font-size: 1.3em; + margin-top: 2em; } + +h2.subtitle { + text-align: center; } h3 { - font-size: 1.3em; + font-size: 1.125em; font-style: italic; - margin-top: 0.75em; } + margin-top: 1.5em; } h4 { - font-size: 1.3em; - margin-top: 0.5em; } + font-size: 1.125em; + margin-top: 1em; } h5 { - font-size: 1.2em; - margin-top: 0.25em; } + font-size: 1.125em; + margin-top: 0.75em; } h6 { font-size: 1.1em; } + ul, ol { padding: 0; - margin: 0 0 0px 15px; } + margin-top: 0.5em; + margin-left: 0.75em; } ul ul, ul ol, ol ol, ol ul { - margin-bottom: 0; } + margin-bottom: 0; + margin-left: 1.25em; } li { - line-height: 20px; } - -dl { - margin-bottom: 20px; } - -dt, -dd { - line-height: 20px; } - -dt { - font-weight: bold; } - -dd { - margin-left: 10px; - margin-bottom: 26px; } - -hr { - margin: 20px 0; - border: 0; - border-top: 1px solid #eeeeee; - border-bottom: 1px solid #ffffff; } - -abbr[title], -abbr[data-original-title] { - cursor: help; - border-bottom: 1px dotted #999999; } - -abbr.initialism { - font-size: 90%; - text-transform: uppercase; } - -blockquote { - padding: 0 0 0 15px; - margin: 0 0 20px; - border-left: 5px solid #EFEBE0; } - -table.docinfo + blockquote, table.docinfo blockquote, h1 + blockquote { - border-left: 5px solid #c9c9c9; + list-style-type: circle; } -table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { - margin-bottom: 0; - font-size: 15px; - font-weight: 200; - line-height: 1.5; - font-style: italic; } +ul.simple-boot li { + list-style-type: none; + margin-left: 0em; + margin-bottom: 0.5em; +} -q:before, -q:after, -blockquote:before, -blockquote:after { - content: ""; } +ol.simple > li, ul.simple > li { + margin-bottom: 0.25em; + margin-left: 0.4em } -address { - display: block; - margin-bottom: 20px; - font-style: normal; - line-height: 20px; } +ul.simple.simple-toc > li { + margin-top: 1em; +} -code, -pre { - font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - padding: 0 3px 2px; - font-weight: 500; - font-size: 12px; - color: #444444; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; } +ul.simple-toc { + list-style: none; + font-size: 0.9em; + margin-left: -0.3em; + margin-top: 1em; } + +ul.simple-toc > li { + list-style-type: none; +} + +ul.simple-toc-section { + list-style-type: circle; + margin-left: 1em; + color: #6c9aae; } + + +ol.arabic { + list-style: decimal; } + +ol.loweralpha { + list-style: lower-alpha; } + +ol.upperalpha { + list-style: upper-alpha; } + +ol.lowerroman { + list-style: lower-roman; } + +ol.upperroman { + list-style: upper-roman; } + +ul.auto-toc { + list-style-type: none; } + + +dl { + margin-bottom: 1.5em; } + +dt { + margin-bottom: -0.5em; + margin-left: 0.5em; } + +dd { + margin-left: 0.5em; + margin-bottom: 2.5em; + margin-top: 0.5em; } + + +hr { + margin: 2em 0; + border: 0; + border-top: 1px solid #aaa; } + +blockquote { + font-size: 0.9em; + font-style: italic; + padding-left: 0.5em; + margin-left: 0; + border-left: 5px solid #bbc; +} .pre { font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - font-weight: 600; - /*color: #504da6;*/ + font-weight: 500; + font-size: 0.85em; + background-color: #f0f3ff; + padding-left: 3px; + padding-right: 3px; + border-radius: 4px; } -code { - padding: 2px 4px; - color: #444444; - white-space: nowrap; - background-color: white; - border: 1px solid #777777; } - pre { + font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; + color: #222; + font-weight: 500; display: inline-block; box-sizing: border-box; - min-width: calc(100% - 19.5px); - padding: 9.5px; - margin: 0.25em 10px 10px 10px; - font-size: 15px; - line-height: 20px; + min-width: 100%; + padding: 0.5em; + margin-top: 0.5em; + margin-bottom: 0.5em; + font-size: 0.85em; white-space: pre !important; overflow-y: hidden; overflow-x: visible; - background-color: rgba(0, 0, 0, 0.01); - border: 1px solid #cccccc; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; } - -pre.prettyprint { - margin-bottom: 20px; } - -pre code { - padding: 0; - color: inherit; - white-space: pre; - overflow-x: visible; - background-color: transparent; - border: 0; } + background-color: ghostwhite; + border: 1px solid #dde; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; } .pre-scrollable { max-height: 340px; overflow-y: scroll; } + +/* Nim line-numbered tables */ +.line-nums-table { + width: 100%; + table-layout: fixed; } + +table.line-nums-table { + border-radius: 4px; + border: 1px solid #cccccc; + background-color: ghostwhite; + border-collapse: separate; + margin-top: 15px; + margin-bottom: 25px; } + +.line-nums-table tbody { + border: none; } + +.line-nums-table td pre { + border: none; + background-color: transparent; } + +.line-nums-table td.blob-line-nums { + width: 28px; } + +.line-nums-table td.blob-line-nums pre { + color: #b0b0b0; + -webkit-filter: opacity(75%); + text-align: right; + border-color: transparent; + background-color: transparent; + padding-left: 0px; + margin-left: 0px; + padding-right: 0px; + margin-right: 0px; } + + table { max-width: 100%; background-color: transparent; + margin-top: 0.5em; + margin-bottom: 1.5em; border-collapse: collapse; - border-spacing: 0; } - -table th, table td { - padding: 0px 8px 0px; + border-color: #ccc; + border-spacing: 0; + font-size: 0.9em; } -.table { - width: 100%; - margin-bottom: 20px; } +table th, table td { + padding: 0px 0.5em 0px; +} -.table th, -.table td { - padding: 8px; - line-height: 20px; - text-align: left; - vertical-align: top; - border-top: 1px solid #444444; } - -.table th { +table th { + background-color: #e8e8e8; font-weight: bold; } -.table thead th { - vertical-align: bottom; } +table th.docinfo-name { + background-color: transparent; +} -.table caption + thead tr:first-child th, -.table caption + thead tr:first-child td, -.table colgroup + thead tr:first-child th, -.table colgroup + thead tr:first-child td, -.table thead:first-child tr:first-child th, -.table thead:first-child tr:first-child td { - border-top: 0; } +table tr:hover { + background-color: ghostwhite; } -.table tbody + tbody { - border-top: 2px solid #444444; } - -.table .table { - background-color: rgba(252, 248, 244, 0.75); } - -.table-condensed th, -.table-condensed td { - padding: 4px 5px; } - -.table-bordered { - border: 1px solid #444444; - border-collapse: separate; - *border-collapse: collapse; - border-left: 0; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; } - -.table-bordered th, -.table-bordered td { - border-left: 1px solid #444444; } - -.table-bordered caption + thead tr:first-child th, -.table-bordered caption + tbody tr:first-child th, -.table-bordered caption + tbody tr:first-child td, -.table-bordered colgroup + thead tr:first-child th, -.table-bordered colgroup + tbody tr:first-child th, -.table-bordered colgroup + tbody tr:first-child td, -.table-bordered thead:first-child tr:first-child th, -.table-bordered tbody:first-child tr:first-child th, -.table-bordered tbody:first-child tr:first-child td { - border-top: 0; } - -.table-bordered thead:first-child tr:first-child > th:first-child, -.table-bordered tbody:first-child tr:first-child > td:first-child, -.table-bordered tbody:first-child tr:first-child > th:first-child { - -webkit-border-top-left-radius: 4px; - border-top-left-radius: 4px; - -moz-border-radius-topleft: 4px; } - -.table-bordered thead:first-child tr:first-child > th:last-child, -.table-bordered tbody:first-child tr:first-child > td:last-child, -.table-bordered tbody:first-child tr:first-child > th:last-child { - -webkit-border-top-right-radius: 4px; - border-top-right-radius: 4px; - -moz-border-radius-topright: 4px; } - -.table-bordered thead:last-child tr:last-child > th:first-child, -.table-bordered tbody:last-child tr:last-child > td:first-child, -.table-bordered tbody:last-child tr:last-child > th:first-child, -.table-bordered tfoot:last-child tr:last-child > td:first-child, -.table-bordered tfoot:last-child tr:last-child > th:first-child { - -webkit-border-bottom-left-radius: 4px; - border-bottom-left-radius: 4px; - -moz-border-radius-bottomleft: 4px; } - -.table-bordered thead:last-child tr:last-child > th:last-child, -.table-bordered tbody:last-child tr:last-child > td:last-child, -.table-bordered tbody:last-child tr:last-child > th:last-child, -.table-bordered tfoot:last-child tr:last-child > td:last-child, -.table-bordered tfoot:last-child tr:last-child > th:last-child { - -webkit-border-bottom-right-radius: 4px; - border-bottom-right-radius: 4px; - -moz-border-radius-bottomright: 4px; } - -.table-bordered tfoot + tbody:last-child tr:last-child td:first-child { - -webkit-border-bottom-left-radius: 0; - border-bottom-left-radius: 0; - -moz-border-radius-bottomleft: 0; } - -.table-bordered tfoot + tbody:last-child tr:last-child td:last-child { - -webkit-border-bottom-right-radius: 0; - border-bottom-right-radius: 0; - -moz-border-radius-bottomright: 0; } - -.table-bordered caption + thead tr:first-child th:first-child, -.table-bordered caption + tbody tr:first-child td:first-child, -.table-bordered colgroup + thead tr:first-child th:first-child, -.table-bordered colgroup + tbody tr:first-child td:first-child { - -webkit-border-top-left-radius: 4px; - border-top-left-radius: 4px; - -moz-border-radius-topleft: 4px; } - -.table-bordered caption + thead tr:first-child th:last-child, -.table-bordered caption + tbody tr:first-child td:last-child, -.table-bordered colgroup + thead tr:first-child th:last-child, -.table-bordered colgroup + tbody tr:first-child td:last-child { - -webkit-border-top-right-radius: 4px; - border-top-right-radius: 4px; - -moz-border-radius-topright: 4px; } - -table.docutils th { - background-color: #e8e8e8; } - -table.docutils tr:hover { - background-color: whitesmoke; } - -.table-striped tbody > tr:nth-child(odd) > td, -.table-striped tbody > tr:nth-child(odd) > th { - background-color: rgba(252, 248, 244, 0.75); } - -.table-hover tbody tr:hover > td, -.table-hover tbody tr:hover > th { - background-color: rgba(241, 222, 204, 0.75); } - -table td[class*="span"], -table th[class*="span"], -.row-fluid table td[class*="span"], -.row-fluid table th[class*="span"] { - display: table-cell; - float: none; - margin-left: 0; } - -.hero-unit { - padding: 60px; - margin-bottom: 30px; - font-size: 18px; - font-weight: 200; - line-height: 30px; - color: inherit; - background-color: rgba(230, 197, 164, 0.75); - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; } - -.hero-unit h1 { - margin-bottom: 0; - font-size: 60px; - line-height: 1; - letter-spacing: -1px; - color: inherit; } - -.hero-unit li { - line-height: 30px; } /* rst2html default used to remove borders from tables and images */ .borderless, table.borderless td, table.borderless th { @@ -722,10 +482,6 @@ table.borderless td, table.borderless th { .hidden { display: none; } -a.toc-backref { - text-decoration: none; - color: #444444; } - blockquote.epigraph { margin: 2em 5em; } @@ -735,85 +491,6 @@ dl.docutils dd { object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] { overflow: hidden; } -/* Uncomment (and remove this text!) to get bold-faced definition list terms -dl.docutils dt { - font-weight: bold } -*/ -div.abstract { - margin: 2em 5em; } - -div.abstract p.topic-title { - font-weight: bold; - text-align: center; } - -div.admonition, div.attention, div.caution, div.danger, div.error, -div.hint, div.important, div.note, div.tip, div.warning { - margin: 2em; - border: medium outset; - padding: 1em; } - -div.note, div.warning { - margin: 1.5em 0px; - border: none; } - -div.note p.admonition-title, -div.warning p.admonition-title { - display: none; } - -/* Clearfix - * http://css-tricks.com/snippets/css/clear-fix/ - */ -div.note:after, -div.warning:after { - content: ""; - display: table; - clear: both; } - -div.note p:before, -div.warning p:before { - display: block; - float: left; - font-size: 4em; - line-height: 1em; - margin-right: 20px; - margin-left: 0em; - margin-top: -10px; - content: '\0270D'; - /*handwriting*/ } - -div.warning p:before { - content: '\026A0'; - /*warning*/ } - -div.admonition p.admonition-title, div.hint p.admonition-title, -div.important p.admonition-title, div.note p.admonition-title, -div.tip p.admonition-title { - font-weight: bold; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } - -div.attention p.admonition-title, div.caution p.admonition-title, -div.danger p.admonition-title, div.error p.admonition-title, -div.warning p.admonition-title, .code .error { - color: #b30000; - font-weight: bold; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } - -/* Uncomment (and remove this text!) to get reduced vertical space in - compound paragraphs. -div.compound .compound-first, div.compound .compound-middle { - margin-bottom: 0.5em } - -div.compound .compound-last, div.compound .compound-middle { - margin-top: 0.5em } -*/ -div.dedication { - margin: 2em 5em; - text-align: center; - font-style: italic; } - -div.dedication p.topic-title { - font-weight: bold; - font-style: normal; } div.figure { margin-left: 2em; @@ -821,8 +498,14 @@ div.figure { div.footer, div.header { clear: both; + text-align: center; + color: #666; font-size: smaller; } +div.footer { + padding-top: 5em; +} + div.line-block { display: block; margin-top: 1em; @@ -833,45 +516,24 @@ div.line-block div.line-block { margin-bottom: 0; margin-left: 1.5em; } -div.sidebar { - margin: 0 0 0.5em 1em; - border: medium outset; - padding: 1em; - background-color: rgba(252, 248, 244, 0.75); - width: 40%; - float: right; - clear: right; } - -div.sidebar p.rubric { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-size: medium; } - -div.system-messages { - margin: 5em; } - -div.system-messages h1 { - color: #b30000; } - -div.system-message { - border: medium outset; - padding: 1em; } - -div.system-message p.system-message-title { - color: #b30000; - font-weight: bold; } - div.topic { margin: 2em; } -h1.section-subtitle, h2.section-subtitle, h3.section-subtitle, -h4.section-subtitle, h5.section-subtitle, h6.section-subtitle { - margin-top: 0.4em; } +div.search_results { + background-color: antiquewhite; + margin: 3em; + padding: 1em; + border: 1px solid #4d4d4d; +} -h1.title { - text-align: center; } +div#global-links ul { + margin-left: 0; + list-style-type: none; +} -h2.subtitle { - text-align: center; } +div#global-links > simple-boot { + margin-left: 3em; +} hr.docutils { width: 75%; } @@ -905,30 +567,6 @@ img.align-center, .figure.align-center, object.align-center { div.align-right { text-align: inherit; } -/* div.align-center * { */ -/* text-align: left } */ - -ul.simple > li { - margin-bottom: 0.5em } - -ol.simple, ul.simple { - margin-bottom: 1em; } - -ol.arabic { - list-style: decimal; } - -ol.loweralpha { - list-style: lower-alpha; } - -ol.upperalpha { - list-style: upper-alpha; } - -ol.lowerroman { - list-style: lower-roman; } - -ol.upperroman { - list-style: upper-roman; } - p.attribution { text-align: right; margin-left: 50%; } @@ -949,15 +587,6 @@ p.rubric { color: maroon; text-align: center; } -p.sidebar-title { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-weight: bold; - font-size: larger; } - -p.sidebar-subtitle { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-weight: bold; } - p.topic-title { font-weight: bold; } @@ -997,22 +626,14 @@ pre.code .inserted, code .inserted { background-color: #A3D289; } span.classifier { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-style: oblique; } span.classifier-delimiter { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: bold; } -span.interpreted { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } - span.option { white-space: nowrap; } -span.pre { - white-space: pre; } - span.problematic { color: #b30000; } @@ -1020,44 +641,6 @@ span.section-subtitle { /* font-size relative to parent (h1..h6 element) */ font-size: 80%; } -table.citation { - border-left: solid 1px #666666; - margin-left: 1px; } - -table.docinfo { - margin: 0em; - margin-top: 2em; - margin-bottom: 2em; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; - color: #444444; } - -table.docutils { - margin-top: 0.5em; - margin-bottom: 0.5em; } - -table.footnote { - border-left: solid 1px #2d2d2d; - margin-left: 1px; } - -table.docutils td, table.docutils th, -table.docinfo td, table.docinfo th { - padding-left: 0.5em; - padding-right: 0.5em; - vertical-align: top; } - -table.docutils th.field-name, table.docinfo th.docinfo-name { - font-weight: 700; - text-align: left; - white-space: nowrap; - padding-left: 0; } - -h1 tt.docutils, h2 tt.docutils, h3 tt.docutils, -h4 tt.docutils, h5 tt.docutils, h6 tt.docutils { - font-size: 100%; } - -ul.auto-toc { - list-style-type: none; } - span.DecNumber { color: #252dbe; } @@ -1074,7 +657,7 @@ span.FloatNumber { color: #252dbe; } span.Identifier { - color: #3b3b3b; } + color: #222; } span.Keyword { font-weight: 600; @@ -1139,38 +722,23 @@ dt pre > span.Identifier, dt pre > span.Operator { color: #155da4; font-weight: 700; } -dt pre > span.Identifier ~ span.Identifier, dt pre > span.Operator ~ span.Identifier { - color: inherit; - font-weight: inherit; } - -dt pre > span.Operator ~ span.Identifier { +dt pre > span.Keyword ~ span.Identifier, dt pre > span.Identifier ~ span.Identifier, +dt pre > span.Operator ~ span.Identifier, dt pre > span.Other ~ span.Identifier { color: inherit; font-weight: inherit; } /* Nim sprite for the footer (taken from main page favicon) */ .nim-sprite { display: inline-block; - height: 12px; - width: 12px; + height: 16px; + width: 16px; background-position: 0 0; - background-size: 12px 12px; + background-size: 16px 16px; -webkit-filter: opacity(50%); background-repeat: no-repeat; background-image: url("data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="); margin-bottom: -5px; } -div.search_results { - background-color: antiquewhite; - margin: 3em; - padding: 1em; - border: 1px solid #4d4d4d; -} - -div#global-links ul { - margin-left: 0; - list-style-type: none; -} - span.pragmadots { /* Position: relative frees us up to make the dots look really nice without fucking up the layout and @@ -1178,18 +746,14 @@ span.pragmadots { position: relative; /* 1px down looks slightly nicer */ top: 1px; - padding: 2px; - background-color: #D3D3D3; + background-color: #e8e8e8; border-radius: 4px; margin: 0 2px; cursor: pointer; - - /* For some reason on Chrome, making the font size - smaller than 1em is causing the parent container to - bulge slightly. So, we're stuck with inheriting 1em, - which is sad, because 0.8em looks better... */ + font-size: 0.8em; } + span.pragmadots:hover { background-color: #DBDBDB; } @@ -1287,7 +851,7 @@ function main() { diff --git a/plugin.idx b/plugin.idx old mode 100644 new mode 100755 diff --git a/theindex.html b/theindex.html new file mode 100755 index 0000000..add5db3 --- /dev/null +++ b/theindex.html @@ -0,0 +1,936 @@ + + + + + + + + + + + + + + + + + +Index + + + + + + + + +
      +
      +

      Index

      + Modules: cimport, git, paths, plugin, types.

      API symbols

      +
      cAddSearchDir:
      +
      cAddStdDir:
      +
      cCompile:
      +
      cDebug:
      +
      cDefine:
      +
      cDisableCaching:
      +
      cImport:
      +
      cIncludeDir:
      +
      cOverride:
      +
      cpFile:
      +
      cPlugin:
      +
      cSearchPath:
      +
      cSkipSymbol:
      +
      defineEnum:
      +
      downloadUrl:
      +
      enumOp:
      +
      execAction:
      +
      extractZip:
      +
      gitCheckout:
      +
      gitPull:
      +
      gitReset:
      +
      incDir:
      +
      mkDir:
      +
      mvFile:
      +
      nimteropBuildDir:
      +
      nimteropRoot:
      +
      nimteropSrcDir:
      +
      OnSymbol:
      +
      ptrdiff_t:
      +
      Symbol:
      +
      testsIncludeDir:
      +
      time_t:
      +
      toastExePath:
      +
      va_list:
      +
      +
      + +
      +
      +
      + + + diff --git a/types.html b/types.html old mode 100644 new mode 100755 index 9914a3f..654188c --- a/types.html +++ b/types.html @@ -27,232 +27,113 @@ customize this style sheet. Modified from Chad Skeeters' rst2html-style https://bitbucket.org/cskeeters/rst2html-style/ -Modified by Boyd Greenfield +Modified by Boyd Greenfield and narimiran */ -/* SCSS variables */ -/* Text weights */ -/* Body colors */ -/* Text colors */ -/* Link colors */ -/* Syntax highlighting colors */ -/* Pct changes */ -/* Mixins */ -/* Body/layout */ + html { font-size: 100%; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; } -/* Where we want fancier font if available */ -h1, h2, h3, h4, h5, h6, p.module-desc, table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; } - -h1.title { - font-weight: 900; } - body { font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: 400; - font-size: 16px; - line-height: 20px; - color: #444; - letter-spacing: 0.15px; - background-color: #FDFBFA; } + font-size: 1.125em; + line-height: 1.5; + color: #222; + background-color: #FCFCFC; } /* Skeleton grid */ .container { position: relative; width: 100%; - max-width: 960px; + max-width: 1050px; margin: 0 auto; - padding: 0 20px; + padding: 0; box-sizing: border-box; } .column, .columns { width: 100%; float: left; - box-sizing: border-box; } + box-sizing: border-box; + margin-left: 1%; +} -/* For devices larger than 400px */ -@media (min-width: 400px) { - .container { - width: 100%; - padding: 0; } } -/* For devices larger than 650px */ -@media (min-width: 650px) { - .container { - width: 100%; } +.column:first-child, +.columns:first-child { + margin-left: 0; } - .column, - .columns { - margin-left: 4%; } +.three.columns { + width: 19%; } - .column:first-child, - .columns:first-child { - margin-left: 0; } +.nine.columns { + width: 80.0%; } - .one.column, - .one.columns { - width: 4.66666666667%; } - - .two.columns { - width: 13.3333333333%; } +.twelve.columns { + width: 100%; + margin-left: 0; } +@media screen and (max-width: 860px) { .three.columns { - width: 22%; } - - .four.columns { - width: 30.6666666667%; } - - .five.columns { - width: 39.3333333333%; } - - .six.columns { - width: 48%; } - - .seven.columns { - width: 56.6666666667%; } - - .eight.columns { - width: 65.3333333333%; } - + display: none; + } .nine.columns { - width: 74.0%; } - - .ten.columns { - width: 82.6666666667%; } - - .eleven.columns { - width: 91.3333333333%; } - - .twelve.columns { - width: 100%; - margin-left: 0; } - - .one-third.column { - width: 30.6666666667%; } - - .two-thirds.column { - width: 65.3333333333%; } } -/* Customer Overrides */ -.footer { - text-align: center; - color: #969696; - padding-top: 10%; } - -p.module-desc { - font-size: 1.1em; - color: #666666; } - -a.link-seesrc { - color: #aec7d2; - font-style: italic; } - -a.link-seesrc:hover { - color: #6c9aae; } - -#toc-list { - word-wrap: break-word; } - -ul.simple-toc { - list-style: none; } - -ul.simple-toc a.reference-toplevel { - font-weight: bold; - color: #0077b3; } - -ul.simple-toc-section { - list-style-type: circle; - color: #6c9aae; } - -ul.simple-toc-section a.reference { - color: #0077b3; } + width: 98.0%; + } + body { + font-size: 1em; + line-height: 1.35; + } +} cite { font-style: italic !important; } -dt > pre { - border-color: rgba(0, 0, 0, 0.1); - background-color: rgba(255, 255, 255, 0.3); - margin: 15px 0px 5px; } - -dd > pre { - border-color: rgba(0, 0, 0, 0.1); - background-color: whitesmoke; - margin-top: 8px; } - -.item > dd { - margin-left: 10px; - margin-bottom: 30px; } - -/* Nim line-numbered tables */ -.line-nums-table { - width: 100%; - table-layout: fixed; } /* Nim search input */ div#searchInputDiv { - margin-bottom: 8px; + margin-bottom: 1em; } -div#searchInputDiv input#searchInput { - width: 10em; -} -div.search-groupby { - margin-bottom: 8px; +input#searchInput { + width: 80%; } -table.line-nums-table { - border-radius: 4px; - border: 1px solid #cccccc; - background-color: whitesmoke; - border-collapse: separate; - margin-top: 15px; - margin-bottom: 25px; } - -.line-nums-table tbody { - border: none; } - -.line-nums-table td pre { - border: none; - background-color: transparent; } - -.line-nums-table td.blob-line-nums { - width: 28px; } - -.line-nums-table td.blob-line-nums pre { - color: #b0b0b0; - -webkit-filter: opacity(75%); - text-align: right; - border-color: transparent; - background-color: transparent; - padding-left: 0px; - margin-left: 0px; - padding-right: 0px; - margin-right: 0px; } /* Docgen styles */ /* Links */ a { - color: #0077b3; - text-decoration: none; } + color: #07b; + text-decoration: none; +} + +a span.Identifier { + text-decoration: underline; + text-decoration-color: #aab; +} + +a.reference-toplevel { + font-weight: bold; +} + +a.toc-backref { + text-decoration: none; + color: #222; } + +a.link-seesrc { + color: #607c9f; + font-size: 0.9em; + font-style: italic; } a:hover, a:focus { - color: #00334d; + color: #607c9f; text-decoration: underline; } -a:visited { - color: #00334d; } +a:hover span.Identifier { + color: #607c9f; +} -a:focus { - outline: thin dotted #2d2d2d; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; } - -a:hover, -a:active { - outline: 0; } sub, sup { @@ -329,379 +210,258 @@ img { h2, h3 { - page-break-after: avoid; } } -.img-rounded { - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; } + page-break-after: avoid; } +} -.img-polaroid { - padding: 4px; - background-color: rgba(252, 248, 244, 0.75); - border: 1px solid #ccc; - border: 1px solid rgba(0, 0, 0, 0.2); - -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); - -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); } p { - margin: 0 0 8px; } + margin-top: 0.5em; + margin-bottom: 0.5em; +} small { font-size: 85%; } strong { - font-weight: 600; } + font-weight: 600; + font-size: 0.95em; + color: #3c3c3c; +} em { font-style: italic; } -cite { - font-style: normal; } - -h1, -h2, -h3, -h4, -h5, -h6 { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-weight: 600; - line-height: 20px; - color: inherit; - text-rendering: optimizelegibility; } - h1 { - font-size: 2em; + font-size: 1.8em; font-weight: 400; - padding-bottom: .15em; - border-bottom: 1px solid #aaaaaa; - margin-top: 1.0em; + padding-bottom: .25em; + border-bottom: 1px solid #aaa; + margin-top: 2.5em; + margin-bottom: 1em; line-height: 1.2em; } h1.title { padding-bottom: 1em; border-bottom: 0px; - font-size: 2.75em; } + font-size: 2.5em; + text-align: center; + font-weight: 900; + margin-top: 0.75em; + margin-bottom: 0em; +} h2 { - font-size: 1.5em; - margin-top: 1.5em; } + font-size: 1.3em; + margin-top: 2em; } + +h2.subtitle { + text-align: center; } h3 { - font-size: 1.3em; + font-size: 1.125em; font-style: italic; - margin-top: 0.75em; } + margin-top: 1.5em; } h4 { - font-size: 1.3em; - margin-top: 0.5em; } + font-size: 1.125em; + margin-top: 1em; } h5 { - font-size: 1.2em; - margin-top: 0.25em; } + font-size: 1.125em; + margin-top: 0.75em; } h6 { font-size: 1.1em; } + ul, ol { padding: 0; - margin: 0 0 0px 15px; } + margin-top: 0.5em; + margin-left: 0.75em; } ul ul, ul ol, ol ol, ol ul { - margin-bottom: 0; } + margin-bottom: 0; + margin-left: 1.25em; } li { - line-height: 20px; } - -dl { - margin-bottom: 20px; } - -dt, -dd { - line-height: 20px; } - -dt { - font-weight: bold; } - -dd { - margin-left: 10px; - margin-bottom: 26px; } - -hr { - margin: 20px 0; - border: 0; - border-top: 1px solid #eeeeee; - border-bottom: 1px solid #ffffff; } - -abbr[title], -abbr[data-original-title] { - cursor: help; - border-bottom: 1px dotted #999999; } - -abbr.initialism { - font-size: 90%; - text-transform: uppercase; } - -blockquote { - padding: 0 0 0 15px; - margin: 0 0 20px; - border-left: 5px solid #EFEBE0; } - -table.docinfo + blockquote, table.docinfo blockquote, h1 + blockquote { - border-left: 5px solid #c9c9c9; + list-style-type: circle; } -table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { - margin-bottom: 0; - font-size: 15px; - font-weight: 200; - line-height: 1.5; - font-style: italic; } +ul.simple-boot li { + list-style-type: none; + margin-left: 0em; + margin-bottom: 0.5em; +} -q:before, -q:after, -blockquote:before, -blockquote:after { - content: ""; } +ol.simple > li, ul.simple > li { + margin-bottom: 0.25em; + margin-left: 0.4em } -address { - display: block; - margin-bottom: 20px; - font-style: normal; - line-height: 20px; } +ul.simple.simple-toc > li { + margin-top: 1em; +} -code, -pre { - font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - padding: 0 3px 2px; - font-weight: 500; - font-size: 12px; - color: #444444; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; } +ul.simple-toc { + list-style: none; + font-size: 0.9em; + margin-left: -0.3em; + margin-top: 1em; } + +ul.simple-toc > li { + list-style-type: none; +} + +ul.simple-toc-section { + list-style-type: circle; + margin-left: 1em; + color: #6c9aae; } + + +ol.arabic { + list-style: decimal; } + +ol.loweralpha { + list-style: lower-alpha; } + +ol.upperalpha { + list-style: upper-alpha; } + +ol.lowerroman { + list-style: lower-roman; } + +ol.upperroman { + list-style: upper-roman; } + +ul.auto-toc { + list-style-type: none; } + + +dl { + margin-bottom: 1.5em; } + +dt { + margin-bottom: -0.5em; + margin-left: 0.5em; } + +dd { + margin-left: 0.5em; + margin-bottom: 2.5em; + margin-top: 0.5em; } + + +hr { + margin: 2em 0; + border: 0; + border-top: 1px solid #aaa; } + +blockquote { + font-size: 0.9em; + font-style: italic; + padding-left: 0.5em; + margin-left: 0; + border-left: 5px solid #bbc; +} .pre { font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - font-weight: 600; - /*color: #504da6;*/ + font-weight: 500; + font-size: 0.85em; + background-color: #f0f3ff; + padding-left: 3px; + padding-right: 3px; + border-radius: 4px; } -code { - padding: 2px 4px; - color: #444444; - white-space: nowrap; - background-color: white; - border: 1px solid #777777; } - pre { + font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; + color: #222; + font-weight: 500; display: inline-block; box-sizing: border-box; - min-width: calc(100% - 19.5px); - padding: 9.5px; - margin: 0.25em 10px 10px 10px; - font-size: 15px; - line-height: 20px; + min-width: 100%; + padding: 0.5em; + margin-top: 0.5em; + margin-bottom: 0.5em; + font-size: 0.85em; white-space: pre !important; overflow-y: hidden; overflow-x: visible; - background-color: rgba(0, 0, 0, 0.01); - border: 1px solid #cccccc; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; } - -pre.prettyprint { - margin-bottom: 20px; } - -pre code { - padding: 0; - color: inherit; - white-space: pre; - overflow-x: visible; - background-color: transparent; - border: 0; } + background-color: ghostwhite; + border: 1px solid #dde; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; } .pre-scrollable { max-height: 340px; overflow-y: scroll; } + +/* Nim line-numbered tables */ +.line-nums-table { + width: 100%; + table-layout: fixed; } + +table.line-nums-table { + border-radius: 4px; + border: 1px solid #cccccc; + background-color: ghostwhite; + border-collapse: separate; + margin-top: 15px; + margin-bottom: 25px; } + +.line-nums-table tbody { + border: none; } + +.line-nums-table td pre { + border: none; + background-color: transparent; } + +.line-nums-table td.blob-line-nums { + width: 28px; } + +.line-nums-table td.blob-line-nums pre { + color: #b0b0b0; + -webkit-filter: opacity(75%); + text-align: right; + border-color: transparent; + background-color: transparent; + padding-left: 0px; + margin-left: 0px; + padding-right: 0px; + margin-right: 0px; } + + table { max-width: 100%; background-color: transparent; + margin-top: 0.5em; + margin-bottom: 1.5em; border-collapse: collapse; - border-spacing: 0; } - -table th, table td { - padding: 0px 8px 0px; + border-color: #ccc; + border-spacing: 0; + font-size: 0.9em; } -.table { - width: 100%; - margin-bottom: 20px; } +table th, table td { + padding: 0px 0.5em 0px; +} -.table th, -.table td { - padding: 8px; - line-height: 20px; - text-align: left; - vertical-align: top; - border-top: 1px solid #444444; } - -.table th { +table th { + background-color: #e8e8e8; font-weight: bold; } -.table thead th { - vertical-align: bottom; } +table th.docinfo-name { + background-color: transparent; +} -.table caption + thead tr:first-child th, -.table caption + thead tr:first-child td, -.table colgroup + thead tr:first-child th, -.table colgroup + thead tr:first-child td, -.table thead:first-child tr:first-child th, -.table thead:first-child tr:first-child td { - border-top: 0; } +table tr:hover { + background-color: ghostwhite; } -.table tbody + tbody { - border-top: 2px solid #444444; } - -.table .table { - background-color: rgba(252, 248, 244, 0.75); } - -.table-condensed th, -.table-condensed td { - padding: 4px 5px; } - -.table-bordered { - border: 1px solid #444444; - border-collapse: separate; - *border-collapse: collapse; - border-left: 0; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; } - -.table-bordered th, -.table-bordered td { - border-left: 1px solid #444444; } - -.table-bordered caption + thead tr:first-child th, -.table-bordered caption + tbody tr:first-child th, -.table-bordered caption + tbody tr:first-child td, -.table-bordered colgroup + thead tr:first-child th, -.table-bordered colgroup + tbody tr:first-child th, -.table-bordered colgroup + tbody tr:first-child td, -.table-bordered thead:first-child tr:first-child th, -.table-bordered tbody:first-child tr:first-child th, -.table-bordered tbody:first-child tr:first-child td { - border-top: 0; } - -.table-bordered thead:first-child tr:first-child > th:first-child, -.table-bordered tbody:first-child tr:first-child > td:first-child, -.table-bordered tbody:first-child tr:first-child > th:first-child { - -webkit-border-top-left-radius: 4px; - border-top-left-radius: 4px; - -moz-border-radius-topleft: 4px; } - -.table-bordered thead:first-child tr:first-child > th:last-child, -.table-bordered tbody:first-child tr:first-child > td:last-child, -.table-bordered tbody:first-child tr:first-child > th:last-child { - -webkit-border-top-right-radius: 4px; - border-top-right-radius: 4px; - -moz-border-radius-topright: 4px; } - -.table-bordered thead:last-child tr:last-child > th:first-child, -.table-bordered tbody:last-child tr:last-child > td:first-child, -.table-bordered tbody:last-child tr:last-child > th:first-child, -.table-bordered tfoot:last-child tr:last-child > td:first-child, -.table-bordered tfoot:last-child tr:last-child > th:first-child { - -webkit-border-bottom-left-radius: 4px; - border-bottom-left-radius: 4px; - -moz-border-radius-bottomleft: 4px; } - -.table-bordered thead:last-child tr:last-child > th:last-child, -.table-bordered tbody:last-child tr:last-child > td:last-child, -.table-bordered tbody:last-child tr:last-child > th:last-child, -.table-bordered tfoot:last-child tr:last-child > td:last-child, -.table-bordered tfoot:last-child tr:last-child > th:last-child { - -webkit-border-bottom-right-radius: 4px; - border-bottom-right-radius: 4px; - -moz-border-radius-bottomright: 4px; } - -.table-bordered tfoot + tbody:last-child tr:last-child td:first-child { - -webkit-border-bottom-left-radius: 0; - border-bottom-left-radius: 0; - -moz-border-radius-bottomleft: 0; } - -.table-bordered tfoot + tbody:last-child tr:last-child td:last-child { - -webkit-border-bottom-right-radius: 0; - border-bottom-right-radius: 0; - -moz-border-radius-bottomright: 0; } - -.table-bordered caption + thead tr:first-child th:first-child, -.table-bordered caption + tbody tr:first-child td:first-child, -.table-bordered colgroup + thead tr:first-child th:first-child, -.table-bordered colgroup + tbody tr:first-child td:first-child { - -webkit-border-top-left-radius: 4px; - border-top-left-radius: 4px; - -moz-border-radius-topleft: 4px; } - -.table-bordered caption + thead tr:first-child th:last-child, -.table-bordered caption + tbody tr:first-child td:last-child, -.table-bordered colgroup + thead tr:first-child th:last-child, -.table-bordered colgroup + tbody tr:first-child td:last-child { - -webkit-border-top-right-radius: 4px; - border-top-right-radius: 4px; - -moz-border-radius-topright: 4px; } - -table.docutils th { - background-color: #e8e8e8; } - -table.docutils tr:hover { - background-color: whitesmoke; } - -.table-striped tbody > tr:nth-child(odd) > td, -.table-striped tbody > tr:nth-child(odd) > th { - background-color: rgba(252, 248, 244, 0.75); } - -.table-hover tbody tr:hover > td, -.table-hover tbody tr:hover > th { - background-color: rgba(241, 222, 204, 0.75); } - -table td[class*="span"], -table th[class*="span"], -.row-fluid table td[class*="span"], -.row-fluid table th[class*="span"] { - display: table-cell; - float: none; - margin-left: 0; } - -.hero-unit { - padding: 60px; - margin-bottom: 30px; - font-size: 18px; - font-weight: 200; - line-height: 30px; - color: inherit; - background-color: rgba(230, 197, 164, 0.75); - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; } - -.hero-unit h1 { - margin-bottom: 0; - font-size: 60px; - line-height: 1; - letter-spacing: -1px; - color: inherit; } - -.hero-unit li { - line-height: 30px; } /* rst2html default used to remove borders from tables and images */ .borderless, table.borderless td, table.borderless th { @@ -722,10 +482,6 @@ table.borderless td, table.borderless th { .hidden { display: none; } -a.toc-backref { - text-decoration: none; - color: #444444; } - blockquote.epigraph { margin: 2em 5em; } @@ -735,85 +491,6 @@ dl.docutils dd { object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] { overflow: hidden; } -/* Uncomment (and remove this text!) to get bold-faced definition list terms -dl.docutils dt { - font-weight: bold } -*/ -div.abstract { - margin: 2em 5em; } - -div.abstract p.topic-title { - font-weight: bold; - text-align: center; } - -div.admonition, div.attention, div.caution, div.danger, div.error, -div.hint, div.important, div.note, div.tip, div.warning { - margin: 2em; - border: medium outset; - padding: 1em; } - -div.note, div.warning { - margin: 1.5em 0px; - border: none; } - -div.note p.admonition-title, -div.warning p.admonition-title { - display: none; } - -/* Clearfix - * http://css-tricks.com/snippets/css/clear-fix/ - */ -div.note:after, -div.warning:after { - content: ""; - display: table; - clear: both; } - -div.note p:before, -div.warning p:before { - display: block; - float: left; - font-size: 4em; - line-height: 1em; - margin-right: 20px; - margin-left: 0em; - margin-top: -10px; - content: '\0270D'; - /*handwriting*/ } - -div.warning p:before { - content: '\026A0'; - /*warning*/ } - -div.admonition p.admonition-title, div.hint p.admonition-title, -div.important p.admonition-title, div.note p.admonition-title, -div.tip p.admonition-title { - font-weight: bold; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } - -div.attention p.admonition-title, div.caution p.admonition-title, -div.danger p.admonition-title, div.error p.admonition-title, -div.warning p.admonition-title, .code .error { - color: #b30000; - font-weight: bold; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } - -/* Uncomment (and remove this text!) to get reduced vertical space in - compound paragraphs. -div.compound .compound-first, div.compound .compound-middle { - margin-bottom: 0.5em } - -div.compound .compound-last, div.compound .compound-middle { - margin-top: 0.5em } -*/ -div.dedication { - margin: 2em 5em; - text-align: center; - font-style: italic; } - -div.dedication p.topic-title { - font-weight: bold; - font-style: normal; } div.figure { margin-left: 2em; @@ -821,8 +498,14 @@ div.figure { div.footer, div.header { clear: both; + text-align: center; + color: #666; font-size: smaller; } +div.footer { + padding-top: 5em; +} + div.line-block { display: block; margin-top: 1em; @@ -833,45 +516,24 @@ div.line-block div.line-block { margin-bottom: 0; margin-left: 1.5em; } -div.sidebar { - margin: 0 0 0.5em 1em; - border: medium outset; - padding: 1em; - background-color: rgba(252, 248, 244, 0.75); - width: 40%; - float: right; - clear: right; } - -div.sidebar p.rubric { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-size: medium; } - -div.system-messages { - margin: 5em; } - -div.system-messages h1 { - color: #b30000; } - -div.system-message { - border: medium outset; - padding: 1em; } - -div.system-message p.system-message-title { - color: #b30000; - font-weight: bold; } - div.topic { margin: 2em; } -h1.section-subtitle, h2.section-subtitle, h3.section-subtitle, -h4.section-subtitle, h5.section-subtitle, h6.section-subtitle { - margin-top: 0.4em; } +div.search_results { + background-color: antiquewhite; + margin: 3em; + padding: 1em; + border: 1px solid #4d4d4d; +} -h1.title { - text-align: center; } +div#global-links ul { + margin-left: 0; + list-style-type: none; +} -h2.subtitle { - text-align: center; } +div#global-links > simple-boot { + margin-left: 3em; +} hr.docutils { width: 75%; } @@ -905,30 +567,6 @@ img.align-center, .figure.align-center, object.align-center { div.align-right { text-align: inherit; } -/* div.align-center * { */ -/* text-align: left } */ - -ul.simple > li { - margin-bottom: 0.5em } - -ol.simple, ul.simple { - margin-bottom: 1em; } - -ol.arabic { - list-style: decimal; } - -ol.loweralpha { - list-style: lower-alpha; } - -ol.upperalpha { - list-style: upper-alpha; } - -ol.lowerroman { - list-style: lower-roman; } - -ol.upperroman { - list-style: upper-roman; } - p.attribution { text-align: right; margin-left: 50%; } @@ -949,15 +587,6 @@ p.rubric { color: maroon; text-align: center; } -p.sidebar-title { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-weight: bold; - font-size: larger; } - -p.sidebar-subtitle { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-weight: bold; } - p.topic-title { font-weight: bold; } @@ -997,22 +626,14 @@ pre.code .inserted, code .inserted { background-color: #A3D289; } span.classifier { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-style: oblique; } span.classifier-delimiter { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: bold; } -span.interpreted { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } - span.option { white-space: nowrap; } -span.pre { - white-space: pre; } - span.problematic { color: #b30000; } @@ -1020,44 +641,6 @@ span.section-subtitle { /* font-size relative to parent (h1..h6 element) */ font-size: 80%; } -table.citation { - border-left: solid 1px #666666; - margin-left: 1px; } - -table.docinfo { - margin: 0em; - margin-top: 2em; - margin-bottom: 2em; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; - color: #444444; } - -table.docutils { - margin-top: 0.5em; - margin-bottom: 0.5em; } - -table.footnote { - border-left: solid 1px #2d2d2d; - margin-left: 1px; } - -table.docutils td, table.docutils th, -table.docinfo td, table.docinfo th { - padding-left: 0.5em; - padding-right: 0.5em; - vertical-align: top; } - -table.docutils th.field-name, table.docinfo th.docinfo-name { - font-weight: 700; - text-align: left; - white-space: nowrap; - padding-left: 0; } - -h1 tt.docutils, h2 tt.docutils, h3 tt.docutils, -h4 tt.docutils, h5 tt.docutils, h6 tt.docutils { - font-size: 100%; } - -ul.auto-toc { - list-style-type: none; } - span.DecNumber { color: #252dbe; } @@ -1074,7 +657,7 @@ span.FloatNumber { color: #252dbe; } span.Identifier { - color: #3b3b3b; } + color: #222; } span.Keyword { font-weight: 600; @@ -1139,38 +722,23 @@ dt pre > span.Identifier, dt pre > span.Operator { color: #155da4; font-weight: 700; } -dt pre > span.Identifier ~ span.Identifier, dt pre > span.Operator ~ span.Identifier { - color: inherit; - font-weight: inherit; } - -dt pre > span.Operator ~ span.Identifier { +dt pre > span.Keyword ~ span.Identifier, dt pre > span.Identifier ~ span.Identifier, +dt pre > span.Operator ~ span.Identifier, dt pre > span.Other ~ span.Identifier { color: inherit; font-weight: inherit; } /* Nim sprite for the footer (taken from main page favicon) */ .nim-sprite { display: inline-block; - height: 12px; - width: 12px; + height: 16px; + width: 16px; background-position: 0 0; - background-size: 12px 12px; + background-size: 16px 16px; -webkit-filter: opacity(50%); background-repeat: no-repeat; background-image: url("data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="); margin-bottom: -5px; } -div.search_results { - background-color: antiquewhite; - margin: 3em; - padding: 1em; - border: 1px solid #4d4d4d; -} - -div#global-links ul { - margin-left: 0; - list-style-type: none; -} - span.pragmadots { /* Position: relative frees us up to make the dots look really nice without fucking up the layout and @@ -1178,18 +746,14 @@ span.pragmadots { position: relative; /* 1px down looks slightly nicer */ top: 1px; - padding: 2px; - background-color: #D3D3D3; + background-color: #e8e8e8; border-radius: 4px; margin: 0 2px; cursor: pointer; - - /* For some reason on Chrome, making the font size - smaller than 1em is causing the parent container to - bulge slightly. So, we're stuck with inheriting 1em, - which is sad, because 0.8em looks better... */ + font-size: 0.8em; } + span.pragmadots:hover { background-color: #DBDBDB; } @@ -1242,7 +806,7 @@ function main() { Types @@ -1271,7 +835,7 @@ function main() {

      Types

      -
      time_t = Time
      +
      time_t = time_t_temp.Time
      @@ -1294,13 +858,13 @@ function main() {

      Templates

      -
      template enumOp(op, typ, typout)
      +
      template enumOp(op, typ, typout)
      - -
      template defineEnum(typ)
      + +
      template defineEnum(typ)
      @@ -1315,7 +879,7 @@ function main() { diff --git a/types.idx b/types.idx old mode 100644 new mode 100755 index d4ab217..5bc0938 --- a/types.idx +++ b/types.idx @@ -2,4 +2,4 @@ time_t types.html#time_t types: time_t ptrdiff_t types.html#ptrdiff_t types: ptrdiff_t va_list types.html#va_list types: va_list enumOp types.html#enumOp.t,,, types: enumOp(op, typ, typout) -defineEnum types.html#defineEnum.t, types: defineEnum(typ) +defineEnum types.html#defineEnum.t types: defineEnum(typ) From 1c8aa85ee793508bd861bfd556161779c8e41047 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Fri, 8 Feb 2019 16:37:05 -0600 Subject: [PATCH 171/593] Update documentation From 8bda9049d0caf7a90474f3733057c5bd8f97b332 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Fri, 8 Feb 2019 16:37:17 -0600 Subject: [PATCH 172/593] Update documentation From 5e212ce60634e2ab670819541b7a25fdd422de0e Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Fri, 8 Feb 2019 14:48:24 -0800 Subject: [PATCH 173/593] make relativePath more robust (#115) --- nimterop/all.nim | 2 +- nimterop/compat.nim | 24 ++++++++++++++++++++++++ nimterop/git.nim | 12 +----------- 3 files changed, 26 insertions(+), 12 deletions(-) create mode 100644 nimterop/compat.nim diff --git a/nimterop/all.nim b/nimterop/all.nim index dd42c03..78249a1 100644 --- a/nimterop/all.nim +++ b/nimterop/all.nim @@ -4,4 +4,4 @@ Module that should import everything so that `nim doc --project nimtero/all` run # TODO: make sure it does import everything. -import "."/[cimport, git, types, plugin] +import "."/[cimport, git, types, plugin, compat] diff --git a/nimterop/compat.nim b/nimterop/compat.nim new file mode 100644 index 0000000..7f89358 --- /dev/null +++ b/nimterop/compat.nim @@ -0,0 +1,24 @@ +#[ +module for backward compatibility +put everything that requires `when (NimMajor, NimMinor, NimPatch)` here +]# + +import os + +when (NimMajor, NimMinor, NimPatch) >= (0, 19, 9): + export relativePath +else: + import std/[ospaths,strutils] + + proc relativePath*(file, base: string): string = + ## naive version of `os.relativePath` ; remove after nim >= 0.19.9 + runnableExamples: + import ospaths, unittest + check: + "/foo/bar/baz/log.txt".unixToNativePath.relativePath("/foo/bar".unixToNativePath) == "baz/log.txt".unixToNativePath + "foo/bar/baz/log.txt".unixToNativePath.relativePath("foo/bar".unixToNativePath) == "baz/log.txt".unixToNativePath + var base = base.normalizedPath + var file = file.normalizedPath + if not base.endsWith DirSep: base.add DirSep + doAssert file.startsWith base + result = file[base.len .. ^1] diff --git a/nimterop/git.nim b/nimterop/git.nim index 1d28179..c51c079 100644 --- a/nimterop/git.nim +++ b/nimterop/git.nim @@ -1,6 +1,6 @@ import macros, os, osproc, regex, strformat, strutils -import "."/paths +import "."/[paths, compat] proc execAction*(cmd: string, nostderr=false): string = var @@ -49,16 +49,6 @@ proc cpFile*(source, dest: string, move=false) = proc mvFile*(source, dest: string) = cpFile(source, dest, move=true) -when (NimMajor, NimMinor, NimPatch) < (0, 19, 9): - proc relativePath*(file, base: string): string = - ## naive version of `os.relativePath` ; remove after nim >= 0.19.9 - runnableExamples: - doAssert "/foo/bar/baz/log.txt".relativePath("/foo/bar") == "baz/log.txt" - var base = base - if not base.endsWith "/": base.add "/" - doAssert file.startsWith base - result = file[base.len .. ^1] - proc extractZip*(zipfile, outdir: string) = var cmd = "unzip -o $#" if defined(Windows): From fcc1dde1239ca6c7c553a2252a93177d62cf18a1 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Tue, 12 Feb 2019 15:34:03 -0800 Subject: [PATCH 174/593] fix some links nimgen,genotrance => nimterop (#118) --- README.md | 13 +++++++------ nimterop/cimport.nim | 4 ++-- nimterop/types.nim | 2 +- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 320cbd2..80b6877 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,9 @@ -[![Chat on Gitter](https://badges.gitter.im/gitterHQ/gitter.png)](https://gitter.im/nimgen/Lobby) +[![Chat on Gitter](https://badges.gitter.im/gitterHQ/gitter.png)](https://gitter.im/nimterop/Lobby) [![Build status](https://ci.appveyor.com/api/projects/status/hol1yvqbp6hq4ao8/branch/master?svg=true)](https://ci.appveyor.com/project/genotrance/nimterop-8jcj7/branch/master) [![Build Status](https://travis-ci.org/nimterop/nimterop.svg?branch=master)](https://travis-ci.org/nimterop/nimterop) +Detailed documentation [here](https://nimterop.github.io/nimterop/theindex.html). + Nimterop is a [Nim](https://nim-lang.org/) package that aims to make C/C++ interop seamless Nim has one of the best FFI you can find - importing C/C++ is supported out of the box. All you need to provide is type and proc definitions for Nim to interop with C/C++ binaries. Generation of these wrappers is easy for simple libraries but quickly gets out of hand. [c2nim](https://github.com/nim-lang/c2nim) greatly helps here by parsing and converting C/C++ into Nim but is limited due to the complex and constantly evolving C/C++ grammar. [nimgen](https://github.com/genotrance/nimgen) mainly focuses on automating the wrapping process and fills some holes but is again limited to c2nim's capabilities. @@ -25,8 +27,9 @@ nimble install nimterop -y ``` or: ```bash -git clone http://github.com/genotrance/nimterop && cd nimterop -nimble install -y +git clone http://github.com/nimterop/nimterop && cd nimterop +nimble develop -y +nimble build ``` This will download and install nimterop in the standard Nimble package location, typically `~/.nimble`. Once installed, it can be imported into any Nim program. Note that the `~/.nimble/bin` directory needs to be added to the `PATH` for nimterop to work. @@ -50,8 +53,6 @@ Refer to the ```tests``` directory for examples on how the library can be used. The `toast` binary can also be used directly on the CLI. The `--help` flag provides more details. -Detailed documentation is available: [cimport](https://genotrance.github.io/nimterop/cimport.html), [plugin](https://genotrance.github.io/nimterop/plugin.html), [git](https://genotrance.github.io/nimterop/git.html) - __Implementation Details__ In order to use the tree-sitter C library, it has to be compiled into a separate binary called `toast` (to AST) since the Nim VM doesn't yet support FFI. `toast` takes a C/C++ file and runs it through the tree-sitter API which returns an AST data structure. This can then be printed out to stdout in a Lisp S-Expression format or the relevant Nim wrapper output. This content can be saved to a `.nim` file and imported if so desired. @@ -68,4 +69,4 @@ Nimterop depends on [tree-sitter](http://tree-sitter.github.io/tree-sitter/) and __Feedback__ -Nimterop is a work in progress and any feedback or suggestions are welcome. It is hosted on [GitHub](https://github.com/genotrance/nimterop) with an MIT license so issues, forks and PRs are most appreciated. +Nimterop is a work in progress and any feedback or suggestions are welcome. It is hosted on [GitHub](https://github.com/nimterop/nimterop) with an MIT license so issues, forks and PRs are most appreciated. diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index 4950d7b..90b10d8 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -139,7 +139,7 @@ proc getToast(fullpath: string, recurse: bool = false): string = cmd.add &" {fullpath.quoteShell}" echo cmd - # see https://github.com/genotrance/nimterop/issues/69 + # see https://github.com/nimterop/nimterop/issues/69 (result, ret) = gorgeEx(cmd, cache=getCacheValue(fullpath)) doAssert ret == 0, getToastError(result) @@ -297,7 +297,7 @@ macro cDefine*(name: static string, val: static string = ""): untyped = result = newNimNode(nnkStmtList) var str = name - # todo: see https://github.com/genotrance/nimterop/issues/100 for + # todo: see https://github.com/nimterop/nimterop/issues/100 for # edge case of empty strings if val.nBl: str &= &"={val.quoteShell}" diff --git a/nimterop/types.nim b/nimterop/types.nim index 17b4795..d161ddb 100644 --- a/nimterop/types.nim +++ b/nimterop/types.nim @@ -1,4 +1,4 @@ -# see https://github.com/genotrance/nimterop/issues/79 +# see https://github.com/nimterop/nimterop/issues/79 when (NimMajor, NimMinor, NimPatch) < (0, 19, 9): # clean this up once upgraded; adapted from std/time_t From fc1bc78250432059edd552679b3efbb0e99a302c Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 7 Mar 2019 12:21:31 -0600 Subject: [PATCH 175/593] Fix powershell TLS issue with download --- nimterop/git.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimterop/git.nim b/nimterop/git.nim index c51c079..9998a44 100644 --- a/nimterop/git.nim +++ b/nimterop/git.nim @@ -68,7 +68,7 @@ proc downloadUrl*(url, outdir: string) = echo "Downloading " & file mkDir(outdir) var cmd = if defined(Windows): - "powershell wget $# -OutFile $#" + "powershell [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; wget $# -OutFile $#" else: "curl $# -o $#" discard execAction(cmd % [url, outdir/file]) From 295e838bc18aa52c5213ed2172f615511bf7a906 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 14 Mar 2019 10:46:13 -0500 Subject: [PATCH 176/593] Fix include of stdlib in recurse --- nimterop/getters.nim | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 63836e3..8504d34 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -226,7 +226,9 @@ proc getPreprocessor*(fullpath: string, mode = "cpp"): string = elif not ("\\" in line) and not ("/" in line) and extractFilename(sfile) in line: start = true elif gStateRT.recurse: - if sfile.parentDir() in saniLine: + let + pDir = sfile.expandFilename().parentDir() + if pDir.len == 0 or pDir in saniLine: start = true else: for inc in gStateRT.includeDirs: From 28e2d7bb872c94ca0f25ba0e018b5d6132dc8fbc Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 21 Mar 2019 10:51:00 -0500 Subject: [PATCH 177/593] Fix #120 - object --- nimterop/getters.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 8504d34..2fe7447 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -119,7 +119,7 @@ proc getIdentifier*(name: string, kind: NimSymKind, parent=""): string = checkIdentifier(result, $kind, parent, name) - if result in gReserved: + if result in gReserved or (result == "object" and kind != nskType): result = &"`{result}`" else: result = "" From 454403b9fe96788534ade09631d3546edc418add Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Sat, 23 Mar 2019 13:33:52 -0500 Subject: [PATCH 178/593] Double pointer support --- nimterop/ast.nim | 9 +++++ nimterop/getters.nim | 6 ++- nimterop/globals.nim | 4 +- nimterop/grammar.nim | 89 +++++++++++++++++++++++++++++-------------- tests/include/test.c | 4 ++ tests/include/test.h | 15 ++++++++ tests/tnimterop_c.nim | 16 ++++++++ 7 files changed, 111 insertions(+), 32 deletions(-) diff --git a/nimterop/ast.nim b/nimterop/ast.nim index aede004..dc0ac3c 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -23,6 +23,7 @@ proc saveNodeData(node: TSNode, nimState: NimState): bool = pname = node.getPxName(1) ppname = node.getPxName(2) pppname = node.getPxName(3) + ppppname = node.getPxName(4) if node.tsNodePrevNamedSibling().tsNodeIsNull(): if pname == "pointer_declarator": @@ -30,9 +31,15 @@ proc saveNodeData(node: TSNode, nimState: NimState): bool = nimState.data.add(("pointer_declarator", "")) elif ppname == "array_declarator": nimState.data.add(("array_pointer_declarator", "")) + + # Double pointer + if ppname == "pointer_declarator": + nimState.data.add(("pointer_declarator", "")) elif pname in ["function_declarator", "array_declarator"]: if ppname == "pointer_declarator": nimState.data.add(("pointer_declarator", "")) + if pppname == "pointer_declarator": + nimState.data.add(("pointer_declarator", "")) nimState.data.add((name, val)) @@ -41,6 +48,8 @@ proc saveNodeData(node: TSNode, nimState: NimState): bool = ppname == "function_declarator": if pppname == "pointer_declarator": nimState.data.insert(("pointer_declarator", ""), nimState.data.len-1) + if ppppname == "pointer_declarator": + nimState.data.insert(("pointer_declarator", ""), nimState.data.len-1) nimState.data.add(("function_declarator", "")) elif name in gExpressions: diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 2fe7447..052e532 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -24,7 +24,7 @@ using var when while xor -yield""".split(Whitespace).toSet() +yield""".split(Whitespace).toHashSet() const gTypeMap = { # char @@ -151,8 +151,12 @@ proc getPtrType*(str: string): string = result = case str: of "ptr cchar": "cstring" + of "ptr ptr cchar": + "ptr cstring" of "ptr object": "pointer" + of "ptr ptr object": + "ptr pointer" else: str diff --git a/nimterop/globals.nim b/nimterop/globals.nim index bdb29dc..2f1a451 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -16,14 +16,14 @@ const "primitive_type", "sized_type_specifier", "type_identifier" - ].toSet() + ].toHashSet() gExpressions {.used.} = @[ "parenthesized_expression", "bitwise_expression", "shift_expression", "math_expression" - ].toSet() + ].toHashSet() gEnumVals {.used.} = @[ "identifier", diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index 3895aa1..8cd3275 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -50,6 +50,9 @@ proc initGrammar(): Grammar = {typeGrammar} (identifier|type_identifier?) (pointer_declarator? + (pointer_declarator! + (identifier|type_identifier) + ) (identifier|type_identifier) ) (abstract_pointer_declarator?) @@ -61,6 +64,9 @@ proc initGrammar(): Grammar = (function_declarator* (identifier|type_identifier!) (pointer_declarator + (pointer_declarator! + (type_identifier) + ) (type_identifier) ) {paramListGrammar} @@ -70,6 +76,9 @@ proc initGrammar(): Grammar = arrGrammar = &""" (array_declarator! (pointer_declarator! + (pointer_declarator! + (type_identifier) + ) (type_identifier) ) (type_identifier) @@ -80,11 +89,10 @@ proc initGrammar(): Grammar = template funcParamCommon(fname, pname, ptyp, pptr, pout, count, i: untyped): untyped = ptyp = nimState.data[i].val.getIdentifier(nskType, fname) - if i+1 < nimState.data.len and nimState.data[i+1].name == "pointer_declarator": - pptr = "ptr " + pptr = "" + while i+1 < nimState.data.len and nimState.data[i+1].name == "pointer_declarator": + pptr &= "ptr " i += 1 - else: - pptr = "" if i+1 < nimState.data.len and nimState.data[i+1].name == "identifier": pname = nimState.data[i+1].val.getIdentifier(nskParam, fname) @@ -94,8 +102,8 @@ proc initGrammar(): Grammar = count += 1 i += 1 - if pptr == "ptr " or ptyp != "object": - pout &= &"{pname}: {getPtrType(pptr&ptyp)}," + if pptr.len != 0 or ptyp != "object": + pout &= &"{pname}: {getPtrType(pptr&ptyp)}, " # typedef int X # typedef X Y @@ -107,6 +115,11 @@ proc initGrammar(): Grammar = (type_identifier!) {arrGrammar} (pointer_declarator! + (pointer_declarator! + (type_identifier!) + {arrGrammar} + {funcGrammar} + ) (type_identifier!) {arrGrammar} {funcGrammar} @@ -123,13 +136,13 @@ proc initGrammar(): Grammar = aptr = "" i += 1 - if i < nimState.data.len: + while i < nimState.data.len and "pointer" in nimState.data[i].name: case nimState.data[i].name: of "pointer_declarator": - tptr = "ptr " + tptr &= "ptr " i += 1 of "array_pointer_declarator": - aptr = "ptr " + aptr &= "ptr " i += 1 if i < nimState.data.len: @@ -149,10 +162,10 @@ proc initGrammar(): Grammar = funcParamCommon(fname, pname, ptyp, pptr, pout, count, i) - if pout.len != 0 and pout[^1] == ',': - pout = pout[0 .. ^2] + if pout.len != 0 and pout[^2 .. ^1] == ", ": + pout = pout[0 .. ^3] - if tptr == "ptr " or typ != "object": + if tptr.len != 0 or typ != "object": nimState.typeStr &= &"\n {name}* = proc({pout}): {getPtrType(tptr&typ)} {{.nimcall.}}" else: nimState.typeStr &= &"\n {name}* = proc({pout}) {{.nimcall.}}" @@ -242,13 +255,14 @@ proc initGrammar(): Grammar = ftyp = nimState.data[i].val.getType() i += 1 - case nimState.data[i].name: - of "pointer_declarator": - fptr = "ptr " - i += 1 - of "array_pointer_declarator": - aptr = "ptr " - i += 1 + while i < nimState.data.len-fend and "pointer" in nimState.data[i].name: + case nimState.data[i].name: + of "pointer_declarator": + fptr &= "ptr " + i += 1 + of "array_pointer_declarator": + aptr &= "ptr " + i += 1 fname = nimState.data[i].val.getIdentifier(nskField, nname) @@ -273,9 +287,9 @@ proc initGrammar(): Grammar = funcParamCommon(fname, pname, ptyp, pptr, pout, count, i) - if pout.len != 0 and pout[^1] == ',': - pout = pout[0 .. ^2] - if fptr == "ptr " or ftyp != "object": + if pout.len != 0 and pout[^2 .. ^1] == ", ": + pout = pout[0 .. ^3] + if fptr.len != 0 or ftyp != "object": nimState.typeStr &= &"\n {fname}*: proc({pout}): {getPtrType(fptr&ftyp)} {{.nimcall.}}" else: nimState.typeStr &= &"\n {fname}*: proc({pout}) {{.nimcall.}}" @@ -297,12 +311,18 @@ proc initGrammar(): Grammar = (array_declarator! (field_identifier!) (pointer_declarator + (pointer_declarator! + (field_identifier) + ) (field_identifier) ) (^$1+) ) (function_declarator+ (pointer_declarator + (pointer_declarator! + (field_identifier) + ) (field_identifier) ) {paramListGrammar} @@ -314,6 +334,9 @@ proc initGrammar(): Grammar = (field_declaration+ {typeGrammar} (pointer_declarator! + (pointer_declarator! + {fieldGrammar} + ) {fieldGrammar} ) {fieldGrammar} @@ -341,6 +364,9 @@ proc initGrammar(): Grammar = ) (type_identifier!) (pointer_declarator + (pointer_declarator! + (type_identifier) + ) (type_identifier) ) ) @@ -433,6 +459,9 @@ proc initGrammar(): Grammar = {result[^1].grammar} (type_identifier!) (pointer_declarator + (pointer_declarator! + (type_identifier) + ) (type_identifier) ) ) @@ -459,6 +488,9 @@ proc initGrammar(): Grammar = (storage_class_specifier?) {typeGrammar} (pointer_declarator! + (pointer_declarator! + {funcGrammar} + ) {funcGrammar} ) {funcGrammar} @@ -474,11 +506,10 @@ proc initGrammar(): Grammar = i += 1 continue - if nimState.data[i].name == "pointer_declarator": - fptr = "ptr " + fptr = "" + while i < nimState.data.len and nimState.data[i].name == "pointer_declarator": + fptr &= "ptr " i += 1 - else: - fptr = "" var fname = nimState.data[i].val @@ -493,12 +524,12 @@ proc initGrammar(): Grammar = funcParamCommon(fnname, pname, ptyp, pptr, pout, count, i) - if pout.len != 0 and pout[^1] == ',': - pout = pout[0 .. ^2] + if pout.len != 0 and pout[^2 .. ^1] == ", ": + pout = pout[0 .. ^3] if fnname.nBl and nimState.identifiers.addNewIdentifer(fnname): let ftyp = nimState.data[0].val.getIdentifier(nskType, fnname) - if fptr == "ptr " or ftyp != "object": + if fptr.len != 0 or ftyp != "object": nimState.procStr &= &"\nproc {fnname}*({pout}): {getPtrType(fptr&ftyp)} {{.{genImportC(fname, fnname)}, header: {nimState.currentHeader}.}}" else: nimState.procStr &= &"\nproc {fnname}*({pout}) {{.{genImportC(fname, fnname)}, header: {nimState.currentHeader}.}}" diff --git a/tests/include/test.c b/tests/include/test.c index 0312b4f..8990df9 100644 --- a/tests/include/test.c +++ b/tests/include/test.c @@ -60,6 +60,10 @@ void *test_call9() { return NULL; } +void **test_call10(int **param1) { + return NULL; +} + void multiline1(void) {} void *multiline2(void) { diff --git a/tests/include/test.h b/tests/include/test.h index e85acfd..9dba8ba 100644 --- a/tests/include/test.h +++ b/tests/include/test.h @@ -108,6 +108,7 @@ unsigned char test_call_param6(UNION2 param1); int test_call_param7(union UNION1 param1); float test_call_param8(int *param1); void *test_call9(); +void **test_call10(int **param1); // Issue #58 void @@ -131,6 +132,20 @@ UNION3 test_call_etype_ptr3(); typedef struct _Kernel { char name; } *Kernel; +// Double pointers +typedef void **DVOIDPTR; +typedef int **DINTPTR; + +struct dstruct { + int **field1; +}; + +typedef struct dstruct2 { + char **field1; + float **field2; + void **(*tcv)(int **param1); +} DSTRUCT2; + #ifdef __cplusplus } #endif \ No newline at end of file diff --git a/tests/tnimterop_c.nim b/tests/tnimterop_c.nim index 86ac0fd..3fc33b9 100644 --- a/tests/tnimterop_c.nim +++ b/tests/tnimterop_c.nim @@ -145,3 +145,19 @@ when false: doAssert foobar1(3) == OSDEF * 3 when false: # Error: undeclared identifier: 'foobar2' doAssert foobar2(3) == 3 + 1 + +# Double pointer +var + dv: DVOIDPTR + di: DINTPTR + ds: dstruct + cstr = "Hello".cstring + ds2: DSTRUCT2 + +dv = addr vptr +di = addr iptr + +ds.field1 = di +ds2.field1 = addr cstr +ds2.tcv = test_call10 +check ds2.tcv(di) == nil \ No newline at end of file From 98352b889914e40b3838115a42e07d822e50d0d9 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Sat, 23 Mar 2019 13:59:03 -0500 Subject: [PATCH 179/593] Fix CI --- .travis.yml | 4 ++-- appveyor.yml | 2 +- nimterop/getters.nim | 2 +- nimterop/globals.nim | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 991cbe7..a2cc870 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,12 +5,12 @@ os: language: c env: - - BRANCH=0.19.2 + - BRANCH=0.19.4 - BRANCH=devel cache: directories: - - "$HOME/.choosenim/toolchains/nim-0.19.2" + - "$HOME/.choosenim/toolchains/nim-0.19.4" install: # `set -u` failed for ubuntu: /home/travis/.travis/job_stages: line 107: secure: unbound variable diff --git a/appveyor.yml b/appveyor.yml index b7f97f3..fa94a2d 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -9,7 +9,7 @@ matrix: environment: matrix: - - NIM_VERSION: 0.19.2 + - NIM_VERSION: 0.19.4 for: - diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 052e532..2cce70f 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -24,7 +24,7 @@ using var when while xor -yield""".split(Whitespace).toHashSet() +yield""".split(Whitespace).toSet() const gTypeMap = { # char diff --git a/nimterop/globals.nim b/nimterop/globals.nim index 2f1a451..bdb29dc 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -16,14 +16,14 @@ const "primitive_type", "sized_type_specifier", "type_identifier" - ].toHashSet() + ].toSet() gExpressions {.used.} = @[ "parenthesized_expression", "bitwise_expression", "shift_expression", "math_expression" - ].toHashSet() + ].toSet() gEnumVals {.used.} = @[ "identifier", From da4d800fade4d0559eb0a658fe02269edfe0ec12 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 1 Apr 2019 12:05:43 -0500 Subject: [PATCH 180/593] Fix for upstream tree-sitter changes --- nimterop/setup.nim | 10 +++++----- nimterop/treesitter/c.nim | 8 ++++++-- nimterop/treesitter/cpp.nim | 8 +++++--- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/nimterop/setup.nim b/nimterop/setup.nim index fceac88..e50a5ef 100644 --- a/nimterop/setup.nim +++ b/nimterop/setup.nim @@ -4,7 +4,7 @@ import "."/[git, paths] proc treesitterSetup*() = gitPull("https://github.com/tree-sitter/tree-sitter/", incDir() / "treesitter", """ -lib/include/* +lib/include/tree_sitter/api.h lib/src/* """) @@ -24,13 +24,13 @@ proc treesitterCSetup*() = src/*.h src/*.c src/*.cc +src/tree_sitter/parser.h """) let - headerc = incDir() / "treesitter_c/src/parser.h" + headerc = incDir() / "treesitter_c/src/api.h" headerc.writeFile(""" -typedef struct TSLanguage TSLanguage; const TSLanguage *tree_sitter_c(); """) @@ -39,12 +39,12 @@ proc treesitterCppSetup*() = src/*.h src/*.c src/*.cc +src/tree_sitter/parser.h """) let - headercpp = incDir() / "treesitter_cpp/src/parser.h" + headercpp = incDir() / "treesitter_cpp/src/api.h" headercpp.writeFile(""" -typedef struct TSLanguage TSLanguage; const TSLanguage *tree_sitter_cpp(); """) diff --git a/nimterop/treesitter/c.nim b/nimterop/treesitter/c.nim index 0170a5d..86cb71a 100644 --- a/nimterop/treesitter/c.nim +++ b/nimterop/treesitter/c.nim @@ -5,8 +5,12 @@ import ".."/[setup, paths] static: treesitterCSetup() +const srcDir = incDir() / "treesitter_c/src" + +{.passC: "-I$1" % srcDir.} + import "."/api -{.compile: incDir() / "treesitter_c/src/parser.c".} +{.compile: srcDir / "parser.c".} -proc treeSitterC*(): ptr TSLanguage {.importc: "tree_sitter_c", header: incDir() / "treesitter_c/src/parser.h".} +proc treeSitterC*(): ptr TSLanguage {.importc: "tree_sitter_c", header: srcDir / "api.h".} diff --git a/nimterop/treesitter/cpp.nim b/nimterop/treesitter/cpp.nim index 296929f..90db000 100644 --- a/nimterop/treesitter/cpp.nim +++ b/nimterop/treesitter/cpp.nim @@ -5,10 +5,12 @@ import ".."/[setup, paths] static: treesitterCppSetup() -import "."/api - const srcDir = incDir() / "treesitter_cpp/src" +{.passC: "-I$1" % srcDir.} + +import "."/api + when (NimMajor, NimMinor, NimPatch) < (0, 19, 9): const srcDirRel = "../../build/inc/treesitter_cpp/src" else: @@ -31,4 +33,4 @@ that we link against, which avoids the linker hack. {.compile: srcDir / "scanner.cc".} -proc treeSitterCpp*(): ptr TSLanguage {.importc: "tree_sitter_cpp", header: srcDir / "parser.h".} +proc treeSitterCpp*(): ptr TSLanguage {.importc: "tree_sitter_cpp", header: srcDir / "api.h".} From 50f4d73db92d78474c66f2e7aebdb7cb8c7f4eef Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 1 Apr 2019 12:53:37 -0500 Subject: [PATCH 181/593] Verbose logging --- .travis.yml | 6 +++--- appveyor.yml | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index a2cc870..2c2d7cf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,6 +23,6 @@ install: script: - set -e - - nimble install -y - - nimble test - - nimble --nimbleDir:`pwd`/build/fakenimble install nimterop -y + - nimble --verbose install -y + - nimble --verbose test + - nimble --verbose --nimbleDir:`pwd`/build/fakenimble install nimterop -y diff --git a/appveyor.yml b/appveyor.yml index fa94a2d..aafd970 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -78,10 +78,10 @@ for: - /home/appveyor/binaries build_script: - - nimble install -y + - nimble --verbose install -y test_script: - - nimble test - - nimble --nimbleDir:test install nimterop -y + - nimble --verbose test + - nimble --verbose --nimbleDir:test install nimterop -y deploy: off From cc1cbb459c0e725a038df449ff265c484b4086c0 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 1 Apr 2019 16:57:28 -0500 Subject: [PATCH 182/593] Fix for parser.h --- nimterop/setup.nim | 17 ++++++++++++++--- nimterop/treesitter/c.nim | 4 ++-- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/nimterop/setup.nim b/nimterop/setup.nim index e50a5ef..2e436cb 100644 --- a/nimterop/setup.nim +++ b/nimterop/setup.nim @@ -4,7 +4,7 @@ import "."/[git, paths] proc treesitterSetup*() = gitPull("https://github.com/tree-sitter/tree-sitter/", incDir() / "treesitter", """ -lib/include/tree_sitter/api.h +lib/include/* lib/src/* """) @@ -13,12 +13,23 @@ lib/src/* *.h """) - # TODO: does this work on windows? if not use `os.unixToNativePath` let - stack = incDir() / "treesitter/lib/src/stack.c" + tbase = incDir() / "treesitter/lib" + stack = tbase / "src/stack.c" + parser = tbase / "include/tree_sitter/parser.h" + tparser = parser.replace("parser", "tparser") + language = tbase / "src/language.h" + lexer = tbase / "src/lexer.h" + subtree = tbase / "src/subtree.h" stack.writeFile(stack.readFile().replace("inline Stack", "Stack")) + # parser.h + mvFile(parser, tparser) + language.writeFile(language.readFile().replace("parser.h", "tparser.h")) + lexer.writeFile(lexer.readFile().replace("parser.h", "tparser.h")) + subtree.writeFile(subtree.readFile().replace("parser.h", "tparser.h")) + proc treesitterCSetup*() = gitPull("https://github.com/tree-sitter/tree-sitter-c", incDir() / "treesitter_c", """ src/*.h diff --git a/nimterop/treesitter/c.nim b/nimterop/treesitter/c.nim index 86cb71a..a39ee65 100644 --- a/nimterop/treesitter/c.nim +++ b/nimterop/treesitter/c.nim @@ -7,10 +7,10 @@ static: const srcDir = incDir() / "treesitter_c/src" -{.passC: "-I$1" % srcDir.} - import "."/api +{.passC: "-I$1" % srcDir.} + {.compile: srcDir / "parser.c".} proc treeSitterC*(): ptr TSLanguage {.importc: "tree_sitter_c", header: srcDir / "api.h".} From 9a90495a1e4350ba9f3153fee9d18ebfca597fa1 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Fri, 5 Apr 2019 12:14:27 -0500 Subject: [PATCH 183/593] Handle struct pointer first field, additional debugging --- nimterop/ast.nim | 6 ++++-- nimterop/globals.nim | 2 ++ nimterop/grammar.nim | 33 +++++++++++++++++++++++++++++++-- tests/include/test.h | 1 + 4 files changed, 38 insertions(+), 4 deletions(-) diff --git a/nimterop/ast.nim b/nimterop/ast.nim index dc0ac3c..0d96dfd 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -108,7 +108,7 @@ proc searchAst(root: TSNode, astTable: AstTable, nimState: NimState) = if searchAstForNode(ast, node, nimState): ast.tonim(ast, node, nimState) if gStateRT.debug: - nimState.debugStr &= "\n# " & nimState.data.join("\n# ") + nimState.debugStr &= "\n# " & nimState.data.join("\n# ") & "\n" break nimState.data = @[] else: @@ -157,6 +157,8 @@ proc printNim*(fullpath: string, root: TSNode, astTable: AstTable) = nimState.currentHeader = getCurrentHeader(fullpath) nimState.constStr &= &"\n {nimState.currentHeader} {{.used.}} = \"{fp}\"" + nimState.debug = gStateRT.debug + root.searchAst(astTable, nimState) if nimState.enumStr.nBl: @@ -171,5 +173,5 @@ proc printNim*(fullpath: string, root: TSNode, astTable: AstTable) = if nimState.procStr.nBl: echo &"{nimState.procStr}\n" - if gStateRT.debug and nimState.debugStr.nBl: + if nimState.debugStr.nBl: echo nimState.debugStr \ No newline at end of file diff --git a/nimterop/globals.nim b/nimterop/globals.nim index bdb29dc..f866e71 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -63,6 +63,8 @@ type constStr*, debugStr*, enumStr*, procStr*, typeStr*: string + debug*: bool + currentHeader*: string data*: seq[tuple[name, val: string]] diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index 8cd3275..e83c2a1 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -21,6 +21,9 @@ proc initGrammar(): Grammar = ) """, proc (ast: ref Ast, node: TSNode, nimState: NimState) = + if nimState.debug: + nimState.debugStr &= "\n# define X Y" + let val = nimState.data[1].val.getLit() @@ -128,6 +131,9 @@ proc initGrammar(): Grammar = ) """, proc (ast: ref Ast, node: TSNode, nimState: NimState) = + if nimState.debug: + nimState.debugStr &= "\n# typedef X Y" + var i = 0 typ = nimState.data[i].val.getIdentifier(nskType) @@ -184,8 +190,10 @@ proc initGrammar(): Grammar = nimState.typeStr &= &"\n {name}* = {getPtrType(tptr&typ)}" )) - proc pDupTypeCommon(nname: string, fend: int, nimState: NimState, isEnum=false) = + if nimState.debug: + nimState.debugStr &= "\n# pDupTypeCommon()" + var dname = nimState.data[^1].val ndname = nimState.data[^1].val.getIdentifier(nskType) @@ -205,6 +213,9 @@ proc initGrammar(): Grammar = &"\n {ndname}* {{.{genImportC(dname, ndname)}, header: {nimState.currentHeader}, bycopy.}} = {dptr}{nname}" proc pStructCommon(ast: ref Ast, node: TSNode, name: string, fstart, fend: int, nimState: NimState) = + if nimState.debug: + nimState.debugStr &= "\n# pStructCommon" + var nname = name.getIdentifier(nskType) prefix = "" @@ -352,6 +363,9 @@ proc initGrammar(): Grammar = ) """, proc (ast: ref Ast, node: TSNode, nimState: NimState) = + if nimState.debug: + nimState.debugStr &= "\n# struct X {}" + pStructCommon(ast, node, nimState.data[0].val, 1, 1, nimState) )) @@ -372,6 +386,9 @@ proc initGrammar(): Grammar = ) """, proc (ast: ref Ast, node: TSNode, nimState: NimState) = + if nimState.debug: + nimState.debugStr &= "\n# typedef struct X {}" + var fstart = 0 fend = 1 @@ -381,7 +398,7 @@ proc initGrammar(): Grammar = if nimState.data.len > 1 and nimState.data[0].name == "type_identifier" and - nimState.data[1].name != "field_identifier": + nimState.data[1].name notin ["field_identifier", "pointer_declarator"]: fstart = 1 pStructCommon(ast, node, nimState.data[0].val, fstart, fend, nimState) @@ -390,6 +407,9 @@ proc initGrammar(): Grammar = )) proc pEnumCommon(ast: ref Ast, node: TSNode, name: string, fstart, fend: int, nimState: NimState) = + if nimState.debug: + nimState.debugStr &= "\n# pEnumCommon()" + let nname = if name.len == 0: getUniqueIdentifier(nimState.identifiers, "Enum") @@ -442,6 +462,9 @@ proc initGrammar(): Grammar = ) """ % gEnumVals.join("|"), proc (ast: ref Ast, node: TSNode, nimState: NimState) = + if nimState.debug: + nimState.debugStr &= "\n# enum X {}" + var name = "" offset = 0 @@ -467,6 +490,9 @@ proc initGrammar(): Grammar = ) """, proc (ast: ref Ast, node: TSNode, nimState: NimState) = + if nimState.debug: + nimState.debugStr &= "\n# typedef enum {}" + var fstart = 0 fend = 1 @@ -497,6 +523,9 @@ proc initGrammar(): Grammar = ) """, proc (ast: ref Ast, node: TSNode, nimState: NimState) = + if nimState.debug: + nimState.debugStr &= "\n# typ function" + var fptr = "" i = 1 diff --git a/tests/include/test.h b/tests/include/test.h index 9dba8ba..eb36650 100644 --- a/tests/include/test.h +++ b/tests/include/test.h @@ -74,6 +74,7 @@ typedef void * VOIDPTR; typedef int * INTPTR; typedef struct { + struct STRUCT1 *field0; int *field; int field2[TEST_INT]; enum ENUM field3[TEST_INT]; From 7bee0392e7a1a2453f0a2ea428087a8f4f369963 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Fri, 5 Apr 2019 16:20:15 -0500 Subject: [PATCH 184/593] Show stackTrace on asserts --- config.nims | 12 +++++------- nimterop/git.nim | 4 +--- nimterop/treesitter/cpp.nim | 12 ------------ 3 files changed, 6 insertions(+), 22 deletions(-) diff --git a/config.nims b/config.nims index d43b04f..54a9a06 100644 --- a/config.nims +++ b/config.nims @@ -1,9 +1,4 @@ -#[ -see D20190127T231316 workaround for fact that toast needs to build -scanner.cc, which would otherwise result in link errors such as: -"std::terminate()", referenced from: - ___clang_call_terminate in scanner.cc.o -]# +# Workaround for C++ scanner.cc causing link error with other C obj files when defined(MacOSX): switch("clang.linkerexe", "g++") else: @@ -11,4 +6,7 @@ else: # Workaround for NilAccessError crash on Windows #98 when defined(Windows): - switch("gc", "markAndSweep") \ No newline at end of file + switch("gc", "markAndSweep") + +# Retain stackTrace for clear errors +switch("stackTrace", "on") \ No newline at end of file diff --git a/nimterop/git.nim b/nimterop/git.nim index 9998a44..740eef2 100644 --- a/nimterop/git.nim +++ b/nimterop/git.nim @@ -18,9 +18,7 @@ proc execAction*(cmd: string, nostderr=false): string = else: let opt = if nostderr: {poUsePath} else: {poStdErrToStdOut, poUsePath} (result, ret) = execCmdEx(ccmd, opt) - if ret != 0: - let msg = "Command failed: " & $(ret, nostderr) & "\nccmd: " & ccmd & "\nresult:\n" & result - doAssert false, msg + doAssert ret == 0, "Command failed: " & $(ret, nostderr) & "\nccmd: " & ccmd & "\nresult:\n" & result proc mkDir*(dir: string) = if not dirExists(dir): diff --git a/nimterop/treesitter/cpp.nim b/nimterop/treesitter/cpp.nim index 90db000..1b47206 100644 --- a/nimterop/treesitter/cpp.nim +++ b/nimterop/treesitter/cpp.nim @@ -19,18 +19,6 @@ else: # pending https://github.com/nim-lang/Nim/issues/9370 we need srcDirRel instead # of srcDir {.compile: (srcDirRel / "parser.c", "nimtero_cpp_parser.c.o").} - -#[ -D20190127T231316:here note: this will be compiled as a C++ file even with -`nim c`, thanks to the extension (which clang/gcc understands); -however, in `nim c` mode this will fail in link phase -(which by default would use `clang/gcc`) -unless linker is overridden, see D20190127T231316. - -cleaner alternative: compile `scanner.cc` into a shared library -that we link against, which avoids the linker hack. -]# - {.compile: srcDir / "scanner.cc".} proc treeSitterCpp*(): ptr TSLanguage {.importc: "tree_sitter_cpp", header: srcDir / "api.h".} From a17c654fac5eeabc2f1a7ebd0a90d0d08ed55831 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Fri, 5 Apr 2019 16:42:41 -0500 Subject: [PATCH 185/593] Fix #124 --- nimterop/getters.nim | 6 +++--- nimterop/git.nim | 14 +++++++------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 2cce70f..3510e27 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -211,12 +211,12 @@ proc getPreprocessor*(fullpath: string, mode = "cpp"): string = sfile = fullpath.sanitizePath for inc in gStateRT.includeDirs: - cmd &= &"-I\"{inc}\" " + cmd &= &"-I{inc.quoteShell} " for def in gStateRT.defines: cmd &= &"-D{def} " - cmd &= &"\"{fullpath}\"" + cmd &= &"\"{fullpath.quoteShell}\"" # Include content only from file for line in execAction(cmd).splitLines(): @@ -357,7 +357,7 @@ proc loadPlugin*(sourcePath: string) = pdll = sourcePath.dll if not fileExists(pdll) or sourcePath.getLastModificationTime() > pdll.getLastModificationTime(): - discard execAction("nim c --app:lib " & sourcePath) + discard execAction("nim c --app:lib " & sourcePath.quoteShell) doAssert fileExists(pdll), "No plugin binary generated for " & sourcePath let lib = loadLib(pdll) diff --git a/nimterop/git.nim b/nimterop/git.nim index 740eef2..960ab25 100644 --- a/nimterop/git.nim +++ b/nimterop/git.nim @@ -69,7 +69,7 @@ proc downloadUrl*(url, outdir: string) = "powershell [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; wget $# -OutFile $#" else: "curl $# -o $#" - discard execAction(cmd % [url, outdir/file]) + discard execAction(cmd % [url, (outdir/file).quoteShell]) if ext == ".zip": extractZip(file, outdir) @@ -101,20 +101,20 @@ proc gitPull*(url: string, outdir = "", plist = "", checkout = "") = mkDir(outdir2) echo "Setting up Git repo: " & url - discard execAction(&"cd {outdir2} && git init .") - discard execAction(&"cd {outdir2} && git remote add origin {url}") + discard execAction(&"cd {outdir2.quoteShell} && git init .") + discard execAction(&"cd {outdir2.quoteShell} && git remote add origin {url}") if plist.len != 0: # TODO: document this, it's not clear let sparsefile = outdir / ".git/info/sparse-checkout" - discard execAction(&"cd {outdir2} && git config core.sparsecheckout true") + discard execAction(&"cd {outdir2.quoteShell} && git config core.sparsecheckout true") writeFile(sparsefile, plist) if checkout.len != 0: echo "Checking out " & checkout - discard execAction(&"cd {outdir2} && git pull --tags origin master") - discard execAction(&"cd {outdir2} && git checkout {checkout}") + discard execAction(&"cd {outdir2.quoteShell} && git pull --tags origin master") + discard execAction(&"cd {outdir2.quoteShell} && git checkout {checkout}") else: echo "Pulling repository" - discard execAction(&"cd {outdir2} && git pull --depth=1 origin master") + discard execAction(&"cd {outdir2.quoteShell} && git pull --depth=1 origin master") From 8fcf8011a50d574fef2e87f0d3db2d7a9bcffd93 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Fri, 5 Apr 2019 17:46:03 -0500 Subject: [PATCH 186/593] Fix #124 --- nimterop/git.nim | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/nimterop/git.nim b/nimterop/git.nim index 960ab25..b0380c2 100644 --- a/nimterop/git.nim +++ b/nimterop/git.nim @@ -96,25 +96,25 @@ proc gitPull*(url: string, outdir = "", plist = "", checkout = "") = return let - outdir2 = outdir.quoteShell + outdirQ = outdir.quoteShell - mkDir(outdir2) + mkDir(outdir) echo "Setting up Git repo: " & url - discard execAction(&"cd {outdir2.quoteShell} && git init .") - discard execAction(&"cd {outdir2.quoteShell} && git remote add origin {url}") + discard execAction(&"cd {outdirQ} && git init .") + discard execAction(&"cd {outdirQ} && git remote add origin {url}") if plist.len != 0: # TODO: document this, it's not clear let sparsefile = outdir / ".git/info/sparse-checkout" - discard execAction(&"cd {outdir2.quoteShell} && git config core.sparsecheckout true") + discard execAction(&"cd {outdirQ} && git config core.sparsecheckout true") writeFile(sparsefile, plist) if checkout.len != 0: echo "Checking out " & checkout - discard execAction(&"cd {outdir2.quoteShell} && git pull --tags origin master") - discard execAction(&"cd {outdir2.quoteShell} && git checkout {checkout}") + discard execAction(&"cd {outdirQ} && git pull --tags origin master") + discard execAction(&"cd {outdirQ} && git checkout {checkout}") else: echo "Pulling repository" - discard execAction(&"cd {outdir2.quoteShell} && git pull --depth=1 origin master") + discard execAction(&"cd {outdirQ} && git pull --depth=1 origin master") From 2bad84c4c174009890cb07ca7016b8353fb6da40 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Sat, 6 Apr 2019 18:33:40 -0500 Subject: [PATCH 187/593] Fix #123 --- nimterop/getters.nim | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 3510e27..c9aecf8 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -74,7 +74,7 @@ const gTypeMap = { }.toTable() proc sanitizePath*(path: string): string = - path.multiReplace([("\\\\", $DirSep), ("\\", $DirSep), ("//", $DirSep)]) + path.multiReplace([("\\\\", $DirSep), ("\\", $DirSep), ("/", $DirSep)]) proc getType*(str: string): string = if str == "void": @@ -216,7 +216,7 @@ proc getPreprocessor*(fullpath: string, mode = "cpp"): string = for def in gStateRT.defines: cmd &= &"-D{def} " - cmd &= &"\"{fullpath.quoteShell}\"" + cmd &= &"{fullpath.quoteShell}" # Include content only from file for line in execAction(cmd).splitLines(): @@ -231,7 +231,7 @@ proc getPreprocessor*(fullpath: string, mode = "cpp"): string = start = true elif gStateRT.recurse: let - pDir = sfile.expandFilename().parentDir() + pDir = sfile.expandFilename().parentDir().sanitizePath() if pDir.len == 0 or pDir in saniLine: start = true else: From 7bf38b6a0c49a89252ece889bf0d4af922c786ff Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Sat, 6 Apr 2019 18:36:38 -0500 Subject: [PATCH 188/593] Update documentation --- all.html | 14 +- cimport.html | 66 +- cimport.idx | 2 +- compat.html | 828 +++++++++++++++++++++++ compat.idx | 1 + dochack.js | 1758 ++++++++++++++++++++++++------------------------- git.html | 38 +- paths.html | 24 +- plugin.html | 16 +- theindex.html | 20 +- types.html | 22 +- 11 files changed, 1825 insertions(+), 964 deletions(-) create mode 100755 compat.html create mode 100755 compat.idx diff --git a/all.html b/all.html index 82d847d..257944c 100755 --- a/all.html +++ b/all.html @@ -345,11 +345,11 @@ dl { dt { margin-bottom: -0.5em; - margin-left: 0.5em; } + margin-left: 0.0em; } dd { - margin-left: 0.5em; - margin-bottom: 2.5em; + margin-left: 2.0em; + margin-bottom: 3.0em; margin-top: 0.5em; } @@ -761,6 +761,10 @@ span.pragmawrap { display: none; } +span.attachedType { + display: none; + visibility: hidden; +} @@ -818,7 +822,7 @@ function main() { @@ -828,7 +832,7 @@ function main() { diff --git a/cimport.html b/cimport.html index ef6a06c..07617b1 100755 --- a/cimport.html +++ b/cimport.html @@ -345,11 +345,11 @@ dl { dt { margin-bottom: -0.5em; - margin-left: 0.5em; } + margin-left: 0.0em; } dd { - margin-left: 0.5em; - margin-bottom: 2.5em; + margin-left: 2.0em; + margin-bottom: 3.0em; margin-top: 0.5em; } @@ -761,6 +761,10 @@ span.pragmawrap { display: none; } +span.attachedType { + display: none; + visibility: hidden; +} @@ -802,12 +806,6 @@ function main() {
        -
      • - Exports -
          - -
        -
      • Imports
          @@ -817,18 +815,18 @@ function main() {
        • Procs
        • @@ -836,20 +834,26 @@ function main() { Macros
          • cOverride
          • + title="cOverride(body): untyped">cOverride
          • cPlugin
          • + title="cPlugin(body): untyped">cPlugin
          • cDefine
          • + title="cDefine(name: static string; val: static string = ""): untyped">cDefine
          • cIncludeDir
          • + title="cIncludeDir(dir: static string): untyped">cIncludeDir
          • cCompile
          • + title="cCompile(path: static string; mode = "c"; exclude = ""): untyped">cCompile
          • cImport
          • + title="cImport(filename: static string; recurse: static bool = false): untyped">cImport
          +
        • + Exports +
            + +
          +
        @@ -862,12 +866,7 @@ static: cAddStdDir()

      - -
      +

      Imports

      plugin, git, paths, types @@ -875,8 +874,8 @@ static:

      Procs

      - -
      proc cSkipSymbol(skips: seq[string]) {...}{.compileTime, raises: [], tags: [].}
      + +
      proc cSkipSymbol(skips: seq[string]) {...}{.compileTime, raises: [], tags: [].}
      Similar to cOverride(), this macro allows filtering out symbols not of interest from the generated output.

      Examples:

      @@ -1008,6 +1007,11 @@ Add an include directory that is forwarded to the C/C++ compiler using +
      +
      @@ -1017,7 +1021,7 @@ Add an include directory that is forwarded to the C/C++ compiler using
      - Made with Nim. Generated: 2019-02-08 22:35:14 UTC + Made with Nim. Generated: 2019-04-06 23:36:36 UTC
      diff --git a/cimport.idx b/cimport.idx index 6358c57..834bea9 100755 --- a/cimport.idx +++ b/cimport.idx @@ -1,5 +1,5 @@ cOverride cimport.html#cOverride.m cimport: cOverride(body): untyped -cSkipSymbol cimport.html#cSkipSymbol,seq[string] cimport: cSkipSymbol(skips: seq[string]) +cSkipSymbol cimport.html#cSkipSymbol,seq[T][string] cimport: cSkipSymbol(skips: seq[string]) cPlugin cimport.html#cPlugin.m cimport: cPlugin(body): untyped cSearchPath cimport.html#cSearchPath,string cimport: cSearchPath(path: string): string cDebug cimport.html#cDebug cimport: cDebug() diff --git a/compat.html b/compat.html new file mode 100755 index 0000000..3906011 --- /dev/null +++ b/compat.html @@ -0,0 +1,828 @@ + + + + + + + + + + + + + + + + + +compat + + + + + + + + +
      +
      +

      compat

      +
      +
      + +
      + Search: +
      +
      + Group by: + +
      + +
      +
      +
      +

      + +
      +
      + +
      + +
      +
      +
      + + + diff --git a/compat.idx b/compat.idx new file mode 100755 index 0000000..826a528 --- /dev/null +++ b/compat.idx @@ -0,0 +1 @@ +relativePath compat.html#relativePath,string,string compat: relativePath(file, base: string): string diff --git a/dochack.js b/dochack.js index e23a822..28e8125 100755 --- a/dochack.js +++ b/dochack.js @@ -1,5 +1,5 @@ /* Generated by the Nim Compiler v0.19.9 */ -/* (c) 2018 Andreas Rumpf */ +/* (c) 2019 Andreas Rumpf */ var framePtr = null; var excHandler = 0; @@ -12,247 +12,247 @@ if (typeof Uint16Array === 'undefined') Uint16Array = Array; if (typeof Uint32Array === 'undefined') Uint32Array = Array; if (typeof Float32Array === 'undefined') Float32Array = Array; if (typeof Float64Array === 'undefined') Float64Array = Array; -var NTI37032 = {size: 0,kind: 1,base: null,node: null,finalizer: null}; -var NTI180074 = {size: 0, kind: 18, base: null, node: null, finalizer: null}; -var NTI41262 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI182526 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; -var NTI71442 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI71438 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI71434 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI71430 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI71426 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI71422 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI71418 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI71414 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI71410 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI71406 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI71402 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI71398 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI71394 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI71390 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI71386 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI71382 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI71378 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI71374 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI71370 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI71366 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI71205 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI71277 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI71275 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; -var NTI71221 = {size: 0, kind: 14, base: null, node: null, finalizer: null}; -var NTI71520 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; -var NTI71518 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; -var NTI71516 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; -var NTI71225 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI71223 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; -var NTI73045 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; -var NTI41250 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI41258 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI37006 = {size: 0,kind: 31,base: null,node: null,finalizer: null}; -var NTI53541 = {size: 0, kind: 18, base: null, node: null, finalizer: null}; -var NTI41208 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI41314 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; -var NTI37016 = {size: 0,kind: 40,base: null,node: null,finalizer: null}; -var NTI37040 = {size: 0,kind: 28,base: null,node: null,finalizer: null}; -var NTI37042 = {size: 0,kind: 29,base: null,node: null,finalizer: null}; -var NTI41308 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; -var NTI41226 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI41228 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI41242 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI41246 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NNI41246 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; -NTI41246.node = NNI41246; -var NNI41242 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; -NTI41242.node = NNI41242; -var NNI41228 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; -NTI41228.node = NNI41228; -NTI41308.base = NTI41226; -NTI41314.base = NTI41226; -var NNI41226 = {kind: 2, len: 6, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "parent", len: 0, typ: NTI41308, name: "parent", sons: null}, -{kind: 1, offset: "name", len: 0, typ: NTI37042, name: "name", sons: null}, -{kind: 1, offset: "message", len: 0, typ: NTI37040, name: "msg", sons: null}, -{kind: 1, offset: "trace", len: 0, typ: NTI37040, name: "trace", sons: null}, -{kind: 1, offset: "raiseId", len: 0, typ: NTI37016, name: "raiseId", sons: null}, -{kind: 1, offset: "up", len: 0, typ: NTI41314, name: "up", sons: null}]}; -NTI41226.node = NNI41226; -var NNI41208 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; -NTI41208.node = NNI41208; -NTI41226.base = NTI41208; -NTI41228.base = NTI41226; -NTI41242.base = NTI41228; -NTI41246.base = NTI41242; -var NNI53541 = {kind: 2, len: 2, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "Field0", len: 0, typ: NTI37042, name: "Field0", sons: null}, -{kind: 1, offset: "Field1", len: 0, typ: NTI37006, name: "Field1", sons: null}]}; -NTI53541.node = NNI53541; -var NNI41258 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; -NTI41258.node = NNI41258; -NTI41258.base = NTI41228; -var NNI41250 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; -NTI41250.node = NNI41250; -NTI41250.base = NTI41228; -NTI71516.base = NTI71223; -NTI71518.base = NTI71223; -NTI71520.base = NTI71223; -var NNI71221 = {kind: 2, offset: 0, typ: null, name: null, len: 12, sons: {"1": {kind: 1, offset: 1, typ: NTI71221, name: "ElementNode", len: 0, sons: null}, -"2": {kind: 1, offset: 2, typ: NTI71221, name: "AttributeNode", len: 0, sons: null}, -"3": {kind: 1, offset: 3, typ: NTI71221, name: "TextNode", len: 0, sons: null}, -"4": {kind: 1, offset: 4, typ: NTI71221, name: "CDATANode", len: 0, sons: null}, -"5": {kind: 1, offset: 5, typ: NTI71221, name: "EntityRefNode", len: 0, sons: null}, -"6": {kind: 1, offset: 6, typ: NTI71221, name: "EntityNode", len: 0, sons: null}, -"7": {kind: 1, offset: 7, typ: NTI71221, name: "ProcessingInstructionNode", len: 0, sons: null}, -"8": {kind: 1, offset: 8, typ: NTI71221, name: "CommentNode", len: 0, sons: null}, -"9": {kind: 1, offset: 9, typ: NTI71221, name: "DocumentNode", len: 0, sons: null}, -"10": {kind: 1, offset: 10, typ: NTI71221, name: "DocumentTypeNode", len: 0, sons: null}, -"11": {kind: 1, offset: 11, typ: NTI71221, name: "DocumentFragmentNode", len: 0, sons: null}, -"12": {kind: 1, offset: 12, typ: NTI71221, name: "NotationNode", len: 0, sons: null}}}; -NTI71221.node = NNI71221; -var NNI71277 = {kind: 2, len: 91, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "background", len: 0, typ: NTI37042, name: "background", sons: null}, -{kind: 1, offset: "backgroundAttachment", len: 0, typ: NTI37042, name: "backgroundAttachment", sons: null}, -{kind: 1, offset: "backgroundColor", len: 0, typ: NTI37042, name: "backgroundColor", sons: null}, -{kind: 1, offset: "backgroundImage", len: 0, typ: NTI37042, name: "backgroundImage", sons: null}, -{kind: 1, offset: "backgroundPosition", len: 0, typ: NTI37042, name: "backgroundPosition", sons: null}, -{kind: 1, offset: "backgroundRepeat", len: 0, typ: NTI37042, name: "backgroundRepeat", sons: null}, -{kind: 1, offset: "border", len: 0, typ: NTI37042, name: "border", sons: null}, -{kind: 1, offset: "borderBottom", len: 0, typ: NTI37042, name: "borderBottom", sons: null}, -{kind: 1, offset: "borderBottomColor", len: 0, typ: NTI37042, name: "borderBottomColor", sons: null}, -{kind: 1, offset: "borderBottomStyle", len: 0, typ: NTI37042, name: "borderBottomStyle", sons: null}, -{kind: 1, offset: "borderBottomWidth", len: 0, typ: NTI37042, name: "borderBottomWidth", sons: null}, -{kind: 1, offset: "borderColor", len: 0, typ: NTI37042, name: "borderColor", sons: null}, -{kind: 1, offset: "borderLeft", len: 0, typ: NTI37042, name: "borderLeft", sons: null}, -{kind: 1, offset: "borderLeftColor", len: 0, typ: NTI37042, name: "borderLeftColor", sons: null}, -{kind: 1, offset: "borderLeftStyle", len: 0, typ: NTI37042, name: "borderLeftStyle", sons: null}, -{kind: 1, offset: "borderLeftWidth", len: 0, typ: NTI37042, name: "borderLeftWidth", sons: null}, -{kind: 1, offset: "borderRight", len: 0, typ: NTI37042, name: "borderRight", sons: null}, -{kind: 1, offset: "borderRightColor", len: 0, typ: NTI37042, name: "borderRightColor", sons: null}, -{kind: 1, offset: "borderRightStyle", len: 0, typ: NTI37042, name: "borderRightStyle", sons: null}, -{kind: 1, offset: "borderRightWidth", len: 0, typ: NTI37042, name: "borderRightWidth", sons: null}, -{kind: 1, offset: "borderStyle", len: 0, typ: NTI37042, name: "borderStyle", sons: null}, -{kind: 1, offset: "borderTop", len: 0, typ: NTI37042, name: "borderTop", sons: null}, -{kind: 1, offset: "borderTopColor", len: 0, typ: NTI37042, name: "borderTopColor", sons: null}, -{kind: 1, offset: "borderTopStyle", len: 0, typ: NTI37042, name: "borderTopStyle", sons: null}, -{kind: 1, offset: "borderTopWidth", len: 0, typ: NTI37042, name: "borderTopWidth", sons: null}, -{kind: 1, offset: "borderWidth", len: 0, typ: NTI37042, name: "borderWidth", sons: null}, -{kind: 1, offset: "bottom", len: 0, typ: NTI37042, name: "bottom", sons: null}, -{kind: 1, offset: "captionSide", len: 0, typ: NTI37042, name: "captionSide", sons: null}, -{kind: 1, offset: "clear", len: 0, typ: NTI37042, name: "clear", sons: null}, -{kind: 1, offset: "clip", len: 0, typ: NTI37042, name: "clip", sons: null}, -{kind: 1, offset: "color", len: 0, typ: NTI37042, name: "color", sons: null}, -{kind: 1, offset: "cursor", len: 0, typ: NTI37042, name: "cursor", sons: null}, -{kind: 1, offset: "direction", len: 0, typ: NTI37042, name: "direction", sons: null}, -{kind: 1, offset: "display", len: 0, typ: NTI37042, name: "display", sons: null}, -{kind: 1, offset: "emptyCells", len: 0, typ: NTI37042, name: "emptyCells", sons: null}, -{kind: 1, offset: "cssFloat", len: 0, typ: NTI37042, name: "cssFloat", sons: null}, -{kind: 1, offset: "font", len: 0, typ: NTI37042, name: "font", sons: null}, -{kind: 1, offset: "fontFamily", len: 0, typ: NTI37042, name: "fontFamily", sons: null}, -{kind: 1, offset: "fontSize", len: 0, typ: NTI37042, name: "fontSize", sons: null}, -{kind: 1, offset: "fontStretch", len: 0, typ: NTI37042, name: "fontStretch", sons: null}, -{kind: 1, offset: "fontStyle", len: 0, typ: NTI37042, name: "fontStyle", sons: null}, -{kind: 1, offset: "fontVariant", len: 0, typ: NTI37042, name: "fontVariant", sons: null}, -{kind: 1, offset: "fontWeight", len: 0, typ: NTI37042, name: "fontWeight", sons: null}, -{kind: 1, offset: "height", len: 0, typ: NTI37042, name: "height", sons: null}, -{kind: 1, offset: "left", len: 0, typ: NTI37042, name: "left", sons: null}, -{kind: 1, offset: "letterSpacing", len: 0, typ: NTI37042, name: "letterSpacing", sons: null}, -{kind: 1, offset: "lineHeight", len: 0, typ: NTI37042, name: "lineHeight", sons: null}, -{kind: 1, offset: "listStyle", len: 0, typ: NTI37042, name: "listStyle", sons: null}, -{kind: 1, offset: "listStyleImage", len: 0, typ: NTI37042, name: "listStyleImage", sons: null}, -{kind: 1, offset: "listStylePosition", len: 0, typ: NTI37042, name: "listStylePosition", sons: null}, -{kind: 1, offset: "listStyleType", len: 0, typ: NTI37042, name: "listStyleType", sons: null}, -{kind: 1, offset: "margin", len: 0, typ: NTI37042, name: "margin", sons: null}, -{kind: 1, offset: "marginBottom", len: 0, typ: NTI37042, name: "marginBottom", sons: null}, -{kind: 1, offset: "marginLeft", len: 0, typ: NTI37042, name: "marginLeft", sons: null}, -{kind: 1, offset: "marginRight", len: 0, typ: NTI37042, name: "marginRight", sons: null}, -{kind: 1, offset: "marginTop", len: 0, typ: NTI37042, name: "marginTop", sons: null}, -{kind: 1, offset: "maxHeight", len: 0, typ: NTI37042, name: "maxHeight", sons: null}, -{kind: 1, offset: "maxWidth", len: 0, typ: NTI37042, name: "maxWidth", sons: null}, -{kind: 1, offset: "minHeight", len: 0, typ: NTI37042, name: "minHeight", sons: null}, -{kind: 1, offset: "minWidth", len: 0, typ: NTI37042, name: "minWidth", sons: null}, -{kind: 1, offset: "overflow", len: 0, typ: NTI37042, name: "overflow", sons: null}, -{kind: 1, offset: "padding", len: 0, typ: NTI37042, name: "padding", sons: null}, -{kind: 1, offset: "paddingBottom", len: 0, typ: NTI37042, name: "paddingBottom", sons: null}, -{kind: 1, offset: "paddingLeft", len: 0, typ: NTI37042, name: "paddingLeft", sons: null}, -{kind: 1, offset: "paddingRight", len: 0, typ: NTI37042, name: "paddingRight", sons: null}, -{kind: 1, offset: "paddingTop", len: 0, typ: NTI37042, name: "paddingTop", sons: null}, -{kind: 1, offset: "pageBreakAfter", len: 0, typ: NTI37042, name: "pageBreakAfter", sons: null}, -{kind: 1, offset: "pageBreakBefore", len: 0, typ: NTI37042, name: "pageBreakBefore", sons: null}, -{kind: 1, offset: "pointerEvents", len: 0, typ: NTI37042, name: "pointerEvents", sons: null}, -{kind: 1, offset: "position", len: 0, typ: NTI37042, name: "position", sons: null}, -{kind: 1, offset: "right", len: 0, typ: NTI37042, name: "right", sons: null}, -{kind: 1, offset: "scrollbar3dLightColor", len: 0, typ: NTI37042, name: "scrollbar3dLightColor", sons: null}, -{kind: 1, offset: "scrollbarArrowColor", len: 0, typ: NTI37042, name: "scrollbarArrowColor", sons: null}, -{kind: 1, offset: "scrollbarBaseColor", len: 0, typ: NTI37042, name: "scrollbarBaseColor", sons: null}, -{kind: 1, offset: "scrollbarDarkshadowColor", len: 0, typ: NTI37042, name: "scrollbarDarkshadowColor", sons: null}, -{kind: 1, offset: "scrollbarFaceColor", len: 0, typ: NTI37042, name: "scrollbarFaceColor", sons: null}, -{kind: 1, offset: "scrollbarHighlightColor", len: 0, typ: NTI37042, name: "scrollbarHighlightColor", sons: null}, -{kind: 1, offset: "scrollbarShadowColor", len: 0, typ: NTI37042, name: "scrollbarShadowColor", sons: null}, -{kind: 1, offset: "scrollbarTrackColor", len: 0, typ: NTI37042, name: "scrollbarTrackColor", sons: null}, -{kind: 1, offset: "tableLayout", len: 0, typ: NTI37042, name: "tableLayout", sons: null}, -{kind: 1, offset: "textAlign", len: 0, typ: NTI37042, name: "textAlign", sons: null}, -{kind: 1, offset: "textDecoration", len: 0, typ: NTI37042, name: "textDecoration", sons: null}, -{kind: 1, offset: "textIndent", len: 0, typ: NTI37042, name: "textIndent", sons: null}, -{kind: 1, offset: "textTransform", len: 0, typ: NTI37042, name: "textTransform", sons: null}, -{kind: 1, offset: "transform", len: 0, typ: NTI37042, name: "transform", sons: null}, -{kind: 1, offset: "top", len: 0, typ: NTI37042, name: "top", sons: null}, -{kind: 1, offset: "verticalAlign", len: 0, typ: NTI37042, name: "verticalAlign", sons: null}, -{kind: 1, offset: "visibility", len: 0, typ: NTI37042, name: "visibility", sons: null}, -{kind: 1, offset: "width", len: 0, typ: NTI37042, name: "width", sons: null}, -{kind: 1, offset: "wordSpacing", len: 0, typ: NTI37042, name: "wordSpacing", sons: null}, -{kind: 1, offset: "zIndex", len: 0, typ: NTI37006, name: "zIndex", sons: null}]}; -NTI71277.node = NNI71277; -NTI71277.base = NTI41208; -NTI71275.base = NTI71277; -var NNI71225 = {kind: 2, len: 14, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "attributes", len: 0, typ: NTI71516, name: "attributes", sons: null}, -{kind: 1, offset: "childNodes", len: 0, typ: NTI71518, name: "childNodes", sons: null}, -{kind: 1, offset: "children", len: 0, typ: NTI71520, name: "children", sons: null}, -{kind: 1, offset: "data", len: 0, typ: NTI37042, name: "data", sons: null}, -{kind: 1, offset: "firstChild", len: 0, typ: NTI71223, name: "firstChild", sons: null}, -{kind: 1, offset: "lastChild", len: 0, typ: NTI71223, name: "lastChild", sons: null}, -{kind: 1, offset: "nextSibling", len: 0, typ: NTI71223, name: "nextSibling", sons: null}, -{kind: 1, offset: "nodeName", len: 0, typ: NTI37042, name: "nodeName", sons: null}, -{kind: 1, offset: "nodeType", len: 0, typ: NTI71221, name: "nodeType", sons: null}, -{kind: 1, offset: "nodeValue", len: 0, typ: NTI37042, name: "nodeValue", sons: null}, -{kind: 1, offset: "parentNode", len: 0, typ: NTI71223, name: "parentNode", sons: null}, -{kind: 1, offset: "previousSibling", len: 0, typ: NTI71223, name: "previousSibling", sons: null}, -{kind: 1, offset: "innerHTML", len: 0, typ: NTI37042, name: "innerHTML", sons: null}, -{kind: 1, offset: "style", len: 0, typ: NTI71275, name: "style", sons: null}]}; -NTI71225.node = NNI71225; -var NNI71205 = {kind: 2, len: 20, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "onabort", len: 0, typ: NTI71366, name: "onabort", sons: null}, -{kind: 1, offset: "onblur", len: 0, typ: NTI71370, name: "onblur", sons: null}, -{kind: 1, offset: "onchange", len: 0, typ: NTI71374, name: "onchange", sons: null}, -{kind: 1, offset: "onclick", len: 0, typ: NTI71378, name: "onclick", sons: null}, -{kind: 1, offset: "ondblclick", len: 0, typ: NTI71382, name: "ondblclick", sons: null}, -{kind: 1, offset: "onerror", len: 0, typ: NTI71386, name: "onerror", sons: null}, -{kind: 1, offset: "onfocus", len: 0, typ: NTI71390, name: "onfocus", sons: null}, -{kind: 1, offset: "onkeydown", len: 0, typ: NTI71394, name: "onkeydown", sons: null}, -{kind: 1, offset: "onkeypress", len: 0, typ: NTI71398, name: "onkeypress", sons: null}, -{kind: 1, offset: "onkeyup", len: 0, typ: NTI71402, name: "onkeyup", sons: null}, -{kind: 1, offset: "onload", len: 0, typ: NTI71406, name: "onload", sons: null}, -{kind: 1, offset: "onmousedown", len: 0, typ: NTI71410, name: "onmousedown", sons: null}, -{kind: 1, offset: "onmousemove", len: 0, typ: NTI71414, name: "onmousemove", sons: null}, -{kind: 1, offset: "onmouseout", len: 0, typ: NTI71418, name: "onmouseout", sons: null}, -{kind: 1, offset: "onmouseover", len: 0, typ: NTI71422, name: "onmouseover", sons: null}, -{kind: 1, offset: "onmouseup", len: 0, typ: NTI71426, name: "onmouseup", sons: null}, -{kind: 1, offset: "onreset", len: 0, typ: NTI71430, name: "onreset", sons: null}, -{kind: 1, offset: "onselect", len: 0, typ: NTI71434, name: "onselect", sons: null}, -{kind: 1, offset: "onsubmit", len: 0, typ: NTI71438, name: "onsubmit", sons: null}, -{kind: 1, offset: "onunload", len: 0, typ: NTI71442, name: "onunload", sons: null}]}; -NTI71205.node = NNI71205; -NTI71205.base = NTI41208; -NTI71225.base = NTI71205; -NTI71223.base = NTI71225; -NTI73045.base = NTI71223; -NTI182526.base = NTI37042; -var NNI41262 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; -NTI41262.node = NNI41262; -NTI41262.base = NTI41228; -var NNI180074 = {kind: 2, len: 2, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "Field0", len: 0, typ: NTI37006, name: "Field0", sons: null}, -{kind: 1, offset: "Field1", len: 0, typ: NTI37032, name: "Field1", sons: null}]}; -NTI180074.node = NNI180074; +var NTI43032 = {size: 0,kind: 1,base: null,node: null,finalizer: null}; +var NTI202074 = {size: 0, kind: 18, base: null, node: null, finalizer: null}; +var NTI46862 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI205327 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; +var NTI84448 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI84444 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI84440 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI84436 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI84432 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI84428 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI84424 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI84420 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI84416 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI84412 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI84408 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI84404 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI84400 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI84396 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI84392 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI84388 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI84384 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI84380 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI84376 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI84372 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI84205 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI84283 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI84281 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; +var NTI84227 = {size: 0, kind: 14, base: null, node: null, finalizer: null}; +var NTI84565 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; +var NTI84563 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; +var NTI84561 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; +var NTI84231 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI84229 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; +var NTI86305 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; +var NTI46850 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI46858 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI43006 = {size: 0,kind: 31,base: null,node: null,finalizer: null}; +var NTI62231 = {size: 0, kind: 18, base: null, node: null, finalizer: null}; +var NTI46808 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI46914 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; +var NTI43016 = {size: 0,kind: 40,base: null,node: null,finalizer: null}; +var NTI43040 = {size: 0,kind: 28,base: null,node: null,finalizer: null}; +var NTI43042 = {size: 0,kind: 29,base: null,node: null,finalizer: null}; +var NTI46908 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; +var NTI46826 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI46828 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI46842 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI46846 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NNI46846 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI46846.node = NNI46846; +var NNI46842 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI46842.node = NNI46842; +var NNI46828 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI46828.node = NNI46828; +NTI46908.base = NTI46826; +NTI46914.base = NTI46826; +var NNI46826 = {kind: 2, len: 6, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "parent", len: 0, typ: NTI46908, name: "parent", sons: null}, +{kind: 1, offset: "name", len: 0, typ: NTI43042, name: "name", sons: null}, +{kind: 1, offset: "message", len: 0, typ: NTI43040, name: "msg", sons: null}, +{kind: 1, offset: "trace", len: 0, typ: NTI43040, name: "trace", sons: null}, +{kind: 1, offset: "raiseId", len: 0, typ: NTI43016, name: "raiseId", sons: null}, +{kind: 1, offset: "up", len: 0, typ: NTI46914, name: "up", sons: null}]}; +NTI46826.node = NNI46826; +var NNI46808 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI46808.node = NNI46808; +NTI46826.base = NTI46808; +NTI46828.base = NTI46826; +NTI46842.base = NTI46828; +NTI46846.base = NTI46842; +var NNI62231 = {kind: 2, len: 2, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "Field0", len: 0, typ: NTI43042, name: "Field0", sons: null}, +{kind: 1, offset: "Field1", len: 0, typ: NTI43006, name: "Field1", sons: null}]}; +NTI62231.node = NNI62231; +var NNI46858 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI46858.node = NNI46858; +NTI46858.base = NTI46828; +var NNI46850 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI46850.node = NNI46850; +NTI46850.base = NTI46828; +NTI84561.base = NTI84229; +NTI84563.base = NTI84229; +NTI84565.base = NTI84229; +var NNI84227 = {kind: 2, offset: 0, typ: null, name: null, len: 12, sons: {"1": {kind: 1, offset: 1, typ: NTI84227, name: "ElementNode", len: 0, sons: null}, +"2": {kind: 1, offset: 2, typ: NTI84227, name: "AttributeNode", len: 0, sons: null}, +"3": {kind: 1, offset: 3, typ: NTI84227, name: "TextNode", len: 0, sons: null}, +"4": {kind: 1, offset: 4, typ: NTI84227, name: "CDATANode", len: 0, sons: null}, +"5": {kind: 1, offset: 5, typ: NTI84227, name: "EntityRefNode", len: 0, sons: null}, +"6": {kind: 1, offset: 6, typ: NTI84227, name: "EntityNode", len: 0, sons: null}, +"7": {kind: 1, offset: 7, typ: NTI84227, name: "ProcessingInstructionNode", len: 0, sons: null}, +"8": {kind: 1, offset: 8, typ: NTI84227, name: "CommentNode", len: 0, sons: null}, +"9": {kind: 1, offset: 9, typ: NTI84227, name: "DocumentNode", len: 0, sons: null}, +"10": {kind: 1, offset: 10, typ: NTI84227, name: "DocumentTypeNode", len: 0, sons: null}, +"11": {kind: 1, offset: 11, typ: NTI84227, name: "DocumentFragmentNode", len: 0, sons: null}, +"12": {kind: 1, offset: 12, typ: NTI84227, name: "NotationNode", len: 0, sons: null}}}; +NTI84227.node = NNI84227; +var NNI84283 = {kind: 2, len: 91, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "background", len: 0, typ: NTI43042, name: "background", sons: null}, +{kind: 1, offset: "backgroundAttachment", len: 0, typ: NTI43042, name: "backgroundAttachment", sons: null}, +{kind: 1, offset: "backgroundColor", len: 0, typ: NTI43042, name: "backgroundColor", sons: null}, +{kind: 1, offset: "backgroundImage", len: 0, typ: NTI43042, name: "backgroundImage", sons: null}, +{kind: 1, offset: "backgroundPosition", len: 0, typ: NTI43042, name: "backgroundPosition", sons: null}, +{kind: 1, offset: "backgroundRepeat", len: 0, typ: NTI43042, name: "backgroundRepeat", sons: null}, +{kind: 1, offset: "border", len: 0, typ: NTI43042, name: "border", sons: null}, +{kind: 1, offset: "borderBottom", len: 0, typ: NTI43042, name: "borderBottom", sons: null}, +{kind: 1, offset: "borderBottomColor", len: 0, typ: NTI43042, name: "borderBottomColor", sons: null}, +{kind: 1, offset: "borderBottomStyle", len: 0, typ: NTI43042, name: "borderBottomStyle", sons: null}, +{kind: 1, offset: "borderBottomWidth", len: 0, typ: NTI43042, name: "borderBottomWidth", sons: null}, +{kind: 1, offset: "borderColor", len: 0, typ: NTI43042, name: "borderColor", sons: null}, +{kind: 1, offset: "borderLeft", len: 0, typ: NTI43042, name: "borderLeft", sons: null}, +{kind: 1, offset: "borderLeftColor", len: 0, typ: NTI43042, name: "borderLeftColor", sons: null}, +{kind: 1, offset: "borderLeftStyle", len: 0, typ: NTI43042, name: "borderLeftStyle", sons: null}, +{kind: 1, offset: "borderLeftWidth", len: 0, typ: NTI43042, name: "borderLeftWidth", sons: null}, +{kind: 1, offset: "borderRight", len: 0, typ: NTI43042, name: "borderRight", sons: null}, +{kind: 1, offset: "borderRightColor", len: 0, typ: NTI43042, name: "borderRightColor", sons: null}, +{kind: 1, offset: "borderRightStyle", len: 0, typ: NTI43042, name: "borderRightStyle", sons: null}, +{kind: 1, offset: "borderRightWidth", len: 0, typ: NTI43042, name: "borderRightWidth", sons: null}, +{kind: 1, offset: "borderStyle", len: 0, typ: NTI43042, name: "borderStyle", sons: null}, +{kind: 1, offset: "borderTop", len: 0, typ: NTI43042, name: "borderTop", sons: null}, +{kind: 1, offset: "borderTopColor", len: 0, typ: NTI43042, name: "borderTopColor", sons: null}, +{kind: 1, offset: "borderTopStyle", len: 0, typ: NTI43042, name: "borderTopStyle", sons: null}, +{kind: 1, offset: "borderTopWidth", len: 0, typ: NTI43042, name: "borderTopWidth", sons: null}, +{kind: 1, offset: "borderWidth", len: 0, typ: NTI43042, name: "borderWidth", sons: null}, +{kind: 1, offset: "bottom", len: 0, typ: NTI43042, name: "bottom", sons: null}, +{kind: 1, offset: "captionSide", len: 0, typ: NTI43042, name: "captionSide", sons: null}, +{kind: 1, offset: "clear", len: 0, typ: NTI43042, name: "clear", sons: null}, +{kind: 1, offset: "clip", len: 0, typ: NTI43042, name: "clip", sons: null}, +{kind: 1, offset: "color", len: 0, typ: NTI43042, name: "color", sons: null}, +{kind: 1, offset: "cursor", len: 0, typ: NTI43042, name: "cursor", sons: null}, +{kind: 1, offset: "direction", len: 0, typ: NTI43042, name: "direction", sons: null}, +{kind: 1, offset: "display", len: 0, typ: NTI43042, name: "display", sons: null}, +{kind: 1, offset: "emptyCells", len: 0, typ: NTI43042, name: "emptyCells", sons: null}, +{kind: 1, offset: "cssFloat", len: 0, typ: NTI43042, name: "cssFloat", sons: null}, +{kind: 1, offset: "font", len: 0, typ: NTI43042, name: "font", sons: null}, +{kind: 1, offset: "fontFamily", len: 0, typ: NTI43042, name: "fontFamily", sons: null}, +{kind: 1, offset: "fontSize", len: 0, typ: NTI43042, name: "fontSize", sons: null}, +{kind: 1, offset: "fontStretch", len: 0, typ: NTI43042, name: "fontStretch", sons: null}, +{kind: 1, offset: "fontStyle", len: 0, typ: NTI43042, name: "fontStyle", sons: null}, +{kind: 1, offset: "fontVariant", len: 0, typ: NTI43042, name: "fontVariant", sons: null}, +{kind: 1, offset: "fontWeight", len: 0, typ: NTI43042, name: "fontWeight", sons: null}, +{kind: 1, offset: "height", len: 0, typ: NTI43042, name: "height", sons: null}, +{kind: 1, offset: "left", len: 0, typ: NTI43042, name: "left", sons: null}, +{kind: 1, offset: "letterSpacing", len: 0, typ: NTI43042, name: "letterSpacing", sons: null}, +{kind: 1, offset: "lineHeight", len: 0, typ: NTI43042, name: "lineHeight", sons: null}, +{kind: 1, offset: "listStyle", len: 0, typ: NTI43042, name: "listStyle", sons: null}, +{kind: 1, offset: "listStyleImage", len: 0, typ: NTI43042, name: "listStyleImage", sons: null}, +{kind: 1, offset: "listStylePosition", len: 0, typ: NTI43042, name: "listStylePosition", sons: null}, +{kind: 1, offset: "listStyleType", len: 0, typ: NTI43042, name: "listStyleType", sons: null}, +{kind: 1, offset: "margin", len: 0, typ: NTI43042, name: "margin", sons: null}, +{kind: 1, offset: "marginBottom", len: 0, typ: NTI43042, name: "marginBottom", sons: null}, +{kind: 1, offset: "marginLeft", len: 0, typ: NTI43042, name: "marginLeft", sons: null}, +{kind: 1, offset: "marginRight", len: 0, typ: NTI43042, name: "marginRight", sons: null}, +{kind: 1, offset: "marginTop", len: 0, typ: NTI43042, name: "marginTop", sons: null}, +{kind: 1, offset: "maxHeight", len: 0, typ: NTI43042, name: "maxHeight", sons: null}, +{kind: 1, offset: "maxWidth", len: 0, typ: NTI43042, name: "maxWidth", sons: null}, +{kind: 1, offset: "minHeight", len: 0, typ: NTI43042, name: "minHeight", sons: null}, +{kind: 1, offset: "minWidth", len: 0, typ: NTI43042, name: "minWidth", sons: null}, +{kind: 1, offset: "overflow", len: 0, typ: NTI43042, name: "overflow", sons: null}, +{kind: 1, offset: "padding", len: 0, typ: NTI43042, name: "padding", sons: null}, +{kind: 1, offset: "paddingBottom", len: 0, typ: NTI43042, name: "paddingBottom", sons: null}, +{kind: 1, offset: "paddingLeft", len: 0, typ: NTI43042, name: "paddingLeft", sons: null}, +{kind: 1, offset: "paddingRight", len: 0, typ: NTI43042, name: "paddingRight", sons: null}, +{kind: 1, offset: "paddingTop", len: 0, typ: NTI43042, name: "paddingTop", sons: null}, +{kind: 1, offset: "pageBreakAfter", len: 0, typ: NTI43042, name: "pageBreakAfter", sons: null}, +{kind: 1, offset: "pageBreakBefore", len: 0, typ: NTI43042, name: "pageBreakBefore", sons: null}, +{kind: 1, offset: "pointerEvents", len: 0, typ: NTI43042, name: "pointerEvents", sons: null}, +{kind: 1, offset: "position", len: 0, typ: NTI43042, name: "position", sons: null}, +{kind: 1, offset: "right", len: 0, typ: NTI43042, name: "right", sons: null}, +{kind: 1, offset: "scrollbar3dLightColor", len: 0, typ: NTI43042, name: "scrollbar3dLightColor", sons: null}, +{kind: 1, offset: "scrollbarArrowColor", len: 0, typ: NTI43042, name: "scrollbarArrowColor", sons: null}, +{kind: 1, offset: "scrollbarBaseColor", len: 0, typ: NTI43042, name: "scrollbarBaseColor", sons: null}, +{kind: 1, offset: "scrollbarDarkshadowColor", len: 0, typ: NTI43042, name: "scrollbarDarkshadowColor", sons: null}, +{kind: 1, offset: "scrollbarFaceColor", len: 0, typ: NTI43042, name: "scrollbarFaceColor", sons: null}, +{kind: 1, offset: "scrollbarHighlightColor", len: 0, typ: NTI43042, name: "scrollbarHighlightColor", sons: null}, +{kind: 1, offset: "scrollbarShadowColor", len: 0, typ: NTI43042, name: "scrollbarShadowColor", sons: null}, +{kind: 1, offset: "scrollbarTrackColor", len: 0, typ: NTI43042, name: "scrollbarTrackColor", sons: null}, +{kind: 1, offset: "tableLayout", len: 0, typ: NTI43042, name: "tableLayout", sons: null}, +{kind: 1, offset: "textAlign", len: 0, typ: NTI43042, name: "textAlign", sons: null}, +{kind: 1, offset: "textDecoration", len: 0, typ: NTI43042, name: "textDecoration", sons: null}, +{kind: 1, offset: "textIndent", len: 0, typ: NTI43042, name: "textIndent", sons: null}, +{kind: 1, offset: "textTransform", len: 0, typ: NTI43042, name: "textTransform", sons: null}, +{kind: 1, offset: "transform", len: 0, typ: NTI43042, name: "transform", sons: null}, +{kind: 1, offset: "top", len: 0, typ: NTI43042, name: "top", sons: null}, +{kind: 1, offset: "verticalAlign", len: 0, typ: NTI43042, name: "verticalAlign", sons: null}, +{kind: 1, offset: "visibility", len: 0, typ: NTI43042, name: "visibility", sons: null}, +{kind: 1, offset: "width", len: 0, typ: NTI43042, name: "width", sons: null}, +{kind: 1, offset: "wordSpacing", len: 0, typ: NTI43042, name: "wordSpacing", sons: null}, +{kind: 1, offset: "zIndex", len: 0, typ: NTI43006, name: "zIndex", sons: null}]}; +NTI84283.node = NNI84283; +NTI84283.base = NTI46808; +NTI84281.base = NTI84283; +var NNI84231 = {kind: 2, len: 14, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "attributes", len: 0, typ: NTI84561, name: "attributes", sons: null}, +{kind: 1, offset: "childNodes", len: 0, typ: NTI84563, name: "childNodes", sons: null}, +{kind: 1, offset: "children", len: 0, typ: NTI84565, name: "children", sons: null}, +{kind: 1, offset: "data", len: 0, typ: NTI43042, name: "data", sons: null}, +{kind: 1, offset: "firstChild", len: 0, typ: NTI84229, name: "firstChild", sons: null}, +{kind: 1, offset: "lastChild", len: 0, typ: NTI84229, name: "lastChild", sons: null}, +{kind: 1, offset: "nextSibling", len: 0, typ: NTI84229, name: "nextSibling", sons: null}, +{kind: 1, offset: "nodeName", len: 0, typ: NTI43042, name: "nodeName", sons: null}, +{kind: 1, offset: "nodeType", len: 0, typ: NTI84227, name: "nodeType", sons: null}, +{kind: 1, offset: "nodeValue", len: 0, typ: NTI43042, name: "nodeValue", sons: null}, +{kind: 1, offset: "parentNode", len: 0, typ: NTI84229, name: "parentNode", sons: null}, +{kind: 1, offset: "previousSibling", len: 0, typ: NTI84229, name: "previousSibling", sons: null}, +{kind: 1, offset: "innerHTML", len: 0, typ: NTI43042, name: "innerHTML", sons: null}, +{kind: 1, offset: "style", len: 0, typ: NTI84281, name: "style", sons: null}]}; +NTI84231.node = NNI84231; +var NNI84205 = {kind: 2, len: 20, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "onabort", len: 0, typ: NTI84372, name: "onabort", sons: null}, +{kind: 1, offset: "onblur", len: 0, typ: NTI84376, name: "onblur", sons: null}, +{kind: 1, offset: "onchange", len: 0, typ: NTI84380, name: "onchange", sons: null}, +{kind: 1, offset: "onclick", len: 0, typ: NTI84384, name: "onclick", sons: null}, +{kind: 1, offset: "ondblclick", len: 0, typ: NTI84388, name: "ondblclick", sons: null}, +{kind: 1, offset: "onerror", len: 0, typ: NTI84392, name: "onerror", sons: null}, +{kind: 1, offset: "onfocus", len: 0, typ: NTI84396, name: "onfocus", sons: null}, +{kind: 1, offset: "onkeydown", len: 0, typ: NTI84400, name: "onkeydown", sons: null}, +{kind: 1, offset: "onkeypress", len: 0, typ: NTI84404, name: "onkeypress", sons: null}, +{kind: 1, offset: "onkeyup", len: 0, typ: NTI84408, name: "onkeyup", sons: null}, +{kind: 1, offset: "onload", len: 0, typ: NTI84412, name: "onload", sons: null}, +{kind: 1, offset: "onmousedown", len: 0, typ: NTI84416, name: "onmousedown", sons: null}, +{kind: 1, offset: "onmousemove", len: 0, typ: NTI84420, name: "onmousemove", sons: null}, +{kind: 1, offset: "onmouseout", len: 0, typ: NTI84424, name: "onmouseout", sons: null}, +{kind: 1, offset: "onmouseover", len: 0, typ: NTI84428, name: "onmouseover", sons: null}, +{kind: 1, offset: "onmouseup", len: 0, typ: NTI84432, name: "onmouseup", sons: null}, +{kind: 1, offset: "onreset", len: 0, typ: NTI84436, name: "onreset", sons: null}, +{kind: 1, offset: "onselect", len: 0, typ: NTI84440, name: "onselect", sons: null}, +{kind: 1, offset: "onsubmit", len: 0, typ: NTI84444, name: "onsubmit", sons: null}, +{kind: 1, offset: "onunload", len: 0, typ: NTI84448, name: "onunload", sons: null}]}; +NTI84205.node = NNI84205; +NTI84205.base = NTI46808; +NTI84231.base = NTI84205; +NTI84229.base = NTI84231; +NTI86305.base = NTI84229; +NTI205327.base = NTI43042; +var NNI46862 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI46862.node = NNI46862; +NTI46862.base = NTI46828; +var NNI202074 = {kind: 2, len: 2, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "Field0", len: 0, typ: NTI43006, name: "Field0", sons: null}, +{kind: 1, offset: "Field1", len: 0, typ: NTI43032, name: "Field1", sons: null}]}; +NTI202074.node = NNI202074; -function makeNimstrLit(c_54391) { - var ln = c_54391.length; +function makeNimstrLit(c_64273) { + var ln = c_64273.length; var result = new Array(ln); for (var i = 0; i < ln; ++i) { - result[i] = c_54391.charCodeAt(i); + result[i] = c_64273.charCodeAt(i); } return result; @@ -279,99 +279,99 @@ function setConstr() { } var ConstSet1 = setConstr(17, 16, 4, 18, 27, 19, 23, 22, 21); -function nimCopy(dest_55427, src_55428, ti_55429) { - var result_55619 = null; +function nimCopy(dest_65442, src_65443, ti_65444) { + var result_65619 = null; - switch (ti_55429.kind) { + switch (ti_65444.kind) { case 21: case 22: case 23: case 5: - if (!(is_fat_pointer_55401(ti_55429))) { - result_55619 = src_55428; + if (!(is_fat_pointer_65401(ti_65444))) { + result_65619 = src_65443; } else { - result_55619 = [src_55428[0], src_55428[1]]; + result_65619 = [src_65443[0], src_65443[1]]; } break; case 19: - if (dest_55427 === null || dest_55427 === undefined) { - dest_55427 = {}; + if (dest_65442 === null || dest_65442 === undefined) { + dest_65442 = {}; } else { - for (var key in dest_55427) { delete dest_55427[key]; } + for (var key in dest_65442) { delete dest_65442[key]; } } - for (var key in src_55428) { dest_55427[key] = src_55428[key]; } - result_55619 = dest_55427; + for (var key in src_65443) { dest_65442[key] = src_65443[key]; } + result_65619 = dest_65442; break; case 18: case 17: - if (!((ti_55429.base == null))) { - result_55619 = nimCopy(dest_55427, src_55428, ti_55429.base); + if (!((ti_65444.base == null))) { + result_65619 = nimCopy(dest_65442, src_65443, ti_65444.base); } else { - if ((ti_55429.kind == 17)) { - result_55619 = (dest_55427 === null || dest_55427 === undefined) ? {m_type: ti_55429} : dest_55427; + if ((ti_65444.kind == 17)) { + result_65619 = (dest_65442 === null || dest_65442 === undefined) ? {m_type: ti_65444} : dest_65442; } else { - result_55619 = (dest_55427 === null || dest_55427 === undefined) ? {} : dest_55427; + result_65619 = (dest_65442 === null || dest_65442 === undefined) ? {} : dest_65442; } } - nimCopyAux(result_55619, src_55428, ti_55429.node); + nimCopyAux(result_65619, src_65443, ti_65444.node); break; case 24: case 4: case 27: case 16: - if (src_55428 === null) { - result_55619 = null; + if (src_65443 === null) { + result_65619 = null; } else { - if (dest_55427 === null || dest_55427 === undefined) { - dest_55427 = new Array(src_55428.length); + if (dest_65442 === null || dest_65442 === undefined) { + dest_65442 = new Array(src_65443.length); } else { - dest_55427.length = src_55428.length; + dest_65442.length = src_65443.length; } - result_55619 = dest_55427; - for (var i = 0; i < src_55428.length; ++i) { - result_55619[i] = nimCopy(result_55619[i], src_55428[i], ti_55429.base); + result_65619 = dest_65442; + for (var i = 0; i < src_65443.length; ++i) { + result_65619[i] = nimCopy(result_65619[i], src_65443[i], ti_65444.base); } } break; case 28: - if (src_55428 !== null) { - result_55619 = src_55428.slice(0); + if (src_65443 !== null) { + result_65619 = src_65443.slice(0); } break; default: - result_55619 = src_55428; + result_65619 = src_65443; break; } - return result_55619; + return result_65619; } -function arrayConstr(len_55671, value_55672, typ_55673) { - var result = new Array(len_55671); - for (var i = 0; i < len_55671; ++i) result[i] = nimCopy(null, value_55672, typ_55673); +function arrayConstr(len_65761, value_65762, typ_65763) { + var result = new Array(len_65761); + for (var i = 0; i < len_65761; ++i) result[i] = nimCopy(null, value_65762, typ_65763); return result; } -function cstrToNimstr(c_54408) { - var ln = c_54408.length; +function cstrToNimstr(c_64290) { + var ln = c_64290.length; var result = new Array(ln); var r = 0; for (var i = 0; i < ln; ++i) { - var ch = c_54408.charCodeAt(i); + var ch = c_64290.charCodeAt(i); if (ch < 128) { result[r] = ch; @@ -386,7 +386,7 @@ function cstrToNimstr(c_54408) { } else { ++i; - ch = 65536 + (((ch & 1023) << 10) | (c_54408.charCodeAt(i) & 1023)); + ch = 65536 + (((ch & 1023) << 10) | (c_64290.charCodeAt(i) & 1023)); result[r] = (ch >> 18) | 240; ++r; result[r] = ((ch >> 12) & 63) | 128; @@ -405,9 +405,9 @@ function cstrToNimstr(c_54408) { } -function toJSStr(s_54425) { - if (s_54425 === null) return ""; - var len = s_54425.length; +function toJSStr(s_64307) { + if (s_64307 === null) return ""; + var len = s_64307.length; var asciiPart = new Array(len); var fcc = String.fromCharCode; var nonAsciiPart = null; @@ -415,15 +415,15 @@ function toJSStr(s_54425) { for (var i = 0; i < len; ++i) { if (nonAsciiPart !== null) { var offset = (i - nonAsciiOffset) * 2; - var code = s_54425[i].toString(16); + var code = s_64307[i].toString(16); if (code.length == 1) { code = "0"+code; } nonAsciiPart[offset] = "%"; nonAsciiPart[offset + 1] = code; } - else if (s_54425[i] < 128) - asciiPart[i] = fcc(s_54425[i]); + else if (s_64307[i] < 128) + asciiPart[i] = fcc(s_64307[i]); else { asciiPart.length = i; nonAsciiOffset = i; @@ -439,20 +439,20 @@ function toJSStr(s_54425) { } -function raiseException(e_54018, ename_54019) { - e_54018.name = ename_54019; +function raiseException(e_62818, ename_62819) { + e_62818.name = ename_62819; if ((excHandler == 0)) { - unhandledException(e_54018); + unhandledException(e_62818); } - e_54018.trace = nimCopy(null, raw_write_stack_trace_53838(), NTI37040); - throw e_54018; + e_62818.trace = nimCopy(null, raw_write_stack_trace_62543(), NTI43040); + throw e_62818; } -function addInt(a_54803, b_54804) { - var result = a_54803 + b_54804; +function addInt(a_64603, b_64604) { + var result = a_64603 + b_64604; if (result > 2147483647 || result < -2147483648) raiseOverflow(); return result; @@ -460,28 +460,28 @@ function addInt(a_54803, b_54804) { } -function chckIndx(i_55690, a_55691, b_55692) { +function chckIndx(i_65780, a_65781, b_65782) { var Tmp1; - var result_55693 = 0; + var result_65783 = 0; BeforeRet: do { - if (!(a_55691 <= i_55690)) Tmp1 = false; else { Tmp1 = (i_55690 <= b_55692); } if (Tmp1) { - result_55693 = i_55690; + if (!(a_65781 <= i_65780)) Tmp1 = false; else { Tmp1 = (i_65780 <= b_65782); } if (Tmp1) { + result_65783 = i_65780; break BeforeRet; } else { - raiseIndexError(); + raiseIndexError(i_65780, a_65781, b_65782); } } while (false); - return result_55693; + return result_65783; } -function subInt(a_54821, b_54822) { - var result = a_54821 - b_54822; +function subInt(a_64621, b_64622) { + var result = a_64621 - b_64622; if (result > 2147483647 || result < -2147483648) raiseOverflow(); return result; @@ -490,14 +490,14 @@ function subInt(a_54821, b_54822) { } var ConstSet2 = setConstr([65, 90]); -function chckRange(i_55709, a_55710, b_55711) { +function chckRange(i_65814, a_65815, b_65816) { var Tmp1; - var result_55712 = 0; + var result_65817 = 0; BeforeRet: do { - if (!(a_55710 <= i_55709)) Tmp1 = false; else { Tmp1 = (i_55709 <= b_55711); } if (Tmp1) { - result_55712 = i_55709; + if (!(a_65815 <= i_65814)) Tmp1 = false; else { Tmp1 = (i_65814 <= b_65816); } if (Tmp1) { + result_65817 = i_65814; break BeforeRet; } else { @@ -506,14 +506,14 @@ function chckRange(i_55709, a_55710, b_55711) { } while (false); - return result_55712; + return result_65817; } var ConstSet3 = setConstr(95, 32, 46); var ConstSet4 = setConstr(95, 32, 46); -function mulInt(a_54839, b_54840) { - var result = a_54839 * b_54840; +function mulInt(a_64639, b_64640) { + var result = a_64639 * b_64640; if (result > 2147483647 || result < -2147483648) raiseOverflow(); return result; @@ -525,51 +525,51 @@ var ConstSet6 = setConstr([65, 90], [97, 122]); var ConstSet7 = setConstr([97, 122]); var ConstSet8 = setConstr([65, 90]); -function nimMax(a_55158, b_55159) { +function nimMax(a_64973, b_64974) { var Tmp1; - var result_55160 = 0; + var result_64975 = 0; BeforeRet: do { - if ((b_55159 <= a_55158)) { - Tmp1 = a_55158; + if ((b_64974 <= a_64973)) { + Tmp1 = a_64973; } else { - Tmp1 = b_55159; + Tmp1 = b_64974; } - result_55160 = Tmp1; + result_64975 = Tmp1; break BeforeRet; } while (false); - return result_55160; + return result_64975; } -function nimMin(a_55140, b_55141) { +function nimMin(a_64955, b_64956) { var Tmp1; - var result_55142 = 0; + var result_64957 = 0; BeforeRet: do { - if ((a_55140 <= b_55141)) { - Tmp1 = a_55140; + if ((a_64955 <= b_64956)) { + Tmp1 = a_64955; } else { - Tmp1 = b_55141; + Tmp1 = b_64956; } - result_55142 = Tmp1; + result_64957 = Tmp1; break BeforeRet; } while (false); - return result_55142; + return result_64957; } var nim_program_result = 0; -var global_raise_hook_51418 = [null]; -var local_raise_hook_51423 = [null]; -var out_of_mem_hook_51426 = [null]; +var global_raise_hook_59618 = [null]; +var local_raise_hook_59623 = [null]; +var out_of_mem_hook_59626 = [null]; if (!Math.trunc) { Math.trunc = function(v) { v = +v; @@ -578,38 +578,38 @@ var out_of_mem_hook_51426 = [null]; return (v - v % 1) || (v < 0 ? -0 : v === 0 ? v : 0); }; } -var alternative_182285 = [null]; +var alternative_205020 = [null]; -function is_fat_pointer_55401(ti_55403) { - var result_55404 = false; +function is_fat_pointer_65401(ti_65403) { + var result_65404 = false; BeforeRet: do { - result_55404 = !((ConstSet1[ti_55403.base.kind] != undefined)); + result_65404 = !((ConstSet1[ti_65403.base.kind] != undefined)); break BeforeRet; } while (false); - return result_55404; + return result_65404; } -function nimCopyAux(dest_55432, src_55433, n_55435) { - switch (n_55435.kind) { +function nimCopyAux(dest_65447, src_65448, n_65450) { + switch (n_65450.kind) { case 0: break; case 1: - dest_55432[n_55435.offset] = nimCopy(dest_55432[n_55435.offset], src_55433[n_55435.offset], n_55435.typ); + dest_65447[n_65450.offset] = nimCopy(dest_65447[n_65450.offset], src_65448[n_65450.offset], n_65450.typ); break; case 2: - for (var i = 0; i < n_55435.sons.length; i++) { - nimCopyAux(dest_55432, src_55433, n_55435.sons[i]); + for (var i = 0; i < n_65450.sons.length; i++) { + nimCopyAux(dest_65447, src_65448, n_65450.sons[i]); } break; case 3: - dest_55432[n_55435.offset] = nimCopy(dest_55432[n_55435.offset], src_55433[n_55435.offset], n_55435.typ); - for (var i = 0; i < n_55435.sons.length; ++i) { - nimCopyAux(dest_55432, src_55433, n_55435.sons[i][1]); + dest_65447[n_65450.offset] = nimCopy(dest_65447[n_65450.offset], src_65448[n_65450.offset], n_65450.typ); + for (var i = 0; i < n_65450.sons.length; ++i) { + nimCopyAux(dest_65447, src_65448, n_65450.sons[i][1]); } break; @@ -618,112 +618,112 @@ function nimCopyAux(dest_55432, src_55433, n_55435) { } -function add_51438(x_51441, x_51441_Idx, y_51442) { - if (x_51441[x_51441_Idx] === null) { x_51441[x_51441_Idx] = []; } - var off = x_51441[x_51441_Idx].length; - x_51441[x_51441_Idx].length += y_51442.length; - for (var i = 0; i < y_51442.length; ++i) { - x_51441[x_51441_Idx][off+i] = y_51442.charCodeAt(i); +function add_59638(x_59641, x_59641_Idx, y_59642) { + if (x_59641[x_59641_Idx] === null) { x_59641[x_59641_Idx] = []; } + var off = x_59641[x_59641_Idx].length; + x_59641[x_59641_Idx].length += y_59642.length; + for (var i = 0; i < y_59642.length; ++i) { + x_59641[x_59641_Idx][off+i] = y_59642.charCodeAt(i); } } -function aux_write_stack_trace_53536(f_53538) { +function aux_write_stack_trace_62226(f_62228) { var Tmp3; - var result_53539 = [null]; + var result_62229 = [null]; - var it_53547 = f_53538; - var i_53549 = 0; - var total_53551 = 0; - var temp_frames_53558 = arrayConstr(64, {Field0: null, Field1: 0}, NTI53541); + var it_62237 = f_62228; + var i_62239 = 0; + var total_62241 = 0; + var temp_frames_62248 = arrayConstr(64, {Field0: null, Field1: 0}, NTI62231); L1: do { L2: while (true) { - if (!!((it_53547 == null))) Tmp3 = false; else { Tmp3 = (i_53549 <= 63); } if (!Tmp3) break L2; - temp_frames_53558[i_53549].Field0 = it_53547.procname; - temp_frames_53558[i_53549].Field1 = it_53547.line; - i_53549 += 1; - total_53551 += 1; - it_53547 = it_53547.prev; + if (!!((it_62237 == null))) Tmp3 = false; else { Tmp3 = (i_62239 <= 63); } if (!Tmp3) break L2; + temp_frames_62248[i_62239].Field0 = it_62237.procname; + temp_frames_62248[i_62239].Field1 = it_62237.line; + i_62239 += 1; + total_62241 += 1; + it_62237 = it_62237.prev; } } while(false); L4: do { L5: while (true) { - if (!!((it_53547 == null))) break L5; - total_53551 += 1; - it_53547 = it_53547.prev; + if (!!((it_62237 == null))) break L5; + total_62241 += 1; + it_62237 = it_62237.prev; } } while(false); - result_53539[0] = nimCopy(null, [], NTI37040); - if (!((total_53551 == i_53549))) { - if (result_53539[0] != null) { result_53539[0] = (result_53539[0]).concat(makeNimstrLit("(")); } else { result_53539[0] = makeNimstrLit("("); }; - if (result_53539[0] != null) { result_53539[0] = (result_53539[0]).concat(cstrToNimstr(((total_53551 - i_53549))+"")); } else { result_53539[0] = cstrToNimstr(((total_53551 - i_53549))+"").slice(); }; - if (result_53539[0] != null) { result_53539[0] = (result_53539[0]).concat(makeNimstrLit(" calls omitted) ...\x0A")); } else { result_53539[0] = makeNimstrLit(" calls omitted) ...\x0A"); }; + result_62229[0] = nimCopy(null, [], NTI43040); + if (!((total_62241 == i_62239))) { + if (result_62229[0] != null) { result_62229[0] = (result_62229[0]).concat(makeNimstrLit("(")); } else { result_62229[0] = makeNimstrLit("("); }; + if (result_62229[0] != null) { result_62229[0] = (result_62229[0]).concat(cstrToNimstr(((total_62241 - i_62239))+"")); } else { result_62229[0] = cstrToNimstr(((total_62241 - i_62239))+"").slice(); }; + if (result_62229[0] != null) { result_62229[0] = (result_62229[0]).concat(makeNimstrLit(" calls omitted) ...\x0A")); } else { result_62229[0] = makeNimstrLit(" calls omitted) ...\x0A"); }; } L6: do { - var j_53821 = 0; - var colontmp__182426 = 0; - colontmp__182426 = (i_53549 - 1); - var res_182431 = colontmp__182426; + var j_62421 = 0; + var colontmp__205206 = 0; + colontmp__205206 = (i_62239 - 1); + var res_205211 = colontmp__205206; L7: do { L8: while (true) { - if (!(0 <= res_182431)) break L8; - j_53821 = res_182431; - add_51438(result_53539, 0, temp_frames_53558[j_53821].Field0); - if ((0 < temp_frames_53558[j_53821].Field1)) { - if (result_53539[0] != null) { result_53539[0] = (result_53539[0]).concat(makeNimstrLit(", line: ")); } else { result_53539[0] = makeNimstrLit(", line: "); }; - if (result_53539[0] != null) { result_53539[0] = (result_53539[0]).concat(cstrToNimstr((temp_frames_53558[j_53821].Field1)+"")); } else { result_53539[0] = cstrToNimstr((temp_frames_53558[j_53821].Field1)+"").slice(); }; + if (!(0 <= res_205211)) break L8; + j_62421 = res_205211; + add_59638(result_62229, 0, temp_frames_62248[j_62421].Field0); + if ((0 < temp_frames_62248[j_62421].Field1)) { + if (result_62229[0] != null) { result_62229[0] = (result_62229[0]).concat(makeNimstrLit(", line: ")); } else { result_62229[0] = makeNimstrLit(", line: "); }; + if (result_62229[0] != null) { result_62229[0] = (result_62229[0]).concat(cstrToNimstr((temp_frames_62248[j_62421].Field1)+"")); } else { result_62229[0] = cstrToNimstr((temp_frames_62248[j_62421].Field1)+"").slice(); }; } - if (result_53539[0] != null) { result_53539[0] = (result_53539[0]).concat(makeNimstrLit("\x0A")); } else { result_53539[0] = makeNimstrLit("\x0A"); }; - res_182431 -= 1; + if (result_62229[0] != null) { result_62229[0] = (result_62229[0]).concat(makeNimstrLit("\x0A")); } else { result_62229[0] = makeNimstrLit("\x0A"); }; + res_205211 -= 1; } } while(false); } while(false); - return result_53539[0]; + return result_62229[0]; } -function raw_write_stack_trace_53838() { - var result_53840 = null; +function raw_write_stack_trace_62543() { + var result_62545 = null; if (!((framePtr == null))) { - result_53840 = nimCopy(null, (makeNimstrLit("Traceback (most recent call last)\x0A") || []).concat(aux_write_stack_trace_53536(framePtr) || []), NTI37040); + result_62545 = nimCopy(null, (makeNimstrLit("Traceback (most recent call last)\x0A") || []).concat(aux_write_stack_trace_62226(framePtr) || []), NTI43040); } else { - result_53840 = nimCopy(null, makeNimstrLit("No stack traceback available\x0A"), NTI37040); + result_62545 = nimCopy(null, makeNimstrLit("No stack traceback available\x0A"), NTI43040); } - return result_53840; + return result_62545; } -function unhandledException(e_53899) { - var buf_53900 = [[]]; - if (!(((e_53899.message != null ? e_53899.message.length : 0) == 0))) { - if (buf_53900[0] != null) { buf_53900[0] = (buf_53900[0]).concat(makeNimstrLit("Error: unhandled exception: ")); } else { buf_53900[0] = makeNimstrLit("Error: unhandled exception: "); }; - if (buf_53900[0] != null) { buf_53900[0] = (buf_53900[0]).concat(e_53899.message); } else { buf_53900[0] = e_53899.message.slice(); }; +function unhandledException(e_62634) { + var buf_62635 = [[]]; + if (!(((e_62634.message != null ? e_62634.message.length : 0) == 0))) { + if (buf_62635[0] != null) { buf_62635[0] = (buf_62635[0]).concat(makeNimstrLit("Error: unhandled exception: ")); } else { buf_62635[0] = makeNimstrLit("Error: unhandled exception: "); }; + if (buf_62635[0] != null) { buf_62635[0] = (buf_62635[0]).concat(e_62634.message); } else { buf_62635[0] = e_62634.message.slice(); }; } else { - if (buf_53900[0] != null) { buf_53900[0] = (buf_53900[0]).concat(makeNimstrLit("Error: unhandled exception")); } else { buf_53900[0] = makeNimstrLit("Error: unhandled exception"); }; + if (buf_62635[0] != null) { buf_62635[0] = (buf_62635[0]).concat(makeNimstrLit("Error: unhandled exception")); } else { buf_62635[0] = makeNimstrLit("Error: unhandled exception"); }; } - if (buf_53900[0] != null) { buf_53900[0] = (buf_53900[0]).concat(makeNimstrLit(" [")); } else { buf_53900[0] = makeNimstrLit(" ["); }; - add_51438(buf_53900, 0, e_53899.name); - if (buf_53900[0] != null) { buf_53900[0] = (buf_53900[0]).concat(makeNimstrLit("]\x0A")); } else { buf_53900[0] = makeNimstrLit("]\x0A"); }; - if (buf_53900[0] != null) { buf_53900[0] = (buf_53900[0]).concat(raw_write_stack_trace_53838()); } else { buf_53900[0] = raw_write_stack_trace_53838().slice(); }; - var cbuf_54001 = toJSStr(buf_53900[0]); + if (buf_62635[0] != null) { buf_62635[0] = (buf_62635[0]).concat(makeNimstrLit(" [")); } else { buf_62635[0] = makeNimstrLit(" ["); }; + add_59638(buf_62635, 0, e_62634.name); + if (buf_62635[0] != null) { buf_62635[0] = (buf_62635[0]).concat(makeNimstrLit("]\x0A")); } else { buf_62635[0] = makeNimstrLit("]\x0A"); }; + if (buf_62635[0] != null) { buf_62635[0] = (buf_62635[0]).concat(raw_write_stack_trace_62543()); } else { buf_62635[0] = raw_write_stack_trace_62543().slice(); }; + var cbuf_62801 = toJSStr(buf_62635[0]); framePtr = null; if (typeof(Error) !== "undefined") { - throw new Error(cbuf_54001); + throw new Error(cbuf_62801); } else { - throw cbuf_54001; + throw cbuf_62801; } @@ -731,49 +731,49 @@ function unhandledException(e_53899) { } function raiseOverflow() { - var e_54252 = null; - e_54252 = {m_type: NTI41246, parent: null, name: null, message: null, trace: null, raiseId: 0, up: null}; - e_54252.message = nimCopy(null, makeNimstrLit("over- or underflow"), NTI37040); - e_54252.parent = null; - raiseException(e_54252, "OverflowError"); + var e_63261 = null; + e_63261 = {m_type: NTI46846, parent: null, name: null, message: null, trace: null, raiseId: 0, up: null}; + e_63261.message = nimCopy(null, makeNimstrLit("over- or underflow"), NTI43040); + e_63261.parent = null; + raiseException(e_63261, "OverflowError"); } -function is_whitespace_181639(text_181641) { - return !/[^\s]/.test(text_181641); +function is_whitespace_204144(text_204146) { + return !/[^\s]/.test(text_204146); } -function is_whitespace_181656(x_181658) { +function is_whitespace_204161(x_204163) { var Tmp1; var Tmp2; - var result_181659 = false; + var result_204164 = false; var F={procname:"dochack.isWhitespace",prev:framePtr,filename:"dochack.nim",line:0}; framePtr = F; F.line = 134; - if (!(x_181658.nodeName == "#text")) Tmp2 = false; else { Tmp2 = is_whitespace_181639(x_181658.textContent); } if (Tmp2) Tmp1 = true; else { Tmp1 = (x_181658.nodeName == "#comment"); } result_181659 = Tmp1; + if (!(x_204163.nodeName == "#text")) Tmp2 = false; else { Tmp2 = is_whitespace_204144(x_204163.textContent); } if (Tmp2) Tmp1 = true; else { Tmp1 = (x_204163.nodeName == "#comment"); } result_204164 = Tmp1; framePtr = F.prev; - return result_181659; + return result_204164; } -function raiseIndexError() { - var e_54327 = null; - e_54327 = {m_type: NTI41258, parent: null, name: null, message: null, trace: null, raiseId: 0, up: null}; - e_54327.message = nimCopy(null, makeNimstrLit("index out of bounds"), NTI37040); - e_54327.parent = null; - raiseException(e_54327, "IndexError"); +function raiseIndexError(i_63858, a_63859, b_63860) { + var e_63864 = null; + e_63864 = {m_type: NTI46858, parent: null, name: null, message: null, trace: null, raiseId: 0, up: null}; + e_63864.message = nimCopy(null, (makeNimstrLit("index ") || []).concat(cstrToNimstr((i_63858)+"") || [],makeNimstrLit(" not in ") || [],cstrToNimstr((a_63859)+"") || [],makeNimstrLit(" .. ") || [],cstrToNimstr((b_63860)+"") || []), NTI43040); + e_63864.parent = null; + raiseException(e_63864, "IndexError"); } -function to_toc_181673(x_181675, father_181676) { +function to_toc_204178(x_204180, father_204181) { var Tmp5; var Tmp6; var Tmp7; @@ -782,151 +782,151 @@ function to_toc_181673(x_181675, father_181676) { var F={procname:"dochack.toToc",prev:framePtr,filename:"dochack.nim",line:0}; framePtr = F; - if ((x_181675.nodeName == "UL")) { + if ((x_204180.nodeName == "UL")) { F.line = 139; - var f_181695 = {heading: null, kids: [], sortId: (father_181676.kids != null ? father_181676.kids.length : 0), doSort: false}; + var f_204200 = {heading: null, kids: [], sortId: (father_204181.kids != null ? father_204181.kids.length : 0), doSort: false}; F.line = 140; - var i_181697 = 0; + var i_204202 = 0; L1: do { F.line = 141; L2: while (true) { - if (!(i_181697 < x_181675.childNodes.length)) break L2; + if (!(i_204202 < x_204180.childNodes.length)) break L2; F.line = 142; - var nxt_181698 = addInt(i_181697, 1); + var nxt_204203 = addInt(i_204202, 1); L3: do { F.line = 143; L4: while (true) { - if (!(nxt_181698 < x_181675.childNodes.length)) Tmp5 = false; else { Tmp5 = is_whitespace_181656(x_181675.childNodes[nxt_181698]); } if (!Tmp5) break L4; + if (!(nxt_204203 < x_204180.childNodes.length)) Tmp5 = false; else { Tmp5 = is_whitespace_204161(x_204180.childNodes[nxt_204203]); } if (!Tmp5) break L4; F.line = 144; - nxt_181698 = addInt(nxt_181698, 1); + nxt_204203 = addInt(nxt_204203, 1); } } while(false); - if (!(nxt_181698 < x_181675.childNodes.length)) Tmp8 = false; else { Tmp8 = (x_181675.childNodes[i_181697].nodeName == "LI"); } if (!Tmp8) Tmp7 = false; else { Tmp7 = (x_181675.childNodes[i_181697].childNodes.length == 1); } if (!Tmp7) Tmp6 = false; else { Tmp6 = (x_181675.childNodes[nxt_181698].nodeName == "UL"); } if (Tmp6) { + if (!(nxt_204203 < x_204180.childNodes.length)) Tmp8 = false; else { Tmp8 = (x_204180.childNodes[i_204202].nodeName == "LI"); } if (!Tmp8) Tmp7 = false; else { Tmp7 = (x_204180.childNodes[i_204202].childNodes.length == 1); } if (!Tmp7) Tmp6 = false; else { Tmp6 = (x_204180.childNodes[nxt_204203].nodeName == "UL"); } if (Tmp6) { F.line = 147; - var e_181723 = {heading: x_181675.childNodes[i_181697].childNodes[0], kids: [], sortId: (f_181695.kids != null ? f_181695.kids.length : 0), doSort: false}; + var e_204228 = {heading: x_204180.childNodes[i_204202].childNodes[0], kids: [], sortId: (f_204200.kids != null ? f_204200.kids.length : 0), doSort: false}; F.line = 148; - var it_181724 = x_181675.childNodes[nxt_181698]; + var it_204229 = x_204180.childNodes[nxt_204203]; L9: do { F.line = 149; - var j_181731 = 0; - F.line = 3055; - var colontmp__182402 = 0; + var j_204236 = 0; + F.line = 2631; + var colontmp__205182 = 0; F.line = 149; - colontmp__182402 = it_181724.childNodes.length; - F.line = 3056; - var i_182403 = 0; + colontmp__205182 = it_204229.childNodes.length; + F.line = 2632; + var i_205183 = 0; L10: do { - F.line = 3057; + F.line = 2633; L11: while (true) { - if (!(i_182403 < colontmp__182402)) break L11; + if (!(i_205183 < colontmp__205182)) break L11; F.line = 149; - j_181731 = i_182403; + j_204236 = i_205183; F.line = 150; - to_toc_181673(it_181724.childNodes[j_181731], e_181723); - F.line = 3059; - i_182403 = addInt(i_182403, 1); + to_toc_204178(it_204229.childNodes[j_204236], e_204228); + F.line = 2635; + i_205183 = addInt(i_205183, 1); } } while(false); } while(false); F.line = 151; - if (f_181695.kids != null) { f_181695.kids.push(e_181723); } else { f_181695.kids = [e_181723]; }; + if (f_204200.kids != null) { f_204200.kids.push(e_204228); } else { f_204200.kids = [e_204228]; }; F.line = 152; - i_181697 = addInt(nxt_181698, 1); + i_204202 = addInt(nxt_204203, 1); } else { F.line = 154; - to_toc_181673(x_181675.childNodes[i_181697], f_181695); + to_toc_204178(x_204180.childNodes[i_204202], f_204200); F.line = 155; - i_181697 = addInt(i_181697, 1); + i_204202 = addInt(i_204202, 1); } } } while(false); F.line = 156; - if (father_181676.kids != null) { father_181676.kids.push(f_181695); } else { father_181676.kids = [f_181695]; }; + if (father_204181.kids != null) { father_204181.kids.push(f_204200); } else { father_204181.kids = [f_204200]; }; } else { - if (is_whitespace_181656(x_181675)) { + if (is_whitespace_204161(x_204180)) { } else { - if ((x_181675.nodeName == "LI")) { + if ((x_204180.nodeName == "LI")) { F.line = 160; - var idx_181766 = []; + var idx_204271 = []; L12: do { F.line = 161; - var i_181773 = 0; - F.line = 3055; - var colontmp__182407 = 0; + var i_204278 = 0; + F.line = 2631; + var colontmp__205187 = 0; F.line = 161; - colontmp__182407 = x_181675.childNodes.length; - F.line = 3056; - var i_182408 = 0; + colontmp__205187 = x_204180.childNodes.length; + F.line = 2632; + var i_205188 = 0; L13: do { - F.line = 3057; + F.line = 2633; L14: while (true) { - if (!(i_182408 < colontmp__182407)) break L14; + if (!(i_205188 < colontmp__205187)) break L14; F.line = 161; - i_181773 = i_182408; - if (!(is_whitespace_181656(x_181675.childNodes[i_181773]))) { + i_204278 = i_205188; + if (!(is_whitespace_204161(x_204180.childNodes[i_204278]))) { F.line = 162; - if (idx_181766 != null) { idx_181766.push(i_181773); } else { idx_181766 = [i_181773]; }; + if (idx_204271 != null) { idx_204271.push(i_204278); } else { idx_204271 = [i_204278]; }; } - F.line = 3059; - i_182408 = addInt(i_182408, 1); + F.line = 2635; + i_205188 = addInt(i_205188, 1); } } while(false); } while(false); - if (!((idx_181766 != null ? idx_181766.length : 0) == 2)) Tmp15 = false; else { Tmp15 = (x_181675.childNodes[idx_181766[chckIndx(1, 0, idx_181766.length+0-1)-0]].nodeName == "UL"); } if (Tmp15) { + if (!((idx_204271 != null ? idx_204271.length : 0) == 2)) Tmp15 = false; else { Tmp15 = (x_204180.childNodes[idx_204271[chckIndx(1, 0, idx_204271.length+0-1)-0]].nodeName == "UL"); } if (Tmp15) { F.line = 164; - var e_181804 = {heading: x_181675.childNodes[idx_181766[chckIndx(0, 0, idx_181766.length+0-1)-0]], kids: [], sortId: (father_181676.kids != null ? father_181676.kids.length : 0), doSort: false}; + var e_204309 = {heading: x_204180.childNodes[idx_204271[chckIndx(0, 0, idx_204271.length+0-1)-0]], kids: [], sortId: (father_204181.kids != null ? father_204181.kids.length : 0), doSort: false}; F.line = 166; - var it_181805 = x_181675.childNodes[idx_181766[chckIndx(1, 0, idx_181766.length+0-1)-0]]; + var it_204310 = x_204180.childNodes[idx_204271[chckIndx(1, 0, idx_204271.length+0-1)-0]]; L16: do { F.line = 167; - var j_181812 = 0; - F.line = 3055; - var colontmp__182413 = 0; + var j_204317 = 0; + F.line = 2631; + var colontmp__205193 = 0; F.line = 167; - colontmp__182413 = it_181805.childNodes.length; - F.line = 3056; - var i_182414 = 0; + colontmp__205193 = it_204310.childNodes.length; + F.line = 2632; + var i_205194 = 0; L17: do { - F.line = 3057; + F.line = 2633; L18: while (true) { - if (!(i_182414 < colontmp__182413)) break L18; + if (!(i_205194 < colontmp__205193)) break L18; F.line = 167; - j_181812 = i_182414; + j_204317 = i_205194; F.line = 168; - to_toc_181673(it_181805.childNodes[j_181812], e_181804); - F.line = 3059; - i_182414 = addInt(i_182414, 1); + to_toc_204178(it_204310.childNodes[j_204317], e_204309); + F.line = 2635; + i_205194 = addInt(i_205194, 1); } } while(false); } while(false); F.line = 169; - if (father_181676.kids != null) { father_181676.kids.push(e_181804); } else { father_181676.kids = [e_181804]; }; + if (father_204181.kids != null) { father_204181.kids.push(e_204309); } else { father_204181.kids = [e_204309]; }; } else { L19: do { F.line = 171; - var i_181826 = 0; - F.line = 3055; - var colontmp__182418 = 0; + var i_204331 = 0; + F.line = 2631; + var colontmp__205198 = 0; F.line = 171; - colontmp__182418 = x_181675.childNodes.length; - F.line = 3056; - var i_182419 = 0; + colontmp__205198 = x_204180.childNodes.length; + F.line = 2632; + var i_205199 = 0; L20: do { - F.line = 3057; + F.line = 2633; L21: while (true) { - if (!(i_182419 < colontmp__182418)) break L21; + if (!(i_205199 < colontmp__205198)) break L21; F.line = 171; - i_181826 = i_182419; + i_204331 = i_205199; F.line = 172; - to_toc_181673(x_181675.childNodes[i_181826], father_181676); - F.line = 3059; - i_182419 = addInt(i_182419, 1); + to_toc_204178(x_204180.childNodes[i_204331], father_204181); + F.line = 2635; + i_205199 = addInt(i_205199, 1); } } while(false); } while(false); @@ -935,7 +935,7 @@ function to_toc_181673(x_181675, father_181676) { } else { F.line = 174; - if (father_181676.kids != null) { father_181676.kids.push({heading: x_181675, kids: [], sortId: (father_181676.kids != null ? father_181676.kids.length : 0), doSort: false}); } else { father_181676.kids = [{heading: x_181675, kids: [], sortId: (father_181676.kids != null ? father_181676.kids.length : 0), doSort: false}]; }; + if (father_204181.kids != null) { father_204181.kids.push({heading: x_204180, kids: [], sortId: (father_204181.kids != null ? father_204181.kids.length : 0), doSort: false}); } else { father_204181.kids = [{heading: x_204180, kids: [], sortId: (father_204181.kids != null ? father_204181.kids.length : 0), doSort: false}]; }; } }} framePtr = F.prev; @@ -943,37 +943,37 @@ function to_toc_181673(x_181675, father_181676) { } -function extract_items_181307(x_181309, heading_181310, items_181313, items_181313_Idx) { +function extract_items_203577(x_203579, heading_203580, items_203583, items_203583_Idx) { var Tmp1; var F={procname:"dochack.extractItems",prev:framePtr,filename:"dochack.nim",line:0}; framePtr = F; BeforeRet: do { - if ((x_181309 == null)) { + if ((x_203579 == null)) { F.line = 81; break BeforeRet; } - if (!!((x_181309.heading == null))) Tmp1 = false; else { Tmp1 = (x_181309.heading.textContent == heading_181310); } if (Tmp1) { + if (!!((x_203579.heading == null))) Tmp1 = false; else { Tmp1 = (x_203579.heading.textContent == heading_203580); } if (Tmp1) { L2: do { F.line = 83; - var i_181341 = 0; - F.line = 3055; - var colontmp__182437 = 0; + var i_203611 = 0; + F.line = 2631; + var colontmp__205223 = 0; F.line = 83; - colontmp__182437 = (x_181309.kids != null ? x_181309.kids.length : 0); - F.line = 3056; - var i_182438 = 0; + colontmp__205223 = (x_203579.kids != null ? x_203579.kids.length : 0); + F.line = 2632; + var i_205224 = 0; L3: do { - F.line = 3057; + F.line = 2633; L4: while (true) { - if (!(i_182438 < colontmp__182437)) break L4; + if (!(i_205224 < colontmp__205223)) break L4; F.line = 83; - i_181341 = i_182438; + i_203611 = i_205224; F.line = 84; - if (items_181313[items_181313_Idx] != null) { items_181313[items_181313_Idx].push(x_181309.kids[chckIndx(i_181341, 0, x_181309.kids.length+0-1)-0].heading); } else { items_181313[items_181313_Idx] = [x_181309.kids[chckIndx(i_181341, 0, x_181309.kids.length+0-1)-0].heading]; }; - F.line = 3059; - i_182438 = addInt(i_182438, 1); + if (items_203583[items_203583_Idx] != null) { items_203583[items_203583_Idx].push(x_203579.kids[chckIndx(i_203611, 0, x_203579.kids.length+0-1)-0].heading); } else { items_203583[items_203583_Idx] = [x_203579.kids[chckIndx(i_203611, 0, x_203579.kids.length+0-1)-0].heading]; }; + F.line = 2635; + i_205224 = addInt(i_205224, 1); } } while(false); } while(false); @@ -981,25 +981,25 @@ function extract_items_181307(x_181309, heading_181310, items_181313, items_1813 else { L5: do { F.line = 86; - var i_181360 = 0; - F.line = 3055; - var colontmp__182442 = 0; + var i_203630 = 0; + F.line = 2631; + var colontmp__205228 = 0; F.line = 86; - colontmp__182442 = (x_181309.kids != null ? x_181309.kids.length : 0); - F.line = 3056; - var i_182443 = 0; + colontmp__205228 = (x_203579.kids != null ? x_203579.kids.length : 0); + F.line = 2632; + var i_205229 = 0; L6: do { - F.line = 3057; + F.line = 2633; L7: while (true) { - if (!(i_182443 < colontmp__182442)) break L7; + if (!(i_205229 < colontmp__205228)) break L7; F.line = 86; - i_181360 = i_182443; + i_203630 = i_205229; F.line = 87; - var it_181361 = x_181309.kids[chckIndx(i_181360, 0, x_181309.kids.length+0-1)-0]; + var it_203631 = x_203579.kids[chckIndx(i_203630, 0, x_203579.kids.length+0-1)-0]; F.line = 88; - extract_items_181307(it_181361, heading_181310, items_181313, items_181313_Idx); - F.line = 3059; - i_182443 = addInt(i_182443, 1); + extract_items_203577(it_203631, heading_203580, items_203583, items_203583_Idx); + F.line = 2635; + i_205229 = addInt(i_205229, 1); } } while(false); } while(false); @@ -1011,180 +1011,180 @@ function extract_items_181307(x_181309, heading_181310, items_181313, items_1813 } -function tree_181020(tag_181022, kids_181024) { - var result_181025 = null; +function tree_203020(tag_203022, kids_203024) { + var result_203025 = null; var F={procname:"dochack.tree",prev:framePtr,filename:"dochack.nim",line:0}; framePtr = F; F.line = 11; - result_181025 = document.createElement(toJSStr(tag_181022)); + result_203025 = document.createElement(toJSStr(tag_203022)); L1: do { F.line = 12; - var k_181056 = null; - F.line = 2309; - var i_182460 = 0; + var k_203071 = null; + F.line = 3; + var i_205246 = 0; L2: do { - F.line = 2310; + F.line = 4; L3: while (true) { - if (!(i_182460 < (kids_181024 != null ? kids_181024.length : 0))) break L3; + if (!(i_205246 < (kids_203024 != null ? kids_203024.length : 0))) break L3; F.line = 12; - k_181056 = kids_181024[chckIndx(i_182460, 0, kids_181024.length+0-1)-0]; + k_203071 = kids_203024[chckIndx(i_205246, 0, kids_203024.length+0-1)-0]; F.line = 13; - result_181025.appendChild(k_181056); - F.line = 2312; - i_182460 = addInt(i_182460, 1); + result_203025.appendChild(k_203071); + F.line = 6; + i_205246 = addInt(i_205246, 1); } } while(false); } while(false); framePtr = F.prev; - return result_181025; + return result_203025; } -function text_181122(s_181124) { - var result_181125 = null; +function text_203227(s_203229) { + var result_203230 = null; var F={procname:"dochack.text",prev:framePtr,filename:"dochack.nim",line:0}; framePtr = F; F.line = 27; - result_181125 = document.createTextNode(s_181124); + result_203230 = document.createTextNode(s_203229); framePtr = F.prev; - return result_181125; + return result_203230; } -function sys_fatal_58236(message_58240) { - var F={procname:"sysFatal.sysFatal",prev:framePtr,filename:"..\\..\\lib\\system.nim",line:0}; +function sys_fatal_57107(message_57111) { + var F={procname:"sysFatal.sysFatal",prev:framePtr,filename:"..\\..\\lib\\system\\fatal.nim",line:0}; framePtr = F; - F.line = 3015; - var e_58242 = null; - F.line = 3016; - e_58242 = {m_type: NTI41250, parent: null, name: null, message: null, trace: null, raiseId: 0, up: null}; - F.line = 3017; - e_58242.message = nimCopy(null, message_58240, NTI37040); - F.line = 3018; - raiseException(e_58242, "AssertionError"); + F.line = 32; + var e_57207 = null; + F.line = 35; + e_57207 = {m_type: NTI46850, parent: null, name: null, message: null, trace: null, raiseId: 0, up: null}; + F.line = 36; + e_57207.message = nimCopy(null, message_57111, NTI43040); + F.line = 37; + raiseException(e_57207, "AssertionError"); framePtr = F.prev; } -function raise_assert_58232(msg_58234) { - var F={procname:"system.raiseAssert",prev:framePtr,filename:"..\\..\\lib\\system.nim",line:0}; +function raise_assert_57103(msg_57105) { + var F={procname:"assertions.raiseAssert",prev:framePtr,filename:"..\\..\\lib\\system\\assertions.nim",line:0}; framePtr = F; - F.line = 3734; - sys_fatal_58236(msg_58234); + F.line = 20; + sys_fatal_57107(msg_57105); framePtr = F.prev; } -function failed_assert_impl_58275(msg_58277) { - var F={procname:"system.failedAssertImpl",prev:framePtr,filename:"..\\..\\lib\\system.nim",line:0}; +function failed_assert_impl_57270(msg_57272) { + var F={procname:"assertions.failedAssertImpl",prev:framePtr,filename:"..\\..\\lib\\system\\assertions.nim",line:0}; framePtr = F; - F.line = 3741; - raise_assert_58232(msg_58277); + F.line = 27; + raise_assert_57103(msg_57272); framePtr = F.prev; } -function uncovered_181920(x_181922) { +function uncovered_204500(x_204502) { var Tmp1; var Tmp2; - var result_181923 = null; + var result_204503 = null; var F={procname:"dochack.uncovered",prev:framePtr,filename:"dochack.nim",line:0}; framePtr = F; BeforeRet: do { - if (!((x_181922.kids != null ? x_181922.kids.length : 0) == 0)) Tmp1 = false; else { Tmp1 = !((x_181922.heading == null)); } if (Tmp1) { + if (!((x_204502.kids != null ? x_204502.kids.length : 0) == 0)) Tmp1 = false; else { Tmp1 = !((x_204502.heading == null)); } if (Tmp1) { F.line = 194; - if (!(x_181922.heading.hasOwnProperty('__karaxMarker__'))) { - Tmp2 = x_181922; + if (!(x_204502.heading.hasOwnProperty('__karaxMarker__'))) { + Tmp2 = x_204502; } else { Tmp2 = null; } - result_181923 = Tmp2; + result_204503 = Tmp2; break BeforeRet; } F.line = 195; - result_181923 = {heading: x_181922.heading, kids: [], sortId: x_181922.sortId, doSort: x_181922.doSort}; + result_204503 = {heading: x_204502.heading, kids: [], sortId: x_204502.sortId, doSort: x_204502.doSort}; L3: do { F.line = 197; - var i_181961 = 0; - F.line = 3055; - var colontmp__182472 = 0; + var i_204541 = 0; + F.line = 2631; + var colontmp__205258 = 0; F.line = 197; - colontmp__182472 = (x_181922.kids != null ? x_181922.kids.length : 0); - F.line = 3056; - var i_182473 = 0; + colontmp__205258 = (x_204502.kids != null ? x_204502.kids.length : 0); + F.line = 2632; + var i_205259 = 0; L4: do { - F.line = 3057; + F.line = 2633; L5: while (true) { - if (!(i_182473 < colontmp__182472)) break L5; + if (!(i_205259 < colontmp__205258)) break L5; F.line = 197; - i_181961 = i_182473; + i_204541 = i_205259; F.line = 198; - var y_181962 = uncovered_181920(x_181922.kids[chckIndx(i_181961, 0, x_181922.kids.length+0-1)-0]); - if (!((y_181962 == null))) { + var y_204542 = uncovered_204500(x_204502.kids[chckIndx(i_204541, 0, x_204502.kids.length+0-1)-0]); + if (!((y_204542 == null))) { F.line = 199; - if (result_181923.kids != null) { result_181923.kids.push(y_181962); } else { result_181923.kids = [y_181962]; }; + if (result_204503.kids != null) { result_204503.kids.push(y_204542); } else { result_204503.kids = [y_204542]; }; } - F.line = 3059; - i_182473 = addInt(i_182473, 1); + F.line = 2635; + i_205259 = addInt(i_205259, 1); } } while(false); } while(false); - if (((result_181923.kids != null ? result_181923.kids.length : 0) == 0)) { + if (((result_204503.kids != null ? result_204503.kids.length : 0) == 0)) { F.line = 200; - result_181923 = null; + result_204503 = null; } } while (false); framePtr = F.prev; - return result_181923; + return result_204503; } -function merge_tocs_181996(orig_181998, news_181999) { - var result_182000 = null; +function merge_tocs_204591(orig_204593, news_204594) { + var result_204595 = null; var F={procname:"dochack.mergeTocs",prev:framePtr,filename:"dochack.nim",line:0}; framePtr = F; F.line = 203; - result_182000 = uncovered_181920(orig_181998); - if ((result_182000 == null)) { + result_204595 = uncovered_204500(orig_204593); + if ((result_204595 == null)) { F.line = 205; - result_182000 = news_181999; + result_204595 = news_204594; } else { L1: do { F.line = 207; - var i_182020 = 0; - F.line = 3055; - var colontmp__182466 = 0; + var i_204615 = 0; + F.line = 2631; + var colontmp__205252 = 0; F.line = 207; - colontmp__182466 = (news_181999.kids != null ? news_181999.kids.length : 0); - F.line = 3056; - var i_182467 = 0; + colontmp__205252 = (news_204594.kids != null ? news_204594.kids.length : 0); + F.line = 2632; + var i_205253 = 0; L2: do { - F.line = 3057; + F.line = 2633; L3: while (true) { - if (!(i_182467 < colontmp__182466)) break L3; + if (!(i_205253 < colontmp__205252)) break L3; F.line = 207; - i_182020 = i_182467; + i_204615 = i_205253; F.line = 208; - if (result_182000.kids != null) { result_182000.kids.push(news_181999.kids[chckIndx(i_182020, 0, news_181999.kids.length+0-1)-0]); } else { result_182000.kids = [news_181999.kids[chckIndx(i_182020, 0, news_181999.kids.length+0-1)-0]]; }; - F.line = 3059; - i_182467 = addInt(i_182467, 1); + if (result_204595.kids != null) { result_204595.kids.push(news_204594.kids[chckIndx(i_204615, 0, news_204594.kids.length+0-1)-0]); } else { result_204595.kids = [news_204594.kids[chckIndx(i_204615, 0, news_204594.kids.length+0-1)-0]]; }; + F.line = 2635; + i_205253 = addInt(i_205253, 1); } } while(false); } while(false); @@ -1192,110 +1192,110 @@ function merge_tocs_181996(orig_181998, news_181999) { framePtr = F.prev; - return result_182000; + return result_204595; } -function build_toc_182041(orig_182043, types_182045, procs_182046) { - var result_182047 = null; +function build_toc_204636(orig_204638, types_204640, procs_204641) { + var result_204642 = null; var F={procname:"dochack.buildToc",prev:framePtr,filename:"dochack.nim",line:0}; framePtr = F; F.line = 211; - var new_stuff_182061 = {heading: null, kids: [], doSort: true, sortId: 0}; + var new_stuff_204656 = {heading: null, kids: [], doSort: true, sortId: 0}; L1: do { F.line = 212; - var t_182214 = null; - F.line = 3773; - var i_182455 = 0; - F.line = 3774; - var l_182456 = (types_182045 != null ? types_182045.length : 0); + var t_204829 = null; + F.line = 156; + var i_205241 = 0; + F.line = 157; + var l_205242 = (types_204640 != null ? types_204640.length : 0); L2: do { - F.line = 3775; + F.line = 158; L3: while (true) { - if (!(i_182455 < l_182456)) break L3; + if (!(i_205241 < l_205242)) break L3; F.line = 212; - t_182214 = types_182045[chckIndx(i_182455, 0, types_182045.length+0-1)-0]; + t_204829 = types_204640[chckIndx(i_205241, 0, types_204640.length+0-1)-0]; F.line = 213; - var c_182228 = {heading: t_182214.cloneNode(true), kids: [], doSort: true, sortId: 0}; + var c_204843 = {heading: t_204829.cloneNode(true), kids: [], doSort: true, sortId: 0}; F.line = 214; - t_182214.__karaxMarker__ = true; + t_204829.__karaxMarker__ = true; L4: do { F.line = 215; - var p_182235 = null; - F.line = 3773; - var i_182452 = 0; - F.line = 3774; - var l_182453 = (procs_182046 != null ? procs_182046.length : 0); + var p_204850 = null; + F.line = 156; + var i_205238 = 0; + F.line = 157; + var l_205239 = (procs_204641 != null ? procs_204641.length : 0); L5: do { - F.line = 3775; + F.line = 158; L6: while (true) { - if (!(i_182452 < l_182453)) break L6; + if (!(i_205238 < l_205239)) break L6; F.line = 215; - p_182235 = procs_182046[chckIndx(i_182452, 0, procs_182046.length+0-1)-0]; - if (!(p_182235.hasOwnProperty('__karaxMarker__'))) { + p_204850 = procs_204641[chckIndx(i_205238, 0, procs_204641.length+0-1)-0]; + if (!(p_204850.hasOwnProperty('__karaxMarker__'))) { F.line = 217; - var xx_182236 = p_182235.parentNode.getElementsByClassName("attachedType"); - if ((((xx_182236 != null ? xx_182236.length : 0) == 1) && (xx_182236[chckIndx(0, 0, xx_182236.length+0-1)-0].textContent == t_182214.textContent))) { + var xx_204851 = p_204850.parentNode.getElementsByClassName("attachedType"); + if ((((xx_204851 != null ? xx_204851.length : 0) == 1) && (xx_204851[chckIndx(0, 0, xx_204851.length+0-1)-0].textContent == t_204829.textContent))) { F.line = 220; - var q_182244 = tree_181020(makeNimstrLit("A"), [text_181122(p_182235.title)]); + var q_204859 = tree_203020(makeNimstrLit("A"), [text_203227(p_204850.title)]); F.line = 221; - q_182244.setAttribute("href", p_182235.getAttribute("href")); + q_204859.setAttribute("href", p_204850.getAttribute("href")); F.line = 222; - if (c_182228.kids != null) { c_182228.kids.push({heading: q_182244, kids: [], sortId: 0, doSort: false}); } else { c_182228.kids = [{heading: q_182244, kids: [], sortId: 0, doSort: false}]; }; + if (c_204843.kids != null) { c_204843.kids.push({heading: q_204859, kids: [], sortId: 0, doSort: false}); } else { c_204843.kids = [{heading: q_204859, kids: [], sortId: 0, doSort: false}]; }; F.line = 223; - p_182235.__karaxMarker__ = true; + p_204850.__karaxMarker__ = true; } } - F.line = 3777; - i_182452 = addInt(i_182452, 1); - if (!(((procs_182046 != null ? procs_182046.length : 0) == l_182453))) { - F.line = 3778; - failed_assert_impl_58275(makeNimstrLit("c:\\Users\\gt\\Desktop\\dl\\programming\\nimdevel\\lib\\system.nim(3778, 11) `len(a) == L` seq modified while iterating over it")); + F.line = 160; + i_205238 = addInt(i_205238, 1); + if (!(((procs_204641 != null ? procs_204641.length : 0) == l_205239))) { + F.line = 161; + failed_assert_impl_57270(makeNimstrLit("C:\\Users\\gt\\Desktop\\DL\\programming\\nimdevel\\lib\\system\\iterators.nim(161, 11) `len(a) == L` seq modified while iterating over it")); } } } while(false); } while(false); F.line = 224; - if (new_stuff_182061.kids != null) { new_stuff_182061.kids.push(c_182228); } else { new_stuff_182061.kids = [c_182228]; }; - F.line = 3777; - i_182455 = addInt(i_182455, 1); - if (!(((types_182045 != null ? types_182045.length : 0) == l_182456))) { - F.line = 3778; - failed_assert_impl_58275(makeNimstrLit("c:\\Users\\gt\\Desktop\\dl\\programming\\nimdevel\\lib\\system.nim(3778, 11) `len(a) == L` seq modified while iterating over it")); + if (new_stuff_204656.kids != null) { new_stuff_204656.kids.push(c_204843); } else { new_stuff_204656.kids = [c_204843]; }; + F.line = 160; + i_205241 = addInt(i_205241, 1); + if (!(((types_204640 != null ? types_204640.length : 0) == l_205242))) { + F.line = 161; + failed_assert_impl_57270(makeNimstrLit("C:\\Users\\gt\\Desktop\\DL\\programming\\nimdevel\\lib\\system\\iterators.nim(161, 11) `len(a) == L` seq modified while iterating over it")); } } } while(false); } while(false); F.line = 225; - result_182047 = merge_tocs_181996(orig_182043, new_stuff_182061); + result_204642 = merge_tocs_204591(orig_204638, new_stuff_204656); framePtr = F.prev; - return result_182047; + return result_204642; } -function add_181070(parent_181072, kid_181073) { +function add_203145(parent_203147, kid_203148) { var Tmp1; var Tmp2; var F={procname:"dochack.add",prev:framePtr,filename:"dochack.nim",line:0}; framePtr = F; - if (!(parent_181072.nodeName == "TR")) Tmp1 = false; else { if ((kid_181073.nodeName == "TD")) Tmp2 = true; else { Tmp2 = (kid_181073.nodeName == "TH"); } Tmp1 = Tmp2; } if (Tmp1) { + if (!(parent_203147.nodeName == "TR")) Tmp1 = false; else { if ((kid_203148.nodeName == "TD")) Tmp2 = true; else { Tmp2 = (kid_203148.nodeName == "TH"); } Tmp1 = Tmp2; } if (Tmp1) { F.line = 18; - var k_181074 = document.createElement("TD"); + var k_203149 = document.createElement("TD"); F.line = 19; - k_181074.appendChild(kid_181073); + k_203149.appendChild(kid_203148); F.line = 20; - parent_181072.appendChild(k_181074); + parent_203147.appendChild(k_203149); } else { F.line = 22; - parent_181072.appendChild(kid_181073); + parent_203147.appendChild(kid_203148); } framePtr = F.prev; @@ -1303,486 +1303,486 @@ function add_181070(parent_181072, kid_181073) { } -function set_class_181088(e_181090, value_181091) { +function set_class_203163(e_203165, value_203166) { var F={procname:"dochack.setClass",prev:framePtr,filename:"dochack.nim",line:0}; framePtr = F; F.line = 25; - e_181090.setAttribute("class", toJSStr(value_181091)); + e_203165.setAttribute("class", toJSStr(value_203166)); framePtr = F.prev; } -function to_html_181375(x_181377, is_root_181378) { +function to_html_203705(x_203707, is_root_203708) { var Tmp1; - function HEX3Aanonymous_181418(a_181420, b_181421) { + function HEX3Aanonymous_203748(a_203750, b_203751) { var Tmp1; - var result_181422 = 0; + var result_203752 = 0; var F={procname:"toHtml.:anonymous",prev:framePtr,filename:"dochack.nim",line:0}; framePtr = F; BeforeRet: do { - if (!!((a_181420.heading == null))) Tmp1 = false; else { Tmp1 = !((b_181421.heading == null)); } if (Tmp1) { + if (!!((a_203750.heading == null))) Tmp1 = false; else { Tmp1 = !((b_203751.heading == null)); } if (Tmp1) { F.line = 106; - var x_181439 = a_181420.heading.textContent; + var x_203769 = a_203750.heading.textContent; F.line = 107; - var y_181440 = b_181421.heading.textContent; - if ((x_181439 < y_181440)) { + var y_203770 = b_203751.heading.textContent; + if ((x_203769 < y_203770)) { F.line = 108; - result_181422 = -1; + result_203752 = -1; break BeforeRet; } - if ((y_181440 < x_181439)) { + if ((y_203770 < x_203769)) { F.line = 109; - result_181422 = 1; + result_203752 = 1; break BeforeRet; } F.line = 110; - result_181422 = 0; + result_203752 = 0; break BeforeRet; } else { F.line = 113; - result_181422 = subInt(a_181420.sortId, b_181421.sortId); + result_203752 = subInt(a_203750.sortId, b_203751.sortId); break BeforeRet; } } while (false); framePtr = F.prev; - return result_181422; + return result_203752; } - var result_181379 = null; + var result_203709 = null; var F={procname:"dochack.toHtml",prev:framePtr,filename:"dochack.nim",line:0}; framePtr = F; BeforeRet: do { - if ((x_181377 == null)) { + if ((x_203707 == null)) { F.line = 91; - result_181379 = null; + result_203709 = null; break BeforeRet; } - if (((x_181377.kids != null ? x_181377.kids.length : 0) == 0)) { - if ((x_181377.heading == null)) { + if (((x_203707.kids != null ? x_203707.kids.length : 0) == 0)) { + if ((x_203707.heading == null)) { F.line = 93; - result_181379 = null; + result_203709 = null; break BeforeRet; } F.line = 94; - result_181379 = x_181377.heading.cloneNode(true); + result_203709 = x_203707.heading.cloneNode(true); break BeforeRet; } F.line = 95; - result_181379 = tree_181020(makeNimstrLit("DIV"), []); - if (!!((x_181377.heading == null))) Tmp1 = false; else { Tmp1 = !(x_181377.heading.hasOwnProperty('__karaxMarker__')); } if (Tmp1) { + result_203709 = tree_203020(makeNimstrLit("DIV"), []); + if (!!((x_203707.heading == null))) Tmp1 = false; else { Tmp1 = !(x_203707.heading.hasOwnProperty('__karaxMarker__')); } if (Tmp1) { F.line = 97; - add_181070(result_181379, x_181377.heading.cloneNode(true)); + add_203145(result_203709, x_203707.heading.cloneNode(true)); } F.line = 98; - var ul_181415 = tree_181020(makeNimstrLit("UL"), []); - if (is_root_181378) { + var ul_203745 = tree_203020(makeNimstrLit("UL"), []); + if (is_root_203708) { F.line = 100; - set_class_181088(ul_181415, makeNimstrLit("simple simple-toc")); + set_class_203163(ul_203745, makeNimstrLit("simple simple-toc")); } else { F.line = 102; - set_class_181088(ul_181415, makeNimstrLit("simple")); + set_class_203163(ul_203745, makeNimstrLit("simple")); } - if (x_181377.doSort) { + if (x_203707.doSort) { F.line = 104; - x_181377.kids.sort(HEX3Aanonymous_181418); + x_203707.kids.sort(HEX3Aanonymous_203748); } L2: do { F.line = 115; - var k_181614 = null; - F.line = 3771; - var colontmp__182479 = null; + var k_204014 = null; + F.line = 154; + var colontmp__205265 = null; F.line = 115; - colontmp__182479 = x_181377.kids; - F.line = 3773; - var i_182481 = 0; - F.line = 3774; - var l_182482 = (colontmp__182479 != null ? colontmp__182479.length : 0); + colontmp__205265 = x_203707.kids; + F.line = 156; + var i_205267 = 0; + F.line = 157; + var l_205268 = (colontmp__205265 != null ? colontmp__205265.length : 0); L3: do { - F.line = 3775; + F.line = 158; L4: while (true) { - if (!(i_182481 < l_182482)) break L4; + if (!(i_205267 < l_205268)) break L4; F.line = 115; - k_181614 = colontmp__182479[chckIndx(i_182481, 0, colontmp__182479.length+0-1)-0]; + k_204014 = colontmp__205265[chckIndx(i_205267, 0, colontmp__205265.length+0-1)-0]; F.line = 116; - var y_181615 = to_html_181375(k_181614, false); - if (!((y_181615 == null))) { + var y_204015 = to_html_203705(k_204014, false); + if (!((y_204015 == null))) { F.line = 118; - add_181070(ul_181415, tree_181020(makeNimstrLit("LI"), [y_181615])); + add_203145(ul_203745, tree_203020(makeNimstrLit("LI"), [y_204015])); } - F.line = 3777; - i_182481 = addInt(i_182481, 1); - if (!(((colontmp__182479 != null ? colontmp__182479.length : 0) == l_182482))) { - F.line = 3778; - failed_assert_impl_58275(makeNimstrLit("c:\\Users\\gt\\Desktop\\dl\\programming\\nimdevel\\lib\\system.nim(3778, 11) `len(a) == L` seq modified while iterating over it")); + F.line = 160; + i_205267 = addInt(i_205267, 1); + if (!(((colontmp__205265 != null ? colontmp__205265.length : 0) == l_205268))) { + F.line = 161; + failed_assert_impl_57270(makeNimstrLit("C:\\Users\\gt\\Desktop\\DL\\programming\\nimdevel\\lib\\system\\iterators.nim(161, 11) `len(a) == L` seq modified while iterating over it")); } } } while(false); } while(false); - if (!((ul_181415.childNodes.length == 0))) { + if (!((ul_203745.childNodes.length == 0))) { F.line = 119; - add_181070(result_181379, ul_181415); + add_203145(result_203709, ul_203745); } - if ((result_181379.childNodes.length == 0)) { + if ((result_203709.childNodes.length == 0)) { F.line = 120; - result_181379 = null; + result_203709 = null; } } while (false); framePtr = F.prev; - return result_181379; + return result_203709; } -function replace_by_id_181142(id_181144, new_tree_181145) { +function replace_by_id_203247(id_203249, new_tree_203250) { var F={procname:"dochack.replaceById",prev:framePtr,filename:"dochack.nim",line:0}; framePtr = F; F.line = 32; - var x_181146 = document.getElementById(id_181144); + var x_203251 = document.getElementById(id_203249); F.line = 33; - x_181146.parentNode.replaceChild(new_tree_181145, x_181146); + x_203251.parentNode.replaceChild(new_tree_203250, x_203251); F.line = 34; - new_tree_181145.id = id_181144; + new_tree_203250.id = id_203249; framePtr = F.prev; } -function togglevis_182299(d_182301) { +function togglevis_205034(d_205036) { var F={procname:"dochack.togglevis",prev:framePtr,filename:"dochack.nim",line:0}; framePtr = F; F.line = 230; - if (d_182301.style.display == 'none') - d_182301.style.display = 'inline'; + if (d_205036.style.display == 'none') + d_205036.style.display = 'inline'; else - d_182301.style.display = 'none'; + d_205036.style.display = 'none'; framePtr = F.prev; } -function groupBy(value_182317) { +function groupBy(value_205052) { var F={procname:"dochack.groupBy",prev:framePtr,filename:"dochack.nim",line:0}; framePtr = F; F.line = 238; - var toc_182318 = document.getElementById("toc-list"); - if ((alternative_182285[0] == null)) { + var toc_205053 = document.getElementById("toc-list"); + if ((alternative_205020[0] == null)) { F.line = 240; - var tt_182337 = {heading: null, kids: [], sortId: 0, doSort: false}; + var tt_205072 = {heading: null, kids: [], sortId: 0, doSort: false}; F.line = 241; - to_toc_181673(toc_182318, tt_182337); + to_toc_204178(toc_205053, tt_205072); F.line = 242; - tt_182337 = tt_182337.kids[chckIndx(0, 0, tt_182337.kids.length+0-1)-0]; + tt_205072 = tt_205072.kids[chckIndx(0, 0, tt_205072.kids.length+0-1)-0]; F.line = 244; - var types_182352 = [[]]; + var types_205087 = [[]]; F.line = 245; - var procs_182367 = [[]]; + var procs_205102 = [[]]; F.line = 247; - extract_items_181307(tt_182337, "Types", types_182352, 0); + extract_items_203577(tt_205072, "Types", types_205087, 0); F.line = 248; - extract_items_181307(tt_182337, "Procs", procs_182367, 0); + extract_items_203577(tt_205072, "Procs", procs_205102, 0); F.line = 249; - extract_items_181307(tt_182337, "Converters", procs_182367, 0); + extract_items_203577(tt_205072, "Converters", procs_205102, 0); F.line = 250; - extract_items_181307(tt_182337, "Methods", procs_182367, 0); + extract_items_203577(tt_205072, "Methods", procs_205102, 0); F.line = 251; - extract_items_181307(tt_182337, "Templates", procs_182367, 0); + extract_items_203577(tt_205072, "Templates", procs_205102, 0); F.line = 252; - extract_items_181307(tt_182337, "Macros", procs_182367, 0); + extract_items_203577(tt_205072, "Macros", procs_205102, 0); F.line = 253; - extract_items_181307(tt_182337, "Iterators", procs_182367, 0); + extract_items_203577(tt_205072, "Iterators", procs_205102, 0); F.line = 255; - var ntoc_182375 = build_toc_182041(tt_182337, types_182352[0], procs_182367[0]); + var ntoc_205110 = build_toc_204636(tt_205072, types_205087[0], procs_205102[0]); F.line = 256; - var x_182376 = to_html_181375(ntoc_182375, true); + var x_205111 = to_html_203705(ntoc_205110, true); F.line = 257; - alternative_182285[0] = tree_181020(makeNimstrLit("DIV"), [x_182376]); + alternative_205020[0] = tree_203020(makeNimstrLit("DIV"), [x_205111]); } - if ((value_182317 == "type")) { + if ((value_205052 == "type")) { F.line = 259; - replace_by_id_181142("tocRoot", alternative_182285[0]); + replace_by_id_203247("tocRoot", alternative_205020[0]); } else { F.line = 261; - replace_by_id_181142("tocRoot", tree_181020(makeNimstrLit("DIV"), [])); + replace_by_id_203247("tocRoot", tree_203020(makeNimstrLit("DIV"), [])); } F.line = 262; - togglevis_182299(document.getElementById("toc-list")); + togglevis_205034(document.getElementById("toc-list")); framePtr = F.prev; } -var db_182485 = [null]; -var contents_182487 = [null]; -var oldtoc_182742 = [null]; -var timer_182743 = [null]; +var db_205271 = [null]; +var contents_205273 = [null]; +var oldtoc_205677 = [null]; +var timer_205678 = [null]; function raiseRangeError() { - var e_54302 = null; - e_54302 = {m_type: NTI41262, parent: null, name: null, message: null, trace: null, raiseId: 0, up: null}; - e_54302.message = nimCopy(null, makeNimstrLit("value out of range"), NTI37040); - e_54302.parent = null; - raiseException(e_54302, "RangeError"); + var e_63660 = null; + e_63660 = {m_type: NTI46862, parent: null, name: null, message: null, trace: null, raiseId: 0, up: null}; + e_63660.message = nimCopy(null, makeNimstrLit("value out of range"), NTI43040); + e_63660.parent = null; + raiseException(e_63660, "RangeError"); } -function nsuToLowerAsciiChar(c_171980) { - var result_171981 = 0; +function nsuToLowerAsciiChar(c_190980) { + var result_190981 = 0; var F={procname:"strutils.toLowerAscii",prev:framePtr,filename:"..\\..\\lib\\pure\\strutils.nim",line:0}; framePtr = F; - if ((ConstSet2[c_171980] != undefined)) { + if ((ConstSet2[c_190980] != undefined)) { F.line = 222; - result_171981 = chckRange(addInt(c_171980, 32), 0, 255); + result_190981 = chckRange(addInt(c_190980, 32), 0, 255); } else { F.line = 224; - result_171981 = c_171980; + result_190981 = c_190980; } framePtr = F.prev; - return result_171981; + return result_190981; } -function fuzzy_match_180070(pattern_180072, str_180073) { +function fuzzy_match_202070(pattern_202072, str_202073) { var Tmp4; var Tmp5; var Tmp6; - var result_180077 = {Field0: 0, Field1: false}; + var result_202077 = {Field0: 0, Field1: false}; var F={procname:"fuzzysearch.fuzzyMatch",prev:framePtr,filename:"fuzzysearch.nim",line:0}; framePtr = F; F.line = 37; - var score_state_180078 = -100; + var score_state_202078 = -100; F.line = 38; - var header_matched_180079 = false; + var header_matched_202079 = false; F.line = 39; - var unmatched_leading_char_count_180081 = 0; + var unmatched_leading_char_count_202081 = 0; F.line = 40; - var consecutive_match_count_180083 = 0; + var consecutive_match_count_202083 = 0; F.line = 41; - var str_index_180085 = 0; + var str_index_202085 = 0; F.line = 42; - var pat_index_180087 = 0; + var pat_index_202087 = 0; F.line = 43; - var score_180089 = 0; + var score_202089 = 0; L1: do { F.line = 49; L2: while (true) { - if (!((str_index_180085 < (str_180073 != null ? str_180073.length : 0)) && (pat_index_180087 < (pattern_180072 != null ? pattern_180072.length : 0)))) break L2; + if (!((str_index_202085 < (str_202073 != null ? str_202073.length : 0)) && (pat_index_202087 < (pattern_202072 != null ? pattern_202072.length : 0)))) break L2; L3: do { F.line = 51; - var pattern_char_180096 = nsuToLowerAsciiChar(pattern_180072.charCodeAt(chckIndx(pat_index_180087, 0, pattern_180072.length+0-1)-0)); + var pattern_char_202096 = nsuToLowerAsciiChar(pattern_202072.charCodeAt(chckIndx(pat_index_202087, 0, pattern_202072.length+0-1)-0)); F.line = 52; - var str_char_180097 = nsuToLowerAsciiChar(str_180073.charCodeAt(chckIndx(str_index_180085, 0, str_180073.length+0-1)-0)); - if ((ConstSet3[pattern_char_180096] != undefined)) { + var str_char_202097 = nsuToLowerAsciiChar(str_202073.charCodeAt(chckIndx(str_index_202085, 0, str_202073.length+0-1)-0)); + if ((ConstSet3[pattern_char_202096] != undefined)) { F.line = 56; - pat_index_180087 = addInt(pat_index_180087, 1); + pat_index_202087 = addInt(pat_index_202087, 1); F.line = 57; break L3; } - if ((ConstSet4[str_char_180097] != undefined)) { + if ((ConstSet4[str_char_202097] != undefined)) { F.line = 59; - str_index_180085 = addInt(str_index_180085, 1); + str_index_202085 = addInt(str_index_202085, 1); F.line = 60; break L3; } - if ((!(header_matched_180079) && (str_char_180097 == 58))) { + if ((!(header_matched_202079) && (str_char_202097 == 58))) { F.line = 65; - header_matched_180079 = true; + header_matched_202079 = true; F.line = 66; - score_state_180078 = -100; + score_state_202078 = -100; F.line = 67; - score_180089 = Math.trunc(Math.floor((5.0000000000000000e-001 * score_180089))); + score_202089 = Math.trunc(Math.floor((5.0000000000000000e-001 * score_202089))); F.line = 68; - pat_index_180087 = 0; + pat_index_202087 = 0; F.line = 69; - str_index_180085 = addInt(str_index_180085, 1); + str_index_202085 = addInt(str_index_202085, 1); F.line = 70; break L3; } - if ((str_char_180097 == pattern_char_180096)) { + if ((str_char_202097 == pattern_char_202096)) { F.line = 73; - switch (score_state_180078) { + switch (score_state_202078) { case -100: case 20: F.line = 75; - score_state_180078 = 10; + score_state_202078 = 10; break; case 0: F.line = 78; - score_state_180078 = 5; + score_state_202078 = 5; F.line = 78; - score_180089 = addInt(score_180089, score_state_180078); + score_202089 = addInt(score_202089, score_state_202078); break; case 10: case 5: F.line = 81; - consecutive_match_count_180083 = addInt(consecutive_match_count_180083, 1); + consecutive_match_count_202083 = addInt(consecutive_match_count_202083, 1); F.line = 82; - score_state_180078 = 5; + score_state_202078 = 5; F.line = 83; - score_180089 = addInt(score_180089, mulInt(5, consecutive_match_count_180083)); - if ((score_state_180078 == 10)) { + score_202089 = addInt(score_202089, mulInt(5, consecutive_match_count_202083)); + if ((score_state_202078 == 10)) { F.line = 86; - score_180089 = addInt(score_180089, 10); + score_202089 = addInt(score_202089, 10); } F.line = 88; - var on_boundary_180172 = (pat_index_180087 == (pattern_180072 != null ? (pattern_180072.length-1) : -1)); - if ((!(on_boundary_180172) && (str_index_180085 < (str_180073 != null ? (str_180073.length-1) : -1)))) { + var on_boundary_202172 = (pat_index_202087 == (pattern_202072 != null ? (pattern_202072.length-1) : -1)); + if ((!(on_boundary_202172) && (str_index_202085 < (str_202073 != null ? (str_202073.length-1) : -1)))) { F.line = 91; - var next_pattern_char_180173 = nsuToLowerAsciiChar(pattern_180072.charCodeAt(chckIndx(addInt(pat_index_180087, 1), 0, pattern_180072.length+0-1)-0)); + var next_pattern_char_202173 = nsuToLowerAsciiChar(pattern_202072.charCodeAt(chckIndx(addInt(pat_index_202087, 1), 0, pattern_202072.length+0-1)-0)); F.line = 92; - var next_str_char_180174 = nsuToLowerAsciiChar(str_180073.charCodeAt(chckIndx(addInt(str_index_180085, 1), 0, str_180073.length+0-1)-0)); + var next_str_char_202174 = nsuToLowerAsciiChar(str_202073.charCodeAt(chckIndx(addInt(str_index_202085, 1), 0, str_202073.length+0-1)-0)); F.line = 95; - if (!!((ConstSet5[next_str_char_180174] != undefined))) Tmp4 = false; else { Tmp4 = !((next_str_char_180174 == next_pattern_char_180173)); } on_boundary_180172 = Tmp4; + if (!!((ConstSet5[next_str_char_202174] != undefined))) Tmp4 = false; else { Tmp4 = !((next_str_char_202174 == next_pattern_char_202173)); } on_boundary_202172 = Tmp4; } - if (on_boundary_180172) { + if (on_boundary_202172) { F.line = 100; - score_state_180078 = 20; + score_state_202078 = 20; F.line = 100; - score_180089 = addInt(score_180089, score_state_180078); + score_202089 = addInt(score_202089, score_state_202078); } break; case -1: case -3: F.line = 103; - if (!((ConstSet6[str_180073.charCodeAt(chckIndx(subInt(str_index_180085, 1), 0, str_180073.length+0-1)-0)] != undefined))) Tmp5 = true; else { if (!(ConstSet7[str_180073.charCodeAt(chckIndx(subInt(str_index_180085, 1), 0, str_180073.length+0-1)-0)] != undefined)) Tmp6 = false; else { Tmp6 = (ConstSet8[str_180073.charCodeAt(chckIndx(str_index_180085, 0, str_180073.length+0-1)-0)] != undefined); } Tmp5 = Tmp6; } var is_leading_char_180212 = Tmp5; - if (is_leading_char_180212) { + if (!((ConstSet6[str_202073.charCodeAt(chckIndx(subInt(str_index_202085, 1), 0, str_202073.length+0-1)-0)] != undefined))) Tmp5 = true; else { if (!(ConstSet7[str_202073.charCodeAt(chckIndx(subInt(str_index_202085, 1), 0, str_202073.length+0-1)-0)] != undefined)) Tmp6 = false; else { Tmp6 = (ConstSet8[str_202073.charCodeAt(chckIndx(str_index_202085, 0, str_202073.length+0-1)-0)] != undefined); } Tmp5 = Tmp6; } var is_leading_char_202212 = Tmp5; + if (is_leading_char_202212) { F.line = 110; - score_state_180078 = 10; + score_state_202078 = 10; } else { F.line = 114; - score_state_180078 = 0; + score_state_202078 = 0; F.line = 114; - score_180089 = addInt(score_180089, score_state_180078); + score_202089 = addInt(score_202089, score_state_202078); } break; } F.line = 115; - pat_index_180087 = addInt(pat_index_180087, 1); + pat_index_202087 = addInt(pat_index_202087, 1); } else { F.line = 118; - switch (score_state_180078) { + switch (score_state_202078) { case -100: F.line = 120; - score_state_180078 = -3; + score_state_202078 = -3; F.line = 120; - score_180089 = addInt(score_180089, score_state_180078); + score_202089 = addInt(score_202089, score_state_202078); break; case 5: F.line = 123; - score_state_180078 = -1; + score_state_202078 = -1; F.line = 123; - score_180089 = addInt(score_180089, score_state_180078); + score_202089 = addInt(score_202089, score_state_202078); F.line = 124; - consecutive_match_count_180083 = 0; + consecutive_match_count_202083 = 0; break; case -3: - if ((unmatched_leading_char_count_180081 < 3)) { + if ((unmatched_leading_char_count_202081 < 3)) { F.line = 128; - score_state_180078 = -3; + score_state_202078 = -3; F.line = 128; - score_180089 = addInt(score_180089, score_state_180078); + score_202089 = addInt(score_202089, score_state_202078); } F.line = 129; - unmatched_leading_char_count_180081 = addInt(unmatched_leading_char_count_180081, 1); + unmatched_leading_char_count_202081 = addInt(unmatched_leading_char_count_202081, 1); break; default: F.line = 132; - score_state_180078 = -1; + score_state_202078 = -1; F.line = 132; - score_180089 = addInt(score_180089, score_state_180078); + score_202089 = addInt(score_202089, score_state_202078); break; } } F.line = 134; - str_index_180085 = addInt(str_index_180085, 1); + str_index_202085 = addInt(str_index_202085, 1); } while(false); } } while(false); F.line = 136; - nimCopy(result_180077, {Field0: nimMax(0, score_180089), Field1: (0 < score_180089)}, NTI180074); + nimCopy(result_202077, {Field0: nimMax(0, score_202089), Field1: (0 < score_202089)}, NTI202074); framePtr = F.prev; - return result_180077; + return result_202077; } -function text_181105(s_181107) { - var result_181108 = null; +function text_203195(s_203197) { + var result_203198 = null; var F={procname:"dochack.text",prev:framePtr,filename:"dochack.nim",line:0}; framePtr = F; F.line = 26; - result_181108 = document.createTextNode(toJSStr(s_181107)); + result_203198 = document.createTextNode(toJSStr(s_203197)); framePtr = F.prev; - return result_181108; + return result_203198; } -function dosearch_182504(value_182506) { +function dosearch_205305(value_205307) { - function HEX3Aanonymous_182670(a_182679, b_182680) { - var result_182684 = 0; + function HEX3Aanonymous_205470(a_205479, b_205480) { + var result_205484 = 0; var F={procname:"dosearch.:anonymous",prev:framePtr,filename:"dochack.nim",line:0}; framePtr = F; F.line = 305; - result_182684 = subInt(b_182680["Field1"], a_182679["Field1"]); + result_205484 = subInt(b_205480["Field1"], a_205479["Field1"]); framePtr = F.prev; - return result_182684; + return result_205484; } - var result_182507 = null; + var result_205308 = null; var F={procname:"dochack.dosearch",prev:framePtr,filename:"dochack.nim",line:0}; framePtr = F; - if (((db_182485[0] != null ? db_182485[0].length : 0) == 0)) { + if (((db_205271[0] != null ? db_205271[0].length : 0) == 0)) { F.line = 272; - var stuff_182513 = null; + var stuff_205314 = null; F.line = 273; var request = new XMLHttpRequest(); request.open("GET", "theindex.html", false); @@ -1794,32 +1794,32 @@ function dosearch_182504(value_182506) { //parser=new DOMParser(); //doc=parser.parseFromString("", "text/html"); - stuff_182513 = doc.documentElement; + stuff_205314 = doc.documentElement; F.line = 286; - db_182485[0] = nimCopy(null, stuff_182513.getElementsByClassName("reference"), NTI73045); + db_205271[0] = nimCopy(null, stuff_205314.getElementsByClassName("reference"), NTI86305); F.line = 287; - contents_182487[0] = nimCopy(null, [], NTI182526); + contents_205273[0] = nimCopy(null, [], NTI205327); L1: do { F.line = 288; - var ahref_182614 = null; - F.line = 3773; - var i_182811 = 0; - F.line = 3774; - var l_182812 = (db_182485[0] != null ? db_182485[0].length : 0); + var ahref_205414 = null; + F.line = 156; + var i_205806 = 0; + F.line = 157; + var l_205807 = (db_205271[0] != null ? db_205271[0].length : 0); L2: do { - F.line = 3775; + F.line = 158; L3: while (true) { - if (!(i_182811 < l_182812)) break L3; + if (!(i_205806 < l_205807)) break L3; F.line = 288; - ahref_182614 = db_182485[0][chckIndx(i_182811, 0, db_182485[0].length+0-1)-0]; + ahref_205414 = db_205271[0][chckIndx(i_205806, 0, db_205271[0].length+0-1)-0]; F.line = 289; - if (contents_182487[0] != null) { contents_182487[0].push(ahref_182614.getAttribute("data-doc-search-tag")); } else { contents_182487[0] = [ahref_182614.getAttribute("data-doc-search-tag")]; }; - F.line = 3777; - i_182811 = addInt(i_182811, 1); - if (!(((db_182485[0] != null ? db_182485[0].length : 0) == l_182812))) { - F.line = 3778; - failed_assert_impl_58275(makeNimstrLit("c:\\Users\\gt\\Desktop\\dl\\programming\\nimdevel\\lib\\system.nim(3778, 11) `len(a) == L` seq modified while iterating over it")); + if (contents_205273[0] != null) { contents_205273[0].push(ahref_205414.getAttribute("data-doc-search-tag")); } else { contents_205273[0] = [ahref_205414.getAttribute("data-doc-search-tag")]; }; + F.line = 160; + i_205806 = addInt(i_205806, 1); + if (!(((db_205271[0] != null ? db_205271[0].length : 0) == l_205807))) { + F.line = 161; + failed_assert_impl_57270(makeNimstrLit("C:\\Users\\gt\\Desktop\\DL\\programming\\nimdevel\\lib\\system\\iterators.nim(161, 11) `len(a) == L` seq modified while iterating over it")); } } @@ -1828,126 +1828,126 @@ function dosearch_182504(value_182506) { } F.line = 290; - var ul_182625 = tree_181020(makeNimstrLit("UL"), []); + var ul_205425 = tree_203020(makeNimstrLit("UL"), []); F.line = 291; - result_182507 = tree_181020(makeNimstrLit("DIV"), []); + result_205308 = tree_203020(makeNimstrLit("DIV"), []); F.line = 292; - set_class_181088(result_182507, makeNimstrLit("search_results")); + set_class_203163(result_205308, makeNimstrLit("search_results")); F.line = 293; - var matches_182644 = []; + var matches_205444 = []; L4: do { F.line = 294; - var i_182656 = 0; - F.line = 3055; - var colontmp__182818 = 0; + var i_205456 = 0; + F.line = 2631; + var colontmp__205813 = 0; F.line = 294; - colontmp__182818 = (db_182485[0] != null ? db_182485[0].length : 0); - F.line = 3056; - var i_182819 = 0; + colontmp__205813 = (db_205271[0] != null ? db_205271[0].length : 0); + F.line = 2632; + var i_205814 = 0; L5: do { - F.line = 3057; + F.line = 2633; L6: while (true) { - if (!(i_182819 < colontmp__182818)) break L6; + if (!(i_205814 < colontmp__205813)) break L6; F.line = 294; - i_182656 = i_182819; + i_205456 = i_205814; L7: do { F.line = 295; - var c_182657 = contents_182487[0][chckIndx(i_182656, 0, contents_182487[0].length+0-1)-0]; - if (((c_182657 == "Examples") || (c_182657 == "PEG construction"))) { + var c_205457 = contents_205273[0][chckIndx(i_205456, 0, contents_205273[0].length+0-1)-0]; + if (((c_205457 == "Examples") || (c_205457 == "PEG construction"))) { F.line = 300; break L7; } F.line = 301; - var colontmp__182828 = {Field0: 0, Field1: false}; + var colontmp__205823 = {Field0: 0, Field1: false}; F.line = 301; - var score_182658 = 0; + var score_205458 = 0; F.line = 301; - var matched_182659 = false; + var matched_205459 = false; F.line = 301; - nimCopy(colontmp__182828, fuzzy_match_180070(value_182506, c_182657), NTI180074); + nimCopy(colontmp__205823, fuzzy_match_202070(value_205307, c_205457), NTI202074); F.line = 301; - score_182658 = colontmp__182828["Field0"]; + score_205458 = colontmp__205823["Field0"]; F.line = 301; - matched_182659 = colontmp__182828["Field1"]; - if (matched_182659) { + matched_205459 = colontmp__205823["Field1"]; + if (matched_205459) { F.line = 303; - if (matches_182644 != null) { matches_182644.push({Field0: db_182485[0][chckIndx(i_182656, 0, db_182485[0].length+0-1)-0], Field1: score_182658}); } else { matches_182644 = [{Field0: db_182485[0][chckIndx(i_182656, 0, db_182485[0].length+0-1)-0], Field1: score_182658}]; }; + if (matches_205444 != null) { matches_205444.push({Field0: db_205271[0][chckIndx(i_205456, 0, db_205271[0].length+0-1)-0], Field1: score_205458}); } else { matches_205444 = [{Field0: db_205271[0][chckIndx(i_205456, 0, db_205271[0].length+0-1)-0], Field1: score_205458}]; }; } } while(false); - F.line = 3059; - i_182819 = addInt(i_182819, 1); + F.line = 2635; + i_205814 = addInt(i_205814, 1); } } while(false); } while(false); F.line = 305; - matches_182644.sort(HEX3Aanonymous_182670); + matches_205444.sort(HEX3Aanonymous_205470); L8: do { F.line = 306; - var i_182722 = 0; - F.line = 3055; - var colontmp__182824 = 0; + var i_205522 = 0; + F.line = 2631; + var colontmp__205819 = 0; F.line = 306; - colontmp__182824 = nimMin((matches_182644 != null ? matches_182644.length : 0), 19); - F.line = 3056; - var i_182825 = 0; + colontmp__205819 = nimMin((matches_205444 != null ? matches_205444.length : 0), 19); + F.line = 2632; + var i_205820 = 0; L9: do { - F.line = 3057; + F.line = 2633; L10: while (true) { - if (!(i_182825 < colontmp__182824)) break L10; + if (!(i_205820 < colontmp__205819)) break L10; F.line = 306; - i_182722 = i_182825; + i_205522 = i_205820; F.line = 307; - matches_182644[chckIndx(i_182722, 0, matches_182644.length+0-1)-0]["Field0"].innerHTML = matches_182644[chckIndx(i_182722, 0, matches_182644.length+0-1)-0]["Field0"].getAttribute("data-doc-search-tag"); + matches_205444[chckIndx(i_205522, 0, matches_205444.length+0-1)-0]["Field0"].innerHTML = matches_205444[chckIndx(i_205522, 0, matches_205444.length+0-1)-0]["Field0"].getAttribute("data-doc-search-tag"); F.line = 308; - add_181070(ul_182625, tree_181020(makeNimstrLit("LI"), [matches_182644[chckIndx(i_182722, 0, matches_182644.length+0-1)-0]["Field0"]])); - F.line = 3059; - i_182825 = addInt(i_182825, 1); + add_203145(ul_205425, tree_203020(makeNimstrLit("LI"), [matches_205444[chckIndx(i_205522, 0, matches_205444.length+0-1)-0]["Field0"]])); + F.line = 2635; + i_205820 = addInt(i_205820, 1); } } while(false); } while(false); - if ((ul_182625.childNodes.length == 0)) { + if ((ul_205425.childNodes.length == 0)) { F.line = 310; - add_181070(result_182507, tree_181020(makeNimstrLit("B"), [text_181105(makeNimstrLit("no search results"))])); + add_203145(result_205308, tree_203020(makeNimstrLit("B"), [text_203195(makeNimstrLit("no search results"))])); } else { F.line = 312; - add_181070(result_182507, tree_181020(makeNimstrLit("B"), [text_181105(makeNimstrLit("search results"))])); + add_203145(result_205308, tree_203020(makeNimstrLit("B"), [text_203195(makeNimstrLit("search results"))])); F.line = 313; - add_181070(result_182507, ul_182625); + add_203145(result_205308, ul_205425); } framePtr = F.prev; - return result_182507; + return result_205308; } function search() { - function wrapper_182759() { + function wrapper_205709() { var F={procname:"search.wrapper",prev:framePtr,filename:"dochack.nim",line:0}; framePtr = F; F.line = 320; - var elem_182761 = document.getElementById("searchInput"); + var elem_205711 = document.getElementById("searchInput"); F.line = 321; - var value_182762 = elem_182761.value; - if (!(((value_182762 != null ? value_182762.length : 0) == 0))) { - if ((oldtoc_182742[0] == null)) { + var value_205712 = elem_205711.value; + if (!(((value_205712 != null ? value_205712.length : 0) == 0))) { + if ((oldtoc_205677[0] == null)) { F.line = 324; - oldtoc_182742[0] = document.getElementById("tocRoot"); + oldtoc_205677[0] = document.getElementById("tocRoot"); } F.line = 325; - var results_182768 = dosearch_182504(value_182762); + var results_205718 = dosearch_205305(value_205712); F.line = 326; - replace_by_id_181142("tocRoot", results_182768); + replace_by_id_203247("tocRoot", results_205718); } else { - if (!((oldtoc_182742[0] == null))) { + if (!((oldtoc_205677[0] == null))) { F.line = 328; - replace_by_id_181142("tocRoot", oldtoc_182742[0]); + replace_by_id_203247("tocRoot", oldtoc_205677[0]); } } framePtr = F.prev; @@ -1957,13 +1957,13 @@ function search() { var F={procname:"dochack.search",prev:framePtr,filename:"dochack.nim",line:0}; framePtr = F; - if (!((timer_182743[0] == null))) { + if (!((timer_205678[0] == null))) { F.line = 330; - clearTimeout(timer_182743[0]); + clearTimeout(timer_205678[0]); } F.line = 331; - timer_182743[0] = setTimeout(wrapper_182759, 400); + timer_205678[0] = setTimeout(wrapper_205709, 400); framePtr = F.prev; diff --git a/git.html b/git.html index bb96fef..8af13aa 100755 --- a/git.html +++ b/git.html @@ -345,11 +345,11 @@ dl { dt { margin-bottom: -0.5em; - margin-left: 0.5em; } + margin-left: 0.0em; } dd { - margin-left: 0.5em; - margin-bottom: 2.5em; + margin-left: 2.0em; + margin-bottom: 3.0em; margin-top: 0.5em; } @@ -761,6 +761,10 @@ span.pragmawrap { display: none; } +span.attachedType { + display: none; + visibility: hidden; +} @@ -812,23 +816,23 @@ function main() { Procs
      • execAction
      • + title="execAction(cmd: string; nostderr = false): string">execAction
      • mkDir
      • + title="mkDir(dir: string)">mkDir
      • cpFile
      • + title="cpFile(source, dest: string; move = false)">cpFile
      • mvFile
      • + title="mvFile(source, dest: string)">mvFile
      • extractZip
      • + title="extractZip(zipfile, outdir: string)">extractZip
      • downloadUrl
      • + title="downloadUrl(url, outdir: string)">downloadUrl
      • gitReset
      • + title="gitReset(outdir: string)">gitReset
      • gitCheckout
      • + title="gitCheckout(file, outdir: string)">gitCheckout
      • gitPull
      • + title="gitPull(url: string; outdir = ""; plist = ""; checkout = "")">gitPull
    • @@ -842,7 +846,7 @@ function main() {

      Procs

      @@ -893,14 +897,14 @@ function main() { -
      proc gitReset(outdir: string) {...}{.raises: [OSError, Exception, ValueError, IOError, Defect], tags: [
      +
      proc gitReset(outdir: string) {...}{.raises: [ValueError, OSError, Exception, IOError, Defect], tags: [
           ExecIOEffect, ReadIOEffect, RootEffect, TimeEffect].}
      -
      proc gitCheckout(file, outdir: string) {...}{.raises: [OSError, Exception, ValueError,
      +
      proc gitCheckout(file, outdir: string) {...}{.raises: [ValueError, OSError, Exception,
           IOError, Defect], tags: [ExecIOEffect, ReadIOEffect, RootEffect, TimeEffect].}
      @@ -908,7 +912,7 @@ function main() {
      proc gitPull(url: string; outdir = ""; plist = ""; checkout = "") {...}{.
      -    raises: [OSError, Exception, ValueError, IOError, Defect], tags: [ReadDirEffect,
      +    raises: [ValueError, OSError, Exception, IOError, Defect], tags: [ReadDirEffect,
           ExecIOEffect, ReadIOEffect, RootEffect, TimeEffect, WriteIOEffect].}
      @@ -924,7 +928,7 @@ function main() {
      diff --git a/paths.html b/paths.html index 474bcf5..68f55c2 100755 --- a/paths.html +++ b/paths.html @@ -345,11 +345,11 @@ dl { dt { margin-bottom: -0.5em; - margin-left: 0.5em; } + margin-left: 0.0em; } dd { - margin-left: 0.5em; - margin-bottom: 2.5em; + margin-left: 2.0em; + margin-bottom: 3.0em; margin-top: 0.5em; } @@ -761,6 +761,10 @@ span.pragmawrap { display: none; } +span.attachedType { + display: none; + visibility: hidden; +} @@ -806,17 +810,17 @@ function main() { Procs @@ -876,7 +880,7 @@ all nimterop generated files go under here (gitignored) diff --git a/plugin.html b/plugin.html index 5e00f23..3e2203e 100755 --- a/plugin.html +++ b/plugin.html @@ -345,11 +345,11 @@ dl { dt { margin-bottom: -0.5em; - margin-left: 0.5em; } + margin-left: 0.0em; } dd { - margin-left: 0.5em; - margin-bottom: 2.5em; + margin-left: 2.0em; + margin-bottom: 3.0em; margin-top: 0.5em; } @@ -761,6 +761,10 @@ span.pragmawrap { display: none; } +span.attachedType { + display: none; + visibility: hidden; +} @@ -809,9 +813,9 @@ function main() { title="Symbol = object name*: string parent*: string - kind*: NimSymKind">Symbol + kind*: NimSymKind">Symbol
    • OnSymbol
    • + title="OnSymbol = proc (sym: var Symbol) {.cdecl.}">OnSymbol
  • @@ -851,7 +855,7 @@ function main() { diff --git a/theindex.html b/theindex.html index add5db3..fc4bc03 100755 --- a/theindex.html +++ b/theindex.html @@ -345,11 +345,11 @@ dl { dt { margin-bottom: -0.5em; - margin-left: 0.5em; } + margin-left: 0.0em; } dd { - margin-left: 0.5em; - margin-bottom: 2.5em; + margin-left: 2.0em; + margin-bottom: 3.0em; margin-top: 0.5em; } @@ -761,6 +761,10 @@ span.pragmawrap { display: none; } +span.attachedType { + display: none; + visibility: hidden; +} @@ -784,7 +788,7 @@ function main() {

    Index

    - Modules: cimport, git, paths, plugin, types.

    API symbols

    + Modules: cimport, compat, git, paths, plugin, types.

    API symbols

    cAddSearchDir:
    cSkipSymbol:
    • cimport: cSkipSymbol(skips: seq[string])
    • + data-doc-search-tag="cimport: cSkipSymbol(skips: seq[string])" href="cimport.html#cSkipSymbol%2Cseq%5BT%5D%5Bstring%5D">cimport: cSkipSymbol(skips: seq[string])
    defineEnum:
    +
    relativePath:
    Symbol:
    • plugin: Symbol
    • @@ -926,7 +934,7 @@ function main() {
    diff --git a/types.html b/types.html index 654188c..e8eab1c 100755 --- a/types.html +++ b/types.html @@ -345,11 +345,11 @@ dl { dt { margin-bottom: -0.5em; - margin-left: 0.5em; } + margin-left: 0.0em; } dd { - margin-left: 0.5em; - margin-bottom: 2.5em; + margin-left: 2.0em; + margin-bottom: 3.0em; margin-top: 0.5em; } @@ -761,6 +761,10 @@ span.pragmawrap { display: none; } +span.attachedType { + display: none; + visibility: hidden; +} @@ -806,11 +810,11 @@ function main() { Types
    • time_t
    • + title="time_t = time_t_temp.Time">time_t
    • ptrdiff_t
    • + title="ptrdiff_t = ByteAddress">ptrdiff_t
    • va_list
    • + title="va_list {.importc, header: "<stdarg.h>".} = object">va_list
    @@ -818,9 +822,9 @@ function main() { Templates
    • enumOp
    • + title="enumOp(op, typ, typout)">enumOp
    • defineEnum
    • + title="defineEnum(typ)">defineEnum
    @@ -879,7 +883,7 @@ function main() { From 1114b7edbe02bb775bc7bf1c590caf5abecf08cd Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 10 Apr 2019 11:46:45 -0500 Subject: [PATCH 189/593] Comment non-nim output in cimport --- nimterop/cimport.nim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index 90b10d8..1f0de30 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -138,7 +138,7 @@ proc getToast(fullpath: string, recurse: bool = false): string = cmd.add &" --pluginSourcePath={gStateCT.pluginSourcePath.quoteShell}" cmd.add &" {fullpath.quoteShell}" - echo cmd + echo "# " & cmd # see https://github.com/nimterop/nimterop/issues/69 (result, ret) = gorgeEx(cmd, cache=getCacheValue(fullpath)) doAssert ret == 0, getToastError(result) @@ -468,7 +468,7 @@ macro cImport*(filename: static string, recurse: static bool = false): untyped = let fullpath = findPath(filename) - echo "Importing " & fullpath + echo "# Importing " & fullpath let output = getToast(fullpath, recurse) From 301138a005d59c7669b8d387fc23d9a34170f3fb Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 10 Apr 2019 22:27:53 -0500 Subject: [PATCH 190/593] Update documentation --- all.html | 2 +- cimport.html | 11 ++++++++++- compat.html | 2 +- git.html | 2 +- paths.html | 2 +- plugin.html | 2 +- theindex.html | 2 +- types.html | 2 +- 8 files changed, 17 insertions(+), 8 deletions(-) diff --git a/all.html b/all.html index 257944c..a91e4fb 100755 --- a/all.html +++ b/all.html @@ -832,7 +832,7 @@ function main() { diff --git a/cimport.html b/cimport.html index 07617b1..fb66659 100755 --- a/cimport.html +++ b/cimport.html @@ -972,6 +972,15 @@ When cOverride()< proc onSymbol*(sym: var Symbol) {...}{.exportc, dynlib.} = sym.name = sym.name.strip(chars = {'_'}) +

    Examples:

    +
    cPlugin:
    +  import
    +    strutils
    +
    +  proc onSymbol*(sym: var Symbol) {...}{.exportc, dynlib.} =
    +    if sym.kind == nskProc and sym.name.contains("SDL_"):
    +      sym.name = sym.name.replace("SDL_", "")
    +
    @@ -1021,7 +1030,7 @@ Add an include directory that is forwarded to the C/C++ compiler using
    - Made with Nim. Generated: 2019-04-06 23:36:36 UTC + Made with Nim. Generated: 2019-04-11 03:27:51 UTC diff --git a/compat.html b/compat.html index 3906011..cf2f629 100755 --- a/compat.html +++ b/compat.html @@ -818,7 +818,7 @@ function main() { diff --git a/git.html b/git.html index 8af13aa..eab21fb 100755 --- a/git.html +++ b/git.html @@ -928,7 +928,7 @@ function main() { diff --git a/paths.html b/paths.html index 68f55c2..9e294e1 100755 --- a/paths.html +++ b/paths.html @@ -880,7 +880,7 @@ all nimterop generated files go under here (gitignored) diff --git a/plugin.html b/plugin.html index 3e2203e..52eeb70 100755 --- a/plugin.html +++ b/plugin.html @@ -855,7 +855,7 @@ function main() { diff --git a/theindex.html b/theindex.html index fc4bc03..49d04cb 100755 --- a/theindex.html +++ b/theindex.html @@ -934,7 +934,7 @@ function main() { diff --git a/types.html b/types.html index e8eab1c..63806ac 100755 --- a/types.html +++ b/types.html @@ -883,7 +883,7 @@ function main() { From 46ddc05e2e2b13d37dae4ea5074fa9e99582cfc5 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 10 Apr 2019 22:28:28 -0500 Subject: [PATCH 191/593] Prefix stripping example --- nimterop/cimport.nim | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index 1f0de30..1f82b6f 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -235,9 +235,19 @@ macro cPlugin*(body): untyped = cPlugin: import strutils + # Strip leading and trailing underscores proc onSymbol*(sym: var Symbol) {.exportc, dynlib.} = sym.name = sym.name.strip(chars={'_'}) + runnableExamples: + cPlugin: + import strutils + + # Strip prefix from procs + proc onSymbol*(sym: var Symbol) {.exportc, dynlib.} = + if sym.kind == nskProc and sym.name.contains("SDL_"): + sym.name = sym.name.replace("SDL_", "") + let data = "import nimterop/plugin\n\n" & body.repr hash = data.hash().abs() From ea258079af5c41deec7ffff89cd877c09cf1023f Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 10 Apr 2019 22:28:46 -0500 Subject: [PATCH 192/593] Update documentation --- all.html | 2 +- cimport.html | 2 +- compat.html | 2 +- git.html | 2 +- paths.html | 2 +- plugin.html | 2 +- theindex.html | 2 +- types.html | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/all.html b/all.html index a91e4fb..afbc77b 100755 --- a/all.html +++ b/all.html @@ -832,7 +832,7 @@ function main() { diff --git a/cimport.html b/cimport.html index fb66659..5709786 100755 --- a/cimport.html +++ b/cimport.html @@ -1030,7 +1030,7 @@ Add an include directory that is forwarded to the C/C++ compiler using
    - Made with Nim. Generated: 2019-04-11 03:27:51 UTC + Made with Nim. Generated: 2019-04-11 03:28:45 UTC diff --git a/compat.html b/compat.html index cf2f629..f565882 100755 --- a/compat.html +++ b/compat.html @@ -818,7 +818,7 @@ function main() { diff --git a/git.html b/git.html index eab21fb..41769f0 100755 --- a/git.html +++ b/git.html @@ -928,7 +928,7 @@ function main() { diff --git a/paths.html b/paths.html index 9e294e1..cef8ed6 100755 --- a/paths.html +++ b/paths.html @@ -880,7 +880,7 @@ all nimterop generated files go under here (gitignored) diff --git a/plugin.html b/plugin.html index 52eeb70..ac2cd77 100755 --- a/plugin.html +++ b/plugin.html @@ -855,7 +855,7 @@ function main() { diff --git a/theindex.html b/theindex.html index 49d04cb..9127e0c 100755 --- a/theindex.html +++ b/theindex.html @@ -934,7 +934,7 @@ function main() { diff --git a/types.html b/types.html index 63806ac..87eec73 100755 --- a/types.html +++ b/types.html @@ -883,7 +883,7 @@ function main() { From ad90b586c4ecc2d99ce32bd70f458d9f41810293 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Sat, 4 May 2019 13:05:38 -0500 Subject: [PATCH 193/593] Fix abstract double pointer param --- nimterop/grammar.nim | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index e83c2a1..6492fac 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -58,7 +58,9 @@ proc initGrammar(): Grammar = ) (identifier|type_identifier) ) - (abstract_pointer_declarator?) + (abstract_pointer_declarator? + (abstract_pointer_declarator?) + ) ) ) """ From d21ec6287be4882d14332c14bb302b50f1296c22 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 6 May 2019 23:45:25 -0500 Subject: [PATCH 194/593] Fix enum identifier or'd, add configure support --- nimterop/ast.nim | 4 ++-- nimterop/git.nim | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/nimterop/ast.nim b/nimterop/ast.nim index 0d96dfd..c66d504 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -13,7 +13,7 @@ proc saveNodeData(node: TSNode, nimState: NimState): bool = if name == "primitive_type" and node.tsNodeParent.tsNodeType() == "sized_type_specifier": return true - if name == "number_literal" and $node.tsNodeParent.tsNodeType() in gExpressions: + if name in ["number_literal", "identifier"] and $node.tsNodeParent.tsNodeType() in gExpressions: return true if name in ["primitive_type", "sized_type_specifier"]: @@ -174,4 +174,4 @@ proc printNim*(fullpath: string, root: TSNode, astTable: AstTable) = echo &"{nimState.procStr}\n" if nimState.debugStr.nBl: - echo nimState.debugStr \ No newline at end of file + echo nimState.debugStr diff --git a/nimterop/git.nim b/nimterop/git.nim index b0380c2..c652d16 100644 --- a/nimterop/git.nim +++ b/nimterop/git.nim @@ -118,3 +118,21 @@ proc gitPull*(url: string, outdir = "", plist = "", checkout = "") = else: echo "Pulling repository" discard execAction(&"cd {outdirQ} && git pull --depth=1 origin master") + +proc configure*(path, check: string) = + if (path / check).fileExists(): + return + + echo "Configuring " & path + + if not fileExists(path / "configure"): + if fileExists(path / "autogen.sh"): + echo " Running autogen.sh" + + discard execAction(&"cd {path.quoteShell} && bash autogen.sh") + + if fileExists(path / "configure"): + echo " Running configure" + + discard execAction(&"cd {path.quoteShell} && bash configure") + From 62f5dc121b6b66b6e80500ce044666ae4b11d7c6 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 7 May 2019 00:11:58 -0500 Subject: [PATCH 195/593] Test case for enum identifer or'd --- tests/include/test.h | 6 ++++-- tests/tnimterop_c.nim | 5 ++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/tests/include/test.h b/tests/include/test.h index eb36650..8138e54 100644 --- a/tests/include/test.h +++ b/tests/include/test.h @@ -49,7 +49,9 @@ enum ENUM { typedef enum { enum4 = 3, enum5, - enum6 + enum6, + enum6a = enum5 & enum6, + enum6b = enum5 | enum6 } ENUM2; enum { @@ -149,4 +151,4 @@ typedef struct dstruct2 { #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/tests/tnimterop_c.nim b/tests/tnimterop_c.nim index 3fc33b9..01fa70b 100644 --- a/tests/tnimterop_c.nim +++ b/tests/tnimterop_c.nim @@ -116,6 +116,9 @@ else: check test_call9() == nil +check enum6a == 4 +check enum6b == 5 + check e3 == enum7 check e4 == enum11 @@ -160,4 +163,4 @@ di = addr iptr ds.field1 = di ds2.field1 = addr cstr ds2.tcv = test_call10 -check ds2.tcv(di) == nil \ No newline at end of file +check ds2.tcv(di) == nil From e851a9adf3d5dbc67886e02150ef873ac02d670f Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 7 May 2019 00:38:43 -0500 Subject: [PATCH 196/593] Support for type qualifier after type --- nimterop/grammar.nim | 1 + tests/include/test.c | 2 +- tests/include/test.h | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index 6492fac..2a8b330 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -39,6 +39,7 @@ proc initGrammar(): Grammar = typeGrammar = """ (type_qualifier?) (primitive_type|type_identifier?) + (type_qualifier?) (sized_type_specifier? (primitive_type?) ) diff --git a/tests/include/test.c b/tests/include/test.c index 8990df9..d67fd92 100644 --- a/tests/include/test.c +++ b/tests/include/test.c @@ -50,7 +50,7 @@ int test_call_param7(union UNION1 param1) { return param1.field1; } -float test_call_param8(int *param1) { +float test_call_param8(int volatile *param1) { *param1 = 5 * *param1; return 1.0 * *param1; diff --git a/tests/include/test.h b/tests/include/test.h index 8138e54..73eb951 100644 --- a/tests/include/test.h +++ b/tests/include/test.h @@ -109,7 +109,7 @@ ENUM2 test_call_param4(enum ENUM param1); union UNION1 test_call_param5(float param1); unsigned char test_call_param6(UNION2 param1); int test_call_param7(union UNION1 param1); -float test_call_param8(int *param1); +float test_call_param8(int volatile *param1); void *test_call9(); void **test_call10(int **param1); From 69cfce561a2114616e57c64effc2f6d36db1967d Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 7 May 2019 00:43:36 -0500 Subject: [PATCH 197/593] Undo volatile testcase --- tests/include/test.c | 2 +- tests/include/test.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/include/test.c b/tests/include/test.c index d67fd92..8990df9 100644 --- a/tests/include/test.c +++ b/tests/include/test.c @@ -50,7 +50,7 @@ int test_call_param7(union UNION1 param1) { return param1.field1; } -float test_call_param8(int volatile *param1) { +float test_call_param8(int *param1) { *param1 = 5 * *param1; return 1.0 * *param1; diff --git a/tests/include/test.h b/tests/include/test.h index 73eb951..8138e54 100644 --- a/tests/include/test.h +++ b/tests/include/test.h @@ -109,7 +109,7 @@ ENUM2 test_call_param4(enum ENUM param1); union UNION1 test_call_param5(float param1); unsigned char test_call_param6(UNION2 param1); int test_call_param7(union UNION1 param1); -float test_call_param8(int volatile *param1); +float test_call_param8(int *param1); void *test_call9(); void **test_call10(int **param1); From 2457671f9eef2c90fd5f403fbcde97c69c5aa64b Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 7 May 2019 11:44:32 -0500 Subject: [PATCH 198/593] Pragma cleanup and fixes --- nimterop/ast.nim | 1 - nimterop/grammar.nim | 50 ++++++++++++++++++++++++++++++------------- tests/include/test.h | 1 + tests/tnimterop_c.nim | 2 ++ 4 files changed, 38 insertions(+), 16 deletions(-) diff --git a/nimterop/ast.nim b/nimterop/ast.nim index c66d504..c40e8c8 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -142,7 +142,6 @@ proc printNimHeader*() = # Command line: # $2 $3 -{.experimental: "codeReordering".} {.hint[ConvFromXtoItselfNotNeeded]: off.} import nimterop/types diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index 2a8b330..daf5f15 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -7,10 +7,19 @@ import "."/[getters, globals, lisp, treesitter/api] type Grammar = seq[tuple[grammar: string, call: proc(ast: ref Ast, node: TSNode, nimState: NimState) {.nimcall.}]] -proc genImportC(origName, nimName: string): string = +proc genImportC(nimState: NimState, origName, nimName: string): string = result = "importc" if nimName != origName: result.add &": \"{origName}\"" # used as {.importc: "foo".} + result.add &", header: {nimState.currentHeader}" + +proc genPragma(pragmas: varargs[string]): string = + result = "" + for pragma in pragmas.items(): + if pragma.len != 0: + result &= pragma & ", " + if result.len != 0: + result = " {." & result[0 .. ^2] & ".}" proc initGrammar(): Grammar = # #define X Y @@ -141,6 +150,7 @@ proc initGrammar(): Grammar = i = 0 typ = nimState.data[i].val.getIdentifier(nskType) name = "" + nname = "" tptr = "" aptr = "" @@ -155,13 +165,17 @@ proc initGrammar(): Grammar = i += 1 if i < nimState.data.len: - name = nimState.data[i].val.getIdentifier(nskType) + name = nimState.data[i].val + nname = nimState.data[i].val.getIdentifier(nskType) i += 1 - if typ.nBl and name.nBl and nimState.identifiers.addNewIdentifer(name): + let + pragma = genPragma(nimState.genImportC(name, nname)) + + if typ.nBl and nname.nBl and nimState.identifiers.addNewIdentifer(nname): if i < nimState.data.len and nimState.data[^1].name == "function_declarator": var - fname = name + fname = nname pout, pname, ptyp, pptr = "" count = 1 @@ -175,9 +189,9 @@ proc initGrammar(): Grammar = pout = pout[0 .. ^3] if tptr.len != 0 or typ != "object": - nimState.typeStr &= &"\n {name}* = proc({pout}): {getPtrType(tptr&typ)} {{.nimcall.}}" + nimState.typeStr &= &"\n {nname}*{pragma} = proc({pout}): {getPtrType(tptr&typ)} {{.nimcall.}}" else: - nimState.typeStr &= &"\n {name}* = proc({pout}) {{.nimcall.}}" + nimState.typeStr &= &"\n {nname}*{pragma} = proc({pout}) {{.nimcall.}}" else: if i < nimState.data.len and nimState.data[i].name in ["identifier", "number_literal"]: var @@ -185,12 +199,12 @@ proc initGrammar(): Grammar = if nimState.data[i].name == "identifier": flen = flen.getIdentifier(nskConst, name) - nimState.typeStr &= &"\n {name}* = {aptr}array[{flen}, {getPtrType(tptr&typ)}]" + nimState.typeStr &= &"\n {nname}*{pragma} = {aptr}array[{flen}, {getPtrType(tptr&typ)}]" else: if name == typ: - nimState.typeStr &= &"\n {name}* = object" + nimState.typeStr &= &"\n {nname}*{pragma} = object" else: - nimState.typeStr &= &"\n {name}* = {getPtrType(tptr&typ)}" + nimState.typeStr &= &"\n {nname}*{pragma} = {getPtrType(tptr&typ)}" )) proc pDupTypeCommon(nname: string, fend: int, nimState: NimState, isEnum=false) = @@ -212,8 +226,10 @@ proc initGrammar(): Grammar = nimState.enumStr &= &"\ntype {ndname}* = {dptr}{nname}" else: if nimState.identifiers.addNewIdentifer(ndname): + let + pragma = genPragma(nimState.genImportc(dname, ndname), "bycopy") nimState.typeStr &= - &"\n {ndname}* {{.{genImportC(dname, ndname)}, header: {nimState.currentHeader}, bycopy.}} = {dptr}{nname}" + &"\n {ndname}*{pragma} = {dptr}{nname}" proc pStructCommon(ast: ref Ast, node: TSNode, name: string, fstart, fend: int, nimState: NimState) = if nimState.debug: @@ -250,8 +266,9 @@ proc initGrammar(): Grammar = if nimState.data.len == 1: nimState.typeStr &= &"\n {nname}* {{.bycopy.}} = object{union}" else: - let importCDecl = genImportC(prefix & name, nname) - nimState.typeStr &= &"\n {nname}* {{.{importCDecl}, header: {nimState.currentHeader}, bycopy.}} = object{union}" + let + pragma = genPragma(nimState.genImportC(prefix & name, nname), "bycopy") + nimState.typeStr &= &"\n {nname}*{pragma} = object{union}" var i = fstart @@ -560,11 +577,14 @@ proc initGrammar(): Grammar = pout = pout[0 .. ^3] if fnname.nBl and nimState.identifiers.addNewIdentifer(fnname): - let ftyp = nimState.data[0].val.getIdentifier(nskType, fnname) + let + ftyp = nimState.data[0].val.getIdentifier(nskType, fnname) + pragma = genPragma(nimState.genImportC(fname, fnname)) + if fptr.len != 0 or ftyp != "object": - nimState.procStr &= &"\nproc {fnname}*({pout}): {getPtrType(fptr&ftyp)} {{.{genImportC(fname, fnname)}, header: {nimState.currentHeader}.}}" + nimState.procStr &= &"\nproc {fnname}*({pout}): {getPtrType(fptr&ftyp)}{pragma}" else: - nimState.procStr &= &"\nproc {fnname}*({pout}) {{.{genImportC(fname, fnname)}, header: {nimState.currentHeader}.}}" + nimState.procStr &= &"\nproc {fnname}*({pout}){pragma}" )) proc initRegex(ast: ref Ast) = diff --git a/tests/include/test.h b/tests/include/test.h index 8138e54..2e4cf08 100644 --- a/tests/include/test.h +++ b/tests/include/test.h @@ -27,6 +27,7 @@ extern "C" { typedef uint8_t PRIMTYPE; typedef PRIMTYPE CUSTTYPE; +typedef CUSTTYPE _CCUSTTYPE_; struct STRUCT0; diff --git a/tests/tnimterop_c.nim b/tests/tnimterop_c.nim index 01fa70b..0eafa11 100644 --- a/tests/tnimterop_c.nim +++ b/tests/tnimterop_c.nim @@ -40,6 +40,7 @@ block: var pt: PRIMTYPE ct: CUSTTYPE + cct: CCUSTTYPE s0: STRUCT0 s1: STRUCT1 @@ -64,6 +65,7 @@ var pt = 3 ct = 4 +cct = 5 s1.field1 = 5 s2.field1 = 6 From 80545a8221b5561ebf22f1ea5a0684ee35832f1e Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 7 May 2019 11:49:19 -0500 Subject: [PATCH 199/593] cdecl by default --- nimterop/grammar.nim | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index daf5f15..22a0456 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -189,9 +189,9 @@ proc initGrammar(): Grammar = pout = pout[0 .. ^3] if tptr.len != 0 or typ != "object": - nimState.typeStr &= &"\n {nname}*{pragma} = proc({pout}): {getPtrType(tptr&typ)} {{.nimcall.}}" + nimState.typeStr &= &"\n {nname}*{pragma} = proc({pout}): {getPtrType(tptr&typ)} {{.cdecl.}}" else: - nimState.typeStr &= &"\n {nname}*{pragma} = proc({pout}) {{.nimcall.}}" + nimState.typeStr &= &"\n {nname}*{pragma} = proc({pout}) {{.cdecl.}}" else: if i < nimState.data.len and nimState.data[i].name in ["identifier", "number_literal"]: var @@ -321,9 +321,9 @@ proc initGrammar(): Grammar = if pout.len != 0 and pout[^2 .. ^1] == ", ": pout = pout[0 .. ^3] if fptr.len != 0 or ftyp != "object": - nimState.typeStr &= &"\n {fname}*: proc({pout}): {getPtrType(fptr&ftyp)} {{.nimcall.}}" + nimState.typeStr &= &"\n {fname}*: proc({pout}): {getPtrType(fptr&ftyp)} {{.cdecl.}}" else: - nimState.typeStr &= &"\n {fname}*: proc({pout}) {{.nimcall.}}" + nimState.typeStr &= &"\n {fname}*: proc({pout}) {{.cdecl.}}" i += 1 else: if ftyp == "object": @@ -579,7 +579,7 @@ proc initGrammar(): Grammar = if fnname.nBl and nimState.identifiers.addNewIdentifer(fnname): let ftyp = nimState.data[0].val.getIdentifier(nskType, fnname) - pragma = genPragma(nimState.genImportC(fname, fnname)) + pragma = genPragma(nimState.genImportC(fname, fnname), "cdecl") if fptr.len != 0 or ftyp != "object": nimState.procStr &= &"\nproc {fnname}*({pout}): {getPtrType(fptr&ftyp)}{pragma}" From ba9b9f0bc1e8d56c68333dac9a753588ff9b4ad9 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 7 May 2019 15:11:11 -0500 Subject: [PATCH 200/593] Workaround AppVeyor failure --- tests/tmath.nim | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/tmath.nim b/tests/tmath.nim index 95fc086..b2f803b 100644 --- a/tests/tmath.nim +++ b/tests/tmath.nim @@ -6,6 +6,11 @@ type mingw_ldbl_type_t = object mingw_dbl_type_t = object +when defined(windows): + cOverride: + type + complex = object + static: cDebug() cDisableCaching() From 961a739a4ac601875a0bded4df8018fd4689ef95 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 7 May 2019 15:43:54 -0500 Subject: [PATCH 201/593] Fix illegal recursion typedefs --- nimterop/grammar.nim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index 22a0456..5ae8741 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -197,11 +197,11 @@ proc initGrammar(): Grammar = var flen = nimState.data[i].val if nimState.data[i].name == "identifier": - flen = flen.getIdentifier(nskConst, name) + flen = flen.getIdentifier(nskConst, nname) nimState.typeStr &= &"\n {nname}*{pragma} = {aptr}array[{flen}, {getPtrType(tptr&typ)}]" else: - if name == typ: + if nname == typ: nimState.typeStr &= &"\n {nname}*{pragma} = object" else: nimState.typeStr &= &"\n {nname}*{pragma} = {getPtrType(tptr&typ)}" From 2679833d22de0f3cee5fc2a0bef1e7065bc92ff5 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 7 May 2019 16:52:13 -0500 Subject: [PATCH 202/593] Shorten pragmas --- nimterop/ast.nim | 6 ++++++ nimterop/globals.nim | 4 ++-- nimterop/grammar.nim | 18 ++++++++++-------- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/nimterop/ast.nim b/nimterop/ast.nim index c40e8c8..dce61f9 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -154,6 +154,7 @@ proc printNim*(fullpath: string, root: TSNode, astTable: AstTable) = nimState.identifiers = newTable[string, string]() nimState.currentHeader = getCurrentHeader(fullpath) + nimState.impHeader = nimState.currentHeader.replace("header", "imp") nimState.constStr &= &"\n {nimState.currentHeader} {{.used.}} = \"{fp}\"" nimState.debug = gStateRT.debug @@ -166,6 +167,11 @@ proc printNim*(fullpath: string, root: TSNode, astTable: AstTable) = if nimState.constStr.nBl: echo &"const {nimState.constStr}\n" + echo &""" +{{.pragma: {nimState.impHeader}, importc, header: {nimState.currentHeader}.}} +{{.pragma: {nimState.impHeader}C, {nimState.impHeader}, cdecl.}} +""" + if nimState.typeStr.nBl: echo &"type {nimState.typeStr}\n" diff --git a/nimterop/globals.nim b/nimterop/globals.nim index f866e71..85aa06e 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -65,7 +65,7 @@ type debug*: bool - currentHeader*: string + currentHeader*, impHeader*: string data*: seq[tuple[name, val: string]] @@ -84,4 +84,4 @@ type CompileMode = enum const modeDefault {.used.} = $cpp # TODO: USE this everywhere relevant when not declared(CIMPORT): - export gAtoms, gExpressions, gEnumVals, Kind, Ast, AstTable, State, NimState, gStateRT, nBl, CompileMode, modeDefault \ No newline at end of file + export gAtoms, gExpressions, gEnumVals, Kind, Ast, AstTable, State, NimState, gStateRT, nBl, CompileMode, modeDefault diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index 5ae8741..11c5f55 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -8,12 +8,12 @@ type Grammar = seq[tuple[grammar: string, call: proc(ast: ref Ast, node: TSNode, nimState: NimState) {.nimcall.}]] proc genImportC(nimState: NimState, origName, nimName: string): string = - result = "importc" if nimName != origName: - result.add &": \"{origName}\"" # used as {.importc: "foo".} - result.add &", header: {nimState.currentHeader}" + result = &"importc: \"{origName}\", header: {nimState.currentHeader}" + else: + result = nimState.impHeader -proc genPragma(pragmas: varargs[string]): string = +proc genPragma(nimState: NimState, pragmas: varargs[string]): string = result = "" for pragma in pragmas.items(): if pragma.len != 0: @@ -21,6 +21,8 @@ proc genPragma(pragmas: varargs[string]): string = if result.len != 0: result = " {." & result[0 .. ^2] & ".}" + result = result.replace(nimState.impHeader & ", cdecl", nimState.impHeader & "C") + proc initGrammar(): Grammar = # #define X Y result.add((""" @@ -170,7 +172,7 @@ proc initGrammar(): Grammar = i += 1 let - pragma = genPragma(nimState.genImportC(name, nname)) + pragma = nimState.genPragma(nimState.genImportC(name, nname)) if typ.nBl and nname.nBl and nimState.identifiers.addNewIdentifer(nname): if i < nimState.data.len and nimState.data[^1].name == "function_declarator": @@ -227,7 +229,7 @@ proc initGrammar(): Grammar = else: if nimState.identifiers.addNewIdentifer(ndname): let - pragma = genPragma(nimState.genImportc(dname, ndname), "bycopy") + pragma = nimState.genPragma(nimState.genImportc(dname, ndname), "bycopy") nimState.typeStr &= &"\n {ndname}*{pragma} = {dptr}{nname}" @@ -267,7 +269,7 @@ proc initGrammar(): Grammar = nimState.typeStr &= &"\n {nname}* {{.bycopy.}} = object{union}" else: let - pragma = genPragma(nimState.genImportC(prefix & name, nname), "bycopy") + pragma = nimState.genPragma(nimState.genImportC(prefix & name, nname), "bycopy") nimState.typeStr &= &"\n {nname}*{pragma} = object{union}" var @@ -579,7 +581,7 @@ proc initGrammar(): Grammar = if fnname.nBl and nimState.identifiers.addNewIdentifer(fnname): let ftyp = nimState.data[0].val.getIdentifier(nskType, fnname) - pragma = genPragma(nimState.genImportC(fname, fnname), "cdecl") + pragma = nimState.genPragma(nimState.genImportC(fname, fnname), "cdecl") if fptr.len != 0 or ftyp != "object": nimState.procStr &= &"\nproc {fnname}*({pout}): {getPtrType(fptr&ftyp)}{pragma}" From f8c433832e2bc2832dec3fd8ebe8b01453104455 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 7 May 2019 22:22:25 -0500 Subject: [PATCH 203/593] Add support for char enums - #119 --- nimterop/ast.nim | 2 +- nimterop/globals.nim | 7 +++++-- tests/include/test.h | 5 +++++ tests/tnimterop_c.nim | 2 ++ 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/nimterop/ast.nim b/nimterop/ast.nim index dce61f9..c85d5dd 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -52,7 +52,7 @@ proc saveNodeData(node: TSNode, nimState: NimState): bool = nimState.data.insert(("pointer_declarator", ""), nimState.data.len-1) nimState.data.add(("function_declarator", "")) - elif name in gExpressions: + elif name in gExpressions and name != "escape_sequence": if $node.tsNodeParent.tsNodeType() notin gExpressions: nimState.data.add((name, node.getNodeVal())) diff --git a/nimterop/globals.nim b/nimterop/globals.nim index 85aa06e..61054b9 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -12,6 +12,7 @@ const "field_identifier", "identifier", "number_literal", + "char_literal", "preproc_arg", "primitive_type", "sized_type_specifier", @@ -22,12 +23,14 @@ const "parenthesized_expression", "bitwise_expression", "shift_expression", - "math_expression" + "math_expression", + "escape_sequence" ].toSet() gEnumVals {.used.} = @[ "identifier", - "number_literal" + "number_literal", + "char_literal" ].concat(toSeq(gExpressions.items)) type diff --git a/tests/include/test.h b/tests/include/test.h index 2e4cf08..9a28dc0 100644 --- a/tests/include/test.h +++ b/tests/include/test.h @@ -73,6 +73,11 @@ enum ENUM5 { enum15 = (1 << (1 & 1)) }; +enum ENUM7 { + enum17 = '\0', + enum18 = 'A' +}; + typedef void * VOIDPTR; typedef int * INTPTR; diff --git a/tests/tnimterop_c.nim b/tests/tnimterop_c.nim index 0eafa11..ddfa43e 100644 --- a/tests/tnimterop_c.nim +++ b/tests/tnimterop_c.nim @@ -127,6 +127,8 @@ check e4 == enum11 check enum13 == 4 check enum14 == 9 check enum15 == 2 +check enum17 == '\0'.ENUM7 +check enum18 == 'A'.ENUM7 # Issue #58 multiline1() From d65520322b8fc3881f71b2d3ab440053547b9e53 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 7 May 2019 22:40:45 -0500 Subject: [PATCH 204/593] Readme updates --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 80b6877..cbd5e2a 100644 --- a/README.md +++ b/README.md @@ -10,13 +10,14 @@ Nim has one of the best FFI you can find - importing C/C++ is supported out of t The goal of nimterop is to leverage the [tree-sitter](http://tree-sitter.github.io/tree-sitter/) engine to parse C/C++ code and then convert relevant portions of the AST into Nim definitions. [tree-sitter](https://github.com/tree-sitter) is a Github sponsored project that can parse a variety of languages into an AST which is then leveraged by the [Atom](https://atom.io/) editor for syntax highlighting and code folding. The advantages of this approach are multifold: - Benefit from the tree-sitter community's investment into language parsing +- Wrap what is recognized in the AST rather than completely failing due to parsing errors - Avoid depending on Nim compiler API which is evolving constantly and makes backwards compatibility a bit challenging Most of the functionality is contained within the `toast` binary that is built when nimterop is installed and can be used standalone similar to how c2nim can be used today. In addition, nimterop also offers an API to pull in the generated Nim content directly into an application. The nimterop feature set is still limited to C but is expanding rapidly. C++ support will be added once most popular C libraries can be wrapped seamlessly. -Given the simplicity and success of this approach so far, it seems feasible to continue on for more complex code. The goal is to make interop seamless so nimterop will focus on wrapping headers and not the outright conversion of C/C++ implementation. +Nimterop has seen some adoption within the community and the simplicity and success of this approach justifies additional investment of time and effort. Regardless, the goal is to make interop seamless so nimterop will focus on wrapping headers and not the outright conversion of C/C++ implementation. __Installation__ @@ -57,15 +58,15 @@ __Implementation Details__ In order to use the tree-sitter C library, it has to be compiled into a separate binary called `toast` (to AST) since the Nim VM doesn't yet support FFI. `toast` takes a C/C++ file and runs it through the tree-sitter API which returns an AST data structure. This can then be printed out to stdout in a Lisp S-Expression format or the relevant Nim wrapper output. This content can be saved to a `.nim` file and imported if so desired. -Alternatively, the `cImport()` macro allows easier creation of wrappers in code. It runs `toast` on the specified header file and injects the generated wrapper content into the application at compile time. A few other helper procs are provided to influence this process. +Alternatively, the `cImport()` macro allows easier creation of wrappers in code. It runs `toast` on the specified header file and injects the generated wrapper content into the application at compile time. A few other helper procs are provided to influence this process. Output is cached to save time on subsequent runs. -`toast` can also be used to run the header through the preprocessor which cleans up the code considerably. Along with the recursion capability which runs through all #include files, one large simpler header file can be created which can then be processed with c2nim if so desired. +`toast` can also be used to run the header through the preprocessor which cleans up the code considerably. Along with the recursion capability which runs through all #include files, one large simpler header file can be created which can then be processed with `toast` or even `c2nim` if so desired. The tree-sitter library is limited as well - it may fail on some advanced language constructs but is designed to handle them gracefully since it is expected to have bad code while actively typing in an editor. When an error is detected, tree-sitter includes an ERROR node at that location in the AST. At this time, `cImport()` will complain and continue if it encounters any errors. Depending on how severe the errors are, compilation may succeed or fail. Glaring issues will be communicated to the tree-sitter team but their goals may not always align with those of this project. __Credits__ -Nimterop depends on [tree-sitter](http://tree-sitter.github.io/tree-sitter/) and all licensing terms of [tree-sitter](https://github.com/tree-sitter/tree-sitter/blob/master/LICENSE) apply to the usage of this package. Interestingly, the tree-sitter functionality is [wrapped](https://github.com/genotrance/nimtreesitter) using c2nim and nimgen at this time. Depending on the success of this project, those could perhaps be bootstrapped using nimterop eventually. +Nimterop depends on [tree-sitter](http://tree-sitter.github.io/tree-sitter/) and all licensing terms of [tree-sitter](https://github.com/tree-sitter/tree-sitter/blob/master/LICENSE) apply to the usage of this package. The tree-sitter functionality is pulled and wrapped using nimterop itself. __Feedback__ From 268b474332b0e0f4f1ca7cf296caf5039351f1e5 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 8 May 2019 00:59:54 -0500 Subject: [PATCH 205/593] Include comments in output - #61, clean up output --- nimterop/ast.nim | 6 ++--- nimterop/cimport.nim | 12 ++++----- nimterop/getters.nim | 2 +- nimterop/git.nim | 24 ++++++++--------- nimterop/globals.nim | 2 +- nimterop/grammar.nim | 61 +++++++++++++++++++++++++++++--------------- nimterop/lisp.nim | 11 ++++---- 7 files changed, 69 insertions(+), 49 deletions(-) diff --git a/nimterop/ast.nim b/nimterop/ast.nim index c85d5dd..eeaa13e 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -162,10 +162,10 @@ proc printNim*(fullpath: string, root: TSNode, astTable: AstTable) = root.searchAst(astTable, nimState) if nimState.enumStr.nBl: - echo nimState.enumStr + echo &"{nimState.enumStr}\n" if nimState.constStr.nBl: - echo &"const {nimState.constStr}\n" + echo &"const{nimState.constStr}\n" echo &""" {{.pragma: {nimState.impHeader}, importc, header: {nimState.currentHeader}.}} @@ -173,7 +173,7 @@ proc printNim*(fullpath: string, root: TSNode, astTable: AstTable) = """ if nimState.typeStr.nBl: - echo &"type {nimState.typeStr}\n" + echo &"type{nimState.typeStr}\n" if nimState.procStr.nBl: echo &"{nimState.procStr}\n" diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index 1f82b6f..5fade3a 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -138,7 +138,7 @@ proc getToast(fullpath: string, recurse: bool = false): string = cmd.add &" --pluginSourcePath={gStateCT.pluginSourcePath.quoteShell}" cmd.add &" {fullpath.quoteShell}" - echo "# " & cmd + # see https://github.com/nimterop/nimterop/issues/69 (result, ret) = gorgeEx(cmd, cache=getCacheValue(fullpath)) doAssert ret == 0, getToastError(result) @@ -195,7 +195,7 @@ macro cOverride*(body): untyped = result = body if gStateCT.debug: - echo "Overriding " & gStateCT.symOverride.join(" ") + echo "# Overriding " & gStateCT.symOverride.join(" ") proc cSkipSymbol*(skips: seq[string]) {.compileTime.} = ## Similar to `cOverride() `_, this macro allows @@ -320,7 +320,7 @@ macro cDefine*(name: static string, val: static string = ""): untyped = {.passC: `str`.} if gStateCT.debug: - echo result.repr + echo result.repr & "\n" proc cAddSearchDir*(dir: string) {.compileTime.} = ## Add directory ``dir`` to the search path used in calls to @@ -483,13 +483,13 @@ macro cImport*(filename: static string, recurse: static bool = false): untyped = let output = getToast(fullpath, recurse) + if gStateCT.debug: + echo output + try: let body = parseStmt(output) result.add body - - if gStateCT.debug: - echo result.repr except: let (tmpFile, errors) = getNimCheckError(output) diff --git a/nimterop/getters.nim b/nimterop/getters.nim index c9aecf8..93beb80 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -204,7 +204,7 @@ proc removeStatic(content: string): string = proc getPreprocessor*(fullpath: string, mode = "cpp"): string = var mmode = if mode == "cpp": "c++" else: mode - cmd = &"gcc -E -dD -x{mmode} -w " + cmd = &"gcc -E -CC -dD -x{mmode} -w " rdata: seq[string] = @[] start = false diff --git a/nimterop/git.nim b/nimterop/git.nim index c652d16..3a0f493 100644 --- a/nimterop/git.nim +++ b/nimterop/git.nim @@ -54,7 +54,7 @@ proc extractZip*(zipfile, outdir: string) = "'System.IO.Compression.FileSystem'; " & "[IO.Compression.ZipFile]::ExtractToDirectory('$#', '.'); }\"" - echo "Extracting " & zipfile + echo "# Extracting " & zipfile discard execAction(&"cd {outdir.quoteShell} && {cmd % zipfile}") proc downloadUrl*(url, outdir: string) = @@ -63,7 +63,7 @@ proc downloadUrl*(url, outdir: string) = ext = file.splitFile().ext.toLowerAscii() if not (ext == ".zip" and fileExists(outdir/file)): - echo "Downloading " & file + echo "# Downloading " & file mkDir(outdir) var cmd = if defined(Windows): "powershell [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; wget $# -OutFile $#" @@ -75,20 +75,20 @@ proc downloadUrl*(url, outdir: string) = extractZip(file, outdir) proc gitReset*(outdir: string) = - echo "Resetting " & outdir + echo "# Resetting " & outdir let cmd = &"cd {outdir.quoteShell} && git reset --hard" while execAction(cmd).contains("Permission denied"): sleep(1000) - echo " Retrying ..." + echo "# Retrying ..." proc gitCheckout*(file, outdir: string) = - echo "Resetting " & file + echo "# Resetting " & file let file2 = file.relativePath outdir let cmd = &"cd {outdir.quoteShell} && git checkout {file2.quoteShell}" while execAction(cmd).contains("Permission denied"): sleep(500) - echo " Retrying ..." + echo "# Retrying ..." proc gitPull*(url: string, outdir = "", plist = "", checkout = "") = if dirExists(outdir/".git"): @@ -100,7 +100,7 @@ proc gitPull*(url: string, outdir = "", plist = "", checkout = "") = mkDir(outdir) - echo "Setting up Git repo: " & url + echo "# Setting up Git repo: " & url discard execAction(&"cd {outdirQ} && git init .") discard execAction(&"cd {outdirQ} && git remote add origin {url}") @@ -112,27 +112,27 @@ proc gitPull*(url: string, outdir = "", plist = "", checkout = "") = writeFile(sparsefile, plist) if checkout.len != 0: - echo "Checking out " & checkout + echo "# Checking out " & checkout discard execAction(&"cd {outdirQ} && git pull --tags origin master") discard execAction(&"cd {outdirQ} && git checkout {checkout}") else: - echo "Pulling repository" + echo "# Pulling repository" discard execAction(&"cd {outdirQ} && git pull --depth=1 origin master") proc configure*(path, check: string) = if (path / check).fileExists(): return - echo "Configuring " & path + echo "# Configuring " & path if not fileExists(path / "configure"): if fileExists(path / "autogen.sh"): - echo " Running autogen.sh" + echo "# Running autogen.sh" discard execAction(&"cd {path.quoteShell} && bash autogen.sh") if fileExists(path / "configure"): - echo " Running configure" + echo "# Running configure" discard execAction(&"cd {path.quoteShell} && bash configure") diff --git a/nimterop/globals.nim b/nimterop/globals.nim index 61054b9..2d8d651 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -64,7 +64,7 @@ type NimState {.used.} = ref object identifiers*: TableRef[string, string] - constStr*, debugStr*, enumStr*, procStr*, typeStr*: string + constStr*, debugStr*, enumStr*, procStr*, typeStr*, commentStr*: string debug*: bool diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index 11c5f55..4918d05 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -23,6 +23,11 @@ proc genPragma(nimState: NimState, pragmas: varargs[string]): string = result = result.replace(nimState.impHeader & ", cdecl", nimState.impHeader & "C") +proc getComments(nimState: NimState): string = + if nimState.commentStr.len != 0: + result = "\n" & nimState.commentStr + nimState.commentStr = "" + proc initGrammar(): Grammar = # #define X Y result.add((""" @@ -43,7 +48,7 @@ proc initGrammar(): Grammar = name = nimState.data[0].val.getIdentifier(nskConst) if name.nBl and nimState.identifiers.addNewIdentifer(name): - nimState.constStr &= &"\n {name}* = {val}" + nimState.constStr &= &"{nimState.getComments()}\n {name}* = {val}" )) let @@ -191,9 +196,9 @@ proc initGrammar(): Grammar = pout = pout[0 .. ^3] if tptr.len != 0 or typ != "object": - nimState.typeStr &= &"\n {nname}*{pragma} = proc({pout}): {getPtrType(tptr&typ)} {{.cdecl.}}" + nimState.typeStr &= &"{nimState.getComments()}\n {nname}*{pragma} = proc({pout}): {getPtrType(tptr&typ)} {{.cdecl.}}" else: - nimState.typeStr &= &"\n {nname}*{pragma} = proc({pout}) {{.cdecl.}}" + nimState.typeStr &= &"{nimState.getComments()}\n {nname}*{pragma} = proc({pout}) {{.cdecl.}}" else: if i < nimState.data.len and nimState.data[i].name in ["identifier", "number_literal"]: var @@ -201,12 +206,12 @@ proc initGrammar(): Grammar = if nimState.data[i].name == "identifier": flen = flen.getIdentifier(nskConst, nname) - nimState.typeStr &= &"\n {nname}*{pragma} = {aptr}array[{flen}, {getPtrType(tptr&typ)}]" + nimState.typeStr &= &"{nimState.getComments()}\n {nname}*{pragma} = {aptr}array[{flen}, {getPtrType(tptr&typ)}]" else: if nname == typ: - nimState.typeStr &= &"\n {nname}*{pragma} = object" + nimState.typeStr &= &"{nimState.getComments()}\n {nname}*{pragma} = object" else: - nimState.typeStr &= &"\n {nname}*{pragma} = {getPtrType(tptr&typ)}" + nimState.typeStr &= &"{nimState.getComments()}\n {nname}*{pragma} = {getPtrType(tptr&typ)}" )) proc pDupTypeCommon(nname: string, fend: int, nimState: NimState, isEnum=false) = @@ -225,13 +230,13 @@ proc initGrammar(): Grammar = if ndname.nBl and ndname != nname: if isEnum: if nimState.identifiers.addNewIdentifer(ndname): - nimState.enumStr &= &"\ntype {ndname}* = {dptr}{nname}" + nimState.enumStr &= &"{nimState.getComments()}\ntype {ndname}* = {dptr}{nname}" else: if nimState.identifiers.addNewIdentifer(ndname): let pragma = nimState.genPragma(nimState.genImportc(dname, ndname), "bycopy") nimState.typeStr &= - &"\n {ndname}*{pragma} = {dptr}{nname}" + &"{nimState.getComments()}\n {ndname}*{pragma} = {dptr}{nname}" proc pStructCommon(ast: ref Ast, node: TSNode, name: string, fstart, fend: int, nimState: NimState) = if nimState.debug: @@ -266,11 +271,11 @@ proc initGrammar(): Grammar = if nname.nBl and nimState.identifiers.addNewIdentifer(nname): if nimState.data.len == 1: - nimState.typeStr &= &"\n {nname}* {{.bycopy.}} = object{union}" + nimState.typeStr &= &"{nimState.getComments()}\n {nname}* {{.bycopy.}} = object{union}" else: let pragma = nimState.genPragma(nimState.genImportC(prefix & name, nname), "bycopy") - nimState.typeStr &= &"\n {nname}*{pragma} = object{union}" + nimState.typeStr &= &"{nimState.getComments()}\n {nname}*{pragma} = object{union}" var i = fstart @@ -302,7 +307,7 @@ proc initGrammar(): Grammar = if i+1 < nimState.data.len-fend and nimState.data[i+1].name in gEnumVals: let flen = nimState.data[i+1].val.getNimExpression() - nimState.typeStr &= &"\n {fname}*: {aptr}array[{flen}, {getPtrType(fptr&ftyp)}]" + nimState.typeStr &= &"{nimState.getComments()}\n {fname}*: {aptr}array[{flen}, {getPtrType(fptr&ftyp)}]" i += 2 elif i+1 < nimState.data.len-fend and nimState.data[i+1].name == "function_declarator": var @@ -323,15 +328,15 @@ proc initGrammar(): Grammar = if pout.len != 0 and pout[^2 .. ^1] == ", ": pout = pout[0 .. ^3] if fptr.len != 0 or ftyp != "object": - nimState.typeStr &= &"\n {fname}*: proc({pout}): {getPtrType(fptr&ftyp)} {{.cdecl.}}" + nimState.typeStr &= &"{nimState.getComments()}\n {fname}*: proc({pout}): {getPtrType(fptr&ftyp)} {{.cdecl.}}" else: - nimState.typeStr &= &"\n {fname}*: proc({pout}) {{.cdecl.}}" + nimState.typeStr &= &"{nimState.getComments()}\n {fname}*: proc({pout}) {{.cdecl.}}" i += 1 else: if ftyp == "object": - nimState.typeStr &= &"\n {fname}*: pointer" + nimState.typeStr &= &"{nimState.getComments()}\n {fname}*: pointer" else: - nimState.typeStr &= &"\n {fname}*: {getPtrType(fptr&ftyp)}" + nimState.typeStr &= &"{nimState.getComments()}\n {fname}*: {getPtrType(fptr&ftyp)}" i += 1 if node.tsNodeType() == "type_definition" and @@ -439,7 +444,7 @@ proc initGrammar(): Grammar = name.getIdentifier(nskType) if nname.nBl and nimState.identifiers.addNewIdentifer(nname): - nimState.enumStr &= &"\ndefineEnum({nname})" + nimState.enumStr &= &"{nimState.getComments()}\ndefineEnum({nname})" var i = fstart @@ -455,7 +460,7 @@ proc initGrammar(): Grammar = if i+1 < nimState.data.len-fend and nimState.data[i+1].name in gEnumVals: if fname.nBl and nimState.identifiers.addNewIdentifer(fname): - nimState.constStr &= &"\n {fname}* = ({nimState.data[i+1].val.getNimExpression()}).{nname}" + nimState.constStr &= &"{nimState.getComments()}\n {fname}* = ({nimState.data[i+1].val.getNimExpression()}).{nname}" try: count = nimState.data[i+1].val.parseInt() + 1 except: @@ -463,7 +468,7 @@ proc initGrammar(): Grammar = i += 2 else: if fname.nBl and nimState.identifiers.addNewIdentifer(fname): - nimState.constStr &= &"\n {fname}* = {count}.{nname}" + nimState.constStr &= &"{nimState.getComments()}\n {fname}* = {count}.{nname}" i += 1 count += 1 @@ -584,9 +589,25 @@ proc initGrammar(): Grammar = pragma = nimState.genPragma(nimState.genImportC(fname, fnname), "cdecl") if fptr.len != 0 or ftyp != "object": - nimState.procStr &= &"\nproc {fnname}*({pout}): {getPtrType(fptr&ftyp)}{pragma}" + nimState.procStr &= &"{nimState.getComments()}\nproc {fnname}*({pout}): {getPtrType(fptr&ftyp)}{pragma}" else: - nimState.procStr &= &"\nproc {fnname}*({pout}){pragma}" + nimState.procStr &= &"{nimState.getComments()}\nproc {fnname}*({pout}){pragma}" + )) + + # // comment + result.add((&""" + (comment + ) + """, + proc (ast: ref Ast, node: TSNode, nimState: NimState) = + let + cmt = $node.getNodeVal() + + for line in cmt.splitLines(): + let + line = line.multiReplace([("//", ""), ("/*", ""), ("*/", "")]) + + nimState.commentStr &= &"\n#{line.strip(leading=false)}" )) proc initRegex(ast: ref Ast) = diff --git a/nimterop/lisp.nim b/nimterop/lisp.nim index 119de36..8a256be 100644 --- a/nimterop/lisp.nim +++ b/nimterop/lisp.nim @@ -30,12 +30,11 @@ proc readFromTokens(): ref Ast = if gTokens[idx] == "(": if gTokens.len - idx < 2: doAssert false, "Corrupt AST " & $(gTokensLen: gTokens.len, idx: idx) - if gTokens[idx+1] != "comment": - result = new(Ast) - (result.name, result.kind, result.recursive) = gTokens[idx+1].getNameKind() - result.children = @[] - if result.recursive: - result.children.add(result) + result = new(Ast) + (result.name, result.kind, result.recursive) = gTokens[idx+1].getNameKind() + result.children = @[] + if result.recursive: + result.children.add(result) idx += 2 while gTokens[idx] != ")": var res = readFromTokens() From b0a8f9bec5fb00ecf070a445f1b3b6a419fee103 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 8 May 2019 20:16:02 -0500 Subject: [PATCH 206/593] Remove global state from toast --- nimterop/ast.nim | 11 +- nimterop/astold.nim | 297 ------------------------------------------- nimterop/getters.nim | 54 ++++---- nimterop/globals.nim | 13 +- nimterop/grammar.nim | 68 +++++----- nimterop/toast.nim | 60 +++++---- 6 files changed, 99 insertions(+), 404 deletions(-) delete mode 100644 nimterop/astold.nim diff --git a/nimterop/ast.nim b/nimterop/ast.nim index eeaa13e..d6b3f76 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -8,7 +8,7 @@ proc saveNodeData(node: TSNode, nimState: NimState): bool = let name = $node.tsNodeType() if name in gAtoms: var - val = node.getNodeVal() + val = nimState.getNodeVal(node) if name == "primitive_type" and node.tsNodeParent.tsNodeType() == "sized_type_specifier": return true @@ -54,7 +54,7 @@ proc saveNodeData(node: TSNode, nimState: NimState): bool = elif name in gExpressions and name != "escape_sequence": if $node.tsNodeParent.tsNodeType() notin gExpressions: - nimState.data.add((name, node.getNodeVal())) + nimState.data.add((name, nimState.getNodeVal(node))) elif name in ["abstract_pointer_declarator", "enumerator", "field_declaration", "function_declarator"]: nimState.data.add((name.replace("abstract_", ""), "")) @@ -107,7 +107,7 @@ proc searchAst(root: TSNode, astTable: AstTable, nimState: NimState) = for ast in astTable[name]: if searchAstForNode(ast, node, nimState): ast.tonim(ast, node, nimState) - if gStateRT.debug: + if nimState.gState.debug: nimState.debugStr &= "\n# " & nimState.data.join("\n# ") & "\n" break nimState.data = @[] @@ -147,7 +147,7 @@ proc printNimHeader*() = import nimterop/types """ % [$now(), getAppFilename(), commandLineParams().join(" ")] -proc printNim*(fullpath: string, root: TSNode, astTable: AstTable) = +proc printNim*(gState: State, fullpath: string, root: TSNode, astTable: AstTable) = var nimState = new(NimState) fp = fullpath.replace("\\", "/") @@ -155,9 +155,10 @@ proc printNim*(fullpath: string, root: TSNode, astTable: AstTable) = nimState.currentHeader = getCurrentHeader(fullpath) nimState.impHeader = nimState.currentHeader.replace("header", "imp") + nimState.sourceFile = fullpath nimState.constStr &= &"\n {nimState.currentHeader} {{.used.}} = \"{fp}\"" - nimState.debug = gStateRT.debug + nimState.gState = gState root.searchAst(astTable, nimState) diff --git a/nimterop/astold.nim b/nimterop/astold.nim deleted file mode 100644 index a0c5b93..0000000 --- a/nimterop/astold.nim +++ /dev/null @@ -1,297 +0,0 @@ -import macros, os, strformat, strutils - -import treesitter/api - -import getters, globals - -# -# Preprocessor -# - -proc pPreprocDef(node: TSNode) = - if node.tsNodeNamedChildCount() == 2: - let - name = getNodeValIf(node.tsNodeNamedChild(0), "identifier") - val = getNodeValIf(node.tsNodeNamedChild(1), "preproc_arg") - - if name.nBl and val.nBl and name notin gStateRT.consts: - gStateRT.consts.add(name) - if val.getLit().nBl: - # #define NAME VALUE - gStateRT.constStr &= &" {name.getIdentifier()}* = {val} # pPreprocDef()\n" - -# -# Types -# - -proc typeScan(node: TSNode, sym, id: string, offset: string): string = - if node.tsNodeIsNull() or $node.tsNodeType() != sym or node.tsNodeNamedChildCount() != 2: - return - - var - name = getNodeValIf(node.tsNodeNamedChild(1), id) - ptyp = getNodeValIf(node.tsNodeNamedChild(0), "primitive_type") - ttyp = getNodeValIf(node.tsNodeNamedChild(0), "type_identifier") - ptrname = false - - if name.len == 0 and $node.tsNodeNamedChild(1).tsNodeType() == "pointer_declarator" and node.tsNodeNamedChild(1).tsNodeNamedChildCount() == 1: - name = getNodeValIf(node.tsNodeNamedChild(1).tsNodeNamedChild(0), id) - ptrname = true - - if name.len == 0: - return - elif ptyp.nBl: - ptyp = ptyp.getType() - if ptyp != "object" and ptrname: - ptyp = &"ptr {ptyp}" - result = &"{offset}{name.getIdentifier()}: {ptyp}" - elif ttyp.nBl: - if ptrname: - ttyp = &"ptr {ttyp}" - result = &"{offset}{name.getIdentifier()}: {ttyp}" - elif $node.tsNodeNamedChild(0).tsNodeType() in ["struct_specifier", "enum_specifier"] and node.tsNodeNamedChild(0).tsNodeNamedChildCount() == 1: - var styp = getNodeValIf(node.tsNodeNamedChild(0).tsNodeNamedChild(0), "type_identifier") - if styp.nBl: - if ptrname: - styp = &"ptr {styp}" - result = &"{offset}{name.getIdentifier()}: {styp}" - -proc pStructSpecifier(node: TSNode, name = "") = - var stmt: string - if node.tsNodeNamedChildCount() == 1 and name notin gStateRT.types: - case $node.tsNodeNamedChild(0).tsNodeType(): - of "type_identifier": - let typ = getNodeValIf(node.tsNodeNamedChild(0), "type_identifier") - if typ.nBl: - gStateRT.types.add(name) - if name != typ: - # typedef struct X Y - gStateRT.typeStr &= &" {name.getIdentifier()}* = {typ} #1 pStructSpecifier()\n" - else: - # typedef struct X X - gStateRT.typeStr &= &" {name.getIdentifier()}* {{.importc: \"{name}\", header: {gStateRT.currentHeader}, bycopy.}} = object #2 pStructSpecifier()\n" - - of "field_declaration_list": - # typedef struct { fields } X - stmt = &" {name.getIdentifier()}* {{.importc: \"{name}\", header: {gStateRT.currentHeader}, bycopy.}} = object #3 pStructSpecifier()\n" - - if node.tsNodeNamedChild(0).tsNodeNamedChildCount() != 0: - for i in 0 .. node.tsNodeNamedChild(0).tsNodeNamedChildCount()-1: - if $node.tsNodeNamedChild(0).tsNodeNamedChild(i).tsNodeType() == "comment": - continue - let ts = typeScan(node.tsNodeNamedChild(0).tsNodeNamedChild(i), "field_declaration", "field_identifier", " ") - if ts.len == 0: - return - stmt &= ts & "\n" - - gStateRT.types.add(name) - gStateRT.typeStr &= stmt - else: - discard - - elif name.len == 0 and node.tsNodeNamedChildCount() == 2 and $node.tsNodeNamedChild(1).tsNodeType() == "field_declaration_list": - let ename = getNodeValIf(node.tsNodeNamedChild(0), "type_identifier") - if ename.nBl and ename notin gStateRT.types: - # struct X { fields } - stmt &= &" {ename}* {{.importc: \"struct {ename}\", header: {gStateRT.currentHeader}, bycopy.}} = object #4 pStructSpecifier()\n" - - if node.tsNodeNamedChild(1).tsNodeNamedChildCount() != 0: - for i in 0 .. node.tsNodeNamedChild(1).tsNodeNamedChildCount()-1: - if $node.tsNodeNamedChild(1).tsNodeNamedChild(i).tsNodeType() == "comment": - continue - let ts = typeScan(node.tsNodeNamedChild(1).tsNodeNamedChild(i), "field_declaration", "field_identifier", " ") - if ts.len == 0: - return - stmt &= ts & "\n" - - gStateRT.types.add(name) - gStateRT.typeStr &= stmt - -proc pEnumSpecifier(node: TSNode, name = "") = - var - ename: string - elid: uint32 - stmt: string - - if node.tsNodeNamedChildCount() == 1 and $node.tsNodeNamedChild(0).tsNodeType() == "enumerator_list": - # typedef enum { fields } X - ename = name - elid = 0 - stmt = &" {name.getIdentifier()}* = enum #1 pEnumSpecifier()\n" - elif node.tsNodeNamedChildCount() == 2 and $node.tsNodeNamedChild(1).tsNodeType() == "enumerator_list": - if name.len == 0: - ename = getNodeValIf(node.tsNodeNamedChild(0), "type_identifier") - else: - ename = name - elid = 1 - if ename.nBl: - # enum X { fields } - stmt = &" {ename}* = enum #2 pEnumSpecifier()\n" - else: - return - else: - return - - if node.tsNodeNamedChild(elid).tsNodeNamedChildCount() != 0: - for i in 0 .. node.tsNodeNamedChild(elid).tsNodeNamedChildCount()-1: - let field = node.tsNodeNamedChild(elid).tsNodeNamedChild(i) - if $field.tsNodeType() == "comment": - continue - if not field.tsNodeIsNull() and $field.tsNodeType() == "enumerator": - let fname = getNodeValIf(field.tsNodeNamedChild(0), "identifier") - if field.tsNodeNamedChildCount() == 1: - stmt &= &" {fname}\n" - elif field.tsNodeNamedChildCount() == 2 and $field.tsNodeNamedChild(1).tsNodeType() == "number_literal": - let num = getNodeValIf(field.tsNodeNamedChild(1), "number_literal") - stmt &= &" {fname} = {num}\n" - else: - return - - if ename notin gStateRT.types: - gStateRT.types.add(name) - gStateRT.typeStr &= stmt - -proc pTypeDefinition(node: TSNode) = - if node.tsNodeNamedChildCount() == 2: - var - name = getNodeValIf(node.tsNodeNamedChild(1), "type_identifier") - ptyp = getNodeValIf(node.tsNodeNamedChild(0), "primitive_type") - ttyp = getNodeValIf(node.tsNodeNamedChild(0), "type_identifier") - ptrname = false - - if name.len == 0 and $node.tsNodeNamedChild(1).tsNodeType() == "pointer_declarator" and node.tsNodeNamedChild(1).tsNodeNamedChildCount() == 1: - name = getNodeValIf(node.tsNodeNamedChild(1).tsNodeNamedChild(0), "type_identifier") - ptrname = true - - if name.nBl and name notin gStateRT.types: - if ptyp.nBl: - # typedef int X - gStateRT.types.add(name) - ptyp = ptyp.getType() - if ptyp != "object" and ptrname: - ptyp = &"ptr {ptyp}" - gStateRT.typeStr &= &" {name.getIdentifier()}* = {ptyp} #1 pTypeDefinition()\n" - elif ttyp.nBl: - # typedef X Y - gStateRT.types.add(name) - if ptrname: - ttyp = &"ptr {ttyp}" - gStateRT.typeStr &= &" {name.getIdentifier()}* = {ttyp} #2 pTypeDefinition()\n" - else: - case $node.tsNodeNamedChild(0).tsNodeType(): - of "struct_specifier": - pStructSpecifier(node.tsNodeNamedChild(0), name) - of "enum_specifier": - pEnumSpecifier(node.tsNodeNamedChild(0), name) - else: - discard - -proc pFunctionDeclarator(node: TSNode, typ: string) = - if node.tsNodeNamedChildCount() == 2: - let - name = getNodeValIf(node.tsNodeNamedChild(0), "identifier") - - if name.nBl and name notin gStateRT.procs and $node.tsNodeNamedChild(1).tsNodeType() == "parameter_list": - # typ function(typ param1, ...) - var stmt = &"# pFunctionDeclarator()\nproc {name.getIdentifier()}*(" - - if node.tsNodeNamedChild(1).tsNodeNamedChildCount() != 0: - for i in 0 .. node.tsNodeNamedChild(1).tsNodeNamedChildCount()-1: - let ts = typeScan(node.tsNodeNamedChild(1).tsNodeNamedChild(i), "parameter_declaration", "identifier", "") - if ts.len == 0: - return - stmt &= ts - if i != node.tsNodeNamedChild(1).tsNodeNamedChildCount()-1: - stmt &= ", " - - if typ != "void": - stmt &= &"): {typ.getType()} " - else: - stmt &= ") " - - stmt &= &"{{.importc: \"{name}\", header: {gStateRT.currentHeader}.}}\n" - - gStateRT.procs.add(name) - gStateRT.procStr &= stmt - -proc pDeclaration*(node: TSNode) = - if node.tsNodeNamedChildCount() == 2 and $node.tsNodeNamedChild(1).tsNodeType() == "function_declarator": - let - ptyp = getNodeValIf(node.tsNodeNamedChild(0), "primitive_type") - ttyp = getNodeValIf(node.tsNodeNamedChild(0), "type_identifier") - - if ptyp.nBl: - pFunctionDeclarator(node.tsNodeNamedChild(1), ptyp.getType()) - elif ttyp.nBl: - pFunctionDeclarator(node.tsNodeNamedChild(1), ttyp) - elif $node.tsNodeNamedChild(0).tsNodeType() == "struct_specifier" and node.tsNodeNamedChild(0).tsNodeNamedChildCount() == 1: - let styp = getNodeValIf(node.tsNodeNamedChild(0).tsNodeNamedChild(0), "type_identifier") - if styp.nBl: - pFunctionDeclarator(node.tsNodeNamedChild(1), styp) - -proc genNimAst(root: TSNode) = - var - node = root - nextnode: TSNode - - while true: - if not node.tsNodeIsNull(): - case $node.tsNodeType(): - of "ERROR": - let (line, col) = getLineCol(node) - let file = gStateRT.sourceFile - echo &"# [toast] Potentially invalid syntax at {file}:{line}:{col}" - of "preproc_def": - pPreprocDef(node) - of "type_definition": - pTypeDefinition(node) - of "declaration": - pDeclaration(node) - of "struct_specifier": - if $node.tsNodeParent().tsNodeType() notin ["type_definition", "declaration"]: - pStructSpecifier(node) - of "enum_specifier": - if $node.tsNodeParent.tsNodeType() notin ["type_definition", "declaration"]: - pEnumSpecifier(node) - else: - # TODO: log - discard - else: - return - - if node.tsNodeNamedChildCount() != 0: - nextnode = node.tsNodeNamedChild(0) - else: - nextnode = node.tsNodeNextNamedSibling() - - if nextnode.tsNodeIsNull(): - while true: - node = node.tsNodeParent() - if node == root: - break - if not node.tsNodeNextNamedSibling().tsNodeIsNull(): - node = node.tsNodeNextNamedSibling() - break - else: - node = nextnode - - if node == root: - break - -proc printNim*(fullpath: string, root: TSNode) = - echo "{.experimental: \"codeReordering\".}" - - var fp = fullpath.replace("\\", "/") - gStateRT.currentHeader = getCurrentHeader(fullpath) - gStateRT.constStr &= &" {gStateRT.currentHeader} = \"{fp}\"\n" - - genNimAst(root) - - if gStateRT.constStr.nBl: - echo "const\n" & gStateRT.constStr - - if gStateRT.typeStr.nBl: - echo "type\n" & gStateRT.typeStr - - if gStateRT.procStr.nBl: - echo gStateRT.procStr diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 93beb80..ad1cb95 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -104,14 +104,14 @@ proc checkIdentifier(name, kind, parent, origName: string) = if parent.nBl: doAssert name.nBl, &"Blank identifier, originally '{parentStr}{name}' ({kind}), cannot be empty" -proc getIdentifier*(name: string, kind: NimSymKind, parent=""): string = +proc getIdentifier*(nimState: NimState, name: string, kind: NimSymKind, parent=""): string = doAssert name.len != 0, "Blank identifier error" - if name notin gStateRT.symOverride or parent.nBl: - if gStateRT.onSymbol != nil: + if name notin nimState.gState.symOverride or parent.nBl: + if nimState.gState.onSymbol != nil: var sym = Symbol(name: name, parent: parent, kind: kind) - gStateRT.onSymbol(sym) + nimState.gState.onSymbol(sym) result = sym.name else: @@ -124,27 +124,27 @@ proc getIdentifier*(name: string, kind: NimSymKind, parent=""): string = else: result = "" -proc getUniqueIdentifier*(existing: TableRef[string, string], prefix = ""): string = +proc getUniqueIdentifier*(nimState: NimState, prefix = ""): string = var - name = prefix & "_" & gStateRT.sourceFile.extractFilename().multiReplace([(".", ""), ("-", "")]) + name = prefix & "_" & nimState.sourceFile.extractFilename().multiReplace([(".", ""), ("-", "")]) nimName = name[0] & name[1 .. ^1].replace("_", "").toLowerAscii count = 1 - while (nimName & $count) in existing: + while (nimName & $count) in nimState.identifiers: count += 1 return name & $count -proc addNewIdentifer*(existing: var TableRef[string, string], name: string): bool = - if name notin gStateRT.symOverride: +proc addNewIdentifer*(nimState: NimState, name: string): bool = + if name notin nimState.gState.symOverride: let nimName = name[0] & name[1 .. ^1].replace("_", "").toLowerAscii - if existing.hasKey(nimName): - doAssert name == existing[nimName], &"Identifier '{name}' is a stylistic duplicate of identifier '{existing[nimName]}', use 'cPlugin:onSymbol()' to rename" + if nimState.identifiers.hasKey(nimName): + doAssert name == nimState.identifiers[nimName], &"Identifier '{name}' is a stylistic duplicate of identifier '{nimState.identifiers[nimName]}', use 'cPlugin:onSymbol()' to rename" result = false else: - existing[nimName] = name + nimState.identifiers[nimName] = name result = true proc getPtrType*(str: string): string = @@ -166,20 +166,14 @@ proc getLit*(str: string): string = str.contains(re"^0x[\d]+$"): return str -proc getNodeVal*(node: TSNode): string = - return gStateRT.code[node.tsNodeStartByte() .. node.tsNodeEndByte()-1].strip() +proc getNodeVal*(nimState: NimState, node: TSNode): string = + return nimState.gState.code[node.tsNodeStartByte() .. node.tsNodeEndByte()-1].strip() -proc getNodeValIf*(node: TSNode, esym: string): string = - if esym != $node.tsNodeType(): - return - - return node.getNodeVal() - -proc getLineCol*(node: TSNode): tuple[line, col: int] = +proc getLineCol*(gState: State, node: TSNode): tuple[line, col: int] = result.line = 1 result.col = 1 for i in 0 .. node.tsNodeStartByte().int-1: - if gStateRT.code[i] == '\n': + if gState.code[i] == '\n': result.col = 0 result.line += 1 result.col += 1 @@ -201,7 +195,7 @@ proc removeStatic(content: string): string = result.add(body.replace(re"(?m)^(.*\n?)", "//$1")) ) -proc getPreprocessor*(fullpath: string, mode = "cpp"): string = +proc getPreprocessor*(gState: State, fullpath: string, mode = "cpp"): string = var mmode = if mode == "cpp": "c++" else: mode cmd = &"gcc -E -CC -dD -x{mmode} -w " @@ -210,10 +204,10 @@ proc getPreprocessor*(fullpath: string, mode = "cpp"): string = start = false sfile = fullpath.sanitizePath - for inc in gStateRT.includeDirs: + for inc in gState.includeDirs: cmd &= &"-I{inc.quoteShell} " - for def in gStateRT.defines: + for def in gState.defines: cmd &= &"-D{def} " cmd &= &"{fullpath.quoteShell}" @@ -229,13 +223,13 @@ proc getPreprocessor*(fullpath: string, mode = "cpp"): string = start = true elif not ("\\" in line) and not ("/" in line) and extractFilename(sfile) in line: start = true - elif gStateRT.recurse: + elif gState.recurse: let pDir = sfile.expandFilename().parentDir().sanitizePath() if pDir.len == 0 or pDir in saniLine: start = true else: - for inc in gStateRT.includeDirs: + for inc in gState.includeDirs: if inc.absolutePath().sanitizePath in saniLine: start = true break @@ -350,7 +344,7 @@ proc dll*(path: string): string = result = dir / (DynlibFormat % name) -proc loadPlugin*(sourcePath: string) = +proc loadPlugin*(gState: State, sourcePath: string) = doAssert fileExists(sourcePath), "Plugin file does not exist: " & sourcePath let @@ -363,5 +357,5 @@ proc loadPlugin*(sourcePath: string) = let lib = loadLib(pdll) doAssert lib != nil, "Plugin $1 compiled to $2 failed to load" % [sourcePath, pdll] - gStateRT.onSymbol = cast[OnSymbol](lib.symAddr("onSymbol")) - doAssert gStateRT.onSymbol != nil, "onSymbol() load failed from " & pdll + gState.onSymbol = cast[OnSymbol](lib.symAddr("onSymbol")) + doAssert gState.onSymbol != nil, "onSymbol() load failed from " & pdll diff --git a/nimterop/globals.nim b/nimterop/globals.nim index 2d8d651..10b6ac3 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -52,12 +52,12 @@ type AstTable {.used.} = TableRef[string, seq[ref Ast]] - State = object + State = ref object compile*, defines*, headers*, includeDirs*, searchDirs*, symOverride*: seq[string] nocache*, debug*, past*, preprocess*, pnim*, pretty*, recurse*: bool - code*, mode*, pluginSourcePath*, sourceFile*: string + code*, mode*, pluginSourcePath*: string onSymbol*: OnSymbol @@ -66,15 +66,14 @@ type constStr*, debugStr*, enumStr*, procStr*, typeStr*, commentStr*: string - debug*: bool + gState*: State - currentHeader*, impHeader*: string + currentHeader*, impHeader*, sourceFile*: string data*: seq[tuple[name, val: string]] var - gStateCT {.compiletime, used.}: State - gStateRT {.used.}: State + gStateCT {.compiletime, used.} = new(State) template nBl(s: typed): untyped {.used.} = (s.len != 0) @@ -87,4 +86,4 @@ type CompileMode = enum const modeDefault {.used.} = $cpp # TODO: USE this everywhere relevant when not declared(CIMPORT): - export gAtoms, gExpressions, gEnumVals, Kind, Ast, AstTable, State, NimState, gStateRT, nBl, CompileMode, modeDefault + export gAtoms, gExpressions, gEnumVals, Kind, Ast, AstTable, State, NimState, nBl, CompileMode, modeDefault diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index 4918d05..f9bb2cb 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -37,7 +37,7 @@ proc initGrammar(): Grammar = ) """, proc (ast: ref Ast, node: TSNode, nimState: NimState) = - if nimState.debug: + if nimState.gState.debug: nimState.debugStr &= "\n# define X Y" let @@ -45,9 +45,9 @@ proc initGrammar(): Grammar = if val.nBl: let - name = nimState.data[0].val.getIdentifier(nskConst) + name = nimState.getIdentifier(nimState.data[0].val, nskConst) - if name.nBl and nimState.identifiers.addNewIdentifer(name): + if name.nBl and nimState.addNewIdentifer(name): nimState.constStr &= &"{nimState.getComments()}\n {name}* = {val}" )) @@ -109,7 +109,7 @@ proc initGrammar(): Grammar = """ template funcParamCommon(fname, pname, ptyp, pptr, pout, count, i: untyped): untyped = - ptyp = nimState.data[i].val.getIdentifier(nskType, fname) + ptyp = nimState.getIdentifier(nimState.data[i].val, nskType, fname) pptr = "" while i+1 < nimState.data.len and nimState.data[i+1].name == "pointer_declarator": @@ -117,7 +117,7 @@ proc initGrammar(): Grammar = i += 1 if i+1 < nimState.data.len and nimState.data[i+1].name == "identifier": - pname = nimState.data[i+1].val.getIdentifier(nskParam, fname) + pname = nimState.getIdentifier(nimState.data[i+1].val, nskParam, fname) i += 2 else: pname = "a" & $count @@ -150,12 +150,12 @@ proc initGrammar(): Grammar = ) """, proc (ast: ref Ast, node: TSNode, nimState: NimState) = - if nimState.debug: + if nimState.gState.debug: nimState.debugStr &= "\n# typedef X Y" var i = 0 - typ = nimState.data[i].val.getIdentifier(nskType) + typ = nimState.getIdentifier(nimState.data[i].val, nskType) name = "" nname = "" tptr = "" @@ -173,13 +173,13 @@ proc initGrammar(): Grammar = if i < nimState.data.len: name = nimState.data[i].val - nname = nimState.data[i].val.getIdentifier(nskType) + nname = nimState.getIdentifier(name, nskType) i += 1 let pragma = nimState.genPragma(nimState.genImportC(name, nname)) - if typ.nBl and nname.nBl and nimState.identifiers.addNewIdentifer(nname): + if typ.nBl and nname.nBl and nimState.addNewIdentifer(nname): if i < nimState.data.len and nimState.data[^1].name == "function_declarator": var fname = nname @@ -204,7 +204,7 @@ proc initGrammar(): Grammar = var flen = nimState.data[i].val if nimState.data[i].name == "identifier": - flen = flen.getIdentifier(nskConst, nname) + flen = nimState.getIdentifier(flen, nskConst, nname) nimState.typeStr &= &"{nimState.getComments()}\n {nname}*{pragma} = {aptr}array[{flen}, {getPtrType(tptr&typ)}]" else: @@ -215,12 +215,12 @@ proc initGrammar(): Grammar = )) proc pDupTypeCommon(nname: string, fend: int, nimState: NimState, isEnum=false) = - if nimState.debug: + if nimState.gState.debug: nimState.debugStr &= "\n# pDupTypeCommon()" var dname = nimState.data[^1].val - ndname = nimState.data[^1].val.getIdentifier(nskType) + ndname = nimState.getIdentifier(dname, nskType) dptr = if fend == 2: "ptr " @@ -229,21 +229,21 @@ proc initGrammar(): Grammar = if ndname.nBl and ndname != nname: if isEnum: - if nimState.identifiers.addNewIdentifer(ndname): + if nimState.addNewIdentifer(ndname): nimState.enumStr &= &"{nimState.getComments()}\ntype {ndname}* = {dptr}{nname}" else: - if nimState.identifiers.addNewIdentifer(ndname): + if nimState.addNewIdentifer(ndname): let pragma = nimState.genPragma(nimState.genImportc(dname, ndname), "bycopy") nimState.typeStr &= &"{nimState.getComments()}\n {ndname}*{pragma} = {dptr}{nname}" proc pStructCommon(ast: ref Ast, node: TSNode, name: string, fstart, fend: int, nimState: NimState) = - if nimState.debug: + if nimState.gState.debug: nimState.debugStr &= "\n# pStructCommon" var - nname = name.getIdentifier(nskType) + nname = nimState.getIdentifier(name, nskType) prefix = "" union = "" @@ -269,7 +269,7 @@ proc initGrammar(): Grammar = union = " {.union.}" break - if nname.nBl and nimState.identifiers.addNewIdentifer(nname): + if nname.nBl and nimState.addNewIdentifer(nname): if nimState.data.len == 1: nimState.typeStr &= &"{nimState.getComments()}\n {nname}* {{.bycopy.}} = object{union}" else: @@ -302,7 +302,7 @@ proc initGrammar(): Grammar = aptr &= "ptr " i += 1 - fname = nimState.data[i].val.getIdentifier(nskField, nname) + fname = nimState.getIdentifier(nimState.data[i].val, nskField, nname) if i+1 < nimState.data.len-fend and nimState.data[i+1].name in gEnumVals: let @@ -390,7 +390,7 @@ proc initGrammar(): Grammar = ) """, proc (ast: ref Ast, node: TSNode, nimState: NimState) = - if nimState.debug: + if nimState.gState.debug: nimState.debugStr &= "\n# struct X {}" pStructCommon(ast, node, nimState.data[0].val, 1, 1, nimState) @@ -413,7 +413,7 @@ proc initGrammar(): Grammar = ) """, proc (ast: ref Ast, node: TSNode, nimState: NimState) = - if nimState.debug: + if nimState.gState.debug: nimState.debugStr &= "\n# typedef struct X {}" var @@ -434,16 +434,16 @@ proc initGrammar(): Grammar = )) proc pEnumCommon(ast: ref Ast, node: TSNode, name: string, fstart, fend: int, nimState: NimState) = - if nimState.debug: + if nimState.gState.debug: nimState.debugStr &= "\n# pEnumCommon()" let nname = if name.len == 0: - getUniqueIdentifier(nimState.identifiers, "Enum") + getUniqueIdentifier(nimState, "Enum") else: - name.getIdentifier(nskType) + nimState.getIdentifier(name, nskType) - if nname.nBl and nimState.identifiers.addNewIdentifer(nname): + if nname.nBl and nimState.addNewIdentifer(nname): nimState.enumStr &= &"{nimState.getComments()}\ndefineEnum({nname})" var @@ -455,11 +455,11 @@ proc initGrammar(): Grammar = continue let - fname = nimState.data[i].val.getIdentifier(nskEnumField) + fname = nimState.getIdentifier(nimState.data[i].val, nskEnumField) if i+1 < nimState.data.len-fend and nimState.data[i+1].name in gEnumVals: - if fname.nBl and nimState.identifiers.addNewIdentifer(fname): + if fname.nBl and nimState.addNewIdentifer(fname): nimState.constStr &= &"{nimState.getComments()}\n {fname}* = ({nimState.data[i+1].val.getNimExpression()}).{nname}" try: count = nimState.data[i+1].val.parseInt() + 1 @@ -467,7 +467,7 @@ proc initGrammar(): Grammar = count += 1 i += 2 else: - if fname.nBl and nimState.identifiers.addNewIdentifer(fname): + if fname.nBl and nimState.addNewIdentifer(fname): nimState.constStr &= &"{nimState.getComments()}\n {fname}* = {count}.{nname}" i += 1 count += 1 @@ -489,7 +489,7 @@ proc initGrammar(): Grammar = ) """ % gEnumVals.join("|"), proc (ast: ref Ast, node: TSNode, nimState: NimState) = - if nimState.debug: + if nimState.gState.debug: nimState.debugStr &= "\n# enum X {}" var @@ -517,7 +517,7 @@ proc initGrammar(): Grammar = ) """, proc (ast: ref Ast, node: TSNode, nimState: NimState) = - if nimState.debug: + if nimState.gState.debug: nimState.debugStr &= "\n# typedef enum {}" var @@ -550,7 +550,7 @@ proc initGrammar(): Grammar = ) """, proc (ast: ref Ast, node: TSNode, nimState: NimState) = - if nimState.debug: + if nimState.gState.debug: nimState.debugStr &= "\n# typ function" var @@ -569,7 +569,7 @@ proc initGrammar(): Grammar = var fname = nimState.data[i].val - fnname = fname.getIdentifier(nskProc) + fnname = nimState.getIdentifier(fname, nskProc) pout, pname, ptyp, pptr = "" count = 1 @@ -583,9 +583,9 @@ proc initGrammar(): Grammar = if pout.len != 0 and pout[^2 .. ^1] == ", ": pout = pout[0 .. ^3] - if fnname.nBl and nimState.identifiers.addNewIdentifer(fnname): + if fnname.nBl and nimState.addNewIdentifer(fnname): let - ftyp = nimState.data[0].val.getIdentifier(nskType, fnname) + ftyp = nimState.getIdentifier(nimState.data[0].val, nskType, fnname) pragma = nimState.genPragma(nimState.genImportC(fname, fnname), "cdecl") if fptr.len != 0 or ftyp != "object": @@ -601,7 +601,7 @@ proc initGrammar(): Grammar = """, proc (ast: ref Ast, node: TSNode, nimState: NimState) = let - cmt = $node.getNodeVal() + cmt = $nimState.getNodeVal(node) for line in cmt.splitLines(): let diff --git a/nimterop/toast.nim b/nimterop/toast.nim index e3651a0..bf34f41 100644 --- a/nimterop/toast.nim +++ b/nimterop/toast.nim @@ -4,7 +4,7 @@ import "."/treesitter/[api, c, cpp] import "."/[ast, globals, getters, grammar] -proc printLisp(root: TSNode) = +proc printLisp(gState: State, root: TSNode) = var node = root nextnode: TSNode @@ -12,21 +12,21 @@ proc printLisp(root: TSNode) = while true: if not node.tsNodeIsNull() and depth > -1: - if gStateRT.pretty: + if gState.pretty: stdout.write spaces(depth) let - (line, col) = node.getLineCol() + (line, col) = gState.getLineCol(node) stdout.write &"({$node.tsNodeType()} {line} {col} {node.tsNodeEndByte() - node.tsNodeStartByte()}" else: break if node.tsNodeNamedChildCount() != 0: - if gStateRT.pretty: + if gState.pretty: echo "" nextnode = node.tsNodeNamedChild(0) depth += 1 else: - if gStateRT.pretty: + if gState.pretty: echo ")" else: stdout.write ")" @@ -38,7 +38,7 @@ proc printLisp(root: TSNode) = depth -= 1 if depth == -1: break - if gStateRT.pretty: + if gState.pretty: echo spaces(depth) & ")" else: stdout.write ")" @@ -53,7 +53,7 @@ proc printLisp(root: TSNode) = if node == root: break -proc process(path: string, astTable: AstTable) = +proc process(gState: State, path: string, astTable: AstTable) = doAssert existsFile(path), "Invalid path " & path var @@ -63,41 +63,39 @@ proc process(path: string, astTable: AstTable) = defer: parser.tsParserDelete() - gStateRT.sourceFile = path - - if gStateRT.mode.len == 0: + if gState.mode.len == 0: if ext in [".h", ".c"]: - gStateRT.mode = "c" + gState.mode = "c" elif ext in [".hxx", ".hpp", ".hh", ".H", ".h++", ".cpp", ".cxx", ".cc", ".C", ".c++"]: - gStateRT.mode = "cpp" + gState.mode = "cpp" - if gStateRT.preprocess: - gStateRT.code = getPreprocessor(path) + if gState.preprocess: + gState.code = gState.getPreprocessor(path) else: - gStateRT.code = readFile(path) + gState.code = readFile(path) - doAssert gStateRT.code.len != 0, "Empty file or preprocessor error" + doAssert gState.code.len != 0, "Empty file or preprocessor error" - if gStateRT.mode == "c": + if gState.mode == "c": doAssert parser.tsParserSetLanguage(treeSitterC()), "Failed to load C parser" - elif gStateRT.mode == "cpp": + elif gState.mode == "cpp": doAssert parser.tsParserSetLanguage(treeSitterCpp()), "Failed to load C++ parser" else: - doAssert false, "Invalid parser " & gStateRT.mode + doAssert false, "Invalid parser " & gState.mode var - tree = parser.tsParserParseString(nil, gStateRT.code.cstring, gStateRT.code.len.uint32) + tree = parser.tsParserParseString(nil, gState.code.cstring, gState.code.len.uint32) root = tree.tsTreeRootNode() defer: tree.tsTreeDelete() - if gStateRT.past: - printLisp(root) - elif gStateRT.pnim: - printNim(path, root, astTable) - elif gStateRT.preprocess: - echo gStateRT.code + if gState.past: + gState.printLisp(root) + elif gState.pnim: + gState.printNim(path, root, astTable) + elif gState.preprocess: + echo gState.code proc main( mode = modeDefault, @@ -115,7 +113,7 @@ proc main( source: seq[string], ) = - gStateRT = State( + var gState = State( mode: mode, past: past, pnim: pnim, @@ -129,20 +127,20 @@ proc main( pluginSourcePath: pluginSourcePath ) - gStateRT.symOverride = gStateRT.symOverride.getSplitComma() + gState.symOverride = gState.symOverride.getSplitComma() if pluginSourcePath.nBl: - loadPlugin(pluginSourcePath) + gState.loadPlugin(pluginSourcePath) let astTable = parseGrammar() if pgrammar: astTable.printGrammar() elif source.len != 0: - if gStateRT.pnim: + if gState.pnim: printNimHeader() for src in source: - process(src, astTable) + gState.process(src, astTable) when isMainModule: import cligen From d9ab18c7757193f14fac69f3b462981b79defc93 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 8 May 2019 20:54:03 -0500 Subject: [PATCH 207/593] Exclude comments from output with flag --- nimterop.nimble | 9 +++------ nimterop/globals.nim | 4 ++-- nimterop/grammar.nim | 2 +- nimterop/toast.nim | 39 +++++++++++++++++++++------------------ 4 files changed, 27 insertions(+), 27 deletions(-) diff --git a/nimterop.nimble b/nimterop.nimble index c53e4dc..a9a99ee 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -27,12 +27,9 @@ proc execTest(test: string) = proc tsoloud() = execTest "tests/tsoloud.nim" -proc buildToast() = - execCmd(&"nim c -d:release nimterop/toast.nim") - -task rebuildToast, "rebuild toast": +task buildToast, "build toast": # If need to manually rebuild (automatically built on 1st need) - buildToast() + execCmd(&"nim c -d:release nimterop/toast.nim") proc testAll() = execTest "tests/tnimterop_c.nim" @@ -69,7 +66,7 @@ proc runNimDoc() = execCmd &"nim js -o:{htmldocsDir}/dochack.js {getNimRootDir()}/tools/dochack/dochack.nim" task test, "Test": - buildToast() + buildToastTask() testAll() runNimDoc() diff --git a/nimterop/globals.nim b/nimterop/globals.nim index 10b6ac3..1bef589 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -55,7 +55,7 @@ type State = ref object compile*, defines*, headers*, includeDirs*, searchDirs*, symOverride*: seq[string] - nocache*, debug*, past*, preprocess*, pnim*, pretty*, recurse*: bool + nocache*, nocomments*, debug*, past*, preprocess*, pnim*, pretty*, recurse*: bool code*, mode*, pluginSourcePath*: string @@ -64,7 +64,7 @@ type NimState {.used.} = ref object identifiers*: TableRef[string, string] - constStr*, debugStr*, enumStr*, procStr*, typeStr*, commentStr*: string + commentStr*, constStr*, debugStr*, enumStr*, procStr*, typeStr*: string gState*: State diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index f9bb2cb..3010966 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -24,7 +24,7 @@ proc genPragma(nimState: NimState, pragmas: varargs[string]): string = result = result.replace(nimState.impHeader & ", cdecl", nimState.impHeader & "C") proc getComments(nimState: NimState): string = - if nimState.commentStr.len != 0: + if not nimState.gState.nocomments and nimState.commentStr.len != 0: result = "\n" & nimState.commentStr nimState.commentStr = "" diff --git a/nimterop/toast.nim b/nimterop/toast.nim index bf34f41..eed39d8 100644 --- a/nimterop/toast.nim +++ b/nimterop/toast.nim @@ -98,33 +98,34 @@ proc process(gState: State, path: string, astTable: AstTable) = echo gState.code proc main( - mode = modeDefault, + preprocess = false, past = false, pnim = false, - pretty = true, - preprocess = false, - pgrammar = false, recurse = false, - debug = false, + nocomments = false, defines: seq[string] = @[], includeDirs: seq[string] = @[], symOverride: seq[string] = @[], pluginSourcePath: string = "", - source: seq[string], + debug = false, + mode = modeDefault, + pgrammar = false, + source: seq[string] ) = var gState = State( - mode: mode, + preprocess: preprocess, past: past, pnim: pnim, - pretty: pretty, - preprocess: preprocess, recurse: recurse, - debug: debug, + nocomments: nocomments, defines: defines, includeDirs: includeDirs, symOverride: symOverride, - pluginSourcePath: pluginSourcePath + pluginSourcePath: pluginSourcePath, + debug: debug, + mode: mode, + pretty: true ) gState.symOverride = gState.symOverride.getSplitComma() @@ -145,26 +146,28 @@ proc main( when isMainModule: import cligen dispatch(main, help = { + "preprocess": "run preprocessor on header", "past": "print AST output", - "mode": "language; see CompileMode", # TODO: auto-generate valid choices "pnim": "print Nim output", + "recurse": "process #include files", + "nocomments": "exclude top-level comments from output", "defines": "definitions to pass to preprocessor", "includeDirs": "include directory to pass to preprocessor", "symOverride": "skip generating specified symbols", "pluginSourcePath": "Nim file to build and load as a plugin", - "preprocess": "run preprocessor on header", - "pgrammar": "print grammar", - "recurse": "process #include files", "debug": "enable debug output", - "source" : "C/C++ source/header", + "mode": "language parser: c or cpp", + "pgrammar": "print grammar", + "source" : "C/C++ source/header" }, short = { + "preprocess": 'p', "past": 'a', "pnim": 'n', + "recurse": 'r', + "nocomments": 'c', "defines": 'D', "includeDirs": 'I', "symOverride": 'O', - "preprocess": 'p', - "recurse": 'r', "debug": 'd', "pgrammar": 'g' }) From 5898e4ee208666a382c150071df573e776142e2f Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 8 May 2019 21:07:18 -0500 Subject: [PATCH 208/593] Update documentation --- all.html | 962 ++++++++++++++++++++-------- cimport.html | 1089 +++++++++++++++++++++---------- cimport.idx | 14 +- compat.html | 995 ++++++++++++++++++++-------- dochack.js | 1708 +++++++++++++++++++++++++------------------------ git.html | 1018 ++++++++++++++++++++--------- git.idx | 1 + paths.html | 1008 ++++++++++++++++++++--------- paths.idx | 12 +- plugin.html | 964 ++++++++++++++++++++-------- theindex.html | 992 ++++++++++++++++++++-------- types.html | 980 ++++++++++++++++++++-------- types.idx | 2 +- 13 files changed, 6625 insertions(+), 3120 deletions(-) diff --git a/all.html b/all.html index afbc77b..5a030d1 100755 --- a/all.html +++ b/all.html @@ -27,113 +27,232 @@ customize this style sheet. Modified from Chad Skeeters' rst2html-style https://bitbucket.org/cskeeters/rst2html-style/ -Modified by Boyd Greenfield and narimiran +Modified by Boyd Greenfield */ - +/* SCSS variables */ +/* Text weights */ +/* Body colors */ +/* Text colors */ +/* Link colors */ +/* Syntax highlighting colors */ +/* Pct changes */ +/* Mixins */ +/* Body/layout */ html { font-size: 100%; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; } +/* Where we want fancier font if available */ +h1, h2, h3, h4, h5, h6, p.module-desc, table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; } + +h1.title { + font-weight: 900; } + body { font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: 400; - font-size: 1.125em; - line-height: 1.5; - color: #222; - background-color: #FCFCFC; } + font-size: 16px; + line-height: 20px; + color: #444; + letter-spacing: 0.15px; + background-color: #FDFBFA; } /* Skeleton grid */ .container { position: relative; width: 100%; - max-width: 1050px; + max-width: 960px; margin: 0 auto; - padding: 0; + padding: 0 20px; box-sizing: border-box; } .column, .columns { width: 100%; float: left; - box-sizing: border-box; - margin-left: 1%; -} + box-sizing: border-box; } -.column:first-child, -.columns:first-child { - margin-left: 0; } +/* For devices larger than 400px */ +@media (min-width: 400px) { + .container { + width: 100%; + padding: 0; } } +/* For devices larger than 650px */ +@media (min-width: 650px) { + .container { + width: 100%; } -.three.columns { - width: 19%; } + .column, + .columns { + margin-left: 4%; } -.nine.columns { - width: 80.0%; } + .column:first-child, + .columns:first-child { + margin-left: 0; } -.twelve.columns { - width: 100%; - margin-left: 0; } + .one.column, + .one.columns { + width: 4.66666666667%; } + + .two.columns { + width: 13.3333333333%; } -@media screen and (max-width: 860px) { .three.columns { - display: none; - } + width: 22%; } + + .four.columns { + width: 30.6666666667%; } + + .five.columns { + width: 39.3333333333%; } + + .six.columns { + width: 48%; } + + .seven.columns { + width: 56.6666666667%; } + + .eight.columns { + width: 65.3333333333%; } + .nine.columns { - width: 98.0%; - } - body { - font-size: 1em; - line-height: 1.35; - } -} + width: 74.0%; } + + .ten.columns { + width: 82.6666666667%; } + + .eleven.columns { + width: 91.3333333333%; } + + .twelve.columns { + width: 100%; + margin-left: 0; } + + .one-third.column { + width: 30.6666666667%; } + + .two-thirds.column { + width: 65.3333333333%; } } +/* Customer Overrides */ +.footer { + text-align: center; + color: #969696; + padding-top: 10%; } + +p.module-desc { + font-size: 1.1em; + color: #666666; } + +a.link-seesrc { + color: #aec7d2; + font-style: italic; } + +a.link-seesrc:hover { + color: #6c9aae; } + +#toc-list { + word-wrap: break-word; } + +ul.simple-toc { + list-style: none; } + +ul.simple-toc a.reference-toplevel { + font-weight: bold; + color: #0077b3; } + +ul.simple-toc-section { + list-style-type: circle; + color: #6c9aae; } + +ul.simple-toc-section a.reference { + color: #0077b3; } cite { font-style: italic !important; } +dt > pre { + border-color: rgba(0, 0, 0, 0.1); + background-color: rgba(255, 255, 255, 0.3); + margin: 15px 0px 5px; } + +dd > pre { + border-color: rgba(0, 0, 0, 0.1); + background-color: whitesmoke; + margin-top: 8px; } + +.item > dd { + margin-left: 10px; + margin-bottom: 30px; } + +/* Nim line-numbered tables */ +.line-nums-table { + width: 100%; + table-layout: fixed; } /* Nim search input */ div#searchInputDiv { - margin-bottom: 1em; + margin-bottom: 8px; } -input#searchInput { - width: 80%; +div#searchInputDiv input#searchInput { + width: 10em; +} +div.search-groupby { + margin-bottom: 8px; } +table.line-nums-table { + border-radius: 4px; + border: 1px solid #cccccc; + background-color: whitesmoke; + border-collapse: separate; + margin-top: 15px; + margin-bottom: 25px; } + +.line-nums-table tbody { + border: none; } + +.line-nums-table td pre { + border: none; + background-color: transparent; } + +.line-nums-table td.blob-line-nums { + width: 28px; } + +.line-nums-table td.blob-line-nums pre { + color: #b0b0b0; + -webkit-filter: opacity(75%); + text-align: right; + border-color: transparent; + background-color: transparent; + padding-left: 0px; + margin-left: 0px; + padding-right: 0px; + margin-right: 0px; } /* Docgen styles */ /* Links */ a { - color: #07b; - text-decoration: none; -} - -a span.Identifier { - text-decoration: underline; - text-decoration-color: #aab; -} - -a.reference-toplevel { - font-weight: bold; -} - -a.toc-backref { - text-decoration: none; - color: #222; } - -a.link-seesrc { - color: #607c9f; - font-size: 0.9em; - font-style: italic; } + color: #0077b3; + text-decoration: none; } a:hover, a:focus { - color: #607c9f; + color: #00334d; text-decoration: underline; } -a:hover span.Identifier { - color: #607c9f; -} +a:visited { + color: #00334d; } +a:focus { + outline: thin dotted #2d2d2d; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; } + +a:hover, +a:active { + outline: 0; } sub, sup { @@ -210,258 +329,379 @@ img { h2, h3 { - page-break-after: avoid; } -} + page-break-after: avoid; } } +.img-rounded { + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; } +.img-polaroid { + padding: 4px; + background-color: rgba(252, 248, 244, 0.75); + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.2); + -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); } p { - margin-top: 0.5em; - margin-bottom: 0.5em; -} + margin: 0 0 8px; } small { font-size: 85%; } strong { - font-weight: 600; - font-size: 0.95em; - color: #3c3c3c; -} + font-weight: 600; } em { font-style: italic; } +cite { + font-style: normal; } + +h1, +h2, +h3, +h4, +h5, +h6 { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-weight: 600; + line-height: 20px; + color: inherit; + text-rendering: optimizelegibility; } + h1 { - font-size: 1.8em; + font-size: 2em; font-weight: 400; - padding-bottom: .25em; - border-bottom: 1px solid #aaa; - margin-top: 2.5em; - margin-bottom: 1em; + padding-bottom: .15em; + border-bottom: 1px solid #aaaaaa; + margin-top: 1.0em; line-height: 1.2em; } h1.title { padding-bottom: 1em; border-bottom: 0px; - font-size: 2.5em; - text-align: center; - font-weight: 900; - margin-top: 0.75em; - margin-bottom: 0em; -} + font-size: 2.75em; } h2 { - font-size: 1.3em; - margin-top: 2em; } - -h2.subtitle { - text-align: center; } - -h3 { - font-size: 1.125em; - font-style: italic; + font-size: 1.5em; margin-top: 1.5em; } +h3 { + font-size: 1.3em; + font-style: italic; + margin-top: 0.75em; } + h4 { - font-size: 1.125em; - margin-top: 1em; } + font-size: 1.3em; + margin-top: 0.5em; } h5 { - font-size: 1.125em; - margin-top: 0.75em; } + font-size: 1.2em; + margin-top: 0.25em; } h6 { font-size: 1.1em; } - ul, ol { padding: 0; - margin-top: 0.5em; - margin-left: 0.75em; } + margin: 0 0 0px 15px; } ul ul, ul ol, ol ol, ol ul { - margin-bottom: 0; - margin-left: 1.25em; } + margin-bottom: 0; } li { - list-style-type: circle; -} - -ul.simple-boot li { - list-style-type: none; - margin-left: 0em; - margin-bottom: 0.5em; -} - -ol.simple > li, ul.simple > li { - margin-bottom: 0.25em; - margin-left: 0.4em } - -ul.simple.simple-toc > li { - margin-top: 1em; -} - -ul.simple-toc { - list-style: none; - font-size: 0.9em; - margin-left: -0.3em; - margin-top: 1em; } - -ul.simple-toc > li { - list-style-type: none; -} - -ul.simple-toc-section { - list-style-type: circle; - margin-left: 1em; - color: #6c9aae; } - - -ol.arabic { - list-style: decimal; } - -ol.loweralpha { - list-style: lower-alpha; } - -ol.upperalpha { - list-style: upper-alpha; } - -ol.lowerroman { - list-style: lower-roman; } - -ol.upperroman { - list-style: upper-roman; } - -ul.auto-toc { - list-style-type: none; } - + line-height: 20px; } dl { - margin-bottom: 1.5em; } + margin-bottom: 20px; } + +dt, +dd { + line-height: 20px; } dt { - margin-bottom: -0.5em; - margin-left: 0.0em; } + font-weight: bold; } dd { - margin-left: 2.0em; - margin-bottom: 3.0em; - margin-top: 0.5em; } - + margin-left: 10px; + margin-bottom: 26px; } hr { - margin: 2em 0; + margin: 20px 0; border: 0; - border-top: 1px solid #aaa; } + border-top: 1px solid #eeeeee; + border-bottom: 1px solid #ffffff; } + +abbr[title], +abbr[data-original-title] { + cursor: help; + border-bottom: 1px dotted #999999; } + +abbr.initialism { + font-size: 90%; + text-transform: uppercase; } blockquote { - font-size: 0.9em; - font-style: italic; - padding-left: 0.5em; - margin-left: 0; - border-left: 5px solid #bbc; + padding: 0 0 0 15px; + margin: 0 0 20px; + border-left: 5px solid #EFEBE0; } + +table.docinfo + blockquote, table.docinfo blockquote, h1 + blockquote { + border-left: 5px solid #c9c9c9; } +table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { + margin-bottom: 0; + font-size: 15px; + font-weight: 200; + line-height: 1.5; + font-style: italic; } + +q:before, +q:after, +blockquote:before, +blockquote:after { + content: ""; } + +address { + display: block; + margin-bottom: 20px; + font-style: normal; + line-height: 20px; } + +code, +pre { + font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; + padding: 0 3px 2px; + font-weight: 500; + font-size: 12px; + color: #444444; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; } + .pre { font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - font-weight: 500; - font-size: 0.85em; - background-color: #f0f3ff; - padding-left: 3px; - padding-right: 3px; - border-radius: 4px; + font-weight: 600; + /*color: #504da6;*/ } +code { + padding: 2px 4px; + color: #444444; + white-space: nowrap; + background-color: white; + border: 1px solid #777777; } + pre { - font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - color: #222; - font-weight: 500; display: inline-block; box-sizing: border-box; - min-width: 100%; - padding: 0.5em; - margin-top: 0.5em; - margin-bottom: 0.5em; - font-size: 0.85em; + min-width: calc(100% - 19.5px); + padding: 9.5px; + margin: 0.25em 10px 10px 10px; + font-size: 15px; + line-height: 20px; white-space: pre !important; overflow-y: hidden; overflow-x: visible; - background-color: ghostwhite; - border: 1px solid #dde; - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; } + background-color: rgba(0, 0, 0, 0.01); + border: 1px solid #cccccc; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; } + +pre.prettyprint { + margin-bottom: 20px; } + +pre code { + padding: 0; + color: inherit; + white-space: pre; + overflow-x: visible; + background-color: transparent; + border: 0; } .pre-scrollable { max-height: 340px; overflow-y: scroll; } - -/* Nim line-numbered tables */ -.line-nums-table { - width: 100%; - table-layout: fixed; } - -table.line-nums-table { - border-radius: 4px; - border: 1px solid #cccccc; - background-color: ghostwhite; - border-collapse: separate; - margin-top: 15px; - margin-bottom: 25px; } - -.line-nums-table tbody { - border: none; } - -.line-nums-table td pre { - border: none; - background-color: transparent; } - -.line-nums-table td.blob-line-nums { - width: 28px; } - -.line-nums-table td.blob-line-nums pre { - color: #b0b0b0; - -webkit-filter: opacity(75%); - text-align: right; - border-color: transparent; - background-color: transparent; - padding-left: 0px; - margin-left: 0px; - padding-right: 0px; - margin-right: 0px; } - - table { max-width: 100%; background-color: transparent; - margin-top: 0.5em; - margin-bottom: 1.5em; border-collapse: collapse; - border-color: #ccc; - border-spacing: 0; - font-size: 0.9em; -} + border-spacing: 0; } table th, table td { - padding: 0px 0.5em 0px; + padding: 0px 8px 0px; } -table th { - background-color: #e8e8e8; +.table { + width: 100%; + margin-bottom: 20px; } + +.table th, +.table td { + padding: 8px; + line-height: 20px; + text-align: left; + vertical-align: top; + border-top: 1px solid #444444; } + +.table th { font-weight: bold; } -table th.docinfo-name { - background-color: transparent; -} +.table thead th { + vertical-align: bottom; } -table tr:hover { - background-color: ghostwhite; } +.table caption + thead tr:first-child th, +.table caption + thead tr:first-child td, +.table colgroup + thead tr:first-child th, +.table colgroup + thead tr:first-child td, +.table thead:first-child tr:first-child th, +.table thead:first-child tr:first-child td { + border-top: 0; } +.table tbody + tbody { + border-top: 2px solid #444444; } + +.table .table { + background-color: rgba(252, 248, 244, 0.75); } + +.table-condensed th, +.table-condensed td { + padding: 4px 5px; } + +.table-bordered { + border: 1px solid #444444; + border-collapse: separate; + *border-collapse: collapse; + border-left: 0; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; } + +.table-bordered th, +.table-bordered td { + border-left: 1px solid #444444; } + +.table-bordered caption + thead tr:first-child th, +.table-bordered caption + tbody tr:first-child th, +.table-bordered caption + tbody tr:first-child td, +.table-bordered colgroup + thead tr:first-child th, +.table-bordered colgroup + tbody tr:first-child th, +.table-bordered colgroup + tbody tr:first-child td, +.table-bordered thead:first-child tr:first-child th, +.table-bordered tbody:first-child tr:first-child th, +.table-bordered tbody:first-child tr:first-child td { + border-top: 0; } + +.table-bordered thead:first-child tr:first-child > th:first-child, +.table-bordered tbody:first-child tr:first-child > td:first-child, +.table-bordered tbody:first-child tr:first-child > th:first-child { + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; } + +.table-bordered thead:first-child tr:first-child > th:last-child, +.table-bordered tbody:first-child tr:first-child > td:last-child, +.table-bordered tbody:first-child tr:first-child > th:last-child { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; } + +.table-bordered thead:last-child tr:last-child > th:first-child, +.table-bordered tbody:last-child tr:last-child > td:first-child, +.table-bordered tbody:last-child tr:last-child > th:first-child, +.table-bordered tfoot:last-child tr:last-child > td:first-child, +.table-bordered tfoot:last-child tr:last-child > th:first-child { + -webkit-border-bottom-left-radius: 4px; + border-bottom-left-radius: 4px; + -moz-border-radius-bottomleft: 4px; } + +.table-bordered thead:last-child tr:last-child > th:last-child, +.table-bordered tbody:last-child tr:last-child > td:last-child, +.table-bordered tbody:last-child tr:last-child > th:last-child, +.table-bordered tfoot:last-child tr:last-child > td:last-child, +.table-bordered tfoot:last-child tr:last-child > th:last-child { + -webkit-border-bottom-right-radius: 4px; + border-bottom-right-radius: 4px; + -moz-border-radius-bottomright: 4px; } + +.table-bordered tfoot + tbody:last-child tr:last-child td:first-child { + -webkit-border-bottom-left-radius: 0; + border-bottom-left-radius: 0; + -moz-border-radius-bottomleft: 0; } + +.table-bordered tfoot + tbody:last-child tr:last-child td:last-child { + -webkit-border-bottom-right-radius: 0; + border-bottom-right-radius: 0; + -moz-border-radius-bottomright: 0; } + +.table-bordered caption + thead tr:first-child th:first-child, +.table-bordered caption + tbody tr:first-child td:first-child, +.table-bordered colgroup + thead tr:first-child th:first-child, +.table-bordered colgroup + tbody tr:first-child td:first-child { + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; } + +.table-bordered caption + thead tr:first-child th:last-child, +.table-bordered caption + tbody tr:first-child td:last-child, +.table-bordered colgroup + thead tr:first-child th:last-child, +.table-bordered colgroup + tbody tr:first-child td:last-child { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; } + +table.docutils th { + background-color: #e8e8e8; } + +table.docutils tr:hover { + background-color: whitesmoke; } + +.table-striped tbody > tr:nth-child(odd) > td, +.table-striped tbody > tr:nth-child(odd) > th { + background-color: rgba(252, 248, 244, 0.75); } + +.table-hover tbody tr:hover > td, +.table-hover tbody tr:hover > th { + background-color: rgba(241, 222, 204, 0.75); } + +table td[class*="span"], +table th[class*="span"], +.row-fluid table td[class*="span"], +.row-fluid table th[class*="span"] { + display: table-cell; + float: none; + margin-left: 0; } + +.hero-unit { + padding: 60px; + margin-bottom: 30px; + font-size: 18px; + font-weight: 200; + line-height: 30px; + color: inherit; + background-color: rgba(230, 197, 164, 0.75); + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; } + +.hero-unit h1 { + margin-bottom: 0; + font-size: 60px; + line-height: 1; + letter-spacing: -1px; + color: inherit; } + +.hero-unit li { + line-height: 30px; } /* rst2html default used to remove borders from tables and images */ .borderless, table.borderless td, table.borderless th { @@ -482,6 +722,10 @@ table.borderless td, table.borderless th { .hidden { display: none; } +a.toc-backref { + text-decoration: none; + color: #444444; } + blockquote.epigraph { margin: 2em 5em; } @@ -491,6 +735,85 @@ dl.docutils dd { object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] { overflow: hidden; } +/* Uncomment (and remove this text!) to get bold-faced definition list terms +dl.docutils dt { + font-weight: bold } +*/ +div.abstract { + margin: 2em 5em; } + +div.abstract p.topic-title { + font-weight: bold; + text-align: center; } + +div.admonition, div.attention, div.caution, div.danger, div.error, +div.hint, div.important, div.note, div.tip, div.warning { + margin: 2em; + border: medium outset; + padding: 1em; } + +div.note, div.warning { + margin: 1.5em 0px; + border: none; } + +div.note p.admonition-title, +div.warning p.admonition-title { + display: none; } + +/* Clearfix + * http://css-tricks.com/snippets/css/clear-fix/ + */ +div.note:after, +div.warning:after { + content: ""; + display: table; + clear: both; } + +div.note p:before, +div.warning p:before { + display: block; + float: left; + font-size: 4em; + line-height: 1em; + margin-right: 20px; + margin-left: 0em; + margin-top: -10px; + content: '\0270D'; + /*handwriting*/ } + +div.warning p:before { + content: '\026A0'; + /*warning*/ } + +div.admonition p.admonition-title, div.hint p.admonition-title, +div.important p.admonition-title, div.note p.admonition-title, +div.tip p.admonition-title { + font-weight: bold; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } + +div.attention p.admonition-title, div.caution p.admonition-title, +div.danger p.admonition-title, div.error p.admonition-title, +div.warning p.admonition-title, .code .error { + color: #b30000; + font-weight: bold; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } + +/* Uncomment (and remove this text!) to get reduced vertical space in + compound paragraphs. +div.compound .compound-first, div.compound .compound-middle { + margin-bottom: 0.5em } + +div.compound .compound-last, div.compound .compound-middle { + margin-top: 0.5em } +*/ +div.dedication { + margin: 2em 5em; + text-align: center; + font-style: italic; } + +div.dedication p.topic-title { + font-weight: bold; + font-style: normal; } div.figure { margin-left: 2em; @@ -498,14 +821,8 @@ div.figure { div.footer, div.header { clear: both; - text-align: center; - color: #666; font-size: smaller; } -div.footer { - padding-top: 5em; -} - div.line-block { display: block; margin-top: 1em; @@ -516,24 +833,45 @@ div.line-block div.line-block { margin-bottom: 0; margin-left: 1.5em; } +div.sidebar { + margin: 0 0 0.5em 1em; + border: medium outset; + padding: 1em; + background-color: rgba(252, 248, 244, 0.75); + width: 40%; + float: right; + clear: right; } + +div.sidebar p.rubric { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-size: medium; } + +div.system-messages { + margin: 5em; } + +div.system-messages h1 { + color: #b30000; } + +div.system-message { + border: medium outset; + padding: 1em; } + +div.system-message p.system-message-title { + color: #b30000; + font-weight: bold; } + div.topic { margin: 2em; } -div.search_results { - background-color: antiquewhite; - margin: 3em; - padding: 1em; - border: 1px solid #4d4d4d; -} +h1.section-subtitle, h2.section-subtitle, h3.section-subtitle, +h4.section-subtitle, h5.section-subtitle, h6.section-subtitle { + margin-top: 0.4em; } -div#global-links ul { - margin-left: 0; - list-style-type: none; -} +h1.title { + text-align: center; } -div#global-links > simple-boot { - margin-left: 3em; -} +h2.subtitle { + text-align: center; } hr.docutils { width: 75%; } @@ -567,6 +905,30 @@ img.align-center, .figure.align-center, object.align-center { div.align-right { text-align: inherit; } +/* div.align-center * { */ +/* text-align: left } */ + +ul.simple > li { + margin-bottom: 0.5em } + +ol.simple, ul.simple { + margin-bottom: 1em; } + +ol.arabic { + list-style: decimal; } + +ol.loweralpha { + list-style: lower-alpha; } + +ol.upperalpha { + list-style: upper-alpha; } + +ol.lowerroman { + list-style: lower-roman; } + +ol.upperroman { + list-style: upper-roman; } + p.attribution { text-align: right; margin-left: 50%; } @@ -587,6 +949,15 @@ p.rubric { color: maroon; text-align: center; } +p.sidebar-title { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-weight: bold; + font-size: larger; } + +p.sidebar-subtitle { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-weight: bold; } + p.topic-title { font-weight: bold; } @@ -626,14 +997,22 @@ pre.code .inserted, code .inserted { background-color: #A3D289; } span.classifier { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-style: oblique; } span.classifier-delimiter { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: bold; } +span.interpreted { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } + span.option { white-space: nowrap; } +span.pre { + white-space: pre; } + span.problematic { color: #b30000; } @@ -641,6 +1020,44 @@ span.section-subtitle { /* font-size relative to parent (h1..h6 element) */ font-size: 80%; } +table.citation { + border-left: solid 1px #666666; + margin-left: 1px; } + +table.docinfo { + margin: 0em; + margin-top: 2em; + margin-bottom: 2em; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; + color: #444444; } + +table.docutils { + margin-top: 0.5em; + margin-bottom: 0.5em; } + +table.footnote { + border-left: solid 1px #2d2d2d; + margin-left: 1px; } + +table.docutils td, table.docutils th, +table.docinfo td, table.docinfo th { + padding-left: 0.5em; + padding-right: 0.5em; + vertical-align: top; } + +table.docutils th.field-name, table.docinfo th.docinfo-name { + font-weight: 700; + text-align: left; + white-space: nowrap; + padding-left: 0; } + +h1 tt.docutils, h2 tt.docutils, h3 tt.docutils, +h4 tt.docutils, h5 tt.docutils, h6 tt.docutils { + font-size: 100%; } + +ul.auto-toc { + list-style-type: none; } + span.DecNumber { color: #252dbe; } @@ -657,7 +1074,7 @@ span.FloatNumber { color: #252dbe; } span.Identifier { - color: #222; } + color: #3b3b3b; } span.Keyword { font-weight: 600; @@ -722,23 +1139,38 @@ dt pre > span.Identifier, dt pre > span.Operator { color: #155da4; font-weight: 700; } -dt pre > span.Keyword ~ span.Identifier, dt pre > span.Identifier ~ span.Identifier, -dt pre > span.Operator ~ span.Identifier, dt pre > span.Other ~ span.Identifier { +dt pre > span.Identifier ~ span.Identifier, dt pre > span.Operator ~ span.Identifier { + color: inherit; + font-weight: inherit; } + +dt pre > span.Operator ~ span.Identifier { color: inherit; font-weight: inherit; } /* Nim sprite for the footer (taken from main page favicon) */ .nim-sprite { display: inline-block; - height: 16px; - width: 16px; + height: 12px; + width: 12px; background-position: 0 0; - background-size: 16px 16px; + background-size: 12px 12px; -webkit-filter: opacity(50%); background-repeat: no-repeat; background-image: url("data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="); margin-bottom: -5px; } +div.search_results { + background-color: antiquewhite; + margin: 3em; + padding: 1em; + border: 1px solid #4d4d4d; +} + +div#global-links ul { + margin-left: 0; + list-style-type: none; +} + span.pragmadots { /* Position: relative frees us up to make the dots look really nice without fucking up the layout and @@ -746,14 +1178,18 @@ span.pragmadots { position: relative; /* 1px down looks slightly nicer */ top: 1px; + padding: 2px; - background-color: #e8e8e8; + background-color: #D3D3D3; border-radius: 4px; margin: 0 2px; cursor: pointer; - font-size: 0.8em; -} + /* For some reason on Chrome, making the font size + smaller than 1em is causing the parent container to + bulge slightly. So, we're stuck with inheriting 1em, + which is sad, because 0.8em looks better... */ +} span.pragmadots:hover { background-color: #DBDBDB; } @@ -761,10 +1197,6 @@ span.pragmawrap { display: none; } -span.attachedType { - display: none; - visibility: hidden; -} @@ -818,7 +1250,7 @@ function main() {
    -

    Module that should import everything so that nim doc --project nimtero/all runs docs on everything.

    +

    Module that should import everything so that nim doc --project nimtero/all runs docs on everything.

    Imports

    @@ -832,7 +1264,7 @@ function main() {
    diff --git a/cimport.html b/cimport.html index 5709786..6d150b9 100755 --- a/cimport.html +++ b/cimport.html @@ -27,113 +27,232 @@ customize this style sheet. Modified from Chad Skeeters' rst2html-style https://bitbucket.org/cskeeters/rst2html-style/ -Modified by Boyd Greenfield and narimiran +Modified by Boyd Greenfield */ - +/* SCSS variables */ +/* Text weights */ +/* Body colors */ +/* Text colors */ +/* Link colors */ +/* Syntax highlighting colors */ +/* Pct changes */ +/* Mixins */ +/* Body/layout */ html { font-size: 100%; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; } +/* Where we want fancier font if available */ +h1, h2, h3, h4, h5, h6, p.module-desc, table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; } + +h1.title { + font-weight: 900; } + body { font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: 400; - font-size: 1.125em; - line-height: 1.5; - color: #222; - background-color: #FCFCFC; } + font-size: 16px; + line-height: 20px; + color: #444; + letter-spacing: 0.15px; + background-color: #FDFBFA; } /* Skeleton grid */ .container { position: relative; width: 100%; - max-width: 1050px; + max-width: 960px; margin: 0 auto; - padding: 0; + padding: 0 20px; box-sizing: border-box; } .column, .columns { width: 100%; float: left; - box-sizing: border-box; - margin-left: 1%; -} + box-sizing: border-box; } -.column:first-child, -.columns:first-child { - margin-left: 0; } +/* For devices larger than 400px */ +@media (min-width: 400px) { + .container { + width: 100%; + padding: 0; } } +/* For devices larger than 650px */ +@media (min-width: 650px) { + .container { + width: 100%; } -.three.columns { - width: 19%; } + .column, + .columns { + margin-left: 4%; } -.nine.columns { - width: 80.0%; } + .column:first-child, + .columns:first-child { + margin-left: 0; } -.twelve.columns { - width: 100%; - margin-left: 0; } + .one.column, + .one.columns { + width: 4.66666666667%; } + + .two.columns { + width: 13.3333333333%; } -@media screen and (max-width: 860px) { .three.columns { - display: none; - } + width: 22%; } + + .four.columns { + width: 30.6666666667%; } + + .five.columns { + width: 39.3333333333%; } + + .six.columns { + width: 48%; } + + .seven.columns { + width: 56.6666666667%; } + + .eight.columns { + width: 65.3333333333%; } + .nine.columns { - width: 98.0%; - } - body { - font-size: 1em; - line-height: 1.35; - } -} + width: 74.0%; } + + .ten.columns { + width: 82.6666666667%; } + + .eleven.columns { + width: 91.3333333333%; } + + .twelve.columns { + width: 100%; + margin-left: 0; } + + .one-third.column { + width: 30.6666666667%; } + + .two-thirds.column { + width: 65.3333333333%; } } +/* Customer Overrides */ +.footer { + text-align: center; + color: #969696; + padding-top: 10%; } + +p.module-desc { + font-size: 1.1em; + color: #666666; } + +a.link-seesrc { + color: #aec7d2; + font-style: italic; } + +a.link-seesrc:hover { + color: #6c9aae; } + +#toc-list { + word-wrap: break-word; } + +ul.simple-toc { + list-style: none; } + +ul.simple-toc a.reference-toplevel { + font-weight: bold; + color: #0077b3; } + +ul.simple-toc-section { + list-style-type: circle; + color: #6c9aae; } + +ul.simple-toc-section a.reference { + color: #0077b3; } cite { font-style: italic !important; } +dt > pre { + border-color: rgba(0, 0, 0, 0.1); + background-color: rgba(255, 255, 255, 0.3); + margin: 15px 0px 5px; } + +dd > pre { + border-color: rgba(0, 0, 0, 0.1); + background-color: whitesmoke; + margin-top: 8px; } + +.item > dd { + margin-left: 10px; + margin-bottom: 30px; } + +/* Nim line-numbered tables */ +.line-nums-table { + width: 100%; + table-layout: fixed; } /* Nim search input */ div#searchInputDiv { - margin-bottom: 1em; + margin-bottom: 8px; } -input#searchInput { - width: 80%; +div#searchInputDiv input#searchInput { + width: 10em; +} +div.search-groupby { + margin-bottom: 8px; } +table.line-nums-table { + border-radius: 4px; + border: 1px solid #cccccc; + background-color: whitesmoke; + border-collapse: separate; + margin-top: 15px; + margin-bottom: 25px; } + +.line-nums-table tbody { + border: none; } + +.line-nums-table td pre { + border: none; + background-color: transparent; } + +.line-nums-table td.blob-line-nums { + width: 28px; } + +.line-nums-table td.blob-line-nums pre { + color: #b0b0b0; + -webkit-filter: opacity(75%); + text-align: right; + border-color: transparent; + background-color: transparent; + padding-left: 0px; + margin-left: 0px; + padding-right: 0px; + margin-right: 0px; } /* Docgen styles */ /* Links */ a { - color: #07b; - text-decoration: none; -} - -a span.Identifier { - text-decoration: underline; - text-decoration-color: #aab; -} - -a.reference-toplevel { - font-weight: bold; -} - -a.toc-backref { - text-decoration: none; - color: #222; } - -a.link-seesrc { - color: #607c9f; - font-size: 0.9em; - font-style: italic; } + color: #0077b3; + text-decoration: none; } a:hover, a:focus { - color: #607c9f; + color: #00334d; text-decoration: underline; } -a:hover span.Identifier { - color: #607c9f; -} +a:visited { + color: #00334d; } +a:focus { + outline: thin dotted #2d2d2d; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; } + +a:hover, +a:active { + outline: 0; } sub, sup { @@ -210,258 +329,379 @@ img { h2, h3 { - page-break-after: avoid; } -} + page-break-after: avoid; } } +.img-rounded { + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; } +.img-polaroid { + padding: 4px; + background-color: rgba(252, 248, 244, 0.75); + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.2); + -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); } p { - margin-top: 0.5em; - margin-bottom: 0.5em; -} + margin: 0 0 8px; } small { font-size: 85%; } strong { - font-weight: 600; - font-size: 0.95em; - color: #3c3c3c; -} + font-weight: 600; } em { font-style: italic; } +cite { + font-style: normal; } + +h1, +h2, +h3, +h4, +h5, +h6 { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-weight: 600; + line-height: 20px; + color: inherit; + text-rendering: optimizelegibility; } + h1 { - font-size: 1.8em; + font-size: 2em; font-weight: 400; - padding-bottom: .25em; - border-bottom: 1px solid #aaa; - margin-top: 2.5em; - margin-bottom: 1em; + padding-bottom: .15em; + border-bottom: 1px solid #aaaaaa; + margin-top: 1.0em; line-height: 1.2em; } h1.title { padding-bottom: 1em; border-bottom: 0px; - font-size: 2.5em; - text-align: center; - font-weight: 900; - margin-top: 0.75em; - margin-bottom: 0em; -} + font-size: 2.75em; } h2 { - font-size: 1.3em; - margin-top: 2em; } - -h2.subtitle { - text-align: center; } - -h3 { - font-size: 1.125em; - font-style: italic; + font-size: 1.5em; margin-top: 1.5em; } +h3 { + font-size: 1.3em; + font-style: italic; + margin-top: 0.75em; } + h4 { - font-size: 1.125em; - margin-top: 1em; } + font-size: 1.3em; + margin-top: 0.5em; } h5 { - font-size: 1.125em; - margin-top: 0.75em; } + font-size: 1.2em; + margin-top: 0.25em; } h6 { font-size: 1.1em; } - ul, ol { padding: 0; - margin-top: 0.5em; - margin-left: 0.75em; } + margin: 0 0 0px 15px; } ul ul, ul ol, ol ol, ol ul { - margin-bottom: 0; - margin-left: 1.25em; } + margin-bottom: 0; } li { - list-style-type: circle; -} - -ul.simple-boot li { - list-style-type: none; - margin-left: 0em; - margin-bottom: 0.5em; -} - -ol.simple > li, ul.simple > li { - margin-bottom: 0.25em; - margin-left: 0.4em } - -ul.simple.simple-toc > li { - margin-top: 1em; -} - -ul.simple-toc { - list-style: none; - font-size: 0.9em; - margin-left: -0.3em; - margin-top: 1em; } - -ul.simple-toc > li { - list-style-type: none; -} - -ul.simple-toc-section { - list-style-type: circle; - margin-left: 1em; - color: #6c9aae; } - - -ol.arabic { - list-style: decimal; } - -ol.loweralpha { - list-style: lower-alpha; } - -ol.upperalpha { - list-style: upper-alpha; } - -ol.lowerroman { - list-style: lower-roman; } - -ol.upperroman { - list-style: upper-roman; } - -ul.auto-toc { - list-style-type: none; } - + line-height: 20px; } dl { - margin-bottom: 1.5em; } + margin-bottom: 20px; } + +dt, +dd { + line-height: 20px; } dt { - margin-bottom: -0.5em; - margin-left: 0.0em; } + font-weight: bold; } dd { - margin-left: 2.0em; - margin-bottom: 3.0em; - margin-top: 0.5em; } - + margin-left: 10px; + margin-bottom: 26px; } hr { - margin: 2em 0; + margin: 20px 0; border: 0; - border-top: 1px solid #aaa; } + border-top: 1px solid #eeeeee; + border-bottom: 1px solid #ffffff; } + +abbr[title], +abbr[data-original-title] { + cursor: help; + border-bottom: 1px dotted #999999; } + +abbr.initialism { + font-size: 90%; + text-transform: uppercase; } blockquote { - font-size: 0.9em; - font-style: italic; - padding-left: 0.5em; - margin-left: 0; - border-left: 5px solid #bbc; + padding: 0 0 0 15px; + margin: 0 0 20px; + border-left: 5px solid #EFEBE0; } + +table.docinfo + blockquote, table.docinfo blockquote, h1 + blockquote { + border-left: 5px solid #c9c9c9; } +table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { + margin-bottom: 0; + font-size: 15px; + font-weight: 200; + line-height: 1.5; + font-style: italic; } + +q:before, +q:after, +blockquote:before, +blockquote:after { + content: ""; } + +address { + display: block; + margin-bottom: 20px; + font-style: normal; + line-height: 20px; } + +code, +pre { + font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; + padding: 0 3px 2px; + font-weight: 500; + font-size: 12px; + color: #444444; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; } + .pre { font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - font-weight: 500; - font-size: 0.85em; - background-color: #f0f3ff; - padding-left: 3px; - padding-right: 3px; - border-radius: 4px; + font-weight: 600; + /*color: #504da6;*/ } +code { + padding: 2px 4px; + color: #444444; + white-space: nowrap; + background-color: white; + border: 1px solid #777777; } + pre { - font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - color: #222; - font-weight: 500; display: inline-block; box-sizing: border-box; - min-width: 100%; - padding: 0.5em; - margin-top: 0.5em; - margin-bottom: 0.5em; - font-size: 0.85em; + min-width: calc(100% - 19.5px); + padding: 9.5px; + margin: 0.25em 10px 10px 10px; + font-size: 15px; + line-height: 20px; white-space: pre !important; overflow-y: hidden; overflow-x: visible; - background-color: ghostwhite; - border: 1px solid #dde; - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; } + background-color: rgba(0, 0, 0, 0.01); + border: 1px solid #cccccc; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; } + +pre.prettyprint { + margin-bottom: 20px; } + +pre code { + padding: 0; + color: inherit; + white-space: pre; + overflow-x: visible; + background-color: transparent; + border: 0; } .pre-scrollable { max-height: 340px; overflow-y: scroll; } - -/* Nim line-numbered tables */ -.line-nums-table { - width: 100%; - table-layout: fixed; } - -table.line-nums-table { - border-radius: 4px; - border: 1px solid #cccccc; - background-color: ghostwhite; - border-collapse: separate; - margin-top: 15px; - margin-bottom: 25px; } - -.line-nums-table tbody { - border: none; } - -.line-nums-table td pre { - border: none; - background-color: transparent; } - -.line-nums-table td.blob-line-nums { - width: 28px; } - -.line-nums-table td.blob-line-nums pre { - color: #b0b0b0; - -webkit-filter: opacity(75%); - text-align: right; - border-color: transparent; - background-color: transparent; - padding-left: 0px; - margin-left: 0px; - padding-right: 0px; - margin-right: 0px; } - - table { max-width: 100%; background-color: transparent; - margin-top: 0.5em; - margin-bottom: 1.5em; border-collapse: collapse; - border-color: #ccc; - border-spacing: 0; - font-size: 0.9em; -} + border-spacing: 0; } table th, table td { - padding: 0px 0.5em 0px; + padding: 0px 8px 0px; } -table th { - background-color: #e8e8e8; +.table { + width: 100%; + margin-bottom: 20px; } + +.table th, +.table td { + padding: 8px; + line-height: 20px; + text-align: left; + vertical-align: top; + border-top: 1px solid #444444; } + +.table th { font-weight: bold; } -table th.docinfo-name { - background-color: transparent; -} +.table thead th { + vertical-align: bottom; } -table tr:hover { - background-color: ghostwhite; } +.table caption + thead tr:first-child th, +.table caption + thead tr:first-child td, +.table colgroup + thead tr:first-child th, +.table colgroup + thead tr:first-child td, +.table thead:first-child tr:first-child th, +.table thead:first-child tr:first-child td { + border-top: 0; } +.table tbody + tbody { + border-top: 2px solid #444444; } + +.table .table { + background-color: rgba(252, 248, 244, 0.75); } + +.table-condensed th, +.table-condensed td { + padding: 4px 5px; } + +.table-bordered { + border: 1px solid #444444; + border-collapse: separate; + *border-collapse: collapse; + border-left: 0; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; } + +.table-bordered th, +.table-bordered td { + border-left: 1px solid #444444; } + +.table-bordered caption + thead tr:first-child th, +.table-bordered caption + tbody tr:first-child th, +.table-bordered caption + tbody tr:first-child td, +.table-bordered colgroup + thead tr:first-child th, +.table-bordered colgroup + tbody tr:first-child th, +.table-bordered colgroup + tbody tr:first-child td, +.table-bordered thead:first-child tr:first-child th, +.table-bordered tbody:first-child tr:first-child th, +.table-bordered tbody:first-child tr:first-child td { + border-top: 0; } + +.table-bordered thead:first-child tr:first-child > th:first-child, +.table-bordered tbody:first-child tr:first-child > td:first-child, +.table-bordered tbody:first-child tr:first-child > th:first-child { + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; } + +.table-bordered thead:first-child tr:first-child > th:last-child, +.table-bordered tbody:first-child tr:first-child > td:last-child, +.table-bordered tbody:first-child tr:first-child > th:last-child { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; } + +.table-bordered thead:last-child tr:last-child > th:first-child, +.table-bordered tbody:last-child tr:last-child > td:first-child, +.table-bordered tbody:last-child tr:last-child > th:first-child, +.table-bordered tfoot:last-child tr:last-child > td:first-child, +.table-bordered tfoot:last-child tr:last-child > th:first-child { + -webkit-border-bottom-left-radius: 4px; + border-bottom-left-radius: 4px; + -moz-border-radius-bottomleft: 4px; } + +.table-bordered thead:last-child tr:last-child > th:last-child, +.table-bordered tbody:last-child tr:last-child > td:last-child, +.table-bordered tbody:last-child tr:last-child > th:last-child, +.table-bordered tfoot:last-child tr:last-child > td:last-child, +.table-bordered tfoot:last-child tr:last-child > th:last-child { + -webkit-border-bottom-right-radius: 4px; + border-bottom-right-radius: 4px; + -moz-border-radius-bottomright: 4px; } + +.table-bordered tfoot + tbody:last-child tr:last-child td:first-child { + -webkit-border-bottom-left-radius: 0; + border-bottom-left-radius: 0; + -moz-border-radius-bottomleft: 0; } + +.table-bordered tfoot + tbody:last-child tr:last-child td:last-child { + -webkit-border-bottom-right-radius: 0; + border-bottom-right-radius: 0; + -moz-border-radius-bottomright: 0; } + +.table-bordered caption + thead tr:first-child th:first-child, +.table-bordered caption + tbody tr:first-child td:first-child, +.table-bordered colgroup + thead tr:first-child th:first-child, +.table-bordered colgroup + tbody tr:first-child td:first-child { + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; } + +.table-bordered caption + thead tr:first-child th:last-child, +.table-bordered caption + tbody tr:first-child td:last-child, +.table-bordered colgroup + thead tr:first-child th:last-child, +.table-bordered colgroup + tbody tr:first-child td:last-child { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; } + +table.docutils th { + background-color: #e8e8e8; } + +table.docutils tr:hover { + background-color: whitesmoke; } + +.table-striped tbody > tr:nth-child(odd) > td, +.table-striped tbody > tr:nth-child(odd) > th { + background-color: rgba(252, 248, 244, 0.75); } + +.table-hover tbody tr:hover > td, +.table-hover tbody tr:hover > th { + background-color: rgba(241, 222, 204, 0.75); } + +table td[class*="span"], +table th[class*="span"], +.row-fluid table td[class*="span"], +.row-fluid table th[class*="span"] { + display: table-cell; + float: none; + margin-left: 0; } + +.hero-unit { + padding: 60px; + margin-bottom: 30px; + font-size: 18px; + font-weight: 200; + line-height: 30px; + color: inherit; + background-color: rgba(230, 197, 164, 0.75); + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; } + +.hero-unit h1 { + margin-bottom: 0; + font-size: 60px; + line-height: 1; + letter-spacing: -1px; + color: inherit; } + +.hero-unit li { + line-height: 30px; } /* rst2html default used to remove borders from tables and images */ .borderless, table.borderless td, table.borderless th { @@ -482,6 +722,10 @@ table.borderless td, table.borderless th { .hidden { display: none; } +a.toc-backref { + text-decoration: none; + color: #444444; } + blockquote.epigraph { margin: 2em 5em; } @@ -491,6 +735,85 @@ dl.docutils dd { object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] { overflow: hidden; } +/* Uncomment (and remove this text!) to get bold-faced definition list terms +dl.docutils dt { + font-weight: bold } +*/ +div.abstract { + margin: 2em 5em; } + +div.abstract p.topic-title { + font-weight: bold; + text-align: center; } + +div.admonition, div.attention, div.caution, div.danger, div.error, +div.hint, div.important, div.note, div.tip, div.warning { + margin: 2em; + border: medium outset; + padding: 1em; } + +div.note, div.warning { + margin: 1.5em 0px; + border: none; } + +div.note p.admonition-title, +div.warning p.admonition-title { + display: none; } + +/* Clearfix + * http://css-tricks.com/snippets/css/clear-fix/ + */ +div.note:after, +div.warning:after { + content: ""; + display: table; + clear: both; } + +div.note p:before, +div.warning p:before { + display: block; + float: left; + font-size: 4em; + line-height: 1em; + margin-right: 20px; + margin-left: 0em; + margin-top: -10px; + content: '\0270D'; + /*handwriting*/ } + +div.warning p:before { + content: '\026A0'; + /*warning*/ } + +div.admonition p.admonition-title, div.hint p.admonition-title, +div.important p.admonition-title, div.note p.admonition-title, +div.tip p.admonition-title { + font-weight: bold; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } + +div.attention p.admonition-title, div.caution p.admonition-title, +div.danger p.admonition-title, div.error p.admonition-title, +div.warning p.admonition-title, .code .error { + color: #b30000; + font-weight: bold; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } + +/* Uncomment (and remove this text!) to get reduced vertical space in + compound paragraphs. +div.compound .compound-first, div.compound .compound-middle { + margin-bottom: 0.5em } + +div.compound .compound-last, div.compound .compound-middle { + margin-top: 0.5em } +*/ +div.dedication { + margin: 2em 5em; + text-align: center; + font-style: italic; } + +div.dedication p.topic-title { + font-weight: bold; + font-style: normal; } div.figure { margin-left: 2em; @@ -498,14 +821,8 @@ div.figure { div.footer, div.header { clear: both; - text-align: center; - color: #666; font-size: smaller; } -div.footer { - padding-top: 5em; -} - div.line-block { display: block; margin-top: 1em; @@ -516,24 +833,45 @@ div.line-block div.line-block { margin-bottom: 0; margin-left: 1.5em; } +div.sidebar { + margin: 0 0 0.5em 1em; + border: medium outset; + padding: 1em; + background-color: rgba(252, 248, 244, 0.75); + width: 40%; + float: right; + clear: right; } + +div.sidebar p.rubric { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-size: medium; } + +div.system-messages { + margin: 5em; } + +div.system-messages h1 { + color: #b30000; } + +div.system-message { + border: medium outset; + padding: 1em; } + +div.system-message p.system-message-title { + color: #b30000; + font-weight: bold; } + div.topic { margin: 2em; } -div.search_results { - background-color: antiquewhite; - margin: 3em; - padding: 1em; - border: 1px solid #4d4d4d; -} +h1.section-subtitle, h2.section-subtitle, h3.section-subtitle, +h4.section-subtitle, h5.section-subtitle, h6.section-subtitle { + margin-top: 0.4em; } -div#global-links ul { - margin-left: 0; - list-style-type: none; -} +h1.title { + text-align: center; } -div#global-links > simple-boot { - margin-left: 3em; -} +h2.subtitle { + text-align: center; } hr.docutils { width: 75%; } @@ -567,6 +905,30 @@ img.align-center, .figure.align-center, object.align-center { div.align-right { text-align: inherit; } +/* div.align-center * { */ +/* text-align: left } */ + +ul.simple > li { + margin-bottom: 0.5em } + +ol.simple, ul.simple { + margin-bottom: 1em; } + +ol.arabic { + list-style: decimal; } + +ol.loweralpha { + list-style: lower-alpha; } + +ol.upperalpha { + list-style: upper-alpha; } + +ol.lowerroman { + list-style: lower-roman; } + +ol.upperroman { + list-style: upper-roman; } + p.attribution { text-align: right; margin-left: 50%; } @@ -587,6 +949,15 @@ p.rubric { color: maroon; text-align: center; } +p.sidebar-title { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-weight: bold; + font-size: larger; } + +p.sidebar-subtitle { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-weight: bold; } + p.topic-title { font-weight: bold; } @@ -626,14 +997,22 @@ pre.code .inserted, code .inserted { background-color: #A3D289; } span.classifier { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-style: oblique; } span.classifier-delimiter { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: bold; } +span.interpreted { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } + span.option { white-space: nowrap; } +span.pre { + white-space: pre; } + span.problematic { color: #b30000; } @@ -641,6 +1020,44 @@ span.section-subtitle { /* font-size relative to parent (h1..h6 element) */ font-size: 80%; } +table.citation { + border-left: solid 1px #666666; + margin-left: 1px; } + +table.docinfo { + margin: 0em; + margin-top: 2em; + margin-bottom: 2em; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; + color: #444444; } + +table.docutils { + margin-top: 0.5em; + margin-bottom: 0.5em; } + +table.footnote { + border-left: solid 1px #2d2d2d; + margin-left: 1px; } + +table.docutils td, table.docutils th, +table.docinfo td, table.docinfo th { + padding-left: 0.5em; + padding-right: 0.5em; + vertical-align: top; } + +table.docutils th.field-name, table.docinfo th.docinfo-name { + font-weight: 700; + text-align: left; + white-space: nowrap; + padding-left: 0; } + +h1 tt.docutils, h2 tt.docutils, h3 tt.docutils, +h4 tt.docutils, h5 tt.docutils, h6 tt.docutils { + font-size: 100%; } + +ul.auto-toc { + list-style-type: none; } + span.DecNumber { color: #252dbe; } @@ -657,7 +1074,7 @@ span.FloatNumber { color: #252dbe; } span.Identifier { - color: #222; } + color: #3b3b3b; } span.Keyword { font-weight: 600; @@ -722,23 +1139,38 @@ dt pre > span.Identifier, dt pre > span.Operator { color: #155da4; font-weight: 700; } -dt pre > span.Keyword ~ span.Identifier, dt pre > span.Identifier ~ span.Identifier, -dt pre > span.Operator ~ span.Identifier, dt pre > span.Other ~ span.Identifier { +dt pre > span.Identifier ~ span.Identifier, dt pre > span.Operator ~ span.Identifier { + color: inherit; + font-weight: inherit; } + +dt pre > span.Operator ~ span.Identifier { color: inherit; font-weight: inherit; } /* Nim sprite for the footer (taken from main page favicon) */ .nim-sprite { display: inline-block; - height: 16px; - width: 16px; + height: 12px; + width: 12px; background-position: 0 0; - background-size: 16px 16px; + background-size: 12px 12px; -webkit-filter: opacity(50%); background-repeat: no-repeat; background-image: url("data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="); margin-bottom: -5px; } +div.search_results { + background-color: antiquewhite; + margin: 3em; + padding: 1em; + border: 1px solid #4d4d4d; +} + +div#global-links ul { + margin-left: 0; + list-style-type: none; +} + span.pragmadots { /* Position: relative frees us up to make the dots look really nice without fucking up the layout and @@ -746,14 +1178,18 @@ span.pragmadots { position: relative; /* 1px down looks slightly nicer */ top: 1px; + padding: 2px; - background-color: #e8e8e8; + background-color: #D3D3D3; border-radius: 4px; margin: 0 2px; cursor: pointer; - font-size: 0.8em; -} + /* For some reason on Chrome, making the font size + smaller than 1em is causing the parent container to + bulge slightly. So, we're stuck with inheriting 1em, + which is sad, because 0.8em looks better... */ +} span.pragmadots:hover { background-color: #DBDBDB; } @@ -761,10 +1197,6 @@ span.pragmawrap { display: none; } -span.attachedType { - display: none; - visibility: hidden; -} @@ -806,6 +1238,12 @@ function main() {
      +
    • + Exports +
        + +
      +
    • Imports
      -

      Main import file to write wrappers. Each compileTime proc must be used in a compile time context, eg using:

      -

      -static:
      -  cAddStdDir()
      -

      +

      Main import file to write wrappers. Each compileTime proc must be used in a compile time context, eg using:

      +

      ```

      +
      static:
      +
      cAddStdDir()
      +
      +

      ```

      -
      + +

      Imports

      plugin, git, paths, types @@ -874,8 +1312,8 @@ static:

      Procs

      - -
      proc cSkipSymbol(skips: seq[string]) {...}{.compileTime, raises: [], tags: [].}
      + +
      proc cSkipSymbol(skips: seq[string]) {...}{.compileTime, raises: [], tags: [].}
      Similar to cOverride(), this macro allows filtering out symbols not of interest from the generated output.

      Examples:

      @@ -884,21 +1322,21 @@ Similar to cOverr
      -
      proc cSearchPath(path: string): string {...}{.compileTime, raises: [], tags: [ReadDirEffect].}
      +
      proc cSearchPath(path: string): string {...}{.compileTime, raises: [], tags: [ReadDirEffect].}

      Get full path to file or directory path in search path configured using cAddSearchDir() and cAddStdDir().

      This can be used to locate files or directories that can be passed onto cCompile(), cIncludeDir() and cImport().

      - -
      proc cDebug() {...}{.compileTime, raises: [], tags: [].}
      + +
      proc cDebug() {...}{.compileTime, raises: [], tags: [].}
      Enable debug messages and display the generated Nim code
      - -
      proc cDisableCaching() {...}{.compileTime, raises: [], tags: [].}
      + +
      proc cDisableCaching() {...}{.compileTime, raises: [], tags: [].}

      Disable caching of generated Nim code - useful during wrapper development

      If files included by header being processed by cImport() change and affect the generated content, they will be ignored and the cached value will continue to be used . Use cDisableCaching() to avoid this scenario during development.

      @@ -907,7 +1345,7 @@ Enable debug messages and display the generated Nim code
      -
      proc cAddSearchDir(dir: string) {...}{.compileTime, raises: [], tags: [].}
      +
      proc cAddSearchDir(dir: string) {...}{.compileTime, raises: [], tags: [].}
      Add directory dir to the search path used in calls to cSearchPath().

      Examples:

      @@ -920,7 +1358,7 @@ Add directory dir to
      -
      proc cAddStdDir(mode = "c") {...}{.compileTime, raises: [], tags: [].}
      +
      proc cAddStdDir(mode = "c") {...}{.compileTime, raises: [], tags: [].}
      Add the standard c [default] or cpp include paths to search path used in calls to cSearchPath()

      Examples:

      @@ -937,8 +1375,8 @@ Add the standard c [d

      Macros

      - -
      macro cOverride(body): untyped
      + +
      macro cOverride(body): untyped

      When the wrapper code generated by nimterop is missing certain symbols or not accurate, it may be required to hand wrap them. Define them in a cOverride() macro block so that Nimterop no longer defines these symbols.

      For example:

      @@ -949,20 +1387,20 @@ Add the standard c [d
      - -
      macro cPlugin(body): untyped
      + +
      macro cPlugin(body): untyped
      -When cOverride() and cSkipSymbol() are not adequate, the cPlugin() macro can be used to customize the generated Nim output. The following callbacks are available at this time.
      proc onSymbol(sym: var Symbol) {.exportc, dynlib.}

      onSymbol() can be used to handle symbol name modifications required due to invalid characters like leading/trailing _ or rename symbols that would clash due to Nim's style insensitivity. It can also be used to remove prefixes and suffixes like SDL_. The symbol name and type is provided to the callback and the name can be modified.

      -

      Returning a blank name will result in the symbol being skipped. This will fail for nskParam and nskField since the generated Nim code will be wrong.

      +When cOverride() and cSkipSymbol() are not adequate, the cPlugin() macro can be used to customize the generated Nim output. The following callbacks are available at this time.
      proc onSymbol(sym: var Symbol) {.exportc, dynlib.}

      onSymbol() can be used to handle symbol name modifications required due to invalid characters like leading/trailing _ or rename symbols that would clash due to Nim's style insensitivity. It can also be used to remove prefixes and suffixes like SDL_. The symbol name and type is provided to the callback and the name can be modified.

      +

      Returning a blank name will result in the symbol being skipped. This will fail for nskParam and nskField since the generated Nim code will be wrong.

      Symbol types can be any of the following:

      -
      • nskConst for constants
      • -
      • nskType for type identifiers, including primitive
      • -
      • nskParam for param names
      • -
      • nskField for struct field names
      • -
      • nskEnumField for enum (field) names, though they are in the global namespace as nskConst
      • -
      • nskProc - for proc names
      • +
        • nskConst for constants
        • +
        • nskType for type identifiers, including primitive
        • +
        • nskParam for param names
        • +
        • nskField for struct field names
        • +
        • nskEnumField for enum (field) names, though they are in the global namespace as nskConst
        • +
        • nskProc - for proc names
        -

        nimterop/plugins is implicitly imported to provide access to standard plugin facilities.

        +

        nimterop/plugins is implicitly imported to provide access to standard plugin facilities.

        Examples:

        cPlugin:
        @@ -984,19 +1422,19 @@ When cOverride()<
         
         
      -
      macro cDefine(name: static string; val: static string = ""): untyped
      +
      macro cDefine(name: static string; val: static string = ""): untyped
      #define an identifer that is forwarded to the C/C++ compiler using {.passC: "-DXXX".}
      - -
      macro cIncludeDir(dir: static string): untyped
      + +
      macro cIncludeDir(dir: static string): untyped
      Add an include directory that is forwarded to the C/C++ compiler using {.passC: "-IXXX".}. This is also provided to the preprocessor during Nim code generation.
      -
      macro cCompile(path: static string; mode = "c"; exclude = ""): untyped
      +
      macro cCompile(path: static string; mode = "c"; exclude = ""): untyped

      Compile and link C/C++ implementation into resulting binary using {.compile.}

      path can be a specific file or contain wildcards:

      @@ -1007,8 +1445,8 @@ Add an include directory that is forwarded to the C/C++ compiler using cCompile("path/to/dir", exclude="test2.c")
      - -
      macro cImport(filename: static string; recurse: static bool = false): untyped
      + +
      macro cImport(filename: static string; recurse: static bool = false): untyped

      Import all supported definitions from specified header file. Generated content is cached in nimcache until filename changes unless cDisableCaching() is set. nim -f can also be used after Nim v0.19.4 to flush the cache.

      recurse can be used to generate Nim wrappers from #include files referenced in filename. This is only done for files in the same directory as filename or in a directory added using cIncludeDir()

      @@ -1016,11 +1454,6 @@ Add an include directory that is forwarded to the C/C++ compiler using -
      -
      @@ -1030,7 +1463,7 @@ Add an include directory that is forwarded to the C/C++ compiler using
      - Made with Nim. Generated: 2019-04-11 03:28:45 UTC + Made with Nim. Generated: 2019-05-09 02:07:17 UTC
      diff --git a/cimport.idx b/cimport.idx index 834bea9..65b278b 100755 --- a/cimport.idx +++ b/cimport.idx @@ -1,12 +1,12 @@ -cOverride cimport.html#cOverride.m cimport: cOverride(body): untyped -cSkipSymbol cimport.html#cSkipSymbol,seq[T][string] cimport: cSkipSymbol(skips: seq[string]) -cPlugin cimport.html#cPlugin.m cimport: cPlugin(body): untyped +cOverride cimport.html#cOverride.m, cimport: cOverride(body): untyped +cSkipSymbol cimport.html#cSkipSymbol,seq[string] cimport: cSkipSymbol(skips: seq[string]) +cPlugin cimport.html#cPlugin.m, cimport: cPlugin(body): untyped cSearchPath cimport.html#cSearchPath,string cimport: cSearchPath(path: string): string -cDebug cimport.html#cDebug cimport: cDebug() -cDisableCaching cimport.html#cDisableCaching cimport: cDisableCaching() +cDebug cimport.html#cDebug, cimport: cDebug() +cDisableCaching cimport.html#cDisableCaching, cimport: cDisableCaching() cDefine cimport.html#cDefine.m,,string cimport: cDefine(name: static string; val: static string = ""): untyped cAddSearchDir cimport.html#cAddSearchDir,string cimport: cAddSearchDir(dir: string) -cIncludeDir cimport.html#cIncludeDir.m cimport: cIncludeDir(dir: static string): untyped +cIncludeDir cimport.html#cIncludeDir.m, cimport: cIncludeDir(dir: static string): untyped cAddStdDir cimport.html#cAddStdDir,string cimport: cAddStdDir(mode = "c") cCompile cimport.html#cCompile.m,,string,string cimport: cCompile(path: static string; mode = "c"; exclude = ""): untyped -cImport cimport.html#cImport.m cimport: cImport(filename: static string; recurse: static bool = false): untyped +cImport cimport.html#cImport.m, cimport: cImport(filename: static string; recurse: static bool = false): untyped diff --git a/compat.html b/compat.html index f565882..d70bd18 100755 --- a/compat.html +++ b/compat.html @@ -27,113 +27,232 @@ customize this style sheet. Modified from Chad Skeeters' rst2html-style https://bitbucket.org/cskeeters/rst2html-style/ -Modified by Boyd Greenfield and narimiran +Modified by Boyd Greenfield */ - +/* SCSS variables */ +/* Text weights */ +/* Body colors */ +/* Text colors */ +/* Link colors */ +/* Syntax highlighting colors */ +/* Pct changes */ +/* Mixins */ +/* Body/layout */ html { font-size: 100%; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; } +/* Where we want fancier font if available */ +h1, h2, h3, h4, h5, h6, p.module-desc, table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; } + +h1.title { + font-weight: 900; } + body { font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: 400; - font-size: 1.125em; - line-height: 1.5; - color: #222; - background-color: #FCFCFC; } + font-size: 16px; + line-height: 20px; + color: #444; + letter-spacing: 0.15px; + background-color: #FDFBFA; } /* Skeleton grid */ .container { position: relative; width: 100%; - max-width: 1050px; + max-width: 960px; margin: 0 auto; - padding: 0; + padding: 0 20px; box-sizing: border-box; } .column, .columns { width: 100%; float: left; - box-sizing: border-box; - margin-left: 1%; -} + box-sizing: border-box; } -.column:first-child, -.columns:first-child { - margin-left: 0; } +/* For devices larger than 400px */ +@media (min-width: 400px) { + .container { + width: 100%; + padding: 0; } } +/* For devices larger than 650px */ +@media (min-width: 650px) { + .container { + width: 100%; } -.three.columns { - width: 19%; } + .column, + .columns { + margin-left: 4%; } -.nine.columns { - width: 80.0%; } + .column:first-child, + .columns:first-child { + margin-left: 0; } -.twelve.columns { - width: 100%; - margin-left: 0; } + .one.column, + .one.columns { + width: 4.66666666667%; } + + .two.columns { + width: 13.3333333333%; } -@media screen and (max-width: 860px) { .three.columns { - display: none; - } + width: 22%; } + + .four.columns { + width: 30.6666666667%; } + + .five.columns { + width: 39.3333333333%; } + + .six.columns { + width: 48%; } + + .seven.columns { + width: 56.6666666667%; } + + .eight.columns { + width: 65.3333333333%; } + .nine.columns { - width: 98.0%; - } - body { - font-size: 1em; - line-height: 1.35; - } -} + width: 74.0%; } + + .ten.columns { + width: 82.6666666667%; } + + .eleven.columns { + width: 91.3333333333%; } + + .twelve.columns { + width: 100%; + margin-left: 0; } + + .one-third.column { + width: 30.6666666667%; } + + .two-thirds.column { + width: 65.3333333333%; } } +/* Customer Overrides */ +.footer { + text-align: center; + color: #969696; + padding-top: 10%; } + +p.module-desc { + font-size: 1.1em; + color: #666666; } + +a.link-seesrc { + color: #aec7d2; + font-style: italic; } + +a.link-seesrc:hover { + color: #6c9aae; } + +#toc-list { + word-wrap: break-word; } + +ul.simple-toc { + list-style: none; } + +ul.simple-toc a.reference-toplevel { + font-weight: bold; + color: #0077b3; } + +ul.simple-toc-section { + list-style-type: circle; + color: #6c9aae; } + +ul.simple-toc-section a.reference { + color: #0077b3; } cite { font-style: italic !important; } +dt > pre { + border-color: rgba(0, 0, 0, 0.1); + background-color: rgba(255, 255, 255, 0.3); + margin: 15px 0px 5px; } + +dd > pre { + border-color: rgba(0, 0, 0, 0.1); + background-color: whitesmoke; + margin-top: 8px; } + +.item > dd { + margin-left: 10px; + margin-bottom: 30px; } + +/* Nim line-numbered tables */ +.line-nums-table { + width: 100%; + table-layout: fixed; } /* Nim search input */ div#searchInputDiv { - margin-bottom: 1em; + margin-bottom: 8px; } -input#searchInput { - width: 80%; +div#searchInputDiv input#searchInput { + width: 10em; +} +div.search-groupby { + margin-bottom: 8px; } +table.line-nums-table { + border-radius: 4px; + border: 1px solid #cccccc; + background-color: whitesmoke; + border-collapse: separate; + margin-top: 15px; + margin-bottom: 25px; } + +.line-nums-table tbody { + border: none; } + +.line-nums-table td pre { + border: none; + background-color: transparent; } + +.line-nums-table td.blob-line-nums { + width: 28px; } + +.line-nums-table td.blob-line-nums pre { + color: #b0b0b0; + -webkit-filter: opacity(75%); + text-align: right; + border-color: transparent; + background-color: transparent; + padding-left: 0px; + margin-left: 0px; + padding-right: 0px; + margin-right: 0px; } /* Docgen styles */ /* Links */ a { - color: #07b; - text-decoration: none; -} - -a span.Identifier { - text-decoration: underline; - text-decoration-color: #aab; -} - -a.reference-toplevel { - font-weight: bold; -} - -a.toc-backref { - text-decoration: none; - color: #222; } - -a.link-seesrc { - color: #607c9f; - font-size: 0.9em; - font-style: italic; } + color: #0077b3; + text-decoration: none; } a:hover, a:focus { - color: #607c9f; + color: #00334d; text-decoration: underline; } -a:hover span.Identifier { - color: #607c9f; -} +a:visited { + color: #00334d; } +a:focus { + outline: thin dotted #2d2d2d; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; } + +a:hover, +a:active { + outline: 0; } sub, sup { @@ -210,258 +329,379 @@ img { h2, h3 { - page-break-after: avoid; } -} + page-break-after: avoid; } } +.img-rounded { + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; } +.img-polaroid { + padding: 4px; + background-color: rgba(252, 248, 244, 0.75); + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.2); + -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); } p { - margin-top: 0.5em; - margin-bottom: 0.5em; -} + margin: 0 0 8px; } small { font-size: 85%; } strong { - font-weight: 600; - font-size: 0.95em; - color: #3c3c3c; -} + font-weight: 600; } em { font-style: italic; } +cite { + font-style: normal; } + +h1, +h2, +h3, +h4, +h5, +h6 { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-weight: 600; + line-height: 20px; + color: inherit; + text-rendering: optimizelegibility; } + h1 { - font-size: 1.8em; + font-size: 2em; font-weight: 400; - padding-bottom: .25em; - border-bottom: 1px solid #aaa; - margin-top: 2.5em; - margin-bottom: 1em; + padding-bottom: .15em; + border-bottom: 1px solid #aaaaaa; + margin-top: 1.0em; line-height: 1.2em; } h1.title { padding-bottom: 1em; border-bottom: 0px; - font-size: 2.5em; - text-align: center; - font-weight: 900; - margin-top: 0.75em; - margin-bottom: 0em; -} + font-size: 2.75em; } h2 { - font-size: 1.3em; - margin-top: 2em; } - -h2.subtitle { - text-align: center; } - -h3 { - font-size: 1.125em; - font-style: italic; + font-size: 1.5em; margin-top: 1.5em; } +h3 { + font-size: 1.3em; + font-style: italic; + margin-top: 0.75em; } + h4 { - font-size: 1.125em; - margin-top: 1em; } + font-size: 1.3em; + margin-top: 0.5em; } h5 { - font-size: 1.125em; - margin-top: 0.75em; } + font-size: 1.2em; + margin-top: 0.25em; } h6 { font-size: 1.1em; } - ul, ol { padding: 0; - margin-top: 0.5em; - margin-left: 0.75em; } + margin: 0 0 0px 15px; } ul ul, ul ol, ol ol, ol ul { - margin-bottom: 0; - margin-left: 1.25em; } + margin-bottom: 0; } li { - list-style-type: circle; -} - -ul.simple-boot li { - list-style-type: none; - margin-left: 0em; - margin-bottom: 0.5em; -} - -ol.simple > li, ul.simple > li { - margin-bottom: 0.25em; - margin-left: 0.4em } - -ul.simple.simple-toc > li { - margin-top: 1em; -} - -ul.simple-toc { - list-style: none; - font-size: 0.9em; - margin-left: -0.3em; - margin-top: 1em; } - -ul.simple-toc > li { - list-style-type: none; -} - -ul.simple-toc-section { - list-style-type: circle; - margin-left: 1em; - color: #6c9aae; } - - -ol.arabic { - list-style: decimal; } - -ol.loweralpha { - list-style: lower-alpha; } - -ol.upperalpha { - list-style: upper-alpha; } - -ol.lowerroman { - list-style: lower-roman; } - -ol.upperroman { - list-style: upper-roman; } - -ul.auto-toc { - list-style-type: none; } - + line-height: 20px; } dl { - margin-bottom: 1.5em; } + margin-bottom: 20px; } + +dt, +dd { + line-height: 20px; } dt { - margin-bottom: -0.5em; - margin-left: 0.0em; } + font-weight: bold; } dd { - margin-left: 2.0em; - margin-bottom: 3.0em; - margin-top: 0.5em; } - + margin-left: 10px; + margin-bottom: 26px; } hr { - margin: 2em 0; + margin: 20px 0; border: 0; - border-top: 1px solid #aaa; } + border-top: 1px solid #eeeeee; + border-bottom: 1px solid #ffffff; } + +abbr[title], +abbr[data-original-title] { + cursor: help; + border-bottom: 1px dotted #999999; } + +abbr.initialism { + font-size: 90%; + text-transform: uppercase; } blockquote { - font-size: 0.9em; - font-style: italic; - padding-left: 0.5em; - margin-left: 0; - border-left: 5px solid #bbc; + padding: 0 0 0 15px; + margin: 0 0 20px; + border-left: 5px solid #EFEBE0; } + +table.docinfo + blockquote, table.docinfo blockquote, h1 + blockquote { + border-left: 5px solid #c9c9c9; } +table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { + margin-bottom: 0; + font-size: 15px; + font-weight: 200; + line-height: 1.5; + font-style: italic; } + +q:before, +q:after, +blockquote:before, +blockquote:after { + content: ""; } + +address { + display: block; + margin-bottom: 20px; + font-style: normal; + line-height: 20px; } + +code, +pre { + font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; + padding: 0 3px 2px; + font-weight: 500; + font-size: 12px; + color: #444444; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; } + .pre { font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - font-weight: 500; - font-size: 0.85em; - background-color: #f0f3ff; - padding-left: 3px; - padding-right: 3px; - border-radius: 4px; + font-weight: 600; + /*color: #504da6;*/ } +code { + padding: 2px 4px; + color: #444444; + white-space: nowrap; + background-color: white; + border: 1px solid #777777; } + pre { - font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - color: #222; - font-weight: 500; display: inline-block; box-sizing: border-box; - min-width: 100%; - padding: 0.5em; - margin-top: 0.5em; - margin-bottom: 0.5em; - font-size: 0.85em; + min-width: calc(100% - 19.5px); + padding: 9.5px; + margin: 0.25em 10px 10px 10px; + font-size: 15px; + line-height: 20px; white-space: pre !important; overflow-y: hidden; overflow-x: visible; - background-color: ghostwhite; - border: 1px solid #dde; - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; } + background-color: rgba(0, 0, 0, 0.01); + border: 1px solid #cccccc; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; } + +pre.prettyprint { + margin-bottom: 20px; } + +pre code { + padding: 0; + color: inherit; + white-space: pre; + overflow-x: visible; + background-color: transparent; + border: 0; } .pre-scrollable { max-height: 340px; overflow-y: scroll; } - -/* Nim line-numbered tables */ -.line-nums-table { - width: 100%; - table-layout: fixed; } - -table.line-nums-table { - border-radius: 4px; - border: 1px solid #cccccc; - background-color: ghostwhite; - border-collapse: separate; - margin-top: 15px; - margin-bottom: 25px; } - -.line-nums-table tbody { - border: none; } - -.line-nums-table td pre { - border: none; - background-color: transparent; } - -.line-nums-table td.blob-line-nums { - width: 28px; } - -.line-nums-table td.blob-line-nums pre { - color: #b0b0b0; - -webkit-filter: opacity(75%); - text-align: right; - border-color: transparent; - background-color: transparent; - padding-left: 0px; - margin-left: 0px; - padding-right: 0px; - margin-right: 0px; } - - table { max-width: 100%; background-color: transparent; - margin-top: 0.5em; - margin-bottom: 1.5em; border-collapse: collapse; - border-color: #ccc; - border-spacing: 0; - font-size: 0.9em; -} + border-spacing: 0; } table th, table td { - padding: 0px 0.5em 0px; + padding: 0px 8px 0px; } -table th { - background-color: #e8e8e8; +.table { + width: 100%; + margin-bottom: 20px; } + +.table th, +.table td { + padding: 8px; + line-height: 20px; + text-align: left; + vertical-align: top; + border-top: 1px solid #444444; } + +.table th { font-weight: bold; } -table th.docinfo-name { - background-color: transparent; -} +.table thead th { + vertical-align: bottom; } -table tr:hover { - background-color: ghostwhite; } +.table caption + thead tr:first-child th, +.table caption + thead tr:first-child td, +.table colgroup + thead tr:first-child th, +.table colgroup + thead tr:first-child td, +.table thead:first-child tr:first-child th, +.table thead:first-child tr:first-child td { + border-top: 0; } +.table tbody + tbody { + border-top: 2px solid #444444; } + +.table .table { + background-color: rgba(252, 248, 244, 0.75); } + +.table-condensed th, +.table-condensed td { + padding: 4px 5px; } + +.table-bordered { + border: 1px solid #444444; + border-collapse: separate; + *border-collapse: collapse; + border-left: 0; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; } + +.table-bordered th, +.table-bordered td { + border-left: 1px solid #444444; } + +.table-bordered caption + thead tr:first-child th, +.table-bordered caption + tbody tr:first-child th, +.table-bordered caption + tbody tr:first-child td, +.table-bordered colgroup + thead tr:first-child th, +.table-bordered colgroup + tbody tr:first-child th, +.table-bordered colgroup + tbody tr:first-child td, +.table-bordered thead:first-child tr:first-child th, +.table-bordered tbody:first-child tr:first-child th, +.table-bordered tbody:first-child tr:first-child td { + border-top: 0; } + +.table-bordered thead:first-child tr:first-child > th:first-child, +.table-bordered tbody:first-child tr:first-child > td:first-child, +.table-bordered tbody:first-child tr:first-child > th:first-child { + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; } + +.table-bordered thead:first-child tr:first-child > th:last-child, +.table-bordered tbody:first-child tr:first-child > td:last-child, +.table-bordered tbody:first-child tr:first-child > th:last-child { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; } + +.table-bordered thead:last-child tr:last-child > th:first-child, +.table-bordered tbody:last-child tr:last-child > td:first-child, +.table-bordered tbody:last-child tr:last-child > th:first-child, +.table-bordered tfoot:last-child tr:last-child > td:first-child, +.table-bordered tfoot:last-child tr:last-child > th:first-child { + -webkit-border-bottom-left-radius: 4px; + border-bottom-left-radius: 4px; + -moz-border-radius-bottomleft: 4px; } + +.table-bordered thead:last-child tr:last-child > th:last-child, +.table-bordered tbody:last-child tr:last-child > td:last-child, +.table-bordered tbody:last-child tr:last-child > th:last-child, +.table-bordered tfoot:last-child tr:last-child > td:last-child, +.table-bordered tfoot:last-child tr:last-child > th:last-child { + -webkit-border-bottom-right-radius: 4px; + border-bottom-right-radius: 4px; + -moz-border-radius-bottomright: 4px; } + +.table-bordered tfoot + tbody:last-child tr:last-child td:first-child { + -webkit-border-bottom-left-radius: 0; + border-bottom-left-radius: 0; + -moz-border-radius-bottomleft: 0; } + +.table-bordered tfoot + tbody:last-child tr:last-child td:last-child { + -webkit-border-bottom-right-radius: 0; + border-bottom-right-radius: 0; + -moz-border-radius-bottomright: 0; } + +.table-bordered caption + thead tr:first-child th:first-child, +.table-bordered caption + tbody tr:first-child td:first-child, +.table-bordered colgroup + thead tr:first-child th:first-child, +.table-bordered colgroup + tbody tr:first-child td:first-child { + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; } + +.table-bordered caption + thead tr:first-child th:last-child, +.table-bordered caption + tbody tr:first-child td:last-child, +.table-bordered colgroup + thead tr:first-child th:last-child, +.table-bordered colgroup + tbody tr:first-child td:last-child { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; } + +table.docutils th { + background-color: #e8e8e8; } + +table.docutils tr:hover { + background-color: whitesmoke; } + +.table-striped tbody > tr:nth-child(odd) > td, +.table-striped tbody > tr:nth-child(odd) > th { + background-color: rgba(252, 248, 244, 0.75); } + +.table-hover tbody tr:hover > td, +.table-hover tbody tr:hover > th { + background-color: rgba(241, 222, 204, 0.75); } + +table td[class*="span"], +table th[class*="span"], +.row-fluid table td[class*="span"], +.row-fluid table th[class*="span"] { + display: table-cell; + float: none; + margin-left: 0; } + +.hero-unit { + padding: 60px; + margin-bottom: 30px; + font-size: 18px; + font-weight: 200; + line-height: 30px; + color: inherit; + background-color: rgba(230, 197, 164, 0.75); + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; } + +.hero-unit h1 { + margin-bottom: 0; + font-size: 60px; + line-height: 1; + letter-spacing: -1px; + color: inherit; } + +.hero-unit li { + line-height: 30px; } /* rst2html default used to remove borders from tables and images */ .borderless, table.borderless td, table.borderless th { @@ -482,6 +722,10 @@ table.borderless td, table.borderless th { .hidden { display: none; } +a.toc-backref { + text-decoration: none; + color: #444444; } + blockquote.epigraph { margin: 2em 5em; } @@ -491,6 +735,85 @@ dl.docutils dd { object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] { overflow: hidden; } +/* Uncomment (and remove this text!) to get bold-faced definition list terms +dl.docutils dt { + font-weight: bold } +*/ +div.abstract { + margin: 2em 5em; } + +div.abstract p.topic-title { + font-weight: bold; + text-align: center; } + +div.admonition, div.attention, div.caution, div.danger, div.error, +div.hint, div.important, div.note, div.tip, div.warning { + margin: 2em; + border: medium outset; + padding: 1em; } + +div.note, div.warning { + margin: 1.5em 0px; + border: none; } + +div.note p.admonition-title, +div.warning p.admonition-title { + display: none; } + +/* Clearfix + * http://css-tricks.com/snippets/css/clear-fix/ + */ +div.note:after, +div.warning:after { + content: ""; + display: table; + clear: both; } + +div.note p:before, +div.warning p:before { + display: block; + float: left; + font-size: 4em; + line-height: 1em; + margin-right: 20px; + margin-left: 0em; + margin-top: -10px; + content: '\0270D'; + /*handwriting*/ } + +div.warning p:before { + content: '\026A0'; + /*warning*/ } + +div.admonition p.admonition-title, div.hint p.admonition-title, +div.important p.admonition-title, div.note p.admonition-title, +div.tip p.admonition-title { + font-weight: bold; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } + +div.attention p.admonition-title, div.caution p.admonition-title, +div.danger p.admonition-title, div.error p.admonition-title, +div.warning p.admonition-title, .code .error { + color: #b30000; + font-weight: bold; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } + +/* Uncomment (and remove this text!) to get reduced vertical space in + compound paragraphs. +div.compound .compound-first, div.compound .compound-middle { + margin-bottom: 0.5em } + +div.compound .compound-last, div.compound .compound-middle { + margin-top: 0.5em } +*/ +div.dedication { + margin: 2em 5em; + text-align: center; + font-style: italic; } + +div.dedication p.topic-title { + font-weight: bold; + font-style: normal; } div.figure { margin-left: 2em; @@ -498,14 +821,8 @@ div.figure { div.footer, div.header { clear: both; - text-align: center; - color: #666; font-size: smaller; } -div.footer { - padding-top: 5em; -} - div.line-block { display: block; margin-top: 1em; @@ -516,24 +833,45 @@ div.line-block div.line-block { margin-bottom: 0; margin-left: 1.5em; } +div.sidebar { + margin: 0 0 0.5em 1em; + border: medium outset; + padding: 1em; + background-color: rgba(252, 248, 244, 0.75); + width: 40%; + float: right; + clear: right; } + +div.sidebar p.rubric { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-size: medium; } + +div.system-messages { + margin: 5em; } + +div.system-messages h1 { + color: #b30000; } + +div.system-message { + border: medium outset; + padding: 1em; } + +div.system-message p.system-message-title { + color: #b30000; + font-weight: bold; } + div.topic { margin: 2em; } -div.search_results { - background-color: antiquewhite; - margin: 3em; - padding: 1em; - border: 1px solid #4d4d4d; -} +h1.section-subtitle, h2.section-subtitle, h3.section-subtitle, +h4.section-subtitle, h5.section-subtitle, h6.section-subtitle { + margin-top: 0.4em; } -div#global-links ul { - margin-left: 0; - list-style-type: none; -} +h1.title { + text-align: center; } -div#global-links > simple-boot { - margin-left: 3em; -} +h2.subtitle { + text-align: center; } hr.docutils { width: 75%; } @@ -567,6 +905,30 @@ img.align-center, .figure.align-center, object.align-center { div.align-right { text-align: inherit; } +/* div.align-center * { */ +/* text-align: left } */ + +ul.simple > li { + margin-bottom: 0.5em } + +ol.simple, ul.simple { + margin-bottom: 1em; } + +ol.arabic { + list-style: decimal; } + +ol.loweralpha { + list-style: lower-alpha; } + +ol.upperalpha { + list-style: upper-alpha; } + +ol.lowerroman { + list-style: lower-roman; } + +ol.upperroman { + list-style: upper-roman; } + p.attribution { text-align: right; margin-left: 50%; } @@ -587,6 +949,15 @@ p.rubric { color: maroon; text-align: center; } +p.sidebar-title { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-weight: bold; + font-size: larger; } + +p.sidebar-subtitle { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-weight: bold; } + p.topic-title { font-weight: bold; } @@ -626,14 +997,22 @@ pre.code .inserted, code .inserted { background-color: #A3D289; } span.classifier { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-style: oblique; } span.classifier-delimiter { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: bold; } +span.interpreted { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } + span.option { white-space: nowrap; } +span.pre { + white-space: pre; } + span.problematic { color: #b30000; } @@ -641,6 +1020,44 @@ span.section-subtitle { /* font-size relative to parent (h1..h6 element) */ font-size: 80%; } +table.citation { + border-left: solid 1px #666666; + margin-left: 1px; } + +table.docinfo { + margin: 0em; + margin-top: 2em; + margin-bottom: 2em; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; + color: #444444; } + +table.docutils { + margin-top: 0.5em; + margin-bottom: 0.5em; } + +table.footnote { + border-left: solid 1px #2d2d2d; + margin-left: 1px; } + +table.docutils td, table.docutils th, +table.docinfo td, table.docinfo th { + padding-left: 0.5em; + padding-right: 0.5em; + vertical-align: top; } + +table.docutils th.field-name, table.docinfo th.docinfo-name { + font-weight: 700; + text-align: left; + white-space: nowrap; + padding-left: 0; } + +h1 tt.docutils, h2 tt.docutils, h3 tt.docutils, +h4 tt.docutils, h5 tt.docutils, h6 tt.docutils { + font-size: 100%; } + +ul.auto-toc { + list-style-type: none; } + span.DecNumber { color: #252dbe; } @@ -657,7 +1074,7 @@ span.FloatNumber { color: #252dbe; } span.Identifier { - color: #222; } + color: #3b3b3b; } span.Keyword { font-weight: 600; @@ -722,23 +1139,38 @@ dt pre > span.Identifier, dt pre > span.Operator { color: #155da4; font-weight: 700; } -dt pre > span.Keyword ~ span.Identifier, dt pre > span.Identifier ~ span.Identifier, -dt pre > span.Operator ~ span.Identifier, dt pre > span.Other ~ span.Identifier { +dt pre > span.Identifier ~ span.Identifier, dt pre > span.Operator ~ span.Identifier { + color: inherit; + font-weight: inherit; } + +dt pre > span.Operator ~ span.Identifier { color: inherit; font-weight: inherit; } /* Nim sprite for the footer (taken from main page favicon) */ .nim-sprite { display: inline-block; - height: 16px; - width: 16px; + height: 12px; + width: 12px; background-position: 0 0; - background-size: 16px 16px; + background-size: 12px 12px; -webkit-filter: opacity(50%); background-repeat: no-repeat; background-image: url("data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="); margin-bottom: -5px; } +div.search_results { + background-color: antiquewhite; + margin: 3em; + padding: 1em; + border: 1px solid #4d4d4d; +} + +div#global-links ul { + margin-left: 0; + list-style-type: none; +} + span.pragmadots { /* Position: relative frees us up to make the dots look really nice without fucking up the layout and @@ -746,14 +1178,18 @@ span.pragmadots { position: relative; /* 1px down looks slightly nicer */ top: 1px; + padding: 2px; - background-color: #e8e8e8; + background-color: #D3D3D3; border-radius: 4px; margin: 0 2px; cursor: pointer; - font-size: 0.8em; -} + /* For some reason on Chrome, making the font size + smaller than 1em is causing the parent container to + bulge slightly. So, we're stuck with inheriting 1em, + which is sad, because 0.8em looks better... */ +} span.pragmadots:hover { background-color: #DBDBDB; } @@ -761,10 +1197,6 @@ span.pragmawrap { display: none; } -span.attachedType { - display: none; - visibility: hidden; -} @@ -805,12 +1237,43 @@ function main() { - + +

      - +
      +

      Procs

      +
      + +
      proc relativePath(file, base: string): string {...}{.raises: [], tags: [].}
      +
      +naive version of os.relativePath ; remove after nim >= 0.19.9 +

      Examples:

      +
      import
      +  ospaths, unittest
      +
      +check:
      +  "/foo/bar/baz/log.txt".unixToNativePath.relativePath(
      +      "/foo/bar".unixToNativePath) == "baz/log.txt".unixToNativePath
      +  "foo/bar/baz/log.txt".unixToNativePath.relativePath("foo/bar".unixToNativePath) ==
      +      "baz/log.txt".unixToNativePath
      + +
      + +
      +
      @@ -818,7 +1281,7 @@ function main() { diff --git a/dochack.js b/dochack.js index 28e8125..2405199 100755 --- a/dochack.js +++ b/dochack.js @@ -12,247 +12,247 @@ if (typeof Uint16Array === 'undefined') Uint16Array = Array; if (typeof Uint32Array === 'undefined') Uint32Array = Array; if (typeof Float32Array === 'undefined') Float32Array = Array; if (typeof Float64Array === 'undefined') Float64Array = Array; -var NTI43032 = {size: 0,kind: 1,base: null,node: null,finalizer: null}; -var NTI202074 = {size: 0, kind: 18, base: null, node: null, finalizer: null}; -var NTI46862 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI205327 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; -var NTI84448 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI84444 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI84440 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI84436 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI84432 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI84428 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI84424 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI84420 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI84416 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI84412 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI84408 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI84404 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI84400 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI84396 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI84392 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI84388 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI84384 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI84380 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI84376 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI84372 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI84205 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI84283 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI84281 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; -var NTI84227 = {size: 0, kind: 14, base: null, node: null, finalizer: null}; -var NTI84565 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; -var NTI84563 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; -var NTI84561 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; -var NTI84231 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI84229 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; -var NTI86305 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; -var NTI46850 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI46858 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI43006 = {size: 0,kind: 31,base: null,node: null,finalizer: null}; -var NTI62231 = {size: 0, kind: 18, base: null, node: null, finalizer: null}; -var NTI46808 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI46914 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; -var NTI43016 = {size: 0,kind: 40,base: null,node: null,finalizer: null}; -var NTI43040 = {size: 0,kind: 28,base: null,node: null,finalizer: null}; -var NTI43042 = {size: 0,kind: 29,base: null,node: null,finalizer: null}; -var NTI46908 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; -var NTI46826 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI46828 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI46842 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI46846 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NNI46846 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; -NTI46846.node = NNI46846; -var NNI46842 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; -NTI46842.node = NNI46842; -var NNI46828 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; -NTI46828.node = NNI46828; -NTI46908.base = NTI46826; -NTI46914.base = NTI46826; -var NNI46826 = {kind: 2, len: 6, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "parent", len: 0, typ: NTI46908, name: "parent", sons: null}, -{kind: 1, offset: "name", len: 0, typ: NTI43042, name: "name", sons: null}, -{kind: 1, offset: "message", len: 0, typ: NTI43040, name: "msg", sons: null}, -{kind: 1, offset: "trace", len: 0, typ: NTI43040, name: "trace", sons: null}, -{kind: 1, offset: "raiseId", len: 0, typ: NTI43016, name: "raiseId", sons: null}, -{kind: 1, offset: "up", len: 0, typ: NTI46914, name: "up", sons: null}]}; -NTI46826.node = NNI46826; -var NNI46808 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; -NTI46808.node = NNI46808; -NTI46826.base = NTI46808; -NTI46828.base = NTI46826; -NTI46842.base = NTI46828; -NTI46846.base = NTI46842; -var NNI62231 = {kind: 2, len: 2, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "Field0", len: 0, typ: NTI43042, name: "Field0", sons: null}, -{kind: 1, offset: "Field1", len: 0, typ: NTI43006, name: "Field1", sons: null}]}; -NTI62231.node = NNI62231; -var NNI46858 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; -NTI46858.node = NNI46858; -NTI46858.base = NTI46828; -var NNI46850 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; -NTI46850.node = NNI46850; -NTI46850.base = NTI46828; -NTI84561.base = NTI84229; -NTI84563.base = NTI84229; -NTI84565.base = NTI84229; -var NNI84227 = {kind: 2, offset: 0, typ: null, name: null, len: 12, sons: {"1": {kind: 1, offset: 1, typ: NTI84227, name: "ElementNode", len: 0, sons: null}, -"2": {kind: 1, offset: 2, typ: NTI84227, name: "AttributeNode", len: 0, sons: null}, -"3": {kind: 1, offset: 3, typ: NTI84227, name: "TextNode", len: 0, sons: null}, -"4": {kind: 1, offset: 4, typ: NTI84227, name: "CDATANode", len: 0, sons: null}, -"5": {kind: 1, offset: 5, typ: NTI84227, name: "EntityRefNode", len: 0, sons: null}, -"6": {kind: 1, offset: 6, typ: NTI84227, name: "EntityNode", len: 0, sons: null}, -"7": {kind: 1, offset: 7, typ: NTI84227, name: "ProcessingInstructionNode", len: 0, sons: null}, -"8": {kind: 1, offset: 8, typ: NTI84227, name: "CommentNode", len: 0, sons: null}, -"9": {kind: 1, offset: 9, typ: NTI84227, name: "DocumentNode", len: 0, sons: null}, -"10": {kind: 1, offset: 10, typ: NTI84227, name: "DocumentTypeNode", len: 0, sons: null}, -"11": {kind: 1, offset: 11, typ: NTI84227, name: "DocumentFragmentNode", len: 0, sons: null}, -"12": {kind: 1, offset: 12, typ: NTI84227, name: "NotationNode", len: 0, sons: null}}}; -NTI84227.node = NNI84227; -var NNI84283 = {kind: 2, len: 91, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "background", len: 0, typ: NTI43042, name: "background", sons: null}, -{kind: 1, offset: "backgroundAttachment", len: 0, typ: NTI43042, name: "backgroundAttachment", sons: null}, -{kind: 1, offset: "backgroundColor", len: 0, typ: NTI43042, name: "backgroundColor", sons: null}, -{kind: 1, offset: "backgroundImage", len: 0, typ: NTI43042, name: "backgroundImage", sons: null}, -{kind: 1, offset: "backgroundPosition", len: 0, typ: NTI43042, name: "backgroundPosition", sons: null}, -{kind: 1, offset: "backgroundRepeat", len: 0, typ: NTI43042, name: "backgroundRepeat", sons: null}, -{kind: 1, offset: "border", len: 0, typ: NTI43042, name: "border", sons: null}, -{kind: 1, offset: "borderBottom", len: 0, typ: NTI43042, name: "borderBottom", sons: null}, -{kind: 1, offset: "borderBottomColor", len: 0, typ: NTI43042, name: "borderBottomColor", sons: null}, -{kind: 1, offset: "borderBottomStyle", len: 0, typ: NTI43042, name: "borderBottomStyle", sons: null}, -{kind: 1, offset: "borderBottomWidth", len: 0, typ: NTI43042, name: "borderBottomWidth", sons: null}, -{kind: 1, offset: "borderColor", len: 0, typ: NTI43042, name: "borderColor", sons: null}, -{kind: 1, offset: "borderLeft", len: 0, typ: NTI43042, name: "borderLeft", sons: null}, -{kind: 1, offset: "borderLeftColor", len: 0, typ: NTI43042, name: "borderLeftColor", sons: null}, -{kind: 1, offset: "borderLeftStyle", len: 0, typ: NTI43042, name: "borderLeftStyle", sons: null}, -{kind: 1, offset: "borderLeftWidth", len: 0, typ: NTI43042, name: "borderLeftWidth", sons: null}, -{kind: 1, offset: "borderRight", len: 0, typ: NTI43042, name: "borderRight", sons: null}, -{kind: 1, offset: "borderRightColor", len: 0, typ: NTI43042, name: "borderRightColor", sons: null}, -{kind: 1, offset: "borderRightStyle", len: 0, typ: NTI43042, name: "borderRightStyle", sons: null}, -{kind: 1, offset: "borderRightWidth", len: 0, typ: NTI43042, name: "borderRightWidth", sons: null}, -{kind: 1, offset: "borderStyle", len: 0, typ: NTI43042, name: "borderStyle", sons: null}, -{kind: 1, offset: "borderTop", len: 0, typ: NTI43042, name: "borderTop", sons: null}, -{kind: 1, offset: "borderTopColor", len: 0, typ: NTI43042, name: "borderTopColor", sons: null}, -{kind: 1, offset: "borderTopStyle", len: 0, typ: NTI43042, name: "borderTopStyle", sons: null}, -{kind: 1, offset: "borderTopWidth", len: 0, typ: NTI43042, name: "borderTopWidth", sons: null}, -{kind: 1, offset: "borderWidth", len: 0, typ: NTI43042, name: "borderWidth", sons: null}, -{kind: 1, offset: "bottom", len: 0, typ: NTI43042, name: "bottom", sons: null}, -{kind: 1, offset: "captionSide", len: 0, typ: NTI43042, name: "captionSide", sons: null}, -{kind: 1, offset: "clear", len: 0, typ: NTI43042, name: "clear", sons: null}, -{kind: 1, offset: "clip", len: 0, typ: NTI43042, name: "clip", sons: null}, -{kind: 1, offset: "color", len: 0, typ: NTI43042, name: "color", sons: null}, -{kind: 1, offset: "cursor", len: 0, typ: NTI43042, name: "cursor", sons: null}, -{kind: 1, offset: "direction", len: 0, typ: NTI43042, name: "direction", sons: null}, -{kind: 1, offset: "display", len: 0, typ: NTI43042, name: "display", sons: null}, -{kind: 1, offset: "emptyCells", len: 0, typ: NTI43042, name: "emptyCells", sons: null}, -{kind: 1, offset: "cssFloat", len: 0, typ: NTI43042, name: "cssFloat", sons: null}, -{kind: 1, offset: "font", len: 0, typ: NTI43042, name: "font", sons: null}, -{kind: 1, offset: "fontFamily", len: 0, typ: NTI43042, name: "fontFamily", sons: null}, -{kind: 1, offset: "fontSize", len: 0, typ: NTI43042, name: "fontSize", sons: null}, -{kind: 1, offset: "fontStretch", len: 0, typ: NTI43042, name: "fontStretch", sons: null}, -{kind: 1, offset: "fontStyle", len: 0, typ: NTI43042, name: "fontStyle", sons: null}, -{kind: 1, offset: "fontVariant", len: 0, typ: NTI43042, name: "fontVariant", sons: null}, -{kind: 1, offset: "fontWeight", len: 0, typ: NTI43042, name: "fontWeight", sons: null}, -{kind: 1, offset: "height", len: 0, typ: NTI43042, name: "height", sons: null}, -{kind: 1, offset: "left", len: 0, typ: NTI43042, name: "left", sons: null}, -{kind: 1, offset: "letterSpacing", len: 0, typ: NTI43042, name: "letterSpacing", sons: null}, -{kind: 1, offset: "lineHeight", len: 0, typ: NTI43042, name: "lineHeight", sons: null}, -{kind: 1, offset: "listStyle", len: 0, typ: NTI43042, name: "listStyle", sons: null}, -{kind: 1, offset: "listStyleImage", len: 0, typ: NTI43042, name: "listStyleImage", sons: null}, -{kind: 1, offset: "listStylePosition", len: 0, typ: NTI43042, name: "listStylePosition", sons: null}, -{kind: 1, offset: "listStyleType", len: 0, typ: NTI43042, name: "listStyleType", sons: null}, -{kind: 1, offset: "margin", len: 0, typ: NTI43042, name: "margin", sons: null}, -{kind: 1, offset: "marginBottom", len: 0, typ: NTI43042, name: "marginBottom", sons: null}, -{kind: 1, offset: "marginLeft", len: 0, typ: NTI43042, name: "marginLeft", sons: null}, -{kind: 1, offset: "marginRight", len: 0, typ: NTI43042, name: "marginRight", sons: null}, -{kind: 1, offset: "marginTop", len: 0, typ: NTI43042, name: "marginTop", sons: null}, -{kind: 1, offset: "maxHeight", len: 0, typ: NTI43042, name: "maxHeight", sons: null}, -{kind: 1, offset: "maxWidth", len: 0, typ: NTI43042, name: "maxWidth", sons: null}, -{kind: 1, offset: "minHeight", len: 0, typ: NTI43042, name: "minHeight", sons: null}, -{kind: 1, offset: "minWidth", len: 0, typ: NTI43042, name: "minWidth", sons: null}, -{kind: 1, offset: "overflow", len: 0, typ: NTI43042, name: "overflow", sons: null}, -{kind: 1, offset: "padding", len: 0, typ: NTI43042, name: "padding", sons: null}, -{kind: 1, offset: "paddingBottom", len: 0, typ: NTI43042, name: "paddingBottom", sons: null}, -{kind: 1, offset: "paddingLeft", len: 0, typ: NTI43042, name: "paddingLeft", sons: null}, -{kind: 1, offset: "paddingRight", len: 0, typ: NTI43042, name: "paddingRight", sons: null}, -{kind: 1, offset: "paddingTop", len: 0, typ: NTI43042, name: "paddingTop", sons: null}, -{kind: 1, offset: "pageBreakAfter", len: 0, typ: NTI43042, name: "pageBreakAfter", sons: null}, -{kind: 1, offset: "pageBreakBefore", len: 0, typ: NTI43042, name: "pageBreakBefore", sons: null}, -{kind: 1, offset: "pointerEvents", len: 0, typ: NTI43042, name: "pointerEvents", sons: null}, -{kind: 1, offset: "position", len: 0, typ: NTI43042, name: "position", sons: null}, -{kind: 1, offset: "right", len: 0, typ: NTI43042, name: "right", sons: null}, -{kind: 1, offset: "scrollbar3dLightColor", len: 0, typ: NTI43042, name: "scrollbar3dLightColor", sons: null}, -{kind: 1, offset: "scrollbarArrowColor", len: 0, typ: NTI43042, name: "scrollbarArrowColor", sons: null}, -{kind: 1, offset: "scrollbarBaseColor", len: 0, typ: NTI43042, name: "scrollbarBaseColor", sons: null}, -{kind: 1, offset: "scrollbarDarkshadowColor", len: 0, typ: NTI43042, name: "scrollbarDarkshadowColor", sons: null}, -{kind: 1, offset: "scrollbarFaceColor", len: 0, typ: NTI43042, name: "scrollbarFaceColor", sons: null}, -{kind: 1, offset: "scrollbarHighlightColor", len: 0, typ: NTI43042, name: "scrollbarHighlightColor", sons: null}, -{kind: 1, offset: "scrollbarShadowColor", len: 0, typ: NTI43042, name: "scrollbarShadowColor", sons: null}, -{kind: 1, offset: "scrollbarTrackColor", len: 0, typ: NTI43042, name: "scrollbarTrackColor", sons: null}, -{kind: 1, offset: "tableLayout", len: 0, typ: NTI43042, name: "tableLayout", sons: null}, -{kind: 1, offset: "textAlign", len: 0, typ: NTI43042, name: "textAlign", sons: null}, -{kind: 1, offset: "textDecoration", len: 0, typ: NTI43042, name: "textDecoration", sons: null}, -{kind: 1, offset: "textIndent", len: 0, typ: NTI43042, name: "textIndent", sons: null}, -{kind: 1, offset: "textTransform", len: 0, typ: NTI43042, name: "textTransform", sons: null}, -{kind: 1, offset: "transform", len: 0, typ: NTI43042, name: "transform", sons: null}, -{kind: 1, offset: "top", len: 0, typ: NTI43042, name: "top", sons: null}, -{kind: 1, offset: "verticalAlign", len: 0, typ: NTI43042, name: "verticalAlign", sons: null}, -{kind: 1, offset: "visibility", len: 0, typ: NTI43042, name: "visibility", sons: null}, -{kind: 1, offset: "width", len: 0, typ: NTI43042, name: "width", sons: null}, -{kind: 1, offset: "wordSpacing", len: 0, typ: NTI43042, name: "wordSpacing", sons: null}, -{kind: 1, offset: "zIndex", len: 0, typ: NTI43006, name: "zIndex", sons: null}]}; -NTI84283.node = NNI84283; -NTI84283.base = NTI46808; -NTI84281.base = NTI84283; -var NNI84231 = {kind: 2, len: 14, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "attributes", len: 0, typ: NTI84561, name: "attributes", sons: null}, -{kind: 1, offset: "childNodes", len: 0, typ: NTI84563, name: "childNodes", sons: null}, -{kind: 1, offset: "children", len: 0, typ: NTI84565, name: "children", sons: null}, -{kind: 1, offset: "data", len: 0, typ: NTI43042, name: "data", sons: null}, -{kind: 1, offset: "firstChild", len: 0, typ: NTI84229, name: "firstChild", sons: null}, -{kind: 1, offset: "lastChild", len: 0, typ: NTI84229, name: "lastChild", sons: null}, -{kind: 1, offset: "nextSibling", len: 0, typ: NTI84229, name: "nextSibling", sons: null}, -{kind: 1, offset: "nodeName", len: 0, typ: NTI43042, name: "nodeName", sons: null}, -{kind: 1, offset: "nodeType", len: 0, typ: NTI84227, name: "nodeType", sons: null}, -{kind: 1, offset: "nodeValue", len: 0, typ: NTI43042, name: "nodeValue", sons: null}, -{kind: 1, offset: "parentNode", len: 0, typ: NTI84229, name: "parentNode", sons: null}, -{kind: 1, offset: "previousSibling", len: 0, typ: NTI84229, name: "previousSibling", sons: null}, -{kind: 1, offset: "innerHTML", len: 0, typ: NTI43042, name: "innerHTML", sons: null}, -{kind: 1, offset: "style", len: 0, typ: NTI84281, name: "style", sons: null}]}; -NTI84231.node = NNI84231; -var NNI84205 = {kind: 2, len: 20, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "onabort", len: 0, typ: NTI84372, name: "onabort", sons: null}, -{kind: 1, offset: "onblur", len: 0, typ: NTI84376, name: "onblur", sons: null}, -{kind: 1, offset: "onchange", len: 0, typ: NTI84380, name: "onchange", sons: null}, -{kind: 1, offset: "onclick", len: 0, typ: NTI84384, name: "onclick", sons: null}, -{kind: 1, offset: "ondblclick", len: 0, typ: NTI84388, name: "ondblclick", sons: null}, -{kind: 1, offset: "onerror", len: 0, typ: NTI84392, name: "onerror", sons: null}, -{kind: 1, offset: "onfocus", len: 0, typ: NTI84396, name: "onfocus", sons: null}, -{kind: 1, offset: "onkeydown", len: 0, typ: NTI84400, name: "onkeydown", sons: null}, -{kind: 1, offset: "onkeypress", len: 0, typ: NTI84404, name: "onkeypress", sons: null}, -{kind: 1, offset: "onkeyup", len: 0, typ: NTI84408, name: "onkeyup", sons: null}, -{kind: 1, offset: "onload", len: 0, typ: NTI84412, name: "onload", sons: null}, -{kind: 1, offset: "onmousedown", len: 0, typ: NTI84416, name: "onmousedown", sons: null}, -{kind: 1, offset: "onmousemove", len: 0, typ: NTI84420, name: "onmousemove", sons: null}, -{kind: 1, offset: "onmouseout", len: 0, typ: NTI84424, name: "onmouseout", sons: null}, -{kind: 1, offset: "onmouseover", len: 0, typ: NTI84428, name: "onmouseover", sons: null}, -{kind: 1, offset: "onmouseup", len: 0, typ: NTI84432, name: "onmouseup", sons: null}, -{kind: 1, offset: "onreset", len: 0, typ: NTI84436, name: "onreset", sons: null}, -{kind: 1, offset: "onselect", len: 0, typ: NTI84440, name: "onselect", sons: null}, -{kind: 1, offset: "onsubmit", len: 0, typ: NTI84444, name: "onsubmit", sons: null}, -{kind: 1, offset: "onunload", len: 0, typ: NTI84448, name: "onunload", sons: null}]}; -NTI84205.node = NNI84205; -NTI84205.base = NTI46808; -NTI84231.base = NTI84205; -NTI84229.base = NTI84231; -NTI86305.base = NTI84229; -NTI205327.base = NTI43042; -var NNI46862 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; -NTI46862.node = NNI46862; -NTI46862.base = NTI46828; -var NNI202074 = {kind: 2, len: 2, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "Field0", len: 0, typ: NTI43006, name: "Field0", sons: null}, -{kind: 1, offset: "Field1", len: 0, typ: NTI43032, name: "Field1", sons: null}]}; -NTI202074.node = NNI202074; +var NTI42032 = {size: 0,kind: 1,base: null,node: null,finalizer: null}; +var NTI195074 = {size: 0, kind: 18, base: null, node: null, finalizer: null}; +var NTI45862 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI197577 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; +var NTI81448 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI81444 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI81440 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI81436 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI81432 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI81428 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI81424 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI81420 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI81416 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI81412 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI81408 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI81404 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI81400 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI81396 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI81392 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI81388 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI81384 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI81380 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI81376 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI81372 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI81205 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI81283 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI81281 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; +var NTI81227 = {size: 0, kind: 14, base: null, node: null, finalizer: null}; +var NTI81565 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; +var NTI81563 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; +var NTI81561 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; +var NTI81231 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI81229 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; +var NTI83305 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; +var NTI45850 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI45858 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI42006 = {size: 0,kind: 31,base: null,node: null,finalizer: null}; +var NTI60156 = {size: 0, kind: 18, base: null, node: null, finalizer: null}; +var NTI45808 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI45914 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; +var NTI42016 = {size: 0,kind: 40,base: null,node: null,finalizer: null}; +var NTI42040 = {size: 0,kind: 28,base: null,node: null,finalizer: null}; +var NTI42042 = {size: 0,kind: 29,base: null,node: null,finalizer: null}; +var NTI45908 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; +var NTI45826 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI45828 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI45842 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI45846 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NNI45846 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI45846.node = NNI45846; +var NNI45842 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI45842.node = NNI45842; +var NNI45828 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI45828.node = NNI45828; +NTI45908.base = NTI45826; +NTI45914.base = NTI45826; +var NNI45826 = {kind: 2, len: 6, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "parent", len: 0, typ: NTI45908, name: "parent", sons: null}, +{kind: 1, offset: "name", len: 0, typ: NTI42042, name: "name", sons: null}, +{kind: 1, offset: "message", len: 0, typ: NTI42040, name: "msg", sons: null}, +{kind: 1, offset: "trace", len: 0, typ: NTI42040, name: "trace", sons: null}, +{kind: 1, offset: "raiseId", len: 0, typ: NTI42016, name: "raiseId", sons: null}, +{kind: 1, offset: "up", len: 0, typ: NTI45914, name: "up", sons: null}]}; +NTI45826.node = NNI45826; +var NNI45808 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI45808.node = NNI45808; +NTI45826.base = NTI45808; +NTI45828.base = NTI45826; +NTI45842.base = NTI45828; +NTI45846.base = NTI45842; +var NNI60156 = {kind: 2, len: 2, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "Field0", len: 0, typ: NTI42042, name: "Field0", sons: null}, +{kind: 1, offset: "Field1", len: 0, typ: NTI42006, name: "Field1", sons: null}]}; +NTI60156.node = NNI60156; +var NNI45858 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI45858.node = NNI45858; +NTI45858.base = NTI45828; +var NNI45850 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI45850.node = NNI45850; +NTI45850.base = NTI45828; +NTI81561.base = NTI81229; +NTI81563.base = NTI81229; +NTI81565.base = NTI81229; +var NNI81227 = {kind: 2, offset: 0, typ: null, name: null, len: 12, sons: {"1": {kind: 1, offset: 1, typ: NTI81227, name: "ElementNode", len: 0, sons: null}, +"2": {kind: 1, offset: 2, typ: NTI81227, name: "AttributeNode", len: 0, sons: null}, +"3": {kind: 1, offset: 3, typ: NTI81227, name: "TextNode", len: 0, sons: null}, +"4": {kind: 1, offset: 4, typ: NTI81227, name: "CDATANode", len: 0, sons: null}, +"5": {kind: 1, offset: 5, typ: NTI81227, name: "EntityRefNode", len: 0, sons: null}, +"6": {kind: 1, offset: 6, typ: NTI81227, name: "EntityNode", len: 0, sons: null}, +"7": {kind: 1, offset: 7, typ: NTI81227, name: "ProcessingInstructionNode", len: 0, sons: null}, +"8": {kind: 1, offset: 8, typ: NTI81227, name: "CommentNode", len: 0, sons: null}, +"9": {kind: 1, offset: 9, typ: NTI81227, name: "DocumentNode", len: 0, sons: null}, +"10": {kind: 1, offset: 10, typ: NTI81227, name: "DocumentTypeNode", len: 0, sons: null}, +"11": {kind: 1, offset: 11, typ: NTI81227, name: "DocumentFragmentNode", len: 0, sons: null}, +"12": {kind: 1, offset: 12, typ: NTI81227, name: "NotationNode", len: 0, sons: null}}}; +NTI81227.node = NNI81227; +var NNI81283 = {kind: 2, len: 91, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "background", len: 0, typ: NTI42042, name: "background", sons: null}, +{kind: 1, offset: "backgroundAttachment", len: 0, typ: NTI42042, name: "backgroundAttachment", sons: null}, +{kind: 1, offset: "backgroundColor", len: 0, typ: NTI42042, name: "backgroundColor", sons: null}, +{kind: 1, offset: "backgroundImage", len: 0, typ: NTI42042, name: "backgroundImage", sons: null}, +{kind: 1, offset: "backgroundPosition", len: 0, typ: NTI42042, name: "backgroundPosition", sons: null}, +{kind: 1, offset: "backgroundRepeat", len: 0, typ: NTI42042, name: "backgroundRepeat", sons: null}, +{kind: 1, offset: "border", len: 0, typ: NTI42042, name: "border", sons: null}, +{kind: 1, offset: "borderBottom", len: 0, typ: NTI42042, name: "borderBottom", sons: null}, +{kind: 1, offset: "borderBottomColor", len: 0, typ: NTI42042, name: "borderBottomColor", sons: null}, +{kind: 1, offset: "borderBottomStyle", len: 0, typ: NTI42042, name: "borderBottomStyle", sons: null}, +{kind: 1, offset: "borderBottomWidth", len: 0, typ: NTI42042, name: "borderBottomWidth", sons: null}, +{kind: 1, offset: "borderColor", len: 0, typ: NTI42042, name: "borderColor", sons: null}, +{kind: 1, offset: "borderLeft", len: 0, typ: NTI42042, name: "borderLeft", sons: null}, +{kind: 1, offset: "borderLeftColor", len: 0, typ: NTI42042, name: "borderLeftColor", sons: null}, +{kind: 1, offset: "borderLeftStyle", len: 0, typ: NTI42042, name: "borderLeftStyle", sons: null}, +{kind: 1, offset: "borderLeftWidth", len: 0, typ: NTI42042, name: "borderLeftWidth", sons: null}, +{kind: 1, offset: "borderRight", len: 0, typ: NTI42042, name: "borderRight", sons: null}, +{kind: 1, offset: "borderRightColor", len: 0, typ: NTI42042, name: "borderRightColor", sons: null}, +{kind: 1, offset: "borderRightStyle", len: 0, typ: NTI42042, name: "borderRightStyle", sons: null}, +{kind: 1, offset: "borderRightWidth", len: 0, typ: NTI42042, name: "borderRightWidth", sons: null}, +{kind: 1, offset: "borderStyle", len: 0, typ: NTI42042, name: "borderStyle", sons: null}, +{kind: 1, offset: "borderTop", len: 0, typ: NTI42042, name: "borderTop", sons: null}, +{kind: 1, offset: "borderTopColor", len: 0, typ: NTI42042, name: "borderTopColor", sons: null}, +{kind: 1, offset: "borderTopStyle", len: 0, typ: NTI42042, name: "borderTopStyle", sons: null}, +{kind: 1, offset: "borderTopWidth", len: 0, typ: NTI42042, name: "borderTopWidth", sons: null}, +{kind: 1, offset: "borderWidth", len: 0, typ: NTI42042, name: "borderWidth", sons: null}, +{kind: 1, offset: "bottom", len: 0, typ: NTI42042, name: "bottom", sons: null}, +{kind: 1, offset: "captionSide", len: 0, typ: NTI42042, name: "captionSide", sons: null}, +{kind: 1, offset: "clear", len: 0, typ: NTI42042, name: "clear", sons: null}, +{kind: 1, offset: "clip", len: 0, typ: NTI42042, name: "clip", sons: null}, +{kind: 1, offset: "color", len: 0, typ: NTI42042, name: "color", sons: null}, +{kind: 1, offset: "cursor", len: 0, typ: NTI42042, name: "cursor", sons: null}, +{kind: 1, offset: "direction", len: 0, typ: NTI42042, name: "direction", sons: null}, +{kind: 1, offset: "display", len: 0, typ: NTI42042, name: "display", sons: null}, +{kind: 1, offset: "emptyCells", len: 0, typ: NTI42042, name: "emptyCells", sons: null}, +{kind: 1, offset: "cssFloat", len: 0, typ: NTI42042, name: "cssFloat", sons: null}, +{kind: 1, offset: "font", len: 0, typ: NTI42042, name: "font", sons: null}, +{kind: 1, offset: "fontFamily", len: 0, typ: NTI42042, name: "fontFamily", sons: null}, +{kind: 1, offset: "fontSize", len: 0, typ: NTI42042, name: "fontSize", sons: null}, +{kind: 1, offset: "fontStretch", len: 0, typ: NTI42042, name: "fontStretch", sons: null}, +{kind: 1, offset: "fontStyle", len: 0, typ: NTI42042, name: "fontStyle", sons: null}, +{kind: 1, offset: "fontVariant", len: 0, typ: NTI42042, name: "fontVariant", sons: null}, +{kind: 1, offset: "fontWeight", len: 0, typ: NTI42042, name: "fontWeight", sons: null}, +{kind: 1, offset: "height", len: 0, typ: NTI42042, name: "height", sons: null}, +{kind: 1, offset: "left", len: 0, typ: NTI42042, name: "left", sons: null}, +{kind: 1, offset: "letterSpacing", len: 0, typ: NTI42042, name: "letterSpacing", sons: null}, +{kind: 1, offset: "lineHeight", len: 0, typ: NTI42042, name: "lineHeight", sons: null}, +{kind: 1, offset: "listStyle", len: 0, typ: NTI42042, name: "listStyle", sons: null}, +{kind: 1, offset: "listStyleImage", len: 0, typ: NTI42042, name: "listStyleImage", sons: null}, +{kind: 1, offset: "listStylePosition", len: 0, typ: NTI42042, name: "listStylePosition", sons: null}, +{kind: 1, offset: "listStyleType", len: 0, typ: NTI42042, name: "listStyleType", sons: null}, +{kind: 1, offset: "margin", len: 0, typ: NTI42042, name: "margin", sons: null}, +{kind: 1, offset: "marginBottom", len: 0, typ: NTI42042, name: "marginBottom", sons: null}, +{kind: 1, offset: "marginLeft", len: 0, typ: NTI42042, name: "marginLeft", sons: null}, +{kind: 1, offset: "marginRight", len: 0, typ: NTI42042, name: "marginRight", sons: null}, +{kind: 1, offset: "marginTop", len: 0, typ: NTI42042, name: "marginTop", sons: null}, +{kind: 1, offset: "maxHeight", len: 0, typ: NTI42042, name: "maxHeight", sons: null}, +{kind: 1, offset: "maxWidth", len: 0, typ: NTI42042, name: "maxWidth", sons: null}, +{kind: 1, offset: "minHeight", len: 0, typ: NTI42042, name: "minHeight", sons: null}, +{kind: 1, offset: "minWidth", len: 0, typ: NTI42042, name: "minWidth", sons: null}, +{kind: 1, offset: "overflow", len: 0, typ: NTI42042, name: "overflow", sons: null}, +{kind: 1, offset: "padding", len: 0, typ: NTI42042, name: "padding", sons: null}, +{kind: 1, offset: "paddingBottom", len: 0, typ: NTI42042, name: "paddingBottom", sons: null}, +{kind: 1, offset: "paddingLeft", len: 0, typ: NTI42042, name: "paddingLeft", sons: null}, +{kind: 1, offset: "paddingRight", len: 0, typ: NTI42042, name: "paddingRight", sons: null}, +{kind: 1, offset: "paddingTop", len: 0, typ: NTI42042, name: "paddingTop", sons: null}, +{kind: 1, offset: "pageBreakAfter", len: 0, typ: NTI42042, name: "pageBreakAfter", sons: null}, +{kind: 1, offset: "pageBreakBefore", len: 0, typ: NTI42042, name: "pageBreakBefore", sons: null}, +{kind: 1, offset: "pointerEvents", len: 0, typ: NTI42042, name: "pointerEvents", sons: null}, +{kind: 1, offset: "position", len: 0, typ: NTI42042, name: "position", sons: null}, +{kind: 1, offset: "right", len: 0, typ: NTI42042, name: "right", sons: null}, +{kind: 1, offset: "scrollbar3dLightColor", len: 0, typ: NTI42042, name: "scrollbar3dLightColor", sons: null}, +{kind: 1, offset: "scrollbarArrowColor", len: 0, typ: NTI42042, name: "scrollbarArrowColor", sons: null}, +{kind: 1, offset: "scrollbarBaseColor", len: 0, typ: NTI42042, name: "scrollbarBaseColor", sons: null}, +{kind: 1, offset: "scrollbarDarkshadowColor", len: 0, typ: NTI42042, name: "scrollbarDarkshadowColor", sons: null}, +{kind: 1, offset: "scrollbarFaceColor", len: 0, typ: NTI42042, name: "scrollbarFaceColor", sons: null}, +{kind: 1, offset: "scrollbarHighlightColor", len: 0, typ: NTI42042, name: "scrollbarHighlightColor", sons: null}, +{kind: 1, offset: "scrollbarShadowColor", len: 0, typ: NTI42042, name: "scrollbarShadowColor", sons: null}, +{kind: 1, offset: "scrollbarTrackColor", len: 0, typ: NTI42042, name: "scrollbarTrackColor", sons: null}, +{kind: 1, offset: "tableLayout", len: 0, typ: NTI42042, name: "tableLayout", sons: null}, +{kind: 1, offset: "textAlign", len: 0, typ: NTI42042, name: "textAlign", sons: null}, +{kind: 1, offset: "textDecoration", len: 0, typ: NTI42042, name: "textDecoration", sons: null}, +{kind: 1, offset: "textIndent", len: 0, typ: NTI42042, name: "textIndent", sons: null}, +{kind: 1, offset: "textTransform", len: 0, typ: NTI42042, name: "textTransform", sons: null}, +{kind: 1, offset: "transform", len: 0, typ: NTI42042, name: "transform", sons: null}, +{kind: 1, offset: "top", len: 0, typ: NTI42042, name: "top", sons: null}, +{kind: 1, offset: "verticalAlign", len: 0, typ: NTI42042, name: "verticalAlign", sons: null}, +{kind: 1, offset: "visibility", len: 0, typ: NTI42042, name: "visibility", sons: null}, +{kind: 1, offset: "width", len: 0, typ: NTI42042, name: "width", sons: null}, +{kind: 1, offset: "wordSpacing", len: 0, typ: NTI42042, name: "wordSpacing", sons: null}, +{kind: 1, offset: "zIndex", len: 0, typ: NTI42006, name: "zIndex", sons: null}]}; +NTI81283.node = NNI81283; +NTI81283.base = NTI45808; +NTI81281.base = NTI81283; +var NNI81231 = {kind: 2, len: 14, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "attributes", len: 0, typ: NTI81561, name: "attributes", sons: null}, +{kind: 1, offset: "childNodes", len: 0, typ: NTI81563, name: "childNodes", sons: null}, +{kind: 1, offset: "children", len: 0, typ: NTI81565, name: "children", sons: null}, +{kind: 1, offset: "data", len: 0, typ: NTI42042, name: "data", sons: null}, +{kind: 1, offset: "firstChild", len: 0, typ: NTI81229, name: "firstChild", sons: null}, +{kind: 1, offset: "lastChild", len: 0, typ: NTI81229, name: "lastChild", sons: null}, +{kind: 1, offset: "nextSibling", len: 0, typ: NTI81229, name: "nextSibling", sons: null}, +{kind: 1, offset: "nodeName", len: 0, typ: NTI42042, name: "nodeName", sons: null}, +{kind: 1, offset: "nodeType", len: 0, typ: NTI81227, name: "nodeType", sons: null}, +{kind: 1, offset: "nodeValue", len: 0, typ: NTI42042, name: "nodeValue", sons: null}, +{kind: 1, offset: "parentNode", len: 0, typ: NTI81229, name: "parentNode", sons: null}, +{kind: 1, offset: "previousSibling", len: 0, typ: NTI81229, name: "previousSibling", sons: null}, +{kind: 1, offset: "innerHTML", len: 0, typ: NTI42042, name: "innerHTML", sons: null}, +{kind: 1, offset: "style", len: 0, typ: NTI81281, name: "style", sons: null}]}; +NTI81231.node = NNI81231; +var NNI81205 = {kind: 2, len: 20, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "onabort", len: 0, typ: NTI81372, name: "onabort", sons: null}, +{kind: 1, offset: "onblur", len: 0, typ: NTI81376, name: "onblur", sons: null}, +{kind: 1, offset: "onchange", len: 0, typ: NTI81380, name: "onchange", sons: null}, +{kind: 1, offset: "onclick", len: 0, typ: NTI81384, name: "onclick", sons: null}, +{kind: 1, offset: "ondblclick", len: 0, typ: NTI81388, name: "ondblclick", sons: null}, +{kind: 1, offset: "onerror", len: 0, typ: NTI81392, name: "onerror", sons: null}, +{kind: 1, offset: "onfocus", len: 0, typ: NTI81396, name: "onfocus", sons: null}, +{kind: 1, offset: "onkeydown", len: 0, typ: NTI81400, name: "onkeydown", sons: null}, +{kind: 1, offset: "onkeypress", len: 0, typ: NTI81404, name: "onkeypress", sons: null}, +{kind: 1, offset: "onkeyup", len: 0, typ: NTI81408, name: "onkeyup", sons: null}, +{kind: 1, offset: "onload", len: 0, typ: NTI81412, name: "onload", sons: null}, +{kind: 1, offset: "onmousedown", len: 0, typ: NTI81416, name: "onmousedown", sons: null}, +{kind: 1, offset: "onmousemove", len: 0, typ: NTI81420, name: "onmousemove", sons: null}, +{kind: 1, offset: "onmouseout", len: 0, typ: NTI81424, name: "onmouseout", sons: null}, +{kind: 1, offset: "onmouseover", len: 0, typ: NTI81428, name: "onmouseover", sons: null}, +{kind: 1, offset: "onmouseup", len: 0, typ: NTI81432, name: "onmouseup", sons: null}, +{kind: 1, offset: "onreset", len: 0, typ: NTI81436, name: "onreset", sons: null}, +{kind: 1, offset: "onselect", len: 0, typ: NTI81440, name: "onselect", sons: null}, +{kind: 1, offset: "onsubmit", len: 0, typ: NTI81444, name: "onsubmit", sons: null}, +{kind: 1, offset: "onunload", len: 0, typ: NTI81448, name: "onunload", sons: null}]}; +NTI81205.node = NNI81205; +NTI81205.base = NTI45808; +NTI81231.base = NTI81205; +NTI81229.base = NTI81231; +NTI83305.base = NTI81229; +NTI197577.base = NTI42042; +var NNI45862 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI45862.node = NNI45862; +NTI45862.base = NTI45828; +var NNI195074 = {kind: 2, len: 2, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "Field0", len: 0, typ: NTI42006, name: "Field0", sons: null}, +{kind: 1, offset: "Field1", len: 0, typ: NTI42032, name: "Field1", sons: null}]}; +NTI195074.node = NNI195074; -function makeNimstrLit(c_64273) { - var ln = c_64273.length; +function makeNimstrLit(c_62058) { + var ln = c_62058.length; var result = new Array(ln); for (var i = 0; i < ln; ++i) { - result[i] = c_64273.charCodeAt(i); + result[i] = c_62058.charCodeAt(i); } return result; @@ -279,99 +279,99 @@ function setConstr() { } var ConstSet1 = setConstr(17, 16, 4, 18, 27, 19, 23, 22, 21); -function nimCopy(dest_65442, src_65443, ti_65444) { - var result_65619 = null; +function nimCopy(dest_63027, src_63028, ti_63029) { + var result_63219 = null; - switch (ti_65444.kind) { + switch (ti_63029.kind) { case 21: case 22: case 23: case 5: - if (!(is_fat_pointer_65401(ti_65444))) { - result_65619 = src_65443; + if (!(is_fat_pointer_63001(ti_63029))) { + result_63219 = src_63028; } else { - result_65619 = [src_65443[0], src_65443[1]]; + result_63219 = [src_63028[0], src_63028[1]]; } break; case 19: - if (dest_65442 === null || dest_65442 === undefined) { - dest_65442 = {}; + if (dest_63027 === null || dest_63027 === undefined) { + dest_63027 = {}; } else { - for (var key in dest_65442) { delete dest_65442[key]; } + for (var key in dest_63027) { delete dest_63027[key]; } } - for (var key in src_65443) { dest_65442[key] = src_65443[key]; } - result_65619 = dest_65442; + for (var key in src_63028) { dest_63027[key] = src_63028[key]; } + result_63219 = dest_63027; break; case 18: case 17: - if (!((ti_65444.base == null))) { - result_65619 = nimCopy(dest_65442, src_65443, ti_65444.base); + if (!((ti_63029.base == null))) { + result_63219 = nimCopy(dest_63027, src_63028, ti_63029.base); } else { - if ((ti_65444.kind == 17)) { - result_65619 = (dest_65442 === null || dest_65442 === undefined) ? {m_type: ti_65444} : dest_65442; + if ((ti_63029.kind == 17)) { + result_63219 = (dest_63027 === null || dest_63027 === undefined) ? {m_type: ti_63029} : dest_63027; } else { - result_65619 = (dest_65442 === null || dest_65442 === undefined) ? {} : dest_65442; + result_63219 = (dest_63027 === null || dest_63027 === undefined) ? {} : dest_63027; } } - nimCopyAux(result_65619, src_65443, ti_65444.node); + nimCopyAux(result_63219, src_63028, ti_63029.node); break; case 24: case 4: case 27: case 16: - if (src_65443 === null) { - result_65619 = null; + if (src_63028 === null) { + result_63219 = null; } else { - if (dest_65442 === null || dest_65442 === undefined) { - dest_65442 = new Array(src_65443.length); + if (dest_63027 === null || dest_63027 === undefined) { + dest_63027 = new Array(src_63028.length); } else { - dest_65442.length = src_65443.length; + dest_63027.length = src_63028.length; } - result_65619 = dest_65442; - for (var i = 0; i < src_65443.length; ++i) { - result_65619[i] = nimCopy(result_65619[i], src_65443[i], ti_65444.base); + result_63219 = dest_63027; + for (var i = 0; i < src_63028.length; ++i) { + result_63219[i] = nimCopy(result_63219[i], src_63028[i], ti_63029.base); } } break; case 28: - if (src_65443 !== null) { - result_65619 = src_65443.slice(0); + if (src_63028 !== null) { + result_63219 = src_63028.slice(0); } break; default: - result_65619 = src_65443; + result_63219 = src_63028; break; } - return result_65619; + return result_63219; } -function arrayConstr(len_65761, value_65762, typ_65763) { - var result = new Array(len_65761); - for (var i = 0; i < len_65761; ++i) result[i] = nimCopy(null, value_65762, typ_65763); +function arrayConstr(len_63286, value_63287, typ_63288) { + var result = new Array(len_63286); + for (var i = 0; i < len_63286; ++i) result[i] = nimCopy(null, value_63287, typ_63288); return result; } -function cstrToNimstr(c_64290) { - var ln = c_64290.length; +function cstrToNimstr(c_62075) { + var ln = c_62075.length; var result = new Array(ln); var r = 0; for (var i = 0; i < ln; ++i) { - var ch = c_64290.charCodeAt(i); + var ch = c_62075.charCodeAt(i); if (ch < 128) { result[r] = ch; @@ -386,7 +386,7 @@ function cstrToNimstr(c_64290) { } else { ++i; - ch = 65536 + (((ch & 1023) << 10) | (c_64290.charCodeAt(i) & 1023)); + ch = 65536 + (((ch & 1023) << 10) | (c_62075.charCodeAt(i) & 1023)); result[r] = (ch >> 18) | 240; ++r; result[r] = ((ch >> 12) & 63) | 128; @@ -405,9 +405,9 @@ function cstrToNimstr(c_64290) { } -function toJSStr(s_64307) { - if (s_64307 === null) return ""; - var len = s_64307.length; +function toJSStr(s_62092) { + if (s_62092 === null) return ""; + var len = s_62092.length; var asciiPart = new Array(len); var fcc = String.fromCharCode; var nonAsciiPart = null; @@ -415,15 +415,15 @@ function toJSStr(s_64307) { for (var i = 0; i < len; ++i) { if (nonAsciiPart !== null) { var offset = (i - nonAsciiOffset) * 2; - var code = s_64307[i].toString(16); + var code = s_62092[i].toString(16); if (code.length == 1) { code = "0"+code; } nonAsciiPart[offset] = "%"; nonAsciiPart[offset + 1] = code; } - else if (s_64307[i] < 128) - asciiPart[i] = fcc(s_64307[i]); + else if (s_62092[i] < 128) + asciiPart[i] = fcc(s_62092[i]); else { asciiPart.length = i; nonAsciiOffset = i; @@ -439,20 +439,20 @@ function toJSStr(s_64307) { } -function raiseException(e_62818, ename_62819) { - e_62818.name = ename_62819; +function raiseException(e_60618, ename_60619) { + e_60618.name = ename_60619; if ((excHandler == 0)) { - unhandledException(e_62818); + unhandledException(e_60618); } - e_62818.trace = nimCopy(null, raw_write_stack_trace_62543(), NTI43040); - throw e_62818; + e_60618.trace = nimCopy(null, raw_write_stack_trace_60468(), NTI42040); + throw e_60618; } -function addInt(a_64603, b_64604) { - var result = a_64603 + b_64604; +function addInt(a_62403, b_62404) { + var result = a_62403 + b_62404; if (result > 2147483647 || result < -2147483648) raiseOverflow(); return result; @@ -460,28 +460,28 @@ function addInt(a_64603, b_64604) { } -function chckIndx(i_65780, a_65781, b_65782) { +function chckIndx(i_63305, a_63306, b_63307) { var Tmp1; - var result_65783 = 0; + var result_63308 = 0; BeforeRet: do { - if (!(a_65781 <= i_65780)) Tmp1 = false; else { Tmp1 = (i_65780 <= b_65782); } if (Tmp1) { - result_65783 = i_65780; + if (!(a_63306 <= i_63305)) Tmp1 = false; else { Tmp1 = (i_63305 <= b_63307); } if (Tmp1) { + result_63308 = i_63305; break BeforeRet; } else { - raiseIndexError(i_65780, a_65781, b_65782); + raiseIndexError(i_63305, a_63306, b_63307); } } while (false); - return result_65783; + return result_63308; } -function subInt(a_64621, b_64622) { - var result = a_64621 - b_64622; +function subInt(a_62421, b_62422) { + var result = a_62421 - b_62422; if (result > 2147483647 || result < -2147483648) raiseOverflow(); return result; @@ -490,14 +490,14 @@ function subInt(a_64621, b_64622) { } var ConstSet2 = setConstr([65, 90]); -function chckRange(i_65814, a_65815, b_65816) { +function chckRange(i_63324, a_63325, b_63326) { var Tmp1; - var result_65817 = 0; + var result_63327 = 0; BeforeRet: do { - if (!(a_65815 <= i_65814)) Tmp1 = false; else { Tmp1 = (i_65814 <= b_65816); } if (Tmp1) { - result_65817 = i_65814; + if (!(a_63325 <= i_63324)) Tmp1 = false; else { Tmp1 = (i_63324 <= b_63326); } if (Tmp1) { + result_63327 = i_63324; break BeforeRet; } else { @@ -506,14 +506,14 @@ function chckRange(i_65814, a_65815, b_65816) { } while (false); - return result_65817; + return result_63327; } var ConstSet3 = setConstr(95, 32, 46); var ConstSet4 = setConstr(95, 32, 46); -function mulInt(a_64639, b_64640) { - var result = a_64639 * b_64640; +function mulInt(a_62439, b_62440) { + var result = a_62439 * b_62440; if (result > 2147483647 || result < -2147483648) raiseOverflow(); return result; @@ -525,51 +525,51 @@ var ConstSet6 = setConstr([65, 90], [97, 122]); var ConstSet7 = setConstr([97, 122]); var ConstSet8 = setConstr([65, 90]); -function nimMax(a_64973, b_64974) { +function nimMax(a_62758, b_62759) { var Tmp1; - var result_64975 = 0; + var result_62760 = 0; BeforeRet: do { - if ((b_64974 <= a_64973)) { - Tmp1 = a_64973; + if ((b_62759 <= a_62758)) { + Tmp1 = a_62758; } else { - Tmp1 = b_64974; + Tmp1 = b_62759; } - result_64975 = Tmp1; + result_62760 = Tmp1; break BeforeRet; } while (false); - return result_64975; + return result_62760; } -function nimMin(a_64955, b_64956) { +function nimMin(a_62740, b_62741) { var Tmp1; - var result_64957 = 0; + var result_62742 = 0; BeforeRet: do { - if ((a_64955 <= b_64956)) { - Tmp1 = a_64955; + if ((a_62740 <= b_62741)) { + Tmp1 = a_62740; } else { - Tmp1 = b_64956; + Tmp1 = b_62741; } - result_64957 = Tmp1; + result_62742 = Tmp1; break BeforeRet; } while (false); - return result_64957; + return result_62742; } var nim_program_result = 0; -var global_raise_hook_59618 = [null]; -var local_raise_hook_59623 = [null]; -var out_of_mem_hook_59626 = [null]; +var global_raise_hook_57618 = [null]; +var local_raise_hook_57623 = [null]; +var out_of_mem_hook_57626 = [null]; if (!Math.trunc) { Math.trunc = function(v) { v = +v; @@ -578,38 +578,38 @@ var out_of_mem_hook_59626 = [null]; return (v - v % 1) || (v < 0 ? -0 : v === 0 ? v : 0); }; } -var alternative_205020 = [null]; +var alternative_197315 = [null]; -function is_fat_pointer_65401(ti_65403) { - var result_65404 = false; +function is_fat_pointer_63001(ti_63003) { + var result_63004 = false; BeforeRet: do { - result_65404 = !((ConstSet1[ti_65403.base.kind] != undefined)); + result_63004 = !((ConstSet1[ti_63003.base.kind] != undefined)); break BeforeRet; } while (false); - return result_65404; + return result_63004; } -function nimCopyAux(dest_65447, src_65448, n_65450) { - switch (n_65450.kind) { +function nimCopyAux(dest_63032, src_63033, n_63035) { + switch (n_63035.kind) { case 0: break; case 1: - dest_65447[n_65450.offset] = nimCopy(dest_65447[n_65450.offset], src_65448[n_65450.offset], n_65450.typ); + dest_63032[n_63035.offset] = nimCopy(dest_63032[n_63035.offset], src_63033[n_63035.offset], n_63035.typ); break; case 2: - for (var i = 0; i < n_65450.sons.length; i++) { - nimCopyAux(dest_65447, src_65448, n_65450.sons[i]); + for (var i = 0; i < n_63035.sons.length; i++) { + nimCopyAux(dest_63032, src_63033, n_63035.sons[i]); } break; case 3: - dest_65447[n_65450.offset] = nimCopy(dest_65447[n_65450.offset], src_65448[n_65450.offset], n_65450.typ); - for (var i = 0; i < n_65450.sons.length; ++i) { - nimCopyAux(dest_65447, src_65448, n_65450.sons[i][1]); + dest_63032[n_63035.offset] = nimCopy(dest_63032[n_63035.offset], src_63033[n_63035.offset], n_63035.typ); + for (var i = 0; i < n_63035.sons.length; ++i) { + nimCopyAux(dest_63032, src_63033, n_63035.sons[i][1]); } break; @@ -618,112 +618,112 @@ function nimCopyAux(dest_65447, src_65448, n_65450) { } -function add_59638(x_59641, x_59641_Idx, y_59642) { - if (x_59641[x_59641_Idx] === null) { x_59641[x_59641_Idx] = []; } - var off = x_59641[x_59641_Idx].length; - x_59641[x_59641_Idx].length += y_59642.length; - for (var i = 0; i < y_59642.length; ++i) { - x_59641[x_59641_Idx][off+i] = y_59642.charCodeAt(i); +function add_57638(x_57641, x_57641_Idx, y_57642) { + if (x_57641[x_57641_Idx] === null) { x_57641[x_57641_Idx] = []; } + var off = x_57641[x_57641_Idx].length; + x_57641[x_57641_Idx].length += y_57642.length; + for (var i = 0; i < y_57642.length; ++i) { + x_57641[x_57641_Idx][off+i] = y_57642.charCodeAt(i); } } -function aux_write_stack_trace_62226(f_62228) { +function aux_write_stack_trace_60151(f_60153) { var Tmp3; - var result_62229 = [null]; + var result_60154 = [null]; - var it_62237 = f_62228; - var i_62239 = 0; - var total_62241 = 0; - var temp_frames_62248 = arrayConstr(64, {Field0: null, Field1: 0}, NTI62231); + var it_60162 = f_60153; + var i_60164 = 0; + var total_60166 = 0; + var temp_frames_60173 = arrayConstr(64, {Field0: null, Field1: 0}, NTI60156); L1: do { L2: while (true) { - if (!!((it_62237 == null))) Tmp3 = false; else { Tmp3 = (i_62239 <= 63); } if (!Tmp3) break L2; - temp_frames_62248[i_62239].Field0 = it_62237.procname; - temp_frames_62248[i_62239].Field1 = it_62237.line; - i_62239 += 1; - total_62241 += 1; - it_62237 = it_62237.prev; + if (!!((it_60162 == null))) Tmp3 = false; else { Tmp3 = (i_60164 <= 63); } if (!Tmp3) break L2; + temp_frames_60173[i_60164].Field0 = it_60162.procname; + temp_frames_60173[i_60164].Field1 = it_60162.line; + i_60164 += 1; + total_60166 += 1; + it_60162 = it_60162.prev; } } while(false); L4: do { L5: while (true) { - if (!!((it_62237 == null))) break L5; - total_62241 += 1; - it_62237 = it_62237.prev; + if (!!((it_60162 == null))) break L5; + total_60166 += 1; + it_60162 = it_60162.prev; } } while(false); - result_62229[0] = nimCopy(null, [], NTI43040); - if (!((total_62241 == i_62239))) { - if (result_62229[0] != null) { result_62229[0] = (result_62229[0]).concat(makeNimstrLit("(")); } else { result_62229[0] = makeNimstrLit("("); }; - if (result_62229[0] != null) { result_62229[0] = (result_62229[0]).concat(cstrToNimstr(((total_62241 - i_62239))+"")); } else { result_62229[0] = cstrToNimstr(((total_62241 - i_62239))+"").slice(); }; - if (result_62229[0] != null) { result_62229[0] = (result_62229[0]).concat(makeNimstrLit(" calls omitted) ...\x0A")); } else { result_62229[0] = makeNimstrLit(" calls omitted) ...\x0A"); }; + result_60154[0] = nimCopy(null, [], NTI42040); + if (!((total_60166 == i_60164))) { + if (result_60154[0] != null) { result_60154[0] = (result_60154[0]).concat(makeNimstrLit("(")); } else { result_60154[0] = makeNimstrLit("("); }; + if (result_60154[0] != null) { result_60154[0] = (result_60154[0]).concat(cstrToNimstr(((total_60166 - i_60164))+"")); } else { result_60154[0] = cstrToNimstr(((total_60166 - i_60164))+"").slice(); }; + if (result_60154[0] != null) { result_60154[0] = (result_60154[0]).concat(makeNimstrLit(" calls omitted) ...\x0A")); } else { result_60154[0] = makeNimstrLit(" calls omitted) ...\x0A"); }; } L6: do { - var j_62421 = 0; - var colontmp__205206 = 0; - colontmp__205206 = (i_62239 - 1); - var res_205211 = colontmp__205206; + var j_60421 = 0; + var colontmp__197456 = 0; + colontmp__197456 = (i_60164 - 1); + var res_197461 = colontmp__197456; L7: do { L8: while (true) { - if (!(0 <= res_205211)) break L8; - j_62421 = res_205211; - add_59638(result_62229, 0, temp_frames_62248[j_62421].Field0); - if ((0 < temp_frames_62248[j_62421].Field1)) { - if (result_62229[0] != null) { result_62229[0] = (result_62229[0]).concat(makeNimstrLit(", line: ")); } else { result_62229[0] = makeNimstrLit(", line: "); }; - if (result_62229[0] != null) { result_62229[0] = (result_62229[0]).concat(cstrToNimstr((temp_frames_62248[j_62421].Field1)+"")); } else { result_62229[0] = cstrToNimstr((temp_frames_62248[j_62421].Field1)+"").slice(); }; + if (!(0 <= res_197461)) break L8; + j_60421 = res_197461; + add_57638(result_60154, 0, temp_frames_60173[j_60421].Field0); + if ((0 < temp_frames_60173[j_60421].Field1)) { + if (result_60154[0] != null) { result_60154[0] = (result_60154[0]).concat(makeNimstrLit(", line: ")); } else { result_60154[0] = makeNimstrLit(", line: "); }; + if (result_60154[0] != null) { result_60154[0] = (result_60154[0]).concat(cstrToNimstr((temp_frames_60173[j_60421].Field1)+"")); } else { result_60154[0] = cstrToNimstr((temp_frames_60173[j_60421].Field1)+"").slice(); }; } - if (result_62229[0] != null) { result_62229[0] = (result_62229[0]).concat(makeNimstrLit("\x0A")); } else { result_62229[0] = makeNimstrLit("\x0A"); }; - res_205211 -= 1; + if (result_60154[0] != null) { result_60154[0] = (result_60154[0]).concat(makeNimstrLit("\x0A")); } else { result_60154[0] = makeNimstrLit("\x0A"); }; + res_197461 -= 1; } } while(false); } while(false); - return result_62229[0]; + return result_60154[0]; } -function raw_write_stack_trace_62543() { - var result_62545 = null; +function raw_write_stack_trace_60468() { + var result_60470 = null; if (!((framePtr == null))) { - result_62545 = nimCopy(null, (makeNimstrLit("Traceback (most recent call last)\x0A") || []).concat(aux_write_stack_trace_62226(framePtr) || []), NTI43040); + result_60470 = nimCopy(null, (makeNimstrLit("Traceback (most recent call last)\x0A") || []).concat(aux_write_stack_trace_60151(framePtr) || []), NTI42040); } else { - result_62545 = nimCopy(null, makeNimstrLit("No stack traceback available\x0A"), NTI43040); + result_60470 = nimCopy(null, makeNimstrLit("No stack traceback available\x0A"), NTI42040); } - return result_62545; + return result_60470; } -function unhandledException(e_62634) { - var buf_62635 = [[]]; - if (!(((e_62634.message != null ? e_62634.message.length : 0) == 0))) { - if (buf_62635[0] != null) { buf_62635[0] = (buf_62635[0]).concat(makeNimstrLit("Error: unhandled exception: ")); } else { buf_62635[0] = makeNimstrLit("Error: unhandled exception: "); }; - if (buf_62635[0] != null) { buf_62635[0] = (buf_62635[0]).concat(e_62634.message); } else { buf_62635[0] = e_62634.message.slice(); }; +function unhandledException(e_60529) { + var buf_60530 = [[]]; + if (!(((e_60529.message != null ? e_60529.message.length : 0) == 0))) { + if (buf_60530[0] != null) { buf_60530[0] = (buf_60530[0]).concat(makeNimstrLit("Error: unhandled exception: ")); } else { buf_60530[0] = makeNimstrLit("Error: unhandled exception: "); }; + if (buf_60530[0] != null) { buf_60530[0] = (buf_60530[0]).concat(e_60529.message); } else { buf_60530[0] = e_60529.message.slice(); }; } else { - if (buf_62635[0] != null) { buf_62635[0] = (buf_62635[0]).concat(makeNimstrLit("Error: unhandled exception")); } else { buf_62635[0] = makeNimstrLit("Error: unhandled exception"); }; + if (buf_60530[0] != null) { buf_60530[0] = (buf_60530[0]).concat(makeNimstrLit("Error: unhandled exception")); } else { buf_60530[0] = makeNimstrLit("Error: unhandled exception"); }; } - if (buf_62635[0] != null) { buf_62635[0] = (buf_62635[0]).concat(makeNimstrLit(" [")); } else { buf_62635[0] = makeNimstrLit(" ["); }; - add_59638(buf_62635, 0, e_62634.name); - if (buf_62635[0] != null) { buf_62635[0] = (buf_62635[0]).concat(makeNimstrLit("]\x0A")); } else { buf_62635[0] = makeNimstrLit("]\x0A"); }; - if (buf_62635[0] != null) { buf_62635[0] = (buf_62635[0]).concat(raw_write_stack_trace_62543()); } else { buf_62635[0] = raw_write_stack_trace_62543().slice(); }; - var cbuf_62801 = toJSStr(buf_62635[0]); + if (buf_60530[0] != null) { buf_60530[0] = (buf_60530[0]).concat(makeNimstrLit(" [")); } else { buf_60530[0] = makeNimstrLit(" ["); }; + add_57638(buf_60530, 0, e_60529.name); + if (buf_60530[0] != null) { buf_60530[0] = (buf_60530[0]).concat(makeNimstrLit("]\x0A")); } else { buf_60530[0] = makeNimstrLit("]\x0A"); }; + if (buf_60530[0] != null) { buf_60530[0] = (buf_60530[0]).concat(raw_write_stack_trace_60468()); } else { buf_60530[0] = raw_write_stack_trace_60468().slice(); }; + var cbuf_60601 = toJSStr(buf_60530[0]); framePtr = null; if (typeof(Error) !== "undefined") { - throw new Error(cbuf_62801); + throw new Error(cbuf_60601); } else { - throw cbuf_62801; + throw cbuf_60601; } @@ -731,49 +731,49 @@ function unhandledException(e_62634) { } function raiseOverflow() { - var e_63261 = null; - e_63261 = {m_type: NTI46846, parent: null, name: null, message: null, trace: null, raiseId: 0, up: null}; - e_63261.message = nimCopy(null, makeNimstrLit("over- or underflow"), NTI43040); - e_63261.parent = null; - raiseException(e_63261, "OverflowError"); + var e_61046 = null; + e_61046 = {m_type: NTI45846, parent: null, name: null, message: null, trace: null, raiseId: 0, up: null}; + e_61046.message = nimCopy(null, makeNimstrLit("over- or underflow"), NTI42040); + e_61046.parent = null; + raiseException(e_61046, "OverflowError"); } -function is_whitespace_204144(text_204146) { - return !/[^\s]/.test(text_204146); +function is_whitespace_196654(text_196656) { + return !/[^\s]/.test(text_196656); } -function is_whitespace_204161(x_204163) { +function is_whitespace_196671(x_196673) { var Tmp1; var Tmp2; - var result_204164 = false; + var result_196674 = false; var F={procname:"dochack.isWhitespace",prev:framePtr,filename:"dochack.nim",line:0}; framePtr = F; F.line = 134; - if (!(x_204163.nodeName == "#text")) Tmp2 = false; else { Tmp2 = is_whitespace_204144(x_204163.textContent); } if (Tmp2) Tmp1 = true; else { Tmp1 = (x_204163.nodeName == "#comment"); } result_204164 = Tmp1; + if (!(x_196673.nodeName == "#text")) Tmp2 = false; else { Tmp2 = is_whitespace_196654(x_196673.textContent); } if (Tmp2) Tmp1 = true; else { Tmp1 = (x_196673.nodeName == "#comment"); } result_196674 = Tmp1; framePtr = F.prev; - return result_204164; + return result_196674; } -function raiseIndexError(i_63858, a_63859, b_63860) { - var e_63864 = null; - e_63864 = {m_type: NTI46858, parent: null, name: null, message: null, trace: null, raiseId: 0, up: null}; - e_63864.message = nimCopy(null, (makeNimstrLit("index ") || []).concat(cstrToNimstr((i_63858)+"") || [],makeNimstrLit(" not in ") || [],cstrToNimstr((a_63859)+"") || [],makeNimstrLit(" .. ") || [],cstrToNimstr((b_63860)+"") || []), NTI43040); - e_63864.parent = null; - raiseException(e_63864, "IndexError"); +function raiseIndexError(i_61643, a_61644, b_61645) { + var e_61649 = null; + e_61649 = {m_type: NTI45858, parent: null, name: null, message: null, trace: null, raiseId: 0, up: null}; + e_61649.message = nimCopy(null, (makeNimstrLit("index ") || []).concat(cstrToNimstr((i_61643)+"") || [],makeNimstrLit(" not in ") || [],cstrToNimstr((a_61644)+"") || [],makeNimstrLit(" .. ") || [],cstrToNimstr((b_61645)+"") || []), NTI42040); + e_61649.parent = null; + raiseException(e_61649, "IndexError"); } -function to_toc_204178(x_204180, father_204181) { +function to_toc_196688(x_196690, father_196691) { var Tmp5; var Tmp6; var Tmp7; @@ -782,151 +782,151 @@ function to_toc_204178(x_204180, father_204181) { var F={procname:"dochack.toToc",prev:framePtr,filename:"dochack.nim",line:0}; framePtr = F; - if ((x_204180.nodeName == "UL")) { + if ((x_196690.nodeName == "UL")) { F.line = 139; - var f_204200 = {heading: null, kids: [], sortId: (father_204181.kids != null ? father_204181.kids.length : 0), doSort: false}; + var f_196710 = {heading: null, kids: [], sortId: (father_196691.kids != null ? father_196691.kids.length : 0), doSort: false}; F.line = 140; - var i_204202 = 0; + var i_196712 = 0; L1: do { F.line = 141; L2: while (true) { - if (!(i_204202 < x_204180.childNodes.length)) break L2; + if (!(i_196712 < x_196690.childNodes.length)) break L2; F.line = 142; - var nxt_204203 = addInt(i_204202, 1); + var nxt_196713 = addInt(i_196712, 1); L3: do { F.line = 143; L4: while (true) { - if (!(nxt_204203 < x_204180.childNodes.length)) Tmp5 = false; else { Tmp5 = is_whitespace_204161(x_204180.childNodes[nxt_204203]); } if (!Tmp5) break L4; + if (!(nxt_196713 < x_196690.childNodes.length)) Tmp5 = false; else { Tmp5 = is_whitespace_196671(x_196690.childNodes[nxt_196713]); } if (!Tmp5) break L4; F.line = 144; - nxt_204203 = addInt(nxt_204203, 1); + nxt_196713 = addInt(nxt_196713, 1); } } while(false); - if (!(nxt_204203 < x_204180.childNodes.length)) Tmp8 = false; else { Tmp8 = (x_204180.childNodes[i_204202].nodeName == "LI"); } if (!Tmp8) Tmp7 = false; else { Tmp7 = (x_204180.childNodes[i_204202].childNodes.length == 1); } if (!Tmp7) Tmp6 = false; else { Tmp6 = (x_204180.childNodes[nxt_204203].nodeName == "UL"); } if (Tmp6) { + if (!(nxt_196713 < x_196690.childNodes.length)) Tmp8 = false; else { Tmp8 = (x_196690.childNodes[i_196712].nodeName == "LI"); } if (!Tmp8) Tmp7 = false; else { Tmp7 = (x_196690.childNodes[i_196712].childNodes.length == 1); } if (!Tmp7) Tmp6 = false; else { Tmp6 = (x_196690.childNodes[nxt_196713].nodeName == "UL"); } if (Tmp6) { F.line = 147; - var e_204228 = {heading: x_204180.childNodes[i_204202].childNodes[0], kids: [], sortId: (f_204200.kids != null ? f_204200.kids.length : 0), doSort: false}; + var e_196738 = {heading: x_196690.childNodes[i_196712].childNodes[0], kids: [], sortId: (f_196710.kids != null ? f_196710.kids.length : 0), doSort: false}; F.line = 148; - var it_204229 = x_204180.childNodes[nxt_204203]; + var it_196739 = x_196690.childNodes[nxt_196713]; L9: do { F.line = 149; - var j_204236 = 0; - F.line = 2631; - var colontmp__205182 = 0; + var j_196746 = 0; + F.line = 2638; + var colontmp__197432 = 0; F.line = 149; - colontmp__205182 = it_204229.childNodes.length; - F.line = 2632; - var i_205183 = 0; + colontmp__197432 = it_196739.childNodes.length; + F.line = 2639; + var i_197433 = 0; L10: do { - F.line = 2633; + F.line = 2640; L11: while (true) { - if (!(i_205183 < colontmp__205182)) break L11; + if (!(i_197433 < colontmp__197432)) break L11; F.line = 149; - j_204236 = i_205183; + j_196746 = i_197433; F.line = 150; - to_toc_204178(it_204229.childNodes[j_204236], e_204228); - F.line = 2635; - i_205183 = addInt(i_205183, 1); + to_toc_196688(it_196739.childNodes[j_196746], e_196738); + F.line = 2642; + i_197433 = addInt(i_197433, 1); } } while(false); } while(false); F.line = 151; - if (f_204200.kids != null) { f_204200.kids.push(e_204228); } else { f_204200.kids = [e_204228]; }; + if (f_196710.kids != null) { f_196710.kids.push(e_196738); } else { f_196710.kids = [e_196738]; }; F.line = 152; - i_204202 = addInt(nxt_204203, 1); + i_196712 = addInt(nxt_196713, 1); } else { F.line = 154; - to_toc_204178(x_204180.childNodes[i_204202], f_204200); + to_toc_196688(x_196690.childNodes[i_196712], f_196710); F.line = 155; - i_204202 = addInt(i_204202, 1); + i_196712 = addInt(i_196712, 1); } } } while(false); F.line = 156; - if (father_204181.kids != null) { father_204181.kids.push(f_204200); } else { father_204181.kids = [f_204200]; }; + if (father_196691.kids != null) { father_196691.kids.push(f_196710); } else { father_196691.kids = [f_196710]; }; } else { - if (is_whitespace_204161(x_204180)) { + if (is_whitespace_196671(x_196690)) { } else { - if ((x_204180.nodeName == "LI")) { + if ((x_196690.nodeName == "LI")) { F.line = 160; - var idx_204271 = []; + var idx_196781 = []; L12: do { F.line = 161; - var i_204278 = 0; - F.line = 2631; - var colontmp__205187 = 0; + var i_196788 = 0; + F.line = 2638; + var colontmp__197437 = 0; F.line = 161; - colontmp__205187 = x_204180.childNodes.length; - F.line = 2632; - var i_205188 = 0; + colontmp__197437 = x_196690.childNodes.length; + F.line = 2639; + var i_197438 = 0; L13: do { - F.line = 2633; + F.line = 2640; L14: while (true) { - if (!(i_205188 < colontmp__205187)) break L14; + if (!(i_197438 < colontmp__197437)) break L14; F.line = 161; - i_204278 = i_205188; - if (!(is_whitespace_204161(x_204180.childNodes[i_204278]))) { + i_196788 = i_197438; + if (!(is_whitespace_196671(x_196690.childNodes[i_196788]))) { F.line = 162; - if (idx_204271 != null) { idx_204271.push(i_204278); } else { idx_204271 = [i_204278]; }; + if (idx_196781 != null) { idx_196781.push(i_196788); } else { idx_196781 = [i_196788]; }; } - F.line = 2635; - i_205188 = addInt(i_205188, 1); + F.line = 2642; + i_197438 = addInt(i_197438, 1); } } while(false); } while(false); - if (!((idx_204271 != null ? idx_204271.length : 0) == 2)) Tmp15 = false; else { Tmp15 = (x_204180.childNodes[idx_204271[chckIndx(1, 0, idx_204271.length+0-1)-0]].nodeName == "UL"); } if (Tmp15) { + if (!((idx_196781 != null ? idx_196781.length : 0) == 2)) Tmp15 = false; else { Tmp15 = (x_196690.childNodes[idx_196781[chckIndx(1, 0, idx_196781.length+0-1)-0]].nodeName == "UL"); } if (Tmp15) { F.line = 164; - var e_204309 = {heading: x_204180.childNodes[idx_204271[chckIndx(0, 0, idx_204271.length+0-1)-0]], kids: [], sortId: (father_204181.kids != null ? father_204181.kids.length : 0), doSort: false}; + var e_196819 = {heading: x_196690.childNodes[idx_196781[chckIndx(0, 0, idx_196781.length+0-1)-0]], kids: [], sortId: (father_196691.kids != null ? father_196691.kids.length : 0), doSort: false}; F.line = 166; - var it_204310 = x_204180.childNodes[idx_204271[chckIndx(1, 0, idx_204271.length+0-1)-0]]; + var it_196820 = x_196690.childNodes[idx_196781[chckIndx(1, 0, idx_196781.length+0-1)-0]]; L16: do { F.line = 167; - var j_204317 = 0; - F.line = 2631; - var colontmp__205193 = 0; + var j_196827 = 0; + F.line = 2638; + var colontmp__197443 = 0; F.line = 167; - colontmp__205193 = it_204310.childNodes.length; - F.line = 2632; - var i_205194 = 0; + colontmp__197443 = it_196820.childNodes.length; + F.line = 2639; + var i_197444 = 0; L17: do { - F.line = 2633; + F.line = 2640; L18: while (true) { - if (!(i_205194 < colontmp__205193)) break L18; + if (!(i_197444 < colontmp__197443)) break L18; F.line = 167; - j_204317 = i_205194; + j_196827 = i_197444; F.line = 168; - to_toc_204178(it_204310.childNodes[j_204317], e_204309); - F.line = 2635; - i_205194 = addInt(i_205194, 1); + to_toc_196688(it_196820.childNodes[j_196827], e_196819); + F.line = 2642; + i_197444 = addInt(i_197444, 1); } } while(false); } while(false); F.line = 169; - if (father_204181.kids != null) { father_204181.kids.push(e_204309); } else { father_204181.kids = [e_204309]; }; + if (father_196691.kids != null) { father_196691.kids.push(e_196819); } else { father_196691.kids = [e_196819]; }; } else { L19: do { F.line = 171; - var i_204331 = 0; - F.line = 2631; - var colontmp__205198 = 0; + var i_196841 = 0; + F.line = 2638; + var colontmp__197448 = 0; F.line = 171; - colontmp__205198 = x_204180.childNodes.length; - F.line = 2632; - var i_205199 = 0; + colontmp__197448 = x_196690.childNodes.length; + F.line = 2639; + var i_197449 = 0; L20: do { - F.line = 2633; + F.line = 2640; L21: while (true) { - if (!(i_205199 < colontmp__205198)) break L21; + if (!(i_197449 < colontmp__197448)) break L21; F.line = 171; - i_204331 = i_205199; + i_196841 = i_197449; F.line = 172; - to_toc_204178(x_204180.childNodes[i_204331], father_204181); - F.line = 2635; - i_205199 = addInt(i_205199, 1); + to_toc_196688(x_196690.childNodes[i_196841], father_196691); + F.line = 2642; + i_197449 = addInt(i_197449, 1); } } while(false); } while(false); @@ -935,7 +935,7 @@ function to_toc_204178(x_204180, father_204181) { } else { F.line = 174; - if (father_204181.kids != null) { father_204181.kids.push({heading: x_204180, kids: [], sortId: (father_204181.kids != null ? father_204181.kids.length : 0), doSort: false}); } else { father_204181.kids = [{heading: x_204180, kids: [], sortId: (father_204181.kids != null ? father_204181.kids.length : 0), doSort: false}]; }; + if (father_196691.kids != null) { father_196691.kids.push({heading: x_196690, kids: [], sortId: (father_196691.kids != null ? father_196691.kids.length : 0), doSort: false}); } else { father_196691.kids = [{heading: x_196690, kids: [], sortId: (father_196691.kids != null ? father_196691.kids.length : 0), doSort: false}]; }; } }} framePtr = F.prev; @@ -943,37 +943,37 @@ function to_toc_204178(x_204180, father_204181) { } -function extract_items_203577(x_203579, heading_203580, items_203583, items_203583_Idx) { +function extract_items_196337(x_196339, heading_196340, items_196343, items_196343_Idx) { var Tmp1; var F={procname:"dochack.extractItems",prev:framePtr,filename:"dochack.nim",line:0}; framePtr = F; BeforeRet: do { - if ((x_203579 == null)) { + if ((x_196339 == null)) { F.line = 81; break BeforeRet; } - if (!!((x_203579.heading == null))) Tmp1 = false; else { Tmp1 = (x_203579.heading.textContent == heading_203580); } if (Tmp1) { + if (!!((x_196339.heading == null))) Tmp1 = false; else { Tmp1 = (x_196339.heading.textContent == heading_196340); } if (Tmp1) { L2: do { F.line = 83; - var i_203611 = 0; - F.line = 2631; - var colontmp__205223 = 0; + var i_196371 = 0; + F.line = 2638; + var colontmp__197473 = 0; F.line = 83; - colontmp__205223 = (x_203579.kids != null ? x_203579.kids.length : 0); - F.line = 2632; - var i_205224 = 0; + colontmp__197473 = (x_196339.kids != null ? x_196339.kids.length : 0); + F.line = 2639; + var i_197474 = 0; L3: do { - F.line = 2633; + F.line = 2640; L4: while (true) { - if (!(i_205224 < colontmp__205223)) break L4; + if (!(i_197474 < colontmp__197473)) break L4; F.line = 83; - i_203611 = i_205224; + i_196371 = i_197474; F.line = 84; - if (items_203583[items_203583_Idx] != null) { items_203583[items_203583_Idx].push(x_203579.kids[chckIndx(i_203611, 0, x_203579.kids.length+0-1)-0].heading); } else { items_203583[items_203583_Idx] = [x_203579.kids[chckIndx(i_203611, 0, x_203579.kids.length+0-1)-0].heading]; }; - F.line = 2635; - i_205224 = addInt(i_205224, 1); + if (items_196343[items_196343_Idx] != null) { items_196343[items_196343_Idx].push(x_196339.kids[chckIndx(i_196371, 0, x_196339.kids.length+0-1)-0].heading); } else { items_196343[items_196343_Idx] = [x_196339.kids[chckIndx(i_196371, 0, x_196339.kids.length+0-1)-0].heading]; }; + F.line = 2642; + i_197474 = addInt(i_197474, 1); } } while(false); } while(false); @@ -981,25 +981,25 @@ function extract_items_203577(x_203579, heading_203580, items_203583, items_2035 else { L5: do { F.line = 86; - var i_203630 = 0; - F.line = 2631; - var colontmp__205228 = 0; + var i_196390 = 0; + F.line = 2638; + var colontmp__197478 = 0; F.line = 86; - colontmp__205228 = (x_203579.kids != null ? x_203579.kids.length : 0); - F.line = 2632; - var i_205229 = 0; + colontmp__197478 = (x_196339.kids != null ? x_196339.kids.length : 0); + F.line = 2639; + var i_197479 = 0; L6: do { - F.line = 2633; + F.line = 2640; L7: while (true) { - if (!(i_205229 < colontmp__205228)) break L7; + if (!(i_197479 < colontmp__197478)) break L7; F.line = 86; - i_203630 = i_205229; + i_196390 = i_197479; F.line = 87; - var it_203631 = x_203579.kids[chckIndx(i_203630, 0, x_203579.kids.length+0-1)-0]; + var it_196391 = x_196339.kids[chckIndx(i_196390, 0, x_196339.kids.length+0-1)-0]; F.line = 88; - extract_items_203577(it_203631, heading_203580, items_203583, items_203583_Idx); - F.line = 2635; - i_205229 = addInt(i_205229, 1); + extract_items_196337(it_196391, heading_196340, items_196343, items_196343_Idx); + F.line = 2642; + i_197479 = addInt(i_197479, 1); } } while(false); } while(false); @@ -1011,180 +1011,180 @@ function extract_items_203577(x_203579, heading_203580, items_203583, items_2035 } -function tree_203020(tag_203022, kids_203024) { - var result_203025 = null; +function tree_196020(tag_196022, kids_196024) { + var result_196025 = null; var F={procname:"dochack.tree",prev:framePtr,filename:"dochack.nim",line:0}; framePtr = F; F.line = 11; - result_203025 = document.createElement(toJSStr(tag_203022)); + result_196025 = document.createElement(toJSStr(tag_196022)); L1: do { F.line = 12; - var k_203071 = null; + var k_196056 = null; F.line = 3; - var i_205246 = 0; + var i_197496 = 0; L2: do { F.line = 4; L3: while (true) { - if (!(i_205246 < (kids_203024 != null ? kids_203024.length : 0))) break L3; + if (!(i_197496 < (kids_196024 != null ? kids_196024.length : 0))) break L3; F.line = 12; - k_203071 = kids_203024[chckIndx(i_205246, 0, kids_203024.length+0-1)-0]; + k_196056 = kids_196024[chckIndx(i_197496, 0, kids_196024.length+0-1)-0]; F.line = 13; - result_203025.appendChild(k_203071); + result_196025.appendChild(k_196056); F.line = 6; - i_205246 = addInt(i_205246, 1); + i_197496 = addInt(i_197496, 1); } } while(false); } while(false); framePtr = F.prev; - return result_203025; + return result_196025; } -function text_203227(s_203229) { - var result_203230 = null; +function text_196152(s_196154) { + var result_196155 = null; var F={procname:"dochack.text",prev:framePtr,filename:"dochack.nim",line:0}; framePtr = F; F.line = 27; - result_203230 = document.createTextNode(s_203229); + result_196155 = document.createTextNode(s_196154); framePtr = F.prev; - return result_203230; + return result_196155; } -function sys_fatal_57107(message_57111) { - var F={procname:"sysFatal.sysFatal",prev:framePtr,filename:"..\\..\\lib\\system\\fatal.nim",line:0}; +function sys_fatal_55662(message_55666) { + var F={procname:"sysFatal.sysFatal",prev:framePtr,filename:"../../lib/system/fatal.nim",line:0}; framePtr = F; - F.line = 32; - var e_57207 = null; - F.line = 35; - e_57207 = {m_type: NTI46850, parent: null, name: null, message: null, trace: null, raiseId: 0, up: null}; - F.line = 36; - e_57207.message = nimCopy(null, message_57111, NTI43040); + F.line = 34; + var e_55807 = null; F.line = 37; - raiseException(e_57207, "AssertionError"); + e_55807 = {m_type: NTI45850, parent: null, name: null, message: null, trace: null, raiseId: 0, up: null}; + F.line = 38; + e_55807.message = nimCopy(null, message_55666, NTI42040); + F.line = 39; + raiseException(e_55807, "AssertionError"); framePtr = F.prev; } -function raise_assert_57103(msg_57105) { - var F={procname:"assertions.raiseAssert",prev:framePtr,filename:"..\\..\\lib\\system\\assertions.nim",line:0}; +function raise_assert_55658(msg_55660) { + var F={procname:"assertions.raiseAssert",prev:framePtr,filename:"../../lib/system/assertions.nim",line:0}; framePtr = F; F.line = 20; - sys_fatal_57107(msg_57105); + sys_fatal_55662(msg_55660); framePtr = F.prev; } -function failed_assert_impl_57270(msg_57272) { - var F={procname:"assertions.failedAssertImpl",prev:framePtr,filename:"..\\..\\lib\\system\\assertions.nim",line:0}; +function failed_assert_impl_55855(msg_55857) { + var F={procname:"assertions.failedAssertImpl",prev:framePtr,filename:"../../lib/system/assertions.nim",line:0}; framePtr = F; F.line = 27; - raise_assert_57103(msg_57272); + raise_assert_55658(msg_55857); framePtr = F.prev; } -function uncovered_204500(x_204502) { +function uncovered_196935(x_196937) { var Tmp1; var Tmp2; - var result_204503 = null; + var result_196938 = null; var F={procname:"dochack.uncovered",prev:framePtr,filename:"dochack.nim",line:0}; framePtr = F; BeforeRet: do { - if (!((x_204502.kids != null ? x_204502.kids.length : 0) == 0)) Tmp1 = false; else { Tmp1 = !((x_204502.heading == null)); } if (Tmp1) { + if (!((x_196937.kids != null ? x_196937.kids.length : 0) == 0)) Tmp1 = false; else { Tmp1 = !((x_196937.heading == null)); } if (Tmp1) { F.line = 194; - if (!(x_204502.heading.hasOwnProperty('__karaxMarker__'))) { - Tmp2 = x_204502; + if (!(x_196937.heading.hasOwnProperty('__karaxMarker__'))) { + Tmp2 = x_196937; } else { Tmp2 = null; } - result_204503 = Tmp2; + result_196938 = Tmp2; break BeforeRet; } F.line = 195; - result_204503 = {heading: x_204502.heading, kids: [], sortId: x_204502.sortId, doSort: x_204502.doSort}; + result_196938 = {heading: x_196937.heading, kids: [], sortId: x_196937.sortId, doSort: x_196937.doSort}; L3: do { F.line = 197; - var i_204541 = 0; - F.line = 2631; - var colontmp__205258 = 0; + var i_196976 = 0; + F.line = 2638; + var colontmp__197508 = 0; F.line = 197; - colontmp__205258 = (x_204502.kids != null ? x_204502.kids.length : 0); - F.line = 2632; - var i_205259 = 0; + colontmp__197508 = (x_196937.kids != null ? x_196937.kids.length : 0); + F.line = 2639; + var i_197509 = 0; L4: do { - F.line = 2633; + F.line = 2640; L5: while (true) { - if (!(i_205259 < colontmp__205258)) break L5; + if (!(i_197509 < colontmp__197508)) break L5; F.line = 197; - i_204541 = i_205259; + i_196976 = i_197509; F.line = 198; - var y_204542 = uncovered_204500(x_204502.kids[chckIndx(i_204541, 0, x_204502.kids.length+0-1)-0]); - if (!((y_204542 == null))) { + var y_196977 = uncovered_196935(x_196937.kids[chckIndx(i_196976, 0, x_196937.kids.length+0-1)-0]); + if (!((y_196977 == null))) { F.line = 199; - if (result_204503.kids != null) { result_204503.kids.push(y_204542); } else { result_204503.kids = [y_204542]; }; + if (result_196938.kids != null) { result_196938.kids.push(y_196977); } else { result_196938.kids = [y_196977]; }; } - F.line = 2635; - i_205259 = addInt(i_205259, 1); + F.line = 2642; + i_197509 = addInt(i_197509, 1); } } while(false); } while(false); - if (((result_204503.kids != null ? result_204503.kids.length : 0) == 0)) { + if (((result_196938.kids != null ? result_196938.kids.length : 0) == 0)) { F.line = 200; - result_204503 = null; + result_196938 = null; } } while (false); framePtr = F.prev; - return result_204503; + return result_196938; } -function merge_tocs_204591(orig_204593, news_204594) { - var result_204595 = null; +function merge_tocs_197011(orig_197013, news_197014) { + var result_197015 = null; var F={procname:"dochack.mergeTocs",prev:framePtr,filename:"dochack.nim",line:0}; framePtr = F; F.line = 203; - result_204595 = uncovered_204500(orig_204593); - if ((result_204595 == null)) { + result_197015 = uncovered_196935(orig_197013); + if ((result_197015 == null)) { F.line = 205; - result_204595 = news_204594; + result_197015 = news_197014; } else { L1: do { F.line = 207; - var i_204615 = 0; - F.line = 2631; - var colontmp__205252 = 0; + var i_197035 = 0; + F.line = 2638; + var colontmp__197502 = 0; F.line = 207; - colontmp__205252 = (news_204594.kids != null ? news_204594.kids.length : 0); - F.line = 2632; - var i_205253 = 0; + colontmp__197502 = (news_197014.kids != null ? news_197014.kids.length : 0); + F.line = 2639; + var i_197503 = 0; L2: do { - F.line = 2633; + F.line = 2640; L3: while (true) { - if (!(i_205253 < colontmp__205252)) break L3; + if (!(i_197503 < colontmp__197502)) break L3; F.line = 207; - i_204615 = i_205253; + i_197035 = i_197503; F.line = 208; - if (result_204595.kids != null) { result_204595.kids.push(news_204594.kids[chckIndx(i_204615, 0, news_204594.kids.length+0-1)-0]); } else { result_204595.kids = [news_204594.kids[chckIndx(i_204615, 0, news_204594.kids.length+0-1)-0]]; }; - F.line = 2635; - i_205253 = addInt(i_205253, 1); + if (result_197015.kids != null) { result_197015.kids.push(news_197014.kids[chckIndx(i_197035, 0, news_197014.kids.length+0-1)-0]); } else { result_197015.kids = [news_197014.kids[chckIndx(i_197035, 0, news_197014.kids.length+0-1)-0]]; }; + F.line = 2642; + i_197503 = addInt(i_197503, 1); } } while(false); } while(false); @@ -1192,110 +1192,110 @@ function merge_tocs_204591(orig_204593, news_204594) { framePtr = F.prev; - return result_204595; + return result_197015; } -function build_toc_204636(orig_204638, types_204640, procs_204641) { - var result_204642 = null; +function build_toc_197056(orig_197058, types_197060, procs_197061) { + var result_197062 = null; var F={procname:"dochack.buildToc",prev:framePtr,filename:"dochack.nim",line:0}; framePtr = F; F.line = 211; - var new_stuff_204656 = {heading: null, kids: [], doSort: true, sortId: 0}; + var new_stuff_197076 = {heading: null, kids: [], doSort: true, sortId: 0}; L1: do { F.line = 212; - var t_204829 = null; + var t_197214 = null; F.line = 156; - var i_205241 = 0; + var i_197491 = 0; F.line = 157; - var l_205242 = (types_204640 != null ? types_204640.length : 0); + var l_197492 = (types_197060 != null ? types_197060.length : 0); L2: do { F.line = 158; L3: while (true) { - if (!(i_205241 < l_205242)) break L3; + if (!(i_197491 < l_197492)) break L3; F.line = 212; - t_204829 = types_204640[chckIndx(i_205241, 0, types_204640.length+0-1)-0]; + t_197214 = types_197060[chckIndx(i_197491, 0, types_197060.length+0-1)-0]; F.line = 213; - var c_204843 = {heading: t_204829.cloneNode(true), kids: [], doSort: true, sortId: 0}; + var c_197228 = {heading: t_197214.cloneNode(true), kids: [], doSort: true, sortId: 0}; F.line = 214; - t_204829.__karaxMarker__ = true; + t_197214.__karaxMarker__ = true; L4: do { F.line = 215; - var p_204850 = null; + var p_197235 = null; F.line = 156; - var i_205238 = 0; + var i_197488 = 0; F.line = 157; - var l_205239 = (procs_204641 != null ? procs_204641.length : 0); + var l_197489 = (procs_197061 != null ? procs_197061.length : 0); L5: do { F.line = 158; L6: while (true) { - if (!(i_205238 < l_205239)) break L6; + if (!(i_197488 < l_197489)) break L6; F.line = 215; - p_204850 = procs_204641[chckIndx(i_205238, 0, procs_204641.length+0-1)-0]; - if (!(p_204850.hasOwnProperty('__karaxMarker__'))) { + p_197235 = procs_197061[chckIndx(i_197488, 0, procs_197061.length+0-1)-0]; + if (!(p_197235.hasOwnProperty('__karaxMarker__'))) { F.line = 217; - var xx_204851 = p_204850.parentNode.getElementsByClassName("attachedType"); - if ((((xx_204851 != null ? xx_204851.length : 0) == 1) && (xx_204851[chckIndx(0, 0, xx_204851.length+0-1)-0].textContent == t_204829.textContent))) { + var xx_197236 = p_197235.parentNode.getElementsByClassName("attachedType"); + if ((((xx_197236 != null ? xx_197236.length : 0) == 1) && (xx_197236[chckIndx(0, 0, xx_197236.length+0-1)-0].textContent == t_197214.textContent))) { F.line = 220; - var q_204859 = tree_203020(makeNimstrLit("A"), [text_203227(p_204850.title)]); + var q_197244 = tree_196020(makeNimstrLit("A"), [text_196152(p_197235.title)]); F.line = 221; - q_204859.setAttribute("href", p_204850.getAttribute("href")); + q_197244.setAttribute("href", p_197235.getAttribute("href")); F.line = 222; - if (c_204843.kids != null) { c_204843.kids.push({heading: q_204859, kids: [], sortId: 0, doSort: false}); } else { c_204843.kids = [{heading: q_204859, kids: [], sortId: 0, doSort: false}]; }; + if (c_197228.kids != null) { c_197228.kids.push({heading: q_197244, kids: [], sortId: 0, doSort: false}); } else { c_197228.kids = [{heading: q_197244, kids: [], sortId: 0, doSort: false}]; }; F.line = 223; - p_204850.__karaxMarker__ = true; + p_197235.__karaxMarker__ = true; } } F.line = 160; - i_205238 = addInt(i_205238, 1); - if (!(((procs_204641 != null ? procs_204641.length : 0) == l_205239))) { + i_197488 = addInt(i_197488, 1); + if (!(((procs_197061 != null ? procs_197061.length : 0) == l_197489))) { F.line = 161; - failed_assert_impl_57270(makeNimstrLit("C:\\Users\\gt\\Desktop\\DL\\programming\\nimdevel\\lib\\system\\iterators.nim(161, 11) `len(a) == L` seq modified while iterating over it")); + failed_assert_impl_55855(makeNimstrLit("/home/genotrance/programming/nimdevel/lib/system/iterators.nim(161, 11) `len(a) == L` seq modified while iterating over it")); } } } while(false); } while(false); F.line = 224; - if (new_stuff_204656.kids != null) { new_stuff_204656.kids.push(c_204843); } else { new_stuff_204656.kids = [c_204843]; }; + if (new_stuff_197076.kids != null) { new_stuff_197076.kids.push(c_197228); } else { new_stuff_197076.kids = [c_197228]; }; F.line = 160; - i_205241 = addInt(i_205241, 1); - if (!(((types_204640 != null ? types_204640.length : 0) == l_205242))) { + i_197491 = addInt(i_197491, 1); + if (!(((types_197060 != null ? types_197060.length : 0) == l_197492))) { F.line = 161; - failed_assert_impl_57270(makeNimstrLit("C:\\Users\\gt\\Desktop\\DL\\programming\\nimdevel\\lib\\system\\iterators.nim(161, 11) `len(a) == L` seq modified while iterating over it")); + failed_assert_impl_55855(makeNimstrLit("/home/genotrance/programming/nimdevel/lib/system/iterators.nim(161, 11) `len(a) == L` seq modified while iterating over it")); } } } while(false); } while(false); F.line = 225; - result_204642 = merge_tocs_204591(orig_204638, new_stuff_204656); + result_197062 = merge_tocs_197011(orig_197058, new_stuff_197076); framePtr = F.prev; - return result_204642; + return result_197062; } -function add_203145(parent_203147, kid_203148) { +function add_196085(parent_196087, kid_196088) { var Tmp1; var Tmp2; var F={procname:"dochack.add",prev:framePtr,filename:"dochack.nim",line:0}; framePtr = F; - if (!(parent_203147.nodeName == "TR")) Tmp1 = false; else { if ((kid_203148.nodeName == "TD")) Tmp2 = true; else { Tmp2 = (kid_203148.nodeName == "TH"); } Tmp1 = Tmp2; } if (Tmp1) { + if (!(parent_196087.nodeName == "TR")) Tmp1 = false; else { if ((kid_196088.nodeName == "TD")) Tmp2 = true; else { Tmp2 = (kid_196088.nodeName == "TH"); } Tmp1 = Tmp2; } if (Tmp1) { F.line = 18; - var k_203149 = document.createElement("TD"); + var k_196089 = document.createElement("TD"); F.line = 19; - k_203149.appendChild(kid_203148); + k_196089.appendChild(kid_196088); F.line = 20; - parent_203147.appendChild(k_203149); + parent_196087.appendChild(k_196089); } else { F.line = 22; - parent_203147.appendChild(kid_203148); + parent_196087.appendChild(kid_196088); } framePtr = F.prev; @@ -1303,486 +1303,490 @@ function add_203145(parent_203147, kid_203148) { } -function set_class_203163(e_203165, value_203166) { +function set_class_196103(e_196105, value_196106) { var F={procname:"dochack.setClass",prev:framePtr,filename:"dochack.nim",line:0}; framePtr = F; F.line = 25; - e_203165.setAttribute("class", toJSStr(value_203166)); + e_196105.setAttribute("class", toJSStr(value_196106)); framePtr = F.prev; } -function to_html_203705(x_203707, is_root_203708) { +function to_html_196420(x_196422, is_root_196423) { var Tmp1; - function HEX3Aanonymous_203748(a_203750, b_203751) { + function HEX3Aanonymous_196463(a_196465, b_196466) { var Tmp1; - var result_203752 = 0; + var result_196467 = 0; var F={procname:"toHtml.:anonymous",prev:framePtr,filename:"dochack.nim",line:0}; framePtr = F; BeforeRet: do { - if (!!((a_203750.heading == null))) Tmp1 = false; else { Tmp1 = !((b_203751.heading == null)); } if (Tmp1) { + if (!!((a_196465.heading == null))) Tmp1 = false; else { Tmp1 = !((b_196466.heading == null)); } if (Tmp1) { F.line = 106; - var x_203769 = a_203750.heading.textContent; + var x_196484 = a_196465.heading.textContent; F.line = 107; - var y_203770 = b_203751.heading.textContent; - if ((x_203769 < y_203770)) { + var y_196485 = b_196466.heading.textContent; + if ((x_196484 < y_196485)) { F.line = 108; - result_203752 = -1; + result_196467 = -1; break BeforeRet; } - if ((y_203770 < x_203769)) { + if ((y_196485 < x_196484)) { F.line = 109; - result_203752 = 1; + result_196467 = 1; break BeforeRet; } F.line = 110; - result_203752 = 0; + result_196467 = 0; break BeforeRet; } else { F.line = 113; - result_203752 = subInt(a_203750.sortId, b_203751.sortId); + result_196467 = subInt(a_196465.sortId, b_196466.sortId); break BeforeRet; } } while (false); framePtr = F.prev; - return result_203752; + return result_196467; } - var result_203709 = null; + var result_196424 = null; var F={procname:"dochack.toHtml",prev:framePtr,filename:"dochack.nim",line:0}; framePtr = F; BeforeRet: do { - if ((x_203707 == null)) { + if ((x_196422 == null)) { F.line = 91; - result_203709 = null; + result_196424 = null; break BeforeRet; } - if (((x_203707.kids != null ? x_203707.kids.length : 0) == 0)) { - if ((x_203707.heading == null)) { + if (((x_196422.kids != null ? x_196422.kids.length : 0) == 0)) { + if ((x_196422.heading == null)) { F.line = 93; - result_203709 = null; + result_196424 = null; break BeforeRet; } F.line = 94; - result_203709 = x_203707.heading.cloneNode(true); + result_196424 = x_196422.heading.cloneNode(true); break BeforeRet; } F.line = 95; - result_203709 = tree_203020(makeNimstrLit("DIV"), []); - if (!!((x_203707.heading == null))) Tmp1 = false; else { Tmp1 = !(x_203707.heading.hasOwnProperty('__karaxMarker__')); } if (Tmp1) { + result_196424 = tree_196020(makeNimstrLit("DIV"), []); + if (!!((x_196422.heading == null))) Tmp1 = false; else { Tmp1 = !(x_196422.heading.hasOwnProperty('__karaxMarker__')); } if (Tmp1) { F.line = 97; - add_203145(result_203709, x_203707.heading.cloneNode(true)); + add_196085(result_196424, x_196422.heading.cloneNode(true)); } F.line = 98; - var ul_203745 = tree_203020(makeNimstrLit("UL"), []); - if (is_root_203708) { + var ul_196460 = tree_196020(makeNimstrLit("UL"), []); + if (is_root_196423) { F.line = 100; - set_class_203163(ul_203745, makeNimstrLit("simple simple-toc")); + set_class_196103(ul_196460, makeNimstrLit("simple simple-toc")); } else { F.line = 102; - set_class_203163(ul_203745, makeNimstrLit("simple")); + set_class_196103(ul_196460, makeNimstrLit("simple")); } - if (x_203707.doSort) { + if (x_196422.doSort) { F.line = 104; - x_203707.kids.sort(HEX3Aanonymous_203748); + x_196422.kids.sort(HEX3Aanonymous_196463); } L2: do { F.line = 115; - var k_204014 = null; + var k_196614 = null; F.line = 154; - var colontmp__205265 = null; + var colontmp__197515 = null; F.line = 115; - colontmp__205265 = x_203707.kids; + colontmp__197515 = x_196422.kids; F.line = 156; - var i_205267 = 0; + var i_197517 = 0; F.line = 157; - var l_205268 = (colontmp__205265 != null ? colontmp__205265.length : 0); + var l_197518 = (colontmp__197515 != null ? colontmp__197515.length : 0); L3: do { F.line = 158; L4: while (true) { - if (!(i_205267 < l_205268)) break L4; + if (!(i_197517 < l_197518)) break L4; F.line = 115; - k_204014 = colontmp__205265[chckIndx(i_205267, 0, colontmp__205265.length+0-1)-0]; + k_196614 = colontmp__197515[chckIndx(i_197517, 0, colontmp__197515.length+0-1)-0]; F.line = 116; - var y_204015 = to_html_203705(k_204014, false); - if (!((y_204015 == null))) { + var y_196615 = to_html_196420(k_196614, false); + if (!((y_196615 == null))) { F.line = 118; - add_203145(ul_203745, tree_203020(makeNimstrLit("LI"), [y_204015])); + add_196085(ul_196460, tree_196020(makeNimstrLit("LI"), [y_196615])); } F.line = 160; - i_205267 = addInt(i_205267, 1); - if (!(((colontmp__205265 != null ? colontmp__205265.length : 0) == l_205268))) { + i_197517 = addInt(i_197517, 1); + if (!(((colontmp__197515 != null ? colontmp__197515.length : 0) == l_197518))) { F.line = 161; - failed_assert_impl_57270(makeNimstrLit("C:\\Users\\gt\\Desktop\\DL\\programming\\nimdevel\\lib\\system\\iterators.nim(161, 11) `len(a) == L` seq modified while iterating over it")); + failed_assert_impl_55855(makeNimstrLit("/home/genotrance/programming/nimdevel/lib/system/iterators.nim(161, 11) `len(a) == L` seq modified while iterating over it")); } } } while(false); } while(false); - if (!((ul_203745.childNodes.length == 0))) { + if (!((ul_196460.childNodes.length == 0))) { F.line = 119; - add_203145(result_203709, ul_203745); + add_196085(result_196424, ul_196460); } - if ((result_203709.childNodes.length == 0)) { + if ((result_196424.childNodes.length == 0)) { F.line = 120; - result_203709 = null; + result_196424 = null; } } while (false); framePtr = F.prev; - return result_203709; + return result_196424; } -function replace_by_id_203247(id_203249, new_tree_203250) { +function replace_by_id_196172(id_196174, new_tree_196175) { var F={procname:"dochack.replaceById",prev:framePtr,filename:"dochack.nim",line:0}; framePtr = F; F.line = 32; - var x_203251 = document.getElementById(id_203249); + var x_196176 = document.getElementById(id_196174); F.line = 33; - x_203251.parentNode.replaceChild(new_tree_203250, x_203251); + x_196176.parentNode.replaceChild(new_tree_196175, x_196176); F.line = 34; - new_tree_203250.id = id_203249; + new_tree_196175.id = id_196174; framePtr = F.prev; } -function togglevis_205034(d_205036) { +function togglevis_197329(d_197331) { var F={procname:"dochack.togglevis",prev:framePtr,filename:"dochack.nim",line:0}; framePtr = F; F.line = 230; - if (d_205036.style.display == 'none') - d_205036.style.display = 'inline'; + if (d_197331.style.display == 'none') + d_197331.style.display = 'inline'; else - d_205036.style.display = 'none'; + d_197331.style.display = 'none'; framePtr = F.prev; } -function groupBy(value_205052) { +function groupBy(value_197347) { var F={procname:"dochack.groupBy",prev:framePtr,filename:"dochack.nim",line:0}; framePtr = F; F.line = 238; - var toc_205053 = document.getElementById("toc-list"); - if ((alternative_205020[0] == null)) { + var toc_197348 = document.getElementById("toc-list"); + if ((alternative_197315[0] == null)) { F.line = 240; - var tt_205072 = {heading: null, kids: [], sortId: 0, doSort: false}; + var tt_197367 = {heading: null, kids: [], sortId: 0, doSort: false}; F.line = 241; - to_toc_204178(toc_205053, tt_205072); + to_toc_196688(toc_197348, tt_197367); F.line = 242; - tt_205072 = tt_205072.kids[chckIndx(0, 0, tt_205072.kids.length+0-1)-0]; + tt_197367 = tt_197367.kids[chckIndx(0, 0, tt_197367.kids.length+0-1)-0]; F.line = 244; - var types_205087 = [[]]; + var types_197382 = [[]]; F.line = 245; - var procs_205102 = [[]]; + var procs_197397 = [[]]; F.line = 247; - extract_items_203577(tt_205072, "Types", types_205087, 0); + extract_items_196337(tt_197367, "Types", types_197382, 0); F.line = 248; - extract_items_203577(tt_205072, "Procs", procs_205102, 0); + extract_items_196337(tt_197367, "Procs", procs_197397, 0); F.line = 249; - extract_items_203577(tt_205072, "Converters", procs_205102, 0); + extract_items_196337(tt_197367, "Converters", procs_197397, 0); F.line = 250; - extract_items_203577(tt_205072, "Methods", procs_205102, 0); + extract_items_196337(tt_197367, "Methods", procs_197397, 0); F.line = 251; - extract_items_203577(tt_205072, "Templates", procs_205102, 0); + extract_items_196337(tt_197367, "Templates", procs_197397, 0); F.line = 252; - extract_items_203577(tt_205072, "Macros", procs_205102, 0); + extract_items_196337(tt_197367, "Macros", procs_197397, 0); F.line = 253; - extract_items_203577(tt_205072, "Iterators", procs_205102, 0); + extract_items_196337(tt_197367, "Iterators", procs_197397, 0); F.line = 255; - var ntoc_205110 = build_toc_204636(tt_205072, types_205087[0], procs_205102[0]); + var ntoc_197405 = build_toc_197056(tt_197367, types_197382[0], procs_197397[0]); F.line = 256; - var x_205111 = to_html_203705(ntoc_205110, true); + var x_197406 = to_html_196420(ntoc_197405, true); F.line = 257; - alternative_205020[0] = tree_203020(makeNimstrLit("DIV"), [x_205111]); + alternative_197315[0] = tree_196020(makeNimstrLit("DIV"), [x_197406]); } - if ((value_205052 == "type")) { + if ((value_197347 == "type")) { F.line = 259; - replace_by_id_203247("tocRoot", alternative_205020[0]); + replace_by_id_196172("tocRoot", alternative_197315[0]); } else { F.line = 261; - replace_by_id_203247("tocRoot", tree_203020(makeNimstrLit("DIV"), [])); + replace_by_id_196172("tocRoot", tree_196020(makeNimstrLit("DIV"), [])); } F.line = 262; - togglevis_205034(document.getElementById("toc-list")); + togglevis_197329(document.getElementById("toc-list")); framePtr = F.prev; } -var db_205271 = [null]; -var contents_205273 = [null]; -var oldtoc_205677 = [null]; -var timer_205678 = [null]; +var db_197521 = [null]; +var contents_197523 = [null]; +var oldtoc_197957 = [null]; +var timer_197958 = [null]; function raiseRangeError() { - var e_63660 = null; - e_63660 = {m_type: NTI46862, parent: null, name: null, message: null, trace: null, raiseId: 0, up: null}; - e_63660.message = nimCopy(null, makeNimstrLit("value out of range"), NTI43040); - e_63660.parent = null; - raiseException(e_63660, "RangeError"); + var e_61445 = null; + e_61445 = {m_type: NTI45862, parent: null, name: null, message: null, trace: null, raiseId: 0, up: null}; + e_61445.message = nimCopy(null, makeNimstrLit("value out of range"), NTI42040); + e_61445.parent = null; + raiseException(e_61445, "RangeError"); } -function nsuToLowerAsciiChar(c_190980) { - var result_190981 = 0; +function nsuToLowerAsciiChar(c_184980) { + var result_184981 = 0; - var F={procname:"strutils.toLowerAscii",prev:framePtr,filename:"..\\..\\lib\\pure\\strutils.nim",line:0}; + var F={procname:"strutils.toLowerAscii",prev:framePtr,filename:"../../lib/pure/strutils.nim",line:0}; framePtr = F; - if ((ConstSet2[c_190980] != undefined)) { + if ((ConstSet2[c_184980] != undefined)) { F.line = 222; - result_190981 = chckRange(addInt(c_190980, 32), 0, 255); + result_184981 = chckRange(addInt(c_184980, 32), 0, 255); } else { F.line = 224; - result_190981 = c_190980; + result_184981 = c_184980; } framePtr = F.prev; - return result_190981; + return result_184981; } -function fuzzy_match_202070(pattern_202072, str_202073) { +function fuzzy_match_195070(pattern_195072, str_195073) { var Tmp4; var Tmp5; var Tmp6; - var result_202077 = {Field0: 0, Field1: false}; + var result_195077 = {Field0: 0, Field1: false}; var F={procname:"fuzzysearch.fuzzyMatch",prev:framePtr,filename:"fuzzysearch.nim",line:0}; framePtr = F; F.line = 37; - var score_state_202078 = -100; + var score_state_195078 = -100; F.line = 38; - var header_matched_202079 = false; + var header_matched_195079 = false; F.line = 39; - var unmatched_leading_char_count_202081 = 0; + var unmatched_leading_char_count_195081 = 0; F.line = 40; - var consecutive_match_count_202083 = 0; + var consecutive_match_count_195083 = 0; F.line = 41; - var str_index_202085 = 0; + var str_index_195085 = 0; F.line = 42; - var pat_index_202087 = 0; + var pat_index_195087 = 0; F.line = 43; - var score_202089 = 0; + var score_195089 = 0; L1: do { F.line = 49; L2: while (true) { - if (!((str_index_202085 < (str_202073 != null ? str_202073.length : 0)) && (pat_index_202087 < (pattern_202072 != null ? pattern_202072.length : 0)))) break L2; + if (!((str_index_195085 < (str_195073 != null ? str_195073.length : 0)) && (pat_index_195087 < (pattern_195072 != null ? pattern_195072.length : 0)))) break L2; L3: do { F.line = 51; - var pattern_char_202096 = nsuToLowerAsciiChar(pattern_202072.charCodeAt(chckIndx(pat_index_202087, 0, pattern_202072.length+0-1)-0)); + var pattern_char_195096 = nsuToLowerAsciiChar(pattern_195072.charCodeAt(chckIndx(pat_index_195087, 0, pattern_195072.length+0-1)-0)); F.line = 52; - var str_char_202097 = nsuToLowerAsciiChar(str_202073.charCodeAt(chckIndx(str_index_202085, 0, str_202073.length+0-1)-0)); - if ((ConstSet3[pattern_char_202096] != undefined)) { + var str_char_195097 = nsuToLowerAsciiChar(str_195073.charCodeAt(chckIndx(str_index_195085, 0, str_195073.length+0-1)-0)); + if ((ConstSet3[pattern_char_195096] != undefined)) { F.line = 56; - pat_index_202087 = addInt(pat_index_202087, 1); + pat_index_195087 = addInt(pat_index_195087, 1); F.line = 57; break L3; } - if ((ConstSet4[str_char_202097] != undefined)) { + if ((ConstSet4[str_char_195097] != undefined)) { F.line = 59; - str_index_202085 = addInt(str_index_202085, 1); + str_index_195085 = addInt(str_index_195085, 1); F.line = 60; break L3; } - if ((!(header_matched_202079) && (str_char_202097 == 58))) { + if ((!(header_matched_195079) && (str_char_195097 == 58))) { F.line = 65; - header_matched_202079 = true; + header_matched_195079 = true; F.line = 66; - score_state_202078 = -100; + score_state_195078 = -100; F.line = 67; - score_202089 = Math.trunc(Math.floor((5.0000000000000000e-001 * score_202089))); + score_195089 = Math.trunc(Math.floor((5.0000000000000000e-01 * score_195089))); F.line = 68; - pat_index_202087 = 0; + pat_index_195087 = 0; F.line = 69; - str_index_202085 = addInt(str_index_202085, 1); + str_index_195085 = addInt(str_index_195085, 1); F.line = 70; break L3; } - if ((str_char_202097 == pattern_char_202096)) { + if ((str_char_195097 == pattern_char_195096)) { F.line = 73; - switch (score_state_202078) { + switch (score_state_195078) { case -100: case 20: F.line = 75; - score_state_202078 = 10; + score_state_195078 = 10; break; case 0: F.line = 78; - score_state_202078 = 5; + score_state_195078 = 5; F.line = 78; - score_202089 = addInt(score_202089, score_state_202078); + score_195089 = addInt(score_195089, score_state_195078); break; case 10: case 5: F.line = 81; - consecutive_match_count_202083 = addInt(consecutive_match_count_202083, 1); + consecutive_match_count_195083 = addInt(consecutive_match_count_195083, 1); F.line = 82; - score_state_202078 = 5; + score_state_195078 = 5; F.line = 83; - score_202089 = addInt(score_202089, mulInt(5, consecutive_match_count_202083)); - if ((score_state_202078 == 10)) { + score_195089 = addInt(score_195089, mulInt(5, consecutive_match_count_195083)); + if ((score_state_195078 == 10)) { F.line = 86; - score_202089 = addInt(score_202089, 10); + score_195089 = addInt(score_195089, 10); } F.line = 88; - var on_boundary_202172 = (pat_index_202087 == (pattern_202072 != null ? (pattern_202072.length-1) : -1)); - if ((!(on_boundary_202172) && (str_index_202085 < (str_202073 != null ? (str_202073.length-1) : -1)))) { + var on_boundary_195172 = (pat_index_195087 == (pattern_195072 != null ? (pattern_195072.length-1) : -1)); + if ((!(on_boundary_195172) && (str_index_195085 < (str_195073 != null ? (str_195073.length-1) : -1)))) { F.line = 91; - var next_pattern_char_202173 = nsuToLowerAsciiChar(pattern_202072.charCodeAt(chckIndx(addInt(pat_index_202087, 1), 0, pattern_202072.length+0-1)-0)); + var next_pattern_char_195173 = nsuToLowerAsciiChar(pattern_195072.charCodeAt(chckIndx(addInt(pat_index_195087, 1), 0, pattern_195072.length+0-1)-0)); F.line = 92; - var next_str_char_202174 = nsuToLowerAsciiChar(str_202073.charCodeAt(chckIndx(addInt(str_index_202085, 1), 0, str_202073.length+0-1)-0)); + var next_str_char_195174 = nsuToLowerAsciiChar(str_195073.charCodeAt(chckIndx(addInt(str_index_195085, 1), 0, str_195073.length+0-1)-0)); F.line = 95; - if (!!((ConstSet5[next_str_char_202174] != undefined))) Tmp4 = false; else { Tmp4 = !((next_str_char_202174 == next_pattern_char_202173)); } on_boundary_202172 = Tmp4; + if (!!((ConstSet5[next_str_char_195174] != undefined))) Tmp4 = false; else { Tmp4 = !((next_str_char_195174 == next_pattern_char_195173)); } on_boundary_195172 = Tmp4; } - if (on_boundary_202172) { + if (on_boundary_195172) { F.line = 100; - score_state_202078 = 20; + score_state_195078 = 20; F.line = 100; - score_202089 = addInt(score_202089, score_state_202078); + score_195089 = addInt(score_195089, score_state_195078); } break; case -1: case -3: F.line = 103; - if (!((ConstSet6[str_202073.charCodeAt(chckIndx(subInt(str_index_202085, 1), 0, str_202073.length+0-1)-0)] != undefined))) Tmp5 = true; else { if (!(ConstSet7[str_202073.charCodeAt(chckIndx(subInt(str_index_202085, 1), 0, str_202073.length+0-1)-0)] != undefined)) Tmp6 = false; else { Tmp6 = (ConstSet8[str_202073.charCodeAt(chckIndx(str_index_202085, 0, str_202073.length+0-1)-0)] != undefined); } Tmp5 = Tmp6; } var is_leading_char_202212 = Tmp5; - if (is_leading_char_202212) { + if (!((ConstSet6[str_195073.charCodeAt(chckIndx(subInt(str_index_195085, 1), 0, str_195073.length+0-1)-0)] != undefined))) Tmp5 = true; else { if (!(ConstSet7[str_195073.charCodeAt(chckIndx(subInt(str_index_195085, 1), 0, str_195073.length+0-1)-0)] != undefined)) Tmp6 = false; else { Tmp6 = (ConstSet8[str_195073.charCodeAt(chckIndx(str_index_195085, 0, str_195073.length+0-1)-0)] != undefined); } Tmp5 = Tmp6; } var is_leading_char_195212 = Tmp5; + if (is_leading_char_195212) { F.line = 110; - score_state_202078 = 10; + score_state_195078 = 10; } else { F.line = 114; - score_state_202078 = 0; + score_state_195078 = 0; F.line = 114; - score_202089 = addInt(score_202089, score_state_202078); + score_195089 = addInt(score_195089, score_state_195078); } break; } F.line = 115; - pat_index_202087 = addInt(pat_index_202087, 1); + pat_index_195087 = addInt(pat_index_195087, 1); } else { F.line = 118; - switch (score_state_202078) { + switch (score_state_195078) { case -100: F.line = 120; - score_state_202078 = -3; + score_state_195078 = -3; F.line = 120; - score_202089 = addInt(score_202089, score_state_202078); + score_195089 = addInt(score_195089, score_state_195078); break; case 5: F.line = 123; - score_state_202078 = -1; + score_state_195078 = -1; F.line = 123; - score_202089 = addInt(score_202089, score_state_202078); + score_195089 = addInt(score_195089, score_state_195078); F.line = 124; - consecutive_match_count_202083 = 0; + consecutive_match_count_195083 = 0; break; case -3: - if ((unmatched_leading_char_count_202081 < 3)) { + if ((unmatched_leading_char_count_195081 < 3)) { F.line = 128; - score_state_202078 = -3; + score_state_195078 = -3; F.line = 128; - score_202089 = addInt(score_202089, score_state_202078); + score_195089 = addInt(score_195089, score_state_195078); } F.line = 129; - unmatched_leading_char_count_202081 = addInt(unmatched_leading_char_count_202081, 1); + unmatched_leading_char_count_195081 = addInt(unmatched_leading_char_count_195081, 1); break; default: F.line = 132; - score_state_202078 = -1; + score_state_195078 = -1; F.line = 132; - score_202089 = addInt(score_202089, score_state_202078); + score_195089 = addInt(score_195089, score_state_195078); break; } } F.line = 134; - str_index_202085 = addInt(str_index_202085, 1); + str_index_195085 = addInt(str_index_195085, 1); } while(false); } } while(false); + F.line = 137; + var colontmp__198061 = nimMax(0, score_195089); + F.line = 138; + var colontmp__198062 = (0 < score_195089); F.line = 136; - nimCopy(result_202077, {Field0: nimMax(0, score_202089), Field1: (0 < score_202089)}, NTI202074); + nimCopy(result_195077, {Field0: colontmp__198061, Field1: colontmp__198062}, NTI195074); framePtr = F.prev; - return result_202077; + return result_195077; } -function text_203195(s_203197) { - var result_203198 = null; +function text_196120(s_196122) { + var result_196123 = null; var F={procname:"dochack.text",prev:framePtr,filename:"dochack.nim",line:0}; framePtr = F; F.line = 26; - result_203198 = document.createTextNode(toJSStr(s_203197)); + result_196123 = document.createTextNode(toJSStr(s_196122)); framePtr = F.prev; - return result_203198; + return result_196123; } -function dosearch_205305(value_205307) { +function dosearch_197555(value_197557) { - function HEX3Aanonymous_205470(a_205479, b_205480) { - var result_205484 = 0; + function HEX3Aanonymous_197870(a_197879, b_197880) { + var result_197884 = 0; var F={procname:"dosearch.:anonymous",prev:framePtr,filename:"dochack.nim",line:0}; framePtr = F; F.line = 305; - result_205484 = subInt(b_205480["Field1"], a_205479["Field1"]); + result_197884 = subInt(b_197880["Field1"], a_197879["Field1"]); framePtr = F.prev; - return result_205484; + return result_197884; } - var result_205308 = null; + var result_197558 = null; var F={procname:"dochack.dosearch",prev:framePtr,filename:"dochack.nim",line:0}; framePtr = F; - if (((db_205271[0] != null ? db_205271[0].length : 0) == 0)) { + if (((db_197521[0] != null ? db_197521[0].length : 0) == 0)) { F.line = 272; - var stuff_205314 = null; + var stuff_197564 = null; F.line = 273; var request = new XMLHttpRequest(); request.open("GET", "theindex.html", false); @@ -1794,32 +1798,32 @@ function dosearch_205305(value_205307) { //parser=new DOMParser(); //doc=parser.parseFromString("", "text/html"); - stuff_205314 = doc.documentElement; + stuff_197564 = doc.documentElement; F.line = 286; - db_205271[0] = nimCopy(null, stuff_205314.getElementsByClassName("reference"), NTI86305); + db_197521[0] = nimCopy(null, stuff_197564.getElementsByClassName("reference"), NTI83305); F.line = 287; - contents_205273[0] = nimCopy(null, [], NTI205327); + contents_197523[0] = nimCopy(null, [], NTI197577); L1: do { F.line = 288; - var ahref_205414 = null; + var ahref_197814 = null; F.line = 156; - var i_205806 = 0; + var i_198041 = 0; F.line = 157; - var l_205807 = (db_205271[0] != null ? db_205271[0].length : 0); + var l_198042 = (db_197521[0] != null ? db_197521[0].length : 0); L2: do { F.line = 158; L3: while (true) { - if (!(i_205806 < l_205807)) break L3; + if (!(i_198041 < l_198042)) break L3; F.line = 288; - ahref_205414 = db_205271[0][chckIndx(i_205806, 0, db_205271[0].length+0-1)-0]; + ahref_197814 = db_197521[0][chckIndx(i_198041, 0, db_197521[0].length+0-1)-0]; F.line = 289; - if (contents_205273[0] != null) { contents_205273[0].push(ahref_205414.getAttribute("data-doc-search-tag")); } else { contents_205273[0] = [ahref_205414.getAttribute("data-doc-search-tag")]; }; + if (contents_197523[0] != null) { contents_197523[0].push(ahref_197814.getAttribute("data-doc-search-tag")); } else { contents_197523[0] = [ahref_197814.getAttribute("data-doc-search-tag")]; }; F.line = 160; - i_205806 = addInt(i_205806, 1); - if (!(((db_205271[0] != null ? db_205271[0].length : 0) == l_205807))) { + i_198041 = addInt(i_198041, 1); + if (!(((db_197521[0] != null ? db_197521[0].length : 0) == l_198042))) { F.line = 161; - failed_assert_impl_57270(makeNimstrLit("C:\\Users\\gt\\Desktop\\DL\\programming\\nimdevel\\lib\\system\\iterators.nim(161, 11) `len(a) == L` seq modified while iterating over it")); + failed_assert_impl_55855(makeNimstrLit("/home/genotrance/programming/nimdevel/lib/system/iterators.nim(161, 11) `len(a) == L` seq modified while iterating over it")); } } @@ -1828,126 +1832,126 @@ function dosearch_205305(value_205307) { } F.line = 290; - var ul_205425 = tree_203020(makeNimstrLit("UL"), []); + var ul_197825 = tree_196020(makeNimstrLit("UL"), []); F.line = 291; - result_205308 = tree_203020(makeNimstrLit("DIV"), []); + result_197558 = tree_196020(makeNimstrLit("DIV"), []); F.line = 292; - set_class_203163(result_205308, makeNimstrLit("search_results")); + set_class_196103(result_197558, makeNimstrLit("search_results")); F.line = 293; - var matches_205444 = []; + var matches_197844 = []; L4: do { F.line = 294; - var i_205456 = 0; - F.line = 2631; - var colontmp__205813 = 0; + var i_197856 = 0; + F.line = 2638; + var colontmp__198048 = 0; F.line = 294; - colontmp__205813 = (db_205271[0] != null ? db_205271[0].length : 0); - F.line = 2632; - var i_205814 = 0; + colontmp__198048 = (db_197521[0] != null ? db_197521[0].length : 0); + F.line = 2639; + var i_198049 = 0; L5: do { - F.line = 2633; + F.line = 2640; L6: while (true) { - if (!(i_205814 < colontmp__205813)) break L6; + if (!(i_198049 < colontmp__198048)) break L6; F.line = 294; - i_205456 = i_205814; + i_197856 = i_198049; L7: do { F.line = 295; - var c_205457 = contents_205273[0][chckIndx(i_205456, 0, contents_205273[0].length+0-1)-0]; - if (((c_205457 == "Examples") || (c_205457 == "PEG construction"))) { + var c_197857 = contents_197523[0][chckIndx(i_197856, 0, contents_197523[0].length+0-1)-0]; + if (((c_197857 == "Examples") || (c_197857 == "PEG construction"))) { F.line = 300; break L7; } F.line = 301; - var colontmp__205823 = {Field0: 0, Field1: false}; + var colontmp__198058 = {Field0: 0, Field1: false}; F.line = 301; - var score_205458 = 0; + var score_197858 = 0; F.line = 301; - var matched_205459 = false; + var matched_197859 = false; F.line = 301; - nimCopy(colontmp__205823, fuzzy_match_202070(value_205307, c_205457), NTI202074); + nimCopy(colontmp__198058, fuzzy_match_195070(value_197557, c_197857), NTI195074); F.line = 301; - score_205458 = colontmp__205823["Field0"]; + score_197858 = colontmp__198058["Field0"]; F.line = 301; - matched_205459 = colontmp__205823["Field1"]; - if (matched_205459) { + matched_197859 = colontmp__198058["Field1"]; + if (matched_197859) { F.line = 303; - if (matches_205444 != null) { matches_205444.push({Field0: db_205271[0][chckIndx(i_205456, 0, db_205271[0].length+0-1)-0], Field1: score_205458}); } else { matches_205444 = [{Field0: db_205271[0][chckIndx(i_205456, 0, db_205271[0].length+0-1)-0], Field1: score_205458}]; }; + if (matches_197844 != null) { matches_197844.push({Field0: db_197521[0][chckIndx(i_197856, 0, db_197521[0].length+0-1)-0], Field1: score_197858}); } else { matches_197844 = [{Field0: db_197521[0][chckIndx(i_197856, 0, db_197521[0].length+0-1)-0], Field1: score_197858}]; }; } } while(false); - F.line = 2635; - i_205814 = addInt(i_205814, 1); + F.line = 2642; + i_198049 = addInt(i_198049, 1); } } while(false); } while(false); F.line = 305; - matches_205444.sort(HEX3Aanonymous_205470); + matches_197844.sort(HEX3Aanonymous_197870); L8: do { F.line = 306; - var i_205522 = 0; - F.line = 2631; - var colontmp__205819 = 0; + var i_197922 = 0; + F.line = 2638; + var colontmp__198054 = 0; F.line = 306; - colontmp__205819 = nimMin((matches_205444 != null ? matches_205444.length : 0), 19); - F.line = 2632; - var i_205820 = 0; + colontmp__198054 = nimMin((matches_197844 != null ? matches_197844.length : 0), 19); + F.line = 2639; + var i_198055 = 0; L9: do { - F.line = 2633; + F.line = 2640; L10: while (true) { - if (!(i_205820 < colontmp__205819)) break L10; + if (!(i_198055 < colontmp__198054)) break L10; F.line = 306; - i_205522 = i_205820; + i_197922 = i_198055; F.line = 307; - matches_205444[chckIndx(i_205522, 0, matches_205444.length+0-1)-0]["Field0"].innerHTML = matches_205444[chckIndx(i_205522, 0, matches_205444.length+0-1)-0]["Field0"].getAttribute("data-doc-search-tag"); + matches_197844[chckIndx(i_197922, 0, matches_197844.length+0-1)-0]["Field0"].innerHTML = matches_197844[chckIndx(i_197922, 0, matches_197844.length+0-1)-0]["Field0"].getAttribute("data-doc-search-tag"); F.line = 308; - add_203145(ul_205425, tree_203020(makeNimstrLit("LI"), [matches_205444[chckIndx(i_205522, 0, matches_205444.length+0-1)-0]["Field0"]])); - F.line = 2635; - i_205820 = addInt(i_205820, 1); + add_196085(ul_197825, tree_196020(makeNimstrLit("LI"), [matches_197844[chckIndx(i_197922, 0, matches_197844.length+0-1)-0]["Field0"]])); + F.line = 2642; + i_198055 = addInt(i_198055, 1); } } while(false); } while(false); - if ((ul_205425.childNodes.length == 0)) { + if ((ul_197825.childNodes.length == 0)) { F.line = 310; - add_203145(result_205308, tree_203020(makeNimstrLit("B"), [text_203195(makeNimstrLit("no search results"))])); + add_196085(result_197558, tree_196020(makeNimstrLit("B"), [text_196120(makeNimstrLit("no search results"))])); } else { F.line = 312; - add_203145(result_205308, tree_203020(makeNimstrLit("B"), [text_203195(makeNimstrLit("search results"))])); + add_196085(result_197558, tree_196020(makeNimstrLit("B"), [text_196120(makeNimstrLit("search results"))])); F.line = 313; - add_203145(result_205308, ul_205425); + add_196085(result_197558, ul_197825); } framePtr = F.prev; - return result_205308; + return result_197558; } function search() { - function wrapper_205709() { + function wrapper_197989() { var F={procname:"search.wrapper",prev:framePtr,filename:"dochack.nim",line:0}; framePtr = F; F.line = 320; - var elem_205711 = document.getElementById("searchInput"); + var elem_197991 = document.getElementById("searchInput"); F.line = 321; - var value_205712 = elem_205711.value; - if (!(((value_205712 != null ? value_205712.length : 0) == 0))) { - if ((oldtoc_205677[0] == null)) { + var value_197992 = elem_197991.value; + if (!(((value_197992 != null ? value_197992.length : 0) == 0))) { + if ((oldtoc_197957[0] == null)) { F.line = 324; - oldtoc_205677[0] = document.getElementById("tocRoot"); + oldtoc_197957[0] = document.getElementById("tocRoot"); } F.line = 325; - var results_205718 = dosearch_205305(value_205712); + var results_197998 = dosearch_197555(value_197992); F.line = 326; - replace_by_id_203247("tocRoot", results_205718); + replace_by_id_196172("tocRoot", results_197998); } else { - if (!((oldtoc_205677[0] == null))) { + if (!((oldtoc_197957[0] == null))) { F.line = 328; - replace_by_id_203247("tocRoot", oldtoc_205677[0]); + replace_by_id_196172("tocRoot", oldtoc_197957[0]); } } framePtr = F.prev; @@ -1957,13 +1961,13 @@ function search() { var F={procname:"dochack.search",prev:framePtr,filename:"dochack.nim",line:0}; framePtr = F; - if (!((timer_205678[0] == null))) { + if (!((timer_197958[0] == null))) { F.line = 330; - clearTimeout(timer_205678[0]); + clearTimeout(timer_197958[0]); } F.line = 331; - timer_205678[0] = setTimeout(wrapper_205709, 400); + timer_197958[0] = setTimeout(wrapper_197989, 400); framePtr = F.prev; diff --git a/git.html b/git.html index 41769f0..1d9883c 100755 --- a/git.html +++ b/git.html @@ -27,113 +27,232 @@ customize this style sheet. Modified from Chad Skeeters' rst2html-style https://bitbucket.org/cskeeters/rst2html-style/ -Modified by Boyd Greenfield and narimiran +Modified by Boyd Greenfield */ - +/* SCSS variables */ +/* Text weights */ +/* Body colors */ +/* Text colors */ +/* Link colors */ +/* Syntax highlighting colors */ +/* Pct changes */ +/* Mixins */ +/* Body/layout */ html { font-size: 100%; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; } +/* Where we want fancier font if available */ +h1, h2, h3, h4, h5, h6, p.module-desc, table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; } + +h1.title { + font-weight: 900; } + body { font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: 400; - font-size: 1.125em; - line-height: 1.5; - color: #222; - background-color: #FCFCFC; } + font-size: 16px; + line-height: 20px; + color: #444; + letter-spacing: 0.15px; + background-color: #FDFBFA; } /* Skeleton grid */ .container { position: relative; width: 100%; - max-width: 1050px; + max-width: 960px; margin: 0 auto; - padding: 0; + padding: 0 20px; box-sizing: border-box; } .column, .columns { width: 100%; float: left; - box-sizing: border-box; - margin-left: 1%; -} + box-sizing: border-box; } -.column:first-child, -.columns:first-child { - margin-left: 0; } +/* For devices larger than 400px */ +@media (min-width: 400px) { + .container { + width: 100%; + padding: 0; } } +/* For devices larger than 650px */ +@media (min-width: 650px) { + .container { + width: 100%; } -.three.columns { - width: 19%; } + .column, + .columns { + margin-left: 4%; } -.nine.columns { - width: 80.0%; } + .column:first-child, + .columns:first-child { + margin-left: 0; } -.twelve.columns { - width: 100%; - margin-left: 0; } + .one.column, + .one.columns { + width: 4.66666666667%; } + + .two.columns { + width: 13.3333333333%; } -@media screen and (max-width: 860px) { .three.columns { - display: none; - } + width: 22%; } + + .four.columns { + width: 30.6666666667%; } + + .five.columns { + width: 39.3333333333%; } + + .six.columns { + width: 48%; } + + .seven.columns { + width: 56.6666666667%; } + + .eight.columns { + width: 65.3333333333%; } + .nine.columns { - width: 98.0%; - } - body { - font-size: 1em; - line-height: 1.35; - } -} + width: 74.0%; } + + .ten.columns { + width: 82.6666666667%; } + + .eleven.columns { + width: 91.3333333333%; } + + .twelve.columns { + width: 100%; + margin-left: 0; } + + .one-third.column { + width: 30.6666666667%; } + + .two-thirds.column { + width: 65.3333333333%; } } +/* Customer Overrides */ +.footer { + text-align: center; + color: #969696; + padding-top: 10%; } + +p.module-desc { + font-size: 1.1em; + color: #666666; } + +a.link-seesrc { + color: #aec7d2; + font-style: italic; } + +a.link-seesrc:hover { + color: #6c9aae; } + +#toc-list { + word-wrap: break-word; } + +ul.simple-toc { + list-style: none; } + +ul.simple-toc a.reference-toplevel { + font-weight: bold; + color: #0077b3; } + +ul.simple-toc-section { + list-style-type: circle; + color: #6c9aae; } + +ul.simple-toc-section a.reference { + color: #0077b3; } cite { font-style: italic !important; } +dt > pre { + border-color: rgba(0, 0, 0, 0.1); + background-color: rgba(255, 255, 255, 0.3); + margin: 15px 0px 5px; } + +dd > pre { + border-color: rgba(0, 0, 0, 0.1); + background-color: whitesmoke; + margin-top: 8px; } + +.item > dd { + margin-left: 10px; + margin-bottom: 30px; } + +/* Nim line-numbered tables */ +.line-nums-table { + width: 100%; + table-layout: fixed; } /* Nim search input */ div#searchInputDiv { - margin-bottom: 1em; + margin-bottom: 8px; } -input#searchInput { - width: 80%; +div#searchInputDiv input#searchInput { + width: 10em; +} +div.search-groupby { + margin-bottom: 8px; } +table.line-nums-table { + border-radius: 4px; + border: 1px solid #cccccc; + background-color: whitesmoke; + border-collapse: separate; + margin-top: 15px; + margin-bottom: 25px; } + +.line-nums-table tbody { + border: none; } + +.line-nums-table td pre { + border: none; + background-color: transparent; } + +.line-nums-table td.blob-line-nums { + width: 28px; } + +.line-nums-table td.blob-line-nums pre { + color: #b0b0b0; + -webkit-filter: opacity(75%); + text-align: right; + border-color: transparent; + background-color: transparent; + padding-left: 0px; + margin-left: 0px; + padding-right: 0px; + margin-right: 0px; } /* Docgen styles */ /* Links */ a { - color: #07b; - text-decoration: none; -} - -a span.Identifier { - text-decoration: underline; - text-decoration-color: #aab; -} - -a.reference-toplevel { - font-weight: bold; -} - -a.toc-backref { - text-decoration: none; - color: #222; } - -a.link-seesrc { - color: #607c9f; - font-size: 0.9em; - font-style: italic; } + color: #0077b3; + text-decoration: none; } a:hover, a:focus { - color: #607c9f; + color: #00334d; text-decoration: underline; } -a:hover span.Identifier { - color: #607c9f; -} +a:visited { + color: #00334d; } +a:focus { + outline: thin dotted #2d2d2d; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; } + +a:hover, +a:active { + outline: 0; } sub, sup { @@ -210,258 +329,379 @@ img { h2, h3 { - page-break-after: avoid; } -} + page-break-after: avoid; } } +.img-rounded { + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; } +.img-polaroid { + padding: 4px; + background-color: rgba(252, 248, 244, 0.75); + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.2); + -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); } p { - margin-top: 0.5em; - margin-bottom: 0.5em; -} + margin: 0 0 8px; } small { font-size: 85%; } strong { - font-weight: 600; - font-size: 0.95em; - color: #3c3c3c; -} + font-weight: 600; } em { font-style: italic; } +cite { + font-style: normal; } + +h1, +h2, +h3, +h4, +h5, +h6 { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-weight: 600; + line-height: 20px; + color: inherit; + text-rendering: optimizelegibility; } + h1 { - font-size: 1.8em; + font-size: 2em; font-weight: 400; - padding-bottom: .25em; - border-bottom: 1px solid #aaa; - margin-top: 2.5em; - margin-bottom: 1em; + padding-bottom: .15em; + border-bottom: 1px solid #aaaaaa; + margin-top: 1.0em; line-height: 1.2em; } h1.title { padding-bottom: 1em; border-bottom: 0px; - font-size: 2.5em; - text-align: center; - font-weight: 900; - margin-top: 0.75em; - margin-bottom: 0em; -} + font-size: 2.75em; } h2 { - font-size: 1.3em; - margin-top: 2em; } - -h2.subtitle { - text-align: center; } - -h3 { - font-size: 1.125em; - font-style: italic; + font-size: 1.5em; margin-top: 1.5em; } +h3 { + font-size: 1.3em; + font-style: italic; + margin-top: 0.75em; } + h4 { - font-size: 1.125em; - margin-top: 1em; } + font-size: 1.3em; + margin-top: 0.5em; } h5 { - font-size: 1.125em; - margin-top: 0.75em; } + font-size: 1.2em; + margin-top: 0.25em; } h6 { font-size: 1.1em; } - ul, ol { padding: 0; - margin-top: 0.5em; - margin-left: 0.75em; } + margin: 0 0 0px 15px; } ul ul, ul ol, ol ol, ol ul { - margin-bottom: 0; - margin-left: 1.25em; } + margin-bottom: 0; } li { - list-style-type: circle; -} - -ul.simple-boot li { - list-style-type: none; - margin-left: 0em; - margin-bottom: 0.5em; -} - -ol.simple > li, ul.simple > li { - margin-bottom: 0.25em; - margin-left: 0.4em } - -ul.simple.simple-toc > li { - margin-top: 1em; -} - -ul.simple-toc { - list-style: none; - font-size: 0.9em; - margin-left: -0.3em; - margin-top: 1em; } - -ul.simple-toc > li { - list-style-type: none; -} - -ul.simple-toc-section { - list-style-type: circle; - margin-left: 1em; - color: #6c9aae; } - - -ol.arabic { - list-style: decimal; } - -ol.loweralpha { - list-style: lower-alpha; } - -ol.upperalpha { - list-style: upper-alpha; } - -ol.lowerroman { - list-style: lower-roman; } - -ol.upperroman { - list-style: upper-roman; } - -ul.auto-toc { - list-style-type: none; } - + line-height: 20px; } dl { - margin-bottom: 1.5em; } + margin-bottom: 20px; } + +dt, +dd { + line-height: 20px; } dt { - margin-bottom: -0.5em; - margin-left: 0.0em; } + font-weight: bold; } dd { - margin-left: 2.0em; - margin-bottom: 3.0em; - margin-top: 0.5em; } - + margin-left: 10px; + margin-bottom: 26px; } hr { - margin: 2em 0; + margin: 20px 0; border: 0; - border-top: 1px solid #aaa; } + border-top: 1px solid #eeeeee; + border-bottom: 1px solid #ffffff; } + +abbr[title], +abbr[data-original-title] { + cursor: help; + border-bottom: 1px dotted #999999; } + +abbr.initialism { + font-size: 90%; + text-transform: uppercase; } blockquote { - font-size: 0.9em; - font-style: italic; - padding-left: 0.5em; - margin-left: 0; - border-left: 5px solid #bbc; + padding: 0 0 0 15px; + margin: 0 0 20px; + border-left: 5px solid #EFEBE0; } + +table.docinfo + blockquote, table.docinfo blockquote, h1 + blockquote { + border-left: 5px solid #c9c9c9; } +table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { + margin-bottom: 0; + font-size: 15px; + font-weight: 200; + line-height: 1.5; + font-style: italic; } + +q:before, +q:after, +blockquote:before, +blockquote:after { + content: ""; } + +address { + display: block; + margin-bottom: 20px; + font-style: normal; + line-height: 20px; } + +code, +pre { + font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; + padding: 0 3px 2px; + font-weight: 500; + font-size: 12px; + color: #444444; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; } + .pre { font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - font-weight: 500; - font-size: 0.85em; - background-color: #f0f3ff; - padding-left: 3px; - padding-right: 3px; - border-radius: 4px; + font-weight: 600; + /*color: #504da6;*/ } +code { + padding: 2px 4px; + color: #444444; + white-space: nowrap; + background-color: white; + border: 1px solid #777777; } + pre { - font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - color: #222; - font-weight: 500; display: inline-block; box-sizing: border-box; - min-width: 100%; - padding: 0.5em; - margin-top: 0.5em; - margin-bottom: 0.5em; - font-size: 0.85em; + min-width: calc(100% - 19.5px); + padding: 9.5px; + margin: 0.25em 10px 10px 10px; + font-size: 15px; + line-height: 20px; white-space: pre !important; overflow-y: hidden; overflow-x: visible; - background-color: ghostwhite; - border: 1px solid #dde; - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; } + background-color: rgba(0, 0, 0, 0.01); + border: 1px solid #cccccc; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; } + +pre.prettyprint { + margin-bottom: 20px; } + +pre code { + padding: 0; + color: inherit; + white-space: pre; + overflow-x: visible; + background-color: transparent; + border: 0; } .pre-scrollable { max-height: 340px; overflow-y: scroll; } - -/* Nim line-numbered tables */ -.line-nums-table { - width: 100%; - table-layout: fixed; } - -table.line-nums-table { - border-radius: 4px; - border: 1px solid #cccccc; - background-color: ghostwhite; - border-collapse: separate; - margin-top: 15px; - margin-bottom: 25px; } - -.line-nums-table tbody { - border: none; } - -.line-nums-table td pre { - border: none; - background-color: transparent; } - -.line-nums-table td.blob-line-nums { - width: 28px; } - -.line-nums-table td.blob-line-nums pre { - color: #b0b0b0; - -webkit-filter: opacity(75%); - text-align: right; - border-color: transparent; - background-color: transparent; - padding-left: 0px; - margin-left: 0px; - padding-right: 0px; - margin-right: 0px; } - - table { max-width: 100%; background-color: transparent; - margin-top: 0.5em; - margin-bottom: 1.5em; border-collapse: collapse; - border-color: #ccc; - border-spacing: 0; - font-size: 0.9em; -} + border-spacing: 0; } table th, table td { - padding: 0px 0.5em 0px; + padding: 0px 8px 0px; } -table th { - background-color: #e8e8e8; +.table { + width: 100%; + margin-bottom: 20px; } + +.table th, +.table td { + padding: 8px; + line-height: 20px; + text-align: left; + vertical-align: top; + border-top: 1px solid #444444; } + +.table th { font-weight: bold; } -table th.docinfo-name { - background-color: transparent; -} +.table thead th { + vertical-align: bottom; } -table tr:hover { - background-color: ghostwhite; } +.table caption + thead tr:first-child th, +.table caption + thead tr:first-child td, +.table colgroup + thead tr:first-child th, +.table colgroup + thead tr:first-child td, +.table thead:first-child tr:first-child th, +.table thead:first-child tr:first-child td { + border-top: 0; } +.table tbody + tbody { + border-top: 2px solid #444444; } + +.table .table { + background-color: rgba(252, 248, 244, 0.75); } + +.table-condensed th, +.table-condensed td { + padding: 4px 5px; } + +.table-bordered { + border: 1px solid #444444; + border-collapse: separate; + *border-collapse: collapse; + border-left: 0; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; } + +.table-bordered th, +.table-bordered td { + border-left: 1px solid #444444; } + +.table-bordered caption + thead tr:first-child th, +.table-bordered caption + tbody tr:first-child th, +.table-bordered caption + tbody tr:first-child td, +.table-bordered colgroup + thead tr:first-child th, +.table-bordered colgroup + tbody tr:first-child th, +.table-bordered colgroup + tbody tr:first-child td, +.table-bordered thead:first-child tr:first-child th, +.table-bordered tbody:first-child tr:first-child th, +.table-bordered tbody:first-child tr:first-child td { + border-top: 0; } + +.table-bordered thead:first-child tr:first-child > th:first-child, +.table-bordered tbody:first-child tr:first-child > td:first-child, +.table-bordered tbody:first-child tr:first-child > th:first-child { + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; } + +.table-bordered thead:first-child tr:first-child > th:last-child, +.table-bordered tbody:first-child tr:first-child > td:last-child, +.table-bordered tbody:first-child tr:first-child > th:last-child { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; } + +.table-bordered thead:last-child tr:last-child > th:first-child, +.table-bordered tbody:last-child tr:last-child > td:first-child, +.table-bordered tbody:last-child tr:last-child > th:first-child, +.table-bordered tfoot:last-child tr:last-child > td:first-child, +.table-bordered tfoot:last-child tr:last-child > th:first-child { + -webkit-border-bottom-left-radius: 4px; + border-bottom-left-radius: 4px; + -moz-border-radius-bottomleft: 4px; } + +.table-bordered thead:last-child tr:last-child > th:last-child, +.table-bordered tbody:last-child tr:last-child > td:last-child, +.table-bordered tbody:last-child tr:last-child > th:last-child, +.table-bordered tfoot:last-child tr:last-child > td:last-child, +.table-bordered tfoot:last-child tr:last-child > th:last-child { + -webkit-border-bottom-right-radius: 4px; + border-bottom-right-radius: 4px; + -moz-border-radius-bottomright: 4px; } + +.table-bordered tfoot + tbody:last-child tr:last-child td:first-child { + -webkit-border-bottom-left-radius: 0; + border-bottom-left-radius: 0; + -moz-border-radius-bottomleft: 0; } + +.table-bordered tfoot + tbody:last-child tr:last-child td:last-child { + -webkit-border-bottom-right-radius: 0; + border-bottom-right-radius: 0; + -moz-border-radius-bottomright: 0; } + +.table-bordered caption + thead tr:first-child th:first-child, +.table-bordered caption + tbody tr:first-child td:first-child, +.table-bordered colgroup + thead tr:first-child th:first-child, +.table-bordered colgroup + tbody tr:first-child td:first-child { + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; } + +.table-bordered caption + thead tr:first-child th:last-child, +.table-bordered caption + tbody tr:first-child td:last-child, +.table-bordered colgroup + thead tr:first-child th:last-child, +.table-bordered colgroup + tbody tr:first-child td:last-child { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; } + +table.docutils th { + background-color: #e8e8e8; } + +table.docutils tr:hover { + background-color: whitesmoke; } + +.table-striped tbody > tr:nth-child(odd) > td, +.table-striped tbody > tr:nth-child(odd) > th { + background-color: rgba(252, 248, 244, 0.75); } + +.table-hover tbody tr:hover > td, +.table-hover tbody tr:hover > th { + background-color: rgba(241, 222, 204, 0.75); } + +table td[class*="span"], +table th[class*="span"], +.row-fluid table td[class*="span"], +.row-fluid table th[class*="span"] { + display: table-cell; + float: none; + margin-left: 0; } + +.hero-unit { + padding: 60px; + margin-bottom: 30px; + font-size: 18px; + font-weight: 200; + line-height: 30px; + color: inherit; + background-color: rgba(230, 197, 164, 0.75); + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; } + +.hero-unit h1 { + margin-bottom: 0; + font-size: 60px; + line-height: 1; + letter-spacing: -1px; + color: inherit; } + +.hero-unit li { + line-height: 30px; } /* rst2html default used to remove borders from tables and images */ .borderless, table.borderless td, table.borderless th { @@ -482,6 +722,10 @@ table.borderless td, table.borderless th { .hidden { display: none; } +a.toc-backref { + text-decoration: none; + color: #444444; } + blockquote.epigraph { margin: 2em 5em; } @@ -491,6 +735,85 @@ dl.docutils dd { object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] { overflow: hidden; } +/* Uncomment (and remove this text!) to get bold-faced definition list terms +dl.docutils dt { + font-weight: bold } +*/ +div.abstract { + margin: 2em 5em; } + +div.abstract p.topic-title { + font-weight: bold; + text-align: center; } + +div.admonition, div.attention, div.caution, div.danger, div.error, +div.hint, div.important, div.note, div.tip, div.warning { + margin: 2em; + border: medium outset; + padding: 1em; } + +div.note, div.warning { + margin: 1.5em 0px; + border: none; } + +div.note p.admonition-title, +div.warning p.admonition-title { + display: none; } + +/* Clearfix + * http://css-tricks.com/snippets/css/clear-fix/ + */ +div.note:after, +div.warning:after { + content: ""; + display: table; + clear: both; } + +div.note p:before, +div.warning p:before { + display: block; + float: left; + font-size: 4em; + line-height: 1em; + margin-right: 20px; + margin-left: 0em; + margin-top: -10px; + content: '\0270D'; + /*handwriting*/ } + +div.warning p:before { + content: '\026A0'; + /*warning*/ } + +div.admonition p.admonition-title, div.hint p.admonition-title, +div.important p.admonition-title, div.note p.admonition-title, +div.tip p.admonition-title { + font-weight: bold; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } + +div.attention p.admonition-title, div.caution p.admonition-title, +div.danger p.admonition-title, div.error p.admonition-title, +div.warning p.admonition-title, .code .error { + color: #b30000; + font-weight: bold; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } + +/* Uncomment (and remove this text!) to get reduced vertical space in + compound paragraphs. +div.compound .compound-first, div.compound .compound-middle { + margin-bottom: 0.5em } + +div.compound .compound-last, div.compound .compound-middle { + margin-top: 0.5em } +*/ +div.dedication { + margin: 2em 5em; + text-align: center; + font-style: italic; } + +div.dedication p.topic-title { + font-weight: bold; + font-style: normal; } div.figure { margin-left: 2em; @@ -498,14 +821,8 @@ div.figure { div.footer, div.header { clear: both; - text-align: center; - color: #666; font-size: smaller; } -div.footer { - padding-top: 5em; -} - div.line-block { display: block; margin-top: 1em; @@ -516,24 +833,45 @@ div.line-block div.line-block { margin-bottom: 0; margin-left: 1.5em; } +div.sidebar { + margin: 0 0 0.5em 1em; + border: medium outset; + padding: 1em; + background-color: rgba(252, 248, 244, 0.75); + width: 40%; + float: right; + clear: right; } + +div.sidebar p.rubric { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-size: medium; } + +div.system-messages { + margin: 5em; } + +div.system-messages h1 { + color: #b30000; } + +div.system-message { + border: medium outset; + padding: 1em; } + +div.system-message p.system-message-title { + color: #b30000; + font-weight: bold; } + div.topic { margin: 2em; } -div.search_results { - background-color: antiquewhite; - margin: 3em; - padding: 1em; - border: 1px solid #4d4d4d; -} +h1.section-subtitle, h2.section-subtitle, h3.section-subtitle, +h4.section-subtitle, h5.section-subtitle, h6.section-subtitle { + margin-top: 0.4em; } -div#global-links ul { - margin-left: 0; - list-style-type: none; -} +h1.title { + text-align: center; } -div#global-links > simple-boot { - margin-left: 3em; -} +h2.subtitle { + text-align: center; } hr.docutils { width: 75%; } @@ -567,6 +905,30 @@ img.align-center, .figure.align-center, object.align-center { div.align-right { text-align: inherit; } +/* div.align-center * { */ +/* text-align: left } */ + +ul.simple > li { + margin-bottom: 0.5em } + +ol.simple, ul.simple { + margin-bottom: 1em; } + +ol.arabic { + list-style: decimal; } + +ol.loweralpha { + list-style: lower-alpha; } + +ol.upperalpha { + list-style: upper-alpha; } + +ol.lowerroman { + list-style: lower-roman; } + +ol.upperroman { + list-style: upper-roman; } + p.attribution { text-align: right; margin-left: 50%; } @@ -587,6 +949,15 @@ p.rubric { color: maroon; text-align: center; } +p.sidebar-title { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-weight: bold; + font-size: larger; } + +p.sidebar-subtitle { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-weight: bold; } + p.topic-title { font-weight: bold; } @@ -626,14 +997,22 @@ pre.code .inserted, code .inserted { background-color: #A3D289; } span.classifier { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-style: oblique; } span.classifier-delimiter { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: bold; } +span.interpreted { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } + span.option { white-space: nowrap; } +span.pre { + white-space: pre; } + span.problematic { color: #b30000; } @@ -641,6 +1020,44 @@ span.section-subtitle { /* font-size relative to parent (h1..h6 element) */ font-size: 80%; } +table.citation { + border-left: solid 1px #666666; + margin-left: 1px; } + +table.docinfo { + margin: 0em; + margin-top: 2em; + margin-bottom: 2em; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; + color: #444444; } + +table.docutils { + margin-top: 0.5em; + margin-bottom: 0.5em; } + +table.footnote { + border-left: solid 1px #2d2d2d; + margin-left: 1px; } + +table.docutils td, table.docutils th, +table.docinfo td, table.docinfo th { + padding-left: 0.5em; + padding-right: 0.5em; + vertical-align: top; } + +table.docutils th.field-name, table.docinfo th.docinfo-name { + font-weight: 700; + text-align: left; + white-space: nowrap; + padding-left: 0; } + +h1 tt.docutils, h2 tt.docutils, h3 tt.docutils, +h4 tt.docutils, h5 tt.docutils, h6 tt.docutils { + font-size: 100%; } + +ul.auto-toc { + list-style-type: none; } + span.DecNumber { color: #252dbe; } @@ -657,7 +1074,7 @@ span.FloatNumber { color: #252dbe; } span.Identifier { - color: #222; } + color: #3b3b3b; } span.Keyword { font-weight: 600; @@ -722,23 +1139,38 @@ dt pre > span.Identifier, dt pre > span.Operator { color: #155da4; font-weight: 700; } -dt pre > span.Keyword ~ span.Identifier, dt pre > span.Identifier ~ span.Identifier, -dt pre > span.Operator ~ span.Identifier, dt pre > span.Other ~ span.Identifier { +dt pre > span.Identifier ~ span.Identifier, dt pre > span.Operator ~ span.Identifier { + color: inherit; + font-weight: inherit; } + +dt pre > span.Operator ~ span.Identifier { color: inherit; font-weight: inherit; } /* Nim sprite for the footer (taken from main page favicon) */ .nim-sprite { display: inline-block; - height: 16px; - width: 16px; + height: 12px; + width: 12px; background-position: 0 0; - background-size: 16px 16px; + background-size: 12px 12px; -webkit-filter: opacity(50%); background-repeat: no-repeat; background-image: url("data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="); margin-bottom: -5px; } +div.search_results { + background-color: antiquewhite; + margin: 3em; + padding: 1em; + border: 1px solid #4d4d4d; +} + +div#global-links ul { + margin-left: 0; + list-style-type: none; +} + span.pragmadots { /* Position: relative frees us up to make the dots look really nice without fucking up the layout and @@ -746,14 +1178,18 @@ span.pragmadots { position: relative; /* 1px down looks slightly nicer */ top: 1px; + padding: 2px; - background-color: #e8e8e8; + background-color: #D3D3D3; border-radius: 4px; margin: 0 2px; cursor: pointer; - font-size: 0.8em; -} + /* For some reason on Chrome, making the font size + smaller than 1em is causing the parent container to + bulge slightly. So, we're stuck with inheriting 1em, + which is sad, because 0.8em looks better... */ +} span.pragmadots:hover { background-color: #DBDBDB; } @@ -761,10 +1197,6 @@ span.pragmawrap { display: none; } -span.attachedType { - display: none; - visibility: hidden; -} @@ -816,23 +1248,25 @@ function main() { Procs
      • execAction
      • + title="execAction(cmd: string; nostderr = false): string">execAction
      • mkDir
      • + title="mkDir(dir: string)">mkDir
      • cpFile
      • + title="cpFile(source, dest: string; move = false)">cpFile
      • mvFile
      • + title="mvFile(source, dest: string)">mvFile
      • extractZip
      • + title="extractZip(zipfile, outdir: string)">extractZip
      • downloadUrl
      • + title="downloadUrl(url, outdir: string)">downloadUrl
      • gitReset
      • + title="gitReset(outdir: string)">gitReset
      • gitCheckout
      • + title="gitCheckout(file, outdir: string)">gitCheckout
      • gitPull
      • + title="gitPull(url: string; outdir = ""; plist = ""; checkout = "")">gitPull +
      • configure
    • @@ -852,71 +1286,77 @@ function main() {

      Procs

      -
      proc execAction(cmd: string; nostderr = false): string {...}{.
      -    raises: [OSError, Exception, ValueError, IOError, Defect],
      +
      proc execAction(cmd: string; nostderr = false): string {...}{.
      +    raises: [OSError, Exception, ValueError],
           tags: [ExecIOEffect, ReadIOEffect, RootEffect].}
      -
      proc mkDir(dir: string) {...}{.raises: [OSError, Exception, ValueError, IOError, Defect], tags: [
      +
      proc mkDir(dir: string) {...}{.raises: [OSError, Exception, ValueError], tags: [
           ReadDirEffect, ExecIOEffect, ReadIOEffect, RootEffect].}
      -
      proc cpFile(source, dest: string; move = false) {...}{.
      -    raises: [OSError, Exception, ValueError, IOError, Defect],
      +
      proc cpFile(source, dest: string; move = false) {...}{.
      +    raises: [OSError, Exception, ValueError],
           tags: [ExecIOEffect, ReadIOEffect, RootEffect].}
      -
      proc mvFile(source, dest: string) {...}{.raises: [OSError, Exception, ValueError, IOError,
      -                                        Defect],
      +
      proc mvFile(source, dest: string) {...}{.raises: [OSError, Exception, ValueError],
                                       tags: [ExecIOEffect, ReadIOEffect, RootEffect].}
      -
      proc extractZip(zipfile, outdir: string) {...}{.raises: [OSError, Exception, ValueError,
      -    IOError, Defect], tags: [ExecIOEffect, ReadIOEffect, RootEffect].}
      +
      proc extractZip(zipfile, outdir: string) {...}{.raises: [OSError, Exception, ValueError], tags: [
      +    ExecIOEffect, ReadIOEffect, RootEffect].}
      -
      proc downloadUrl(url, outdir: string) {...}{.raises: [OSError, Exception, ValueError,
      -    IOError, Defect], tags: [ReadDirEffect, ExecIOEffect, ReadIOEffect, RootEffect].}
      +
      proc downloadUrl(url, outdir: string) {...}{.raises: [OSError, Exception, ValueError], tags: [
      +    ReadDirEffect, ExecIOEffect, ReadIOEffect, RootEffect].}
      -
      proc gitReset(outdir: string) {...}{.raises: [ValueError, OSError, Exception, IOError, Defect], tags: [
      +
      proc gitReset(outdir: string) {...}{.raises: [OSError, Exception, ValueError], tags: [
           ExecIOEffect, ReadIOEffect, RootEffect, TimeEffect].}
      -
      proc gitCheckout(file, outdir: string) {...}{.raises: [ValueError, OSError, Exception,
      -    IOError, Defect], tags: [ExecIOEffect, ReadIOEffect, RootEffect, TimeEffect].}
      +
      proc gitCheckout(file, outdir: string) {...}{.raises: [OSError, Exception, ValueError], tags: [
      +    ExecIOEffect, ReadIOEffect, RootEffect, TimeEffect].}
      -
      proc gitPull(url: string; outdir = ""; plist = ""; checkout = "") {...}{.
      -    raises: [ValueError, OSError, Exception, IOError, Defect], tags: [ReadDirEffect,
      +
      proc gitPull(url: string; outdir = ""; plist = ""; checkout = "") {...}{.
      +    raises: [OSError, Exception, ValueError, IOError], tags: [ReadDirEffect,
           ExecIOEffect, ReadIOEffect, RootEffect, TimeEffect, WriteIOEffect].}
      +
      + +
      proc configure(path, check: string) {...}{.raises: [OSError, Exception, ValueError], tags: [
      +    ReadDirEffect, ExecIOEffect, ReadIOEffect, RootEffect].}
      +
      + +
      @@ -928,7 +1368,7 @@ function main() { diff --git a/git.idx b/git.idx index ac1d642..a48f1b4 100755 --- a/git.idx +++ b/git.idx @@ -7,3 +7,4 @@ downloadUrl git.html#downloadUrl,string,string git: downloadUrl(url, outdir: str gitReset git.html#gitReset,string git: gitReset(outdir: string) gitCheckout git.html#gitCheckout,string,string git: gitCheckout(file, outdir: string) gitPull git.html#gitPull,string,string,string,string git: gitPull(url: string; outdir = ""; plist = ""; checkout = "") +configure git.html#configure,string,string git: configure(path, check: string) diff --git a/paths.html b/paths.html index cef8ed6..8ae6986 100755 --- a/paths.html +++ b/paths.html @@ -27,113 +27,232 @@ customize this style sheet. Modified from Chad Skeeters' rst2html-style https://bitbucket.org/cskeeters/rst2html-style/ -Modified by Boyd Greenfield and narimiran +Modified by Boyd Greenfield */ - +/* SCSS variables */ +/* Text weights */ +/* Body colors */ +/* Text colors */ +/* Link colors */ +/* Syntax highlighting colors */ +/* Pct changes */ +/* Mixins */ +/* Body/layout */ html { font-size: 100%; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; } +/* Where we want fancier font if available */ +h1, h2, h3, h4, h5, h6, p.module-desc, table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; } + +h1.title { + font-weight: 900; } + body { font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: 400; - font-size: 1.125em; - line-height: 1.5; - color: #222; - background-color: #FCFCFC; } + font-size: 16px; + line-height: 20px; + color: #444; + letter-spacing: 0.15px; + background-color: #FDFBFA; } /* Skeleton grid */ .container { position: relative; width: 100%; - max-width: 1050px; + max-width: 960px; margin: 0 auto; - padding: 0; + padding: 0 20px; box-sizing: border-box; } .column, .columns { width: 100%; float: left; - box-sizing: border-box; - margin-left: 1%; -} + box-sizing: border-box; } -.column:first-child, -.columns:first-child { - margin-left: 0; } +/* For devices larger than 400px */ +@media (min-width: 400px) { + .container { + width: 100%; + padding: 0; } } +/* For devices larger than 650px */ +@media (min-width: 650px) { + .container { + width: 100%; } -.three.columns { - width: 19%; } + .column, + .columns { + margin-left: 4%; } -.nine.columns { - width: 80.0%; } + .column:first-child, + .columns:first-child { + margin-left: 0; } -.twelve.columns { - width: 100%; - margin-left: 0; } + .one.column, + .one.columns { + width: 4.66666666667%; } + + .two.columns { + width: 13.3333333333%; } -@media screen and (max-width: 860px) { .three.columns { - display: none; - } + width: 22%; } + + .four.columns { + width: 30.6666666667%; } + + .five.columns { + width: 39.3333333333%; } + + .six.columns { + width: 48%; } + + .seven.columns { + width: 56.6666666667%; } + + .eight.columns { + width: 65.3333333333%; } + .nine.columns { - width: 98.0%; - } - body { - font-size: 1em; - line-height: 1.35; - } -} + width: 74.0%; } + + .ten.columns { + width: 82.6666666667%; } + + .eleven.columns { + width: 91.3333333333%; } + + .twelve.columns { + width: 100%; + margin-left: 0; } + + .one-third.column { + width: 30.6666666667%; } + + .two-thirds.column { + width: 65.3333333333%; } } +/* Customer Overrides */ +.footer { + text-align: center; + color: #969696; + padding-top: 10%; } + +p.module-desc { + font-size: 1.1em; + color: #666666; } + +a.link-seesrc { + color: #aec7d2; + font-style: italic; } + +a.link-seesrc:hover { + color: #6c9aae; } + +#toc-list { + word-wrap: break-word; } + +ul.simple-toc { + list-style: none; } + +ul.simple-toc a.reference-toplevel { + font-weight: bold; + color: #0077b3; } + +ul.simple-toc-section { + list-style-type: circle; + color: #6c9aae; } + +ul.simple-toc-section a.reference { + color: #0077b3; } cite { font-style: italic !important; } +dt > pre { + border-color: rgba(0, 0, 0, 0.1); + background-color: rgba(255, 255, 255, 0.3); + margin: 15px 0px 5px; } + +dd > pre { + border-color: rgba(0, 0, 0, 0.1); + background-color: whitesmoke; + margin-top: 8px; } + +.item > dd { + margin-left: 10px; + margin-bottom: 30px; } + +/* Nim line-numbered tables */ +.line-nums-table { + width: 100%; + table-layout: fixed; } /* Nim search input */ div#searchInputDiv { - margin-bottom: 1em; + margin-bottom: 8px; } -input#searchInput { - width: 80%; +div#searchInputDiv input#searchInput { + width: 10em; +} +div.search-groupby { + margin-bottom: 8px; } +table.line-nums-table { + border-radius: 4px; + border: 1px solid #cccccc; + background-color: whitesmoke; + border-collapse: separate; + margin-top: 15px; + margin-bottom: 25px; } + +.line-nums-table tbody { + border: none; } + +.line-nums-table td pre { + border: none; + background-color: transparent; } + +.line-nums-table td.blob-line-nums { + width: 28px; } + +.line-nums-table td.blob-line-nums pre { + color: #b0b0b0; + -webkit-filter: opacity(75%); + text-align: right; + border-color: transparent; + background-color: transparent; + padding-left: 0px; + margin-left: 0px; + padding-right: 0px; + margin-right: 0px; } /* Docgen styles */ /* Links */ a { - color: #07b; - text-decoration: none; -} - -a span.Identifier { - text-decoration: underline; - text-decoration-color: #aab; -} - -a.reference-toplevel { - font-weight: bold; -} - -a.toc-backref { - text-decoration: none; - color: #222; } - -a.link-seesrc { - color: #607c9f; - font-size: 0.9em; - font-style: italic; } + color: #0077b3; + text-decoration: none; } a:hover, a:focus { - color: #607c9f; + color: #00334d; text-decoration: underline; } -a:hover span.Identifier { - color: #607c9f; -} +a:visited { + color: #00334d; } +a:focus { + outline: thin dotted #2d2d2d; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; } + +a:hover, +a:active { + outline: 0; } sub, sup { @@ -210,258 +329,379 @@ img { h2, h3 { - page-break-after: avoid; } -} + page-break-after: avoid; } } +.img-rounded { + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; } +.img-polaroid { + padding: 4px; + background-color: rgba(252, 248, 244, 0.75); + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.2); + -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); } p { - margin-top: 0.5em; - margin-bottom: 0.5em; -} + margin: 0 0 8px; } small { font-size: 85%; } strong { - font-weight: 600; - font-size: 0.95em; - color: #3c3c3c; -} + font-weight: 600; } em { font-style: italic; } +cite { + font-style: normal; } + +h1, +h2, +h3, +h4, +h5, +h6 { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-weight: 600; + line-height: 20px; + color: inherit; + text-rendering: optimizelegibility; } + h1 { - font-size: 1.8em; + font-size: 2em; font-weight: 400; - padding-bottom: .25em; - border-bottom: 1px solid #aaa; - margin-top: 2.5em; - margin-bottom: 1em; + padding-bottom: .15em; + border-bottom: 1px solid #aaaaaa; + margin-top: 1.0em; line-height: 1.2em; } h1.title { padding-bottom: 1em; border-bottom: 0px; - font-size: 2.5em; - text-align: center; - font-weight: 900; - margin-top: 0.75em; - margin-bottom: 0em; -} + font-size: 2.75em; } h2 { - font-size: 1.3em; - margin-top: 2em; } - -h2.subtitle { - text-align: center; } - -h3 { - font-size: 1.125em; - font-style: italic; + font-size: 1.5em; margin-top: 1.5em; } +h3 { + font-size: 1.3em; + font-style: italic; + margin-top: 0.75em; } + h4 { - font-size: 1.125em; - margin-top: 1em; } + font-size: 1.3em; + margin-top: 0.5em; } h5 { - font-size: 1.125em; - margin-top: 0.75em; } + font-size: 1.2em; + margin-top: 0.25em; } h6 { font-size: 1.1em; } - ul, ol { padding: 0; - margin-top: 0.5em; - margin-left: 0.75em; } + margin: 0 0 0px 15px; } ul ul, ul ol, ol ol, ol ul { - margin-bottom: 0; - margin-left: 1.25em; } + margin-bottom: 0; } li { - list-style-type: circle; -} - -ul.simple-boot li { - list-style-type: none; - margin-left: 0em; - margin-bottom: 0.5em; -} - -ol.simple > li, ul.simple > li { - margin-bottom: 0.25em; - margin-left: 0.4em } - -ul.simple.simple-toc > li { - margin-top: 1em; -} - -ul.simple-toc { - list-style: none; - font-size: 0.9em; - margin-left: -0.3em; - margin-top: 1em; } - -ul.simple-toc > li { - list-style-type: none; -} - -ul.simple-toc-section { - list-style-type: circle; - margin-left: 1em; - color: #6c9aae; } - - -ol.arabic { - list-style: decimal; } - -ol.loweralpha { - list-style: lower-alpha; } - -ol.upperalpha { - list-style: upper-alpha; } - -ol.lowerroman { - list-style: lower-roman; } - -ol.upperroman { - list-style: upper-roman; } - -ul.auto-toc { - list-style-type: none; } - + line-height: 20px; } dl { - margin-bottom: 1.5em; } + margin-bottom: 20px; } + +dt, +dd { + line-height: 20px; } dt { - margin-bottom: -0.5em; - margin-left: 0.0em; } + font-weight: bold; } dd { - margin-left: 2.0em; - margin-bottom: 3.0em; - margin-top: 0.5em; } - + margin-left: 10px; + margin-bottom: 26px; } hr { - margin: 2em 0; + margin: 20px 0; border: 0; - border-top: 1px solid #aaa; } + border-top: 1px solid #eeeeee; + border-bottom: 1px solid #ffffff; } + +abbr[title], +abbr[data-original-title] { + cursor: help; + border-bottom: 1px dotted #999999; } + +abbr.initialism { + font-size: 90%; + text-transform: uppercase; } blockquote { - font-size: 0.9em; - font-style: italic; - padding-left: 0.5em; - margin-left: 0; - border-left: 5px solid #bbc; + padding: 0 0 0 15px; + margin: 0 0 20px; + border-left: 5px solid #EFEBE0; } + +table.docinfo + blockquote, table.docinfo blockquote, h1 + blockquote { + border-left: 5px solid #c9c9c9; } +table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { + margin-bottom: 0; + font-size: 15px; + font-weight: 200; + line-height: 1.5; + font-style: italic; } + +q:before, +q:after, +blockquote:before, +blockquote:after { + content: ""; } + +address { + display: block; + margin-bottom: 20px; + font-style: normal; + line-height: 20px; } + +code, +pre { + font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; + padding: 0 3px 2px; + font-weight: 500; + font-size: 12px; + color: #444444; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; } + .pre { font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - font-weight: 500; - font-size: 0.85em; - background-color: #f0f3ff; - padding-left: 3px; - padding-right: 3px; - border-radius: 4px; + font-weight: 600; + /*color: #504da6;*/ } +code { + padding: 2px 4px; + color: #444444; + white-space: nowrap; + background-color: white; + border: 1px solid #777777; } + pre { - font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - color: #222; - font-weight: 500; display: inline-block; box-sizing: border-box; - min-width: 100%; - padding: 0.5em; - margin-top: 0.5em; - margin-bottom: 0.5em; - font-size: 0.85em; + min-width: calc(100% - 19.5px); + padding: 9.5px; + margin: 0.25em 10px 10px 10px; + font-size: 15px; + line-height: 20px; white-space: pre !important; overflow-y: hidden; overflow-x: visible; - background-color: ghostwhite; - border: 1px solid #dde; - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; } + background-color: rgba(0, 0, 0, 0.01); + border: 1px solid #cccccc; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; } + +pre.prettyprint { + margin-bottom: 20px; } + +pre code { + padding: 0; + color: inherit; + white-space: pre; + overflow-x: visible; + background-color: transparent; + border: 0; } .pre-scrollable { max-height: 340px; overflow-y: scroll; } - -/* Nim line-numbered tables */ -.line-nums-table { - width: 100%; - table-layout: fixed; } - -table.line-nums-table { - border-radius: 4px; - border: 1px solid #cccccc; - background-color: ghostwhite; - border-collapse: separate; - margin-top: 15px; - margin-bottom: 25px; } - -.line-nums-table tbody { - border: none; } - -.line-nums-table td pre { - border: none; - background-color: transparent; } - -.line-nums-table td.blob-line-nums { - width: 28px; } - -.line-nums-table td.blob-line-nums pre { - color: #b0b0b0; - -webkit-filter: opacity(75%); - text-align: right; - border-color: transparent; - background-color: transparent; - padding-left: 0px; - margin-left: 0px; - padding-right: 0px; - margin-right: 0px; } - - table { max-width: 100%; background-color: transparent; - margin-top: 0.5em; - margin-bottom: 1.5em; border-collapse: collapse; - border-color: #ccc; - border-spacing: 0; - font-size: 0.9em; -} + border-spacing: 0; } table th, table td { - padding: 0px 0.5em 0px; + padding: 0px 8px 0px; } -table th { - background-color: #e8e8e8; +.table { + width: 100%; + margin-bottom: 20px; } + +.table th, +.table td { + padding: 8px; + line-height: 20px; + text-align: left; + vertical-align: top; + border-top: 1px solid #444444; } + +.table th { font-weight: bold; } -table th.docinfo-name { - background-color: transparent; -} +.table thead th { + vertical-align: bottom; } -table tr:hover { - background-color: ghostwhite; } +.table caption + thead tr:first-child th, +.table caption + thead tr:first-child td, +.table colgroup + thead tr:first-child th, +.table colgroup + thead tr:first-child td, +.table thead:first-child tr:first-child th, +.table thead:first-child tr:first-child td { + border-top: 0; } +.table tbody + tbody { + border-top: 2px solid #444444; } + +.table .table { + background-color: rgba(252, 248, 244, 0.75); } + +.table-condensed th, +.table-condensed td { + padding: 4px 5px; } + +.table-bordered { + border: 1px solid #444444; + border-collapse: separate; + *border-collapse: collapse; + border-left: 0; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; } + +.table-bordered th, +.table-bordered td { + border-left: 1px solid #444444; } + +.table-bordered caption + thead tr:first-child th, +.table-bordered caption + tbody tr:first-child th, +.table-bordered caption + tbody tr:first-child td, +.table-bordered colgroup + thead tr:first-child th, +.table-bordered colgroup + tbody tr:first-child th, +.table-bordered colgroup + tbody tr:first-child td, +.table-bordered thead:first-child tr:first-child th, +.table-bordered tbody:first-child tr:first-child th, +.table-bordered tbody:first-child tr:first-child td { + border-top: 0; } + +.table-bordered thead:first-child tr:first-child > th:first-child, +.table-bordered tbody:first-child tr:first-child > td:first-child, +.table-bordered tbody:first-child tr:first-child > th:first-child { + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; } + +.table-bordered thead:first-child tr:first-child > th:last-child, +.table-bordered tbody:first-child tr:first-child > td:last-child, +.table-bordered tbody:first-child tr:first-child > th:last-child { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; } + +.table-bordered thead:last-child tr:last-child > th:first-child, +.table-bordered tbody:last-child tr:last-child > td:first-child, +.table-bordered tbody:last-child tr:last-child > th:first-child, +.table-bordered tfoot:last-child tr:last-child > td:first-child, +.table-bordered tfoot:last-child tr:last-child > th:first-child { + -webkit-border-bottom-left-radius: 4px; + border-bottom-left-radius: 4px; + -moz-border-radius-bottomleft: 4px; } + +.table-bordered thead:last-child tr:last-child > th:last-child, +.table-bordered tbody:last-child tr:last-child > td:last-child, +.table-bordered tbody:last-child tr:last-child > th:last-child, +.table-bordered tfoot:last-child tr:last-child > td:last-child, +.table-bordered tfoot:last-child tr:last-child > th:last-child { + -webkit-border-bottom-right-radius: 4px; + border-bottom-right-radius: 4px; + -moz-border-radius-bottomright: 4px; } + +.table-bordered tfoot + tbody:last-child tr:last-child td:first-child { + -webkit-border-bottom-left-radius: 0; + border-bottom-left-radius: 0; + -moz-border-radius-bottomleft: 0; } + +.table-bordered tfoot + tbody:last-child tr:last-child td:last-child { + -webkit-border-bottom-right-radius: 0; + border-bottom-right-radius: 0; + -moz-border-radius-bottomright: 0; } + +.table-bordered caption + thead tr:first-child th:first-child, +.table-bordered caption + tbody tr:first-child td:first-child, +.table-bordered colgroup + thead tr:first-child th:first-child, +.table-bordered colgroup + tbody tr:first-child td:first-child { + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; } + +.table-bordered caption + thead tr:first-child th:last-child, +.table-bordered caption + tbody tr:first-child td:last-child, +.table-bordered colgroup + thead tr:first-child th:last-child, +.table-bordered colgroup + tbody tr:first-child td:last-child { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; } + +table.docutils th { + background-color: #e8e8e8; } + +table.docutils tr:hover { + background-color: whitesmoke; } + +.table-striped tbody > tr:nth-child(odd) > td, +.table-striped tbody > tr:nth-child(odd) > th { + background-color: rgba(252, 248, 244, 0.75); } + +.table-hover tbody tr:hover > td, +.table-hover tbody tr:hover > th { + background-color: rgba(241, 222, 204, 0.75); } + +table td[class*="span"], +table th[class*="span"], +.row-fluid table td[class*="span"], +.row-fluid table th[class*="span"] { + display: table-cell; + float: none; + margin-left: 0; } + +.hero-unit { + padding: 60px; + margin-bottom: 30px; + font-size: 18px; + font-weight: 200; + line-height: 30px; + color: inherit; + background-color: rgba(230, 197, 164, 0.75); + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; } + +.hero-unit h1 { + margin-bottom: 0; + font-size: 60px; + line-height: 1; + letter-spacing: -1px; + color: inherit; } + +.hero-unit li { + line-height: 30px; } /* rst2html default used to remove borders from tables and images */ .borderless, table.borderless td, table.borderless th { @@ -482,6 +722,10 @@ table.borderless td, table.borderless th { .hidden { display: none; } +a.toc-backref { + text-decoration: none; + color: #444444; } + blockquote.epigraph { margin: 2em 5em; } @@ -491,6 +735,85 @@ dl.docutils dd { object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] { overflow: hidden; } +/* Uncomment (and remove this text!) to get bold-faced definition list terms +dl.docutils dt { + font-weight: bold } +*/ +div.abstract { + margin: 2em 5em; } + +div.abstract p.topic-title { + font-weight: bold; + text-align: center; } + +div.admonition, div.attention, div.caution, div.danger, div.error, +div.hint, div.important, div.note, div.tip, div.warning { + margin: 2em; + border: medium outset; + padding: 1em; } + +div.note, div.warning { + margin: 1.5em 0px; + border: none; } + +div.note p.admonition-title, +div.warning p.admonition-title { + display: none; } + +/* Clearfix + * http://css-tricks.com/snippets/css/clear-fix/ + */ +div.note:after, +div.warning:after { + content: ""; + display: table; + clear: both; } + +div.note p:before, +div.warning p:before { + display: block; + float: left; + font-size: 4em; + line-height: 1em; + margin-right: 20px; + margin-left: 0em; + margin-top: -10px; + content: '\0270D'; + /*handwriting*/ } + +div.warning p:before { + content: '\026A0'; + /*warning*/ } + +div.admonition p.admonition-title, div.hint p.admonition-title, +div.important p.admonition-title, div.note p.admonition-title, +div.tip p.admonition-title { + font-weight: bold; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } + +div.attention p.admonition-title, div.caution p.admonition-title, +div.danger p.admonition-title, div.error p.admonition-title, +div.warning p.admonition-title, .code .error { + color: #b30000; + font-weight: bold; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } + +/* Uncomment (and remove this text!) to get reduced vertical space in + compound paragraphs. +div.compound .compound-first, div.compound .compound-middle { + margin-bottom: 0.5em } + +div.compound .compound-last, div.compound .compound-middle { + margin-top: 0.5em } +*/ +div.dedication { + margin: 2em 5em; + text-align: center; + font-style: italic; } + +div.dedication p.topic-title { + font-weight: bold; + font-style: normal; } div.figure { margin-left: 2em; @@ -498,14 +821,8 @@ div.figure { div.footer, div.header { clear: both; - text-align: center; - color: #666; font-size: smaller; } -div.footer { - padding-top: 5em; -} - div.line-block { display: block; margin-top: 1em; @@ -516,24 +833,45 @@ div.line-block div.line-block { margin-bottom: 0; margin-left: 1.5em; } +div.sidebar { + margin: 0 0 0.5em 1em; + border: medium outset; + padding: 1em; + background-color: rgba(252, 248, 244, 0.75); + width: 40%; + float: right; + clear: right; } + +div.sidebar p.rubric { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-size: medium; } + +div.system-messages { + margin: 5em; } + +div.system-messages h1 { + color: #b30000; } + +div.system-message { + border: medium outset; + padding: 1em; } + +div.system-message p.system-message-title { + color: #b30000; + font-weight: bold; } + div.topic { margin: 2em; } -div.search_results { - background-color: antiquewhite; - margin: 3em; - padding: 1em; - border: 1px solid #4d4d4d; -} +h1.section-subtitle, h2.section-subtitle, h3.section-subtitle, +h4.section-subtitle, h5.section-subtitle, h6.section-subtitle { + margin-top: 0.4em; } -div#global-links ul { - margin-left: 0; - list-style-type: none; -} +h1.title { + text-align: center; } -div#global-links > simple-boot { - margin-left: 3em; -} +h2.subtitle { + text-align: center; } hr.docutils { width: 75%; } @@ -567,6 +905,30 @@ img.align-center, .figure.align-center, object.align-center { div.align-right { text-align: inherit; } +/* div.align-center * { */ +/* text-align: left } */ + +ul.simple > li { + margin-bottom: 0.5em } + +ol.simple, ul.simple { + margin-bottom: 1em; } + +ol.arabic { + list-style: decimal; } + +ol.loweralpha { + list-style: lower-alpha; } + +ol.upperalpha { + list-style: upper-alpha; } + +ol.lowerroman { + list-style: lower-roman; } + +ol.upperroman { + list-style: upper-roman; } + p.attribution { text-align: right; margin-left: 50%; } @@ -587,6 +949,15 @@ p.rubric { color: maroon; text-align: center; } +p.sidebar-title { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-weight: bold; + font-size: larger; } + +p.sidebar-subtitle { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-weight: bold; } + p.topic-title { font-weight: bold; } @@ -626,14 +997,22 @@ pre.code .inserted, code .inserted { background-color: #A3D289; } span.classifier { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-style: oblique; } span.classifier-delimiter { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: bold; } +span.interpreted { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } + span.option { white-space: nowrap; } +span.pre { + white-space: pre; } + span.problematic { color: #b30000; } @@ -641,6 +1020,44 @@ span.section-subtitle { /* font-size relative to parent (h1..h6 element) */ font-size: 80%; } +table.citation { + border-left: solid 1px #666666; + margin-left: 1px; } + +table.docinfo { + margin: 0em; + margin-top: 2em; + margin-bottom: 2em; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; + color: #444444; } + +table.docutils { + margin-top: 0.5em; + margin-bottom: 0.5em; } + +table.footnote { + border-left: solid 1px #2d2d2d; + margin-left: 1px; } + +table.docutils td, table.docutils th, +table.docinfo td, table.docinfo th { + padding-left: 0.5em; + padding-right: 0.5em; + vertical-align: top; } + +table.docutils th.field-name, table.docinfo th.docinfo-name { + font-weight: 700; + text-align: left; + white-space: nowrap; + padding-left: 0; } + +h1 tt.docutils, h2 tt.docutils, h3 tt.docutils, +h4 tt.docutils, h5 tt.docutils, h6 tt.docutils { + font-size: 100%; } + +ul.auto-toc { + list-style-type: none; } + span.DecNumber { color: #252dbe; } @@ -657,7 +1074,7 @@ span.FloatNumber { color: #252dbe; } span.Identifier { - color: #222; } + color: #3b3b3b; } span.Keyword { font-weight: 600; @@ -722,23 +1139,38 @@ dt pre > span.Identifier, dt pre > span.Operator { color: #155da4; font-weight: 700; } -dt pre > span.Keyword ~ span.Identifier, dt pre > span.Identifier ~ span.Identifier, -dt pre > span.Operator ~ span.Identifier, dt pre > span.Other ~ span.Identifier { +dt pre > span.Identifier ~ span.Identifier, dt pre > span.Operator ~ span.Identifier { + color: inherit; + font-weight: inherit; } + +dt pre > span.Operator ~ span.Identifier { color: inherit; font-weight: inherit; } /* Nim sprite for the footer (taken from main page favicon) */ .nim-sprite { display: inline-block; - height: 16px; - width: 16px; + height: 12px; + width: 12px; background-position: 0 0; - background-size: 16px 16px; + background-size: 12px 12px; -webkit-filter: opacity(50%); background-repeat: no-repeat; background-image: url("data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="); margin-bottom: -5px; } +div.search_results { + background-color: antiquewhite; + margin: 3em; + padding: 1em; + border: 1px solid #4d4d4d; +} + +div#global-links ul { + margin-left: 0; + list-style-type: none; +} + span.pragmadots { /* Position: relative frees us up to make the dots look really nice without fucking up the layout and @@ -746,14 +1178,18 @@ span.pragmadots { position: relative; /* 1px down looks slightly nicer */ top: 1px; + padding: 2px; - background-color: #e8e8e8; + background-color: #D3D3D3; border-radius: 4px; margin: 0 2px; cursor: pointer; - font-size: 0.8em; -} + /* For some reason on Chrome, making the font size + smaller than 1em is causing the parent container to + bulge slightly. So, we're stuck with inheriting 1em, + which is sad, because 0.8em looks better... */ +} span.pragmadots:hover { background-color: #DBDBDB; } @@ -761,10 +1197,6 @@ span.pragmawrap { display: none; } -span.attachedType { - display: none; - visibility: hidden; -} @@ -809,18 +1241,18 @@ function main() {
    • Procs
    • @@ -834,38 +1266,38 @@ function main() {

      Procs

      - -
      proc nimteropRoot(): string {...}{.raises: [], tags: [].}
      + +
      proc nimteropRoot(): string {...}{.raises: [], tags: [].}
      - -
      proc nimteropBuildDir(): string {...}{.raises: [], tags: [].}
      + +
      proc nimteropBuildDir(): string {...}{.raises: [], tags: [].}
      all nimterop generated files go under here (gitignored)
      - -
      proc nimteropSrcDir(): string {...}{.raises: [], tags: [].}
      + +
      proc nimteropSrcDir(): string {...}{.raises: [], tags: [].}
      - -
      proc toastExePath(): string {...}{.raises: [], tags: [].}
      + +
      proc toastExePath(): string {...}{.raises: [], tags: [].}
      - -
      proc incDir(): string {...}{.raises: [], tags: [].}
      + +
      proc incDir(): string {...}{.raises: [], tags: [].}
      - -
      proc testsIncludeDir(): string {...}{.raises: [], tags: [].}
      + +
      proc testsIncludeDir(): string {...}{.raises: [], tags: [].}
      @@ -880,7 +1312,7 @@ all nimterop generated files go under here (gitignored)
      diff --git a/paths.idx b/paths.idx index 8a688d4..df86edd 100755 --- a/paths.idx +++ b/paths.idx @@ -1,6 +1,6 @@ -nimteropRoot paths.html#nimteropRoot paths: nimteropRoot(): string -nimteropBuildDir paths.html#nimteropBuildDir paths: nimteropBuildDir(): string -nimteropSrcDir paths.html#nimteropSrcDir paths: nimteropSrcDir(): string -toastExePath paths.html#toastExePath paths: toastExePath(): string -incDir paths.html#incDir paths: incDir(): string -testsIncludeDir paths.html#testsIncludeDir paths: testsIncludeDir(): string +nimteropRoot paths.html#nimteropRoot, paths: nimteropRoot(): string +nimteropBuildDir paths.html#nimteropBuildDir, paths: nimteropBuildDir(): string +nimteropSrcDir paths.html#nimteropSrcDir, paths: nimteropSrcDir(): string +toastExePath paths.html#toastExePath, paths: toastExePath(): string +incDir paths.html#incDir, paths: incDir(): string +testsIncludeDir paths.html#testsIncludeDir, paths: testsIncludeDir(): string diff --git a/plugin.html b/plugin.html index ac2cd77..0e103c7 100755 --- a/plugin.html +++ b/plugin.html @@ -27,113 +27,232 @@ customize this style sheet. Modified from Chad Skeeters' rst2html-style https://bitbucket.org/cskeeters/rst2html-style/ -Modified by Boyd Greenfield and narimiran +Modified by Boyd Greenfield */ - +/* SCSS variables */ +/* Text weights */ +/* Body colors */ +/* Text colors */ +/* Link colors */ +/* Syntax highlighting colors */ +/* Pct changes */ +/* Mixins */ +/* Body/layout */ html { font-size: 100%; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; } +/* Where we want fancier font if available */ +h1, h2, h3, h4, h5, h6, p.module-desc, table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; } + +h1.title { + font-weight: 900; } + body { font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: 400; - font-size: 1.125em; - line-height: 1.5; - color: #222; - background-color: #FCFCFC; } + font-size: 16px; + line-height: 20px; + color: #444; + letter-spacing: 0.15px; + background-color: #FDFBFA; } /* Skeleton grid */ .container { position: relative; width: 100%; - max-width: 1050px; + max-width: 960px; margin: 0 auto; - padding: 0; + padding: 0 20px; box-sizing: border-box; } .column, .columns { width: 100%; float: left; - box-sizing: border-box; - margin-left: 1%; -} + box-sizing: border-box; } -.column:first-child, -.columns:first-child { - margin-left: 0; } +/* For devices larger than 400px */ +@media (min-width: 400px) { + .container { + width: 100%; + padding: 0; } } +/* For devices larger than 650px */ +@media (min-width: 650px) { + .container { + width: 100%; } -.three.columns { - width: 19%; } + .column, + .columns { + margin-left: 4%; } -.nine.columns { - width: 80.0%; } + .column:first-child, + .columns:first-child { + margin-left: 0; } -.twelve.columns { - width: 100%; - margin-left: 0; } + .one.column, + .one.columns { + width: 4.66666666667%; } + + .two.columns { + width: 13.3333333333%; } -@media screen and (max-width: 860px) { .three.columns { - display: none; - } + width: 22%; } + + .four.columns { + width: 30.6666666667%; } + + .five.columns { + width: 39.3333333333%; } + + .six.columns { + width: 48%; } + + .seven.columns { + width: 56.6666666667%; } + + .eight.columns { + width: 65.3333333333%; } + .nine.columns { - width: 98.0%; - } - body { - font-size: 1em; - line-height: 1.35; - } -} + width: 74.0%; } + + .ten.columns { + width: 82.6666666667%; } + + .eleven.columns { + width: 91.3333333333%; } + + .twelve.columns { + width: 100%; + margin-left: 0; } + + .one-third.column { + width: 30.6666666667%; } + + .two-thirds.column { + width: 65.3333333333%; } } +/* Customer Overrides */ +.footer { + text-align: center; + color: #969696; + padding-top: 10%; } + +p.module-desc { + font-size: 1.1em; + color: #666666; } + +a.link-seesrc { + color: #aec7d2; + font-style: italic; } + +a.link-seesrc:hover { + color: #6c9aae; } + +#toc-list { + word-wrap: break-word; } + +ul.simple-toc { + list-style: none; } + +ul.simple-toc a.reference-toplevel { + font-weight: bold; + color: #0077b3; } + +ul.simple-toc-section { + list-style-type: circle; + color: #6c9aae; } + +ul.simple-toc-section a.reference { + color: #0077b3; } cite { font-style: italic !important; } +dt > pre { + border-color: rgba(0, 0, 0, 0.1); + background-color: rgba(255, 255, 255, 0.3); + margin: 15px 0px 5px; } + +dd > pre { + border-color: rgba(0, 0, 0, 0.1); + background-color: whitesmoke; + margin-top: 8px; } + +.item > dd { + margin-left: 10px; + margin-bottom: 30px; } + +/* Nim line-numbered tables */ +.line-nums-table { + width: 100%; + table-layout: fixed; } /* Nim search input */ div#searchInputDiv { - margin-bottom: 1em; + margin-bottom: 8px; } -input#searchInput { - width: 80%; +div#searchInputDiv input#searchInput { + width: 10em; +} +div.search-groupby { + margin-bottom: 8px; } +table.line-nums-table { + border-radius: 4px; + border: 1px solid #cccccc; + background-color: whitesmoke; + border-collapse: separate; + margin-top: 15px; + margin-bottom: 25px; } + +.line-nums-table tbody { + border: none; } + +.line-nums-table td pre { + border: none; + background-color: transparent; } + +.line-nums-table td.blob-line-nums { + width: 28px; } + +.line-nums-table td.blob-line-nums pre { + color: #b0b0b0; + -webkit-filter: opacity(75%); + text-align: right; + border-color: transparent; + background-color: transparent; + padding-left: 0px; + margin-left: 0px; + padding-right: 0px; + margin-right: 0px; } /* Docgen styles */ /* Links */ a { - color: #07b; - text-decoration: none; -} - -a span.Identifier { - text-decoration: underline; - text-decoration-color: #aab; -} - -a.reference-toplevel { - font-weight: bold; -} - -a.toc-backref { - text-decoration: none; - color: #222; } - -a.link-seesrc { - color: #607c9f; - font-size: 0.9em; - font-style: italic; } + color: #0077b3; + text-decoration: none; } a:hover, a:focus { - color: #607c9f; + color: #00334d; text-decoration: underline; } -a:hover span.Identifier { - color: #607c9f; -} +a:visited { + color: #00334d; } +a:focus { + outline: thin dotted #2d2d2d; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; } + +a:hover, +a:active { + outline: 0; } sub, sup { @@ -210,258 +329,379 @@ img { h2, h3 { - page-break-after: avoid; } -} + page-break-after: avoid; } } +.img-rounded { + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; } +.img-polaroid { + padding: 4px; + background-color: rgba(252, 248, 244, 0.75); + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.2); + -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); } p { - margin-top: 0.5em; - margin-bottom: 0.5em; -} + margin: 0 0 8px; } small { font-size: 85%; } strong { - font-weight: 600; - font-size: 0.95em; - color: #3c3c3c; -} + font-weight: 600; } em { font-style: italic; } +cite { + font-style: normal; } + +h1, +h2, +h3, +h4, +h5, +h6 { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-weight: 600; + line-height: 20px; + color: inherit; + text-rendering: optimizelegibility; } + h1 { - font-size: 1.8em; + font-size: 2em; font-weight: 400; - padding-bottom: .25em; - border-bottom: 1px solid #aaa; - margin-top: 2.5em; - margin-bottom: 1em; + padding-bottom: .15em; + border-bottom: 1px solid #aaaaaa; + margin-top: 1.0em; line-height: 1.2em; } h1.title { padding-bottom: 1em; border-bottom: 0px; - font-size: 2.5em; - text-align: center; - font-weight: 900; - margin-top: 0.75em; - margin-bottom: 0em; -} + font-size: 2.75em; } h2 { - font-size: 1.3em; - margin-top: 2em; } - -h2.subtitle { - text-align: center; } - -h3 { - font-size: 1.125em; - font-style: italic; + font-size: 1.5em; margin-top: 1.5em; } +h3 { + font-size: 1.3em; + font-style: italic; + margin-top: 0.75em; } + h4 { - font-size: 1.125em; - margin-top: 1em; } + font-size: 1.3em; + margin-top: 0.5em; } h5 { - font-size: 1.125em; - margin-top: 0.75em; } + font-size: 1.2em; + margin-top: 0.25em; } h6 { font-size: 1.1em; } - ul, ol { padding: 0; - margin-top: 0.5em; - margin-left: 0.75em; } + margin: 0 0 0px 15px; } ul ul, ul ol, ol ol, ol ul { - margin-bottom: 0; - margin-left: 1.25em; } + margin-bottom: 0; } li { - list-style-type: circle; -} - -ul.simple-boot li { - list-style-type: none; - margin-left: 0em; - margin-bottom: 0.5em; -} - -ol.simple > li, ul.simple > li { - margin-bottom: 0.25em; - margin-left: 0.4em } - -ul.simple.simple-toc > li { - margin-top: 1em; -} - -ul.simple-toc { - list-style: none; - font-size: 0.9em; - margin-left: -0.3em; - margin-top: 1em; } - -ul.simple-toc > li { - list-style-type: none; -} - -ul.simple-toc-section { - list-style-type: circle; - margin-left: 1em; - color: #6c9aae; } - - -ol.arabic { - list-style: decimal; } - -ol.loweralpha { - list-style: lower-alpha; } - -ol.upperalpha { - list-style: upper-alpha; } - -ol.lowerroman { - list-style: lower-roman; } - -ol.upperroman { - list-style: upper-roman; } - -ul.auto-toc { - list-style-type: none; } - + line-height: 20px; } dl { - margin-bottom: 1.5em; } + margin-bottom: 20px; } + +dt, +dd { + line-height: 20px; } dt { - margin-bottom: -0.5em; - margin-left: 0.0em; } + font-weight: bold; } dd { - margin-left: 2.0em; - margin-bottom: 3.0em; - margin-top: 0.5em; } - + margin-left: 10px; + margin-bottom: 26px; } hr { - margin: 2em 0; + margin: 20px 0; border: 0; - border-top: 1px solid #aaa; } + border-top: 1px solid #eeeeee; + border-bottom: 1px solid #ffffff; } + +abbr[title], +abbr[data-original-title] { + cursor: help; + border-bottom: 1px dotted #999999; } + +abbr.initialism { + font-size: 90%; + text-transform: uppercase; } blockquote { - font-size: 0.9em; - font-style: italic; - padding-left: 0.5em; - margin-left: 0; - border-left: 5px solid #bbc; + padding: 0 0 0 15px; + margin: 0 0 20px; + border-left: 5px solid #EFEBE0; } + +table.docinfo + blockquote, table.docinfo blockquote, h1 + blockquote { + border-left: 5px solid #c9c9c9; } +table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { + margin-bottom: 0; + font-size: 15px; + font-weight: 200; + line-height: 1.5; + font-style: italic; } + +q:before, +q:after, +blockquote:before, +blockquote:after { + content: ""; } + +address { + display: block; + margin-bottom: 20px; + font-style: normal; + line-height: 20px; } + +code, +pre { + font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; + padding: 0 3px 2px; + font-weight: 500; + font-size: 12px; + color: #444444; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; } + .pre { font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - font-weight: 500; - font-size: 0.85em; - background-color: #f0f3ff; - padding-left: 3px; - padding-right: 3px; - border-radius: 4px; + font-weight: 600; + /*color: #504da6;*/ } +code { + padding: 2px 4px; + color: #444444; + white-space: nowrap; + background-color: white; + border: 1px solid #777777; } + pre { - font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - color: #222; - font-weight: 500; display: inline-block; box-sizing: border-box; - min-width: 100%; - padding: 0.5em; - margin-top: 0.5em; - margin-bottom: 0.5em; - font-size: 0.85em; + min-width: calc(100% - 19.5px); + padding: 9.5px; + margin: 0.25em 10px 10px 10px; + font-size: 15px; + line-height: 20px; white-space: pre !important; overflow-y: hidden; overflow-x: visible; - background-color: ghostwhite; - border: 1px solid #dde; - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; } + background-color: rgba(0, 0, 0, 0.01); + border: 1px solid #cccccc; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; } + +pre.prettyprint { + margin-bottom: 20px; } + +pre code { + padding: 0; + color: inherit; + white-space: pre; + overflow-x: visible; + background-color: transparent; + border: 0; } .pre-scrollable { max-height: 340px; overflow-y: scroll; } - -/* Nim line-numbered tables */ -.line-nums-table { - width: 100%; - table-layout: fixed; } - -table.line-nums-table { - border-radius: 4px; - border: 1px solid #cccccc; - background-color: ghostwhite; - border-collapse: separate; - margin-top: 15px; - margin-bottom: 25px; } - -.line-nums-table tbody { - border: none; } - -.line-nums-table td pre { - border: none; - background-color: transparent; } - -.line-nums-table td.blob-line-nums { - width: 28px; } - -.line-nums-table td.blob-line-nums pre { - color: #b0b0b0; - -webkit-filter: opacity(75%); - text-align: right; - border-color: transparent; - background-color: transparent; - padding-left: 0px; - margin-left: 0px; - padding-right: 0px; - margin-right: 0px; } - - table { max-width: 100%; background-color: transparent; - margin-top: 0.5em; - margin-bottom: 1.5em; border-collapse: collapse; - border-color: #ccc; - border-spacing: 0; - font-size: 0.9em; -} + border-spacing: 0; } table th, table td { - padding: 0px 0.5em 0px; + padding: 0px 8px 0px; } -table th { - background-color: #e8e8e8; +.table { + width: 100%; + margin-bottom: 20px; } + +.table th, +.table td { + padding: 8px; + line-height: 20px; + text-align: left; + vertical-align: top; + border-top: 1px solid #444444; } + +.table th { font-weight: bold; } -table th.docinfo-name { - background-color: transparent; -} +.table thead th { + vertical-align: bottom; } -table tr:hover { - background-color: ghostwhite; } +.table caption + thead tr:first-child th, +.table caption + thead tr:first-child td, +.table colgroup + thead tr:first-child th, +.table colgroup + thead tr:first-child td, +.table thead:first-child tr:first-child th, +.table thead:first-child tr:first-child td { + border-top: 0; } +.table tbody + tbody { + border-top: 2px solid #444444; } + +.table .table { + background-color: rgba(252, 248, 244, 0.75); } + +.table-condensed th, +.table-condensed td { + padding: 4px 5px; } + +.table-bordered { + border: 1px solid #444444; + border-collapse: separate; + *border-collapse: collapse; + border-left: 0; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; } + +.table-bordered th, +.table-bordered td { + border-left: 1px solid #444444; } + +.table-bordered caption + thead tr:first-child th, +.table-bordered caption + tbody tr:first-child th, +.table-bordered caption + tbody tr:first-child td, +.table-bordered colgroup + thead tr:first-child th, +.table-bordered colgroup + tbody tr:first-child th, +.table-bordered colgroup + tbody tr:first-child td, +.table-bordered thead:first-child tr:first-child th, +.table-bordered tbody:first-child tr:first-child th, +.table-bordered tbody:first-child tr:first-child td { + border-top: 0; } + +.table-bordered thead:first-child tr:first-child > th:first-child, +.table-bordered tbody:first-child tr:first-child > td:first-child, +.table-bordered tbody:first-child tr:first-child > th:first-child { + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; } + +.table-bordered thead:first-child tr:first-child > th:last-child, +.table-bordered tbody:first-child tr:first-child > td:last-child, +.table-bordered tbody:first-child tr:first-child > th:last-child { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; } + +.table-bordered thead:last-child tr:last-child > th:first-child, +.table-bordered tbody:last-child tr:last-child > td:first-child, +.table-bordered tbody:last-child tr:last-child > th:first-child, +.table-bordered tfoot:last-child tr:last-child > td:first-child, +.table-bordered tfoot:last-child tr:last-child > th:first-child { + -webkit-border-bottom-left-radius: 4px; + border-bottom-left-radius: 4px; + -moz-border-radius-bottomleft: 4px; } + +.table-bordered thead:last-child tr:last-child > th:last-child, +.table-bordered tbody:last-child tr:last-child > td:last-child, +.table-bordered tbody:last-child tr:last-child > th:last-child, +.table-bordered tfoot:last-child tr:last-child > td:last-child, +.table-bordered tfoot:last-child tr:last-child > th:last-child { + -webkit-border-bottom-right-radius: 4px; + border-bottom-right-radius: 4px; + -moz-border-radius-bottomright: 4px; } + +.table-bordered tfoot + tbody:last-child tr:last-child td:first-child { + -webkit-border-bottom-left-radius: 0; + border-bottom-left-radius: 0; + -moz-border-radius-bottomleft: 0; } + +.table-bordered tfoot + tbody:last-child tr:last-child td:last-child { + -webkit-border-bottom-right-radius: 0; + border-bottom-right-radius: 0; + -moz-border-radius-bottomright: 0; } + +.table-bordered caption + thead tr:first-child th:first-child, +.table-bordered caption + tbody tr:first-child td:first-child, +.table-bordered colgroup + thead tr:first-child th:first-child, +.table-bordered colgroup + tbody tr:first-child td:first-child { + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; } + +.table-bordered caption + thead tr:first-child th:last-child, +.table-bordered caption + tbody tr:first-child td:last-child, +.table-bordered colgroup + thead tr:first-child th:last-child, +.table-bordered colgroup + tbody tr:first-child td:last-child { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; } + +table.docutils th { + background-color: #e8e8e8; } + +table.docutils tr:hover { + background-color: whitesmoke; } + +.table-striped tbody > tr:nth-child(odd) > td, +.table-striped tbody > tr:nth-child(odd) > th { + background-color: rgba(252, 248, 244, 0.75); } + +.table-hover tbody tr:hover > td, +.table-hover tbody tr:hover > th { + background-color: rgba(241, 222, 204, 0.75); } + +table td[class*="span"], +table th[class*="span"], +.row-fluid table td[class*="span"], +.row-fluid table th[class*="span"] { + display: table-cell; + float: none; + margin-left: 0; } + +.hero-unit { + padding: 60px; + margin-bottom: 30px; + font-size: 18px; + font-weight: 200; + line-height: 30px; + color: inherit; + background-color: rgba(230, 197, 164, 0.75); + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; } + +.hero-unit h1 { + margin-bottom: 0; + font-size: 60px; + line-height: 1; + letter-spacing: -1px; + color: inherit; } + +.hero-unit li { + line-height: 30px; } /* rst2html default used to remove borders from tables and images */ .borderless, table.borderless td, table.borderless th { @@ -482,6 +722,10 @@ table.borderless td, table.borderless th { .hidden { display: none; } +a.toc-backref { + text-decoration: none; + color: #444444; } + blockquote.epigraph { margin: 2em 5em; } @@ -491,6 +735,85 @@ dl.docutils dd { object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] { overflow: hidden; } +/* Uncomment (and remove this text!) to get bold-faced definition list terms +dl.docutils dt { + font-weight: bold } +*/ +div.abstract { + margin: 2em 5em; } + +div.abstract p.topic-title { + font-weight: bold; + text-align: center; } + +div.admonition, div.attention, div.caution, div.danger, div.error, +div.hint, div.important, div.note, div.tip, div.warning { + margin: 2em; + border: medium outset; + padding: 1em; } + +div.note, div.warning { + margin: 1.5em 0px; + border: none; } + +div.note p.admonition-title, +div.warning p.admonition-title { + display: none; } + +/* Clearfix + * http://css-tricks.com/snippets/css/clear-fix/ + */ +div.note:after, +div.warning:after { + content: ""; + display: table; + clear: both; } + +div.note p:before, +div.warning p:before { + display: block; + float: left; + font-size: 4em; + line-height: 1em; + margin-right: 20px; + margin-left: 0em; + margin-top: -10px; + content: '\0270D'; + /*handwriting*/ } + +div.warning p:before { + content: '\026A0'; + /*warning*/ } + +div.admonition p.admonition-title, div.hint p.admonition-title, +div.important p.admonition-title, div.note p.admonition-title, +div.tip p.admonition-title { + font-weight: bold; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } + +div.attention p.admonition-title, div.caution p.admonition-title, +div.danger p.admonition-title, div.error p.admonition-title, +div.warning p.admonition-title, .code .error { + color: #b30000; + font-weight: bold; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } + +/* Uncomment (and remove this text!) to get reduced vertical space in + compound paragraphs. +div.compound .compound-first, div.compound .compound-middle { + margin-bottom: 0.5em } + +div.compound .compound-last, div.compound .compound-middle { + margin-top: 0.5em } +*/ +div.dedication { + margin: 2em 5em; + text-align: center; + font-style: italic; } + +div.dedication p.topic-title { + font-weight: bold; + font-style: normal; } div.figure { margin-left: 2em; @@ -498,14 +821,8 @@ div.figure { div.footer, div.header { clear: both; - text-align: center; - color: #666; font-size: smaller; } -div.footer { - padding-top: 5em; -} - div.line-block { display: block; margin-top: 1em; @@ -516,24 +833,45 @@ div.line-block div.line-block { margin-bottom: 0; margin-left: 1.5em; } +div.sidebar { + margin: 0 0 0.5em 1em; + border: medium outset; + padding: 1em; + background-color: rgba(252, 248, 244, 0.75); + width: 40%; + float: right; + clear: right; } + +div.sidebar p.rubric { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-size: medium; } + +div.system-messages { + margin: 5em; } + +div.system-messages h1 { + color: #b30000; } + +div.system-message { + border: medium outset; + padding: 1em; } + +div.system-message p.system-message-title { + color: #b30000; + font-weight: bold; } + div.topic { margin: 2em; } -div.search_results { - background-color: antiquewhite; - margin: 3em; - padding: 1em; - border: 1px solid #4d4d4d; -} +h1.section-subtitle, h2.section-subtitle, h3.section-subtitle, +h4.section-subtitle, h5.section-subtitle, h6.section-subtitle { + margin-top: 0.4em; } -div#global-links ul { - margin-left: 0; - list-style-type: none; -} +h1.title { + text-align: center; } -div#global-links > simple-boot { - margin-left: 3em; -} +h2.subtitle { + text-align: center; } hr.docutils { width: 75%; } @@ -567,6 +905,30 @@ img.align-center, .figure.align-center, object.align-center { div.align-right { text-align: inherit; } +/* div.align-center * { */ +/* text-align: left } */ + +ul.simple > li { + margin-bottom: 0.5em } + +ol.simple, ul.simple { + margin-bottom: 1em; } + +ol.arabic { + list-style: decimal; } + +ol.loweralpha { + list-style: lower-alpha; } + +ol.upperalpha { + list-style: upper-alpha; } + +ol.lowerroman { + list-style: lower-roman; } + +ol.upperroman { + list-style: upper-roman; } + p.attribution { text-align: right; margin-left: 50%; } @@ -587,6 +949,15 @@ p.rubric { color: maroon; text-align: center; } +p.sidebar-title { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-weight: bold; + font-size: larger; } + +p.sidebar-subtitle { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-weight: bold; } + p.topic-title { font-weight: bold; } @@ -626,14 +997,22 @@ pre.code .inserted, code .inserted { background-color: #A3D289; } span.classifier { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-style: oblique; } span.classifier-delimiter { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: bold; } +span.interpreted { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } + span.option { white-space: nowrap; } +span.pre { + white-space: pre; } + span.problematic { color: #b30000; } @@ -641,6 +1020,44 @@ span.section-subtitle { /* font-size relative to parent (h1..h6 element) */ font-size: 80%; } +table.citation { + border-left: solid 1px #666666; + margin-left: 1px; } + +table.docinfo { + margin: 0em; + margin-top: 2em; + margin-bottom: 2em; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; + color: #444444; } + +table.docutils { + margin-top: 0.5em; + margin-bottom: 0.5em; } + +table.footnote { + border-left: solid 1px #2d2d2d; + margin-left: 1px; } + +table.docutils td, table.docutils th, +table.docinfo td, table.docinfo th { + padding-left: 0.5em; + padding-right: 0.5em; + vertical-align: top; } + +table.docutils th.field-name, table.docinfo th.docinfo-name { + font-weight: 700; + text-align: left; + white-space: nowrap; + padding-left: 0; } + +h1 tt.docutils, h2 tt.docutils, h3 tt.docutils, +h4 tt.docutils, h5 tt.docutils, h6 tt.docutils { + font-size: 100%; } + +ul.auto-toc { + list-style-type: none; } + span.DecNumber { color: #252dbe; } @@ -657,7 +1074,7 @@ span.FloatNumber { color: #252dbe; } span.Identifier { - color: #222; } + color: #3b3b3b; } span.Keyword { font-weight: 600; @@ -722,23 +1139,38 @@ dt pre > span.Identifier, dt pre > span.Operator { color: #155da4; font-weight: 700; } -dt pre > span.Keyword ~ span.Identifier, dt pre > span.Identifier ~ span.Identifier, -dt pre > span.Operator ~ span.Identifier, dt pre > span.Other ~ span.Identifier { +dt pre > span.Identifier ~ span.Identifier, dt pre > span.Operator ~ span.Identifier { + color: inherit; + font-weight: inherit; } + +dt pre > span.Operator ~ span.Identifier { color: inherit; font-weight: inherit; } /* Nim sprite for the footer (taken from main page favicon) */ .nim-sprite { display: inline-block; - height: 16px; - width: 16px; + height: 12px; + width: 12px; background-position: 0 0; - background-size: 16px 16px; + background-size: 12px 12px; -webkit-filter: opacity(50%); background-repeat: no-repeat; background-image: url("data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="); margin-bottom: -5px; } +div.search_results { + background-color: antiquewhite; + margin: 3em; + padding: 1em; + border: 1px solid #4d4d4d; +} + +div#global-links ul { + margin-left: 0; + list-style-type: none; +} + span.pragmadots { /* Position: relative frees us up to make the dots look really nice without fucking up the layout and @@ -746,14 +1178,18 @@ span.pragmadots { position: relative; /* 1px down looks slightly nicer */ top: 1px; + padding: 2px; - background-color: #e8e8e8; + background-color: #D3D3D3; border-radius: 4px; margin: 0 2px; cursor: pointer; - font-size: 0.8em; -} + /* For some reason on Chrome, making the font size + smaller than 1em is causing the parent container to + bulge slightly. So, we're stuck with inheriting 1em, + which is sad, because 0.8em looks better... */ +} span.pragmadots:hover { background-color: #DBDBDB; } @@ -761,10 +1197,6 @@ span.pragmawrap { display: none; } -span.attachedType { - display: none; - visibility: hidden; -} @@ -813,9 +1245,9 @@ function main() { title="Symbol = object name*: string parent*: string - kind*: NimSymKind">Symbol + kind*: NimSymKind">Symbol
    • OnSymbol
    • + title="OnSymbol = proc (sym: var Symbol) {.cdecl.}">OnSymbol
    @@ -855,7 +1287,7 @@ function main() { diff --git a/theindex.html b/theindex.html index 9127e0c..55e6c34 100755 --- a/theindex.html +++ b/theindex.html @@ -27,113 +27,232 @@ customize this style sheet. Modified from Chad Skeeters' rst2html-style https://bitbucket.org/cskeeters/rst2html-style/ -Modified by Boyd Greenfield and narimiran +Modified by Boyd Greenfield */ - +/* SCSS variables */ +/* Text weights */ +/* Body colors */ +/* Text colors */ +/* Link colors */ +/* Syntax highlighting colors */ +/* Pct changes */ +/* Mixins */ +/* Body/layout */ html { font-size: 100%; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; } +/* Where we want fancier font if available */ +h1, h2, h3, h4, h5, h6, p.module-desc, table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; } + +h1.title { + font-weight: 900; } + body { font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: 400; - font-size: 1.125em; - line-height: 1.5; - color: #222; - background-color: #FCFCFC; } + font-size: 16px; + line-height: 20px; + color: #444; + letter-spacing: 0.15px; + background-color: #FDFBFA; } /* Skeleton grid */ .container { position: relative; width: 100%; - max-width: 1050px; + max-width: 960px; margin: 0 auto; - padding: 0; + padding: 0 20px; box-sizing: border-box; } .column, .columns { width: 100%; float: left; - box-sizing: border-box; - margin-left: 1%; -} + box-sizing: border-box; } -.column:first-child, -.columns:first-child { - margin-left: 0; } +/* For devices larger than 400px */ +@media (min-width: 400px) { + .container { + width: 100%; + padding: 0; } } +/* For devices larger than 650px */ +@media (min-width: 650px) { + .container { + width: 100%; } -.three.columns { - width: 19%; } + .column, + .columns { + margin-left: 4%; } -.nine.columns { - width: 80.0%; } + .column:first-child, + .columns:first-child { + margin-left: 0; } -.twelve.columns { - width: 100%; - margin-left: 0; } + .one.column, + .one.columns { + width: 4.66666666667%; } + + .two.columns { + width: 13.3333333333%; } -@media screen and (max-width: 860px) { .three.columns { - display: none; - } + width: 22%; } + + .four.columns { + width: 30.6666666667%; } + + .five.columns { + width: 39.3333333333%; } + + .six.columns { + width: 48%; } + + .seven.columns { + width: 56.6666666667%; } + + .eight.columns { + width: 65.3333333333%; } + .nine.columns { - width: 98.0%; - } - body { - font-size: 1em; - line-height: 1.35; - } -} + width: 74.0%; } + + .ten.columns { + width: 82.6666666667%; } + + .eleven.columns { + width: 91.3333333333%; } + + .twelve.columns { + width: 100%; + margin-left: 0; } + + .one-third.column { + width: 30.6666666667%; } + + .two-thirds.column { + width: 65.3333333333%; } } +/* Customer Overrides */ +.footer { + text-align: center; + color: #969696; + padding-top: 10%; } + +p.module-desc { + font-size: 1.1em; + color: #666666; } + +a.link-seesrc { + color: #aec7d2; + font-style: italic; } + +a.link-seesrc:hover { + color: #6c9aae; } + +#toc-list { + word-wrap: break-word; } + +ul.simple-toc { + list-style: none; } + +ul.simple-toc a.reference-toplevel { + font-weight: bold; + color: #0077b3; } + +ul.simple-toc-section { + list-style-type: circle; + color: #6c9aae; } + +ul.simple-toc-section a.reference { + color: #0077b3; } cite { font-style: italic !important; } +dt > pre { + border-color: rgba(0, 0, 0, 0.1); + background-color: rgba(255, 255, 255, 0.3); + margin: 15px 0px 5px; } + +dd > pre { + border-color: rgba(0, 0, 0, 0.1); + background-color: whitesmoke; + margin-top: 8px; } + +.item > dd { + margin-left: 10px; + margin-bottom: 30px; } + +/* Nim line-numbered tables */ +.line-nums-table { + width: 100%; + table-layout: fixed; } /* Nim search input */ div#searchInputDiv { - margin-bottom: 1em; + margin-bottom: 8px; } -input#searchInput { - width: 80%; +div#searchInputDiv input#searchInput { + width: 10em; +} +div.search-groupby { + margin-bottom: 8px; } +table.line-nums-table { + border-radius: 4px; + border: 1px solid #cccccc; + background-color: whitesmoke; + border-collapse: separate; + margin-top: 15px; + margin-bottom: 25px; } + +.line-nums-table tbody { + border: none; } + +.line-nums-table td pre { + border: none; + background-color: transparent; } + +.line-nums-table td.blob-line-nums { + width: 28px; } + +.line-nums-table td.blob-line-nums pre { + color: #b0b0b0; + -webkit-filter: opacity(75%); + text-align: right; + border-color: transparent; + background-color: transparent; + padding-left: 0px; + margin-left: 0px; + padding-right: 0px; + margin-right: 0px; } /* Docgen styles */ /* Links */ a { - color: #07b; - text-decoration: none; -} - -a span.Identifier { - text-decoration: underline; - text-decoration-color: #aab; -} - -a.reference-toplevel { - font-weight: bold; -} - -a.toc-backref { - text-decoration: none; - color: #222; } - -a.link-seesrc { - color: #607c9f; - font-size: 0.9em; - font-style: italic; } + color: #0077b3; + text-decoration: none; } a:hover, a:focus { - color: #607c9f; + color: #00334d; text-decoration: underline; } -a:hover span.Identifier { - color: #607c9f; -} +a:visited { + color: #00334d; } +a:focus { + outline: thin dotted #2d2d2d; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; } + +a:hover, +a:active { + outline: 0; } sub, sup { @@ -210,258 +329,379 @@ img { h2, h3 { - page-break-after: avoid; } -} + page-break-after: avoid; } } +.img-rounded { + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; } +.img-polaroid { + padding: 4px; + background-color: rgba(252, 248, 244, 0.75); + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.2); + -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); } p { - margin-top: 0.5em; - margin-bottom: 0.5em; -} + margin: 0 0 8px; } small { font-size: 85%; } strong { - font-weight: 600; - font-size: 0.95em; - color: #3c3c3c; -} + font-weight: 600; } em { font-style: italic; } +cite { + font-style: normal; } + +h1, +h2, +h3, +h4, +h5, +h6 { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-weight: 600; + line-height: 20px; + color: inherit; + text-rendering: optimizelegibility; } + h1 { - font-size: 1.8em; + font-size: 2em; font-weight: 400; - padding-bottom: .25em; - border-bottom: 1px solid #aaa; - margin-top: 2.5em; - margin-bottom: 1em; + padding-bottom: .15em; + border-bottom: 1px solid #aaaaaa; + margin-top: 1.0em; line-height: 1.2em; } h1.title { padding-bottom: 1em; border-bottom: 0px; - font-size: 2.5em; - text-align: center; - font-weight: 900; - margin-top: 0.75em; - margin-bottom: 0em; -} + font-size: 2.75em; } h2 { - font-size: 1.3em; - margin-top: 2em; } - -h2.subtitle { - text-align: center; } - -h3 { - font-size: 1.125em; - font-style: italic; + font-size: 1.5em; margin-top: 1.5em; } +h3 { + font-size: 1.3em; + font-style: italic; + margin-top: 0.75em; } + h4 { - font-size: 1.125em; - margin-top: 1em; } + font-size: 1.3em; + margin-top: 0.5em; } h5 { - font-size: 1.125em; - margin-top: 0.75em; } + font-size: 1.2em; + margin-top: 0.25em; } h6 { font-size: 1.1em; } - ul, ol { padding: 0; - margin-top: 0.5em; - margin-left: 0.75em; } + margin: 0 0 0px 15px; } ul ul, ul ol, ol ol, ol ul { - margin-bottom: 0; - margin-left: 1.25em; } + margin-bottom: 0; } li { - list-style-type: circle; -} - -ul.simple-boot li { - list-style-type: none; - margin-left: 0em; - margin-bottom: 0.5em; -} - -ol.simple > li, ul.simple > li { - margin-bottom: 0.25em; - margin-left: 0.4em } - -ul.simple.simple-toc > li { - margin-top: 1em; -} - -ul.simple-toc { - list-style: none; - font-size: 0.9em; - margin-left: -0.3em; - margin-top: 1em; } - -ul.simple-toc > li { - list-style-type: none; -} - -ul.simple-toc-section { - list-style-type: circle; - margin-left: 1em; - color: #6c9aae; } - - -ol.arabic { - list-style: decimal; } - -ol.loweralpha { - list-style: lower-alpha; } - -ol.upperalpha { - list-style: upper-alpha; } - -ol.lowerroman { - list-style: lower-roman; } - -ol.upperroman { - list-style: upper-roman; } - -ul.auto-toc { - list-style-type: none; } - + line-height: 20px; } dl { - margin-bottom: 1.5em; } + margin-bottom: 20px; } + +dt, +dd { + line-height: 20px; } dt { - margin-bottom: -0.5em; - margin-left: 0.0em; } + font-weight: bold; } dd { - margin-left: 2.0em; - margin-bottom: 3.0em; - margin-top: 0.5em; } - + margin-left: 10px; + margin-bottom: 26px; } hr { - margin: 2em 0; + margin: 20px 0; border: 0; - border-top: 1px solid #aaa; } + border-top: 1px solid #eeeeee; + border-bottom: 1px solid #ffffff; } + +abbr[title], +abbr[data-original-title] { + cursor: help; + border-bottom: 1px dotted #999999; } + +abbr.initialism { + font-size: 90%; + text-transform: uppercase; } blockquote { - font-size: 0.9em; - font-style: italic; - padding-left: 0.5em; - margin-left: 0; - border-left: 5px solid #bbc; + padding: 0 0 0 15px; + margin: 0 0 20px; + border-left: 5px solid #EFEBE0; } + +table.docinfo + blockquote, table.docinfo blockquote, h1 + blockquote { + border-left: 5px solid #c9c9c9; } +table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { + margin-bottom: 0; + font-size: 15px; + font-weight: 200; + line-height: 1.5; + font-style: italic; } + +q:before, +q:after, +blockquote:before, +blockquote:after { + content: ""; } + +address { + display: block; + margin-bottom: 20px; + font-style: normal; + line-height: 20px; } + +code, +pre { + font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; + padding: 0 3px 2px; + font-weight: 500; + font-size: 12px; + color: #444444; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; } + .pre { font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - font-weight: 500; - font-size: 0.85em; - background-color: #f0f3ff; - padding-left: 3px; - padding-right: 3px; - border-radius: 4px; + font-weight: 600; + /*color: #504da6;*/ } +code { + padding: 2px 4px; + color: #444444; + white-space: nowrap; + background-color: white; + border: 1px solid #777777; } + pre { - font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - color: #222; - font-weight: 500; display: inline-block; box-sizing: border-box; - min-width: 100%; - padding: 0.5em; - margin-top: 0.5em; - margin-bottom: 0.5em; - font-size: 0.85em; + min-width: calc(100% - 19.5px); + padding: 9.5px; + margin: 0.25em 10px 10px 10px; + font-size: 15px; + line-height: 20px; white-space: pre !important; overflow-y: hidden; overflow-x: visible; - background-color: ghostwhite; - border: 1px solid #dde; - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; } + background-color: rgba(0, 0, 0, 0.01); + border: 1px solid #cccccc; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; } + +pre.prettyprint { + margin-bottom: 20px; } + +pre code { + padding: 0; + color: inherit; + white-space: pre; + overflow-x: visible; + background-color: transparent; + border: 0; } .pre-scrollable { max-height: 340px; overflow-y: scroll; } - -/* Nim line-numbered tables */ -.line-nums-table { - width: 100%; - table-layout: fixed; } - -table.line-nums-table { - border-radius: 4px; - border: 1px solid #cccccc; - background-color: ghostwhite; - border-collapse: separate; - margin-top: 15px; - margin-bottom: 25px; } - -.line-nums-table tbody { - border: none; } - -.line-nums-table td pre { - border: none; - background-color: transparent; } - -.line-nums-table td.blob-line-nums { - width: 28px; } - -.line-nums-table td.blob-line-nums pre { - color: #b0b0b0; - -webkit-filter: opacity(75%); - text-align: right; - border-color: transparent; - background-color: transparent; - padding-left: 0px; - margin-left: 0px; - padding-right: 0px; - margin-right: 0px; } - - table { max-width: 100%; background-color: transparent; - margin-top: 0.5em; - margin-bottom: 1.5em; border-collapse: collapse; - border-color: #ccc; - border-spacing: 0; - font-size: 0.9em; -} + border-spacing: 0; } table th, table td { - padding: 0px 0.5em 0px; + padding: 0px 8px 0px; } -table th { - background-color: #e8e8e8; +.table { + width: 100%; + margin-bottom: 20px; } + +.table th, +.table td { + padding: 8px; + line-height: 20px; + text-align: left; + vertical-align: top; + border-top: 1px solid #444444; } + +.table th { font-weight: bold; } -table th.docinfo-name { - background-color: transparent; -} +.table thead th { + vertical-align: bottom; } -table tr:hover { - background-color: ghostwhite; } +.table caption + thead tr:first-child th, +.table caption + thead tr:first-child td, +.table colgroup + thead tr:first-child th, +.table colgroup + thead tr:first-child td, +.table thead:first-child tr:first-child th, +.table thead:first-child tr:first-child td { + border-top: 0; } +.table tbody + tbody { + border-top: 2px solid #444444; } + +.table .table { + background-color: rgba(252, 248, 244, 0.75); } + +.table-condensed th, +.table-condensed td { + padding: 4px 5px; } + +.table-bordered { + border: 1px solid #444444; + border-collapse: separate; + *border-collapse: collapse; + border-left: 0; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; } + +.table-bordered th, +.table-bordered td { + border-left: 1px solid #444444; } + +.table-bordered caption + thead tr:first-child th, +.table-bordered caption + tbody tr:first-child th, +.table-bordered caption + tbody tr:first-child td, +.table-bordered colgroup + thead tr:first-child th, +.table-bordered colgroup + tbody tr:first-child th, +.table-bordered colgroup + tbody tr:first-child td, +.table-bordered thead:first-child tr:first-child th, +.table-bordered tbody:first-child tr:first-child th, +.table-bordered tbody:first-child tr:first-child td { + border-top: 0; } + +.table-bordered thead:first-child tr:first-child > th:first-child, +.table-bordered tbody:first-child tr:first-child > td:first-child, +.table-bordered tbody:first-child tr:first-child > th:first-child { + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; } + +.table-bordered thead:first-child tr:first-child > th:last-child, +.table-bordered tbody:first-child tr:first-child > td:last-child, +.table-bordered tbody:first-child tr:first-child > th:last-child { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; } + +.table-bordered thead:last-child tr:last-child > th:first-child, +.table-bordered tbody:last-child tr:last-child > td:first-child, +.table-bordered tbody:last-child tr:last-child > th:first-child, +.table-bordered tfoot:last-child tr:last-child > td:first-child, +.table-bordered tfoot:last-child tr:last-child > th:first-child { + -webkit-border-bottom-left-radius: 4px; + border-bottom-left-radius: 4px; + -moz-border-radius-bottomleft: 4px; } + +.table-bordered thead:last-child tr:last-child > th:last-child, +.table-bordered tbody:last-child tr:last-child > td:last-child, +.table-bordered tbody:last-child tr:last-child > th:last-child, +.table-bordered tfoot:last-child tr:last-child > td:last-child, +.table-bordered tfoot:last-child tr:last-child > th:last-child { + -webkit-border-bottom-right-radius: 4px; + border-bottom-right-radius: 4px; + -moz-border-radius-bottomright: 4px; } + +.table-bordered tfoot + tbody:last-child tr:last-child td:first-child { + -webkit-border-bottom-left-radius: 0; + border-bottom-left-radius: 0; + -moz-border-radius-bottomleft: 0; } + +.table-bordered tfoot + tbody:last-child tr:last-child td:last-child { + -webkit-border-bottom-right-radius: 0; + border-bottom-right-radius: 0; + -moz-border-radius-bottomright: 0; } + +.table-bordered caption + thead tr:first-child th:first-child, +.table-bordered caption + tbody tr:first-child td:first-child, +.table-bordered colgroup + thead tr:first-child th:first-child, +.table-bordered colgroup + tbody tr:first-child td:first-child { + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; } + +.table-bordered caption + thead tr:first-child th:last-child, +.table-bordered caption + tbody tr:first-child td:last-child, +.table-bordered colgroup + thead tr:first-child th:last-child, +.table-bordered colgroup + tbody tr:first-child td:last-child { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; } + +table.docutils th { + background-color: #e8e8e8; } + +table.docutils tr:hover { + background-color: whitesmoke; } + +.table-striped tbody > tr:nth-child(odd) > td, +.table-striped tbody > tr:nth-child(odd) > th { + background-color: rgba(252, 248, 244, 0.75); } + +.table-hover tbody tr:hover > td, +.table-hover tbody tr:hover > th { + background-color: rgba(241, 222, 204, 0.75); } + +table td[class*="span"], +table th[class*="span"], +.row-fluid table td[class*="span"], +.row-fluid table th[class*="span"] { + display: table-cell; + float: none; + margin-left: 0; } + +.hero-unit { + padding: 60px; + margin-bottom: 30px; + font-size: 18px; + font-weight: 200; + line-height: 30px; + color: inherit; + background-color: rgba(230, 197, 164, 0.75); + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; } + +.hero-unit h1 { + margin-bottom: 0; + font-size: 60px; + line-height: 1; + letter-spacing: -1px; + color: inherit; } + +.hero-unit li { + line-height: 30px; } /* rst2html default used to remove borders from tables and images */ .borderless, table.borderless td, table.borderless th { @@ -482,6 +722,10 @@ table.borderless td, table.borderless th { .hidden { display: none; } +a.toc-backref { + text-decoration: none; + color: #444444; } + blockquote.epigraph { margin: 2em 5em; } @@ -491,6 +735,85 @@ dl.docutils dd { object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] { overflow: hidden; } +/* Uncomment (and remove this text!) to get bold-faced definition list terms +dl.docutils dt { + font-weight: bold } +*/ +div.abstract { + margin: 2em 5em; } + +div.abstract p.topic-title { + font-weight: bold; + text-align: center; } + +div.admonition, div.attention, div.caution, div.danger, div.error, +div.hint, div.important, div.note, div.tip, div.warning { + margin: 2em; + border: medium outset; + padding: 1em; } + +div.note, div.warning { + margin: 1.5em 0px; + border: none; } + +div.note p.admonition-title, +div.warning p.admonition-title { + display: none; } + +/* Clearfix + * http://css-tricks.com/snippets/css/clear-fix/ + */ +div.note:after, +div.warning:after { + content: ""; + display: table; + clear: both; } + +div.note p:before, +div.warning p:before { + display: block; + float: left; + font-size: 4em; + line-height: 1em; + margin-right: 20px; + margin-left: 0em; + margin-top: -10px; + content: '\0270D'; + /*handwriting*/ } + +div.warning p:before { + content: '\026A0'; + /*warning*/ } + +div.admonition p.admonition-title, div.hint p.admonition-title, +div.important p.admonition-title, div.note p.admonition-title, +div.tip p.admonition-title { + font-weight: bold; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } + +div.attention p.admonition-title, div.caution p.admonition-title, +div.danger p.admonition-title, div.error p.admonition-title, +div.warning p.admonition-title, .code .error { + color: #b30000; + font-weight: bold; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } + +/* Uncomment (and remove this text!) to get reduced vertical space in + compound paragraphs. +div.compound .compound-first, div.compound .compound-middle { + margin-bottom: 0.5em } + +div.compound .compound-last, div.compound .compound-middle { + margin-top: 0.5em } +*/ +div.dedication { + margin: 2em 5em; + text-align: center; + font-style: italic; } + +div.dedication p.topic-title { + font-weight: bold; + font-style: normal; } div.figure { margin-left: 2em; @@ -498,14 +821,8 @@ div.figure { div.footer, div.header { clear: both; - text-align: center; - color: #666; font-size: smaller; } -div.footer { - padding-top: 5em; -} - div.line-block { display: block; margin-top: 1em; @@ -516,24 +833,45 @@ div.line-block div.line-block { margin-bottom: 0; margin-left: 1.5em; } +div.sidebar { + margin: 0 0 0.5em 1em; + border: medium outset; + padding: 1em; + background-color: rgba(252, 248, 244, 0.75); + width: 40%; + float: right; + clear: right; } + +div.sidebar p.rubric { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-size: medium; } + +div.system-messages { + margin: 5em; } + +div.system-messages h1 { + color: #b30000; } + +div.system-message { + border: medium outset; + padding: 1em; } + +div.system-message p.system-message-title { + color: #b30000; + font-weight: bold; } + div.topic { margin: 2em; } -div.search_results { - background-color: antiquewhite; - margin: 3em; - padding: 1em; - border: 1px solid #4d4d4d; -} +h1.section-subtitle, h2.section-subtitle, h3.section-subtitle, +h4.section-subtitle, h5.section-subtitle, h6.section-subtitle { + margin-top: 0.4em; } -div#global-links ul { - margin-left: 0; - list-style-type: none; -} +h1.title { + text-align: center; } -div#global-links > simple-boot { - margin-left: 3em; -} +h2.subtitle { + text-align: center; } hr.docutils { width: 75%; } @@ -567,6 +905,30 @@ img.align-center, .figure.align-center, object.align-center { div.align-right { text-align: inherit; } +/* div.align-center * { */ +/* text-align: left } */ + +ul.simple > li { + margin-bottom: 0.5em } + +ol.simple, ul.simple { + margin-bottom: 1em; } + +ol.arabic { + list-style: decimal; } + +ol.loweralpha { + list-style: lower-alpha; } + +ol.upperalpha { + list-style: upper-alpha; } + +ol.lowerroman { + list-style: lower-roman; } + +ol.upperroman { + list-style: upper-roman; } + p.attribution { text-align: right; margin-left: 50%; } @@ -587,6 +949,15 @@ p.rubric { color: maroon; text-align: center; } +p.sidebar-title { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-weight: bold; + font-size: larger; } + +p.sidebar-subtitle { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-weight: bold; } + p.topic-title { font-weight: bold; } @@ -626,14 +997,22 @@ pre.code .inserted, code .inserted { background-color: #A3D289; } span.classifier { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-style: oblique; } span.classifier-delimiter { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: bold; } +span.interpreted { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } + span.option { white-space: nowrap; } +span.pre { + white-space: pre; } + span.problematic { color: #b30000; } @@ -641,6 +1020,44 @@ span.section-subtitle { /* font-size relative to parent (h1..h6 element) */ font-size: 80%; } +table.citation { + border-left: solid 1px #666666; + margin-left: 1px; } + +table.docinfo { + margin: 0em; + margin-top: 2em; + margin-bottom: 2em; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; + color: #444444; } + +table.docutils { + margin-top: 0.5em; + margin-bottom: 0.5em; } + +table.footnote { + border-left: solid 1px #2d2d2d; + margin-left: 1px; } + +table.docutils td, table.docutils th, +table.docinfo td, table.docinfo th { + padding-left: 0.5em; + padding-right: 0.5em; + vertical-align: top; } + +table.docutils th.field-name, table.docinfo th.docinfo-name { + font-weight: 700; + text-align: left; + white-space: nowrap; + padding-left: 0; } + +h1 tt.docutils, h2 tt.docutils, h3 tt.docutils, +h4 tt.docutils, h5 tt.docutils, h6 tt.docutils { + font-size: 100%; } + +ul.auto-toc { + list-style-type: none; } + span.DecNumber { color: #252dbe; } @@ -657,7 +1074,7 @@ span.FloatNumber { color: #252dbe; } span.Identifier { - color: #222; } + color: #3b3b3b; } span.Keyword { font-weight: 600; @@ -722,23 +1139,38 @@ dt pre > span.Identifier, dt pre > span.Operator { color: #155da4; font-weight: 700; } -dt pre > span.Keyword ~ span.Identifier, dt pre > span.Identifier ~ span.Identifier, -dt pre > span.Operator ~ span.Identifier, dt pre > span.Other ~ span.Identifier { +dt pre > span.Identifier ~ span.Identifier, dt pre > span.Operator ~ span.Identifier { + color: inherit; + font-weight: inherit; } + +dt pre > span.Operator ~ span.Identifier { color: inherit; font-weight: inherit; } /* Nim sprite for the footer (taken from main page favicon) */ .nim-sprite { display: inline-block; - height: 16px; - width: 16px; + height: 12px; + width: 12px; background-position: 0 0; - background-size: 16px 16px; + background-size: 12px 12px; -webkit-filter: opacity(50%); background-repeat: no-repeat; background-image: url("data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="); margin-bottom: -5px; } +div.search_results { + background-color: antiquewhite; + margin: 3em; + padding: 1em; + border: 1px solid #4d4d4d; +} + +div#global-links ul { + margin-left: 0; + list-style-type: none; +} + span.pragmadots { /* Position: relative frees us up to make the dots look really nice without fucking up the layout and @@ -746,14 +1178,18 @@ span.pragmadots { position: relative; /* 1px down looks slightly nicer */ top: 1px; + padding: 2px; - background-color: #e8e8e8; + background-color: #D3D3D3; border-radius: 4px; margin: 0 2px; cursor: pointer; - font-size: 0.8em; -} + /* For some reason on Chrome, making the font size + smaller than 1em is causing the parent container to + bulge slightly. So, we're stuck with inheriting 1em, + which is sad, because 0.8em looks better... */ +} span.pragmadots:hover { background-color: #DBDBDB; } @@ -761,10 +1197,6 @@ span.pragmawrap { display: none; } -span.attachedType { - display: none; - visibility: hidden; -} @@ -803,7 +1235,7 @@ function main() {
cDebug:
  • cimport: cDebug()
  • + data-doc-search-tag="cimport: cDebug()" href="cimport.html#cDebug%2C">cimport: cDebug()
cDefine:
cDisableCaching:
  • cimport: cDisableCaching()
  • + data-doc-search-tag="cimport: cDisableCaching()" href="cimport.html#cDisableCaching%2C">cimport: cDisableCaching()
cImport:
cIncludeDir:
+
configure:
cOverride:
cpFile:
cPlugin:
cSearchPath:
cSkipSymbol:
defineEnum:
  • types: defineEnum(typ)
  • + data-doc-search-tag="types: defineEnum(typ)" href="types.html#defineEnum.t%2C">types: defineEnum(typ)
downloadUrl:
incDir:
  • paths: incDir(): string
  • + data-doc-search-tag="paths: incDir(): string" href="paths.html#incDir%2C">paths: incDir(): string
mkDir:
nimteropBuildDir:
  • paths: nimteropBuildDir(): string
  • + data-doc-search-tag="paths: nimteropBuildDir(): string" href="paths.html#nimteropBuildDir%2C">paths: nimteropBuildDir(): string
nimteropRoot:
  • paths: nimteropRoot(): string
  • + data-doc-search-tag="paths: nimteropRoot(): string" href="paths.html#nimteropRoot%2C">paths: nimteropRoot(): string
nimteropSrcDir:
  • paths: nimteropSrcDir(): string
  • + data-doc-search-tag="paths: nimteropSrcDir(): string" href="paths.html#nimteropSrcDir%2C">paths: nimteropSrcDir(): string
OnSymbol:
testsIncludeDir:
  • paths: testsIncludeDir(): string
  • + data-doc-search-tag="paths: testsIncludeDir(): string" href="paths.html#testsIncludeDir%2C">paths: testsIncludeDir(): string
time_t:
toastExePath:
  • paths: toastExePath(): string
  • + data-doc-search-tag="paths: toastExePath(): string" href="paths.html#toastExePath%2C">paths: toastExePath(): string
va_list:
@@ -1445,11 +1446,26 @@ Add an include directory that is forwarded to the C/C++ compiler using cCompile("path/to/dir", exclude="test2.c")
- -
macro cImport(filename: static string; recurse: static bool = false): untyped
+ +
macro cImport(filename: static string; recurse: static bool = false;
+             dynlib: static string = ""): untyped

Import all supported definitions from specified header file. Generated content is cached in nimcache until filename changes unless cDisableCaching() is set. nim -f can also be used after Nim v0.19.4 to flush the cache.

recurse can be used to generate Nim wrappers from #include files referenced in filename. This is only done for files in the same directory as filename or in a directory added using cIncludeDir()

+

dynlib can be used to specify the Nim string to use to specify the dynamic library to load the imported symbols from. For example:

+
const
+  dynpcre =
+    when defined(windows):
+      when defined(cpu64):
+        "pcre64.dll"
+      else:
+        "pcre32.dll"
+    elif hostOS == "macosx":
+      "libpcre(.3|.1|).dylib"
+    else:
+      "libpcre.so(.3|.1|)"
+
+cImport("pcre.h", dynlib="dynpcre")

If dynlib is not specified, the C/C++ implementation files can be compiled in with cCompile(), or the {.passL.} pragma can be used to specify the static lib to link.

@@ -1463,7 +1479,7 @@ Add an include directory that is forwarded to the C/C++ compiler using
- Made with Nim. Generated: 2019-05-09 02:07:17 UTC + Made with Nim. Generated: 2019-05-09 04:53:00 UTC diff --git a/cimport.idx b/cimport.idx index 65b278b..19d15b6 100755 --- a/cimport.idx +++ b/cimport.idx @@ -9,4 +9,4 @@ cAddSearchDir cimport.html#cAddSearchDir,string cimport: cAddSearchDir(dir: stri cIncludeDir cimport.html#cIncludeDir.m, cimport: cIncludeDir(dir: static string): untyped cAddStdDir cimport.html#cAddStdDir,string cimport: cAddStdDir(mode = "c") cCompile cimport.html#cCompile.m,,string,string cimport: cCompile(path: static string; mode = "c"; exclude = ""): untyped -cImport cimport.html#cImport.m, cimport: cImport(filename: static string; recurse: static bool = false): untyped +cImport cimport.html#cImport.m,,string cimport: cImport(filename: static string; recurse: static bool = false;\n dynlib: static string = ""): untyped diff --git a/compat.html b/compat.html index d70bd18..2dbd266 100755 --- a/compat.html +++ b/compat.html @@ -1281,7 +1281,7 @@ naive version of os.relativePath ; remove after nim >= 0.19.9 diff --git a/git.html b/git.html index 1d9883c..03d6476 100755 --- a/git.html +++ b/git.html @@ -1368,7 +1368,7 @@ function main() { diff --git a/paths.html b/paths.html index 8ae6986..c245185 100755 --- a/paths.html +++ b/paths.html @@ -1312,7 +1312,7 @@ all nimterop generated files go under here (gitignored) diff --git a/plugin.html b/plugin.html index 0e103c7..7211c2c 100755 --- a/plugin.html +++ b/plugin.html @@ -1287,7 +1287,7 @@ function main() { diff --git a/theindex.html b/theindex.html index 55e6c34..51d103e 100755 --- a/theindex.html +++ b/theindex.html @@ -1247,7 +1247,9 @@ function main() {
cImport:
cIncludeDir:
@@ -1477,7 +1477,7 @@ Add an include directory that is forwarded to the C/C++ compiler using
- Made with Nim. Generated: 2019-05-09 06:07:27 UTC + Made with Nim. Generated: 2019-05-09 06:10:00 UTC diff --git a/compat.html b/compat.html index 1bfc001..6ef1cba 100755 --- a/compat.html +++ b/compat.html @@ -1281,7 +1281,7 @@ naive version of os.relativePath ; remove after nim >= 0.19.9 diff --git a/git.html b/git.html index dd7e21e..35225ee 100755 --- a/git.html +++ b/git.html @@ -1368,7 +1368,7 @@ function main() { diff --git a/paths.html b/paths.html index 3c29d67..0b5a138 100755 --- a/paths.html +++ b/paths.html @@ -1312,7 +1312,7 @@ all nimterop generated files go under here (gitignored) diff --git a/plugin.html b/plugin.html index f53a574..d219e65 100755 --- a/plugin.html +++ b/plugin.html @@ -1287,7 +1287,7 @@ function main() { diff --git a/theindex.html b/theindex.html index 63f9762..c2bed34 100755 --- a/theindex.html +++ b/theindex.html @@ -1372,7 +1372,7 @@ function main() { diff --git a/types.html b/types.html index 8a55a35..3a49234 100755 --- a/types.html +++ b/types.html @@ -1315,7 +1315,7 @@ function main() { From 2352e77c5e02bba9e327c6a140a04a8c283480af Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 9 May 2019 02:57:55 -0500 Subject: [PATCH 216/593] Import macros in plugin, no newlines in enum expressions, strformat issue --- nimterop/cimport.nim | 2 +- nimterop/getters.nim | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index e356d11..d2c1e69 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -258,7 +258,7 @@ macro cPlugin*(body): untyped = sym.name = sym.name.replace("SDL_", "") let - data = "import nimterop/plugin\n\n" & body.repr + data = "import macros, nimterop/plugin\n\n" & body.repr hash = data.hash().abs() path = getTempDir() / "nimterop_" & $hash & ".nim" diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 67482d1..6eaf049 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -94,7 +94,7 @@ proc checkIdentifier(name, kind, parent, origName: string) = if name.len != 0: let - origStr = if name != origName: ", originally '{origName}' before 'cPlugin:onSymbol()', still" else: "" + origStr = if name != origName: &", originally '{origName}' before 'cPlugin:onSymbol()', still" else: "" errmsg = &"Identifier '{parentStr}{name}' ({kind}){origStr} contains" doAssert name[0] != '_' and name[^1] != '_', errmsg & " leading/trailing underscores '_'" @@ -331,7 +331,7 @@ proc getNimExpression*(expr: string): string = (" ", ""), ("<<", " shl "), (">>", " shr "), ("^", " xor "), ("&", " and "), ("|", " or "), - ("~", " not ") + ("~", " not "), ("\n", " "), ("\r", "") ]) proc getSplitComma*(joined: seq[string]): seq[string] = From 78d116b2050d538a11086912af2161da40681c52 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Fri, 10 May 2019 08:47:12 -0500 Subject: [PATCH 217/593] Add lite template, clarify order of calls --- README.md | 2 +- nimterop/cimport.nim | 14 ++++++++++++-- nimterop/template.nim | 4 ++-- nimterop/templite.nim | 36 ++++++++++++++++++++++++++++++++++++ 4 files changed, 51 insertions(+), 5 deletions(-) create mode 100644 nimterop/templite.nim diff --git a/README.md b/README.md index f9cb9f6..f14070b 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,7 @@ cImport("clib.h") cCompile("clib/src/*.c") ``` -Check out [template.nim](https://github.com/nimterop/nimterop/blob/master/nimterop/template.nim) as a starting point for wrapping a new library. The template can be copied and trimmed down and modified as required. +Check out [template.nim](https://github.com/nimterop/nimterop/blob/master/nimterop/template.nim) as a starting point for wrapping a new library. The template can be copied and trimmed down and modified as required. [templite.nim](https://github.com/nimterop/nimterop/blob/master/nimterop/templite.nim) is a shorter version for more experienced users. Refer to the ```tests``` directory for examples on how the library can be used. diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index d2c1e69..764fc10 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -3,7 +3,8 @@ This is the main nimterop import file to help with wrapping C/C++ source code. Check out `template.nim `_ as a starting point for wrapping a new library. The template can be copied and -trimmed down and modified as required. +trimmed down and modified as required. `templite.nim `_ is a shorter +version for more experienced users. All ``{.compileTime.}`` procs must be used in a compile time context, e.g. using: @@ -188,6 +189,9 @@ macro cOverride*(body): untyped = ## Using the `cOverride() `_ block, nimterop ## can be instructed to skip over ``svGetCallerInfo()``. This works for procs, ## consts and types. + ## + ## `cOverride() `_ only affects calls to + ## `cImport() `_ that follow it. proc recFindIdent(node: NimNode): seq[string] = if node.kind != nnkIdent: @@ -209,6 +213,9 @@ macro cOverride*(body): untyped = proc cSkipSymbol*(skips: seq[string]) {.compileTime.} = ## Similar to `cOverride() `_, this macro allows ## filtering out symbols not of interest from the generated output. + ## + ## `cSkipSymbol() `_ only affects calls to + ## `cImport() `_ that follow it. runnableExamples: static: cSkipSymbol @["proc1", "Type2"] gStateCT.symOverride.add skips @@ -239,7 +246,10 @@ macro cPlugin*(body): untyped = ## - `nskEnumField` for enum (field) names, though they are in the global namespace as `nskConst` ## - `nskProc` - for proc names ## - ## `nimterop/plugins` is implicitly imported to provide access to standard plugin facilities. + ## ``nimterop/plugins`` is implicitly imported to provide access to standard plugin facilities. + ## + ## `cPlugin() `_ only affects calls to + ## `cImport() `_ that follow it. runnableExamples: cPlugin: import strutils diff --git a/nimterop/template.nim b/nimterop/template.nim index aea8535..04a0219 100644 --- a/nimterop/template.nim +++ b/nimterop/template.nim @@ -52,7 +52,7 @@ cOverride: symbol = object # Specify include directories for gcc and Nim -cInclude(srcDir/"include") +cIncludeDir(srcDir/"include") # Define global symbols cDefine("SYMBOL", "value") @@ -64,7 +64,7 @@ cDefine("SYMBOL", "value") {.passL: "flags".} # Compile in any common source code -cCompile(srcDir/"windows/file.c") +cCompile(srcDir/"file.c") # Perform OS specific tasks when defined(windows): diff --git a/nimterop/templite.nim b/nimterop/templite.nim new file mode 100644 index 0000000..71262df --- /dev/null +++ b/nimterop/templite.nim @@ -0,0 +1,36 @@ +import os, strutils + +import nimterop/[cimport, git, paths] + +const + baseDir = currentSourcePath.parentDir()/"build" + + srcDir = baseDir/"project" + +static: + cDebug() + cDisableCaching() + + gitPull("https://github.com/user/project", outdir = srcDir, plist = """ +include/*.h +src/*.c +""", checkout = "tag/branch/hash") + + downloadUrl("https://hostname.com/file.h", outdir = srcDir) + +cIncludeDir(srcDir/"include") + +cDefine("SYMBOL", "value") + +{.passC: "flags".} +{.passL: "flags".} + +cCompile(srcDir/"file.c") + +cPlugin: + import strutils + + proc onSymbol*(sym: var Symbol) {.exportc, dynlib.} = + sym.name = sym.name.strip(chars = {'_'}) + +cImport(srcDir/"include/file.h", recurse = true) From 7729ea93cab424ca629216aa52df289afc206a91 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Fri, 10 May 2019 18:51:46 -0500 Subject: [PATCH 218/593] Use $CC for gcc and user specified Nim --- README.md | 3 ++- nimterop/cimport.nim | 12 ++++++++++-- nimterop/getters.nim | 4 ++-- nimterop/globals.nim | 2 +- nimterop/toast.nim | 3 +++ 5 files changed, 18 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index f14070b..9977e29 100644 --- a/README.md +++ b/README.md @@ -72,6 +72,7 @@ Usage: -I=, --includeDirs= strings {} include directory to pass to preprocessor -l=, --dynlib= string "" Import symbols from library in specified Nim string -O=, --symOverride= strings {} skip generating specified symbols + --nim= string "nim" use a particular Nim executable (default: $PATH/nim) --pluginSourcePath= string "" Nim file to build and load as a plugin -d, --debug bool false enable debug output -m=, --mode= string "cpp" language parser: c or cpp @@ -84,7 +85,7 @@ In order to use the tree-sitter C library, it has to be compiled into a separate Alternatively, the `cImport()` macro allows easier creation of wrappers in code. It runs `toast` on the specified header file and injects the generated wrapper content into the application at compile time. A few other helper procs are provided to influence this process. Output is cached to save time on subsequent runs. -`toast` can also be used to run the header through the preprocessor which cleans up the code considerably. Along with the recursion capability which runs through all #include files, one large simpler header file can be created which can then be processed with `toast` or even `c2nim` if so desired. +`toast` can also be used to run the header through the preprocessor which cleans up the code considerably. Along with the recursion capability which runs through all #include files, one large simpler header file can be created which can then be processed with `toast` or even `c2nim` if so desired. By default, the `$CC` environment variable is used. If not found, `toast` defaults to `gcc`. The tree-sitter library is limited as well - it may fail on some advanced language constructs but is designed to handle them gracefully since it is expected to have bad code while actively typing in an editor. When an error is detected, tree-sitter includes an ERROR node at that location in the AST. At this time, `cImport()` will complain and continue if it encounters any errors. Depending on how severe the errors are, compilation may succeed or fail. Glaring issues will be communicated to the tree-sitter team but their goals may not always align with those of this project. diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index 764fc10..5717ac3 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -115,7 +115,12 @@ proc getNimCheckError(output: string): tuple[tmpFile, errors: string] = doAssert fileExists(result.tmpFile), "Bad codegen - unable to write to TEMP: " & result.tmpFile let - (check, _) = gorgeEx("nim check " & result.tmpFile) + nim = + when (NimMajor, NimMinor, NimPatch) >= (0, 19, 9): + getCurrentCompilerExe() + else: + "nim" + (check, _) = gorgeEx(&"{nim} check {result.tmpFile.quoteShell}") result.errors = "\n\n" & check @@ -144,6 +149,9 @@ proc getToast(fullpath: string, recurse: bool = false, dynlib: string = ""): str if gStateCT.symOverride.len != 0: cmd.add &" --symOverride={gStateCT.symOverride.join(\",\")}" + when (NimMajor, NimMinor, NimPatch) >= (0, 19, 9): + cmd.add &" --nim:{getCurrentCompilerExe().quoteShell}" + if gStateCT.pluginSourcePath.nBl: cmd.add &" --pluginSourcePath={gStateCT.pluginSourcePath.quoteShell}" @@ -159,7 +167,7 @@ proc getGccPaths(mode = "c"): string = nul = when defined(Windows): "nul" else: "/dev/null" mmode = if mode == "cpp": "c++" else: mode - (result, ret) = gorgeEx("gcc -Wp,-v -x" & mmode & " " & nul) + (result, ret) = gorgeEx(&"""{getEnv("CC", "gcc")} -Wp,-v -x{mmode} {nul}""") macro cOverride*(body): untyped = ## When the wrapper code generated by nimterop is missing certain symbols or not diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 6eaf049..1051e4f 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -198,7 +198,7 @@ proc removeStatic(content: string): string = proc getPreprocessor*(gState: State, fullpath: string, mode = "cpp"): string = var mmode = if mode == "cpp": "c++" else: mode - cmd = &"gcc -E -CC -dD -x{mmode} -w " + cmd = &"""{getEnv("CC", "gcc")} -E -CC -dD -x{mmode} -w """ rdata: seq[string] = @[] start = false @@ -392,7 +392,7 @@ proc loadPlugin*(gState: State, sourcePath: string) = pdll = sourcePath.dll if not fileExists(pdll) or sourcePath.getLastModificationTime() > pdll.getLastModificationTime(): - discard execAction("nim c --app:lib " & sourcePath.quoteShell) + discard execAction(&"{gState.nim.quoteShell} c --app:lib {sourcePath.quoteShell}") doAssert fileExists(pdll), "No plugin binary generated for " & sourcePath let lib = loadLib(pdll) diff --git a/nimterop/globals.nim b/nimterop/globals.nim index 2db31be..32a461c 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -57,7 +57,7 @@ type nocache*, nocomments*, debug*, past*, preprocess*, pnim*, pretty*, recurse*: bool - code*, dynlib*, mode*, pluginSourcePath*: string + code*, dynlib*, mode*, nim*, pluginSourcePath*: string onSymbol*: OnSymbol diff --git a/nimterop/toast.nim b/nimterop/toast.nim index da903b0..6e38670 100644 --- a/nimterop/toast.nim +++ b/nimterop/toast.nim @@ -107,6 +107,7 @@ proc main( includeDirs: seq[string] = @[], dynlib: string = "", symOverride: seq[string] = @[], + nim: string = "nim", pluginSourcePath: string = "", debug = false, mode = modeDefault, @@ -124,6 +125,7 @@ proc main( includeDirs: includeDirs, dynlib: dynlib, symOverride: symOverride, + nim: nim, pluginSourcePath: pluginSourcePath, debug: debug, mode: mode, @@ -157,6 +159,7 @@ when isMainModule: "includeDirs": "include directory to pass to preprocessor", "dynlib": "Import symbols from library in specified Nim string", "symOverride": "skip generating specified symbols", + "nim": "use a particular Nim executable (default: $PATH/nim)", "pluginSourcePath": "Nim file to build and load as a plugin", "debug": "enable debug output", "mode": "language parser: c or cpp", From d3921f9ed2b49549ac7d3a21266a237d4e93552f Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Sun, 12 May 2019 03:25:07 -0500 Subject: [PATCH 219/593] Fix type qualifiers within pointer --- nimterop/grammar.nim | 2 ++ 1 file changed, 2 insertions(+) diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index 33399c9..043099c 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -49,7 +49,9 @@ proc initGrammar(): Grammar = {typeGrammar} (identifier|type_identifier?) (pointer_declarator? + (type_qualifier?) (pointer_declarator! + (type_qualifier?) (identifier|type_identifier) ) (identifier|type_identifier) From ebb78480f7cdd5a5857afe20942516fbf9521238 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 16 May 2019 11:49:33 -0500 Subject: [PATCH 220/593] Fix git pull issue --- nimterop/setup.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimterop/setup.nim b/nimterop/setup.nim index 2e436cb..ed03650 100644 --- a/nimterop/setup.nim +++ b/nimterop/setup.nim @@ -3,7 +3,7 @@ import os, strutils import "."/[git, paths] proc treesitterSetup*() = - gitPull("https://github.com/tree-sitter/tree-sitter/", incDir() / "treesitter", """ + gitPull("https://github.com/tree-sitter/tree-sitter", incDir() / "treesitter", """ lib/include/* lib/src/* """) From e245e17488de47cf28e1b6d5d66fe76e6fc3c8c5 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 16 May 2019 13:01:20 -0500 Subject: [PATCH 221/593] Fix configure call in template --- nimterop/template.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimterop/template.nim b/nimterop/template.nim index 04a0219..1c9fc7c 100644 --- a/nimterop/template.nim +++ b/nimterop/template.nim @@ -33,7 +33,7 @@ src/*.c # Run GNU configure on the source when defined(posix): - configure(srcDir) + configure(srcDir, fileThatShouldGetGenerated) # Run standard file/directory operations with mkDir(), cpFile(), mvFile() From 9387de8638d7805130c2c9dc53e83541eb399f6b Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 27 May 2019 17:19:47 -0500 Subject: [PATCH 222/593] Handle comments in #defines --- nimterop/getters.nim | 3 +++ 1 file changed, 3 insertions(+) diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 1051e4f..51d63a7 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -161,6 +161,9 @@ proc getPtrType*(str: string): string = str proc getLit*(str: string): string = + let + str = str.replace(re"//.*?$", "").replace(re"/\*.*?\*/", "").strip() + if str.contains(re"^[\-]?[\d]+$") or str.contains(re"^[\-]?[\d]*\.[\d]+$") or str.contains(re"^0x[\d]+$"): From 68ab2dbec18d9edc3392bdb56f818db6830fb52c Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Sun, 9 Jun 2019 15:58:01 -0500 Subject: [PATCH 223/593] Bitfield support, space after comments --- nimterop/ast.nim | 30 +++++++++++++++++------------- nimterop/grammar.nim | 10 +++++++++- tests/include/test.h | 1 + tests/tnimterop_c.nim | 4 ++++ 4 files changed, 31 insertions(+), 14 deletions(-) diff --git a/nimterop/ast.nim b/nimterop/ast.nim index 8efdf6f..f858043 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -7,24 +7,28 @@ import "."/[getters, globals, grammar, treesitter/api] proc saveNodeData(node: TSNode, nimState: NimState): bool = let name = $node.tsNodeType() if name in gAtoms: - var - val = nimState.getNodeVal(node) - - if name == "primitive_type" and node.tsNodeParent.tsNodeType() == "sized_type_specifier": - return true - - if name in ["number_literal", "identifier"] and $node.tsNodeParent.tsNodeType() in gExpressions: - return true - - if name in ["primitive_type", "sized_type_specifier"]: - val = val.getType() - let pname = node.getPxName(1) ppname = node.getPxName(2) pppname = node.getPxName(3) ppppname = node.getPxName(4) + var + val = nimState.getNodeVal(node) + + if name == "primitive_type" and pname == "sized_type_specifier": + return true + + if name in ["number_literal", "identifier"] and pname in gExpressions: + return true + + if name in ["number_literal"] and pname == "bitfield_clause": + nimState.data.add(("bitfield_clause", val)) + return true + + if name in ["primitive_type", "sized_type_specifier"]: + val = val.getType() + if node.tsNodePrevNamedSibling().tsNodeIsNull(): if pname == "pointer_declarator": if ppname notin ["function_declarator", "array_declarator"]: @@ -43,7 +47,7 @@ proc saveNodeData(node: TSNode, nimState: NimState): bool = nimState.data.add((name, val)) - if node.tsNodeType() == "field_identifier" and + if name == "field_identifier" and pname == "pointer_declarator" and ppname == "function_declarator": if pppname == "pointer_declarator": diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index 043099c..e40a4dc 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -290,6 +290,11 @@ proc initGrammar(): Grammar = flen = nimState.data[i+1].val.getNimExpression() nimState.typeStr &= &"{nimState.getComments()}\n {fname}*: {aptr}array[{flen}, {getPtrType(fptr&ftyp)}]" i += 2 + elif i+1 < nimState.data.len-fend and nimState.data[i+1].name == "bitfield_clause": + let + size = nimState.data[i+1].val + nimState.typeStr &= &"{nimState.getComments()}\n {fname}* {{.bitsize: {size}.}} : {getPtrType(fptr&ftyp)} " + i += 2 elif i+1 < nimState.data.len-fend and nimState.data[i+1].name == "function_declarator": var pout, pname, ptyp, pptr = "" @@ -327,6 +332,9 @@ proc initGrammar(): Grammar = let fieldGrammar = &""" (field_identifier!) + (bitfield_clause! + (number_literal) + ) (array_declarator! (field_identifier!) (pointer_declarator @@ -588,7 +596,7 @@ proc initGrammar(): Grammar = let line = line.multiReplace([("//", ""), ("/*", ""), ("*/", "")]) - nimState.commentStr &= &"\n#{line.strip(leading=false)}" + nimState.commentStr &= &"\n# {line.strip(leading=false)}" )) proc initRegex(ast: ref Ast) = diff --git a/tests/include/test.h b/tests/include/test.h index 9a28dc0..91bfd75 100644 --- a/tests/include/test.h +++ b/tests/include/test.h @@ -88,6 +88,7 @@ typedef struct { enum ENUM field3[TEST_INT]; int *field4[TEST_INT]; ENUM4 *field5[TEST_INT+TEST_INT]; + int field6 : 1; } STRUCT4; typedef struct struct5 { diff --git a/tests/tnimterop_c.nim b/tests/tnimterop_c.nim index ddfa43e..9f37141 100644 --- a/tests/tnimterop_c.nim +++ b/tests/tnimterop_c.nim @@ -78,6 +78,10 @@ when defined(cpp): else: s4.field3[3] = enum1 +s4.field6 = 1 +s4.field6 += 1 +check s4.field6 == 0 + s5.tci = test_call_int s5.tcp = test_call_param s5.tcp8 = test_call_param8 From 99c95ec658fd5b5b62c700b8e02f190defdb58bc Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 27 Jun 2019 14:34:10 -0500 Subject: [PATCH 224/593] Use tree-sitter v0.15.5/0 due to break in newer versions --- nimterop/setup.nim | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nimterop/setup.nim b/nimterop/setup.nim index ed03650..8e70e64 100644 --- a/nimterop/setup.nim +++ b/nimterop/setup.nim @@ -6,7 +6,7 @@ proc treesitterSetup*() = gitPull("https://github.com/tree-sitter/tree-sitter", incDir() / "treesitter", """ lib/include/* lib/src/* -""") +""", "0.15.5") gitPull("https://github.com/JuliaStrings/utf8proc", incDir() / "utf8proc", """ *.c @@ -36,7 +36,7 @@ src/*.h src/*.c src/*.cc src/tree_sitter/parser.h -""") +""", "v0.15.0") let headerc = incDir() / "treesitter_c/src/api.h" @@ -51,7 +51,7 @@ src/*.h src/*.c src/*.cc src/tree_sitter/parser.h -""") +""", "v0.15.0") let headercpp = incDir() / "treesitter_cpp/src/api.h" From 3bdc321d609c611e1d36ac07b6323d5d786e546c Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 10 Jul 2019 13:41:31 -0500 Subject: [PATCH 225/593] Update nim versions --- .travis.yml | 6 ++++-- appveyor.yml | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2c2d7cf..f323941 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,12 +5,14 @@ os: language: c env: - - BRANCH=0.19.4 + - BRANCH=0.19.6 + - BRANCH=0.20.0 - BRANCH=devel cache: directories: - - "$HOME/.choosenim/toolchains/nim-0.19.4" + - "$HOME/.choosenim/toolchains/nim-0.19.6" + - "$HOME/.choosenim/toolchains/nim-0.20.0" install: # `set -u` failed for ubuntu: /home/travis/.travis/job_stages: line 107: secure: unbound variable diff --git a/appveyor.yml b/appveyor.yml index aafd970..9525673 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -9,7 +9,8 @@ matrix: environment: matrix: - - NIM_VERSION: 0.19.4 + - NIM_VERSION: 0.19.6 + - NIM_VERSION: 0.20.0 for: - From 79c64d5186728b3683760ac2611d9935d002d280 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 18 Jul 2019 01:10:32 -0500 Subject: [PATCH 226/593] C2nim, cmake and make support, additional documentation --- nimterop/cimport.nim | 98 +++++++++++++++++++++++++++++++++++++++----- nimterop/git.nim | 93 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 178 insertions(+), 13 deletions(-) diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index 5717ac3..a4e1761 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -124,7 +124,7 @@ proc getNimCheckError(output: string): tuple[tmpFile, errors: string] = result.errors = "\n\n" & check -proc getToast(fullpath: string, recurse: bool = false, dynlib: string = ""): string = +proc getToast(fullpath: string, recurse: bool = false, dynlib: string = "", noNimout = false): string = var ret = 0 cmd = when defined(Windows): "cmd /c " else: "" @@ -132,7 +132,7 @@ proc getToast(fullpath: string, recurse: bool = false, dynlib: string = ""): str let toastExe = toastExePath() doAssert fileExists(toastExe), "toast not compiled: " & toastExe.quoteShell & " make sure 'nimble build' or 'nimble install' built it" - cmd &= &"{toastExe} --pnim --preprocess" + cmd &= &"{toastExe} --preprocess" if recurse: cmd.add " --recurse" @@ -143,17 +143,20 @@ proc getToast(fullpath: string, recurse: bool = false, dynlib: string = ""): str for i in gStateCT.includeDirs: cmd.add &" --includeDirs+={i.quoteShell}" - if dynlib.len != 0: - cmd.add &" --dynlib={dynlib}" + if not noNimout: + cmd.add &" --pnim" - if gStateCT.symOverride.len != 0: - cmd.add &" --symOverride={gStateCT.symOverride.join(\",\")}" + if dynlib.len != 0: + cmd.add &" --dynlib={dynlib}" - when (NimMajor, NimMinor, NimPatch) >= (0, 19, 9): - cmd.add &" --nim:{getCurrentCompilerExe().quoteShell}" + if gStateCT.symOverride.len != 0: + cmd.add &" --symOverride={gStateCT.symOverride.join(\",\")}" - if gStateCT.pluginSourcePath.nBl: - cmd.add &" --pluginSourcePath={gStateCT.pluginSourcePath.quoteShell}" + when (NimMajor, NimMinor, NimPatch) >= (0, 19, 9): + cmd.add &" --nim:{getCurrentCompilerExe().quoteShell}" + + if gStateCT.pluginSourcePath.nBl: + cmd.add &" --pluginSourcePath={gStateCT.pluginSourcePath.quoteShell}" cmd.add &" {fullpath.quoteShell}" @@ -542,3 +545,78 @@ macro cImport*(filename: static string, recurse: static bool = false, dynlib: st (tmpFile, errors) = getNimCheckError(output) doAssert false, errors & "\n\nNimterop codegen limitation or error - review 'nim check' output above generated for " & tmpFile +macro c2nImport*(filename: static string, recurse: static bool = false, dynlib: static string = "", + mode: static string = "c", flags: static string = ""): untyped = + ## Import all supported definitions from specified header file using ``c2nim`` + ## + ## Similar to `cImport() `_ but uses ``c2nim`` to generate + ## the Nim wrapper instead of ``toast``. Note that neither + ## `cOverride() `_, `cSkipSymbol() `_ + ## nor `cPlugin() `_ have any impact on ``c2nim``. + ## + ## ``toast`` is only used to preprocess the header file and recurse + ## if specified. + ## + ## ``mode`` should be set to ``cpp`` for c2nim to wrap C++ headers. + ## + ## ``flags`` can be used to pass other command line arguments to ``c2nim``. + ## + ## ``nimterop`` does not depend on ``c2nim`` as a ``nimble`` dependency so it + ## does not get installed automatically. Any wrapper or library that requires this proc + ## needs to install ``c2nim`` with ``nimble install c2nim`` or add it as a dependency in + ## its own ``.nimble`` file. + + result = newNimNode(nnkStmtList) + + let + fullpath = findPath(filename) + + echo "# Importing " & fullpath & " with c2nim" + + let + output = getToast(fullpath, recurse, dynlib, noNimout = true) + hash = output.hash().abs() + hpath = getTempDir() / "nimterop_" & $hash & ".h" + npath = hpath[0 .. hpath.rfind('.')] & "nim" + header = ("header" & fullpath.splitFile().name.replace(re"[-.]+", "")) + + if not fileExists(hpath) or gStateCT.nocache or compileOption("forceBuild"): + writeFile(hpath, output) + + doAssert fileExists(hpath), "Unable to write temporary header file: " & hpath + + var + cmd = &"c2nim {hpath} --header:{header}" + + if dynlib.len != 0: + cmd.add &" --dynlib:{dynlib}" + if mode.contains("cpp"): + cmd.add " --cpp" + if flags.len != 0: + cmd.add &" {flags}" + + for i in gStateCT.defines: + cmd.add &" --assumedef:{i.quoteShell}" + + let + (c2nimout, ret) = gorgeEx(cmd, cache=getCacheValue(hpath)) + doAssert ret == 0, c2nimout + + var + nimout = &"const {header} = \"{fullpath}\"\n\n" & readFile(npath) + + nimout = nimout. + replace(re"([u]?int[\d]+)_t", "$1"). + replace(re"([u]?int)ptr_t", "ptr $1") + + if gStateCT.debug: + echo nimout + + try: + let body = parseStmt(nimout) + + result.add body + except: + let + (tmpFile, errors) = getNimCheckError(nimout) + doAssert false, errors & "\n\nc2nim codegen limitation or error - review 'nim check' output above generated for " & tmpFile diff --git a/nimterop/git.nim b/nimterop/git.nim index 01afa9e..6e8fcac 100644 --- a/nimterop/git.nim +++ b/nimterop/git.nim @@ -3,6 +3,10 @@ import macros, os, osproc, regex, strformat, strutils import "."/[paths, compat] proc execAction*(cmd: string, nostderr=false): string = + ## Execute an external command - supported at compile time + ## + ## Checks if command exits successfully before returning. If not, an + ## error is raised. var ccmd = "" ret = 0 @@ -21,12 +25,17 @@ proc execAction*(cmd: string, nostderr=false): string = doAssert ret == 0, "Command failed: " & $(ret, nostderr) & "\nccmd: " & ccmd & "\nresult:\n" & result proc mkDir*(dir: string) = + ## Create a directory at cmopile time + ## + ## The `os` module is not available at compile time so a few + ## crucial helper functions are included with nimterop. if not dirExists(dir): let flag = when not defined(Windows): "-p" else: "" discard execAction(&"mkdir {flag} {dir.quoteShell}") proc cpFile*(source, dest: string, move=false) = + ## Copy a file from source to destination at compile time let source = source.replace("/", $DirSep) dest = dest.replace("/", $DirSep) @@ -45,9 +54,12 @@ proc cpFile*(source, dest: string, move=false) = discard execAction(&"{cmd} {source.quoteShell} {dest.quoteShell}") proc mvFile*(source, dest: string) = + ## Move a file from source to destination at compile time cpFile(source, dest, move=true) proc extractZip*(zipfile, outdir: string) = + ## Extract a zip file using powershell on Windows and unzip on other + ## systems to the specified output directory var cmd = "unzip -o $#" if defined(Windows): cmd = "powershell -nologo -noprofile -command \"& { Add-Type -A " & @@ -58,6 +70,10 @@ proc extractZip*(zipfile, outdir: string) = discard execAction(&"cd {outdir.quoteShell} && {cmd % zipfile}") proc downloadUrl*(url, outdir: string) = + ## Download a file using powershell on Windows and curl on other + ## systems to the specified output directory + ## + ## If a zip file, it is automatically extracted after download. let file = url.extractFilename() ext = file.splitFile().ext.toLowerAscii() @@ -75,6 +91,7 @@ proc downloadUrl*(url, outdir: string) = extractZip(file, outdir) proc gitReset*(outdir: string) = + ## Hard reset the git repository at the specified directory echo "# Resetting " & outdir let cmd = &"cd {outdir.quoteShell} && git reset --hard" @@ -83,6 +100,10 @@ proc gitReset*(outdir: string) = echo "# Retrying ..." proc gitCheckout*(file, outdir: string) = + ## Checkout the specified file in the git repository specified + ## + ## This effectively resets all changes in the file and can be + ## used after `cImport()` if required. echo "# Resetting " & file let file2 = file.relativePath outdir let cmd = &"cd {outdir.quoteShell} && git checkout {file2.quoteShell}" @@ -91,6 +112,10 @@ proc gitCheckout*(file, outdir: string) = echo "# Retrying ..." proc gitPull*(url: string, outdir = "", plist = "", checkout = "") = + ## Pull the specified git repository to the output directory + ## + ## `plist` is the list of specific files and directories or wildcards + ## to sparse checkout. Multiples can be specified one entry per line. if dirExists(outdir/".git"): gitReset(outdir) return @@ -105,7 +130,8 @@ proc gitPull*(url: string, outdir = "", plist = "", checkout = "") = discard execAction(&"cd {outdirQ} && git remote add origin {url}") if plist.len != 0: - # TODO: document this, it's not clear + # If a specific list of files is required, create a sparse checkout + # file for git in its config directory let sparsefile = outdir / ".git/info/sparse-checkout" discard execAction(&"cd {outdirQ} && git config core.sparsecheckout true") @@ -119,7 +145,18 @@ proc gitPull*(url: string, outdir = "", plist = "", checkout = "") = echo "# Pulling repository" discard execAction(&"cd {outdirQ} && git pull --depth=1 origin master") -proc configure*(path, check: string) = +proc configure*(path, check: string, flags = "") = + ## Run the GNU `configure` command to generate all Makefiles or other + ## build scripts in the specified path + ## + ## If a `configure` script is not present and an `autogen.sh` script + ## is present, it will be run before attempting `configure`. + ## + ## `check` is a file that will be generated by the `configure` command. + ## This is required to prevent configure from running on every build. It + ## is relative to the `path` and should not be an absolute path. + ## + ## `flags` are any flags that should be passed to the `configure` command. if (path / check).fileExists(): return @@ -134,5 +171,55 @@ proc configure*(path, check: string) = if fileExists(path / "configure"): echo "# Running configure" - discard execAction(&"cd {path.quoteShell} && bash configure") + var + cmd = &"cd {path.quoteShell} && bash configure" + if flags.len != 0: + cmd &= &" {flags}" + echo execAction(cmd) + +proc cmake*(path, check, flags: string) = + ## Run the `cmake` command to generate all Makefiles or other + ## build scripts in the specified path + ## + ## `path` will be created since typically `cmake` is run in an + ## empty directory. + ## + ## `check` is a file that will be generated by the `cmake` command. + ## This is required to prevent `cmake` from running on every build. It + ## is relative to the `path` and should not be an absolute path. + ## + ## `flags` are any flags that should be passed to the `cmake` command. + ## Unlike `configure`, it is required since typically it will be the + ## path to the repository, typically `..` when `path` is a subdir. + if (path / check).fileExists(): + return + + echo "# Running cmake " & path + + mkDir(path) + + var + cmd = &"cd {path.quoteShell} && cmake {flags}" + + echo execAction(cmd) + +proc make*(path, check: string, flags = "") = + ## Run the `make` command to build all binaries in the specified path + ## + ## `check` is a file that will be generated by the `make` command. + ## This is required to prevent `make` from running on every build. It + ## is relative to the `path` and should not be an absolute path. + ## + ## `flags` are any flags that should be passed to the `make` command. + if (path / check).fileExists(): + return + + echo "# Running make " & path + + var + cmd = &"cd {path.quoteShell} && make" + if flags.len != 0: + cmd &= &" {flags}" + + echo execAction(cmd) \ No newline at end of file From 92903c009cc0a4b6e83f08358c12de39c5de058b Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 18 Jul 2019 01:10:51 -0500 Subject: [PATCH 227/593] Update documentation --- all.html | 992 ++++++++-------------------- cimport.html | 1142 +++++++++++--------------------- cimport.idx | 13 +- compat.html | 1025 ++++++++--------------------- compat.idx | 0 dochack.js | 1755 +++++++++++++++++++++++++------------------------ git.html | 1101 +++++++++++-------------------- git.idx | 4 +- paths.html | 1044 +++++++++-------------------- paths.idx | 12 +- plugin.html | 996 ++++++++-------------------- plugin.idx | 0 theindex.html | 1033 +++++++++-------------------- types.html | 1015 +++++++++------------------- types.idx | 2 +- 15 files changed, 3458 insertions(+), 6676 deletions(-) mode change 100755 => 100644 all.html mode change 100755 => 100644 cimport.html mode change 100755 => 100644 cimport.idx mode change 100755 => 100644 compat.html mode change 100755 => 100644 compat.idx mode change 100755 => 100644 dochack.js mode change 100755 => 100644 git.html mode change 100755 => 100644 git.idx mode change 100755 => 100644 paths.html mode change 100755 => 100644 paths.idx mode change 100755 => 100644 plugin.html mode change 100755 => 100644 plugin.idx mode change 100755 => 100644 theindex.html mode change 100755 => 100644 types.html mode change 100755 => 100644 types.idx diff --git a/all.html b/all.html old mode 100755 new mode 100644 index 01b70ff..5d58312 --- a/all.html +++ b/all.html @@ -27,232 +27,130 @@ customize this style sheet. Modified from Chad Skeeters' rst2html-style https://bitbucket.org/cskeeters/rst2html-style/ -Modified by Boyd Greenfield +Modified by Boyd Greenfield and narimiran */ -/* SCSS variables */ -/* Text weights */ -/* Body colors */ -/* Text colors */ -/* Link colors */ -/* Syntax highlighting colors */ -/* Pct changes */ -/* Mixins */ -/* Body/layout */ + html { font-size: 100%; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; } -/* Where we want fancier font if available */ -h1, h2, h3, h4, h5, h6, p.module-desc, table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; } - -h1.title { - font-weight: 900; } - body { font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: 400; - font-size: 16px; - line-height: 20px; - color: #444; - letter-spacing: 0.15px; - background-color: #FDFBFA; } + font-size: 1.125em; + line-height: 1.5; + color: #222; + background-color: #FCFCFC; } /* Skeleton grid */ .container { position: relative; width: 100%; - max-width: 960px; + max-width: 1050px; margin: 0 auto; - padding: 0 20px; + padding: 0; box-sizing: border-box; } .column, .columns { width: 100%; float: left; - box-sizing: border-box; } + box-sizing: border-box; + margin-left: 1%; +} -/* For devices larger than 400px */ -@media (min-width: 400px) { - .container { - width: 100%; - padding: 0; } } -/* For devices larger than 650px */ -@media (min-width: 650px) { - .container { - width: 100%; } +.column:first-child, +.columns:first-child { + margin-left: 0; } - .column, - .columns { - margin-left: 4%; } +.three.columns { + width: 19%; } - .column:first-child, - .columns:first-child { - margin-left: 0; } +.nine.columns { + width: 80.0%; } - .one.column, - .one.columns { - width: 4.66666666667%; } - - .two.columns { - width: 13.3333333333%; } +.twelve.columns { + width: 100%; + margin-left: 0; } +@media screen and (max-width: 860px) { .three.columns { - width: 22%; } - - .four.columns { - width: 30.6666666667%; } - - .five.columns { - width: 39.3333333333%; } - - .six.columns { - width: 48%; } - - .seven.columns { - width: 56.6666666667%; } - - .eight.columns { - width: 65.3333333333%; } - + display: none; + } .nine.columns { - width: 74.0%; } - - .ten.columns { - width: 82.6666666667%; } - - .eleven.columns { - width: 91.3333333333%; } - - .twelve.columns { - width: 100%; - margin-left: 0; } - - .one-third.column { - width: 30.6666666667%; } - - .two-thirds.column { - width: 65.3333333333%; } } -/* Customer Overrides */ -.footer { - text-align: center; - color: #969696; - padding-top: 10%; } - -p.module-desc { - font-size: 1.1em; - color: #666666; } - -a.link-seesrc { - color: #aec7d2; - font-style: italic; } - -a.link-seesrc:hover { - color: #6c9aae; } - -#toc-list { - word-wrap: break-word; } - -ul.simple-toc { - list-style: none; } - -ul.simple-toc a.reference-toplevel { - font-weight: bold; - color: #0077b3; } - -ul.simple-toc-section { - list-style-type: circle; - color: #6c9aae; } - -ul.simple-toc-section a.reference { - color: #0077b3; } + width: 98.0%; + } + body { + font-size: 1em; + line-height: 1.35; + } +} cite { font-style: italic !important; } -dt > pre { - border-color: rgba(0, 0, 0, 0.1); - background-color: rgba(255, 255, 255, 0.3); - margin: 15px 0px 5px; } - -dd > pre { - border-color: rgba(0, 0, 0, 0.1); - background-color: whitesmoke; - margin-top: 8px; } - -.item > dd { - margin-left: 10px; - margin-bottom: 30px; } - -/* Nim line-numbered tables */ -.line-nums-table { - width: 100%; - table-layout: fixed; } /* Nim search input */ div#searchInputDiv { - margin-bottom: 8px; + margin-bottom: 1em; } -div#searchInputDiv input#searchInput { - width: 10em; -} -div.search-groupby { - margin-bottom: 8px; +input#searchInput { + width: 80%; } -table.line-nums-table { - border-radius: 4px; - border: 1px solid #cccccc; - background-color: whitesmoke; - border-collapse: separate; - margin-top: 15px; - margin-bottom: 25px; } - -.line-nums-table tbody { - border: none; } - -.line-nums-table td pre { - border: none; - background-color: transparent; } - -.line-nums-table td.blob-line-nums { - width: 28px; } - -.line-nums-table td.blob-line-nums pre { - color: #b0b0b0; - -webkit-filter: opacity(75%); - text-align: right; - border-color: transparent; - background-color: transparent; - padding-left: 0px; - margin-left: 0px; - padding-right: 0px; - margin-right: 0px; } +/* + * Some custom formatting for input forms. + * This also fixes input form colors on Firefox with a dark system theme on Linux. + */ +input { + -moz-appearance: none; + color: #333; + background-color: #f8f8f8; + border: 1px solid #aaa; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-size: 0.9em; + padding: 6px; +} +input:focus { + border: 1px solid #1fa0eb; + box-shadow: 0 0 2px #1fa0eb; +} /* Docgen styles */ /* Links */ a { - color: #0077b3; - text-decoration: none; } + color: #07b; + text-decoration: none; +} + +a span.Identifier { + text-decoration: underline; + text-decoration-color: #aab; +} + +a.reference-toplevel { + font-weight: bold; +} + +a.toc-backref { + text-decoration: none; + color: #222; } + +a.link-seesrc { + color: #607c9f; + font-size: 0.9em; + font-style: italic; } a:hover, a:focus { - color: #00334d; + color: #607c9f; text-decoration: underline; } -a:visited { - color: #00334d; } +a:hover span.Identifier { + color: #607c9f; +} -a:focus { - outline: thin dotted #2d2d2d; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; } - -a:hover, -a:active { - outline: 0; } sub, sup { @@ -329,379 +227,258 @@ img { h2, h3 { - page-break-after: avoid; } } -.img-rounded { - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; } + page-break-after: avoid; } +} -.img-polaroid { - padding: 4px; - background-color: rgba(252, 248, 244, 0.75); - border: 1px solid #ccc; - border: 1px solid rgba(0, 0, 0, 0.2); - -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); - -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); } p { - margin: 0 0 8px; } + margin-top: 0.5em; + margin-bottom: 0.5em; +} small { font-size: 85%; } strong { - font-weight: 600; } + font-weight: 600; + font-size: 0.95em; + color: #3c3c3c; +} em { font-style: italic; } -cite { - font-style: normal; } - -h1, -h2, -h3, -h4, -h5, -h6 { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-weight: 600; - line-height: 20px; - color: inherit; - text-rendering: optimizelegibility; } - h1 { - font-size: 2em; + font-size: 1.8em; font-weight: 400; - padding-bottom: .15em; - border-bottom: 1px solid #aaaaaa; - margin-top: 1.0em; + padding-bottom: .25em; + border-bottom: 1px solid #aaa; + margin-top: 2.5em; + margin-bottom: 1em; line-height: 1.2em; } h1.title { padding-bottom: 1em; border-bottom: 0px; - font-size: 2.75em; } + font-size: 2.5em; + text-align: center; + font-weight: 900; + margin-top: 0.75em; + margin-bottom: 0em; +} h2 { - font-size: 1.5em; - margin-top: 1.5em; } + font-size: 1.3em; + margin-top: 2em; } + +h2.subtitle { + text-align: center; } h3 { - font-size: 1.3em; + font-size: 1.125em; font-style: italic; - margin-top: 0.75em; } + margin-top: 1.5em; } h4 { - font-size: 1.3em; - margin-top: 0.5em; } + font-size: 1.125em; + margin-top: 1em; } h5 { - font-size: 1.2em; - margin-top: 0.25em; } + font-size: 1.125em; + margin-top: 0.75em; } h6 { font-size: 1.1em; } + ul, ol { padding: 0; - margin: 0 0 0px 15px; } + margin-top: 0.5em; + margin-left: 0.75em; } ul ul, ul ol, ol ol, ol ul { - margin-bottom: 0; } + margin-bottom: 0; + margin-left: 1.25em; } li { - line-height: 20px; } - -dl { - margin-bottom: 20px; } - -dt, -dd { - line-height: 20px; } - -dt { - font-weight: bold; } - -dd { - margin-left: 10px; - margin-bottom: 26px; } - -hr { - margin: 20px 0; - border: 0; - border-top: 1px solid #eeeeee; - border-bottom: 1px solid #ffffff; } - -abbr[title], -abbr[data-original-title] { - cursor: help; - border-bottom: 1px dotted #999999; } - -abbr.initialism { - font-size: 90%; - text-transform: uppercase; } - -blockquote { - padding: 0 0 0 15px; - margin: 0 0 20px; - border-left: 5px solid #EFEBE0; } - -table.docinfo + blockquote, table.docinfo blockquote, h1 + blockquote { - border-left: 5px solid #c9c9c9; + list-style-type: circle; } -table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { - margin-bottom: 0; - font-size: 15px; - font-weight: 200; - line-height: 1.5; - font-style: italic; } +ul.simple-boot li { + list-style-type: none; + margin-left: 0em; + margin-bottom: 0.5em; +} -q:before, -q:after, -blockquote:before, -blockquote:after { - content: ""; } +ol.simple > li, ul.simple > li { + margin-bottom: 0.25em; + margin-left: 0.4em } -address { - display: block; - margin-bottom: 20px; - font-style: normal; - line-height: 20px; } +ul.simple.simple-toc > li { + margin-top: 1em; +} -code, -pre { - font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - padding: 0 3px 2px; - font-weight: 500; - font-size: 12px; - color: #444444; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; } +ul.simple-toc { + list-style: none; + font-size: 0.9em; + margin-left: -0.3em; + margin-top: 1em; } + +ul.simple-toc > li { + list-style-type: none; +} + +ul.simple-toc-section { + list-style-type: circle; + margin-left: 1em; + color: #6c9aae; } + + +ol.arabic { + list-style: decimal; } + +ol.loweralpha { + list-style: lower-alpha; } + +ol.upperalpha { + list-style: upper-alpha; } + +ol.lowerroman { + list-style: lower-roman; } + +ol.upperroman { + list-style: upper-roman; } + +ul.auto-toc { + list-style-type: none; } + + +dl { + margin-bottom: 1.5em; } + +dt { + margin-bottom: -0.5em; + margin-left: 0.0em; } + +dd { + margin-left: 2.0em; + margin-bottom: 3.0em; + margin-top: 0.5em; } + + +hr { + margin: 2em 0; + border: 0; + border-top: 1px solid #aaa; } + +blockquote { + font-size: 0.9em; + font-style: italic; + padding-left: 0.5em; + margin-left: 0; + border-left: 5px solid #bbc; +} .pre { font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - font-weight: 600; - /*color: #504da6;*/ + font-weight: 500; + font-size: 0.85em; + background-color: #f0f3ff; + padding-left: 3px; + padding-right: 3px; + border-radius: 4px; } -code { - padding: 2px 4px; - color: #444444; - white-space: nowrap; - background-color: white; - border: 1px solid #777777; } - pre { + font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; + color: #222; + font-weight: 500; display: inline-block; box-sizing: border-box; - min-width: calc(100% - 19.5px); - padding: 9.5px; - margin: 0.25em 10px 10px 10px; - font-size: 15px; - line-height: 20px; + min-width: 100%; + padding: 0.5em; + margin-top: 0.5em; + margin-bottom: 0.5em; + font-size: 0.85em; white-space: pre !important; overflow-y: hidden; overflow-x: visible; - background-color: rgba(0, 0, 0, 0.01); - border: 1px solid #cccccc; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; } - -pre.prettyprint { - margin-bottom: 20px; } - -pre code { - padding: 0; - color: inherit; - white-space: pre; - overflow-x: visible; - background-color: transparent; - border: 0; } + background-color: ghostwhite; + border: 1px solid #dde; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; } .pre-scrollable { max-height: 340px; overflow-y: scroll; } + +/* Nim line-numbered tables */ +.line-nums-table { + width: 100%; + table-layout: fixed; } + +table.line-nums-table { + border-radius: 4px; + border: 1px solid #cccccc; + background-color: ghostwhite; + border-collapse: separate; + margin-top: 15px; + margin-bottom: 25px; } + +.line-nums-table tbody { + border: none; } + +.line-nums-table td pre { + border: none; + background-color: transparent; } + +.line-nums-table td.blob-line-nums { + width: 28px; } + +.line-nums-table td.blob-line-nums pre { + color: #b0b0b0; + -webkit-filter: opacity(75%); + text-align: right; + border-color: transparent; + background-color: transparent; + padding-left: 0px; + margin-left: 0px; + padding-right: 0px; + margin-right: 0px; } + + table { max-width: 100%; background-color: transparent; + margin-top: 0.5em; + margin-bottom: 1.5em; border-collapse: collapse; - border-spacing: 0; } - -table th, table td { - padding: 0px 8px 0px; + border-color: #ccc; + border-spacing: 0; + font-size: 0.9em; } -.table { - width: 100%; - margin-bottom: 20px; } +table th, table td { + padding: 0px 0.5em 0px; +} -.table th, -.table td { - padding: 8px; - line-height: 20px; - text-align: left; - vertical-align: top; - border-top: 1px solid #444444; } - -.table th { +table th { + background-color: #e8e8e8; font-weight: bold; } -.table thead th { - vertical-align: bottom; } +table th.docinfo-name { + background-color: transparent; +} -.table caption + thead tr:first-child th, -.table caption + thead tr:first-child td, -.table colgroup + thead tr:first-child th, -.table colgroup + thead tr:first-child td, -.table thead:first-child tr:first-child th, -.table thead:first-child tr:first-child td { - border-top: 0; } +table tr:hover { + background-color: ghostwhite; } -.table tbody + tbody { - border-top: 2px solid #444444; } - -.table .table { - background-color: rgba(252, 248, 244, 0.75); } - -.table-condensed th, -.table-condensed td { - padding: 4px 5px; } - -.table-bordered { - border: 1px solid #444444; - border-collapse: separate; - *border-collapse: collapse; - border-left: 0; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; } - -.table-bordered th, -.table-bordered td { - border-left: 1px solid #444444; } - -.table-bordered caption + thead tr:first-child th, -.table-bordered caption + tbody tr:first-child th, -.table-bordered caption + tbody tr:first-child td, -.table-bordered colgroup + thead tr:first-child th, -.table-bordered colgroup + tbody tr:first-child th, -.table-bordered colgroup + tbody tr:first-child td, -.table-bordered thead:first-child tr:first-child th, -.table-bordered tbody:first-child tr:first-child th, -.table-bordered tbody:first-child tr:first-child td { - border-top: 0; } - -.table-bordered thead:first-child tr:first-child > th:first-child, -.table-bordered tbody:first-child tr:first-child > td:first-child, -.table-bordered tbody:first-child tr:first-child > th:first-child { - -webkit-border-top-left-radius: 4px; - border-top-left-radius: 4px; - -moz-border-radius-topleft: 4px; } - -.table-bordered thead:first-child tr:first-child > th:last-child, -.table-bordered tbody:first-child tr:first-child > td:last-child, -.table-bordered tbody:first-child tr:first-child > th:last-child { - -webkit-border-top-right-radius: 4px; - border-top-right-radius: 4px; - -moz-border-radius-topright: 4px; } - -.table-bordered thead:last-child tr:last-child > th:first-child, -.table-bordered tbody:last-child tr:last-child > td:first-child, -.table-bordered tbody:last-child tr:last-child > th:first-child, -.table-bordered tfoot:last-child tr:last-child > td:first-child, -.table-bordered tfoot:last-child tr:last-child > th:first-child { - -webkit-border-bottom-left-radius: 4px; - border-bottom-left-radius: 4px; - -moz-border-radius-bottomleft: 4px; } - -.table-bordered thead:last-child tr:last-child > th:last-child, -.table-bordered tbody:last-child tr:last-child > td:last-child, -.table-bordered tbody:last-child tr:last-child > th:last-child, -.table-bordered tfoot:last-child tr:last-child > td:last-child, -.table-bordered tfoot:last-child tr:last-child > th:last-child { - -webkit-border-bottom-right-radius: 4px; - border-bottom-right-radius: 4px; - -moz-border-radius-bottomright: 4px; } - -.table-bordered tfoot + tbody:last-child tr:last-child td:first-child { - -webkit-border-bottom-left-radius: 0; - border-bottom-left-radius: 0; - -moz-border-radius-bottomleft: 0; } - -.table-bordered tfoot + tbody:last-child tr:last-child td:last-child { - -webkit-border-bottom-right-radius: 0; - border-bottom-right-radius: 0; - -moz-border-radius-bottomright: 0; } - -.table-bordered caption + thead tr:first-child th:first-child, -.table-bordered caption + tbody tr:first-child td:first-child, -.table-bordered colgroup + thead tr:first-child th:first-child, -.table-bordered colgroup + tbody tr:first-child td:first-child { - -webkit-border-top-left-radius: 4px; - border-top-left-radius: 4px; - -moz-border-radius-topleft: 4px; } - -.table-bordered caption + thead tr:first-child th:last-child, -.table-bordered caption + tbody tr:first-child td:last-child, -.table-bordered colgroup + thead tr:first-child th:last-child, -.table-bordered colgroup + tbody tr:first-child td:last-child { - -webkit-border-top-right-radius: 4px; - border-top-right-radius: 4px; - -moz-border-radius-topright: 4px; } - -table.docutils th { - background-color: #e8e8e8; } - -table.docutils tr:hover { - background-color: whitesmoke; } - -.table-striped tbody > tr:nth-child(odd) > td, -.table-striped tbody > tr:nth-child(odd) > th { - background-color: rgba(252, 248, 244, 0.75); } - -.table-hover tbody tr:hover > td, -.table-hover tbody tr:hover > th { - background-color: rgba(241, 222, 204, 0.75); } - -table td[class*="span"], -table th[class*="span"], -.row-fluid table td[class*="span"], -.row-fluid table th[class*="span"] { - display: table-cell; - float: none; - margin-left: 0; } - -.hero-unit { - padding: 60px; - margin-bottom: 30px; - font-size: 18px; - font-weight: 200; - line-height: 30px; - color: inherit; - background-color: rgba(230, 197, 164, 0.75); - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; } - -.hero-unit h1 { - margin-bottom: 0; - font-size: 60px; - line-height: 1; - letter-spacing: -1px; - color: inherit; } - -.hero-unit li { - line-height: 30px; } /* rst2html default used to remove borders from tables and images */ .borderless, table.borderless td, table.borderless th { @@ -722,10 +499,6 @@ table.borderless td, table.borderless th { .hidden { display: none; } -a.toc-backref { - text-decoration: none; - color: #444444; } - blockquote.epigraph { margin: 2em 5em; } @@ -735,85 +508,6 @@ dl.docutils dd { object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] { overflow: hidden; } -/* Uncomment (and remove this text!) to get bold-faced definition list terms -dl.docutils dt { - font-weight: bold } -*/ -div.abstract { - margin: 2em 5em; } - -div.abstract p.topic-title { - font-weight: bold; - text-align: center; } - -div.admonition, div.attention, div.caution, div.danger, div.error, -div.hint, div.important, div.note, div.tip, div.warning { - margin: 2em; - border: medium outset; - padding: 1em; } - -div.note, div.warning { - margin: 1.5em 0px; - border: none; } - -div.note p.admonition-title, -div.warning p.admonition-title { - display: none; } - -/* Clearfix - * http://css-tricks.com/snippets/css/clear-fix/ - */ -div.note:after, -div.warning:after { - content: ""; - display: table; - clear: both; } - -div.note p:before, -div.warning p:before { - display: block; - float: left; - font-size: 4em; - line-height: 1em; - margin-right: 20px; - margin-left: 0em; - margin-top: -10px; - content: '\0270D'; - /*handwriting*/ } - -div.warning p:before { - content: '\026A0'; - /*warning*/ } - -div.admonition p.admonition-title, div.hint p.admonition-title, -div.important p.admonition-title, div.note p.admonition-title, -div.tip p.admonition-title { - font-weight: bold; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } - -div.attention p.admonition-title, div.caution p.admonition-title, -div.danger p.admonition-title, div.error p.admonition-title, -div.warning p.admonition-title, .code .error { - color: #b30000; - font-weight: bold; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } - -/* Uncomment (and remove this text!) to get reduced vertical space in - compound paragraphs. -div.compound .compound-first, div.compound .compound-middle { - margin-bottom: 0.5em } - -div.compound .compound-last, div.compound .compound-middle { - margin-top: 0.5em } -*/ -div.dedication { - margin: 2em 5em; - text-align: center; - font-style: italic; } - -div.dedication p.topic-title { - font-weight: bold; - font-style: normal; } div.figure { margin-left: 2em; @@ -821,8 +515,14 @@ div.figure { div.footer, div.header { clear: both; + text-align: center; + color: #666; font-size: smaller; } +div.footer { + padding-top: 5em; +} + div.line-block { display: block; margin-top: 1em; @@ -833,45 +533,24 @@ div.line-block div.line-block { margin-bottom: 0; margin-left: 1.5em; } -div.sidebar { - margin: 0 0 0.5em 1em; - border: medium outset; - padding: 1em; - background-color: rgba(252, 248, 244, 0.75); - width: 40%; - float: right; - clear: right; } - -div.sidebar p.rubric { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-size: medium; } - -div.system-messages { - margin: 5em; } - -div.system-messages h1 { - color: #b30000; } - -div.system-message { - border: medium outset; - padding: 1em; } - -div.system-message p.system-message-title { - color: #b30000; - font-weight: bold; } - div.topic { margin: 2em; } -h1.section-subtitle, h2.section-subtitle, h3.section-subtitle, -h4.section-subtitle, h5.section-subtitle, h6.section-subtitle { - margin-top: 0.4em; } +div.search_results { + background-color: antiquewhite; + margin: 3em; + padding: 1em; + border: 1px solid #4d4d4d; +} -h1.title { - text-align: center; } +div#global-links ul { + margin-left: 0; + list-style-type: none; +} -h2.subtitle { - text-align: center; } +div#global-links > simple-boot { + margin-left: 3em; +} hr.docutils { width: 75%; } @@ -905,30 +584,6 @@ img.align-center, .figure.align-center, object.align-center { div.align-right { text-align: inherit; } -/* div.align-center * { */ -/* text-align: left } */ - -ul.simple > li { - margin-bottom: 0.5em } - -ol.simple, ul.simple { - margin-bottom: 1em; } - -ol.arabic { - list-style: decimal; } - -ol.loweralpha { - list-style: lower-alpha; } - -ol.upperalpha { - list-style: upper-alpha; } - -ol.lowerroman { - list-style: lower-roman; } - -ol.upperroman { - list-style: upper-roman; } - p.attribution { text-align: right; margin-left: 50%; } @@ -949,15 +604,6 @@ p.rubric { color: maroon; text-align: center; } -p.sidebar-title { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-weight: bold; - font-size: larger; } - -p.sidebar-subtitle { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-weight: bold; } - p.topic-title { font-weight: bold; } @@ -997,22 +643,14 @@ pre.code .inserted, code .inserted { background-color: #A3D289; } span.classifier { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-style: oblique; } span.classifier-delimiter { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: bold; } -span.interpreted { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } - span.option { white-space: nowrap; } -span.pre { - white-space: pre; } - span.problematic { color: #b30000; } @@ -1020,44 +658,6 @@ span.section-subtitle { /* font-size relative to parent (h1..h6 element) */ font-size: 80%; } -table.citation { - border-left: solid 1px #666666; - margin-left: 1px; } - -table.docinfo { - margin: 0em; - margin-top: 2em; - margin-bottom: 2em; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; - color: #444444; } - -table.docutils { - margin-top: 0.5em; - margin-bottom: 0.5em; } - -table.footnote { - border-left: solid 1px #2d2d2d; - margin-left: 1px; } - -table.docutils td, table.docutils th, -table.docinfo td, table.docinfo th { - padding-left: 0.5em; - padding-right: 0.5em; - vertical-align: top; } - -table.docutils th.field-name, table.docinfo th.docinfo-name { - font-weight: 700; - text-align: left; - white-space: nowrap; - padding-left: 0; } - -h1 tt.docutils, h2 tt.docutils, h3 tt.docutils, -h4 tt.docutils, h5 tt.docutils, h6 tt.docutils { - font-size: 100%; } - -ul.auto-toc { - list-style-type: none; } - span.DecNumber { color: #252dbe; } @@ -1074,7 +674,7 @@ span.FloatNumber { color: #252dbe; } span.Identifier { - color: #3b3b3b; } + color: #222; } span.Keyword { font-weight: 600; @@ -1139,38 +739,23 @@ dt pre > span.Identifier, dt pre > span.Operator { color: #155da4; font-weight: 700; } -dt pre > span.Identifier ~ span.Identifier, dt pre > span.Operator ~ span.Identifier { - color: inherit; - font-weight: inherit; } - -dt pre > span.Operator ~ span.Identifier { +dt pre > span.Keyword ~ span.Identifier, dt pre > span.Identifier ~ span.Identifier, +dt pre > span.Operator ~ span.Identifier, dt pre > span.Other ~ span.Identifier { color: inherit; font-weight: inherit; } /* Nim sprite for the footer (taken from main page favicon) */ .nim-sprite { display: inline-block; - height: 12px; - width: 12px; + height: 16px; + width: 16px; background-position: 0 0; - background-size: 12px 12px; + background-size: 16px 16px; -webkit-filter: opacity(50%); background-repeat: no-repeat; background-image: url("data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="); margin-bottom: -5px; } -div.search_results { - background-color: antiquewhite; - margin: 3em; - padding: 1em; - border: 1px solid #4d4d4d; -} - -div#global-links ul { - margin-left: 0; - list-style-type: none; -} - span.pragmadots { /* Position: relative frees us up to make the dots look really nice without fucking up the layout and @@ -1178,18 +763,14 @@ span.pragmadots { position: relative; /* 1px down looks slightly nicer */ top: 1px; - padding: 2px; - background-color: #D3D3D3; + background-color: #e8e8e8; border-radius: 4px; margin: 0 2px; cursor: pointer; - - /* For some reason on Chrome, making the font size - smaller than 1em is causing the parent container to - bulge slightly. So, we're stuck with inheriting 1em, - which is sad, because 0.8em looks better... */ + font-size: 0.8em; } + span.pragmadots:hover { background-color: #DBDBDB; } @@ -1197,6 +778,10 @@ span.pragmawrap { display: none; } +span.attachedType { + display: none; + visibility: hidden; +} @@ -1250,7 +835,8 @@ function main() {
-

Module that should import everything so that nim doc --project nimtero/all runs docs on everything.

+ +

Module that should import everything so that nim doc --project nimtero/all runs docs on everything.

Imports

@@ -1264,7 +850,7 @@ function main() {
diff --git a/cimport.html b/cimport.html old mode 100755 new mode 100644 index d58d588..6066a47 --- a/cimport.html +++ b/cimport.html @@ -27,232 +27,130 @@ customize this style sheet. Modified from Chad Skeeters' rst2html-style https://bitbucket.org/cskeeters/rst2html-style/ -Modified by Boyd Greenfield +Modified by Boyd Greenfield and narimiran */ -/* SCSS variables */ -/* Text weights */ -/* Body colors */ -/* Text colors */ -/* Link colors */ -/* Syntax highlighting colors */ -/* Pct changes */ -/* Mixins */ -/* Body/layout */ + html { font-size: 100%; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; } -/* Where we want fancier font if available */ -h1, h2, h3, h4, h5, h6, p.module-desc, table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; } - -h1.title { - font-weight: 900; } - body { font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: 400; - font-size: 16px; - line-height: 20px; - color: #444; - letter-spacing: 0.15px; - background-color: #FDFBFA; } + font-size: 1.125em; + line-height: 1.5; + color: #222; + background-color: #FCFCFC; } /* Skeleton grid */ .container { position: relative; width: 100%; - max-width: 960px; + max-width: 1050px; margin: 0 auto; - padding: 0 20px; + padding: 0; box-sizing: border-box; } .column, .columns { width: 100%; float: left; - box-sizing: border-box; } + box-sizing: border-box; + margin-left: 1%; +} -/* For devices larger than 400px */ -@media (min-width: 400px) { - .container { - width: 100%; - padding: 0; } } -/* For devices larger than 650px */ -@media (min-width: 650px) { - .container { - width: 100%; } +.column:first-child, +.columns:first-child { + margin-left: 0; } - .column, - .columns { - margin-left: 4%; } +.three.columns { + width: 19%; } - .column:first-child, - .columns:first-child { - margin-left: 0; } +.nine.columns { + width: 80.0%; } - .one.column, - .one.columns { - width: 4.66666666667%; } - - .two.columns { - width: 13.3333333333%; } +.twelve.columns { + width: 100%; + margin-left: 0; } +@media screen and (max-width: 860px) { .three.columns { - width: 22%; } - - .four.columns { - width: 30.6666666667%; } - - .five.columns { - width: 39.3333333333%; } - - .six.columns { - width: 48%; } - - .seven.columns { - width: 56.6666666667%; } - - .eight.columns { - width: 65.3333333333%; } - + display: none; + } .nine.columns { - width: 74.0%; } - - .ten.columns { - width: 82.6666666667%; } - - .eleven.columns { - width: 91.3333333333%; } - - .twelve.columns { - width: 100%; - margin-left: 0; } - - .one-third.column { - width: 30.6666666667%; } - - .two-thirds.column { - width: 65.3333333333%; } } -/* Customer Overrides */ -.footer { - text-align: center; - color: #969696; - padding-top: 10%; } - -p.module-desc { - font-size: 1.1em; - color: #666666; } - -a.link-seesrc { - color: #aec7d2; - font-style: italic; } - -a.link-seesrc:hover { - color: #6c9aae; } - -#toc-list { - word-wrap: break-word; } - -ul.simple-toc { - list-style: none; } - -ul.simple-toc a.reference-toplevel { - font-weight: bold; - color: #0077b3; } - -ul.simple-toc-section { - list-style-type: circle; - color: #6c9aae; } - -ul.simple-toc-section a.reference { - color: #0077b3; } + width: 98.0%; + } + body { + font-size: 1em; + line-height: 1.35; + } +} cite { font-style: italic !important; } -dt > pre { - border-color: rgba(0, 0, 0, 0.1); - background-color: rgba(255, 255, 255, 0.3); - margin: 15px 0px 5px; } - -dd > pre { - border-color: rgba(0, 0, 0, 0.1); - background-color: whitesmoke; - margin-top: 8px; } - -.item > dd { - margin-left: 10px; - margin-bottom: 30px; } - -/* Nim line-numbered tables */ -.line-nums-table { - width: 100%; - table-layout: fixed; } /* Nim search input */ div#searchInputDiv { - margin-bottom: 8px; + margin-bottom: 1em; } -div#searchInputDiv input#searchInput { - width: 10em; -} -div.search-groupby { - margin-bottom: 8px; +input#searchInput { + width: 80%; } -table.line-nums-table { - border-radius: 4px; - border: 1px solid #cccccc; - background-color: whitesmoke; - border-collapse: separate; - margin-top: 15px; - margin-bottom: 25px; } - -.line-nums-table tbody { - border: none; } - -.line-nums-table td pre { - border: none; - background-color: transparent; } - -.line-nums-table td.blob-line-nums { - width: 28px; } - -.line-nums-table td.blob-line-nums pre { - color: #b0b0b0; - -webkit-filter: opacity(75%); - text-align: right; - border-color: transparent; - background-color: transparent; - padding-left: 0px; - margin-left: 0px; - padding-right: 0px; - margin-right: 0px; } +/* + * Some custom formatting for input forms. + * This also fixes input form colors on Firefox with a dark system theme on Linux. + */ +input { + -moz-appearance: none; + color: #333; + background-color: #f8f8f8; + border: 1px solid #aaa; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-size: 0.9em; + padding: 6px; +} +input:focus { + border: 1px solid #1fa0eb; + box-shadow: 0 0 2px #1fa0eb; +} /* Docgen styles */ /* Links */ a { - color: #0077b3; - text-decoration: none; } + color: #07b; + text-decoration: none; +} + +a span.Identifier { + text-decoration: underline; + text-decoration-color: #aab; +} + +a.reference-toplevel { + font-weight: bold; +} + +a.toc-backref { + text-decoration: none; + color: #222; } + +a.link-seesrc { + color: #607c9f; + font-size: 0.9em; + font-style: italic; } a:hover, a:focus { - color: #00334d; + color: #607c9f; text-decoration: underline; } -a:visited { - color: #00334d; } +a:hover span.Identifier { + color: #607c9f; +} -a:focus { - outline: thin dotted #2d2d2d; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; } - -a:hover, -a:active { - outline: 0; } sub, sup { @@ -329,379 +227,258 @@ img { h2, h3 { - page-break-after: avoid; } } -.img-rounded { - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; } + page-break-after: avoid; } +} -.img-polaroid { - padding: 4px; - background-color: rgba(252, 248, 244, 0.75); - border: 1px solid #ccc; - border: 1px solid rgba(0, 0, 0, 0.2); - -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); - -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); } p { - margin: 0 0 8px; } + margin-top: 0.5em; + margin-bottom: 0.5em; +} small { font-size: 85%; } strong { - font-weight: 600; } + font-weight: 600; + font-size: 0.95em; + color: #3c3c3c; +} em { font-style: italic; } -cite { - font-style: normal; } - -h1, -h2, -h3, -h4, -h5, -h6 { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-weight: 600; - line-height: 20px; - color: inherit; - text-rendering: optimizelegibility; } - h1 { - font-size: 2em; + font-size: 1.8em; font-weight: 400; - padding-bottom: .15em; - border-bottom: 1px solid #aaaaaa; - margin-top: 1.0em; + padding-bottom: .25em; + border-bottom: 1px solid #aaa; + margin-top: 2.5em; + margin-bottom: 1em; line-height: 1.2em; } h1.title { padding-bottom: 1em; border-bottom: 0px; - font-size: 2.75em; } + font-size: 2.5em; + text-align: center; + font-weight: 900; + margin-top: 0.75em; + margin-bottom: 0em; +} h2 { - font-size: 1.5em; - margin-top: 1.5em; } + font-size: 1.3em; + margin-top: 2em; } + +h2.subtitle { + text-align: center; } h3 { - font-size: 1.3em; + font-size: 1.125em; font-style: italic; - margin-top: 0.75em; } + margin-top: 1.5em; } h4 { - font-size: 1.3em; - margin-top: 0.5em; } + font-size: 1.125em; + margin-top: 1em; } h5 { - font-size: 1.2em; - margin-top: 0.25em; } + font-size: 1.125em; + margin-top: 0.75em; } h6 { font-size: 1.1em; } + ul, ol { padding: 0; - margin: 0 0 0px 15px; } + margin-top: 0.5em; + margin-left: 0.75em; } ul ul, ul ol, ol ol, ol ul { - margin-bottom: 0; } + margin-bottom: 0; + margin-left: 1.25em; } li { - line-height: 20px; } - -dl { - margin-bottom: 20px; } - -dt, -dd { - line-height: 20px; } - -dt { - font-weight: bold; } - -dd { - margin-left: 10px; - margin-bottom: 26px; } - -hr { - margin: 20px 0; - border: 0; - border-top: 1px solid #eeeeee; - border-bottom: 1px solid #ffffff; } - -abbr[title], -abbr[data-original-title] { - cursor: help; - border-bottom: 1px dotted #999999; } - -abbr.initialism { - font-size: 90%; - text-transform: uppercase; } - -blockquote { - padding: 0 0 0 15px; - margin: 0 0 20px; - border-left: 5px solid #EFEBE0; } - -table.docinfo + blockquote, table.docinfo blockquote, h1 + blockquote { - border-left: 5px solid #c9c9c9; + list-style-type: circle; } -table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { - margin-bottom: 0; - font-size: 15px; - font-weight: 200; - line-height: 1.5; - font-style: italic; } +ul.simple-boot li { + list-style-type: none; + margin-left: 0em; + margin-bottom: 0.5em; +} -q:before, -q:after, -blockquote:before, -blockquote:after { - content: ""; } +ol.simple > li, ul.simple > li { + margin-bottom: 0.25em; + margin-left: 0.4em } -address { - display: block; - margin-bottom: 20px; - font-style: normal; - line-height: 20px; } +ul.simple.simple-toc > li { + margin-top: 1em; +} -code, -pre { - font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - padding: 0 3px 2px; - font-weight: 500; - font-size: 12px; - color: #444444; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; } +ul.simple-toc { + list-style: none; + font-size: 0.9em; + margin-left: -0.3em; + margin-top: 1em; } + +ul.simple-toc > li { + list-style-type: none; +} + +ul.simple-toc-section { + list-style-type: circle; + margin-left: 1em; + color: #6c9aae; } + + +ol.arabic { + list-style: decimal; } + +ol.loweralpha { + list-style: lower-alpha; } + +ol.upperalpha { + list-style: upper-alpha; } + +ol.lowerroman { + list-style: lower-roman; } + +ol.upperroman { + list-style: upper-roman; } + +ul.auto-toc { + list-style-type: none; } + + +dl { + margin-bottom: 1.5em; } + +dt { + margin-bottom: -0.5em; + margin-left: 0.0em; } + +dd { + margin-left: 2.0em; + margin-bottom: 3.0em; + margin-top: 0.5em; } + + +hr { + margin: 2em 0; + border: 0; + border-top: 1px solid #aaa; } + +blockquote { + font-size: 0.9em; + font-style: italic; + padding-left: 0.5em; + margin-left: 0; + border-left: 5px solid #bbc; +} .pre { font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - font-weight: 600; - /*color: #504da6;*/ + font-weight: 500; + font-size: 0.85em; + background-color: #f0f3ff; + padding-left: 3px; + padding-right: 3px; + border-radius: 4px; } -code { - padding: 2px 4px; - color: #444444; - white-space: nowrap; - background-color: white; - border: 1px solid #777777; } - pre { + font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; + color: #222; + font-weight: 500; display: inline-block; box-sizing: border-box; - min-width: calc(100% - 19.5px); - padding: 9.5px; - margin: 0.25em 10px 10px 10px; - font-size: 15px; - line-height: 20px; + min-width: 100%; + padding: 0.5em; + margin-top: 0.5em; + margin-bottom: 0.5em; + font-size: 0.85em; white-space: pre !important; overflow-y: hidden; overflow-x: visible; - background-color: rgba(0, 0, 0, 0.01); - border: 1px solid #cccccc; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; } - -pre.prettyprint { - margin-bottom: 20px; } - -pre code { - padding: 0; - color: inherit; - white-space: pre; - overflow-x: visible; - background-color: transparent; - border: 0; } + background-color: ghostwhite; + border: 1px solid #dde; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; } .pre-scrollable { max-height: 340px; overflow-y: scroll; } + +/* Nim line-numbered tables */ +.line-nums-table { + width: 100%; + table-layout: fixed; } + +table.line-nums-table { + border-radius: 4px; + border: 1px solid #cccccc; + background-color: ghostwhite; + border-collapse: separate; + margin-top: 15px; + margin-bottom: 25px; } + +.line-nums-table tbody { + border: none; } + +.line-nums-table td pre { + border: none; + background-color: transparent; } + +.line-nums-table td.blob-line-nums { + width: 28px; } + +.line-nums-table td.blob-line-nums pre { + color: #b0b0b0; + -webkit-filter: opacity(75%); + text-align: right; + border-color: transparent; + background-color: transparent; + padding-left: 0px; + margin-left: 0px; + padding-right: 0px; + margin-right: 0px; } + + table { max-width: 100%; background-color: transparent; + margin-top: 0.5em; + margin-bottom: 1.5em; border-collapse: collapse; - border-spacing: 0; } - -table th, table td { - padding: 0px 8px 0px; + border-color: #ccc; + border-spacing: 0; + font-size: 0.9em; } -.table { - width: 100%; - margin-bottom: 20px; } +table th, table td { + padding: 0px 0.5em 0px; +} -.table th, -.table td { - padding: 8px; - line-height: 20px; - text-align: left; - vertical-align: top; - border-top: 1px solid #444444; } - -.table th { +table th { + background-color: #e8e8e8; font-weight: bold; } -.table thead th { - vertical-align: bottom; } +table th.docinfo-name { + background-color: transparent; +} -.table caption + thead tr:first-child th, -.table caption + thead tr:first-child td, -.table colgroup + thead tr:first-child th, -.table colgroup + thead tr:first-child td, -.table thead:first-child tr:first-child th, -.table thead:first-child tr:first-child td { - border-top: 0; } +table tr:hover { + background-color: ghostwhite; } -.table tbody + tbody { - border-top: 2px solid #444444; } - -.table .table { - background-color: rgba(252, 248, 244, 0.75); } - -.table-condensed th, -.table-condensed td { - padding: 4px 5px; } - -.table-bordered { - border: 1px solid #444444; - border-collapse: separate; - *border-collapse: collapse; - border-left: 0; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; } - -.table-bordered th, -.table-bordered td { - border-left: 1px solid #444444; } - -.table-bordered caption + thead tr:first-child th, -.table-bordered caption + tbody tr:first-child th, -.table-bordered caption + tbody tr:first-child td, -.table-bordered colgroup + thead tr:first-child th, -.table-bordered colgroup + tbody tr:first-child th, -.table-bordered colgroup + tbody tr:first-child td, -.table-bordered thead:first-child tr:first-child th, -.table-bordered tbody:first-child tr:first-child th, -.table-bordered tbody:first-child tr:first-child td { - border-top: 0; } - -.table-bordered thead:first-child tr:first-child > th:first-child, -.table-bordered tbody:first-child tr:first-child > td:first-child, -.table-bordered tbody:first-child tr:first-child > th:first-child { - -webkit-border-top-left-radius: 4px; - border-top-left-radius: 4px; - -moz-border-radius-topleft: 4px; } - -.table-bordered thead:first-child tr:first-child > th:last-child, -.table-bordered tbody:first-child tr:first-child > td:last-child, -.table-bordered tbody:first-child tr:first-child > th:last-child { - -webkit-border-top-right-radius: 4px; - border-top-right-radius: 4px; - -moz-border-radius-topright: 4px; } - -.table-bordered thead:last-child tr:last-child > th:first-child, -.table-bordered tbody:last-child tr:last-child > td:first-child, -.table-bordered tbody:last-child tr:last-child > th:first-child, -.table-bordered tfoot:last-child tr:last-child > td:first-child, -.table-bordered tfoot:last-child tr:last-child > th:first-child { - -webkit-border-bottom-left-radius: 4px; - border-bottom-left-radius: 4px; - -moz-border-radius-bottomleft: 4px; } - -.table-bordered thead:last-child tr:last-child > th:last-child, -.table-bordered tbody:last-child tr:last-child > td:last-child, -.table-bordered tbody:last-child tr:last-child > th:last-child, -.table-bordered tfoot:last-child tr:last-child > td:last-child, -.table-bordered tfoot:last-child tr:last-child > th:last-child { - -webkit-border-bottom-right-radius: 4px; - border-bottom-right-radius: 4px; - -moz-border-radius-bottomright: 4px; } - -.table-bordered tfoot + tbody:last-child tr:last-child td:first-child { - -webkit-border-bottom-left-radius: 0; - border-bottom-left-radius: 0; - -moz-border-radius-bottomleft: 0; } - -.table-bordered tfoot + tbody:last-child tr:last-child td:last-child { - -webkit-border-bottom-right-radius: 0; - border-bottom-right-radius: 0; - -moz-border-radius-bottomright: 0; } - -.table-bordered caption + thead tr:first-child th:first-child, -.table-bordered caption + tbody tr:first-child td:first-child, -.table-bordered colgroup + thead tr:first-child th:first-child, -.table-bordered colgroup + tbody tr:first-child td:first-child { - -webkit-border-top-left-radius: 4px; - border-top-left-radius: 4px; - -moz-border-radius-topleft: 4px; } - -.table-bordered caption + thead tr:first-child th:last-child, -.table-bordered caption + tbody tr:first-child td:last-child, -.table-bordered colgroup + thead tr:first-child th:last-child, -.table-bordered colgroup + tbody tr:first-child td:last-child { - -webkit-border-top-right-radius: 4px; - border-top-right-radius: 4px; - -moz-border-radius-topright: 4px; } - -table.docutils th { - background-color: #e8e8e8; } - -table.docutils tr:hover { - background-color: whitesmoke; } - -.table-striped tbody > tr:nth-child(odd) > td, -.table-striped tbody > tr:nth-child(odd) > th { - background-color: rgba(252, 248, 244, 0.75); } - -.table-hover tbody tr:hover > td, -.table-hover tbody tr:hover > th { - background-color: rgba(241, 222, 204, 0.75); } - -table td[class*="span"], -table th[class*="span"], -.row-fluid table td[class*="span"], -.row-fluid table th[class*="span"] { - display: table-cell; - float: none; - margin-left: 0; } - -.hero-unit { - padding: 60px; - margin-bottom: 30px; - font-size: 18px; - font-weight: 200; - line-height: 30px; - color: inherit; - background-color: rgba(230, 197, 164, 0.75); - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; } - -.hero-unit h1 { - margin-bottom: 0; - font-size: 60px; - line-height: 1; - letter-spacing: -1px; - color: inherit; } - -.hero-unit li { - line-height: 30px; } /* rst2html default used to remove borders from tables and images */ .borderless, table.borderless td, table.borderless th { @@ -722,10 +499,6 @@ table.borderless td, table.borderless th { .hidden { display: none; } -a.toc-backref { - text-decoration: none; - color: #444444; } - blockquote.epigraph { margin: 2em 5em; } @@ -735,85 +508,6 @@ dl.docutils dd { object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] { overflow: hidden; } -/* Uncomment (and remove this text!) to get bold-faced definition list terms -dl.docutils dt { - font-weight: bold } -*/ -div.abstract { - margin: 2em 5em; } - -div.abstract p.topic-title { - font-weight: bold; - text-align: center; } - -div.admonition, div.attention, div.caution, div.danger, div.error, -div.hint, div.important, div.note, div.tip, div.warning { - margin: 2em; - border: medium outset; - padding: 1em; } - -div.note, div.warning { - margin: 1.5em 0px; - border: none; } - -div.note p.admonition-title, -div.warning p.admonition-title { - display: none; } - -/* Clearfix - * http://css-tricks.com/snippets/css/clear-fix/ - */ -div.note:after, -div.warning:after { - content: ""; - display: table; - clear: both; } - -div.note p:before, -div.warning p:before { - display: block; - float: left; - font-size: 4em; - line-height: 1em; - margin-right: 20px; - margin-left: 0em; - margin-top: -10px; - content: '\0270D'; - /*handwriting*/ } - -div.warning p:before { - content: '\026A0'; - /*warning*/ } - -div.admonition p.admonition-title, div.hint p.admonition-title, -div.important p.admonition-title, div.note p.admonition-title, -div.tip p.admonition-title { - font-weight: bold; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } - -div.attention p.admonition-title, div.caution p.admonition-title, -div.danger p.admonition-title, div.error p.admonition-title, -div.warning p.admonition-title, .code .error { - color: #b30000; - font-weight: bold; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } - -/* Uncomment (and remove this text!) to get reduced vertical space in - compound paragraphs. -div.compound .compound-first, div.compound .compound-middle { - margin-bottom: 0.5em } - -div.compound .compound-last, div.compound .compound-middle { - margin-top: 0.5em } -*/ -div.dedication { - margin: 2em 5em; - text-align: center; - font-style: italic; } - -div.dedication p.topic-title { - font-weight: bold; - font-style: normal; } div.figure { margin-left: 2em; @@ -821,8 +515,14 @@ div.figure { div.footer, div.header { clear: both; + text-align: center; + color: #666; font-size: smaller; } +div.footer { + padding-top: 5em; +} + div.line-block { display: block; margin-top: 1em; @@ -833,45 +533,24 @@ div.line-block div.line-block { margin-bottom: 0; margin-left: 1.5em; } -div.sidebar { - margin: 0 0 0.5em 1em; - border: medium outset; - padding: 1em; - background-color: rgba(252, 248, 244, 0.75); - width: 40%; - float: right; - clear: right; } - -div.sidebar p.rubric { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-size: medium; } - -div.system-messages { - margin: 5em; } - -div.system-messages h1 { - color: #b30000; } - -div.system-message { - border: medium outset; - padding: 1em; } - -div.system-message p.system-message-title { - color: #b30000; - font-weight: bold; } - div.topic { margin: 2em; } -h1.section-subtitle, h2.section-subtitle, h3.section-subtitle, -h4.section-subtitle, h5.section-subtitle, h6.section-subtitle { - margin-top: 0.4em; } +div.search_results { + background-color: antiquewhite; + margin: 3em; + padding: 1em; + border: 1px solid #4d4d4d; +} -h1.title { - text-align: center; } +div#global-links ul { + margin-left: 0; + list-style-type: none; +} -h2.subtitle { - text-align: center; } +div#global-links > simple-boot { + margin-left: 3em; +} hr.docutils { width: 75%; } @@ -905,30 +584,6 @@ img.align-center, .figure.align-center, object.align-center { div.align-right { text-align: inherit; } -/* div.align-center * { */ -/* text-align: left } */ - -ul.simple > li { - margin-bottom: 0.5em } - -ol.simple, ul.simple { - margin-bottom: 1em; } - -ol.arabic { - list-style: decimal; } - -ol.loweralpha { - list-style: lower-alpha; } - -ol.upperalpha { - list-style: upper-alpha; } - -ol.lowerroman { - list-style: lower-roman; } - -ol.upperroman { - list-style: upper-roman; } - p.attribution { text-align: right; margin-left: 50%; } @@ -949,15 +604,6 @@ p.rubric { color: maroon; text-align: center; } -p.sidebar-title { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-weight: bold; - font-size: larger; } - -p.sidebar-subtitle { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-weight: bold; } - p.topic-title { font-weight: bold; } @@ -997,22 +643,14 @@ pre.code .inserted, code .inserted { background-color: #A3D289; } span.classifier { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-style: oblique; } span.classifier-delimiter { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: bold; } -span.interpreted { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } - span.option { white-space: nowrap; } -span.pre { - white-space: pre; } - span.problematic { color: #b30000; } @@ -1020,44 +658,6 @@ span.section-subtitle { /* font-size relative to parent (h1..h6 element) */ font-size: 80%; } -table.citation { - border-left: solid 1px #666666; - margin-left: 1px; } - -table.docinfo { - margin: 0em; - margin-top: 2em; - margin-bottom: 2em; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; - color: #444444; } - -table.docutils { - margin-top: 0.5em; - margin-bottom: 0.5em; } - -table.footnote { - border-left: solid 1px #2d2d2d; - margin-left: 1px; } - -table.docutils td, table.docutils th, -table.docinfo td, table.docinfo th { - padding-left: 0.5em; - padding-right: 0.5em; - vertical-align: top; } - -table.docutils th.field-name, table.docinfo th.docinfo-name { - font-weight: 700; - text-align: left; - white-space: nowrap; - padding-left: 0; } - -h1 tt.docutils, h2 tt.docutils, h3 tt.docutils, -h4 tt.docutils, h5 tt.docutils, h6 tt.docutils { - font-size: 100%; } - -ul.auto-toc { - list-style-type: none; } - span.DecNumber { color: #252dbe; } @@ -1074,7 +674,7 @@ span.FloatNumber { color: #252dbe; } span.Identifier { - color: #3b3b3b; } + color: #222; } span.Keyword { font-weight: 600; @@ -1139,38 +739,23 @@ dt pre > span.Identifier, dt pre > span.Operator { color: #155da4; font-weight: 700; } -dt pre > span.Identifier ~ span.Identifier, dt pre > span.Operator ~ span.Identifier { - color: inherit; - font-weight: inherit; } - -dt pre > span.Operator ~ span.Identifier { +dt pre > span.Keyword ~ span.Identifier, dt pre > span.Identifier ~ span.Identifier, +dt pre > span.Operator ~ span.Identifier, dt pre > span.Other ~ span.Identifier { color: inherit; font-weight: inherit; } /* Nim sprite for the footer (taken from main page favicon) */ .nim-sprite { display: inline-block; - height: 12px; - width: 12px; + height: 16px; + width: 16px; background-position: 0 0; - background-size: 12px 12px; + background-size: 16px 16px; -webkit-filter: opacity(50%); background-repeat: no-repeat; background-image: url("data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="); margin-bottom: -5px; } -div.search_results { - background-color: antiquewhite; - margin: 3em; - padding: 1em; - border: 1px solid #4d4d4d; -} - -div#global-links ul { - margin-left: 0; - list-style-type: none; -} - span.pragmadots { /* Position: relative frees us up to make the dots look really nice without fucking up the layout and @@ -1178,18 +763,14 @@ span.pragmadots { position: relative; /* 1px down looks slightly nicer */ top: 1px; - padding: 2px; - background-color: #D3D3D3; + background-color: #e8e8e8; border-radius: 4px; margin: 0 2px; cursor: pointer; - - /* For some reason on Chrome, making the font size - smaller than 1em is causing the parent container to - bulge slightly. So, we're stuck with inheriting 1em, - which is sad, because 0.8em looks better... */ + font-size: 0.8em; } + span.pragmadots:hover { background-color: #DBDBDB; } @@ -1197,6 +778,10 @@ span.pragmawrap { display: none; } +span.attachedType { + display: none; + visibility: hidden; +} @@ -1238,12 +823,6 @@ function main() {
    -
  • - Exports -
      - -
    -
  • Imports
    +

    This is the main nimterop import file to help with wrapping C/C++ source code.

    -

    Check out template.nim as a starting point for wrapping a new library. The template can be copied and trimmed down and modified as required.

    +

    Check out template.nim as a starting point for wrapping a new library. The template can be copied and trimmed down and modified as required. templite.nim is a shorter version for more experienced users.

    All {.compileTime.} procs must be used in a compile time context, e.g. using:

    static:
       cAddStdDir()

    - -
    +

    Imports

    plugin, git, paths, types @@ -1311,32 +895,38 @@ function main() {

    Procs

    - -
    proc cSkipSymbol(skips: seq[string]) {...}{.compileTime, raises: [], tags: [].}
    + +
    proc cSkipSymbol(skips: seq[string]) {...}{.compileTime, raises: [], tags: [].}
    -Similar to cOverride(), this macro allows filtering out symbols not of interest from the generated output. + +

    Similar to cOverride(), this macro allows filtering out symbols not of interest from the generated output.

    +

    cSkipSymbol() only affects calls to cImport() that follow it.

    +

    Examples:

    static :
       cSkipSymbol @["proc1", "Type2"]
    -
    proc cSearchPath(path: string): string {...}{.compileTime, raises: [], tags: [ReadDirEffect].}
    +
    proc cSearchPath(path: string): string {...}{.compileTime, raises: [], tags: [ReadDirEffect].}
    +

    Get full path to file or directory path in search path configured using cAddSearchDir() and cAddStdDir().

    This can be used to locate files or directories that can be passed onto cCompile(), cIncludeDir() and cImport().

    - -
    proc cDebug() {...}{.compileTime, raises: [], tags: [].}
    + +
    proc cDebug() {...}{.compileTime, raises: [], tags: [].}
    + Enable debug messages and display the generated Nim code
    - -
    proc cDisableCaching() {...}{.compileTime, raises: [], tags: [].}
    + +
    proc cDisableCaching() {...}{.compileTime, raises: [], tags: [].}
    +

    Disable caching of generated Nim code - useful during wrapper development

    If files included by header being processed by cImport() change and affect the generated content, they will be ignored and the cached value will continue to be used . Use cDisableCaching() to avoid this scenario during development.

    nim -f was broken prior to 0.19.4 but can also be used to flush the cached content.

    @@ -1344,8 +934,9 @@ Enable debug messages and display the generated Nim code
    -
    proc cAddSearchDir(dir: string) {...}{.compileTime, raises: [], tags: [].}
    +
    proc cAddSearchDir(dir: string) {...}{.compileTime, raises: [], tags: [].}
    + Add directory dir to the search path used in calls to cSearchPath().

    Examples:

    import
    @@ -1357,8 +948,9 @@ Add directory dir to
     
     
    -
    proc cAddStdDir(mode = "c") {...}{.compileTime, raises: [], tags: [].}
    +
    proc cAddStdDir(mode = "c") {...}{.compileTime, raises: [ValueError], tags: [ReadEnvEffect].}
    + Add the standard c [default] or cpp include paths to search path used in calls to cSearchPath()

    Examples:

    static :
    @@ -1374,32 +966,36 @@ Add the standard c [d
     

    Macros

    - -
    macro cOverride(body): untyped
    + +
    macro cOverride(body): untyped
    +

    When the wrapper code generated by nimterop is missing certain symbols or not accurate, it may be required to hand wrap them. Define them in a cOverride() macro block so that Nimterop no longer defines these symbols.

    For example:

    int svGetCallerInfo(const char** fileName, int *lineNumber);

    This might map to:

    proc svGetCallerInfo(fileName: ptr cstring; lineNumber: var cint)

    Whereas it might mean:

    cOverride:
       proc svGetCallerInfo(fileName: var cstring; lineNumber: var cint)

    Using the cOverride() block, nimterop can be instructed to skip over svGetCallerInfo(). This works for procs, consts and types.

    +

    cOverride() only affects calls to cImport() that follow it.

    - -
    macro cPlugin(body): untyped
    + +
    macro cPlugin(body): untyped
    -When cOverride() and cSkipSymbol() are not adequate, the cPlugin() macro can be used to customize the generated Nim output. The following callbacks are available at this time.
    proc onSymbol(sym: var Symbol) {.exportc, dynlib.}

    onSymbol() can be used to handle symbol name modifications required due to invalid characters like leading/trailing _ or rename symbols that would clash due to Nim's style insensitivity. It can also be used to remove prefixes and suffixes like SDL_. The symbol name and type is provided to the callback and the name can be modified.

    -

    Returning a blank name will result in the symbol being skipped. This will fail for nskParam and nskField since the generated Nim code will be wrong.

    + +When cOverride() and cSkipSymbol() are not adequate, the cPlugin() macro can be used to customize the generated Nim output. The following callbacks are available at this time.
    proc onSymbol(sym: var Symbol) {.exportc, dynlib.}

    onSymbol() can be used to handle symbol name modifications required due to invalid characters like leading/trailing _ or rename symbols that would clash due to Nim's style insensitivity. It can also be used to remove prefixes and suffixes like SDL_. The symbol name and type is provided to the callback and the name can be modified.

    +

    Returning a blank name will result in the symbol being skipped. This will fail for nskParam and nskField since the generated Nim code will be wrong.

    Symbol types can be any of the following:

    -
    • nskConst for constants
    • -
    • nskType for type identifiers, including primitive
    • -
    • nskParam for param names
    • -
    • nskField for struct field names
    • -
    • nskEnumField for enum (field) names, though they are in the global namespace as nskConst
    • -
    • nskProc - for proc names
    • +
      • nskConst for constants
      • +
      • nskType for type identifiers, including primitive
      • +
      • nskParam for param names
      • +
      • nskField for struct field names
      • +
      • nskEnumField for enum (field) names, though they are in the global namespace as nskConst
      • +
      • nskProc - for proc names
      -

      nimterop/plugins is implicitly imported to provide access to standard plugin facilities.

      +

      nimterop/plugins is implicitly imported to provide access to standard plugin facilities.

      +

      cPlugin() only affects calls to cImport() that follow it.

      Examples:

      cPlugin:
      @@ -1421,20 +1017,23 @@ When cOverride()<
       
       
    -
    macro cDefine(name: static string; val: static string = ""): untyped
    +
    macro cDefine(name: static string; val: static string = ""): untyped
    + #define an identifer that is forwarded to the C/C++ compiler using {.passC: "-DXXX".}
    - -
    macro cIncludeDir(dir: static string): untyped
    + +
    macro cIncludeDir(dir: static string): untyped
    + Add an include directory that is forwarded to the C/C++ compiler using {.passC: "-IXXX".}. This is also provided to the preprocessor during Nim code generation.
    -
    macro cCompile(path: static string; mode = "c"; exclude = ""): untyped
    +
    macro cCompile(path: static string; mode = "c"; exclude = ""): untyped
    +

    Compile and link C/C++ implementation into resulting binary using {.compile.}

    path can be a specific file or contain wildcards:

    cCompile("file.c")
    @@ -1445,9 +1044,10 @@ Add an include directory that is forwarded to the C/C++ compiler using 
     
    -
    macro cImport(filename: static string; recurse: static bool = false;
    +
    macro cImport(filename: static string; recurse: static bool = false;
                  dynlib: static string = ""): untyped
    +

    Import all supported definitions from specified header file. Generated content is cached in nimcache until filename changes unless cDisableCaching() is set. nim -f can also be used after Nim v0.19.4 to flush the cache.

    recurse can be used to generate Nim wrappers from #include files referenced in filename. This is only done for files in the same directory as filename or in a directory added using cIncludeDir()

    dynlib can be used to specify the Nim string to use to specify the dynamic library to load the imported symbols from. For example:

    @@ -1467,7 +1067,27 @@ Add an include directory that is forwarded to the C/C++ compiler using + +
    macro c2nImport(filename: static string; recurse: static bool = false;
    +               dynlib: static string = ""; mode: static string = "c";
    +               flags: static string = ""): untyped
    +
    +

    Import all supported definitions from specified header file using c2nim

    +

    Similar to cImport() but uses c2nim to generate the Nim wrapper instead of toast. Note that neither cOverride(), cSkipSymbol() nor cPlugin() have any impact on c2nim.

    +

    toast is only used to preprocess the header file and recurse if specified.

    +

    mode should be set to cpp for c2nim to wrap C++ headers.

    +

    flags can be used to pass other command line arguments to c2nim.

    +

    nimterop does not depend on c2nim as a nimble dependency so it does not get installed automatically. Any wrapper or library that requires this proc needs to install c2nim with nimble install c2nim or add it as a dependency in its own .nimble file.

    + + +
    + +
    +
    @@ -1477,7 +1097,7 @@ Add an include directory that is forwarded to the C/C++ compiler using
    - Made with Nim. Generated: 2019-05-09 06:10:00 UTC + Made with Nim. Generated: 2019-07-18 06:10:50 UTC
    diff --git a/cimport.idx b/cimport.idx old mode 100755 new mode 100644 index 19d15b6..b477ab8 --- a/cimport.idx +++ b/cimport.idx @@ -1,12 +1,13 @@ -cOverride cimport.html#cOverride.m, cimport: cOverride(body): untyped -cSkipSymbol cimport.html#cSkipSymbol,seq[string] cimport: cSkipSymbol(skips: seq[string]) -cPlugin cimport.html#cPlugin.m, cimport: cPlugin(body): untyped +cOverride cimport.html#cOverride.m cimport: cOverride(body): untyped +cSkipSymbol cimport.html#cSkipSymbol,seq[T][string] cimport: cSkipSymbol(skips: seq[string]) +cPlugin cimport.html#cPlugin.m cimport: cPlugin(body): untyped cSearchPath cimport.html#cSearchPath,string cimport: cSearchPath(path: string): string -cDebug cimport.html#cDebug, cimport: cDebug() -cDisableCaching cimport.html#cDisableCaching, cimport: cDisableCaching() +cDebug cimport.html#cDebug cimport: cDebug() +cDisableCaching cimport.html#cDisableCaching cimport: cDisableCaching() cDefine cimport.html#cDefine.m,,string cimport: cDefine(name: static string; val: static string = ""): untyped cAddSearchDir cimport.html#cAddSearchDir,string cimport: cAddSearchDir(dir: string) -cIncludeDir cimport.html#cIncludeDir.m, cimport: cIncludeDir(dir: static string): untyped +cIncludeDir cimport.html#cIncludeDir.m cimport: cIncludeDir(dir: static string): untyped cAddStdDir cimport.html#cAddStdDir,string cimport: cAddStdDir(mode = "c") cCompile cimport.html#cCompile.m,,string,string cimport: cCompile(path: static string; mode = "c"; exclude = ""): untyped cImport cimport.html#cImport.m,,string cimport: cImport(filename: static string; recurse: static bool = false;\n dynlib: static string = ""): untyped +c2nImport cimport.html#c2nImport.m,,string,string,string cimport: c2nImport(filename: static string; recurse: static bool = false;\n dynlib: static string = ""; mode: static string = "c"; flags: static string = ""): untyped diff --git a/compat.html b/compat.html old mode 100755 new mode 100644 index 6ef1cba..28bd722 --- a/compat.html +++ b/compat.html @@ -27,232 +27,130 @@ customize this style sheet. Modified from Chad Skeeters' rst2html-style https://bitbucket.org/cskeeters/rst2html-style/ -Modified by Boyd Greenfield +Modified by Boyd Greenfield and narimiran */ -/* SCSS variables */ -/* Text weights */ -/* Body colors */ -/* Text colors */ -/* Link colors */ -/* Syntax highlighting colors */ -/* Pct changes */ -/* Mixins */ -/* Body/layout */ + html { font-size: 100%; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; } -/* Where we want fancier font if available */ -h1, h2, h3, h4, h5, h6, p.module-desc, table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; } - -h1.title { - font-weight: 900; } - body { font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: 400; - font-size: 16px; - line-height: 20px; - color: #444; - letter-spacing: 0.15px; - background-color: #FDFBFA; } + font-size: 1.125em; + line-height: 1.5; + color: #222; + background-color: #FCFCFC; } /* Skeleton grid */ .container { position: relative; width: 100%; - max-width: 960px; + max-width: 1050px; margin: 0 auto; - padding: 0 20px; + padding: 0; box-sizing: border-box; } .column, .columns { width: 100%; float: left; - box-sizing: border-box; } + box-sizing: border-box; + margin-left: 1%; +} -/* For devices larger than 400px */ -@media (min-width: 400px) { - .container { - width: 100%; - padding: 0; } } -/* For devices larger than 650px */ -@media (min-width: 650px) { - .container { - width: 100%; } +.column:first-child, +.columns:first-child { + margin-left: 0; } - .column, - .columns { - margin-left: 4%; } +.three.columns { + width: 19%; } - .column:first-child, - .columns:first-child { - margin-left: 0; } +.nine.columns { + width: 80.0%; } - .one.column, - .one.columns { - width: 4.66666666667%; } - - .two.columns { - width: 13.3333333333%; } +.twelve.columns { + width: 100%; + margin-left: 0; } +@media screen and (max-width: 860px) { .three.columns { - width: 22%; } - - .four.columns { - width: 30.6666666667%; } - - .five.columns { - width: 39.3333333333%; } - - .six.columns { - width: 48%; } - - .seven.columns { - width: 56.6666666667%; } - - .eight.columns { - width: 65.3333333333%; } - + display: none; + } .nine.columns { - width: 74.0%; } - - .ten.columns { - width: 82.6666666667%; } - - .eleven.columns { - width: 91.3333333333%; } - - .twelve.columns { - width: 100%; - margin-left: 0; } - - .one-third.column { - width: 30.6666666667%; } - - .two-thirds.column { - width: 65.3333333333%; } } -/* Customer Overrides */ -.footer { - text-align: center; - color: #969696; - padding-top: 10%; } - -p.module-desc { - font-size: 1.1em; - color: #666666; } - -a.link-seesrc { - color: #aec7d2; - font-style: italic; } - -a.link-seesrc:hover { - color: #6c9aae; } - -#toc-list { - word-wrap: break-word; } - -ul.simple-toc { - list-style: none; } - -ul.simple-toc a.reference-toplevel { - font-weight: bold; - color: #0077b3; } - -ul.simple-toc-section { - list-style-type: circle; - color: #6c9aae; } - -ul.simple-toc-section a.reference { - color: #0077b3; } + width: 98.0%; + } + body { + font-size: 1em; + line-height: 1.35; + } +} cite { font-style: italic !important; } -dt > pre { - border-color: rgba(0, 0, 0, 0.1); - background-color: rgba(255, 255, 255, 0.3); - margin: 15px 0px 5px; } - -dd > pre { - border-color: rgba(0, 0, 0, 0.1); - background-color: whitesmoke; - margin-top: 8px; } - -.item > dd { - margin-left: 10px; - margin-bottom: 30px; } - -/* Nim line-numbered tables */ -.line-nums-table { - width: 100%; - table-layout: fixed; } /* Nim search input */ div#searchInputDiv { - margin-bottom: 8px; + margin-bottom: 1em; } -div#searchInputDiv input#searchInput { - width: 10em; -} -div.search-groupby { - margin-bottom: 8px; +input#searchInput { + width: 80%; } -table.line-nums-table { - border-radius: 4px; - border: 1px solid #cccccc; - background-color: whitesmoke; - border-collapse: separate; - margin-top: 15px; - margin-bottom: 25px; } - -.line-nums-table tbody { - border: none; } - -.line-nums-table td pre { - border: none; - background-color: transparent; } - -.line-nums-table td.blob-line-nums { - width: 28px; } - -.line-nums-table td.blob-line-nums pre { - color: #b0b0b0; - -webkit-filter: opacity(75%); - text-align: right; - border-color: transparent; - background-color: transparent; - padding-left: 0px; - margin-left: 0px; - padding-right: 0px; - margin-right: 0px; } +/* + * Some custom formatting for input forms. + * This also fixes input form colors on Firefox with a dark system theme on Linux. + */ +input { + -moz-appearance: none; + color: #333; + background-color: #f8f8f8; + border: 1px solid #aaa; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-size: 0.9em; + padding: 6px; +} +input:focus { + border: 1px solid #1fa0eb; + box-shadow: 0 0 2px #1fa0eb; +} /* Docgen styles */ /* Links */ a { - color: #0077b3; - text-decoration: none; } + color: #07b; + text-decoration: none; +} + +a span.Identifier { + text-decoration: underline; + text-decoration-color: #aab; +} + +a.reference-toplevel { + font-weight: bold; +} + +a.toc-backref { + text-decoration: none; + color: #222; } + +a.link-seesrc { + color: #607c9f; + font-size: 0.9em; + font-style: italic; } a:hover, a:focus { - color: #00334d; + color: #607c9f; text-decoration: underline; } -a:visited { - color: #00334d; } +a:hover span.Identifier { + color: #607c9f; +} -a:focus { - outline: thin dotted #2d2d2d; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; } - -a:hover, -a:active { - outline: 0; } sub, sup { @@ -329,379 +227,258 @@ img { h2, h3 { - page-break-after: avoid; } } -.img-rounded { - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; } + page-break-after: avoid; } +} -.img-polaroid { - padding: 4px; - background-color: rgba(252, 248, 244, 0.75); - border: 1px solid #ccc; - border: 1px solid rgba(0, 0, 0, 0.2); - -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); - -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); } p { - margin: 0 0 8px; } + margin-top: 0.5em; + margin-bottom: 0.5em; +} small { font-size: 85%; } strong { - font-weight: 600; } + font-weight: 600; + font-size: 0.95em; + color: #3c3c3c; +} em { font-style: italic; } -cite { - font-style: normal; } - -h1, -h2, -h3, -h4, -h5, -h6 { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-weight: 600; - line-height: 20px; - color: inherit; - text-rendering: optimizelegibility; } - h1 { - font-size: 2em; + font-size: 1.8em; font-weight: 400; - padding-bottom: .15em; - border-bottom: 1px solid #aaaaaa; - margin-top: 1.0em; + padding-bottom: .25em; + border-bottom: 1px solid #aaa; + margin-top: 2.5em; + margin-bottom: 1em; line-height: 1.2em; } h1.title { padding-bottom: 1em; border-bottom: 0px; - font-size: 2.75em; } + font-size: 2.5em; + text-align: center; + font-weight: 900; + margin-top: 0.75em; + margin-bottom: 0em; +} h2 { - font-size: 1.5em; - margin-top: 1.5em; } + font-size: 1.3em; + margin-top: 2em; } + +h2.subtitle { + text-align: center; } h3 { - font-size: 1.3em; + font-size: 1.125em; font-style: italic; - margin-top: 0.75em; } + margin-top: 1.5em; } h4 { - font-size: 1.3em; - margin-top: 0.5em; } + font-size: 1.125em; + margin-top: 1em; } h5 { - font-size: 1.2em; - margin-top: 0.25em; } + font-size: 1.125em; + margin-top: 0.75em; } h6 { font-size: 1.1em; } + ul, ol { padding: 0; - margin: 0 0 0px 15px; } + margin-top: 0.5em; + margin-left: 0.75em; } ul ul, ul ol, ol ol, ol ul { - margin-bottom: 0; } + margin-bottom: 0; + margin-left: 1.25em; } li { - line-height: 20px; } - -dl { - margin-bottom: 20px; } - -dt, -dd { - line-height: 20px; } - -dt { - font-weight: bold; } - -dd { - margin-left: 10px; - margin-bottom: 26px; } - -hr { - margin: 20px 0; - border: 0; - border-top: 1px solid #eeeeee; - border-bottom: 1px solid #ffffff; } - -abbr[title], -abbr[data-original-title] { - cursor: help; - border-bottom: 1px dotted #999999; } - -abbr.initialism { - font-size: 90%; - text-transform: uppercase; } - -blockquote { - padding: 0 0 0 15px; - margin: 0 0 20px; - border-left: 5px solid #EFEBE0; } - -table.docinfo + blockquote, table.docinfo blockquote, h1 + blockquote { - border-left: 5px solid #c9c9c9; + list-style-type: circle; } -table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { - margin-bottom: 0; - font-size: 15px; - font-weight: 200; - line-height: 1.5; - font-style: italic; } +ul.simple-boot li { + list-style-type: none; + margin-left: 0em; + margin-bottom: 0.5em; +} -q:before, -q:after, -blockquote:before, -blockquote:after { - content: ""; } +ol.simple > li, ul.simple > li { + margin-bottom: 0.25em; + margin-left: 0.4em } -address { - display: block; - margin-bottom: 20px; - font-style: normal; - line-height: 20px; } +ul.simple.simple-toc > li { + margin-top: 1em; +} -code, -pre { - font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - padding: 0 3px 2px; - font-weight: 500; - font-size: 12px; - color: #444444; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; } +ul.simple-toc { + list-style: none; + font-size: 0.9em; + margin-left: -0.3em; + margin-top: 1em; } + +ul.simple-toc > li { + list-style-type: none; +} + +ul.simple-toc-section { + list-style-type: circle; + margin-left: 1em; + color: #6c9aae; } + + +ol.arabic { + list-style: decimal; } + +ol.loweralpha { + list-style: lower-alpha; } + +ol.upperalpha { + list-style: upper-alpha; } + +ol.lowerroman { + list-style: lower-roman; } + +ol.upperroman { + list-style: upper-roman; } + +ul.auto-toc { + list-style-type: none; } + + +dl { + margin-bottom: 1.5em; } + +dt { + margin-bottom: -0.5em; + margin-left: 0.0em; } + +dd { + margin-left: 2.0em; + margin-bottom: 3.0em; + margin-top: 0.5em; } + + +hr { + margin: 2em 0; + border: 0; + border-top: 1px solid #aaa; } + +blockquote { + font-size: 0.9em; + font-style: italic; + padding-left: 0.5em; + margin-left: 0; + border-left: 5px solid #bbc; +} .pre { font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - font-weight: 600; - /*color: #504da6;*/ + font-weight: 500; + font-size: 0.85em; + background-color: #f0f3ff; + padding-left: 3px; + padding-right: 3px; + border-radius: 4px; } -code { - padding: 2px 4px; - color: #444444; - white-space: nowrap; - background-color: white; - border: 1px solid #777777; } - pre { + font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; + color: #222; + font-weight: 500; display: inline-block; box-sizing: border-box; - min-width: calc(100% - 19.5px); - padding: 9.5px; - margin: 0.25em 10px 10px 10px; - font-size: 15px; - line-height: 20px; + min-width: 100%; + padding: 0.5em; + margin-top: 0.5em; + margin-bottom: 0.5em; + font-size: 0.85em; white-space: pre !important; overflow-y: hidden; overflow-x: visible; - background-color: rgba(0, 0, 0, 0.01); - border: 1px solid #cccccc; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; } - -pre.prettyprint { - margin-bottom: 20px; } - -pre code { - padding: 0; - color: inherit; - white-space: pre; - overflow-x: visible; - background-color: transparent; - border: 0; } + background-color: ghostwhite; + border: 1px solid #dde; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; } .pre-scrollable { max-height: 340px; overflow-y: scroll; } + +/* Nim line-numbered tables */ +.line-nums-table { + width: 100%; + table-layout: fixed; } + +table.line-nums-table { + border-radius: 4px; + border: 1px solid #cccccc; + background-color: ghostwhite; + border-collapse: separate; + margin-top: 15px; + margin-bottom: 25px; } + +.line-nums-table tbody { + border: none; } + +.line-nums-table td pre { + border: none; + background-color: transparent; } + +.line-nums-table td.blob-line-nums { + width: 28px; } + +.line-nums-table td.blob-line-nums pre { + color: #b0b0b0; + -webkit-filter: opacity(75%); + text-align: right; + border-color: transparent; + background-color: transparent; + padding-left: 0px; + margin-left: 0px; + padding-right: 0px; + margin-right: 0px; } + + table { max-width: 100%; background-color: transparent; + margin-top: 0.5em; + margin-bottom: 1.5em; border-collapse: collapse; - border-spacing: 0; } - -table th, table td { - padding: 0px 8px 0px; + border-color: #ccc; + border-spacing: 0; + font-size: 0.9em; } -.table { - width: 100%; - margin-bottom: 20px; } +table th, table td { + padding: 0px 0.5em 0px; +} -.table th, -.table td { - padding: 8px; - line-height: 20px; - text-align: left; - vertical-align: top; - border-top: 1px solid #444444; } - -.table th { +table th { + background-color: #e8e8e8; font-weight: bold; } -.table thead th { - vertical-align: bottom; } +table th.docinfo-name { + background-color: transparent; +} -.table caption + thead tr:first-child th, -.table caption + thead tr:first-child td, -.table colgroup + thead tr:first-child th, -.table colgroup + thead tr:first-child td, -.table thead:first-child tr:first-child th, -.table thead:first-child tr:first-child td { - border-top: 0; } +table tr:hover { + background-color: ghostwhite; } -.table tbody + tbody { - border-top: 2px solid #444444; } - -.table .table { - background-color: rgba(252, 248, 244, 0.75); } - -.table-condensed th, -.table-condensed td { - padding: 4px 5px; } - -.table-bordered { - border: 1px solid #444444; - border-collapse: separate; - *border-collapse: collapse; - border-left: 0; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; } - -.table-bordered th, -.table-bordered td { - border-left: 1px solid #444444; } - -.table-bordered caption + thead tr:first-child th, -.table-bordered caption + tbody tr:first-child th, -.table-bordered caption + tbody tr:first-child td, -.table-bordered colgroup + thead tr:first-child th, -.table-bordered colgroup + tbody tr:first-child th, -.table-bordered colgroup + tbody tr:first-child td, -.table-bordered thead:first-child tr:first-child th, -.table-bordered tbody:first-child tr:first-child th, -.table-bordered tbody:first-child tr:first-child td { - border-top: 0; } - -.table-bordered thead:first-child tr:first-child > th:first-child, -.table-bordered tbody:first-child tr:first-child > td:first-child, -.table-bordered tbody:first-child tr:first-child > th:first-child { - -webkit-border-top-left-radius: 4px; - border-top-left-radius: 4px; - -moz-border-radius-topleft: 4px; } - -.table-bordered thead:first-child tr:first-child > th:last-child, -.table-bordered tbody:first-child tr:first-child > td:last-child, -.table-bordered tbody:first-child tr:first-child > th:last-child { - -webkit-border-top-right-radius: 4px; - border-top-right-radius: 4px; - -moz-border-radius-topright: 4px; } - -.table-bordered thead:last-child tr:last-child > th:first-child, -.table-bordered tbody:last-child tr:last-child > td:first-child, -.table-bordered tbody:last-child tr:last-child > th:first-child, -.table-bordered tfoot:last-child tr:last-child > td:first-child, -.table-bordered tfoot:last-child tr:last-child > th:first-child { - -webkit-border-bottom-left-radius: 4px; - border-bottom-left-radius: 4px; - -moz-border-radius-bottomleft: 4px; } - -.table-bordered thead:last-child tr:last-child > th:last-child, -.table-bordered tbody:last-child tr:last-child > td:last-child, -.table-bordered tbody:last-child tr:last-child > th:last-child, -.table-bordered tfoot:last-child tr:last-child > td:last-child, -.table-bordered tfoot:last-child tr:last-child > th:last-child { - -webkit-border-bottom-right-radius: 4px; - border-bottom-right-radius: 4px; - -moz-border-radius-bottomright: 4px; } - -.table-bordered tfoot + tbody:last-child tr:last-child td:first-child { - -webkit-border-bottom-left-radius: 0; - border-bottom-left-radius: 0; - -moz-border-radius-bottomleft: 0; } - -.table-bordered tfoot + tbody:last-child tr:last-child td:last-child { - -webkit-border-bottom-right-radius: 0; - border-bottom-right-radius: 0; - -moz-border-radius-bottomright: 0; } - -.table-bordered caption + thead tr:first-child th:first-child, -.table-bordered caption + tbody tr:first-child td:first-child, -.table-bordered colgroup + thead tr:first-child th:first-child, -.table-bordered colgroup + tbody tr:first-child td:first-child { - -webkit-border-top-left-radius: 4px; - border-top-left-radius: 4px; - -moz-border-radius-topleft: 4px; } - -.table-bordered caption + thead tr:first-child th:last-child, -.table-bordered caption + tbody tr:first-child td:last-child, -.table-bordered colgroup + thead tr:first-child th:last-child, -.table-bordered colgroup + tbody tr:first-child td:last-child { - -webkit-border-top-right-radius: 4px; - border-top-right-radius: 4px; - -moz-border-radius-topright: 4px; } - -table.docutils th { - background-color: #e8e8e8; } - -table.docutils tr:hover { - background-color: whitesmoke; } - -.table-striped tbody > tr:nth-child(odd) > td, -.table-striped tbody > tr:nth-child(odd) > th { - background-color: rgba(252, 248, 244, 0.75); } - -.table-hover tbody tr:hover > td, -.table-hover tbody tr:hover > th { - background-color: rgba(241, 222, 204, 0.75); } - -table td[class*="span"], -table th[class*="span"], -.row-fluid table td[class*="span"], -.row-fluid table th[class*="span"] { - display: table-cell; - float: none; - margin-left: 0; } - -.hero-unit { - padding: 60px; - margin-bottom: 30px; - font-size: 18px; - font-weight: 200; - line-height: 30px; - color: inherit; - background-color: rgba(230, 197, 164, 0.75); - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; } - -.hero-unit h1 { - margin-bottom: 0; - font-size: 60px; - line-height: 1; - letter-spacing: -1px; - color: inherit; } - -.hero-unit li { - line-height: 30px; } /* rst2html default used to remove borders from tables and images */ .borderless, table.borderless td, table.borderless th { @@ -722,10 +499,6 @@ table.borderless td, table.borderless th { .hidden { display: none; } -a.toc-backref { - text-decoration: none; - color: #444444; } - blockquote.epigraph { margin: 2em 5em; } @@ -735,85 +508,6 @@ dl.docutils dd { object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] { overflow: hidden; } -/* Uncomment (and remove this text!) to get bold-faced definition list terms -dl.docutils dt { - font-weight: bold } -*/ -div.abstract { - margin: 2em 5em; } - -div.abstract p.topic-title { - font-weight: bold; - text-align: center; } - -div.admonition, div.attention, div.caution, div.danger, div.error, -div.hint, div.important, div.note, div.tip, div.warning { - margin: 2em; - border: medium outset; - padding: 1em; } - -div.note, div.warning { - margin: 1.5em 0px; - border: none; } - -div.note p.admonition-title, -div.warning p.admonition-title { - display: none; } - -/* Clearfix - * http://css-tricks.com/snippets/css/clear-fix/ - */ -div.note:after, -div.warning:after { - content: ""; - display: table; - clear: both; } - -div.note p:before, -div.warning p:before { - display: block; - float: left; - font-size: 4em; - line-height: 1em; - margin-right: 20px; - margin-left: 0em; - margin-top: -10px; - content: '\0270D'; - /*handwriting*/ } - -div.warning p:before { - content: '\026A0'; - /*warning*/ } - -div.admonition p.admonition-title, div.hint p.admonition-title, -div.important p.admonition-title, div.note p.admonition-title, -div.tip p.admonition-title { - font-weight: bold; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } - -div.attention p.admonition-title, div.caution p.admonition-title, -div.danger p.admonition-title, div.error p.admonition-title, -div.warning p.admonition-title, .code .error { - color: #b30000; - font-weight: bold; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } - -/* Uncomment (and remove this text!) to get reduced vertical space in - compound paragraphs. -div.compound .compound-first, div.compound .compound-middle { - margin-bottom: 0.5em } - -div.compound .compound-last, div.compound .compound-middle { - margin-top: 0.5em } -*/ -div.dedication { - margin: 2em 5em; - text-align: center; - font-style: italic; } - -div.dedication p.topic-title { - font-weight: bold; - font-style: normal; } div.figure { margin-left: 2em; @@ -821,8 +515,14 @@ div.figure { div.footer, div.header { clear: both; + text-align: center; + color: #666; font-size: smaller; } +div.footer { + padding-top: 5em; +} + div.line-block { display: block; margin-top: 1em; @@ -833,45 +533,24 @@ div.line-block div.line-block { margin-bottom: 0; margin-left: 1.5em; } -div.sidebar { - margin: 0 0 0.5em 1em; - border: medium outset; - padding: 1em; - background-color: rgba(252, 248, 244, 0.75); - width: 40%; - float: right; - clear: right; } - -div.sidebar p.rubric { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-size: medium; } - -div.system-messages { - margin: 5em; } - -div.system-messages h1 { - color: #b30000; } - -div.system-message { - border: medium outset; - padding: 1em; } - -div.system-message p.system-message-title { - color: #b30000; - font-weight: bold; } - div.topic { margin: 2em; } -h1.section-subtitle, h2.section-subtitle, h3.section-subtitle, -h4.section-subtitle, h5.section-subtitle, h6.section-subtitle { - margin-top: 0.4em; } +div.search_results { + background-color: antiquewhite; + margin: 3em; + padding: 1em; + border: 1px solid #4d4d4d; +} -h1.title { - text-align: center; } +div#global-links ul { + margin-left: 0; + list-style-type: none; +} -h2.subtitle { - text-align: center; } +div#global-links > simple-boot { + margin-left: 3em; +} hr.docutils { width: 75%; } @@ -905,30 +584,6 @@ img.align-center, .figure.align-center, object.align-center { div.align-right { text-align: inherit; } -/* div.align-center * { */ -/* text-align: left } */ - -ul.simple > li { - margin-bottom: 0.5em } - -ol.simple, ul.simple { - margin-bottom: 1em; } - -ol.arabic { - list-style: decimal; } - -ol.loweralpha { - list-style: lower-alpha; } - -ol.upperalpha { - list-style: upper-alpha; } - -ol.lowerroman { - list-style: lower-roman; } - -ol.upperroman { - list-style: upper-roman; } - p.attribution { text-align: right; margin-left: 50%; } @@ -949,15 +604,6 @@ p.rubric { color: maroon; text-align: center; } -p.sidebar-title { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-weight: bold; - font-size: larger; } - -p.sidebar-subtitle { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-weight: bold; } - p.topic-title { font-weight: bold; } @@ -997,22 +643,14 @@ pre.code .inserted, code .inserted { background-color: #A3D289; } span.classifier { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-style: oblique; } span.classifier-delimiter { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: bold; } -span.interpreted { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } - span.option { white-space: nowrap; } -span.pre { - white-space: pre; } - span.problematic { color: #b30000; } @@ -1020,44 +658,6 @@ span.section-subtitle { /* font-size relative to parent (h1..h6 element) */ font-size: 80%; } -table.citation { - border-left: solid 1px #666666; - margin-left: 1px; } - -table.docinfo { - margin: 0em; - margin-top: 2em; - margin-bottom: 2em; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; - color: #444444; } - -table.docutils { - margin-top: 0.5em; - margin-bottom: 0.5em; } - -table.footnote { - border-left: solid 1px #2d2d2d; - margin-left: 1px; } - -table.docutils td, table.docutils th, -table.docinfo td, table.docinfo th { - padding-left: 0.5em; - padding-right: 0.5em; - vertical-align: top; } - -table.docutils th.field-name, table.docinfo th.docinfo-name { - font-weight: 700; - text-align: left; - white-space: nowrap; - padding-left: 0; } - -h1 tt.docutils, h2 tt.docutils, h3 tt.docutils, -h4 tt.docutils, h5 tt.docutils, h6 tt.docutils { - font-size: 100%; } - -ul.auto-toc { - list-style-type: none; } - span.DecNumber { color: #252dbe; } @@ -1074,7 +674,7 @@ span.FloatNumber { color: #252dbe; } span.Identifier { - color: #3b3b3b; } + color: #222; } span.Keyword { font-weight: 600; @@ -1139,38 +739,23 @@ dt pre > span.Identifier, dt pre > span.Operator { color: #155da4; font-weight: 700; } -dt pre > span.Identifier ~ span.Identifier, dt pre > span.Operator ~ span.Identifier { - color: inherit; - font-weight: inherit; } - -dt pre > span.Operator ~ span.Identifier { +dt pre > span.Keyword ~ span.Identifier, dt pre > span.Identifier ~ span.Identifier, +dt pre > span.Operator ~ span.Identifier, dt pre > span.Other ~ span.Identifier { color: inherit; font-weight: inherit; } /* Nim sprite for the footer (taken from main page favicon) */ .nim-sprite { display: inline-block; - height: 12px; - width: 12px; + height: 16px; + width: 16px; background-position: 0 0; - background-size: 12px 12px; + background-size: 16px 16px; -webkit-filter: opacity(50%); background-repeat: no-repeat; background-image: url("data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="); margin-bottom: -5px; } -div.search_results { - background-color: antiquewhite; - margin: 3em; - padding: 1em; - border: 1px solid #4d4d4d; -} - -div#global-links ul { - margin-left: 0; - list-style-type: none; -} - span.pragmadots { /* Position: relative frees us up to make the dots look really nice without fucking up the layout and @@ -1178,18 +763,14 @@ span.pragmadots { position: relative; /* 1px down looks slightly nicer */ top: 1px; - padding: 2px; - background-color: #D3D3D3; + background-color: #e8e8e8; border-radius: 4px; margin: 0 2px; cursor: pointer; - - /* For some reason on Chrome, making the font size - smaller than 1em is causing the parent container to - bulge slightly. So, we're stuck with inheriting 1em, - which is sad, because 0.8em looks better... */ + font-size: 0.8em; } + span.pragmadots:hover { background-color: #DBDBDB; } @@ -1197,6 +778,10 @@ span.pragmawrap { display: none; } +span.attachedType { + display: none; + visibility: hidden; +} @@ -1237,43 +822,13 @@ function main() { - - +
    +

    -
    -

    Procs

    -
    - -
    proc relativePath(file, base: string): string {...}{.raises: [], tags: [].}
    -
    -naive version of os.relativePath ; remove after nim >= 0.19.9 -

    Examples:

    -
    import
    -  ospaths, unittest
    -
    -check:
    -  "/foo/bar/baz/log.txt".unixToNativePath.relativePath(
    -      "/foo/bar".unixToNativePath) == "baz/log.txt".unixToNativePath
    -  "foo/bar/baz/log.txt".unixToNativePath.relativePath("foo/bar".unixToNativePath) ==
    -      "baz/log.txt".unixToNativePath
    - -
    - -
    - +
    @@ -1281,7 +836,7 @@ naive version of os.relativePath ; remove after nim >= 0.19.9 diff --git a/compat.idx b/compat.idx old mode 100755 new mode 100644 diff --git a/dochack.js b/dochack.js old mode 100755 new mode 100644 index 2405199..cfd9e26 --- a/dochack.js +++ b/dochack.js @@ -1,4 +1,4 @@ -/* Generated by the Nim Compiler v0.19.9 */ +/* Generated by the Nim Compiler v0.20.99 */ /* (c) 2019 Andreas Rumpf */ var framePtr = null; @@ -12,247 +12,247 @@ if (typeof Uint16Array === 'undefined') Uint16Array = Array; if (typeof Uint32Array === 'undefined') Uint32Array = Array; if (typeof Float32Array === 'undefined') Float32Array = Array; if (typeof Float64Array === 'undefined') Float64Array = Array; -var NTI42032 = {size: 0,kind: 1,base: null,node: null,finalizer: null}; -var NTI195074 = {size: 0, kind: 18, base: null, node: null, finalizer: null}; -var NTI45862 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI197577 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; -var NTI81448 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI81444 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI81440 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI81436 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI81432 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI81428 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI81424 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI81420 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI81416 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI81412 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI81408 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI81404 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI81400 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI81396 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI81392 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI81388 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI81384 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI81380 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI81376 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI81372 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI81205 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI81283 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI81281 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; -var NTI81227 = {size: 0, kind: 14, base: null, node: null, finalizer: null}; -var NTI81565 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; -var NTI81563 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; -var NTI81561 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; -var NTI81231 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI81229 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; -var NTI83305 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; -var NTI45850 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI45858 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI42006 = {size: 0,kind: 31,base: null,node: null,finalizer: null}; -var NTI60156 = {size: 0, kind: 18, base: null, node: null, finalizer: null}; -var NTI45808 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI45914 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; -var NTI42016 = {size: 0,kind: 40,base: null,node: null,finalizer: null}; -var NTI42040 = {size: 0,kind: 28,base: null,node: null,finalizer: null}; -var NTI42042 = {size: 0,kind: 29,base: null,node: null,finalizer: null}; -var NTI45908 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; -var NTI45826 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI45828 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI45842 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI45846 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NNI45846 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; -NTI45846.node = NNI45846; -var NNI45842 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; -NTI45842.node = NNI45842; -var NNI45828 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; -NTI45828.node = NNI45828; -NTI45908.base = NTI45826; -NTI45914.base = NTI45826; -var NNI45826 = {kind: 2, len: 6, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "parent", len: 0, typ: NTI45908, name: "parent", sons: null}, -{kind: 1, offset: "name", len: 0, typ: NTI42042, name: "name", sons: null}, -{kind: 1, offset: "message", len: 0, typ: NTI42040, name: "msg", sons: null}, -{kind: 1, offset: "trace", len: 0, typ: NTI42040, name: "trace", sons: null}, -{kind: 1, offset: "raiseId", len: 0, typ: NTI42016, name: "raiseId", sons: null}, -{kind: 1, offset: "up", len: 0, typ: NTI45914, name: "up", sons: null}]}; -NTI45826.node = NNI45826; -var NNI45808 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; -NTI45808.node = NNI45808; -NTI45826.base = NTI45808; -NTI45828.base = NTI45826; -NTI45842.base = NTI45828; -NTI45846.base = NTI45842; -var NNI60156 = {kind: 2, len: 2, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "Field0", len: 0, typ: NTI42042, name: "Field0", sons: null}, -{kind: 1, offset: "Field1", len: 0, typ: NTI42006, name: "Field1", sons: null}]}; -NTI60156.node = NNI60156; -var NNI45858 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; -NTI45858.node = NNI45858; -NTI45858.base = NTI45828; -var NNI45850 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; -NTI45850.node = NNI45850; -NTI45850.base = NTI45828; -NTI81561.base = NTI81229; -NTI81563.base = NTI81229; -NTI81565.base = NTI81229; -var NNI81227 = {kind: 2, offset: 0, typ: null, name: null, len: 12, sons: {"1": {kind: 1, offset: 1, typ: NTI81227, name: "ElementNode", len: 0, sons: null}, -"2": {kind: 1, offset: 2, typ: NTI81227, name: "AttributeNode", len: 0, sons: null}, -"3": {kind: 1, offset: 3, typ: NTI81227, name: "TextNode", len: 0, sons: null}, -"4": {kind: 1, offset: 4, typ: NTI81227, name: "CDATANode", len: 0, sons: null}, -"5": {kind: 1, offset: 5, typ: NTI81227, name: "EntityRefNode", len: 0, sons: null}, -"6": {kind: 1, offset: 6, typ: NTI81227, name: "EntityNode", len: 0, sons: null}, -"7": {kind: 1, offset: 7, typ: NTI81227, name: "ProcessingInstructionNode", len: 0, sons: null}, -"8": {kind: 1, offset: 8, typ: NTI81227, name: "CommentNode", len: 0, sons: null}, -"9": {kind: 1, offset: 9, typ: NTI81227, name: "DocumentNode", len: 0, sons: null}, -"10": {kind: 1, offset: 10, typ: NTI81227, name: "DocumentTypeNode", len: 0, sons: null}, -"11": {kind: 1, offset: 11, typ: NTI81227, name: "DocumentFragmentNode", len: 0, sons: null}, -"12": {kind: 1, offset: 12, typ: NTI81227, name: "NotationNode", len: 0, sons: null}}}; -NTI81227.node = NNI81227; -var NNI81283 = {kind: 2, len: 91, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "background", len: 0, typ: NTI42042, name: "background", sons: null}, -{kind: 1, offset: "backgroundAttachment", len: 0, typ: NTI42042, name: "backgroundAttachment", sons: null}, -{kind: 1, offset: "backgroundColor", len: 0, typ: NTI42042, name: "backgroundColor", sons: null}, -{kind: 1, offset: "backgroundImage", len: 0, typ: NTI42042, name: "backgroundImage", sons: null}, -{kind: 1, offset: "backgroundPosition", len: 0, typ: NTI42042, name: "backgroundPosition", sons: null}, -{kind: 1, offset: "backgroundRepeat", len: 0, typ: NTI42042, name: "backgroundRepeat", sons: null}, -{kind: 1, offset: "border", len: 0, typ: NTI42042, name: "border", sons: null}, -{kind: 1, offset: "borderBottom", len: 0, typ: NTI42042, name: "borderBottom", sons: null}, -{kind: 1, offset: "borderBottomColor", len: 0, typ: NTI42042, name: "borderBottomColor", sons: null}, -{kind: 1, offset: "borderBottomStyle", len: 0, typ: NTI42042, name: "borderBottomStyle", sons: null}, -{kind: 1, offset: "borderBottomWidth", len: 0, typ: NTI42042, name: "borderBottomWidth", sons: null}, -{kind: 1, offset: "borderColor", len: 0, typ: NTI42042, name: "borderColor", sons: null}, -{kind: 1, offset: "borderLeft", len: 0, typ: NTI42042, name: "borderLeft", sons: null}, -{kind: 1, offset: "borderLeftColor", len: 0, typ: NTI42042, name: "borderLeftColor", sons: null}, -{kind: 1, offset: "borderLeftStyle", len: 0, typ: NTI42042, name: "borderLeftStyle", sons: null}, -{kind: 1, offset: "borderLeftWidth", len: 0, typ: NTI42042, name: "borderLeftWidth", sons: null}, -{kind: 1, offset: "borderRight", len: 0, typ: NTI42042, name: "borderRight", sons: null}, -{kind: 1, offset: "borderRightColor", len: 0, typ: NTI42042, name: "borderRightColor", sons: null}, -{kind: 1, offset: "borderRightStyle", len: 0, typ: NTI42042, name: "borderRightStyle", sons: null}, -{kind: 1, offset: "borderRightWidth", len: 0, typ: NTI42042, name: "borderRightWidth", sons: null}, -{kind: 1, offset: "borderStyle", len: 0, typ: NTI42042, name: "borderStyle", sons: null}, -{kind: 1, offset: "borderTop", len: 0, typ: NTI42042, name: "borderTop", sons: null}, -{kind: 1, offset: "borderTopColor", len: 0, typ: NTI42042, name: "borderTopColor", sons: null}, -{kind: 1, offset: "borderTopStyle", len: 0, typ: NTI42042, name: "borderTopStyle", sons: null}, -{kind: 1, offset: "borderTopWidth", len: 0, typ: NTI42042, name: "borderTopWidth", sons: null}, -{kind: 1, offset: "borderWidth", len: 0, typ: NTI42042, name: "borderWidth", sons: null}, -{kind: 1, offset: "bottom", len: 0, typ: NTI42042, name: "bottom", sons: null}, -{kind: 1, offset: "captionSide", len: 0, typ: NTI42042, name: "captionSide", sons: null}, -{kind: 1, offset: "clear", len: 0, typ: NTI42042, name: "clear", sons: null}, -{kind: 1, offset: "clip", len: 0, typ: NTI42042, name: "clip", sons: null}, -{kind: 1, offset: "color", len: 0, typ: NTI42042, name: "color", sons: null}, -{kind: 1, offset: "cursor", len: 0, typ: NTI42042, name: "cursor", sons: null}, -{kind: 1, offset: "direction", len: 0, typ: NTI42042, name: "direction", sons: null}, -{kind: 1, offset: "display", len: 0, typ: NTI42042, name: "display", sons: null}, -{kind: 1, offset: "emptyCells", len: 0, typ: NTI42042, name: "emptyCells", sons: null}, -{kind: 1, offset: "cssFloat", len: 0, typ: NTI42042, name: "cssFloat", sons: null}, -{kind: 1, offset: "font", len: 0, typ: NTI42042, name: "font", sons: null}, -{kind: 1, offset: "fontFamily", len: 0, typ: NTI42042, name: "fontFamily", sons: null}, -{kind: 1, offset: "fontSize", len: 0, typ: NTI42042, name: "fontSize", sons: null}, -{kind: 1, offset: "fontStretch", len: 0, typ: NTI42042, name: "fontStretch", sons: null}, -{kind: 1, offset: "fontStyle", len: 0, typ: NTI42042, name: "fontStyle", sons: null}, -{kind: 1, offset: "fontVariant", len: 0, typ: NTI42042, name: "fontVariant", sons: null}, -{kind: 1, offset: "fontWeight", len: 0, typ: NTI42042, name: "fontWeight", sons: null}, -{kind: 1, offset: "height", len: 0, typ: NTI42042, name: "height", sons: null}, -{kind: 1, offset: "left", len: 0, typ: NTI42042, name: "left", sons: null}, -{kind: 1, offset: "letterSpacing", len: 0, typ: NTI42042, name: "letterSpacing", sons: null}, -{kind: 1, offset: "lineHeight", len: 0, typ: NTI42042, name: "lineHeight", sons: null}, -{kind: 1, offset: "listStyle", len: 0, typ: NTI42042, name: "listStyle", sons: null}, -{kind: 1, offset: "listStyleImage", len: 0, typ: NTI42042, name: "listStyleImage", sons: null}, -{kind: 1, offset: "listStylePosition", len: 0, typ: NTI42042, name: "listStylePosition", sons: null}, -{kind: 1, offset: "listStyleType", len: 0, typ: NTI42042, name: "listStyleType", sons: null}, -{kind: 1, offset: "margin", len: 0, typ: NTI42042, name: "margin", sons: null}, -{kind: 1, offset: "marginBottom", len: 0, typ: NTI42042, name: "marginBottom", sons: null}, -{kind: 1, offset: "marginLeft", len: 0, typ: NTI42042, name: "marginLeft", sons: null}, -{kind: 1, offset: "marginRight", len: 0, typ: NTI42042, name: "marginRight", sons: null}, -{kind: 1, offset: "marginTop", len: 0, typ: NTI42042, name: "marginTop", sons: null}, -{kind: 1, offset: "maxHeight", len: 0, typ: NTI42042, name: "maxHeight", sons: null}, -{kind: 1, offset: "maxWidth", len: 0, typ: NTI42042, name: "maxWidth", sons: null}, -{kind: 1, offset: "minHeight", len: 0, typ: NTI42042, name: "minHeight", sons: null}, -{kind: 1, offset: "minWidth", len: 0, typ: NTI42042, name: "minWidth", sons: null}, -{kind: 1, offset: "overflow", len: 0, typ: NTI42042, name: "overflow", sons: null}, -{kind: 1, offset: "padding", len: 0, typ: NTI42042, name: "padding", sons: null}, -{kind: 1, offset: "paddingBottom", len: 0, typ: NTI42042, name: "paddingBottom", sons: null}, -{kind: 1, offset: "paddingLeft", len: 0, typ: NTI42042, name: "paddingLeft", sons: null}, -{kind: 1, offset: "paddingRight", len: 0, typ: NTI42042, name: "paddingRight", sons: null}, -{kind: 1, offset: "paddingTop", len: 0, typ: NTI42042, name: "paddingTop", sons: null}, -{kind: 1, offset: "pageBreakAfter", len: 0, typ: NTI42042, name: "pageBreakAfter", sons: null}, -{kind: 1, offset: "pageBreakBefore", len: 0, typ: NTI42042, name: "pageBreakBefore", sons: null}, -{kind: 1, offset: "pointerEvents", len: 0, typ: NTI42042, name: "pointerEvents", sons: null}, -{kind: 1, offset: "position", len: 0, typ: NTI42042, name: "position", sons: null}, -{kind: 1, offset: "right", len: 0, typ: NTI42042, name: "right", sons: null}, -{kind: 1, offset: "scrollbar3dLightColor", len: 0, typ: NTI42042, name: "scrollbar3dLightColor", sons: null}, -{kind: 1, offset: "scrollbarArrowColor", len: 0, typ: NTI42042, name: "scrollbarArrowColor", sons: null}, -{kind: 1, offset: "scrollbarBaseColor", len: 0, typ: NTI42042, name: "scrollbarBaseColor", sons: null}, -{kind: 1, offset: "scrollbarDarkshadowColor", len: 0, typ: NTI42042, name: "scrollbarDarkshadowColor", sons: null}, -{kind: 1, offset: "scrollbarFaceColor", len: 0, typ: NTI42042, name: "scrollbarFaceColor", sons: null}, -{kind: 1, offset: "scrollbarHighlightColor", len: 0, typ: NTI42042, name: "scrollbarHighlightColor", sons: null}, -{kind: 1, offset: "scrollbarShadowColor", len: 0, typ: NTI42042, name: "scrollbarShadowColor", sons: null}, -{kind: 1, offset: "scrollbarTrackColor", len: 0, typ: NTI42042, name: "scrollbarTrackColor", sons: null}, -{kind: 1, offset: "tableLayout", len: 0, typ: NTI42042, name: "tableLayout", sons: null}, -{kind: 1, offset: "textAlign", len: 0, typ: NTI42042, name: "textAlign", sons: null}, -{kind: 1, offset: "textDecoration", len: 0, typ: NTI42042, name: "textDecoration", sons: null}, -{kind: 1, offset: "textIndent", len: 0, typ: NTI42042, name: "textIndent", sons: null}, -{kind: 1, offset: "textTransform", len: 0, typ: NTI42042, name: "textTransform", sons: null}, -{kind: 1, offset: "transform", len: 0, typ: NTI42042, name: "transform", sons: null}, -{kind: 1, offset: "top", len: 0, typ: NTI42042, name: "top", sons: null}, -{kind: 1, offset: "verticalAlign", len: 0, typ: NTI42042, name: "verticalAlign", sons: null}, -{kind: 1, offset: "visibility", len: 0, typ: NTI42042, name: "visibility", sons: null}, -{kind: 1, offset: "width", len: 0, typ: NTI42042, name: "width", sons: null}, -{kind: 1, offset: "wordSpacing", len: 0, typ: NTI42042, name: "wordSpacing", sons: null}, -{kind: 1, offset: "zIndex", len: 0, typ: NTI42006, name: "zIndex", sons: null}]}; -NTI81283.node = NNI81283; -NTI81283.base = NTI45808; -NTI81281.base = NTI81283; -var NNI81231 = {kind: 2, len: 14, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "attributes", len: 0, typ: NTI81561, name: "attributes", sons: null}, -{kind: 1, offset: "childNodes", len: 0, typ: NTI81563, name: "childNodes", sons: null}, -{kind: 1, offset: "children", len: 0, typ: NTI81565, name: "children", sons: null}, -{kind: 1, offset: "data", len: 0, typ: NTI42042, name: "data", sons: null}, -{kind: 1, offset: "firstChild", len: 0, typ: NTI81229, name: "firstChild", sons: null}, -{kind: 1, offset: "lastChild", len: 0, typ: NTI81229, name: "lastChild", sons: null}, -{kind: 1, offset: "nextSibling", len: 0, typ: NTI81229, name: "nextSibling", sons: null}, -{kind: 1, offset: "nodeName", len: 0, typ: NTI42042, name: "nodeName", sons: null}, -{kind: 1, offset: "nodeType", len: 0, typ: NTI81227, name: "nodeType", sons: null}, -{kind: 1, offset: "nodeValue", len: 0, typ: NTI42042, name: "nodeValue", sons: null}, -{kind: 1, offset: "parentNode", len: 0, typ: NTI81229, name: "parentNode", sons: null}, -{kind: 1, offset: "previousSibling", len: 0, typ: NTI81229, name: "previousSibling", sons: null}, -{kind: 1, offset: "innerHTML", len: 0, typ: NTI42042, name: "innerHTML", sons: null}, -{kind: 1, offset: "style", len: 0, typ: NTI81281, name: "style", sons: null}]}; -NTI81231.node = NNI81231; -var NNI81205 = {kind: 2, len: 20, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "onabort", len: 0, typ: NTI81372, name: "onabort", sons: null}, -{kind: 1, offset: "onblur", len: 0, typ: NTI81376, name: "onblur", sons: null}, -{kind: 1, offset: "onchange", len: 0, typ: NTI81380, name: "onchange", sons: null}, -{kind: 1, offset: "onclick", len: 0, typ: NTI81384, name: "onclick", sons: null}, -{kind: 1, offset: "ondblclick", len: 0, typ: NTI81388, name: "ondblclick", sons: null}, -{kind: 1, offset: "onerror", len: 0, typ: NTI81392, name: "onerror", sons: null}, -{kind: 1, offset: "onfocus", len: 0, typ: NTI81396, name: "onfocus", sons: null}, -{kind: 1, offset: "onkeydown", len: 0, typ: NTI81400, name: "onkeydown", sons: null}, -{kind: 1, offset: "onkeypress", len: 0, typ: NTI81404, name: "onkeypress", sons: null}, -{kind: 1, offset: "onkeyup", len: 0, typ: NTI81408, name: "onkeyup", sons: null}, -{kind: 1, offset: "onload", len: 0, typ: NTI81412, name: "onload", sons: null}, -{kind: 1, offset: "onmousedown", len: 0, typ: NTI81416, name: "onmousedown", sons: null}, -{kind: 1, offset: "onmousemove", len: 0, typ: NTI81420, name: "onmousemove", sons: null}, -{kind: 1, offset: "onmouseout", len: 0, typ: NTI81424, name: "onmouseout", sons: null}, -{kind: 1, offset: "onmouseover", len: 0, typ: NTI81428, name: "onmouseover", sons: null}, -{kind: 1, offset: "onmouseup", len: 0, typ: NTI81432, name: "onmouseup", sons: null}, -{kind: 1, offset: "onreset", len: 0, typ: NTI81436, name: "onreset", sons: null}, -{kind: 1, offset: "onselect", len: 0, typ: NTI81440, name: "onselect", sons: null}, -{kind: 1, offset: "onsubmit", len: 0, typ: NTI81444, name: "onsubmit", sons: null}, -{kind: 1, offset: "onunload", len: 0, typ: NTI81448, name: "onunload", sons: null}]}; -NTI81205.node = NNI81205; -NTI81205.base = NTI45808; -NTI81231.base = NTI81205; -NTI81229.base = NTI81231; -NTI83305.base = NTI81229; -NTI197577.base = NTI42042; -var NNI45862 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; -NTI45862.node = NNI45862; -NTI45862.base = NTI45828; -var NNI195074 = {kind: 2, len: 2, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "Field0", len: 0, typ: NTI42006, name: "Field0", sons: null}, -{kind: 1, offset: "Field1", len: 0, typ: NTI42032, name: "Field1", sons: null}]}; -NTI195074.node = NNI195074; +var NTI44032 = {size: 0,kind: 1,base: null,node: null,finalizer: null}; +var NTI205074 = {size: 0, kind: 18, base: null, node: null, finalizer: null}; +var NTI47862 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI207579 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; +var NTI85448 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI85444 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI85440 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI85436 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI85432 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI85428 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI85424 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI85420 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI85416 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI85412 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI85408 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI85404 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI85400 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI85396 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI85392 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI85388 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI85384 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI85380 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI85376 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI85372 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI85205 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI85283 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI85281 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; +var NTI85227 = {size: 0, kind: 14, base: null, node: null, finalizer: null}; +var NTI85565 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; +var NTI85563 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; +var NTI85561 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; +var NTI85231 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI85229 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; +var NTI87305 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; +var NTI47850 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI47858 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI44006 = {size: 0,kind: 31,base: null,node: null,finalizer: null}; +var NTI64156 = {size: 0, kind: 18, base: null, node: null, finalizer: null}; +var NTI47808 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI47914 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; +var NTI44016 = {size: 0,kind: 40,base: null,node: null,finalizer: null}; +var NTI44040 = {size: 0,kind: 28,base: null,node: null,finalizer: null}; +var NTI44042 = {size: 0,kind: 29,base: null,node: null,finalizer: null}; +var NTI47908 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; +var NTI47826 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI47828 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI47842 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI47846 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NNI47846 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI47846.node = NNI47846; +var NNI47842 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI47842.node = NNI47842; +var NNI47828 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI47828.node = NNI47828; +NTI47908.base = NTI47826; +NTI47914.base = NTI47826; +var NNI47826 = {kind: 2, len: 6, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "parent", len: 0, typ: NTI47908, name: "parent", sons: null}, +{kind: 1, offset: "name", len: 0, typ: NTI44042, name: "name", sons: null}, +{kind: 1, offset: "message", len: 0, typ: NTI44040, name: "msg", sons: null}, +{kind: 1, offset: "trace", len: 0, typ: NTI44040, name: "trace", sons: null}, +{kind: 1, offset: "raiseId", len: 0, typ: NTI44016, name: "raiseId", sons: null}, +{kind: 1, offset: "up", len: 0, typ: NTI47914, name: "up", sons: null}]}; +NTI47826.node = NNI47826; +var NNI47808 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI47808.node = NNI47808; +NTI47826.base = NTI47808; +NTI47828.base = NTI47826; +NTI47842.base = NTI47828; +NTI47846.base = NTI47842; +var NNI64156 = {kind: 2, len: 2, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "Field0", len: 0, typ: NTI44042, name: "Field0", sons: null}, +{kind: 1, offset: "Field1", len: 0, typ: NTI44006, name: "Field1", sons: null}]}; +NTI64156.node = NNI64156; +var NNI47858 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI47858.node = NNI47858; +NTI47858.base = NTI47828; +var NNI47850 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI47850.node = NNI47850; +NTI47850.base = NTI47828; +NTI85561.base = NTI85229; +NTI85563.base = NTI85229; +NTI85565.base = NTI85229; +var NNI85227 = {kind: 2, offset: 0, typ: null, name: null, len: 12, sons: {"1": {kind: 1, offset: 1, typ: NTI85227, name: "ElementNode", len: 0, sons: null}, +"2": {kind: 1, offset: 2, typ: NTI85227, name: "AttributeNode", len: 0, sons: null}, +"3": {kind: 1, offset: 3, typ: NTI85227, name: "TextNode", len: 0, sons: null}, +"4": {kind: 1, offset: 4, typ: NTI85227, name: "CDATANode", len: 0, sons: null}, +"5": {kind: 1, offset: 5, typ: NTI85227, name: "EntityRefNode", len: 0, sons: null}, +"6": {kind: 1, offset: 6, typ: NTI85227, name: "EntityNode", len: 0, sons: null}, +"7": {kind: 1, offset: 7, typ: NTI85227, name: "ProcessingInstructionNode", len: 0, sons: null}, +"8": {kind: 1, offset: 8, typ: NTI85227, name: "CommentNode", len: 0, sons: null}, +"9": {kind: 1, offset: 9, typ: NTI85227, name: "DocumentNode", len: 0, sons: null}, +"10": {kind: 1, offset: 10, typ: NTI85227, name: "DocumentTypeNode", len: 0, sons: null}, +"11": {kind: 1, offset: 11, typ: NTI85227, name: "DocumentFragmentNode", len: 0, sons: null}, +"12": {kind: 1, offset: 12, typ: NTI85227, name: "NotationNode", len: 0, sons: null}}}; +NTI85227.node = NNI85227; +var NNI85283 = {kind: 2, len: 91, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "background", len: 0, typ: NTI44042, name: "background", sons: null}, +{kind: 1, offset: "backgroundAttachment", len: 0, typ: NTI44042, name: "backgroundAttachment", sons: null}, +{kind: 1, offset: "backgroundColor", len: 0, typ: NTI44042, name: "backgroundColor", sons: null}, +{kind: 1, offset: "backgroundImage", len: 0, typ: NTI44042, name: "backgroundImage", sons: null}, +{kind: 1, offset: "backgroundPosition", len: 0, typ: NTI44042, name: "backgroundPosition", sons: null}, +{kind: 1, offset: "backgroundRepeat", len: 0, typ: NTI44042, name: "backgroundRepeat", sons: null}, +{kind: 1, offset: "border", len: 0, typ: NTI44042, name: "border", sons: null}, +{kind: 1, offset: "borderBottom", len: 0, typ: NTI44042, name: "borderBottom", sons: null}, +{kind: 1, offset: "borderBottomColor", len: 0, typ: NTI44042, name: "borderBottomColor", sons: null}, +{kind: 1, offset: "borderBottomStyle", len: 0, typ: NTI44042, name: "borderBottomStyle", sons: null}, +{kind: 1, offset: "borderBottomWidth", len: 0, typ: NTI44042, name: "borderBottomWidth", sons: null}, +{kind: 1, offset: "borderColor", len: 0, typ: NTI44042, name: "borderColor", sons: null}, +{kind: 1, offset: "borderLeft", len: 0, typ: NTI44042, name: "borderLeft", sons: null}, +{kind: 1, offset: "borderLeftColor", len: 0, typ: NTI44042, name: "borderLeftColor", sons: null}, +{kind: 1, offset: "borderLeftStyle", len: 0, typ: NTI44042, name: "borderLeftStyle", sons: null}, +{kind: 1, offset: "borderLeftWidth", len: 0, typ: NTI44042, name: "borderLeftWidth", sons: null}, +{kind: 1, offset: "borderRight", len: 0, typ: NTI44042, name: "borderRight", sons: null}, +{kind: 1, offset: "borderRightColor", len: 0, typ: NTI44042, name: "borderRightColor", sons: null}, +{kind: 1, offset: "borderRightStyle", len: 0, typ: NTI44042, name: "borderRightStyle", sons: null}, +{kind: 1, offset: "borderRightWidth", len: 0, typ: NTI44042, name: "borderRightWidth", sons: null}, +{kind: 1, offset: "borderStyle", len: 0, typ: NTI44042, name: "borderStyle", sons: null}, +{kind: 1, offset: "borderTop", len: 0, typ: NTI44042, name: "borderTop", sons: null}, +{kind: 1, offset: "borderTopColor", len: 0, typ: NTI44042, name: "borderTopColor", sons: null}, +{kind: 1, offset: "borderTopStyle", len: 0, typ: NTI44042, name: "borderTopStyle", sons: null}, +{kind: 1, offset: "borderTopWidth", len: 0, typ: NTI44042, name: "borderTopWidth", sons: null}, +{kind: 1, offset: "borderWidth", len: 0, typ: NTI44042, name: "borderWidth", sons: null}, +{kind: 1, offset: "bottom", len: 0, typ: NTI44042, name: "bottom", sons: null}, +{kind: 1, offset: "captionSide", len: 0, typ: NTI44042, name: "captionSide", sons: null}, +{kind: 1, offset: "clear", len: 0, typ: NTI44042, name: "clear", sons: null}, +{kind: 1, offset: "clip", len: 0, typ: NTI44042, name: "clip", sons: null}, +{kind: 1, offset: "color", len: 0, typ: NTI44042, name: "color", sons: null}, +{kind: 1, offset: "cursor", len: 0, typ: NTI44042, name: "cursor", sons: null}, +{kind: 1, offset: "direction", len: 0, typ: NTI44042, name: "direction", sons: null}, +{kind: 1, offset: "display", len: 0, typ: NTI44042, name: "display", sons: null}, +{kind: 1, offset: "emptyCells", len: 0, typ: NTI44042, name: "emptyCells", sons: null}, +{kind: 1, offset: "cssFloat", len: 0, typ: NTI44042, name: "cssFloat", sons: null}, +{kind: 1, offset: "font", len: 0, typ: NTI44042, name: "font", sons: null}, +{kind: 1, offset: "fontFamily", len: 0, typ: NTI44042, name: "fontFamily", sons: null}, +{kind: 1, offset: "fontSize", len: 0, typ: NTI44042, name: "fontSize", sons: null}, +{kind: 1, offset: "fontStretch", len: 0, typ: NTI44042, name: "fontStretch", sons: null}, +{kind: 1, offset: "fontStyle", len: 0, typ: NTI44042, name: "fontStyle", sons: null}, +{kind: 1, offset: "fontVariant", len: 0, typ: NTI44042, name: "fontVariant", sons: null}, +{kind: 1, offset: "fontWeight", len: 0, typ: NTI44042, name: "fontWeight", sons: null}, +{kind: 1, offset: "height", len: 0, typ: NTI44042, name: "height", sons: null}, +{kind: 1, offset: "left", len: 0, typ: NTI44042, name: "left", sons: null}, +{kind: 1, offset: "letterSpacing", len: 0, typ: NTI44042, name: "letterSpacing", sons: null}, +{kind: 1, offset: "lineHeight", len: 0, typ: NTI44042, name: "lineHeight", sons: null}, +{kind: 1, offset: "listStyle", len: 0, typ: NTI44042, name: "listStyle", sons: null}, +{kind: 1, offset: "listStyleImage", len: 0, typ: NTI44042, name: "listStyleImage", sons: null}, +{kind: 1, offset: "listStylePosition", len: 0, typ: NTI44042, name: "listStylePosition", sons: null}, +{kind: 1, offset: "listStyleType", len: 0, typ: NTI44042, name: "listStyleType", sons: null}, +{kind: 1, offset: "margin", len: 0, typ: NTI44042, name: "margin", sons: null}, +{kind: 1, offset: "marginBottom", len: 0, typ: NTI44042, name: "marginBottom", sons: null}, +{kind: 1, offset: "marginLeft", len: 0, typ: NTI44042, name: "marginLeft", sons: null}, +{kind: 1, offset: "marginRight", len: 0, typ: NTI44042, name: "marginRight", sons: null}, +{kind: 1, offset: "marginTop", len: 0, typ: NTI44042, name: "marginTop", sons: null}, +{kind: 1, offset: "maxHeight", len: 0, typ: NTI44042, name: "maxHeight", sons: null}, +{kind: 1, offset: "maxWidth", len: 0, typ: NTI44042, name: "maxWidth", sons: null}, +{kind: 1, offset: "minHeight", len: 0, typ: NTI44042, name: "minHeight", sons: null}, +{kind: 1, offset: "minWidth", len: 0, typ: NTI44042, name: "minWidth", sons: null}, +{kind: 1, offset: "overflow", len: 0, typ: NTI44042, name: "overflow", sons: null}, +{kind: 1, offset: "padding", len: 0, typ: NTI44042, name: "padding", sons: null}, +{kind: 1, offset: "paddingBottom", len: 0, typ: NTI44042, name: "paddingBottom", sons: null}, +{kind: 1, offset: "paddingLeft", len: 0, typ: NTI44042, name: "paddingLeft", sons: null}, +{kind: 1, offset: "paddingRight", len: 0, typ: NTI44042, name: "paddingRight", sons: null}, +{kind: 1, offset: "paddingTop", len: 0, typ: NTI44042, name: "paddingTop", sons: null}, +{kind: 1, offset: "pageBreakAfter", len: 0, typ: NTI44042, name: "pageBreakAfter", sons: null}, +{kind: 1, offset: "pageBreakBefore", len: 0, typ: NTI44042, name: "pageBreakBefore", sons: null}, +{kind: 1, offset: "pointerEvents", len: 0, typ: NTI44042, name: "pointerEvents", sons: null}, +{kind: 1, offset: "position", len: 0, typ: NTI44042, name: "position", sons: null}, +{kind: 1, offset: "right", len: 0, typ: NTI44042, name: "right", sons: null}, +{kind: 1, offset: "scrollbar3dLightColor", len: 0, typ: NTI44042, name: "scrollbar3dLightColor", sons: null}, +{kind: 1, offset: "scrollbarArrowColor", len: 0, typ: NTI44042, name: "scrollbarArrowColor", sons: null}, +{kind: 1, offset: "scrollbarBaseColor", len: 0, typ: NTI44042, name: "scrollbarBaseColor", sons: null}, +{kind: 1, offset: "scrollbarDarkshadowColor", len: 0, typ: NTI44042, name: "scrollbarDarkshadowColor", sons: null}, +{kind: 1, offset: "scrollbarFaceColor", len: 0, typ: NTI44042, name: "scrollbarFaceColor", sons: null}, +{kind: 1, offset: "scrollbarHighlightColor", len: 0, typ: NTI44042, name: "scrollbarHighlightColor", sons: null}, +{kind: 1, offset: "scrollbarShadowColor", len: 0, typ: NTI44042, name: "scrollbarShadowColor", sons: null}, +{kind: 1, offset: "scrollbarTrackColor", len: 0, typ: NTI44042, name: "scrollbarTrackColor", sons: null}, +{kind: 1, offset: "tableLayout", len: 0, typ: NTI44042, name: "tableLayout", sons: null}, +{kind: 1, offset: "textAlign", len: 0, typ: NTI44042, name: "textAlign", sons: null}, +{kind: 1, offset: "textDecoration", len: 0, typ: NTI44042, name: "textDecoration", sons: null}, +{kind: 1, offset: "textIndent", len: 0, typ: NTI44042, name: "textIndent", sons: null}, +{kind: 1, offset: "textTransform", len: 0, typ: NTI44042, name: "textTransform", sons: null}, +{kind: 1, offset: "transform", len: 0, typ: NTI44042, name: "transform", sons: null}, +{kind: 1, offset: "top", len: 0, typ: NTI44042, name: "top", sons: null}, +{kind: 1, offset: "verticalAlign", len: 0, typ: NTI44042, name: "verticalAlign", sons: null}, +{kind: 1, offset: "visibility", len: 0, typ: NTI44042, name: "visibility", sons: null}, +{kind: 1, offset: "width", len: 0, typ: NTI44042, name: "width", sons: null}, +{kind: 1, offset: "wordSpacing", len: 0, typ: NTI44042, name: "wordSpacing", sons: null}, +{kind: 1, offset: "zIndex", len: 0, typ: NTI44006, name: "zIndex", sons: null}]}; +NTI85283.node = NNI85283; +NTI85283.base = NTI47808; +NTI85281.base = NTI85283; +var NNI85231 = {kind: 2, len: 14, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "attributes", len: 0, typ: NTI85561, name: "attributes", sons: null}, +{kind: 1, offset: "childNodes", len: 0, typ: NTI85563, name: "childNodes", sons: null}, +{kind: 1, offset: "children", len: 0, typ: NTI85565, name: "children", sons: null}, +{kind: 1, offset: "data", len: 0, typ: NTI44042, name: "data", sons: null}, +{kind: 1, offset: "firstChild", len: 0, typ: NTI85229, name: "firstChild", sons: null}, +{kind: 1, offset: "lastChild", len: 0, typ: NTI85229, name: "lastChild", sons: null}, +{kind: 1, offset: "nextSibling", len: 0, typ: NTI85229, name: "nextSibling", sons: null}, +{kind: 1, offset: "nodeName", len: 0, typ: NTI44042, name: "nodeName", sons: null}, +{kind: 1, offset: "nodeType", len: 0, typ: NTI85227, name: "nodeType", sons: null}, +{kind: 1, offset: "nodeValue", len: 0, typ: NTI44042, name: "nodeValue", sons: null}, +{kind: 1, offset: "parentNode", len: 0, typ: NTI85229, name: "parentNode", sons: null}, +{kind: 1, offset: "previousSibling", len: 0, typ: NTI85229, name: "previousSibling", sons: null}, +{kind: 1, offset: "innerHTML", len: 0, typ: NTI44042, name: "innerHTML", sons: null}, +{kind: 1, offset: "style", len: 0, typ: NTI85281, name: "style", sons: null}]}; +NTI85231.node = NNI85231; +var NNI85205 = {kind: 2, len: 20, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "onabort", len: 0, typ: NTI85372, name: "onabort", sons: null}, +{kind: 1, offset: "onblur", len: 0, typ: NTI85376, name: "onblur", sons: null}, +{kind: 1, offset: "onchange", len: 0, typ: NTI85380, name: "onchange", sons: null}, +{kind: 1, offset: "onclick", len: 0, typ: NTI85384, name: "onclick", sons: null}, +{kind: 1, offset: "ondblclick", len: 0, typ: NTI85388, name: "ondblclick", sons: null}, +{kind: 1, offset: "onerror", len: 0, typ: NTI85392, name: "onerror", sons: null}, +{kind: 1, offset: "onfocus", len: 0, typ: NTI85396, name: "onfocus", sons: null}, +{kind: 1, offset: "onkeydown", len: 0, typ: NTI85400, name: "onkeydown", sons: null}, +{kind: 1, offset: "onkeypress", len: 0, typ: NTI85404, name: "onkeypress", sons: null}, +{kind: 1, offset: "onkeyup", len: 0, typ: NTI85408, name: "onkeyup", sons: null}, +{kind: 1, offset: "onload", len: 0, typ: NTI85412, name: "onload", sons: null}, +{kind: 1, offset: "onmousedown", len: 0, typ: NTI85416, name: "onmousedown", sons: null}, +{kind: 1, offset: "onmousemove", len: 0, typ: NTI85420, name: "onmousemove", sons: null}, +{kind: 1, offset: "onmouseout", len: 0, typ: NTI85424, name: "onmouseout", sons: null}, +{kind: 1, offset: "onmouseover", len: 0, typ: NTI85428, name: "onmouseover", sons: null}, +{kind: 1, offset: "onmouseup", len: 0, typ: NTI85432, name: "onmouseup", sons: null}, +{kind: 1, offset: "onreset", len: 0, typ: NTI85436, name: "onreset", sons: null}, +{kind: 1, offset: "onselect", len: 0, typ: NTI85440, name: "onselect", sons: null}, +{kind: 1, offset: "onsubmit", len: 0, typ: NTI85444, name: "onsubmit", sons: null}, +{kind: 1, offset: "onunload", len: 0, typ: NTI85448, name: "onunload", sons: null}]}; +NTI85205.node = NNI85205; +NTI85205.base = NTI47808; +NTI85231.base = NTI85205; +NTI85229.base = NTI85231; +NTI87305.base = NTI85229; +NTI207579.base = NTI44042; +var NNI47862 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI47862.node = NNI47862; +NTI47862.base = NTI47828; +var NNI205074 = {kind: 2, len: 2, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "Field0", len: 0, typ: NTI44006, name: "Field0", sons: null}, +{kind: 1, offset: "Field1", len: 0, typ: NTI44032, name: "Field1", sons: null}]}; +NTI205074.node = NNI205074; -function makeNimstrLit(c_62058) { - var ln = c_62058.length; +function makeNimstrLit(c_66254) { + var ln = c_66254.length; var result = new Array(ln); for (var i = 0; i < ln; ++i) { - result[i] = c_62058.charCodeAt(i); + result[i] = c_66254.charCodeAt(i); } return result; @@ -279,99 +279,99 @@ function setConstr() { } var ConstSet1 = setConstr(17, 16, 4, 18, 27, 19, 23, 22, 21); -function nimCopy(dest_63027, src_63028, ti_63029) { - var result_63219 = null; +function nimCopy(dest_67427, src_67428, ti_67429) { + var result_67619 = null; - switch (ti_63029.kind) { + switch (ti_67429.kind) { case 21: case 22: case 23: case 5: - if (!(is_fat_pointer_63001(ti_63029))) { - result_63219 = src_63028; + if (!(is_fat_pointer_67401(ti_67429))) { + result_67619 = src_67428; } else { - result_63219 = [src_63028[0], src_63028[1]]; + result_67619 = [src_67428[0], src_67428[1]]; } break; case 19: - if (dest_63027 === null || dest_63027 === undefined) { - dest_63027 = {}; + if (dest_67427 === null || dest_67427 === undefined) { + dest_67427 = {}; } else { - for (var key in dest_63027) { delete dest_63027[key]; } + for (var key in dest_67427) { delete dest_67427[key]; } } - for (var key in src_63028) { dest_63027[key] = src_63028[key]; } - result_63219 = dest_63027; + for (var key in src_67428) { dest_67427[key] = src_67428[key]; } + result_67619 = dest_67427; break; case 18: case 17: - if (!((ti_63029.base == null))) { - result_63219 = nimCopy(dest_63027, src_63028, ti_63029.base); + if (!((ti_67429.base == null))) { + result_67619 = nimCopy(dest_67427, src_67428, ti_67429.base); } else { - if ((ti_63029.kind == 17)) { - result_63219 = (dest_63027 === null || dest_63027 === undefined) ? {m_type: ti_63029} : dest_63027; + if ((ti_67429.kind == 17)) { + result_67619 = (dest_67427 === null || dest_67427 === undefined) ? {m_type: ti_67429} : dest_67427; } else { - result_63219 = (dest_63027 === null || dest_63027 === undefined) ? {} : dest_63027; + result_67619 = (dest_67427 === null || dest_67427 === undefined) ? {} : dest_67427; } } - nimCopyAux(result_63219, src_63028, ti_63029.node); + nimCopyAux(result_67619, src_67428, ti_67429.node); break; case 24: case 4: case 27: case 16: - if (src_63028 === null) { - result_63219 = null; + if (src_67428 === null) { + result_67619 = null; } else { - if (dest_63027 === null || dest_63027 === undefined) { - dest_63027 = new Array(src_63028.length); + if (dest_67427 === null || dest_67427 === undefined) { + dest_67427 = new Array(src_67428.length); } else { - dest_63027.length = src_63028.length; + dest_67427.length = src_67428.length; } - result_63219 = dest_63027; - for (var i = 0; i < src_63028.length; ++i) { - result_63219[i] = nimCopy(result_63219[i], src_63028[i], ti_63029.base); + result_67619 = dest_67427; + for (var i = 0; i < src_67428.length; ++i) { + result_67619[i] = nimCopy(result_67619[i], src_67428[i], ti_67429.base); } } break; case 28: - if (src_63028 !== null) { - result_63219 = src_63028.slice(0); + if (src_67428 !== null) { + result_67619 = src_67428.slice(0); } break; default: - result_63219 = src_63028; + result_67619 = src_67428; break; } - return result_63219; + return result_67619; } -function arrayConstr(len_63286, value_63287, typ_63288) { - var result = new Array(len_63286); - for (var i = 0; i < len_63286; ++i) result[i] = nimCopy(null, value_63287, typ_63288); +function arrayConstr(len_67686, value_67687, typ_67688) { + var result = new Array(len_67686); + for (var i = 0; i < len_67686; ++i) result[i] = nimCopy(null, value_67687, typ_67688); return result; } -function cstrToNimstr(c_62075) { - var ln = c_62075.length; +function cstrToNimstr(c_66271) { + var ln = c_66271.length; var result = new Array(ln); var r = 0; for (var i = 0; i < ln; ++i) { - var ch = c_62075.charCodeAt(i); + var ch = c_66271.charCodeAt(i); if (ch < 128) { result[r] = ch; @@ -386,7 +386,7 @@ function cstrToNimstr(c_62075) { } else { ++i; - ch = 65536 + (((ch & 1023) << 10) | (c_62075.charCodeAt(i) & 1023)); + ch = 65536 + (((ch & 1023) << 10) | (c_66271.charCodeAt(i) & 1023)); result[r] = (ch >> 18) | 240; ++r; result[r] = ((ch >> 12) & 63) | 128; @@ -405,9 +405,9 @@ function cstrToNimstr(c_62075) { } -function toJSStr(s_62092) { - if (s_62092 === null) return ""; - var len = s_62092.length; +function toJSStr(s_66288) { + if (s_66288 === null) return ""; + var len = s_66288.length; var asciiPart = new Array(len); var fcc = String.fromCharCode; var nonAsciiPart = null; @@ -415,15 +415,15 @@ function toJSStr(s_62092) { for (var i = 0; i < len; ++i) { if (nonAsciiPart !== null) { var offset = (i - nonAsciiOffset) * 2; - var code = s_62092[i].toString(16); + var code = s_66288[i].toString(16); if (code.length == 1) { code = "0"+code; } nonAsciiPart[offset] = "%"; nonAsciiPart[offset + 1] = code; } - else if (s_62092[i] < 128) - asciiPart[i] = fcc(s_62092[i]); + else if (s_66288[i] < 128) + asciiPart[i] = fcc(s_66288[i]); else { asciiPart.length = i; nonAsciiOffset = i; @@ -439,20 +439,20 @@ function toJSStr(s_62092) { } -function raiseException(e_60618, ename_60619) { - e_60618.name = ename_60619; +function raiseException(e_64618, ename_64619) { + e_64618.name = ename_64619; if ((excHandler == 0)) { - unhandledException(e_60618); + unhandledException(e_64618); } - e_60618.trace = nimCopy(null, raw_write_stack_trace_60468(), NTI42040); - throw e_60618; + e_64618.trace = nimCopy(null, raw_write_stack_trace_64468(), NTI44040); + throw e_64618; } -function addInt(a_62403, b_62404) { - var result = a_62403 + b_62404; +function addInt(a_66603, b_66604) { + var result = a_66603 + b_66604; if (result > 2147483647 || result < -2147483648) raiseOverflow(); return result; @@ -460,28 +460,28 @@ function addInt(a_62403, b_62404) { } -function chckIndx(i_63305, a_63306, b_63307) { +function chckIndx(i_67705, a_67706, b_67707) { var Tmp1; - var result_63308 = 0; + var result_67708 = 0; BeforeRet: do { - if (!(a_63306 <= i_63305)) Tmp1 = false; else { Tmp1 = (i_63305 <= b_63307); } if (Tmp1) { - result_63308 = i_63305; + if (!(a_67706 <= i_67705)) Tmp1 = false; else { Tmp1 = (i_67705 <= b_67707); } if (Tmp1) { + result_67708 = i_67705; break BeforeRet; } else { - raiseIndexError(i_63305, a_63306, b_63307); + raiseIndexError(i_67705, a_67706, b_67707); } } while (false); - return result_63308; + return result_67708; } -function subInt(a_62421, b_62422) { - var result = a_62421 - b_62422; +function subInt(a_66621, b_66622) { + var result = a_66621 - b_66622; if (result > 2147483647 || result < -2147483648) raiseOverflow(); return result; @@ -490,14 +490,14 @@ function subInt(a_62421, b_62422) { } var ConstSet2 = setConstr([65, 90]); -function chckRange(i_63324, a_63325, b_63326) { +function chckRange(i_67724, a_67725, b_67726) { var Tmp1; - var result_63327 = 0; + var result_67727 = 0; BeforeRet: do { - if (!(a_63325 <= i_63324)) Tmp1 = false; else { Tmp1 = (i_63324 <= b_63326); } if (Tmp1) { - result_63327 = i_63324; + if (!(a_67725 <= i_67724)) Tmp1 = false; else { Tmp1 = (i_67724 <= b_67726); } if (Tmp1) { + result_67727 = i_67724; break BeforeRet; } else { @@ -506,14 +506,14 @@ function chckRange(i_63324, a_63325, b_63326) { } while (false); - return result_63327; + return result_67727; } var ConstSet3 = setConstr(95, 32, 46); var ConstSet4 = setConstr(95, 32, 46); -function mulInt(a_62439, b_62440) { - var result = a_62439 * b_62440; +function mulInt(a_66639, b_66640) { + var result = a_66639 * b_66640; if (result > 2147483647 || result < -2147483648) raiseOverflow(); return result; @@ -525,51 +525,51 @@ var ConstSet6 = setConstr([65, 90], [97, 122]); var ConstSet7 = setConstr([97, 122]); var ConstSet8 = setConstr([65, 90]); -function nimMax(a_62758, b_62759) { +function nimMax(a_67021, b_67022) { var Tmp1; - var result_62760 = 0; + var result_67023 = 0; BeforeRet: do { - if ((b_62759 <= a_62758)) { - Tmp1 = a_62758; + if ((b_67022 <= a_67021)) { + Tmp1 = a_67021; } else { - Tmp1 = b_62759; + Tmp1 = b_67022; } - result_62760 = Tmp1; + result_67023 = Tmp1; break BeforeRet; } while (false); - return result_62760; + return result_67023; } -function nimMin(a_62740, b_62741) { +function nimMin(a_67003, b_67004) { var Tmp1; - var result_62742 = 0; + var result_67005 = 0; BeforeRet: do { - if ((a_62740 <= b_62741)) { - Tmp1 = a_62740; + if ((a_67003 <= b_67004)) { + Tmp1 = a_67003; } else { - Tmp1 = b_62741; + Tmp1 = b_67004; } - result_62742 = Tmp1; + result_67005 = Tmp1; break BeforeRet; } while (false); - return result_62742; + return result_67005; } var nim_program_result = 0; -var global_raise_hook_57618 = [null]; -var local_raise_hook_57623 = [null]; -var out_of_mem_hook_57626 = [null]; +var global_raise_hook_61618 = [null]; +var local_raise_hook_61623 = [null]; +var out_of_mem_hook_61626 = [null]; if (!Math.trunc) { Math.trunc = function(v) { v = +v; @@ -578,38 +578,38 @@ var out_of_mem_hook_57626 = [null]; return (v - v % 1) || (v < 0 ? -0 : v === 0 ? v : 0); }; } -var alternative_197315 = [null]; +var alternative_207315 = [null]; -function is_fat_pointer_63001(ti_63003) { - var result_63004 = false; +function is_fat_pointer_67401(ti_67403) { + var result_67404 = false; BeforeRet: do { - result_63004 = !((ConstSet1[ti_63003.base.kind] != undefined)); + result_67404 = !((ConstSet1[ti_67403.base.kind] != undefined)); break BeforeRet; } while (false); - return result_63004; + return result_67404; } -function nimCopyAux(dest_63032, src_63033, n_63035) { - switch (n_63035.kind) { +function nimCopyAux(dest_67432, src_67433, n_67435) { + switch (n_67435.kind) { case 0: break; case 1: - dest_63032[n_63035.offset] = nimCopy(dest_63032[n_63035.offset], src_63033[n_63035.offset], n_63035.typ); + dest_67432[n_67435.offset] = nimCopy(dest_67432[n_67435.offset], src_67433[n_67435.offset], n_67435.typ); break; case 2: - for (var i = 0; i < n_63035.sons.length; i++) { - nimCopyAux(dest_63032, src_63033, n_63035.sons[i]); + for (var i = 0; i < n_67435.sons.length; i++) { + nimCopyAux(dest_67432, src_67433, n_67435.sons[i]); } break; case 3: - dest_63032[n_63035.offset] = nimCopy(dest_63032[n_63035.offset], src_63033[n_63035.offset], n_63035.typ); - for (var i = 0; i < n_63035.sons.length; ++i) { - nimCopyAux(dest_63032, src_63033, n_63035.sons[i][1]); + dest_67432[n_67435.offset] = nimCopy(dest_67432[n_67435.offset], src_67433[n_67435.offset], n_67435.typ); + for (var i = 0; i < n_67435.sons.length; ++i) { + nimCopyAux(dest_67432, src_67433, n_67435.sons[i][1]); } break; @@ -618,112 +618,112 @@ function nimCopyAux(dest_63032, src_63033, n_63035) { } -function add_57638(x_57641, x_57641_Idx, y_57642) { - if (x_57641[x_57641_Idx] === null) { x_57641[x_57641_Idx] = []; } - var off = x_57641[x_57641_Idx].length; - x_57641[x_57641_Idx].length += y_57642.length; - for (var i = 0; i < y_57642.length; ++i) { - x_57641[x_57641_Idx][off+i] = y_57642.charCodeAt(i); +function add_61638(x_61641, x_61641_Idx, y_61642) { + if (x_61641[x_61641_Idx] === null) { x_61641[x_61641_Idx] = []; } + var off = x_61641[x_61641_Idx].length; + x_61641[x_61641_Idx].length += y_61642.length; + for (var i = 0; i < y_61642.length; ++i) { + x_61641[x_61641_Idx][off+i] = y_61642.charCodeAt(i); } } -function aux_write_stack_trace_60151(f_60153) { +function aux_write_stack_trace_64151(f_64153) { var Tmp3; - var result_60154 = [null]; + var result_64154 = [null]; - var it_60162 = f_60153; - var i_60164 = 0; - var total_60166 = 0; - var temp_frames_60173 = arrayConstr(64, {Field0: null, Field1: 0}, NTI60156); + var it_64162 = f_64153; + var i_64164 = 0; + var total_64166 = 0; + var temp_frames_64173 = arrayConstr(64, {Field0: null, Field1: 0}, NTI64156); L1: do { L2: while (true) { - if (!!((it_60162 == null))) Tmp3 = false; else { Tmp3 = (i_60164 <= 63); } if (!Tmp3) break L2; - temp_frames_60173[i_60164].Field0 = it_60162.procname; - temp_frames_60173[i_60164].Field1 = it_60162.line; - i_60164 += 1; - total_60166 += 1; - it_60162 = it_60162.prev; + if (!!((it_64162 == null))) Tmp3 = false; else { Tmp3 = (i_64164 <= 63); } if (!Tmp3) break L2; + temp_frames_64173[i_64164].Field0 = it_64162.procname; + temp_frames_64173[i_64164].Field1 = it_64162.line; + i_64164 += 1; + total_64166 += 1; + it_64162 = it_64162.prev; } } while(false); L4: do { L5: while (true) { - if (!!((it_60162 == null))) break L5; - total_60166 += 1; - it_60162 = it_60162.prev; + if (!!((it_64162 == null))) break L5; + total_64166 += 1; + it_64162 = it_64162.prev; } } while(false); - result_60154[0] = nimCopy(null, [], NTI42040); - if (!((total_60166 == i_60164))) { - if (result_60154[0] != null) { result_60154[0] = (result_60154[0]).concat(makeNimstrLit("(")); } else { result_60154[0] = makeNimstrLit("("); }; - if (result_60154[0] != null) { result_60154[0] = (result_60154[0]).concat(cstrToNimstr(((total_60166 - i_60164))+"")); } else { result_60154[0] = cstrToNimstr(((total_60166 - i_60164))+"").slice(); }; - if (result_60154[0] != null) { result_60154[0] = (result_60154[0]).concat(makeNimstrLit(" calls omitted) ...\x0A")); } else { result_60154[0] = makeNimstrLit(" calls omitted) ...\x0A"); }; + result_64154[0] = nimCopy(null, [], NTI44040); + if (!((total_64166 == i_64164))) { + if (result_64154[0] != null) { result_64154[0] = (result_64154[0]).concat(makeNimstrLit("(")); } else { result_64154[0] = makeNimstrLit("("); }; + if (result_64154[0] != null) { result_64154[0] = (result_64154[0]).concat(cstrToNimstr(((total_64166 - i_64164))+"")); } else { result_64154[0] = cstrToNimstr(((total_64166 - i_64164))+"").slice(); }; + if (result_64154[0] != null) { result_64154[0] = (result_64154[0]).concat(makeNimstrLit(" calls omitted) ...\x0A")); } else { result_64154[0] = makeNimstrLit(" calls omitted) ...\x0A"); }; } L6: do { - var j_60421 = 0; - var colontmp__197456 = 0; - colontmp__197456 = (i_60164 - 1); - var res_197461 = colontmp__197456; + var j_64421 = 0; + var colontmp__207456 = 0; + colontmp__207456 = (i_64164 - 1); + var res_207461 = colontmp__207456; L7: do { L8: while (true) { - if (!(0 <= res_197461)) break L8; - j_60421 = res_197461; - add_57638(result_60154, 0, temp_frames_60173[j_60421].Field0); - if ((0 < temp_frames_60173[j_60421].Field1)) { - if (result_60154[0] != null) { result_60154[0] = (result_60154[0]).concat(makeNimstrLit(", line: ")); } else { result_60154[0] = makeNimstrLit(", line: "); }; - if (result_60154[0] != null) { result_60154[0] = (result_60154[0]).concat(cstrToNimstr((temp_frames_60173[j_60421].Field1)+"")); } else { result_60154[0] = cstrToNimstr((temp_frames_60173[j_60421].Field1)+"").slice(); }; + if (!(0 <= res_207461)) break L8; + j_64421 = res_207461; + add_61638(result_64154, 0, temp_frames_64173[j_64421].Field0); + if ((0 < temp_frames_64173[j_64421].Field1)) { + if (result_64154[0] != null) { result_64154[0] = (result_64154[0]).concat(makeNimstrLit(", line: ")); } else { result_64154[0] = makeNimstrLit(", line: "); }; + if (result_64154[0] != null) { result_64154[0] = (result_64154[0]).concat(cstrToNimstr((temp_frames_64173[j_64421].Field1)+"")); } else { result_64154[0] = cstrToNimstr((temp_frames_64173[j_64421].Field1)+"").slice(); }; } - if (result_60154[0] != null) { result_60154[0] = (result_60154[0]).concat(makeNimstrLit("\x0A")); } else { result_60154[0] = makeNimstrLit("\x0A"); }; - res_197461 -= 1; + if (result_64154[0] != null) { result_64154[0] = (result_64154[0]).concat(makeNimstrLit("\x0A")); } else { result_64154[0] = makeNimstrLit("\x0A"); }; + res_207461 -= 1; } } while(false); } while(false); - return result_60154[0]; + return result_64154[0]; } -function raw_write_stack_trace_60468() { - var result_60470 = null; +function raw_write_stack_trace_64468() { + var result_64470 = null; if (!((framePtr == null))) { - result_60470 = nimCopy(null, (makeNimstrLit("Traceback (most recent call last)\x0A") || []).concat(aux_write_stack_trace_60151(framePtr) || []), NTI42040); + result_64470 = nimCopy(null, (makeNimstrLit("Traceback (most recent call last)\x0A") || []).concat(aux_write_stack_trace_64151(framePtr) || []), NTI44040); } else { - result_60470 = nimCopy(null, makeNimstrLit("No stack traceback available\x0A"), NTI42040); + result_64470 = nimCopy(null, makeNimstrLit("No stack traceback available\x0A"), NTI44040); } - return result_60470; + return result_64470; } -function unhandledException(e_60529) { - var buf_60530 = [[]]; - if (!(((e_60529.message != null ? e_60529.message.length : 0) == 0))) { - if (buf_60530[0] != null) { buf_60530[0] = (buf_60530[0]).concat(makeNimstrLit("Error: unhandled exception: ")); } else { buf_60530[0] = makeNimstrLit("Error: unhandled exception: "); }; - if (buf_60530[0] != null) { buf_60530[0] = (buf_60530[0]).concat(e_60529.message); } else { buf_60530[0] = e_60529.message.slice(); }; +function unhandledException(e_64529) { + var buf_64530 = [[]]; + if (!(((e_64529.message != null ? e_64529.message.length : 0) == 0))) { + if (buf_64530[0] != null) { buf_64530[0] = (buf_64530[0]).concat(makeNimstrLit("Error: unhandled exception: ")); } else { buf_64530[0] = makeNimstrLit("Error: unhandled exception: "); }; + if (buf_64530[0] != null) { buf_64530[0] = (buf_64530[0]).concat(e_64529.message); } else { buf_64530[0] = e_64529.message.slice(); }; } else { - if (buf_60530[0] != null) { buf_60530[0] = (buf_60530[0]).concat(makeNimstrLit("Error: unhandled exception")); } else { buf_60530[0] = makeNimstrLit("Error: unhandled exception"); }; + if (buf_64530[0] != null) { buf_64530[0] = (buf_64530[0]).concat(makeNimstrLit("Error: unhandled exception")); } else { buf_64530[0] = makeNimstrLit("Error: unhandled exception"); }; } - if (buf_60530[0] != null) { buf_60530[0] = (buf_60530[0]).concat(makeNimstrLit(" [")); } else { buf_60530[0] = makeNimstrLit(" ["); }; - add_57638(buf_60530, 0, e_60529.name); - if (buf_60530[0] != null) { buf_60530[0] = (buf_60530[0]).concat(makeNimstrLit("]\x0A")); } else { buf_60530[0] = makeNimstrLit("]\x0A"); }; - if (buf_60530[0] != null) { buf_60530[0] = (buf_60530[0]).concat(raw_write_stack_trace_60468()); } else { buf_60530[0] = raw_write_stack_trace_60468().slice(); }; - var cbuf_60601 = toJSStr(buf_60530[0]); + if (buf_64530[0] != null) { buf_64530[0] = (buf_64530[0]).concat(makeNimstrLit(" [")); } else { buf_64530[0] = makeNimstrLit(" ["); }; + add_61638(buf_64530, 0, e_64529.name); + if (buf_64530[0] != null) { buf_64530[0] = (buf_64530[0]).concat(makeNimstrLit("]\x0A")); } else { buf_64530[0] = makeNimstrLit("]\x0A"); }; + if (buf_64530[0] != null) { buf_64530[0] = (buf_64530[0]).concat(raw_write_stack_trace_64468()); } else { buf_64530[0] = raw_write_stack_trace_64468().slice(); }; + var cbuf_64601 = toJSStr(buf_64530[0]); framePtr = null; if (typeof(Error) !== "undefined") { - throw new Error(cbuf_60601); + throw new Error(cbuf_64601); } else { - throw cbuf_60601; + throw cbuf_64601; } @@ -731,49 +731,58 @@ function unhandledException(e_60529) { } function raiseOverflow() { - var e_61046 = null; - e_61046 = {m_type: NTI45846, parent: null, name: null, message: null, trace: null, raiseId: 0, up: null}; - e_61046.message = nimCopy(null, makeNimstrLit("over- or underflow"), NTI42040); - e_61046.parent = null; - raiseException(e_61046, "OverflowError"); + var e_65042 = null; + e_65042 = {m_type: NTI47846, parent: null, name: null, message: null, trace: null, raiseId: 0, up: null}; + e_65042.message = nimCopy(null, makeNimstrLit("over- or underflow"), NTI44040); + e_65042.parent = null; + raiseException(e_65042, "OverflowError"); } -function is_whitespace_196654(text_196656) { - return !/[^\s]/.test(text_196656); +function is_whitespace_206654(text_206656) { + return !/[^\s]/.test(text_206656); } -function is_whitespace_196671(x_196673) { +function is_whitespace_206671(x_206673) { var Tmp1; var Tmp2; - var result_196674 = false; + var result_206674 = false; var F={procname:"dochack.isWhitespace",prev:framePtr,filename:"dochack.nim",line:0}; framePtr = F; F.line = 134; - if (!(x_196673.nodeName == "#text")) Tmp2 = false; else { Tmp2 = is_whitespace_196654(x_196673.textContent); } if (Tmp2) Tmp1 = true; else { Tmp1 = (x_196673.nodeName == "#comment"); } result_196674 = Tmp1; + if (!(x_206673.nodeName == "#text")) Tmp2 = false; else { Tmp2 = is_whitespace_206654(x_206673.textContent); } if (Tmp2) Tmp1 = true; else { Tmp1 = (x_206673.nodeName == "#comment"); } result_206674 = Tmp1; framePtr = F.prev; - return result_196674; + return result_206674; } -function raiseIndexError(i_61643, a_61644, b_61645) { - var e_61649 = null; - e_61649 = {m_type: NTI45858, parent: null, name: null, message: null, trace: null, raiseId: 0, up: null}; - e_61649.message = nimCopy(null, (makeNimstrLit("index ") || []).concat(cstrToNimstr((i_61643)+"") || [],makeNimstrLit(" not in ") || [],cstrToNimstr((a_61644)+"") || [],makeNimstrLit(" .. ") || [],cstrToNimstr((b_61645)+"") || []), NTI42040); - e_61649.parent = null; - raiseException(e_61649, "IndexError"); +function raiseIndexError(i_65639, a_65640, b_65641) { + var Tmp1; + + var e_65802 = null; + e_65802 = {m_type: NTI47858, parent: null, name: null, message: null, trace: null, raiseId: 0, up: null}; + if ((b_65641 < a_65640)) { + Tmp1 = makeNimstrLit("index out of bounds, the container is empty"); + } + else { + Tmp1 = (makeNimstrLit("index ") || []).concat(cstrToNimstr((i_65639)+"") || [],makeNimstrLit(" not in ") || [],cstrToNimstr((a_65640)+"") || [],makeNimstrLit(" .. ") || [],cstrToNimstr((b_65641)+"") || []); + } + + e_65802.message = nimCopy(null, Tmp1, NTI44040); + e_65802.parent = null; + raiseException(e_65802, "IndexError"); } -function to_toc_196688(x_196690, father_196691) { +function to_toc_206688(x_206690, father_206691) { var Tmp5; var Tmp6; var Tmp7; @@ -782,151 +791,151 @@ function to_toc_196688(x_196690, father_196691) { var F={procname:"dochack.toToc",prev:framePtr,filename:"dochack.nim",line:0}; framePtr = F; - if ((x_196690.nodeName == "UL")) { + if ((x_206690.nodeName == "UL")) { F.line = 139; - var f_196710 = {heading: null, kids: [], sortId: (father_196691.kids != null ? father_196691.kids.length : 0), doSort: false}; + var f_206710 = {heading: null, kids: [], sortId: (father_206691.kids != null ? father_206691.kids.length : 0), doSort: false}; F.line = 140; - var i_196712 = 0; + var i_206712 = 0; L1: do { F.line = 141; L2: while (true) { - if (!(i_196712 < x_196690.childNodes.length)) break L2; + if (!(i_206712 < x_206690.childNodes.length)) break L2; F.line = 142; - var nxt_196713 = addInt(i_196712, 1); + var nxt_206713 = addInt(i_206712, 1); L3: do { F.line = 143; L4: while (true) { - if (!(nxt_196713 < x_196690.childNodes.length)) Tmp5 = false; else { Tmp5 = is_whitespace_196671(x_196690.childNodes[nxt_196713]); } if (!Tmp5) break L4; + if (!(nxt_206713 < x_206690.childNodes.length)) Tmp5 = false; else { Tmp5 = is_whitespace_206671(x_206690.childNodes[nxt_206713]); } if (!Tmp5) break L4; F.line = 144; - nxt_196713 = addInt(nxt_196713, 1); + nxt_206713 = addInt(nxt_206713, 1); } } while(false); - if (!(nxt_196713 < x_196690.childNodes.length)) Tmp8 = false; else { Tmp8 = (x_196690.childNodes[i_196712].nodeName == "LI"); } if (!Tmp8) Tmp7 = false; else { Tmp7 = (x_196690.childNodes[i_196712].childNodes.length == 1); } if (!Tmp7) Tmp6 = false; else { Tmp6 = (x_196690.childNodes[nxt_196713].nodeName == "UL"); } if (Tmp6) { + if (!(nxt_206713 < x_206690.childNodes.length)) Tmp8 = false; else { Tmp8 = (x_206690.childNodes[i_206712].nodeName == "LI"); } if (!Tmp8) Tmp7 = false; else { Tmp7 = (x_206690.childNodes[i_206712].childNodes.length == 1); } if (!Tmp7) Tmp6 = false; else { Tmp6 = (x_206690.childNodes[nxt_206713].nodeName == "UL"); } if (Tmp6) { F.line = 147; - var e_196738 = {heading: x_196690.childNodes[i_196712].childNodes[0], kids: [], sortId: (f_196710.kids != null ? f_196710.kids.length : 0), doSort: false}; + var e_206738 = {heading: x_206690.childNodes[i_206712].childNodes[0], kids: [], sortId: (f_206710.kids != null ? f_206710.kids.length : 0), doSort: false}; F.line = 148; - var it_196739 = x_196690.childNodes[nxt_196713]; + var it_206739 = x_206690.childNodes[nxt_206713]; L9: do { F.line = 149; - var j_196746 = 0; - F.line = 2638; - var colontmp__197432 = 0; + var j_206747 = 0; + F.line = 2716; + var colontmp__207432 = 0; F.line = 149; - colontmp__197432 = it_196739.childNodes.length; - F.line = 2639; - var i_197433 = 0; + colontmp__207432 = it_206739.childNodes.length; + F.line = 2717; + var i_207433 = 0; L10: do { - F.line = 2640; + F.line = 2718; L11: while (true) { - if (!(i_197433 < colontmp__197432)) break L11; + if (!(i_207433 < colontmp__207432)) break L11; F.line = 149; - j_196746 = i_197433; + j_206747 = i_207433; F.line = 150; - to_toc_196688(it_196739.childNodes[j_196746], e_196738); - F.line = 2642; - i_197433 = addInt(i_197433, 1); + to_toc_206688(it_206739.childNodes[j_206747], e_206738); + F.line = 2720; + i_207433 = addInt(i_207433, 1); } } while(false); } while(false); F.line = 151; - if (f_196710.kids != null) { f_196710.kids.push(e_196738); } else { f_196710.kids = [e_196738]; }; + if (f_206710.kids != null) { f_206710.kids.push(e_206738); } else { f_206710.kids = [e_206738]; }; F.line = 152; - i_196712 = addInt(nxt_196713, 1); + i_206712 = addInt(nxt_206713, 1); } else { F.line = 154; - to_toc_196688(x_196690.childNodes[i_196712], f_196710); + to_toc_206688(x_206690.childNodes[i_206712], f_206710); F.line = 155; - i_196712 = addInt(i_196712, 1); + i_206712 = addInt(i_206712, 1); } } } while(false); F.line = 156; - if (father_196691.kids != null) { father_196691.kids.push(f_196710); } else { father_196691.kids = [f_196710]; }; + if (father_206691.kids != null) { father_206691.kids.push(f_206710); } else { father_206691.kids = [f_206710]; }; } else { - if (is_whitespace_196671(x_196690)) { + if (is_whitespace_206671(x_206690)) { } else { - if ((x_196690.nodeName == "LI")) { + if ((x_206690.nodeName == "LI")) { F.line = 160; - var idx_196781 = []; + var idx_206782 = []; L12: do { F.line = 161; - var i_196788 = 0; - F.line = 2638; - var colontmp__197437 = 0; + var i_206790 = 0; + F.line = 2716; + var colontmp__207437 = 0; F.line = 161; - colontmp__197437 = x_196690.childNodes.length; - F.line = 2639; - var i_197438 = 0; + colontmp__207437 = x_206690.childNodes.length; + F.line = 2717; + var i_207438 = 0; L13: do { - F.line = 2640; + F.line = 2718; L14: while (true) { - if (!(i_197438 < colontmp__197437)) break L14; + if (!(i_207438 < colontmp__207437)) break L14; F.line = 161; - i_196788 = i_197438; - if (!(is_whitespace_196671(x_196690.childNodes[i_196788]))) { + i_206790 = i_207438; + if (!(is_whitespace_206671(x_206690.childNodes[i_206790]))) { F.line = 162; - if (idx_196781 != null) { idx_196781.push(i_196788); } else { idx_196781 = [i_196788]; }; + if (idx_206782 != null) { idx_206782.push(i_206790); } else { idx_206782 = [i_206790]; }; } - F.line = 2642; - i_197438 = addInt(i_197438, 1); + F.line = 2720; + i_207438 = addInt(i_207438, 1); } } while(false); } while(false); - if (!((idx_196781 != null ? idx_196781.length : 0) == 2)) Tmp15 = false; else { Tmp15 = (x_196690.childNodes[idx_196781[chckIndx(1, 0, idx_196781.length+0-1)-0]].nodeName == "UL"); } if (Tmp15) { + if (!((idx_206782 != null ? idx_206782.length : 0) == 2)) Tmp15 = false; else { Tmp15 = (x_206690.childNodes[idx_206782[chckIndx(1, 0, idx_206782.length+0-1)-0]].nodeName == "UL"); } if (Tmp15) { F.line = 164; - var e_196819 = {heading: x_196690.childNodes[idx_196781[chckIndx(0, 0, idx_196781.length+0-1)-0]], kids: [], sortId: (father_196691.kids != null ? father_196691.kids.length : 0), doSort: false}; + var e_206821 = {heading: x_206690.childNodes[idx_206782[chckIndx(0, 0, idx_206782.length+0-1)-0]], kids: [], sortId: (father_206691.kids != null ? father_206691.kids.length : 0), doSort: false}; F.line = 166; - var it_196820 = x_196690.childNodes[idx_196781[chckIndx(1, 0, idx_196781.length+0-1)-0]]; + var it_206822 = x_206690.childNodes[idx_206782[chckIndx(1, 0, idx_206782.length+0-1)-0]]; L16: do { F.line = 167; - var j_196827 = 0; - F.line = 2638; - var colontmp__197443 = 0; + var j_206830 = 0; + F.line = 2716; + var colontmp__207443 = 0; F.line = 167; - colontmp__197443 = it_196820.childNodes.length; - F.line = 2639; - var i_197444 = 0; + colontmp__207443 = it_206822.childNodes.length; + F.line = 2717; + var i_207444 = 0; L17: do { - F.line = 2640; + F.line = 2718; L18: while (true) { - if (!(i_197444 < colontmp__197443)) break L18; + if (!(i_207444 < colontmp__207443)) break L18; F.line = 167; - j_196827 = i_197444; + j_206830 = i_207444; F.line = 168; - to_toc_196688(it_196820.childNodes[j_196827], e_196819); - F.line = 2642; - i_197444 = addInt(i_197444, 1); + to_toc_206688(it_206822.childNodes[j_206830], e_206821); + F.line = 2720; + i_207444 = addInt(i_207444, 1); } } while(false); } while(false); F.line = 169; - if (father_196691.kids != null) { father_196691.kids.push(e_196819); } else { father_196691.kids = [e_196819]; }; + if (father_206691.kids != null) { father_206691.kids.push(e_206821); } else { father_206691.kids = [e_206821]; }; } else { L19: do { F.line = 171; - var i_196841 = 0; - F.line = 2638; - var colontmp__197448 = 0; + var i_206845 = 0; + F.line = 2716; + var colontmp__207448 = 0; F.line = 171; - colontmp__197448 = x_196690.childNodes.length; - F.line = 2639; - var i_197449 = 0; + colontmp__207448 = x_206690.childNodes.length; + F.line = 2717; + var i_207449 = 0; L20: do { - F.line = 2640; + F.line = 2718; L21: while (true) { - if (!(i_197449 < colontmp__197448)) break L21; + if (!(i_207449 < colontmp__207448)) break L21; F.line = 171; - i_196841 = i_197449; + i_206845 = i_207449; F.line = 172; - to_toc_196688(x_196690.childNodes[i_196841], father_196691); - F.line = 2642; - i_197449 = addInt(i_197449, 1); + to_toc_206688(x_206690.childNodes[i_206845], father_206691); + F.line = 2720; + i_207449 = addInt(i_207449, 1); } } while(false); } while(false); @@ -935,7 +944,7 @@ function to_toc_196688(x_196690, father_196691) { } else { F.line = 174; - if (father_196691.kids != null) { father_196691.kids.push({heading: x_196690, kids: [], sortId: (father_196691.kids != null ? father_196691.kids.length : 0), doSort: false}); } else { father_196691.kids = [{heading: x_196690, kids: [], sortId: (father_196691.kids != null ? father_196691.kids.length : 0), doSort: false}]; }; + if (father_206691.kids != null) { father_206691.kids.push({heading: x_206690, kids: [], sortId: (father_206691.kids != null ? father_206691.kids.length : 0), doSort: false}); } else { father_206691.kids = [{heading: x_206690, kids: [], sortId: (father_206691.kids != null ? father_206691.kids.length : 0), doSort: false}]; }; } }} framePtr = F.prev; @@ -943,37 +952,37 @@ function to_toc_196688(x_196690, father_196691) { } -function extract_items_196337(x_196339, heading_196340, items_196343, items_196343_Idx) { +function extract_items_206339(x_206341, heading_206342, items_206345, items_206345_Idx) { var Tmp1; var F={procname:"dochack.extractItems",prev:framePtr,filename:"dochack.nim",line:0}; framePtr = F; BeforeRet: do { - if ((x_196339 == null)) { + if ((x_206341 == null)) { F.line = 81; break BeforeRet; } - if (!!((x_196339.heading == null))) Tmp1 = false; else { Tmp1 = (x_196339.heading.textContent == heading_196340); } if (Tmp1) { + if (!!((x_206341.heading == null))) Tmp1 = false; else { Tmp1 = (x_206341.heading.textContent == heading_206342); } if (Tmp1) { L2: do { F.line = 83; - var i_196371 = 0; - F.line = 2638; - var colontmp__197473 = 0; + var i_206374 = 0; + F.line = 2716; + var colontmp__207475 = 0; F.line = 83; - colontmp__197473 = (x_196339.kids != null ? x_196339.kids.length : 0); - F.line = 2639; - var i_197474 = 0; + colontmp__207475 = (x_206341.kids != null ? x_206341.kids.length : 0); + F.line = 2717; + var i_207476 = 0; L3: do { - F.line = 2640; + F.line = 2718; L4: while (true) { - if (!(i_197474 < colontmp__197473)) break L4; + if (!(i_207476 < colontmp__207475)) break L4; F.line = 83; - i_196371 = i_197474; + i_206374 = i_207476; F.line = 84; - if (items_196343[items_196343_Idx] != null) { items_196343[items_196343_Idx].push(x_196339.kids[chckIndx(i_196371, 0, x_196339.kids.length+0-1)-0].heading); } else { items_196343[items_196343_Idx] = [x_196339.kids[chckIndx(i_196371, 0, x_196339.kids.length+0-1)-0].heading]; }; - F.line = 2642; - i_197474 = addInt(i_197474, 1); + if (items_206345[items_206345_Idx] != null) { items_206345[items_206345_Idx].push(x_206341.kids[chckIndx(i_206374, 0, x_206341.kids.length+0-1)-0].heading); } else { items_206345[items_206345_Idx] = [x_206341.kids[chckIndx(i_206374, 0, x_206341.kids.length+0-1)-0].heading]; }; + F.line = 2720; + i_207476 = addInt(i_207476, 1); } } while(false); } while(false); @@ -981,25 +990,25 @@ function extract_items_196337(x_196339, heading_196340, items_196343, items_1963 else { L5: do { F.line = 86; - var i_196390 = 0; - F.line = 2638; - var colontmp__197478 = 0; + var i_206394 = 0; + F.line = 2716; + var colontmp__207480 = 0; F.line = 86; - colontmp__197478 = (x_196339.kids != null ? x_196339.kids.length : 0); - F.line = 2639; - var i_197479 = 0; + colontmp__207480 = (x_206341.kids != null ? x_206341.kids.length : 0); + F.line = 2717; + var i_207481 = 0; L6: do { - F.line = 2640; + F.line = 2718; L7: while (true) { - if (!(i_197479 < colontmp__197478)) break L7; + if (!(i_207481 < colontmp__207480)) break L7; F.line = 86; - i_196390 = i_197479; + i_206394 = i_207481; F.line = 87; - var it_196391 = x_196339.kids[chckIndx(i_196390, 0, x_196339.kids.length+0-1)-0]; + var it_206395 = x_206341.kids[chckIndx(i_206394, 0, x_206341.kids.length+0-1)-0]; F.line = 88; - extract_items_196337(it_196391, heading_196340, items_196343, items_196343_Idx); - F.line = 2642; - i_197479 = addInt(i_197479, 1); + extract_items_206339(it_206395, heading_206342, items_206345, items_206345_Idx); + F.line = 2720; + i_207481 = addInt(i_207481, 1); } } while(false); } while(false); @@ -1011,180 +1020,180 @@ function extract_items_196337(x_196339, heading_196340, items_196343, items_1963 } -function tree_196020(tag_196022, kids_196024) { - var result_196025 = null; +function tree_206020(tag_206022, kids_206024) { + var result_206025 = null; var F={procname:"dochack.tree",prev:framePtr,filename:"dochack.nim",line:0}; framePtr = F; F.line = 11; - result_196025 = document.createElement(toJSStr(tag_196022)); + result_206025 = document.createElement(toJSStr(tag_206022)); L1: do { F.line = 12; - var k_196056 = null; + var k_206056 = null; F.line = 3; - var i_197496 = 0; + var i_207498 = 0; L2: do { F.line = 4; L3: while (true) { - if (!(i_197496 < (kids_196024 != null ? kids_196024.length : 0))) break L3; + if (!(i_207498 < (kids_206024 != null ? kids_206024.length : 0))) break L3; F.line = 12; - k_196056 = kids_196024[chckIndx(i_197496, 0, kids_196024.length+0-1)-0]; + k_206056 = kids_206024[chckIndx(i_207498, 0, kids_206024.length+0-1)-0]; F.line = 13; - result_196025.appendChild(k_196056); + result_206025.appendChild(k_206056); F.line = 6; - i_197496 = addInt(i_197496, 1); + i_207498 = addInt(i_207498, 1); } } while(false); } while(false); framePtr = F.prev; - return result_196025; + return result_206025; } -function text_196152(s_196154) { - var result_196155 = null; +function text_206152(s_206154) { + var result_206155 = null; var F={procname:"dochack.text",prev:framePtr,filename:"dochack.nim",line:0}; framePtr = F; F.line = 27; - result_196155 = document.createTextNode(s_196154); + result_206155 = document.createTextNode(s_206154); framePtr = F.prev; - return result_196155; + return result_206155; } -function sys_fatal_55662(message_55666) { - var F={procname:"sysFatal.sysFatal",prev:framePtr,filename:"../../lib/system/fatal.nim",line:0}; +function sys_fatal_58662(message_58666) { + var F={procname:"sysFatal.sysFatal",prev:framePtr,filename:"fatal.nim",line:0}; framePtr = F; F.line = 34; - var e_55807 = null; + var e_58803 = null; F.line = 37; - e_55807 = {m_type: NTI45850, parent: null, name: null, message: null, trace: null, raiseId: 0, up: null}; + e_58803 = {m_type: NTI47850, parent: null, name: null, message: null, trace: null, raiseId: 0, up: null}; F.line = 38; - e_55807.message = nimCopy(null, message_55666, NTI42040); + e_58803.message = nimCopy(null, message_58666, NTI44040); F.line = 39; - raiseException(e_55807, "AssertionError"); + raiseException(e_58803, "AssertionError"); framePtr = F.prev; } -function raise_assert_55658(msg_55660) { - var F={procname:"assertions.raiseAssert",prev:framePtr,filename:"../../lib/system/assertions.nim",line:0}; +function raise_assert_58658(msg_58660) { + var F={procname:"assertions.raiseAssert",prev:framePtr,filename:"assertions.nim",line:0}; framePtr = F; F.line = 20; - sys_fatal_55662(msg_55660); + sys_fatal_58662(msg_58660); framePtr = F.prev; } -function failed_assert_impl_55855(msg_55857) { - var F={procname:"assertions.failedAssertImpl",prev:framePtr,filename:"../../lib/system/assertions.nim",line:0}; +function failed_assert_impl_58851(msg_58853) { + var F={procname:"assertions.failedAssertImpl",prev:framePtr,filename:"assertions.nim",line:0}; framePtr = F; F.line = 27; - raise_assert_55658(msg_55857); + raise_assert_58658(msg_58853); framePtr = F.prev; } -function uncovered_196935(x_196937) { +function uncovered_206940(x_206942) { var Tmp1; var Tmp2; - var result_196938 = null; + var result_206943 = null; var F={procname:"dochack.uncovered",prev:framePtr,filename:"dochack.nim",line:0}; framePtr = F; BeforeRet: do { - if (!((x_196937.kids != null ? x_196937.kids.length : 0) == 0)) Tmp1 = false; else { Tmp1 = !((x_196937.heading == null)); } if (Tmp1) { + if (!((x_206942.kids != null ? x_206942.kids.length : 0) == 0)) Tmp1 = false; else { Tmp1 = !((x_206942.heading == null)); } if (Tmp1) { F.line = 194; - if (!(x_196937.heading.hasOwnProperty('__karaxMarker__'))) { - Tmp2 = x_196937; + if (!(x_206942.heading.hasOwnProperty('__karaxMarker__'))) { + Tmp2 = x_206942; } else { Tmp2 = null; } - result_196938 = Tmp2; + result_206943 = Tmp2; break BeforeRet; } F.line = 195; - result_196938 = {heading: x_196937.heading, kids: [], sortId: x_196937.sortId, doSort: x_196937.doSort}; + result_206943 = {heading: x_206942.heading, kids: [], sortId: x_206942.sortId, doSort: x_206942.doSort}; L3: do { F.line = 197; - var i_196976 = 0; - F.line = 2638; - var colontmp__197508 = 0; + var i_206982 = 0; + F.line = 2716; + var colontmp__207510 = 0; F.line = 197; - colontmp__197508 = (x_196937.kids != null ? x_196937.kids.length : 0); - F.line = 2639; - var i_197509 = 0; + colontmp__207510 = (x_206942.kids != null ? x_206942.kids.length : 0); + F.line = 2717; + var i_207511 = 0; L4: do { - F.line = 2640; + F.line = 2718; L5: while (true) { - if (!(i_197509 < colontmp__197508)) break L5; + if (!(i_207511 < colontmp__207510)) break L5; F.line = 197; - i_196976 = i_197509; + i_206982 = i_207511; F.line = 198; - var y_196977 = uncovered_196935(x_196937.kids[chckIndx(i_196976, 0, x_196937.kids.length+0-1)-0]); - if (!((y_196977 == null))) { + var y_206983 = uncovered_206940(x_206942.kids[chckIndx(i_206982, 0, x_206942.kids.length+0-1)-0]); + if (!((y_206983 == null))) { F.line = 199; - if (result_196938.kids != null) { result_196938.kids.push(y_196977); } else { result_196938.kids = [y_196977]; }; + if (result_206943.kids != null) { result_206943.kids.push(y_206983); } else { result_206943.kids = [y_206983]; }; } - F.line = 2642; - i_197509 = addInt(i_197509, 1); + F.line = 2720; + i_207511 = addInt(i_207511, 1); } } while(false); } while(false); - if (((result_196938.kids != null ? result_196938.kids.length : 0) == 0)) { + if (((result_206943.kids != null ? result_206943.kids.length : 0) == 0)) { F.line = 200; - result_196938 = null; + result_206943 = null; } } while (false); framePtr = F.prev; - return result_196938; + return result_206943; } -function merge_tocs_197011(orig_197013, news_197014) { - var result_197015 = null; +function merge_tocs_207017(orig_207019, news_207020) { + var result_207021 = null; var F={procname:"dochack.mergeTocs",prev:framePtr,filename:"dochack.nim",line:0}; framePtr = F; F.line = 203; - result_197015 = uncovered_196935(orig_197013); - if ((result_197015 == null)) { + result_207021 = uncovered_206940(orig_207019); + if ((result_207021 == null)) { F.line = 205; - result_197015 = news_197014; + result_207021 = news_207020; } else { L1: do { F.line = 207; - var i_197035 = 0; - F.line = 2638; - var colontmp__197502 = 0; + var i_207042 = 0; + F.line = 2716; + var colontmp__207504 = 0; F.line = 207; - colontmp__197502 = (news_197014.kids != null ? news_197014.kids.length : 0); - F.line = 2639; - var i_197503 = 0; + colontmp__207504 = (news_207020.kids != null ? news_207020.kids.length : 0); + F.line = 2717; + var i_207505 = 0; L2: do { - F.line = 2640; + F.line = 2718; L3: while (true) { - if (!(i_197503 < colontmp__197502)) break L3; + if (!(i_207505 < colontmp__207504)) break L3; F.line = 207; - i_197035 = i_197503; + i_207042 = i_207505; F.line = 208; - if (result_197015.kids != null) { result_197015.kids.push(news_197014.kids[chckIndx(i_197035, 0, news_197014.kids.length+0-1)-0]); } else { result_197015.kids = [news_197014.kids[chckIndx(i_197035, 0, news_197014.kids.length+0-1)-0]]; }; - F.line = 2642; - i_197503 = addInt(i_197503, 1); + if (result_207021.kids != null) { result_207021.kids.push(news_207020.kids[chckIndx(i_207042, 0, news_207020.kids.length+0-1)-0]); } else { result_207021.kids = [news_207020.kids[chckIndx(i_207042, 0, news_207020.kids.length+0-1)-0]]; }; + F.line = 2720; + i_207505 = addInt(i_207505, 1); } } while(false); } while(false); @@ -1192,110 +1201,110 @@ function merge_tocs_197011(orig_197013, news_197014) { framePtr = F.prev; - return result_197015; + return result_207021; } -function build_toc_197056(orig_197058, types_197060, procs_197061) { - var result_197062 = null; +function build_toc_207063(orig_207065, types_207067, procs_207068) { + var result_207069 = null; var F={procname:"dochack.buildToc",prev:framePtr,filename:"dochack.nim",line:0}; framePtr = F; F.line = 211; - var new_stuff_197076 = {heading: null, kids: [], doSort: true, sortId: 0}; + var new_stuff_207083 = {heading: null, kids: [], doSort: true, sortId: 0}; L1: do { F.line = 212; - var t_197214 = null; - F.line = 156; - var i_197491 = 0; - F.line = 157; - var l_197492 = (types_197060 != null ? types_197060.length : 0); + var t_207214 = null; + F.line = 185; + var i_207493 = 0; + F.line = 186; + var l_207494 = (types_207067 != null ? types_207067.length : 0); L2: do { - F.line = 158; + F.line = 187; L3: while (true) { - if (!(i_197491 < l_197492)) break L3; + if (!(i_207493 < l_207494)) break L3; F.line = 212; - t_197214 = types_197060[chckIndx(i_197491, 0, types_197060.length+0-1)-0]; + t_207214 = types_207067[chckIndx(i_207493, 0, types_207067.length+0-1)-0]; F.line = 213; - var c_197228 = {heading: t_197214.cloneNode(true), kids: [], doSort: true, sortId: 0}; + var c_207228 = {heading: t_207214.cloneNode(true), kids: [], doSort: true, sortId: 0}; F.line = 214; - t_197214.__karaxMarker__ = true; + t_207214.__karaxMarker__ = true; L4: do { F.line = 215; - var p_197235 = null; - F.line = 156; - var i_197488 = 0; - F.line = 157; - var l_197489 = (procs_197061 != null ? procs_197061.length : 0); + var p_207235 = null; + F.line = 185; + var i_207490 = 0; + F.line = 186; + var l_207491 = (procs_207068 != null ? procs_207068.length : 0); L5: do { - F.line = 158; + F.line = 187; L6: while (true) { - if (!(i_197488 < l_197489)) break L6; + if (!(i_207490 < l_207491)) break L6; F.line = 215; - p_197235 = procs_197061[chckIndx(i_197488, 0, procs_197061.length+0-1)-0]; - if (!(p_197235.hasOwnProperty('__karaxMarker__'))) { + p_207235 = procs_207068[chckIndx(i_207490, 0, procs_207068.length+0-1)-0]; + if (!(p_207235.hasOwnProperty('__karaxMarker__'))) { F.line = 217; - var xx_197236 = p_197235.parentNode.getElementsByClassName("attachedType"); - if ((((xx_197236 != null ? xx_197236.length : 0) == 1) && (xx_197236[chckIndx(0, 0, xx_197236.length+0-1)-0].textContent == t_197214.textContent))) { + var xx_207236 = p_207235.parentNode.getElementsByClassName("attachedType"); + if ((((xx_207236 != null ? xx_207236.length : 0) == 1) && (xx_207236[chckIndx(0, 0, xx_207236.length+0-1)-0].textContent == t_207214.textContent))) { F.line = 220; - var q_197244 = tree_196020(makeNimstrLit("A"), [text_196152(p_197235.title)]); + var q_207244 = tree_206020(makeNimstrLit("A"), [text_206152(p_207235.title)]); F.line = 221; - q_197244.setAttribute("href", p_197235.getAttribute("href")); + q_207244.setAttribute("href", p_207235.getAttribute("href")); F.line = 222; - if (c_197228.kids != null) { c_197228.kids.push({heading: q_197244, kids: [], sortId: 0, doSort: false}); } else { c_197228.kids = [{heading: q_197244, kids: [], sortId: 0, doSort: false}]; }; + if (c_207228.kids != null) { c_207228.kids.push({heading: q_207244, kids: [], sortId: 0, doSort: false}); } else { c_207228.kids = [{heading: q_207244, kids: [], sortId: 0, doSort: false}]; }; F.line = 223; - p_197235.__karaxMarker__ = true; + p_207235.__karaxMarker__ = true; } } - F.line = 160; - i_197488 = addInt(i_197488, 1); - if (!(((procs_197061 != null ? procs_197061.length : 0) == l_197489))) { - F.line = 161; - failed_assert_impl_55855(makeNimstrLit("/home/genotrance/programming/nimdevel/lib/system/iterators.nim(161, 11) `len(a) == L` seq modified while iterating over it")); + F.line = 189; + i_207490 = addInt(i_207490, 1); + if (!(((procs_207068 != null ? procs_207068.length : 0) == l_207491))) { + F.line = 190; + failed_assert_impl_58851(makeNimstrLit("/home/genotrance/programming/nimdevel/lib/system/iterators.nim(190, 11) `len(a) == L` the length of the seq changed while iterating over it")); } } } while(false); } while(false); F.line = 224; - if (new_stuff_197076.kids != null) { new_stuff_197076.kids.push(c_197228); } else { new_stuff_197076.kids = [c_197228]; }; - F.line = 160; - i_197491 = addInt(i_197491, 1); - if (!(((types_197060 != null ? types_197060.length : 0) == l_197492))) { - F.line = 161; - failed_assert_impl_55855(makeNimstrLit("/home/genotrance/programming/nimdevel/lib/system/iterators.nim(161, 11) `len(a) == L` seq modified while iterating over it")); + if (new_stuff_207083.kids != null) { new_stuff_207083.kids.push(c_207228); } else { new_stuff_207083.kids = [c_207228]; }; + F.line = 189; + i_207493 = addInt(i_207493, 1); + if (!(((types_207067 != null ? types_207067.length : 0) == l_207494))) { + F.line = 190; + failed_assert_impl_58851(makeNimstrLit("/home/genotrance/programming/nimdevel/lib/system/iterators.nim(190, 11) `len(a) == L` the length of the seq changed while iterating over it")); } } } while(false); } while(false); F.line = 225; - result_197062 = merge_tocs_197011(orig_197058, new_stuff_197076); + result_207069 = merge_tocs_207017(orig_207065, new_stuff_207083); framePtr = F.prev; - return result_197062; + return result_207069; } -function add_196085(parent_196087, kid_196088) { +function add_206085(parent_206087, kid_206088) { var Tmp1; var Tmp2; var F={procname:"dochack.add",prev:framePtr,filename:"dochack.nim",line:0}; framePtr = F; - if (!(parent_196087.nodeName == "TR")) Tmp1 = false; else { if ((kid_196088.nodeName == "TD")) Tmp2 = true; else { Tmp2 = (kid_196088.nodeName == "TH"); } Tmp1 = Tmp2; } if (Tmp1) { + if (!(parent_206087.nodeName == "TR")) Tmp1 = false; else { if ((kid_206088.nodeName == "TD")) Tmp2 = true; else { Tmp2 = (kid_206088.nodeName == "TH"); } Tmp1 = Tmp2; } if (Tmp1) { F.line = 18; - var k_196089 = document.createElement("TD"); + var k_206089 = document.createElement("TD"); F.line = 19; - k_196089.appendChild(kid_196088); + k_206089.appendChild(kid_206088); F.line = 20; - parent_196087.appendChild(k_196089); + parent_206087.appendChild(k_206089); } else { F.line = 22; - parent_196087.appendChild(kid_196088); + parent_206087.appendChild(kid_206088); } framePtr = F.prev; @@ -1303,490 +1312,490 @@ function add_196085(parent_196087, kid_196088) { } -function set_class_196103(e_196105, value_196106) { +function set_class_206103(e_206105, value_206106) { var F={procname:"dochack.setClass",prev:framePtr,filename:"dochack.nim",line:0}; framePtr = F; F.line = 25; - e_196105.setAttribute("class", toJSStr(value_196106)); + e_206105.setAttribute("class", toJSStr(value_206106)); framePtr = F.prev; } -function to_html_196420(x_196422, is_root_196423) { +function to_html_206424(x_206426, is_root_206427) { var Tmp1; - function HEX3Aanonymous_196463(a_196465, b_196466) { + function HEX3Aanonymous_206467(a_206469, b_206470) { var Tmp1; - var result_196467 = 0; + var result_206471 = 0; var F={procname:"toHtml.:anonymous",prev:framePtr,filename:"dochack.nim",line:0}; framePtr = F; BeforeRet: do { - if (!!((a_196465.heading == null))) Tmp1 = false; else { Tmp1 = !((b_196466.heading == null)); } if (Tmp1) { + if (!!((a_206469.heading == null))) Tmp1 = false; else { Tmp1 = !((b_206470.heading == null)); } if (Tmp1) { F.line = 106; - var x_196484 = a_196465.heading.textContent; + var x_206488 = a_206469.heading.textContent; F.line = 107; - var y_196485 = b_196466.heading.textContent; - if ((x_196484 < y_196485)) { + var y_206489 = b_206470.heading.textContent; + if ((x_206488 < y_206489)) { F.line = 108; - result_196467 = -1; + result_206471 = -1; break BeforeRet; } - if ((y_196485 < x_196484)) { + if ((y_206489 < x_206488)) { F.line = 109; - result_196467 = 1; + result_206471 = 1; break BeforeRet; } F.line = 110; - result_196467 = 0; + result_206471 = 0; break BeforeRet; } else { F.line = 113; - result_196467 = subInt(a_196465.sortId, b_196466.sortId); + result_206471 = subInt(a_206469.sortId, b_206470.sortId); break BeforeRet; } } while (false); framePtr = F.prev; - return result_196467; + return result_206471; } - var result_196424 = null; + var result_206428 = null; var F={procname:"dochack.toHtml",prev:framePtr,filename:"dochack.nim",line:0}; framePtr = F; BeforeRet: do { - if ((x_196422 == null)) { + if ((x_206426 == null)) { F.line = 91; - result_196424 = null; + result_206428 = null; break BeforeRet; } - if (((x_196422.kids != null ? x_196422.kids.length : 0) == 0)) { - if ((x_196422.heading == null)) { + if (((x_206426.kids != null ? x_206426.kids.length : 0) == 0)) { + if ((x_206426.heading == null)) { F.line = 93; - result_196424 = null; + result_206428 = null; break BeforeRet; } F.line = 94; - result_196424 = x_196422.heading.cloneNode(true); + result_206428 = x_206426.heading.cloneNode(true); break BeforeRet; } F.line = 95; - result_196424 = tree_196020(makeNimstrLit("DIV"), []); - if (!!((x_196422.heading == null))) Tmp1 = false; else { Tmp1 = !(x_196422.heading.hasOwnProperty('__karaxMarker__')); } if (Tmp1) { + result_206428 = tree_206020(makeNimstrLit("DIV"), []); + if (!!((x_206426.heading == null))) Tmp1 = false; else { Tmp1 = !(x_206426.heading.hasOwnProperty('__karaxMarker__')); } if (Tmp1) { F.line = 97; - add_196085(result_196424, x_196422.heading.cloneNode(true)); + add_206085(result_206428, x_206426.heading.cloneNode(true)); } F.line = 98; - var ul_196460 = tree_196020(makeNimstrLit("UL"), []); - if (is_root_196423) { + var ul_206464 = tree_206020(makeNimstrLit("UL"), []); + if (is_root_206427) { F.line = 100; - set_class_196103(ul_196460, makeNimstrLit("simple simple-toc")); + set_class_206103(ul_206464, makeNimstrLit("simple simple-toc")); } else { F.line = 102; - set_class_196103(ul_196460, makeNimstrLit("simple")); + set_class_206103(ul_206464, makeNimstrLit("simple")); } - if (x_196422.doSort) { + if (x_206426.doSort) { F.line = 104; - x_196422.kids.sort(HEX3Aanonymous_196463); + x_206426.kids.sort(HEX3Aanonymous_206467); } L2: do { F.line = 115; - var k_196614 = null; - F.line = 154; - var colontmp__197515 = null; + var k_206614 = null; + F.line = 183; + var colontmp__207517 = null; F.line = 115; - colontmp__197515 = x_196422.kids; - F.line = 156; - var i_197517 = 0; - F.line = 157; - var l_197518 = (colontmp__197515 != null ? colontmp__197515.length : 0); + colontmp__207517 = x_206426.kids; + F.line = 185; + var i_207519 = 0; + F.line = 186; + var l_207520 = (colontmp__207517 != null ? colontmp__207517.length : 0); L3: do { - F.line = 158; + F.line = 187; L4: while (true) { - if (!(i_197517 < l_197518)) break L4; + if (!(i_207519 < l_207520)) break L4; F.line = 115; - k_196614 = colontmp__197515[chckIndx(i_197517, 0, colontmp__197515.length+0-1)-0]; + k_206614 = colontmp__207517[chckIndx(i_207519, 0, colontmp__207517.length+0-1)-0]; F.line = 116; - var y_196615 = to_html_196420(k_196614, false); - if (!((y_196615 == null))) { + var y_206615 = to_html_206424(k_206614, false); + if (!((y_206615 == null))) { F.line = 118; - add_196085(ul_196460, tree_196020(makeNimstrLit("LI"), [y_196615])); + add_206085(ul_206464, tree_206020(makeNimstrLit("LI"), [y_206615])); } - F.line = 160; - i_197517 = addInt(i_197517, 1); - if (!(((colontmp__197515 != null ? colontmp__197515.length : 0) == l_197518))) { - F.line = 161; - failed_assert_impl_55855(makeNimstrLit("/home/genotrance/programming/nimdevel/lib/system/iterators.nim(161, 11) `len(a) == L` seq modified while iterating over it")); + F.line = 189; + i_207519 = addInt(i_207519, 1); + if (!(((colontmp__207517 != null ? colontmp__207517.length : 0) == l_207520))) { + F.line = 190; + failed_assert_impl_58851(makeNimstrLit("/home/genotrance/programming/nimdevel/lib/system/iterators.nim(190, 11) `len(a) == L` the length of the seq changed while iterating over it")); } } } while(false); } while(false); - if (!((ul_196460.childNodes.length == 0))) { + if (!((ul_206464.childNodes.length == 0))) { F.line = 119; - add_196085(result_196424, ul_196460); + add_206085(result_206428, ul_206464); } - if ((result_196424.childNodes.length == 0)) { + if ((result_206428.childNodes.length == 0)) { F.line = 120; - result_196424 = null; + result_206428 = null; } } while (false); framePtr = F.prev; - return result_196424; + return result_206428; } -function replace_by_id_196172(id_196174, new_tree_196175) { +function replace_by_id_206172(id_206174, new_tree_206175) { var F={procname:"dochack.replaceById",prev:framePtr,filename:"dochack.nim",line:0}; framePtr = F; F.line = 32; - var x_196176 = document.getElementById(id_196174); + var x_206176 = document.getElementById(id_206174); F.line = 33; - x_196176.parentNode.replaceChild(new_tree_196175, x_196176); + x_206176.parentNode.replaceChild(new_tree_206175, x_206176); F.line = 34; - new_tree_196175.id = id_196174; + new_tree_206175.id = id_206174; framePtr = F.prev; } -function togglevis_197329(d_197331) { +function togglevis_207329(d_207331) { var F={procname:"dochack.togglevis",prev:framePtr,filename:"dochack.nim",line:0}; framePtr = F; F.line = 230; - if (d_197331.style.display == 'none') - d_197331.style.display = 'inline'; + if (d_207331.style.display == 'none') + d_207331.style.display = 'inline'; else - d_197331.style.display = 'none'; + d_207331.style.display = 'none'; framePtr = F.prev; } -function groupBy(value_197347) { +function groupBy(value_207347) { var F={procname:"dochack.groupBy",prev:framePtr,filename:"dochack.nim",line:0}; framePtr = F; F.line = 238; - var toc_197348 = document.getElementById("toc-list"); - if ((alternative_197315[0] == null)) { + var toc_207348 = document.getElementById("toc-list"); + if ((alternative_207315[0] == null)) { F.line = 240; - var tt_197367 = {heading: null, kids: [], sortId: 0, doSort: false}; + var tt_207367 = {heading: null, kids: [], sortId: 0, doSort: false}; F.line = 241; - to_toc_196688(toc_197348, tt_197367); + to_toc_206688(toc_207348, tt_207367); F.line = 242; - tt_197367 = tt_197367.kids[chckIndx(0, 0, tt_197367.kids.length+0-1)-0]; + tt_207367 = tt_207367.kids[chckIndx(0, 0, tt_207367.kids.length+0-1)-0]; F.line = 244; - var types_197382 = [[]]; + var types_207382 = [[]]; F.line = 245; - var procs_197397 = [[]]; + var procs_207397 = [[]]; F.line = 247; - extract_items_196337(tt_197367, "Types", types_197382, 0); + extract_items_206339(tt_207367, "Types", types_207382, 0); F.line = 248; - extract_items_196337(tt_197367, "Procs", procs_197397, 0); + extract_items_206339(tt_207367, "Procs", procs_207397, 0); F.line = 249; - extract_items_196337(tt_197367, "Converters", procs_197397, 0); + extract_items_206339(tt_207367, "Converters", procs_207397, 0); F.line = 250; - extract_items_196337(tt_197367, "Methods", procs_197397, 0); + extract_items_206339(tt_207367, "Methods", procs_207397, 0); F.line = 251; - extract_items_196337(tt_197367, "Templates", procs_197397, 0); + extract_items_206339(tt_207367, "Templates", procs_207397, 0); F.line = 252; - extract_items_196337(tt_197367, "Macros", procs_197397, 0); + extract_items_206339(tt_207367, "Macros", procs_207397, 0); F.line = 253; - extract_items_196337(tt_197367, "Iterators", procs_197397, 0); + extract_items_206339(tt_207367, "Iterators", procs_207397, 0); F.line = 255; - var ntoc_197405 = build_toc_197056(tt_197367, types_197382[0], procs_197397[0]); + var ntoc_207405 = build_toc_207063(tt_207367, types_207382[0], procs_207397[0]); F.line = 256; - var x_197406 = to_html_196420(ntoc_197405, true); + var x_207406 = to_html_206424(ntoc_207405, true); F.line = 257; - alternative_197315[0] = tree_196020(makeNimstrLit("DIV"), [x_197406]); + alternative_207315[0] = tree_206020(makeNimstrLit("DIV"), [x_207406]); } - if ((value_197347 == "type")) { + if ((value_207347 == "type")) { F.line = 259; - replace_by_id_196172("tocRoot", alternative_197315[0]); + replace_by_id_206172("tocRoot", alternative_207315[0]); } else { F.line = 261; - replace_by_id_196172("tocRoot", tree_196020(makeNimstrLit("DIV"), [])); + replace_by_id_206172("tocRoot", tree_206020(makeNimstrLit("DIV"), [])); } F.line = 262; - togglevis_197329(document.getElementById("toc-list")); + togglevis_207329(document.getElementById("toc-list")); framePtr = F.prev; } -var db_197521 = [null]; -var contents_197523 = [null]; -var oldtoc_197957 = [null]; -var timer_197958 = [null]; +var db_207523 = [null]; +var contents_207525 = [null]; +var oldtoc_207959 = [null]; +var timer_207960 = [null]; function raiseRangeError() { - var e_61445 = null; - e_61445 = {m_type: NTI45862, parent: null, name: null, message: null, trace: null, raiseId: 0, up: null}; - e_61445.message = nimCopy(null, makeNimstrLit("value out of range"), NTI42040); - e_61445.parent = null; - raiseException(e_61445, "RangeError"); + var e_65441 = null; + e_65441 = {m_type: NTI47862, parent: null, name: null, message: null, trace: null, raiseId: 0, up: null}; + e_65441.message = nimCopy(null, makeNimstrLit("value out of range"), NTI44040); + e_65441.parent = null; + raiseException(e_65441, "RangeError"); } -function nsuToLowerAsciiChar(c_184980) { - var result_184981 = 0; +function nsuToLowerAsciiChar(c_194780) { + var result_194781 = 0; - var F={procname:"strutils.toLowerAscii",prev:framePtr,filename:"../../lib/pure/strutils.nim",line:0}; + var F={procname:"strutils.toLowerAscii",prev:framePtr,filename:"strutils.nim",line:0}; framePtr = F; - if ((ConstSet2[c_184980] != undefined)) { + if ((ConstSet2[c_194780] != undefined)) { F.line = 222; - result_184981 = chckRange(addInt(c_184980, 32), 0, 255); + result_194781 = chckRange(addInt(c_194780, 32), 0, 255); } else { F.line = 224; - result_184981 = c_184980; + result_194781 = c_194780; } framePtr = F.prev; - return result_184981; + return result_194781; } -function fuzzy_match_195070(pattern_195072, str_195073) { +function fuzzy_match_205070(pattern_205072, str_205073) { var Tmp4; var Tmp5; var Tmp6; - var result_195077 = {Field0: 0, Field1: false}; + var result_205077 = {Field0: 0, Field1: false}; var F={procname:"fuzzysearch.fuzzyMatch",prev:framePtr,filename:"fuzzysearch.nim",line:0}; framePtr = F; F.line = 37; - var score_state_195078 = -100; + var score_state_205078 = -100; F.line = 38; - var header_matched_195079 = false; + var header_matched_205079 = false; F.line = 39; - var unmatched_leading_char_count_195081 = 0; + var unmatched_leading_char_count_205081 = 0; F.line = 40; - var consecutive_match_count_195083 = 0; + var consecutive_match_count_205083 = 0; F.line = 41; - var str_index_195085 = 0; + var str_index_205085 = 0; F.line = 42; - var pat_index_195087 = 0; + var pat_index_205087 = 0; F.line = 43; - var score_195089 = 0; + var score_205089 = 0; L1: do { F.line = 49; L2: while (true) { - if (!((str_index_195085 < (str_195073 != null ? str_195073.length : 0)) && (pat_index_195087 < (pattern_195072 != null ? pattern_195072.length : 0)))) break L2; + if (!((str_index_205085 < (str_205073 != null ? str_205073.length : 0)) && (pat_index_205087 < (pattern_205072 != null ? pattern_205072.length : 0)))) break L2; L3: do { F.line = 51; - var pattern_char_195096 = nsuToLowerAsciiChar(pattern_195072.charCodeAt(chckIndx(pat_index_195087, 0, pattern_195072.length+0-1)-0)); + var pattern_char_205095 = nsuToLowerAsciiChar(pattern_205072.charCodeAt(chckIndx(pat_index_205087, 0, pattern_205072.length+0-1)-0)); F.line = 52; - var str_char_195097 = nsuToLowerAsciiChar(str_195073.charCodeAt(chckIndx(str_index_195085, 0, str_195073.length+0-1)-0)); - if ((ConstSet3[pattern_char_195096] != undefined)) { + var str_char_205096 = nsuToLowerAsciiChar(str_205073.charCodeAt(chckIndx(str_index_205085, 0, str_205073.length+0-1)-0)); + if ((ConstSet3[pattern_char_205095] != undefined)) { F.line = 56; - pat_index_195087 = addInt(pat_index_195087, 1); + pat_index_205087 = addInt(pat_index_205087, 1); F.line = 57; break L3; } - if ((ConstSet4[str_char_195097] != undefined)) { + if ((ConstSet4[str_char_205096] != undefined)) { F.line = 59; - str_index_195085 = addInt(str_index_195085, 1); + str_index_205085 = addInt(str_index_205085, 1); F.line = 60; break L3; } - if ((!(header_matched_195079) && (str_char_195097 == 58))) { + if ((!(header_matched_205079) && (str_char_205096 == 58))) { F.line = 65; - header_matched_195079 = true; + header_matched_205079 = true; F.line = 66; - score_state_195078 = -100; + score_state_205078 = -100; F.line = 67; - score_195089 = Math.trunc(Math.floor((5.0000000000000000e-01 * score_195089))); + score_205089 = Math.trunc(Math.floor((5.0000000000000000e-01 * score_205089))); F.line = 68; - pat_index_195087 = 0; + pat_index_205087 = 0; F.line = 69; - str_index_195085 = addInt(str_index_195085, 1); + str_index_205085 = addInt(str_index_205085, 1); F.line = 70; break L3; } - if ((str_char_195097 == pattern_char_195096)) { + if ((str_char_205096 == pattern_char_205095)) { F.line = 73; - switch (score_state_195078) { + switch (score_state_205078) { case -100: case 20: F.line = 75; - score_state_195078 = 10; + score_state_205078 = 10; break; case 0: F.line = 78; - score_state_195078 = 5; + score_state_205078 = 5; F.line = 78; - score_195089 = addInt(score_195089, score_state_195078); + score_205089 = addInt(score_205089, score_state_205078); break; case 10: case 5: F.line = 81; - consecutive_match_count_195083 = addInt(consecutive_match_count_195083, 1); + consecutive_match_count_205083 = addInt(consecutive_match_count_205083, 1); F.line = 82; - score_state_195078 = 5; + score_state_205078 = 5; F.line = 83; - score_195089 = addInt(score_195089, mulInt(5, consecutive_match_count_195083)); - if ((score_state_195078 == 10)) { + score_205089 = addInt(score_205089, mulInt(5, consecutive_match_count_205083)); + if ((score_state_205078 == 10)) { F.line = 86; - score_195089 = addInt(score_195089, 10); + score_205089 = addInt(score_205089, 10); } F.line = 88; - var on_boundary_195172 = (pat_index_195087 == (pattern_195072 != null ? (pattern_195072.length-1) : -1)); - if ((!(on_boundary_195172) && (str_index_195085 < (str_195073 != null ? (str_195073.length-1) : -1)))) { + var on_boundary_205171 = (pat_index_205087 == (pattern_205072 != null ? (pattern_205072.length-1) : -1)); + if ((!(on_boundary_205171) && (str_index_205085 < (str_205073 != null ? (str_205073.length-1) : -1)))) { F.line = 91; - var next_pattern_char_195173 = nsuToLowerAsciiChar(pattern_195072.charCodeAt(chckIndx(addInt(pat_index_195087, 1), 0, pattern_195072.length+0-1)-0)); + var next_pattern_char_205172 = nsuToLowerAsciiChar(pattern_205072.charCodeAt(chckIndx(addInt(pat_index_205087, 1), 0, pattern_205072.length+0-1)-0)); F.line = 92; - var next_str_char_195174 = nsuToLowerAsciiChar(str_195073.charCodeAt(chckIndx(addInt(str_index_195085, 1), 0, str_195073.length+0-1)-0)); + var next_str_char_205173 = nsuToLowerAsciiChar(str_205073.charCodeAt(chckIndx(addInt(str_index_205085, 1), 0, str_205073.length+0-1)-0)); F.line = 95; - if (!!((ConstSet5[next_str_char_195174] != undefined))) Tmp4 = false; else { Tmp4 = !((next_str_char_195174 == next_pattern_char_195173)); } on_boundary_195172 = Tmp4; + if (!!((ConstSet5[next_str_char_205173] != undefined))) Tmp4 = false; else { Tmp4 = !((next_str_char_205173 == next_pattern_char_205172)); } on_boundary_205171 = Tmp4; } - if (on_boundary_195172) { + if (on_boundary_205171) { F.line = 100; - score_state_195078 = 20; + score_state_205078 = 20; F.line = 100; - score_195089 = addInt(score_195089, score_state_195078); + score_205089 = addInt(score_205089, score_state_205078); } break; case -1: case -3: F.line = 103; - if (!((ConstSet6[str_195073.charCodeAt(chckIndx(subInt(str_index_195085, 1), 0, str_195073.length+0-1)-0)] != undefined))) Tmp5 = true; else { if (!(ConstSet7[str_195073.charCodeAt(chckIndx(subInt(str_index_195085, 1), 0, str_195073.length+0-1)-0)] != undefined)) Tmp6 = false; else { Tmp6 = (ConstSet8[str_195073.charCodeAt(chckIndx(str_index_195085, 0, str_195073.length+0-1)-0)] != undefined); } Tmp5 = Tmp6; } var is_leading_char_195212 = Tmp5; - if (is_leading_char_195212) { + if (!((ConstSet6[str_205073.charCodeAt(chckIndx(subInt(str_index_205085, 1), 0, str_205073.length+0-1)-0)] != undefined))) Tmp5 = true; else { if (!(ConstSet7[str_205073.charCodeAt(chckIndx(subInt(str_index_205085, 1), 0, str_205073.length+0-1)-0)] != undefined)) Tmp6 = false; else { Tmp6 = (ConstSet8[str_205073.charCodeAt(chckIndx(str_index_205085, 0, str_205073.length+0-1)-0)] != undefined); } Tmp5 = Tmp6; } var is_leading_char_205211 = Tmp5; + if (is_leading_char_205211) { F.line = 110; - score_state_195078 = 10; + score_state_205078 = 10; } else { F.line = 114; - score_state_195078 = 0; + score_state_205078 = 0; F.line = 114; - score_195089 = addInt(score_195089, score_state_195078); + score_205089 = addInt(score_205089, score_state_205078); } break; } F.line = 115; - pat_index_195087 = addInt(pat_index_195087, 1); + pat_index_205087 = addInt(pat_index_205087, 1); } else { F.line = 118; - switch (score_state_195078) { + switch (score_state_205078) { case -100: F.line = 120; - score_state_195078 = -3; + score_state_205078 = -3; F.line = 120; - score_195089 = addInt(score_195089, score_state_195078); + score_205089 = addInt(score_205089, score_state_205078); break; case 5: F.line = 123; - score_state_195078 = -1; + score_state_205078 = -1; F.line = 123; - score_195089 = addInt(score_195089, score_state_195078); + score_205089 = addInt(score_205089, score_state_205078); F.line = 124; - consecutive_match_count_195083 = 0; + consecutive_match_count_205083 = 0; break; case -3: - if ((unmatched_leading_char_count_195081 < 3)) { + if ((unmatched_leading_char_count_205081 < 3)) { F.line = 128; - score_state_195078 = -3; + score_state_205078 = -3; F.line = 128; - score_195089 = addInt(score_195089, score_state_195078); + score_205089 = addInt(score_205089, score_state_205078); } F.line = 129; - unmatched_leading_char_count_195081 = addInt(unmatched_leading_char_count_195081, 1); + unmatched_leading_char_count_205081 = addInt(unmatched_leading_char_count_205081, 1); break; default: F.line = 132; - score_state_195078 = -1; + score_state_205078 = -1; F.line = 132; - score_195089 = addInt(score_195089, score_state_195078); + score_205089 = addInt(score_205089, score_state_205078); break; } } F.line = 134; - str_index_195085 = addInt(str_index_195085, 1); + str_index_205085 = addInt(str_index_205085, 1); } while(false); } } while(false); F.line = 137; - var colontmp__198061 = nimMax(0, score_195089); + var colontmp__208063 = nimMax(0, score_205089); F.line = 138; - var colontmp__198062 = (0 < score_195089); + var colontmp__208064 = (0 < score_205089); F.line = 136; - nimCopy(result_195077, {Field0: colontmp__198061, Field1: colontmp__198062}, NTI195074); + nimCopy(result_205077, {Field0: colontmp__208063, Field1: colontmp__208064}, NTI205074); framePtr = F.prev; - return result_195077; + return result_205077; } -function text_196120(s_196122) { - var result_196123 = null; +function text_206120(s_206122) { + var result_206123 = null; var F={procname:"dochack.text",prev:framePtr,filename:"dochack.nim",line:0}; framePtr = F; F.line = 26; - result_196123 = document.createTextNode(toJSStr(s_196122)); + result_206123 = document.createTextNode(toJSStr(s_206122)); framePtr = F.prev; - return result_196123; + return result_206123; } -function dosearch_197555(value_197557) { +function dosearch_207557(value_207559) { - function HEX3Aanonymous_197870(a_197879, b_197880) { - var result_197884 = 0; + function HEX3Aanonymous_207871(a_207880, b_207881) { + var result_207885 = 0; var F={procname:"dosearch.:anonymous",prev:framePtr,filename:"dochack.nim",line:0}; framePtr = F; F.line = 305; - result_197884 = subInt(b_197880["Field1"], a_197879["Field1"]); + result_207885 = subInt(b_207881["Field1"], a_207880["Field1"]); framePtr = F.prev; - return result_197884; + return result_207885; } - var result_197558 = null; + var result_207560 = null; var F={procname:"dochack.dosearch",prev:framePtr,filename:"dochack.nim",line:0}; framePtr = F; - if (((db_197521[0] != null ? db_197521[0].length : 0) == 0)) { + if (((db_207523[0] != null ? db_207523[0].length : 0) == 0)) { F.line = 272; - var stuff_197564 = null; + var stuff_207566 = null; F.line = 273; var request = new XMLHttpRequest(); request.open("GET", "theindex.html", false); @@ -1798,32 +1807,32 @@ function dosearch_197555(value_197557) { //parser=new DOMParser(); //doc=parser.parseFromString("", "text/html"); - stuff_197564 = doc.documentElement; + stuff_207566 = doc.documentElement; F.line = 286; - db_197521[0] = nimCopy(null, stuff_197564.getElementsByClassName("reference"), NTI83305); + db_207523[0] = nimCopy(null, stuff_207566.getElementsByClassName("reference"), NTI87305); F.line = 287; - contents_197523[0] = nimCopy(null, [], NTI197577); + contents_207525[0] = nimCopy(null, [], NTI207579); L1: do { F.line = 288; - var ahref_197814 = null; - F.line = 156; - var i_198041 = 0; - F.line = 157; - var l_198042 = (db_197521[0] != null ? db_197521[0].length : 0); + var ahref_207814 = null; + F.line = 185; + var i_208043 = 0; + F.line = 186; + var l_208044 = (db_207523[0] != null ? db_207523[0].length : 0); L2: do { - F.line = 158; + F.line = 187; L3: while (true) { - if (!(i_198041 < l_198042)) break L3; + if (!(i_208043 < l_208044)) break L3; F.line = 288; - ahref_197814 = db_197521[0][chckIndx(i_198041, 0, db_197521[0].length+0-1)-0]; + ahref_207814 = db_207523[0][chckIndx(i_208043, 0, db_207523[0].length+0-1)-0]; F.line = 289; - if (contents_197523[0] != null) { contents_197523[0].push(ahref_197814.getAttribute("data-doc-search-tag")); } else { contents_197523[0] = [ahref_197814.getAttribute("data-doc-search-tag")]; }; - F.line = 160; - i_198041 = addInt(i_198041, 1); - if (!(((db_197521[0] != null ? db_197521[0].length : 0) == l_198042))) { - F.line = 161; - failed_assert_impl_55855(makeNimstrLit("/home/genotrance/programming/nimdevel/lib/system/iterators.nim(161, 11) `len(a) == L` seq modified while iterating over it")); + if (contents_207525[0] != null) { contents_207525[0].push(ahref_207814.getAttribute("data-doc-search-tag")); } else { contents_207525[0] = [ahref_207814.getAttribute("data-doc-search-tag")]; }; + F.line = 189; + i_208043 = addInt(i_208043, 1); + if (!(((db_207523[0] != null ? db_207523[0].length : 0) == l_208044))) { + F.line = 190; + failed_assert_impl_58851(makeNimstrLit("/home/genotrance/programming/nimdevel/lib/system/iterators.nim(190, 11) `len(a) == L` the length of the seq changed while iterating over it")); } } @@ -1832,126 +1841,126 @@ function dosearch_197555(value_197557) { } F.line = 290; - var ul_197825 = tree_196020(makeNimstrLit("UL"), []); + var ul_207825 = tree_206020(makeNimstrLit("UL"), []); F.line = 291; - result_197558 = tree_196020(makeNimstrLit("DIV"), []); + result_207560 = tree_206020(makeNimstrLit("DIV"), []); F.line = 292; - set_class_196103(result_197558, makeNimstrLit("search_results")); + set_class_206103(result_207560, makeNimstrLit("search_results")); F.line = 293; - var matches_197844 = []; + var matches_207844 = []; L4: do { F.line = 294; - var i_197856 = 0; - F.line = 2638; - var colontmp__198048 = 0; + var i_207857 = 0; + F.line = 2716; + var colontmp__208050 = 0; F.line = 294; - colontmp__198048 = (db_197521[0] != null ? db_197521[0].length : 0); - F.line = 2639; - var i_198049 = 0; + colontmp__208050 = (db_207523[0] != null ? db_207523[0].length : 0); + F.line = 2717; + var i_208051 = 0; L5: do { - F.line = 2640; + F.line = 2718; L6: while (true) { - if (!(i_198049 < colontmp__198048)) break L6; + if (!(i_208051 < colontmp__208050)) break L6; F.line = 294; - i_197856 = i_198049; + i_207857 = i_208051; L7: do { F.line = 295; - var c_197857 = contents_197523[0][chckIndx(i_197856, 0, contents_197523[0].length+0-1)-0]; - if (((c_197857 == "Examples") || (c_197857 == "PEG construction"))) { + var c_207858 = contents_207525[0][chckIndx(i_207857, 0, contents_207525[0].length+0-1)-0]; + if (((c_207858 == "Examples") || (c_207858 == "PEG construction"))) { F.line = 300; break L7; } F.line = 301; - var colontmp__198058 = {Field0: 0, Field1: false}; + var colontmp__208060 = {Field0: 0, Field1: false}; F.line = 301; - var score_197858 = 0; + var score_207859 = 0; F.line = 301; - var matched_197859 = false; + var matched_207860 = false; F.line = 301; - nimCopy(colontmp__198058, fuzzy_match_195070(value_197557, c_197857), NTI195074); + nimCopy(colontmp__208060, fuzzy_match_205070(value_207559, c_207858), NTI205074); F.line = 301; - score_197858 = colontmp__198058["Field0"]; + score_207859 = colontmp__208060["Field0"]; F.line = 301; - matched_197859 = colontmp__198058["Field1"]; - if (matched_197859) { + matched_207860 = colontmp__208060["Field1"]; + if (matched_207860) { F.line = 303; - if (matches_197844 != null) { matches_197844.push({Field0: db_197521[0][chckIndx(i_197856, 0, db_197521[0].length+0-1)-0], Field1: score_197858}); } else { matches_197844 = [{Field0: db_197521[0][chckIndx(i_197856, 0, db_197521[0].length+0-1)-0], Field1: score_197858}]; }; + if (matches_207844 != null) { matches_207844.push({Field0: db_207523[0][chckIndx(i_207857, 0, db_207523[0].length+0-1)-0], Field1: score_207859}); } else { matches_207844 = [{Field0: db_207523[0][chckIndx(i_207857, 0, db_207523[0].length+0-1)-0], Field1: score_207859}]; }; } } while(false); - F.line = 2642; - i_198049 = addInt(i_198049, 1); + F.line = 2720; + i_208051 = addInt(i_208051, 1); } } while(false); } while(false); F.line = 305; - matches_197844.sort(HEX3Aanonymous_197870); + matches_207844.sort(HEX3Aanonymous_207871); L8: do { F.line = 306; - var i_197922 = 0; - F.line = 2638; - var colontmp__198054 = 0; + var i_207924 = 0; + F.line = 2716; + var colontmp__208056 = 0; F.line = 306; - colontmp__198054 = nimMin((matches_197844 != null ? matches_197844.length : 0), 19); - F.line = 2639; - var i_198055 = 0; + colontmp__208056 = nimMin((matches_207844 != null ? matches_207844.length : 0), 19); + F.line = 2717; + var i_208057 = 0; L9: do { - F.line = 2640; + F.line = 2718; L10: while (true) { - if (!(i_198055 < colontmp__198054)) break L10; + if (!(i_208057 < colontmp__208056)) break L10; F.line = 306; - i_197922 = i_198055; + i_207924 = i_208057; F.line = 307; - matches_197844[chckIndx(i_197922, 0, matches_197844.length+0-1)-0]["Field0"].innerHTML = matches_197844[chckIndx(i_197922, 0, matches_197844.length+0-1)-0]["Field0"].getAttribute("data-doc-search-tag"); + matches_207844[chckIndx(i_207924, 0, matches_207844.length+0-1)-0]["Field0"].innerHTML = matches_207844[chckIndx(i_207924, 0, matches_207844.length+0-1)-0]["Field0"].getAttribute("data-doc-search-tag"); F.line = 308; - add_196085(ul_197825, tree_196020(makeNimstrLit("LI"), [matches_197844[chckIndx(i_197922, 0, matches_197844.length+0-1)-0]["Field0"]])); - F.line = 2642; - i_198055 = addInt(i_198055, 1); + add_206085(ul_207825, tree_206020(makeNimstrLit("LI"), [matches_207844[chckIndx(i_207924, 0, matches_207844.length+0-1)-0]["Field0"]])); + F.line = 2720; + i_208057 = addInt(i_208057, 1); } } while(false); } while(false); - if ((ul_197825.childNodes.length == 0)) { + if ((ul_207825.childNodes.length == 0)) { F.line = 310; - add_196085(result_197558, tree_196020(makeNimstrLit("B"), [text_196120(makeNimstrLit("no search results"))])); + add_206085(result_207560, tree_206020(makeNimstrLit("B"), [text_206120(makeNimstrLit("no search results"))])); } else { F.line = 312; - add_196085(result_197558, tree_196020(makeNimstrLit("B"), [text_196120(makeNimstrLit("search results"))])); + add_206085(result_207560, tree_206020(makeNimstrLit("B"), [text_206120(makeNimstrLit("search results"))])); F.line = 313; - add_196085(result_197558, ul_197825); + add_206085(result_207560, ul_207825); } framePtr = F.prev; - return result_197558; + return result_207560; } function search() { - function wrapper_197989() { + function wrapper_207991() { var F={procname:"search.wrapper",prev:framePtr,filename:"dochack.nim",line:0}; framePtr = F; F.line = 320; - var elem_197991 = document.getElementById("searchInput"); + var elem_207993 = document.getElementById("searchInput"); F.line = 321; - var value_197992 = elem_197991.value; - if (!(((value_197992 != null ? value_197992.length : 0) == 0))) { - if ((oldtoc_197957[0] == null)) { + var value_207994 = elem_207993.value; + if (!(((value_207994 != null ? value_207994.length : 0) == 0))) { + if ((oldtoc_207959[0] == null)) { F.line = 324; - oldtoc_197957[0] = document.getElementById("tocRoot"); + oldtoc_207959[0] = document.getElementById("tocRoot"); } F.line = 325; - var results_197998 = dosearch_197555(value_197992); + var results_208000 = dosearch_207557(value_207994); F.line = 326; - replace_by_id_196172("tocRoot", results_197998); + replace_by_id_206172("tocRoot", results_208000); } else { - if (!((oldtoc_197957[0] == null))) { + if (!((oldtoc_207959[0] == null))) { F.line = 328; - replace_by_id_196172("tocRoot", oldtoc_197957[0]); + replace_by_id_206172("tocRoot", oldtoc_207959[0]); } } framePtr = F.prev; @@ -1961,13 +1970,13 @@ function search() { var F={procname:"dochack.search",prev:framePtr,filename:"dochack.nim",line:0}; framePtr = F; - if (!((timer_197958[0] == null))) { + if (!((timer_207960[0] == null))) { F.line = 330; - clearTimeout(timer_197958[0]); + clearTimeout(timer_207960[0]); } F.line = 331; - timer_197958[0] = setTimeout(wrapper_197989, 400); + timer_207960[0] = setTimeout(wrapper_207991, 400); framePtr = F.prev; diff --git a/git.html b/git.html old mode 100755 new mode 100644 index 35225ee..dfaf0fb --- a/git.html +++ b/git.html @@ -27,232 +27,130 @@ customize this style sheet. Modified from Chad Skeeters' rst2html-style https://bitbucket.org/cskeeters/rst2html-style/ -Modified by Boyd Greenfield +Modified by Boyd Greenfield and narimiran */ -/* SCSS variables */ -/* Text weights */ -/* Body colors */ -/* Text colors */ -/* Link colors */ -/* Syntax highlighting colors */ -/* Pct changes */ -/* Mixins */ -/* Body/layout */ + html { font-size: 100%; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; } -/* Where we want fancier font if available */ -h1, h2, h3, h4, h5, h6, p.module-desc, table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; } - -h1.title { - font-weight: 900; } - body { font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: 400; - font-size: 16px; - line-height: 20px; - color: #444; - letter-spacing: 0.15px; - background-color: #FDFBFA; } + font-size: 1.125em; + line-height: 1.5; + color: #222; + background-color: #FCFCFC; } /* Skeleton grid */ .container { position: relative; width: 100%; - max-width: 960px; + max-width: 1050px; margin: 0 auto; - padding: 0 20px; + padding: 0; box-sizing: border-box; } .column, .columns { width: 100%; float: left; - box-sizing: border-box; } + box-sizing: border-box; + margin-left: 1%; +} -/* For devices larger than 400px */ -@media (min-width: 400px) { - .container { - width: 100%; - padding: 0; } } -/* For devices larger than 650px */ -@media (min-width: 650px) { - .container { - width: 100%; } +.column:first-child, +.columns:first-child { + margin-left: 0; } - .column, - .columns { - margin-left: 4%; } +.three.columns { + width: 19%; } - .column:first-child, - .columns:first-child { - margin-left: 0; } +.nine.columns { + width: 80.0%; } - .one.column, - .one.columns { - width: 4.66666666667%; } - - .two.columns { - width: 13.3333333333%; } +.twelve.columns { + width: 100%; + margin-left: 0; } +@media screen and (max-width: 860px) { .three.columns { - width: 22%; } - - .four.columns { - width: 30.6666666667%; } - - .five.columns { - width: 39.3333333333%; } - - .six.columns { - width: 48%; } - - .seven.columns { - width: 56.6666666667%; } - - .eight.columns { - width: 65.3333333333%; } - + display: none; + } .nine.columns { - width: 74.0%; } - - .ten.columns { - width: 82.6666666667%; } - - .eleven.columns { - width: 91.3333333333%; } - - .twelve.columns { - width: 100%; - margin-left: 0; } - - .one-third.column { - width: 30.6666666667%; } - - .two-thirds.column { - width: 65.3333333333%; } } -/* Customer Overrides */ -.footer { - text-align: center; - color: #969696; - padding-top: 10%; } - -p.module-desc { - font-size: 1.1em; - color: #666666; } - -a.link-seesrc { - color: #aec7d2; - font-style: italic; } - -a.link-seesrc:hover { - color: #6c9aae; } - -#toc-list { - word-wrap: break-word; } - -ul.simple-toc { - list-style: none; } - -ul.simple-toc a.reference-toplevel { - font-weight: bold; - color: #0077b3; } - -ul.simple-toc-section { - list-style-type: circle; - color: #6c9aae; } - -ul.simple-toc-section a.reference { - color: #0077b3; } + width: 98.0%; + } + body { + font-size: 1em; + line-height: 1.35; + } +} cite { font-style: italic !important; } -dt > pre { - border-color: rgba(0, 0, 0, 0.1); - background-color: rgba(255, 255, 255, 0.3); - margin: 15px 0px 5px; } - -dd > pre { - border-color: rgba(0, 0, 0, 0.1); - background-color: whitesmoke; - margin-top: 8px; } - -.item > dd { - margin-left: 10px; - margin-bottom: 30px; } - -/* Nim line-numbered tables */ -.line-nums-table { - width: 100%; - table-layout: fixed; } /* Nim search input */ div#searchInputDiv { - margin-bottom: 8px; + margin-bottom: 1em; } -div#searchInputDiv input#searchInput { - width: 10em; -} -div.search-groupby { - margin-bottom: 8px; +input#searchInput { + width: 80%; } -table.line-nums-table { - border-radius: 4px; - border: 1px solid #cccccc; - background-color: whitesmoke; - border-collapse: separate; - margin-top: 15px; - margin-bottom: 25px; } - -.line-nums-table tbody { - border: none; } - -.line-nums-table td pre { - border: none; - background-color: transparent; } - -.line-nums-table td.blob-line-nums { - width: 28px; } - -.line-nums-table td.blob-line-nums pre { - color: #b0b0b0; - -webkit-filter: opacity(75%); - text-align: right; - border-color: transparent; - background-color: transparent; - padding-left: 0px; - margin-left: 0px; - padding-right: 0px; - margin-right: 0px; } +/* + * Some custom formatting for input forms. + * This also fixes input form colors on Firefox with a dark system theme on Linux. + */ +input { + -moz-appearance: none; + color: #333; + background-color: #f8f8f8; + border: 1px solid #aaa; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-size: 0.9em; + padding: 6px; +} +input:focus { + border: 1px solid #1fa0eb; + box-shadow: 0 0 2px #1fa0eb; +} /* Docgen styles */ /* Links */ a { - color: #0077b3; - text-decoration: none; } + color: #07b; + text-decoration: none; +} + +a span.Identifier { + text-decoration: underline; + text-decoration-color: #aab; +} + +a.reference-toplevel { + font-weight: bold; +} + +a.toc-backref { + text-decoration: none; + color: #222; } + +a.link-seesrc { + color: #607c9f; + font-size: 0.9em; + font-style: italic; } a:hover, a:focus { - color: #00334d; + color: #607c9f; text-decoration: underline; } -a:visited { - color: #00334d; } +a:hover span.Identifier { + color: #607c9f; +} -a:focus { - outline: thin dotted #2d2d2d; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; } - -a:hover, -a:active { - outline: 0; } sub, sup { @@ -329,379 +227,258 @@ img { h2, h3 { - page-break-after: avoid; } } -.img-rounded { - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; } + page-break-after: avoid; } +} -.img-polaroid { - padding: 4px; - background-color: rgba(252, 248, 244, 0.75); - border: 1px solid #ccc; - border: 1px solid rgba(0, 0, 0, 0.2); - -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); - -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); } p { - margin: 0 0 8px; } + margin-top: 0.5em; + margin-bottom: 0.5em; +} small { font-size: 85%; } strong { - font-weight: 600; } + font-weight: 600; + font-size: 0.95em; + color: #3c3c3c; +} em { font-style: italic; } -cite { - font-style: normal; } - -h1, -h2, -h3, -h4, -h5, -h6 { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-weight: 600; - line-height: 20px; - color: inherit; - text-rendering: optimizelegibility; } - h1 { - font-size: 2em; + font-size: 1.8em; font-weight: 400; - padding-bottom: .15em; - border-bottom: 1px solid #aaaaaa; - margin-top: 1.0em; + padding-bottom: .25em; + border-bottom: 1px solid #aaa; + margin-top: 2.5em; + margin-bottom: 1em; line-height: 1.2em; } h1.title { padding-bottom: 1em; border-bottom: 0px; - font-size: 2.75em; } + font-size: 2.5em; + text-align: center; + font-weight: 900; + margin-top: 0.75em; + margin-bottom: 0em; +} h2 { - font-size: 1.5em; - margin-top: 1.5em; } + font-size: 1.3em; + margin-top: 2em; } + +h2.subtitle { + text-align: center; } h3 { - font-size: 1.3em; + font-size: 1.125em; font-style: italic; - margin-top: 0.75em; } + margin-top: 1.5em; } h4 { - font-size: 1.3em; - margin-top: 0.5em; } + font-size: 1.125em; + margin-top: 1em; } h5 { - font-size: 1.2em; - margin-top: 0.25em; } + font-size: 1.125em; + margin-top: 0.75em; } h6 { font-size: 1.1em; } + ul, ol { padding: 0; - margin: 0 0 0px 15px; } + margin-top: 0.5em; + margin-left: 0.75em; } ul ul, ul ol, ol ol, ol ul { - margin-bottom: 0; } + margin-bottom: 0; + margin-left: 1.25em; } li { - line-height: 20px; } - -dl { - margin-bottom: 20px; } - -dt, -dd { - line-height: 20px; } - -dt { - font-weight: bold; } - -dd { - margin-left: 10px; - margin-bottom: 26px; } - -hr { - margin: 20px 0; - border: 0; - border-top: 1px solid #eeeeee; - border-bottom: 1px solid #ffffff; } - -abbr[title], -abbr[data-original-title] { - cursor: help; - border-bottom: 1px dotted #999999; } - -abbr.initialism { - font-size: 90%; - text-transform: uppercase; } - -blockquote { - padding: 0 0 0 15px; - margin: 0 0 20px; - border-left: 5px solid #EFEBE0; } - -table.docinfo + blockquote, table.docinfo blockquote, h1 + blockquote { - border-left: 5px solid #c9c9c9; + list-style-type: circle; } -table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { - margin-bottom: 0; - font-size: 15px; - font-weight: 200; - line-height: 1.5; - font-style: italic; } +ul.simple-boot li { + list-style-type: none; + margin-left: 0em; + margin-bottom: 0.5em; +} -q:before, -q:after, -blockquote:before, -blockquote:after { - content: ""; } +ol.simple > li, ul.simple > li { + margin-bottom: 0.25em; + margin-left: 0.4em } -address { - display: block; - margin-bottom: 20px; - font-style: normal; - line-height: 20px; } +ul.simple.simple-toc > li { + margin-top: 1em; +} -code, -pre { - font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - padding: 0 3px 2px; - font-weight: 500; - font-size: 12px; - color: #444444; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; } +ul.simple-toc { + list-style: none; + font-size: 0.9em; + margin-left: -0.3em; + margin-top: 1em; } + +ul.simple-toc > li { + list-style-type: none; +} + +ul.simple-toc-section { + list-style-type: circle; + margin-left: 1em; + color: #6c9aae; } + + +ol.arabic { + list-style: decimal; } + +ol.loweralpha { + list-style: lower-alpha; } + +ol.upperalpha { + list-style: upper-alpha; } + +ol.lowerroman { + list-style: lower-roman; } + +ol.upperroman { + list-style: upper-roman; } + +ul.auto-toc { + list-style-type: none; } + + +dl { + margin-bottom: 1.5em; } + +dt { + margin-bottom: -0.5em; + margin-left: 0.0em; } + +dd { + margin-left: 2.0em; + margin-bottom: 3.0em; + margin-top: 0.5em; } + + +hr { + margin: 2em 0; + border: 0; + border-top: 1px solid #aaa; } + +blockquote { + font-size: 0.9em; + font-style: italic; + padding-left: 0.5em; + margin-left: 0; + border-left: 5px solid #bbc; +} .pre { font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - font-weight: 600; - /*color: #504da6;*/ + font-weight: 500; + font-size: 0.85em; + background-color: #f0f3ff; + padding-left: 3px; + padding-right: 3px; + border-radius: 4px; } -code { - padding: 2px 4px; - color: #444444; - white-space: nowrap; - background-color: white; - border: 1px solid #777777; } - pre { + font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; + color: #222; + font-weight: 500; display: inline-block; box-sizing: border-box; - min-width: calc(100% - 19.5px); - padding: 9.5px; - margin: 0.25em 10px 10px 10px; - font-size: 15px; - line-height: 20px; + min-width: 100%; + padding: 0.5em; + margin-top: 0.5em; + margin-bottom: 0.5em; + font-size: 0.85em; white-space: pre !important; overflow-y: hidden; overflow-x: visible; - background-color: rgba(0, 0, 0, 0.01); - border: 1px solid #cccccc; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; } - -pre.prettyprint { - margin-bottom: 20px; } - -pre code { - padding: 0; - color: inherit; - white-space: pre; - overflow-x: visible; - background-color: transparent; - border: 0; } + background-color: ghostwhite; + border: 1px solid #dde; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; } .pre-scrollable { max-height: 340px; overflow-y: scroll; } + +/* Nim line-numbered tables */ +.line-nums-table { + width: 100%; + table-layout: fixed; } + +table.line-nums-table { + border-radius: 4px; + border: 1px solid #cccccc; + background-color: ghostwhite; + border-collapse: separate; + margin-top: 15px; + margin-bottom: 25px; } + +.line-nums-table tbody { + border: none; } + +.line-nums-table td pre { + border: none; + background-color: transparent; } + +.line-nums-table td.blob-line-nums { + width: 28px; } + +.line-nums-table td.blob-line-nums pre { + color: #b0b0b0; + -webkit-filter: opacity(75%); + text-align: right; + border-color: transparent; + background-color: transparent; + padding-left: 0px; + margin-left: 0px; + padding-right: 0px; + margin-right: 0px; } + + table { max-width: 100%; background-color: transparent; + margin-top: 0.5em; + margin-bottom: 1.5em; border-collapse: collapse; - border-spacing: 0; } - -table th, table td { - padding: 0px 8px 0px; + border-color: #ccc; + border-spacing: 0; + font-size: 0.9em; } -.table { - width: 100%; - margin-bottom: 20px; } +table th, table td { + padding: 0px 0.5em 0px; +} -.table th, -.table td { - padding: 8px; - line-height: 20px; - text-align: left; - vertical-align: top; - border-top: 1px solid #444444; } - -.table th { +table th { + background-color: #e8e8e8; font-weight: bold; } -.table thead th { - vertical-align: bottom; } +table th.docinfo-name { + background-color: transparent; +} -.table caption + thead tr:first-child th, -.table caption + thead tr:first-child td, -.table colgroup + thead tr:first-child th, -.table colgroup + thead tr:first-child td, -.table thead:first-child tr:first-child th, -.table thead:first-child tr:first-child td { - border-top: 0; } +table tr:hover { + background-color: ghostwhite; } -.table tbody + tbody { - border-top: 2px solid #444444; } - -.table .table { - background-color: rgba(252, 248, 244, 0.75); } - -.table-condensed th, -.table-condensed td { - padding: 4px 5px; } - -.table-bordered { - border: 1px solid #444444; - border-collapse: separate; - *border-collapse: collapse; - border-left: 0; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; } - -.table-bordered th, -.table-bordered td { - border-left: 1px solid #444444; } - -.table-bordered caption + thead tr:first-child th, -.table-bordered caption + tbody tr:first-child th, -.table-bordered caption + tbody tr:first-child td, -.table-bordered colgroup + thead tr:first-child th, -.table-bordered colgroup + tbody tr:first-child th, -.table-bordered colgroup + tbody tr:first-child td, -.table-bordered thead:first-child tr:first-child th, -.table-bordered tbody:first-child tr:first-child th, -.table-bordered tbody:first-child tr:first-child td { - border-top: 0; } - -.table-bordered thead:first-child tr:first-child > th:first-child, -.table-bordered tbody:first-child tr:first-child > td:first-child, -.table-bordered tbody:first-child tr:first-child > th:first-child { - -webkit-border-top-left-radius: 4px; - border-top-left-radius: 4px; - -moz-border-radius-topleft: 4px; } - -.table-bordered thead:first-child tr:first-child > th:last-child, -.table-bordered tbody:first-child tr:first-child > td:last-child, -.table-bordered tbody:first-child tr:first-child > th:last-child { - -webkit-border-top-right-radius: 4px; - border-top-right-radius: 4px; - -moz-border-radius-topright: 4px; } - -.table-bordered thead:last-child tr:last-child > th:first-child, -.table-bordered tbody:last-child tr:last-child > td:first-child, -.table-bordered tbody:last-child tr:last-child > th:first-child, -.table-bordered tfoot:last-child tr:last-child > td:first-child, -.table-bordered tfoot:last-child tr:last-child > th:first-child { - -webkit-border-bottom-left-radius: 4px; - border-bottom-left-radius: 4px; - -moz-border-radius-bottomleft: 4px; } - -.table-bordered thead:last-child tr:last-child > th:last-child, -.table-bordered tbody:last-child tr:last-child > td:last-child, -.table-bordered tbody:last-child tr:last-child > th:last-child, -.table-bordered tfoot:last-child tr:last-child > td:last-child, -.table-bordered tfoot:last-child tr:last-child > th:last-child { - -webkit-border-bottom-right-radius: 4px; - border-bottom-right-radius: 4px; - -moz-border-radius-bottomright: 4px; } - -.table-bordered tfoot + tbody:last-child tr:last-child td:first-child { - -webkit-border-bottom-left-radius: 0; - border-bottom-left-radius: 0; - -moz-border-radius-bottomleft: 0; } - -.table-bordered tfoot + tbody:last-child tr:last-child td:last-child { - -webkit-border-bottom-right-radius: 0; - border-bottom-right-radius: 0; - -moz-border-radius-bottomright: 0; } - -.table-bordered caption + thead tr:first-child th:first-child, -.table-bordered caption + tbody tr:first-child td:first-child, -.table-bordered colgroup + thead tr:first-child th:first-child, -.table-bordered colgroup + tbody tr:first-child td:first-child { - -webkit-border-top-left-radius: 4px; - border-top-left-radius: 4px; - -moz-border-radius-topleft: 4px; } - -.table-bordered caption + thead tr:first-child th:last-child, -.table-bordered caption + tbody tr:first-child td:last-child, -.table-bordered colgroup + thead tr:first-child th:last-child, -.table-bordered colgroup + tbody tr:first-child td:last-child { - -webkit-border-top-right-radius: 4px; - border-top-right-radius: 4px; - -moz-border-radius-topright: 4px; } - -table.docutils th { - background-color: #e8e8e8; } - -table.docutils tr:hover { - background-color: whitesmoke; } - -.table-striped tbody > tr:nth-child(odd) > td, -.table-striped tbody > tr:nth-child(odd) > th { - background-color: rgba(252, 248, 244, 0.75); } - -.table-hover tbody tr:hover > td, -.table-hover tbody tr:hover > th { - background-color: rgba(241, 222, 204, 0.75); } - -table td[class*="span"], -table th[class*="span"], -.row-fluid table td[class*="span"], -.row-fluid table th[class*="span"] { - display: table-cell; - float: none; - margin-left: 0; } - -.hero-unit { - padding: 60px; - margin-bottom: 30px; - font-size: 18px; - font-weight: 200; - line-height: 30px; - color: inherit; - background-color: rgba(230, 197, 164, 0.75); - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; } - -.hero-unit h1 { - margin-bottom: 0; - font-size: 60px; - line-height: 1; - letter-spacing: -1px; - color: inherit; } - -.hero-unit li { - line-height: 30px; } /* rst2html default used to remove borders from tables and images */ .borderless, table.borderless td, table.borderless th { @@ -722,10 +499,6 @@ table.borderless td, table.borderless th { .hidden { display: none; } -a.toc-backref { - text-decoration: none; - color: #444444; } - blockquote.epigraph { margin: 2em 5em; } @@ -735,85 +508,6 @@ dl.docutils dd { object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] { overflow: hidden; } -/* Uncomment (and remove this text!) to get bold-faced definition list terms -dl.docutils dt { - font-weight: bold } -*/ -div.abstract { - margin: 2em 5em; } - -div.abstract p.topic-title { - font-weight: bold; - text-align: center; } - -div.admonition, div.attention, div.caution, div.danger, div.error, -div.hint, div.important, div.note, div.tip, div.warning { - margin: 2em; - border: medium outset; - padding: 1em; } - -div.note, div.warning { - margin: 1.5em 0px; - border: none; } - -div.note p.admonition-title, -div.warning p.admonition-title { - display: none; } - -/* Clearfix - * http://css-tricks.com/snippets/css/clear-fix/ - */ -div.note:after, -div.warning:after { - content: ""; - display: table; - clear: both; } - -div.note p:before, -div.warning p:before { - display: block; - float: left; - font-size: 4em; - line-height: 1em; - margin-right: 20px; - margin-left: 0em; - margin-top: -10px; - content: '\0270D'; - /*handwriting*/ } - -div.warning p:before { - content: '\026A0'; - /*warning*/ } - -div.admonition p.admonition-title, div.hint p.admonition-title, -div.important p.admonition-title, div.note p.admonition-title, -div.tip p.admonition-title { - font-weight: bold; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } - -div.attention p.admonition-title, div.caution p.admonition-title, -div.danger p.admonition-title, div.error p.admonition-title, -div.warning p.admonition-title, .code .error { - color: #b30000; - font-weight: bold; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } - -/* Uncomment (and remove this text!) to get reduced vertical space in - compound paragraphs. -div.compound .compound-first, div.compound .compound-middle { - margin-bottom: 0.5em } - -div.compound .compound-last, div.compound .compound-middle { - margin-top: 0.5em } -*/ -div.dedication { - margin: 2em 5em; - text-align: center; - font-style: italic; } - -div.dedication p.topic-title { - font-weight: bold; - font-style: normal; } div.figure { margin-left: 2em; @@ -821,8 +515,14 @@ div.figure { div.footer, div.header { clear: both; + text-align: center; + color: #666; font-size: smaller; } +div.footer { + padding-top: 5em; +} + div.line-block { display: block; margin-top: 1em; @@ -833,45 +533,24 @@ div.line-block div.line-block { margin-bottom: 0; margin-left: 1.5em; } -div.sidebar { - margin: 0 0 0.5em 1em; - border: medium outset; - padding: 1em; - background-color: rgba(252, 248, 244, 0.75); - width: 40%; - float: right; - clear: right; } - -div.sidebar p.rubric { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-size: medium; } - -div.system-messages { - margin: 5em; } - -div.system-messages h1 { - color: #b30000; } - -div.system-message { - border: medium outset; - padding: 1em; } - -div.system-message p.system-message-title { - color: #b30000; - font-weight: bold; } - div.topic { margin: 2em; } -h1.section-subtitle, h2.section-subtitle, h3.section-subtitle, -h4.section-subtitle, h5.section-subtitle, h6.section-subtitle { - margin-top: 0.4em; } +div.search_results { + background-color: antiquewhite; + margin: 3em; + padding: 1em; + border: 1px solid #4d4d4d; +} -h1.title { - text-align: center; } +div#global-links ul { + margin-left: 0; + list-style-type: none; +} -h2.subtitle { - text-align: center; } +div#global-links > simple-boot { + margin-left: 3em; +} hr.docutils { width: 75%; } @@ -905,30 +584,6 @@ img.align-center, .figure.align-center, object.align-center { div.align-right { text-align: inherit; } -/* div.align-center * { */ -/* text-align: left } */ - -ul.simple > li { - margin-bottom: 0.5em } - -ol.simple, ul.simple { - margin-bottom: 1em; } - -ol.arabic { - list-style: decimal; } - -ol.loweralpha { - list-style: lower-alpha; } - -ol.upperalpha { - list-style: upper-alpha; } - -ol.lowerroman { - list-style: lower-roman; } - -ol.upperroman { - list-style: upper-roman; } - p.attribution { text-align: right; margin-left: 50%; } @@ -949,15 +604,6 @@ p.rubric { color: maroon; text-align: center; } -p.sidebar-title { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-weight: bold; - font-size: larger; } - -p.sidebar-subtitle { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-weight: bold; } - p.topic-title { font-weight: bold; } @@ -997,22 +643,14 @@ pre.code .inserted, code .inserted { background-color: #A3D289; } span.classifier { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-style: oblique; } span.classifier-delimiter { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: bold; } -span.interpreted { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } - span.option { white-space: nowrap; } -span.pre { - white-space: pre; } - span.problematic { color: #b30000; } @@ -1020,44 +658,6 @@ span.section-subtitle { /* font-size relative to parent (h1..h6 element) */ font-size: 80%; } -table.citation { - border-left: solid 1px #666666; - margin-left: 1px; } - -table.docinfo { - margin: 0em; - margin-top: 2em; - margin-bottom: 2em; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; - color: #444444; } - -table.docutils { - margin-top: 0.5em; - margin-bottom: 0.5em; } - -table.footnote { - border-left: solid 1px #2d2d2d; - margin-left: 1px; } - -table.docutils td, table.docutils th, -table.docinfo td, table.docinfo th { - padding-left: 0.5em; - padding-right: 0.5em; - vertical-align: top; } - -table.docutils th.field-name, table.docinfo th.docinfo-name { - font-weight: 700; - text-align: left; - white-space: nowrap; - padding-left: 0; } - -h1 tt.docutils, h2 tt.docutils, h3 tt.docutils, -h4 tt.docutils, h5 tt.docutils, h6 tt.docutils { - font-size: 100%; } - -ul.auto-toc { - list-style-type: none; } - span.DecNumber { color: #252dbe; } @@ -1074,7 +674,7 @@ span.FloatNumber { color: #252dbe; } span.Identifier { - color: #3b3b3b; } + color: #222; } span.Keyword { font-weight: 600; @@ -1139,38 +739,23 @@ dt pre > span.Identifier, dt pre > span.Operator { color: #155da4; font-weight: 700; } -dt pre > span.Identifier ~ span.Identifier, dt pre > span.Operator ~ span.Identifier { - color: inherit; - font-weight: inherit; } - -dt pre > span.Operator ~ span.Identifier { +dt pre > span.Keyword ~ span.Identifier, dt pre > span.Identifier ~ span.Identifier, +dt pre > span.Operator ~ span.Identifier, dt pre > span.Other ~ span.Identifier { color: inherit; font-weight: inherit; } /* Nim sprite for the footer (taken from main page favicon) */ .nim-sprite { display: inline-block; - height: 12px; - width: 12px; + height: 16px; + width: 16px; background-position: 0 0; - background-size: 12px 12px; + background-size: 16px 16px; -webkit-filter: opacity(50%); background-repeat: no-repeat; background-image: url("data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="); margin-bottom: -5px; } -div.search_results { - background-color: antiquewhite; - margin: 3em; - padding: 1em; - border: 1px solid #4d4d4d; -} - -div#global-links ul { - margin-left: 0; - list-style-type: none; -} - span.pragmadots { /* Position: relative frees us up to make the dots look really nice without fucking up the layout and @@ -1178,18 +763,14 @@ span.pragmadots { position: relative; /* 1px down looks slightly nicer */ top: 1px; - padding: 2px; - background-color: #D3D3D3; + background-color: #e8e8e8; border-radius: 4px; margin: 0 2px; cursor: pointer; - - /* For some reason on Chrome, making the font size - smaller than 1em is causing the parent container to - bulge slightly. So, we're stuck with inheriting 1em, - which is sad, because 0.8em looks better... */ + font-size: 0.8em; } + span.pragmadots:hover { background-color: #DBDBDB; } @@ -1197,6 +778,10 @@ span.pragmawrap { display: none; } +span.attachedType { + display: none; + visibility: hidden; +} @@ -1248,25 +833,29 @@ function main() { Procs
    • execAction
    • + title="execAction(cmd: string; nostderr = false): string">execAction
    • mkDir
    • + title="mkDir(dir: string)">mkDir
    • cpFile
    • + title="cpFile(source, dest: string; move = false)">cpFile
    • mvFile
    • + title="mvFile(source, dest: string)">mvFile
    • extractZip
    • + title="extractZip(zipfile, outdir: string)">extractZip
    • downloadUrl
    • + title="downloadUrl(url, outdir: string)">downloadUrl
    • gitReset
    • + title="gitReset(outdir: string)">gitReset
    • gitCheckout
    • + title="gitCheckout(file, outdir: string)">gitCheckout
    • gitPull
    • -
    • configure
    • + title="gitPull(url: string; outdir = ""; plist = ""; checkout = "")">gitPull +
    • configure
    • +
    • cmake
    • +
    • make
  • @@ -1276,6 +865,7 @@ function main() {
    +

    Imports

    @@ -1286,76 +876,125 @@ function main() {

    Procs

    -
    proc execAction(cmd: string; nostderr = false): string {...}{.
    -    raises: [OSError, Exception, ValueError],
    +
    proc execAction(cmd: string; nostderr = false): string {...}{.
    +    raises: [OSError, Exception, IOError, Defect],
         tags: [ExecIOEffect, ReadIOEffect, RootEffect].}
    +

    Execute an external command - supported at compile time

    +

    Checks if command exits successfully before returning. If not, an error is raised.

    +
    -
    proc mkDir(dir: string) {...}{.raises: [OSError, Exception, ValueError], tags: [
    +
    proc mkDir(dir: string) {...}{.raises: [OSError, Exception, IOError, Defect, ValueError], tags: [
         ReadDirEffect, ExecIOEffect, ReadIOEffect, RootEffect].}
    +

    Create a directory at cmopile time

    +

    The os module is not available at compile time so a few crucial helper functions are included with nimterop.

    +
    -
    proc cpFile(source, dest: string; move = false) {...}{.
    -    raises: [OSError, Exception, ValueError],
    +
    proc cpFile(source, dest: string; move = false) {...}{.
    +    raises: [OSError, Exception, IOError, Defect, ValueError],
         tags: [ExecIOEffect, ReadIOEffect, RootEffect].}
    +Copy a file from source to destination at compile time
    -
    proc mvFile(source, dest: string) {...}{.raises: [OSError, Exception, ValueError],
    +
    proc mvFile(source, dest: string) {...}{.raises: [OSError, Exception, IOError, Defect,
    +                                        ValueError],
                                     tags: [ExecIOEffect, ReadIOEffect, RootEffect].}
    +Move a file from source to destination at compile time
    -
    proc extractZip(zipfile, outdir: string) {...}{.raises: [OSError, Exception, ValueError], tags: [
    -    ExecIOEffect, ReadIOEffect, RootEffect].}
    +
    proc extractZip(zipfile, outdir: string) {...}{.raises: [OSError, Exception, IOError, Defect,
    +    ValueError], tags: [ExecIOEffect, ReadIOEffect, RootEffect].}
    +Extract a zip file using powershell on Windows and unzip on other systems to the specified output directory
    -
    proc downloadUrl(url, outdir: string) {...}{.raises: [OSError, Exception, ValueError], tags: [
    -    ReadDirEffect, ExecIOEffect, ReadIOEffect, RootEffect].}
    +
    proc downloadUrl(url, outdir: string) {...}{.raises: [OSError, Exception, IOError, Defect,
    +    ValueError], tags: [ReadDirEffect, ExecIOEffect, ReadIOEffect, RootEffect].}
    +

    Download a file using powershell on Windows and curl on other systems to the specified output directory

    +

    If a zip file, it is automatically extracted after download.

    +
    -
    proc gitReset(outdir: string) {...}{.raises: [OSError, Exception, ValueError], tags: [
    +
    proc gitReset(outdir: string) {...}{.raises: [ValueError, OSError, Exception, IOError, Defect], tags: [
         ExecIOEffect, ReadIOEffect, RootEffect, TimeEffect].}
    +Hard reset the git repository at the specified directory
    -
    proc gitCheckout(file, outdir: string) {...}{.raises: [OSError, Exception, ValueError], tags: [
    -    ExecIOEffect, ReadIOEffect, RootEffect, TimeEffect].}
    +
    proc gitCheckout(file, outdir: string) {...}{.raises: [ValueError, OSError, Exception,
    +    IOError, Defect], tags: [ExecIOEffect, ReadIOEffect, RootEffect, TimeEffect].}
    +

    Checkout the specified file in the git repository specified

    +

    This effectively resets all changes in the file and can be used after cImport() if required.

    +
    -
    proc gitPull(url: string; outdir = ""; plist = ""; checkout = "") {...}{.
    -    raises: [OSError, Exception, ValueError, IOError], tags: [ReadDirEffect,
    +
    proc gitPull(url: string; outdir = ""; plist = ""; checkout = "") {...}{.
    +    raises: [ValueError, OSError, Exception, IOError, Defect], tags: [ReadDirEffect,
         ExecIOEffect, ReadIOEffect, RootEffect, TimeEffect, WriteIOEffect].}
    +

    Pull the specified git repository to the output directory

    +

    plist is the list of specific files and directories or wildcards to sparse checkout. Multiples can be specified one entry per line.

    +
    - -
    proc configure(path, check: string) {...}{.raises: [OSError, Exception, ValueError], tags: [
    -    ReadDirEffect, ExecIOEffect, ReadIOEffect, RootEffect].}
    + +
    proc configure(path, check: string; flags = "") {...}{.
    +    raises: [OSError, Exception, IOError, Defect, ValueError],
    +    tags: [ReadDirEffect, ExecIOEffect, ReadIOEffect, RootEffect].}
    +

    Run the GNU configure command to generate all Makefiles or other build scripts in the specified path

    +

    If a configure script is not present and an autogen.sh script is present, it will be run before attempting configure.

    +

    check is a file that will be generated by the configure command. This is required to prevent configure from running on every build. It is relative to the path and should not be an absolute path.

    +

    flags are any flags that should be passed to the configure command.

    + + +
    + +
    proc cmake(path, check, flags: string) {...}{.raises: [OSError, Exception, IOError, Defect,
    +    ValueError], tags: [ReadDirEffect, ExecIOEffect, ReadIOEffect, RootEffect].}
    +
    + +

    Run the cmake command to generate all Makefiles or other build scripts in the specified path

    +

    path will be created since typically cmake is run in an empty directory.

    +

    check is a file that will be generated by the cmake command. This is required to prevent cmake from running on every build. It is relative to the path and should not be an absolute path.

    +

    flags are any flags that should be passed to the cmake command. Unlike configure, it is required since typically it will be the path to the repository, typically .. when path is a subdir.

    + + +
    + +
    proc make(path, check: string; flags = "") {...}{.raises: [ValueError, OSError, Exception,
    +    IOError, Defect], tags: [ReadDirEffect, ExecIOEffect, ReadIOEffect, RootEffect].}
    +
    + +

    Run the make command to build all binaries in the specified path

    +

    check is a file that will be generated by the make command. This is required to prevent make from running on every build. It is relative to the path and should not be an absolute path.

    +

    flags are any flags that should be passed to the make command.

    +
    @@ -1368,7 +1007,7 @@ function main() {
    diff --git a/git.idx b/git.idx old mode 100755 new mode 100644 index a48f1b4..7cc5775 --- a/git.idx +++ b/git.idx @@ -7,4 +7,6 @@ downloadUrl git.html#downloadUrl,string,string git: downloadUrl(url, outdir: str gitReset git.html#gitReset,string git: gitReset(outdir: string) gitCheckout git.html#gitCheckout,string,string git: gitCheckout(file, outdir: string) gitPull git.html#gitPull,string,string,string,string git: gitPull(url: string; outdir = ""; plist = ""; checkout = "") -configure git.html#configure,string,string git: configure(path, check: string) +configure git.html#configure,string,string,string git: configure(path, check: string; flags = "") +cmake git.html#cmake,string,string,string git: cmake(path, check, flags: string) +make git.html#make,string,string,string git: make(path, check: string; flags = "") diff --git a/paths.html b/paths.html old mode 100755 new mode 100644 index 0b5a138..fa6e18e --- a/paths.html +++ b/paths.html @@ -27,232 +27,130 @@ customize this style sheet. Modified from Chad Skeeters' rst2html-style https://bitbucket.org/cskeeters/rst2html-style/ -Modified by Boyd Greenfield +Modified by Boyd Greenfield and narimiran */ -/* SCSS variables */ -/* Text weights */ -/* Body colors */ -/* Text colors */ -/* Link colors */ -/* Syntax highlighting colors */ -/* Pct changes */ -/* Mixins */ -/* Body/layout */ + html { font-size: 100%; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; } -/* Where we want fancier font if available */ -h1, h2, h3, h4, h5, h6, p.module-desc, table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; } - -h1.title { - font-weight: 900; } - body { font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: 400; - font-size: 16px; - line-height: 20px; - color: #444; - letter-spacing: 0.15px; - background-color: #FDFBFA; } + font-size: 1.125em; + line-height: 1.5; + color: #222; + background-color: #FCFCFC; } /* Skeleton grid */ .container { position: relative; width: 100%; - max-width: 960px; + max-width: 1050px; margin: 0 auto; - padding: 0 20px; + padding: 0; box-sizing: border-box; } .column, .columns { width: 100%; float: left; - box-sizing: border-box; } + box-sizing: border-box; + margin-left: 1%; +} -/* For devices larger than 400px */ -@media (min-width: 400px) { - .container { - width: 100%; - padding: 0; } } -/* For devices larger than 650px */ -@media (min-width: 650px) { - .container { - width: 100%; } +.column:first-child, +.columns:first-child { + margin-left: 0; } - .column, - .columns { - margin-left: 4%; } +.three.columns { + width: 19%; } - .column:first-child, - .columns:first-child { - margin-left: 0; } +.nine.columns { + width: 80.0%; } - .one.column, - .one.columns { - width: 4.66666666667%; } - - .two.columns { - width: 13.3333333333%; } +.twelve.columns { + width: 100%; + margin-left: 0; } +@media screen and (max-width: 860px) { .three.columns { - width: 22%; } - - .four.columns { - width: 30.6666666667%; } - - .five.columns { - width: 39.3333333333%; } - - .six.columns { - width: 48%; } - - .seven.columns { - width: 56.6666666667%; } - - .eight.columns { - width: 65.3333333333%; } - + display: none; + } .nine.columns { - width: 74.0%; } - - .ten.columns { - width: 82.6666666667%; } - - .eleven.columns { - width: 91.3333333333%; } - - .twelve.columns { - width: 100%; - margin-left: 0; } - - .one-third.column { - width: 30.6666666667%; } - - .two-thirds.column { - width: 65.3333333333%; } } -/* Customer Overrides */ -.footer { - text-align: center; - color: #969696; - padding-top: 10%; } - -p.module-desc { - font-size: 1.1em; - color: #666666; } - -a.link-seesrc { - color: #aec7d2; - font-style: italic; } - -a.link-seesrc:hover { - color: #6c9aae; } - -#toc-list { - word-wrap: break-word; } - -ul.simple-toc { - list-style: none; } - -ul.simple-toc a.reference-toplevel { - font-weight: bold; - color: #0077b3; } - -ul.simple-toc-section { - list-style-type: circle; - color: #6c9aae; } - -ul.simple-toc-section a.reference { - color: #0077b3; } + width: 98.0%; + } + body { + font-size: 1em; + line-height: 1.35; + } +} cite { font-style: italic !important; } -dt > pre { - border-color: rgba(0, 0, 0, 0.1); - background-color: rgba(255, 255, 255, 0.3); - margin: 15px 0px 5px; } - -dd > pre { - border-color: rgba(0, 0, 0, 0.1); - background-color: whitesmoke; - margin-top: 8px; } - -.item > dd { - margin-left: 10px; - margin-bottom: 30px; } - -/* Nim line-numbered tables */ -.line-nums-table { - width: 100%; - table-layout: fixed; } /* Nim search input */ div#searchInputDiv { - margin-bottom: 8px; + margin-bottom: 1em; } -div#searchInputDiv input#searchInput { - width: 10em; -} -div.search-groupby { - margin-bottom: 8px; +input#searchInput { + width: 80%; } -table.line-nums-table { - border-radius: 4px; - border: 1px solid #cccccc; - background-color: whitesmoke; - border-collapse: separate; - margin-top: 15px; - margin-bottom: 25px; } - -.line-nums-table tbody { - border: none; } - -.line-nums-table td pre { - border: none; - background-color: transparent; } - -.line-nums-table td.blob-line-nums { - width: 28px; } - -.line-nums-table td.blob-line-nums pre { - color: #b0b0b0; - -webkit-filter: opacity(75%); - text-align: right; - border-color: transparent; - background-color: transparent; - padding-left: 0px; - margin-left: 0px; - padding-right: 0px; - margin-right: 0px; } +/* + * Some custom formatting for input forms. + * This also fixes input form colors on Firefox with a dark system theme on Linux. + */ +input { + -moz-appearance: none; + color: #333; + background-color: #f8f8f8; + border: 1px solid #aaa; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-size: 0.9em; + padding: 6px; +} +input:focus { + border: 1px solid #1fa0eb; + box-shadow: 0 0 2px #1fa0eb; +} /* Docgen styles */ /* Links */ a { - color: #0077b3; - text-decoration: none; } + color: #07b; + text-decoration: none; +} + +a span.Identifier { + text-decoration: underline; + text-decoration-color: #aab; +} + +a.reference-toplevel { + font-weight: bold; +} + +a.toc-backref { + text-decoration: none; + color: #222; } + +a.link-seesrc { + color: #607c9f; + font-size: 0.9em; + font-style: italic; } a:hover, a:focus { - color: #00334d; + color: #607c9f; text-decoration: underline; } -a:visited { - color: #00334d; } +a:hover span.Identifier { + color: #607c9f; +} -a:focus { - outline: thin dotted #2d2d2d; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; } - -a:hover, -a:active { - outline: 0; } sub, sup { @@ -329,379 +227,258 @@ img { h2, h3 { - page-break-after: avoid; } } -.img-rounded { - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; } + page-break-after: avoid; } +} -.img-polaroid { - padding: 4px; - background-color: rgba(252, 248, 244, 0.75); - border: 1px solid #ccc; - border: 1px solid rgba(0, 0, 0, 0.2); - -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); - -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); } p { - margin: 0 0 8px; } + margin-top: 0.5em; + margin-bottom: 0.5em; +} small { font-size: 85%; } strong { - font-weight: 600; } + font-weight: 600; + font-size: 0.95em; + color: #3c3c3c; +} em { font-style: italic; } -cite { - font-style: normal; } - -h1, -h2, -h3, -h4, -h5, -h6 { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-weight: 600; - line-height: 20px; - color: inherit; - text-rendering: optimizelegibility; } - h1 { - font-size: 2em; + font-size: 1.8em; font-weight: 400; - padding-bottom: .15em; - border-bottom: 1px solid #aaaaaa; - margin-top: 1.0em; + padding-bottom: .25em; + border-bottom: 1px solid #aaa; + margin-top: 2.5em; + margin-bottom: 1em; line-height: 1.2em; } h1.title { padding-bottom: 1em; border-bottom: 0px; - font-size: 2.75em; } + font-size: 2.5em; + text-align: center; + font-weight: 900; + margin-top: 0.75em; + margin-bottom: 0em; +} h2 { - font-size: 1.5em; - margin-top: 1.5em; } + font-size: 1.3em; + margin-top: 2em; } + +h2.subtitle { + text-align: center; } h3 { - font-size: 1.3em; + font-size: 1.125em; font-style: italic; - margin-top: 0.75em; } + margin-top: 1.5em; } h4 { - font-size: 1.3em; - margin-top: 0.5em; } + font-size: 1.125em; + margin-top: 1em; } h5 { - font-size: 1.2em; - margin-top: 0.25em; } + font-size: 1.125em; + margin-top: 0.75em; } h6 { font-size: 1.1em; } + ul, ol { padding: 0; - margin: 0 0 0px 15px; } + margin-top: 0.5em; + margin-left: 0.75em; } ul ul, ul ol, ol ol, ol ul { - margin-bottom: 0; } + margin-bottom: 0; + margin-left: 1.25em; } li { - line-height: 20px; } - -dl { - margin-bottom: 20px; } - -dt, -dd { - line-height: 20px; } - -dt { - font-weight: bold; } - -dd { - margin-left: 10px; - margin-bottom: 26px; } - -hr { - margin: 20px 0; - border: 0; - border-top: 1px solid #eeeeee; - border-bottom: 1px solid #ffffff; } - -abbr[title], -abbr[data-original-title] { - cursor: help; - border-bottom: 1px dotted #999999; } - -abbr.initialism { - font-size: 90%; - text-transform: uppercase; } - -blockquote { - padding: 0 0 0 15px; - margin: 0 0 20px; - border-left: 5px solid #EFEBE0; } - -table.docinfo + blockquote, table.docinfo blockquote, h1 + blockquote { - border-left: 5px solid #c9c9c9; + list-style-type: circle; } -table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { - margin-bottom: 0; - font-size: 15px; - font-weight: 200; - line-height: 1.5; - font-style: italic; } +ul.simple-boot li { + list-style-type: none; + margin-left: 0em; + margin-bottom: 0.5em; +} -q:before, -q:after, -blockquote:before, -blockquote:after { - content: ""; } +ol.simple > li, ul.simple > li { + margin-bottom: 0.25em; + margin-left: 0.4em } -address { - display: block; - margin-bottom: 20px; - font-style: normal; - line-height: 20px; } +ul.simple.simple-toc > li { + margin-top: 1em; +} -code, -pre { - font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - padding: 0 3px 2px; - font-weight: 500; - font-size: 12px; - color: #444444; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; } +ul.simple-toc { + list-style: none; + font-size: 0.9em; + margin-left: -0.3em; + margin-top: 1em; } + +ul.simple-toc > li { + list-style-type: none; +} + +ul.simple-toc-section { + list-style-type: circle; + margin-left: 1em; + color: #6c9aae; } + + +ol.arabic { + list-style: decimal; } + +ol.loweralpha { + list-style: lower-alpha; } + +ol.upperalpha { + list-style: upper-alpha; } + +ol.lowerroman { + list-style: lower-roman; } + +ol.upperroman { + list-style: upper-roman; } + +ul.auto-toc { + list-style-type: none; } + + +dl { + margin-bottom: 1.5em; } + +dt { + margin-bottom: -0.5em; + margin-left: 0.0em; } + +dd { + margin-left: 2.0em; + margin-bottom: 3.0em; + margin-top: 0.5em; } + + +hr { + margin: 2em 0; + border: 0; + border-top: 1px solid #aaa; } + +blockquote { + font-size: 0.9em; + font-style: italic; + padding-left: 0.5em; + margin-left: 0; + border-left: 5px solid #bbc; +} .pre { font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - font-weight: 600; - /*color: #504da6;*/ + font-weight: 500; + font-size: 0.85em; + background-color: #f0f3ff; + padding-left: 3px; + padding-right: 3px; + border-radius: 4px; } -code { - padding: 2px 4px; - color: #444444; - white-space: nowrap; - background-color: white; - border: 1px solid #777777; } - pre { + font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; + color: #222; + font-weight: 500; display: inline-block; box-sizing: border-box; - min-width: calc(100% - 19.5px); - padding: 9.5px; - margin: 0.25em 10px 10px 10px; - font-size: 15px; - line-height: 20px; + min-width: 100%; + padding: 0.5em; + margin-top: 0.5em; + margin-bottom: 0.5em; + font-size: 0.85em; white-space: pre !important; overflow-y: hidden; overflow-x: visible; - background-color: rgba(0, 0, 0, 0.01); - border: 1px solid #cccccc; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; } - -pre.prettyprint { - margin-bottom: 20px; } - -pre code { - padding: 0; - color: inherit; - white-space: pre; - overflow-x: visible; - background-color: transparent; - border: 0; } + background-color: ghostwhite; + border: 1px solid #dde; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; } .pre-scrollable { max-height: 340px; overflow-y: scroll; } + +/* Nim line-numbered tables */ +.line-nums-table { + width: 100%; + table-layout: fixed; } + +table.line-nums-table { + border-radius: 4px; + border: 1px solid #cccccc; + background-color: ghostwhite; + border-collapse: separate; + margin-top: 15px; + margin-bottom: 25px; } + +.line-nums-table tbody { + border: none; } + +.line-nums-table td pre { + border: none; + background-color: transparent; } + +.line-nums-table td.blob-line-nums { + width: 28px; } + +.line-nums-table td.blob-line-nums pre { + color: #b0b0b0; + -webkit-filter: opacity(75%); + text-align: right; + border-color: transparent; + background-color: transparent; + padding-left: 0px; + margin-left: 0px; + padding-right: 0px; + margin-right: 0px; } + + table { max-width: 100%; background-color: transparent; + margin-top: 0.5em; + margin-bottom: 1.5em; border-collapse: collapse; - border-spacing: 0; } - -table th, table td { - padding: 0px 8px 0px; + border-color: #ccc; + border-spacing: 0; + font-size: 0.9em; } -.table { - width: 100%; - margin-bottom: 20px; } +table th, table td { + padding: 0px 0.5em 0px; +} -.table th, -.table td { - padding: 8px; - line-height: 20px; - text-align: left; - vertical-align: top; - border-top: 1px solid #444444; } - -.table th { +table th { + background-color: #e8e8e8; font-weight: bold; } -.table thead th { - vertical-align: bottom; } +table th.docinfo-name { + background-color: transparent; +} -.table caption + thead tr:first-child th, -.table caption + thead tr:first-child td, -.table colgroup + thead tr:first-child th, -.table colgroup + thead tr:first-child td, -.table thead:first-child tr:first-child th, -.table thead:first-child tr:first-child td { - border-top: 0; } +table tr:hover { + background-color: ghostwhite; } -.table tbody + tbody { - border-top: 2px solid #444444; } - -.table .table { - background-color: rgba(252, 248, 244, 0.75); } - -.table-condensed th, -.table-condensed td { - padding: 4px 5px; } - -.table-bordered { - border: 1px solid #444444; - border-collapse: separate; - *border-collapse: collapse; - border-left: 0; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; } - -.table-bordered th, -.table-bordered td { - border-left: 1px solid #444444; } - -.table-bordered caption + thead tr:first-child th, -.table-bordered caption + tbody tr:first-child th, -.table-bordered caption + tbody tr:first-child td, -.table-bordered colgroup + thead tr:first-child th, -.table-bordered colgroup + tbody tr:first-child th, -.table-bordered colgroup + tbody tr:first-child td, -.table-bordered thead:first-child tr:first-child th, -.table-bordered tbody:first-child tr:first-child th, -.table-bordered tbody:first-child tr:first-child td { - border-top: 0; } - -.table-bordered thead:first-child tr:first-child > th:first-child, -.table-bordered tbody:first-child tr:first-child > td:first-child, -.table-bordered tbody:first-child tr:first-child > th:first-child { - -webkit-border-top-left-radius: 4px; - border-top-left-radius: 4px; - -moz-border-radius-topleft: 4px; } - -.table-bordered thead:first-child tr:first-child > th:last-child, -.table-bordered tbody:first-child tr:first-child > td:last-child, -.table-bordered tbody:first-child tr:first-child > th:last-child { - -webkit-border-top-right-radius: 4px; - border-top-right-radius: 4px; - -moz-border-radius-topright: 4px; } - -.table-bordered thead:last-child tr:last-child > th:first-child, -.table-bordered tbody:last-child tr:last-child > td:first-child, -.table-bordered tbody:last-child tr:last-child > th:first-child, -.table-bordered tfoot:last-child tr:last-child > td:first-child, -.table-bordered tfoot:last-child tr:last-child > th:first-child { - -webkit-border-bottom-left-radius: 4px; - border-bottom-left-radius: 4px; - -moz-border-radius-bottomleft: 4px; } - -.table-bordered thead:last-child tr:last-child > th:last-child, -.table-bordered tbody:last-child tr:last-child > td:last-child, -.table-bordered tbody:last-child tr:last-child > th:last-child, -.table-bordered tfoot:last-child tr:last-child > td:last-child, -.table-bordered tfoot:last-child tr:last-child > th:last-child { - -webkit-border-bottom-right-radius: 4px; - border-bottom-right-radius: 4px; - -moz-border-radius-bottomright: 4px; } - -.table-bordered tfoot + tbody:last-child tr:last-child td:first-child { - -webkit-border-bottom-left-radius: 0; - border-bottom-left-radius: 0; - -moz-border-radius-bottomleft: 0; } - -.table-bordered tfoot + tbody:last-child tr:last-child td:last-child { - -webkit-border-bottom-right-radius: 0; - border-bottom-right-radius: 0; - -moz-border-radius-bottomright: 0; } - -.table-bordered caption + thead tr:first-child th:first-child, -.table-bordered caption + tbody tr:first-child td:first-child, -.table-bordered colgroup + thead tr:first-child th:first-child, -.table-bordered colgroup + tbody tr:first-child td:first-child { - -webkit-border-top-left-radius: 4px; - border-top-left-radius: 4px; - -moz-border-radius-topleft: 4px; } - -.table-bordered caption + thead tr:first-child th:last-child, -.table-bordered caption + tbody tr:first-child td:last-child, -.table-bordered colgroup + thead tr:first-child th:last-child, -.table-bordered colgroup + tbody tr:first-child td:last-child { - -webkit-border-top-right-radius: 4px; - border-top-right-radius: 4px; - -moz-border-radius-topright: 4px; } - -table.docutils th { - background-color: #e8e8e8; } - -table.docutils tr:hover { - background-color: whitesmoke; } - -.table-striped tbody > tr:nth-child(odd) > td, -.table-striped tbody > tr:nth-child(odd) > th { - background-color: rgba(252, 248, 244, 0.75); } - -.table-hover tbody tr:hover > td, -.table-hover tbody tr:hover > th { - background-color: rgba(241, 222, 204, 0.75); } - -table td[class*="span"], -table th[class*="span"], -.row-fluid table td[class*="span"], -.row-fluid table th[class*="span"] { - display: table-cell; - float: none; - margin-left: 0; } - -.hero-unit { - padding: 60px; - margin-bottom: 30px; - font-size: 18px; - font-weight: 200; - line-height: 30px; - color: inherit; - background-color: rgba(230, 197, 164, 0.75); - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; } - -.hero-unit h1 { - margin-bottom: 0; - font-size: 60px; - line-height: 1; - letter-spacing: -1px; - color: inherit; } - -.hero-unit li { - line-height: 30px; } /* rst2html default used to remove borders from tables and images */ .borderless, table.borderless td, table.borderless th { @@ -722,10 +499,6 @@ table.borderless td, table.borderless th { .hidden { display: none; } -a.toc-backref { - text-decoration: none; - color: #444444; } - blockquote.epigraph { margin: 2em 5em; } @@ -735,85 +508,6 @@ dl.docutils dd { object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] { overflow: hidden; } -/* Uncomment (and remove this text!) to get bold-faced definition list terms -dl.docutils dt { - font-weight: bold } -*/ -div.abstract { - margin: 2em 5em; } - -div.abstract p.topic-title { - font-weight: bold; - text-align: center; } - -div.admonition, div.attention, div.caution, div.danger, div.error, -div.hint, div.important, div.note, div.tip, div.warning { - margin: 2em; - border: medium outset; - padding: 1em; } - -div.note, div.warning { - margin: 1.5em 0px; - border: none; } - -div.note p.admonition-title, -div.warning p.admonition-title { - display: none; } - -/* Clearfix - * http://css-tricks.com/snippets/css/clear-fix/ - */ -div.note:after, -div.warning:after { - content: ""; - display: table; - clear: both; } - -div.note p:before, -div.warning p:before { - display: block; - float: left; - font-size: 4em; - line-height: 1em; - margin-right: 20px; - margin-left: 0em; - margin-top: -10px; - content: '\0270D'; - /*handwriting*/ } - -div.warning p:before { - content: '\026A0'; - /*warning*/ } - -div.admonition p.admonition-title, div.hint p.admonition-title, -div.important p.admonition-title, div.note p.admonition-title, -div.tip p.admonition-title { - font-weight: bold; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } - -div.attention p.admonition-title, div.caution p.admonition-title, -div.danger p.admonition-title, div.error p.admonition-title, -div.warning p.admonition-title, .code .error { - color: #b30000; - font-weight: bold; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } - -/* Uncomment (and remove this text!) to get reduced vertical space in - compound paragraphs. -div.compound .compound-first, div.compound .compound-middle { - margin-bottom: 0.5em } - -div.compound .compound-last, div.compound .compound-middle { - margin-top: 0.5em } -*/ -div.dedication { - margin: 2em 5em; - text-align: center; - font-style: italic; } - -div.dedication p.topic-title { - font-weight: bold; - font-style: normal; } div.figure { margin-left: 2em; @@ -821,8 +515,14 @@ div.figure { div.footer, div.header { clear: both; + text-align: center; + color: #666; font-size: smaller; } +div.footer { + padding-top: 5em; +} + div.line-block { display: block; margin-top: 1em; @@ -833,45 +533,24 @@ div.line-block div.line-block { margin-bottom: 0; margin-left: 1.5em; } -div.sidebar { - margin: 0 0 0.5em 1em; - border: medium outset; - padding: 1em; - background-color: rgba(252, 248, 244, 0.75); - width: 40%; - float: right; - clear: right; } - -div.sidebar p.rubric { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-size: medium; } - -div.system-messages { - margin: 5em; } - -div.system-messages h1 { - color: #b30000; } - -div.system-message { - border: medium outset; - padding: 1em; } - -div.system-message p.system-message-title { - color: #b30000; - font-weight: bold; } - div.topic { margin: 2em; } -h1.section-subtitle, h2.section-subtitle, h3.section-subtitle, -h4.section-subtitle, h5.section-subtitle, h6.section-subtitle { - margin-top: 0.4em; } +div.search_results { + background-color: antiquewhite; + margin: 3em; + padding: 1em; + border: 1px solid #4d4d4d; +} -h1.title { - text-align: center; } +div#global-links ul { + margin-left: 0; + list-style-type: none; +} -h2.subtitle { - text-align: center; } +div#global-links > simple-boot { + margin-left: 3em; +} hr.docutils { width: 75%; } @@ -905,30 +584,6 @@ img.align-center, .figure.align-center, object.align-center { div.align-right { text-align: inherit; } -/* div.align-center * { */ -/* text-align: left } */ - -ul.simple > li { - margin-bottom: 0.5em } - -ol.simple, ul.simple { - margin-bottom: 1em; } - -ol.arabic { - list-style: decimal; } - -ol.loweralpha { - list-style: lower-alpha; } - -ol.upperalpha { - list-style: upper-alpha; } - -ol.lowerroman { - list-style: lower-roman; } - -ol.upperroman { - list-style: upper-roman; } - p.attribution { text-align: right; margin-left: 50%; } @@ -949,15 +604,6 @@ p.rubric { color: maroon; text-align: center; } -p.sidebar-title { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-weight: bold; - font-size: larger; } - -p.sidebar-subtitle { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-weight: bold; } - p.topic-title { font-weight: bold; } @@ -997,22 +643,14 @@ pre.code .inserted, code .inserted { background-color: #A3D289; } span.classifier { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-style: oblique; } span.classifier-delimiter { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: bold; } -span.interpreted { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } - span.option { white-space: nowrap; } -span.pre { - white-space: pre; } - span.problematic { color: #b30000; } @@ -1020,44 +658,6 @@ span.section-subtitle { /* font-size relative to parent (h1..h6 element) */ font-size: 80%; } -table.citation { - border-left: solid 1px #666666; - margin-left: 1px; } - -table.docinfo { - margin: 0em; - margin-top: 2em; - margin-bottom: 2em; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; - color: #444444; } - -table.docutils { - margin-top: 0.5em; - margin-bottom: 0.5em; } - -table.footnote { - border-left: solid 1px #2d2d2d; - margin-left: 1px; } - -table.docutils td, table.docutils th, -table.docinfo td, table.docinfo th { - padding-left: 0.5em; - padding-right: 0.5em; - vertical-align: top; } - -table.docutils th.field-name, table.docinfo th.docinfo-name { - font-weight: 700; - text-align: left; - white-space: nowrap; - padding-left: 0; } - -h1 tt.docutils, h2 tt.docutils, h3 tt.docutils, -h4 tt.docutils, h5 tt.docutils, h6 tt.docutils { - font-size: 100%; } - -ul.auto-toc { - list-style-type: none; } - span.DecNumber { color: #252dbe; } @@ -1074,7 +674,7 @@ span.FloatNumber { color: #252dbe; } span.Identifier { - color: #3b3b3b; } + color: #222; } span.Keyword { font-weight: 600; @@ -1139,38 +739,23 @@ dt pre > span.Identifier, dt pre > span.Operator { color: #155da4; font-weight: 700; } -dt pre > span.Identifier ~ span.Identifier, dt pre > span.Operator ~ span.Identifier { - color: inherit; - font-weight: inherit; } - -dt pre > span.Operator ~ span.Identifier { +dt pre > span.Keyword ~ span.Identifier, dt pre > span.Identifier ~ span.Identifier, +dt pre > span.Operator ~ span.Identifier, dt pre > span.Other ~ span.Identifier { color: inherit; font-weight: inherit; } /* Nim sprite for the footer (taken from main page favicon) */ .nim-sprite { display: inline-block; - height: 12px; - width: 12px; + height: 16px; + width: 16px; background-position: 0 0; - background-size: 12px 12px; + background-size: 16px 16px; -webkit-filter: opacity(50%); background-repeat: no-repeat; background-image: url("data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="); margin-bottom: -5px; } -div.search_results { - background-color: antiquewhite; - margin: 3em; - padding: 1em; - border: 1px solid #4d4d4d; -} - -div#global-links ul { - margin-left: 0; - list-style-type: none; -} - span.pragmadots { /* Position: relative frees us up to make the dots look really nice without fucking up the layout and @@ -1178,18 +763,14 @@ span.pragmadots { position: relative; /* 1px down looks slightly nicer */ top: 1px; - padding: 2px; - background-color: #D3D3D3; + background-color: #e8e8e8; border-radius: 4px; margin: 0 2px; cursor: pointer; - - /* For some reason on Chrome, making the font size - smaller than 1em is causing the parent container to - bulge slightly. So, we're stuck with inheriting 1em, - which is sad, because 0.8em looks better... */ + font-size: 0.8em; } + span.pragmadots:hover { background-color: #DBDBDB; } @@ -1197,6 +778,10 @@ span.pragmawrap { display: none; } +span.attachedType { + display: none; + visibility: hidden; +} @@ -1241,18 +826,18 @@ function main() {
  • Procs
  • @@ -1262,45 +847,52 @@ function main() {
    +

    Procs

    - -
    proc nimteropRoot(): string {...}{.raises: [], tags: [].}
    + +
    proc nimteropRoot(): string {...}{.raises: [], tags: [].}
    +
    - -
    proc nimteropBuildDir(): string {...}{.raises: [], tags: [].}
    + +
    proc nimteropBuildDir(): string {...}{.raises: [], tags: [].}
    + all nimterop generated files go under here (gitignored)
    - -
    proc nimteropSrcDir(): string {...}{.raises: [], tags: [].}
    + +
    proc nimteropSrcDir(): string {...}{.raises: [], tags: [].}
    +
    - -
    proc toastExePath(): string {...}{.raises: [], tags: [].}
    + +
    proc toastExePath(): string {...}{.raises: [], tags: [].}
    +
    - -
    proc incDir(): string {...}{.raises: [], tags: [].}
    + +
    proc incDir(): string {...}{.raises: [], tags: [].}
    +
    - -
    proc testsIncludeDir(): string {...}{.raises: [], tags: [].}
    + +
    proc testsIncludeDir(): string {...}{.raises: [], tags: [].}
    +
    @@ -1312,7 +904,7 @@ all nimterop generated files go under here (gitignored)
    diff --git a/paths.idx b/paths.idx old mode 100755 new mode 100644 index df86edd..8a688d4 --- a/paths.idx +++ b/paths.idx @@ -1,6 +1,6 @@ -nimteropRoot paths.html#nimteropRoot, paths: nimteropRoot(): string -nimteropBuildDir paths.html#nimteropBuildDir, paths: nimteropBuildDir(): string -nimteropSrcDir paths.html#nimteropSrcDir, paths: nimteropSrcDir(): string -toastExePath paths.html#toastExePath, paths: toastExePath(): string -incDir paths.html#incDir, paths: incDir(): string -testsIncludeDir paths.html#testsIncludeDir, paths: testsIncludeDir(): string +nimteropRoot paths.html#nimteropRoot paths: nimteropRoot(): string +nimteropBuildDir paths.html#nimteropBuildDir paths: nimteropBuildDir(): string +nimteropSrcDir paths.html#nimteropSrcDir paths: nimteropSrcDir(): string +toastExePath paths.html#toastExePath paths: toastExePath(): string +incDir paths.html#incDir paths: incDir(): string +testsIncludeDir paths.html#testsIncludeDir paths: testsIncludeDir(): string diff --git a/plugin.html b/plugin.html old mode 100755 new mode 100644 index d219e65..9bf3942 --- a/plugin.html +++ b/plugin.html @@ -27,232 +27,130 @@ customize this style sheet. Modified from Chad Skeeters' rst2html-style https://bitbucket.org/cskeeters/rst2html-style/ -Modified by Boyd Greenfield +Modified by Boyd Greenfield and narimiran */ -/* SCSS variables */ -/* Text weights */ -/* Body colors */ -/* Text colors */ -/* Link colors */ -/* Syntax highlighting colors */ -/* Pct changes */ -/* Mixins */ -/* Body/layout */ + html { font-size: 100%; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; } -/* Where we want fancier font if available */ -h1, h2, h3, h4, h5, h6, p.module-desc, table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; } - -h1.title { - font-weight: 900; } - body { font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: 400; - font-size: 16px; - line-height: 20px; - color: #444; - letter-spacing: 0.15px; - background-color: #FDFBFA; } + font-size: 1.125em; + line-height: 1.5; + color: #222; + background-color: #FCFCFC; } /* Skeleton grid */ .container { position: relative; width: 100%; - max-width: 960px; + max-width: 1050px; margin: 0 auto; - padding: 0 20px; + padding: 0; box-sizing: border-box; } .column, .columns { width: 100%; float: left; - box-sizing: border-box; } + box-sizing: border-box; + margin-left: 1%; +} -/* For devices larger than 400px */ -@media (min-width: 400px) { - .container { - width: 100%; - padding: 0; } } -/* For devices larger than 650px */ -@media (min-width: 650px) { - .container { - width: 100%; } +.column:first-child, +.columns:first-child { + margin-left: 0; } - .column, - .columns { - margin-left: 4%; } +.three.columns { + width: 19%; } - .column:first-child, - .columns:first-child { - margin-left: 0; } +.nine.columns { + width: 80.0%; } - .one.column, - .one.columns { - width: 4.66666666667%; } - - .two.columns { - width: 13.3333333333%; } +.twelve.columns { + width: 100%; + margin-left: 0; } +@media screen and (max-width: 860px) { .three.columns { - width: 22%; } - - .four.columns { - width: 30.6666666667%; } - - .five.columns { - width: 39.3333333333%; } - - .six.columns { - width: 48%; } - - .seven.columns { - width: 56.6666666667%; } - - .eight.columns { - width: 65.3333333333%; } - + display: none; + } .nine.columns { - width: 74.0%; } - - .ten.columns { - width: 82.6666666667%; } - - .eleven.columns { - width: 91.3333333333%; } - - .twelve.columns { - width: 100%; - margin-left: 0; } - - .one-third.column { - width: 30.6666666667%; } - - .two-thirds.column { - width: 65.3333333333%; } } -/* Customer Overrides */ -.footer { - text-align: center; - color: #969696; - padding-top: 10%; } - -p.module-desc { - font-size: 1.1em; - color: #666666; } - -a.link-seesrc { - color: #aec7d2; - font-style: italic; } - -a.link-seesrc:hover { - color: #6c9aae; } - -#toc-list { - word-wrap: break-word; } - -ul.simple-toc { - list-style: none; } - -ul.simple-toc a.reference-toplevel { - font-weight: bold; - color: #0077b3; } - -ul.simple-toc-section { - list-style-type: circle; - color: #6c9aae; } - -ul.simple-toc-section a.reference { - color: #0077b3; } + width: 98.0%; + } + body { + font-size: 1em; + line-height: 1.35; + } +} cite { font-style: italic !important; } -dt > pre { - border-color: rgba(0, 0, 0, 0.1); - background-color: rgba(255, 255, 255, 0.3); - margin: 15px 0px 5px; } - -dd > pre { - border-color: rgba(0, 0, 0, 0.1); - background-color: whitesmoke; - margin-top: 8px; } - -.item > dd { - margin-left: 10px; - margin-bottom: 30px; } - -/* Nim line-numbered tables */ -.line-nums-table { - width: 100%; - table-layout: fixed; } /* Nim search input */ div#searchInputDiv { - margin-bottom: 8px; + margin-bottom: 1em; } -div#searchInputDiv input#searchInput { - width: 10em; -} -div.search-groupby { - margin-bottom: 8px; +input#searchInput { + width: 80%; } -table.line-nums-table { - border-radius: 4px; - border: 1px solid #cccccc; - background-color: whitesmoke; - border-collapse: separate; - margin-top: 15px; - margin-bottom: 25px; } - -.line-nums-table tbody { - border: none; } - -.line-nums-table td pre { - border: none; - background-color: transparent; } - -.line-nums-table td.blob-line-nums { - width: 28px; } - -.line-nums-table td.blob-line-nums pre { - color: #b0b0b0; - -webkit-filter: opacity(75%); - text-align: right; - border-color: transparent; - background-color: transparent; - padding-left: 0px; - margin-left: 0px; - padding-right: 0px; - margin-right: 0px; } +/* + * Some custom formatting for input forms. + * This also fixes input form colors on Firefox with a dark system theme on Linux. + */ +input { + -moz-appearance: none; + color: #333; + background-color: #f8f8f8; + border: 1px solid #aaa; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-size: 0.9em; + padding: 6px; +} +input:focus { + border: 1px solid #1fa0eb; + box-shadow: 0 0 2px #1fa0eb; +} /* Docgen styles */ /* Links */ a { - color: #0077b3; - text-decoration: none; } + color: #07b; + text-decoration: none; +} + +a span.Identifier { + text-decoration: underline; + text-decoration-color: #aab; +} + +a.reference-toplevel { + font-weight: bold; +} + +a.toc-backref { + text-decoration: none; + color: #222; } + +a.link-seesrc { + color: #607c9f; + font-size: 0.9em; + font-style: italic; } a:hover, a:focus { - color: #00334d; + color: #607c9f; text-decoration: underline; } -a:visited { - color: #00334d; } +a:hover span.Identifier { + color: #607c9f; +} -a:focus { - outline: thin dotted #2d2d2d; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; } - -a:hover, -a:active { - outline: 0; } sub, sup { @@ -329,379 +227,258 @@ img { h2, h3 { - page-break-after: avoid; } } -.img-rounded { - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; } + page-break-after: avoid; } +} -.img-polaroid { - padding: 4px; - background-color: rgba(252, 248, 244, 0.75); - border: 1px solid #ccc; - border: 1px solid rgba(0, 0, 0, 0.2); - -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); - -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); } p { - margin: 0 0 8px; } + margin-top: 0.5em; + margin-bottom: 0.5em; +} small { font-size: 85%; } strong { - font-weight: 600; } + font-weight: 600; + font-size: 0.95em; + color: #3c3c3c; +} em { font-style: italic; } -cite { - font-style: normal; } - -h1, -h2, -h3, -h4, -h5, -h6 { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-weight: 600; - line-height: 20px; - color: inherit; - text-rendering: optimizelegibility; } - h1 { - font-size: 2em; + font-size: 1.8em; font-weight: 400; - padding-bottom: .15em; - border-bottom: 1px solid #aaaaaa; - margin-top: 1.0em; + padding-bottom: .25em; + border-bottom: 1px solid #aaa; + margin-top: 2.5em; + margin-bottom: 1em; line-height: 1.2em; } h1.title { padding-bottom: 1em; border-bottom: 0px; - font-size: 2.75em; } + font-size: 2.5em; + text-align: center; + font-weight: 900; + margin-top: 0.75em; + margin-bottom: 0em; +} h2 { - font-size: 1.5em; - margin-top: 1.5em; } + font-size: 1.3em; + margin-top: 2em; } + +h2.subtitle { + text-align: center; } h3 { - font-size: 1.3em; + font-size: 1.125em; font-style: italic; - margin-top: 0.75em; } + margin-top: 1.5em; } h4 { - font-size: 1.3em; - margin-top: 0.5em; } + font-size: 1.125em; + margin-top: 1em; } h5 { - font-size: 1.2em; - margin-top: 0.25em; } + font-size: 1.125em; + margin-top: 0.75em; } h6 { font-size: 1.1em; } + ul, ol { padding: 0; - margin: 0 0 0px 15px; } + margin-top: 0.5em; + margin-left: 0.75em; } ul ul, ul ol, ol ol, ol ul { - margin-bottom: 0; } + margin-bottom: 0; + margin-left: 1.25em; } li { - line-height: 20px; } - -dl { - margin-bottom: 20px; } - -dt, -dd { - line-height: 20px; } - -dt { - font-weight: bold; } - -dd { - margin-left: 10px; - margin-bottom: 26px; } - -hr { - margin: 20px 0; - border: 0; - border-top: 1px solid #eeeeee; - border-bottom: 1px solid #ffffff; } - -abbr[title], -abbr[data-original-title] { - cursor: help; - border-bottom: 1px dotted #999999; } - -abbr.initialism { - font-size: 90%; - text-transform: uppercase; } - -blockquote { - padding: 0 0 0 15px; - margin: 0 0 20px; - border-left: 5px solid #EFEBE0; } - -table.docinfo + blockquote, table.docinfo blockquote, h1 + blockquote { - border-left: 5px solid #c9c9c9; + list-style-type: circle; } -table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { - margin-bottom: 0; - font-size: 15px; - font-weight: 200; - line-height: 1.5; - font-style: italic; } +ul.simple-boot li { + list-style-type: none; + margin-left: 0em; + margin-bottom: 0.5em; +} -q:before, -q:after, -blockquote:before, -blockquote:after { - content: ""; } +ol.simple > li, ul.simple > li { + margin-bottom: 0.25em; + margin-left: 0.4em } -address { - display: block; - margin-bottom: 20px; - font-style: normal; - line-height: 20px; } +ul.simple.simple-toc > li { + margin-top: 1em; +} -code, -pre { - font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - padding: 0 3px 2px; - font-weight: 500; - font-size: 12px; - color: #444444; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; } +ul.simple-toc { + list-style: none; + font-size: 0.9em; + margin-left: -0.3em; + margin-top: 1em; } + +ul.simple-toc > li { + list-style-type: none; +} + +ul.simple-toc-section { + list-style-type: circle; + margin-left: 1em; + color: #6c9aae; } + + +ol.arabic { + list-style: decimal; } + +ol.loweralpha { + list-style: lower-alpha; } + +ol.upperalpha { + list-style: upper-alpha; } + +ol.lowerroman { + list-style: lower-roman; } + +ol.upperroman { + list-style: upper-roman; } + +ul.auto-toc { + list-style-type: none; } + + +dl { + margin-bottom: 1.5em; } + +dt { + margin-bottom: -0.5em; + margin-left: 0.0em; } + +dd { + margin-left: 2.0em; + margin-bottom: 3.0em; + margin-top: 0.5em; } + + +hr { + margin: 2em 0; + border: 0; + border-top: 1px solid #aaa; } + +blockquote { + font-size: 0.9em; + font-style: italic; + padding-left: 0.5em; + margin-left: 0; + border-left: 5px solid #bbc; +} .pre { font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - font-weight: 600; - /*color: #504da6;*/ + font-weight: 500; + font-size: 0.85em; + background-color: #f0f3ff; + padding-left: 3px; + padding-right: 3px; + border-radius: 4px; } -code { - padding: 2px 4px; - color: #444444; - white-space: nowrap; - background-color: white; - border: 1px solid #777777; } - pre { + font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; + color: #222; + font-weight: 500; display: inline-block; box-sizing: border-box; - min-width: calc(100% - 19.5px); - padding: 9.5px; - margin: 0.25em 10px 10px 10px; - font-size: 15px; - line-height: 20px; + min-width: 100%; + padding: 0.5em; + margin-top: 0.5em; + margin-bottom: 0.5em; + font-size: 0.85em; white-space: pre !important; overflow-y: hidden; overflow-x: visible; - background-color: rgba(0, 0, 0, 0.01); - border: 1px solid #cccccc; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; } - -pre.prettyprint { - margin-bottom: 20px; } - -pre code { - padding: 0; - color: inherit; - white-space: pre; - overflow-x: visible; - background-color: transparent; - border: 0; } + background-color: ghostwhite; + border: 1px solid #dde; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; } .pre-scrollable { max-height: 340px; overflow-y: scroll; } + +/* Nim line-numbered tables */ +.line-nums-table { + width: 100%; + table-layout: fixed; } + +table.line-nums-table { + border-radius: 4px; + border: 1px solid #cccccc; + background-color: ghostwhite; + border-collapse: separate; + margin-top: 15px; + margin-bottom: 25px; } + +.line-nums-table tbody { + border: none; } + +.line-nums-table td pre { + border: none; + background-color: transparent; } + +.line-nums-table td.blob-line-nums { + width: 28px; } + +.line-nums-table td.blob-line-nums pre { + color: #b0b0b0; + -webkit-filter: opacity(75%); + text-align: right; + border-color: transparent; + background-color: transparent; + padding-left: 0px; + margin-left: 0px; + padding-right: 0px; + margin-right: 0px; } + + table { max-width: 100%; background-color: transparent; + margin-top: 0.5em; + margin-bottom: 1.5em; border-collapse: collapse; - border-spacing: 0; } - -table th, table td { - padding: 0px 8px 0px; + border-color: #ccc; + border-spacing: 0; + font-size: 0.9em; } -.table { - width: 100%; - margin-bottom: 20px; } +table th, table td { + padding: 0px 0.5em 0px; +} -.table th, -.table td { - padding: 8px; - line-height: 20px; - text-align: left; - vertical-align: top; - border-top: 1px solid #444444; } - -.table th { +table th { + background-color: #e8e8e8; font-weight: bold; } -.table thead th { - vertical-align: bottom; } +table th.docinfo-name { + background-color: transparent; +} -.table caption + thead tr:first-child th, -.table caption + thead tr:first-child td, -.table colgroup + thead tr:first-child th, -.table colgroup + thead tr:first-child td, -.table thead:first-child tr:first-child th, -.table thead:first-child tr:first-child td { - border-top: 0; } +table tr:hover { + background-color: ghostwhite; } -.table tbody + tbody { - border-top: 2px solid #444444; } - -.table .table { - background-color: rgba(252, 248, 244, 0.75); } - -.table-condensed th, -.table-condensed td { - padding: 4px 5px; } - -.table-bordered { - border: 1px solid #444444; - border-collapse: separate; - *border-collapse: collapse; - border-left: 0; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; } - -.table-bordered th, -.table-bordered td { - border-left: 1px solid #444444; } - -.table-bordered caption + thead tr:first-child th, -.table-bordered caption + tbody tr:first-child th, -.table-bordered caption + tbody tr:first-child td, -.table-bordered colgroup + thead tr:first-child th, -.table-bordered colgroup + tbody tr:first-child th, -.table-bordered colgroup + tbody tr:first-child td, -.table-bordered thead:first-child tr:first-child th, -.table-bordered tbody:first-child tr:first-child th, -.table-bordered tbody:first-child tr:first-child td { - border-top: 0; } - -.table-bordered thead:first-child tr:first-child > th:first-child, -.table-bordered tbody:first-child tr:first-child > td:first-child, -.table-bordered tbody:first-child tr:first-child > th:first-child { - -webkit-border-top-left-radius: 4px; - border-top-left-radius: 4px; - -moz-border-radius-topleft: 4px; } - -.table-bordered thead:first-child tr:first-child > th:last-child, -.table-bordered tbody:first-child tr:first-child > td:last-child, -.table-bordered tbody:first-child tr:first-child > th:last-child { - -webkit-border-top-right-radius: 4px; - border-top-right-radius: 4px; - -moz-border-radius-topright: 4px; } - -.table-bordered thead:last-child tr:last-child > th:first-child, -.table-bordered tbody:last-child tr:last-child > td:first-child, -.table-bordered tbody:last-child tr:last-child > th:first-child, -.table-bordered tfoot:last-child tr:last-child > td:first-child, -.table-bordered tfoot:last-child tr:last-child > th:first-child { - -webkit-border-bottom-left-radius: 4px; - border-bottom-left-radius: 4px; - -moz-border-radius-bottomleft: 4px; } - -.table-bordered thead:last-child tr:last-child > th:last-child, -.table-bordered tbody:last-child tr:last-child > td:last-child, -.table-bordered tbody:last-child tr:last-child > th:last-child, -.table-bordered tfoot:last-child tr:last-child > td:last-child, -.table-bordered tfoot:last-child tr:last-child > th:last-child { - -webkit-border-bottom-right-radius: 4px; - border-bottom-right-radius: 4px; - -moz-border-radius-bottomright: 4px; } - -.table-bordered tfoot + tbody:last-child tr:last-child td:first-child { - -webkit-border-bottom-left-radius: 0; - border-bottom-left-radius: 0; - -moz-border-radius-bottomleft: 0; } - -.table-bordered tfoot + tbody:last-child tr:last-child td:last-child { - -webkit-border-bottom-right-radius: 0; - border-bottom-right-radius: 0; - -moz-border-radius-bottomright: 0; } - -.table-bordered caption + thead tr:first-child th:first-child, -.table-bordered caption + tbody tr:first-child td:first-child, -.table-bordered colgroup + thead tr:first-child th:first-child, -.table-bordered colgroup + tbody tr:first-child td:first-child { - -webkit-border-top-left-radius: 4px; - border-top-left-radius: 4px; - -moz-border-radius-topleft: 4px; } - -.table-bordered caption + thead tr:first-child th:last-child, -.table-bordered caption + tbody tr:first-child td:last-child, -.table-bordered colgroup + thead tr:first-child th:last-child, -.table-bordered colgroup + tbody tr:first-child td:last-child { - -webkit-border-top-right-radius: 4px; - border-top-right-radius: 4px; - -moz-border-radius-topright: 4px; } - -table.docutils th { - background-color: #e8e8e8; } - -table.docutils tr:hover { - background-color: whitesmoke; } - -.table-striped tbody > tr:nth-child(odd) > td, -.table-striped tbody > tr:nth-child(odd) > th { - background-color: rgba(252, 248, 244, 0.75); } - -.table-hover tbody tr:hover > td, -.table-hover tbody tr:hover > th { - background-color: rgba(241, 222, 204, 0.75); } - -table td[class*="span"], -table th[class*="span"], -.row-fluid table td[class*="span"], -.row-fluid table th[class*="span"] { - display: table-cell; - float: none; - margin-left: 0; } - -.hero-unit { - padding: 60px; - margin-bottom: 30px; - font-size: 18px; - font-weight: 200; - line-height: 30px; - color: inherit; - background-color: rgba(230, 197, 164, 0.75); - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; } - -.hero-unit h1 { - margin-bottom: 0; - font-size: 60px; - line-height: 1; - letter-spacing: -1px; - color: inherit; } - -.hero-unit li { - line-height: 30px; } /* rst2html default used to remove borders from tables and images */ .borderless, table.borderless td, table.borderless th { @@ -722,10 +499,6 @@ table.borderless td, table.borderless th { .hidden { display: none; } -a.toc-backref { - text-decoration: none; - color: #444444; } - blockquote.epigraph { margin: 2em 5em; } @@ -735,85 +508,6 @@ dl.docutils dd { object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] { overflow: hidden; } -/* Uncomment (and remove this text!) to get bold-faced definition list terms -dl.docutils dt { - font-weight: bold } -*/ -div.abstract { - margin: 2em 5em; } - -div.abstract p.topic-title { - font-weight: bold; - text-align: center; } - -div.admonition, div.attention, div.caution, div.danger, div.error, -div.hint, div.important, div.note, div.tip, div.warning { - margin: 2em; - border: medium outset; - padding: 1em; } - -div.note, div.warning { - margin: 1.5em 0px; - border: none; } - -div.note p.admonition-title, -div.warning p.admonition-title { - display: none; } - -/* Clearfix - * http://css-tricks.com/snippets/css/clear-fix/ - */ -div.note:after, -div.warning:after { - content: ""; - display: table; - clear: both; } - -div.note p:before, -div.warning p:before { - display: block; - float: left; - font-size: 4em; - line-height: 1em; - margin-right: 20px; - margin-left: 0em; - margin-top: -10px; - content: '\0270D'; - /*handwriting*/ } - -div.warning p:before { - content: '\026A0'; - /*warning*/ } - -div.admonition p.admonition-title, div.hint p.admonition-title, -div.important p.admonition-title, div.note p.admonition-title, -div.tip p.admonition-title { - font-weight: bold; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } - -div.attention p.admonition-title, div.caution p.admonition-title, -div.danger p.admonition-title, div.error p.admonition-title, -div.warning p.admonition-title, .code .error { - color: #b30000; - font-weight: bold; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } - -/* Uncomment (and remove this text!) to get reduced vertical space in - compound paragraphs. -div.compound .compound-first, div.compound .compound-middle { - margin-bottom: 0.5em } - -div.compound .compound-last, div.compound .compound-middle { - margin-top: 0.5em } -*/ -div.dedication { - margin: 2em 5em; - text-align: center; - font-style: italic; } - -div.dedication p.topic-title { - font-weight: bold; - font-style: normal; } div.figure { margin-left: 2em; @@ -821,8 +515,14 @@ div.figure { div.footer, div.header { clear: both; + text-align: center; + color: #666; font-size: smaller; } +div.footer { + padding-top: 5em; +} + div.line-block { display: block; margin-top: 1em; @@ -833,45 +533,24 @@ div.line-block div.line-block { margin-bottom: 0; margin-left: 1.5em; } -div.sidebar { - margin: 0 0 0.5em 1em; - border: medium outset; - padding: 1em; - background-color: rgba(252, 248, 244, 0.75); - width: 40%; - float: right; - clear: right; } - -div.sidebar p.rubric { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-size: medium; } - -div.system-messages { - margin: 5em; } - -div.system-messages h1 { - color: #b30000; } - -div.system-message { - border: medium outset; - padding: 1em; } - -div.system-message p.system-message-title { - color: #b30000; - font-weight: bold; } - div.topic { margin: 2em; } -h1.section-subtitle, h2.section-subtitle, h3.section-subtitle, -h4.section-subtitle, h5.section-subtitle, h6.section-subtitle { - margin-top: 0.4em; } +div.search_results { + background-color: antiquewhite; + margin: 3em; + padding: 1em; + border: 1px solid #4d4d4d; +} -h1.title { - text-align: center; } +div#global-links ul { + margin-left: 0; + list-style-type: none; +} -h2.subtitle { - text-align: center; } +div#global-links > simple-boot { + margin-left: 3em; +} hr.docutils { width: 75%; } @@ -905,30 +584,6 @@ img.align-center, .figure.align-center, object.align-center { div.align-right { text-align: inherit; } -/* div.align-center * { */ -/* text-align: left } */ - -ul.simple > li { - margin-bottom: 0.5em } - -ol.simple, ul.simple { - margin-bottom: 1em; } - -ol.arabic { - list-style: decimal; } - -ol.loweralpha { - list-style: lower-alpha; } - -ol.upperalpha { - list-style: upper-alpha; } - -ol.lowerroman { - list-style: lower-roman; } - -ol.upperroman { - list-style: upper-roman; } - p.attribution { text-align: right; margin-left: 50%; } @@ -949,15 +604,6 @@ p.rubric { color: maroon; text-align: center; } -p.sidebar-title { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-weight: bold; - font-size: larger; } - -p.sidebar-subtitle { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-weight: bold; } - p.topic-title { font-weight: bold; } @@ -997,22 +643,14 @@ pre.code .inserted, code .inserted { background-color: #A3D289; } span.classifier { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-style: oblique; } span.classifier-delimiter { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: bold; } -span.interpreted { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } - span.option { white-space: nowrap; } -span.pre { - white-space: pre; } - span.problematic { color: #b30000; } @@ -1020,44 +658,6 @@ span.section-subtitle { /* font-size relative to parent (h1..h6 element) */ font-size: 80%; } -table.citation { - border-left: solid 1px #666666; - margin-left: 1px; } - -table.docinfo { - margin: 0em; - margin-top: 2em; - margin-bottom: 2em; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; - color: #444444; } - -table.docutils { - margin-top: 0.5em; - margin-bottom: 0.5em; } - -table.footnote { - border-left: solid 1px #2d2d2d; - margin-left: 1px; } - -table.docutils td, table.docutils th, -table.docinfo td, table.docinfo th { - padding-left: 0.5em; - padding-right: 0.5em; - vertical-align: top; } - -table.docutils th.field-name, table.docinfo th.docinfo-name { - font-weight: 700; - text-align: left; - white-space: nowrap; - padding-left: 0; } - -h1 tt.docutils, h2 tt.docutils, h3 tt.docutils, -h4 tt.docutils, h5 tt.docutils, h6 tt.docutils { - font-size: 100%; } - -ul.auto-toc { - list-style-type: none; } - span.DecNumber { color: #252dbe; } @@ -1074,7 +674,7 @@ span.FloatNumber { color: #252dbe; } span.Identifier { - color: #3b3b3b; } + color: #222; } span.Keyword { font-weight: 600; @@ -1139,38 +739,23 @@ dt pre > span.Identifier, dt pre > span.Operator { color: #155da4; font-weight: 700; } -dt pre > span.Identifier ~ span.Identifier, dt pre > span.Operator ~ span.Identifier { - color: inherit; - font-weight: inherit; } - -dt pre > span.Operator ~ span.Identifier { +dt pre > span.Keyword ~ span.Identifier, dt pre > span.Identifier ~ span.Identifier, +dt pre > span.Operator ~ span.Identifier, dt pre > span.Other ~ span.Identifier { color: inherit; font-weight: inherit; } /* Nim sprite for the footer (taken from main page favicon) */ .nim-sprite { display: inline-block; - height: 12px; - width: 12px; + height: 16px; + width: 16px; background-position: 0 0; - background-size: 12px 12px; + background-size: 16px 16px; -webkit-filter: opacity(50%); background-repeat: no-repeat; background-image: url("data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="); margin-bottom: -5px; } -div.search_results { - background-color: antiquewhite; - margin: 3em; - padding: 1em; - border: 1px solid #4d4d4d; -} - -div#global-links ul { - margin-left: 0; - list-style-type: none; -} - span.pragmadots { /* Position: relative frees us up to make the dots look really nice without fucking up the layout and @@ -1178,18 +763,14 @@ span.pragmadots { position: relative; /* 1px down looks slightly nicer */ top: 1px; - padding: 2px; - background-color: #D3D3D3; + background-color: #e8e8e8; border-radius: 4px; margin: 0 2px; cursor: pointer; - - /* For some reason on Chrome, making the font size - smaller than 1em is causing the parent container to - bulge slightly. So, we're stuck with inheriting 1em, - which is sad, because 0.8em looks better... */ + font-size: 0.8em; } + span.pragmadots:hover { background-color: #DBDBDB; } @@ -1197,6 +778,10 @@ span.pragmawrap { display: none; } +span.attachedType { + display: none; + visibility: hidden; +} @@ -1245,9 +830,9 @@ function main() { title="Symbol = object name*: string parent*: string - kind*: NimSymKind">Symbol + kind*: NimSymKind">Symbol
  • OnSymbol
  • + title="OnSymbol = proc (sym: var Symbol) {.cdecl.}">OnSymbol
@@ -1257,6 +842,7 @@ function main() {
+

Types

@@ -1270,12 +856,14 @@ function main() {
+
OnSymbol = proc (sym: var Symbol) {...}{.cdecl.}
+
@@ -1287,7 +875,7 @@ function main() {
diff --git a/plugin.idx b/plugin.idx old mode 100755 new mode 100644 diff --git a/theindex.html b/theindex.html old mode 100755 new mode 100644 index c2bed34..bae06e4 --- a/theindex.html +++ b/theindex.html @@ -27,232 +27,130 @@ customize this style sheet. Modified from Chad Skeeters' rst2html-style https://bitbucket.org/cskeeters/rst2html-style/ -Modified by Boyd Greenfield +Modified by Boyd Greenfield and narimiran */ -/* SCSS variables */ -/* Text weights */ -/* Body colors */ -/* Text colors */ -/* Link colors */ -/* Syntax highlighting colors */ -/* Pct changes */ -/* Mixins */ -/* Body/layout */ + html { font-size: 100%; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; } -/* Where we want fancier font if available */ -h1, h2, h3, h4, h5, h6, p.module-desc, table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; } - -h1.title { - font-weight: 900; } - body { font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: 400; - font-size: 16px; - line-height: 20px; - color: #444; - letter-spacing: 0.15px; - background-color: #FDFBFA; } + font-size: 1.125em; + line-height: 1.5; + color: #222; + background-color: #FCFCFC; } /* Skeleton grid */ .container { position: relative; width: 100%; - max-width: 960px; + max-width: 1050px; margin: 0 auto; - padding: 0 20px; + padding: 0; box-sizing: border-box; } .column, .columns { width: 100%; float: left; - box-sizing: border-box; } + box-sizing: border-box; + margin-left: 1%; +} -/* For devices larger than 400px */ -@media (min-width: 400px) { - .container { - width: 100%; - padding: 0; } } -/* For devices larger than 650px */ -@media (min-width: 650px) { - .container { - width: 100%; } +.column:first-child, +.columns:first-child { + margin-left: 0; } - .column, - .columns { - margin-left: 4%; } +.three.columns { + width: 19%; } - .column:first-child, - .columns:first-child { - margin-left: 0; } +.nine.columns { + width: 80.0%; } - .one.column, - .one.columns { - width: 4.66666666667%; } - - .two.columns { - width: 13.3333333333%; } +.twelve.columns { + width: 100%; + margin-left: 0; } +@media screen and (max-width: 860px) { .three.columns { - width: 22%; } - - .four.columns { - width: 30.6666666667%; } - - .five.columns { - width: 39.3333333333%; } - - .six.columns { - width: 48%; } - - .seven.columns { - width: 56.6666666667%; } - - .eight.columns { - width: 65.3333333333%; } - + display: none; + } .nine.columns { - width: 74.0%; } - - .ten.columns { - width: 82.6666666667%; } - - .eleven.columns { - width: 91.3333333333%; } - - .twelve.columns { - width: 100%; - margin-left: 0; } - - .one-third.column { - width: 30.6666666667%; } - - .two-thirds.column { - width: 65.3333333333%; } } -/* Customer Overrides */ -.footer { - text-align: center; - color: #969696; - padding-top: 10%; } - -p.module-desc { - font-size: 1.1em; - color: #666666; } - -a.link-seesrc { - color: #aec7d2; - font-style: italic; } - -a.link-seesrc:hover { - color: #6c9aae; } - -#toc-list { - word-wrap: break-word; } - -ul.simple-toc { - list-style: none; } - -ul.simple-toc a.reference-toplevel { - font-weight: bold; - color: #0077b3; } - -ul.simple-toc-section { - list-style-type: circle; - color: #6c9aae; } - -ul.simple-toc-section a.reference { - color: #0077b3; } + width: 98.0%; + } + body { + font-size: 1em; + line-height: 1.35; + } +} cite { font-style: italic !important; } -dt > pre { - border-color: rgba(0, 0, 0, 0.1); - background-color: rgba(255, 255, 255, 0.3); - margin: 15px 0px 5px; } - -dd > pre { - border-color: rgba(0, 0, 0, 0.1); - background-color: whitesmoke; - margin-top: 8px; } - -.item > dd { - margin-left: 10px; - margin-bottom: 30px; } - -/* Nim line-numbered tables */ -.line-nums-table { - width: 100%; - table-layout: fixed; } /* Nim search input */ div#searchInputDiv { - margin-bottom: 8px; + margin-bottom: 1em; } -div#searchInputDiv input#searchInput { - width: 10em; -} -div.search-groupby { - margin-bottom: 8px; +input#searchInput { + width: 80%; } -table.line-nums-table { - border-radius: 4px; - border: 1px solid #cccccc; - background-color: whitesmoke; - border-collapse: separate; - margin-top: 15px; - margin-bottom: 25px; } - -.line-nums-table tbody { - border: none; } - -.line-nums-table td pre { - border: none; - background-color: transparent; } - -.line-nums-table td.blob-line-nums { - width: 28px; } - -.line-nums-table td.blob-line-nums pre { - color: #b0b0b0; - -webkit-filter: opacity(75%); - text-align: right; - border-color: transparent; - background-color: transparent; - padding-left: 0px; - margin-left: 0px; - padding-right: 0px; - margin-right: 0px; } +/* + * Some custom formatting for input forms. + * This also fixes input form colors on Firefox with a dark system theme on Linux. + */ +input { + -moz-appearance: none; + color: #333; + background-color: #f8f8f8; + border: 1px solid #aaa; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-size: 0.9em; + padding: 6px; +} +input:focus { + border: 1px solid #1fa0eb; + box-shadow: 0 0 2px #1fa0eb; +} /* Docgen styles */ /* Links */ a { - color: #0077b3; - text-decoration: none; } + color: #07b; + text-decoration: none; +} + +a span.Identifier { + text-decoration: underline; + text-decoration-color: #aab; +} + +a.reference-toplevel { + font-weight: bold; +} + +a.toc-backref { + text-decoration: none; + color: #222; } + +a.link-seesrc { + color: #607c9f; + font-size: 0.9em; + font-style: italic; } a:hover, a:focus { - color: #00334d; + color: #607c9f; text-decoration: underline; } -a:visited { - color: #00334d; } +a:hover span.Identifier { + color: #607c9f; +} -a:focus { - outline: thin dotted #2d2d2d; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; } - -a:hover, -a:active { - outline: 0; } sub, sup { @@ -329,379 +227,258 @@ img { h2, h3 { - page-break-after: avoid; } } -.img-rounded { - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; } + page-break-after: avoid; } +} -.img-polaroid { - padding: 4px; - background-color: rgba(252, 248, 244, 0.75); - border: 1px solid #ccc; - border: 1px solid rgba(0, 0, 0, 0.2); - -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); - -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); } p { - margin: 0 0 8px; } + margin-top: 0.5em; + margin-bottom: 0.5em; +} small { font-size: 85%; } strong { - font-weight: 600; } + font-weight: 600; + font-size: 0.95em; + color: #3c3c3c; +} em { font-style: italic; } -cite { - font-style: normal; } - -h1, -h2, -h3, -h4, -h5, -h6 { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-weight: 600; - line-height: 20px; - color: inherit; - text-rendering: optimizelegibility; } - h1 { - font-size: 2em; + font-size: 1.8em; font-weight: 400; - padding-bottom: .15em; - border-bottom: 1px solid #aaaaaa; - margin-top: 1.0em; + padding-bottom: .25em; + border-bottom: 1px solid #aaa; + margin-top: 2.5em; + margin-bottom: 1em; line-height: 1.2em; } h1.title { padding-bottom: 1em; border-bottom: 0px; - font-size: 2.75em; } + font-size: 2.5em; + text-align: center; + font-weight: 900; + margin-top: 0.75em; + margin-bottom: 0em; +} h2 { - font-size: 1.5em; - margin-top: 1.5em; } + font-size: 1.3em; + margin-top: 2em; } + +h2.subtitle { + text-align: center; } h3 { - font-size: 1.3em; + font-size: 1.125em; font-style: italic; - margin-top: 0.75em; } + margin-top: 1.5em; } h4 { - font-size: 1.3em; - margin-top: 0.5em; } + font-size: 1.125em; + margin-top: 1em; } h5 { - font-size: 1.2em; - margin-top: 0.25em; } + font-size: 1.125em; + margin-top: 0.75em; } h6 { font-size: 1.1em; } + ul, ol { padding: 0; - margin: 0 0 0px 15px; } + margin-top: 0.5em; + margin-left: 0.75em; } ul ul, ul ol, ol ol, ol ul { - margin-bottom: 0; } + margin-bottom: 0; + margin-left: 1.25em; } li { - line-height: 20px; } - -dl { - margin-bottom: 20px; } - -dt, -dd { - line-height: 20px; } - -dt { - font-weight: bold; } - -dd { - margin-left: 10px; - margin-bottom: 26px; } - -hr { - margin: 20px 0; - border: 0; - border-top: 1px solid #eeeeee; - border-bottom: 1px solid #ffffff; } - -abbr[title], -abbr[data-original-title] { - cursor: help; - border-bottom: 1px dotted #999999; } - -abbr.initialism { - font-size: 90%; - text-transform: uppercase; } - -blockquote { - padding: 0 0 0 15px; - margin: 0 0 20px; - border-left: 5px solid #EFEBE0; } - -table.docinfo + blockquote, table.docinfo blockquote, h1 + blockquote { - border-left: 5px solid #c9c9c9; + list-style-type: circle; } -table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { - margin-bottom: 0; - font-size: 15px; - font-weight: 200; - line-height: 1.5; - font-style: italic; } +ul.simple-boot li { + list-style-type: none; + margin-left: 0em; + margin-bottom: 0.5em; +} -q:before, -q:after, -blockquote:before, -blockquote:after { - content: ""; } +ol.simple > li, ul.simple > li { + margin-bottom: 0.25em; + margin-left: 0.4em } -address { - display: block; - margin-bottom: 20px; - font-style: normal; - line-height: 20px; } +ul.simple.simple-toc > li { + margin-top: 1em; +} -code, -pre { - font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - padding: 0 3px 2px; - font-weight: 500; - font-size: 12px; - color: #444444; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; } +ul.simple-toc { + list-style: none; + font-size: 0.9em; + margin-left: -0.3em; + margin-top: 1em; } + +ul.simple-toc > li { + list-style-type: none; +} + +ul.simple-toc-section { + list-style-type: circle; + margin-left: 1em; + color: #6c9aae; } + + +ol.arabic { + list-style: decimal; } + +ol.loweralpha { + list-style: lower-alpha; } + +ol.upperalpha { + list-style: upper-alpha; } + +ol.lowerroman { + list-style: lower-roman; } + +ol.upperroman { + list-style: upper-roman; } + +ul.auto-toc { + list-style-type: none; } + + +dl { + margin-bottom: 1.5em; } + +dt { + margin-bottom: -0.5em; + margin-left: 0.0em; } + +dd { + margin-left: 2.0em; + margin-bottom: 3.0em; + margin-top: 0.5em; } + + +hr { + margin: 2em 0; + border: 0; + border-top: 1px solid #aaa; } + +blockquote { + font-size: 0.9em; + font-style: italic; + padding-left: 0.5em; + margin-left: 0; + border-left: 5px solid #bbc; +} .pre { font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - font-weight: 600; - /*color: #504da6;*/ + font-weight: 500; + font-size: 0.85em; + background-color: #f0f3ff; + padding-left: 3px; + padding-right: 3px; + border-radius: 4px; } -code { - padding: 2px 4px; - color: #444444; - white-space: nowrap; - background-color: white; - border: 1px solid #777777; } - pre { + font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; + color: #222; + font-weight: 500; display: inline-block; box-sizing: border-box; - min-width: calc(100% - 19.5px); - padding: 9.5px; - margin: 0.25em 10px 10px 10px; - font-size: 15px; - line-height: 20px; + min-width: 100%; + padding: 0.5em; + margin-top: 0.5em; + margin-bottom: 0.5em; + font-size: 0.85em; white-space: pre !important; overflow-y: hidden; overflow-x: visible; - background-color: rgba(0, 0, 0, 0.01); - border: 1px solid #cccccc; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; } - -pre.prettyprint { - margin-bottom: 20px; } - -pre code { - padding: 0; - color: inherit; - white-space: pre; - overflow-x: visible; - background-color: transparent; - border: 0; } + background-color: ghostwhite; + border: 1px solid #dde; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; } .pre-scrollable { max-height: 340px; overflow-y: scroll; } + +/* Nim line-numbered tables */ +.line-nums-table { + width: 100%; + table-layout: fixed; } + +table.line-nums-table { + border-radius: 4px; + border: 1px solid #cccccc; + background-color: ghostwhite; + border-collapse: separate; + margin-top: 15px; + margin-bottom: 25px; } + +.line-nums-table tbody { + border: none; } + +.line-nums-table td pre { + border: none; + background-color: transparent; } + +.line-nums-table td.blob-line-nums { + width: 28px; } + +.line-nums-table td.blob-line-nums pre { + color: #b0b0b0; + -webkit-filter: opacity(75%); + text-align: right; + border-color: transparent; + background-color: transparent; + padding-left: 0px; + margin-left: 0px; + padding-right: 0px; + margin-right: 0px; } + + table { max-width: 100%; background-color: transparent; + margin-top: 0.5em; + margin-bottom: 1.5em; border-collapse: collapse; - border-spacing: 0; } - -table th, table td { - padding: 0px 8px 0px; + border-color: #ccc; + border-spacing: 0; + font-size: 0.9em; } -.table { - width: 100%; - margin-bottom: 20px; } +table th, table td { + padding: 0px 0.5em 0px; +} -.table th, -.table td { - padding: 8px; - line-height: 20px; - text-align: left; - vertical-align: top; - border-top: 1px solid #444444; } - -.table th { +table th { + background-color: #e8e8e8; font-weight: bold; } -.table thead th { - vertical-align: bottom; } +table th.docinfo-name { + background-color: transparent; +} -.table caption + thead tr:first-child th, -.table caption + thead tr:first-child td, -.table colgroup + thead tr:first-child th, -.table colgroup + thead tr:first-child td, -.table thead:first-child tr:first-child th, -.table thead:first-child tr:first-child td { - border-top: 0; } +table tr:hover { + background-color: ghostwhite; } -.table tbody + tbody { - border-top: 2px solid #444444; } - -.table .table { - background-color: rgba(252, 248, 244, 0.75); } - -.table-condensed th, -.table-condensed td { - padding: 4px 5px; } - -.table-bordered { - border: 1px solid #444444; - border-collapse: separate; - *border-collapse: collapse; - border-left: 0; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; } - -.table-bordered th, -.table-bordered td { - border-left: 1px solid #444444; } - -.table-bordered caption + thead tr:first-child th, -.table-bordered caption + tbody tr:first-child th, -.table-bordered caption + tbody tr:first-child td, -.table-bordered colgroup + thead tr:first-child th, -.table-bordered colgroup + tbody tr:first-child th, -.table-bordered colgroup + tbody tr:first-child td, -.table-bordered thead:first-child tr:first-child th, -.table-bordered tbody:first-child tr:first-child th, -.table-bordered tbody:first-child tr:first-child td { - border-top: 0; } - -.table-bordered thead:first-child tr:first-child > th:first-child, -.table-bordered tbody:first-child tr:first-child > td:first-child, -.table-bordered tbody:first-child tr:first-child > th:first-child { - -webkit-border-top-left-radius: 4px; - border-top-left-radius: 4px; - -moz-border-radius-topleft: 4px; } - -.table-bordered thead:first-child tr:first-child > th:last-child, -.table-bordered tbody:first-child tr:first-child > td:last-child, -.table-bordered tbody:first-child tr:first-child > th:last-child { - -webkit-border-top-right-radius: 4px; - border-top-right-radius: 4px; - -moz-border-radius-topright: 4px; } - -.table-bordered thead:last-child tr:last-child > th:first-child, -.table-bordered tbody:last-child tr:last-child > td:first-child, -.table-bordered tbody:last-child tr:last-child > th:first-child, -.table-bordered tfoot:last-child tr:last-child > td:first-child, -.table-bordered tfoot:last-child tr:last-child > th:first-child { - -webkit-border-bottom-left-radius: 4px; - border-bottom-left-radius: 4px; - -moz-border-radius-bottomleft: 4px; } - -.table-bordered thead:last-child tr:last-child > th:last-child, -.table-bordered tbody:last-child tr:last-child > td:last-child, -.table-bordered tbody:last-child tr:last-child > th:last-child, -.table-bordered tfoot:last-child tr:last-child > td:last-child, -.table-bordered tfoot:last-child tr:last-child > th:last-child { - -webkit-border-bottom-right-radius: 4px; - border-bottom-right-radius: 4px; - -moz-border-radius-bottomright: 4px; } - -.table-bordered tfoot + tbody:last-child tr:last-child td:first-child { - -webkit-border-bottom-left-radius: 0; - border-bottom-left-radius: 0; - -moz-border-radius-bottomleft: 0; } - -.table-bordered tfoot + tbody:last-child tr:last-child td:last-child { - -webkit-border-bottom-right-radius: 0; - border-bottom-right-radius: 0; - -moz-border-radius-bottomright: 0; } - -.table-bordered caption + thead tr:first-child th:first-child, -.table-bordered caption + tbody tr:first-child td:first-child, -.table-bordered colgroup + thead tr:first-child th:first-child, -.table-bordered colgroup + tbody tr:first-child td:first-child { - -webkit-border-top-left-radius: 4px; - border-top-left-radius: 4px; - -moz-border-radius-topleft: 4px; } - -.table-bordered caption + thead tr:first-child th:last-child, -.table-bordered caption + tbody tr:first-child td:last-child, -.table-bordered colgroup + thead tr:first-child th:last-child, -.table-bordered colgroup + tbody tr:first-child td:last-child { - -webkit-border-top-right-radius: 4px; - border-top-right-radius: 4px; - -moz-border-radius-topright: 4px; } - -table.docutils th { - background-color: #e8e8e8; } - -table.docutils tr:hover { - background-color: whitesmoke; } - -.table-striped tbody > tr:nth-child(odd) > td, -.table-striped tbody > tr:nth-child(odd) > th { - background-color: rgba(252, 248, 244, 0.75); } - -.table-hover tbody tr:hover > td, -.table-hover tbody tr:hover > th { - background-color: rgba(241, 222, 204, 0.75); } - -table td[class*="span"], -table th[class*="span"], -.row-fluid table td[class*="span"], -.row-fluid table th[class*="span"] { - display: table-cell; - float: none; - margin-left: 0; } - -.hero-unit { - padding: 60px; - margin-bottom: 30px; - font-size: 18px; - font-weight: 200; - line-height: 30px; - color: inherit; - background-color: rgba(230, 197, 164, 0.75); - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; } - -.hero-unit h1 { - margin-bottom: 0; - font-size: 60px; - line-height: 1; - letter-spacing: -1px; - color: inherit; } - -.hero-unit li { - line-height: 30px; } /* rst2html default used to remove borders from tables and images */ .borderless, table.borderless td, table.borderless th { @@ -722,10 +499,6 @@ table.borderless td, table.borderless th { .hidden { display: none; } -a.toc-backref { - text-decoration: none; - color: #444444; } - blockquote.epigraph { margin: 2em 5em; } @@ -735,85 +508,6 @@ dl.docutils dd { object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] { overflow: hidden; } -/* Uncomment (and remove this text!) to get bold-faced definition list terms -dl.docutils dt { - font-weight: bold } -*/ -div.abstract { - margin: 2em 5em; } - -div.abstract p.topic-title { - font-weight: bold; - text-align: center; } - -div.admonition, div.attention, div.caution, div.danger, div.error, -div.hint, div.important, div.note, div.tip, div.warning { - margin: 2em; - border: medium outset; - padding: 1em; } - -div.note, div.warning { - margin: 1.5em 0px; - border: none; } - -div.note p.admonition-title, -div.warning p.admonition-title { - display: none; } - -/* Clearfix - * http://css-tricks.com/snippets/css/clear-fix/ - */ -div.note:after, -div.warning:after { - content: ""; - display: table; - clear: both; } - -div.note p:before, -div.warning p:before { - display: block; - float: left; - font-size: 4em; - line-height: 1em; - margin-right: 20px; - margin-left: 0em; - margin-top: -10px; - content: '\0270D'; - /*handwriting*/ } - -div.warning p:before { - content: '\026A0'; - /*warning*/ } - -div.admonition p.admonition-title, div.hint p.admonition-title, -div.important p.admonition-title, div.note p.admonition-title, -div.tip p.admonition-title { - font-weight: bold; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } - -div.attention p.admonition-title, div.caution p.admonition-title, -div.danger p.admonition-title, div.error p.admonition-title, -div.warning p.admonition-title, .code .error { - color: #b30000; - font-weight: bold; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } - -/* Uncomment (and remove this text!) to get reduced vertical space in - compound paragraphs. -div.compound .compound-first, div.compound .compound-middle { - margin-bottom: 0.5em } - -div.compound .compound-last, div.compound .compound-middle { - margin-top: 0.5em } -*/ -div.dedication { - margin: 2em 5em; - text-align: center; - font-style: italic; } - -div.dedication p.topic-title { - font-weight: bold; - font-style: normal; } div.figure { margin-left: 2em; @@ -821,8 +515,14 @@ div.figure { div.footer, div.header { clear: both; + text-align: center; + color: #666; font-size: smaller; } +div.footer { + padding-top: 5em; +} + div.line-block { display: block; margin-top: 1em; @@ -833,45 +533,24 @@ div.line-block div.line-block { margin-bottom: 0; margin-left: 1.5em; } -div.sidebar { - margin: 0 0 0.5em 1em; - border: medium outset; - padding: 1em; - background-color: rgba(252, 248, 244, 0.75); - width: 40%; - float: right; - clear: right; } - -div.sidebar p.rubric { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-size: medium; } - -div.system-messages { - margin: 5em; } - -div.system-messages h1 { - color: #b30000; } - -div.system-message { - border: medium outset; - padding: 1em; } - -div.system-message p.system-message-title { - color: #b30000; - font-weight: bold; } - div.topic { margin: 2em; } -h1.section-subtitle, h2.section-subtitle, h3.section-subtitle, -h4.section-subtitle, h5.section-subtitle, h6.section-subtitle { - margin-top: 0.4em; } +div.search_results { + background-color: antiquewhite; + margin: 3em; + padding: 1em; + border: 1px solid #4d4d4d; +} -h1.title { - text-align: center; } +div#global-links ul { + margin-left: 0; + list-style-type: none; +} -h2.subtitle { - text-align: center; } +div#global-links > simple-boot { + margin-left: 3em; +} hr.docutils { width: 75%; } @@ -905,30 +584,6 @@ img.align-center, .figure.align-center, object.align-center { div.align-right { text-align: inherit; } -/* div.align-center * { */ -/* text-align: left } */ - -ul.simple > li { - margin-bottom: 0.5em } - -ol.simple, ul.simple { - margin-bottom: 1em; } - -ol.arabic { - list-style: decimal; } - -ol.loweralpha { - list-style: lower-alpha; } - -ol.upperalpha { - list-style: upper-alpha; } - -ol.lowerroman { - list-style: lower-roman; } - -ol.upperroman { - list-style: upper-roman; } - p.attribution { text-align: right; margin-left: 50%; } @@ -949,15 +604,6 @@ p.rubric { color: maroon; text-align: center; } -p.sidebar-title { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-weight: bold; - font-size: larger; } - -p.sidebar-subtitle { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-weight: bold; } - p.topic-title { font-weight: bold; } @@ -997,22 +643,14 @@ pre.code .inserted, code .inserted { background-color: #A3D289; } span.classifier { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-style: oblique; } span.classifier-delimiter { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: bold; } -span.interpreted { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } - span.option { white-space: nowrap; } -span.pre { - white-space: pre; } - span.problematic { color: #b30000; } @@ -1020,44 +658,6 @@ span.section-subtitle { /* font-size relative to parent (h1..h6 element) */ font-size: 80%; } -table.citation { - border-left: solid 1px #666666; - margin-left: 1px; } - -table.docinfo { - margin: 0em; - margin-top: 2em; - margin-bottom: 2em; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; - color: #444444; } - -table.docutils { - margin-top: 0.5em; - margin-bottom: 0.5em; } - -table.footnote { - border-left: solid 1px #2d2d2d; - margin-left: 1px; } - -table.docutils td, table.docutils th, -table.docinfo td, table.docinfo th { - padding-left: 0.5em; - padding-right: 0.5em; - vertical-align: top; } - -table.docutils th.field-name, table.docinfo th.docinfo-name { - font-weight: 700; - text-align: left; - white-space: nowrap; - padding-left: 0; } - -h1 tt.docutils, h2 tt.docutils, h3 tt.docutils, -h4 tt.docutils, h5 tt.docutils, h6 tt.docutils { - font-size: 100%; } - -ul.auto-toc { - list-style-type: none; } - span.DecNumber { color: #252dbe; } @@ -1074,7 +674,7 @@ span.FloatNumber { color: #252dbe; } span.Identifier { - color: #3b3b3b; } + color: #222; } span.Keyword { font-weight: 600; @@ -1139,38 +739,23 @@ dt pre > span.Identifier, dt pre > span.Operator { color: #155da4; font-weight: 700; } -dt pre > span.Identifier ~ span.Identifier, dt pre > span.Operator ~ span.Identifier { - color: inherit; - font-weight: inherit; } - -dt pre > span.Operator ~ span.Identifier { +dt pre > span.Keyword ~ span.Identifier, dt pre > span.Identifier ~ span.Identifier, +dt pre > span.Operator ~ span.Identifier, dt pre > span.Other ~ span.Identifier { color: inherit; font-weight: inherit; } /* Nim sprite for the footer (taken from main page favicon) */ .nim-sprite { display: inline-block; - height: 12px; - width: 12px; + height: 16px; + width: 16px; background-position: 0 0; - background-size: 12px 12px; + background-size: 16px 16px; -webkit-filter: opacity(50%); background-repeat: no-repeat; background-image: url("data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="); margin-bottom: -5px; } -div.search_results { - background-color: antiquewhite; - margin: 3em; - padding: 1em; - border: 1px solid #4d4d4d; -} - -div#global-links ul { - margin-left: 0; - list-style-type: none; -} - span.pragmadots { /* Position: relative frees us up to make the dots look really nice without fucking up the layout and @@ -1178,18 +763,14 @@ span.pragmadots { position: relative; /* 1px down looks slightly nicer */ top: 1px; - padding: 2px; - background-color: #D3D3D3; + background-color: #e8e8e8; border-radius: 4px; margin: 0 2px; cursor: pointer; - - /* For some reason on Chrome, making the font size - smaller than 1em is causing the parent container to - bulge slightly. So, we're stuck with inheriting 1em, - which is sad, because 0.8em looks better... */ + font-size: 0.8em; } + span.pragmadots:hover { background-color: #DBDBDB; } @@ -1197,6 +778,10 @@ span.pragmawrap { display: none; } +span.attachedType { + display: none; + visibility: hidden; +} @@ -1221,7 +806,13 @@ function main() {

Index

Modules: cimport, compat, git, paths, plugin, types.

API symbols

-
cAddSearchDir:
cDebug:
  • cimport: cDebug()
  • + data-doc-search-tag="cimport: cDebug()" href="cimport.html#cDebug">cimport: cDebug()
cDefine:
cDisableCaching:
  • cimport: cDisableCaching()
  • + data-doc-search-tag="cimport: cDisableCaching()" href="cimport.html#cDisableCaching">cimport: cDisableCaching()
cImport:
cIncludeDir:
+
cmake:
configure:
  • git: configure(path, check: string)
  • + data-doc-search-tag="git: configure(path, check: string; flags = "")" href="git.html#configure%2Cstring%2Cstring%2Cstring">git: configure(path, check: string; flags = "")
cOverride:
cpFile:
cPlugin:
cSearchPath:
cSkipSymbol:
  • cimport: cSkipSymbol(skips: seq[string])
  • + data-doc-search-tag="cimport: cSkipSymbol(skips: seq[string])" href="cimport.html#cSkipSymbol%2Cseq%5BT%5D%5Bstring%5D">cimport: cSkipSymbol(skips: seq[string])
defineEnum:
  • types: defineEnum(typ)
  • + data-doc-search-tag="types: defineEnum(typ)" href="types.html#defineEnum.t">types: defineEnum(typ)
downloadUrl:
incDir:
  • paths: incDir(): string
  • + data-doc-search-tag="paths: incDir(): string" href="paths.html#incDir">paths: incDir(): string +
+
make:
mkDir:
nimteropBuildDir:
nimteropRoot:
  • paths: nimteropRoot(): string
  • + data-doc-search-tag="paths: nimteropRoot(): string" href="paths.html#nimteropRoot">paths: nimteropRoot(): string
nimteropSrcDir:
OnSymbol:
testsIncludeDir:
time_t:
toastExePath:
  • paths: toastExePath(): string
  • + data-doc-search-tag="paths: toastExePath(): string" href="paths.html#toastExePath">paths: toastExePath(): string
va_list:
diff --git a/types.html b/types.html old mode 100755 new mode 100644 index 3a49234..7c5fff9 --- a/types.html +++ b/types.html @@ -27,232 +27,130 @@ customize this style sheet. Modified from Chad Skeeters' rst2html-style https://bitbucket.org/cskeeters/rst2html-style/ -Modified by Boyd Greenfield +Modified by Boyd Greenfield and narimiran */ -/* SCSS variables */ -/* Text weights */ -/* Body colors */ -/* Text colors */ -/* Link colors */ -/* Syntax highlighting colors */ -/* Pct changes */ -/* Mixins */ -/* Body/layout */ + html { font-size: 100%; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; } -/* Where we want fancier font if available */ -h1, h2, h3, h4, h5, h6, p.module-desc, table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; } - -h1.title { - font-weight: 900; } - body { font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: 400; - font-size: 16px; - line-height: 20px; - color: #444; - letter-spacing: 0.15px; - background-color: #FDFBFA; } + font-size: 1.125em; + line-height: 1.5; + color: #222; + background-color: #FCFCFC; } /* Skeleton grid */ .container { position: relative; width: 100%; - max-width: 960px; + max-width: 1050px; margin: 0 auto; - padding: 0 20px; + padding: 0; box-sizing: border-box; } .column, .columns { width: 100%; float: left; - box-sizing: border-box; } + box-sizing: border-box; + margin-left: 1%; +} -/* For devices larger than 400px */ -@media (min-width: 400px) { - .container { - width: 100%; - padding: 0; } } -/* For devices larger than 650px */ -@media (min-width: 650px) { - .container { - width: 100%; } +.column:first-child, +.columns:first-child { + margin-left: 0; } - .column, - .columns { - margin-left: 4%; } +.three.columns { + width: 19%; } - .column:first-child, - .columns:first-child { - margin-left: 0; } +.nine.columns { + width: 80.0%; } - .one.column, - .one.columns { - width: 4.66666666667%; } - - .two.columns { - width: 13.3333333333%; } +.twelve.columns { + width: 100%; + margin-left: 0; } +@media screen and (max-width: 860px) { .three.columns { - width: 22%; } - - .four.columns { - width: 30.6666666667%; } - - .five.columns { - width: 39.3333333333%; } - - .six.columns { - width: 48%; } - - .seven.columns { - width: 56.6666666667%; } - - .eight.columns { - width: 65.3333333333%; } - + display: none; + } .nine.columns { - width: 74.0%; } - - .ten.columns { - width: 82.6666666667%; } - - .eleven.columns { - width: 91.3333333333%; } - - .twelve.columns { - width: 100%; - margin-left: 0; } - - .one-third.column { - width: 30.6666666667%; } - - .two-thirds.column { - width: 65.3333333333%; } } -/* Customer Overrides */ -.footer { - text-align: center; - color: #969696; - padding-top: 10%; } - -p.module-desc { - font-size: 1.1em; - color: #666666; } - -a.link-seesrc { - color: #aec7d2; - font-style: italic; } - -a.link-seesrc:hover { - color: #6c9aae; } - -#toc-list { - word-wrap: break-word; } - -ul.simple-toc { - list-style: none; } - -ul.simple-toc a.reference-toplevel { - font-weight: bold; - color: #0077b3; } - -ul.simple-toc-section { - list-style-type: circle; - color: #6c9aae; } - -ul.simple-toc-section a.reference { - color: #0077b3; } + width: 98.0%; + } + body { + font-size: 1em; + line-height: 1.35; + } +} cite { font-style: italic !important; } -dt > pre { - border-color: rgba(0, 0, 0, 0.1); - background-color: rgba(255, 255, 255, 0.3); - margin: 15px 0px 5px; } - -dd > pre { - border-color: rgba(0, 0, 0, 0.1); - background-color: whitesmoke; - margin-top: 8px; } - -.item > dd { - margin-left: 10px; - margin-bottom: 30px; } - -/* Nim line-numbered tables */ -.line-nums-table { - width: 100%; - table-layout: fixed; } /* Nim search input */ div#searchInputDiv { - margin-bottom: 8px; + margin-bottom: 1em; } -div#searchInputDiv input#searchInput { - width: 10em; -} -div.search-groupby { - margin-bottom: 8px; +input#searchInput { + width: 80%; } -table.line-nums-table { - border-radius: 4px; - border: 1px solid #cccccc; - background-color: whitesmoke; - border-collapse: separate; - margin-top: 15px; - margin-bottom: 25px; } - -.line-nums-table tbody { - border: none; } - -.line-nums-table td pre { - border: none; - background-color: transparent; } - -.line-nums-table td.blob-line-nums { - width: 28px; } - -.line-nums-table td.blob-line-nums pre { - color: #b0b0b0; - -webkit-filter: opacity(75%); - text-align: right; - border-color: transparent; - background-color: transparent; - padding-left: 0px; - margin-left: 0px; - padding-right: 0px; - margin-right: 0px; } +/* + * Some custom formatting for input forms. + * This also fixes input form colors on Firefox with a dark system theme on Linux. + */ +input { + -moz-appearance: none; + color: #333; + background-color: #f8f8f8; + border: 1px solid #aaa; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-size: 0.9em; + padding: 6px; +} +input:focus { + border: 1px solid #1fa0eb; + box-shadow: 0 0 2px #1fa0eb; +} /* Docgen styles */ /* Links */ a { - color: #0077b3; - text-decoration: none; } + color: #07b; + text-decoration: none; +} + +a span.Identifier { + text-decoration: underline; + text-decoration-color: #aab; +} + +a.reference-toplevel { + font-weight: bold; +} + +a.toc-backref { + text-decoration: none; + color: #222; } + +a.link-seesrc { + color: #607c9f; + font-size: 0.9em; + font-style: italic; } a:hover, a:focus { - color: #00334d; + color: #607c9f; text-decoration: underline; } -a:visited { - color: #00334d; } +a:hover span.Identifier { + color: #607c9f; +} -a:focus { - outline: thin dotted #2d2d2d; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; } - -a:hover, -a:active { - outline: 0; } sub, sup { @@ -329,379 +227,258 @@ img { h2, h3 { - page-break-after: avoid; } } -.img-rounded { - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; } + page-break-after: avoid; } +} -.img-polaroid { - padding: 4px; - background-color: rgba(252, 248, 244, 0.75); - border: 1px solid #ccc; - border: 1px solid rgba(0, 0, 0, 0.2); - -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); - -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); } p { - margin: 0 0 8px; } + margin-top: 0.5em; + margin-bottom: 0.5em; +} small { font-size: 85%; } strong { - font-weight: 600; } + font-weight: 600; + font-size: 0.95em; + color: #3c3c3c; +} em { font-style: italic; } -cite { - font-style: normal; } - -h1, -h2, -h3, -h4, -h5, -h6 { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-weight: 600; - line-height: 20px; - color: inherit; - text-rendering: optimizelegibility; } - h1 { - font-size: 2em; + font-size: 1.8em; font-weight: 400; - padding-bottom: .15em; - border-bottom: 1px solid #aaaaaa; - margin-top: 1.0em; + padding-bottom: .25em; + border-bottom: 1px solid #aaa; + margin-top: 2.5em; + margin-bottom: 1em; line-height: 1.2em; } h1.title { padding-bottom: 1em; border-bottom: 0px; - font-size: 2.75em; } + font-size: 2.5em; + text-align: center; + font-weight: 900; + margin-top: 0.75em; + margin-bottom: 0em; +} h2 { - font-size: 1.5em; - margin-top: 1.5em; } + font-size: 1.3em; + margin-top: 2em; } + +h2.subtitle { + text-align: center; } h3 { - font-size: 1.3em; + font-size: 1.125em; font-style: italic; - margin-top: 0.75em; } + margin-top: 1.5em; } h4 { - font-size: 1.3em; - margin-top: 0.5em; } + font-size: 1.125em; + margin-top: 1em; } h5 { - font-size: 1.2em; - margin-top: 0.25em; } + font-size: 1.125em; + margin-top: 0.75em; } h6 { font-size: 1.1em; } + ul, ol { padding: 0; - margin: 0 0 0px 15px; } + margin-top: 0.5em; + margin-left: 0.75em; } ul ul, ul ol, ol ol, ol ul { - margin-bottom: 0; } + margin-bottom: 0; + margin-left: 1.25em; } li { - line-height: 20px; } - -dl { - margin-bottom: 20px; } - -dt, -dd { - line-height: 20px; } - -dt { - font-weight: bold; } - -dd { - margin-left: 10px; - margin-bottom: 26px; } - -hr { - margin: 20px 0; - border: 0; - border-top: 1px solid #eeeeee; - border-bottom: 1px solid #ffffff; } - -abbr[title], -abbr[data-original-title] { - cursor: help; - border-bottom: 1px dotted #999999; } - -abbr.initialism { - font-size: 90%; - text-transform: uppercase; } - -blockquote { - padding: 0 0 0 15px; - margin: 0 0 20px; - border-left: 5px solid #EFEBE0; } - -table.docinfo + blockquote, table.docinfo blockquote, h1 + blockquote { - border-left: 5px solid #c9c9c9; + list-style-type: circle; } -table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { - margin-bottom: 0; - font-size: 15px; - font-weight: 200; - line-height: 1.5; - font-style: italic; } +ul.simple-boot li { + list-style-type: none; + margin-left: 0em; + margin-bottom: 0.5em; +} -q:before, -q:after, -blockquote:before, -blockquote:after { - content: ""; } +ol.simple > li, ul.simple > li { + margin-bottom: 0.25em; + margin-left: 0.4em } -address { - display: block; - margin-bottom: 20px; - font-style: normal; - line-height: 20px; } +ul.simple.simple-toc > li { + margin-top: 1em; +} -code, -pre { - font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - padding: 0 3px 2px; - font-weight: 500; - font-size: 12px; - color: #444444; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; } +ul.simple-toc { + list-style: none; + font-size: 0.9em; + margin-left: -0.3em; + margin-top: 1em; } + +ul.simple-toc > li { + list-style-type: none; +} + +ul.simple-toc-section { + list-style-type: circle; + margin-left: 1em; + color: #6c9aae; } + + +ol.arabic { + list-style: decimal; } + +ol.loweralpha { + list-style: lower-alpha; } + +ol.upperalpha { + list-style: upper-alpha; } + +ol.lowerroman { + list-style: lower-roman; } + +ol.upperroman { + list-style: upper-roman; } + +ul.auto-toc { + list-style-type: none; } + + +dl { + margin-bottom: 1.5em; } + +dt { + margin-bottom: -0.5em; + margin-left: 0.0em; } + +dd { + margin-left: 2.0em; + margin-bottom: 3.0em; + margin-top: 0.5em; } + + +hr { + margin: 2em 0; + border: 0; + border-top: 1px solid #aaa; } + +blockquote { + font-size: 0.9em; + font-style: italic; + padding-left: 0.5em; + margin-left: 0; + border-left: 5px solid #bbc; +} .pre { font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - font-weight: 600; - /*color: #504da6;*/ + font-weight: 500; + font-size: 0.85em; + background-color: #f0f3ff; + padding-left: 3px; + padding-right: 3px; + border-radius: 4px; } -code { - padding: 2px 4px; - color: #444444; - white-space: nowrap; - background-color: white; - border: 1px solid #777777; } - pre { + font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; + color: #222; + font-weight: 500; display: inline-block; box-sizing: border-box; - min-width: calc(100% - 19.5px); - padding: 9.5px; - margin: 0.25em 10px 10px 10px; - font-size: 15px; - line-height: 20px; + min-width: 100%; + padding: 0.5em; + margin-top: 0.5em; + margin-bottom: 0.5em; + font-size: 0.85em; white-space: pre !important; overflow-y: hidden; overflow-x: visible; - background-color: rgba(0, 0, 0, 0.01); - border: 1px solid #cccccc; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; } - -pre.prettyprint { - margin-bottom: 20px; } - -pre code { - padding: 0; - color: inherit; - white-space: pre; - overflow-x: visible; - background-color: transparent; - border: 0; } + background-color: ghostwhite; + border: 1px solid #dde; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; } .pre-scrollable { max-height: 340px; overflow-y: scroll; } + +/* Nim line-numbered tables */ +.line-nums-table { + width: 100%; + table-layout: fixed; } + +table.line-nums-table { + border-radius: 4px; + border: 1px solid #cccccc; + background-color: ghostwhite; + border-collapse: separate; + margin-top: 15px; + margin-bottom: 25px; } + +.line-nums-table tbody { + border: none; } + +.line-nums-table td pre { + border: none; + background-color: transparent; } + +.line-nums-table td.blob-line-nums { + width: 28px; } + +.line-nums-table td.blob-line-nums pre { + color: #b0b0b0; + -webkit-filter: opacity(75%); + text-align: right; + border-color: transparent; + background-color: transparent; + padding-left: 0px; + margin-left: 0px; + padding-right: 0px; + margin-right: 0px; } + + table { max-width: 100%; background-color: transparent; + margin-top: 0.5em; + margin-bottom: 1.5em; border-collapse: collapse; - border-spacing: 0; } - -table th, table td { - padding: 0px 8px 0px; + border-color: #ccc; + border-spacing: 0; + font-size: 0.9em; } -.table { - width: 100%; - margin-bottom: 20px; } +table th, table td { + padding: 0px 0.5em 0px; +} -.table th, -.table td { - padding: 8px; - line-height: 20px; - text-align: left; - vertical-align: top; - border-top: 1px solid #444444; } - -.table th { +table th { + background-color: #e8e8e8; font-weight: bold; } -.table thead th { - vertical-align: bottom; } +table th.docinfo-name { + background-color: transparent; +} -.table caption + thead tr:first-child th, -.table caption + thead tr:first-child td, -.table colgroup + thead tr:first-child th, -.table colgroup + thead tr:first-child td, -.table thead:first-child tr:first-child th, -.table thead:first-child tr:first-child td { - border-top: 0; } +table tr:hover { + background-color: ghostwhite; } -.table tbody + tbody { - border-top: 2px solid #444444; } - -.table .table { - background-color: rgba(252, 248, 244, 0.75); } - -.table-condensed th, -.table-condensed td { - padding: 4px 5px; } - -.table-bordered { - border: 1px solid #444444; - border-collapse: separate; - *border-collapse: collapse; - border-left: 0; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; } - -.table-bordered th, -.table-bordered td { - border-left: 1px solid #444444; } - -.table-bordered caption + thead tr:first-child th, -.table-bordered caption + tbody tr:first-child th, -.table-bordered caption + tbody tr:first-child td, -.table-bordered colgroup + thead tr:first-child th, -.table-bordered colgroup + tbody tr:first-child th, -.table-bordered colgroup + tbody tr:first-child td, -.table-bordered thead:first-child tr:first-child th, -.table-bordered tbody:first-child tr:first-child th, -.table-bordered tbody:first-child tr:first-child td { - border-top: 0; } - -.table-bordered thead:first-child tr:first-child > th:first-child, -.table-bordered tbody:first-child tr:first-child > td:first-child, -.table-bordered tbody:first-child tr:first-child > th:first-child { - -webkit-border-top-left-radius: 4px; - border-top-left-radius: 4px; - -moz-border-radius-topleft: 4px; } - -.table-bordered thead:first-child tr:first-child > th:last-child, -.table-bordered tbody:first-child tr:first-child > td:last-child, -.table-bordered tbody:first-child tr:first-child > th:last-child { - -webkit-border-top-right-radius: 4px; - border-top-right-radius: 4px; - -moz-border-radius-topright: 4px; } - -.table-bordered thead:last-child tr:last-child > th:first-child, -.table-bordered tbody:last-child tr:last-child > td:first-child, -.table-bordered tbody:last-child tr:last-child > th:first-child, -.table-bordered tfoot:last-child tr:last-child > td:first-child, -.table-bordered tfoot:last-child tr:last-child > th:first-child { - -webkit-border-bottom-left-radius: 4px; - border-bottom-left-radius: 4px; - -moz-border-radius-bottomleft: 4px; } - -.table-bordered thead:last-child tr:last-child > th:last-child, -.table-bordered tbody:last-child tr:last-child > td:last-child, -.table-bordered tbody:last-child tr:last-child > th:last-child, -.table-bordered tfoot:last-child tr:last-child > td:last-child, -.table-bordered tfoot:last-child tr:last-child > th:last-child { - -webkit-border-bottom-right-radius: 4px; - border-bottom-right-radius: 4px; - -moz-border-radius-bottomright: 4px; } - -.table-bordered tfoot + tbody:last-child tr:last-child td:first-child { - -webkit-border-bottom-left-radius: 0; - border-bottom-left-radius: 0; - -moz-border-radius-bottomleft: 0; } - -.table-bordered tfoot + tbody:last-child tr:last-child td:last-child { - -webkit-border-bottom-right-radius: 0; - border-bottom-right-radius: 0; - -moz-border-radius-bottomright: 0; } - -.table-bordered caption + thead tr:first-child th:first-child, -.table-bordered caption + tbody tr:first-child td:first-child, -.table-bordered colgroup + thead tr:first-child th:first-child, -.table-bordered colgroup + tbody tr:first-child td:first-child { - -webkit-border-top-left-radius: 4px; - border-top-left-radius: 4px; - -moz-border-radius-topleft: 4px; } - -.table-bordered caption + thead tr:first-child th:last-child, -.table-bordered caption + tbody tr:first-child td:last-child, -.table-bordered colgroup + thead tr:first-child th:last-child, -.table-bordered colgroup + tbody tr:first-child td:last-child { - -webkit-border-top-right-radius: 4px; - border-top-right-radius: 4px; - -moz-border-radius-topright: 4px; } - -table.docutils th { - background-color: #e8e8e8; } - -table.docutils tr:hover { - background-color: whitesmoke; } - -.table-striped tbody > tr:nth-child(odd) > td, -.table-striped tbody > tr:nth-child(odd) > th { - background-color: rgba(252, 248, 244, 0.75); } - -.table-hover tbody tr:hover > td, -.table-hover tbody tr:hover > th { - background-color: rgba(241, 222, 204, 0.75); } - -table td[class*="span"], -table th[class*="span"], -.row-fluid table td[class*="span"], -.row-fluid table th[class*="span"] { - display: table-cell; - float: none; - margin-left: 0; } - -.hero-unit { - padding: 60px; - margin-bottom: 30px; - font-size: 18px; - font-weight: 200; - line-height: 30px; - color: inherit; - background-color: rgba(230, 197, 164, 0.75); - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; } - -.hero-unit h1 { - margin-bottom: 0; - font-size: 60px; - line-height: 1; - letter-spacing: -1px; - color: inherit; } - -.hero-unit li { - line-height: 30px; } /* rst2html default used to remove borders from tables and images */ .borderless, table.borderless td, table.borderless th { @@ -722,10 +499,6 @@ table.borderless td, table.borderless th { .hidden { display: none; } -a.toc-backref { - text-decoration: none; - color: #444444; } - blockquote.epigraph { margin: 2em 5em; } @@ -735,85 +508,6 @@ dl.docutils dd { object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] { overflow: hidden; } -/* Uncomment (and remove this text!) to get bold-faced definition list terms -dl.docutils dt { - font-weight: bold } -*/ -div.abstract { - margin: 2em 5em; } - -div.abstract p.topic-title { - font-weight: bold; - text-align: center; } - -div.admonition, div.attention, div.caution, div.danger, div.error, -div.hint, div.important, div.note, div.tip, div.warning { - margin: 2em; - border: medium outset; - padding: 1em; } - -div.note, div.warning { - margin: 1.5em 0px; - border: none; } - -div.note p.admonition-title, -div.warning p.admonition-title { - display: none; } - -/* Clearfix - * http://css-tricks.com/snippets/css/clear-fix/ - */ -div.note:after, -div.warning:after { - content: ""; - display: table; - clear: both; } - -div.note p:before, -div.warning p:before { - display: block; - float: left; - font-size: 4em; - line-height: 1em; - margin-right: 20px; - margin-left: 0em; - margin-top: -10px; - content: '\0270D'; - /*handwriting*/ } - -div.warning p:before { - content: '\026A0'; - /*warning*/ } - -div.admonition p.admonition-title, div.hint p.admonition-title, -div.important p.admonition-title, div.note p.admonition-title, -div.tip p.admonition-title { - font-weight: bold; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } - -div.attention p.admonition-title, div.caution p.admonition-title, -div.danger p.admonition-title, div.error p.admonition-title, -div.warning p.admonition-title, .code .error { - color: #b30000; - font-weight: bold; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } - -/* Uncomment (and remove this text!) to get reduced vertical space in - compound paragraphs. -div.compound .compound-first, div.compound .compound-middle { - margin-bottom: 0.5em } - -div.compound .compound-last, div.compound .compound-middle { - margin-top: 0.5em } -*/ -div.dedication { - margin: 2em 5em; - text-align: center; - font-style: italic; } - -div.dedication p.topic-title { - font-weight: bold; - font-style: normal; } div.figure { margin-left: 2em; @@ -821,8 +515,14 @@ div.figure { div.footer, div.header { clear: both; + text-align: center; + color: #666; font-size: smaller; } +div.footer { + padding-top: 5em; +} + div.line-block { display: block; margin-top: 1em; @@ -833,45 +533,24 @@ div.line-block div.line-block { margin-bottom: 0; margin-left: 1.5em; } -div.sidebar { - margin: 0 0 0.5em 1em; - border: medium outset; - padding: 1em; - background-color: rgba(252, 248, 244, 0.75); - width: 40%; - float: right; - clear: right; } - -div.sidebar p.rubric { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-size: medium; } - -div.system-messages { - margin: 5em; } - -div.system-messages h1 { - color: #b30000; } - -div.system-message { - border: medium outset; - padding: 1em; } - -div.system-message p.system-message-title { - color: #b30000; - font-weight: bold; } - div.topic { margin: 2em; } -h1.section-subtitle, h2.section-subtitle, h3.section-subtitle, -h4.section-subtitle, h5.section-subtitle, h6.section-subtitle { - margin-top: 0.4em; } +div.search_results { + background-color: antiquewhite; + margin: 3em; + padding: 1em; + border: 1px solid #4d4d4d; +} -h1.title { - text-align: center; } +div#global-links ul { + margin-left: 0; + list-style-type: none; +} -h2.subtitle { - text-align: center; } +div#global-links > simple-boot { + margin-left: 3em; +} hr.docutils { width: 75%; } @@ -905,30 +584,6 @@ img.align-center, .figure.align-center, object.align-center { div.align-right { text-align: inherit; } -/* div.align-center * { */ -/* text-align: left } */ - -ul.simple > li { - margin-bottom: 0.5em } - -ol.simple, ul.simple { - margin-bottom: 1em; } - -ol.arabic { - list-style: decimal; } - -ol.loweralpha { - list-style: lower-alpha; } - -ol.upperalpha { - list-style: upper-alpha; } - -ol.lowerroman { - list-style: lower-roman; } - -ol.upperroman { - list-style: upper-roman; } - p.attribution { text-align: right; margin-left: 50%; } @@ -949,15 +604,6 @@ p.rubric { color: maroon; text-align: center; } -p.sidebar-title { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-weight: bold; - font-size: larger; } - -p.sidebar-subtitle { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-weight: bold; } - p.topic-title { font-weight: bold; } @@ -997,22 +643,14 @@ pre.code .inserted, code .inserted { background-color: #A3D289; } span.classifier { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-style: oblique; } span.classifier-delimiter { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: bold; } -span.interpreted { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } - span.option { white-space: nowrap; } -span.pre { - white-space: pre; } - span.problematic { color: #b30000; } @@ -1020,44 +658,6 @@ span.section-subtitle { /* font-size relative to parent (h1..h6 element) */ font-size: 80%; } -table.citation { - border-left: solid 1px #666666; - margin-left: 1px; } - -table.docinfo { - margin: 0em; - margin-top: 2em; - margin-bottom: 2em; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; - color: #444444; } - -table.docutils { - margin-top: 0.5em; - margin-bottom: 0.5em; } - -table.footnote { - border-left: solid 1px #2d2d2d; - margin-left: 1px; } - -table.docutils td, table.docutils th, -table.docinfo td, table.docinfo th { - padding-left: 0.5em; - padding-right: 0.5em; - vertical-align: top; } - -table.docutils th.field-name, table.docinfo th.docinfo-name { - font-weight: 700; - text-align: left; - white-space: nowrap; - padding-left: 0; } - -h1 tt.docutils, h2 tt.docutils, h3 tt.docutils, -h4 tt.docutils, h5 tt.docutils, h6 tt.docutils { - font-size: 100%; } - -ul.auto-toc { - list-style-type: none; } - span.DecNumber { color: #252dbe; } @@ -1074,7 +674,7 @@ span.FloatNumber { color: #252dbe; } span.Identifier { - color: #3b3b3b; } + color: #222; } span.Keyword { font-weight: 600; @@ -1139,38 +739,23 @@ dt pre > span.Identifier, dt pre > span.Operator { color: #155da4; font-weight: 700; } -dt pre > span.Identifier ~ span.Identifier, dt pre > span.Operator ~ span.Identifier { - color: inherit; - font-weight: inherit; } - -dt pre > span.Operator ~ span.Identifier { +dt pre > span.Keyword ~ span.Identifier, dt pre > span.Identifier ~ span.Identifier, +dt pre > span.Operator ~ span.Identifier, dt pre > span.Other ~ span.Identifier { color: inherit; font-weight: inherit; } /* Nim sprite for the footer (taken from main page favicon) */ .nim-sprite { display: inline-block; - height: 12px; - width: 12px; + height: 16px; + width: 16px; background-position: 0 0; - background-size: 12px 12px; + background-size: 16px 16px; -webkit-filter: opacity(50%); background-repeat: no-repeat; background-image: url("data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="); margin-bottom: -5px; } -div.search_results { - background-color: antiquewhite; - margin: 3em; - padding: 1em; - border: 1px solid #4d4d4d; -} - -div#global-links ul { - margin-left: 0; - list-style-type: none; -} - span.pragmadots { /* Position: relative frees us up to make the dots look really nice without fucking up the layout and @@ -1178,18 +763,14 @@ span.pragmadots { position: relative; /* 1px down looks slightly nicer */ top: 1px; - padding: 2px; - background-color: #D3D3D3; + background-color: #e8e8e8; border-radius: 4px; margin: 0 2px; cursor: pointer; - - /* For some reason on Chrome, making the font size - smaller than 1em is causing the parent container to - bulge slightly. So, we're stuck with inheriting 1em, - which is sad, because 0.8em looks better... */ + font-size: 0.8em; } + span.pragmadots:hover { background-color: #DBDBDB; } @@ -1197,6 +778,10 @@ span.pragmawrap { display: none; } +span.attachedType { + display: none; + visibility: hidden; +} @@ -1242,11 +827,11 @@ function main() { Types
  • time_t
  • + title="time_t = time_t_temp.Time">time_t
  • ptrdiff_t
  • + title="ptrdiff_t = ByteAddress">ptrdiff_t
  • va_list
  • + title="va_list {.importc, header: "<stdarg.h>".} = object">va_list
@@ -1254,9 +839,9 @@ function main() { Templates @@ -1266,27 +851,31 @@ function main() {
+

Types

-
time_t = Time
+
time_t = time_t_temp.Time
+
ptrdiff_t = ByteAddress
+
va_list {...}{.importc, header: "<stdarg.h>".} = object
+
@@ -1294,16 +883,18 @@ function main() {

Templates

-
template enumOp(op, typ, typout)
+
template enumOp(op, typ, typout)
+
- -
template defineEnum(typ)
+ +
template defineEnum(typ)
+
@@ -1315,7 +906,7 @@ function main() { diff --git a/types.idx b/types.idx old mode 100755 new mode 100644 index d4ab217..5bc0938 --- a/types.idx +++ b/types.idx @@ -2,4 +2,4 @@ time_t types.html#time_t types: time_t ptrdiff_t types.html#ptrdiff_t types: ptrdiff_t va_list types.html#va_list types: va_list enumOp types.html#enumOp.t,,, types: enumOp(op, typ, typout) -defineEnum types.html#defineEnum.t, types: defineEnum(typ) +defineEnum types.html#defineEnum.t types: defineEnum(typ) From 547ee5801ec01ba9363b8de2a0f173bd824e4a24 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Fri, 19 Jul 2019 19:38:41 -0500 Subject: [PATCH 228/593] Minor c2nim fixes --- nimterop/cimport.nim | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index a4e1761..1249ee9 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -586,7 +586,8 @@ macro c2nImport*(filename: static string, recurse: static bool = false, dynlib: doAssert fileExists(hpath), "Unable to write temporary header file: " & hpath var - cmd = &"c2nim {hpath} --header:{header}" + cmd = when defined(Windows): "cmd /c " else: "" + cmd &= &"c2nim {hpath} --header:{header}" if dynlib.len != 0: cmd.add &" --dynlib:{dynlib}" @@ -600,7 +601,7 @@ macro c2nImport*(filename: static string, recurse: static bool = false, dynlib: let (c2nimout, ret) = gorgeEx(cmd, cache=getCacheValue(hpath)) - doAssert ret == 0, c2nimout + doAssert ret == 0, "Command failed:\n " & cmd var nimout = &"const {header} = \"{fullpath}\"\n\n" & readFile(npath) From 11cfed08cee3efe946428a12c8d35e050ae386b2 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 25 Jul 2019 22:52:40 -0500 Subject: [PATCH 229/593] Add link to wrappers --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 9977e29..6dfcb04 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,8 @@ This will download and install nimterop in the standard Nimble package location, __Usage__ +Check out the [wiki](https://github.com/nimterop/nimterop/wiki/Wrappers) for a list of all known wrappers that have been created using nimterop. Please do add your project once you are done so that others can benefit from your work. + ```nim import nimterop/cimport From 90a5d0ebc816f5ff8bdf254a3fde8e37b78c0386 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 29 Jul 2019 09:17:11 -0500 Subject: [PATCH 230/593] Update documentation --- all.html | 980 +++++++++++++++++------- cimport.html | 1107 ++++++++++++++++++--------- cimport.idx | 12 +- compat.html | 1013 ++++++++++++++++++------- dochack.js | 1983 ------------------------------------------------- git.html | 1089 ++++++++++++++++++--------- paths.html | 1032 +++++++++++++++++-------- paths.idx | 12 +- plugin.html | 984 +++++++++++++++++------- theindex.html | 1003 +++++++++++++++++-------- types.html | 1003 +++++++++++++++++-------- types.idx | 2 +- 12 files changed, 5770 insertions(+), 4450 deletions(-) delete mode 100644 dochack.js diff --git a/all.html b/all.html index 5d58312..f9e6987 100644 --- a/all.html +++ b/all.html @@ -27,130 +27,232 @@ customize this style sheet. Modified from Chad Skeeters' rst2html-style https://bitbucket.org/cskeeters/rst2html-style/ -Modified by Boyd Greenfield and narimiran +Modified by Boyd Greenfield */ - +/* SCSS variables */ +/* Text weights */ +/* Body colors */ +/* Text colors */ +/* Link colors */ +/* Syntax highlighting colors */ +/* Pct changes */ +/* Mixins */ +/* Body/layout */ html { font-size: 100%; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; } +/* Where we want fancier font if available */ +h1, h2, h3, h4, h5, h6, p.module-desc, table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; } + +h1.title { + font-weight: 900; } + body { font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: 400; - font-size: 1.125em; - line-height: 1.5; - color: #222; - background-color: #FCFCFC; } + font-size: 16px; + line-height: 20px; + color: #444; + letter-spacing: 0.15px; + background-color: #FDFBFA; } /* Skeleton grid */ .container { position: relative; width: 100%; - max-width: 1050px; + max-width: 960px; margin: 0 auto; - padding: 0; + padding: 0 20px; box-sizing: border-box; } .column, .columns { width: 100%; float: left; - box-sizing: border-box; - margin-left: 1%; -} + box-sizing: border-box; } -.column:first-child, -.columns:first-child { - margin-left: 0; } +/* For devices larger than 400px */ +@media (min-width: 400px) { + .container { + width: 100%; + padding: 0; } } +/* For devices larger than 650px */ +@media (min-width: 650px) { + .container { + width: 100%; } -.three.columns { - width: 19%; } + .column, + .columns { + margin-left: 4%; } -.nine.columns { - width: 80.0%; } + .column:first-child, + .columns:first-child { + margin-left: 0; } -.twelve.columns { - width: 100%; - margin-left: 0; } + .one.column, + .one.columns { + width: 4.66666666667%; } + + .two.columns { + width: 13.3333333333%; } -@media screen and (max-width: 860px) { .three.columns { - display: none; - } + width: 22%; } + + .four.columns { + width: 30.6666666667%; } + + .five.columns { + width: 39.3333333333%; } + + .six.columns { + width: 48%; } + + .seven.columns { + width: 56.6666666667%; } + + .eight.columns { + width: 65.3333333333%; } + .nine.columns { - width: 98.0%; - } - body { - font-size: 1em; - line-height: 1.35; - } -} + width: 74.0%; } + + .ten.columns { + width: 82.6666666667%; } + + .eleven.columns { + width: 91.3333333333%; } + + .twelve.columns { + width: 100%; + margin-left: 0; } + + .one-third.column { + width: 30.6666666667%; } + + .two-thirds.column { + width: 65.3333333333%; } } +/* Customer Overrides */ +.footer { + text-align: center; + color: #969696; + padding-top: 10%; } + +p.module-desc { + font-size: 1.1em; + color: #666666; } + +a.link-seesrc { + color: #aec7d2; + font-style: italic; } + +a.link-seesrc:hover { + color: #6c9aae; } + +#toc-list { + word-wrap: break-word; } + +ul.simple-toc { + list-style: none; } + +ul.simple-toc a.reference-toplevel { + font-weight: bold; + color: #0077b3; } + +ul.simple-toc-section { + list-style-type: circle; + color: #6c9aae; } + +ul.simple-toc-section a.reference { + color: #0077b3; } cite { font-style: italic !important; } +dt > pre { + border-color: rgba(0, 0, 0, 0.1); + background-color: rgba(255, 255, 255, 0.3); + margin: 15px 0px 5px; } + +dd > pre { + border-color: rgba(0, 0, 0, 0.1); + background-color: whitesmoke; + margin-top: 8px; } + +.item > dd { + margin-left: 10px; + margin-bottom: 30px; } + +/* Nim line-numbered tables */ +.line-nums-table { + width: 100%; + table-layout: fixed; } /* Nim search input */ div#searchInputDiv { - margin-bottom: 1em; + margin-bottom: 8px; } -input#searchInput { - width: 80%; +div#searchInputDiv input#searchInput { + width: 10em; +} +div.search-groupby { + margin-bottom: 8px; } -/* - * Some custom formatting for input forms. - * This also fixes input form colors on Firefox with a dark system theme on Linux. - */ -input { - -moz-appearance: none; - color: #333; - background-color: #f8f8f8; - border: 1px solid #aaa; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-size: 0.9em; - padding: 6px; -} -input:focus { - border: 1px solid #1fa0eb; - box-shadow: 0 0 2px #1fa0eb; -} +table.line-nums-table { + border-radius: 4px; + border: 1px solid #cccccc; + background-color: whitesmoke; + border-collapse: separate; + margin-top: 15px; + margin-bottom: 25px; } + +.line-nums-table tbody { + border: none; } + +.line-nums-table td pre { + border: none; + background-color: transparent; } + +.line-nums-table td.blob-line-nums { + width: 28px; } + +.line-nums-table td.blob-line-nums pre { + color: #b0b0b0; + -webkit-filter: opacity(75%); + text-align: right; + border-color: transparent; + background-color: transparent; + padding-left: 0px; + margin-left: 0px; + padding-right: 0px; + margin-right: 0px; } /* Docgen styles */ /* Links */ a { - color: #07b; - text-decoration: none; -} - -a span.Identifier { - text-decoration: underline; - text-decoration-color: #aab; -} - -a.reference-toplevel { - font-weight: bold; -} - -a.toc-backref { - text-decoration: none; - color: #222; } - -a.link-seesrc { - color: #607c9f; - font-size: 0.9em; - font-style: italic; } + color: #0077b3; + text-decoration: none; } a:hover, a:focus { - color: #607c9f; + color: #00334d; text-decoration: underline; } -a:hover span.Identifier { - color: #607c9f; -} +a:visited { + color: #00334d; } +a:focus { + outline: thin dotted #2d2d2d; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; } + +a:hover, +a:active { + outline: 0; } sub, sup { @@ -227,258 +329,379 @@ img { h2, h3 { - page-break-after: avoid; } -} + page-break-after: avoid; } } +.img-rounded { + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; } +.img-polaroid { + padding: 4px; + background-color: rgba(252, 248, 244, 0.75); + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.2); + -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); } p { - margin-top: 0.5em; - margin-bottom: 0.5em; -} + margin: 0 0 8px; } small { font-size: 85%; } strong { - font-weight: 600; - font-size: 0.95em; - color: #3c3c3c; -} + font-weight: 600; } em { font-style: italic; } +cite { + font-style: normal; } + +h1, +h2, +h3, +h4, +h5, +h6 { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-weight: 600; + line-height: 20px; + color: inherit; + text-rendering: optimizelegibility; } + h1 { - font-size: 1.8em; + font-size: 2em; font-weight: 400; - padding-bottom: .25em; - border-bottom: 1px solid #aaa; - margin-top: 2.5em; - margin-bottom: 1em; + padding-bottom: .15em; + border-bottom: 1px solid #aaaaaa; + margin-top: 1.0em; line-height: 1.2em; } h1.title { padding-bottom: 1em; border-bottom: 0px; - font-size: 2.5em; - text-align: center; - font-weight: 900; - margin-top: 0.75em; - margin-bottom: 0em; -} + font-size: 2.75em; } h2 { - font-size: 1.3em; - margin-top: 2em; } - -h2.subtitle { - text-align: center; } - -h3 { - font-size: 1.125em; - font-style: italic; + font-size: 1.5em; margin-top: 1.5em; } +h3 { + font-size: 1.3em; + font-style: italic; + margin-top: 0.75em; } + h4 { - font-size: 1.125em; - margin-top: 1em; } + font-size: 1.3em; + margin-top: 0.5em; } h5 { - font-size: 1.125em; - margin-top: 0.75em; } + font-size: 1.2em; + margin-top: 0.25em; } h6 { font-size: 1.1em; } - ul, ol { padding: 0; - margin-top: 0.5em; - margin-left: 0.75em; } + margin: 0 0 0px 15px; } ul ul, ul ol, ol ol, ol ul { - margin-bottom: 0; - margin-left: 1.25em; } + margin-bottom: 0; } li { - list-style-type: circle; -} - -ul.simple-boot li { - list-style-type: none; - margin-left: 0em; - margin-bottom: 0.5em; -} - -ol.simple > li, ul.simple > li { - margin-bottom: 0.25em; - margin-left: 0.4em } - -ul.simple.simple-toc > li { - margin-top: 1em; -} - -ul.simple-toc { - list-style: none; - font-size: 0.9em; - margin-left: -0.3em; - margin-top: 1em; } - -ul.simple-toc > li { - list-style-type: none; -} - -ul.simple-toc-section { - list-style-type: circle; - margin-left: 1em; - color: #6c9aae; } - - -ol.arabic { - list-style: decimal; } - -ol.loweralpha { - list-style: lower-alpha; } - -ol.upperalpha { - list-style: upper-alpha; } - -ol.lowerroman { - list-style: lower-roman; } - -ol.upperroman { - list-style: upper-roman; } - -ul.auto-toc { - list-style-type: none; } - + line-height: 20px; } dl { - margin-bottom: 1.5em; } + margin-bottom: 20px; } + +dt, +dd { + line-height: 20px; } dt { - margin-bottom: -0.5em; - margin-left: 0.0em; } + font-weight: bold; } dd { - margin-left: 2.0em; - margin-bottom: 3.0em; - margin-top: 0.5em; } - + margin-left: 10px; + margin-bottom: 26px; } hr { - margin: 2em 0; + margin: 20px 0; border: 0; - border-top: 1px solid #aaa; } + border-top: 1px solid #eeeeee; + border-bottom: 1px solid #ffffff; } + +abbr[title], +abbr[data-original-title] { + cursor: help; + border-bottom: 1px dotted #999999; } + +abbr.initialism { + font-size: 90%; + text-transform: uppercase; } blockquote { - font-size: 0.9em; - font-style: italic; - padding-left: 0.5em; - margin-left: 0; - border-left: 5px solid #bbc; + padding: 0 0 0 15px; + margin: 0 0 20px; + border-left: 5px solid #EFEBE0; } + +table.docinfo + blockquote, table.docinfo blockquote, h1 + blockquote { + border-left: 5px solid #c9c9c9; } +table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { + margin-bottom: 0; + font-size: 15px; + font-weight: 200; + line-height: 1.5; + font-style: italic; } + +q:before, +q:after, +blockquote:before, +blockquote:after { + content: ""; } + +address { + display: block; + margin-bottom: 20px; + font-style: normal; + line-height: 20px; } + +code, +pre { + font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; + padding: 0 3px 2px; + font-weight: 500; + font-size: 12px; + color: #444444; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; } + .pre { font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - font-weight: 500; - font-size: 0.85em; - background-color: #f0f3ff; - padding-left: 3px; - padding-right: 3px; - border-radius: 4px; + font-weight: 600; + /*color: #504da6;*/ } +code { + padding: 2px 4px; + color: #444444; + white-space: nowrap; + background-color: white; + border: 1px solid #777777; } + pre { - font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - color: #222; - font-weight: 500; display: inline-block; box-sizing: border-box; - min-width: 100%; - padding: 0.5em; - margin-top: 0.5em; - margin-bottom: 0.5em; - font-size: 0.85em; + min-width: calc(100% - 19.5px); + padding: 9.5px; + margin: 0.25em 10px 10px 10px; + font-size: 15px; + line-height: 20px; white-space: pre !important; overflow-y: hidden; overflow-x: visible; - background-color: ghostwhite; - border: 1px solid #dde; - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; } + background-color: rgba(0, 0, 0, 0.01); + border: 1px solid #cccccc; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; } + +pre.prettyprint { + margin-bottom: 20px; } + +pre code { + padding: 0; + color: inherit; + white-space: pre; + overflow-x: visible; + background-color: transparent; + border: 0; } .pre-scrollable { max-height: 340px; overflow-y: scroll; } - -/* Nim line-numbered tables */ -.line-nums-table { - width: 100%; - table-layout: fixed; } - -table.line-nums-table { - border-radius: 4px; - border: 1px solid #cccccc; - background-color: ghostwhite; - border-collapse: separate; - margin-top: 15px; - margin-bottom: 25px; } - -.line-nums-table tbody { - border: none; } - -.line-nums-table td pre { - border: none; - background-color: transparent; } - -.line-nums-table td.blob-line-nums { - width: 28px; } - -.line-nums-table td.blob-line-nums pre { - color: #b0b0b0; - -webkit-filter: opacity(75%); - text-align: right; - border-color: transparent; - background-color: transparent; - padding-left: 0px; - margin-left: 0px; - padding-right: 0px; - margin-right: 0px; } - - table { max-width: 100%; background-color: transparent; - margin-top: 0.5em; - margin-bottom: 1.5em; border-collapse: collapse; - border-color: #ccc; - border-spacing: 0; - font-size: 0.9em; -} + border-spacing: 0; } table th, table td { - padding: 0px 0.5em 0px; + padding: 0px 8px 0px; } -table th { - background-color: #e8e8e8; +.table { + width: 100%; + margin-bottom: 20px; } + +.table th, +.table td { + padding: 8px; + line-height: 20px; + text-align: left; + vertical-align: top; + border-top: 1px solid #444444; } + +.table th { font-weight: bold; } -table th.docinfo-name { - background-color: transparent; -} +.table thead th { + vertical-align: bottom; } -table tr:hover { - background-color: ghostwhite; } +.table caption + thead tr:first-child th, +.table caption + thead tr:first-child td, +.table colgroup + thead tr:first-child th, +.table colgroup + thead tr:first-child td, +.table thead:first-child tr:first-child th, +.table thead:first-child tr:first-child td { + border-top: 0; } +.table tbody + tbody { + border-top: 2px solid #444444; } + +.table .table { + background-color: rgba(252, 248, 244, 0.75); } + +.table-condensed th, +.table-condensed td { + padding: 4px 5px; } + +.table-bordered { + border: 1px solid #444444; + border-collapse: separate; + *border-collapse: collapse; + border-left: 0; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; } + +.table-bordered th, +.table-bordered td { + border-left: 1px solid #444444; } + +.table-bordered caption + thead tr:first-child th, +.table-bordered caption + tbody tr:first-child th, +.table-bordered caption + tbody tr:first-child td, +.table-bordered colgroup + thead tr:first-child th, +.table-bordered colgroup + tbody tr:first-child th, +.table-bordered colgroup + tbody tr:first-child td, +.table-bordered thead:first-child tr:first-child th, +.table-bordered tbody:first-child tr:first-child th, +.table-bordered tbody:first-child tr:first-child td { + border-top: 0; } + +.table-bordered thead:first-child tr:first-child > th:first-child, +.table-bordered tbody:first-child tr:first-child > td:first-child, +.table-bordered tbody:first-child tr:first-child > th:first-child { + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; } + +.table-bordered thead:first-child tr:first-child > th:last-child, +.table-bordered tbody:first-child tr:first-child > td:last-child, +.table-bordered tbody:first-child tr:first-child > th:last-child { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; } + +.table-bordered thead:last-child tr:last-child > th:first-child, +.table-bordered tbody:last-child tr:last-child > td:first-child, +.table-bordered tbody:last-child tr:last-child > th:first-child, +.table-bordered tfoot:last-child tr:last-child > td:first-child, +.table-bordered tfoot:last-child tr:last-child > th:first-child { + -webkit-border-bottom-left-radius: 4px; + border-bottom-left-radius: 4px; + -moz-border-radius-bottomleft: 4px; } + +.table-bordered thead:last-child tr:last-child > th:last-child, +.table-bordered tbody:last-child tr:last-child > td:last-child, +.table-bordered tbody:last-child tr:last-child > th:last-child, +.table-bordered tfoot:last-child tr:last-child > td:last-child, +.table-bordered tfoot:last-child tr:last-child > th:last-child { + -webkit-border-bottom-right-radius: 4px; + border-bottom-right-radius: 4px; + -moz-border-radius-bottomright: 4px; } + +.table-bordered tfoot + tbody:last-child tr:last-child td:first-child { + -webkit-border-bottom-left-radius: 0; + border-bottom-left-radius: 0; + -moz-border-radius-bottomleft: 0; } + +.table-bordered tfoot + tbody:last-child tr:last-child td:last-child { + -webkit-border-bottom-right-radius: 0; + border-bottom-right-radius: 0; + -moz-border-radius-bottomright: 0; } + +.table-bordered caption + thead tr:first-child th:first-child, +.table-bordered caption + tbody tr:first-child td:first-child, +.table-bordered colgroup + thead tr:first-child th:first-child, +.table-bordered colgroup + tbody tr:first-child td:first-child { + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; } + +.table-bordered caption + thead tr:first-child th:last-child, +.table-bordered caption + tbody tr:first-child td:last-child, +.table-bordered colgroup + thead tr:first-child th:last-child, +.table-bordered colgroup + tbody tr:first-child td:last-child { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; } + +table.docutils th { + background-color: #e8e8e8; } + +table.docutils tr:hover { + background-color: whitesmoke; } + +.table-striped tbody > tr:nth-child(odd) > td, +.table-striped tbody > tr:nth-child(odd) > th { + background-color: rgba(252, 248, 244, 0.75); } + +.table-hover tbody tr:hover > td, +.table-hover tbody tr:hover > th { + background-color: rgba(241, 222, 204, 0.75); } + +table td[class*="span"], +table th[class*="span"], +.row-fluid table td[class*="span"], +.row-fluid table th[class*="span"] { + display: table-cell; + float: none; + margin-left: 0; } + +.hero-unit { + padding: 60px; + margin-bottom: 30px; + font-size: 18px; + font-weight: 200; + line-height: 30px; + color: inherit; + background-color: rgba(230, 197, 164, 0.75); + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; } + +.hero-unit h1 { + margin-bottom: 0; + font-size: 60px; + line-height: 1; + letter-spacing: -1px; + color: inherit; } + +.hero-unit li { + line-height: 30px; } /* rst2html default used to remove borders from tables and images */ .borderless, table.borderless td, table.borderless th { @@ -499,6 +722,10 @@ table.borderless td, table.borderless th { .hidden { display: none; } +a.toc-backref { + text-decoration: none; + color: #444444; } + blockquote.epigraph { margin: 2em 5em; } @@ -508,6 +735,85 @@ dl.docutils dd { object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] { overflow: hidden; } +/* Uncomment (and remove this text!) to get bold-faced definition list terms +dl.docutils dt { + font-weight: bold } +*/ +div.abstract { + margin: 2em 5em; } + +div.abstract p.topic-title { + font-weight: bold; + text-align: center; } + +div.admonition, div.attention, div.caution, div.danger, div.error, +div.hint, div.important, div.note, div.tip, div.warning { + margin: 2em; + border: medium outset; + padding: 1em; } + +div.note, div.warning { + margin: 1.5em 0px; + border: none; } + +div.note p.admonition-title, +div.warning p.admonition-title { + display: none; } + +/* Clearfix + * http://css-tricks.com/snippets/css/clear-fix/ + */ +div.note:after, +div.warning:after { + content: ""; + display: table; + clear: both; } + +div.note p:before, +div.warning p:before { + display: block; + float: left; + font-size: 4em; + line-height: 1em; + margin-right: 20px; + margin-left: 0em; + margin-top: -10px; + content: '\0270D'; + /*handwriting*/ } + +div.warning p:before { + content: '\026A0'; + /*warning*/ } + +div.admonition p.admonition-title, div.hint p.admonition-title, +div.important p.admonition-title, div.note p.admonition-title, +div.tip p.admonition-title { + font-weight: bold; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } + +div.attention p.admonition-title, div.caution p.admonition-title, +div.danger p.admonition-title, div.error p.admonition-title, +div.warning p.admonition-title, .code .error { + color: #b30000; + font-weight: bold; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } + +/* Uncomment (and remove this text!) to get reduced vertical space in + compound paragraphs. +div.compound .compound-first, div.compound .compound-middle { + margin-bottom: 0.5em } + +div.compound .compound-last, div.compound .compound-middle { + margin-top: 0.5em } +*/ +div.dedication { + margin: 2em 5em; + text-align: center; + font-style: italic; } + +div.dedication p.topic-title { + font-weight: bold; + font-style: normal; } div.figure { margin-left: 2em; @@ -515,14 +821,8 @@ div.figure { div.footer, div.header { clear: both; - text-align: center; - color: #666; font-size: smaller; } -div.footer { - padding-top: 5em; -} - div.line-block { display: block; margin-top: 1em; @@ -533,24 +833,45 @@ div.line-block div.line-block { margin-bottom: 0; margin-left: 1.5em; } +div.sidebar { + margin: 0 0 0.5em 1em; + border: medium outset; + padding: 1em; + background-color: rgba(252, 248, 244, 0.75); + width: 40%; + float: right; + clear: right; } + +div.sidebar p.rubric { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-size: medium; } + +div.system-messages { + margin: 5em; } + +div.system-messages h1 { + color: #b30000; } + +div.system-message { + border: medium outset; + padding: 1em; } + +div.system-message p.system-message-title { + color: #b30000; + font-weight: bold; } + div.topic { margin: 2em; } -div.search_results { - background-color: antiquewhite; - margin: 3em; - padding: 1em; - border: 1px solid #4d4d4d; -} +h1.section-subtitle, h2.section-subtitle, h3.section-subtitle, +h4.section-subtitle, h5.section-subtitle, h6.section-subtitle { + margin-top: 0.4em; } -div#global-links ul { - margin-left: 0; - list-style-type: none; -} +h1.title { + text-align: center; } -div#global-links > simple-boot { - margin-left: 3em; -} +h2.subtitle { + text-align: center; } hr.docutils { width: 75%; } @@ -584,6 +905,30 @@ img.align-center, .figure.align-center, object.align-center { div.align-right { text-align: inherit; } +/* div.align-center * { */ +/* text-align: left } */ + +ul.simple > li { + margin-bottom: 0.5em } + +ol.simple, ul.simple { + margin-bottom: 1em; } + +ol.arabic { + list-style: decimal; } + +ol.loweralpha { + list-style: lower-alpha; } + +ol.upperalpha { + list-style: upper-alpha; } + +ol.lowerroman { + list-style: lower-roman; } + +ol.upperroman { + list-style: upper-roman; } + p.attribution { text-align: right; margin-left: 50%; } @@ -604,6 +949,15 @@ p.rubric { color: maroon; text-align: center; } +p.sidebar-title { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-weight: bold; + font-size: larger; } + +p.sidebar-subtitle { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-weight: bold; } + p.topic-title { font-weight: bold; } @@ -643,14 +997,22 @@ pre.code .inserted, code .inserted { background-color: #A3D289; } span.classifier { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-style: oblique; } span.classifier-delimiter { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: bold; } +span.interpreted { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } + span.option { white-space: nowrap; } +span.pre { + white-space: pre; } + span.problematic { color: #b30000; } @@ -658,6 +1020,44 @@ span.section-subtitle { /* font-size relative to parent (h1..h6 element) */ font-size: 80%; } +table.citation { + border-left: solid 1px #666666; + margin-left: 1px; } + +table.docinfo { + margin: 0em; + margin-top: 2em; + margin-bottom: 2em; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; + color: #444444; } + +table.docutils { + margin-top: 0.5em; + margin-bottom: 0.5em; } + +table.footnote { + border-left: solid 1px #2d2d2d; + margin-left: 1px; } + +table.docutils td, table.docutils th, +table.docinfo td, table.docinfo th { + padding-left: 0.5em; + padding-right: 0.5em; + vertical-align: top; } + +table.docutils th.field-name, table.docinfo th.docinfo-name { + font-weight: 700; + text-align: left; + white-space: nowrap; + padding-left: 0; } + +h1 tt.docutils, h2 tt.docutils, h3 tt.docutils, +h4 tt.docutils, h5 tt.docutils, h6 tt.docutils { + font-size: 100%; } + +ul.auto-toc { + list-style-type: none; } + span.DecNumber { color: #252dbe; } @@ -674,7 +1074,7 @@ span.FloatNumber { color: #252dbe; } span.Identifier { - color: #222; } + color: #3b3b3b; } span.Keyword { font-weight: 600; @@ -739,23 +1139,38 @@ dt pre > span.Identifier, dt pre > span.Operator { color: #155da4; font-weight: 700; } -dt pre > span.Keyword ~ span.Identifier, dt pre > span.Identifier ~ span.Identifier, -dt pre > span.Operator ~ span.Identifier, dt pre > span.Other ~ span.Identifier { +dt pre > span.Identifier ~ span.Identifier, dt pre > span.Operator ~ span.Identifier { + color: inherit; + font-weight: inherit; } + +dt pre > span.Operator ~ span.Identifier { color: inherit; font-weight: inherit; } /* Nim sprite for the footer (taken from main page favicon) */ .nim-sprite { display: inline-block; - height: 16px; - width: 16px; + height: 12px; + width: 12px; background-position: 0 0; - background-size: 16px 16px; + background-size: 12px 12px; -webkit-filter: opacity(50%); background-repeat: no-repeat; background-image: url("data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="); margin-bottom: -5px; } +div.search_results { + background-color: antiquewhite; + margin: 3em; + padding: 1em; + border: 1px solid #4d4d4d; +} + +div#global-links ul { + margin-left: 0; + list-style-type: none; +} + span.pragmadots { /* Position: relative frees us up to make the dots look really nice without fucking up the layout and @@ -763,14 +1178,18 @@ span.pragmadots { position: relative; /* 1px down looks slightly nicer */ top: 1px; + padding: 2px; - background-color: #e8e8e8; + background-color: #D3D3D3; border-radius: 4px; margin: 0 2px; cursor: pointer; - font-size: 0.8em; -} + /* For some reason on Chrome, making the font size + smaller than 1em is causing the parent container to + bulge slightly. So, we're stuck with inheriting 1em, + which is sad, because 0.8em looks better... */ +} span.pragmadots:hover { background-color: #DBDBDB; } @@ -778,10 +1197,6 @@ span.pragmawrap { display: none; } -span.attachedType { - display: none; - visibility: hidden; -} @@ -835,8 +1250,7 @@ function main() {
- -

Module that should import everything so that nim doc --project nimtero/all runs docs on everything.

+

Module that should import everything so that nim doc --project nimtero/all runs docs on everything.

Imports

@@ -850,7 +1264,7 @@ function main() {
diff --git a/cimport.html b/cimport.html index 6066a47..c8ad735 100644 --- a/cimport.html +++ b/cimport.html @@ -27,130 +27,232 @@ customize this style sheet. Modified from Chad Skeeters' rst2html-style https://bitbucket.org/cskeeters/rst2html-style/ -Modified by Boyd Greenfield and narimiran +Modified by Boyd Greenfield */ - +/* SCSS variables */ +/* Text weights */ +/* Body colors */ +/* Text colors */ +/* Link colors */ +/* Syntax highlighting colors */ +/* Pct changes */ +/* Mixins */ +/* Body/layout */ html { font-size: 100%; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; } +/* Where we want fancier font if available */ +h1, h2, h3, h4, h5, h6, p.module-desc, table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; } + +h1.title { + font-weight: 900; } + body { font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: 400; - font-size: 1.125em; - line-height: 1.5; - color: #222; - background-color: #FCFCFC; } + font-size: 16px; + line-height: 20px; + color: #444; + letter-spacing: 0.15px; + background-color: #FDFBFA; } /* Skeleton grid */ .container { position: relative; width: 100%; - max-width: 1050px; + max-width: 960px; margin: 0 auto; - padding: 0; + padding: 0 20px; box-sizing: border-box; } .column, .columns { width: 100%; float: left; - box-sizing: border-box; - margin-left: 1%; -} + box-sizing: border-box; } -.column:first-child, -.columns:first-child { - margin-left: 0; } +/* For devices larger than 400px */ +@media (min-width: 400px) { + .container { + width: 100%; + padding: 0; } } +/* For devices larger than 650px */ +@media (min-width: 650px) { + .container { + width: 100%; } -.three.columns { - width: 19%; } + .column, + .columns { + margin-left: 4%; } -.nine.columns { - width: 80.0%; } + .column:first-child, + .columns:first-child { + margin-left: 0; } -.twelve.columns { - width: 100%; - margin-left: 0; } + .one.column, + .one.columns { + width: 4.66666666667%; } + + .two.columns { + width: 13.3333333333%; } -@media screen and (max-width: 860px) { .three.columns { - display: none; - } + width: 22%; } + + .four.columns { + width: 30.6666666667%; } + + .five.columns { + width: 39.3333333333%; } + + .six.columns { + width: 48%; } + + .seven.columns { + width: 56.6666666667%; } + + .eight.columns { + width: 65.3333333333%; } + .nine.columns { - width: 98.0%; - } - body { - font-size: 1em; - line-height: 1.35; - } -} + width: 74.0%; } + + .ten.columns { + width: 82.6666666667%; } + + .eleven.columns { + width: 91.3333333333%; } + + .twelve.columns { + width: 100%; + margin-left: 0; } + + .one-third.column { + width: 30.6666666667%; } + + .two-thirds.column { + width: 65.3333333333%; } } +/* Customer Overrides */ +.footer { + text-align: center; + color: #969696; + padding-top: 10%; } + +p.module-desc { + font-size: 1.1em; + color: #666666; } + +a.link-seesrc { + color: #aec7d2; + font-style: italic; } + +a.link-seesrc:hover { + color: #6c9aae; } + +#toc-list { + word-wrap: break-word; } + +ul.simple-toc { + list-style: none; } + +ul.simple-toc a.reference-toplevel { + font-weight: bold; + color: #0077b3; } + +ul.simple-toc-section { + list-style-type: circle; + color: #6c9aae; } + +ul.simple-toc-section a.reference { + color: #0077b3; } cite { font-style: italic !important; } +dt > pre { + border-color: rgba(0, 0, 0, 0.1); + background-color: rgba(255, 255, 255, 0.3); + margin: 15px 0px 5px; } + +dd > pre { + border-color: rgba(0, 0, 0, 0.1); + background-color: whitesmoke; + margin-top: 8px; } + +.item > dd { + margin-left: 10px; + margin-bottom: 30px; } + +/* Nim line-numbered tables */ +.line-nums-table { + width: 100%; + table-layout: fixed; } /* Nim search input */ div#searchInputDiv { - margin-bottom: 1em; + margin-bottom: 8px; } -input#searchInput { - width: 80%; +div#searchInputDiv input#searchInput { + width: 10em; +} +div.search-groupby { + margin-bottom: 8px; } -/* - * Some custom formatting for input forms. - * This also fixes input form colors on Firefox with a dark system theme on Linux. - */ -input { - -moz-appearance: none; - color: #333; - background-color: #f8f8f8; - border: 1px solid #aaa; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-size: 0.9em; - padding: 6px; -} -input:focus { - border: 1px solid #1fa0eb; - box-shadow: 0 0 2px #1fa0eb; -} +table.line-nums-table { + border-radius: 4px; + border: 1px solid #cccccc; + background-color: whitesmoke; + border-collapse: separate; + margin-top: 15px; + margin-bottom: 25px; } + +.line-nums-table tbody { + border: none; } + +.line-nums-table td pre { + border: none; + background-color: transparent; } + +.line-nums-table td.blob-line-nums { + width: 28px; } + +.line-nums-table td.blob-line-nums pre { + color: #b0b0b0; + -webkit-filter: opacity(75%); + text-align: right; + border-color: transparent; + background-color: transparent; + padding-left: 0px; + margin-left: 0px; + padding-right: 0px; + margin-right: 0px; } /* Docgen styles */ /* Links */ a { - color: #07b; - text-decoration: none; -} - -a span.Identifier { - text-decoration: underline; - text-decoration-color: #aab; -} - -a.reference-toplevel { - font-weight: bold; -} - -a.toc-backref { - text-decoration: none; - color: #222; } - -a.link-seesrc { - color: #607c9f; - font-size: 0.9em; - font-style: italic; } + color: #0077b3; + text-decoration: none; } a:hover, a:focus { - color: #607c9f; + color: #00334d; text-decoration: underline; } -a:hover span.Identifier { - color: #607c9f; -} +a:visited { + color: #00334d; } +a:focus { + outline: thin dotted #2d2d2d; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; } + +a:hover, +a:active { + outline: 0; } sub, sup { @@ -227,258 +329,379 @@ img { h2, h3 { - page-break-after: avoid; } -} + page-break-after: avoid; } } +.img-rounded { + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; } +.img-polaroid { + padding: 4px; + background-color: rgba(252, 248, 244, 0.75); + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.2); + -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); } p { - margin-top: 0.5em; - margin-bottom: 0.5em; -} + margin: 0 0 8px; } small { font-size: 85%; } strong { - font-weight: 600; - font-size: 0.95em; - color: #3c3c3c; -} + font-weight: 600; } em { font-style: italic; } +cite { + font-style: normal; } + +h1, +h2, +h3, +h4, +h5, +h6 { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-weight: 600; + line-height: 20px; + color: inherit; + text-rendering: optimizelegibility; } + h1 { - font-size: 1.8em; + font-size: 2em; font-weight: 400; - padding-bottom: .25em; - border-bottom: 1px solid #aaa; - margin-top: 2.5em; - margin-bottom: 1em; + padding-bottom: .15em; + border-bottom: 1px solid #aaaaaa; + margin-top: 1.0em; line-height: 1.2em; } h1.title { padding-bottom: 1em; border-bottom: 0px; - font-size: 2.5em; - text-align: center; - font-weight: 900; - margin-top: 0.75em; - margin-bottom: 0em; -} + font-size: 2.75em; } h2 { - font-size: 1.3em; - margin-top: 2em; } - -h2.subtitle { - text-align: center; } - -h3 { - font-size: 1.125em; - font-style: italic; + font-size: 1.5em; margin-top: 1.5em; } +h3 { + font-size: 1.3em; + font-style: italic; + margin-top: 0.75em; } + h4 { - font-size: 1.125em; - margin-top: 1em; } + font-size: 1.3em; + margin-top: 0.5em; } h5 { - font-size: 1.125em; - margin-top: 0.75em; } + font-size: 1.2em; + margin-top: 0.25em; } h6 { font-size: 1.1em; } - ul, ol { padding: 0; - margin-top: 0.5em; - margin-left: 0.75em; } + margin: 0 0 0px 15px; } ul ul, ul ol, ol ol, ol ul { - margin-bottom: 0; - margin-left: 1.25em; } + margin-bottom: 0; } li { - list-style-type: circle; -} - -ul.simple-boot li { - list-style-type: none; - margin-left: 0em; - margin-bottom: 0.5em; -} - -ol.simple > li, ul.simple > li { - margin-bottom: 0.25em; - margin-left: 0.4em } - -ul.simple.simple-toc > li { - margin-top: 1em; -} - -ul.simple-toc { - list-style: none; - font-size: 0.9em; - margin-left: -0.3em; - margin-top: 1em; } - -ul.simple-toc > li { - list-style-type: none; -} - -ul.simple-toc-section { - list-style-type: circle; - margin-left: 1em; - color: #6c9aae; } - - -ol.arabic { - list-style: decimal; } - -ol.loweralpha { - list-style: lower-alpha; } - -ol.upperalpha { - list-style: upper-alpha; } - -ol.lowerroman { - list-style: lower-roman; } - -ol.upperroman { - list-style: upper-roman; } - -ul.auto-toc { - list-style-type: none; } - + line-height: 20px; } dl { - margin-bottom: 1.5em; } + margin-bottom: 20px; } + +dt, +dd { + line-height: 20px; } dt { - margin-bottom: -0.5em; - margin-left: 0.0em; } + font-weight: bold; } dd { - margin-left: 2.0em; - margin-bottom: 3.0em; - margin-top: 0.5em; } - + margin-left: 10px; + margin-bottom: 26px; } hr { - margin: 2em 0; + margin: 20px 0; border: 0; - border-top: 1px solid #aaa; } + border-top: 1px solid #eeeeee; + border-bottom: 1px solid #ffffff; } + +abbr[title], +abbr[data-original-title] { + cursor: help; + border-bottom: 1px dotted #999999; } + +abbr.initialism { + font-size: 90%; + text-transform: uppercase; } blockquote { - font-size: 0.9em; - font-style: italic; - padding-left: 0.5em; - margin-left: 0; - border-left: 5px solid #bbc; + padding: 0 0 0 15px; + margin: 0 0 20px; + border-left: 5px solid #EFEBE0; } + +table.docinfo + blockquote, table.docinfo blockquote, h1 + blockquote { + border-left: 5px solid #c9c9c9; } +table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { + margin-bottom: 0; + font-size: 15px; + font-weight: 200; + line-height: 1.5; + font-style: italic; } + +q:before, +q:after, +blockquote:before, +blockquote:after { + content: ""; } + +address { + display: block; + margin-bottom: 20px; + font-style: normal; + line-height: 20px; } + +code, +pre { + font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; + padding: 0 3px 2px; + font-weight: 500; + font-size: 12px; + color: #444444; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; } + .pre { font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - font-weight: 500; - font-size: 0.85em; - background-color: #f0f3ff; - padding-left: 3px; - padding-right: 3px; - border-radius: 4px; + font-weight: 600; + /*color: #504da6;*/ } +code { + padding: 2px 4px; + color: #444444; + white-space: nowrap; + background-color: white; + border: 1px solid #777777; } + pre { - font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - color: #222; - font-weight: 500; display: inline-block; box-sizing: border-box; - min-width: 100%; - padding: 0.5em; - margin-top: 0.5em; - margin-bottom: 0.5em; - font-size: 0.85em; + min-width: calc(100% - 19.5px); + padding: 9.5px; + margin: 0.25em 10px 10px 10px; + font-size: 15px; + line-height: 20px; white-space: pre !important; overflow-y: hidden; overflow-x: visible; - background-color: ghostwhite; - border: 1px solid #dde; - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; } + background-color: rgba(0, 0, 0, 0.01); + border: 1px solid #cccccc; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; } + +pre.prettyprint { + margin-bottom: 20px; } + +pre code { + padding: 0; + color: inherit; + white-space: pre; + overflow-x: visible; + background-color: transparent; + border: 0; } .pre-scrollable { max-height: 340px; overflow-y: scroll; } - -/* Nim line-numbered tables */ -.line-nums-table { - width: 100%; - table-layout: fixed; } - -table.line-nums-table { - border-radius: 4px; - border: 1px solid #cccccc; - background-color: ghostwhite; - border-collapse: separate; - margin-top: 15px; - margin-bottom: 25px; } - -.line-nums-table tbody { - border: none; } - -.line-nums-table td pre { - border: none; - background-color: transparent; } - -.line-nums-table td.blob-line-nums { - width: 28px; } - -.line-nums-table td.blob-line-nums pre { - color: #b0b0b0; - -webkit-filter: opacity(75%); - text-align: right; - border-color: transparent; - background-color: transparent; - padding-left: 0px; - margin-left: 0px; - padding-right: 0px; - margin-right: 0px; } - - table { max-width: 100%; background-color: transparent; - margin-top: 0.5em; - margin-bottom: 1.5em; border-collapse: collapse; - border-color: #ccc; - border-spacing: 0; - font-size: 0.9em; -} + border-spacing: 0; } table th, table td { - padding: 0px 0.5em 0px; + padding: 0px 8px 0px; } -table th { - background-color: #e8e8e8; +.table { + width: 100%; + margin-bottom: 20px; } + +.table th, +.table td { + padding: 8px; + line-height: 20px; + text-align: left; + vertical-align: top; + border-top: 1px solid #444444; } + +.table th { font-weight: bold; } -table th.docinfo-name { - background-color: transparent; -} +.table thead th { + vertical-align: bottom; } -table tr:hover { - background-color: ghostwhite; } +.table caption + thead tr:first-child th, +.table caption + thead tr:first-child td, +.table colgroup + thead tr:first-child th, +.table colgroup + thead tr:first-child td, +.table thead:first-child tr:first-child th, +.table thead:first-child tr:first-child td { + border-top: 0; } +.table tbody + tbody { + border-top: 2px solid #444444; } + +.table .table { + background-color: rgba(252, 248, 244, 0.75); } + +.table-condensed th, +.table-condensed td { + padding: 4px 5px; } + +.table-bordered { + border: 1px solid #444444; + border-collapse: separate; + *border-collapse: collapse; + border-left: 0; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; } + +.table-bordered th, +.table-bordered td { + border-left: 1px solid #444444; } + +.table-bordered caption + thead tr:first-child th, +.table-bordered caption + tbody tr:first-child th, +.table-bordered caption + tbody tr:first-child td, +.table-bordered colgroup + thead tr:first-child th, +.table-bordered colgroup + tbody tr:first-child th, +.table-bordered colgroup + tbody tr:first-child td, +.table-bordered thead:first-child tr:first-child th, +.table-bordered tbody:first-child tr:first-child th, +.table-bordered tbody:first-child tr:first-child td { + border-top: 0; } + +.table-bordered thead:first-child tr:first-child > th:first-child, +.table-bordered tbody:first-child tr:first-child > td:first-child, +.table-bordered tbody:first-child tr:first-child > th:first-child { + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; } + +.table-bordered thead:first-child tr:first-child > th:last-child, +.table-bordered tbody:first-child tr:first-child > td:last-child, +.table-bordered tbody:first-child tr:first-child > th:last-child { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; } + +.table-bordered thead:last-child tr:last-child > th:first-child, +.table-bordered tbody:last-child tr:last-child > td:first-child, +.table-bordered tbody:last-child tr:last-child > th:first-child, +.table-bordered tfoot:last-child tr:last-child > td:first-child, +.table-bordered tfoot:last-child tr:last-child > th:first-child { + -webkit-border-bottom-left-radius: 4px; + border-bottom-left-radius: 4px; + -moz-border-radius-bottomleft: 4px; } + +.table-bordered thead:last-child tr:last-child > th:last-child, +.table-bordered tbody:last-child tr:last-child > td:last-child, +.table-bordered tbody:last-child tr:last-child > th:last-child, +.table-bordered tfoot:last-child tr:last-child > td:last-child, +.table-bordered tfoot:last-child tr:last-child > th:last-child { + -webkit-border-bottom-right-radius: 4px; + border-bottom-right-radius: 4px; + -moz-border-radius-bottomright: 4px; } + +.table-bordered tfoot + tbody:last-child tr:last-child td:first-child { + -webkit-border-bottom-left-radius: 0; + border-bottom-left-radius: 0; + -moz-border-radius-bottomleft: 0; } + +.table-bordered tfoot + tbody:last-child tr:last-child td:last-child { + -webkit-border-bottom-right-radius: 0; + border-bottom-right-radius: 0; + -moz-border-radius-bottomright: 0; } + +.table-bordered caption + thead tr:first-child th:first-child, +.table-bordered caption + tbody tr:first-child td:first-child, +.table-bordered colgroup + thead tr:first-child th:first-child, +.table-bordered colgroup + tbody tr:first-child td:first-child { + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; } + +.table-bordered caption + thead tr:first-child th:last-child, +.table-bordered caption + tbody tr:first-child td:last-child, +.table-bordered colgroup + thead tr:first-child th:last-child, +.table-bordered colgroup + tbody tr:first-child td:last-child { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; } + +table.docutils th { + background-color: #e8e8e8; } + +table.docutils tr:hover { + background-color: whitesmoke; } + +.table-striped tbody > tr:nth-child(odd) > td, +.table-striped tbody > tr:nth-child(odd) > th { + background-color: rgba(252, 248, 244, 0.75); } + +.table-hover tbody tr:hover > td, +.table-hover tbody tr:hover > th { + background-color: rgba(241, 222, 204, 0.75); } + +table td[class*="span"], +table th[class*="span"], +.row-fluid table td[class*="span"], +.row-fluid table th[class*="span"] { + display: table-cell; + float: none; + margin-left: 0; } + +.hero-unit { + padding: 60px; + margin-bottom: 30px; + font-size: 18px; + font-weight: 200; + line-height: 30px; + color: inherit; + background-color: rgba(230, 197, 164, 0.75); + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; } + +.hero-unit h1 { + margin-bottom: 0; + font-size: 60px; + line-height: 1; + letter-spacing: -1px; + color: inherit; } + +.hero-unit li { + line-height: 30px; } /* rst2html default used to remove borders from tables and images */ .borderless, table.borderless td, table.borderless th { @@ -499,6 +722,10 @@ table.borderless td, table.borderless th { .hidden { display: none; } +a.toc-backref { + text-decoration: none; + color: #444444; } + blockquote.epigraph { margin: 2em 5em; } @@ -508,6 +735,85 @@ dl.docutils dd { object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] { overflow: hidden; } +/* Uncomment (and remove this text!) to get bold-faced definition list terms +dl.docutils dt { + font-weight: bold } +*/ +div.abstract { + margin: 2em 5em; } + +div.abstract p.topic-title { + font-weight: bold; + text-align: center; } + +div.admonition, div.attention, div.caution, div.danger, div.error, +div.hint, div.important, div.note, div.tip, div.warning { + margin: 2em; + border: medium outset; + padding: 1em; } + +div.note, div.warning { + margin: 1.5em 0px; + border: none; } + +div.note p.admonition-title, +div.warning p.admonition-title { + display: none; } + +/* Clearfix + * http://css-tricks.com/snippets/css/clear-fix/ + */ +div.note:after, +div.warning:after { + content: ""; + display: table; + clear: both; } + +div.note p:before, +div.warning p:before { + display: block; + float: left; + font-size: 4em; + line-height: 1em; + margin-right: 20px; + margin-left: 0em; + margin-top: -10px; + content: '\0270D'; + /*handwriting*/ } + +div.warning p:before { + content: '\026A0'; + /*warning*/ } + +div.admonition p.admonition-title, div.hint p.admonition-title, +div.important p.admonition-title, div.note p.admonition-title, +div.tip p.admonition-title { + font-weight: bold; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } + +div.attention p.admonition-title, div.caution p.admonition-title, +div.danger p.admonition-title, div.error p.admonition-title, +div.warning p.admonition-title, .code .error { + color: #b30000; + font-weight: bold; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } + +/* Uncomment (and remove this text!) to get reduced vertical space in + compound paragraphs. +div.compound .compound-first, div.compound .compound-middle { + margin-bottom: 0.5em } + +div.compound .compound-last, div.compound .compound-middle { + margin-top: 0.5em } +*/ +div.dedication { + margin: 2em 5em; + text-align: center; + font-style: italic; } + +div.dedication p.topic-title { + font-weight: bold; + font-style: normal; } div.figure { margin-left: 2em; @@ -515,14 +821,8 @@ div.figure { div.footer, div.header { clear: both; - text-align: center; - color: #666; font-size: smaller; } -div.footer { - padding-top: 5em; -} - div.line-block { display: block; margin-top: 1em; @@ -533,24 +833,45 @@ div.line-block div.line-block { margin-bottom: 0; margin-left: 1.5em; } +div.sidebar { + margin: 0 0 0.5em 1em; + border: medium outset; + padding: 1em; + background-color: rgba(252, 248, 244, 0.75); + width: 40%; + float: right; + clear: right; } + +div.sidebar p.rubric { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-size: medium; } + +div.system-messages { + margin: 5em; } + +div.system-messages h1 { + color: #b30000; } + +div.system-message { + border: medium outset; + padding: 1em; } + +div.system-message p.system-message-title { + color: #b30000; + font-weight: bold; } + div.topic { margin: 2em; } -div.search_results { - background-color: antiquewhite; - margin: 3em; - padding: 1em; - border: 1px solid #4d4d4d; -} +h1.section-subtitle, h2.section-subtitle, h3.section-subtitle, +h4.section-subtitle, h5.section-subtitle, h6.section-subtitle { + margin-top: 0.4em; } -div#global-links ul { - margin-left: 0; - list-style-type: none; -} +h1.title { + text-align: center; } -div#global-links > simple-boot { - margin-left: 3em; -} +h2.subtitle { + text-align: center; } hr.docutils { width: 75%; } @@ -584,6 +905,30 @@ img.align-center, .figure.align-center, object.align-center { div.align-right { text-align: inherit; } +/* div.align-center * { */ +/* text-align: left } */ + +ul.simple > li { + margin-bottom: 0.5em } + +ol.simple, ul.simple { + margin-bottom: 1em; } + +ol.arabic { + list-style: decimal; } + +ol.loweralpha { + list-style: lower-alpha; } + +ol.upperalpha { + list-style: upper-alpha; } + +ol.lowerroman { + list-style: lower-roman; } + +ol.upperroman { + list-style: upper-roman; } + p.attribution { text-align: right; margin-left: 50%; } @@ -604,6 +949,15 @@ p.rubric { color: maroon; text-align: center; } +p.sidebar-title { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-weight: bold; + font-size: larger; } + +p.sidebar-subtitle { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-weight: bold; } + p.topic-title { font-weight: bold; } @@ -643,14 +997,22 @@ pre.code .inserted, code .inserted { background-color: #A3D289; } span.classifier { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-style: oblique; } span.classifier-delimiter { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: bold; } +span.interpreted { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } + span.option { white-space: nowrap; } +span.pre { + white-space: pre; } + span.problematic { color: #b30000; } @@ -658,6 +1020,44 @@ span.section-subtitle { /* font-size relative to parent (h1..h6 element) */ font-size: 80%; } +table.citation { + border-left: solid 1px #666666; + margin-left: 1px; } + +table.docinfo { + margin: 0em; + margin-top: 2em; + margin-bottom: 2em; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; + color: #444444; } + +table.docutils { + margin-top: 0.5em; + margin-bottom: 0.5em; } + +table.footnote { + border-left: solid 1px #2d2d2d; + margin-left: 1px; } + +table.docutils td, table.docutils th, +table.docinfo td, table.docinfo th { + padding-left: 0.5em; + padding-right: 0.5em; + vertical-align: top; } + +table.docutils th.field-name, table.docinfo th.docinfo-name { + font-weight: 700; + text-align: left; + white-space: nowrap; + padding-left: 0; } + +h1 tt.docutils, h2 tt.docutils, h3 tt.docutils, +h4 tt.docutils, h5 tt.docutils, h6 tt.docutils { + font-size: 100%; } + +ul.auto-toc { + list-style-type: none; } + span.DecNumber { color: #252dbe; } @@ -674,7 +1074,7 @@ span.FloatNumber { color: #252dbe; } span.Identifier { - color: #222; } + color: #3b3b3b; } span.Keyword { font-weight: 600; @@ -739,23 +1139,38 @@ dt pre > span.Identifier, dt pre > span.Operator { color: #155da4; font-weight: 700; } -dt pre > span.Keyword ~ span.Identifier, dt pre > span.Identifier ~ span.Identifier, -dt pre > span.Operator ~ span.Identifier, dt pre > span.Other ~ span.Identifier { +dt pre > span.Identifier ~ span.Identifier, dt pre > span.Operator ~ span.Identifier { + color: inherit; + font-weight: inherit; } + +dt pre > span.Operator ~ span.Identifier { color: inherit; font-weight: inherit; } /* Nim sprite for the footer (taken from main page favicon) */ .nim-sprite { display: inline-block; - height: 16px; - width: 16px; + height: 12px; + width: 12px; background-position: 0 0; - background-size: 16px 16px; + background-size: 12px 12px; -webkit-filter: opacity(50%); background-repeat: no-repeat; background-image: url("data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="); margin-bottom: -5px; } +div.search_results { + background-color: antiquewhite; + margin: 3em; + padding: 1em; + border: 1px solid #4d4d4d; +} + +div#global-links ul { + margin-left: 0; + list-style-type: none; +} + span.pragmadots { /* Position: relative frees us up to make the dots look really nice without fucking up the layout and @@ -763,14 +1178,18 @@ span.pragmadots { position: relative; /* 1px down looks slightly nicer */ top: 1px; + padding: 2px; - background-color: #e8e8e8; + background-color: #D3D3D3; border-radius: 4px; margin: 0 2px; cursor: pointer; - font-size: 0.8em; -} + /* For some reason on Chrome, making the font size + smaller than 1em is causing the parent container to + bulge slightly. So, we're stuck with inheriting 1em, + which is sad, because 0.8em looks better... */ +} span.pragmadots:hover { background-color: #DBDBDB; } @@ -778,10 +1197,6 @@ span.pragmawrap { display: none; } -span.attachedType { - display: none; - visibility: hidden; -} @@ -823,6 +1238,12 @@ function main() {
    +
  • + Exports +
      + +
    +
  • Imports
    -

    This is the main nimterop import file to help with wrapping C/C++ source code.

    Check out template.nim as a starting point for wrapping a new library. The template can be copied and trimmed down and modified as required. templite.nim is a shorter version for more experienced users.

    All {.compileTime.} procs must be used in a compile time context, e.g. using:

    static:
       cAddStdDir()

    -
    + +

    Imports

    plugin, git, paths, types @@ -895,10 +1314,9 @@ function main() {

    Procs

    - -
    proc cSkipSymbol(skips: seq[string]) {...}{.compileTime, raises: [], tags: [].}
    + +
    proc cSkipSymbol(skips: seq[string]) {...}{.compileTime, raises: [], tags: [].}
    -

    Similar to cOverride(), this macro allows filtering out symbols not of interest from the generated output.

    cSkipSymbol() only affects calls to cImport() that follow it.

    @@ -908,25 +1326,22 @@ function main() {
    -
    proc cSearchPath(path: string): string {...}{.compileTime, raises: [], tags: [ReadDirEffect].}
    +
    proc cSearchPath(path: string): string {...}{.compileTime, raises: [], tags: [ReadDirEffect].}
    -

    Get full path to file or directory path in search path configured using cAddSearchDir() and cAddStdDir().

    This can be used to locate files or directories that can be passed onto cCompile(), cIncludeDir() and cImport().

    - -
    proc cDebug() {...}{.compileTime, raises: [], tags: [].}
    + +
    proc cDebug() {...}{.compileTime, raises: [], tags: [].}
    - Enable debug messages and display the generated Nim code
    - -
    proc cDisableCaching() {...}{.compileTime, raises: [], tags: [].}
    + +
    proc cDisableCaching() {...}{.compileTime, raises: [], tags: [].}
    -

    Disable caching of generated Nim code - useful during wrapper development

    If files included by header being processed by cImport() change and affect the generated content, they will be ignored and the cached value will continue to be used . Use cDisableCaching() to avoid this scenario during development.

    nim -f was broken prior to 0.19.4 but can also be used to flush the cached content.

    @@ -934,9 +1349,8 @@ Enable debug messages and display the generated Nim code
    -
    proc cAddSearchDir(dir: string) {...}{.compileTime, raises: [], tags: [].}
    +
    proc cAddSearchDir(dir: string) {...}{.compileTime, raises: [], tags: [].}
    - Add directory dir to the search path used in calls to cSearchPath().

    Examples:

    import
    @@ -948,9 +1362,8 @@ Add directory dir to
     
     
    -
    proc cAddStdDir(mode = "c") {...}{.compileTime, raises: [ValueError], tags: [ReadEnvEffect].}
    +
    proc cAddStdDir(mode = "c") {...}{.compileTime, raises: [], tags: [ReadEnvEffect].}
    - Add the standard c [default] or cpp include paths to search path used in calls to cSearchPath()

    Examples:

    static :
    @@ -966,10 +1379,9 @@ Add the standard c [d
     

    Macros

    - -
    macro cOverride(body): untyped
    + +
    macro cOverride(body): untyped
    -

    When the wrapper code generated by nimterop is missing certain symbols or not accurate, it may be required to hand wrap them. Define them in a cOverride() macro block so that Nimterop no longer defines these symbols.

    For example:

    int svGetCallerInfo(const char** fileName, int *lineNumber);

    This might map to:

    @@ -980,19 +1392,18 @@ Add the standard c [d
    - -
    macro cPlugin(body): untyped
    + +
    macro cPlugin(body): untyped
    - -When cOverride() and cSkipSymbol() are not adequate, the cPlugin() macro can be used to customize the generated Nim output. The following callbacks are available at this time.
    proc onSymbol(sym: var Symbol) {.exportc, dynlib.}

    onSymbol() can be used to handle symbol name modifications required due to invalid characters like leading/trailing _ or rename symbols that would clash due to Nim's style insensitivity. It can also be used to remove prefixes and suffixes like SDL_. The symbol name and type is provided to the callback and the name can be modified.

    -

    Returning a blank name will result in the symbol being skipped. This will fail for nskParam and nskField since the generated Nim code will be wrong.

    +When cOverride() and cSkipSymbol() are not adequate, the cPlugin() macro can be used to customize the generated Nim output. The following callbacks are available at this time.
    proc onSymbol(sym: var Symbol) {.exportc, dynlib.}

    onSymbol() can be used to handle symbol name modifications required due to invalid characters like leading/trailing _ or rename symbols that would clash due to Nim's style insensitivity. It can also be used to remove prefixes and suffixes like SDL_. The symbol name and type is provided to the callback and the name can be modified.

    +

    Returning a blank name will result in the symbol being skipped. This will fail for nskParam and nskField since the generated Nim code will be wrong.

    Symbol types can be any of the following:

    -
    • nskConst for constants
    • -
    • nskType for type identifiers, including primitive
    • -
    • nskParam for param names
    • -
    • nskField for struct field names
    • -
    • nskEnumField for enum (field) names, though they are in the global namespace as nskConst
    • -
    • nskProc - for proc names
    • +
      • nskConst for constants
      • +
      • nskType for type identifiers, including primitive
      • +
      • nskParam for param names
      • +
      • nskField for struct field names
      • +
      • nskEnumField for enum (field) names, though they are in the global namespace as nskConst
      • +
      • nskProc - for proc names

      nimterop/plugins is implicitly imported to provide access to standard plugin facilities.

      cPlugin() only affects calls to cImport() that follow it.

      @@ -1017,23 +1428,20 @@ When cOverride()<
    -
    macro cDefine(name: static string; val: static string = ""): untyped
    +
    macro cDefine(name: static string; val: static string = ""): untyped
    - #define an identifer that is forwarded to the C/C++ compiler using {.passC: "-DXXX".}
    - -
    macro cIncludeDir(dir: static string): untyped
    + +
    macro cIncludeDir(dir: static string): untyped
    - Add an include directory that is forwarded to the C/C++ compiler using {.passC: "-IXXX".}. This is also provided to the preprocessor during Nim code generation.
    -
    macro cCompile(path: static string; mode = "c"; exclude = ""): untyped
    +
    macro cCompile(path: static string; mode = "c"; exclude = ""): untyped
    -

    Compile and link C/C++ implementation into resulting binary using {.compile.}

    path can be a specific file or contain wildcards:

    cCompile("file.c")
    @@ -1044,10 +1452,9 @@ Add an include directory that is forwarded to the C/C++ compiler using 
     
    -
    macro cImport(filename: static string; recurse: static bool = false;
    +
    macro cImport(filename: static string; recurse: static bool = false;
                  dynlib: static string = ""): untyped
    -

    Import all supported definitions from specified header file. Generated content is cached in nimcache until filename changes unless cDisableCaching() is set. nim -f can also be used after Nim v0.19.4 to flush the cache.

    recurse can be used to generate Nim wrappers from #include files referenced in filename. This is only done for files in the same directory as filename or in a directory added using cIncludeDir()

    dynlib can be used to specify the Nim string to use to specify the dynamic library to load the imported symbols from. For example:

    @@ -1068,11 +1475,10 @@ Add an include directory that is forwarded to the C/C++ compiler using -
    macro c2nImport(filename: static string; recurse: static bool = false;
    +
    macro c2nImport(filename: static string; recurse: static bool = false;
                    dynlib: static string = ""; mode: static string = "c";
                    flags: static string = ""): untyped
    -

    Import all supported definitions from specified header file using c2nim

    Similar to cImport() but uses c2nim to generate the Nim wrapper instead of toast. Note that neither cOverride(), cSkipSymbol() nor cPlugin() have any impact on c2nim.

    toast is only used to preprocess the header file and recurse if specified.

    @@ -1083,11 +1489,6 @@ Add an include directory that is forwarded to the C/C++ compiler using -
    -
    @@ -1097,7 +1498,7 @@ Add an include directory that is forwarded to the C/C++ compiler using
    - Made with Nim. Generated: 2019-07-18 06:10:50 UTC + Made with Nim. Generated: 2019-07-29 14:17:11 UTC
    diff --git a/cimport.idx b/cimport.idx index b477ab8..9a0b8f5 100644 --- a/cimport.idx +++ b/cimport.idx @@ -1,12 +1,12 @@ -cOverride cimport.html#cOverride.m cimport: cOverride(body): untyped -cSkipSymbol cimport.html#cSkipSymbol,seq[T][string] cimport: cSkipSymbol(skips: seq[string]) -cPlugin cimport.html#cPlugin.m cimport: cPlugin(body): untyped +cOverride cimport.html#cOverride.m, cimport: cOverride(body): untyped +cSkipSymbol cimport.html#cSkipSymbol,seq[string] cimport: cSkipSymbol(skips: seq[string]) +cPlugin cimport.html#cPlugin.m, cimport: cPlugin(body): untyped cSearchPath cimport.html#cSearchPath,string cimport: cSearchPath(path: string): string -cDebug cimport.html#cDebug cimport: cDebug() -cDisableCaching cimport.html#cDisableCaching cimport: cDisableCaching() +cDebug cimport.html#cDebug, cimport: cDebug() +cDisableCaching cimport.html#cDisableCaching, cimport: cDisableCaching() cDefine cimport.html#cDefine.m,,string cimport: cDefine(name: static string; val: static string = ""): untyped cAddSearchDir cimport.html#cAddSearchDir,string cimport: cAddSearchDir(dir: string) -cIncludeDir cimport.html#cIncludeDir.m cimport: cIncludeDir(dir: static string): untyped +cIncludeDir cimport.html#cIncludeDir.m, cimport: cIncludeDir(dir: static string): untyped cAddStdDir cimport.html#cAddStdDir,string cimport: cAddStdDir(mode = "c") cCompile cimport.html#cCompile.m,,string,string cimport: cCompile(path: static string; mode = "c"; exclude = ""): untyped cImport cimport.html#cImport.m,,string cimport: cImport(filename: static string; recurse: static bool = false;\n dynlib: static string = ""): untyped diff --git a/compat.html b/compat.html index 28bd722..995d828 100644 --- a/compat.html +++ b/compat.html @@ -27,130 +27,232 @@ customize this style sheet. Modified from Chad Skeeters' rst2html-style https://bitbucket.org/cskeeters/rst2html-style/ -Modified by Boyd Greenfield and narimiran +Modified by Boyd Greenfield */ - +/* SCSS variables */ +/* Text weights */ +/* Body colors */ +/* Text colors */ +/* Link colors */ +/* Syntax highlighting colors */ +/* Pct changes */ +/* Mixins */ +/* Body/layout */ html { font-size: 100%; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; } +/* Where we want fancier font if available */ +h1, h2, h3, h4, h5, h6, p.module-desc, table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; } + +h1.title { + font-weight: 900; } + body { font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: 400; - font-size: 1.125em; - line-height: 1.5; - color: #222; - background-color: #FCFCFC; } + font-size: 16px; + line-height: 20px; + color: #444; + letter-spacing: 0.15px; + background-color: #FDFBFA; } /* Skeleton grid */ .container { position: relative; width: 100%; - max-width: 1050px; + max-width: 960px; margin: 0 auto; - padding: 0; + padding: 0 20px; box-sizing: border-box; } .column, .columns { width: 100%; float: left; - box-sizing: border-box; - margin-left: 1%; -} + box-sizing: border-box; } -.column:first-child, -.columns:first-child { - margin-left: 0; } +/* For devices larger than 400px */ +@media (min-width: 400px) { + .container { + width: 100%; + padding: 0; } } +/* For devices larger than 650px */ +@media (min-width: 650px) { + .container { + width: 100%; } -.three.columns { - width: 19%; } + .column, + .columns { + margin-left: 4%; } -.nine.columns { - width: 80.0%; } + .column:first-child, + .columns:first-child { + margin-left: 0; } -.twelve.columns { - width: 100%; - margin-left: 0; } + .one.column, + .one.columns { + width: 4.66666666667%; } + + .two.columns { + width: 13.3333333333%; } -@media screen and (max-width: 860px) { .three.columns { - display: none; - } + width: 22%; } + + .four.columns { + width: 30.6666666667%; } + + .five.columns { + width: 39.3333333333%; } + + .six.columns { + width: 48%; } + + .seven.columns { + width: 56.6666666667%; } + + .eight.columns { + width: 65.3333333333%; } + .nine.columns { - width: 98.0%; - } - body { - font-size: 1em; - line-height: 1.35; - } -} + width: 74.0%; } + + .ten.columns { + width: 82.6666666667%; } + + .eleven.columns { + width: 91.3333333333%; } + + .twelve.columns { + width: 100%; + margin-left: 0; } + + .one-third.column { + width: 30.6666666667%; } + + .two-thirds.column { + width: 65.3333333333%; } } +/* Customer Overrides */ +.footer { + text-align: center; + color: #969696; + padding-top: 10%; } + +p.module-desc { + font-size: 1.1em; + color: #666666; } + +a.link-seesrc { + color: #aec7d2; + font-style: italic; } + +a.link-seesrc:hover { + color: #6c9aae; } + +#toc-list { + word-wrap: break-word; } + +ul.simple-toc { + list-style: none; } + +ul.simple-toc a.reference-toplevel { + font-weight: bold; + color: #0077b3; } + +ul.simple-toc-section { + list-style-type: circle; + color: #6c9aae; } + +ul.simple-toc-section a.reference { + color: #0077b3; } cite { font-style: italic !important; } +dt > pre { + border-color: rgba(0, 0, 0, 0.1); + background-color: rgba(255, 255, 255, 0.3); + margin: 15px 0px 5px; } + +dd > pre { + border-color: rgba(0, 0, 0, 0.1); + background-color: whitesmoke; + margin-top: 8px; } + +.item > dd { + margin-left: 10px; + margin-bottom: 30px; } + +/* Nim line-numbered tables */ +.line-nums-table { + width: 100%; + table-layout: fixed; } /* Nim search input */ div#searchInputDiv { - margin-bottom: 1em; + margin-bottom: 8px; } -input#searchInput { - width: 80%; +div#searchInputDiv input#searchInput { + width: 10em; +} +div.search-groupby { + margin-bottom: 8px; } -/* - * Some custom formatting for input forms. - * This also fixes input form colors on Firefox with a dark system theme on Linux. - */ -input { - -moz-appearance: none; - color: #333; - background-color: #f8f8f8; - border: 1px solid #aaa; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-size: 0.9em; - padding: 6px; -} -input:focus { - border: 1px solid #1fa0eb; - box-shadow: 0 0 2px #1fa0eb; -} +table.line-nums-table { + border-radius: 4px; + border: 1px solid #cccccc; + background-color: whitesmoke; + border-collapse: separate; + margin-top: 15px; + margin-bottom: 25px; } + +.line-nums-table tbody { + border: none; } + +.line-nums-table td pre { + border: none; + background-color: transparent; } + +.line-nums-table td.blob-line-nums { + width: 28px; } + +.line-nums-table td.blob-line-nums pre { + color: #b0b0b0; + -webkit-filter: opacity(75%); + text-align: right; + border-color: transparent; + background-color: transparent; + padding-left: 0px; + margin-left: 0px; + padding-right: 0px; + margin-right: 0px; } /* Docgen styles */ /* Links */ a { - color: #07b; - text-decoration: none; -} - -a span.Identifier { - text-decoration: underline; - text-decoration-color: #aab; -} - -a.reference-toplevel { - font-weight: bold; -} - -a.toc-backref { - text-decoration: none; - color: #222; } - -a.link-seesrc { - color: #607c9f; - font-size: 0.9em; - font-style: italic; } + color: #0077b3; + text-decoration: none; } a:hover, a:focus { - color: #607c9f; + color: #00334d; text-decoration: underline; } -a:hover span.Identifier { - color: #607c9f; -} +a:visited { + color: #00334d; } +a:focus { + outline: thin dotted #2d2d2d; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; } + +a:hover, +a:active { + outline: 0; } sub, sup { @@ -227,258 +329,379 @@ img { h2, h3 { - page-break-after: avoid; } -} + page-break-after: avoid; } } +.img-rounded { + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; } +.img-polaroid { + padding: 4px; + background-color: rgba(252, 248, 244, 0.75); + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.2); + -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); } p { - margin-top: 0.5em; - margin-bottom: 0.5em; -} + margin: 0 0 8px; } small { font-size: 85%; } strong { - font-weight: 600; - font-size: 0.95em; - color: #3c3c3c; -} + font-weight: 600; } em { font-style: italic; } +cite { + font-style: normal; } + +h1, +h2, +h3, +h4, +h5, +h6 { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-weight: 600; + line-height: 20px; + color: inherit; + text-rendering: optimizelegibility; } + h1 { - font-size: 1.8em; + font-size: 2em; font-weight: 400; - padding-bottom: .25em; - border-bottom: 1px solid #aaa; - margin-top: 2.5em; - margin-bottom: 1em; + padding-bottom: .15em; + border-bottom: 1px solid #aaaaaa; + margin-top: 1.0em; line-height: 1.2em; } h1.title { padding-bottom: 1em; border-bottom: 0px; - font-size: 2.5em; - text-align: center; - font-weight: 900; - margin-top: 0.75em; - margin-bottom: 0em; -} + font-size: 2.75em; } h2 { - font-size: 1.3em; - margin-top: 2em; } - -h2.subtitle { - text-align: center; } - -h3 { - font-size: 1.125em; - font-style: italic; + font-size: 1.5em; margin-top: 1.5em; } +h3 { + font-size: 1.3em; + font-style: italic; + margin-top: 0.75em; } + h4 { - font-size: 1.125em; - margin-top: 1em; } + font-size: 1.3em; + margin-top: 0.5em; } h5 { - font-size: 1.125em; - margin-top: 0.75em; } + font-size: 1.2em; + margin-top: 0.25em; } h6 { font-size: 1.1em; } - ul, ol { padding: 0; - margin-top: 0.5em; - margin-left: 0.75em; } + margin: 0 0 0px 15px; } ul ul, ul ol, ol ol, ol ul { - margin-bottom: 0; - margin-left: 1.25em; } + margin-bottom: 0; } li { - list-style-type: circle; -} - -ul.simple-boot li { - list-style-type: none; - margin-left: 0em; - margin-bottom: 0.5em; -} - -ol.simple > li, ul.simple > li { - margin-bottom: 0.25em; - margin-left: 0.4em } - -ul.simple.simple-toc > li { - margin-top: 1em; -} - -ul.simple-toc { - list-style: none; - font-size: 0.9em; - margin-left: -0.3em; - margin-top: 1em; } - -ul.simple-toc > li { - list-style-type: none; -} - -ul.simple-toc-section { - list-style-type: circle; - margin-left: 1em; - color: #6c9aae; } - - -ol.arabic { - list-style: decimal; } - -ol.loweralpha { - list-style: lower-alpha; } - -ol.upperalpha { - list-style: upper-alpha; } - -ol.lowerroman { - list-style: lower-roman; } - -ol.upperroman { - list-style: upper-roman; } - -ul.auto-toc { - list-style-type: none; } - + line-height: 20px; } dl { - margin-bottom: 1.5em; } + margin-bottom: 20px; } + +dt, +dd { + line-height: 20px; } dt { - margin-bottom: -0.5em; - margin-left: 0.0em; } + font-weight: bold; } dd { - margin-left: 2.0em; - margin-bottom: 3.0em; - margin-top: 0.5em; } - + margin-left: 10px; + margin-bottom: 26px; } hr { - margin: 2em 0; + margin: 20px 0; border: 0; - border-top: 1px solid #aaa; } + border-top: 1px solid #eeeeee; + border-bottom: 1px solid #ffffff; } + +abbr[title], +abbr[data-original-title] { + cursor: help; + border-bottom: 1px dotted #999999; } + +abbr.initialism { + font-size: 90%; + text-transform: uppercase; } blockquote { - font-size: 0.9em; - font-style: italic; - padding-left: 0.5em; - margin-left: 0; - border-left: 5px solid #bbc; + padding: 0 0 0 15px; + margin: 0 0 20px; + border-left: 5px solid #EFEBE0; } + +table.docinfo + blockquote, table.docinfo blockquote, h1 + blockquote { + border-left: 5px solid #c9c9c9; } +table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { + margin-bottom: 0; + font-size: 15px; + font-weight: 200; + line-height: 1.5; + font-style: italic; } + +q:before, +q:after, +blockquote:before, +blockquote:after { + content: ""; } + +address { + display: block; + margin-bottom: 20px; + font-style: normal; + line-height: 20px; } + +code, +pre { + font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; + padding: 0 3px 2px; + font-weight: 500; + font-size: 12px; + color: #444444; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; } + .pre { font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - font-weight: 500; - font-size: 0.85em; - background-color: #f0f3ff; - padding-left: 3px; - padding-right: 3px; - border-radius: 4px; + font-weight: 600; + /*color: #504da6;*/ } +code { + padding: 2px 4px; + color: #444444; + white-space: nowrap; + background-color: white; + border: 1px solid #777777; } + pre { - font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - color: #222; - font-weight: 500; display: inline-block; box-sizing: border-box; - min-width: 100%; - padding: 0.5em; - margin-top: 0.5em; - margin-bottom: 0.5em; - font-size: 0.85em; + min-width: calc(100% - 19.5px); + padding: 9.5px; + margin: 0.25em 10px 10px 10px; + font-size: 15px; + line-height: 20px; white-space: pre !important; overflow-y: hidden; overflow-x: visible; - background-color: ghostwhite; - border: 1px solid #dde; - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; } + background-color: rgba(0, 0, 0, 0.01); + border: 1px solid #cccccc; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; } + +pre.prettyprint { + margin-bottom: 20px; } + +pre code { + padding: 0; + color: inherit; + white-space: pre; + overflow-x: visible; + background-color: transparent; + border: 0; } .pre-scrollable { max-height: 340px; overflow-y: scroll; } - -/* Nim line-numbered tables */ -.line-nums-table { - width: 100%; - table-layout: fixed; } - -table.line-nums-table { - border-radius: 4px; - border: 1px solid #cccccc; - background-color: ghostwhite; - border-collapse: separate; - margin-top: 15px; - margin-bottom: 25px; } - -.line-nums-table tbody { - border: none; } - -.line-nums-table td pre { - border: none; - background-color: transparent; } - -.line-nums-table td.blob-line-nums { - width: 28px; } - -.line-nums-table td.blob-line-nums pre { - color: #b0b0b0; - -webkit-filter: opacity(75%); - text-align: right; - border-color: transparent; - background-color: transparent; - padding-left: 0px; - margin-left: 0px; - padding-right: 0px; - margin-right: 0px; } - - table { max-width: 100%; background-color: transparent; - margin-top: 0.5em; - margin-bottom: 1.5em; border-collapse: collapse; - border-color: #ccc; - border-spacing: 0; - font-size: 0.9em; -} + border-spacing: 0; } table th, table td { - padding: 0px 0.5em 0px; + padding: 0px 8px 0px; } -table th { - background-color: #e8e8e8; +.table { + width: 100%; + margin-bottom: 20px; } + +.table th, +.table td { + padding: 8px; + line-height: 20px; + text-align: left; + vertical-align: top; + border-top: 1px solid #444444; } + +.table th { font-weight: bold; } -table th.docinfo-name { - background-color: transparent; -} +.table thead th { + vertical-align: bottom; } -table tr:hover { - background-color: ghostwhite; } +.table caption + thead tr:first-child th, +.table caption + thead tr:first-child td, +.table colgroup + thead tr:first-child th, +.table colgroup + thead tr:first-child td, +.table thead:first-child tr:first-child th, +.table thead:first-child tr:first-child td { + border-top: 0; } +.table tbody + tbody { + border-top: 2px solid #444444; } + +.table .table { + background-color: rgba(252, 248, 244, 0.75); } + +.table-condensed th, +.table-condensed td { + padding: 4px 5px; } + +.table-bordered { + border: 1px solid #444444; + border-collapse: separate; + *border-collapse: collapse; + border-left: 0; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; } + +.table-bordered th, +.table-bordered td { + border-left: 1px solid #444444; } + +.table-bordered caption + thead tr:first-child th, +.table-bordered caption + tbody tr:first-child th, +.table-bordered caption + tbody tr:first-child td, +.table-bordered colgroup + thead tr:first-child th, +.table-bordered colgroup + tbody tr:first-child th, +.table-bordered colgroup + tbody tr:first-child td, +.table-bordered thead:first-child tr:first-child th, +.table-bordered tbody:first-child tr:first-child th, +.table-bordered tbody:first-child tr:first-child td { + border-top: 0; } + +.table-bordered thead:first-child tr:first-child > th:first-child, +.table-bordered tbody:first-child tr:first-child > td:first-child, +.table-bordered tbody:first-child tr:first-child > th:first-child { + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; } + +.table-bordered thead:first-child tr:first-child > th:last-child, +.table-bordered tbody:first-child tr:first-child > td:last-child, +.table-bordered tbody:first-child tr:first-child > th:last-child { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; } + +.table-bordered thead:last-child tr:last-child > th:first-child, +.table-bordered tbody:last-child tr:last-child > td:first-child, +.table-bordered tbody:last-child tr:last-child > th:first-child, +.table-bordered tfoot:last-child tr:last-child > td:first-child, +.table-bordered tfoot:last-child tr:last-child > th:first-child { + -webkit-border-bottom-left-radius: 4px; + border-bottom-left-radius: 4px; + -moz-border-radius-bottomleft: 4px; } + +.table-bordered thead:last-child tr:last-child > th:last-child, +.table-bordered tbody:last-child tr:last-child > td:last-child, +.table-bordered tbody:last-child tr:last-child > th:last-child, +.table-bordered tfoot:last-child tr:last-child > td:last-child, +.table-bordered tfoot:last-child tr:last-child > th:last-child { + -webkit-border-bottom-right-radius: 4px; + border-bottom-right-radius: 4px; + -moz-border-radius-bottomright: 4px; } + +.table-bordered tfoot + tbody:last-child tr:last-child td:first-child { + -webkit-border-bottom-left-radius: 0; + border-bottom-left-radius: 0; + -moz-border-radius-bottomleft: 0; } + +.table-bordered tfoot + tbody:last-child tr:last-child td:last-child { + -webkit-border-bottom-right-radius: 0; + border-bottom-right-radius: 0; + -moz-border-radius-bottomright: 0; } + +.table-bordered caption + thead tr:first-child th:first-child, +.table-bordered caption + tbody tr:first-child td:first-child, +.table-bordered colgroup + thead tr:first-child th:first-child, +.table-bordered colgroup + tbody tr:first-child td:first-child { + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; } + +.table-bordered caption + thead tr:first-child th:last-child, +.table-bordered caption + tbody tr:first-child td:last-child, +.table-bordered colgroup + thead tr:first-child th:last-child, +.table-bordered colgroup + tbody tr:first-child td:last-child { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; } + +table.docutils th { + background-color: #e8e8e8; } + +table.docutils tr:hover { + background-color: whitesmoke; } + +.table-striped tbody > tr:nth-child(odd) > td, +.table-striped tbody > tr:nth-child(odd) > th { + background-color: rgba(252, 248, 244, 0.75); } + +.table-hover tbody tr:hover > td, +.table-hover tbody tr:hover > th { + background-color: rgba(241, 222, 204, 0.75); } + +table td[class*="span"], +table th[class*="span"], +.row-fluid table td[class*="span"], +.row-fluid table th[class*="span"] { + display: table-cell; + float: none; + margin-left: 0; } + +.hero-unit { + padding: 60px; + margin-bottom: 30px; + font-size: 18px; + font-weight: 200; + line-height: 30px; + color: inherit; + background-color: rgba(230, 197, 164, 0.75); + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; } + +.hero-unit h1 { + margin-bottom: 0; + font-size: 60px; + line-height: 1; + letter-spacing: -1px; + color: inherit; } + +.hero-unit li { + line-height: 30px; } /* rst2html default used to remove borders from tables and images */ .borderless, table.borderless td, table.borderless th { @@ -499,6 +722,10 @@ table.borderless td, table.borderless th { .hidden { display: none; } +a.toc-backref { + text-decoration: none; + color: #444444; } + blockquote.epigraph { margin: 2em 5em; } @@ -508,6 +735,85 @@ dl.docutils dd { object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] { overflow: hidden; } +/* Uncomment (and remove this text!) to get bold-faced definition list terms +dl.docutils dt { + font-weight: bold } +*/ +div.abstract { + margin: 2em 5em; } + +div.abstract p.topic-title { + font-weight: bold; + text-align: center; } + +div.admonition, div.attention, div.caution, div.danger, div.error, +div.hint, div.important, div.note, div.tip, div.warning { + margin: 2em; + border: medium outset; + padding: 1em; } + +div.note, div.warning { + margin: 1.5em 0px; + border: none; } + +div.note p.admonition-title, +div.warning p.admonition-title { + display: none; } + +/* Clearfix + * http://css-tricks.com/snippets/css/clear-fix/ + */ +div.note:after, +div.warning:after { + content: ""; + display: table; + clear: both; } + +div.note p:before, +div.warning p:before { + display: block; + float: left; + font-size: 4em; + line-height: 1em; + margin-right: 20px; + margin-left: 0em; + margin-top: -10px; + content: '\0270D'; + /*handwriting*/ } + +div.warning p:before { + content: '\026A0'; + /*warning*/ } + +div.admonition p.admonition-title, div.hint p.admonition-title, +div.important p.admonition-title, div.note p.admonition-title, +div.tip p.admonition-title { + font-weight: bold; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } + +div.attention p.admonition-title, div.caution p.admonition-title, +div.danger p.admonition-title, div.error p.admonition-title, +div.warning p.admonition-title, .code .error { + color: #b30000; + font-weight: bold; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } + +/* Uncomment (and remove this text!) to get reduced vertical space in + compound paragraphs. +div.compound .compound-first, div.compound .compound-middle { + margin-bottom: 0.5em } + +div.compound .compound-last, div.compound .compound-middle { + margin-top: 0.5em } +*/ +div.dedication { + margin: 2em 5em; + text-align: center; + font-style: italic; } + +div.dedication p.topic-title { + font-weight: bold; + font-style: normal; } div.figure { margin-left: 2em; @@ -515,14 +821,8 @@ div.figure { div.footer, div.header { clear: both; - text-align: center; - color: #666; font-size: smaller; } -div.footer { - padding-top: 5em; -} - div.line-block { display: block; margin-top: 1em; @@ -533,24 +833,45 @@ div.line-block div.line-block { margin-bottom: 0; margin-left: 1.5em; } +div.sidebar { + margin: 0 0 0.5em 1em; + border: medium outset; + padding: 1em; + background-color: rgba(252, 248, 244, 0.75); + width: 40%; + float: right; + clear: right; } + +div.sidebar p.rubric { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-size: medium; } + +div.system-messages { + margin: 5em; } + +div.system-messages h1 { + color: #b30000; } + +div.system-message { + border: medium outset; + padding: 1em; } + +div.system-message p.system-message-title { + color: #b30000; + font-weight: bold; } + div.topic { margin: 2em; } -div.search_results { - background-color: antiquewhite; - margin: 3em; - padding: 1em; - border: 1px solid #4d4d4d; -} +h1.section-subtitle, h2.section-subtitle, h3.section-subtitle, +h4.section-subtitle, h5.section-subtitle, h6.section-subtitle { + margin-top: 0.4em; } -div#global-links ul { - margin-left: 0; - list-style-type: none; -} +h1.title { + text-align: center; } -div#global-links > simple-boot { - margin-left: 3em; -} +h2.subtitle { + text-align: center; } hr.docutils { width: 75%; } @@ -584,6 +905,30 @@ img.align-center, .figure.align-center, object.align-center { div.align-right { text-align: inherit; } +/* div.align-center * { */ +/* text-align: left } */ + +ul.simple > li { + margin-bottom: 0.5em } + +ol.simple, ul.simple { + margin-bottom: 1em; } + +ol.arabic { + list-style: decimal; } + +ol.loweralpha { + list-style: lower-alpha; } + +ol.upperalpha { + list-style: upper-alpha; } + +ol.lowerroman { + list-style: lower-roman; } + +ol.upperroman { + list-style: upper-roman; } + p.attribution { text-align: right; margin-left: 50%; } @@ -604,6 +949,15 @@ p.rubric { color: maroon; text-align: center; } +p.sidebar-title { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-weight: bold; + font-size: larger; } + +p.sidebar-subtitle { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-weight: bold; } + p.topic-title { font-weight: bold; } @@ -643,14 +997,22 @@ pre.code .inserted, code .inserted { background-color: #A3D289; } span.classifier { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-style: oblique; } span.classifier-delimiter { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: bold; } +span.interpreted { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } + span.option { white-space: nowrap; } +span.pre { + white-space: pre; } + span.problematic { color: #b30000; } @@ -658,6 +1020,44 @@ span.section-subtitle { /* font-size relative to parent (h1..h6 element) */ font-size: 80%; } +table.citation { + border-left: solid 1px #666666; + margin-left: 1px; } + +table.docinfo { + margin: 0em; + margin-top: 2em; + margin-bottom: 2em; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; + color: #444444; } + +table.docutils { + margin-top: 0.5em; + margin-bottom: 0.5em; } + +table.footnote { + border-left: solid 1px #2d2d2d; + margin-left: 1px; } + +table.docutils td, table.docutils th, +table.docinfo td, table.docinfo th { + padding-left: 0.5em; + padding-right: 0.5em; + vertical-align: top; } + +table.docutils th.field-name, table.docinfo th.docinfo-name { + font-weight: 700; + text-align: left; + white-space: nowrap; + padding-left: 0; } + +h1 tt.docutils, h2 tt.docutils, h3 tt.docutils, +h4 tt.docutils, h5 tt.docutils, h6 tt.docutils { + font-size: 100%; } + +ul.auto-toc { + list-style-type: none; } + span.DecNumber { color: #252dbe; } @@ -674,7 +1074,7 @@ span.FloatNumber { color: #252dbe; } span.Identifier { - color: #222; } + color: #3b3b3b; } span.Keyword { font-weight: 600; @@ -739,23 +1139,38 @@ dt pre > span.Identifier, dt pre > span.Operator { color: #155da4; font-weight: 700; } -dt pre > span.Keyword ~ span.Identifier, dt pre > span.Identifier ~ span.Identifier, -dt pre > span.Operator ~ span.Identifier, dt pre > span.Other ~ span.Identifier { +dt pre > span.Identifier ~ span.Identifier, dt pre > span.Operator ~ span.Identifier { + color: inherit; + font-weight: inherit; } + +dt pre > span.Operator ~ span.Identifier { color: inherit; font-weight: inherit; } /* Nim sprite for the footer (taken from main page favicon) */ .nim-sprite { display: inline-block; - height: 16px; - width: 16px; + height: 12px; + width: 12px; background-position: 0 0; - background-size: 16px 16px; + background-size: 12px 12px; -webkit-filter: opacity(50%); background-repeat: no-repeat; background-image: url("data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="); margin-bottom: -5px; } +div.search_results { + background-color: antiquewhite; + margin: 3em; + padding: 1em; + border: 1px solid #4d4d4d; +} + +div#global-links ul { + margin-left: 0; + list-style-type: none; +} + span.pragmadots { /* Position: relative frees us up to make the dots look really nice without fucking up the layout and @@ -763,14 +1178,18 @@ span.pragmadots { position: relative; /* 1px down looks slightly nicer */ top: 1px; + padding: 2px; - background-color: #e8e8e8; + background-color: #D3D3D3; border-radius: 4px; margin: 0 2px; cursor: pointer; - font-size: 0.8em; -} + /* For some reason on Chrome, making the font size + smaller than 1em is causing the parent container to + bulge slightly. So, we're stuck with inheriting 1em, + which is sad, because 0.8em looks better... */ +} span.pragmadots:hover { background-color: #DBDBDB; } @@ -778,10 +1197,6 @@ span.pragmawrap { display: none; } -span.attachedType { - display: none; - visibility: hidden; -} @@ -822,13 +1237,43 @@ function main() { - + +
    -

    - +
    +

    Procs

    +
    + +
    proc relativePath(file, base: string): string {...}{.raises: [], tags: [].}
    +
    +naive version of os.relativePath ; remove after nim >= 0.19.9 +

    Examples:

    +
    import
    +  ospaths, unittest
    +
    +check:
    +  "/foo/bar/baz/log.txt".unixToNativePath.relativePath(
    +      "/foo/bar".unixToNativePath) == "baz/log.txt".unixToNativePath
    +  "foo/bar/baz/log.txt".unixToNativePath.relativePath("foo/bar".unixToNativePath) ==
    +      "baz/log.txt".unixToNativePath
    + +
    + +
    +
    @@ -836,7 +1281,7 @@ function main() { diff --git a/dochack.js b/dochack.js deleted file mode 100644 index cfd9e26..0000000 --- a/dochack.js +++ /dev/null @@ -1,1983 +0,0 @@ -/* Generated by the Nim Compiler v0.20.99 */ -/* (c) 2019 Andreas Rumpf */ - -var framePtr = null; -var excHandler = 0; -var lastJSError = null; -if (typeof Int8Array === 'undefined') Int8Array = Array; -if (typeof Int16Array === 'undefined') Int16Array = Array; -if (typeof Int32Array === 'undefined') Int32Array = Array; -if (typeof Uint8Array === 'undefined') Uint8Array = Array; -if (typeof Uint16Array === 'undefined') Uint16Array = Array; -if (typeof Uint32Array === 'undefined') Uint32Array = Array; -if (typeof Float32Array === 'undefined') Float32Array = Array; -if (typeof Float64Array === 'undefined') Float64Array = Array; -var NTI44032 = {size: 0,kind: 1,base: null,node: null,finalizer: null}; -var NTI205074 = {size: 0, kind: 18, base: null, node: null, finalizer: null}; -var NTI47862 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI207579 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; -var NTI85448 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI85444 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI85440 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI85436 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI85432 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI85428 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI85424 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI85420 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI85416 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI85412 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI85408 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI85404 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI85400 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI85396 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI85392 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI85388 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI85384 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI85380 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI85376 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI85372 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI85205 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI85283 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI85281 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; -var NTI85227 = {size: 0, kind: 14, base: null, node: null, finalizer: null}; -var NTI85565 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; -var NTI85563 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; -var NTI85561 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; -var NTI85231 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI85229 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; -var NTI87305 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; -var NTI47850 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI47858 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI44006 = {size: 0,kind: 31,base: null,node: null,finalizer: null}; -var NTI64156 = {size: 0, kind: 18, base: null, node: null, finalizer: null}; -var NTI47808 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI47914 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; -var NTI44016 = {size: 0,kind: 40,base: null,node: null,finalizer: null}; -var NTI44040 = {size: 0,kind: 28,base: null,node: null,finalizer: null}; -var NTI44042 = {size: 0,kind: 29,base: null,node: null,finalizer: null}; -var NTI47908 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; -var NTI47826 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI47828 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI47842 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI47846 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NNI47846 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; -NTI47846.node = NNI47846; -var NNI47842 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; -NTI47842.node = NNI47842; -var NNI47828 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; -NTI47828.node = NNI47828; -NTI47908.base = NTI47826; -NTI47914.base = NTI47826; -var NNI47826 = {kind: 2, len: 6, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "parent", len: 0, typ: NTI47908, name: "parent", sons: null}, -{kind: 1, offset: "name", len: 0, typ: NTI44042, name: "name", sons: null}, -{kind: 1, offset: "message", len: 0, typ: NTI44040, name: "msg", sons: null}, -{kind: 1, offset: "trace", len: 0, typ: NTI44040, name: "trace", sons: null}, -{kind: 1, offset: "raiseId", len: 0, typ: NTI44016, name: "raiseId", sons: null}, -{kind: 1, offset: "up", len: 0, typ: NTI47914, name: "up", sons: null}]}; -NTI47826.node = NNI47826; -var NNI47808 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; -NTI47808.node = NNI47808; -NTI47826.base = NTI47808; -NTI47828.base = NTI47826; -NTI47842.base = NTI47828; -NTI47846.base = NTI47842; -var NNI64156 = {kind: 2, len: 2, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "Field0", len: 0, typ: NTI44042, name: "Field0", sons: null}, -{kind: 1, offset: "Field1", len: 0, typ: NTI44006, name: "Field1", sons: null}]}; -NTI64156.node = NNI64156; -var NNI47858 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; -NTI47858.node = NNI47858; -NTI47858.base = NTI47828; -var NNI47850 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; -NTI47850.node = NNI47850; -NTI47850.base = NTI47828; -NTI85561.base = NTI85229; -NTI85563.base = NTI85229; -NTI85565.base = NTI85229; -var NNI85227 = {kind: 2, offset: 0, typ: null, name: null, len: 12, sons: {"1": {kind: 1, offset: 1, typ: NTI85227, name: "ElementNode", len: 0, sons: null}, -"2": {kind: 1, offset: 2, typ: NTI85227, name: "AttributeNode", len: 0, sons: null}, -"3": {kind: 1, offset: 3, typ: NTI85227, name: "TextNode", len: 0, sons: null}, -"4": {kind: 1, offset: 4, typ: NTI85227, name: "CDATANode", len: 0, sons: null}, -"5": {kind: 1, offset: 5, typ: NTI85227, name: "EntityRefNode", len: 0, sons: null}, -"6": {kind: 1, offset: 6, typ: NTI85227, name: "EntityNode", len: 0, sons: null}, -"7": {kind: 1, offset: 7, typ: NTI85227, name: "ProcessingInstructionNode", len: 0, sons: null}, -"8": {kind: 1, offset: 8, typ: NTI85227, name: "CommentNode", len: 0, sons: null}, -"9": {kind: 1, offset: 9, typ: NTI85227, name: "DocumentNode", len: 0, sons: null}, -"10": {kind: 1, offset: 10, typ: NTI85227, name: "DocumentTypeNode", len: 0, sons: null}, -"11": {kind: 1, offset: 11, typ: NTI85227, name: "DocumentFragmentNode", len: 0, sons: null}, -"12": {kind: 1, offset: 12, typ: NTI85227, name: "NotationNode", len: 0, sons: null}}}; -NTI85227.node = NNI85227; -var NNI85283 = {kind: 2, len: 91, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "background", len: 0, typ: NTI44042, name: "background", sons: null}, -{kind: 1, offset: "backgroundAttachment", len: 0, typ: NTI44042, name: "backgroundAttachment", sons: null}, -{kind: 1, offset: "backgroundColor", len: 0, typ: NTI44042, name: "backgroundColor", sons: null}, -{kind: 1, offset: "backgroundImage", len: 0, typ: NTI44042, name: "backgroundImage", sons: null}, -{kind: 1, offset: "backgroundPosition", len: 0, typ: NTI44042, name: "backgroundPosition", sons: null}, -{kind: 1, offset: "backgroundRepeat", len: 0, typ: NTI44042, name: "backgroundRepeat", sons: null}, -{kind: 1, offset: "border", len: 0, typ: NTI44042, name: "border", sons: null}, -{kind: 1, offset: "borderBottom", len: 0, typ: NTI44042, name: "borderBottom", sons: null}, -{kind: 1, offset: "borderBottomColor", len: 0, typ: NTI44042, name: "borderBottomColor", sons: null}, -{kind: 1, offset: "borderBottomStyle", len: 0, typ: NTI44042, name: "borderBottomStyle", sons: null}, -{kind: 1, offset: "borderBottomWidth", len: 0, typ: NTI44042, name: "borderBottomWidth", sons: null}, -{kind: 1, offset: "borderColor", len: 0, typ: NTI44042, name: "borderColor", sons: null}, -{kind: 1, offset: "borderLeft", len: 0, typ: NTI44042, name: "borderLeft", sons: null}, -{kind: 1, offset: "borderLeftColor", len: 0, typ: NTI44042, name: "borderLeftColor", sons: null}, -{kind: 1, offset: "borderLeftStyle", len: 0, typ: NTI44042, name: "borderLeftStyle", sons: null}, -{kind: 1, offset: "borderLeftWidth", len: 0, typ: NTI44042, name: "borderLeftWidth", sons: null}, -{kind: 1, offset: "borderRight", len: 0, typ: NTI44042, name: "borderRight", sons: null}, -{kind: 1, offset: "borderRightColor", len: 0, typ: NTI44042, name: "borderRightColor", sons: null}, -{kind: 1, offset: "borderRightStyle", len: 0, typ: NTI44042, name: "borderRightStyle", sons: null}, -{kind: 1, offset: "borderRightWidth", len: 0, typ: NTI44042, name: "borderRightWidth", sons: null}, -{kind: 1, offset: "borderStyle", len: 0, typ: NTI44042, name: "borderStyle", sons: null}, -{kind: 1, offset: "borderTop", len: 0, typ: NTI44042, name: "borderTop", sons: null}, -{kind: 1, offset: "borderTopColor", len: 0, typ: NTI44042, name: "borderTopColor", sons: null}, -{kind: 1, offset: "borderTopStyle", len: 0, typ: NTI44042, name: "borderTopStyle", sons: null}, -{kind: 1, offset: "borderTopWidth", len: 0, typ: NTI44042, name: "borderTopWidth", sons: null}, -{kind: 1, offset: "borderWidth", len: 0, typ: NTI44042, name: "borderWidth", sons: null}, -{kind: 1, offset: "bottom", len: 0, typ: NTI44042, name: "bottom", sons: null}, -{kind: 1, offset: "captionSide", len: 0, typ: NTI44042, name: "captionSide", sons: null}, -{kind: 1, offset: "clear", len: 0, typ: NTI44042, name: "clear", sons: null}, -{kind: 1, offset: "clip", len: 0, typ: NTI44042, name: "clip", sons: null}, -{kind: 1, offset: "color", len: 0, typ: NTI44042, name: "color", sons: null}, -{kind: 1, offset: "cursor", len: 0, typ: NTI44042, name: "cursor", sons: null}, -{kind: 1, offset: "direction", len: 0, typ: NTI44042, name: "direction", sons: null}, -{kind: 1, offset: "display", len: 0, typ: NTI44042, name: "display", sons: null}, -{kind: 1, offset: "emptyCells", len: 0, typ: NTI44042, name: "emptyCells", sons: null}, -{kind: 1, offset: "cssFloat", len: 0, typ: NTI44042, name: "cssFloat", sons: null}, -{kind: 1, offset: "font", len: 0, typ: NTI44042, name: "font", sons: null}, -{kind: 1, offset: "fontFamily", len: 0, typ: NTI44042, name: "fontFamily", sons: null}, -{kind: 1, offset: "fontSize", len: 0, typ: NTI44042, name: "fontSize", sons: null}, -{kind: 1, offset: "fontStretch", len: 0, typ: NTI44042, name: "fontStretch", sons: null}, -{kind: 1, offset: "fontStyle", len: 0, typ: NTI44042, name: "fontStyle", sons: null}, -{kind: 1, offset: "fontVariant", len: 0, typ: NTI44042, name: "fontVariant", sons: null}, -{kind: 1, offset: "fontWeight", len: 0, typ: NTI44042, name: "fontWeight", sons: null}, -{kind: 1, offset: "height", len: 0, typ: NTI44042, name: "height", sons: null}, -{kind: 1, offset: "left", len: 0, typ: NTI44042, name: "left", sons: null}, -{kind: 1, offset: "letterSpacing", len: 0, typ: NTI44042, name: "letterSpacing", sons: null}, -{kind: 1, offset: "lineHeight", len: 0, typ: NTI44042, name: "lineHeight", sons: null}, -{kind: 1, offset: "listStyle", len: 0, typ: NTI44042, name: "listStyle", sons: null}, -{kind: 1, offset: "listStyleImage", len: 0, typ: NTI44042, name: "listStyleImage", sons: null}, -{kind: 1, offset: "listStylePosition", len: 0, typ: NTI44042, name: "listStylePosition", sons: null}, -{kind: 1, offset: "listStyleType", len: 0, typ: NTI44042, name: "listStyleType", sons: null}, -{kind: 1, offset: "margin", len: 0, typ: NTI44042, name: "margin", sons: null}, -{kind: 1, offset: "marginBottom", len: 0, typ: NTI44042, name: "marginBottom", sons: null}, -{kind: 1, offset: "marginLeft", len: 0, typ: NTI44042, name: "marginLeft", sons: null}, -{kind: 1, offset: "marginRight", len: 0, typ: NTI44042, name: "marginRight", sons: null}, -{kind: 1, offset: "marginTop", len: 0, typ: NTI44042, name: "marginTop", sons: null}, -{kind: 1, offset: "maxHeight", len: 0, typ: NTI44042, name: "maxHeight", sons: null}, -{kind: 1, offset: "maxWidth", len: 0, typ: NTI44042, name: "maxWidth", sons: null}, -{kind: 1, offset: "minHeight", len: 0, typ: NTI44042, name: "minHeight", sons: null}, -{kind: 1, offset: "minWidth", len: 0, typ: NTI44042, name: "minWidth", sons: null}, -{kind: 1, offset: "overflow", len: 0, typ: NTI44042, name: "overflow", sons: null}, -{kind: 1, offset: "padding", len: 0, typ: NTI44042, name: "padding", sons: null}, -{kind: 1, offset: "paddingBottom", len: 0, typ: NTI44042, name: "paddingBottom", sons: null}, -{kind: 1, offset: "paddingLeft", len: 0, typ: NTI44042, name: "paddingLeft", sons: null}, -{kind: 1, offset: "paddingRight", len: 0, typ: NTI44042, name: "paddingRight", sons: null}, -{kind: 1, offset: "paddingTop", len: 0, typ: NTI44042, name: "paddingTop", sons: null}, -{kind: 1, offset: "pageBreakAfter", len: 0, typ: NTI44042, name: "pageBreakAfter", sons: null}, -{kind: 1, offset: "pageBreakBefore", len: 0, typ: NTI44042, name: "pageBreakBefore", sons: null}, -{kind: 1, offset: "pointerEvents", len: 0, typ: NTI44042, name: "pointerEvents", sons: null}, -{kind: 1, offset: "position", len: 0, typ: NTI44042, name: "position", sons: null}, -{kind: 1, offset: "right", len: 0, typ: NTI44042, name: "right", sons: null}, -{kind: 1, offset: "scrollbar3dLightColor", len: 0, typ: NTI44042, name: "scrollbar3dLightColor", sons: null}, -{kind: 1, offset: "scrollbarArrowColor", len: 0, typ: NTI44042, name: "scrollbarArrowColor", sons: null}, -{kind: 1, offset: "scrollbarBaseColor", len: 0, typ: NTI44042, name: "scrollbarBaseColor", sons: null}, -{kind: 1, offset: "scrollbarDarkshadowColor", len: 0, typ: NTI44042, name: "scrollbarDarkshadowColor", sons: null}, -{kind: 1, offset: "scrollbarFaceColor", len: 0, typ: NTI44042, name: "scrollbarFaceColor", sons: null}, -{kind: 1, offset: "scrollbarHighlightColor", len: 0, typ: NTI44042, name: "scrollbarHighlightColor", sons: null}, -{kind: 1, offset: "scrollbarShadowColor", len: 0, typ: NTI44042, name: "scrollbarShadowColor", sons: null}, -{kind: 1, offset: "scrollbarTrackColor", len: 0, typ: NTI44042, name: "scrollbarTrackColor", sons: null}, -{kind: 1, offset: "tableLayout", len: 0, typ: NTI44042, name: "tableLayout", sons: null}, -{kind: 1, offset: "textAlign", len: 0, typ: NTI44042, name: "textAlign", sons: null}, -{kind: 1, offset: "textDecoration", len: 0, typ: NTI44042, name: "textDecoration", sons: null}, -{kind: 1, offset: "textIndent", len: 0, typ: NTI44042, name: "textIndent", sons: null}, -{kind: 1, offset: "textTransform", len: 0, typ: NTI44042, name: "textTransform", sons: null}, -{kind: 1, offset: "transform", len: 0, typ: NTI44042, name: "transform", sons: null}, -{kind: 1, offset: "top", len: 0, typ: NTI44042, name: "top", sons: null}, -{kind: 1, offset: "verticalAlign", len: 0, typ: NTI44042, name: "verticalAlign", sons: null}, -{kind: 1, offset: "visibility", len: 0, typ: NTI44042, name: "visibility", sons: null}, -{kind: 1, offset: "width", len: 0, typ: NTI44042, name: "width", sons: null}, -{kind: 1, offset: "wordSpacing", len: 0, typ: NTI44042, name: "wordSpacing", sons: null}, -{kind: 1, offset: "zIndex", len: 0, typ: NTI44006, name: "zIndex", sons: null}]}; -NTI85283.node = NNI85283; -NTI85283.base = NTI47808; -NTI85281.base = NTI85283; -var NNI85231 = {kind: 2, len: 14, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "attributes", len: 0, typ: NTI85561, name: "attributes", sons: null}, -{kind: 1, offset: "childNodes", len: 0, typ: NTI85563, name: "childNodes", sons: null}, -{kind: 1, offset: "children", len: 0, typ: NTI85565, name: "children", sons: null}, -{kind: 1, offset: "data", len: 0, typ: NTI44042, name: "data", sons: null}, -{kind: 1, offset: "firstChild", len: 0, typ: NTI85229, name: "firstChild", sons: null}, -{kind: 1, offset: "lastChild", len: 0, typ: NTI85229, name: "lastChild", sons: null}, -{kind: 1, offset: "nextSibling", len: 0, typ: NTI85229, name: "nextSibling", sons: null}, -{kind: 1, offset: "nodeName", len: 0, typ: NTI44042, name: "nodeName", sons: null}, -{kind: 1, offset: "nodeType", len: 0, typ: NTI85227, name: "nodeType", sons: null}, -{kind: 1, offset: "nodeValue", len: 0, typ: NTI44042, name: "nodeValue", sons: null}, -{kind: 1, offset: "parentNode", len: 0, typ: NTI85229, name: "parentNode", sons: null}, -{kind: 1, offset: "previousSibling", len: 0, typ: NTI85229, name: "previousSibling", sons: null}, -{kind: 1, offset: "innerHTML", len: 0, typ: NTI44042, name: "innerHTML", sons: null}, -{kind: 1, offset: "style", len: 0, typ: NTI85281, name: "style", sons: null}]}; -NTI85231.node = NNI85231; -var NNI85205 = {kind: 2, len: 20, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "onabort", len: 0, typ: NTI85372, name: "onabort", sons: null}, -{kind: 1, offset: "onblur", len: 0, typ: NTI85376, name: "onblur", sons: null}, -{kind: 1, offset: "onchange", len: 0, typ: NTI85380, name: "onchange", sons: null}, -{kind: 1, offset: "onclick", len: 0, typ: NTI85384, name: "onclick", sons: null}, -{kind: 1, offset: "ondblclick", len: 0, typ: NTI85388, name: "ondblclick", sons: null}, -{kind: 1, offset: "onerror", len: 0, typ: NTI85392, name: "onerror", sons: null}, -{kind: 1, offset: "onfocus", len: 0, typ: NTI85396, name: "onfocus", sons: null}, -{kind: 1, offset: "onkeydown", len: 0, typ: NTI85400, name: "onkeydown", sons: null}, -{kind: 1, offset: "onkeypress", len: 0, typ: NTI85404, name: "onkeypress", sons: null}, -{kind: 1, offset: "onkeyup", len: 0, typ: NTI85408, name: "onkeyup", sons: null}, -{kind: 1, offset: "onload", len: 0, typ: NTI85412, name: "onload", sons: null}, -{kind: 1, offset: "onmousedown", len: 0, typ: NTI85416, name: "onmousedown", sons: null}, -{kind: 1, offset: "onmousemove", len: 0, typ: NTI85420, name: "onmousemove", sons: null}, -{kind: 1, offset: "onmouseout", len: 0, typ: NTI85424, name: "onmouseout", sons: null}, -{kind: 1, offset: "onmouseover", len: 0, typ: NTI85428, name: "onmouseover", sons: null}, -{kind: 1, offset: "onmouseup", len: 0, typ: NTI85432, name: "onmouseup", sons: null}, -{kind: 1, offset: "onreset", len: 0, typ: NTI85436, name: "onreset", sons: null}, -{kind: 1, offset: "onselect", len: 0, typ: NTI85440, name: "onselect", sons: null}, -{kind: 1, offset: "onsubmit", len: 0, typ: NTI85444, name: "onsubmit", sons: null}, -{kind: 1, offset: "onunload", len: 0, typ: NTI85448, name: "onunload", sons: null}]}; -NTI85205.node = NNI85205; -NTI85205.base = NTI47808; -NTI85231.base = NTI85205; -NTI85229.base = NTI85231; -NTI87305.base = NTI85229; -NTI207579.base = NTI44042; -var NNI47862 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; -NTI47862.node = NNI47862; -NTI47862.base = NTI47828; -var NNI205074 = {kind: 2, len: 2, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "Field0", len: 0, typ: NTI44006, name: "Field0", sons: null}, -{kind: 1, offset: "Field1", len: 0, typ: NTI44032, name: "Field1", sons: null}]}; -NTI205074.node = NNI205074; - -function makeNimstrLit(c_66254) { - var ln = c_66254.length; - var result = new Array(ln); - for (var i = 0; i < ln; ++i) { - result[i] = c_66254.charCodeAt(i); - } - return result; - - - -} - -function setConstr() { - var result = {}; - for (var i = 0; i < arguments.length; ++i) { - var x = arguments[i]; - if (typeof(x) == "object") { - for (var j = x[0]; j <= x[1]; ++j) { - result[j] = true; - } - } else { - result[x] = true; - } - } - return result; - - - -} -var ConstSet1 = setConstr(17, 16, 4, 18, 27, 19, 23, 22, 21); - -function nimCopy(dest_67427, src_67428, ti_67429) { - var result_67619 = null; - - switch (ti_67429.kind) { - case 21: - case 22: - case 23: - case 5: - if (!(is_fat_pointer_67401(ti_67429))) { - result_67619 = src_67428; - } - else { - result_67619 = [src_67428[0], src_67428[1]]; - } - - break; - case 19: - if (dest_67427 === null || dest_67427 === undefined) { - dest_67427 = {}; - } - else { - for (var key in dest_67427) { delete dest_67427[key]; } - } - for (var key in src_67428) { dest_67427[key] = src_67428[key]; } - result_67619 = dest_67427; - - break; - case 18: - case 17: - if (!((ti_67429.base == null))) { - result_67619 = nimCopy(dest_67427, src_67428, ti_67429.base); - } - else { - if ((ti_67429.kind == 17)) { - result_67619 = (dest_67427 === null || dest_67427 === undefined) ? {m_type: ti_67429} : dest_67427; - } - else { - result_67619 = (dest_67427 === null || dest_67427 === undefined) ? {} : dest_67427; - } - } - nimCopyAux(result_67619, src_67428, ti_67429.node); - break; - case 24: - case 4: - case 27: - case 16: - if (src_67428 === null) { - result_67619 = null; - } - else { - if (dest_67427 === null || dest_67427 === undefined) { - dest_67427 = new Array(src_67428.length); - } - else { - dest_67427.length = src_67428.length; - } - result_67619 = dest_67427; - for (var i = 0; i < src_67428.length; ++i) { - result_67619[i] = nimCopy(result_67619[i], src_67428[i], ti_67429.base); - } - } - - break; - case 28: - if (src_67428 !== null) { - result_67619 = src_67428.slice(0); - } - - break; - default: - result_67619 = src_67428; - break; - } - - return result_67619; - -} - -function arrayConstr(len_67686, value_67687, typ_67688) { - var result = new Array(len_67686); - for (var i = 0; i < len_67686; ++i) result[i] = nimCopy(null, value_67687, typ_67688); - return result; - - - -} - -function cstrToNimstr(c_66271) { - var ln = c_66271.length; - var result = new Array(ln); - var r = 0; - for (var i = 0; i < ln; ++i) { - var ch = c_66271.charCodeAt(i); - - if (ch < 128) { - result[r] = ch; - } - else { - if (ch < 2048) { - result[r] = (ch >> 6) | 192; - } - else { - if (ch < 55296 || ch >= 57344) { - result[r] = (ch >> 12) | 224; - } - else { - ++i; - ch = 65536 + (((ch & 1023) << 10) | (c_66271.charCodeAt(i) & 1023)); - result[r] = (ch >> 18) | 240; - ++r; - result[r] = ((ch >> 12) & 63) | 128; - } - ++r; - result[r] = ((ch >> 6) & 63) | 128; - } - ++r; - result[r] = (ch & 63) | 128; - } - ++r; - } - return result; - - - -} - -function toJSStr(s_66288) { - if (s_66288 === null) return ""; - var len = s_66288.length; - var asciiPart = new Array(len); - var fcc = String.fromCharCode; - var nonAsciiPart = null; - var nonAsciiOffset = 0; - for (var i = 0; i < len; ++i) { - if (nonAsciiPart !== null) { - var offset = (i - nonAsciiOffset) * 2; - var code = s_66288[i].toString(16); - if (code.length == 1) { - code = "0"+code; - } - nonAsciiPart[offset] = "%"; - nonAsciiPart[offset + 1] = code; - } - else if (s_66288[i] < 128) - asciiPart[i] = fcc(s_66288[i]); - else { - asciiPart.length = i; - nonAsciiOffset = i; - nonAsciiPart = new Array((len - i) * 2); - --i; - } - } - asciiPart = asciiPart.join(""); - return (nonAsciiPart === null) ? - asciiPart : asciiPart + decodeURIComponent(nonAsciiPart.join("")); - - - -} - -function raiseException(e_64618, ename_64619) { - e_64618.name = ename_64619; - if ((excHandler == 0)) { - unhandledException(e_64618); - } - - e_64618.trace = nimCopy(null, raw_write_stack_trace_64468(), NTI44040); - throw e_64618; - - -} - -function addInt(a_66603, b_66604) { - var result = a_66603 + b_66604; - if (result > 2147483647 || result < -2147483648) raiseOverflow(); - return result; - - - -} - -function chckIndx(i_67705, a_67706, b_67707) { - var Tmp1; - - var result_67708 = 0; - - BeforeRet: do { - if (!(a_67706 <= i_67705)) Tmp1 = false; else { Tmp1 = (i_67705 <= b_67707); } if (Tmp1) { - result_67708 = i_67705; - break BeforeRet; - } - else { - raiseIndexError(i_67705, a_67706, b_67707); - } - - } while (false); - - return result_67708; - -} - -function subInt(a_66621, b_66622) { - var result = a_66621 - b_66622; - if (result > 2147483647 || result < -2147483648) raiseOverflow(); - return result; - - - -} -var ConstSet2 = setConstr([65, 90]); - -function chckRange(i_67724, a_67725, b_67726) { - var Tmp1; - - var result_67727 = 0; - - BeforeRet: do { - if (!(a_67725 <= i_67724)) Tmp1 = false; else { Tmp1 = (i_67724 <= b_67726); } if (Tmp1) { - result_67727 = i_67724; - break BeforeRet; - } - else { - raiseRangeError(); - } - - } while (false); - - return result_67727; - -} -var ConstSet3 = setConstr(95, 32, 46); -var ConstSet4 = setConstr(95, 32, 46); - -function mulInt(a_66639, b_66640) { - var result = a_66639 * b_66640; - if (result > 2147483647 || result < -2147483648) raiseOverflow(); - return result; - - - -} -var ConstSet5 = setConstr([97, 122]); -var ConstSet6 = setConstr([65, 90], [97, 122]); -var ConstSet7 = setConstr([97, 122]); -var ConstSet8 = setConstr([65, 90]); - -function nimMax(a_67021, b_67022) { - var Tmp1; - - var result_67023 = 0; - - BeforeRet: do { - if ((b_67022 <= a_67021)) { - Tmp1 = a_67021; - } - else { - Tmp1 = b_67022; - } - - result_67023 = Tmp1; - break BeforeRet; - } while (false); - - return result_67023; - -} - -function nimMin(a_67003, b_67004) { - var Tmp1; - - var result_67005 = 0; - - BeforeRet: do { - if ((a_67003 <= b_67004)) { - Tmp1 = a_67003; - } - else { - Tmp1 = b_67004; - } - - result_67005 = Tmp1; - break BeforeRet; - } while (false); - - return result_67005; - -} -var nim_program_result = 0; -var global_raise_hook_61618 = [null]; -var local_raise_hook_61623 = [null]; -var out_of_mem_hook_61626 = [null]; - if (!Math.trunc) { - Math.trunc = function(v) { - v = +v; - if (!isFinite(v)) return v; - - return (v - v % 1) || (v < 0 ? -0 : v === 0 ? v : 0); - }; - } -var alternative_207315 = [null]; - -function is_fat_pointer_67401(ti_67403) { - var result_67404 = false; - - BeforeRet: do { - result_67404 = !((ConstSet1[ti_67403.base.kind] != undefined)); - break BeforeRet; - } while (false); - - return result_67404; - -} - -function nimCopyAux(dest_67432, src_67433, n_67435) { - switch (n_67435.kind) { - case 0: - break; - case 1: - dest_67432[n_67435.offset] = nimCopy(dest_67432[n_67435.offset], src_67433[n_67435.offset], n_67435.typ); - - break; - case 2: - for (var i = 0; i < n_67435.sons.length; i++) { - nimCopyAux(dest_67432, src_67433, n_67435.sons[i]); - } - - break; - case 3: - dest_67432[n_67435.offset] = nimCopy(dest_67432[n_67435.offset], src_67433[n_67435.offset], n_67435.typ); - for (var i = 0; i < n_67435.sons.length; ++i) { - nimCopyAux(dest_67432, src_67433, n_67435.sons[i][1]); - } - - break; - } - - -} - -function add_61638(x_61641, x_61641_Idx, y_61642) { - if (x_61641[x_61641_Idx] === null) { x_61641[x_61641_Idx] = []; } - var off = x_61641[x_61641_Idx].length; - x_61641[x_61641_Idx].length += y_61642.length; - for (var i = 0; i < y_61642.length; ++i) { - x_61641[x_61641_Idx][off+i] = y_61642.charCodeAt(i); - } - - - -} - -function aux_write_stack_trace_64151(f_64153) { - var Tmp3; - - var result_64154 = [null]; - - var it_64162 = f_64153; - var i_64164 = 0; - var total_64166 = 0; - var temp_frames_64173 = arrayConstr(64, {Field0: null, Field1: 0}, NTI64156); - L1: do { - L2: while (true) { - if (!!((it_64162 == null))) Tmp3 = false; else { Tmp3 = (i_64164 <= 63); } if (!Tmp3) break L2; - temp_frames_64173[i_64164].Field0 = it_64162.procname; - temp_frames_64173[i_64164].Field1 = it_64162.line; - i_64164 += 1; - total_64166 += 1; - it_64162 = it_64162.prev; - } - } while(false); - L4: do { - L5: while (true) { - if (!!((it_64162 == null))) break L5; - total_64166 += 1; - it_64162 = it_64162.prev; - } - } while(false); - result_64154[0] = nimCopy(null, [], NTI44040); - if (!((total_64166 == i_64164))) { - if (result_64154[0] != null) { result_64154[0] = (result_64154[0]).concat(makeNimstrLit("(")); } else { result_64154[0] = makeNimstrLit("("); }; - if (result_64154[0] != null) { result_64154[0] = (result_64154[0]).concat(cstrToNimstr(((total_64166 - i_64164))+"")); } else { result_64154[0] = cstrToNimstr(((total_64166 - i_64164))+"").slice(); }; - if (result_64154[0] != null) { result_64154[0] = (result_64154[0]).concat(makeNimstrLit(" calls omitted) ...\x0A")); } else { result_64154[0] = makeNimstrLit(" calls omitted) ...\x0A"); }; - } - - L6: do { - var j_64421 = 0; - var colontmp__207456 = 0; - colontmp__207456 = (i_64164 - 1); - var res_207461 = colontmp__207456; - L7: do { - L8: while (true) { - if (!(0 <= res_207461)) break L8; - j_64421 = res_207461; - add_61638(result_64154, 0, temp_frames_64173[j_64421].Field0); - if ((0 < temp_frames_64173[j_64421].Field1)) { - if (result_64154[0] != null) { result_64154[0] = (result_64154[0]).concat(makeNimstrLit(", line: ")); } else { result_64154[0] = makeNimstrLit(", line: "); }; - if (result_64154[0] != null) { result_64154[0] = (result_64154[0]).concat(cstrToNimstr((temp_frames_64173[j_64421].Field1)+"")); } else { result_64154[0] = cstrToNimstr((temp_frames_64173[j_64421].Field1)+"").slice(); }; - } - - if (result_64154[0] != null) { result_64154[0] = (result_64154[0]).concat(makeNimstrLit("\x0A")); } else { result_64154[0] = makeNimstrLit("\x0A"); }; - res_207461 -= 1; - } - } while(false); - } while(false); - - return result_64154[0]; - -} - -function raw_write_stack_trace_64468() { - var result_64470 = null; - - if (!((framePtr == null))) { - result_64470 = nimCopy(null, (makeNimstrLit("Traceback (most recent call last)\x0A") || []).concat(aux_write_stack_trace_64151(framePtr) || []), NTI44040); - } - else { - result_64470 = nimCopy(null, makeNimstrLit("No stack traceback available\x0A"), NTI44040); - } - - - return result_64470; - -} - -function unhandledException(e_64529) { - var buf_64530 = [[]]; - if (!(((e_64529.message != null ? e_64529.message.length : 0) == 0))) { - if (buf_64530[0] != null) { buf_64530[0] = (buf_64530[0]).concat(makeNimstrLit("Error: unhandled exception: ")); } else { buf_64530[0] = makeNimstrLit("Error: unhandled exception: "); }; - if (buf_64530[0] != null) { buf_64530[0] = (buf_64530[0]).concat(e_64529.message); } else { buf_64530[0] = e_64529.message.slice(); }; - } - else { - if (buf_64530[0] != null) { buf_64530[0] = (buf_64530[0]).concat(makeNimstrLit("Error: unhandled exception")); } else { buf_64530[0] = makeNimstrLit("Error: unhandled exception"); }; - } - - if (buf_64530[0] != null) { buf_64530[0] = (buf_64530[0]).concat(makeNimstrLit(" [")); } else { buf_64530[0] = makeNimstrLit(" ["); }; - add_61638(buf_64530, 0, e_64529.name); - if (buf_64530[0] != null) { buf_64530[0] = (buf_64530[0]).concat(makeNimstrLit("]\x0A")); } else { buf_64530[0] = makeNimstrLit("]\x0A"); }; - if (buf_64530[0] != null) { buf_64530[0] = (buf_64530[0]).concat(raw_write_stack_trace_64468()); } else { buf_64530[0] = raw_write_stack_trace_64468().slice(); }; - var cbuf_64601 = toJSStr(buf_64530[0]); - framePtr = null; - if (typeof(Error) !== "undefined") { - throw new Error(cbuf_64601); - } - else { - throw cbuf_64601; - } - - - -} - -function raiseOverflow() { - var e_65042 = null; - e_65042 = {m_type: NTI47846, parent: null, name: null, message: null, trace: null, raiseId: 0, up: null}; - e_65042.message = nimCopy(null, makeNimstrLit("over- or underflow"), NTI44040); - e_65042.parent = null; - raiseException(e_65042, "OverflowError"); - - -} - -function is_whitespace_206654(text_206656) { - return !/[^\s]/.test(text_206656); - - - -} - -function is_whitespace_206671(x_206673) { - var Tmp1; - var Tmp2; - - var result_206674 = false; - - var F={procname:"dochack.isWhitespace",prev:framePtr,filename:"dochack.nim",line:0}; - framePtr = F; - F.line = 134; - if (!(x_206673.nodeName == "#text")) Tmp2 = false; else { Tmp2 = is_whitespace_206654(x_206673.textContent); } if (Tmp2) Tmp1 = true; else { Tmp1 = (x_206673.nodeName == "#comment"); } result_206674 = Tmp1; - framePtr = F.prev; - - return result_206674; - -} - -function raiseIndexError(i_65639, a_65640, b_65641) { - var Tmp1; - - var e_65802 = null; - e_65802 = {m_type: NTI47858, parent: null, name: null, message: null, trace: null, raiseId: 0, up: null}; - if ((b_65641 < a_65640)) { - Tmp1 = makeNimstrLit("index out of bounds, the container is empty"); - } - else { - Tmp1 = (makeNimstrLit("index ") || []).concat(cstrToNimstr((i_65639)+"") || [],makeNimstrLit(" not in ") || [],cstrToNimstr((a_65640)+"") || [],makeNimstrLit(" .. ") || [],cstrToNimstr((b_65641)+"") || []); - } - - e_65802.message = nimCopy(null, Tmp1, NTI44040); - e_65802.parent = null; - raiseException(e_65802, "IndexError"); - - -} - -function to_toc_206688(x_206690, father_206691) { - var Tmp5; - var Tmp6; - var Tmp7; - var Tmp8; - var Tmp15; - - var F={procname:"dochack.toToc",prev:framePtr,filename:"dochack.nim",line:0}; - framePtr = F; - if ((x_206690.nodeName == "UL")) { - F.line = 139; - var f_206710 = {heading: null, kids: [], sortId: (father_206691.kids != null ? father_206691.kids.length : 0), doSort: false}; - F.line = 140; - var i_206712 = 0; - L1: do { - F.line = 141; - L2: while (true) { - if (!(i_206712 < x_206690.childNodes.length)) break L2; - F.line = 142; - var nxt_206713 = addInt(i_206712, 1); - L3: do { - F.line = 143; - L4: while (true) { - if (!(nxt_206713 < x_206690.childNodes.length)) Tmp5 = false; else { Tmp5 = is_whitespace_206671(x_206690.childNodes[nxt_206713]); } if (!Tmp5) break L4; - F.line = 144; - nxt_206713 = addInt(nxt_206713, 1); - } - } while(false); - if (!(nxt_206713 < x_206690.childNodes.length)) Tmp8 = false; else { Tmp8 = (x_206690.childNodes[i_206712].nodeName == "LI"); } if (!Tmp8) Tmp7 = false; else { Tmp7 = (x_206690.childNodes[i_206712].childNodes.length == 1); } if (!Tmp7) Tmp6 = false; else { Tmp6 = (x_206690.childNodes[nxt_206713].nodeName == "UL"); } if (Tmp6) { - F.line = 147; - var e_206738 = {heading: x_206690.childNodes[i_206712].childNodes[0], kids: [], sortId: (f_206710.kids != null ? f_206710.kids.length : 0), doSort: false}; - F.line = 148; - var it_206739 = x_206690.childNodes[nxt_206713]; - L9: do { - F.line = 149; - var j_206747 = 0; - F.line = 2716; - var colontmp__207432 = 0; - F.line = 149; - colontmp__207432 = it_206739.childNodes.length; - F.line = 2717; - var i_207433 = 0; - L10: do { - F.line = 2718; - L11: while (true) { - if (!(i_207433 < colontmp__207432)) break L11; - F.line = 149; - j_206747 = i_207433; - F.line = 150; - to_toc_206688(it_206739.childNodes[j_206747], e_206738); - F.line = 2720; - i_207433 = addInt(i_207433, 1); - } - } while(false); - } while(false); - F.line = 151; - if (f_206710.kids != null) { f_206710.kids.push(e_206738); } else { f_206710.kids = [e_206738]; }; - F.line = 152; - i_206712 = addInt(nxt_206713, 1); - } - else { - F.line = 154; - to_toc_206688(x_206690.childNodes[i_206712], f_206710); - F.line = 155; - i_206712 = addInt(i_206712, 1); - } - - } - } while(false); - F.line = 156; - if (father_206691.kids != null) { father_206691.kids.push(f_206710); } else { father_206691.kids = [f_206710]; }; - } - else { - if (is_whitespace_206671(x_206690)) { - } - else { - if ((x_206690.nodeName == "LI")) { - F.line = 160; - var idx_206782 = []; - L12: do { - F.line = 161; - var i_206790 = 0; - F.line = 2716; - var colontmp__207437 = 0; - F.line = 161; - colontmp__207437 = x_206690.childNodes.length; - F.line = 2717; - var i_207438 = 0; - L13: do { - F.line = 2718; - L14: while (true) { - if (!(i_207438 < colontmp__207437)) break L14; - F.line = 161; - i_206790 = i_207438; - if (!(is_whitespace_206671(x_206690.childNodes[i_206790]))) { - F.line = 162; - if (idx_206782 != null) { idx_206782.push(i_206790); } else { idx_206782 = [i_206790]; }; - } - - F.line = 2720; - i_207438 = addInt(i_207438, 1); - } - } while(false); - } while(false); - if (!((idx_206782 != null ? idx_206782.length : 0) == 2)) Tmp15 = false; else { Tmp15 = (x_206690.childNodes[idx_206782[chckIndx(1, 0, idx_206782.length+0-1)-0]].nodeName == "UL"); } if (Tmp15) { - F.line = 164; - var e_206821 = {heading: x_206690.childNodes[idx_206782[chckIndx(0, 0, idx_206782.length+0-1)-0]], kids: [], sortId: (father_206691.kids != null ? father_206691.kids.length : 0), doSort: false}; - F.line = 166; - var it_206822 = x_206690.childNodes[idx_206782[chckIndx(1, 0, idx_206782.length+0-1)-0]]; - L16: do { - F.line = 167; - var j_206830 = 0; - F.line = 2716; - var colontmp__207443 = 0; - F.line = 167; - colontmp__207443 = it_206822.childNodes.length; - F.line = 2717; - var i_207444 = 0; - L17: do { - F.line = 2718; - L18: while (true) { - if (!(i_207444 < colontmp__207443)) break L18; - F.line = 167; - j_206830 = i_207444; - F.line = 168; - to_toc_206688(it_206822.childNodes[j_206830], e_206821); - F.line = 2720; - i_207444 = addInt(i_207444, 1); - } - } while(false); - } while(false); - F.line = 169; - if (father_206691.kids != null) { father_206691.kids.push(e_206821); } else { father_206691.kids = [e_206821]; }; - } - else { - L19: do { - F.line = 171; - var i_206845 = 0; - F.line = 2716; - var colontmp__207448 = 0; - F.line = 171; - colontmp__207448 = x_206690.childNodes.length; - F.line = 2717; - var i_207449 = 0; - L20: do { - F.line = 2718; - L21: while (true) { - if (!(i_207449 < colontmp__207448)) break L21; - F.line = 171; - i_206845 = i_207449; - F.line = 172; - to_toc_206688(x_206690.childNodes[i_206845], father_206691); - F.line = 2720; - i_207449 = addInt(i_207449, 1); - } - } while(false); - } while(false); - } - - } - else { - F.line = 174; - if (father_206691.kids != null) { father_206691.kids.push({heading: x_206690, kids: [], sortId: (father_206691.kids != null ? father_206691.kids.length : 0), doSort: false}); } else { father_206691.kids = [{heading: x_206690, kids: [], sortId: (father_206691.kids != null ? father_206691.kids.length : 0), doSort: false}]; }; - } - }} - framePtr = F.prev; - - -} - -function extract_items_206339(x_206341, heading_206342, items_206345, items_206345_Idx) { - var Tmp1; - - var F={procname:"dochack.extractItems",prev:framePtr,filename:"dochack.nim",line:0}; - framePtr = F; - BeforeRet: do { - if ((x_206341 == null)) { - F.line = 81; - break BeforeRet; - } - - if (!!((x_206341.heading == null))) Tmp1 = false; else { Tmp1 = (x_206341.heading.textContent == heading_206342); } if (Tmp1) { - L2: do { - F.line = 83; - var i_206374 = 0; - F.line = 2716; - var colontmp__207475 = 0; - F.line = 83; - colontmp__207475 = (x_206341.kids != null ? x_206341.kids.length : 0); - F.line = 2717; - var i_207476 = 0; - L3: do { - F.line = 2718; - L4: while (true) { - if (!(i_207476 < colontmp__207475)) break L4; - F.line = 83; - i_206374 = i_207476; - F.line = 84; - if (items_206345[items_206345_Idx] != null) { items_206345[items_206345_Idx].push(x_206341.kids[chckIndx(i_206374, 0, x_206341.kids.length+0-1)-0].heading); } else { items_206345[items_206345_Idx] = [x_206341.kids[chckIndx(i_206374, 0, x_206341.kids.length+0-1)-0].heading]; }; - F.line = 2720; - i_207476 = addInt(i_207476, 1); - } - } while(false); - } while(false); - } - else { - L5: do { - F.line = 86; - var i_206394 = 0; - F.line = 2716; - var colontmp__207480 = 0; - F.line = 86; - colontmp__207480 = (x_206341.kids != null ? x_206341.kids.length : 0); - F.line = 2717; - var i_207481 = 0; - L6: do { - F.line = 2718; - L7: while (true) { - if (!(i_207481 < colontmp__207480)) break L7; - F.line = 86; - i_206394 = i_207481; - F.line = 87; - var it_206395 = x_206341.kids[chckIndx(i_206394, 0, x_206341.kids.length+0-1)-0]; - F.line = 88; - extract_items_206339(it_206395, heading_206342, items_206345, items_206345_Idx); - F.line = 2720; - i_207481 = addInt(i_207481, 1); - } - } while(false); - } while(false); - } - - } while (false); - framePtr = F.prev; - - -} - -function tree_206020(tag_206022, kids_206024) { - var result_206025 = null; - - var F={procname:"dochack.tree",prev:framePtr,filename:"dochack.nim",line:0}; - framePtr = F; - F.line = 11; - result_206025 = document.createElement(toJSStr(tag_206022)); - L1: do { - F.line = 12; - var k_206056 = null; - F.line = 3; - var i_207498 = 0; - L2: do { - F.line = 4; - L3: while (true) { - if (!(i_207498 < (kids_206024 != null ? kids_206024.length : 0))) break L3; - F.line = 12; - k_206056 = kids_206024[chckIndx(i_207498, 0, kids_206024.length+0-1)-0]; - F.line = 13; - result_206025.appendChild(k_206056); - F.line = 6; - i_207498 = addInt(i_207498, 1); - } - } while(false); - } while(false); - framePtr = F.prev; - - return result_206025; - -} - -function text_206152(s_206154) { - var result_206155 = null; - - var F={procname:"dochack.text",prev:framePtr,filename:"dochack.nim",line:0}; - framePtr = F; - F.line = 27; - result_206155 = document.createTextNode(s_206154); - framePtr = F.prev; - - return result_206155; - -} - -function sys_fatal_58662(message_58666) { - var F={procname:"sysFatal.sysFatal",prev:framePtr,filename:"fatal.nim",line:0}; - framePtr = F; - F.line = 34; - var e_58803 = null; - F.line = 37; - e_58803 = {m_type: NTI47850, parent: null, name: null, message: null, trace: null, raiseId: 0, up: null}; - F.line = 38; - e_58803.message = nimCopy(null, message_58666, NTI44040); - F.line = 39; - raiseException(e_58803, "AssertionError"); - framePtr = F.prev; - - -} - -function raise_assert_58658(msg_58660) { - var F={procname:"assertions.raiseAssert",prev:framePtr,filename:"assertions.nim",line:0}; - framePtr = F; - F.line = 20; - sys_fatal_58662(msg_58660); - framePtr = F.prev; - - -} - -function failed_assert_impl_58851(msg_58853) { - var F={procname:"assertions.failedAssertImpl",prev:framePtr,filename:"assertions.nim",line:0}; - framePtr = F; - F.line = 27; - raise_assert_58658(msg_58853); - framePtr = F.prev; - - -} - -function uncovered_206940(x_206942) { - var Tmp1; - var Tmp2; - - var result_206943 = null; - - var F={procname:"dochack.uncovered",prev:framePtr,filename:"dochack.nim",line:0}; - framePtr = F; - BeforeRet: do { - if (!((x_206942.kids != null ? x_206942.kids.length : 0) == 0)) Tmp1 = false; else { Tmp1 = !((x_206942.heading == null)); } if (Tmp1) { - F.line = 194; - if (!(x_206942.heading.hasOwnProperty('__karaxMarker__'))) { - Tmp2 = x_206942; - } - else { - Tmp2 = null; - } - - result_206943 = Tmp2; - break BeforeRet; - } - - F.line = 195; - result_206943 = {heading: x_206942.heading, kids: [], sortId: x_206942.sortId, doSort: x_206942.doSort}; - L3: do { - F.line = 197; - var i_206982 = 0; - F.line = 2716; - var colontmp__207510 = 0; - F.line = 197; - colontmp__207510 = (x_206942.kids != null ? x_206942.kids.length : 0); - F.line = 2717; - var i_207511 = 0; - L4: do { - F.line = 2718; - L5: while (true) { - if (!(i_207511 < colontmp__207510)) break L5; - F.line = 197; - i_206982 = i_207511; - F.line = 198; - var y_206983 = uncovered_206940(x_206942.kids[chckIndx(i_206982, 0, x_206942.kids.length+0-1)-0]); - if (!((y_206983 == null))) { - F.line = 199; - if (result_206943.kids != null) { result_206943.kids.push(y_206983); } else { result_206943.kids = [y_206983]; }; - } - - F.line = 2720; - i_207511 = addInt(i_207511, 1); - } - } while(false); - } while(false); - if (((result_206943.kids != null ? result_206943.kids.length : 0) == 0)) { - F.line = 200; - result_206943 = null; - } - - } while (false); - framePtr = F.prev; - - return result_206943; - -} - -function merge_tocs_207017(orig_207019, news_207020) { - var result_207021 = null; - - var F={procname:"dochack.mergeTocs",prev:framePtr,filename:"dochack.nim",line:0}; - framePtr = F; - F.line = 203; - result_207021 = uncovered_206940(orig_207019); - if ((result_207021 == null)) { - F.line = 205; - result_207021 = news_207020; - } - else { - L1: do { - F.line = 207; - var i_207042 = 0; - F.line = 2716; - var colontmp__207504 = 0; - F.line = 207; - colontmp__207504 = (news_207020.kids != null ? news_207020.kids.length : 0); - F.line = 2717; - var i_207505 = 0; - L2: do { - F.line = 2718; - L3: while (true) { - if (!(i_207505 < colontmp__207504)) break L3; - F.line = 207; - i_207042 = i_207505; - F.line = 208; - if (result_207021.kids != null) { result_207021.kids.push(news_207020.kids[chckIndx(i_207042, 0, news_207020.kids.length+0-1)-0]); } else { result_207021.kids = [news_207020.kids[chckIndx(i_207042, 0, news_207020.kids.length+0-1)-0]]; }; - F.line = 2720; - i_207505 = addInt(i_207505, 1); - } - } while(false); - } while(false); - } - - framePtr = F.prev; - - return result_207021; - -} - -function build_toc_207063(orig_207065, types_207067, procs_207068) { - var result_207069 = null; - - var F={procname:"dochack.buildToc",prev:framePtr,filename:"dochack.nim",line:0}; - framePtr = F; - F.line = 211; - var new_stuff_207083 = {heading: null, kids: [], doSort: true, sortId: 0}; - L1: do { - F.line = 212; - var t_207214 = null; - F.line = 185; - var i_207493 = 0; - F.line = 186; - var l_207494 = (types_207067 != null ? types_207067.length : 0); - L2: do { - F.line = 187; - L3: while (true) { - if (!(i_207493 < l_207494)) break L3; - F.line = 212; - t_207214 = types_207067[chckIndx(i_207493, 0, types_207067.length+0-1)-0]; - F.line = 213; - var c_207228 = {heading: t_207214.cloneNode(true), kids: [], doSort: true, sortId: 0}; - F.line = 214; - t_207214.__karaxMarker__ = true; - L4: do { - F.line = 215; - var p_207235 = null; - F.line = 185; - var i_207490 = 0; - F.line = 186; - var l_207491 = (procs_207068 != null ? procs_207068.length : 0); - L5: do { - F.line = 187; - L6: while (true) { - if (!(i_207490 < l_207491)) break L6; - F.line = 215; - p_207235 = procs_207068[chckIndx(i_207490, 0, procs_207068.length+0-1)-0]; - if (!(p_207235.hasOwnProperty('__karaxMarker__'))) { - F.line = 217; - var xx_207236 = p_207235.parentNode.getElementsByClassName("attachedType"); - if ((((xx_207236 != null ? xx_207236.length : 0) == 1) && (xx_207236[chckIndx(0, 0, xx_207236.length+0-1)-0].textContent == t_207214.textContent))) { - F.line = 220; - var q_207244 = tree_206020(makeNimstrLit("A"), [text_206152(p_207235.title)]); - F.line = 221; - q_207244.setAttribute("href", p_207235.getAttribute("href")); - F.line = 222; - if (c_207228.kids != null) { c_207228.kids.push({heading: q_207244, kids: [], sortId: 0, doSort: false}); } else { c_207228.kids = [{heading: q_207244, kids: [], sortId: 0, doSort: false}]; }; - F.line = 223; - p_207235.__karaxMarker__ = true; - } - - } - - F.line = 189; - i_207490 = addInt(i_207490, 1); - if (!(((procs_207068 != null ? procs_207068.length : 0) == l_207491))) { - F.line = 190; - failed_assert_impl_58851(makeNimstrLit("/home/genotrance/programming/nimdevel/lib/system/iterators.nim(190, 11) `len(a) == L` the length of the seq changed while iterating over it")); - } - - } - } while(false); - } while(false); - F.line = 224; - if (new_stuff_207083.kids != null) { new_stuff_207083.kids.push(c_207228); } else { new_stuff_207083.kids = [c_207228]; }; - F.line = 189; - i_207493 = addInt(i_207493, 1); - if (!(((types_207067 != null ? types_207067.length : 0) == l_207494))) { - F.line = 190; - failed_assert_impl_58851(makeNimstrLit("/home/genotrance/programming/nimdevel/lib/system/iterators.nim(190, 11) `len(a) == L` the length of the seq changed while iterating over it")); - } - - } - } while(false); - } while(false); - F.line = 225; - result_207069 = merge_tocs_207017(orig_207065, new_stuff_207083); - framePtr = F.prev; - - return result_207069; - -} - -function add_206085(parent_206087, kid_206088) { - var Tmp1; - var Tmp2; - - var F={procname:"dochack.add",prev:framePtr,filename:"dochack.nim",line:0}; - framePtr = F; - if (!(parent_206087.nodeName == "TR")) Tmp1 = false; else { if ((kid_206088.nodeName == "TD")) Tmp2 = true; else { Tmp2 = (kid_206088.nodeName == "TH"); } Tmp1 = Tmp2; } if (Tmp1) { - F.line = 18; - var k_206089 = document.createElement("TD"); - F.line = 19; - k_206089.appendChild(kid_206088); - F.line = 20; - parent_206087.appendChild(k_206089); - } - else { - F.line = 22; - parent_206087.appendChild(kid_206088); - } - - framePtr = F.prev; - - -} - -function set_class_206103(e_206105, value_206106) { - var F={procname:"dochack.setClass",prev:framePtr,filename:"dochack.nim",line:0}; - framePtr = F; - F.line = 25; - e_206105.setAttribute("class", toJSStr(value_206106)); - framePtr = F.prev; - - -} - -function to_html_206424(x_206426, is_root_206427) { - var Tmp1; - - function HEX3Aanonymous_206467(a_206469, b_206470) { - var Tmp1; - - var result_206471 = 0; - - var F={procname:"toHtml.:anonymous",prev:framePtr,filename:"dochack.nim",line:0}; - framePtr = F; - BeforeRet: do { - if (!!((a_206469.heading == null))) Tmp1 = false; else { Tmp1 = !((b_206470.heading == null)); } if (Tmp1) { - F.line = 106; - var x_206488 = a_206469.heading.textContent; - F.line = 107; - var y_206489 = b_206470.heading.textContent; - if ((x_206488 < y_206489)) { - F.line = 108; - result_206471 = -1; - break BeforeRet; - } - - if ((y_206489 < x_206488)) { - F.line = 109; - result_206471 = 1; - break BeforeRet; - } - - F.line = 110; - result_206471 = 0; - break BeforeRet; - } - else { - F.line = 113; - result_206471 = subInt(a_206469.sortId, b_206470.sortId); - break BeforeRet; - } - - } while (false); - framePtr = F.prev; - - return result_206471; - - } - - var result_206428 = null; - - var F={procname:"dochack.toHtml",prev:framePtr,filename:"dochack.nim",line:0}; - framePtr = F; - BeforeRet: do { - if ((x_206426 == null)) { - F.line = 91; - result_206428 = null; - break BeforeRet; - } - - if (((x_206426.kids != null ? x_206426.kids.length : 0) == 0)) { - if ((x_206426.heading == null)) { - F.line = 93; - result_206428 = null; - break BeforeRet; - } - - F.line = 94; - result_206428 = x_206426.heading.cloneNode(true); - break BeforeRet; - } - - F.line = 95; - result_206428 = tree_206020(makeNimstrLit("DIV"), []); - if (!!((x_206426.heading == null))) Tmp1 = false; else { Tmp1 = !(x_206426.heading.hasOwnProperty('__karaxMarker__')); } if (Tmp1) { - F.line = 97; - add_206085(result_206428, x_206426.heading.cloneNode(true)); - } - - F.line = 98; - var ul_206464 = tree_206020(makeNimstrLit("UL"), []); - if (is_root_206427) { - F.line = 100; - set_class_206103(ul_206464, makeNimstrLit("simple simple-toc")); - } - else { - F.line = 102; - set_class_206103(ul_206464, makeNimstrLit("simple")); - } - - if (x_206426.doSort) { - F.line = 104; - x_206426.kids.sort(HEX3Aanonymous_206467); - } - - L2: do { - F.line = 115; - var k_206614 = null; - F.line = 183; - var colontmp__207517 = null; - F.line = 115; - colontmp__207517 = x_206426.kids; - F.line = 185; - var i_207519 = 0; - F.line = 186; - var l_207520 = (colontmp__207517 != null ? colontmp__207517.length : 0); - L3: do { - F.line = 187; - L4: while (true) { - if (!(i_207519 < l_207520)) break L4; - F.line = 115; - k_206614 = colontmp__207517[chckIndx(i_207519, 0, colontmp__207517.length+0-1)-0]; - F.line = 116; - var y_206615 = to_html_206424(k_206614, false); - if (!((y_206615 == null))) { - F.line = 118; - add_206085(ul_206464, tree_206020(makeNimstrLit("LI"), [y_206615])); - } - - F.line = 189; - i_207519 = addInt(i_207519, 1); - if (!(((colontmp__207517 != null ? colontmp__207517.length : 0) == l_207520))) { - F.line = 190; - failed_assert_impl_58851(makeNimstrLit("/home/genotrance/programming/nimdevel/lib/system/iterators.nim(190, 11) `len(a) == L` the length of the seq changed while iterating over it")); - } - - } - } while(false); - } while(false); - if (!((ul_206464.childNodes.length == 0))) { - F.line = 119; - add_206085(result_206428, ul_206464); - } - - if ((result_206428.childNodes.length == 0)) { - F.line = 120; - result_206428 = null; - } - - } while (false); - framePtr = F.prev; - - return result_206428; - -} - -function replace_by_id_206172(id_206174, new_tree_206175) { - var F={procname:"dochack.replaceById",prev:framePtr,filename:"dochack.nim",line:0}; - framePtr = F; - F.line = 32; - var x_206176 = document.getElementById(id_206174); - F.line = 33; - x_206176.parentNode.replaceChild(new_tree_206175, x_206176); - F.line = 34; - new_tree_206175.id = id_206174; - framePtr = F.prev; - - -} - -function togglevis_207329(d_207331) { - var F={procname:"dochack.togglevis",prev:framePtr,filename:"dochack.nim",line:0}; - framePtr = F; - F.line = 230; - if (d_207331.style.display == 'none') - d_207331.style.display = 'inline'; - else - d_207331.style.display = 'none'; - - framePtr = F.prev; - - -} - -function groupBy(value_207347) { - var F={procname:"dochack.groupBy",prev:framePtr,filename:"dochack.nim",line:0}; - framePtr = F; - F.line = 238; - var toc_207348 = document.getElementById("toc-list"); - if ((alternative_207315[0] == null)) { - F.line = 240; - var tt_207367 = {heading: null, kids: [], sortId: 0, doSort: false}; - F.line = 241; - to_toc_206688(toc_207348, tt_207367); - F.line = 242; - tt_207367 = tt_207367.kids[chckIndx(0, 0, tt_207367.kids.length+0-1)-0]; - F.line = 244; - var types_207382 = [[]]; - F.line = 245; - var procs_207397 = [[]]; - F.line = 247; - extract_items_206339(tt_207367, "Types", types_207382, 0); - F.line = 248; - extract_items_206339(tt_207367, "Procs", procs_207397, 0); - F.line = 249; - extract_items_206339(tt_207367, "Converters", procs_207397, 0); - F.line = 250; - extract_items_206339(tt_207367, "Methods", procs_207397, 0); - F.line = 251; - extract_items_206339(tt_207367, "Templates", procs_207397, 0); - F.line = 252; - extract_items_206339(tt_207367, "Macros", procs_207397, 0); - F.line = 253; - extract_items_206339(tt_207367, "Iterators", procs_207397, 0); - F.line = 255; - var ntoc_207405 = build_toc_207063(tt_207367, types_207382[0], procs_207397[0]); - F.line = 256; - var x_207406 = to_html_206424(ntoc_207405, true); - F.line = 257; - alternative_207315[0] = tree_206020(makeNimstrLit("DIV"), [x_207406]); - } - - if ((value_207347 == "type")) { - F.line = 259; - replace_by_id_206172("tocRoot", alternative_207315[0]); - } - else { - F.line = 261; - replace_by_id_206172("tocRoot", tree_206020(makeNimstrLit("DIV"), [])); - } - - F.line = 262; - togglevis_207329(document.getElementById("toc-list")); - framePtr = F.prev; - - -} -var db_207523 = [null]; -var contents_207525 = [null]; -var oldtoc_207959 = [null]; -var timer_207960 = [null]; - -function raiseRangeError() { - var e_65441 = null; - e_65441 = {m_type: NTI47862, parent: null, name: null, message: null, trace: null, raiseId: 0, up: null}; - e_65441.message = nimCopy(null, makeNimstrLit("value out of range"), NTI44040); - e_65441.parent = null; - raiseException(e_65441, "RangeError"); - - -} - -function nsuToLowerAsciiChar(c_194780) { - var result_194781 = 0; - - var F={procname:"strutils.toLowerAscii",prev:framePtr,filename:"strutils.nim",line:0}; - framePtr = F; - if ((ConstSet2[c_194780] != undefined)) { - F.line = 222; - result_194781 = chckRange(addInt(c_194780, 32), 0, 255); - } - else { - F.line = 224; - result_194781 = c_194780; - } - - framePtr = F.prev; - - return result_194781; - -} - -function fuzzy_match_205070(pattern_205072, str_205073) { - var Tmp4; - var Tmp5; - var Tmp6; - - var result_205077 = {Field0: 0, Field1: false}; - - var F={procname:"fuzzysearch.fuzzyMatch",prev:framePtr,filename:"fuzzysearch.nim",line:0}; - framePtr = F; - F.line = 37; - var score_state_205078 = -100; - F.line = 38; - var header_matched_205079 = false; - F.line = 39; - var unmatched_leading_char_count_205081 = 0; - F.line = 40; - var consecutive_match_count_205083 = 0; - F.line = 41; - var str_index_205085 = 0; - F.line = 42; - var pat_index_205087 = 0; - F.line = 43; - var score_205089 = 0; - L1: do { - F.line = 49; - L2: while (true) { - if (!((str_index_205085 < (str_205073 != null ? str_205073.length : 0)) && (pat_index_205087 < (pattern_205072 != null ? pattern_205072.length : 0)))) break L2; - L3: do { - F.line = 51; - var pattern_char_205095 = nsuToLowerAsciiChar(pattern_205072.charCodeAt(chckIndx(pat_index_205087, 0, pattern_205072.length+0-1)-0)); - F.line = 52; - var str_char_205096 = nsuToLowerAsciiChar(str_205073.charCodeAt(chckIndx(str_index_205085, 0, str_205073.length+0-1)-0)); - if ((ConstSet3[pattern_char_205095] != undefined)) { - F.line = 56; - pat_index_205087 = addInt(pat_index_205087, 1); - F.line = 57; - break L3; - } - - if ((ConstSet4[str_char_205096] != undefined)) { - F.line = 59; - str_index_205085 = addInt(str_index_205085, 1); - F.line = 60; - break L3; - } - - if ((!(header_matched_205079) && (str_char_205096 == 58))) { - F.line = 65; - header_matched_205079 = true; - F.line = 66; - score_state_205078 = -100; - F.line = 67; - score_205089 = Math.trunc(Math.floor((5.0000000000000000e-01 * score_205089))); - F.line = 68; - pat_index_205087 = 0; - F.line = 69; - str_index_205085 = addInt(str_index_205085, 1); - F.line = 70; - break L3; - } - - if ((str_char_205096 == pattern_char_205095)) { - F.line = 73; - switch (score_state_205078) { - case -100: - case 20: - F.line = 75; - score_state_205078 = 10; - break; - case 0: - F.line = 78; - score_state_205078 = 5; - F.line = 78; - score_205089 = addInt(score_205089, score_state_205078); - break; - case 10: - case 5: - F.line = 81; - consecutive_match_count_205083 = addInt(consecutive_match_count_205083, 1); - F.line = 82; - score_state_205078 = 5; - F.line = 83; - score_205089 = addInt(score_205089, mulInt(5, consecutive_match_count_205083)); - if ((score_state_205078 == 10)) { - F.line = 86; - score_205089 = addInt(score_205089, 10); - } - - F.line = 88; - var on_boundary_205171 = (pat_index_205087 == (pattern_205072 != null ? (pattern_205072.length-1) : -1)); - if ((!(on_boundary_205171) && (str_index_205085 < (str_205073 != null ? (str_205073.length-1) : -1)))) { - F.line = 91; - var next_pattern_char_205172 = nsuToLowerAsciiChar(pattern_205072.charCodeAt(chckIndx(addInt(pat_index_205087, 1), 0, pattern_205072.length+0-1)-0)); - F.line = 92; - var next_str_char_205173 = nsuToLowerAsciiChar(str_205073.charCodeAt(chckIndx(addInt(str_index_205085, 1), 0, str_205073.length+0-1)-0)); - F.line = 95; - if (!!((ConstSet5[next_str_char_205173] != undefined))) Tmp4 = false; else { Tmp4 = !((next_str_char_205173 == next_pattern_char_205172)); } on_boundary_205171 = Tmp4; - } - - if (on_boundary_205171) { - F.line = 100; - score_state_205078 = 20; - F.line = 100; - score_205089 = addInt(score_205089, score_state_205078); - } - - break; - case -1: - case -3: - F.line = 103; - if (!((ConstSet6[str_205073.charCodeAt(chckIndx(subInt(str_index_205085, 1), 0, str_205073.length+0-1)-0)] != undefined))) Tmp5 = true; else { if (!(ConstSet7[str_205073.charCodeAt(chckIndx(subInt(str_index_205085, 1), 0, str_205073.length+0-1)-0)] != undefined)) Tmp6 = false; else { Tmp6 = (ConstSet8[str_205073.charCodeAt(chckIndx(str_index_205085, 0, str_205073.length+0-1)-0)] != undefined); } Tmp5 = Tmp6; } var is_leading_char_205211 = Tmp5; - if (is_leading_char_205211) { - F.line = 110; - score_state_205078 = 10; - } - else { - F.line = 114; - score_state_205078 = 0; - F.line = 114; - score_205089 = addInt(score_205089, score_state_205078); - } - - break; - } - F.line = 115; - pat_index_205087 = addInt(pat_index_205087, 1); - } - else { - F.line = 118; - switch (score_state_205078) { - case -100: - F.line = 120; - score_state_205078 = -3; - F.line = 120; - score_205089 = addInt(score_205089, score_state_205078); - break; - case 5: - F.line = 123; - score_state_205078 = -1; - F.line = 123; - score_205089 = addInt(score_205089, score_state_205078); - F.line = 124; - consecutive_match_count_205083 = 0; - break; - case -3: - if ((unmatched_leading_char_count_205081 < 3)) { - F.line = 128; - score_state_205078 = -3; - F.line = 128; - score_205089 = addInt(score_205089, score_state_205078); - } - - F.line = 129; - unmatched_leading_char_count_205081 = addInt(unmatched_leading_char_count_205081, 1); - break; - default: - F.line = 132; - score_state_205078 = -1; - F.line = 132; - score_205089 = addInt(score_205089, score_state_205078); - break; - } - } - - F.line = 134; - str_index_205085 = addInt(str_index_205085, 1); - } while(false); - } - } while(false); - F.line = 137; - var colontmp__208063 = nimMax(0, score_205089); - F.line = 138; - var colontmp__208064 = (0 < score_205089); - F.line = 136; - nimCopy(result_205077, {Field0: colontmp__208063, Field1: colontmp__208064}, NTI205074); - framePtr = F.prev; - - return result_205077; - -} - -function text_206120(s_206122) { - var result_206123 = null; - - var F={procname:"dochack.text",prev:framePtr,filename:"dochack.nim",line:0}; - framePtr = F; - F.line = 26; - result_206123 = document.createTextNode(toJSStr(s_206122)); - framePtr = F.prev; - - return result_206123; - -} - -function dosearch_207557(value_207559) { - - function HEX3Aanonymous_207871(a_207880, b_207881) { - var result_207885 = 0; - - var F={procname:"dosearch.:anonymous",prev:framePtr,filename:"dochack.nim",line:0}; - framePtr = F; - F.line = 305; - result_207885 = subInt(b_207881["Field1"], a_207880["Field1"]); - framePtr = F.prev; - - return result_207885; - - } - - var result_207560 = null; - - var F={procname:"dochack.dosearch",prev:framePtr,filename:"dochack.nim",line:0}; - framePtr = F; - if (((db_207523[0] != null ? db_207523[0].length : 0) == 0)) { - F.line = 272; - var stuff_207566 = null; - F.line = 273; - var request = new XMLHttpRequest(); - request.open("GET", "theindex.html", false); - request.send(null); - - var doc = document.implementation.createHTMLDocument("theindex"); - doc.documentElement.innerHTML = request.responseText; - - //parser=new DOMParser(); - //doc=parser.parseFromString("", "text/html"); - - stuff_207566 = doc.documentElement; - - F.line = 286; - db_207523[0] = nimCopy(null, stuff_207566.getElementsByClassName("reference"), NTI87305); - F.line = 287; - contents_207525[0] = nimCopy(null, [], NTI207579); - L1: do { - F.line = 288; - var ahref_207814 = null; - F.line = 185; - var i_208043 = 0; - F.line = 186; - var l_208044 = (db_207523[0] != null ? db_207523[0].length : 0); - L2: do { - F.line = 187; - L3: while (true) { - if (!(i_208043 < l_208044)) break L3; - F.line = 288; - ahref_207814 = db_207523[0][chckIndx(i_208043, 0, db_207523[0].length+0-1)-0]; - F.line = 289; - if (contents_207525[0] != null) { contents_207525[0].push(ahref_207814.getAttribute("data-doc-search-tag")); } else { contents_207525[0] = [ahref_207814.getAttribute("data-doc-search-tag")]; }; - F.line = 189; - i_208043 = addInt(i_208043, 1); - if (!(((db_207523[0] != null ? db_207523[0].length : 0) == l_208044))) { - F.line = 190; - failed_assert_impl_58851(makeNimstrLit("/home/genotrance/programming/nimdevel/lib/system/iterators.nim(190, 11) `len(a) == L` the length of the seq changed while iterating over it")); - } - - } - } while(false); - } while(false); - } - - F.line = 290; - var ul_207825 = tree_206020(makeNimstrLit("UL"), []); - F.line = 291; - result_207560 = tree_206020(makeNimstrLit("DIV"), []); - F.line = 292; - set_class_206103(result_207560, makeNimstrLit("search_results")); - F.line = 293; - var matches_207844 = []; - L4: do { - F.line = 294; - var i_207857 = 0; - F.line = 2716; - var colontmp__208050 = 0; - F.line = 294; - colontmp__208050 = (db_207523[0] != null ? db_207523[0].length : 0); - F.line = 2717; - var i_208051 = 0; - L5: do { - F.line = 2718; - L6: while (true) { - if (!(i_208051 < colontmp__208050)) break L6; - F.line = 294; - i_207857 = i_208051; - L7: do { - F.line = 295; - var c_207858 = contents_207525[0][chckIndx(i_207857, 0, contents_207525[0].length+0-1)-0]; - if (((c_207858 == "Examples") || (c_207858 == "PEG construction"))) { - F.line = 300; - break L7; - } - - F.line = 301; - var colontmp__208060 = {Field0: 0, Field1: false}; - F.line = 301; - var score_207859 = 0; - F.line = 301; - var matched_207860 = false; - F.line = 301; - nimCopy(colontmp__208060, fuzzy_match_205070(value_207559, c_207858), NTI205074); - F.line = 301; - score_207859 = colontmp__208060["Field0"]; - F.line = 301; - matched_207860 = colontmp__208060["Field1"]; - if (matched_207860) { - F.line = 303; - if (matches_207844 != null) { matches_207844.push({Field0: db_207523[0][chckIndx(i_207857, 0, db_207523[0].length+0-1)-0], Field1: score_207859}); } else { matches_207844 = [{Field0: db_207523[0][chckIndx(i_207857, 0, db_207523[0].length+0-1)-0], Field1: score_207859}]; }; - } - - } while(false); - F.line = 2720; - i_208051 = addInt(i_208051, 1); - } - } while(false); - } while(false); - F.line = 305; - matches_207844.sort(HEX3Aanonymous_207871); - L8: do { - F.line = 306; - var i_207924 = 0; - F.line = 2716; - var colontmp__208056 = 0; - F.line = 306; - colontmp__208056 = nimMin((matches_207844 != null ? matches_207844.length : 0), 19); - F.line = 2717; - var i_208057 = 0; - L9: do { - F.line = 2718; - L10: while (true) { - if (!(i_208057 < colontmp__208056)) break L10; - F.line = 306; - i_207924 = i_208057; - F.line = 307; - matches_207844[chckIndx(i_207924, 0, matches_207844.length+0-1)-0]["Field0"].innerHTML = matches_207844[chckIndx(i_207924, 0, matches_207844.length+0-1)-0]["Field0"].getAttribute("data-doc-search-tag"); - F.line = 308; - add_206085(ul_207825, tree_206020(makeNimstrLit("LI"), [matches_207844[chckIndx(i_207924, 0, matches_207844.length+0-1)-0]["Field0"]])); - F.line = 2720; - i_208057 = addInt(i_208057, 1); - } - } while(false); - } while(false); - if ((ul_207825.childNodes.length == 0)) { - F.line = 310; - add_206085(result_207560, tree_206020(makeNimstrLit("B"), [text_206120(makeNimstrLit("no search results"))])); - } - else { - F.line = 312; - add_206085(result_207560, tree_206020(makeNimstrLit("B"), [text_206120(makeNimstrLit("search results"))])); - F.line = 313; - add_206085(result_207560, ul_207825); - } - - framePtr = F.prev; - - return result_207560; - -} - -function search() { - - function wrapper_207991() { - var F={procname:"search.wrapper",prev:framePtr,filename:"dochack.nim",line:0}; - framePtr = F; - F.line = 320; - var elem_207993 = document.getElementById("searchInput"); - F.line = 321; - var value_207994 = elem_207993.value; - if (!(((value_207994 != null ? value_207994.length : 0) == 0))) { - if ((oldtoc_207959[0] == null)) { - F.line = 324; - oldtoc_207959[0] = document.getElementById("tocRoot"); - } - - F.line = 325; - var results_208000 = dosearch_207557(value_207994); - F.line = 326; - replace_by_id_206172("tocRoot", results_208000); - } - else { - if (!((oldtoc_207959[0] == null))) { - F.line = 328; - replace_by_id_206172("tocRoot", oldtoc_207959[0]); - } - } - framePtr = F.prev; - - - } - - var F={procname:"dochack.search",prev:framePtr,filename:"dochack.nim",line:0}; - framePtr = F; - if (!((timer_207960[0] == null))) { - F.line = 330; - clearTimeout(timer_207960[0]); - } - - F.line = 331; - timer_207960[0] = setTimeout(wrapper_207991, 400); - framePtr = F.prev; - - -} diff --git a/git.html b/git.html index dfaf0fb..78b555f 100644 --- a/git.html +++ b/git.html @@ -27,130 +27,232 @@ customize this style sheet. Modified from Chad Skeeters' rst2html-style https://bitbucket.org/cskeeters/rst2html-style/ -Modified by Boyd Greenfield and narimiran +Modified by Boyd Greenfield */ - +/* SCSS variables */ +/* Text weights */ +/* Body colors */ +/* Text colors */ +/* Link colors */ +/* Syntax highlighting colors */ +/* Pct changes */ +/* Mixins */ +/* Body/layout */ html { font-size: 100%; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; } +/* Where we want fancier font if available */ +h1, h2, h3, h4, h5, h6, p.module-desc, table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; } + +h1.title { + font-weight: 900; } + body { font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: 400; - font-size: 1.125em; - line-height: 1.5; - color: #222; - background-color: #FCFCFC; } + font-size: 16px; + line-height: 20px; + color: #444; + letter-spacing: 0.15px; + background-color: #FDFBFA; } /* Skeleton grid */ .container { position: relative; width: 100%; - max-width: 1050px; + max-width: 960px; margin: 0 auto; - padding: 0; + padding: 0 20px; box-sizing: border-box; } .column, .columns { width: 100%; float: left; - box-sizing: border-box; - margin-left: 1%; -} + box-sizing: border-box; } -.column:first-child, -.columns:first-child { - margin-left: 0; } +/* For devices larger than 400px */ +@media (min-width: 400px) { + .container { + width: 100%; + padding: 0; } } +/* For devices larger than 650px */ +@media (min-width: 650px) { + .container { + width: 100%; } -.three.columns { - width: 19%; } + .column, + .columns { + margin-left: 4%; } -.nine.columns { - width: 80.0%; } + .column:first-child, + .columns:first-child { + margin-left: 0; } -.twelve.columns { - width: 100%; - margin-left: 0; } + .one.column, + .one.columns { + width: 4.66666666667%; } + + .two.columns { + width: 13.3333333333%; } -@media screen and (max-width: 860px) { .three.columns { - display: none; - } + width: 22%; } + + .four.columns { + width: 30.6666666667%; } + + .five.columns { + width: 39.3333333333%; } + + .six.columns { + width: 48%; } + + .seven.columns { + width: 56.6666666667%; } + + .eight.columns { + width: 65.3333333333%; } + .nine.columns { - width: 98.0%; - } - body { - font-size: 1em; - line-height: 1.35; - } -} + width: 74.0%; } + + .ten.columns { + width: 82.6666666667%; } + + .eleven.columns { + width: 91.3333333333%; } + + .twelve.columns { + width: 100%; + margin-left: 0; } + + .one-third.column { + width: 30.6666666667%; } + + .two-thirds.column { + width: 65.3333333333%; } } +/* Customer Overrides */ +.footer { + text-align: center; + color: #969696; + padding-top: 10%; } + +p.module-desc { + font-size: 1.1em; + color: #666666; } + +a.link-seesrc { + color: #aec7d2; + font-style: italic; } + +a.link-seesrc:hover { + color: #6c9aae; } + +#toc-list { + word-wrap: break-word; } + +ul.simple-toc { + list-style: none; } + +ul.simple-toc a.reference-toplevel { + font-weight: bold; + color: #0077b3; } + +ul.simple-toc-section { + list-style-type: circle; + color: #6c9aae; } + +ul.simple-toc-section a.reference { + color: #0077b3; } cite { font-style: italic !important; } +dt > pre { + border-color: rgba(0, 0, 0, 0.1); + background-color: rgba(255, 255, 255, 0.3); + margin: 15px 0px 5px; } + +dd > pre { + border-color: rgba(0, 0, 0, 0.1); + background-color: whitesmoke; + margin-top: 8px; } + +.item > dd { + margin-left: 10px; + margin-bottom: 30px; } + +/* Nim line-numbered tables */ +.line-nums-table { + width: 100%; + table-layout: fixed; } /* Nim search input */ div#searchInputDiv { - margin-bottom: 1em; + margin-bottom: 8px; } -input#searchInput { - width: 80%; +div#searchInputDiv input#searchInput { + width: 10em; +} +div.search-groupby { + margin-bottom: 8px; } -/* - * Some custom formatting for input forms. - * This also fixes input form colors on Firefox with a dark system theme on Linux. - */ -input { - -moz-appearance: none; - color: #333; - background-color: #f8f8f8; - border: 1px solid #aaa; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-size: 0.9em; - padding: 6px; -} -input:focus { - border: 1px solid #1fa0eb; - box-shadow: 0 0 2px #1fa0eb; -} +table.line-nums-table { + border-radius: 4px; + border: 1px solid #cccccc; + background-color: whitesmoke; + border-collapse: separate; + margin-top: 15px; + margin-bottom: 25px; } + +.line-nums-table tbody { + border: none; } + +.line-nums-table td pre { + border: none; + background-color: transparent; } + +.line-nums-table td.blob-line-nums { + width: 28px; } + +.line-nums-table td.blob-line-nums pre { + color: #b0b0b0; + -webkit-filter: opacity(75%); + text-align: right; + border-color: transparent; + background-color: transparent; + padding-left: 0px; + margin-left: 0px; + padding-right: 0px; + margin-right: 0px; } /* Docgen styles */ /* Links */ a { - color: #07b; - text-decoration: none; -} - -a span.Identifier { - text-decoration: underline; - text-decoration-color: #aab; -} - -a.reference-toplevel { - font-weight: bold; -} - -a.toc-backref { - text-decoration: none; - color: #222; } - -a.link-seesrc { - color: #607c9f; - font-size: 0.9em; - font-style: italic; } + color: #0077b3; + text-decoration: none; } a:hover, a:focus { - color: #607c9f; + color: #00334d; text-decoration: underline; } -a:hover span.Identifier { - color: #607c9f; -} +a:visited { + color: #00334d; } +a:focus { + outline: thin dotted #2d2d2d; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; } + +a:hover, +a:active { + outline: 0; } sub, sup { @@ -227,258 +329,379 @@ img { h2, h3 { - page-break-after: avoid; } -} + page-break-after: avoid; } } +.img-rounded { + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; } +.img-polaroid { + padding: 4px; + background-color: rgba(252, 248, 244, 0.75); + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.2); + -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); } p { - margin-top: 0.5em; - margin-bottom: 0.5em; -} + margin: 0 0 8px; } small { font-size: 85%; } strong { - font-weight: 600; - font-size: 0.95em; - color: #3c3c3c; -} + font-weight: 600; } em { font-style: italic; } +cite { + font-style: normal; } + +h1, +h2, +h3, +h4, +h5, +h6 { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-weight: 600; + line-height: 20px; + color: inherit; + text-rendering: optimizelegibility; } + h1 { - font-size: 1.8em; + font-size: 2em; font-weight: 400; - padding-bottom: .25em; - border-bottom: 1px solid #aaa; - margin-top: 2.5em; - margin-bottom: 1em; + padding-bottom: .15em; + border-bottom: 1px solid #aaaaaa; + margin-top: 1.0em; line-height: 1.2em; } h1.title { padding-bottom: 1em; border-bottom: 0px; - font-size: 2.5em; - text-align: center; - font-weight: 900; - margin-top: 0.75em; - margin-bottom: 0em; -} + font-size: 2.75em; } h2 { - font-size: 1.3em; - margin-top: 2em; } - -h2.subtitle { - text-align: center; } - -h3 { - font-size: 1.125em; - font-style: italic; + font-size: 1.5em; margin-top: 1.5em; } +h3 { + font-size: 1.3em; + font-style: italic; + margin-top: 0.75em; } + h4 { - font-size: 1.125em; - margin-top: 1em; } + font-size: 1.3em; + margin-top: 0.5em; } h5 { - font-size: 1.125em; - margin-top: 0.75em; } + font-size: 1.2em; + margin-top: 0.25em; } h6 { font-size: 1.1em; } - ul, ol { padding: 0; - margin-top: 0.5em; - margin-left: 0.75em; } + margin: 0 0 0px 15px; } ul ul, ul ol, ol ol, ol ul { - margin-bottom: 0; - margin-left: 1.25em; } + margin-bottom: 0; } li { - list-style-type: circle; -} - -ul.simple-boot li { - list-style-type: none; - margin-left: 0em; - margin-bottom: 0.5em; -} - -ol.simple > li, ul.simple > li { - margin-bottom: 0.25em; - margin-left: 0.4em } - -ul.simple.simple-toc > li { - margin-top: 1em; -} - -ul.simple-toc { - list-style: none; - font-size: 0.9em; - margin-left: -0.3em; - margin-top: 1em; } - -ul.simple-toc > li { - list-style-type: none; -} - -ul.simple-toc-section { - list-style-type: circle; - margin-left: 1em; - color: #6c9aae; } - - -ol.arabic { - list-style: decimal; } - -ol.loweralpha { - list-style: lower-alpha; } - -ol.upperalpha { - list-style: upper-alpha; } - -ol.lowerroman { - list-style: lower-roman; } - -ol.upperroman { - list-style: upper-roman; } - -ul.auto-toc { - list-style-type: none; } - + line-height: 20px; } dl { - margin-bottom: 1.5em; } + margin-bottom: 20px; } + +dt, +dd { + line-height: 20px; } dt { - margin-bottom: -0.5em; - margin-left: 0.0em; } + font-weight: bold; } dd { - margin-left: 2.0em; - margin-bottom: 3.0em; - margin-top: 0.5em; } - + margin-left: 10px; + margin-bottom: 26px; } hr { - margin: 2em 0; + margin: 20px 0; border: 0; - border-top: 1px solid #aaa; } + border-top: 1px solid #eeeeee; + border-bottom: 1px solid #ffffff; } + +abbr[title], +abbr[data-original-title] { + cursor: help; + border-bottom: 1px dotted #999999; } + +abbr.initialism { + font-size: 90%; + text-transform: uppercase; } blockquote { - font-size: 0.9em; - font-style: italic; - padding-left: 0.5em; - margin-left: 0; - border-left: 5px solid #bbc; + padding: 0 0 0 15px; + margin: 0 0 20px; + border-left: 5px solid #EFEBE0; } + +table.docinfo + blockquote, table.docinfo blockquote, h1 + blockquote { + border-left: 5px solid #c9c9c9; } +table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { + margin-bottom: 0; + font-size: 15px; + font-weight: 200; + line-height: 1.5; + font-style: italic; } + +q:before, +q:after, +blockquote:before, +blockquote:after { + content: ""; } + +address { + display: block; + margin-bottom: 20px; + font-style: normal; + line-height: 20px; } + +code, +pre { + font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; + padding: 0 3px 2px; + font-weight: 500; + font-size: 12px; + color: #444444; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; } + .pre { font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - font-weight: 500; - font-size: 0.85em; - background-color: #f0f3ff; - padding-left: 3px; - padding-right: 3px; - border-radius: 4px; + font-weight: 600; + /*color: #504da6;*/ } +code { + padding: 2px 4px; + color: #444444; + white-space: nowrap; + background-color: white; + border: 1px solid #777777; } + pre { - font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - color: #222; - font-weight: 500; display: inline-block; box-sizing: border-box; - min-width: 100%; - padding: 0.5em; - margin-top: 0.5em; - margin-bottom: 0.5em; - font-size: 0.85em; + min-width: calc(100% - 19.5px); + padding: 9.5px; + margin: 0.25em 10px 10px 10px; + font-size: 15px; + line-height: 20px; white-space: pre !important; overflow-y: hidden; overflow-x: visible; - background-color: ghostwhite; - border: 1px solid #dde; - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; } + background-color: rgba(0, 0, 0, 0.01); + border: 1px solid #cccccc; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; } + +pre.prettyprint { + margin-bottom: 20px; } + +pre code { + padding: 0; + color: inherit; + white-space: pre; + overflow-x: visible; + background-color: transparent; + border: 0; } .pre-scrollable { max-height: 340px; overflow-y: scroll; } - -/* Nim line-numbered tables */ -.line-nums-table { - width: 100%; - table-layout: fixed; } - -table.line-nums-table { - border-radius: 4px; - border: 1px solid #cccccc; - background-color: ghostwhite; - border-collapse: separate; - margin-top: 15px; - margin-bottom: 25px; } - -.line-nums-table tbody { - border: none; } - -.line-nums-table td pre { - border: none; - background-color: transparent; } - -.line-nums-table td.blob-line-nums { - width: 28px; } - -.line-nums-table td.blob-line-nums pre { - color: #b0b0b0; - -webkit-filter: opacity(75%); - text-align: right; - border-color: transparent; - background-color: transparent; - padding-left: 0px; - margin-left: 0px; - padding-right: 0px; - margin-right: 0px; } - - table { max-width: 100%; background-color: transparent; - margin-top: 0.5em; - margin-bottom: 1.5em; border-collapse: collapse; - border-color: #ccc; - border-spacing: 0; - font-size: 0.9em; -} + border-spacing: 0; } table th, table td { - padding: 0px 0.5em 0px; + padding: 0px 8px 0px; } -table th { - background-color: #e8e8e8; +.table { + width: 100%; + margin-bottom: 20px; } + +.table th, +.table td { + padding: 8px; + line-height: 20px; + text-align: left; + vertical-align: top; + border-top: 1px solid #444444; } + +.table th { font-weight: bold; } -table th.docinfo-name { - background-color: transparent; -} +.table thead th { + vertical-align: bottom; } -table tr:hover { - background-color: ghostwhite; } +.table caption + thead tr:first-child th, +.table caption + thead tr:first-child td, +.table colgroup + thead tr:first-child th, +.table colgroup + thead tr:first-child td, +.table thead:first-child tr:first-child th, +.table thead:first-child tr:first-child td { + border-top: 0; } +.table tbody + tbody { + border-top: 2px solid #444444; } + +.table .table { + background-color: rgba(252, 248, 244, 0.75); } + +.table-condensed th, +.table-condensed td { + padding: 4px 5px; } + +.table-bordered { + border: 1px solid #444444; + border-collapse: separate; + *border-collapse: collapse; + border-left: 0; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; } + +.table-bordered th, +.table-bordered td { + border-left: 1px solid #444444; } + +.table-bordered caption + thead tr:first-child th, +.table-bordered caption + tbody tr:first-child th, +.table-bordered caption + tbody tr:first-child td, +.table-bordered colgroup + thead tr:first-child th, +.table-bordered colgroup + tbody tr:first-child th, +.table-bordered colgroup + tbody tr:first-child td, +.table-bordered thead:first-child tr:first-child th, +.table-bordered tbody:first-child tr:first-child th, +.table-bordered tbody:first-child tr:first-child td { + border-top: 0; } + +.table-bordered thead:first-child tr:first-child > th:first-child, +.table-bordered tbody:first-child tr:first-child > td:first-child, +.table-bordered tbody:first-child tr:first-child > th:first-child { + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; } + +.table-bordered thead:first-child tr:first-child > th:last-child, +.table-bordered tbody:first-child tr:first-child > td:last-child, +.table-bordered tbody:first-child tr:first-child > th:last-child { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; } + +.table-bordered thead:last-child tr:last-child > th:first-child, +.table-bordered tbody:last-child tr:last-child > td:first-child, +.table-bordered tbody:last-child tr:last-child > th:first-child, +.table-bordered tfoot:last-child tr:last-child > td:first-child, +.table-bordered tfoot:last-child tr:last-child > th:first-child { + -webkit-border-bottom-left-radius: 4px; + border-bottom-left-radius: 4px; + -moz-border-radius-bottomleft: 4px; } + +.table-bordered thead:last-child tr:last-child > th:last-child, +.table-bordered tbody:last-child tr:last-child > td:last-child, +.table-bordered tbody:last-child tr:last-child > th:last-child, +.table-bordered tfoot:last-child tr:last-child > td:last-child, +.table-bordered tfoot:last-child tr:last-child > th:last-child { + -webkit-border-bottom-right-radius: 4px; + border-bottom-right-radius: 4px; + -moz-border-radius-bottomright: 4px; } + +.table-bordered tfoot + tbody:last-child tr:last-child td:first-child { + -webkit-border-bottom-left-radius: 0; + border-bottom-left-radius: 0; + -moz-border-radius-bottomleft: 0; } + +.table-bordered tfoot + tbody:last-child tr:last-child td:last-child { + -webkit-border-bottom-right-radius: 0; + border-bottom-right-radius: 0; + -moz-border-radius-bottomright: 0; } + +.table-bordered caption + thead tr:first-child th:first-child, +.table-bordered caption + tbody tr:first-child td:first-child, +.table-bordered colgroup + thead tr:first-child th:first-child, +.table-bordered colgroup + tbody tr:first-child td:first-child { + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; } + +.table-bordered caption + thead tr:first-child th:last-child, +.table-bordered caption + tbody tr:first-child td:last-child, +.table-bordered colgroup + thead tr:first-child th:last-child, +.table-bordered colgroup + tbody tr:first-child td:last-child { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; } + +table.docutils th { + background-color: #e8e8e8; } + +table.docutils tr:hover { + background-color: whitesmoke; } + +.table-striped tbody > tr:nth-child(odd) > td, +.table-striped tbody > tr:nth-child(odd) > th { + background-color: rgba(252, 248, 244, 0.75); } + +.table-hover tbody tr:hover > td, +.table-hover tbody tr:hover > th { + background-color: rgba(241, 222, 204, 0.75); } + +table td[class*="span"], +table th[class*="span"], +.row-fluid table td[class*="span"], +.row-fluid table th[class*="span"] { + display: table-cell; + float: none; + margin-left: 0; } + +.hero-unit { + padding: 60px; + margin-bottom: 30px; + font-size: 18px; + font-weight: 200; + line-height: 30px; + color: inherit; + background-color: rgba(230, 197, 164, 0.75); + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; } + +.hero-unit h1 { + margin-bottom: 0; + font-size: 60px; + line-height: 1; + letter-spacing: -1px; + color: inherit; } + +.hero-unit li { + line-height: 30px; } /* rst2html default used to remove borders from tables and images */ .borderless, table.borderless td, table.borderless th { @@ -499,6 +722,10 @@ table.borderless td, table.borderless th { .hidden { display: none; } +a.toc-backref { + text-decoration: none; + color: #444444; } + blockquote.epigraph { margin: 2em 5em; } @@ -508,6 +735,85 @@ dl.docutils dd { object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] { overflow: hidden; } +/* Uncomment (and remove this text!) to get bold-faced definition list terms +dl.docutils dt { + font-weight: bold } +*/ +div.abstract { + margin: 2em 5em; } + +div.abstract p.topic-title { + font-weight: bold; + text-align: center; } + +div.admonition, div.attention, div.caution, div.danger, div.error, +div.hint, div.important, div.note, div.tip, div.warning { + margin: 2em; + border: medium outset; + padding: 1em; } + +div.note, div.warning { + margin: 1.5em 0px; + border: none; } + +div.note p.admonition-title, +div.warning p.admonition-title { + display: none; } + +/* Clearfix + * http://css-tricks.com/snippets/css/clear-fix/ + */ +div.note:after, +div.warning:after { + content: ""; + display: table; + clear: both; } + +div.note p:before, +div.warning p:before { + display: block; + float: left; + font-size: 4em; + line-height: 1em; + margin-right: 20px; + margin-left: 0em; + margin-top: -10px; + content: '\0270D'; + /*handwriting*/ } + +div.warning p:before { + content: '\026A0'; + /*warning*/ } + +div.admonition p.admonition-title, div.hint p.admonition-title, +div.important p.admonition-title, div.note p.admonition-title, +div.tip p.admonition-title { + font-weight: bold; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } + +div.attention p.admonition-title, div.caution p.admonition-title, +div.danger p.admonition-title, div.error p.admonition-title, +div.warning p.admonition-title, .code .error { + color: #b30000; + font-weight: bold; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } + +/* Uncomment (and remove this text!) to get reduced vertical space in + compound paragraphs. +div.compound .compound-first, div.compound .compound-middle { + margin-bottom: 0.5em } + +div.compound .compound-last, div.compound .compound-middle { + margin-top: 0.5em } +*/ +div.dedication { + margin: 2em 5em; + text-align: center; + font-style: italic; } + +div.dedication p.topic-title { + font-weight: bold; + font-style: normal; } div.figure { margin-left: 2em; @@ -515,14 +821,8 @@ div.figure { div.footer, div.header { clear: both; - text-align: center; - color: #666; font-size: smaller; } -div.footer { - padding-top: 5em; -} - div.line-block { display: block; margin-top: 1em; @@ -533,24 +833,45 @@ div.line-block div.line-block { margin-bottom: 0; margin-left: 1.5em; } +div.sidebar { + margin: 0 0 0.5em 1em; + border: medium outset; + padding: 1em; + background-color: rgba(252, 248, 244, 0.75); + width: 40%; + float: right; + clear: right; } + +div.sidebar p.rubric { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-size: medium; } + +div.system-messages { + margin: 5em; } + +div.system-messages h1 { + color: #b30000; } + +div.system-message { + border: medium outset; + padding: 1em; } + +div.system-message p.system-message-title { + color: #b30000; + font-weight: bold; } + div.topic { margin: 2em; } -div.search_results { - background-color: antiquewhite; - margin: 3em; - padding: 1em; - border: 1px solid #4d4d4d; -} +h1.section-subtitle, h2.section-subtitle, h3.section-subtitle, +h4.section-subtitle, h5.section-subtitle, h6.section-subtitle { + margin-top: 0.4em; } -div#global-links ul { - margin-left: 0; - list-style-type: none; -} +h1.title { + text-align: center; } -div#global-links > simple-boot { - margin-left: 3em; -} +h2.subtitle { + text-align: center; } hr.docutils { width: 75%; } @@ -584,6 +905,30 @@ img.align-center, .figure.align-center, object.align-center { div.align-right { text-align: inherit; } +/* div.align-center * { */ +/* text-align: left } */ + +ul.simple > li { + margin-bottom: 0.5em } + +ol.simple, ul.simple { + margin-bottom: 1em; } + +ol.arabic { + list-style: decimal; } + +ol.loweralpha { + list-style: lower-alpha; } + +ol.upperalpha { + list-style: upper-alpha; } + +ol.lowerroman { + list-style: lower-roman; } + +ol.upperroman { + list-style: upper-roman; } + p.attribution { text-align: right; margin-left: 50%; } @@ -604,6 +949,15 @@ p.rubric { color: maroon; text-align: center; } +p.sidebar-title { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-weight: bold; + font-size: larger; } + +p.sidebar-subtitle { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-weight: bold; } + p.topic-title { font-weight: bold; } @@ -643,14 +997,22 @@ pre.code .inserted, code .inserted { background-color: #A3D289; } span.classifier { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-style: oblique; } span.classifier-delimiter { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: bold; } +span.interpreted { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } + span.option { white-space: nowrap; } +span.pre { + white-space: pre; } + span.problematic { color: #b30000; } @@ -658,6 +1020,44 @@ span.section-subtitle { /* font-size relative to parent (h1..h6 element) */ font-size: 80%; } +table.citation { + border-left: solid 1px #666666; + margin-left: 1px; } + +table.docinfo { + margin: 0em; + margin-top: 2em; + margin-bottom: 2em; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; + color: #444444; } + +table.docutils { + margin-top: 0.5em; + margin-bottom: 0.5em; } + +table.footnote { + border-left: solid 1px #2d2d2d; + margin-left: 1px; } + +table.docutils td, table.docutils th, +table.docinfo td, table.docinfo th { + padding-left: 0.5em; + padding-right: 0.5em; + vertical-align: top; } + +table.docutils th.field-name, table.docinfo th.docinfo-name { + font-weight: 700; + text-align: left; + white-space: nowrap; + padding-left: 0; } + +h1 tt.docutils, h2 tt.docutils, h3 tt.docutils, +h4 tt.docutils, h5 tt.docutils, h6 tt.docutils { + font-size: 100%; } + +ul.auto-toc { + list-style-type: none; } + span.DecNumber { color: #252dbe; } @@ -674,7 +1074,7 @@ span.FloatNumber { color: #252dbe; } span.Identifier { - color: #222; } + color: #3b3b3b; } span.Keyword { font-weight: 600; @@ -739,23 +1139,38 @@ dt pre > span.Identifier, dt pre > span.Operator { color: #155da4; font-weight: 700; } -dt pre > span.Keyword ~ span.Identifier, dt pre > span.Identifier ~ span.Identifier, -dt pre > span.Operator ~ span.Identifier, dt pre > span.Other ~ span.Identifier { +dt pre > span.Identifier ~ span.Identifier, dt pre > span.Operator ~ span.Identifier { + color: inherit; + font-weight: inherit; } + +dt pre > span.Operator ~ span.Identifier { color: inherit; font-weight: inherit; } /* Nim sprite for the footer (taken from main page favicon) */ .nim-sprite { display: inline-block; - height: 16px; - width: 16px; + height: 12px; + width: 12px; background-position: 0 0; - background-size: 16px 16px; + background-size: 12px 12px; -webkit-filter: opacity(50%); background-repeat: no-repeat; background-image: url("data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="); margin-bottom: -5px; } +div.search_results { + background-color: antiquewhite; + margin: 3em; + padding: 1em; + border: 1px solid #4d4d4d; +} + +div#global-links ul { + margin-left: 0; + list-style-type: none; +} + span.pragmadots { /* Position: relative frees us up to make the dots look really nice without fucking up the layout and @@ -763,14 +1178,18 @@ span.pragmadots { position: relative; /* 1px down looks slightly nicer */ top: 1px; + padding: 2px; - background-color: #e8e8e8; + background-color: #D3D3D3; border-radius: 4px; margin: 0 2px; cursor: pointer; - font-size: 0.8em; -} + /* For some reason on Chrome, making the font size + smaller than 1em is causing the parent container to + bulge slightly. So, we're stuck with inheriting 1em, + which is sad, because 0.8em looks better... */ +} span.pragmadots:hover { background-color: #DBDBDB; } @@ -778,10 +1197,6 @@ span.pragmawrap { display: none; } -span.attachedType { - display: none; - visibility: hidden; -} @@ -833,29 +1248,29 @@ function main() { Procs
    • execAction
    • + title="execAction(cmd: string; nostderr = false): string">execAction
    • mkDir
    • + title="mkDir(dir: string)">mkDir
    • cpFile
    • + title="cpFile(source, dest: string; move = false)">cpFile
    • mvFile
    • + title="mvFile(source, dest: string)">mvFile
    • extractZip
    • + title="extractZip(zipfile, outdir: string)">extractZip
    • downloadUrl
    • + title="downloadUrl(url, outdir: string)">downloadUrl
    • gitReset
    • + title="gitReset(outdir: string)">gitReset
    • gitCheckout
    • + title="gitCheckout(file, outdir: string)">gitCheckout
    • gitPull
    • + title="gitPull(url: string; outdir = ""; plist = ""; checkout = "")">gitPull
    • configure
    • + title="configure(path, check: string; flags = "")">configure
    • cmake
    • + title="cmake(path, check, flags: string)">cmake
    • make
    • + title="make(path, check: string; flags = "")">make
  • @@ -865,7 +1280,6 @@ function main() {
    -

    Imports

    @@ -876,124 +1290,109 @@ function main() {

    Procs

    -
    proc execAction(cmd: string; nostderr = false): string {...}{.
    -    raises: [OSError, Exception, IOError, Defect],
    +
    proc execAction(cmd: string; nostderr = false): string {...}{.raises: [OSError, Exception],
         tags: [ExecIOEffect, ReadIOEffect, RootEffect].}
    -

    Execute an external command - supported at compile time

    Checks if command exits successfully before returning. If not, an error is raised.

    -
    proc mkDir(dir: string) {...}{.raises: [OSError, Exception, IOError, Defect, ValueError], tags: [
    -    ReadDirEffect, ExecIOEffect, ReadIOEffect, RootEffect].}
    +
    proc mkDir(dir: string) {...}{.raises: [OSError, Exception], tags: [ReadDirEffect,
    +    ExecIOEffect, ReadIOEffect, RootEffect].}
    -

    Create a directory at cmopile time

    -

    The os module is not available at compile time so a few crucial helper functions are included with nimterop.

    +

    The os module is not available at compile time so a few crucial helper functions are included with nimterop.

    -
    proc cpFile(source, dest: string; move = false) {...}{.
    -    raises: [OSError, Exception, IOError, Defect, ValueError],
    +
    proc cpFile(source, dest: string; move = false) {...}{.raises: [OSError, Exception],
         tags: [ExecIOEffect, ReadIOEffect, RootEffect].}
    - Copy a file from source to destination at compile time
    -
    proc mvFile(source, dest: string) {...}{.raises: [OSError, Exception, IOError, Defect,
    -                                        ValueError],
    +
    proc mvFile(source, dest: string) {...}{.raises: [OSError, Exception],
                                     tags: [ExecIOEffect, ReadIOEffect, RootEffect].}
    - Move a file from source to destination at compile time
    -
    proc extractZip(zipfile, outdir: string) {...}{.raises: [OSError, Exception, IOError, Defect,
    -    ValueError], tags: [ExecIOEffect, ReadIOEffect, RootEffect].}
    +
    proc extractZip(zipfile, outdir: string) {...}{.raises: [OSError, Exception, ValueError], tags: [
    +    ExecIOEffect, ReadIOEffect, RootEffect].}
    - Extract a zip file using powershell on Windows and unzip on other systems to the specified output directory
    -
    proc downloadUrl(url, outdir: string) {...}{.raises: [OSError, Exception, IOError, Defect,
    -    ValueError], tags: [ReadDirEffect, ExecIOEffect, ReadIOEffect, RootEffect].}
    +
    proc downloadUrl(url, outdir: string) {...}{.raises: [OSError, Exception, ValueError], tags: [
    +    ReadDirEffect, ExecIOEffect, ReadIOEffect, RootEffect].}
    -

    Download a file using powershell on Windows and curl on other systems to the specified output directory

    If a zip file, it is automatically extracted after download.

    -
    proc gitReset(outdir: string) {...}{.raises: [ValueError, OSError, Exception, IOError, Defect], tags: [
    -    ExecIOEffect, ReadIOEffect, RootEffect, TimeEffect].}
    +
    proc gitReset(outdir: string) {...}{.raises: [OSError, Exception], tags: [ExecIOEffect,
    +    ReadIOEffect, RootEffect, TimeEffect].}
    - Hard reset the git repository at the specified directory
    -
    proc gitCheckout(file, outdir: string) {...}{.raises: [ValueError, OSError, Exception,
    -    IOError, Defect], tags: [ExecIOEffect, ReadIOEffect, RootEffect, TimeEffect].}
    +
    proc gitCheckout(file, outdir: string) {...}{.raises: [OSError, Exception], tags: [
    +    ExecIOEffect, ReadIOEffect, RootEffect, TimeEffect].}
    -

    Checkout the specified file in the git repository specified

    -

    This effectively resets all changes in the file and can be used after cImport() if required.

    +

    This effectively resets all changes in the file and can be used to undo any changes that were made to source files to enable successful wrapping with cImport() or c2nImport().

    -
    proc gitPull(url: string; outdir = ""; plist = ""; checkout = "") {...}{.
    -    raises: [ValueError, OSError, Exception, IOError, Defect], tags: [ReadDirEffect,
    -    ExecIOEffect, ReadIOEffect, RootEffect, TimeEffect, WriteIOEffect].}
    +
    proc gitPull(url: string; outdir = ""; plist = ""; checkout = "") {...}{.
    +    raises: [OSError, Exception, IOError], tags: [ReadDirEffect, ExecIOEffect,
    +    ReadIOEffect, RootEffect, TimeEffect, WriteIOEffect].}
    -

    Pull the specified git repository to the output directory

    -

    plist is the list of specific files and directories or wildcards to sparse checkout. Multiples can be specified one entry per line.

    +

    plist is the list of specific files and directories or wildcards to sparsely checkout. Multiple values can be specified one entry per line. It is optional and if omitted, the entire repository will be checked out.

    +

    checkout is the git tag, branch or commit hash to checkout once the repository is downloaded. This allows for pinning to a specific version of the code.

    -
    proc configure(path, check: string; flags = "") {...}{.
    -    raises: [OSError, Exception, IOError, Defect, ValueError],
    +
    proc configure(path, check: string; flags = "") {...}{.raises: [OSError, Exception],
         tags: [ReadDirEffect, ExecIOEffect, ReadIOEffect, RootEffect].}
    - -

    Run the GNU configure command to generate all Makefiles or other build scripts in the specified path

    -

    If a configure script is not present and an autogen.sh script is present, it will be run before attempting configure.

    -

    check is a file that will be generated by the configure command. This is required to prevent configure from running on every build. It is relative to the path and should not be an absolute path.

    -

    flags are any flags that should be passed to the configure command.

    +

    Run the GNU configure command to generate all Makefiles or other build scripts in the specified path

    +

    If a configure script is not present and an autogen.sh script is present, it will be run before attempting configure.

    +

    check is a file that will be generated by the configure command. This is required to prevent configure from running on every build. It is relative to the path and should not be an absolute path.

    +

    flags are any flags that should be passed to the configure command.

    -
    proc cmake(path, check, flags: string) {...}{.raises: [OSError, Exception, IOError, Defect,
    -    ValueError], tags: [ReadDirEffect, ExecIOEffect, ReadIOEffect, RootEffect].}
    +
    proc cmake(path, check, flags: string) {...}{.raises: [OSError, Exception], tags: [
    +    ReadDirEffect, ExecIOEffect, ReadIOEffect, RootEffect].}
    - -

    Run the cmake command to generate all Makefiles or other build scripts in the specified path

    -

    path will be created since typically cmake is run in an empty directory.

    -

    check is a file that will be generated by the cmake command. This is required to prevent cmake from running on every build. It is relative to the path and should not be an absolute path.

    -

    flags are any flags that should be passed to the cmake command. Unlike configure, it is required since typically it will be the path to the repository, typically .. when path is a subdir.

    +

    Run the cmake command to generate all Makefiles or other build scripts in the specified path

    +

    path will be created since typically cmake is run in an empty directory.

    +

    check is a file that will be generated by the cmake command. This is required to prevent cmake from running on every build. It is relative to the path and should not be an absolute path.

    +

    flags are any flags that should be passed to the cmake command. Unlike configure, it is required since typically it will be the path to the repository, typically .. when path is a subdir.

    -
    proc make(path, check: string; flags = "") {...}{.raises: [ValueError, OSError, Exception,
    -    IOError, Defect], tags: [ReadDirEffect, ExecIOEffect, ReadIOEffect, RootEffect].}
    +
    proc make(path, check: string; flags = "") {...}{.raises: [OSError, Exception], tags: [
    +    ReadDirEffect, ExecIOEffect, ReadIOEffect, RootEffect].}
    - -

    Run the make command to build all binaries in the specified path

    -

    check is a file that will be generated by the make command. This is required to prevent make from running on every build. It is relative to the path and should not be an absolute path.

    -

    flags are any flags that should be passed to the make command.

    +

    Run the make command to build all binaries in the specified path

    +

    check is a file that will be generated by the make command. This is required to prevent make from running on every build. It is relative to the path and should not be an absolute path.

    +

    flags are any flags that should be passed to the make command.

    @@ -1007,7 +1406,7 @@ Hard reset the git repository at the specified directory
    diff --git a/paths.html b/paths.html index fa6e18e..c8634e8 100644 --- a/paths.html +++ b/paths.html @@ -27,130 +27,232 @@ customize this style sheet. Modified from Chad Skeeters' rst2html-style https://bitbucket.org/cskeeters/rst2html-style/ -Modified by Boyd Greenfield and narimiran +Modified by Boyd Greenfield */ - +/* SCSS variables */ +/* Text weights */ +/* Body colors */ +/* Text colors */ +/* Link colors */ +/* Syntax highlighting colors */ +/* Pct changes */ +/* Mixins */ +/* Body/layout */ html { font-size: 100%; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; } +/* Where we want fancier font if available */ +h1, h2, h3, h4, h5, h6, p.module-desc, table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; } + +h1.title { + font-weight: 900; } + body { font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: 400; - font-size: 1.125em; - line-height: 1.5; - color: #222; - background-color: #FCFCFC; } + font-size: 16px; + line-height: 20px; + color: #444; + letter-spacing: 0.15px; + background-color: #FDFBFA; } /* Skeleton grid */ .container { position: relative; width: 100%; - max-width: 1050px; + max-width: 960px; margin: 0 auto; - padding: 0; + padding: 0 20px; box-sizing: border-box; } .column, .columns { width: 100%; float: left; - box-sizing: border-box; - margin-left: 1%; -} + box-sizing: border-box; } -.column:first-child, -.columns:first-child { - margin-left: 0; } +/* For devices larger than 400px */ +@media (min-width: 400px) { + .container { + width: 100%; + padding: 0; } } +/* For devices larger than 650px */ +@media (min-width: 650px) { + .container { + width: 100%; } -.three.columns { - width: 19%; } + .column, + .columns { + margin-left: 4%; } -.nine.columns { - width: 80.0%; } + .column:first-child, + .columns:first-child { + margin-left: 0; } -.twelve.columns { - width: 100%; - margin-left: 0; } + .one.column, + .one.columns { + width: 4.66666666667%; } + + .two.columns { + width: 13.3333333333%; } -@media screen and (max-width: 860px) { .three.columns { - display: none; - } + width: 22%; } + + .four.columns { + width: 30.6666666667%; } + + .five.columns { + width: 39.3333333333%; } + + .six.columns { + width: 48%; } + + .seven.columns { + width: 56.6666666667%; } + + .eight.columns { + width: 65.3333333333%; } + .nine.columns { - width: 98.0%; - } - body { - font-size: 1em; - line-height: 1.35; - } -} + width: 74.0%; } + + .ten.columns { + width: 82.6666666667%; } + + .eleven.columns { + width: 91.3333333333%; } + + .twelve.columns { + width: 100%; + margin-left: 0; } + + .one-third.column { + width: 30.6666666667%; } + + .two-thirds.column { + width: 65.3333333333%; } } +/* Customer Overrides */ +.footer { + text-align: center; + color: #969696; + padding-top: 10%; } + +p.module-desc { + font-size: 1.1em; + color: #666666; } + +a.link-seesrc { + color: #aec7d2; + font-style: italic; } + +a.link-seesrc:hover { + color: #6c9aae; } + +#toc-list { + word-wrap: break-word; } + +ul.simple-toc { + list-style: none; } + +ul.simple-toc a.reference-toplevel { + font-weight: bold; + color: #0077b3; } + +ul.simple-toc-section { + list-style-type: circle; + color: #6c9aae; } + +ul.simple-toc-section a.reference { + color: #0077b3; } cite { font-style: italic !important; } +dt > pre { + border-color: rgba(0, 0, 0, 0.1); + background-color: rgba(255, 255, 255, 0.3); + margin: 15px 0px 5px; } + +dd > pre { + border-color: rgba(0, 0, 0, 0.1); + background-color: whitesmoke; + margin-top: 8px; } + +.item > dd { + margin-left: 10px; + margin-bottom: 30px; } + +/* Nim line-numbered tables */ +.line-nums-table { + width: 100%; + table-layout: fixed; } /* Nim search input */ div#searchInputDiv { - margin-bottom: 1em; + margin-bottom: 8px; } -input#searchInput { - width: 80%; +div#searchInputDiv input#searchInput { + width: 10em; +} +div.search-groupby { + margin-bottom: 8px; } -/* - * Some custom formatting for input forms. - * This also fixes input form colors on Firefox with a dark system theme on Linux. - */ -input { - -moz-appearance: none; - color: #333; - background-color: #f8f8f8; - border: 1px solid #aaa; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-size: 0.9em; - padding: 6px; -} -input:focus { - border: 1px solid #1fa0eb; - box-shadow: 0 0 2px #1fa0eb; -} +table.line-nums-table { + border-radius: 4px; + border: 1px solid #cccccc; + background-color: whitesmoke; + border-collapse: separate; + margin-top: 15px; + margin-bottom: 25px; } + +.line-nums-table tbody { + border: none; } + +.line-nums-table td pre { + border: none; + background-color: transparent; } + +.line-nums-table td.blob-line-nums { + width: 28px; } + +.line-nums-table td.blob-line-nums pre { + color: #b0b0b0; + -webkit-filter: opacity(75%); + text-align: right; + border-color: transparent; + background-color: transparent; + padding-left: 0px; + margin-left: 0px; + padding-right: 0px; + margin-right: 0px; } /* Docgen styles */ /* Links */ a { - color: #07b; - text-decoration: none; -} - -a span.Identifier { - text-decoration: underline; - text-decoration-color: #aab; -} - -a.reference-toplevel { - font-weight: bold; -} - -a.toc-backref { - text-decoration: none; - color: #222; } - -a.link-seesrc { - color: #607c9f; - font-size: 0.9em; - font-style: italic; } + color: #0077b3; + text-decoration: none; } a:hover, a:focus { - color: #607c9f; + color: #00334d; text-decoration: underline; } -a:hover span.Identifier { - color: #607c9f; -} +a:visited { + color: #00334d; } +a:focus { + outline: thin dotted #2d2d2d; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; } + +a:hover, +a:active { + outline: 0; } sub, sup { @@ -227,258 +329,379 @@ img { h2, h3 { - page-break-after: avoid; } -} + page-break-after: avoid; } } +.img-rounded { + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; } +.img-polaroid { + padding: 4px; + background-color: rgba(252, 248, 244, 0.75); + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.2); + -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); } p { - margin-top: 0.5em; - margin-bottom: 0.5em; -} + margin: 0 0 8px; } small { font-size: 85%; } strong { - font-weight: 600; - font-size: 0.95em; - color: #3c3c3c; -} + font-weight: 600; } em { font-style: italic; } +cite { + font-style: normal; } + +h1, +h2, +h3, +h4, +h5, +h6 { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-weight: 600; + line-height: 20px; + color: inherit; + text-rendering: optimizelegibility; } + h1 { - font-size: 1.8em; + font-size: 2em; font-weight: 400; - padding-bottom: .25em; - border-bottom: 1px solid #aaa; - margin-top: 2.5em; - margin-bottom: 1em; + padding-bottom: .15em; + border-bottom: 1px solid #aaaaaa; + margin-top: 1.0em; line-height: 1.2em; } h1.title { padding-bottom: 1em; border-bottom: 0px; - font-size: 2.5em; - text-align: center; - font-weight: 900; - margin-top: 0.75em; - margin-bottom: 0em; -} + font-size: 2.75em; } h2 { - font-size: 1.3em; - margin-top: 2em; } - -h2.subtitle { - text-align: center; } - -h3 { - font-size: 1.125em; - font-style: italic; + font-size: 1.5em; margin-top: 1.5em; } +h3 { + font-size: 1.3em; + font-style: italic; + margin-top: 0.75em; } + h4 { - font-size: 1.125em; - margin-top: 1em; } + font-size: 1.3em; + margin-top: 0.5em; } h5 { - font-size: 1.125em; - margin-top: 0.75em; } + font-size: 1.2em; + margin-top: 0.25em; } h6 { font-size: 1.1em; } - ul, ol { padding: 0; - margin-top: 0.5em; - margin-left: 0.75em; } + margin: 0 0 0px 15px; } ul ul, ul ol, ol ol, ol ul { - margin-bottom: 0; - margin-left: 1.25em; } + margin-bottom: 0; } li { - list-style-type: circle; -} - -ul.simple-boot li { - list-style-type: none; - margin-left: 0em; - margin-bottom: 0.5em; -} - -ol.simple > li, ul.simple > li { - margin-bottom: 0.25em; - margin-left: 0.4em } - -ul.simple.simple-toc > li { - margin-top: 1em; -} - -ul.simple-toc { - list-style: none; - font-size: 0.9em; - margin-left: -0.3em; - margin-top: 1em; } - -ul.simple-toc > li { - list-style-type: none; -} - -ul.simple-toc-section { - list-style-type: circle; - margin-left: 1em; - color: #6c9aae; } - - -ol.arabic { - list-style: decimal; } - -ol.loweralpha { - list-style: lower-alpha; } - -ol.upperalpha { - list-style: upper-alpha; } - -ol.lowerroman { - list-style: lower-roman; } - -ol.upperroman { - list-style: upper-roman; } - -ul.auto-toc { - list-style-type: none; } - + line-height: 20px; } dl { - margin-bottom: 1.5em; } + margin-bottom: 20px; } + +dt, +dd { + line-height: 20px; } dt { - margin-bottom: -0.5em; - margin-left: 0.0em; } + font-weight: bold; } dd { - margin-left: 2.0em; - margin-bottom: 3.0em; - margin-top: 0.5em; } - + margin-left: 10px; + margin-bottom: 26px; } hr { - margin: 2em 0; + margin: 20px 0; border: 0; - border-top: 1px solid #aaa; } + border-top: 1px solid #eeeeee; + border-bottom: 1px solid #ffffff; } + +abbr[title], +abbr[data-original-title] { + cursor: help; + border-bottom: 1px dotted #999999; } + +abbr.initialism { + font-size: 90%; + text-transform: uppercase; } blockquote { - font-size: 0.9em; - font-style: italic; - padding-left: 0.5em; - margin-left: 0; - border-left: 5px solid #bbc; + padding: 0 0 0 15px; + margin: 0 0 20px; + border-left: 5px solid #EFEBE0; } + +table.docinfo + blockquote, table.docinfo blockquote, h1 + blockquote { + border-left: 5px solid #c9c9c9; } +table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { + margin-bottom: 0; + font-size: 15px; + font-weight: 200; + line-height: 1.5; + font-style: italic; } + +q:before, +q:after, +blockquote:before, +blockquote:after { + content: ""; } + +address { + display: block; + margin-bottom: 20px; + font-style: normal; + line-height: 20px; } + +code, +pre { + font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; + padding: 0 3px 2px; + font-weight: 500; + font-size: 12px; + color: #444444; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; } + .pre { font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - font-weight: 500; - font-size: 0.85em; - background-color: #f0f3ff; - padding-left: 3px; - padding-right: 3px; - border-radius: 4px; + font-weight: 600; + /*color: #504da6;*/ } +code { + padding: 2px 4px; + color: #444444; + white-space: nowrap; + background-color: white; + border: 1px solid #777777; } + pre { - font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - color: #222; - font-weight: 500; display: inline-block; box-sizing: border-box; - min-width: 100%; - padding: 0.5em; - margin-top: 0.5em; - margin-bottom: 0.5em; - font-size: 0.85em; + min-width: calc(100% - 19.5px); + padding: 9.5px; + margin: 0.25em 10px 10px 10px; + font-size: 15px; + line-height: 20px; white-space: pre !important; overflow-y: hidden; overflow-x: visible; - background-color: ghostwhite; - border: 1px solid #dde; - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; } + background-color: rgba(0, 0, 0, 0.01); + border: 1px solid #cccccc; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; } + +pre.prettyprint { + margin-bottom: 20px; } + +pre code { + padding: 0; + color: inherit; + white-space: pre; + overflow-x: visible; + background-color: transparent; + border: 0; } .pre-scrollable { max-height: 340px; overflow-y: scroll; } - -/* Nim line-numbered tables */ -.line-nums-table { - width: 100%; - table-layout: fixed; } - -table.line-nums-table { - border-radius: 4px; - border: 1px solid #cccccc; - background-color: ghostwhite; - border-collapse: separate; - margin-top: 15px; - margin-bottom: 25px; } - -.line-nums-table tbody { - border: none; } - -.line-nums-table td pre { - border: none; - background-color: transparent; } - -.line-nums-table td.blob-line-nums { - width: 28px; } - -.line-nums-table td.blob-line-nums pre { - color: #b0b0b0; - -webkit-filter: opacity(75%); - text-align: right; - border-color: transparent; - background-color: transparent; - padding-left: 0px; - margin-left: 0px; - padding-right: 0px; - margin-right: 0px; } - - table { max-width: 100%; background-color: transparent; - margin-top: 0.5em; - margin-bottom: 1.5em; border-collapse: collapse; - border-color: #ccc; - border-spacing: 0; - font-size: 0.9em; -} + border-spacing: 0; } table th, table td { - padding: 0px 0.5em 0px; + padding: 0px 8px 0px; } -table th { - background-color: #e8e8e8; +.table { + width: 100%; + margin-bottom: 20px; } + +.table th, +.table td { + padding: 8px; + line-height: 20px; + text-align: left; + vertical-align: top; + border-top: 1px solid #444444; } + +.table th { font-weight: bold; } -table th.docinfo-name { - background-color: transparent; -} +.table thead th { + vertical-align: bottom; } -table tr:hover { - background-color: ghostwhite; } +.table caption + thead tr:first-child th, +.table caption + thead tr:first-child td, +.table colgroup + thead tr:first-child th, +.table colgroup + thead tr:first-child td, +.table thead:first-child tr:first-child th, +.table thead:first-child tr:first-child td { + border-top: 0; } +.table tbody + tbody { + border-top: 2px solid #444444; } + +.table .table { + background-color: rgba(252, 248, 244, 0.75); } + +.table-condensed th, +.table-condensed td { + padding: 4px 5px; } + +.table-bordered { + border: 1px solid #444444; + border-collapse: separate; + *border-collapse: collapse; + border-left: 0; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; } + +.table-bordered th, +.table-bordered td { + border-left: 1px solid #444444; } + +.table-bordered caption + thead tr:first-child th, +.table-bordered caption + tbody tr:first-child th, +.table-bordered caption + tbody tr:first-child td, +.table-bordered colgroup + thead tr:first-child th, +.table-bordered colgroup + tbody tr:first-child th, +.table-bordered colgroup + tbody tr:first-child td, +.table-bordered thead:first-child tr:first-child th, +.table-bordered tbody:first-child tr:first-child th, +.table-bordered tbody:first-child tr:first-child td { + border-top: 0; } + +.table-bordered thead:first-child tr:first-child > th:first-child, +.table-bordered tbody:first-child tr:first-child > td:first-child, +.table-bordered tbody:first-child tr:first-child > th:first-child { + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; } + +.table-bordered thead:first-child tr:first-child > th:last-child, +.table-bordered tbody:first-child tr:first-child > td:last-child, +.table-bordered tbody:first-child tr:first-child > th:last-child { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; } + +.table-bordered thead:last-child tr:last-child > th:first-child, +.table-bordered tbody:last-child tr:last-child > td:first-child, +.table-bordered tbody:last-child tr:last-child > th:first-child, +.table-bordered tfoot:last-child tr:last-child > td:first-child, +.table-bordered tfoot:last-child tr:last-child > th:first-child { + -webkit-border-bottom-left-radius: 4px; + border-bottom-left-radius: 4px; + -moz-border-radius-bottomleft: 4px; } + +.table-bordered thead:last-child tr:last-child > th:last-child, +.table-bordered tbody:last-child tr:last-child > td:last-child, +.table-bordered tbody:last-child tr:last-child > th:last-child, +.table-bordered tfoot:last-child tr:last-child > td:last-child, +.table-bordered tfoot:last-child tr:last-child > th:last-child { + -webkit-border-bottom-right-radius: 4px; + border-bottom-right-radius: 4px; + -moz-border-radius-bottomright: 4px; } + +.table-bordered tfoot + tbody:last-child tr:last-child td:first-child { + -webkit-border-bottom-left-radius: 0; + border-bottom-left-radius: 0; + -moz-border-radius-bottomleft: 0; } + +.table-bordered tfoot + tbody:last-child tr:last-child td:last-child { + -webkit-border-bottom-right-radius: 0; + border-bottom-right-radius: 0; + -moz-border-radius-bottomright: 0; } + +.table-bordered caption + thead tr:first-child th:first-child, +.table-bordered caption + tbody tr:first-child td:first-child, +.table-bordered colgroup + thead tr:first-child th:first-child, +.table-bordered colgroup + tbody tr:first-child td:first-child { + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; } + +.table-bordered caption + thead tr:first-child th:last-child, +.table-bordered caption + tbody tr:first-child td:last-child, +.table-bordered colgroup + thead tr:first-child th:last-child, +.table-bordered colgroup + tbody tr:first-child td:last-child { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; } + +table.docutils th { + background-color: #e8e8e8; } + +table.docutils tr:hover { + background-color: whitesmoke; } + +.table-striped tbody > tr:nth-child(odd) > td, +.table-striped tbody > tr:nth-child(odd) > th { + background-color: rgba(252, 248, 244, 0.75); } + +.table-hover tbody tr:hover > td, +.table-hover tbody tr:hover > th { + background-color: rgba(241, 222, 204, 0.75); } + +table td[class*="span"], +table th[class*="span"], +.row-fluid table td[class*="span"], +.row-fluid table th[class*="span"] { + display: table-cell; + float: none; + margin-left: 0; } + +.hero-unit { + padding: 60px; + margin-bottom: 30px; + font-size: 18px; + font-weight: 200; + line-height: 30px; + color: inherit; + background-color: rgba(230, 197, 164, 0.75); + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; } + +.hero-unit h1 { + margin-bottom: 0; + font-size: 60px; + line-height: 1; + letter-spacing: -1px; + color: inherit; } + +.hero-unit li { + line-height: 30px; } /* rst2html default used to remove borders from tables and images */ .borderless, table.borderless td, table.borderless th { @@ -499,6 +722,10 @@ table.borderless td, table.borderless th { .hidden { display: none; } +a.toc-backref { + text-decoration: none; + color: #444444; } + blockquote.epigraph { margin: 2em 5em; } @@ -508,6 +735,85 @@ dl.docutils dd { object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] { overflow: hidden; } +/* Uncomment (and remove this text!) to get bold-faced definition list terms +dl.docutils dt { + font-weight: bold } +*/ +div.abstract { + margin: 2em 5em; } + +div.abstract p.topic-title { + font-weight: bold; + text-align: center; } + +div.admonition, div.attention, div.caution, div.danger, div.error, +div.hint, div.important, div.note, div.tip, div.warning { + margin: 2em; + border: medium outset; + padding: 1em; } + +div.note, div.warning { + margin: 1.5em 0px; + border: none; } + +div.note p.admonition-title, +div.warning p.admonition-title { + display: none; } + +/* Clearfix + * http://css-tricks.com/snippets/css/clear-fix/ + */ +div.note:after, +div.warning:after { + content: ""; + display: table; + clear: both; } + +div.note p:before, +div.warning p:before { + display: block; + float: left; + font-size: 4em; + line-height: 1em; + margin-right: 20px; + margin-left: 0em; + margin-top: -10px; + content: '\0270D'; + /*handwriting*/ } + +div.warning p:before { + content: '\026A0'; + /*warning*/ } + +div.admonition p.admonition-title, div.hint p.admonition-title, +div.important p.admonition-title, div.note p.admonition-title, +div.tip p.admonition-title { + font-weight: bold; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } + +div.attention p.admonition-title, div.caution p.admonition-title, +div.danger p.admonition-title, div.error p.admonition-title, +div.warning p.admonition-title, .code .error { + color: #b30000; + font-weight: bold; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } + +/* Uncomment (and remove this text!) to get reduced vertical space in + compound paragraphs. +div.compound .compound-first, div.compound .compound-middle { + margin-bottom: 0.5em } + +div.compound .compound-last, div.compound .compound-middle { + margin-top: 0.5em } +*/ +div.dedication { + margin: 2em 5em; + text-align: center; + font-style: italic; } + +div.dedication p.topic-title { + font-weight: bold; + font-style: normal; } div.figure { margin-left: 2em; @@ -515,14 +821,8 @@ div.figure { div.footer, div.header { clear: both; - text-align: center; - color: #666; font-size: smaller; } -div.footer { - padding-top: 5em; -} - div.line-block { display: block; margin-top: 1em; @@ -533,24 +833,45 @@ div.line-block div.line-block { margin-bottom: 0; margin-left: 1.5em; } +div.sidebar { + margin: 0 0 0.5em 1em; + border: medium outset; + padding: 1em; + background-color: rgba(252, 248, 244, 0.75); + width: 40%; + float: right; + clear: right; } + +div.sidebar p.rubric { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-size: medium; } + +div.system-messages { + margin: 5em; } + +div.system-messages h1 { + color: #b30000; } + +div.system-message { + border: medium outset; + padding: 1em; } + +div.system-message p.system-message-title { + color: #b30000; + font-weight: bold; } + div.topic { margin: 2em; } -div.search_results { - background-color: antiquewhite; - margin: 3em; - padding: 1em; - border: 1px solid #4d4d4d; -} +h1.section-subtitle, h2.section-subtitle, h3.section-subtitle, +h4.section-subtitle, h5.section-subtitle, h6.section-subtitle { + margin-top: 0.4em; } -div#global-links ul { - margin-left: 0; - list-style-type: none; -} +h1.title { + text-align: center; } -div#global-links > simple-boot { - margin-left: 3em; -} +h2.subtitle { + text-align: center; } hr.docutils { width: 75%; } @@ -584,6 +905,30 @@ img.align-center, .figure.align-center, object.align-center { div.align-right { text-align: inherit; } +/* div.align-center * { */ +/* text-align: left } */ + +ul.simple > li { + margin-bottom: 0.5em } + +ol.simple, ul.simple { + margin-bottom: 1em; } + +ol.arabic { + list-style: decimal; } + +ol.loweralpha { + list-style: lower-alpha; } + +ol.upperalpha { + list-style: upper-alpha; } + +ol.lowerroman { + list-style: lower-roman; } + +ol.upperroman { + list-style: upper-roman; } + p.attribution { text-align: right; margin-left: 50%; } @@ -604,6 +949,15 @@ p.rubric { color: maroon; text-align: center; } +p.sidebar-title { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-weight: bold; + font-size: larger; } + +p.sidebar-subtitle { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-weight: bold; } + p.topic-title { font-weight: bold; } @@ -643,14 +997,22 @@ pre.code .inserted, code .inserted { background-color: #A3D289; } span.classifier { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-style: oblique; } span.classifier-delimiter { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: bold; } +span.interpreted { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } + span.option { white-space: nowrap; } +span.pre { + white-space: pre; } + span.problematic { color: #b30000; } @@ -658,6 +1020,44 @@ span.section-subtitle { /* font-size relative to parent (h1..h6 element) */ font-size: 80%; } +table.citation { + border-left: solid 1px #666666; + margin-left: 1px; } + +table.docinfo { + margin: 0em; + margin-top: 2em; + margin-bottom: 2em; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; + color: #444444; } + +table.docutils { + margin-top: 0.5em; + margin-bottom: 0.5em; } + +table.footnote { + border-left: solid 1px #2d2d2d; + margin-left: 1px; } + +table.docutils td, table.docutils th, +table.docinfo td, table.docinfo th { + padding-left: 0.5em; + padding-right: 0.5em; + vertical-align: top; } + +table.docutils th.field-name, table.docinfo th.docinfo-name { + font-weight: 700; + text-align: left; + white-space: nowrap; + padding-left: 0; } + +h1 tt.docutils, h2 tt.docutils, h3 tt.docutils, +h4 tt.docutils, h5 tt.docutils, h6 tt.docutils { + font-size: 100%; } + +ul.auto-toc { + list-style-type: none; } + span.DecNumber { color: #252dbe; } @@ -674,7 +1074,7 @@ span.FloatNumber { color: #252dbe; } span.Identifier { - color: #222; } + color: #3b3b3b; } span.Keyword { font-weight: 600; @@ -739,23 +1139,38 @@ dt pre > span.Identifier, dt pre > span.Operator { color: #155da4; font-weight: 700; } -dt pre > span.Keyword ~ span.Identifier, dt pre > span.Identifier ~ span.Identifier, -dt pre > span.Operator ~ span.Identifier, dt pre > span.Other ~ span.Identifier { +dt pre > span.Identifier ~ span.Identifier, dt pre > span.Operator ~ span.Identifier { + color: inherit; + font-weight: inherit; } + +dt pre > span.Operator ~ span.Identifier { color: inherit; font-weight: inherit; } /* Nim sprite for the footer (taken from main page favicon) */ .nim-sprite { display: inline-block; - height: 16px; - width: 16px; + height: 12px; + width: 12px; background-position: 0 0; - background-size: 16px 16px; + background-size: 12px 12px; -webkit-filter: opacity(50%); background-repeat: no-repeat; background-image: url("data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="); margin-bottom: -5px; } +div.search_results { + background-color: antiquewhite; + margin: 3em; + padding: 1em; + border: 1px solid #4d4d4d; +} + +div#global-links ul { + margin-left: 0; + list-style-type: none; +} + span.pragmadots { /* Position: relative frees us up to make the dots look really nice without fucking up the layout and @@ -763,14 +1178,18 @@ span.pragmadots { position: relative; /* 1px down looks slightly nicer */ top: 1px; + padding: 2px; - background-color: #e8e8e8; + background-color: #D3D3D3; border-radius: 4px; margin: 0 2px; cursor: pointer; - font-size: 0.8em; -} + /* For some reason on Chrome, making the font size + smaller than 1em is causing the parent container to + bulge slightly. So, we're stuck with inheriting 1em, + which is sad, because 0.8em looks better... */ +} span.pragmadots:hover { background-color: #DBDBDB; } @@ -778,10 +1197,6 @@ span.pragmawrap { display: none; } -span.attachedType { - display: none; - visibility: hidden; -} @@ -826,18 +1241,18 @@ function main() {
  • Procs
  • @@ -847,52 +1262,45 @@ function main() {
    -

    Procs

    - -
    proc nimteropRoot(): string {...}{.raises: [], tags: [].}
    + +
    proc nimteropRoot(): string {...}{.raises: [], tags: [].}
    -
    - -
    proc nimteropBuildDir(): string {...}{.raises: [], tags: [].}
    + +
    proc nimteropBuildDir(): string {...}{.raises: [], tags: [].}
    - all nimterop generated files go under here (gitignored)
    - -
    proc nimteropSrcDir(): string {...}{.raises: [], tags: [].}
    + +
    proc nimteropSrcDir(): string {...}{.raises: [], tags: [].}
    -
    - -
    proc toastExePath(): string {...}{.raises: [], tags: [].}
    + +
    proc toastExePath(): string {...}{.raises: [], tags: [].}
    -
    - -
    proc incDir(): string {...}{.raises: [], tags: [].}
    + +
    proc incDir(): string {...}{.raises: [], tags: [].}
    -
    - -
    proc testsIncludeDir(): string {...}{.raises: [], tags: [].}
    + +
    proc testsIncludeDir(): string {...}{.raises: [], tags: [].}
    -
    @@ -904,7 +1312,7 @@ all nimterop generated files go under here (gitignored)
    diff --git a/paths.idx b/paths.idx index 8a688d4..df86edd 100644 --- a/paths.idx +++ b/paths.idx @@ -1,6 +1,6 @@ -nimteropRoot paths.html#nimteropRoot paths: nimteropRoot(): string -nimteropBuildDir paths.html#nimteropBuildDir paths: nimteropBuildDir(): string -nimteropSrcDir paths.html#nimteropSrcDir paths: nimteropSrcDir(): string -toastExePath paths.html#toastExePath paths: toastExePath(): string -incDir paths.html#incDir paths: incDir(): string -testsIncludeDir paths.html#testsIncludeDir paths: testsIncludeDir(): string +nimteropRoot paths.html#nimteropRoot, paths: nimteropRoot(): string +nimteropBuildDir paths.html#nimteropBuildDir, paths: nimteropBuildDir(): string +nimteropSrcDir paths.html#nimteropSrcDir, paths: nimteropSrcDir(): string +toastExePath paths.html#toastExePath, paths: toastExePath(): string +incDir paths.html#incDir, paths: incDir(): string +testsIncludeDir paths.html#testsIncludeDir, paths: testsIncludeDir(): string diff --git a/plugin.html b/plugin.html index 9bf3942..1528de6 100644 --- a/plugin.html +++ b/plugin.html @@ -27,130 +27,232 @@ customize this style sheet. Modified from Chad Skeeters' rst2html-style https://bitbucket.org/cskeeters/rst2html-style/ -Modified by Boyd Greenfield and narimiran +Modified by Boyd Greenfield */ - +/* SCSS variables */ +/* Text weights */ +/* Body colors */ +/* Text colors */ +/* Link colors */ +/* Syntax highlighting colors */ +/* Pct changes */ +/* Mixins */ +/* Body/layout */ html { font-size: 100%; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; } +/* Where we want fancier font if available */ +h1, h2, h3, h4, h5, h6, p.module-desc, table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; } + +h1.title { + font-weight: 900; } + body { font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: 400; - font-size: 1.125em; - line-height: 1.5; - color: #222; - background-color: #FCFCFC; } + font-size: 16px; + line-height: 20px; + color: #444; + letter-spacing: 0.15px; + background-color: #FDFBFA; } /* Skeleton grid */ .container { position: relative; width: 100%; - max-width: 1050px; + max-width: 960px; margin: 0 auto; - padding: 0; + padding: 0 20px; box-sizing: border-box; } .column, .columns { width: 100%; float: left; - box-sizing: border-box; - margin-left: 1%; -} + box-sizing: border-box; } -.column:first-child, -.columns:first-child { - margin-left: 0; } +/* For devices larger than 400px */ +@media (min-width: 400px) { + .container { + width: 100%; + padding: 0; } } +/* For devices larger than 650px */ +@media (min-width: 650px) { + .container { + width: 100%; } -.three.columns { - width: 19%; } + .column, + .columns { + margin-left: 4%; } -.nine.columns { - width: 80.0%; } + .column:first-child, + .columns:first-child { + margin-left: 0; } -.twelve.columns { - width: 100%; - margin-left: 0; } + .one.column, + .one.columns { + width: 4.66666666667%; } + + .two.columns { + width: 13.3333333333%; } -@media screen and (max-width: 860px) { .three.columns { - display: none; - } + width: 22%; } + + .four.columns { + width: 30.6666666667%; } + + .five.columns { + width: 39.3333333333%; } + + .six.columns { + width: 48%; } + + .seven.columns { + width: 56.6666666667%; } + + .eight.columns { + width: 65.3333333333%; } + .nine.columns { - width: 98.0%; - } - body { - font-size: 1em; - line-height: 1.35; - } -} + width: 74.0%; } + + .ten.columns { + width: 82.6666666667%; } + + .eleven.columns { + width: 91.3333333333%; } + + .twelve.columns { + width: 100%; + margin-left: 0; } + + .one-third.column { + width: 30.6666666667%; } + + .two-thirds.column { + width: 65.3333333333%; } } +/* Customer Overrides */ +.footer { + text-align: center; + color: #969696; + padding-top: 10%; } + +p.module-desc { + font-size: 1.1em; + color: #666666; } + +a.link-seesrc { + color: #aec7d2; + font-style: italic; } + +a.link-seesrc:hover { + color: #6c9aae; } + +#toc-list { + word-wrap: break-word; } + +ul.simple-toc { + list-style: none; } + +ul.simple-toc a.reference-toplevel { + font-weight: bold; + color: #0077b3; } + +ul.simple-toc-section { + list-style-type: circle; + color: #6c9aae; } + +ul.simple-toc-section a.reference { + color: #0077b3; } cite { font-style: italic !important; } +dt > pre { + border-color: rgba(0, 0, 0, 0.1); + background-color: rgba(255, 255, 255, 0.3); + margin: 15px 0px 5px; } + +dd > pre { + border-color: rgba(0, 0, 0, 0.1); + background-color: whitesmoke; + margin-top: 8px; } + +.item > dd { + margin-left: 10px; + margin-bottom: 30px; } + +/* Nim line-numbered tables */ +.line-nums-table { + width: 100%; + table-layout: fixed; } /* Nim search input */ div#searchInputDiv { - margin-bottom: 1em; + margin-bottom: 8px; } -input#searchInput { - width: 80%; +div#searchInputDiv input#searchInput { + width: 10em; +} +div.search-groupby { + margin-bottom: 8px; } -/* - * Some custom formatting for input forms. - * This also fixes input form colors on Firefox with a dark system theme on Linux. - */ -input { - -moz-appearance: none; - color: #333; - background-color: #f8f8f8; - border: 1px solid #aaa; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-size: 0.9em; - padding: 6px; -} -input:focus { - border: 1px solid #1fa0eb; - box-shadow: 0 0 2px #1fa0eb; -} +table.line-nums-table { + border-radius: 4px; + border: 1px solid #cccccc; + background-color: whitesmoke; + border-collapse: separate; + margin-top: 15px; + margin-bottom: 25px; } + +.line-nums-table tbody { + border: none; } + +.line-nums-table td pre { + border: none; + background-color: transparent; } + +.line-nums-table td.blob-line-nums { + width: 28px; } + +.line-nums-table td.blob-line-nums pre { + color: #b0b0b0; + -webkit-filter: opacity(75%); + text-align: right; + border-color: transparent; + background-color: transparent; + padding-left: 0px; + margin-left: 0px; + padding-right: 0px; + margin-right: 0px; } /* Docgen styles */ /* Links */ a { - color: #07b; - text-decoration: none; -} - -a span.Identifier { - text-decoration: underline; - text-decoration-color: #aab; -} - -a.reference-toplevel { - font-weight: bold; -} - -a.toc-backref { - text-decoration: none; - color: #222; } - -a.link-seesrc { - color: #607c9f; - font-size: 0.9em; - font-style: italic; } + color: #0077b3; + text-decoration: none; } a:hover, a:focus { - color: #607c9f; + color: #00334d; text-decoration: underline; } -a:hover span.Identifier { - color: #607c9f; -} +a:visited { + color: #00334d; } +a:focus { + outline: thin dotted #2d2d2d; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; } + +a:hover, +a:active { + outline: 0; } sub, sup { @@ -227,258 +329,379 @@ img { h2, h3 { - page-break-after: avoid; } -} + page-break-after: avoid; } } +.img-rounded { + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; } +.img-polaroid { + padding: 4px; + background-color: rgba(252, 248, 244, 0.75); + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.2); + -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); } p { - margin-top: 0.5em; - margin-bottom: 0.5em; -} + margin: 0 0 8px; } small { font-size: 85%; } strong { - font-weight: 600; - font-size: 0.95em; - color: #3c3c3c; -} + font-weight: 600; } em { font-style: italic; } +cite { + font-style: normal; } + +h1, +h2, +h3, +h4, +h5, +h6 { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-weight: 600; + line-height: 20px; + color: inherit; + text-rendering: optimizelegibility; } + h1 { - font-size: 1.8em; + font-size: 2em; font-weight: 400; - padding-bottom: .25em; - border-bottom: 1px solid #aaa; - margin-top: 2.5em; - margin-bottom: 1em; + padding-bottom: .15em; + border-bottom: 1px solid #aaaaaa; + margin-top: 1.0em; line-height: 1.2em; } h1.title { padding-bottom: 1em; border-bottom: 0px; - font-size: 2.5em; - text-align: center; - font-weight: 900; - margin-top: 0.75em; - margin-bottom: 0em; -} + font-size: 2.75em; } h2 { - font-size: 1.3em; - margin-top: 2em; } - -h2.subtitle { - text-align: center; } - -h3 { - font-size: 1.125em; - font-style: italic; + font-size: 1.5em; margin-top: 1.5em; } +h3 { + font-size: 1.3em; + font-style: italic; + margin-top: 0.75em; } + h4 { - font-size: 1.125em; - margin-top: 1em; } + font-size: 1.3em; + margin-top: 0.5em; } h5 { - font-size: 1.125em; - margin-top: 0.75em; } + font-size: 1.2em; + margin-top: 0.25em; } h6 { font-size: 1.1em; } - ul, ol { padding: 0; - margin-top: 0.5em; - margin-left: 0.75em; } + margin: 0 0 0px 15px; } ul ul, ul ol, ol ol, ol ul { - margin-bottom: 0; - margin-left: 1.25em; } + margin-bottom: 0; } li { - list-style-type: circle; -} - -ul.simple-boot li { - list-style-type: none; - margin-left: 0em; - margin-bottom: 0.5em; -} - -ol.simple > li, ul.simple > li { - margin-bottom: 0.25em; - margin-left: 0.4em } - -ul.simple.simple-toc > li { - margin-top: 1em; -} - -ul.simple-toc { - list-style: none; - font-size: 0.9em; - margin-left: -0.3em; - margin-top: 1em; } - -ul.simple-toc > li { - list-style-type: none; -} - -ul.simple-toc-section { - list-style-type: circle; - margin-left: 1em; - color: #6c9aae; } - - -ol.arabic { - list-style: decimal; } - -ol.loweralpha { - list-style: lower-alpha; } - -ol.upperalpha { - list-style: upper-alpha; } - -ol.lowerroman { - list-style: lower-roman; } - -ol.upperroman { - list-style: upper-roman; } - -ul.auto-toc { - list-style-type: none; } - + line-height: 20px; } dl { - margin-bottom: 1.5em; } + margin-bottom: 20px; } + +dt, +dd { + line-height: 20px; } dt { - margin-bottom: -0.5em; - margin-left: 0.0em; } + font-weight: bold; } dd { - margin-left: 2.0em; - margin-bottom: 3.0em; - margin-top: 0.5em; } - + margin-left: 10px; + margin-bottom: 26px; } hr { - margin: 2em 0; + margin: 20px 0; border: 0; - border-top: 1px solid #aaa; } + border-top: 1px solid #eeeeee; + border-bottom: 1px solid #ffffff; } + +abbr[title], +abbr[data-original-title] { + cursor: help; + border-bottom: 1px dotted #999999; } + +abbr.initialism { + font-size: 90%; + text-transform: uppercase; } blockquote { - font-size: 0.9em; - font-style: italic; - padding-left: 0.5em; - margin-left: 0; - border-left: 5px solid #bbc; + padding: 0 0 0 15px; + margin: 0 0 20px; + border-left: 5px solid #EFEBE0; } + +table.docinfo + blockquote, table.docinfo blockquote, h1 + blockquote { + border-left: 5px solid #c9c9c9; } +table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { + margin-bottom: 0; + font-size: 15px; + font-weight: 200; + line-height: 1.5; + font-style: italic; } + +q:before, +q:after, +blockquote:before, +blockquote:after { + content: ""; } + +address { + display: block; + margin-bottom: 20px; + font-style: normal; + line-height: 20px; } + +code, +pre { + font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; + padding: 0 3px 2px; + font-weight: 500; + font-size: 12px; + color: #444444; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; } + .pre { font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - font-weight: 500; - font-size: 0.85em; - background-color: #f0f3ff; - padding-left: 3px; - padding-right: 3px; - border-radius: 4px; + font-weight: 600; + /*color: #504da6;*/ } +code { + padding: 2px 4px; + color: #444444; + white-space: nowrap; + background-color: white; + border: 1px solid #777777; } + pre { - font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - color: #222; - font-weight: 500; display: inline-block; box-sizing: border-box; - min-width: 100%; - padding: 0.5em; - margin-top: 0.5em; - margin-bottom: 0.5em; - font-size: 0.85em; + min-width: calc(100% - 19.5px); + padding: 9.5px; + margin: 0.25em 10px 10px 10px; + font-size: 15px; + line-height: 20px; white-space: pre !important; overflow-y: hidden; overflow-x: visible; - background-color: ghostwhite; - border: 1px solid #dde; - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; } + background-color: rgba(0, 0, 0, 0.01); + border: 1px solid #cccccc; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; } + +pre.prettyprint { + margin-bottom: 20px; } + +pre code { + padding: 0; + color: inherit; + white-space: pre; + overflow-x: visible; + background-color: transparent; + border: 0; } .pre-scrollable { max-height: 340px; overflow-y: scroll; } - -/* Nim line-numbered tables */ -.line-nums-table { - width: 100%; - table-layout: fixed; } - -table.line-nums-table { - border-radius: 4px; - border: 1px solid #cccccc; - background-color: ghostwhite; - border-collapse: separate; - margin-top: 15px; - margin-bottom: 25px; } - -.line-nums-table tbody { - border: none; } - -.line-nums-table td pre { - border: none; - background-color: transparent; } - -.line-nums-table td.blob-line-nums { - width: 28px; } - -.line-nums-table td.blob-line-nums pre { - color: #b0b0b0; - -webkit-filter: opacity(75%); - text-align: right; - border-color: transparent; - background-color: transparent; - padding-left: 0px; - margin-left: 0px; - padding-right: 0px; - margin-right: 0px; } - - table { max-width: 100%; background-color: transparent; - margin-top: 0.5em; - margin-bottom: 1.5em; border-collapse: collapse; - border-color: #ccc; - border-spacing: 0; - font-size: 0.9em; -} + border-spacing: 0; } table th, table td { - padding: 0px 0.5em 0px; + padding: 0px 8px 0px; } -table th { - background-color: #e8e8e8; +.table { + width: 100%; + margin-bottom: 20px; } + +.table th, +.table td { + padding: 8px; + line-height: 20px; + text-align: left; + vertical-align: top; + border-top: 1px solid #444444; } + +.table th { font-weight: bold; } -table th.docinfo-name { - background-color: transparent; -} +.table thead th { + vertical-align: bottom; } -table tr:hover { - background-color: ghostwhite; } +.table caption + thead tr:first-child th, +.table caption + thead tr:first-child td, +.table colgroup + thead tr:first-child th, +.table colgroup + thead tr:first-child td, +.table thead:first-child tr:first-child th, +.table thead:first-child tr:first-child td { + border-top: 0; } +.table tbody + tbody { + border-top: 2px solid #444444; } + +.table .table { + background-color: rgba(252, 248, 244, 0.75); } + +.table-condensed th, +.table-condensed td { + padding: 4px 5px; } + +.table-bordered { + border: 1px solid #444444; + border-collapse: separate; + *border-collapse: collapse; + border-left: 0; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; } + +.table-bordered th, +.table-bordered td { + border-left: 1px solid #444444; } + +.table-bordered caption + thead tr:first-child th, +.table-bordered caption + tbody tr:first-child th, +.table-bordered caption + tbody tr:first-child td, +.table-bordered colgroup + thead tr:first-child th, +.table-bordered colgroup + tbody tr:first-child th, +.table-bordered colgroup + tbody tr:first-child td, +.table-bordered thead:first-child tr:first-child th, +.table-bordered tbody:first-child tr:first-child th, +.table-bordered tbody:first-child tr:first-child td { + border-top: 0; } + +.table-bordered thead:first-child tr:first-child > th:first-child, +.table-bordered tbody:first-child tr:first-child > td:first-child, +.table-bordered tbody:first-child tr:first-child > th:first-child { + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; } + +.table-bordered thead:first-child tr:first-child > th:last-child, +.table-bordered tbody:first-child tr:first-child > td:last-child, +.table-bordered tbody:first-child tr:first-child > th:last-child { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; } + +.table-bordered thead:last-child tr:last-child > th:first-child, +.table-bordered tbody:last-child tr:last-child > td:first-child, +.table-bordered tbody:last-child tr:last-child > th:first-child, +.table-bordered tfoot:last-child tr:last-child > td:first-child, +.table-bordered tfoot:last-child tr:last-child > th:first-child { + -webkit-border-bottom-left-radius: 4px; + border-bottom-left-radius: 4px; + -moz-border-radius-bottomleft: 4px; } + +.table-bordered thead:last-child tr:last-child > th:last-child, +.table-bordered tbody:last-child tr:last-child > td:last-child, +.table-bordered tbody:last-child tr:last-child > th:last-child, +.table-bordered tfoot:last-child tr:last-child > td:last-child, +.table-bordered tfoot:last-child tr:last-child > th:last-child { + -webkit-border-bottom-right-radius: 4px; + border-bottom-right-radius: 4px; + -moz-border-radius-bottomright: 4px; } + +.table-bordered tfoot + tbody:last-child tr:last-child td:first-child { + -webkit-border-bottom-left-radius: 0; + border-bottom-left-radius: 0; + -moz-border-radius-bottomleft: 0; } + +.table-bordered tfoot + tbody:last-child tr:last-child td:last-child { + -webkit-border-bottom-right-radius: 0; + border-bottom-right-radius: 0; + -moz-border-radius-bottomright: 0; } + +.table-bordered caption + thead tr:first-child th:first-child, +.table-bordered caption + tbody tr:first-child td:first-child, +.table-bordered colgroup + thead tr:first-child th:first-child, +.table-bordered colgroup + tbody tr:first-child td:first-child { + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; } + +.table-bordered caption + thead tr:first-child th:last-child, +.table-bordered caption + tbody tr:first-child td:last-child, +.table-bordered colgroup + thead tr:first-child th:last-child, +.table-bordered colgroup + tbody tr:first-child td:last-child { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; } + +table.docutils th { + background-color: #e8e8e8; } + +table.docutils tr:hover { + background-color: whitesmoke; } + +.table-striped tbody > tr:nth-child(odd) > td, +.table-striped tbody > tr:nth-child(odd) > th { + background-color: rgba(252, 248, 244, 0.75); } + +.table-hover tbody tr:hover > td, +.table-hover tbody tr:hover > th { + background-color: rgba(241, 222, 204, 0.75); } + +table td[class*="span"], +table th[class*="span"], +.row-fluid table td[class*="span"], +.row-fluid table th[class*="span"] { + display: table-cell; + float: none; + margin-left: 0; } + +.hero-unit { + padding: 60px; + margin-bottom: 30px; + font-size: 18px; + font-weight: 200; + line-height: 30px; + color: inherit; + background-color: rgba(230, 197, 164, 0.75); + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; } + +.hero-unit h1 { + margin-bottom: 0; + font-size: 60px; + line-height: 1; + letter-spacing: -1px; + color: inherit; } + +.hero-unit li { + line-height: 30px; } /* rst2html default used to remove borders from tables and images */ .borderless, table.borderless td, table.borderless th { @@ -499,6 +722,10 @@ table.borderless td, table.borderless th { .hidden { display: none; } +a.toc-backref { + text-decoration: none; + color: #444444; } + blockquote.epigraph { margin: 2em 5em; } @@ -508,6 +735,85 @@ dl.docutils dd { object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] { overflow: hidden; } +/* Uncomment (and remove this text!) to get bold-faced definition list terms +dl.docutils dt { + font-weight: bold } +*/ +div.abstract { + margin: 2em 5em; } + +div.abstract p.topic-title { + font-weight: bold; + text-align: center; } + +div.admonition, div.attention, div.caution, div.danger, div.error, +div.hint, div.important, div.note, div.tip, div.warning { + margin: 2em; + border: medium outset; + padding: 1em; } + +div.note, div.warning { + margin: 1.5em 0px; + border: none; } + +div.note p.admonition-title, +div.warning p.admonition-title { + display: none; } + +/* Clearfix + * http://css-tricks.com/snippets/css/clear-fix/ + */ +div.note:after, +div.warning:after { + content: ""; + display: table; + clear: both; } + +div.note p:before, +div.warning p:before { + display: block; + float: left; + font-size: 4em; + line-height: 1em; + margin-right: 20px; + margin-left: 0em; + margin-top: -10px; + content: '\0270D'; + /*handwriting*/ } + +div.warning p:before { + content: '\026A0'; + /*warning*/ } + +div.admonition p.admonition-title, div.hint p.admonition-title, +div.important p.admonition-title, div.note p.admonition-title, +div.tip p.admonition-title { + font-weight: bold; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } + +div.attention p.admonition-title, div.caution p.admonition-title, +div.danger p.admonition-title, div.error p.admonition-title, +div.warning p.admonition-title, .code .error { + color: #b30000; + font-weight: bold; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } + +/* Uncomment (and remove this text!) to get reduced vertical space in + compound paragraphs. +div.compound .compound-first, div.compound .compound-middle { + margin-bottom: 0.5em } + +div.compound .compound-last, div.compound .compound-middle { + margin-top: 0.5em } +*/ +div.dedication { + margin: 2em 5em; + text-align: center; + font-style: italic; } + +div.dedication p.topic-title { + font-weight: bold; + font-style: normal; } div.figure { margin-left: 2em; @@ -515,14 +821,8 @@ div.figure { div.footer, div.header { clear: both; - text-align: center; - color: #666; font-size: smaller; } -div.footer { - padding-top: 5em; -} - div.line-block { display: block; margin-top: 1em; @@ -533,24 +833,45 @@ div.line-block div.line-block { margin-bottom: 0; margin-left: 1.5em; } +div.sidebar { + margin: 0 0 0.5em 1em; + border: medium outset; + padding: 1em; + background-color: rgba(252, 248, 244, 0.75); + width: 40%; + float: right; + clear: right; } + +div.sidebar p.rubric { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-size: medium; } + +div.system-messages { + margin: 5em; } + +div.system-messages h1 { + color: #b30000; } + +div.system-message { + border: medium outset; + padding: 1em; } + +div.system-message p.system-message-title { + color: #b30000; + font-weight: bold; } + div.topic { margin: 2em; } -div.search_results { - background-color: antiquewhite; - margin: 3em; - padding: 1em; - border: 1px solid #4d4d4d; -} +h1.section-subtitle, h2.section-subtitle, h3.section-subtitle, +h4.section-subtitle, h5.section-subtitle, h6.section-subtitle { + margin-top: 0.4em; } -div#global-links ul { - margin-left: 0; - list-style-type: none; -} +h1.title { + text-align: center; } -div#global-links > simple-boot { - margin-left: 3em; -} +h2.subtitle { + text-align: center; } hr.docutils { width: 75%; } @@ -584,6 +905,30 @@ img.align-center, .figure.align-center, object.align-center { div.align-right { text-align: inherit; } +/* div.align-center * { */ +/* text-align: left } */ + +ul.simple > li { + margin-bottom: 0.5em } + +ol.simple, ul.simple { + margin-bottom: 1em; } + +ol.arabic { + list-style: decimal; } + +ol.loweralpha { + list-style: lower-alpha; } + +ol.upperalpha { + list-style: upper-alpha; } + +ol.lowerroman { + list-style: lower-roman; } + +ol.upperroman { + list-style: upper-roman; } + p.attribution { text-align: right; margin-left: 50%; } @@ -604,6 +949,15 @@ p.rubric { color: maroon; text-align: center; } +p.sidebar-title { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-weight: bold; + font-size: larger; } + +p.sidebar-subtitle { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-weight: bold; } + p.topic-title { font-weight: bold; } @@ -643,14 +997,22 @@ pre.code .inserted, code .inserted { background-color: #A3D289; } span.classifier { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-style: oblique; } span.classifier-delimiter { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: bold; } +span.interpreted { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } + span.option { white-space: nowrap; } +span.pre { + white-space: pre; } + span.problematic { color: #b30000; } @@ -658,6 +1020,44 @@ span.section-subtitle { /* font-size relative to parent (h1..h6 element) */ font-size: 80%; } +table.citation { + border-left: solid 1px #666666; + margin-left: 1px; } + +table.docinfo { + margin: 0em; + margin-top: 2em; + margin-bottom: 2em; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; + color: #444444; } + +table.docutils { + margin-top: 0.5em; + margin-bottom: 0.5em; } + +table.footnote { + border-left: solid 1px #2d2d2d; + margin-left: 1px; } + +table.docutils td, table.docutils th, +table.docinfo td, table.docinfo th { + padding-left: 0.5em; + padding-right: 0.5em; + vertical-align: top; } + +table.docutils th.field-name, table.docinfo th.docinfo-name { + font-weight: 700; + text-align: left; + white-space: nowrap; + padding-left: 0; } + +h1 tt.docutils, h2 tt.docutils, h3 tt.docutils, +h4 tt.docutils, h5 tt.docutils, h6 tt.docutils { + font-size: 100%; } + +ul.auto-toc { + list-style-type: none; } + span.DecNumber { color: #252dbe; } @@ -674,7 +1074,7 @@ span.FloatNumber { color: #252dbe; } span.Identifier { - color: #222; } + color: #3b3b3b; } span.Keyword { font-weight: 600; @@ -739,23 +1139,38 @@ dt pre > span.Identifier, dt pre > span.Operator { color: #155da4; font-weight: 700; } -dt pre > span.Keyword ~ span.Identifier, dt pre > span.Identifier ~ span.Identifier, -dt pre > span.Operator ~ span.Identifier, dt pre > span.Other ~ span.Identifier { +dt pre > span.Identifier ~ span.Identifier, dt pre > span.Operator ~ span.Identifier { + color: inherit; + font-weight: inherit; } + +dt pre > span.Operator ~ span.Identifier { color: inherit; font-weight: inherit; } /* Nim sprite for the footer (taken from main page favicon) */ .nim-sprite { display: inline-block; - height: 16px; - width: 16px; + height: 12px; + width: 12px; background-position: 0 0; - background-size: 16px 16px; + background-size: 12px 12px; -webkit-filter: opacity(50%); background-repeat: no-repeat; background-image: url("data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="); margin-bottom: -5px; } +div.search_results { + background-color: antiquewhite; + margin: 3em; + padding: 1em; + border: 1px solid #4d4d4d; +} + +div#global-links ul { + margin-left: 0; + list-style-type: none; +} + span.pragmadots { /* Position: relative frees us up to make the dots look really nice without fucking up the layout and @@ -763,14 +1178,18 @@ span.pragmadots { position: relative; /* 1px down looks slightly nicer */ top: 1px; + padding: 2px; - background-color: #e8e8e8; + background-color: #D3D3D3; border-radius: 4px; margin: 0 2px; cursor: pointer; - font-size: 0.8em; -} + /* For some reason on Chrome, making the font size + smaller than 1em is causing the parent container to + bulge slightly. So, we're stuck with inheriting 1em, + which is sad, because 0.8em looks better... */ +} span.pragmadots:hover { background-color: #DBDBDB; } @@ -778,10 +1197,6 @@ span.pragmawrap { display: none; } -span.attachedType { - display: none; - visibility: hidden; -} @@ -830,9 +1245,9 @@ function main() { title="Symbol = object name*: string parent*: string - kind*: NimSymKind">Symbol + kind*: NimSymKind">Symbol
  • OnSymbol
  • + title="OnSymbol = proc (sym: var Symbol) {.cdecl.}">OnSymbol
@@ -842,7 +1257,6 @@ function main() {
-

Types

@@ -856,14 +1270,12 @@ function main() {
-
OnSymbol = proc (sym: var Symbol) {...}{.cdecl.}
-
@@ -875,7 +1287,7 @@ function main() {
diff --git a/theindex.html b/theindex.html index bae06e4..e69ee32 100644 --- a/theindex.html +++ b/theindex.html @@ -27,130 +27,232 @@ customize this style sheet. Modified from Chad Skeeters' rst2html-style https://bitbucket.org/cskeeters/rst2html-style/ -Modified by Boyd Greenfield and narimiran +Modified by Boyd Greenfield */ - +/* SCSS variables */ +/* Text weights */ +/* Body colors */ +/* Text colors */ +/* Link colors */ +/* Syntax highlighting colors */ +/* Pct changes */ +/* Mixins */ +/* Body/layout */ html { font-size: 100%; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; } +/* Where we want fancier font if available */ +h1, h2, h3, h4, h5, h6, p.module-desc, table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; } + +h1.title { + font-weight: 900; } + body { font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: 400; - font-size: 1.125em; - line-height: 1.5; - color: #222; - background-color: #FCFCFC; } + font-size: 16px; + line-height: 20px; + color: #444; + letter-spacing: 0.15px; + background-color: #FDFBFA; } /* Skeleton grid */ .container { position: relative; width: 100%; - max-width: 1050px; + max-width: 960px; margin: 0 auto; - padding: 0; + padding: 0 20px; box-sizing: border-box; } .column, .columns { width: 100%; float: left; - box-sizing: border-box; - margin-left: 1%; -} + box-sizing: border-box; } -.column:first-child, -.columns:first-child { - margin-left: 0; } +/* For devices larger than 400px */ +@media (min-width: 400px) { + .container { + width: 100%; + padding: 0; } } +/* For devices larger than 650px */ +@media (min-width: 650px) { + .container { + width: 100%; } -.three.columns { - width: 19%; } + .column, + .columns { + margin-left: 4%; } -.nine.columns { - width: 80.0%; } + .column:first-child, + .columns:first-child { + margin-left: 0; } -.twelve.columns { - width: 100%; - margin-left: 0; } + .one.column, + .one.columns { + width: 4.66666666667%; } + + .two.columns { + width: 13.3333333333%; } -@media screen and (max-width: 860px) { .three.columns { - display: none; - } + width: 22%; } + + .four.columns { + width: 30.6666666667%; } + + .five.columns { + width: 39.3333333333%; } + + .six.columns { + width: 48%; } + + .seven.columns { + width: 56.6666666667%; } + + .eight.columns { + width: 65.3333333333%; } + .nine.columns { - width: 98.0%; - } - body { - font-size: 1em; - line-height: 1.35; - } -} + width: 74.0%; } + + .ten.columns { + width: 82.6666666667%; } + + .eleven.columns { + width: 91.3333333333%; } + + .twelve.columns { + width: 100%; + margin-left: 0; } + + .one-third.column { + width: 30.6666666667%; } + + .two-thirds.column { + width: 65.3333333333%; } } +/* Customer Overrides */ +.footer { + text-align: center; + color: #969696; + padding-top: 10%; } + +p.module-desc { + font-size: 1.1em; + color: #666666; } + +a.link-seesrc { + color: #aec7d2; + font-style: italic; } + +a.link-seesrc:hover { + color: #6c9aae; } + +#toc-list { + word-wrap: break-word; } + +ul.simple-toc { + list-style: none; } + +ul.simple-toc a.reference-toplevel { + font-weight: bold; + color: #0077b3; } + +ul.simple-toc-section { + list-style-type: circle; + color: #6c9aae; } + +ul.simple-toc-section a.reference { + color: #0077b3; } cite { font-style: italic !important; } +dt > pre { + border-color: rgba(0, 0, 0, 0.1); + background-color: rgba(255, 255, 255, 0.3); + margin: 15px 0px 5px; } + +dd > pre { + border-color: rgba(0, 0, 0, 0.1); + background-color: whitesmoke; + margin-top: 8px; } + +.item > dd { + margin-left: 10px; + margin-bottom: 30px; } + +/* Nim line-numbered tables */ +.line-nums-table { + width: 100%; + table-layout: fixed; } /* Nim search input */ div#searchInputDiv { - margin-bottom: 1em; + margin-bottom: 8px; } -input#searchInput { - width: 80%; +div#searchInputDiv input#searchInput { + width: 10em; +} +div.search-groupby { + margin-bottom: 8px; } -/* - * Some custom formatting for input forms. - * This also fixes input form colors on Firefox with a dark system theme on Linux. - */ -input { - -moz-appearance: none; - color: #333; - background-color: #f8f8f8; - border: 1px solid #aaa; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-size: 0.9em; - padding: 6px; -} -input:focus { - border: 1px solid #1fa0eb; - box-shadow: 0 0 2px #1fa0eb; -} +table.line-nums-table { + border-radius: 4px; + border: 1px solid #cccccc; + background-color: whitesmoke; + border-collapse: separate; + margin-top: 15px; + margin-bottom: 25px; } + +.line-nums-table tbody { + border: none; } + +.line-nums-table td pre { + border: none; + background-color: transparent; } + +.line-nums-table td.blob-line-nums { + width: 28px; } + +.line-nums-table td.blob-line-nums pre { + color: #b0b0b0; + -webkit-filter: opacity(75%); + text-align: right; + border-color: transparent; + background-color: transparent; + padding-left: 0px; + margin-left: 0px; + padding-right: 0px; + margin-right: 0px; } /* Docgen styles */ /* Links */ a { - color: #07b; - text-decoration: none; -} - -a span.Identifier { - text-decoration: underline; - text-decoration-color: #aab; -} - -a.reference-toplevel { - font-weight: bold; -} - -a.toc-backref { - text-decoration: none; - color: #222; } - -a.link-seesrc { - color: #607c9f; - font-size: 0.9em; - font-style: italic; } + color: #0077b3; + text-decoration: none; } a:hover, a:focus { - color: #607c9f; + color: #00334d; text-decoration: underline; } -a:hover span.Identifier { - color: #607c9f; -} +a:visited { + color: #00334d; } +a:focus { + outline: thin dotted #2d2d2d; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; } + +a:hover, +a:active { + outline: 0; } sub, sup { @@ -227,258 +329,379 @@ img { h2, h3 { - page-break-after: avoid; } -} + page-break-after: avoid; } } +.img-rounded { + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; } +.img-polaroid { + padding: 4px; + background-color: rgba(252, 248, 244, 0.75); + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.2); + -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); } p { - margin-top: 0.5em; - margin-bottom: 0.5em; -} + margin: 0 0 8px; } small { font-size: 85%; } strong { - font-weight: 600; - font-size: 0.95em; - color: #3c3c3c; -} + font-weight: 600; } em { font-style: italic; } +cite { + font-style: normal; } + +h1, +h2, +h3, +h4, +h5, +h6 { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-weight: 600; + line-height: 20px; + color: inherit; + text-rendering: optimizelegibility; } + h1 { - font-size: 1.8em; + font-size: 2em; font-weight: 400; - padding-bottom: .25em; - border-bottom: 1px solid #aaa; - margin-top: 2.5em; - margin-bottom: 1em; + padding-bottom: .15em; + border-bottom: 1px solid #aaaaaa; + margin-top: 1.0em; line-height: 1.2em; } h1.title { padding-bottom: 1em; border-bottom: 0px; - font-size: 2.5em; - text-align: center; - font-weight: 900; - margin-top: 0.75em; - margin-bottom: 0em; -} + font-size: 2.75em; } h2 { - font-size: 1.3em; - margin-top: 2em; } - -h2.subtitle { - text-align: center; } - -h3 { - font-size: 1.125em; - font-style: italic; + font-size: 1.5em; margin-top: 1.5em; } +h3 { + font-size: 1.3em; + font-style: italic; + margin-top: 0.75em; } + h4 { - font-size: 1.125em; - margin-top: 1em; } + font-size: 1.3em; + margin-top: 0.5em; } h5 { - font-size: 1.125em; - margin-top: 0.75em; } + font-size: 1.2em; + margin-top: 0.25em; } h6 { font-size: 1.1em; } - ul, ol { padding: 0; - margin-top: 0.5em; - margin-left: 0.75em; } + margin: 0 0 0px 15px; } ul ul, ul ol, ol ol, ol ul { - margin-bottom: 0; - margin-left: 1.25em; } + margin-bottom: 0; } li { - list-style-type: circle; -} - -ul.simple-boot li { - list-style-type: none; - margin-left: 0em; - margin-bottom: 0.5em; -} - -ol.simple > li, ul.simple > li { - margin-bottom: 0.25em; - margin-left: 0.4em } - -ul.simple.simple-toc > li { - margin-top: 1em; -} - -ul.simple-toc { - list-style: none; - font-size: 0.9em; - margin-left: -0.3em; - margin-top: 1em; } - -ul.simple-toc > li { - list-style-type: none; -} - -ul.simple-toc-section { - list-style-type: circle; - margin-left: 1em; - color: #6c9aae; } - - -ol.arabic { - list-style: decimal; } - -ol.loweralpha { - list-style: lower-alpha; } - -ol.upperalpha { - list-style: upper-alpha; } - -ol.lowerroman { - list-style: lower-roman; } - -ol.upperroman { - list-style: upper-roman; } - -ul.auto-toc { - list-style-type: none; } - + line-height: 20px; } dl { - margin-bottom: 1.5em; } + margin-bottom: 20px; } + +dt, +dd { + line-height: 20px; } dt { - margin-bottom: -0.5em; - margin-left: 0.0em; } + font-weight: bold; } dd { - margin-left: 2.0em; - margin-bottom: 3.0em; - margin-top: 0.5em; } - + margin-left: 10px; + margin-bottom: 26px; } hr { - margin: 2em 0; + margin: 20px 0; border: 0; - border-top: 1px solid #aaa; } + border-top: 1px solid #eeeeee; + border-bottom: 1px solid #ffffff; } + +abbr[title], +abbr[data-original-title] { + cursor: help; + border-bottom: 1px dotted #999999; } + +abbr.initialism { + font-size: 90%; + text-transform: uppercase; } blockquote { - font-size: 0.9em; - font-style: italic; - padding-left: 0.5em; - margin-left: 0; - border-left: 5px solid #bbc; + padding: 0 0 0 15px; + margin: 0 0 20px; + border-left: 5px solid #EFEBE0; } + +table.docinfo + blockquote, table.docinfo blockquote, h1 + blockquote { + border-left: 5px solid #c9c9c9; } +table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { + margin-bottom: 0; + font-size: 15px; + font-weight: 200; + line-height: 1.5; + font-style: italic; } + +q:before, +q:after, +blockquote:before, +blockquote:after { + content: ""; } + +address { + display: block; + margin-bottom: 20px; + font-style: normal; + line-height: 20px; } + +code, +pre { + font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; + padding: 0 3px 2px; + font-weight: 500; + font-size: 12px; + color: #444444; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; } + .pre { font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - font-weight: 500; - font-size: 0.85em; - background-color: #f0f3ff; - padding-left: 3px; - padding-right: 3px; - border-radius: 4px; + font-weight: 600; + /*color: #504da6;*/ } +code { + padding: 2px 4px; + color: #444444; + white-space: nowrap; + background-color: white; + border: 1px solid #777777; } + pre { - font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - color: #222; - font-weight: 500; display: inline-block; box-sizing: border-box; - min-width: 100%; - padding: 0.5em; - margin-top: 0.5em; - margin-bottom: 0.5em; - font-size: 0.85em; + min-width: calc(100% - 19.5px); + padding: 9.5px; + margin: 0.25em 10px 10px 10px; + font-size: 15px; + line-height: 20px; white-space: pre !important; overflow-y: hidden; overflow-x: visible; - background-color: ghostwhite; - border: 1px solid #dde; - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; } + background-color: rgba(0, 0, 0, 0.01); + border: 1px solid #cccccc; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; } + +pre.prettyprint { + margin-bottom: 20px; } + +pre code { + padding: 0; + color: inherit; + white-space: pre; + overflow-x: visible; + background-color: transparent; + border: 0; } .pre-scrollable { max-height: 340px; overflow-y: scroll; } - -/* Nim line-numbered tables */ -.line-nums-table { - width: 100%; - table-layout: fixed; } - -table.line-nums-table { - border-radius: 4px; - border: 1px solid #cccccc; - background-color: ghostwhite; - border-collapse: separate; - margin-top: 15px; - margin-bottom: 25px; } - -.line-nums-table tbody { - border: none; } - -.line-nums-table td pre { - border: none; - background-color: transparent; } - -.line-nums-table td.blob-line-nums { - width: 28px; } - -.line-nums-table td.blob-line-nums pre { - color: #b0b0b0; - -webkit-filter: opacity(75%); - text-align: right; - border-color: transparent; - background-color: transparent; - padding-left: 0px; - margin-left: 0px; - padding-right: 0px; - margin-right: 0px; } - - table { max-width: 100%; background-color: transparent; - margin-top: 0.5em; - margin-bottom: 1.5em; border-collapse: collapse; - border-color: #ccc; - border-spacing: 0; - font-size: 0.9em; -} + border-spacing: 0; } table th, table td { - padding: 0px 0.5em 0px; + padding: 0px 8px 0px; } -table th { - background-color: #e8e8e8; +.table { + width: 100%; + margin-bottom: 20px; } + +.table th, +.table td { + padding: 8px; + line-height: 20px; + text-align: left; + vertical-align: top; + border-top: 1px solid #444444; } + +.table th { font-weight: bold; } -table th.docinfo-name { - background-color: transparent; -} +.table thead th { + vertical-align: bottom; } -table tr:hover { - background-color: ghostwhite; } +.table caption + thead tr:first-child th, +.table caption + thead tr:first-child td, +.table colgroup + thead tr:first-child th, +.table colgroup + thead tr:first-child td, +.table thead:first-child tr:first-child th, +.table thead:first-child tr:first-child td { + border-top: 0; } +.table tbody + tbody { + border-top: 2px solid #444444; } + +.table .table { + background-color: rgba(252, 248, 244, 0.75); } + +.table-condensed th, +.table-condensed td { + padding: 4px 5px; } + +.table-bordered { + border: 1px solid #444444; + border-collapse: separate; + *border-collapse: collapse; + border-left: 0; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; } + +.table-bordered th, +.table-bordered td { + border-left: 1px solid #444444; } + +.table-bordered caption + thead tr:first-child th, +.table-bordered caption + tbody tr:first-child th, +.table-bordered caption + tbody tr:first-child td, +.table-bordered colgroup + thead tr:first-child th, +.table-bordered colgroup + tbody tr:first-child th, +.table-bordered colgroup + tbody tr:first-child td, +.table-bordered thead:first-child tr:first-child th, +.table-bordered tbody:first-child tr:first-child th, +.table-bordered tbody:first-child tr:first-child td { + border-top: 0; } + +.table-bordered thead:first-child tr:first-child > th:first-child, +.table-bordered tbody:first-child tr:first-child > td:first-child, +.table-bordered tbody:first-child tr:first-child > th:first-child { + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; } + +.table-bordered thead:first-child tr:first-child > th:last-child, +.table-bordered tbody:first-child tr:first-child > td:last-child, +.table-bordered tbody:first-child tr:first-child > th:last-child { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; } + +.table-bordered thead:last-child tr:last-child > th:first-child, +.table-bordered tbody:last-child tr:last-child > td:first-child, +.table-bordered tbody:last-child tr:last-child > th:first-child, +.table-bordered tfoot:last-child tr:last-child > td:first-child, +.table-bordered tfoot:last-child tr:last-child > th:first-child { + -webkit-border-bottom-left-radius: 4px; + border-bottom-left-radius: 4px; + -moz-border-radius-bottomleft: 4px; } + +.table-bordered thead:last-child tr:last-child > th:last-child, +.table-bordered tbody:last-child tr:last-child > td:last-child, +.table-bordered tbody:last-child tr:last-child > th:last-child, +.table-bordered tfoot:last-child tr:last-child > td:last-child, +.table-bordered tfoot:last-child tr:last-child > th:last-child { + -webkit-border-bottom-right-radius: 4px; + border-bottom-right-radius: 4px; + -moz-border-radius-bottomright: 4px; } + +.table-bordered tfoot + tbody:last-child tr:last-child td:first-child { + -webkit-border-bottom-left-radius: 0; + border-bottom-left-radius: 0; + -moz-border-radius-bottomleft: 0; } + +.table-bordered tfoot + tbody:last-child tr:last-child td:last-child { + -webkit-border-bottom-right-radius: 0; + border-bottom-right-radius: 0; + -moz-border-radius-bottomright: 0; } + +.table-bordered caption + thead tr:first-child th:first-child, +.table-bordered caption + tbody tr:first-child td:first-child, +.table-bordered colgroup + thead tr:first-child th:first-child, +.table-bordered colgroup + tbody tr:first-child td:first-child { + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; } + +.table-bordered caption + thead tr:first-child th:last-child, +.table-bordered caption + tbody tr:first-child td:last-child, +.table-bordered colgroup + thead tr:first-child th:last-child, +.table-bordered colgroup + tbody tr:first-child td:last-child { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; } + +table.docutils th { + background-color: #e8e8e8; } + +table.docutils tr:hover { + background-color: whitesmoke; } + +.table-striped tbody > tr:nth-child(odd) > td, +.table-striped tbody > tr:nth-child(odd) > th { + background-color: rgba(252, 248, 244, 0.75); } + +.table-hover tbody tr:hover > td, +.table-hover tbody tr:hover > th { + background-color: rgba(241, 222, 204, 0.75); } + +table td[class*="span"], +table th[class*="span"], +.row-fluid table td[class*="span"], +.row-fluid table th[class*="span"] { + display: table-cell; + float: none; + margin-left: 0; } + +.hero-unit { + padding: 60px; + margin-bottom: 30px; + font-size: 18px; + font-weight: 200; + line-height: 30px; + color: inherit; + background-color: rgba(230, 197, 164, 0.75); + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; } + +.hero-unit h1 { + margin-bottom: 0; + font-size: 60px; + line-height: 1; + letter-spacing: -1px; + color: inherit; } + +.hero-unit li { + line-height: 30px; } /* rst2html default used to remove borders from tables and images */ .borderless, table.borderless td, table.borderless th { @@ -499,6 +722,10 @@ table.borderless td, table.borderless th { .hidden { display: none; } +a.toc-backref { + text-decoration: none; + color: #444444; } + blockquote.epigraph { margin: 2em 5em; } @@ -508,6 +735,85 @@ dl.docutils dd { object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] { overflow: hidden; } +/* Uncomment (and remove this text!) to get bold-faced definition list terms +dl.docutils dt { + font-weight: bold } +*/ +div.abstract { + margin: 2em 5em; } + +div.abstract p.topic-title { + font-weight: bold; + text-align: center; } + +div.admonition, div.attention, div.caution, div.danger, div.error, +div.hint, div.important, div.note, div.tip, div.warning { + margin: 2em; + border: medium outset; + padding: 1em; } + +div.note, div.warning { + margin: 1.5em 0px; + border: none; } + +div.note p.admonition-title, +div.warning p.admonition-title { + display: none; } + +/* Clearfix + * http://css-tricks.com/snippets/css/clear-fix/ + */ +div.note:after, +div.warning:after { + content: ""; + display: table; + clear: both; } + +div.note p:before, +div.warning p:before { + display: block; + float: left; + font-size: 4em; + line-height: 1em; + margin-right: 20px; + margin-left: 0em; + margin-top: -10px; + content: '\0270D'; + /*handwriting*/ } + +div.warning p:before { + content: '\026A0'; + /*warning*/ } + +div.admonition p.admonition-title, div.hint p.admonition-title, +div.important p.admonition-title, div.note p.admonition-title, +div.tip p.admonition-title { + font-weight: bold; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } + +div.attention p.admonition-title, div.caution p.admonition-title, +div.danger p.admonition-title, div.error p.admonition-title, +div.warning p.admonition-title, .code .error { + color: #b30000; + font-weight: bold; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } + +/* Uncomment (and remove this text!) to get reduced vertical space in + compound paragraphs. +div.compound .compound-first, div.compound .compound-middle { + margin-bottom: 0.5em } + +div.compound .compound-last, div.compound .compound-middle { + margin-top: 0.5em } +*/ +div.dedication { + margin: 2em 5em; + text-align: center; + font-style: italic; } + +div.dedication p.topic-title { + font-weight: bold; + font-style: normal; } div.figure { margin-left: 2em; @@ -515,14 +821,8 @@ div.figure { div.footer, div.header { clear: both; - text-align: center; - color: #666; font-size: smaller; } -div.footer { - padding-top: 5em; -} - div.line-block { display: block; margin-top: 1em; @@ -533,24 +833,45 @@ div.line-block div.line-block { margin-bottom: 0; margin-left: 1.5em; } +div.sidebar { + margin: 0 0 0.5em 1em; + border: medium outset; + padding: 1em; + background-color: rgba(252, 248, 244, 0.75); + width: 40%; + float: right; + clear: right; } + +div.sidebar p.rubric { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-size: medium; } + +div.system-messages { + margin: 5em; } + +div.system-messages h1 { + color: #b30000; } + +div.system-message { + border: medium outset; + padding: 1em; } + +div.system-message p.system-message-title { + color: #b30000; + font-weight: bold; } + div.topic { margin: 2em; } -div.search_results { - background-color: antiquewhite; - margin: 3em; - padding: 1em; - border: 1px solid #4d4d4d; -} +h1.section-subtitle, h2.section-subtitle, h3.section-subtitle, +h4.section-subtitle, h5.section-subtitle, h6.section-subtitle { + margin-top: 0.4em; } -div#global-links ul { - margin-left: 0; - list-style-type: none; -} +h1.title { + text-align: center; } -div#global-links > simple-boot { - margin-left: 3em; -} +h2.subtitle { + text-align: center; } hr.docutils { width: 75%; } @@ -584,6 +905,30 @@ img.align-center, .figure.align-center, object.align-center { div.align-right { text-align: inherit; } +/* div.align-center * { */ +/* text-align: left } */ + +ul.simple > li { + margin-bottom: 0.5em } + +ol.simple, ul.simple { + margin-bottom: 1em; } + +ol.arabic { + list-style: decimal; } + +ol.loweralpha { + list-style: lower-alpha; } + +ol.upperalpha { + list-style: upper-alpha; } + +ol.lowerroman { + list-style: lower-roman; } + +ol.upperroman { + list-style: upper-roman; } + p.attribution { text-align: right; margin-left: 50%; } @@ -604,6 +949,15 @@ p.rubric { color: maroon; text-align: center; } +p.sidebar-title { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-weight: bold; + font-size: larger; } + +p.sidebar-subtitle { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-weight: bold; } + p.topic-title { font-weight: bold; } @@ -643,14 +997,22 @@ pre.code .inserted, code .inserted { background-color: #A3D289; } span.classifier { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-style: oblique; } span.classifier-delimiter { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: bold; } +span.interpreted { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } + span.option { white-space: nowrap; } +span.pre { + white-space: pre; } + span.problematic { color: #b30000; } @@ -658,6 +1020,44 @@ span.section-subtitle { /* font-size relative to parent (h1..h6 element) */ font-size: 80%; } +table.citation { + border-left: solid 1px #666666; + margin-left: 1px; } + +table.docinfo { + margin: 0em; + margin-top: 2em; + margin-bottom: 2em; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; + color: #444444; } + +table.docutils { + margin-top: 0.5em; + margin-bottom: 0.5em; } + +table.footnote { + border-left: solid 1px #2d2d2d; + margin-left: 1px; } + +table.docutils td, table.docutils th, +table.docinfo td, table.docinfo th { + padding-left: 0.5em; + padding-right: 0.5em; + vertical-align: top; } + +table.docutils th.field-name, table.docinfo th.docinfo-name { + font-weight: 700; + text-align: left; + white-space: nowrap; + padding-left: 0; } + +h1 tt.docutils, h2 tt.docutils, h3 tt.docutils, +h4 tt.docutils, h5 tt.docutils, h6 tt.docutils { + font-size: 100%; } + +ul.auto-toc { + list-style-type: none; } + span.DecNumber { color: #252dbe; } @@ -674,7 +1074,7 @@ span.FloatNumber { color: #252dbe; } span.Identifier { - color: #222; } + color: #3b3b3b; } span.Keyword { font-weight: 600; @@ -739,23 +1139,38 @@ dt pre > span.Identifier, dt pre > span.Operator { color: #155da4; font-weight: 700; } -dt pre > span.Keyword ~ span.Identifier, dt pre > span.Identifier ~ span.Identifier, -dt pre > span.Operator ~ span.Identifier, dt pre > span.Other ~ span.Identifier { +dt pre > span.Identifier ~ span.Identifier, dt pre > span.Operator ~ span.Identifier { + color: inherit; + font-weight: inherit; } + +dt pre > span.Operator ~ span.Identifier { color: inherit; font-weight: inherit; } /* Nim sprite for the footer (taken from main page favicon) */ .nim-sprite { display: inline-block; - height: 16px; - width: 16px; + height: 12px; + width: 12px; background-position: 0 0; - background-size: 16px 16px; + background-size: 12px 12px; -webkit-filter: opacity(50%); background-repeat: no-repeat; background-image: url("data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="); margin-bottom: -5px; } +div.search_results { + background-color: antiquewhite; + margin: 3em; + padding: 1em; + border: 1px solid #4d4d4d; +} + +div#global-links ul { + margin-left: 0; + list-style-type: none; +} + span.pragmadots { /* Position: relative frees us up to make the dots look really nice without fucking up the layout and @@ -763,14 +1178,18 @@ span.pragmadots { position: relative; /* 1px down looks slightly nicer */ top: 1px; + padding: 2px; - background-color: #e8e8e8; + background-color: #D3D3D3; border-radius: 4px; margin: 0 2px; cursor: pointer; - font-size: 0.8em; -} + /* For some reason on Chrome, making the font size + smaller than 1em is causing the parent container to + bulge slightly. So, we're stuck with inheriting 1em, + which is sad, because 0.8em looks better... */ +} span.pragmadots:hover { background-color: #DBDBDB; } @@ -778,10 +1197,6 @@ span.pragmawrap { display: none; } -span.attachedType { - display: none; - visibility: hidden; -} @@ -826,7 +1241,7 @@ function main() {
cDebug:
  • cimport: cDebug()
  • + data-doc-search-tag="cimport: cDebug()" href="cimport.html#cDebug%2C">cimport: cDebug()
cDefine:
cDisableCaching:
  • cimport: cDisableCaching()
  • + data-doc-search-tag="cimport: cDisableCaching()" href="cimport.html#cDisableCaching%2C">cimport: cDisableCaching()
cImport:
cIncludeDir:
cmake:
cOverride:
cpFile:
cPlugin:
cSearchPath:
cSkipSymbol:
defineEnum:
  • types: defineEnum(typ)
  • + data-doc-search-tag="types: defineEnum(typ)" href="types.html#defineEnum.t%2C">types: defineEnum(typ)
downloadUrl:
incDir:
  • paths: incDir(): string
  • + data-doc-search-tag="paths: incDir(): string" href="paths.html#incDir%2C">paths: incDir(): string
make:
nimteropBuildDir:
  • paths: nimteropBuildDir(): string
  • + data-doc-search-tag="paths: nimteropBuildDir(): string" href="paths.html#nimteropBuildDir%2C">paths: nimteropBuildDir(): string
nimteropRoot:
  • paths: nimteropRoot(): string
  • + data-doc-search-tag="paths: nimteropRoot(): string" href="paths.html#nimteropRoot%2C">paths: nimteropRoot(): string
nimteropSrcDir:
  • paths: nimteropSrcDir(): string
  • + data-doc-search-tag="paths: nimteropSrcDir(): string" href="paths.html#nimteropSrcDir%2C">paths: nimteropSrcDir(): string
OnSymbol:
testsIncludeDir:
  • paths: testsIncludeDir(): string
  • + data-doc-search-tag="paths: testsIncludeDir(): string" href="paths.html#testsIncludeDir%2C">paths: testsIncludeDir(): string
time_t:
toastExePath:
  • paths: toastExePath(): string
  • + data-doc-search-tag="paths: toastExePath(): string" href="paths.html#toastExePath%2C">paths: toastExePath(): string
va_list:

  • - Made with Nim. Generated: 2019-07-18 06:10:50 UTC + Made with Nim. Generated: 2019-07-29 14:17:11 UTC diff --git a/types.html b/types.html index 7c5fff9..a15d2da 100644 --- a/types.html +++ b/types.html @@ -27,130 +27,232 @@ customize this style sheet. Modified from Chad Skeeters' rst2html-style https://bitbucket.org/cskeeters/rst2html-style/ -Modified by Boyd Greenfield and narimiran +Modified by Boyd Greenfield */ - +/* SCSS variables */ +/* Text weights */ +/* Body colors */ +/* Text colors */ +/* Link colors */ +/* Syntax highlighting colors */ +/* Pct changes */ +/* Mixins */ +/* Body/layout */ html { font-size: 100%; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; } +/* Where we want fancier font if available */ +h1, h2, h3, h4, h5, h6, p.module-desc, table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; } + +h1.title { + font-weight: 900; } + body { font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: 400; - font-size: 1.125em; - line-height: 1.5; - color: #222; - background-color: #FCFCFC; } + font-size: 16px; + line-height: 20px; + color: #444; + letter-spacing: 0.15px; + background-color: #FDFBFA; } /* Skeleton grid */ .container { position: relative; width: 100%; - max-width: 1050px; + max-width: 960px; margin: 0 auto; - padding: 0; + padding: 0 20px; box-sizing: border-box; } .column, .columns { width: 100%; float: left; - box-sizing: border-box; - margin-left: 1%; -} + box-sizing: border-box; } -.column:first-child, -.columns:first-child { - margin-left: 0; } +/* For devices larger than 400px */ +@media (min-width: 400px) { + .container { + width: 100%; + padding: 0; } } +/* For devices larger than 650px */ +@media (min-width: 650px) { + .container { + width: 100%; } -.three.columns { - width: 19%; } + .column, + .columns { + margin-left: 4%; } -.nine.columns { - width: 80.0%; } + .column:first-child, + .columns:first-child { + margin-left: 0; } -.twelve.columns { - width: 100%; - margin-left: 0; } + .one.column, + .one.columns { + width: 4.66666666667%; } + + .two.columns { + width: 13.3333333333%; } -@media screen and (max-width: 860px) { .three.columns { - display: none; - } + width: 22%; } + + .four.columns { + width: 30.6666666667%; } + + .five.columns { + width: 39.3333333333%; } + + .six.columns { + width: 48%; } + + .seven.columns { + width: 56.6666666667%; } + + .eight.columns { + width: 65.3333333333%; } + .nine.columns { - width: 98.0%; - } - body { - font-size: 1em; - line-height: 1.35; - } -} + width: 74.0%; } + + .ten.columns { + width: 82.6666666667%; } + + .eleven.columns { + width: 91.3333333333%; } + + .twelve.columns { + width: 100%; + margin-left: 0; } + + .one-third.column { + width: 30.6666666667%; } + + .two-thirds.column { + width: 65.3333333333%; } } +/* Customer Overrides */ +.footer { + text-align: center; + color: #969696; + padding-top: 10%; } + +p.module-desc { + font-size: 1.1em; + color: #666666; } + +a.link-seesrc { + color: #aec7d2; + font-style: italic; } + +a.link-seesrc:hover { + color: #6c9aae; } + +#toc-list { + word-wrap: break-word; } + +ul.simple-toc { + list-style: none; } + +ul.simple-toc a.reference-toplevel { + font-weight: bold; + color: #0077b3; } + +ul.simple-toc-section { + list-style-type: circle; + color: #6c9aae; } + +ul.simple-toc-section a.reference { + color: #0077b3; } cite { font-style: italic !important; } +dt > pre { + border-color: rgba(0, 0, 0, 0.1); + background-color: rgba(255, 255, 255, 0.3); + margin: 15px 0px 5px; } + +dd > pre { + border-color: rgba(0, 0, 0, 0.1); + background-color: whitesmoke; + margin-top: 8px; } + +.item > dd { + margin-left: 10px; + margin-bottom: 30px; } + +/* Nim line-numbered tables */ +.line-nums-table { + width: 100%; + table-layout: fixed; } /* Nim search input */ div#searchInputDiv { - margin-bottom: 1em; + margin-bottom: 8px; } -input#searchInput { - width: 80%; +div#searchInputDiv input#searchInput { + width: 10em; +} +div.search-groupby { + margin-bottom: 8px; } -/* - * Some custom formatting for input forms. - * This also fixes input form colors on Firefox with a dark system theme on Linux. - */ -input { - -moz-appearance: none; - color: #333; - background-color: #f8f8f8; - border: 1px solid #aaa; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-size: 0.9em; - padding: 6px; -} -input:focus { - border: 1px solid #1fa0eb; - box-shadow: 0 0 2px #1fa0eb; -} +table.line-nums-table { + border-radius: 4px; + border: 1px solid #cccccc; + background-color: whitesmoke; + border-collapse: separate; + margin-top: 15px; + margin-bottom: 25px; } + +.line-nums-table tbody { + border: none; } + +.line-nums-table td pre { + border: none; + background-color: transparent; } + +.line-nums-table td.blob-line-nums { + width: 28px; } + +.line-nums-table td.blob-line-nums pre { + color: #b0b0b0; + -webkit-filter: opacity(75%); + text-align: right; + border-color: transparent; + background-color: transparent; + padding-left: 0px; + margin-left: 0px; + padding-right: 0px; + margin-right: 0px; } /* Docgen styles */ /* Links */ a { - color: #07b; - text-decoration: none; -} - -a span.Identifier { - text-decoration: underline; - text-decoration-color: #aab; -} - -a.reference-toplevel { - font-weight: bold; -} - -a.toc-backref { - text-decoration: none; - color: #222; } - -a.link-seesrc { - color: #607c9f; - font-size: 0.9em; - font-style: italic; } + color: #0077b3; + text-decoration: none; } a:hover, a:focus { - color: #607c9f; + color: #00334d; text-decoration: underline; } -a:hover span.Identifier { - color: #607c9f; -} +a:visited { + color: #00334d; } +a:focus { + outline: thin dotted #2d2d2d; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; } + +a:hover, +a:active { + outline: 0; } sub, sup { @@ -227,258 +329,379 @@ img { h2, h3 { - page-break-after: avoid; } -} + page-break-after: avoid; } } +.img-rounded { + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; } +.img-polaroid { + padding: 4px; + background-color: rgba(252, 248, 244, 0.75); + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.2); + -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); } p { - margin-top: 0.5em; - margin-bottom: 0.5em; -} + margin: 0 0 8px; } small { font-size: 85%; } strong { - font-weight: 600; - font-size: 0.95em; - color: #3c3c3c; -} + font-weight: 600; } em { font-style: italic; } +cite { + font-style: normal; } + +h1, +h2, +h3, +h4, +h5, +h6 { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-weight: 600; + line-height: 20px; + color: inherit; + text-rendering: optimizelegibility; } + h1 { - font-size: 1.8em; + font-size: 2em; font-weight: 400; - padding-bottom: .25em; - border-bottom: 1px solid #aaa; - margin-top: 2.5em; - margin-bottom: 1em; + padding-bottom: .15em; + border-bottom: 1px solid #aaaaaa; + margin-top: 1.0em; line-height: 1.2em; } h1.title { padding-bottom: 1em; border-bottom: 0px; - font-size: 2.5em; - text-align: center; - font-weight: 900; - margin-top: 0.75em; - margin-bottom: 0em; -} + font-size: 2.75em; } h2 { - font-size: 1.3em; - margin-top: 2em; } - -h2.subtitle { - text-align: center; } - -h3 { - font-size: 1.125em; - font-style: italic; + font-size: 1.5em; margin-top: 1.5em; } +h3 { + font-size: 1.3em; + font-style: italic; + margin-top: 0.75em; } + h4 { - font-size: 1.125em; - margin-top: 1em; } + font-size: 1.3em; + margin-top: 0.5em; } h5 { - font-size: 1.125em; - margin-top: 0.75em; } + font-size: 1.2em; + margin-top: 0.25em; } h6 { font-size: 1.1em; } - ul, ol { padding: 0; - margin-top: 0.5em; - margin-left: 0.75em; } + margin: 0 0 0px 15px; } ul ul, ul ol, ol ol, ol ul { - margin-bottom: 0; - margin-left: 1.25em; } + margin-bottom: 0; } li { - list-style-type: circle; -} - -ul.simple-boot li { - list-style-type: none; - margin-left: 0em; - margin-bottom: 0.5em; -} - -ol.simple > li, ul.simple > li { - margin-bottom: 0.25em; - margin-left: 0.4em } - -ul.simple.simple-toc > li { - margin-top: 1em; -} - -ul.simple-toc { - list-style: none; - font-size: 0.9em; - margin-left: -0.3em; - margin-top: 1em; } - -ul.simple-toc > li { - list-style-type: none; -} - -ul.simple-toc-section { - list-style-type: circle; - margin-left: 1em; - color: #6c9aae; } - - -ol.arabic { - list-style: decimal; } - -ol.loweralpha { - list-style: lower-alpha; } - -ol.upperalpha { - list-style: upper-alpha; } - -ol.lowerroman { - list-style: lower-roman; } - -ol.upperroman { - list-style: upper-roman; } - -ul.auto-toc { - list-style-type: none; } - + line-height: 20px; } dl { - margin-bottom: 1.5em; } + margin-bottom: 20px; } + +dt, +dd { + line-height: 20px; } dt { - margin-bottom: -0.5em; - margin-left: 0.0em; } + font-weight: bold; } dd { - margin-left: 2.0em; - margin-bottom: 3.0em; - margin-top: 0.5em; } - + margin-left: 10px; + margin-bottom: 26px; } hr { - margin: 2em 0; + margin: 20px 0; border: 0; - border-top: 1px solid #aaa; } + border-top: 1px solid #eeeeee; + border-bottom: 1px solid #ffffff; } + +abbr[title], +abbr[data-original-title] { + cursor: help; + border-bottom: 1px dotted #999999; } + +abbr.initialism { + font-size: 90%; + text-transform: uppercase; } blockquote { - font-size: 0.9em; - font-style: italic; - padding-left: 0.5em; - margin-left: 0; - border-left: 5px solid #bbc; + padding: 0 0 0 15px; + margin: 0 0 20px; + border-left: 5px solid #EFEBE0; } + +table.docinfo + blockquote, table.docinfo blockquote, h1 + blockquote { + border-left: 5px solid #c9c9c9; } +table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { + margin-bottom: 0; + font-size: 15px; + font-weight: 200; + line-height: 1.5; + font-style: italic; } + +q:before, +q:after, +blockquote:before, +blockquote:after { + content: ""; } + +address { + display: block; + margin-bottom: 20px; + font-style: normal; + line-height: 20px; } + +code, +pre { + font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; + padding: 0 3px 2px; + font-weight: 500; + font-size: 12px; + color: #444444; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; } + .pre { font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - font-weight: 500; - font-size: 0.85em; - background-color: #f0f3ff; - padding-left: 3px; - padding-right: 3px; - border-radius: 4px; + font-weight: 600; + /*color: #504da6;*/ } +code { + padding: 2px 4px; + color: #444444; + white-space: nowrap; + background-color: white; + border: 1px solid #777777; } + pre { - font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - color: #222; - font-weight: 500; display: inline-block; box-sizing: border-box; - min-width: 100%; - padding: 0.5em; - margin-top: 0.5em; - margin-bottom: 0.5em; - font-size: 0.85em; + min-width: calc(100% - 19.5px); + padding: 9.5px; + margin: 0.25em 10px 10px 10px; + font-size: 15px; + line-height: 20px; white-space: pre !important; overflow-y: hidden; overflow-x: visible; - background-color: ghostwhite; - border: 1px solid #dde; - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; } + background-color: rgba(0, 0, 0, 0.01); + border: 1px solid #cccccc; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; } + +pre.prettyprint { + margin-bottom: 20px; } + +pre code { + padding: 0; + color: inherit; + white-space: pre; + overflow-x: visible; + background-color: transparent; + border: 0; } .pre-scrollable { max-height: 340px; overflow-y: scroll; } - -/* Nim line-numbered tables */ -.line-nums-table { - width: 100%; - table-layout: fixed; } - -table.line-nums-table { - border-radius: 4px; - border: 1px solid #cccccc; - background-color: ghostwhite; - border-collapse: separate; - margin-top: 15px; - margin-bottom: 25px; } - -.line-nums-table tbody { - border: none; } - -.line-nums-table td pre { - border: none; - background-color: transparent; } - -.line-nums-table td.blob-line-nums { - width: 28px; } - -.line-nums-table td.blob-line-nums pre { - color: #b0b0b0; - -webkit-filter: opacity(75%); - text-align: right; - border-color: transparent; - background-color: transparent; - padding-left: 0px; - margin-left: 0px; - padding-right: 0px; - margin-right: 0px; } - - table { max-width: 100%; background-color: transparent; - margin-top: 0.5em; - margin-bottom: 1.5em; border-collapse: collapse; - border-color: #ccc; - border-spacing: 0; - font-size: 0.9em; -} + border-spacing: 0; } table th, table td { - padding: 0px 0.5em 0px; + padding: 0px 8px 0px; } -table th { - background-color: #e8e8e8; +.table { + width: 100%; + margin-bottom: 20px; } + +.table th, +.table td { + padding: 8px; + line-height: 20px; + text-align: left; + vertical-align: top; + border-top: 1px solid #444444; } + +.table th { font-weight: bold; } -table th.docinfo-name { - background-color: transparent; -} +.table thead th { + vertical-align: bottom; } -table tr:hover { - background-color: ghostwhite; } +.table caption + thead tr:first-child th, +.table caption + thead tr:first-child td, +.table colgroup + thead tr:first-child th, +.table colgroup + thead tr:first-child td, +.table thead:first-child tr:first-child th, +.table thead:first-child tr:first-child td { + border-top: 0; } +.table tbody + tbody { + border-top: 2px solid #444444; } + +.table .table { + background-color: rgba(252, 248, 244, 0.75); } + +.table-condensed th, +.table-condensed td { + padding: 4px 5px; } + +.table-bordered { + border: 1px solid #444444; + border-collapse: separate; + *border-collapse: collapse; + border-left: 0; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; } + +.table-bordered th, +.table-bordered td { + border-left: 1px solid #444444; } + +.table-bordered caption + thead tr:first-child th, +.table-bordered caption + tbody tr:first-child th, +.table-bordered caption + tbody tr:first-child td, +.table-bordered colgroup + thead tr:first-child th, +.table-bordered colgroup + tbody tr:first-child th, +.table-bordered colgroup + tbody tr:first-child td, +.table-bordered thead:first-child tr:first-child th, +.table-bordered tbody:first-child tr:first-child th, +.table-bordered tbody:first-child tr:first-child td { + border-top: 0; } + +.table-bordered thead:first-child tr:first-child > th:first-child, +.table-bordered tbody:first-child tr:first-child > td:first-child, +.table-bordered tbody:first-child tr:first-child > th:first-child { + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; } + +.table-bordered thead:first-child tr:first-child > th:last-child, +.table-bordered tbody:first-child tr:first-child > td:last-child, +.table-bordered tbody:first-child tr:first-child > th:last-child { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; } + +.table-bordered thead:last-child tr:last-child > th:first-child, +.table-bordered tbody:last-child tr:last-child > td:first-child, +.table-bordered tbody:last-child tr:last-child > th:first-child, +.table-bordered tfoot:last-child tr:last-child > td:first-child, +.table-bordered tfoot:last-child tr:last-child > th:first-child { + -webkit-border-bottom-left-radius: 4px; + border-bottom-left-radius: 4px; + -moz-border-radius-bottomleft: 4px; } + +.table-bordered thead:last-child tr:last-child > th:last-child, +.table-bordered tbody:last-child tr:last-child > td:last-child, +.table-bordered tbody:last-child tr:last-child > th:last-child, +.table-bordered tfoot:last-child tr:last-child > td:last-child, +.table-bordered tfoot:last-child tr:last-child > th:last-child { + -webkit-border-bottom-right-radius: 4px; + border-bottom-right-radius: 4px; + -moz-border-radius-bottomright: 4px; } + +.table-bordered tfoot + tbody:last-child tr:last-child td:first-child { + -webkit-border-bottom-left-radius: 0; + border-bottom-left-radius: 0; + -moz-border-radius-bottomleft: 0; } + +.table-bordered tfoot + tbody:last-child tr:last-child td:last-child { + -webkit-border-bottom-right-radius: 0; + border-bottom-right-radius: 0; + -moz-border-radius-bottomright: 0; } + +.table-bordered caption + thead tr:first-child th:first-child, +.table-bordered caption + tbody tr:first-child td:first-child, +.table-bordered colgroup + thead tr:first-child th:first-child, +.table-bordered colgroup + tbody tr:first-child td:first-child { + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; } + +.table-bordered caption + thead tr:first-child th:last-child, +.table-bordered caption + tbody tr:first-child td:last-child, +.table-bordered colgroup + thead tr:first-child th:last-child, +.table-bordered colgroup + tbody tr:first-child td:last-child { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; } + +table.docutils th { + background-color: #e8e8e8; } + +table.docutils tr:hover { + background-color: whitesmoke; } + +.table-striped tbody > tr:nth-child(odd) > td, +.table-striped tbody > tr:nth-child(odd) > th { + background-color: rgba(252, 248, 244, 0.75); } + +.table-hover tbody tr:hover > td, +.table-hover tbody tr:hover > th { + background-color: rgba(241, 222, 204, 0.75); } + +table td[class*="span"], +table th[class*="span"], +.row-fluid table td[class*="span"], +.row-fluid table th[class*="span"] { + display: table-cell; + float: none; + margin-left: 0; } + +.hero-unit { + padding: 60px; + margin-bottom: 30px; + font-size: 18px; + font-weight: 200; + line-height: 30px; + color: inherit; + background-color: rgba(230, 197, 164, 0.75); + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; } + +.hero-unit h1 { + margin-bottom: 0; + font-size: 60px; + line-height: 1; + letter-spacing: -1px; + color: inherit; } + +.hero-unit li { + line-height: 30px; } /* rst2html default used to remove borders from tables and images */ .borderless, table.borderless td, table.borderless th { @@ -499,6 +722,10 @@ table.borderless td, table.borderless th { .hidden { display: none; } +a.toc-backref { + text-decoration: none; + color: #444444; } + blockquote.epigraph { margin: 2em 5em; } @@ -508,6 +735,85 @@ dl.docutils dd { object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] { overflow: hidden; } +/* Uncomment (and remove this text!) to get bold-faced definition list terms +dl.docutils dt { + font-weight: bold } +*/ +div.abstract { + margin: 2em 5em; } + +div.abstract p.topic-title { + font-weight: bold; + text-align: center; } + +div.admonition, div.attention, div.caution, div.danger, div.error, +div.hint, div.important, div.note, div.tip, div.warning { + margin: 2em; + border: medium outset; + padding: 1em; } + +div.note, div.warning { + margin: 1.5em 0px; + border: none; } + +div.note p.admonition-title, +div.warning p.admonition-title { + display: none; } + +/* Clearfix + * http://css-tricks.com/snippets/css/clear-fix/ + */ +div.note:after, +div.warning:after { + content: ""; + display: table; + clear: both; } + +div.note p:before, +div.warning p:before { + display: block; + float: left; + font-size: 4em; + line-height: 1em; + margin-right: 20px; + margin-left: 0em; + margin-top: -10px; + content: '\0270D'; + /*handwriting*/ } + +div.warning p:before { + content: '\026A0'; + /*warning*/ } + +div.admonition p.admonition-title, div.hint p.admonition-title, +div.important p.admonition-title, div.note p.admonition-title, +div.tip p.admonition-title { + font-weight: bold; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } + +div.attention p.admonition-title, div.caution p.admonition-title, +div.danger p.admonition-title, div.error p.admonition-title, +div.warning p.admonition-title, .code .error { + color: #b30000; + font-weight: bold; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } + +/* Uncomment (and remove this text!) to get reduced vertical space in + compound paragraphs. +div.compound .compound-first, div.compound .compound-middle { + margin-bottom: 0.5em } + +div.compound .compound-last, div.compound .compound-middle { + margin-top: 0.5em } +*/ +div.dedication { + margin: 2em 5em; + text-align: center; + font-style: italic; } + +div.dedication p.topic-title { + font-weight: bold; + font-style: normal; } div.figure { margin-left: 2em; @@ -515,14 +821,8 @@ div.figure { div.footer, div.header { clear: both; - text-align: center; - color: #666; font-size: smaller; } -div.footer { - padding-top: 5em; -} - div.line-block { display: block; margin-top: 1em; @@ -533,24 +833,45 @@ div.line-block div.line-block { margin-bottom: 0; margin-left: 1.5em; } +div.sidebar { + margin: 0 0 0.5em 1em; + border: medium outset; + padding: 1em; + background-color: rgba(252, 248, 244, 0.75); + width: 40%; + float: right; + clear: right; } + +div.sidebar p.rubric { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-size: medium; } + +div.system-messages { + margin: 5em; } + +div.system-messages h1 { + color: #b30000; } + +div.system-message { + border: medium outset; + padding: 1em; } + +div.system-message p.system-message-title { + color: #b30000; + font-weight: bold; } + div.topic { margin: 2em; } -div.search_results { - background-color: antiquewhite; - margin: 3em; - padding: 1em; - border: 1px solid #4d4d4d; -} +h1.section-subtitle, h2.section-subtitle, h3.section-subtitle, +h4.section-subtitle, h5.section-subtitle, h6.section-subtitle { + margin-top: 0.4em; } -div#global-links ul { - margin-left: 0; - list-style-type: none; -} +h1.title { + text-align: center; } -div#global-links > simple-boot { - margin-left: 3em; -} +h2.subtitle { + text-align: center; } hr.docutils { width: 75%; } @@ -584,6 +905,30 @@ img.align-center, .figure.align-center, object.align-center { div.align-right { text-align: inherit; } +/* div.align-center * { */ +/* text-align: left } */ + +ul.simple > li { + margin-bottom: 0.5em } + +ol.simple, ul.simple { + margin-bottom: 1em; } + +ol.arabic { + list-style: decimal; } + +ol.loweralpha { + list-style: lower-alpha; } + +ol.upperalpha { + list-style: upper-alpha; } + +ol.lowerroman { + list-style: lower-roman; } + +ol.upperroman { + list-style: upper-roman; } + p.attribution { text-align: right; margin-left: 50%; } @@ -604,6 +949,15 @@ p.rubric { color: maroon; text-align: center; } +p.sidebar-title { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-weight: bold; + font-size: larger; } + +p.sidebar-subtitle { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-weight: bold; } + p.topic-title { font-weight: bold; } @@ -643,14 +997,22 @@ pre.code .inserted, code .inserted { background-color: #A3D289; } span.classifier { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-style: oblique; } span.classifier-delimiter { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: bold; } +span.interpreted { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } + span.option { white-space: nowrap; } +span.pre { + white-space: pre; } + span.problematic { color: #b30000; } @@ -658,6 +1020,44 @@ span.section-subtitle { /* font-size relative to parent (h1..h6 element) */ font-size: 80%; } +table.citation { + border-left: solid 1px #666666; + margin-left: 1px; } + +table.docinfo { + margin: 0em; + margin-top: 2em; + margin-bottom: 2em; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; + color: #444444; } + +table.docutils { + margin-top: 0.5em; + margin-bottom: 0.5em; } + +table.footnote { + border-left: solid 1px #2d2d2d; + margin-left: 1px; } + +table.docutils td, table.docutils th, +table.docinfo td, table.docinfo th { + padding-left: 0.5em; + padding-right: 0.5em; + vertical-align: top; } + +table.docutils th.field-name, table.docinfo th.docinfo-name { + font-weight: 700; + text-align: left; + white-space: nowrap; + padding-left: 0; } + +h1 tt.docutils, h2 tt.docutils, h3 tt.docutils, +h4 tt.docutils, h5 tt.docutils, h6 tt.docutils { + font-size: 100%; } + +ul.auto-toc { + list-style-type: none; } + span.DecNumber { color: #252dbe; } @@ -674,7 +1074,7 @@ span.FloatNumber { color: #252dbe; } span.Identifier { - color: #222; } + color: #3b3b3b; } span.Keyword { font-weight: 600; @@ -739,23 +1139,38 @@ dt pre > span.Identifier, dt pre > span.Operator { color: #155da4; font-weight: 700; } -dt pre > span.Keyword ~ span.Identifier, dt pre > span.Identifier ~ span.Identifier, -dt pre > span.Operator ~ span.Identifier, dt pre > span.Other ~ span.Identifier { +dt pre > span.Identifier ~ span.Identifier, dt pre > span.Operator ~ span.Identifier { + color: inherit; + font-weight: inherit; } + +dt pre > span.Operator ~ span.Identifier { color: inherit; font-weight: inherit; } /* Nim sprite for the footer (taken from main page favicon) */ .nim-sprite { display: inline-block; - height: 16px; - width: 16px; + height: 12px; + width: 12px; background-position: 0 0; - background-size: 16px 16px; + background-size: 12px 12px; -webkit-filter: opacity(50%); background-repeat: no-repeat; background-image: url("data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="); margin-bottom: -5px; } +div.search_results { + background-color: antiquewhite; + margin: 3em; + padding: 1em; + border: 1px solid #4d4d4d; +} + +div#global-links ul { + margin-left: 0; + list-style-type: none; +} + span.pragmadots { /* Position: relative frees us up to make the dots look really nice without fucking up the layout and @@ -763,14 +1178,18 @@ span.pragmadots { position: relative; /* 1px down looks slightly nicer */ top: 1px; + padding: 2px; - background-color: #e8e8e8; + background-color: #D3D3D3; border-radius: 4px; margin: 0 2px; cursor: pointer; - font-size: 0.8em; -} + /* For some reason on Chrome, making the font size + smaller than 1em is causing the parent container to + bulge slightly. So, we're stuck with inheriting 1em, + which is sad, because 0.8em looks better... */ +} span.pragmadots:hover { background-color: #DBDBDB; } @@ -778,10 +1197,6 @@ span.pragmawrap { display: none; } -span.attachedType { - display: none; - visibility: hidden; -} @@ -827,11 +1242,11 @@ function main() {
    Types
    • time_t
    • + title="time_t = Time">time_t
    • ptrdiff_t
    • + title="ptrdiff_t = ByteAddress">ptrdiff_t
    • va_list
    • + title="va_list {.importc, header: "<stdarg.h>".} = object">va_list
  • @@ -839,9 +1254,9 @@ function main() { Templates @@ -851,31 +1266,27 @@ function main() {
    -

    Types

    -
    time_t = time_t_temp.Time
    +
    time_t = Time
    -
    ptrdiff_t = ByteAddress
    -
    va_list {...}{.importc, header: "<stdarg.h>".} = object
    -
    @@ -883,18 +1294,16 @@ function main() {

    Templates

    -
    template enumOp(op, typ, typout)
    +
    template enumOp(op, typ, typout)
    -
    - -
    template defineEnum(typ)
    + +
    template defineEnum(typ)
    -
    @@ -906,7 +1315,7 @@ function main() { diff --git a/types.idx b/types.idx index 5bc0938..d4ab217 100644 --- a/types.idx +++ b/types.idx @@ -2,4 +2,4 @@ time_t types.html#time_t types: time_t ptrdiff_t types.html#ptrdiff_t types: ptrdiff_t va_list types.html#va_list types: va_list enumOp types.html#enumOp.t,,, types: enumOp(op, typ, typout) -defineEnum types.html#defineEnum.t types: defineEnum(typ) +defineEnum types.html#defineEnum.t, types: defineEnum(typ) From 0d41564e92fac7058be3454a3c2ee30621a608d9 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 29 Jul 2019 09:17:36 -0500 Subject: [PATCH 231/593] Fix #135 - plist doc fix --- nimterop/git.nim | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/nimterop/git.nim b/nimterop/git.nim index 6e8fcac..6566c0e 100644 --- a/nimterop/git.nim +++ b/nimterop/git.nim @@ -103,7 +103,8 @@ proc gitCheckout*(file, outdir: string) = ## Checkout the specified file in the git repository specified ## ## This effectively resets all changes in the file and can be - ## used after `cImport()` if required. + ## used to undo any changes that were made to source files to enable + ## successful wrapping with `cImport()` or `c2nImport()`. echo "# Resetting " & file let file2 = file.relativePath outdir let cmd = &"cd {outdir.quoteShell} && git checkout {file2.quoteShell}" @@ -115,7 +116,13 @@ proc gitPull*(url: string, outdir = "", plist = "", checkout = "") = ## Pull the specified git repository to the output directory ## ## `plist` is the list of specific files and directories or wildcards - ## to sparse checkout. Multiples can be specified one entry per line. + ## to sparsely checkout. Multiple values can be specified one entry per + ## line. It is optional and if omitted, the entire repository will be + ## checked out. + ## + ## `checkout` is the git tag, branch or commit hash to checkout once + ## the repository is downloaded. This allows for pinning to a specific + ## version of the code. if dirExists(outdir/".git"): gitReset(outdir) return From e159eb7c9c996d62eecdea4fb989e09566d8dfad Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 29 Jul 2019 19:08:17 -0500 Subject: [PATCH 232/593] Flags for toast, docs update --- nimterop/cimport.nim | 75 ++++++++++++++++++++++++++------------------ 1 file changed, 44 insertions(+), 31 deletions(-) diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index 1249ee9..8c3d6c7 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -124,7 +124,8 @@ proc getNimCheckError(output: string): tuple[tmpFile, errors: string] = result.errors = "\n\n" & check -proc getToast(fullpath: string, recurse: bool = false, dynlib: string = "", noNimout = false): string = +proc getToast(fullpath: string, recurse: bool = false, dynlib: string = "", + mode = "c", flags = "", noNimout = false): string = var ret = 0 cmd = when defined(Windows): "cmd /c " else: "" @@ -137,6 +138,9 @@ proc getToast(fullpath: string, recurse: bool = false, dynlib: string = "", noNi if recurse: cmd.add " --recurse" + if flags.len != 0: + cmd.add flags + for i in gStateCT.defines: cmd.add &" --defines+={i.quoteShell}" @@ -175,7 +179,7 @@ proc getGccPaths(mode = "c"): string = macro cOverride*(body): untyped = ## When the wrapper code generated by nimterop is missing certain symbols or not ## accurate, it may be required to hand wrap them. Define them in a - ## `cOverride() `_ macro block so that Nimterop no + ## `cOverride() `_ macro block so that Nimterop no ## longer defines these symbols. ## ## For example: @@ -197,12 +201,12 @@ macro cOverride*(body): untyped = ## cOverride: ## proc svGetCallerInfo(fileName: var cstring; lineNumber: var cint) ## - ## Using the `cOverride() `_ block, nimterop + ## Using the `cOverride() `_ block, nimterop ## can be instructed to skip over ``svGetCallerInfo()``. This works for procs, ## consts and types. ## - ## `cOverride() `_ only affects calls to - ## `cImport() `_ that follow it. + ## `cOverride() `_ only affects calls to + ## `cImport() `_ that follow it. proc recFindIdent(node: NimNode): seq[string] = if node.kind != nnkIdent: @@ -222,18 +226,18 @@ macro cOverride*(body): untyped = echo "# Overriding " & gStateCT.symOverride.join(" ") proc cSkipSymbol*(skips: seq[string]) {.compileTime.} = - ## Similar to `cOverride() `_, this macro allows + ## Similar to `cOverride() `_, this macro allows ## filtering out symbols not of interest from the generated output. ## - ## `cSkipSymbol() `_ only affects calls to - ## `cImport() `_ that follow it. + ## `cSkipSymbol() `_ only affects calls to + ## `cImport() `_ that follow it. runnableExamples: static: cSkipSymbol @["proc1", "Type2"] gStateCT.symOverride.add skips macro cPlugin*(body): untyped = - ## When `cOverride() `_ and `cSkipSymbol() `_ - ## are not adequate, the `cPlugin() `_ macro can be used + ## When `cOverride() `_ and `cSkipSymbol() `_ + ## are not adequate, the `cPlugin() `_ macro can be used ## to customize the generated Nim output. The following callbacks are available at ## this time. ## @@ -259,8 +263,8 @@ macro cPlugin*(body): untyped = ## ## ``nimterop/plugins`` is implicitly imported to provide access to standard plugin facilities. ## - ## `cPlugin() `_ only affects calls to - ## `cImport() `_ that follow it. + ## `cPlugin() `_ only affects calls to + ## `cImport() `_ that follow it. runnableExamples: cPlugin: import strutils @@ -292,13 +296,13 @@ macro cPlugin*(body): untyped = proc cSearchPath*(path: string): string {.compileTime.}= ## Get full path to file or directory ``path`` in search path configured - ## using `cAddSearchDir() `_ and + ## using `cAddSearchDir() `_ and ## `cAddStdDir() `_. ## ## This can be used to locate files or directories that can be passed onto - ## `cCompile() `_, - ## `cIncludeDir() `_ and - ## `cImport() `_. + ## `cCompile() `_, + ## `cIncludeDir() `_ and + ## `cImport() `_. result = findPath(path, fail = false) if result.len == 0: @@ -318,9 +322,9 @@ proc cDebug*() {.compileTime.} = proc cDisableCaching*() {.compileTime.} = ## Disable caching of generated Nim code - useful during wrapper development ## - ## If files included by header being processed by `cImport() `_ + ## If files included by header being processed by `cImport() `_ ## change and affect the generated content, they will be ignored and the cached - ## value will continue to be used . Use `cDisableCaching() `_ + ## value will continue to be used . Use `cDisableCaching() `_ ## to avoid this scenario during development. ## ## ``nim -f`` was broken prior to 0.19.4 but can also be used to flush the cached content. @@ -328,8 +332,10 @@ proc cDisableCaching*() {.compileTime.} = gStateCT.nocache = true macro cDefine*(name: static string, val: static string = ""): untyped = - ## ``#define`` an identifer that is forwarded to the C/C++ compiler - ## using ``{.passC: "-DXXX".}`` + ## ``#define`` an identifer that is forwarded to the C/C++ preprocessor if + ## called within `cImport() `_ + ## or `c2nImport() `_ as well as to the + ## C/C++ compiler during Nim compilation using ``{.passC: "-DXXX".}`` result = newNimNode(nnkStmtList) @@ -362,9 +368,10 @@ proc cAddSearchDir*(dir: string) {.compileTime.} = gStateCT.searchDirs.add(dir) macro cIncludeDir*(dir: static string): untyped = - ## Add an include directory that is forwarded to the C/C++ compiler - ## using ``{.passC: "-IXXX".}``. This is also provided to the - ## preprocessor during Nim code generation. + ## Add an include directory that is forwarded to the C/C++ preprocessor if + ## called within `cImport() `_ + ## or `c2nImport() `_ as well as to the + ## C/C++ compiler during Nim compilation using ``{.passC: "-IXXX".}``. var dir = interpPath(dir) result = newNimNode(nnkStmtList) @@ -489,16 +496,17 @@ macro cCompile*(path: static string, mode = "c", exclude = ""): untyped = if gStateCT.debug: echo result.repr -macro cImport*(filename: static string, recurse: static bool = false, dynlib: static string = ""): untyped = +macro cImport*(filename: static string, recurse: static bool = false, dynlib: static string = "", + mode: static string = "c", flags: static string = ""): untyped = ## Import all supported definitions from specified header file. Generated ## content is cached in ``nimcache`` until ``filename`` changes unless - ## `cDisableCaching() `_ is set. ``nim -f`` + ## `cDisableCaching() `_ is set. ``nim -f`` ## can also be used after Nim v0.19.4 to flush the cache. ## ## ``recurse`` can be used to generate Nim wrappers from ``#include`` files ## referenced in ``filename``. This is only done for files in the same ## directory as ``filename`` or in a directory added using - ## `cIncludeDir() `_ + ## `cIncludeDir() `_ ## ## ``dynlib`` can be used to specify the Nim string to use to specify the dynamic ## library to load the imported symbols from. For example: @@ -520,8 +528,13 @@ macro cImport*(filename: static string, recurse: static bool = false, dynlib: st ## cImport("pcre.h", dynlib="dynpcre") ## ## If ``dynlib`` is not specified, the C/C++ implementation files can be compiled in - ## with `cCompile() `_, or the ``{.passL.}`` pragma + ## with `cCompile() `_, or the ``{.passL.}`` pragma ## can be used to specify the static lib to link. + ## + ## ``mode`` is purely for forward compatibility when toast adds C++ support. It can + ## be ignored for the foreseeable future. + ## + ## ``flags`` can be used to pass any other command line arguments to ``toast``. result = newNimNode(nnkStmtList) @@ -531,7 +544,7 @@ macro cImport*(filename: static string, recurse: static bool = false, dynlib: st echo "# Importing " & fullpath let - output = getToast(fullpath, recurse, dynlib) + output = getToast(fullpath, recurse, dynlib, mode, flags) if gStateCT.debug: echo output @@ -549,10 +562,10 @@ macro c2nImport*(filename: static string, recurse: static bool = false, dynlib: mode: static string = "c", flags: static string = ""): untyped = ## Import all supported definitions from specified header file using ``c2nim`` ## - ## Similar to `cImport() `_ but uses ``c2nim`` to generate + ## Similar to `cImport() `_ but uses ``c2nim`` to generate ## the Nim wrapper instead of ``toast``. Note that neither - ## `cOverride() `_, `cSkipSymbol() `_ - ## nor `cPlugin() `_ have any impact on ``c2nim``. + ## `cOverride() `_, `cSkipSymbol() `_ + ## nor `cPlugin() `_ have any impact on ``c2nim``. ## ## ``toast`` is only used to preprocess the header file and recurse ## if specified. From 3e93c93fc3e9da938edb1395dd7363b3feb7015c Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 29 Jul 2019 19:08:28 -0500 Subject: [PATCH 233/593] Update documentation --- all.html | 992 +++++++------------------ cimport.html | 1158 ++++++++++------------------- cimport.idx | 14 +- compat.html | 1025 ++++++++----------------- dochack.js | 1983 +++++++++++++++++++++++++++++++++++++++++++++++++ git.html | 1102 +++++++++------------------ paths.html | 1044 ++++++++------------------ paths.idx | 12 +- plugin.html | 996 ++++++++----------------- theindex.html | 1019 ++++++++----------------- types.html | 1015 ++++++++----------------- types.idx | 2 +- 12 files changed, 4523 insertions(+), 5839 deletions(-) create mode 100644 dochack.js diff --git a/all.html b/all.html index f9e6987..1403afc 100644 --- a/all.html +++ b/all.html @@ -27,232 +27,130 @@ customize this style sheet. Modified from Chad Skeeters' rst2html-style https://bitbucket.org/cskeeters/rst2html-style/ -Modified by Boyd Greenfield +Modified by Boyd Greenfield and narimiran */ -/* SCSS variables */ -/* Text weights */ -/* Body colors */ -/* Text colors */ -/* Link colors */ -/* Syntax highlighting colors */ -/* Pct changes */ -/* Mixins */ -/* Body/layout */ + html { font-size: 100%; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; } -/* Where we want fancier font if available */ -h1, h2, h3, h4, h5, h6, p.module-desc, table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; } - -h1.title { - font-weight: 900; } - body { font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: 400; - font-size: 16px; - line-height: 20px; - color: #444; - letter-spacing: 0.15px; - background-color: #FDFBFA; } + font-size: 1.125em; + line-height: 1.5; + color: #222; + background-color: #FCFCFC; } /* Skeleton grid */ .container { position: relative; width: 100%; - max-width: 960px; + max-width: 1050px; margin: 0 auto; - padding: 0 20px; + padding: 0; box-sizing: border-box; } .column, .columns { width: 100%; float: left; - box-sizing: border-box; } + box-sizing: border-box; + margin-left: 1%; +} -/* For devices larger than 400px */ -@media (min-width: 400px) { - .container { - width: 100%; - padding: 0; } } -/* For devices larger than 650px */ -@media (min-width: 650px) { - .container { - width: 100%; } +.column:first-child, +.columns:first-child { + margin-left: 0; } - .column, - .columns { - margin-left: 4%; } +.three.columns { + width: 19%; } - .column:first-child, - .columns:first-child { - margin-left: 0; } +.nine.columns { + width: 80.0%; } - .one.column, - .one.columns { - width: 4.66666666667%; } - - .two.columns { - width: 13.3333333333%; } +.twelve.columns { + width: 100%; + margin-left: 0; } +@media screen and (max-width: 860px) { .three.columns { - width: 22%; } - - .four.columns { - width: 30.6666666667%; } - - .five.columns { - width: 39.3333333333%; } - - .six.columns { - width: 48%; } - - .seven.columns { - width: 56.6666666667%; } - - .eight.columns { - width: 65.3333333333%; } - + display: none; + } .nine.columns { - width: 74.0%; } - - .ten.columns { - width: 82.6666666667%; } - - .eleven.columns { - width: 91.3333333333%; } - - .twelve.columns { - width: 100%; - margin-left: 0; } - - .one-third.column { - width: 30.6666666667%; } - - .two-thirds.column { - width: 65.3333333333%; } } -/* Customer Overrides */ -.footer { - text-align: center; - color: #969696; - padding-top: 10%; } - -p.module-desc { - font-size: 1.1em; - color: #666666; } - -a.link-seesrc { - color: #aec7d2; - font-style: italic; } - -a.link-seesrc:hover { - color: #6c9aae; } - -#toc-list { - word-wrap: break-word; } - -ul.simple-toc { - list-style: none; } - -ul.simple-toc a.reference-toplevel { - font-weight: bold; - color: #0077b3; } - -ul.simple-toc-section { - list-style-type: circle; - color: #6c9aae; } - -ul.simple-toc-section a.reference { - color: #0077b3; } + width: 98.0%; + } + body { + font-size: 1em; + line-height: 1.35; + } +} cite { font-style: italic !important; } -dt > pre { - border-color: rgba(0, 0, 0, 0.1); - background-color: rgba(255, 255, 255, 0.3); - margin: 15px 0px 5px; } - -dd > pre { - border-color: rgba(0, 0, 0, 0.1); - background-color: whitesmoke; - margin-top: 8px; } - -.item > dd { - margin-left: 10px; - margin-bottom: 30px; } - -/* Nim line-numbered tables */ -.line-nums-table { - width: 100%; - table-layout: fixed; } /* Nim search input */ div#searchInputDiv { - margin-bottom: 8px; + margin-bottom: 1em; } -div#searchInputDiv input#searchInput { - width: 10em; -} -div.search-groupby { - margin-bottom: 8px; +input#searchInput { + width: 80%; } -table.line-nums-table { - border-radius: 4px; - border: 1px solid #cccccc; - background-color: whitesmoke; - border-collapse: separate; - margin-top: 15px; - margin-bottom: 25px; } - -.line-nums-table tbody { - border: none; } - -.line-nums-table td pre { - border: none; - background-color: transparent; } - -.line-nums-table td.blob-line-nums { - width: 28px; } - -.line-nums-table td.blob-line-nums pre { - color: #b0b0b0; - -webkit-filter: opacity(75%); - text-align: right; - border-color: transparent; - background-color: transparent; - padding-left: 0px; - margin-left: 0px; - padding-right: 0px; - margin-right: 0px; } +/* + * Some custom formatting for input forms. + * This also fixes input form colors on Firefox with a dark system theme on Linux. + */ +input { + -moz-appearance: none; + color: #333; + background-color: #f8f8f8; + border: 1px solid #aaa; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-size: 0.9em; + padding: 6px; +} +input:focus { + border: 1px solid #1fa0eb; + box-shadow: 0 0 2px #1fa0eb; +} /* Docgen styles */ /* Links */ a { - color: #0077b3; - text-decoration: none; } + color: #07b; + text-decoration: none; +} + +a span.Identifier { + text-decoration: underline; + text-decoration-color: #aab; +} + +a.reference-toplevel { + font-weight: bold; +} + +a.toc-backref { + text-decoration: none; + color: #222; } + +a.link-seesrc { + color: #607c9f; + font-size: 0.9em; + font-style: italic; } a:hover, a:focus { - color: #00334d; + color: #607c9f; text-decoration: underline; } -a:visited { - color: #00334d; } +a:hover span.Identifier { + color: #607c9f; +} -a:focus { - outline: thin dotted #2d2d2d; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; } - -a:hover, -a:active { - outline: 0; } sub, sup { @@ -329,379 +227,258 @@ img { h2, h3 { - page-break-after: avoid; } } -.img-rounded { - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; } + page-break-after: avoid; } +} -.img-polaroid { - padding: 4px; - background-color: rgba(252, 248, 244, 0.75); - border: 1px solid #ccc; - border: 1px solid rgba(0, 0, 0, 0.2); - -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); - -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); } p { - margin: 0 0 8px; } + margin-top: 0.5em; + margin-bottom: 0.5em; +} small { font-size: 85%; } strong { - font-weight: 600; } + font-weight: 600; + font-size: 0.95em; + color: #3c3c3c; +} em { font-style: italic; } -cite { - font-style: normal; } - -h1, -h2, -h3, -h4, -h5, -h6 { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-weight: 600; - line-height: 20px; - color: inherit; - text-rendering: optimizelegibility; } - h1 { - font-size: 2em; + font-size: 1.8em; font-weight: 400; - padding-bottom: .15em; - border-bottom: 1px solid #aaaaaa; - margin-top: 1.0em; + padding-bottom: .25em; + border-bottom: 1px solid #aaa; + margin-top: 2.5em; + margin-bottom: 1em; line-height: 1.2em; } h1.title { padding-bottom: 1em; border-bottom: 0px; - font-size: 2.75em; } + font-size: 2.5em; + text-align: center; + font-weight: 900; + margin-top: 0.75em; + margin-bottom: 0em; +} h2 { - font-size: 1.5em; - margin-top: 1.5em; } + font-size: 1.3em; + margin-top: 2em; } + +h2.subtitle { + text-align: center; } h3 { - font-size: 1.3em; + font-size: 1.125em; font-style: italic; - margin-top: 0.75em; } + margin-top: 1.5em; } h4 { - font-size: 1.3em; - margin-top: 0.5em; } + font-size: 1.125em; + margin-top: 1em; } h5 { - font-size: 1.2em; - margin-top: 0.25em; } + font-size: 1.125em; + margin-top: 0.75em; } h6 { font-size: 1.1em; } + ul, ol { padding: 0; - margin: 0 0 0px 15px; } + margin-top: 0.5em; + margin-left: 0.75em; } ul ul, ul ol, ol ol, ol ul { - margin-bottom: 0; } + margin-bottom: 0; + margin-left: 1.25em; } li { - line-height: 20px; } - -dl { - margin-bottom: 20px; } - -dt, -dd { - line-height: 20px; } - -dt { - font-weight: bold; } - -dd { - margin-left: 10px; - margin-bottom: 26px; } - -hr { - margin: 20px 0; - border: 0; - border-top: 1px solid #eeeeee; - border-bottom: 1px solid #ffffff; } - -abbr[title], -abbr[data-original-title] { - cursor: help; - border-bottom: 1px dotted #999999; } - -abbr.initialism { - font-size: 90%; - text-transform: uppercase; } - -blockquote { - padding: 0 0 0 15px; - margin: 0 0 20px; - border-left: 5px solid #EFEBE0; } - -table.docinfo + blockquote, table.docinfo blockquote, h1 + blockquote { - border-left: 5px solid #c9c9c9; + list-style-type: circle; } -table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { - margin-bottom: 0; - font-size: 15px; - font-weight: 200; - line-height: 1.5; - font-style: italic; } +ul.simple-boot li { + list-style-type: none; + margin-left: 0em; + margin-bottom: 0.5em; +} -q:before, -q:after, -blockquote:before, -blockquote:after { - content: ""; } +ol.simple > li, ul.simple > li { + margin-bottom: 0.25em; + margin-left: 0.4em } -address { - display: block; - margin-bottom: 20px; - font-style: normal; - line-height: 20px; } +ul.simple.simple-toc > li { + margin-top: 1em; +} -code, -pre { - font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - padding: 0 3px 2px; - font-weight: 500; - font-size: 12px; - color: #444444; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; } +ul.simple-toc { + list-style: none; + font-size: 0.9em; + margin-left: -0.3em; + margin-top: 1em; } + +ul.simple-toc > li { + list-style-type: none; +} + +ul.simple-toc-section { + list-style-type: circle; + margin-left: 1em; + color: #6c9aae; } + + +ol.arabic { + list-style: decimal; } + +ol.loweralpha { + list-style: lower-alpha; } + +ol.upperalpha { + list-style: upper-alpha; } + +ol.lowerroman { + list-style: lower-roman; } + +ol.upperroman { + list-style: upper-roman; } + +ul.auto-toc { + list-style-type: none; } + + +dl { + margin-bottom: 1.5em; } + +dt { + margin-bottom: -0.5em; + margin-left: 0.0em; } + +dd { + margin-left: 2.0em; + margin-bottom: 3.0em; + margin-top: 0.5em; } + + +hr { + margin: 2em 0; + border: 0; + border-top: 1px solid #aaa; } + +blockquote { + font-size: 0.9em; + font-style: italic; + padding-left: 0.5em; + margin-left: 0; + border-left: 5px solid #bbc; +} .pre { font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - font-weight: 600; - /*color: #504da6;*/ + font-weight: 500; + font-size: 0.85em; + background-color: #f0f3ff; + padding-left: 3px; + padding-right: 3px; + border-radius: 4px; } -code { - padding: 2px 4px; - color: #444444; - white-space: nowrap; - background-color: white; - border: 1px solid #777777; } - pre { + font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; + color: #222; + font-weight: 500; display: inline-block; box-sizing: border-box; - min-width: calc(100% - 19.5px); - padding: 9.5px; - margin: 0.25em 10px 10px 10px; - font-size: 15px; - line-height: 20px; + min-width: 100%; + padding: 0.5em; + margin-top: 0.5em; + margin-bottom: 0.5em; + font-size: 0.85em; white-space: pre !important; overflow-y: hidden; overflow-x: visible; - background-color: rgba(0, 0, 0, 0.01); - border: 1px solid #cccccc; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; } - -pre.prettyprint { - margin-bottom: 20px; } - -pre code { - padding: 0; - color: inherit; - white-space: pre; - overflow-x: visible; - background-color: transparent; - border: 0; } + background-color: ghostwhite; + border: 1px solid #dde; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; } .pre-scrollable { max-height: 340px; overflow-y: scroll; } + +/* Nim line-numbered tables */ +.line-nums-table { + width: 100%; + table-layout: fixed; } + +table.line-nums-table { + border-radius: 4px; + border: 1px solid #cccccc; + background-color: ghostwhite; + border-collapse: separate; + margin-top: 15px; + margin-bottom: 25px; } + +.line-nums-table tbody { + border: none; } + +.line-nums-table td pre { + border: none; + background-color: transparent; } + +.line-nums-table td.blob-line-nums { + width: 28px; } + +.line-nums-table td.blob-line-nums pre { + color: #b0b0b0; + -webkit-filter: opacity(75%); + text-align: right; + border-color: transparent; + background-color: transparent; + padding-left: 0px; + margin-left: 0px; + padding-right: 0px; + margin-right: 0px; } + + table { max-width: 100%; background-color: transparent; + margin-top: 0.5em; + margin-bottom: 1.5em; border-collapse: collapse; - border-spacing: 0; } - -table th, table td { - padding: 0px 8px 0px; + border-color: #ccc; + border-spacing: 0; + font-size: 0.9em; } -.table { - width: 100%; - margin-bottom: 20px; } +table th, table td { + padding: 0px 0.5em 0px; +} -.table th, -.table td { - padding: 8px; - line-height: 20px; - text-align: left; - vertical-align: top; - border-top: 1px solid #444444; } - -.table th { +table th { + background-color: #e8e8e8; font-weight: bold; } -.table thead th { - vertical-align: bottom; } +table th.docinfo-name { + background-color: transparent; +} -.table caption + thead tr:first-child th, -.table caption + thead tr:first-child td, -.table colgroup + thead tr:first-child th, -.table colgroup + thead tr:first-child td, -.table thead:first-child tr:first-child th, -.table thead:first-child tr:first-child td { - border-top: 0; } +table tr:hover { + background-color: ghostwhite; } -.table tbody + tbody { - border-top: 2px solid #444444; } - -.table .table { - background-color: rgba(252, 248, 244, 0.75); } - -.table-condensed th, -.table-condensed td { - padding: 4px 5px; } - -.table-bordered { - border: 1px solid #444444; - border-collapse: separate; - *border-collapse: collapse; - border-left: 0; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; } - -.table-bordered th, -.table-bordered td { - border-left: 1px solid #444444; } - -.table-bordered caption + thead tr:first-child th, -.table-bordered caption + tbody tr:first-child th, -.table-bordered caption + tbody tr:first-child td, -.table-bordered colgroup + thead tr:first-child th, -.table-bordered colgroup + tbody tr:first-child th, -.table-bordered colgroup + tbody tr:first-child td, -.table-bordered thead:first-child tr:first-child th, -.table-bordered tbody:first-child tr:first-child th, -.table-bordered tbody:first-child tr:first-child td { - border-top: 0; } - -.table-bordered thead:first-child tr:first-child > th:first-child, -.table-bordered tbody:first-child tr:first-child > td:first-child, -.table-bordered tbody:first-child tr:first-child > th:first-child { - -webkit-border-top-left-radius: 4px; - border-top-left-radius: 4px; - -moz-border-radius-topleft: 4px; } - -.table-bordered thead:first-child tr:first-child > th:last-child, -.table-bordered tbody:first-child tr:first-child > td:last-child, -.table-bordered tbody:first-child tr:first-child > th:last-child { - -webkit-border-top-right-radius: 4px; - border-top-right-radius: 4px; - -moz-border-radius-topright: 4px; } - -.table-bordered thead:last-child tr:last-child > th:first-child, -.table-bordered tbody:last-child tr:last-child > td:first-child, -.table-bordered tbody:last-child tr:last-child > th:first-child, -.table-bordered tfoot:last-child tr:last-child > td:first-child, -.table-bordered tfoot:last-child tr:last-child > th:first-child { - -webkit-border-bottom-left-radius: 4px; - border-bottom-left-radius: 4px; - -moz-border-radius-bottomleft: 4px; } - -.table-bordered thead:last-child tr:last-child > th:last-child, -.table-bordered tbody:last-child tr:last-child > td:last-child, -.table-bordered tbody:last-child tr:last-child > th:last-child, -.table-bordered tfoot:last-child tr:last-child > td:last-child, -.table-bordered tfoot:last-child tr:last-child > th:last-child { - -webkit-border-bottom-right-radius: 4px; - border-bottom-right-radius: 4px; - -moz-border-radius-bottomright: 4px; } - -.table-bordered tfoot + tbody:last-child tr:last-child td:first-child { - -webkit-border-bottom-left-radius: 0; - border-bottom-left-radius: 0; - -moz-border-radius-bottomleft: 0; } - -.table-bordered tfoot + tbody:last-child tr:last-child td:last-child { - -webkit-border-bottom-right-radius: 0; - border-bottom-right-radius: 0; - -moz-border-radius-bottomright: 0; } - -.table-bordered caption + thead tr:first-child th:first-child, -.table-bordered caption + tbody tr:first-child td:first-child, -.table-bordered colgroup + thead tr:first-child th:first-child, -.table-bordered colgroup + tbody tr:first-child td:first-child { - -webkit-border-top-left-radius: 4px; - border-top-left-radius: 4px; - -moz-border-radius-topleft: 4px; } - -.table-bordered caption + thead tr:first-child th:last-child, -.table-bordered caption + tbody tr:first-child td:last-child, -.table-bordered colgroup + thead tr:first-child th:last-child, -.table-bordered colgroup + tbody tr:first-child td:last-child { - -webkit-border-top-right-radius: 4px; - border-top-right-radius: 4px; - -moz-border-radius-topright: 4px; } - -table.docutils th { - background-color: #e8e8e8; } - -table.docutils tr:hover { - background-color: whitesmoke; } - -.table-striped tbody > tr:nth-child(odd) > td, -.table-striped tbody > tr:nth-child(odd) > th { - background-color: rgba(252, 248, 244, 0.75); } - -.table-hover tbody tr:hover > td, -.table-hover tbody tr:hover > th { - background-color: rgba(241, 222, 204, 0.75); } - -table td[class*="span"], -table th[class*="span"], -.row-fluid table td[class*="span"], -.row-fluid table th[class*="span"] { - display: table-cell; - float: none; - margin-left: 0; } - -.hero-unit { - padding: 60px; - margin-bottom: 30px; - font-size: 18px; - font-weight: 200; - line-height: 30px; - color: inherit; - background-color: rgba(230, 197, 164, 0.75); - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; } - -.hero-unit h1 { - margin-bottom: 0; - font-size: 60px; - line-height: 1; - letter-spacing: -1px; - color: inherit; } - -.hero-unit li { - line-height: 30px; } /* rst2html default used to remove borders from tables and images */ .borderless, table.borderless td, table.borderless th { @@ -722,10 +499,6 @@ table.borderless td, table.borderless th { .hidden { display: none; } -a.toc-backref { - text-decoration: none; - color: #444444; } - blockquote.epigraph { margin: 2em 5em; } @@ -735,85 +508,6 @@ dl.docutils dd { object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] { overflow: hidden; } -/* Uncomment (and remove this text!) to get bold-faced definition list terms -dl.docutils dt { - font-weight: bold } -*/ -div.abstract { - margin: 2em 5em; } - -div.abstract p.topic-title { - font-weight: bold; - text-align: center; } - -div.admonition, div.attention, div.caution, div.danger, div.error, -div.hint, div.important, div.note, div.tip, div.warning { - margin: 2em; - border: medium outset; - padding: 1em; } - -div.note, div.warning { - margin: 1.5em 0px; - border: none; } - -div.note p.admonition-title, -div.warning p.admonition-title { - display: none; } - -/* Clearfix - * http://css-tricks.com/snippets/css/clear-fix/ - */ -div.note:after, -div.warning:after { - content: ""; - display: table; - clear: both; } - -div.note p:before, -div.warning p:before { - display: block; - float: left; - font-size: 4em; - line-height: 1em; - margin-right: 20px; - margin-left: 0em; - margin-top: -10px; - content: '\0270D'; - /*handwriting*/ } - -div.warning p:before { - content: '\026A0'; - /*warning*/ } - -div.admonition p.admonition-title, div.hint p.admonition-title, -div.important p.admonition-title, div.note p.admonition-title, -div.tip p.admonition-title { - font-weight: bold; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } - -div.attention p.admonition-title, div.caution p.admonition-title, -div.danger p.admonition-title, div.error p.admonition-title, -div.warning p.admonition-title, .code .error { - color: #b30000; - font-weight: bold; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } - -/* Uncomment (and remove this text!) to get reduced vertical space in - compound paragraphs. -div.compound .compound-first, div.compound .compound-middle { - margin-bottom: 0.5em } - -div.compound .compound-last, div.compound .compound-middle { - margin-top: 0.5em } -*/ -div.dedication { - margin: 2em 5em; - text-align: center; - font-style: italic; } - -div.dedication p.topic-title { - font-weight: bold; - font-style: normal; } div.figure { margin-left: 2em; @@ -821,8 +515,14 @@ div.figure { div.footer, div.header { clear: both; + text-align: center; + color: #666; font-size: smaller; } +div.footer { + padding-top: 5em; +} + div.line-block { display: block; margin-top: 1em; @@ -833,45 +533,24 @@ div.line-block div.line-block { margin-bottom: 0; margin-left: 1.5em; } -div.sidebar { - margin: 0 0 0.5em 1em; - border: medium outset; - padding: 1em; - background-color: rgba(252, 248, 244, 0.75); - width: 40%; - float: right; - clear: right; } - -div.sidebar p.rubric { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-size: medium; } - -div.system-messages { - margin: 5em; } - -div.system-messages h1 { - color: #b30000; } - -div.system-message { - border: medium outset; - padding: 1em; } - -div.system-message p.system-message-title { - color: #b30000; - font-weight: bold; } - div.topic { margin: 2em; } -h1.section-subtitle, h2.section-subtitle, h3.section-subtitle, -h4.section-subtitle, h5.section-subtitle, h6.section-subtitle { - margin-top: 0.4em; } +div.search_results { + background-color: antiquewhite; + margin: 3em; + padding: 1em; + border: 1px solid #4d4d4d; +} -h1.title { - text-align: center; } +div#global-links ul { + margin-left: 0; + list-style-type: none; +} -h2.subtitle { - text-align: center; } +div#global-links > simple-boot { + margin-left: 3em; +} hr.docutils { width: 75%; } @@ -905,30 +584,6 @@ img.align-center, .figure.align-center, object.align-center { div.align-right { text-align: inherit; } -/* div.align-center * { */ -/* text-align: left } */ - -ul.simple > li { - margin-bottom: 0.5em } - -ol.simple, ul.simple { - margin-bottom: 1em; } - -ol.arabic { - list-style: decimal; } - -ol.loweralpha { - list-style: lower-alpha; } - -ol.upperalpha { - list-style: upper-alpha; } - -ol.lowerroman { - list-style: lower-roman; } - -ol.upperroman { - list-style: upper-roman; } - p.attribution { text-align: right; margin-left: 50%; } @@ -949,15 +604,6 @@ p.rubric { color: maroon; text-align: center; } -p.sidebar-title { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-weight: bold; - font-size: larger; } - -p.sidebar-subtitle { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-weight: bold; } - p.topic-title { font-weight: bold; } @@ -997,22 +643,14 @@ pre.code .inserted, code .inserted { background-color: #A3D289; } span.classifier { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-style: oblique; } span.classifier-delimiter { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: bold; } -span.interpreted { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } - span.option { white-space: nowrap; } -span.pre { - white-space: pre; } - span.problematic { color: #b30000; } @@ -1020,44 +658,6 @@ span.section-subtitle { /* font-size relative to parent (h1..h6 element) */ font-size: 80%; } -table.citation { - border-left: solid 1px #666666; - margin-left: 1px; } - -table.docinfo { - margin: 0em; - margin-top: 2em; - margin-bottom: 2em; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; - color: #444444; } - -table.docutils { - margin-top: 0.5em; - margin-bottom: 0.5em; } - -table.footnote { - border-left: solid 1px #2d2d2d; - margin-left: 1px; } - -table.docutils td, table.docutils th, -table.docinfo td, table.docinfo th { - padding-left: 0.5em; - padding-right: 0.5em; - vertical-align: top; } - -table.docutils th.field-name, table.docinfo th.docinfo-name { - font-weight: 700; - text-align: left; - white-space: nowrap; - padding-left: 0; } - -h1 tt.docutils, h2 tt.docutils, h3 tt.docutils, -h4 tt.docutils, h5 tt.docutils, h6 tt.docutils { - font-size: 100%; } - -ul.auto-toc { - list-style-type: none; } - span.DecNumber { color: #252dbe; } @@ -1074,7 +674,7 @@ span.FloatNumber { color: #252dbe; } span.Identifier { - color: #3b3b3b; } + color: #222; } span.Keyword { font-weight: 600; @@ -1139,38 +739,23 @@ dt pre > span.Identifier, dt pre > span.Operator { color: #155da4; font-weight: 700; } -dt pre > span.Identifier ~ span.Identifier, dt pre > span.Operator ~ span.Identifier { - color: inherit; - font-weight: inherit; } - -dt pre > span.Operator ~ span.Identifier { +dt pre > span.Keyword ~ span.Identifier, dt pre > span.Identifier ~ span.Identifier, +dt pre > span.Operator ~ span.Identifier, dt pre > span.Other ~ span.Identifier { color: inherit; font-weight: inherit; } /* Nim sprite for the footer (taken from main page favicon) */ .nim-sprite { display: inline-block; - height: 12px; - width: 12px; + height: 16px; + width: 16px; background-position: 0 0; - background-size: 12px 12px; + background-size: 16px 16px; -webkit-filter: opacity(50%); background-repeat: no-repeat; background-image: url("data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="); margin-bottom: -5px; } -div.search_results { - background-color: antiquewhite; - margin: 3em; - padding: 1em; - border: 1px solid #4d4d4d; -} - -div#global-links ul { - margin-left: 0; - list-style-type: none; -} - span.pragmadots { /* Position: relative frees us up to make the dots look really nice without fucking up the layout and @@ -1178,18 +763,14 @@ span.pragmadots { position: relative; /* 1px down looks slightly nicer */ top: 1px; - padding: 2px; - background-color: #D3D3D3; + background-color: #e8e8e8; border-radius: 4px; margin: 0 2px; cursor: pointer; - - /* For some reason on Chrome, making the font size - smaller than 1em is causing the parent container to - bulge slightly. So, we're stuck with inheriting 1em, - which is sad, because 0.8em looks better... */ + font-size: 0.8em; } + span.pragmadots:hover { background-color: #DBDBDB; } @@ -1197,6 +778,10 @@ span.pragmawrap { display: none; } +span.attachedType { + display: none; + visibility: hidden; +} @@ -1250,7 +835,8 @@ function main() {
    -

    Module that should import everything so that nim doc --project nimtero/all runs docs on everything.

    + +

    Module that should import everything so that nim doc --project nimtero/all runs docs on everything.

    Imports

    @@ -1264,7 +850,7 @@ function main() {
    diff --git a/cimport.html b/cimport.html index c8ad735..fa57ca3 100644 --- a/cimport.html +++ b/cimport.html @@ -27,232 +27,130 @@ customize this style sheet. Modified from Chad Skeeters' rst2html-style https://bitbucket.org/cskeeters/rst2html-style/ -Modified by Boyd Greenfield +Modified by Boyd Greenfield and narimiran */ -/* SCSS variables */ -/* Text weights */ -/* Body colors */ -/* Text colors */ -/* Link colors */ -/* Syntax highlighting colors */ -/* Pct changes */ -/* Mixins */ -/* Body/layout */ + html { font-size: 100%; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; } -/* Where we want fancier font if available */ -h1, h2, h3, h4, h5, h6, p.module-desc, table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; } - -h1.title { - font-weight: 900; } - body { font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: 400; - font-size: 16px; - line-height: 20px; - color: #444; - letter-spacing: 0.15px; - background-color: #FDFBFA; } + font-size: 1.125em; + line-height: 1.5; + color: #222; + background-color: #FCFCFC; } /* Skeleton grid */ .container { position: relative; width: 100%; - max-width: 960px; + max-width: 1050px; margin: 0 auto; - padding: 0 20px; + padding: 0; box-sizing: border-box; } .column, .columns { width: 100%; float: left; - box-sizing: border-box; } + box-sizing: border-box; + margin-left: 1%; +} -/* For devices larger than 400px */ -@media (min-width: 400px) { - .container { - width: 100%; - padding: 0; } } -/* For devices larger than 650px */ -@media (min-width: 650px) { - .container { - width: 100%; } +.column:first-child, +.columns:first-child { + margin-left: 0; } - .column, - .columns { - margin-left: 4%; } +.three.columns { + width: 19%; } - .column:first-child, - .columns:first-child { - margin-left: 0; } +.nine.columns { + width: 80.0%; } - .one.column, - .one.columns { - width: 4.66666666667%; } - - .two.columns { - width: 13.3333333333%; } +.twelve.columns { + width: 100%; + margin-left: 0; } +@media screen and (max-width: 860px) { .three.columns { - width: 22%; } - - .four.columns { - width: 30.6666666667%; } - - .five.columns { - width: 39.3333333333%; } - - .six.columns { - width: 48%; } - - .seven.columns { - width: 56.6666666667%; } - - .eight.columns { - width: 65.3333333333%; } - + display: none; + } .nine.columns { - width: 74.0%; } - - .ten.columns { - width: 82.6666666667%; } - - .eleven.columns { - width: 91.3333333333%; } - - .twelve.columns { - width: 100%; - margin-left: 0; } - - .one-third.column { - width: 30.6666666667%; } - - .two-thirds.column { - width: 65.3333333333%; } } -/* Customer Overrides */ -.footer { - text-align: center; - color: #969696; - padding-top: 10%; } - -p.module-desc { - font-size: 1.1em; - color: #666666; } - -a.link-seesrc { - color: #aec7d2; - font-style: italic; } - -a.link-seesrc:hover { - color: #6c9aae; } - -#toc-list { - word-wrap: break-word; } - -ul.simple-toc { - list-style: none; } - -ul.simple-toc a.reference-toplevel { - font-weight: bold; - color: #0077b3; } - -ul.simple-toc-section { - list-style-type: circle; - color: #6c9aae; } - -ul.simple-toc-section a.reference { - color: #0077b3; } + width: 98.0%; + } + body { + font-size: 1em; + line-height: 1.35; + } +} cite { font-style: italic !important; } -dt > pre { - border-color: rgba(0, 0, 0, 0.1); - background-color: rgba(255, 255, 255, 0.3); - margin: 15px 0px 5px; } - -dd > pre { - border-color: rgba(0, 0, 0, 0.1); - background-color: whitesmoke; - margin-top: 8px; } - -.item > dd { - margin-left: 10px; - margin-bottom: 30px; } - -/* Nim line-numbered tables */ -.line-nums-table { - width: 100%; - table-layout: fixed; } /* Nim search input */ div#searchInputDiv { - margin-bottom: 8px; + margin-bottom: 1em; } -div#searchInputDiv input#searchInput { - width: 10em; -} -div.search-groupby { - margin-bottom: 8px; +input#searchInput { + width: 80%; } -table.line-nums-table { - border-radius: 4px; - border: 1px solid #cccccc; - background-color: whitesmoke; - border-collapse: separate; - margin-top: 15px; - margin-bottom: 25px; } - -.line-nums-table tbody { - border: none; } - -.line-nums-table td pre { - border: none; - background-color: transparent; } - -.line-nums-table td.blob-line-nums { - width: 28px; } - -.line-nums-table td.blob-line-nums pre { - color: #b0b0b0; - -webkit-filter: opacity(75%); - text-align: right; - border-color: transparent; - background-color: transparent; - padding-left: 0px; - margin-left: 0px; - padding-right: 0px; - margin-right: 0px; } +/* + * Some custom formatting for input forms. + * This also fixes input form colors on Firefox with a dark system theme on Linux. + */ +input { + -moz-appearance: none; + color: #333; + background-color: #f8f8f8; + border: 1px solid #aaa; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-size: 0.9em; + padding: 6px; +} +input:focus { + border: 1px solid #1fa0eb; + box-shadow: 0 0 2px #1fa0eb; +} /* Docgen styles */ /* Links */ a { - color: #0077b3; - text-decoration: none; } + color: #07b; + text-decoration: none; +} + +a span.Identifier { + text-decoration: underline; + text-decoration-color: #aab; +} + +a.reference-toplevel { + font-weight: bold; +} + +a.toc-backref { + text-decoration: none; + color: #222; } + +a.link-seesrc { + color: #607c9f; + font-size: 0.9em; + font-style: italic; } a:hover, a:focus { - color: #00334d; + color: #607c9f; text-decoration: underline; } -a:visited { - color: #00334d; } +a:hover span.Identifier { + color: #607c9f; +} -a:focus { - outline: thin dotted #2d2d2d; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; } - -a:hover, -a:active { - outline: 0; } sub, sup { @@ -329,379 +227,258 @@ img { h2, h3 { - page-break-after: avoid; } } -.img-rounded { - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; } + page-break-after: avoid; } +} -.img-polaroid { - padding: 4px; - background-color: rgba(252, 248, 244, 0.75); - border: 1px solid #ccc; - border: 1px solid rgba(0, 0, 0, 0.2); - -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); - -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); } p { - margin: 0 0 8px; } + margin-top: 0.5em; + margin-bottom: 0.5em; +} small { font-size: 85%; } strong { - font-weight: 600; } + font-weight: 600; + font-size: 0.95em; + color: #3c3c3c; +} em { font-style: italic; } -cite { - font-style: normal; } - -h1, -h2, -h3, -h4, -h5, -h6 { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-weight: 600; - line-height: 20px; - color: inherit; - text-rendering: optimizelegibility; } - h1 { - font-size: 2em; + font-size: 1.8em; font-weight: 400; - padding-bottom: .15em; - border-bottom: 1px solid #aaaaaa; - margin-top: 1.0em; + padding-bottom: .25em; + border-bottom: 1px solid #aaa; + margin-top: 2.5em; + margin-bottom: 1em; line-height: 1.2em; } h1.title { padding-bottom: 1em; border-bottom: 0px; - font-size: 2.75em; } + font-size: 2.5em; + text-align: center; + font-weight: 900; + margin-top: 0.75em; + margin-bottom: 0em; +} h2 { - font-size: 1.5em; - margin-top: 1.5em; } + font-size: 1.3em; + margin-top: 2em; } + +h2.subtitle { + text-align: center; } h3 { - font-size: 1.3em; + font-size: 1.125em; font-style: italic; - margin-top: 0.75em; } + margin-top: 1.5em; } h4 { - font-size: 1.3em; - margin-top: 0.5em; } + font-size: 1.125em; + margin-top: 1em; } h5 { - font-size: 1.2em; - margin-top: 0.25em; } + font-size: 1.125em; + margin-top: 0.75em; } h6 { font-size: 1.1em; } + ul, ol { padding: 0; - margin: 0 0 0px 15px; } + margin-top: 0.5em; + margin-left: 0.75em; } ul ul, ul ol, ol ol, ol ul { - margin-bottom: 0; } + margin-bottom: 0; + margin-left: 1.25em; } li { - line-height: 20px; } - -dl { - margin-bottom: 20px; } - -dt, -dd { - line-height: 20px; } - -dt { - font-weight: bold; } - -dd { - margin-left: 10px; - margin-bottom: 26px; } - -hr { - margin: 20px 0; - border: 0; - border-top: 1px solid #eeeeee; - border-bottom: 1px solid #ffffff; } - -abbr[title], -abbr[data-original-title] { - cursor: help; - border-bottom: 1px dotted #999999; } - -abbr.initialism { - font-size: 90%; - text-transform: uppercase; } - -blockquote { - padding: 0 0 0 15px; - margin: 0 0 20px; - border-left: 5px solid #EFEBE0; } - -table.docinfo + blockquote, table.docinfo blockquote, h1 + blockquote { - border-left: 5px solid #c9c9c9; + list-style-type: circle; } -table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { - margin-bottom: 0; - font-size: 15px; - font-weight: 200; - line-height: 1.5; - font-style: italic; } +ul.simple-boot li { + list-style-type: none; + margin-left: 0em; + margin-bottom: 0.5em; +} -q:before, -q:after, -blockquote:before, -blockquote:after { - content: ""; } +ol.simple > li, ul.simple > li { + margin-bottom: 0.25em; + margin-left: 0.4em } -address { - display: block; - margin-bottom: 20px; - font-style: normal; - line-height: 20px; } +ul.simple.simple-toc > li { + margin-top: 1em; +} -code, -pre { - font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - padding: 0 3px 2px; - font-weight: 500; - font-size: 12px; - color: #444444; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; } +ul.simple-toc { + list-style: none; + font-size: 0.9em; + margin-left: -0.3em; + margin-top: 1em; } + +ul.simple-toc > li { + list-style-type: none; +} + +ul.simple-toc-section { + list-style-type: circle; + margin-left: 1em; + color: #6c9aae; } + + +ol.arabic { + list-style: decimal; } + +ol.loweralpha { + list-style: lower-alpha; } + +ol.upperalpha { + list-style: upper-alpha; } + +ol.lowerroman { + list-style: lower-roman; } + +ol.upperroman { + list-style: upper-roman; } + +ul.auto-toc { + list-style-type: none; } + + +dl { + margin-bottom: 1.5em; } + +dt { + margin-bottom: -0.5em; + margin-left: 0.0em; } + +dd { + margin-left: 2.0em; + margin-bottom: 3.0em; + margin-top: 0.5em; } + + +hr { + margin: 2em 0; + border: 0; + border-top: 1px solid #aaa; } + +blockquote { + font-size: 0.9em; + font-style: italic; + padding-left: 0.5em; + margin-left: 0; + border-left: 5px solid #bbc; +} .pre { font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - font-weight: 600; - /*color: #504da6;*/ + font-weight: 500; + font-size: 0.85em; + background-color: #f0f3ff; + padding-left: 3px; + padding-right: 3px; + border-radius: 4px; } -code { - padding: 2px 4px; - color: #444444; - white-space: nowrap; - background-color: white; - border: 1px solid #777777; } - pre { + font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; + color: #222; + font-weight: 500; display: inline-block; box-sizing: border-box; - min-width: calc(100% - 19.5px); - padding: 9.5px; - margin: 0.25em 10px 10px 10px; - font-size: 15px; - line-height: 20px; + min-width: 100%; + padding: 0.5em; + margin-top: 0.5em; + margin-bottom: 0.5em; + font-size: 0.85em; white-space: pre !important; overflow-y: hidden; overflow-x: visible; - background-color: rgba(0, 0, 0, 0.01); - border: 1px solid #cccccc; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; } - -pre.prettyprint { - margin-bottom: 20px; } - -pre code { - padding: 0; - color: inherit; - white-space: pre; - overflow-x: visible; - background-color: transparent; - border: 0; } + background-color: ghostwhite; + border: 1px solid #dde; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; } .pre-scrollable { max-height: 340px; overflow-y: scroll; } + +/* Nim line-numbered tables */ +.line-nums-table { + width: 100%; + table-layout: fixed; } + +table.line-nums-table { + border-radius: 4px; + border: 1px solid #cccccc; + background-color: ghostwhite; + border-collapse: separate; + margin-top: 15px; + margin-bottom: 25px; } + +.line-nums-table tbody { + border: none; } + +.line-nums-table td pre { + border: none; + background-color: transparent; } + +.line-nums-table td.blob-line-nums { + width: 28px; } + +.line-nums-table td.blob-line-nums pre { + color: #b0b0b0; + -webkit-filter: opacity(75%); + text-align: right; + border-color: transparent; + background-color: transparent; + padding-left: 0px; + margin-left: 0px; + padding-right: 0px; + margin-right: 0px; } + + table { max-width: 100%; background-color: transparent; + margin-top: 0.5em; + margin-bottom: 1.5em; border-collapse: collapse; - border-spacing: 0; } - -table th, table td { - padding: 0px 8px 0px; + border-color: #ccc; + border-spacing: 0; + font-size: 0.9em; } -.table { - width: 100%; - margin-bottom: 20px; } +table th, table td { + padding: 0px 0.5em 0px; +} -.table th, -.table td { - padding: 8px; - line-height: 20px; - text-align: left; - vertical-align: top; - border-top: 1px solid #444444; } - -.table th { +table th { + background-color: #e8e8e8; font-weight: bold; } -.table thead th { - vertical-align: bottom; } +table th.docinfo-name { + background-color: transparent; +} -.table caption + thead tr:first-child th, -.table caption + thead tr:first-child td, -.table colgroup + thead tr:first-child th, -.table colgroup + thead tr:first-child td, -.table thead:first-child tr:first-child th, -.table thead:first-child tr:first-child td { - border-top: 0; } +table tr:hover { + background-color: ghostwhite; } -.table tbody + tbody { - border-top: 2px solid #444444; } - -.table .table { - background-color: rgba(252, 248, 244, 0.75); } - -.table-condensed th, -.table-condensed td { - padding: 4px 5px; } - -.table-bordered { - border: 1px solid #444444; - border-collapse: separate; - *border-collapse: collapse; - border-left: 0; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; } - -.table-bordered th, -.table-bordered td { - border-left: 1px solid #444444; } - -.table-bordered caption + thead tr:first-child th, -.table-bordered caption + tbody tr:first-child th, -.table-bordered caption + tbody tr:first-child td, -.table-bordered colgroup + thead tr:first-child th, -.table-bordered colgroup + tbody tr:first-child th, -.table-bordered colgroup + tbody tr:first-child td, -.table-bordered thead:first-child tr:first-child th, -.table-bordered tbody:first-child tr:first-child th, -.table-bordered tbody:first-child tr:first-child td { - border-top: 0; } - -.table-bordered thead:first-child tr:first-child > th:first-child, -.table-bordered tbody:first-child tr:first-child > td:first-child, -.table-bordered tbody:first-child tr:first-child > th:first-child { - -webkit-border-top-left-radius: 4px; - border-top-left-radius: 4px; - -moz-border-radius-topleft: 4px; } - -.table-bordered thead:first-child tr:first-child > th:last-child, -.table-bordered tbody:first-child tr:first-child > td:last-child, -.table-bordered tbody:first-child tr:first-child > th:last-child { - -webkit-border-top-right-radius: 4px; - border-top-right-radius: 4px; - -moz-border-radius-topright: 4px; } - -.table-bordered thead:last-child tr:last-child > th:first-child, -.table-bordered tbody:last-child tr:last-child > td:first-child, -.table-bordered tbody:last-child tr:last-child > th:first-child, -.table-bordered tfoot:last-child tr:last-child > td:first-child, -.table-bordered tfoot:last-child tr:last-child > th:first-child { - -webkit-border-bottom-left-radius: 4px; - border-bottom-left-radius: 4px; - -moz-border-radius-bottomleft: 4px; } - -.table-bordered thead:last-child tr:last-child > th:last-child, -.table-bordered tbody:last-child tr:last-child > td:last-child, -.table-bordered tbody:last-child tr:last-child > th:last-child, -.table-bordered tfoot:last-child tr:last-child > td:last-child, -.table-bordered tfoot:last-child tr:last-child > th:last-child { - -webkit-border-bottom-right-radius: 4px; - border-bottom-right-radius: 4px; - -moz-border-radius-bottomright: 4px; } - -.table-bordered tfoot + tbody:last-child tr:last-child td:first-child { - -webkit-border-bottom-left-radius: 0; - border-bottom-left-radius: 0; - -moz-border-radius-bottomleft: 0; } - -.table-bordered tfoot + tbody:last-child tr:last-child td:last-child { - -webkit-border-bottom-right-radius: 0; - border-bottom-right-radius: 0; - -moz-border-radius-bottomright: 0; } - -.table-bordered caption + thead tr:first-child th:first-child, -.table-bordered caption + tbody tr:first-child td:first-child, -.table-bordered colgroup + thead tr:first-child th:first-child, -.table-bordered colgroup + tbody tr:first-child td:first-child { - -webkit-border-top-left-radius: 4px; - border-top-left-radius: 4px; - -moz-border-radius-topleft: 4px; } - -.table-bordered caption + thead tr:first-child th:last-child, -.table-bordered caption + tbody tr:first-child td:last-child, -.table-bordered colgroup + thead tr:first-child th:last-child, -.table-bordered colgroup + tbody tr:first-child td:last-child { - -webkit-border-top-right-radius: 4px; - border-top-right-radius: 4px; - -moz-border-radius-topright: 4px; } - -table.docutils th { - background-color: #e8e8e8; } - -table.docutils tr:hover { - background-color: whitesmoke; } - -.table-striped tbody > tr:nth-child(odd) > td, -.table-striped tbody > tr:nth-child(odd) > th { - background-color: rgba(252, 248, 244, 0.75); } - -.table-hover tbody tr:hover > td, -.table-hover tbody tr:hover > th { - background-color: rgba(241, 222, 204, 0.75); } - -table td[class*="span"], -table th[class*="span"], -.row-fluid table td[class*="span"], -.row-fluid table th[class*="span"] { - display: table-cell; - float: none; - margin-left: 0; } - -.hero-unit { - padding: 60px; - margin-bottom: 30px; - font-size: 18px; - font-weight: 200; - line-height: 30px; - color: inherit; - background-color: rgba(230, 197, 164, 0.75); - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; } - -.hero-unit h1 { - margin-bottom: 0; - font-size: 60px; - line-height: 1; - letter-spacing: -1px; - color: inherit; } - -.hero-unit li { - line-height: 30px; } /* rst2html default used to remove borders from tables and images */ .borderless, table.borderless td, table.borderless th { @@ -722,10 +499,6 @@ table.borderless td, table.borderless th { .hidden { display: none; } -a.toc-backref { - text-decoration: none; - color: #444444; } - blockquote.epigraph { margin: 2em 5em; } @@ -735,85 +508,6 @@ dl.docutils dd { object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] { overflow: hidden; } -/* Uncomment (and remove this text!) to get bold-faced definition list terms -dl.docutils dt { - font-weight: bold } -*/ -div.abstract { - margin: 2em 5em; } - -div.abstract p.topic-title { - font-weight: bold; - text-align: center; } - -div.admonition, div.attention, div.caution, div.danger, div.error, -div.hint, div.important, div.note, div.tip, div.warning { - margin: 2em; - border: medium outset; - padding: 1em; } - -div.note, div.warning { - margin: 1.5em 0px; - border: none; } - -div.note p.admonition-title, -div.warning p.admonition-title { - display: none; } - -/* Clearfix - * http://css-tricks.com/snippets/css/clear-fix/ - */ -div.note:after, -div.warning:after { - content: ""; - display: table; - clear: both; } - -div.note p:before, -div.warning p:before { - display: block; - float: left; - font-size: 4em; - line-height: 1em; - margin-right: 20px; - margin-left: 0em; - margin-top: -10px; - content: '\0270D'; - /*handwriting*/ } - -div.warning p:before { - content: '\026A0'; - /*warning*/ } - -div.admonition p.admonition-title, div.hint p.admonition-title, -div.important p.admonition-title, div.note p.admonition-title, -div.tip p.admonition-title { - font-weight: bold; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } - -div.attention p.admonition-title, div.caution p.admonition-title, -div.danger p.admonition-title, div.error p.admonition-title, -div.warning p.admonition-title, .code .error { - color: #b30000; - font-weight: bold; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } - -/* Uncomment (and remove this text!) to get reduced vertical space in - compound paragraphs. -div.compound .compound-first, div.compound .compound-middle { - margin-bottom: 0.5em } - -div.compound .compound-last, div.compound .compound-middle { - margin-top: 0.5em } -*/ -div.dedication { - margin: 2em 5em; - text-align: center; - font-style: italic; } - -div.dedication p.topic-title { - font-weight: bold; - font-style: normal; } div.figure { margin-left: 2em; @@ -821,8 +515,14 @@ div.figure { div.footer, div.header { clear: both; + text-align: center; + color: #666; font-size: smaller; } +div.footer { + padding-top: 5em; +} + div.line-block { display: block; margin-top: 1em; @@ -833,45 +533,24 @@ div.line-block div.line-block { margin-bottom: 0; margin-left: 1.5em; } -div.sidebar { - margin: 0 0 0.5em 1em; - border: medium outset; - padding: 1em; - background-color: rgba(252, 248, 244, 0.75); - width: 40%; - float: right; - clear: right; } - -div.sidebar p.rubric { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-size: medium; } - -div.system-messages { - margin: 5em; } - -div.system-messages h1 { - color: #b30000; } - -div.system-message { - border: medium outset; - padding: 1em; } - -div.system-message p.system-message-title { - color: #b30000; - font-weight: bold; } - div.topic { margin: 2em; } -h1.section-subtitle, h2.section-subtitle, h3.section-subtitle, -h4.section-subtitle, h5.section-subtitle, h6.section-subtitle { - margin-top: 0.4em; } +div.search_results { + background-color: antiquewhite; + margin: 3em; + padding: 1em; + border: 1px solid #4d4d4d; +} -h1.title { - text-align: center; } +div#global-links ul { + margin-left: 0; + list-style-type: none; +} -h2.subtitle { - text-align: center; } +div#global-links > simple-boot { + margin-left: 3em; +} hr.docutils { width: 75%; } @@ -905,30 +584,6 @@ img.align-center, .figure.align-center, object.align-center { div.align-right { text-align: inherit; } -/* div.align-center * { */ -/* text-align: left } */ - -ul.simple > li { - margin-bottom: 0.5em } - -ol.simple, ul.simple { - margin-bottom: 1em; } - -ol.arabic { - list-style: decimal; } - -ol.loweralpha { - list-style: lower-alpha; } - -ol.upperalpha { - list-style: upper-alpha; } - -ol.lowerroman { - list-style: lower-roman; } - -ol.upperroman { - list-style: upper-roman; } - p.attribution { text-align: right; margin-left: 50%; } @@ -949,15 +604,6 @@ p.rubric { color: maroon; text-align: center; } -p.sidebar-title { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-weight: bold; - font-size: larger; } - -p.sidebar-subtitle { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-weight: bold; } - p.topic-title { font-weight: bold; } @@ -997,22 +643,14 @@ pre.code .inserted, code .inserted { background-color: #A3D289; } span.classifier { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-style: oblique; } span.classifier-delimiter { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: bold; } -span.interpreted { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } - span.option { white-space: nowrap; } -span.pre { - white-space: pre; } - span.problematic { color: #b30000; } @@ -1020,44 +658,6 @@ span.section-subtitle { /* font-size relative to parent (h1..h6 element) */ font-size: 80%; } -table.citation { - border-left: solid 1px #666666; - margin-left: 1px; } - -table.docinfo { - margin: 0em; - margin-top: 2em; - margin-bottom: 2em; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; - color: #444444; } - -table.docutils { - margin-top: 0.5em; - margin-bottom: 0.5em; } - -table.footnote { - border-left: solid 1px #2d2d2d; - margin-left: 1px; } - -table.docutils td, table.docutils th, -table.docinfo td, table.docinfo th { - padding-left: 0.5em; - padding-right: 0.5em; - vertical-align: top; } - -table.docutils th.field-name, table.docinfo th.docinfo-name { - font-weight: 700; - text-align: left; - white-space: nowrap; - padding-left: 0; } - -h1 tt.docutils, h2 tt.docutils, h3 tt.docutils, -h4 tt.docutils, h5 tt.docutils, h6 tt.docutils { - font-size: 100%; } - -ul.auto-toc { - list-style-type: none; } - span.DecNumber { color: #252dbe; } @@ -1074,7 +674,7 @@ span.FloatNumber { color: #252dbe; } span.Identifier { - color: #3b3b3b; } + color: #222; } span.Keyword { font-weight: 600; @@ -1139,38 +739,23 @@ dt pre > span.Identifier, dt pre > span.Operator { color: #155da4; font-weight: 700; } -dt pre > span.Identifier ~ span.Identifier, dt pre > span.Operator ~ span.Identifier { - color: inherit; - font-weight: inherit; } - -dt pre > span.Operator ~ span.Identifier { +dt pre > span.Keyword ~ span.Identifier, dt pre > span.Identifier ~ span.Identifier, +dt pre > span.Operator ~ span.Identifier, dt pre > span.Other ~ span.Identifier { color: inherit; font-weight: inherit; } /* Nim sprite for the footer (taken from main page favicon) */ .nim-sprite { display: inline-block; - height: 12px; - width: 12px; + height: 16px; + width: 16px; background-position: 0 0; - background-size: 12px 12px; + background-size: 16px 16px; -webkit-filter: opacity(50%); background-repeat: no-repeat; background-image: url("data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="); margin-bottom: -5px; } -div.search_results { - background-color: antiquewhite; - margin: 3em; - padding: 1em; - border: 1px solid #4d4d4d; -} - -div#global-links ul { - margin-left: 0; - list-style-type: none; -} - span.pragmadots { /* Position: relative frees us up to make the dots look really nice without fucking up the layout and @@ -1178,18 +763,14 @@ span.pragmadots { position: relative; /* 1px down looks slightly nicer */ top: 1px; - padding: 2px; - background-color: #D3D3D3; + background-color: #e8e8e8; border-radius: 4px; margin: 0 2px; cursor: pointer; - - /* For some reason on Chrome, making the font size - smaller than 1em is causing the parent container to - bulge slightly. So, we're stuck with inheriting 1em, - which is sad, because 0.8em looks better... */ + font-size: 0.8em; } + span.pragmadots:hover { background-color: #DBDBDB; } @@ -1197,6 +778,10 @@ span.pragmawrap { display: none; } +span.attachedType { + display: none; + visibility: hidden; +} @@ -1238,12 +823,6 @@ function main() {
      -
    • - Exports -
        - -
      -
    • Imports
      +

      This is the main nimterop import file to help with wrapping C/C++ source code.

      Check out template.nim as a starting point for wrapping a new library. The template can be copied and trimmed down and modified as required. templite.nim is a shorter version for more experienced users.

      All {.compileTime.} procs must be used in a compile time context, e.g. using:

      static:
         cAddStdDir()

      - -
      +

      Imports

      plugin, git, paths, types @@ -1314,11 +895,12 @@ function main() {

      Procs

      - -
      proc cSkipSymbol(skips: seq[string]) {...}{.compileTime, raises: [], tags: [].}
      + +
      proc cSkipSymbol(skips: seq[string]) {...}{.compileTime, raises: [], tags: [].}
      -

      Similar to cOverride(), this macro allows filtering out symbols not of interest from the generated output.

      -

      cSkipSymbol() only affects calls to cImport() that follow it.

      + +

      Similar to cOverride(), this macro allows filtering out symbols not of interest from the generated output.

      +

      cSkipSymbol() only affects calls to cImport() that follow it.

      Examples:

      static :
      @@ -1326,31 +908,35 @@ function main() {
       
       
      -
      proc cSearchPath(path: string): string {...}{.compileTime, raises: [], tags: [ReadDirEffect].}
      +
      proc cSearchPath(path: string): string {...}{.compileTime, raises: [], tags: [ReadDirEffect].}
      -

      Get full path to file or directory path in search path configured using cAddSearchDir() and cAddStdDir().

      -

      This can be used to locate files or directories that can be passed onto cCompile(), cIncludeDir() and cImport().

      + +

      Get full path to file or directory path in search path configured using cAddSearchDir() and cAddStdDir().

      +

      This can be used to locate files or directories that can be passed onto cCompile(), cIncludeDir() and cImport().

      - -
      proc cDebug() {...}{.compileTime, raises: [], tags: [].}
      + +
      proc cDebug() {...}{.compileTime, raises: [], tags: [].}
      + Enable debug messages and display the generated Nim code
      - -
      proc cDisableCaching() {...}{.compileTime, raises: [], tags: [].}
      + +
      proc cDisableCaching() {...}{.compileTime, raises: [], tags: [].}
      +

      Disable caching of generated Nim code - useful during wrapper development

      -

      If files included by header being processed by cImport() change and affect the generated content, they will be ignored and the cached value will continue to be used . Use cDisableCaching() to avoid this scenario during development.

      +

      If files included by header being processed by cImport() change and affect the generated content, they will be ignored and the cached value will continue to be used . Use cDisableCaching() to avoid this scenario during development.

      nim -f was broken prior to 0.19.4 but can also be used to flush the cached content.

      -
      proc cAddSearchDir(dir: string) {...}{.compileTime, raises: [], tags: [].}
      +
      proc cAddSearchDir(dir: string) {...}{.compileTime, raises: [], tags: [].}
      + Add directory dir to the search path used in calls to cSearchPath().

      Examples:

      import
      @@ -1362,8 +948,9 @@ Add directory dir to
       
       
      -
      proc cAddStdDir(mode = "c") {...}{.compileTime, raises: [], tags: [ReadEnvEffect].}
      +
      proc cAddStdDir(mode = "c") {...}{.compileTime, raises: [ValueError], tags: [ReadEnvEffect].}
      + Add the standard c [default] or cpp include paths to search path used in calls to cSearchPath()

      Examples:

      static :
      @@ -1379,34 +966,36 @@ Add the standard c [d
       

      Macros

      - -
      macro cOverride(body): untyped
      + +
      macro cOverride(body): untyped
      -

      When the wrapper code generated by nimterop is missing certain symbols or not accurate, it may be required to hand wrap them. Define them in a cOverride() macro block so that Nimterop no longer defines these symbols.

      + +

      When the wrapper code generated by nimterop is missing certain symbols or not accurate, it may be required to hand wrap them. Define them in a cOverride() macro block so that Nimterop no longer defines these symbols.

      For example:

      int svGetCallerInfo(const char** fileName, int *lineNumber);

      This might map to:

      proc svGetCallerInfo(fileName: ptr cstring; lineNumber: var cint)

      Whereas it might mean:

      cOverride:
      -  proc svGetCallerInfo(fileName: var cstring; lineNumber: var cint)

      Using the cOverride() block, nimterop can be instructed to skip over svGetCallerInfo(). This works for procs, consts and types.

      -

      cOverride() only affects calls to cImport() that follow it.

      + proc svGetCallerInfo(fileName: var cstring; lineNumber: var cint)

      Using the cOverride() block, nimterop can be instructed to skip over svGetCallerInfo(). This works for procs, consts and types.

      +

      cOverride() only affects calls to cImport() that follow it.

      - -
      macro cPlugin(body): untyped
      + +
      macro cPlugin(body): untyped
      -When cOverride() and cSkipSymbol() are not adequate, the cPlugin() macro can be used to customize the generated Nim output. The following callbacks are available at this time.
      proc onSymbol(sym: var Symbol) {.exportc, dynlib.}

      onSymbol() can be used to handle symbol name modifications required due to invalid characters like leading/trailing _ or rename symbols that would clash due to Nim's style insensitivity. It can also be used to remove prefixes and suffixes like SDL_. The symbol name and type is provided to the callback and the name can be modified.

      -

      Returning a blank name will result in the symbol being skipped. This will fail for nskParam and nskField since the generated Nim code will be wrong.

      + +When cOverride() and cSkipSymbol() are not adequate, the cPlugin() macro can be used to customize the generated Nim output. The following callbacks are available at this time.
      proc onSymbol(sym: var Symbol) {.exportc, dynlib.}

      onSymbol() can be used to handle symbol name modifications required due to invalid characters like leading/trailing _ or rename symbols that would clash due to Nim's style insensitivity. It can also be used to remove prefixes and suffixes like SDL_. The symbol name and type is provided to the callback and the name can be modified.

      +

      Returning a blank name will result in the symbol being skipped. This will fail for nskParam and nskField since the generated Nim code will be wrong.

      Symbol types can be any of the following:

      -
      • nskConst for constants
      • -
      • nskType for type identifiers, including primitive
      • -
      • nskParam for param names
      • -
      • nskField for struct field names
      • -
      • nskEnumField for enum (field) names, though they are in the global namespace as nskConst
      • -
      • nskProc - for proc names
      • +
        • nskConst for constants
        • +
        • nskType for type identifiers, including primitive
        • +
        • nskParam for param names
        • +
        • nskField for struct field names
        • +
        • nskEnumField for enum (field) names, though they are in the global namespace as nskConst
        • +
        • nskProc - for proc names

        nimterop/plugins is implicitly imported to provide access to standard plugin facilities.

        -

        cPlugin() only affects calls to cImport() that follow it.

        +

        cPlugin() only affects calls to cImport() that follow it.

        Examples:

        cPlugin:
        @@ -1428,20 +1017,23 @@ When cOverride()<
         
         
      -
      macro cDefine(name: static string; val: static string = ""): untyped
      +
      macro cDefine(name: static string; val: static string = ""): untyped
      -#define an identifer that is forwarded to the C/C++ compiler using {.passC: "-DXXX".} + +#define an identifer that is forwarded to the C/C++ preprocessor if called within cImport() or c2nImport() as well as to the C/C++ compiler during Nim compilation using {.passC: "-DXXX".}
      - -
      macro cIncludeDir(dir: static string): untyped
      + +
      macro cIncludeDir(dir: static string): untyped
      -Add an include directory that is forwarded to the C/C++ compiler using {.passC: "-IXXX".}. This is also provided to the preprocessor during Nim code generation. + +Add an include directory that is forwarded to the C/C++ preprocessor if called within cImport() or c2nImport() as well as to the C/C++ compiler during Nim compilation using {.passC: "-IXXX".}.
      -
      macro cCompile(path: static string; mode = "c"; exclude = ""): untyped
      +
      macro cCompile(path: static string; mode = "c"; exclude = ""): untyped
      +

      Compile and link C/C++ implementation into resulting binary using {.compile.}

      path can be a specific file or contain wildcards:

      cCompile("file.c")
      @@ -1451,12 +1043,14 @@ Add an include directory that is forwarded to the C/C++ compiler using cCompile("path/to/dir", exclude="test2.c")
      - -
      macro cImport(filename: static string; recurse: static bool = false;
      -             dynlib: static string = ""): untyped
      + +
      macro cImport(filename: static string; recurse: static bool = false;
      +             dynlib: static string = ""; mode: static string = "c";
      +             flags: static string = ""): untyped
      -

      Import all supported definitions from specified header file. Generated content is cached in nimcache until filename changes unless cDisableCaching() is set. nim -f can also be used after Nim v0.19.4 to flush the cache.

      -

      recurse can be used to generate Nim wrappers from #include files referenced in filename. This is only done for files in the same directory as filename or in a directory added using cIncludeDir()

      + +

      Import all supported definitions from specified header file. Generated content is cached in nimcache until filename changes unless cDisableCaching() is set. nim -f can also be used after Nim v0.19.4 to flush the cache.

      +

      recurse can be used to generate Nim wrappers from #include files referenced in filename. This is only done for files in the same directory as filename or in a directory added using cIncludeDir()

      dynlib can be used to specify the Nim string to use to specify the dynamic library to load the imported symbols from. For example:

      const
         dynpcre =
      @@ -1470,17 +1064,20 @@ Add an include directory that is forwarded to the C/C++ compiler using else:
             "libpcre.so(.3|.1|)"
       
      -cImport("pcre.h", dynlib="dynpcre")

      If dynlib is not specified, the C/C++ implementation files can be compiled in with cCompile(), or the {.passL.} pragma can be used to specify the static lib to link.

      +cImport("pcre.h", dynlib="dynpcre")

      If dynlib is not specified, the C/C++ implementation files can be compiled in with cCompile(), or the {.passL.} pragma can be used to specify the static lib to link.

      +

      mode is purely for forward compatibility when toast adds C++ support. It can be ignored for the foreseeable future.

      +

      flags can be used to pass any other command line arguments to toast.

      -
      macro c2nImport(filename: static string; recurse: static bool = false;
      +
      macro c2nImport(filename: static string; recurse: static bool = false;
                      dynlib: static string = ""; mode: static string = "c";
                      flags: static string = ""): untyped
      +

      Import all supported definitions from specified header file using c2nim

      -

      Similar to cImport() but uses c2nim to generate the Nim wrapper instead of toast. Note that neither cOverride(), cSkipSymbol() nor cPlugin() have any impact on c2nim.

      +

      Similar to cImport() but uses c2nim to generate the Nim wrapper instead of toast. Note that neither cOverride(), cSkipSymbol() nor cPlugin() have any impact on c2nim.

      toast is only used to preprocess the header file and recurse if specified.

      mode should be set to cpp for c2nim to wrap C++ headers.

      flags can be used to pass other command line arguments to c2nim.

      @@ -1489,6 +1086,11 @@ Add an include directory that is forwarded to the C/C++ compiler using +
      +
      @@ -1498,7 +1100,7 @@ Add an include directory that is forwarded to the C/C++ compiler using
      - Made with Nim. Generated: 2019-07-29 14:17:11 UTC + Made with Nim. Generated: 2019-07-30 00:08:28 UTC
      diff --git a/cimport.idx b/cimport.idx index 9a0b8f5..ac8ee27 100644 --- a/cimport.idx +++ b/cimport.idx @@ -1,13 +1,13 @@ -cOverride cimport.html#cOverride.m, cimport: cOverride(body): untyped -cSkipSymbol cimport.html#cSkipSymbol,seq[string] cimport: cSkipSymbol(skips: seq[string]) -cPlugin cimport.html#cPlugin.m, cimport: cPlugin(body): untyped +cOverride cimport.html#cOverride.m cimport: cOverride(body): untyped +cSkipSymbol cimport.html#cSkipSymbol,seq[T][string] cimport: cSkipSymbol(skips: seq[string]) +cPlugin cimport.html#cPlugin.m cimport: cPlugin(body): untyped cSearchPath cimport.html#cSearchPath,string cimport: cSearchPath(path: string): string -cDebug cimport.html#cDebug, cimport: cDebug() -cDisableCaching cimport.html#cDisableCaching, cimport: cDisableCaching() +cDebug cimport.html#cDebug cimport: cDebug() +cDisableCaching cimport.html#cDisableCaching cimport: cDisableCaching() cDefine cimport.html#cDefine.m,,string cimport: cDefine(name: static string; val: static string = ""): untyped cAddSearchDir cimport.html#cAddSearchDir,string cimport: cAddSearchDir(dir: string) -cIncludeDir cimport.html#cIncludeDir.m, cimport: cIncludeDir(dir: static string): untyped +cIncludeDir cimport.html#cIncludeDir.m cimport: cIncludeDir(dir: static string): untyped cAddStdDir cimport.html#cAddStdDir,string cimport: cAddStdDir(mode = "c") cCompile cimport.html#cCompile.m,,string,string cimport: cCompile(path: static string; mode = "c"; exclude = ""): untyped -cImport cimport.html#cImport.m,,string cimport: cImport(filename: static string; recurse: static bool = false;\n dynlib: static string = ""): untyped +cImport cimport.html#cImport.m,,string,string,string cimport: cImport(filename: static string; recurse: static bool = false;\n dynlib: static string = ""; mode: static string = "c"; flags: static string = ""): untyped c2nImport cimport.html#c2nImport.m,,string,string,string cimport: c2nImport(filename: static string; recurse: static bool = false;\n dynlib: static string = ""; mode: static string = "c"; flags: static string = ""): untyped diff --git a/compat.html b/compat.html index 995d828..85b8e0e 100644 --- a/compat.html +++ b/compat.html @@ -27,232 +27,130 @@ customize this style sheet. Modified from Chad Skeeters' rst2html-style https://bitbucket.org/cskeeters/rst2html-style/ -Modified by Boyd Greenfield +Modified by Boyd Greenfield and narimiran */ -/* SCSS variables */ -/* Text weights */ -/* Body colors */ -/* Text colors */ -/* Link colors */ -/* Syntax highlighting colors */ -/* Pct changes */ -/* Mixins */ -/* Body/layout */ + html { font-size: 100%; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; } -/* Where we want fancier font if available */ -h1, h2, h3, h4, h5, h6, p.module-desc, table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; } - -h1.title { - font-weight: 900; } - body { font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: 400; - font-size: 16px; - line-height: 20px; - color: #444; - letter-spacing: 0.15px; - background-color: #FDFBFA; } + font-size: 1.125em; + line-height: 1.5; + color: #222; + background-color: #FCFCFC; } /* Skeleton grid */ .container { position: relative; width: 100%; - max-width: 960px; + max-width: 1050px; margin: 0 auto; - padding: 0 20px; + padding: 0; box-sizing: border-box; } .column, .columns { width: 100%; float: left; - box-sizing: border-box; } + box-sizing: border-box; + margin-left: 1%; +} -/* For devices larger than 400px */ -@media (min-width: 400px) { - .container { - width: 100%; - padding: 0; } } -/* For devices larger than 650px */ -@media (min-width: 650px) { - .container { - width: 100%; } +.column:first-child, +.columns:first-child { + margin-left: 0; } - .column, - .columns { - margin-left: 4%; } +.three.columns { + width: 19%; } - .column:first-child, - .columns:first-child { - margin-left: 0; } +.nine.columns { + width: 80.0%; } - .one.column, - .one.columns { - width: 4.66666666667%; } - - .two.columns { - width: 13.3333333333%; } +.twelve.columns { + width: 100%; + margin-left: 0; } +@media screen and (max-width: 860px) { .three.columns { - width: 22%; } - - .four.columns { - width: 30.6666666667%; } - - .five.columns { - width: 39.3333333333%; } - - .six.columns { - width: 48%; } - - .seven.columns { - width: 56.6666666667%; } - - .eight.columns { - width: 65.3333333333%; } - + display: none; + } .nine.columns { - width: 74.0%; } - - .ten.columns { - width: 82.6666666667%; } - - .eleven.columns { - width: 91.3333333333%; } - - .twelve.columns { - width: 100%; - margin-left: 0; } - - .one-third.column { - width: 30.6666666667%; } - - .two-thirds.column { - width: 65.3333333333%; } } -/* Customer Overrides */ -.footer { - text-align: center; - color: #969696; - padding-top: 10%; } - -p.module-desc { - font-size: 1.1em; - color: #666666; } - -a.link-seesrc { - color: #aec7d2; - font-style: italic; } - -a.link-seesrc:hover { - color: #6c9aae; } - -#toc-list { - word-wrap: break-word; } - -ul.simple-toc { - list-style: none; } - -ul.simple-toc a.reference-toplevel { - font-weight: bold; - color: #0077b3; } - -ul.simple-toc-section { - list-style-type: circle; - color: #6c9aae; } - -ul.simple-toc-section a.reference { - color: #0077b3; } + width: 98.0%; + } + body { + font-size: 1em; + line-height: 1.35; + } +} cite { font-style: italic !important; } -dt > pre { - border-color: rgba(0, 0, 0, 0.1); - background-color: rgba(255, 255, 255, 0.3); - margin: 15px 0px 5px; } - -dd > pre { - border-color: rgba(0, 0, 0, 0.1); - background-color: whitesmoke; - margin-top: 8px; } - -.item > dd { - margin-left: 10px; - margin-bottom: 30px; } - -/* Nim line-numbered tables */ -.line-nums-table { - width: 100%; - table-layout: fixed; } /* Nim search input */ div#searchInputDiv { - margin-bottom: 8px; + margin-bottom: 1em; } -div#searchInputDiv input#searchInput { - width: 10em; -} -div.search-groupby { - margin-bottom: 8px; +input#searchInput { + width: 80%; } -table.line-nums-table { - border-radius: 4px; - border: 1px solid #cccccc; - background-color: whitesmoke; - border-collapse: separate; - margin-top: 15px; - margin-bottom: 25px; } - -.line-nums-table tbody { - border: none; } - -.line-nums-table td pre { - border: none; - background-color: transparent; } - -.line-nums-table td.blob-line-nums { - width: 28px; } - -.line-nums-table td.blob-line-nums pre { - color: #b0b0b0; - -webkit-filter: opacity(75%); - text-align: right; - border-color: transparent; - background-color: transparent; - padding-left: 0px; - margin-left: 0px; - padding-right: 0px; - margin-right: 0px; } +/* + * Some custom formatting for input forms. + * This also fixes input form colors on Firefox with a dark system theme on Linux. + */ +input { + -moz-appearance: none; + color: #333; + background-color: #f8f8f8; + border: 1px solid #aaa; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-size: 0.9em; + padding: 6px; +} +input:focus { + border: 1px solid #1fa0eb; + box-shadow: 0 0 2px #1fa0eb; +} /* Docgen styles */ /* Links */ a { - color: #0077b3; - text-decoration: none; } + color: #07b; + text-decoration: none; +} + +a span.Identifier { + text-decoration: underline; + text-decoration-color: #aab; +} + +a.reference-toplevel { + font-weight: bold; +} + +a.toc-backref { + text-decoration: none; + color: #222; } + +a.link-seesrc { + color: #607c9f; + font-size: 0.9em; + font-style: italic; } a:hover, a:focus { - color: #00334d; + color: #607c9f; text-decoration: underline; } -a:visited { - color: #00334d; } +a:hover span.Identifier { + color: #607c9f; +} -a:focus { - outline: thin dotted #2d2d2d; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; } - -a:hover, -a:active { - outline: 0; } sub, sup { @@ -329,379 +227,258 @@ img { h2, h3 { - page-break-after: avoid; } } -.img-rounded { - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; } + page-break-after: avoid; } +} -.img-polaroid { - padding: 4px; - background-color: rgba(252, 248, 244, 0.75); - border: 1px solid #ccc; - border: 1px solid rgba(0, 0, 0, 0.2); - -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); - -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); } p { - margin: 0 0 8px; } + margin-top: 0.5em; + margin-bottom: 0.5em; +} small { font-size: 85%; } strong { - font-weight: 600; } + font-weight: 600; + font-size: 0.95em; + color: #3c3c3c; +} em { font-style: italic; } -cite { - font-style: normal; } - -h1, -h2, -h3, -h4, -h5, -h6 { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-weight: 600; - line-height: 20px; - color: inherit; - text-rendering: optimizelegibility; } - h1 { - font-size: 2em; + font-size: 1.8em; font-weight: 400; - padding-bottom: .15em; - border-bottom: 1px solid #aaaaaa; - margin-top: 1.0em; + padding-bottom: .25em; + border-bottom: 1px solid #aaa; + margin-top: 2.5em; + margin-bottom: 1em; line-height: 1.2em; } h1.title { padding-bottom: 1em; border-bottom: 0px; - font-size: 2.75em; } + font-size: 2.5em; + text-align: center; + font-weight: 900; + margin-top: 0.75em; + margin-bottom: 0em; +} h2 { - font-size: 1.5em; - margin-top: 1.5em; } + font-size: 1.3em; + margin-top: 2em; } + +h2.subtitle { + text-align: center; } h3 { - font-size: 1.3em; + font-size: 1.125em; font-style: italic; - margin-top: 0.75em; } + margin-top: 1.5em; } h4 { - font-size: 1.3em; - margin-top: 0.5em; } + font-size: 1.125em; + margin-top: 1em; } h5 { - font-size: 1.2em; - margin-top: 0.25em; } + font-size: 1.125em; + margin-top: 0.75em; } h6 { font-size: 1.1em; } + ul, ol { padding: 0; - margin: 0 0 0px 15px; } + margin-top: 0.5em; + margin-left: 0.75em; } ul ul, ul ol, ol ol, ol ul { - margin-bottom: 0; } + margin-bottom: 0; + margin-left: 1.25em; } li { - line-height: 20px; } - -dl { - margin-bottom: 20px; } - -dt, -dd { - line-height: 20px; } - -dt { - font-weight: bold; } - -dd { - margin-left: 10px; - margin-bottom: 26px; } - -hr { - margin: 20px 0; - border: 0; - border-top: 1px solid #eeeeee; - border-bottom: 1px solid #ffffff; } - -abbr[title], -abbr[data-original-title] { - cursor: help; - border-bottom: 1px dotted #999999; } - -abbr.initialism { - font-size: 90%; - text-transform: uppercase; } - -blockquote { - padding: 0 0 0 15px; - margin: 0 0 20px; - border-left: 5px solid #EFEBE0; } - -table.docinfo + blockquote, table.docinfo blockquote, h1 + blockquote { - border-left: 5px solid #c9c9c9; + list-style-type: circle; } -table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { - margin-bottom: 0; - font-size: 15px; - font-weight: 200; - line-height: 1.5; - font-style: italic; } +ul.simple-boot li { + list-style-type: none; + margin-left: 0em; + margin-bottom: 0.5em; +} -q:before, -q:after, -blockquote:before, -blockquote:after { - content: ""; } +ol.simple > li, ul.simple > li { + margin-bottom: 0.25em; + margin-left: 0.4em } -address { - display: block; - margin-bottom: 20px; - font-style: normal; - line-height: 20px; } +ul.simple.simple-toc > li { + margin-top: 1em; +} -code, -pre { - font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - padding: 0 3px 2px; - font-weight: 500; - font-size: 12px; - color: #444444; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; } +ul.simple-toc { + list-style: none; + font-size: 0.9em; + margin-left: -0.3em; + margin-top: 1em; } + +ul.simple-toc > li { + list-style-type: none; +} + +ul.simple-toc-section { + list-style-type: circle; + margin-left: 1em; + color: #6c9aae; } + + +ol.arabic { + list-style: decimal; } + +ol.loweralpha { + list-style: lower-alpha; } + +ol.upperalpha { + list-style: upper-alpha; } + +ol.lowerroman { + list-style: lower-roman; } + +ol.upperroman { + list-style: upper-roman; } + +ul.auto-toc { + list-style-type: none; } + + +dl { + margin-bottom: 1.5em; } + +dt { + margin-bottom: -0.5em; + margin-left: 0.0em; } + +dd { + margin-left: 2.0em; + margin-bottom: 3.0em; + margin-top: 0.5em; } + + +hr { + margin: 2em 0; + border: 0; + border-top: 1px solid #aaa; } + +blockquote { + font-size: 0.9em; + font-style: italic; + padding-left: 0.5em; + margin-left: 0; + border-left: 5px solid #bbc; +} .pre { font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - font-weight: 600; - /*color: #504da6;*/ + font-weight: 500; + font-size: 0.85em; + background-color: #f0f3ff; + padding-left: 3px; + padding-right: 3px; + border-radius: 4px; } -code { - padding: 2px 4px; - color: #444444; - white-space: nowrap; - background-color: white; - border: 1px solid #777777; } - pre { + font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; + color: #222; + font-weight: 500; display: inline-block; box-sizing: border-box; - min-width: calc(100% - 19.5px); - padding: 9.5px; - margin: 0.25em 10px 10px 10px; - font-size: 15px; - line-height: 20px; + min-width: 100%; + padding: 0.5em; + margin-top: 0.5em; + margin-bottom: 0.5em; + font-size: 0.85em; white-space: pre !important; overflow-y: hidden; overflow-x: visible; - background-color: rgba(0, 0, 0, 0.01); - border: 1px solid #cccccc; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; } - -pre.prettyprint { - margin-bottom: 20px; } - -pre code { - padding: 0; - color: inherit; - white-space: pre; - overflow-x: visible; - background-color: transparent; - border: 0; } + background-color: ghostwhite; + border: 1px solid #dde; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; } .pre-scrollable { max-height: 340px; overflow-y: scroll; } + +/* Nim line-numbered tables */ +.line-nums-table { + width: 100%; + table-layout: fixed; } + +table.line-nums-table { + border-radius: 4px; + border: 1px solid #cccccc; + background-color: ghostwhite; + border-collapse: separate; + margin-top: 15px; + margin-bottom: 25px; } + +.line-nums-table tbody { + border: none; } + +.line-nums-table td pre { + border: none; + background-color: transparent; } + +.line-nums-table td.blob-line-nums { + width: 28px; } + +.line-nums-table td.blob-line-nums pre { + color: #b0b0b0; + -webkit-filter: opacity(75%); + text-align: right; + border-color: transparent; + background-color: transparent; + padding-left: 0px; + margin-left: 0px; + padding-right: 0px; + margin-right: 0px; } + + table { max-width: 100%; background-color: transparent; + margin-top: 0.5em; + margin-bottom: 1.5em; border-collapse: collapse; - border-spacing: 0; } - -table th, table td { - padding: 0px 8px 0px; + border-color: #ccc; + border-spacing: 0; + font-size: 0.9em; } -.table { - width: 100%; - margin-bottom: 20px; } +table th, table td { + padding: 0px 0.5em 0px; +} -.table th, -.table td { - padding: 8px; - line-height: 20px; - text-align: left; - vertical-align: top; - border-top: 1px solid #444444; } - -.table th { +table th { + background-color: #e8e8e8; font-weight: bold; } -.table thead th { - vertical-align: bottom; } +table th.docinfo-name { + background-color: transparent; +} -.table caption + thead tr:first-child th, -.table caption + thead tr:first-child td, -.table colgroup + thead tr:first-child th, -.table colgroup + thead tr:first-child td, -.table thead:first-child tr:first-child th, -.table thead:first-child tr:first-child td { - border-top: 0; } +table tr:hover { + background-color: ghostwhite; } -.table tbody + tbody { - border-top: 2px solid #444444; } - -.table .table { - background-color: rgba(252, 248, 244, 0.75); } - -.table-condensed th, -.table-condensed td { - padding: 4px 5px; } - -.table-bordered { - border: 1px solid #444444; - border-collapse: separate; - *border-collapse: collapse; - border-left: 0; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; } - -.table-bordered th, -.table-bordered td { - border-left: 1px solid #444444; } - -.table-bordered caption + thead tr:first-child th, -.table-bordered caption + tbody tr:first-child th, -.table-bordered caption + tbody tr:first-child td, -.table-bordered colgroup + thead tr:first-child th, -.table-bordered colgroup + tbody tr:first-child th, -.table-bordered colgroup + tbody tr:first-child td, -.table-bordered thead:first-child tr:first-child th, -.table-bordered tbody:first-child tr:first-child th, -.table-bordered tbody:first-child tr:first-child td { - border-top: 0; } - -.table-bordered thead:first-child tr:first-child > th:first-child, -.table-bordered tbody:first-child tr:first-child > td:first-child, -.table-bordered tbody:first-child tr:first-child > th:first-child { - -webkit-border-top-left-radius: 4px; - border-top-left-radius: 4px; - -moz-border-radius-topleft: 4px; } - -.table-bordered thead:first-child tr:first-child > th:last-child, -.table-bordered tbody:first-child tr:first-child > td:last-child, -.table-bordered tbody:first-child tr:first-child > th:last-child { - -webkit-border-top-right-radius: 4px; - border-top-right-radius: 4px; - -moz-border-radius-topright: 4px; } - -.table-bordered thead:last-child tr:last-child > th:first-child, -.table-bordered tbody:last-child tr:last-child > td:first-child, -.table-bordered tbody:last-child tr:last-child > th:first-child, -.table-bordered tfoot:last-child tr:last-child > td:first-child, -.table-bordered tfoot:last-child tr:last-child > th:first-child { - -webkit-border-bottom-left-radius: 4px; - border-bottom-left-radius: 4px; - -moz-border-radius-bottomleft: 4px; } - -.table-bordered thead:last-child tr:last-child > th:last-child, -.table-bordered tbody:last-child tr:last-child > td:last-child, -.table-bordered tbody:last-child tr:last-child > th:last-child, -.table-bordered tfoot:last-child tr:last-child > td:last-child, -.table-bordered tfoot:last-child tr:last-child > th:last-child { - -webkit-border-bottom-right-radius: 4px; - border-bottom-right-radius: 4px; - -moz-border-radius-bottomright: 4px; } - -.table-bordered tfoot + tbody:last-child tr:last-child td:first-child { - -webkit-border-bottom-left-radius: 0; - border-bottom-left-radius: 0; - -moz-border-radius-bottomleft: 0; } - -.table-bordered tfoot + tbody:last-child tr:last-child td:last-child { - -webkit-border-bottom-right-radius: 0; - border-bottom-right-radius: 0; - -moz-border-radius-bottomright: 0; } - -.table-bordered caption + thead tr:first-child th:first-child, -.table-bordered caption + tbody tr:first-child td:first-child, -.table-bordered colgroup + thead tr:first-child th:first-child, -.table-bordered colgroup + tbody tr:first-child td:first-child { - -webkit-border-top-left-radius: 4px; - border-top-left-radius: 4px; - -moz-border-radius-topleft: 4px; } - -.table-bordered caption + thead tr:first-child th:last-child, -.table-bordered caption + tbody tr:first-child td:last-child, -.table-bordered colgroup + thead tr:first-child th:last-child, -.table-bordered colgroup + tbody tr:first-child td:last-child { - -webkit-border-top-right-radius: 4px; - border-top-right-radius: 4px; - -moz-border-radius-topright: 4px; } - -table.docutils th { - background-color: #e8e8e8; } - -table.docutils tr:hover { - background-color: whitesmoke; } - -.table-striped tbody > tr:nth-child(odd) > td, -.table-striped tbody > tr:nth-child(odd) > th { - background-color: rgba(252, 248, 244, 0.75); } - -.table-hover tbody tr:hover > td, -.table-hover tbody tr:hover > th { - background-color: rgba(241, 222, 204, 0.75); } - -table td[class*="span"], -table th[class*="span"], -.row-fluid table td[class*="span"], -.row-fluid table th[class*="span"] { - display: table-cell; - float: none; - margin-left: 0; } - -.hero-unit { - padding: 60px; - margin-bottom: 30px; - font-size: 18px; - font-weight: 200; - line-height: 30px; - color: inherit; - background-color: rgba(230, 197, 164, 0.75); - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; } - -.hero-unit h1 { - margin-bottom: 0; - font-size: 60px; - line-height: 1; - letter-spacing: -1px; - color: inherit; } - -.hero-unit li { - line-height: 30px; } /* rst2html default used to remove borders from tables and images */ .borderless, table.borderless td, table.borderless th { @@ -722,10 +499,6 @@ table.borderless td, table.borderless th { .hidden { display: none; } -a.toc-backref { - text-decoration: none; - color: #444444; } - blockquote.epigraph { margin: 2em 5em; } @@ -735,85 +508,6 @@ dl.docutils dd { object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] { overflow: hidden; } -/* Uncomment (and remove this text!) to get bold-faced definition list terms -dl.docutils dt { - font-weight: bold } -*/ -div.abstract { - margin: 2em 5em; } - -div.abstract p.topic-title { - font-weight: bold; - text-align: center; } - -div.admonition, div.attention, div.caution, div.danger, div.error, -div.hint, div.important, div.note, div.tip, div.warning { - margin: 2em; - border: medium outset; - padding: 1em; } - -div.note, div.warning { - margin: 1.5em 0px; - border: none; } - -div.note p.admonition-title, -div.warning p.admonition-title { - display: none; } - -/* Clearfix - * http://css-tricks.com/snippets/css/clear-fix/ - */ -div.note:after, -div.warning:after { - content: ""; - display: table; - clear: both; } - -div.note p:before, -div.warning p:before { - display: block; - float: left; - font-size: 4em; - line-height: 1em; - margin-right: 20px; - margin-left: 0em; - margin-top: -10px; - content: '\0270D'; - /*handwriting*/ } - -div.warning p:before { - content: '\026A0'; - /*warning*/ } - -div.admonition p.admonition-title, div.hint p.admonition-title, -div.important p.admonition-title, div.note p.admonition-title, -div.tip p.admonition-title { - font-weight: bold; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } - -div.attention p.admonition-title, div.caution p.admonition-title, -div.danger p.admonition-title, div.error p.admonition-title, -div.warning p.admonition-title, .code .error { - color: #b30000; - font-weight: bold; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } - -/* Uncomment (and remove this text!) to get reduced vertical space in - compound paragraphs. -div.compound .compound-first, div.compound .compound-middle { - margin-bottom: 0.5em } - -div.compound .compound-last, div.compound .compound-middle { - margin-top: 0.5em } -*/ -div.dedication { - margin: 2em 5em; - text-align: center; - font-style: italic; } - -div.dedication p.topic-title { - font-weight: bold; - font-style: normal; } div.figure { margin-left: 2em; @@ -821,8 +515,14 @@ div.figure { div.footer, div.header { clear: both; + text-align: center; + color: #666; font-size: smaller; } +div.footer { + padding-top: 5em; +} + div.line-block { display: block; margin-top: 1em; @@ -833,45 +533,24 @@ div.line-block div.line-block { margin-bottom: 0; margin-left: 1.5em; } -div.sidebar { - margin: 0 0 0.5em 1em; - border: medium outset; - padding: 1em; - background-color: rgba(252, 248, 244, 0.75); - width: 40%; - float: right; - clear: right; } - -div.sidebar p.rubric { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-size: medium; } - -div.system-messages { - margin: 5em; } - -div.system-messages h1 { - color: #b30000; } - -div.system-message { - border: medium outset; - padding: 1em; } - -div.system-message p.system-message-title { - color: #b30000; - font-weight: bold; } - div.topic { margin: 2em; } -h1.section-subtitle, h2.section-subtitle, h3.section-subtitle, -h4.section-subtitle, h5.section-subtitle, h6.section-subtitle { - margin-top: 0.4em; } +div.search_results { + background-color: antiquewhite; + margin: 3em; + padding: 1em; + border: 1px solid #4d4d4d; +} -h1.title { - text-align: center; } +div#global-links ul { + margin-left: 0; + list-style-type: none; +} -h2.subtitle { - text-align: center; } +div#global-links > simple-boot { + margin-left: 3em; +} hr.docutils { width: 75%; } @@ -905,30 +584,6 @@ img.align-center, .figure.align-center, object.align-center { div.align-right { text-align: inherit; } -/* div.align-center * { */ -/* text-align: left } */ - -ul.simple > li { - margin-bottom: 0.5em } - -ol.simple, ul.simple { - margin-bottom: 1em; } - -ol.arabic { - list-style: decimal; } - -ol.loweralpha { - list-style: lower-alpha; } - -ol.upperalpha { - list-style: upper-alpha; } - -ol.lowerroman { - list-style: lower-roman; } - -ol.upperroman { - list-style: upper-roman; } - p.attribution { text-align: right; margin-left: 50%; } @@ -949,15 +604,6 @@ p.rubric { color: maroon; text-align: center; } -p.sidebar-title { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-weight: bold; - font-size: larger; } - -p.sidebar-subtitle { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-weight: bold; } - p.topic-title { font-weight: bold; } @@ -997,22 +643,14 @@ pre.code .inserted, code .inserted { background-color: #A3D289; } span.classifier { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-style: oblique; } span.classifier-delimiter { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: bold; } -span.interpreted { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } - span.option { white-space: nowrap; } -span.pre { - white-space: pre; } - span.problematic { color: #b30000; } @@ -1020,44 +658,6 @@ span.section-subtitle { /* font-size relative to parent (h1..h6 element) */ font-size: 80%; } -table.citation { - border-left: solid 1px #666666; - margin-left: 1px; } - -table.docinfo { - margin: 0em; - margin-top: 2em; - margin-bottom: 2em; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; - color: #444444; } - -table.docutils { - margin-top: 0.5em; - margin-bottom: 0.5em; } - -table.footnote { - border-left: solid 1px #2d2d2d; - margin-left: 1px; } - -table.docutils td, table.docutils th, -table.docinfo td, table.docinfo th { - padding-left: 0.5em; - padding-right: 0.5em; - vertical-align: top; } - -table.docutils th.field-name, table.docinfo th.docinfo-name { - font-weight: 700; - text-align: left; - white-space: nowrap; - padding-left: 0; } - -h1 tt.docutils, h2 tt.docutils, h3 tt.docutils, -h4 tt.docutils, h5 tt.docutils, h6 tt.docutils { - font-size: 100%; } - -ul.auto-toc { - list-style-type: none; } - span.DecNumber { color: #252dbe; } @@ -1074,7 +674,7 @@ span.FloatNumber { color: #252dbe; } span.Identifier { - color: #3b3b3b; } + color: #222; } span.Keyword { font-weight: 600; @@ -1139,38 +739,23 @@ dt pre > span.Identifier, dt pre > span.Operator { color: #155da4; font-weight: 700; } -dt pre > span.Identifier ~ span.Identifier, dt pre > span.Operator ~ span.Identifier { - color: inherit; - font-weight: inherit; } - -dt pre > span.Operator ~ span.Identifier { +dt pre > span.Keyword ~ span.Identifier, dt pre > span.Identifier ~ span.Identifier, +dt pre > span.Operator ~ span.Identifier, dt pre > span.Other ~ span.Identifier { color: inherit; font-weight: inherit; } /* Nim sprite for the footer (taken from main page favicon) */ .nim-sprite { display: inline-block; - height: 12px; - width: 12px; + height: 16px; + width: 16px; background-position: 0 0; - background-size: 12px 12px; + background-size: 16px 16px; -webkit-filter: opacity(50%); background-repeat: no-repeat; background-image: url("data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="); margin-bottom: -5px; } -div.search_results { - background-color: antiquewhite; - margin: 3em; - padding: 1em; - border: 1px solid #4d4d4d; -} - -div#global-links ul { - margin-left: 0; - list-style-type: none; -} - span.pragmadots { /* Position: relative frees us up to make the dots look really nice without fucking up the layout and @@ -1178,18 +763,14 @@ span.pragmadots { position: relative; /* 1px down looks slightly nicer */ top: 1px; - padding: 2px; - background-color: #D3D3D3; + background-color: #e8e8e8; border-radius: 4px; margin: 0 2px; cursor: pointer; - - /* For some reason on Chrome, making the font size - smaller than 1em is causing the parent container to - bulge slightly. So, we're stuck with inheriting 1em, - which is sad, because 0.8em looks better... */ + font-size: 0.8em; } + span.pragmadots:hover { background-color: #DBDBDB; } @@ -1197,6 +778,10 @@ span.pragmawrap { display: none; } +span.attachedType { + display: none; + visibility: hidden; +} @@ -1237,43 +822,13 @@ function main() { - - +
      +

      -
      -

      Procs

      -
      - -
      proc relativePath(file, base: string): string {...}{.raises: [], tags: [].}
      -
      -naive version of os.relativePath ; remove after nim >= 0.19.9 -

      Examples:

      -
      import
      -  ospaths, unittest
      -
      -check:
      -  "/foo/bar/baz/log.txt".unixToNativePath.relativePath(
      -      "/foo/bar".unixToNativePath) == "baz/log.txt".unixToNativePath
      -  "foo/bar/baz/log.txt".unixToNativePath.relativePath("foo/bar".unixToNativePath) ==
      -      "baz/log.txt".unixToNativePath
      - -
      - -
      - +
      @@ -1281,7 +836,7 @@ naive version of os.relativePath ; remove after nim >= 0.19.9 diff --git a/dochack.js b/dochack.js new file mode 100644 index 0000000..b960a56 --- /dev/null +++ b/dochack.js @@ -0,0 +1,1983 @@ +/* Generated by the Nim Compiler v0.20.2 */ +/* (c) 2019 Andreas Rumpf */ + +var framePtr = null; +var excHandler = 0; +var lastJSError = null; +if (typeof Int8Array === 'undefined') Int8Array = Array; +if (typeof Int16Array === 'undefined') Int16Array = Array; +if (typeof Int32Array === 'undefined') Int32Array = Array; +if (typeof Uint8Array === 'undefined') Uint8Array = Array; +if (typeof Uint16Array === 'undefined') Uint16Array = Array; +if (typeof Uint32Array === 'undefined') Uint32Array = Array; +if (typeof Float32Array === 'undefined') Float32Array = Array; +if (typeof Float64Array === 'undefined') Float64Array = Array; +var NTI130 = {size: 0,kind: 1,base: null,node: null,finalizer: null}; +var NTI162074 = {size: 0, kind: 18, base: null, node: null, finalizer: null}; +var NTI4062 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI164579 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; +var NTI42448 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI42444 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI42440 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI42436 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI42432 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI42428 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI42424 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI42420 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI42416 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI42412 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI42408 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI42404 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI42400 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI42396 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI42392 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI42388 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI42384 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI42380 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI42376 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI42372 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI42205 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI42283 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI42281 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; +var NTI42227 = {size: 0, kind: 14, base: null, node: null, finalizer: null}; +var NTI42565 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; +var NTI42563 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; +var NTI42561 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; +var NTI42231 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI42229 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; +var NTI44305 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; +var NTI4050 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI4058 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI104 = {size: 0,kind: 31,base: null,node: null,finalizer: null}; +var NTI21156 = {size: 0, kind: 18, base: null, node: null, finalizer: null}; +var NTI4008 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI4114 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; +var NTI114 = {size: 0,kind: 40,base: null,node: null,finalizer: null}; +var NTI138 = {size: 0,kind: 28,base: null,node: null,finalizer: null}; +var NTI140 = {size: 0,kind: 29,base: null,node: null,finalizer: null}; +var NTI4108 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; +var NTI4026 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI4028 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI4042 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI4046 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NNI4046 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI4046.node = NNI4046; +var NNI4042 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI4042.node = NNI4042; +var NNI4028 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI4028.node = NNI4028; +NTI4108.base = NTI4026; +NTI4114.base = NTI4026; +var NNI4026 = {kind: 2, len: 6, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "parent", len: 0, typ: NTI4108, name: "parent", sons: null}, +{kind: 1, offset: "name", len: 0, typ: NTI140, name: "name", sons: null}, +{kind: 1, offset: "message", len: 0, typ: NTI138, name: "msg", sons: null}, +{kind: 1, offset: "trace", len: 0, typ: NTI138, name: "trace", sons: null}, +{kind: 1, offset: "raiseId", len: 0, typ: NTI114, name: "raiseId", sons: null}, +{kind: 1, offset: "up", len: 0, typ: NTI4114, name: "up", sons: null}]}; +NTI4026.node = NNI4026; +var NNI4008 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI4008.node = NNI4008; +NTI4026.base = NTI4008; +NTI4028.base = NTI4026; +NTI4042.base = NTI4028; +NTI4046.base = NTI4042; +var NNI21156 = {kind: 2, len: 2, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "Field0", len: 0, typ: NTI140, name: "Field0", sons: null}, +{kind: 1, offset: "Field1", len: 0, typ: NTI104, name: "Field1", sons: null}]}; +NTI21156.node = NNI21156; +var NNI4058 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI4058.node = NNI4058; +NTI4058.base = NTI4028; +var NNI4050 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI4050.node = NNI4050; +NTI4050.base = NTI4028; +NTI42561.base = NTI42229; +NTI42563.base = NTI42229; +NTI42565.base = NTI42229; +var NNI42227 = {kind: 2, offset: 0, typ: null, name: null, len: 12, sons: {"1": {kind: 1, offset: 1, typ: NTI42227, name: "ElementNode", len: 0, sons: null}, +"2": {kind: 1, offset: 2, typ: NTI42227, name: "AttributeNode", len: 0, sons: null}, +"3": {kind: 1, offset: 3, typ: NTI42227, name: "TextNode", len: 0, sons: null}, +"4": {kind: 1, offset: 4, typ: NTI42227, name: "CDATANode", len: 0, sons: null}, +"5": {kind: 1, offset: 5, typ: NTI42227, name: "EntityRefNode", len: 0, sons: null}, +"6": {kind: 1, offset: 6, typ: NTI42227, name: "EntityNode", len: 0, sons: null}, +"7": {kind: 1, offset: 7, typ: NTI42227, name: "ProcessingInstructionNode", len: 0, sons: null}, +"8": {kind: 1, offset: 8, typ: NTI42227, name: "CommentNode", len: 0, sons: null}, +"9": {kind: 1, offset: 9, typ: NTI42227, name: "DocumentNode", len: 0, sons: null}, +"10": {kind: 1, offset: 10, typ: NTI42227, name: "DocumentTypeNode", len: 0, sons: null}, +"11": {kind: 1, offset: 11, typ: NTI42227, name: "DocumentFragmentNode", len: 0, sons: null}, +"12": {kind: 1, offset: 12, typ: NTI42227, name: "NotationNode", len: 0, sons: null}}}; +NTI42227.node = NNI42227; +var NNI42283 = {kind: 2, len: 91, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "background", len: 0, typ: NTI140, name: "background", sons: null}, +{kind: 1, offset: "backgroundAttachment", len: 0, typ: NTI140, name: "backgroundAttachment", sons: null}, +{kind: 1, offset: "backgroundColor", len: 0, typ: NTI140, name: "backgroundColor", sons: null}, +{kind: 1, offset: "backgroundImage", len: 0, typ: NTI140, name: "backgroundImage", sons: null}, +{kind: 1, offset: "backgroundPosition", len: 0, typ: NTI140, name: "backgroundPosition", sons: null}, +{kind: 1, offset: "backgroundRepeat", len: 0, typ: NTI140, name: "backgroundRepeat", sons: null}, +{kind: 1, offset: "border", len: 0, typ: NTI140, name: "border", sons: null}, +{kind: 1, offset: "borderBottom", len: 0, typ: NTI140, name: "borderBottom", sons: null}, +{kind: 1, offset: "borderBottomColor", len: 0, typ: NTI140, name: "borderBottomColor", sons: null}, +{kind: 1, offset: "borderBottomStyle", len: 0, typ: NTI140, name: "borderBottomStyle", sons: null}, +{kind: 1, offset: "borderBottomWidth", len: 0, typ: NTI140, name: "borderBottomWidth", sons: null}, +{kind: 1, offset: "borderColor", len: 0, typ: NTI140, name: "borderColor", sons: null}, +{kind: 1, offset: "borderLeft", len: 0, typ: NTI140, name: "borderLeft", sons: null}, +{kind: 1, offset: "borderLeftColor", len: 0, typ: NTI140, name: "borderLeftColor", sons: null}, +{kind: 1, offset: "borderLeftStyle", len: 0, typ: NTI140, name: "borderLeftStyle", sons: null}, +{kind: 1, offset: "borderLeftWidth", len: 0, typ: NTI140, name: "borderLeftWidth", sons: null}, +{kind: 1, offset: "borderRight", len: 0, typ: NTI140, name: "borderRight", sons: null}, +{kind: 1, offset: "borderRightColor", len: 0, typ: NTI140, name: "borderRightColor", sons: null}, +{kind: 1, offset: "borderRightStyle", len: 0, typ: NTI140, name: "borderRightStyle", sons: null}, +{kind: 1, offset: "borderRightWidth", len: 0, typ: NTI140, name: "borderRightWidth", sons: null}, +{kind: 1, offset: "borderStyle", len: 0, typ: NTI140, name: "borderStyle", sons: null}, +{kind: 1, offset: "borderTop", len: 0, typ: NTI140, name: "borderTop", sons: null}, +{kind: 1, offset: "borderTopColor", len: 0, typ: NTI140, name: "borderTopColor", sons: null}, +{kind: 1, offset: "borderTopStyle", len: 0, typ: NTI140, name: "borderTopStyle", sons: null}, +{kind: 1, offset: "borderTopWidth", len: 0, typ: NTI140, name: "borderTopWidth", sons: null}, +{kind: 1, offset: "borderWidth", len: 0, typ: NTI140, name: "borderWidth", sons: null}, +{kind: 1, offset: "bottom", len: 0, typ: NTI140, name: "bottom", sons: null}, +{kind: 1, offset: "captionSide", len: 0, typ: NTI140, name: "captionSide", sons: null}, +{kind: 1, offset: "clear", len: 0, typ: NTI140, name: "clear", sons: null}, +{kind: 1, offset: "clip", len: 0, typ: NTI140, name: "clip", sons: null}, +{kind: 1, offset: "color", len: 0, typ: NTI140, name: "color", sons: null}, +{kind: 1, offset: "cursor", len: 0, typ: NTI140, name: "cursor", sons: null}, +{kind: 1, offset: "direction", len: 0, typ: NTI140, name: "direction", sons: null}, +{kind: 1, offset: "display", len: 0, typ: NTI140, name: "display", sons: null}, +{kind: 1, offset: "emptyCells", len: 0, typ: NTI140, name: "emptyCells", sons: null}, +{kind: 1, offset: "cssFloat", len: 0, typ: NTI140, name: "cssFloat", sons: null}, +{kind: 1, offset: "font", len: 0, typ: NTI140, name: "font", sons: null}, +{kind: 1, offset: "fontFamily", len: 0, typ: NTI140, name: "fontFamily", sons: null}, +{kind: 1, offset: "fontSize", len: 0, typ: NTI140, name: "fontSize", sons: null}, +{kind: 1, offset: "fontStretch", len: 0, typ: NTI140, name: "fontStretch", sons: null}, +{kind: 1, offset: "fontStyle", len: 0, typ: NTI140, name: "fontStyle", sons: null}, +{kind: 1, offset: "fontVariant", len: 0, typ: NTI140, name: "fontVariant", sons: null}, +{kind: 1, offset: "fontWeight", len: 0, typ: NTI140, name: "fontWeight", sons: null}, +{kind: 1, offset: "height", len: 0, typ: NTI140, name: "height", sons: null}, +{kind: 1, offset: "left", len: 0, typ: NTI140, name: "left", sons: null}, +{kind: 1, offset: "letterSpacing", len: 0, typ: NTI140, name: "letterSpacing", sons: null}, +{kind: 1, offset: "lineHeight", len: 0, typ: NTI140, name: "lineHeight", sons: null}, +{kind: 1, offset: "listStyle", len: 0, typ: NTI140, name: "listStyle", sons: null}, +{kind: 1, offset: "listStyleImage", len: 0, typ: NTI140, name: "listStyleImage", sons: null}, +{kind: 1, offset: "listStylePosition", len: 0, typ: NTI140, name: "listStylePosition", sons: null}, +{kind: 1, offset: "listStyleType", len: 0, typ: NTI140, name: "listStyleType", sons: null}, +{kind: 1, offset: "margin", len: 0, typ: NTI140, name: "margin", sons: null}, +{kind: 1, offset: "marginBottom", len: 0, typ: NTI140, name: "marginBottom", sons: null}, +{kind: 1, offset: "marginLeft", len: 0, typ: NTI140, name: "marginLeft", sons: null}, +{kind: 1, offset: "marginRight", len: 0, typ: NTI140, name: "marginRight", sons: null}, +{kind: 1, offset: "marginTop", len: 0, typ: NTI140, name: "marginTop", sons: null}, +{kind: 1, offset: "maxHeight", len: 0, typ: NTI140, name: "maxHeight", sons: null}, +{kind: 1, offset: "maxWidth", len: 0, typ: NTI140, name: "maxWidth", sons: null}, +{kind: 1, offset: "minHeight", len: 0, typ: NTI140, name: "minHeight", sons: null}, +{kind: 1, offset: "minWidth", len: 0, typ: NTI140, name: "minWidth", sons: null}, +{kind: 1, offset: "overflow", len: 0, typ: NTI140, name: "overflow", sons: null}, +{kind: 1, offset: "padding", len: 0, typ: NTI140, name: "padding", sons: null}, +{kind: 1, offset: "paddingBottom", len: 0, typ: NTI140, name: "paddingBottom", sons: null}, +{kind: 1, offset: "paddingLeft", len: 0, typ: NTI140, name: "paddingLeft", sons: null}, +{kind: 1, offset: "paddingRight", len: 0, typ: NTI140, name: "paddingRight", sons: null}, +{kind: 1, offset: "paddingTop", len: 0, typ: NTI140, name: "paddingTop", sons: null}, +{kind: 1, offset: "pageBreakAfter", len: 0, typ: NTI140, name: "pageBreakAfter", sons: null}, +{kind: 1, offset: "pageBreakBefore", len: 0, typ: NTI140, name: "pageBreakBefore", sons: null}, +{kind: 1, offset: "pointerEvents", len: 0, typ: NTI140, name: "pointerEvents", sons: null}, +{kind: 1, offset: "position", len: 0, typ: NTI140, name: "position", sons: null}, +{kind: 1, offset: "right", len: 0, typ: NTI140, name: "right", sons: null}, +{kind: 1, offset: "scrollbar3dLightColor", len: 0, typ: NTI140, name: "scrollbar3dLightColor", sons: null}, +{kind: 1, offset: "scrollbarArrowColor", len: 0, typ: NTI140, name: "scrollbarArrowColor", sons: null}, +{kind: 1, offset: "scrollbarBaseColor", len: 0, typ: NTI140, name: "scrollbarBaseColor", sons: null}, +{kind: 1, offset: "scrollbarDarkshadowColor", len: 0, typ: NTI140, name: "scrollbarDarkshadowColor", sons: null}, +{kind: 1, offset: "scrollbarFaceColor", len: 0, typ: NTI140, name: "scrollbarFaceColor", sons: null}, +{kind: 1, offset: "scrollbarHighlightColor", len: 0, typ: NTI140, name: "scrollbarHighlightColor", sons: null}, +{kind: 1, offset: "scrollbarShadowColor", len: 0, typ: NTI140, name: "scrollbarShadowColor", sons: null}, +{kind: 1, offset: "scrollbarTrackColor", len: 0, typ: NTI140, name: "scrollbarTrackColor", sons: null}, +{kind: 1, offset: "tableLayout", len: 0, typ: NTI140, name: "tableLayout", sons: null}, +{kind: 1, offset: "textAlign", len: 0, typ: NTI140, name: "textAlign", sons: null}, +{kind: 1, offset: "textDecoration", len: 0, typ: NTI140, name: "textDecoration", sons: null}, +{kind: 1, offset: "textIndent", len: 0, typ: NTI140, name: "textIndent", sons: null}, +{kind: 1, offset: "textTransform", len: 0, typ: NTI140, name: "textTransform", sons: null}, +{kind: 1, offset: "transform", len: 0, typ: NTI140, name: "transform", sons: null}, +{kind: 1, offset: "top", len: 0, typ: NTI140, name: "top", sons: null}, +{kind: 1, offset: "verticalAlign", len: 0, typ: NTI140, name: "verticalAlign", sons: null}, +{kind: 1, offset: "visibility", len: 0, typ: NTI140, name: "visibility", sons: null}, +{kind: 1, offset: "width", len: 0, typ: NTI140, name: "width", sons: null}, +{kind: 1, offset: "wordSpacing", len: 0, typ: NTI140, name: "wordSpacing", sons: null}, +{kind: 1, offset: "zIndex", len: 0, typ: NTI104, name: "zIndex", sons: null}]}; +NTI42283.node = NNI42283; +NTI42283.base = NTI4008; +NTI42281.base = NTI42283; +var NNI42231 = {kind: 2, len: 14, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "attributes", len: 0, typ: NTI42561, name: "attributes", sons: null}, +{kind: 1, offset: "childNodes", len: 0, typ: NTI42563, name: "childNodes", sons: null}, +{kind: 1, offset: "children", len: 0, typ: NTI42565, name: "children", sons: null}, +{kind: 1, offset: "data", len: 0, typ: NTI140, name: "data", sons: null}, +{kind: 1, offset: "firstChild", len: 0, typ: NTI42229, name: "firstChild", sons: null}, +{kind: 1, offset: "lastChild", len: 0, typ: NTI42229, name: "lastChild", sons: null}, +{kind: 1, offset: "nextSibling", len: 0, typ: NTI42229, name: "nextSibling", sons: null}, +{kind: 1, offset: "nodeName", len: 0, typ: NTI140, name: "nodeName", sons: null}, +{kind: 1, offset: "nodeType", len: 0, typ: NTI42227, name: "nodeType", sons: null}, +{kind: 1, offset: "nodeValue", len: 0, typ: NTI140, name: "nodeValue", sons: null}, +{kind: 1, offset: "parentNode", len: 0, typ: NTI42229, name: "parentNode", sons: null}, +{kind: 1, offset: "previousSibling", len: 0, typ: NTI42229, name: "previousSibling", sons: null}, +{kind: 1, offset: "innerHTML", len: 0, typ: NTI140, name: "innerHTML", sons: null}, +{kind: 1, offset: "style", len: 0, typ: NTI42281, name: "style", sons: null}]}; +NTI42231.node = NNI42231; +var NNI42205 = {kind: 2, len: 20, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "onabort", len: 0, typ: NTI42372, name: "onabort", sons: null}, +{kind: 1, offset: "onblur", len: 0, typ: NTI42376, name: "onblur", sons: null}, +{kind: 1, offset: "onchange", len: 0, typ: NTI42380, name: "onchange", sons: null}, +{kind: 1, offset: "onclick", len: 0, typ: NTI42384, name: "onclick", sons: null}, +{kind: 1, offset: "ondblclick", len: 0, typ: NTI42388, name: "ondblclick", sons: null}, +{kind: 1, offset: "onerror", len: 0, typ: NTI42392, name: "onerror", sons: null}, +{kind: 1, offset: "onfocus", len: 0, typ: NTI42396, name: "onfocus", sons: null}, +{kind: 1, offset: "onkeydown", len: 0, typ: NTI42400, name: "onkeydown", sons: null}, +{kind: 1, offset: "onkeypress", len: 0, typ: NTI42404, name: "onkeypress", sons: null}, +{kind: 1, offset: "onkeyup", len: 0, typ: NTI42408, name: "onkeyup", sons: null}, +{kind: 1, offset: "onload", len: 0, typ: NTI42412, name: "onload", sons: null}, +{kind: 1, offset: "onmousedown", len: 0, typ: NTI42416, name: "onmousedown", sons: null}, +{kind: 1, offset: "onmousemove", len: 0, typ: NTI42420, name: "onmousemove", sons: null}, +{kind: 1, offset: "onmouseout", len: 0, typ: NTI42424, name: "onmouseout", sons: null}, +{kind: 1, offset: "onmouseover", len: 0, typ: NTI42428, name: "onmouseover", sons: null}, +{kind: 1, offset: "onmouseup", len: 0, typ: NTI42432, name: "onmouseup", sons: null}, +{kind: 1, offset: "onreset", len: 0, typ: NTI42436, name: "onreset", sons: null}, +{kind: 1, offset: "onselect", len: 0, typ: NTI42440, name: "onselect", sons: null}, +{kind: 1, offset: "onsubmit", len: 0, typ: NTI42444, name: "onsubmit", sons: null}, +{kind: 1, offset: "onunload", len: 0, typ: NTI42448, name: "onunload", sons: null}]}; +NTI42205.node = NNI42205; +NTI42205.base = NTI4008; +NTI42231.base = NTI42205; +NTI42229.base = NTI42231; +NTI44305.base = NTI42229; +NTI164579.base = NTI140; +var NNI4062 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI4062.node = NNI4062; +NTI4062.base = NTI4028; +var NNI162074 = {kind: 2, len: 2, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "Field0", len: 0, typ: NTI104, name: "Field0", sons: null}, +{kind: 1, offset: "Field1", len: 0, typ: NTI130, name: "Field1", sons: null}]}; +NTI162074.node = NNI162074; + +function makeNimstrLit(c_23254) { + var ln = c_23254.length; + var result = new Array(ln); + for (var i = 0; i < ln; ++i) { + result[i] = c_23254.charCodeAt(i); + } + return result; + + + +} + +function setConstr() { + var result = {}; + for (var i = 0; i < arguments.length; ++i) { + var x = arguments[i]; + if (typeof(x) == "object") { + for (var j = x[0]; j <= x[1]; ++j) { + result[j] = true; + } + } else { + result[x] = true; + } + } + return result; + + + +} +var ConstSet1 = setConstr(17, 16, 4, 18, 27, 19, 23, 22, 21); + +function nimCopy(dest_24427, src_24428, ti_24429) { + var result_24619 = null; + + switch (ti_24429.kind) { + case 21: + case 22: + case 23: + case 5: + if (!(is_fat_pointer_24401(ti_24429))) { + result_24619 = src_24428; + } + else { + result_24619 = [src_24428[0], src_24428[1]]; + } + + break; + case 19: + if (dest_24427 === null || dest_24427 === undefined) { + dest_24427 = {}; + } + else { + for (var key in dest_24427) { delete dest_24427[key]; } + } + for (var key in src_24428) { dest_24427[key] = src_24428[key]; } + result_24619 = dest_24427; + + break; + case 18: + case 17: + if (!((ti_24429.base == null))) { + result_24619 = nimCopy(dest_24427, src_24428, ti_24429.base); + } + else { + if ((ti_24429.kind == 17)) { + result_24619 = (dest_24427 === null || dest_24427 === undefined) ? {m_type: ti_24429} : dest_24427; + } + else { + result_24619 = (dest_24427 === null || dest_24427 === undefined) ? {} : dest_24427; + } + } + nimCopyAux(result_24619, src_24428, ti_24429.node); + break; + case 24: + case 4: + case 27: + case 16: + if (src_24428 === null) { + result_24619 = null; + } + else { + if (dest_24427 === null || dest_24427 === undefined) { + dest_24427 = new Array(src_24428.length); + } + else { + dest_24427.length = src_24428.length; + } + result_24619 = dest_24427; + for (var i = 0; i < src_24428.length; ++i) { + result_24619[i] = nimCopy(result_24619[i], src_24428[i], ti_24429.base); + } + } + + break; + case 28: + if (src_24428 !== null) { + result_24619 = src_24428.slice(0); + } + + break; + default: + result_24619 = src_24428; + break; + } + + return result_24619; + +} + +function arrayConstr(len_24686, value_24687, typ_24688) { + var result = new Array(len_24686); + for (var i = 0; i < len_24686; ++i) result[i] = nimCopy(null, value_24687, typ_24688); + return result; + + + +} + +function cstrToNimstr(c_23271) { + var ln = c_23271.length; + var result = new Array(ln); + var r = 0; + for (var i = 0; i < ln; ++i) { + var ch = c_23271.charCodeAt(i); + + if (ch < 128) { + result[r] = ch; + } + else { + if (ch < 2048) { + result[r] = (ch >> 6) | 192; + } + else { + if (ch < 55296 || ch >= 57344) { + result[r] = (ch >> 12) | 224; + } + else { + ++i; + ch = 65536 + (((ch & 1023) << 10) | (c_23271.charCodeAt(i) & 1023)); + result[r] = (ch >> 18) | 240; + ++r; + result[r] = ((ch >> 12) & 63) | 128; + } + ++r; + result[r] = ((ch >> 6) & 63) | 128; + } + ++r; + result[r] = (ch & 63) | 128; + } + ++r; + } + return result; + + + +} + +function toJSStr(s_23288) { + if (s_23288 === null) return ""; + var len = s_23288.length; + var asciiPart = new Array(len); + var fcc = String.fromCharCode; + var nonAsciiPart = null; + var nonAsciiOffset = 0; + for (var i = 0; i < len; ++i) { + if (nonAsciiPart !== null) { + var offset = (i - nonAsciiOffset) * 2; + var code = s_23288[i].toString(16); + if (code.length == 1) { + code = "0"+code; + } + nonAsciiPart[offset] = "%"; + nonAsciiPart[offset + 1] = code; + } + else if (s_23288[i] < 128) + asciiPart[i] = fcc(s_23288[i]); + else { + asciiPart.length = i; + nonAsciiOffset = i; + nonAsciiPart = new Array((len - i) * 2); + --i; + } + } + asciiPart = asciiPart.join(""); + return (nonAsciiPart === null) ? + asciiPart : asciiPart + decodeURIComponent(nonAsciiPart.join("")); + + + +} + +function raiseException(e_21618, ename_21619) { + e_21618.name = ename_21619; + if ((excHandler == 0)) { + unhandledException(e_21618); + } + + e_21618.trace = nimCopy(null, raw_write_stack_trace_21468(), NTI138); + throw e_21618; + + +} + +function addInt(a_23603, b_23604) { + var result = a_23603 + b_23604; + if (result > 2147483647 || result < -2147483648) raiseOverflow(); + return result; + + + +} + +function chckIndx(i_24705, a_24706, b_24707) { + var Tmp1; + + var result_24708 = 0; + + BeforeRet: do { + if (!(a_24706 <= i_24705)) Tmp1 = false; else { Tmp1 = (i_24705 <= b_24707); } if (Tmp1) { + result_24708 = i_24705; + break BeforeRet; + } + else { + raiseIndexError(i_24705, a_24706, b_24707); + } + + } while (false); + + return result_24708; + +} + +function subInt(a_23621, b_23622) { + var result = a_23621 - b_23622; + if (result > 2147483647 || result < -2147483648) raiseOverflow(); + return result; + + + +} +var ConstSet2 = setConstr([65, 90]); + +function chckRange(i_24724, a_24725, b_24726) { + var Tmp1; + + var result_24727 = 0; + + BeforeRet: do { + if (!(a_24725 <= i_24724)) Tmp1 = false; else { Tmp1 = (i_24724 <= b_24726); } if (Tmp1) { + result_24727 = i_24724; + break BeforeRet; + } + else { + raiseRangeError(); + } + + } while (false); + + return result_24727; + +} +var ConstSet3 = setConstr(95, 32, 46); +var ConstSet4 = setConstr(95, 32, 46); + +function mulInt(a_23639, b_23640) { + var result = a_23639 * b_23640; + if (result > 2147483647 || result < -2147483648) raiseOverflow(); + return result; + + + +} +var ConstSet5 = setConstr([97, 122]); +var ConstSet6 = setConstr([65, 90], [97, 122]); +var ConstSet7 = setConstr([97, 122]); +var ConstSet8 = setConstr([65, 90]); + +function nimMax(a_24021, b_24022) { + var Tmp1; + + var result_24023 = 0; + + BeforeRet: do { + if ((b_24022 <= a_24021)) { + Tmp1 = a_24021; + } + else { + Tmp1 = b_24022; + } + + result_24023 = Tmp1; + break BeforeRet; + } while (false); + + return result_24023; + +} + +function nimMin(a_24003, b_24004) { + var Tmp1; + + var result_24005 = 0; + + BeforeRet: do { + if ((a_24003 <= b_24004)) { + Tmp1 = a_24003; + } + else { + Tmp1 = b_24004; + } + + result_24005 = Tmp1; + break BeforeRet; + } while (false); + + return result_24005; + +} +var nim_program_result = 0; +var global_raise_hook_18618 = [null]; +var local_raise_hook_18623 = [null]; +var out_of_mem_hook_18626 = [null]; + if (!Math.trunc) { + Math.trunc = function(v) { + v = +v; + if (!isFinite(v)) return v; + + return (v - v % 1) || (v < 0 ? -0 : v === 0 ? v : 0); + }; + } +var alternative_164315 = [null]; + +function is_fat_pointer_24401(ti_24403) { + var result_24404 = false; + + BeforeRet: do { + result_24404 = !((ConstSet1[ti_24403.base.kind] != undefined)); + break BeforeRet; + } while (false); + + return result_24404; + +} + +function nimCopyAux(dest_24432, src_24433, n_24435) { + switch (n_24435.kind) { + case 0: + break; + case 1: + dest_24432[n_24435.offset] = nimCopy(dest_24432[n_24435.offset], src_24433[n_24435.offset], n_24435.typ); + + break; + case 2: + for (var i = 0; i < n_24435.sons.length; i++) { + nimCopyAux(dest_24432, src_24433, n_24435.sons[i]); + } + + break; + case 3: + dest_24432[n_24435.offset] = nimCopy(dest_24432[n_24435.offset], src_24433[n_24435.offset], n_24435.typ); + for (var i = 0; i < n_24435.sons.length; ++i) { + nimCopyAux(dest_24432, src_24433, n_24435.sons[i][1]); + } + + break; + } + + +} + +function add_18638(x_18641, x_18641_Idx, y_18642) { + if (x_18641[x_18641_Idx] === null) { x_18641[x_18641_Idx] = []; } + var off = x_18641[x_18641_Idx].length; + x_18641[x_18641_Idx].length += y_18642.length; + for (var i = 0; i < y_18642.length; ++i) { + x_18641[x_18641_Idx][off+i] = y_18642.charCodeAt(i); + } + + + +} + +function aux_write_stack_trace_21151(f_21153) { + var Tmp3; + + var result_21154 = [null]; + + var it_21162 = f_21153; + var i_21164 = 0; + var total_21166 = 0; + var temp_frames_21173 = arrayConstr(64, {Field0: null, Field1: 0}, NTI21156); + L1: do { + L2: while (true) { + if (!!((it_21162 == null))) Tmp3 = false; else { Tmp3 = (i_21164 <= 63); } if (!Tmp3) break L2; + temp_frames_21173[i_21164].Field0 = it_21162.procname; + temp_frames_21173[i_21164].Field1 = it_21162.line; + i_21164 += 1; + total_21166 += 1; + it_21162 = it_21162.prev; + } + } while(false); + L4: do { + L5: while (true) { + if (!!((it_21162 == null))) break L5; + total_21166 += 1; + it_21162 = it_21162.prev; + } + } while(false); + result_21154[0] = nimCopy(null, [], NTI138); + if (!((total_21166 == i_21164))) { + if (result_21154[0] != null) { result_21154[0] = (result_21154[0]).concat(makeNimstrLit("(")); } else { result_21154[0] = makeNimstrLit("("); }; + if (result_21154[0] != null) { result_21154[0] = (result_21154[0]).concat(cstrToNimstr(((total_21166 - i_21164))+"")); } else { result_21154[0] = cstrToNimstr(((total_21166 - i_21164))+"").slice(); }; + if (result_21154[0] != null) { result_21154[0] = (result_21154[0]).concat(makeNimstrLit(" calls omitted) ...\x0A")); } else { result_21154[0] = makeNimstrLit(" calls omitted) ...\x0A"); }; + } + + L6: do { + var j_21421 = 0; + var colontmp__164456 = 0; + colontmp__164456 = (i_21164 - 1); + var res_164461 = colontmp__164456; + L7: do { + L8: while (true) { + if (!(0 <= res_164461)) break L8; + j_21421 = res_164461; + add_18638(result_21154, 0, temp_frames_21173[j_21421].Field0); + if ((0 < temp_frames_21173[j_21421].Field1)) { + if (result_21154[0] != null) { result_21154[0] = (result_21154[0]).concat(makeNimstrLit(", line: ")); } else { result_21154[0] = makeNimstrLit(", line: "); }; + if (result_21154[0] != null) { result_21154[0] = (result_21154[0]).concat(cstrToNimstr((temp_frames_21173[j_21421].Field1)+"")); } else { result_21154[0] = cstrToNimstr((temp_frames_21173[j_21421].Field1)+"").slice(); }; + } + + if (result_21154[0] != null) { result_21154[0] = (result_21154[0]).concat(makeNimstrLit("\x0A")); } else { result_21154[0] = makeNimstrLit("\x0A"); }; + res_164461 -= 1; + } + } while(false); + } while(false); + + return result_21154[0]; + +} + +function raw_write_stack_trace_21468() { + var result_21470 = null; + + if (!((framePtr == null))) { + result_21470 = nimCopy(null, (makeNimstrLit("Traceback (most recent call last)\x0A") || []).concat(aux_write_stack_trace_21151(framePtr) || []), NTI138); + } + else { + result_21470 = nimCopy(null, makeNimstrLit("No stack traceback available\x0A"), NTI138); + } + + + return result_21470; + +} + +function unhandledException(e_21529) { + var buf_21530 = [[]]; + if (!(((e_21529.message != null ? e_21529.message.length : 0) == 0))) { + if (buf_21530[0] != null) { buf_21530[0] = (buf_21530[0]).concat(makeNimstrLit("Error: unhandled exception: ")); } else { buf_21530[0] = makeNimstrLit("Error: unhandled exception: "); }; + if (buf_21530[0] != null) { buf_21530[0] = (buf_21530[0]).concat(e_21529.message); } else { buf_21530[0] = e_21529.message.slice(); }; + } + else { + if (buf_21530[0] != null) { buf_21530[0] = (buf_21530[0]).concat(makeNimstrLit("Error: unhandled exception")); } else { buf_21530[0] = makeNimstrLit("Error: unhandled exception"); }; + } + + if (buf_21530[0] != null) { buf_21530[0] = (buf_21530[0]).concat(makeNimstrLit(" [")); } else { buf_21530[0] = makeNimstrLit(" ["); }; + add_18638(buf_21530, 0, e_21529.name); + if (buf_21530[0] != null) { buf_21530[0] = (buf_21530[0]).concat(makeNimstrLit("]\x0A")); } else { buf_21530[0] = makeNimstrLit("]\x0A"); }; + if (buf_21530[0] != null) { buf_21530[0] = (buf_21530[0]).concat(raw_write_stack_trace_21468()); } else { buf_21530[0] = raw_write_stack_trace_21468().slice(); }; + var cbuf_21601 = toJSStr(buf_21530[0]); + framePtr = null; + if (typeof(Error) !== "undefined") { + throw new Error(cbuf_21601); + } + else { + throw cbuf_21601; + } + + + +} + +function raiseOverflow() { + var e_22042 = null; + e_22042 = {m_type: NTI4046, parent: null, name: null, message: null, trace: null, raiseId: 0, up: null}; + e_22042.message = nimCopy(null, makeNimstrLit("over- or underflow"), NTI138); + e_22042.parent = null; + raiseException(e_22042, "OverflowError"); + + +} + +function is_whitespace_163654(text_163656) { + return !/[^\s]/.test(text_163656); + + + +} + +function is_whitespace_163671(x_163673) { + var Tmp1; + var Tmp2; + + var result_163674 = false; + + var F={procname:"dochack.isWhitespace",prev:framePtr,filename:"dochack.nim",line:0}; + framePtr = F; + F.line = 134; + if (!(x_163673.nodeName == "#text")) Tmp2 = false; else { Tmp2 = is_whitespace_163654(x_163673.textContent); } if (Tmp2) Tmp1 = true; else { Tmp1 = (x_163673.nodeName == "#comment"); } result_163674 = Tmp1; + framePtr = F.prev; + + return result_163674; + +} + +function raiseIndexError(i_22639, a_22640, b_22641) { + var Tmp1; + + var e_22802 = null; + e_22802 = {m_type: NTI4058, parent: null, name: null, message: null, trace: null, raiseId: 0, up: null}; + if ((b_22641 < a_22640)) { + Tmp1 = makeNimstrLit("index out of bounds, the container is empty"); + } + else { + Tmp1 = (makeNimstrLit("index ") || []).concat(cstrToNimstr((i_22639)+"") || [],makeNimstrLit(" not in ") || [],cstrToNimstr((a_22640)+"") || [],makeNimstrLit(" .. ") || [],cstrToNimstr((b_22641)+"") || []); + } + + e_22802.message = nimCopy(null, Tmp1, NTI138); + e_22802.parent = null; + raiseException(e_22802, "IndexError"); + + +} + +function to_toc_163688(x_163690, father_163691) { + var Tmp5; + var Tmp6; + var Tmp7; + var Tmp8; + var Tmp15; + + var F={procname:"dochack.toToc",prev:framePtr,filename:"dochack.nim",line:0}; + framePtr = F; + if ((x_163690.nodeName == "UL")) { + F.line = 139; + var f_163710 = {heading: null, kids: [], sortId: (father_163691.kids != null ? father_163691.kids.length : 0), doSort: false}; + F.line = 140; + var i_163712 = 0; + L1: do { + F.line = 141; + L2: while (true) { + if (!(i_163712 < x_163690.childNodes.length)) break L2; + F.line = 142; + var nxt_163713 = addInt(i_163712, 1); + L3: do { + F.line = 143; + L4: while (true) { + if (!(nxt_163713 < x_163690.childNodes.length)) Tmp5 = false; else { Tmp5 = is_whitespace_163671(x_163690.childNodes[nxt_163713]); } if (!Tmp5) break L4; + F.line = 144; + nxt_163713 = addInt(nxt_163713, 1); + } + } while(false); + if (!(nxt_163713 < x_163690.childNodes.length)) Tmp8 = false; else { Tmp8 = (x_163690.childNodes[i_163712].nodeName == "LI"); } if (!Tmp8) Tmp7 = false; else { Tmp7 = (x_163690.childNodes[i_163712].childNodes.length == 1); } if (!Tmp7) Tmp6 = false; else { Tmp6 = (x_163690.childNodes[nxt_163713].nodeName == "UL"); } if (Tmp6) { + F.line = 147; + var e_163738 = {heading: x_163690.childNodes[i_163712].childNodes[0], kids: [], sortId: (f_163710.kids != null ? f_163710.kids.length : 0), doSort: false}; + F.line = 148; + var it_163739 = x_163690.childNodes[nxt_163713]; + L9: do { + F.line = 149; + var j_163747 = 0; + F.line = 2716; + var colontmp__164432 = 0; + F.line = 149; + colontmp__164432 = it_163739.childNodes.length; + F.line = 2717; + var i_164433 = 0; + L10: do { + F.line = 2718; + L11: while (true) { + if (!(i_164433 < colontmp__164432)) break L11; + F.line = 149; + j_163747 = i_164433; + F.line = 150; + to_toc_163688(it_163739.childNodes[j_163747], e_163738); + F.line = 2720; + i_164433 = addInt(i_164433, 1); + } + } while(false); + } while(false); + F.line = 151; + if (f_163710.kids != null) { f_163710.kids.push(e_163738); } else { f_163710.kids = [e_163738]; }; + F.line = 152; + i_163712 = addInt(nxt_163713, 1); + } + else { + F.line = 154; + to_toc_163688(x_163690.childNodes[i_163712], f_163710); + F.line = 155; + i_163712 = addInt(i_163712, 1); + } + + } + } while(false); + F.line = 156; + if (father_163691.kids != null) { father_163691.kids.push(f_163710); } else { father_163691.kids = [f_163710]; }; + } + else { + if (is_whitespace_163671(x_163690)) { + } + else { + if ((x_163690.nodeName == "LI")) { + F.line = 160; + var idx_163782 = []; + L12: do { + F.line = 161; + var i_163790 = 0; + F.line = 2716; + var colontmp__164437 = 0; + F.line = 161; + colontmp__164437 = x_163690.childNodes.length; + F.line = 2717; + var i_164438 = 0; + L13: do { + F.line = 2718; + L14: while (true) { + if (!(i_164438 < colontmp__164437)) break L14; + F.line = 161; + i_163790 = i_164438; + if (!(is_whitespace_163671(x_163690.childNodes[i_163790]))) { + F.line = 162; + if (idx_163782 != null) { idx_163782.push(i_163790); } else { idx_163782 = [i_163790]; }; + } + + F.line = 2720; + i_164438 = addInt(i_164438, 1); + } + } while(false); + } while(false); + if (!((idx_163782 != null ? idx_163782.length : 0) == 2)) Tmp15 = false; else { Tmp15 = (x_163690.childNodes[idx_163782[chckIndx(1, 0, idx_163782.length+0-1)-0]].nodeName == "UL"); } if (Tmp15) { + F.line = 164; + var e_163821 = {heading: x_163690.childNodes[idx_163782[chckIndx(0, 0, idx_163782.length+0-1)-0]], kids: [], sortId: (father_163691.kids != null ? father_163691.kids.length : 0), doSort: false}; + F.line = 166; + var it_163822 = x_163690.childNodes[idx_163782[chckIndx(1, 0, idx_163782.length+0-1)-0]]; + L16: do { + F.line = 167; + var j_163830 = 0; + F.line = 2716; + var colontmp__164443 = 0; + F.line = 167; + colontmp__164443 = it_163822.childNodes.length; + F.line = 2717; + var i_164444 = 0; + L17: do { + F.line = 2718; + L18: while (true) { + if (!(i_164444 < colontmp__164443)) break L18; + F.line = 167; + j_163830 = i_164444; + F.line = 168; + to_toc_163688(it_163822.childNodes[j_163830], e_163821); + F.line = 2720; + i_164444 = addInt(i_164444, 1); + } + } while(false); + } while(false); + F.line = 169; + if (father_163691.kids != null) { father_163691.kids.push(e_163821); } else { father_163691.kids = [e_163821]; }; + } + else { + L19: do { + F.line = 171; + var i_163845 = 0; + F.line = 2716; + var colontmp__164448 = 0; + F.line = 171; + colontmp__164448 = x_163690.childNodes.length; + F.line = 2717; + var i_164449 = 0; + L20: do { + F.line = 2718; + L21: while (true) { + if (!(i_164449 < colontmp__164448)) break L21; + F.line = 171; + i_163845 = i_164449; + F.line = 172; + to_toc_163688(x_163690.childNodes[i_163845], father_163691); + F.line = 2720; + i_164449 = addInt(i_164449, 1); + } + } while(false); + } while(false); + } + + } + else { + F.line = 174; + if (father_163691.kids != null) { father_163691.kids.push({heading: x_163690, kids: [], sortId: (father_163691.kids != null ? father_163691.kids.length : 0), doSort: false}); } else { father_163691.kids = [{heading: x_163690, kids: [], sortId: (father_163691.kids != null ? father_163691.kids.length : 0), doSort: false}]; }; + } + }} + framePtr = F.prev; + + +} + +function extract_items_163339(x_163341, heading_163342, items_163345, items_163345_Idx) { + var Tmp1; + + var F={procname:"dochack.extractItems",prev:framePtr,filename:"dochack.nim",line:0}; + framePtr = F; + BeforeRet: do { + if ((x_163341 == null)) { + F.line = 81; + break BeforeRet; + } + + if (!!((x_163341.heading == null))) Tmp1 = false; else { Tmp1 = (x_163341.heading.textContent == heading_163342); } if (Tmp1) { + L2: do { + F.line = 83; + var i_163374 = 0; + F.line = 2716; + var colontmp__164475 = 0; + F.line = 83; + colontmp__164475 = (x_163341.kids != null ? x_163341.kids.length : 0); + F.line = 2717; + var i_164476 = 0; + L3: do { + F.line = 2718; + L4: while (true) { + if (!(i_164476 < colontmp__164475)) break L4; + F.line = 83; + i_163374 = i_164476; + F.line = 84; + if (items_163345[items_163345_Idx] != null) { items_163345[items_163345_Idx].push(x_163341.kids[chckIndx(i_163374, 0, x_163341.kids.length+0-1)-0].heading); } else { items_163345[items_163345_Idx] = [x_163341.kids[chckIndx(i_163374, 0, x_163341.kids.length+0-1)-0].heading]; }; + F.line = 2720; + i_164476 = addInt(i_164476, 1); + } + } while(false); + } while(false); + } + else { + L5: do { + F.line = 86; + var i_163394 = 0; + F.line = 2716; + var colontmp__164480 = 0; + F.line = 86; + colontmp__164480 = (x_163341.kids != null ? x_163341.kids.length : 0); + F.line = 2717; + var i_164481 = 0; + L6: do { + F.line = 2718; + L7: while (true) { + if (!(i_164481 < colontmp__164480)) break L7; + F.line = 86; + i_163394 = i_164481; + F.line = 87; + var it_163395 = x_163341.kids[chckIndx(i_163394, 0, x_163341.kids.length+0-1)-0]; + F.line = 88; + extract_items_163339(it_163395, heading_163342, items_163345, items_163345_Idx); + F.line = 2720; + i_164481 = addInt(i_164481, 1); + } + } while(false); + } while(false); + } + + } while (false); + framePtr = F.prev; + + +} + +function tree_163020(tag_163022, kids_163024) { + var result_163025 = null; + + var F={procname:"dochack.tree",prev:framePtr,filename:"dochack.nim",line:0}; + framePtr = F; + F.line = 11; + result_163025 = document.createElement(toJSStr(tag_163022)); + L1: do { + F.line = 12; + var k_163056 = null; + F.line = 3; + var i_164498 = 0; + L2: do { + F.line = 4; + L3: while (true) { + if (!(i_164498 < (kids_163024 != null ? kids_163024.length : 0))) break L3; + F.line = 12; + k_163056 = kids_163024[chckIndx(i_164498, 0, kids_163024.length+0-1)-0]; + F.line = 13; + result_163025.appendChild(k_163056); + F.line = 6; + i_164498 = addInt(i_164498, 1); + } + } while(false); + } while(false); + framePtr = F.prev; + + return result_163025; + +} + +function text_163152(s_163154) { + var result_163155 = null; + + var F={procname:"dochack.text",prev:framePtr,filename:"dochack.nim",line:0}; + framePtr = F; + F.line = 27; + result_163155 = document.createTextNode(s_163154); + framePtr = F.prev; + + return result_163155; + +} + +function sys_fatal_14862(message_14866) { + var F={procname:"sysFatal.sysFatal",prev:framePtr,filename:"fatal.nim",line:0}; + framePtr = F; + F.line = 34; + var e_15003 = null; + F.line = 37; + e_15003 = {m_type: NTI4050, parent: null, name: null, message: null, trace: null, raiseId: 0, up: null}; + F.line = 38; + e_15003.message = nimCopy(null, message_14866, NTI138); + F.line = 39; + raiseException(e_15003, "AssertionError"); + framePtr = F.prev; + + +} + +function raise_assert_14858(msg_14860) { + var F={procname:"assertions.raiseAssert",prev:framePtr,filename:"assertions.nim",line:0}; + framePtr = F; + F.line = 20; + sys_fatal_14862(msg_14860); + framePtr = F.prev; + + +} + +function failed_assert_impl_15051(msg_15053) { + var F={procname:"assertions.failedAssertImpl",prev:framePtr,filename:"assertions.nim",line:0}; + framePtr = F; + F.line = 27; + raise_assert_14858(msg_15053); + framePtr = F.prev; + + +} + +function uncovered_163940(x_163942) { + var Tmp1; + var Tmp2; + + var result_163943 = null; + + var F={procname:"dochack.uncovered",prev:framePtr,filename:"dochack.nim",line:0}; + framePtr = F; + BeforeRet: do { + if (!((x_163942.kids != null ? x_163942.kids.length : 0) == 0)) Tmp1 = false; else { Tmp1 = !((x_163942.heading == null)); } if (Tmp1) { + F.line = 194; + if (!(x_163942.heading.hasOwnProperty('__karaxMarker__'))) { + Tmp2 = x_163942; + } + else { + Tmp2 = null; + } + + result_163943 = Tmp2; + break BeforeRet; + } + + F.line = 195; + result_163943 = {heading: x_163942.heading, kids: [], sortId: x_163942.sortId, doSort: x_163942.doSort}; + L3: do { + F.line = 197; + var i_163982 = 0; + F.line = 2716; + var colontmp__164510 = 0; + F.line = 197; + colontmp__164510 = (x_163942.kids != null ? x_163942.kids.length : 0); + F.line = 2717; + var i_164511 = 0; + L4: do { + F.line = 2718; + L5: while (true) { + if (!(i_164511 < colontmp__164510)) break L5; + F.line = 197; + i_163982 = i_164511; + F.line = 198; + var y_163983 = uncovered_163940(x_163942.kids[chckIndx(i_163982, 0, x_163942.kids.length+0-1)-0]); + if (!((y_163983 == null))) { + F.line = 199; + if (result_163943.kids != null) { result_163943.kids.push(y_163983); } else { result_163943.kids = [y_163983]; }; + } + + F.line = 2720; + i_164511 = addInt(i_164511, 1); + } + } while(false); + } while(false); + if (((result_163943.kids != null ? result_163943.kids.length : 0) == 0)) { + F.line = 200; + result_163943 = null; + } + + } while (false); + framePtr = F.prev; + + return result_163943; + +} + +function merge_tocs_164017(orig_164019, news_164020) { + var result_164021 = null; + + var F={procname:"dochack.mergeTocs",prev:framePtr,filename:"dochack.nim",line:0}; + framePtr = F; + F.line = 203; + result_164021 = uncovered_163940(orig_164019); + if ((result_164021 == null)) { + F.line = 205; + result_164021 = news_164020; + } + else { + L1: do { + F.line = 207; + var i_164042 = 0; + F.line = 2716; + var colontmp__164504 = 0; + F.line = 207; + colontmp__164504 = (news_164020.kids != null ? news_164020.kids.length : 0); + F.line = 2717; + var i_164505 = 0; + L2: do { + F.line = 2718; + L3: while (true) { + if (!(i_164505 < colontmp__164504)) break L3; + F.line = 207; + i_164042 = i_164505; + F.line = 208; + if (result_164021.kids != null) { result_164021.kids.push(news_164020.kids[chckIndx(i_164042, 0, news_164020.kids.length+0-1)-0]); } else { result_164021.kids = [news_164020.kids[chckIndx(i_164042, 0, news_164020.kids.length+0-1)-0]]; }; + F.line = 2720; + i_164505 = addInt(i_164505, 1); + } + } while(false); + } while(false); + } + + framePtr = F.prev; + + return result_164021; + +} + +function build_toc_164063(orig_164065, types_164067, procs_164068) { + var result_164069 = null; + + var F={procname:"dochack.buildToc",prev:framePtr,filename:"dochack.nim",line:0}; + framePtr = F; + F.line = 211; + var new_stuff_164083 = {heading: null, kids: [], doSort: true, sortId: 0}; + L1: do { + F.line = 212; + var t_164214 = null; + F.line = 185; + var i_164493 = 0; + F.line = 186; + var l_164494 = (types_164067 != null ? types_164067.length : 0); + L2: do { + F.line = 187; + L3: while (true) { + if (!(i_164493 < l_164494)) break L3; + F.line = 212; + t_164214 = types_164067[chckIndx(i_164493, 0, types_164067.length+0-1)-0]; + F.line = 213; + var c_164228 = {heading: t_164214.cloneNode(true), kids: [], doSort: true, sortId: 0}; + F.line = 214; + t_164214.__karaxMarker__ = true; + L4: do { + F.line = 215; + var p_164235 = null; + F.line = 185; + var i_164490 = 0; + F.line = 186; + var l_164491 = (procs_164068 != null ? procs_164068.length : 0); + L5: do { + F.line = 187; + L6: while (true) { + if (!(i_164490 < l_164491)) break L6; + F.line = 215; + p_164235 = procs_164068[chckIndx(i_164490, 0, procs_164068.length+0-1)-0]; + if (!(p_164235.hasOwnProperty('__karaxMarker__'))) { + F.line = 217; + var xx_164236 = p_164235.parentNode.getElementsByClassName("attachedType"); + if ((((xx_164236 != null ? xx_164236.length : 0) == 1) && (xx_164236[chckIndx(0, 0, xx_164236.length+0-1)-0].textContent == t_164214.textContent))) { + F.line = 220; + var q_164244 = tree_163020(makeNimstrLit("A"), [text_163152(p_164235.title)]); + F.line = 221; + q_164244.setAttribute("href", p_164235.getAttribute("href")); + F.line = 222; + if (c_164228.kids != null) { c_164228.kids.push({heading: q_164244, kids: [], sortId: 0, doSort: false}); } else { c_164228.kids = [{heading: q_164244, kids: [], sortId: 0, doSort: false}]; }; + F.line = 223; + p_164235.__karaxMarker__ = true; + } + + } + + F.line = 189; + i_164490 = addInt(i_164490, 1); + if (!(((procs_164068 != null ? procs_164068.length : 0) == l_164491))) { + F.line = 190; + failed_assert_impl_15051(makeNimstrLit("/home/genotrance/.choosenim/toolchains/nim-0.20.2/lib/system/iterators.nim(190, 11) `len(a) == L` the length of the seq changed while iterating over it")); + } + + } + } while(false); + } while(false); + F.line = 224; + if (new_stuff_164083.kids != null) { new_stuff_164083.kids.push(c_164228); } else { new_stuff_164083.kids = [c_164228]; }; + F.line = 189; + i_164493 = addInt(i_164493, 1); + if (!(((types_164067 != null ? types_164067.length : 0) == l_164494))) { + F.line = 190; + failed_assert_impl_15051(makeNimstrLit("/home/genotrance/.choosenim/toolchains/nim-0.20.2/lib/system/iterators.nim(190, 11) `len(a) == L` the length of the seq changed while iterating over it")); + } + + } + } while(false); + } while(false); + F.line = 225; + result_164069 = merge_tocs_164017(orig_164065, new_stuff_164083); + framePtr = F.prev; + + return result_164069; + +} + +function add_163085(parent_163087, kid_163088) { + var Tmp1; + var Tmp2; + + var F={procname:"dochack.add",prev:framePtr,filename:"dochack.nim",line:0}; + framePtr = F; + if (!(parent_163087.nodeName == "TR")) Tmp1 = false; else { if ((kid_163088.nodeName == "TD")) Tmp2 = true; else { Tmp2 = (kid_163088.nodeName == "TH"); } Tmp1 = Tmp2; } if (Tmp1) { + F.line = 18; + var k_163089 = document.createElement("TD"); + F.line = 19; + k_163089.appendChild(kid_163088); + F.line = 20; + parent_163087.appendChild(k_163089); + } + else { + F.line = 22; + parent_163087.appendChild(kid_163088); + } + + framePtr = F.prev; + + +} + +function set_class_163103(e_163105, value_163106) { + var F={procname:"dochack.setClass",prev:framePtr,filename:"dochack.nim",line:0}; + framePtr = F; + F.line = 25; + e_163105.setAttribute("class", toJSStr(value_163106)); + framePtr = F.prev; + + +} + +function to_html_163424(x_163426, is_root_163427) { + var Tmp1; + + function HEX3Aanonymous_163467(a_163469, b_163470) { + var Tmp1; + + var result_163471 = 0; + + var F={procname:"toHtml.:anonymous",prev:framePtr,filename:"dochack.nim",line:0}; + framePtr = F; + BeforeRet: do { + if (!!((a_163469.heading == null))) Tmp1 = false; else { Tmp1 = !((b_163470.heading == null)); } if (Tmp1) { + F.line = 106; + var x_163488 = a_163469.heading.textContent; + F.line = 107; + var y_163489 = b_163470.heading.textContent; + if ((x_163488 < y_163489)) { + F.line = 108; + result_163471 = -1; + break BeforeRet; + } + + if ((y_163489 < x_163488)) { + F.line = 109; + result_163471 = 1; + break BeforeRet; + } + + F.line = 110; + result_163471 = 0; + break BeforeRet; + } + else { + F.line = 113; + result_163471 = subInt(a_163469.sortId, b_163470.sortId); + break BeforeRet; + } + + } while (false); + framePtr = F.prev; + + return result_163471; + + } + + var result_163428 = null; + + var F={procname:"dochack.toHtml",prev:framePtr,filename:"dochack.nim",line:0}; + framePtr = F; + BeforeRet: do { + if ((x_163426 == null)) { + F.line = 91; + result_163428 = null; + break BeforeRet; + } + + if (((x_163426.kids != null ? x_163426.kids.length : 0) == 0)) { + if ((x_163426.heading == null)) { + F.line = 93; + result_163428 = null; + break BeforeRet; + } + + F.line = 94; + result_163428 = x_163426.heading.cloneNode(true); + break BeforeRet; + } + + F.line = 95; + result_163428 = tree_163020(makeNimstrLit("DIV"), []); + if (!!((x_163426.heading == null))) Tmp1 = false; else { Tmp1 = !(x_163426.heading.hasOwnProperty('__karaxMarker__')); } if (Tmp1) { + F.line = 97; + add_163085(result_163428, x_163426.heading.cloneNode(true)); + } + + F.line = 98; + var ul_163464 = tree_163020(makeNimstrLit("UL"), []); + if (is_root_163427) { + F.line = 100; + set_class_163103(ul_163464, makeNimstrLit("simple simple-toc")); + } + else { + F.line = 102; + set_class_163103(ul_163464, makeNimstrLit("simple")); + } + + if (x_163426.doSort) { + F.line = 104; + x_163426.kids.sort(HEX3Aanonymous_163467); + } + + L2: do { + F.line = 115; + var k_163614 = null; + F.line = 183; + var colontmp__164517 = null; + F.line = 115; + colontmp__164517 = x_163426.kids; + F.line = 185; + var i_164519 = 0; + F.line = 186; + var l_164520 = (colontmp__164517 != null ? colontmp__164517.length : 0); + L3: do { + F.line = 187; + L4: while (true) { + if (!(i_164519 < l_164520)) break L4; + F.line = 115; + k_163614 = colontmp__164517[chckIndx(i_164519, 0, colontmp__164517.length+0-1)-0]; + F.line = 116; + var y_163615 = to_html_163424(k_163614, false); + if (!((y_163615 == null))) { + F.line = 118; + add_163085(ul_163464, tree_163020(makeNimstrLit("LI"), [y_163615])); + } + + F.line = 189; + i_164519 = addInt(i_164519, 1); + if (!(((colontmp__164517 != null ? colontmp__164517.length : 0) == l_164520))) { + F.line = 190; + failed_assert_impl_15051(makeNimstrLit("/home/genotrance/.choosenim/toolchains/nim-0.20.2/lib/system/iterators.nim(190, 11) `len(a) == L` the length of the seq changed while iterating over it")); + } + + } + } while(false); + } while(false); + if (!((ul_163464.childNodes.length == 0))) { + F.line = 119; + add_163085(result_163428, ul_163464); + } + + if ((result_163428.childNodes.length == 0)) { + F.line = 120; + result_163428 = null; + } + + } while (false); + framePtr = F.prev; + + return result_163428; + +} + +function replace_by_id_163172(id_163174, new_tree_163175) { + var F={procname:"dochack.replaceById",prev:framePtr,filename:"dochack.nim",line:0}; + framePtr = F; + F.line = 32; + var x_163176 = document.getElementById(id_163174); + F.line = 33; + x_163176.parentNode.replaceChild(new_tree_163175, x_163176); + F.line = 34; + new_tree_163175.id = id_163174; + framePtr = F.prev; + + +} + +function togglevis_164329(d_164331) { + var F={procname:"dochack.togglevis",prev:framePtr,filename:"dochack.nim",line:0}; + framePtr = F; + F.line = 230; + if (d_164331.style.display == 'none') + d_164331.style.display = 'inline'; + else + d_164331.style.display = 'none'; + + framePtr = F.prev; + + +} + +function groupBy(value_164347) { + var F={procname:"dochack.groupBy",prev:framePtr,filename:"dochack.nim",line:0}; + framePtr = F; + F.line = 238; + var toc_164348 = document.getElementById("toc-list"); + if ((alternative_164315[0] == null)) { + F.line = 240; + var tt_164367 = {heading: null, kids: [], sortId: 0, doSort: false}; + F.line = 241; + to_toc_163688(toc_164348, tt_164367); + F.line = 242; + tt_164367 = tt_164367.kids[chckIndx(0, 0, tt_164367.kids.length+0-1)-0]; + F.line = 244; + var types_164382 = [[]]; + F.line = 245; + var procs_164397 = [[]]; + F.line = 247; + extract_items_163339(tt_164367, "Types", types_164382, 0); + F.line = 248; + extract_items_163339(tt_164367, "Procs", procs_164397, 0); + F.line = 249; + extract_items_163339(tt_164367, "Converters", procs_164397, 0); + F.line = 250; + extract_items_163339(tt_164367, "Methods", procs_164397, 0); + F.line = 251; + extract_items_163339(tt_164367, "Templates", procs_164397, 0); + F.line = 252; + extract_items_163339(tt_164367, "Macros", procs_164397, 0); + F.line = 253; + extract_items_163339(tt_164367, "Iterators", procs_164397, 0); + F.line = 255; + var ntoc_164405 = build_toc_164063(tt_164367, types_164382[0], procs_164397[0]); + F.line = 256; + var x_164406 = to_html_163424(ntoc_164405, true); + F.line = 257; + alternative_164315[0] = tree_163020(makeNimstrLit("DIV"), [x_164406]); + } + + if ((value_164347 == "type")) { + F.line = 259; + replace_by_id_163172("tocRoot", alternative_164315[0]); + } + else { + F.line = 261; + replace_by_id_163172("tocRoot", tree_163020(makeNimstrLit("DIV"), [])); + } + + F.line = 262; + togglevis_164329(document.getElementById("toc-list")); + framePtr = F.prev; + + +} +var db_164523 = [null]; +var contents_164525 = [null]; +var oldtoc_164959 = [null]; +var timer_164960 = [null]; + +function raiseRangeError() { + var e_22441 = null; + e_22441 = {m_type: NTI4062, parent: null, name: null, message: null, trace: null, raiseId: 0, up: null}; + e_22441.message = nimCopy(null, makeNimstrLit("value out of range"), NTI138); + e_22441.parent = null; + raiseException(e_22441, "RangeError"); + + +} + +function nsuToLowerAsciiChar(c_151780) { + var result_151781 = 0; + + var F={procname:"strutils.toLowerAscii",prev:framePtr,filename:"strutils.nim",line:0}; + framePtr = F; + if ((ConstSet2[c_151780] != undefined)) { + F.line = 222; + result_151781 = chckRange(addInt(c_151780, 32), 0, 255); + } + else { + F.line = 224; + result_151781 = c_151780; + } + + framePtr = F.prev; + + return result_151781; + +} + +function fuzzy_match_162070(pattern_162072, str_162073) { + var Tmp4; + var Tmp5; + var Tmp6; + + var result_162077 = {Field0: 0, Field1: false}; + + var F={procname:"fuzzysearch.fuzzyMatch",prev:framePtr,filename:"fuzzysearch.nim",line:0}; + framePtr = F; + F.line = 37; + var score_state_162078 = -100; + F.line = 38; + var header_matched_162079 = false; + F.line = 39; + var unmatched_leading_char_count_162081 = 0; + F.line = 40; + var consecutive_match_count_162083 = 0; + F.line = 41; + var str_index_162085 = 0; + F.line = 42; + var pat_index_162087 = 0; + F.line = 43; + var score_162089 = 0; + L1: do { + F.line = 49; + L2: while (true) { + if (!((str_index_162085 < (str_162073 != null ? str_162073.length : 0)) && (pat_index_162087 < (pattern_162072 != null ? pattern_162072.length : 0)))) break L2; + L3: do { + F.line = 51; + var pattern_char_162095 = nsuToLowerAsciiChar(pattern_162072.charCodeAt(chckIndx(pat_index_162087, 0, pattern_162072.length+0-1)-0)); + F.line = 52; + var str_char_162096 = nsuToLowerAsciiChar(str_162073.charCodeAt(chckIndx(str_index_162085, 0, str_162073.length+0-1)-0)); + if ((ConstSet3[pattern_char_162095] != undefined)) { + F.line = 56; + pat_index_162087 = addInt(pat_index_162087, 1); + F.line = 57; + break L3; + } + + if ((ConstSet4[str_char_162096] != undefined)) { + F.line = 59; + str_index_162085 = addInt(str_index_162085, 1); + F.line = 60; + break L3; + } + + if ((!(header_matched_162079) && (str_char_162096 == 58))) { + F.line = 65; + header_matched_162079 = true; + F.line = 66; + score_state_162078 = -100; + F.line = 67; + score_162089 = Math.trunc(Math.floor((5.0000000000000000e-01 * score_162089))); + F.line = 68; + pat_index_162087 = 0; + F.line = 69; + str_index_162085 = addInt(str_index_162085, 1); + F.line = 70; + break L3; + } + + if ((str_char_162096 == pattern_char_162095)) { + F.line = 73; + switch (score_state_162078) { + case -100: + case 20: + F.line = 75; + score_state_162078 = 10; + break; + case 0: + F.line = 78; + score_state_162078 = 5; + F.line = 78; + score_162089 = addInt(score_162089, score_state_162078); + break; + case 10: + case 5: + F.line = 81; + consecutive_match_count_162083 = addInt(consecutive_match_count_162083, 1); + F.line = 82; + score_state_162078 = 5; + F.line = 83; + score_162089 = addInt(score_162089, mulInt(5, consecutive_match_count_162083)); + if ((score_state_162078 == 10)) { + F.line = 86; + score_162089 = addInt(score_162089, 10); + } + + F.line = 88; + var on_boundary_162171 = (pat_index_162087 == (pattern_162072 != null ? (pattern_162072.length-1) : -1)); + if ((!(on_boundary_162171) && (str_index_162085 < (str_162073 != null ? (str_162073.length-1) : -1)))) { + F.line = 91; + var next_pattern_char_162172 = nsuToLowerAsciiChar(pattern_162072.charCodeAt(chckIndx(addInt(pat_index_162087, 1), 0, pattern_162072.length+0-1)-0)); + F.line = 92; + var next_str_char_162173 = nsuToLowerAsciiChar(str_162073.charCodeAt(chckIndx(addInt(str_index_162085, 1), 0, str_162073.length+0-1)-0)); + F.line = 95; + if (!!((ConstSet5[next_str_char_162173] != undefined))) Tmp4 = false; else { Tmp4 = !((next_str_char_162173 == next_pattern_char_162172)); } on_boundary_162171 = Tmp4; + } + + if (on_boundary_162171) { + F.line = 100; + score_state_162078 = 20; + F.line = 100; + score_162089 = addInt(score_162089, score_state_162078); + } + + break; + case -1: + case -3: + F.line = 103; + if (!((ConstSet6[str_162073.charCodeAt(chckIndx(subInt(str_index_162085, 1), 0, str_162073.length+0-1)-0)] != undefined))) Tmp5 = true; else { if (!(ConstSet7[str_162073.charCodeAt(chckIndx(subInt(str_index_162085, 1), 0, str_162073.length+0-1)-0)] != undefined)) Tmp6 = false; else { Tmp6 = (ConstSet8[str_162073.charCodeAt(chckIndx(str_index_162085, 0, str_162073.length+0-1)-0)] != undefined); } Tmp5 = Tmp6; } var is_leading_char_162211 = Tmp5; + if (is_leading_char_162211) { + F.line = 110; + score_state_162078 = 10; + } + else { + F.line = 114; + score_state_162078 = 0; + F.line = 114; + score_162089 = addInt(score_162089, score_state_162078); + } + + break; + } + F.line = 115; + pat_index_162087 = addInt(pat_index_162087, 1); + } + else { + F.line = 118; + switch (score_state_162078) { + case -100: + F.line = 120; + score_state_162078 = -3; + F.line = 120; + score_162089 = addInt(score_162089, score_state_162078); + break; + case 5: + F.line = 123; + score_state_162078 = -1; + F.line = 123; + score_162089 = addInt(score_162089, score_state_162078); + F.line = 124; + consecutive_match_count_162083 = 0; + break; + case -3: + if ((unmatched_leading_char_count_162081 < 3)) { + F.line = 128; + score_state_162078 = -3; + F.line = 128; + score_162089 = addInt(score_162089, score_state_162078); + } + + F.line = 129; + unmatched_leading_char_count_162081 = addInt(unmatched_leading_char_count_162081, 1); + break; + default: + F.line = 132; + score_state_162078 = -1; + F.line = 132; + score_162089 = addInt(score_162089, score_state_162078); + break; + } + } + + F.line = 134; + str_index_162085 = addInt(str_index_162085, 1); + } while(false); + } + } while(false); + F.line = 137; + var colontmp__165063 = nimMax(0, score_162089); + F.line = 138; + var colontmp__165064 = (0 < score_162089); + F.line = 136; + nimCopy(result_162077, {Field0: colontmp__165063, Field1: colontmp__165064}, NTI162074); + framePtr = F.prev; + + return result_162077; + +} + +function text_163120(s_163122) { + var result_163123 = null; + + var F={procname:"dochack.text",prev:framePtr,filename:"dochack.nim",line:0}; + framePtr = F; + F.line = 26; + result_163123 = document.createTextNode(toJSStr(s_163122)); + framePtr = F.prev; + + return result_163123; + +} + +function dosearch_164557(value_164559) { + + function HEX3Aanonymous_164871(a_164880, b_164881) { + var result_164885 = 0; + + var F={procname:"dosearch.:anonymous",prev:framePtr,filename:"dochack.nim",line:0}; + framePtr = F; + F.line = 305; + result_164885 = subInt(b_164881["Field1"], a_164880["Field1"]); + framePtr = F.prev; + + return result_164885; + + } + + var result_164560 = null; + + var F={procname:"dochack.dosearch",prev:framePtr,filename:"dochack.nim",line:0}; + framePtr = F; + if (((db_164523[0] != null ? db_164523[0].length : 0) == 0)) { + F.line = 272; + var stuff_164566 = null; + F.line = 273; + var request = new XMLHttpRequest(); + request.open("GET", "theindex.html", false); + request.send(null); + + var doc = document.implementation.createHTMLDocument("theindex"); + doc.documentElement.innerHTML = request.responseText; + + //parser=new DOMParser(); + //doc=parser.parseFromString("", "text/html"); + + stuff_164566 = doc.documentElement; + + F.line = 286; + db_164523[0] = nimCopy(null, stuff_164566.getElementsByClassName("reference"), NTI44305); + F.line = 287; + contents_164525[0] = nimCopy(null, [], NTI164579); + L1: do { + F.line = 288; + var ahref_164814 = null; + F.line = 185; + var i_165043 = 0; + F.line = 186; + var l_165044 = (db_164523[0] != null ? db_164523[0].length : 0); + L2: do { + F.line = 187; + L3: while (true) { + if (!(i_165043 < l_165044)) break L3; + F.line = 288; + ahref_164814 = db_164523[0][chckIndx(i_165043, 0, db_164523[0].length+0-1)-0]; + F.line = 289; + if (contents_164525[0] != null) { contents_164525[0].push(ahref_164814.getAttribute("data-doc-search-tag")); } else { contents_164525[0] = [ahref_164814.getAttribute("data-doc-search-tag")]; }; + F.line = 189; + i_165043 = addInt(i_165043, 1); + if (!(((db_164523[0] != null ? db_164523[0].length : 0) == l_165044))) { + F.line = 190; + failed_assert_impl_15051(makeNimstrLit("/home/genotrance/.choosenim/toolchains/nim-0.20.2/lib/system/iterators.nim(190, 11) `len(a) == L` the length of the seq changed while iterating over it")); + } + + } + } while(false); + } while(false); + } + + F.line = 290; + var ul_164825 = tree_163020(makeNimstrLit("UL"), []); + F.line = 291; + result_164560 = tree_163020(makeNimstrLit("DIV"), []); + F.line = 292; + set_class_163103(result_164560, makeNimstrLit("search_results")); + F.line = 293; + var matches_164844 = []; + L4: do { + F.line = 294; + var i_164857 = 0; + F.line = 2716; + var colontmp__165050 = 0; + F.line = 294; + colontmp__165050 = (db_164523[0] != null ? db_164523[0].length : 0); + F.line = 2717; + var i_165051 = 0; + L5: do { + F.line = 2718; + L6: while (true) { + if (!(i_165051 < colontmp__165050)) break L6; + F.line = 294; + i_164857 = i_165051; + L7: do { + F.line = 295; + var c_164858 = contents_164525[0][chckIndx(i_164857, 0, contents_164525[0].length+0-1)-0]; + if (((c_164858 == "Examples") || (c_164858 == "PEG construction"))) { + F.line = 300; + break L7; + } + + F.line = 301; + var colontmp__165060 = {Field0: 0, Field1: false}; + F.line = 301; + var score_164859 = 0; + F.line = 301; + var matched_164860 = false; + F.line = 301; + nimCopy(colontmp__165060, fuzzy_match_162070(value_164559, c_164858), NTI162074); + F.line = 301; + score_164859 = colontmp__165060["Field0"]; + F.line = 301; + matched_164860 = colontmp__165060["Field1"]; + if (matched_164860) { + F.line = 303; + if (matches_164844 != null) { matches_164844.push({Field0: db_164523[0][chckIndx(i_164857, 0, db_164523[0].length+0-1)-0], Field1: score_164859}); } else { matches_164844 = [{Field0: db_164523[0][chckIndx(i_164857, 0, db_164523[0].length+0-1)-0], Field1: score_164859}]; }; + } + + } while(false); + F.line = 2720; + i_165051 = addInt(i_165051, 1); + } + } while(false); + } while(false); + F.line = 305; + matches_164844.sort(HEX3Aanonymous_164871); + L8: do { + F.line = 306; + var i_164924 = 0; + F.line = 2716; + var colontmp__165056 = 0; + F.line = 306; + colontmp__165056 = nimMin((matches_164844 != null ? matches_164844.length : 0), 19); + F.line = 2717; + var i_165057 = 0; + L9: do { + F.line = 2718; + L10: while (true) { + if (!(i_165057 < colontmp__165056)) break L10; + F.line = 306; + i_164924 = i_165057; + F.line = 307; + matches_164844[chckIndx(i_164924, 0, matches_164844.length+0-1)-0]["Field0"].innerHTML = matches_164844[chckIndx(i_164924, 0, matches_164844.length+0-1)-0]["Field0"].getAttribute("data-doc-search-tag"); + F.line = 308; + add_163085(ul_164825, tree_163020(makeNimstrLit("LI"), [matches_164844[chckIndx(i_164924, 0, matches_164844.length+0-1)-0]["Field0"]])); + F.line = 2720; + i_165057 = addInt(i_165057, 1); + } + } while(false); + } while(false); + if ((ul_164825.childNodes.length == 0)) { + F.line = 310; + add_163085(result_164560, tree_163020(makeNimstrLit("B"), [text_163120(makeNimstrLit("no search results"))])); + } + else { + F.line = 312; + add_163085(result_164560, tree_163020(makeNimstrLit("B"), [text_163120(makeNimstrLit("search results"))])); + F.line = 313; + add_163085(result_164560, ul_164825); + } + + framePtr = F.prev; + + return result_164560; + +} + +function search() { + + function wrapper_164991() { + var F={procname:"search.wrapper",prev:framePtr,filename:"dochack.nim",line:0}; + framePtr = F; + F.line = 320; + var elem_164993 = document.getElementById("searchInput"); + F.line = 321; + var value_164994 = elem_164993.value; + if (!(((value_164994 != null ? value_164994.length : 0) == 0))) { + if ((oldtoc_164959[0] == null)) { + F.line = 324; + oldtoc_164959[0] = document.getElementById("tocRoot"); + } + + F.line = 325; + var results_165000 = dosearch_164557(value_164994); + F.line = 326; + replace_by_id_163172("tocRoot", results_165000); + } + else { + if (!((oldtoc_164959[0] == null))) { + F.line = 328; + replace_by_id_163172("tocRoot", oldtoc_164959[0]); + } + } + framePtr = F.prev; + + + } + + var F={procname:"dochack.search",prev:framePtr,filename:"dochack.nim",line:0}; + framePtr = F; + if (!((timer_164960[0] == null))) { + F.line = 330; + clearTimeout(timer_164960[0]); + } + + F.line = 331; + timer_164960[0] = setTimeout(wrapper_164991, 400); + framePtr = F.prev; + + +} diff --git a/git.html b/git.html index 78b555f..a78d383 100644 --- a/git.html +++ b/git.html @@ -27,232 +27,130 @@ customize this style sheet. Modified from Chad Skeeters' rst2html-style https://bitbucket.org/cskeeters/rst2html-style/ -Modified by Boyd Greenfield +Modified by Boyd Greenfield and narimiran */ -/* SCSS variables */ -/* Text weights */ -/* Body colors */ -/* Text colors */ -/* Link colors */ -/* Syntax highlighting colors */ -/* Pct changes */ -/* Mixins */ -/* Body/layout */ + html { font-size: 100%; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; } -/* Where we want fancier font if available */ -h1, h2, h3, h4, h5, h6, p.module-desc, table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; } - -h1.title { - font-weight: 900; } - body { font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: 400; - font-size: 16px; - line-height: 20px; - color: #444; - letter-spacing: 0.15px; - background-color: #FDFBFA; } + font-size: 1.125em; + line-height: 1.5; + color: #222; + background-color: #FCFCFC; } /* Skeleton grid */ .container { position: relative; width: 100%; - max-width: 960px; + max-width: 1050px; margin: 0 auto; - padding: 0 20px; + padding: 0; box-sizing: border-box; } .column, .columns { width: 100%; float: left; - box-sizing: border-box; } + box-sizing: border-box; + margin-left: 1%; +} -/* For devices larger than 400px */ -@media (min-width: 400px) { - .container { - width: 100%; - padding: 0; } } -/* For devices larger than 650px */ -@media (min-width: 650px) { - .container { - width: 100%; } +.column:first-child, +.columns:first-child { + margin-left: 0; } - .column, - .columns { - margin-left: 4%; } +.three.columns { + width: 19%; } - .column:first-child, - .columns:first-child { - margin-left: 0; } +.nine.columns { + width: 80.0%; } - .one.column, - .one.columns { - width: 4.66666666667%; } - - .two.columns { - width: 13.3333333333%; } +.twelve.columns { + width: 100%; + margin-left: 0; } +@media screen and (max-width: 860px) { .three.columns { - width: 22%; } - - .four.columns { - width: 30.6666666667%; } - - .five.columns { - width: 39.3333333333%; } - - .six.columns { - width: 48%; } - - .seven.columns { - width: 56.6666666667%; } - - .eight.columns { - width: 65.3333333333%; } - + display: none; + } .nine.columns { - width: 74.0%; } - - .ten.columns { - width: 82.6666666667%; } - - .eleven.columns { - width: 91.3333333333%; } - - .twelve.columns { - width: 100%; - margin-left: 0; } - - .one-third.column { - width: 30.6666666667%; } - - .two-thirds.column { - width: 65.3333333333%; } } -/* Customer Overrides */ -.footer { - text-align: center; - color: #969696; - padding-top: 10%; } - -p.module-desc { - font-size: 1.1em; - color: #666666; } - -a.link-seesrc { - color: #aec7d2; - font-style: italic; } - -a.link-seesrc:hover { - color: #6c9aae; } - -#toc-list { - word-wrap: break-word; } - -ul.simple-toc { - list-style: none; } - -ul.simple-toc a.reference-toplevel { - font-weight: bold; - color: #0077b3; } - -ul.simple-toc-section { - list-style-type: circle; - color: #6c9aae; } - -ul.simple-toc-section a.reference { - color: #0077b3; } + width: 98.0%; + } + body { + font-size: 1em; + line-height: 1.35; + } +} cite { font-style: italic !important; } -dt > pre { - border-color: rgba(0, 0, 0, 0.1); - background-color: rgba(255, 255, 255, 0.3); - margin: 15px 0px 5px; } - -dd > pre { - border-color: rgba(0, 0, 0, 0.1); - background-color: whitesmoke; - margin-top: 8px; } - -.item > dd { - margin-left: 10px; - margin-bottom: 30px; } - -/* Nim line-numbered tables */ -.line-nums-table { - width: 100%; - table-layout: fixed; } /* Nim search input */ div#searchInputDiv { - margin-bottom: 8px; + margin-bottom: 1em; } -div#searchInputDiv input#searchInput { - width: 10em; -} -div.search-groupby { - margin-bottom: 8px; +input#searchInput { + width: 80%; } -table.line-nums-table { - border-radius: 4px; - border: 1px solid #cccccc; - background-color: whitesmoke; - border-collapse: separate; - margin-top: 15px; - margin-bottom: 25px; } - -.line-nums-table tbody { - border: none; } - -.line-nums-table td pre { - border: none; - background-color: transparent; } - -.line-nums-table td.blob-line-nums { - width: 28px; } - -.line-nums-table td.blob-line-nums pre { - color: #b0b0b0; - -webkit-filter: opacity(75%); - text-align: right; - border-color: transparent; - background-color: transparent; - padding-left: 0px; - margin-left: 0px; - padding-right: 0px; - margin-right: 0px; } +/* + * Some custom formatting for input forms. + * This also fixes input form colors on Firefox with a dark system theme on Linux. + */ +input { + -moz-appearance: none; + color: #333; + background-color: #f8f8f8; + border: 1px solid #aaa; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-size: 0.9em; + padding: 6px; +} +input:focus { + border: 1px solid #1fa0eb; + box-shadow: 0 0 2px #1fa0eb; +} /* Docgen styles */ /* Links */ a { - color: #0077b3; - text-decoration: none; } + color: #07b; + text-decoration: none; +} + +a span.Identifier { + text-decoration: underline; + text-decoration-color: #aab; +} + +a.reference-toplevel { + font-weight: bold; +} + +a.toc-backref { + text-decoration: none; + color: #222; } + +a.link-seesrc { + color: #607c9f; + font-size: 0.9em; + font-style: italic; } a:hover, a:focus { - color: #00334d; + color: #607c9f; text-decoration: underline; } -a:visited { - color: #00334d; } +a:hover span.Identifier { + color: #607c9f; +} -a:focus { - outline: thin dotted #2d2d2d; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; } - -a:hover, -a:active { - outline: 0; } sub, sup { @@ -329,379 +227,258 @@ img { h2, h3 { - page-break-after: avoid; } } -.img-rounded { - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; } + page-break-after: avoid; } +} -.img-polaroid { - padding: 4px; - background-color: rgba(252, 248, 244, 0.75); - border: 1px solid #ccc; - border: 1px solid rgba(0, 0, 0, 0.2); - -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); - -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); } p { - margin: 0 0 8px; } + margin-top: 0.5em; + margin-bottom: 0.5em; +} small { font-size: 85%; } strong { - font-weight: 600; } + font-weight: 600; + font-size: 0.95em; + color: #3c3c3c; +} em { font-style: italic; } -cite { - font-style: normal; } - -h1, -h2, -h3, -h4, -h5, -h6 { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-weight: 600; - line-height: 20px; - color: inherit; - text-rendering: optimizelegibility; } - h1 { - font-size: 2em; + font-size: 1.8em; font-weight: 400; - padding-bottom: .15em; - border-bottom: 1px solid #aaaaaa; - margin-top: 1.0em; + padding-bottom: .25em; + border-bottom: 1px solid #aaa; + margin-top: 2.5em; + margin-bottom: 1em; line-height: 1.2em; } h1.title { padding-bottom: 1em; border-bottom: 0px; - font-size: 2.75em; } + font-size: 2.5em; + text-align: center; + font-weight: 900; + margin-top: 0.75em; + margin-bottom: 0em; +} h2 { - font-size: 1.5em; - margin-top: 1.5em; } + font-size: 1.3em; + margin-top: 2em; } + +h2.subtitle { + text-align: center; } h3 { - font-size: 1.3em; + font-size: 1.125em; font-style: italic; - margin-top: 0.75em; } + margin-top: 1.5em; } h4 { - font-size: 1.3em; - margin-top: 0.5em; } + font-size: 1.125em; + margin-top: 1em; } h5 { - font-size: 1.2em; - margin-top: 0.25em; } + font-size: 1.125em; + margin-top: 0.75em; } h6 { font-size: 1.1em; } + ul, ol { padding: 0; - margin: 0 0 0px 15px; } + margin-top: 0.5em; + margin-left: 0.75em; } ul ul, ul ol, ol ol, ol ul { - margin-bottom: 0; } + margin-bottom: 0; + margin-left: 1.25em; } li { - line-height: 20px; } - -dl { - margin-bottom: 20px; } - -dt, -dd { - line-height: 20px; } - -dt { - font-weight: bold; } - -dd { - margin-left: 10px; - margin-bottom: 26px; } - -hr { - margin: 20px 0; - border: 0; - border-top: 1px solid #eeeeee; - border-bottom: 1px solid #ffffff; } - -abbr[title], -abbr[data-original-title] { - cursor: help; - border-bottom: 1px dotted #999999; } - -abbr.initialism { - font-size: 90%; - text-transform: uppercase; } - -blockquote { - padding: 0 0 0 15px; - margin: 0 0 20px; - border-left: 5px solid #EFEBE0; } - -table.docinfo + blockquote, table.docinfo blockquote, h1 + blockquote { - border-left: 5px solid #c9c9c9; + list-style-type: circle; } -table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { - margin-bottom: 0; - font-size: 15px; - font-weight: 200; - line-height: 1.5; - font-style: italic; } +ul.simple-boot li { + list-style-type: none; + margin-left: 0em; + margin-bottom: 0.5em; +} -q:before, -q:after, -blockquote:before, -blockquote:after { - content: ""; } +ol.simple > li, ul.simple > li { + margin-bottom: 0.25em; + margin-left: 0.4em } -address { - display: block; - margin-bottom: 20px; - font-style: normal; - line-height: 20px; } +ul.simple.simple-toc > li { + margin-top: 1em; +} -code, -pre { - font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - padding: 0 3px 2px; - font-weight: 500; - font-size: 12px; - color: #444444; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; } +ul.simple-toc { + list-style: none; + font-size: 0.9em; + margin-left: -0.3em; + margin-top: 1em; } + +ul.simple-toc > li { + list-style-type: none; +} + +ul.simple-toc-section { + list-style-type: circle; + margin-left: 1em; + color: #6c9aae; } + + +ol.arabic { + list-style: decimal; } + +ol.loweralpha { + list-style: lower-alpha; } + +ol.upperalpha { + list-style: upper-alpha; } + +ol.lowerroman { + list-style: lower-roman; } + +ol.upperroman { + list-style: upper-roman; } + +ul.auto-toc { + list-style-type: none; } + + +dl { + margin-bottom: 1.5em; } + +dt { + margin-bottom: -0.5em; + margin-left: 0.0em; } + +dd { + margin-left: 2.0em; + margin-bottom: 3.0em; + margin-top: 0.5em; } + + +hr { + margin: 2em 0; + border: 0; + border-top: 1px solid #aaa; } + +blockquote { + font-size: 0.9em; + font-style: italic; + padding-left: 0.5em; + margin-left: 0; + border-left: 5px solid #bbc; +} .pre { font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - font-weight: 600; - /*color: #504da6;*/ + font-weight: 500; + font-size: 0.85em; + background-color: #f0f3ff; + padding-left: 3px; + padding-right: 3px; + border-radius: 4px; } -code { - padding: 2px 4px; - color: #444444; - white-space: nowrap; - background-color: white; - border: 1px solid #777777; } - pre { + font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; + color: #222; + font-weight: 500; display: inline-block; box-sizing: border-box; - min-width: calc(100% - 19.5px); - padding: 9.5px; - margin: 0.25em 10px 10px 10px; - font-size: 15px; - line-height: 20px; + min-width: 100%; + padding: 0.5em; + margin-top: 0.5em; + margin-bottom: 0.5em; + font-size: 0.85em; white-space: pre !important; overflow-y: hidden; overflow-x: visible; - background-color: rgba(0, 0, 0, 0.01); - border: 1px solid #cccccc; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; } - -pre.prettyprint { - margin-bottom: 20px; } - -pre code { - padding: 0; - color: inherit; - white-space: pre; - overflow-x: visible; - background-color: transparent; - border: 0; } + background-color: ghostwhite; + border: 1px solid #dde; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; } .pre-scrollable { max-height: 340px; overflow-y: scroll; } + +/* Nim line-numbered tables */ +.line-nums-table { + width: 100%; + table-layout: fixed; } + +table.line-nums-table { + border-radius: 4px; + border: 1px solid #cccccc; + background-color: ghostwhite; + border-collapse: separate; + margin-top: 15px; + margin-bottom: 25px; } + +.line-nums-table tbody { + border: none; } + +.line-nums-table td pre { + border: none; + background-color: transparent; } + +.line-nums-table td.blob-line-nums { + width: 28px; } + +.line-nums-table td.blob-line-nums pre { + color: #b0b0b0; + -webkit-filter: opacity(75%); + text-align: right; + border-color: transparent; + background-color: transparent; + padding-left: 0px; + margin-left: 0px; + padding-right: 0px; + margin-right: 0px; } + + table { max-width: 100%; background-color: transparent; + margin-top: 0.5em; + margin-bottom: 1.5em; border-collapse: collapse; - border-spacing: 0; } - -table th, table td { - padding: 0px 8px 0px; + border-color: #ccc; + border-spacing: 0; + font-size: 0.9em; } -.table { - width: 100%; - margin-bottom: 20px; } +table th, table td { + padding: 0px 0.5em 0px; +} -.table th, -.table td { - padding: 8px; - line-height: 20px; - text-align: left; - vertical-align: top; - border-top: 1px solid #444444; } - -.table th { +table th { + background-color: #e8e8e8; font-weight: bold; } -.table thead th { - vertical-align: bottom; } +table th.docinfo-name { + background-color: transparent; +} -.table caption + thead tr:first-child th, -.table caption + thead tr:first-child td, -.table colgroup + thead tr:first-child th, -.table colgroup + thead tr:first-child td, -.table thead:first-child tr:first-child th, -.table thead:first-child tr:first-child td { - border-top: 0; } +table tr:hover { + background-color: ghostwhite; } -.table tbody + tbody { - border-top: 2px solid #444444; } - -.table .table { - background-color: rgba(252, 248, 244, 0.75); } - -.table-condensed th, -.table-condensed td { - padding: 4px 5px; } - -.table-bordered { - border: 1px solid #444444; - border-collapse: separate; - *border-collapse: collapse; - border-left: 0; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; } - -.table-bordered th, -.table-bordered td { - border-left: 1px solid #444444; } - -.table-bordered caption + thead tr:first-child th, -.table-bordered caption + tbody tr:first-child th, -.table-bordered caption + tbody tr:first-child td, -.table-bordered colgroup + thead tr:first-child th, -.table-bordered colgroup + tbody tr:first-child th, -.table-bordered colgroup + tbody tr:first-child td, -.table-bordered thead:first-child tr:first-child th, -.table-bordered tbody:first-child tr:first-child th, -.table-bordered tbody:first-child tr:first-child td { - border-top: 0; } - -.table-bordered thead:first-child tr:first-child > th:first-child, -.table-bordered tbody:first-child tr:first-child > td:first-child, -.table-bordered tbody:first-child tr:first-child > th:first-child { - -webkit-border-top-left-radius: 4px; - border-top-left-radius: 4px; - -moz-border-radius-topleft: 4px; } - -.table-bordered thead:first-child tr:first-child > th:last-child, -.table-bordered tbody:first-child tr:first-child > td:last-child, -.table-bordered tbody:first-child tr:first-child > th:last-child { - -webkit-border-top-right-radius: 4px; - border-top-right-radius: 4px; - -moz-border-radius-topright: 4px; } - -.table-bordered thead:last-child tr:last-child > th:first-child, -.table-bordered tbody:last-child tr:last-child > td:first-child, -.table-bordered tbody:last-child tr:last-child > th:first-child, -.table-bordered tfoot:last-child tr:last-child > td:first-child, -.table-bordered tfoot:last-child tr:last-child > th:first-child { - -webkit-border-bottom-left-radius: 4px; - border-bottom-left-radius: 4px; - -moz-border-radius-bottomleft: 4px; } - -.table-bordered thead:last-child tr:last-child > th:last-child, -.table-bordered tbody:last-child tr:last-child > td:last-child, -.table-bordered tbody:last-child tr:last-child > th:last-child, -.table-bordered tfoot:last-child tr:last-child > td:last-child, -.table-bordered tfoot:last-child tr:last-child > th:last-child { - -webkit-border-bottom-right-radius: 4px; - border-bottom-right-radius: 4px; - -moz-border-radius-bottomright: 4px; } - -.table-bordered tfoot + tbody:last-child tr:last-child td:first-child { - -webkit-border-bottom-left-radius: 0; - border-bottom-left-radius: 0; - -moz-border-radius-bottomleft: 0; } - -.table-bordered tfoot + tbody:last-child tr:last-child td:last-child { - -webkit-border-bottom-right-radius: 0; - border-bottom-right-radius: 0; - -moz-border-radius-bottomright: 0; } - -.table-bordered caption + thead tr:first-child th:first-child, -.table-bordered caption + tbody tr:first-child td:first-child, -.table-bordered colgroup + thead tr:first-child th:first-child, -.table-bordered colgroup + tbody tr:first-child td:first-child { - -webkit-border-top-left-radius: 4px; - border-top-left-radius: 4px; - -moz-border-radius-topleft: 4px; } - -.table-bordered caption + thead tr:first-child th:last-child, -.table-bordered caption + tbody tr:first-child td:last-child, -.table-bordered colgroup + thead tr:first-child th:last-child, -.table-bordered colgroup + tbody tr:first-child td:last-child { - -webkit-border-top-right-radius: 4px; - border-top-right-radius: 4px; - -moz-border-radius-topright: 4px; } - -table.docutils th { - background-color: #e8e8e8; } - -table.docutils tr:hover { - background-color: whitesmoke; } - -.table-striped tbody > tr:nth-child(odd) > td, -.table-striped tbody > tr:nth-child(odd) > th { - background-color: rgba(252, 248, 244, 0.75); } - -.table-hover tbody tr:hover > td, -.table-hover tbody tr:hover > th { - background-color: rgba(241, 222, 204, 0.75); } - -table td[class*="span"], -table th[class*="span"], -.row-fluid table td[class*="span"], -.row-fluid table th[class*="span"] { - display: table-cell; - float: none; - margin-left: 0; } - -.hero-unit { - padding: 60px; - margin-bottom: 30px; - font-size: 18px; - font-weight: 200; - line-height: 30px; - color: inherit; - background-color: rgba(230, 197, 164, 0.75); - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; } - -.hero-unit h1 { - margin-bottom: 0; - font-size: 60px; - line-height: 1; - letter-spacing: -1px; - color: inherit; } - -.hero-unit li { - line-height: 30px; } /* rst2html default used to remove borders from tables and images */ .borderless, table.borderless td, table.borderless th { @@ -722,10 +499,6 @@ table.borderless td, table.borderless th { .hidden { display: none; } -a.toc-backref { - text-decoration: none; - color: #444444; } - blockquote.epigraph { margin: 2em 5em; } @@ -735,85 +508,6 @@ dl.docutils dd { object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] { overflow: hidden; } -/* Uncomment (and remove this text!) to get bold-faced definition list terms -dl.docutils dt { - font-weight: bold } -*/ -div.abstract { - margin: 2em 5em; } - -div.abstract p.topic-title { - font-weight: bold; - text-align: center; } - -div.admonition, div.attention, div.caution, div.danger, div.error, -div.hint, div.important, div.note, div.tip, div.warning { - margin: 2em; - border: medium outset; - padding: 1em; } - -div.note, div.warning { - margin: 1.5em 0px; - border: none; } - -div.note p.admonition-title, -div.warning p.admonition-title { - display: none; } - -/* Clearfix - * http://css-tricks.com/snippets/css/clear-fix/ - */ -div.note:after, -div.warning:after { - content: ""; - display: table; - clear: both; } - -div.note p:before, -div.warning p:before { - display: block; - float: left; - font-size: 4em; - line-height: 1em; - margin-right: 20px; - margin-left: 0em; - margin-top: -10px; - content: '\0270D'; - /*handwriting*/ } - -div.warning p:before { - content: '\026A0'; - /*warning*/ } - -div.admonition p.admonition-title, div.hint p.admonition-title, -div.important p.admonition-title, div.note p.admonition-title, -div.tip p.admonition-title { - font-weight: bold; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } - -div.attention p.admonition-title, div.caution p.admonition-title, -div.danger p.admonition-title, div.error p.admonition-title, -div.warning p.admonition-title, .code .error { - color: #b30000; - font-weight: bold; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } - -/* Uncomment (and remove this text!) to get reduced vertical space in - compound paragraphs. -div.compound .compound-first, div.compound .compound-middle { - margin-bottom: 0.5em } - -div.compound .compound-last, div.compound .compound-middle { - margin-top: 0.5em } -*/ -div.dedication { - margin: 2em 5em; - text-align: center; - font-style: italic; } - -div.dedication p.topic-title { - font-weight: bold; - font-style: normal; } div.figure { margin-left: 2em; @@ -821,8 +515,14 @@ div.figure { div.footer, div.header { clear: both; + text-align: center; + color: #666; font-size: smaller; } +div.footer { + padding-top: 5em; +} + div.line-block { display: block; margin-top: 1em; @@ -833,45 +533,24 @@ div.line-block div.line-block { margin-bottom: 0; margin-left: 1.5em; } -div.sidebar { - margin: 0 0 0.5em 1em; - border: medium outset; - padding: 1em; - background-color: rgba(252, 248, 244, 0.75); - width: 40%; - float: right; - clear: right; } - -div.sidebar p.rubric { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-size: medium; } - -div.system-messages { - margin: 5em; } - -div.system-messages h1 { - color: #b30000; } - -div.system-message { - border: medium outset; - padding: 1em; } - -div.system-message p.system-message-title { - color: #b30000; - font-weight: bold; } - div.topic { margin: 2em; } -h1.section-subtitle, h2.section-subtitle, h3.section-subtitle, -h4.section-subtitle, h5.section-subtitle, h6.section-subtitle { - margin-top: 0.4em; } +div.search_results { + background-color: antiquewhite; + margin: 3em; + padding: 1em; + border: 1px solid #4d4d4d; +} -h1.title { - text-align: center; } +div#global-links ul { + margin-left: 0; + list-style-type: none; +} -h2.subtitle { - text-align: center; } +div#global-links > simple-boot { + margin-left: 3em; +} hr.docutils { width: 75%; } @@ -905,30 +584,6 @@ img.align-center, .figure.align-center, object.align-center { div.align-right { text-align: inherit; } -/* div.align-center * { */ -/* text-align: left } */ - -ul.simple > li { - margin-bottom: 0.5em } - -ol.simple, ul.simple { - margin-bottom: 1em; } - -ol.arabic { - list-style: decimal; } - -ol.loweralpha { - list-style: lower-alpha; } - -ol.upperalpha { - list-style: upper-alpha; } - -ol.lowerroman { - list-style: lower-roman; } - -ol.upperroman { - list-style: upper-roman; } - p.attribution { text-align: right; margin-left: 50%; } @@ -949,15 +604,6 @@ p.rubric { color: maroon; text-align: center; } -p.sidebar-title { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-weight: bold; - font-size: larger; } - -p.sidebar-subtitle { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-weight: bold; } - p.topic-title { font-weight: bold; } @@ -997,22 +643,14 @@ pre.code .inserted, code .inserted { background-color: #A3D289; } span.classifier { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-style: oblique; } span.classifier-delimiter { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: bold; } -span.interpreted { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } - span.option { white-space: nowrap; } -span.pre { - white-space: pre; } - span.problematic { color: #b30000; } @@ -1020,44 +658,6 @@ span.section-subtitle { /* font-size relative to parent (h1..h6 element) */ font-size: 80%; } -table.citation { - border-left: solid 1px #666666; - margin-left: 1px; } - -table.docinfo { - margin: 0em; - margin-top: 2em; - margin-bottom: 2em; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; - color: #444444; } - -table.docutils { - margin-top: 0.5em; - margin-bottom: 0.5em; } - -table.footnote { - border-left: solid 1px #2d2d2d; - margin-left: 1px; } - -table.docutils td, table.docutils th, -table.docinfo td, table.docinfo th { - padding-left: 0.5em; - padding-right: 0.5em; - vertical-align: top; } - -table.docutils th.field-name, table.docinfo th.docinfo-name { - font-weight: 700; - text-align: left; - white-space: nowrap; - padding-left: 0; } - -h1 tt.docutils, h2 tt.docutils, h3 tt.docutils, -h4 tt.docutils, h5 tt.docutils, h6 tt.docutils { - font-size: 100%; } - -ul.auto-toc { - list-style-type: none; } - span.DecNumber { color: #252dbe; } @@ -1074,7 +674,7 @@ span.FloatNumber { color: #252dbe; } span.Identifier { - color: #3b3b3b; } + color: #222; } span.Keyword { font-weight: 600; @@ -1139,38 +739,23 @@ dt pre > span.Identifier, dt pre > span.Operator { color: #155da4; font-weight: 700; } -dt pre > span.Identifier ~ span.Identifier, dt pre > span.Operator ~ span.Identifier { - color: inherit; - font-weight: inherit; } - -dt pre > span.Operator ~ span.Identifier { +dt pre > span.Keyword ~ span.Identifier, dt pre > span.Identifier ~ span.Identifier, +dt pre > span.Operator ~ span.Identifier, dt pre > span.Other ~ span.Identifier { color: inherit; font-weight: inherit; } /* Nim sprite for the footer (taken from main page favicon) */ .nim-sprite { display: inline-block; - height: 12px; - width: 12px; + height: 16px; + width: 16px; background-position: 0 0; - background-size: 12px 12px; + background-size: 16px 16px; -webkit-filter: opacity(50%); background-repeat: no-repeat; background-image: url("data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="); margin-bottom: -5px; } -div.search_results { - background-color: antiquewhite; - margin: 3em; - padding: 1em; - border: 1px solid #4d4d4d; -} - -div#global-links ul { - margin-left: 0; - list-style-type: none; -} - span.pragmadots { /* Position: relative frees us up to make the dots look really nice without fucking up the layout and @@ -1178,18 +763,14 @@ span.pragmadots { position: relative; /* 1px down looks slightly nicer */ top: 1px; - padding: 2px; - background-color: #D3D3D3; + background-color: #e8e8e8; border-radius: 4px; margin: 0 2px; cursor: pointer; - - /* For some reason on Chrome, making the font size - smaller than 1em is causing the parent container to - bulge slightly. So, we're stuck with inheriting 1em, - which is sad, because 0.8em looks better... */ + font-size: 0.8em; } + span.pragmadots:hover { background-color: #DBDBDB; } @@ -1197,6 +778,10 @@ span.pragmawrap { display: none; } +span.attachedType { + display: none; + visibility: hidden; +} @@ -1248,29 +833,29 @@ function main() { Procs
      • execAction
      • + title="execAction(cmd: string; nostderr = false): string">execAction
      • mkDir
      • + title="mkDir(dir: string)">mkDir
      • cpFile
      • + title="cpFile(source, dest: string; move = false)">cpFile
      • mvFile
      • + title="mvFile(source, dest: string)">mvFile
      • extractZip
      • + title="extractZip(zipfile, outdir: string)">extractZip
      • downloadUrl
      • + title="downloadUrl(url, outdir: string)">downloadUrl
      • gitReset
      • + title="gitReset(outdir: string)">gitReset
      • gitCheckout
      • + title="gitCheckout(file, outdir: string)">gitCheckout
      • gitPull
      • + title="gitPull(url: string; outdir = ""; plist = ""; checkout = "")">gitPull
      • configure
      • + title="configure(path, check: string; flags = "")">configure
      • cmake
      • + title="cmake(path, check, flags: string)">cmake
      • make
      • + title="make(path, check: string; flags = "")">make
    • @@ -1280,6 +865,7 @@ function main() {
      +

      Imports

      @@ -1290,109 +876,125 @@ function main() {

      Procs

      -
      proc execAction(cmd: string; nostderr = false): string {...}{.raises: [OSError, Exception],
      +
      proc execAction(cmd: string; nostderr = false): string {...}{.
      +    raises: [OSError, Exception, IOError, Defect],
           tags: [ExecIOEffect, ReadIOEffect, RootEffect].}
      +

      Execute an external command - supported at compile time

      Checks if command exits successfully before returning. If not, an error is raised.

      -
      proc mkDir(dir: string) {...}{.raises: [OSError, Exception], tags: [ReadDirEffect,
      -    ExecIOEffect, ReadIOEffect, RootEffect].}
      +
      proc mkDir(dir: string) {...}{.raises: [OSError, Exception, IOError, Defect, ValueError], tags: [
      +    ReadDirEffect, ExecIOEffect, ReadIOEffect, RootEffect].}
      +

      Create a directory at cmopile time

      -

      The os module is not available at compile time so a few crucial helper functions are included with nimterop.

      +

      The os module is not available at compile time so a few crucial helper functions are included with nimterop.

      -
      proc cpFile(source, dest: string; move = false) {...}{.raises: [OSError, Exception],
      +
      proc cpFile(source, dest: string; move = false) {...}{.
      +    raises: [OSError, Exception, IOError, Defect, ValueError],
           tags: [ExecIOEffect, ReadIOEffect, RootEffect].}
      + Copy a file from source to destination at compile time
      -
      proc mvFile(source, dest: string) {...}{.raises: [OSError, Exception],
      +
      proc mvFile(source, dest: string) {...}{.raises: [OSError, Exception, IOError, Defect,
      +                                        ValueError],
                                       tags: [ExecIOEffect, ReadIOEffect, RootEffect].}
      + Move a file from source to destination at compile time
      -
      proc extractZip(zipfile, outdir: string) {...}{.raises: [OSError, Exception, ValueError], tags: [
      -    ExecIOEffect, ReadIOEffect, RootEffect].}
      +
      proc extractZip(zipfile, outdir: string) {...}{.raises: [OSError, Exception, IOError, Defect,
      +    ValueError], tags: [ExecIOEffect, ReadIOEffect, RootEffect].}
      + Extract a zip file using powershell on Windows and unzip on other systems to the specified output directory
      -
      proc downloadUrl(url, outdir: string) {...}{.raises: [OSError, Exception, ValueError], tags: [
      -    ReadDirEffect, ExecIOEffect, ReadIOEffect, RootEffect].}
      +
      proc downloadUrl(url, outdir: string) {...}{.raises: [OSError, Exception, IOError, Defect,
      +    ValueError], tags: [ReadDirEffect, ExecIOEffect, ReadIOEffect, RootEffect].}
      +

      Download a file using powershell on Windows and curl on other systems to the specified output directory

      If a zip file, it is automatically extracted after download.

      -
      proc gitReset(outdir: string) {...}{.raises: [OSError, Exception], tags: [ExecIOEffect,
      -    ReadIOEffect, RootEffect, TimeEffect].}
      +
      proc gitReset(outdir: string) {...}{.raises: [ValueError, OSError, Exception, IOError, Defect], tags: [
      +    ExecIOEffect, ReadIOEffect, RootEffect, TimeEffect].}
      + Hard reset the git repository at the specified directory
      -
      proc gitCheckout(file, outdir: string) {...}{.raises: [OSError, Exception], tags: [
      -    ExecIOEffect, ReadIOEffect, RootEffect, TimeEffect].}
      +
      proc gitCheckout(file, outdir: string) {...}{.raises: [ValueError, OSError, Exception,
      +    IOError, Defect], tags: [ExecIOEffect, ReadIOEffect, RootEffect, TimeEffect].}
      +

      Checkout the specified file in the git repository specified

      -

      This effectively resets all changes in the file and can be used to undo any changes that were made to source files to enable successful wrapping with cImport() or c2nImport().

      +

      This effectively resets all changes in the file and can be used to undo any changes that were made to source files to enable successful wrapping with cImport() or c2nImport().

      -
      proc gitPull(url: string; outdir = ""; plist = ""; checkout = "") {...}{.
      -    raises: [OSError, Exception, IOError], tags: [ReadDirEffect, ExecIOEffect,
      -    ReadIOEffect, RootEffect, TimeEffect, WriteIOEffect].}
      +
      proc gitPull(url: string; outdir = ""; plist = ""; checkout = "") {...}{.
      +    raises: [ValueError, OSError, Exception, IOError, Defect], tags: [ReadDirEffect,
      +    ExecIOEffect, ReadIOEffect, RootEffect, TimeEffect, WriteIOEffect].}
      +

      Pull the specified git repository to the output directory

      -

      plist is the list of specific files and directories or wildcards to sparsely checkout. Multiple values can be specified one entry per line. It is optional and if omitted, the entire repository will be checked out.

      -

      checkout is the git tag, branch or commit hash to checkout once the repository is downloaded. This allows for pinning to a specific version of the code.

      +

      plist is the list of specific files and directories or wildcards to sparsely checkout. Multiple values can be specified one entry per line. It is optional and if omitted, the entire repository will be checked out.

      +

      checkout is the git tag, branch or commit hash to checkout once the repository is downloaded. This allows for pinning to a specific version of the code.

      -
      proc configure(path, check: string; flags = "") {...}{.raises: [OSError, Exception],
      +
      proc configure(path, check: string; flags = "") {...}{.
      +    raises: [OSError, Exception, IOError, Defect, ValueError],
           tags: [ReadDirEffect, ExecIOEffect, ReadIOEffect, RootEffect].}
      -

      Run the GNU configure command to generate all Makefiles or other build scripts in the specified path

      -

      If a configure script is not present and an autogen.sh script is present, it will be run before attempting configure.

      -

      check is a file that will be generated by the configure command. This is required to prevent configure from running on every build. It is relative to the path and should not be an absolute path.

      -

      flags are any flags that should be passed to the configure command.

      + +

      Run the GNU configure command to generate all Makefiles or other build scripts in the specified path

      +

      If a configure script is not present and an autogen.sh script is present, it will be run before attempting configure.

      +

      check is a file that will be generated by the configure command. This is required to prevent configure from running on every build. It is relative to the path and should not be an absolute path.

      +

      flags are any flags that should be passed to the configure command.

      -
      proc cmake(path, check, flags: string) {...}{.raises: [OSError, Exception], tags: [
      -    ReadDirEffect, ExecIOEffect, ReadIOEffect, RootEffect].}
      +
      proc cmake(path, check, flags: string) {...}{.raises: [OSError, Exception, IOError, Defect,
      +    ValueError], tags: [ReadDirEffect, ExecIOEffect, ReadIOEffect, RootEffect].}
      -

      Run the cmake command to generate all Makefiles or other build scripts in the specified path

      -

      path will be created since typically cmake is run in an empty directory.

      -

      check is a file that will be generated by the cmake command. This is required to prevent cmake from running on every build. It is relative to the path and should not be an absolute path.

      -

      flags are any flags that should be passed to the cmake command. Unlike configure, it is required since typically it will be the path to the repository, typically .. when path is a subdir.

      + +

      Run the cmake command to generate all Makefiles or other build scripts in the specified path

      +

      path will be created since typically cmake is run in an empty directory.

      +

      check is a file that will be generated by the cmake command. This is required to prevent cmake from running on every build. It is relative to the path and should not be an absolute path.

      +

      flags are any flags that should be passed to the cmake command. Unlike configure, it is required since typically it will be the path to the repository, typically .. when path is a subdir.

      -
      proc make(path, check: string; flags = "") {...}{.raises: [OSError, Exception], tags: [
      -    ReadDirEffect, ExecIOEffect, ReadIOEffect, RootEffect].}
      +
      proc make(path, check: string; flags = "") {...}{.raises: [ValueError, OSError, Exception,
      +    IOError, Defect], tags: [ReadDirEffect, ExecIOEffect, ReadIOEffect, RootEffect].}
      -

      Run the make command to build all binaries in the specified path

      -

      check is a file that will be generated by the make command. This is required to prevent make from running on every build. It is relative to the path and should not be an absolute path.

      -

      flags are any flags that should be passed to the make command.

      + +

      Run the make command to build all binaries in the specified path

      +

      check is a file that will be generated by the make command. This is required to prevent make from running on every build. It is relative to the path and should not be an absolute path.

      +

      flags are any flags that should be passed to the make command.

      @@ -1406,7 +1008,7 @@ Hard reset the git repository at the specified directory
      diff --git a/paths.html b/paths.html index c8634e8..60d9e43 100644 --- a/paths.html +++ b/paths.html @@ -27,232 +27,130 @@ customize this style sheet. Modified from Chad Skeeters' rst2html-style https://bitbucket.org/cskeeters/rst2html-style/ -Modified by Boyd Greenfield +Modified by Boyd Greenfield and narimiran */ -/* SCSS variables */ -/* Text weights */ -/* Body colors */ -/* Text colors */ -/* Link colors */ -/* Syntax highlighting colors */ -/* Pct changes */ -/* Mixins */ -/* Body/layout */ + html { font-size: 100%; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; } -/* Where we want fancier font if available */ -h1, h2, h3, h4, h5, h6, p.module-desc, table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; } - -h1.title { - font-weight: 900; } - body { font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: 400; - font-size: 16px; - line-height: 20px; - color: #444; - letter-spacing: 0.15px; - background-color: #FDFBFA; } + font-size: 1.125em; + line-height: 1.5; + color: #222; + background-color: #FCFCFC; } /* Skeleton grid */ .container { position: relative; width: 100%; - max-width: 960px; + max-width: 1050px; margin: 0 auto; - padding: 0 20px; + padding: 0; box-sizing: border-box; } .column, .columns { width: 100%; float: left; - box-sizing: border-box; } + box-sizing: border-box; + margin-left: 1%; +} -/* For devices larger than 400px */ -@media (min-width: 400px) { - .container { - width: 100%; - padding: 0; } } -/* For devices larger than 650px */ -@media (min-width: 650px) { - .container { - width: 100%; } +.column:first-child, +.columns:first-child { + margin-left: 0; } - .column, - .columns { - margin-left: 4%; } +.three.columns { + width: 19%; } - .column:first-child, - .columns:first-child { - margin-left: 0; } +.nine.columns { + width: 80.0%; } - .one.column, - .one.columns { - width: 4.66666666667%; } - - .two.columns { - width: 13.3333333333%; } +.twelve.columns { + width: 100%; + margin-left: 0; } +@media screen and (max-width: 860px) { .three.columns { - width: 22%; } - - .four.columns { - width: 30.6666666667%; } - - .five.columns { - width: 39.3333333333%; } - - .six.columns { - width: 48%; } - - .seven.columns { - width: 56.6666666667%; } - - .eight.columns { - width: 65.3333333333%; } - + display: none; + } .nine.columns { - width: 74.0%; } - - .ten.columns { - width: 82.6666666667%; } - - .eleven.columns { - width: 91.3333333333%; } - - .twelve.columns { - width: 100%; - margin-left: 0; } - - .one-third.column { - width: 30.6666666667%; } - - .two-thirds.column { - width: 65.3333333333%; } } -/* Customer Overrides */ -.footer { - text-align: center; - color: #969696; - padding-top: 10%; } - -p.module-desc { - font-size: 1.1em; - color: #666666; } - -a.link-seesrc { - color: #aec7d2; - font-style: italic; } - -a.link-seesrc:hover { - color: #6c9aae; } - -#toc-list { - word-wrap: break-word; } - -ul.simple-toc { - list-style: none; } - -ul.simple-toc a.reference-toplevel { - font-weight: bold; - color: #0077b3; } - -ul.simple-toc-section { - list-style-type: circle; - color: #6c9aae; } - -ul.simple-toc-section a.reference { - color: #0077b3; } + width: 98.0%; + } + body { + font-size: 1em; + line-height: 1.35; + } +} cite { font-style: italic !important; } -dt > pre { - border-color: rgba(0, 0, 0, 0.1); - background-color: rgba(255, 255, 255, 0.3); - margin: 15px 0px 5px; } - -dd > pre { - border-color: rgba(0, 0, 0, 0.1); - background-color: whitesmoke; - margin-top: 8px; } - -.item > dd { - margin-left: 10px; - margin-bottom: 30px; } - -/* Nim line-numbered tables */ -.line-nums-table { - width: 100%; - table-layout: fixed; } /* Nim search input */ div#searchInputDiv { - margin-bottom: 8px; + margin-bottom: 1em; } -div#searchInputDiv input#searchInput { - width: 10em; -} -div.search-groupby { - margin-bottom: 8px; +input#searchInput { + width: 80%; } -table.line-nums-table { - border-radius: 4px; - border: 1px solid #cccccc; - background-color: whitesmoke; - border-collapse: separate; - margin-top: 15px; - margin-bottom: 25px; } - -.line-nums-table tbody { - border: none; } - -.line-nums-table td pre { - border: none; - background-color: transparent; } - -.line-nums-table td.blob-line-nums { - width: 28px; } - -.line-nums-table td.blob-line-nums pre { - color: #b0b0b0; - -webkit-filter: opacity(75%); - text-align: right; - border-color: transparent; - background-color: transparent; - padding-left: 0px; - margin-left: 0px; - padding-right: 0px; - margin-right: 0px; } +/* + * Some custom formatting for input forms. + * This also fixes input form colors on Firefox with a dark system theme on Linux. + */ +input { + -moz-appearance: none; + color: #333; + background-color: #f8f8f8; + border: 1px solid #aaa; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-size: 0.9em; + padding: 6px; +} +input:focus { + border: 1px solid #1fa0eb; + box-shadow: 0 0 2px #1fa0eb; +} /* Docgen styles */ /* Links */ a { - color: #0077b3; - text-decoration: none; } + color: #07b; + text-decoration: none; +} + +a span.Identifier { + text-decoration: underline; + text-decoration-color: #aab; +} + +a.reference-toplevel { + font-weight: bold; +} + +a.toc-backref { + text-decoration: none; + color: #222; } + +a.link-seesrc { + color: #607c9f; + font-size: 0.9em; + font-style: italic; } a:hover, a:focus { - color: #00334d; + color: #607c9f; text-decoration: underline; } -a:visited { - color: #00334d; } +a:hover span.Identifier { + color: #607c9f; +} -a:focus { - outline: thin dotted #2d2d2d; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; } - -a:hover, -a:active { - outline: 0; } sub, sup { @@ -329,379 +227,258 @@ img { h2, h3 { - page-break-after: avoid; } } -.img-rounded { - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; } + page-break-after: avoid; } +} -.img-polaroid { - padding: 4px; - background-color: rgba(252, 248, 244, 0.75); - border: 1px solid #ccc; - border: 1px solid rgba(0, 0, 0, 0.2); - -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); - -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); } p { - margin: 0 0 8px; } + margin-top: 0.5em; + margin-bottom: 0.5em; +} small { font-size: 85%; } strong { - font-weight: 600; } + font-weight: 600; + font-size: 0.95em; + color: #3c3c3c; +} em { font-style: italic; } -cite { - font-style: normal; } - -h1, -h2, -h3, -h4, -h5, -h6 { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-weight: 600; - line-height: 20px; - color: inherit; - text-rendering: optimizelegibility; } - h1 { - font-size: 2em; + font-size: 1.8em; font-weight: 400; - padding-bottom: .15em; - border-bottom: 1px solid #aaaaaa; - margin-top: 1.0em; + padding-bottom: .25em; + border-bottom: 1px solid #aaa; + margin-top: 2.5em; + margin-bottom: 1em; line-height: 1.2em; } h1.title { padding-bottom: 1em; border-bottom: 0px; - font-size: 2.75em; } + font-size: 2.5em; + text-align: center; + font-weight: 900; + margin-top: 0.75em; + margin-bottom: 0em; +} h2 { - font-size: 1.5em; - margin-top: 1.5em; } + font-size: 1.3em; + margin-top: 2em; } + +h2.subtitle { + text-align: center; } h3 { - font-size: 1.3em; + font-size: 1.125em; font-style: italic; - margin-top: 0.75em; } + margin-top: 1.5em; } h4 { - font-size: 1.3em; - margin-top: 0.5em; } + font-size: 1.125em; + margin-top: 1em; } h5 { - font-size: 1.2em; - margin-top: 0.25em; } + font-size: 1.125em; + margin-top: 0.75em; } h6 { font-size: 1.1em; } + ul, ol { padding: 0; - margin: 0 0 0px 15px; } + margin-top: 0.5em; + margin-left: 0.75em; } ul ul, ul ol, ol ol, ol ul { - margin-bottom: 0; } + margin-bottom: 0; + margin-left: 1.25em; } li { - line-height: 20px; } - -dl { - margin-bottom: 20px; } - -dt, -dd { - line-height: 20px; } - -dt { - font-weight: bold; } - -dd { - margin-left: 10px; - margin-bottom: 26px; } - -hr { - margin: 20px 0; - border: 0; - border-top: 1px solid #eeeeee; - border-bottom: 1px solid #ffffff; } - -abbr[title], -abbr[data-original-title] { - cursor: help; - border-bottom: 1px dotted #999999; } - -abbr.initialism { - font-size: 90%; - text-transform: uppercase; } - -blockquote { - padding: 0 0 0 15px; - margin: 0 0 20px; - border-left: 5px solid #EFEBE0; } - -table.docinfo + blockquote, table.docinfo blockquote, h1 + blockquote { - border-left: 5px solid #c9c9c9; + list-style-type: circle; } -table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { - margin-bottom: 0; - font-size: 15px; - font-weight: 200; - line-height: 1.5; - font-style: italic; } +ul.simple-boot li { + list-style-type: none; + margin-left: 0em; + margin-bottom: 0.5em; +} -q:before, -q:after, -blockquote:before, -blockquote:after { - content: ""; } +ol.simple > li, ul.simple > li { + margin-bottom: 0.25em; + margin-left: 0.4em } -address { - display: block; - margin-bottom: 20px; - font-style: normal; - line-height: 20px; } +ul.simple.simple-toc > li { + margin-top: 1em; +} -code, -pre { - font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - padding: 0 3px 2px; - font-weight: 500; - font-size: 12px; - color: #444444; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; } +ul.simple-toc { + list-style: none; + font-size: 0.9em; + margin-left: -0.3em; + margin-top: 1em; } + +ul.simple-toc > li { + list-style-type: none; +} + +ul.simple-toc-section { + list-style-type: circle; + margin-left: 1em; + color: #6c9aae; } + + +ol.arabic { + list-style: decimal; } + +ol.loweralpha { + list-style: lower-alpha; } + +ol.upperalpha { + list-style: upper-alpha; } + +ol.lowerroman { + list-style: lower-roman; } + +ol.upperroman { + list-style: upper-roman; } + +ul.auto-toc { + list-style-type: none; } + + +dl { + margin-bottom: 1.5em; } + +dt { + margin-bottom: -0.5em; + margin-left: 0.0em; } + +dd { + margin-left: 2.0em; + margin-bottom: 3.0em; + margin-top: 0.5em; } + + +hr { + margin: 2em 0; + border: 0; + border-top: 1px solid #aaa; } + +blockquote { + font-size: 0.9em; + font-style: italic; + padding-left: 0.5em; + margin-left: 0; + border-left: 5px solid #bbc; +} .pre { font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - font-weight: 600; - /*color: #504da6;*/ + font-weight: 500; + font-size: 0.85em; + background-color: #f0f3ff; + padding-left: 3px; + padding-right: 3px; + border-radius: 4px; } -code { - padding: 2px 4px; - color: #444444; - white-space: nowrap; - background-color: white; - border: 1px solid #777777; } - pre { + font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; + color: #222; + font-weight: 500; display: inline-block; box-sizing: border-box; - min-width: calc(100% - 19.5px); - padding: 9.5px; - margin: 0.25em 10px 10px 10px; - font-size: 15px; - line-height: 20px; + min-width: 100%; + padding: 0.5em; + margin-top: 0.5em; + margin-bottom: 0.5em; + font-size: 0.85em; white-space: pre !important; overflow-y: hidden; overflow-x: visible; - background-color: rgba(0, 0, 0, 0.01); - border: 1px solid #cccccc; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; } - -pre.prettyprint { - margin-bottom: 20px; } - -pre code { - padding: 0; - color: inherit; - white-space: pre; - overflow-x: visible; - background-color: transparent; - border: 0; } + background-color: ghostwhite; + border: 1px solid #dde; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; } .pre-scrollable { max-height: 340px; overflow-y: scroll; } + +/* Nim line-numbered tables */ +.line-nums-table { + width: 100%; + table-layout: fixed; } + +table.line-nums-table { + border-radius: 4px; + border: 1px solid #cccccc; + background-color: ghostwhite; + border-collapse: separate; + margin-top: 15px; + margin-bottom: 25px; } + +.line-nums-table tbody { + border: none; } + +.line-nums-table td pre { + border: none; + background-color: transparent; } + +.line-nums-table td.blob-line-nums { + width: 28px; } + +.line-nums-table td.blob-line-nums pre { + color: #b0b0b0; + -webkit-filter: opacity(75%); + text-align: right; + border-color: transparent; + background-color: transparent; + padding-left: 0px; + margin-left: 0px; + padding-right: 0px; + margin-right: 0px; } + + table { max-width: 100%; background-color: transparent; + margin-top: 0.5em; + margin-bottom: 1.5em; border-collapse: collapse; - border-spacing: 0; } - -table th, table td { - padding: 0px 8px 0px; + border-color: #ccc; + border-spacing: 0; + font-size: 0.9em; } -.table { - width: 100%; - margin-bottom: 20px; } +table th, table td { + padding: 0px 0.5em 0px; +} -.table th, -.table td { - padding: 8px; - line-height: 20px; - text-align: left; - vertical-align: top; - border-top: 1px solid #444444; } - -.table th { +table th { + background-color: #e8e8e8; font-weight: bold; } -.table thead th { - vertical-align: bottom; } +table th.docinfo-name { + background-color: transparent; +} -.table caption + thead tr:first-child th, -.table caption + thead tr:first-child td, -.table colgroup + thead tr:first-child th, -.table colgroup + thead tr:first-child td, -.table thead:first-child tr:first-child th, -.table thead:first-child tr:first-child td { - border-top: 0; } +table tr:hover { + background-color: ghostwhite; } -.table tbody + tbody { - border-top: 2px solid #444444; } - -.table .table { - background-color: rgba(252, 248, 244, 0.75); } - -.table-condensed th, -.table-condensed td { - padding: 4px 5px; } - -.table-bordered { - border: 1px solid #444444; - border-collapse: separate; - *border-collapse: collapse; - border-left: 0; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; } - -.table-bordered th, -.table-bordered td { - border-left: 1px solid #444444; } - -.table-bordered caption + thead tr:first-child th, -.table-bordered caption + tbody tr:first-child th, -.table-bordered caption + tbody tr:first-child td, -.table-bordered colgroup + thead tr:first-child th, -.table-bordered colgroup + tbody tr:first-child th, -.table-bordered colgroup + tbody tr:first-child td, -.table-bordered thead:first-child tr:first-child th, -.table-bordered tbody:first-child tr:first-child th, -.table-bordered tbody:first-child tr:first-child td { - border-top: 0; } - -.table-bordered thead:first-child tr:first-child > th:first-child, -.table-bordered tbody:first-child tr:first-child > td:first-child, -.table-bordered tbody:first-child tr:first-child > th:first-child { - -webkit-border-top-left-radius: 4px; - border-top-left-radius: 4px; - -moz-border-radius-topleft: 4px; } - -.table-bordered thead:first-child tr:first-child > th:last-child, -.table-bordered tbody:first-child tr:first-child > td:last-child, -.table-bordered tbody:first-child tr:first-child > th:last-child { - -webkit-border-top-right-radius: 4px; - border-top-right-radius: 4px; - -moz-border-radius-topright: 4px; } - -.table-bordered thead:last-child tr:last-child > th:first-child, -.table-bordered tbody:last-child tr:last-child > td:first-child, -.table-bordered tbody:last-child tr:last-child > th:first-child, -.table-bordered tfoot:last-child tr:last-child > td:first-child, -.table-bordered tfoot:last-child tr:last-child > th:first-child { - -webkit-border-bottom-left-radius: 4px; - border-bottom-left-radius: 4px; - -moz-border-radius-bottomleft: 4px; } - -.table-bordered thead:last-child tr:last-child > th:last-child, -.table-bordered tbody:last-child tr:last-child > td:last-child, -.table-bordered tbody:last-child tr:last-child > th:last-child, -.table-bordered tfoot:last-child tr:last-child > td:last-child, -.table-bordered tfoot:last-child tr:last-child > th:last-child { - -webkit-border-bottom-right-radius: 4px; - border-bottom-right-radius: 4px; - -moz-border-radius-bottomright: 4px; } - -.table-bordered tfoot + tbody:last-child tr:last-child td:first-child { - -webkit-border-bottom-left-radius: 0; - border-bottom-left-radius: 0; - -moz-border-radius-bottomleft: 0; } - -.table-bordered tfoot + tbody:last-child tr:last-child td:last-child { - -webkit-border-bottom-right-radius: 0; - border-bottom-right-radius: 0; - -moz-border-radius-bottomright: 0; } - -.table-bordered caption + thead tr:first-child th:first-child, -.table-bordered caption + tbody tr:first-child td:first-child, -.table-bordered colgroup + thead tr:first-child th:first-child, -.table-bordered colgroup + tbody tr:first-child td:first-child { - -webkit-border-top-left-radius: 4px; - border-top-left-radius: 4px; - -moz-border-radius-topleft: 4px; } - -.table-bordered caption + thead tr:first-child th:last-child, -.table-bordered caption + tbody tr:first-child td:last-child, -.table-bordered colgroup + thead tr:first-child th:last-child, -.table-bordered colgroup + tbody tr:first-child td:last-child { - -webkit-border-top-right-radius: 4px; - border-top-right-radius: 4px; - -moz-border-radius-topright: 4px; } - -table.docutils th { - background-color: #e8e8e8; } - -table.docutils tr:hover { - background-color: whitesmoke; } - -.table-striped tbody > tr:nth-child(odd) > td, -.table-striped tbody > tr:nth-child(odd) > th { - background-color: rgba(252, 248, 244, 0.75); } - -.table-hover tbody tr:hover > td, -.table-hover tbody tr:hover > th { - background-color: rgba(241, 222, 204, 0.75); } - -table td[class*="span"], -table th[class*="span"], -.row-fluid table td[class*="span"], -.row-fluid table th[class*="span"] { - display: table-cell; - float: none; - margin-left: 0; } - -.hero-unit { - padding: 60px; - margin-bottom: 30px; - font-size: 18px; - font-weight: 200; - line-height: 30px; - color: inherit; - background-color: rgba(230, 197, 164, 0.75); - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; } - -.hero-unit h1 { - margin-bottom: 0; - font-size: 60px; - line-height: 1; - letter-spacing: -1px; - color: inherit; } - -.hero-unit li { - line-height: 30px; } /* rst2html default used to remove borders from tables and images */ .borderless, table.borderless td, table.borderless th { @@ -722,10 +499,6 @@ table.borderless td, table.borderless th { .hidden { display: none; } -a.toc-backref { - text-decoration: none; - color: #444444; } - blockquote.epigraph { margin: 2em 5em; } @@ -735,85 +508,6 @@ dl.docutils dd { object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] { overflow: hidden; } -/* Uncomment (and remove this text!) to get bold-faced definition list terms -dl.docutils dt { - font-weight: bold } -*/ -div.abstract { - margin: 2em 5em; } - -div.abstract p.topic-title { - font-weight: bold; - text-align: center; } - -div.admonition, div.attention, div.caution, div.danger, div.error, -div.hint, div.important, div.note, div.tip, div.warning { - margin: 2em; - border: medium outset; - padding: 1em; } - -div.note, div.warning { - margin: 1.5em 0px; - border: none; } - -div.note p.admonition-title, -div.warning p.admonition-title { - display: none; } - -/* Clearfix - * http://css-tricks.com/snippets/css/clear-fix/ - */ -div.note:after, -div.warning:after { - content: ""; - display: table; - clear: both; } - -div.note p:before, -div.warning p:before { - display: block; - float: left; - font-size: 4em; - line-height: 1em; - margin-right: 20px; - margin-left: 0em; - margin-top: -10px; - content: '\0270D'; - /*handwriting*/ } - -div.warning p:before { - content: '\026A0'; - /*warning*/ } - -div.admonition p.admonition-title, div.hint p.admonition-title, -div.important p.admonition-title, div.note p.admonition-title, -div.tip p.admonition-title { - font-weight: bold; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } - -div.attention p.admonition-title, div.caution p.admonition-title, -div.danger p.admonition-title, div.error p.admonition-title, -div.warning p.admonition-title, .code .error { - color: #b30000; - font-weight: bold; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } - -/* Uncomment (and remove this text!) to get reduced vertical space in - compound paragraphs. -div.compound .compound-first, div.compound .compound-middle { - margin-bottom: 0.5em } - -div.compound .compound-last, div.compound .compound-middle { - margin-top: 0.5em } -*/ -div.dedication { - margin: 2em 5em; - text-align: center; - font-style: italic; } - -div.dedication p.topic-title { - font-weight: bold; - font-style: normal; } div.figure { margin-left: 2em; @@ -821,8 +515,14 @@ div.figure { div.footer, div.header { clear: both; + text-align: center; + color: #666; font-size: smaller; } +div.footer { + padding-top: 5em; +} + div.line-block { display: block; margin-top: 1em; @@ -833,45 +533,24 @@ div.line-block div.line-block { margin-bottom: 0; margin-left: 1.5em; } -div.sidebar { - margin: 0 0 0.5em 1em; - border: medium outset; - padding: 1em; - background-color: rgba(252, 248, 244, 0.75); - width: 40%; - float: right; - clear: right; } - -div.sidebar p.rubric { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-size: medium; } - -div.system-messages { - margin: 5em; } - -div.system-messages h1 { - color: #b30000; } - -div.system-message { - border: medium outset; - padding: 1em; } - -div.system-message p.system-message-title { - color: #b30000; - font-weight: bold; } - div.topic { margin: 2em; } -h1.section-subtitle, h2.section-subtitle, h3.section-subtitle, -h4.section-subtitle, h5.section-subtitle, h6.section-subtitle { - margin-top: 0.4em; } +div.search_results { + background-color: antiquewhite; + margin: 3em; + padding: 1em; + border: 1px solid #4d4d4d; +} -h1.title { - text-align: center; } +div#global-links ul { + margin-left: 0; + list-style-type: none; +} -h2.subtitle { - text-align: center; } +div#global-links > simple-boot { + margin-left: 3em; +} hr.docutils { width: 75%; } @@ -905,30 +584,6 @@ img.align-center, .figure.align-center, object.align-center { div.align-right { text-align: inherit; } -/* div.align-center * { */ -/* text-align: left } */ - -ul.simple > li { - margin-bottom: 0.5em } - -ol.simple, ul.simple { - margin-bottom: 1em; } - -ol.arabic { - list-style: decimal; } - -ol.loweralpha { - list-style: lower-alpha; } - -ol.upperalpha { - list-style: upper-alpha; } - -ol.lowerroman { - list-style: lower-roman; } - -ol.upperroman { - list-style: upper-roman; } - p.attribution { text-align: right; margin-left: 50%; } @@ -949,15 +604,6 @@ p.rubric { color: maroon; text-align: center; } -p.sidebar-title { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-weight: bold; - font-size: larger; } - -p.sidebar-subtitle { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-weight: bold; } - p.topic-title { font-weight: bold; } @@ -997,22 +643,14 @@ pre.code .inserted, code .inserted { background-color: #A3D289; } span.classifier { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-style: oblique; } span.classifier-delimiter { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: bold; } -span.interpreted { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } - span.option { white-space: nowrap; } -span.pre { - white-space: pre; } - span.problematic { color: #b30000; } @@ -1020,44 +658,6 @@ span.section-subtitle { /* font-size relative to parent (h1..h6 element) */ font-size: 80%; } -table.citation { - border-left: solid 1px #666666; - margin-left: 1px; } - -table.docinfo { - margin: 0em; - margin-top: 2em; - margin-bottom: 2em; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; - color: #444444; } - -table.docutils { - margin-top: 0.5em; - margin-bottom: 0.5em; } - -table.footnote { - border-left: solid 1px #2d2d2d; - margin-left: 1px; } - -table.docutils td, table.docutils th, -table.docinfo td, table.docinfo th { - padding-left: 0.5em; - padding-right: 0.5em; - vertical-align: top; } - -table.docutils th.field-name, table.docinfo th.docinfo-name { - font-weight: 700; - text-align: left; - white-space: nowrap; - padding-left: 0; } - -h1 tt.docutils, h2 tt.docutils, h3 tt.docutils, -h4 tt.docutils, h5 tt.docutils, h6 tt.docutils { - font-size: 100%; } - -ul.auto-toc { - list-style-type: none; } - span.DecNumber { color: #252dbe; } @@ -1074,7 +674,7 @@ span.FloatNumber { color: #252dbe; } span.Identifier { - color: #3b3b3b; } + color: #222; } span.Keyword { font-weight: 600; @@ -1139,38 +739,23 @@ dt pre > span.Identifier, dt pre > span.Operator { color: #155da4; font-weight: 700; } -dt pre > span.Identifier ~ span.Identifier, dt pre > span.Operator ~ span.Identifier { - color: inherit; - font-weight: inherit; } - -dt pre > span.Operator ~ span.Identifier { +dt pre > span.Keyword ~ span.Identifier, dt pre > span.Identifier ~ span.Identifier, +dt pre > span.Operator ~ span.Identifier, dt pre > span.Other ~ span.Identifier { color: inherit; font-weight: inherit; } /* Nim sprite for the footer (taken from main page favicon) */ .nim-sprite { display: inline-block; - height: 12px; - width: 12px; + height: 16px; + width: 16px; background-position: 0 0; - background-size: 12px 12px; + background-size: 16px 16px; -webkit-filter: opacity(50%); background-repeat: no-repeat; background-image: url("data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="); margin-bottom: -5px; } -div.search_results { - background-color: antiquewhite; - margin: 3em; - padding: 1em; - border: 1px solid #4d4d4d; -} - -div#global-links ul { - margin-left: 0; - list-style-type: none; -} - span.pragmadots { /* Position: relative frees us up to make the dots look really nice without fucking up the layout and @@ -1178,18 +763,14 @@ span.pragmadots { position: relative; /* 1px down looks slightly nicer */ top: 1px; - padding: 2px; - background-color: #D3D3D3; + background-color: #e8e8e8; border-radius: 4px; margin: 0 2px; cursor: pointer; - - /* For some reason on Chrome, making the font size - smaller than 1em is causing the parent container to - bulge slightly. So, we're stuck with inheriting 1em, - which is sad, because 0.8em looks better... */ + font-size: 0.8em; } + span.pragmadots:hover { background-color: #DBDBDB; } @@ -1197,6 +778,10 @@ span.pragmawrap { display: none; } +span.attachedType { + display: none; + visibility: hidden; +} @@ -1241,18 +826,18 @@ function main() {
    • Procs
    • @@ -1262,45 +847,52 @@ function main() {
      +

      Procs

      - -
      proc nimteropRoot(): string {...}{.raises: [], tags: [].}
      + +
      proc nimteropRoot(): string {...}{.raises: [], tags: [].}
      +
      - -
      proc nimteropBuildDir(): string {...}{.raises: [], tags: [].}
      + +
      proc nimteropBuildDir(): string {...}{.raises: [], tags: [].}
      + all nimterop generated files go under here (gitignored)
      - -
      proc nimteropSrcDir(): string {...}{.raises: [], tags: [].}
      + +
      proc nimteropSrcDir(): string {...}{.raises: [], tags: [].}
      +
      - -
      proc toastExePath(): string {...}{.raises: [], tags: [].}
      + +
      proc toastExePath(): string {...}{.raises: [], tags: [].}
      +
      - -
      proc incDir(): string {...}{.raises: [], tags: [].}
      + +
      proc incDir(): string {...}{.raises: [], tags: [].}
      +
      - -
      proc testsIncludeDir(): string {...}{.raises: [], tags: [].}
      + +
      proc testsIncludeDir(): string {...}{.raises: [], tags: [].}
      +
      @@ -1312,7 +904,7 @@ all nimterop generated files go under here (gitignored)
      diff --git a/paths.idx b/paths.idx index df86edd..8a688d4 100644 --- a/paths.idx +++ b/paths.idx @@ -1,6 +1,6 @@ -nimteropRoot paths.html#nimteropRoot, paths: nimteropRoot(): string -nimteropBuildDir paths.html#nimteropBuildDir, paths: nimteropBuildDir(): string -nimteropSrcDir paths.html#nimteropSrcDir, paths: nimteropSrcDir(): string -toastExePath paths.html#toastExePath, paths: toastExePath(): string -incDir paths.html#incDir, paths: incDir(): string -testsIncludeDir paths.html#testsIncludeDir, paths: testsIncludeDir(): string +nimteropRoot paths.html#nimteropRoot paths: nimteropRoot(): string +nimteropBuildDir paths.html#nimteropBuildDir paths: nimteropBuildDir(): string +nimteropSrcDir paths.html#nimteropSrcDir paths: nimteropSrcDir(): string +toastExePath paths.html#toastExePath paths: toastExePath(): string +incDir paths.html#incDir paths: incDir(): string +testsIncludeDir paths.html#testsIncludeDir paths: testsIncludeDir(): string diff --git a/plugin.html b/plugin.html index 1528de6..1b5f4cc 100644 --- a/plugin.html +++ b/plugin.html @@ -27,232 +27,130 @@ customize this style sheet. Modified from Chad Skeeters' rst2html-style https://bitbucket.org/cskeeters/rst2html-style/ -Modified by Boyd Greenfield +Modified by Boyd Greenfield and narimiran */ -/* SCSS variables */ -/* Text weights */ -/* Body colors */ -/* Text colors */ -/* Link colors */ -/* Syntax highlighting colors */ -/* Pct changes */ -/* Mixins */ -/* Body/layout */ + html { font-size: 100%; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; } -/* Where we want fancier font if available */ -h1, h2, h3, h4, h5, h6, p.module-desc, table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; } - -h1.title { - font-weight: 900; } - body { font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: 400; - font-size: 16px; - line-height: 20px; - color: #444; - letter-spacing: 0.15px; - background-color: #FDFBFA; } + font-size: 1.125em; + line-height: 1.5; + color: #222; + background-color: #FCFCFC; } /* Skeleton grid */ .container { position: relative; width: 100%; - max-width: 960px; + max-width: 1050px; margin: 0 auto; - padding: 0 20px; + padding: 0; box-sizing: border-box; } .column, .columns { width: 100%; float: left; - box-sizing: border-box; } + box-sizing: border-box; + margin-left: 1%; +} -/* For devices larger than 400px */ -@media (min-width: 400px) { - .container { - width: 100%; - padding: 0; } } -/* For devices larger than 650px */ -@media (min-width: 650px) { - .container { - width: 100%; } +.column:first-child, +.columns:first-child { + margin-left: 0; } - .column, - .columns { - margin-left: 4%; } +.three.columns { + width: 19%; } - .column:first-child, - .columns:first-child { - margin-left: 0; } +.nine.columns { + width: 80.0%; } - .one.column, - .one.columns { - width: 4.66666666667%; } - - .two.columns { - width: 13.3333333333%; } +.twelve.columns { + width: 100%; + margin-left: 0; } +@media screen and (max-width: 860px) { .three.columns { - width: 22%; } - - .four.columns { - width: 30.6666666667%; } - - .five.columns { - width: 39.3333333333%; } - - .six.columns { - width: 48%; } - - .seven.columns { - width: 56.6666666667%; } - - .eight.columns { - width: 65.3333333333%; } - + display: none; + } .nine.columns { - width: 74.0%; } - - .ten.columns { - width: 82.6666666667%; } - - .eleven.columns { - width: 91.3333333333%; } - - .twelve.columns { - width: 100%; - margin-left: 0; } - - .one-third.column { - width: 30.6666666667%; } - - .two-thirds.column { - width: 65.3333333333%; } } -/* Customer Overrides */ -.footer { - text-align: center; - color: #969696; - padding-top: 10%; } - -p.module-desc { - font-size: 1.1em; - color: #666666; } - -a.link-seesrc { - color: #aec7d2; - font-style: italic; } - -a.link-seesrc:hover { - color: #6c9aae; } - -#toc-list { - word-wrap: break-word; } - -ul.simple-toc { - list-style: none; } - -ul.simple-toc a.reference-toplevel { - font-weight: bold; - color: #0077b3; } - -ul.simple-toc-section { - list-style-type: circle; - color: #6c9aae; } - -ul.simple-toc-section a.reference { - color: #0077b3; } + width: 98.0%; + } + body { + font-size: 1em; + line-height: 1.35; + } +} cite { font-style: italic !important; } -dt > pre { - border-color: rgba(0, 0, 0, 0.1); - background-color: rgba(255, 255, 255, 0.3); - margin: 15px 0px 5px; } - -dd > pre { - border-color: rgba(0, 0, 0, 0.1); - background-color: whitesmoke; - margin-top: 8px; } - -.item > dd { - margin-left: 10px; - margin-bottom: 30px; } - -/* Nim line-numbered tables */ -.line-nums-table { - width: 100%; - table-layout: fixed; } /* Nim search input */ div#searchInputDiv { - margin-bottom: 8px; + margin-bottom: 1em; } -div#searchInputDiv input#searchInput { - width: 10em; -} -div.search-groupby { - margin-bottom: 8px; +input#searchInput { + width: 80%; } -table.line-nums-table { - border-radius: 4px; - border: 1px solid #cccccc; - background-color: whitesmoke; - border-collapse: separate; - margin-top: 15px; - margin-bottom: 25px; } - -.line-nums-table tbody { - border: none; } - -.line-nums-table td pre { - border: none; - background-color: transparent; } - -.line-nums-table td.blob-line-nums { - width: 28px; } - -.line-nums-table td.blob-line-nums pre { - color: #b0b0b0; - -webkit-filter: opacity(75%); - text-align: right; - border-color: transparent; - background-color: transparent; - padding-left: 0px; - margin-left: 0px; - padding-right: 0px; - margin-right: 0px; } +/* + * Some custom formatting for input forms. + * This also fixes input form colors on Firefox with a dark system theme on Linux. + */ +input { + -moz-appearance: none; + color: #333; + background-color: #f8f8f8; + border: 1px solid #aaa; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-size: 0.9em; + padding: 6px; +} +input:focus { + border: 1px solid #1fa0eb; + box-shadow: 0 0 2px #1fa0eb; +} /* Docgen styles */ /* Links */ a { - color: #0077b3; - text-decoration: none; } + color: #07b; + text-decoration: none; +} + +a span.Identifier { + text-decoration: underline; + text-decoration-color: #aab; +} + +a.reference-toplevel { + font-weight: bold; +} + +a.toc-backref { + text-decoration: none; + color: #222; } + +a.link-seesrc { + color: #607c9f; + font-size: 0.9em; + font-style: italic; } a:hover, a:focus { - color: #00334d; + color: #607c9f; text-decoration: underline; } -a:visited { - color: #00334d; } +a:hover span.Identifier { + color: #607c9f; +} -a:focus { - outline: thin dotted #2d2d2d; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; } - -a:hover, -a:active { - outline: 0; } sub, sup { @@ -329,379 +227,258 @@ img { h2, h3 { - page-break-after: avoid; } } -.img-rounded { - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; } + page-break-after: avoid; } +} -.img-polaroid { - padding: 4px; - background-color: rgba(252, 248, 244, 0.75); - border: 1px solid #ccc; - border: 1px solid rgba(0, 0, 0, 0.2); - -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); - -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); } p { - margin: 0 0 8px; } + margin-top: 0.5em; + margin-bottom: 0.5em; +} small { font-size: 85%; } strong { - font-weight: 600; } + font-weight: 600; + font-size: 0.95em; + color: #3c3c3c; +} em { font-style: italic; } -cite { - font-style: normal; } - -h1, -h2, -h3, -h4, -h5, -h6 { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-weight: 600; - line-height: 20px; - color: inherit; - text-rendering: optimizelegibility; } - h1 { - font-size: 2em; + font-size: 1.8em; font-weight: 400; - padding-bottom: .15em; - border-bottom: 1px solid #aaaaaa; - margin-top: 1.0em; + padding-bottom: .25em; + border-bottom: 1px solid #aaa; + margin-top: 2.5em; + margin-bottom: 1em; line-height: 1.2em; } h1.title { padding-bottom: 1em; border-bottom: 0px; - font-size: 2.75em; } + font-size: 2.5em; + text-align: center; + font-weight: 900; + margin-top: 0.75em; + margin-bottom: 0em; +} h2 { - font-size: 1.5em; - margin-top: 1.5em; } + font-size: 1.3em; + margin-top: 2em; } + +h2.subtitle { + text-align: center; } h3 { - font-size: 1.3em; + font-size: 1.125em; font-style: italic; - margin-top: 0.75em; } + margin-top: 1.5em; } h4 { - font-size: 1.3em; - margin-top: 0.5em; } + font-size: 1.125em; + margin-top: 1em; } h5 { - font-size: 1.2em; - margin-top: 0.25em; } + font-size: 1.125em; + margin-top: 0.75em; } h6 { font-size: 1.1em; } + ul, ol { padding: 0; - margin: 0 0 0px 15px; } + margin-top: 0.5em; + margin-left: 0.75em; } ul ul, ul ol, ol ol, ol ul { - margin-bottom: 0; } + margin-bottom: 0; + margin-left: 1.25em; } li { - line-height: 20px; } - -dl { - margin-bottom: 20px; } - -dt, -dd { - line-height: 20px; } - -dt { - font-weight: bold; } - -dd { - margin-left: 10px; - margin-bottom: 26px; } - -hr { - margin: 20px 0; - border: 0; - border-top: 1px solid #eeeeee; - border-bottom: 1px solid #ffffff; } - -abbr[title], -abbr[data-original-title] { - cursor: help; - border-bottom: 1px dotted #999999; } - -abbr.initialism { - font-size: 90%; - text-transform: uppercase; } - -blockquote { - padding: 0 0 0 15px; - margin: 0 0 20px; - border-left: 5px solid #EFEBE0; } - -table.docinfo + blockquote, table.docinfo blockquote, h1 + blockquote { - border-left: 5px solid #c9c9c9; + list-style-type: circle; } -table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { - margin-bottom: 0; - font-size: 15px; - font-weight: 200; - line-height: 1.5; - font-style: italic; } +ul.simple-boot li { + list-style-type: none; + margin-left: 0em; + margin-bottom: 0.5em; +} -q:before, -q:after, -blockquote:before, -blockquote:after { - content: ""; } +ol.simple > li, ul.simple > li { + margin-bottom: 0.25em; + margin-left: 0.4em } -address { - display: block; - margin-bottom: 20px; - font-style: normal; - line-height: 20px; } +ul.simple.simple-toc > li { + margin-top: 1em; +} -code, -pre { - font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - padding: 0 3px 2px; - font-weight: 500; - font-size: 12px; - color: #444444; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; } +ul.simple-toc { + list-style: none; + font-size: 0.9em; + margin-left: -0.3em; + margin-top: 1em; } + +ul.simple-toc > li { + list-style-type: none; +} + +ul.simple-toc-section { + list-style-type: circle; + margin-left: 1em; + color: #6c9aae; } + + +ol.arabic { + list-style: decimal; } + +ol.loweralpha { + list-style: lower-alpha; } + +ol.upperalpha { + list-style: upper-alpha; } + +ol.lowerroman { + list-style: lower-roman; } + +ol.upperroman { + list-style: upper-roman; } + +ul.auto-toc { + list-style-type: none; } + + +dl { + margin-bottom: 1.5em; } + +dt { + margin-bottom: -0.5em; + margin-left: 0.0em; } + +dd { + margin-left: 2.0em; + margin-bottom: 3.0em; + margin-top: 0.5em; } + + +hr { + margin: 2em 0; + border: 0; + border-top: 1px solid #aaa; } + +blockquote { + font-size: 0.9em; + font-style: italic; + padding-left: 0.5em; + margin-left: 0; + border-left: 5px solid #bbc; +} .pre { font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - font-weight: 600; - /*color: #504da6;*/ + font-weight: 500; + font-size: 0.85em; + background-color: #f0f3ff; + padding-left: 3px; + padding-right: 3px; + border-radius: 4px; } -code { - padding: 2px 4px; - color: #444444; - white-space: nowrap; - background-color: white; - border: 1px solid #777777; } - pre { + font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; + color: #222; + font-weight: 500; display: inline-block; box-sizing: border-box; - min-width: calc(100% - 19.5px); - padding: 9.5px; - margin: 0.25em 10px 10px 10px; - font-size: 15px; - line-height: 20px; + min-width: 100%; + padding: 0.5em; + margin-top: 0.5em; + margin-bottom: 0.5em; + font-size: 0.85em; white-space: pre !important; overflow-y: hidden; overflow-x: visible; - background-color: rgba(0, 0, 0, 0.01); - border: 1px solid #cccccc; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; } - -pre.prettyprint { - margin-bottom: 20px; } - -pre code { - padding: 0; - color: inherit; - white-space: pre; - overflow-x: visible; - background-color: transparent; - border: 0; } + background-color: ghostwhite; + border: 1px solid #dde; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; } .pre-scrollable { max-height: 340px; overflow-y: scroll; } + +/* Nim line-numbered tables */ +.line-nums-table { + width: 100%; + table-layout: fixed; } + +table.line-nums-table { + border-radius: 4px; + border: 1px solid #cccccc; + background-color: ghostwhite; + border-collapse: separate; + margin-top: 15px; + margin-bottom: 25px; } + +.line-nums-table tbody { + border: none; } + +.line-nums-table td pre { + border: none; + background-color: transparent; } + +.line-nums-table td.blob-line-nums { + width: 28px; } + +.line-nums-table td.blob-line-nums pre { + color: #b0b0b0; + -webkit-filter: opacity(75%); + text-align: right; + border-color: transparent; + background-color: transparent; + padding-left: 0px; + margin-left: 0px; + padding-right: 0px; + margin-right: 0px; } + + table { max-width: 100%; background-color: transparent; + margin-top: 0.5em; + margin-bottom: 1.5em; border-collapse: collapse; - border-spacing: 0; } - -table th, table td { - padding: 0px 8px 0px; + border-color: #ccc; + border-spacing: 0; + font-size: 0.9em; } -.table { - width: 100%; - margin-bottom: 20px; } +table th, table td { + padding: 0px 0.5em 0px; +} -.table th, -.table td { - padding: 8px; - line-height: 20px; - text-align: left; - vertical-align: top; - border-top: 1px solid #444444; } - -.table th { +table th { + background-color: #e8e8e8; font-weight: bold; } -.table thead th { - vertical-align: bottom; } +table th.docinfo-name { + background-color: transparent; +} -.table caption + thead tr:first-child th, -.table caption + thead tr:first-child td, -.table colgroup + thead tr:first-child th, -.table colgroup + thead tr:first-child td, -.table thead:first-child tr:first-child th, -.table thead:first-child tr:first-child td { - border-top: 0; } +table tr:hover { + background-color: ghostwhite; } -.table tbody + tbody { - border-top: 2px solid #444444; } - -.table .table { - background-color: rgba(252, 248, 244, 0.75); } - -.table-condensed th, -.table-condensed td { - padding: 4px 5px; } - -.table-bordered { - border: 1px solid #444444; - border-collapse: separate; - *border-collapse: collapse; - border-left: 0; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; } - -.table-bordered th, -.table-bordered td { - border-left: 1px solid #444444; } - -.table-bordered caption + thead tr:first-child th, -.table-bordered caption + tbody tr:first-child th, -.table-bordered caption + tbody tr:first-child td, -.table-bordered colgroup + thead tr:first-child th, -.table-bordered colgroup + tbody tr:first-child th, -.table-bordered colgroup + tbody tr:first-child td, -.table-bordered thead:first-child tr:first-child th, -.table-bordered tbody:first-child tr:first-child th, -.table-bordered tbody:first-child tr:first-child td { - border-top: 0; } - -.table-bordered thead:first-child tr:first-child > th:first-child, -.table-bordered tbody:first-child tr:first-child > td:first-child, -.table-bordered tbody:first-child tr:first-child > th:first-child { - -webkit-border-top-left-radius: 4px; - border-top-left-radius: 4px; - -moz-border-radius-topleft: 4px; } - -.table-bordered thead:first-child tr:first-child > th:last-child, -.table-bordered tbody:first-child tr:first-child > td:last-child, -.table-bordered tbody:first-child tr:first-child > th:last-child { - -webkit-border-top-right-radius: 4px; - border-top-right-radius: 4px; - -moz-border-radius-topright: 4px; } - -.table-bordered thead:last-child tr:last-child > th:first-child, -.table-bordered tbody:last-child tr:last-child > td:first-child, -.table-bordered tbody:last-child tr:last-child > th:first-child, -.table-bordered tfoot:last-child tr:last-child > td:first-child, -.table-bordered tfoot:last-child tr:last-child > th:first-child { - -webkit-border-bottom-left-radius: 4px; - border-bottom-left-radius: 4px; - -moz-border-radius-bottomleft: 4px; } - -.table-bordered thead:last-child tr:last-child > th:last-child, -.table-bordered tbody:last-child tr:last-child > td:last-child, -.table-bordered tbody:last-child tr:last-child > th:last-child, -.table-bordered tfoot:last-child tr:last-child > td:last-child, -.table-bordered tfoot:last-child tr:last-child > th:last-child { - -webkit-border-bottom-right-radius: 4px; - border-bottom-right-radius: 4px; - -moz-border-radius-bottomright: 4px; } - -.table-bordered tfoot + tbody:last-child tr:last-child td:first-child { - -webkit-border-bottom-left-radius: 0; - border-bottom-left-radius: 0; - -moz-border-radius-bottomleft: 0; } - -.table-bordered tfoot + tbody:last-child tr:last-child td:last-child { - -webkit-border-bottom-right-radius: 0; - border-bottom-right-radius: 0; - -moz-border-radius-bottomright: 0; } - -.table-bordered caption + thead tr:first-child th:first-child, -.table-bordered caption + tbody tr:first-child td:first-child, -.table-bordered colgroup + thead tr:first-child th:first-child, -.table-bordered colgroup + tbody tr:first-child td:first-child { - -webkit-border-top-left-radius: 4px; - border-top-left-radius: 4px; - -moz-border-radius-topleft: 4px; } - -.table-bordered caption + thead tr:first-child th:last-child, -.table-bordered caption + tbody tr:first-child td:last-child, -.table-bordered colgroup + thead tr:first-child th:last-child, -.table-bordered colgroup + tbody tr:first-child td:last-child { - -webkit-border-top-right-radius: 4px; - border-top-right-radius: 4px; - -moz-border-radius-topright: 4px; } - -table.docutils th { - background-color: #e8e8e8; } - -table.docutils tr:hover { - background-color: whitesmoke; } - -.table-striped tbody > tr:nth-child(odd) > td, -.table-striped tbody > tr:nth-child(odd) > th { - background-color: rgba(252, 248, 244, 0.75); } - -.table-hover tbody tr:hover > td, -.table-hover tbody tr:hover > th { - background-color: rgba(241, 222, 204, 0.75); } - -table td[class*="span"], -table th[class*="span"], -.row-fluid table td[class*="span"], -.row-fluid table th[class*="span"] { - display: table-cell; - float: none; - margin-left: 0; } - -.hero-unit { - padding: 60px; - margin-bottom: 30px; - font-size: 18px; - font-weight: 200; - line-height: 30px; - color: inherit; - background-color: rgba(230, 197, 164, 0.75); - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; } - -.hero-unit h1 { - margin-bottom: 0; - font-size: 60px; - line-height: 1; - letter-spacing: -1px; - color: inherit; } - -.hero-unit li { - line-height: 30px; } /* rst2html default used to remove borders from tables and images */ .borderless, table.borderless td, table.borderless th { @@ -722,10 +499,6 @@ table.borderless td, table.borderless th { .hidden { display: none; } -a.toc-backref { - text-decoration: none; - color: #444444; } - blockquote.epigraph { margin: 2em 5em; } @@ -735,85 +508,6 @@ dl.docutils dd { object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] { overflow: hidden; } -/* Uncomment (and remove this text!) to get bold-faced definition list terms -dl.docutils dt { - font-weight: bold } -*/ -div.abstract { - margin: 2em 5em; } - -div.abstract p.topic-title { - font-weight: bold; - text-align: center; } - -div.admonition, div.attention, div.caution, div.danger, div.error, -div.hint, div.important, div.note, div.tip, div.warning { - margin: 2em; - border: medium outset; - padding: 1em; } - -div.note, div.warning { - margin: 1.5em 0px; - border: none; } - -div.note p.admonition-title, -div.warning p.admonition-title { - display: none; } - -/* Clearfix - * http://css-tricks.com/snippets/css/clear-fix/ - */ -div.note:after, -div.warning:after { - content: ""; - display: table; - clear: both; } - -div.note p:before, -div.warning p:before { - display: block; - float: left; - font-size: 4em; - line-height: 1em; - margin-right: 20px; - margin-left: 0em; - margin-top: -10px; - content: '\0270D'; - /*handwriting*/ } - -div.warning p:before { - content: '\026A0'; - /*warning*/ } - -div.admonition p.admonition-title, div.hint p.admonition-title, -div.important p.admonition-title, div.note p.admonition-title, -div.tip p.admonition-title { - font-weight: bold; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } - -div.attention p.admonition-title, div.caution p.admonition-title, -div.danger p.admonition-title, div.error p.admonition-title, -div.warning p.admonition-title, .code .error { - color: #b30000; - font-weight: bold; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } - -/* Uncomment (and remove this text!) to get reduced vertical space in - compound paragraphs. -div.compound .compound-first, div.compound .compound-middle { - margin-bottom: 0.5em } - -div.compound .compound-last, div.compound .compound-middle { - margin-top: 0.5em } -*/ -div.dedication { - margin: 2em 5em; - text-align: center; - font-style: italic; } - -div.dedication p.topic-title { - font-weight: bold; - font-style: normal; } div.figure { margin-left: 2em; @@ -821,8 +515,14 @@ div.figure { div.footer, div.header { clear: both; + text-align: center; + color: #666; font-size: smaller; } +div.footer { + padding-top: 5em; +} + div.line-block { display: block; margin-top: 1em; @@ -833,45 +533,24 @@ div.line-block div.line-block { margin-bottom: 0; margin-left: 1.5em; } -div.sidebar { - margin: 0 0 0.5em 1em; - border: medium outset; - padding: 1em; - background-color: rgba(252, 248, 244, 0.75); - width: 40%; - float: right; - clear: right; } - -div.sidebar p.rubric { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-size: medium; } - -div.system-messages { - margin: 5em; } - -div.system-messages h1 { - color: #b30000; } - -div.system-message { - border: medium outset; - padding: 1em; } - -div.system-message p.system-message-title { - color: #b30000; - font-weight: bold; } - div.topic { margin: 2em; } -h1.section-subtitle, h2.section-subtitle, h3.section-subtitle, -h4.section-subtitle, h5.section-subtitle, h6.section-subtitle { - margin-top: 0.4em; } +div.search_results { + background-color: antiquewhite; + margin: 3em; + padding: 1em; + border: 1px solid #4d4d4d; +} -h1.title { - text-align: center; } +div#global-links ul { + margin-left: 0; + list-style-type: none; +} -h2.subtitle { - text-align: center; } +div#global-links > simple-boot { + margin-left: 3em; +} hr.docutils { width: 75%; } @@ -905,30 +584,6 @@ img.align-center, .figure.align-center, object.align-center { div.align-right { text-align: inherit; } -/* div.align-center * { */ -/* text-align: left } */ - -ul.simple > li { - margin-bottom: 0.5em } - -ol.simple, ul.simple { - margin-bottom: 1em; } - -ol.arabic { - list-style: decimal; } - -ol.loweralpha { - list-style: lower-alpha; } - -ol.upperalpha { - list-style: upper-alpha; } - -ol.lowerroman { - list-style: lower-roman; } - -ol.upperroman { - list-style: upper-roman; } - p.attribution { text-align: right; margin-left: 50%; } @@ -949,15 +604,6 @@ p.rubric { color: maroon; text-align: center; } -p.sidebar-title { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-weight: bold; - font-size: larger; } - -p.sidebar-subtitle { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-weight: bold; } - p.topic-title { font-weight: bold; } @@ -997,22 +643,14 @@ pre.code .inserted, code .inserted { background-color: #A3D289; } span.classifier { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-style: oblique; } span.classifier-delimiter { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: bold; } -span.interpreted { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } - span.option { white-space: nowrap; } -span.pre { - white-space: pre; } - span.problematic { color: #b30000; } @@ -1020,44 +658,6 @@ span.section-subtitle { /* font-size relative to parent (h1..h6 element) */ font-size: 80%; } -table.citation { - border-left: solid 1px #666666; - margin-left: 1px; } - -table.docinfo { - margin: 0em; - margin-top: 2em; - margin-bottom: 2em; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; - color: #444444; } - -table.docutils { - margin-top: 0.5em; - margin-bottom: 0.5em; } - -table.footnote { - border-left: solid 1px #2d2d2d; - margin-left: 1px; } - -table.docutils td, table.docutils th, -table.docinfo td, table.docinfo th { - padding-left: 0.5em; - padding-right: 0.5em; - vertical-align: top; } - -table.docutils th.field-name, table.docinfo th.docinfo-name { - font-weight: 700; - text-align: left; - white-space: nowrap; - padding-left: 0; } - -h1 tt.docutils, h2 tt.docutils, h3 tt.docutils, -h4 tt.docutils, h5 tt.docutils, h6 tt.docutils { - font-size: 100%; } - -ul.auto-toc { - list-style-type: none; } - span.DecNumber { color: #252dbe; } @@ -1074,7 +674,7 @@ span.FloatNumber { color: #252dbe; } span.Identifier { - color: #3b3b3b; } + color: #222; } span.Keyword { font-weight: 600; @@ -1139,38 +739,23 @@ dt pre > span.Identifier, dt pre > span.Operator { color: #155da4; font-weight: 700; } -dt pre > span.Identifier ~ span.Identifier, dt pre > span.Operator ~ span.Identifier { - color: inherit; - font-weight: inherit; } - -dt pre > span.Operator ~ span.Identifier { +dt pre > span.Keyword ~ span.Identifier, dt pre > span.Identifier ~ span.Identifier, +dt pre > span.Operator ~ span.Identifier, dt pre > span.Other ~ span.Identifier { color: inherit; font-weight: inherit; } /* Nim sprite for the footer (taken from main page favicon) */ .nim-sprite { display: inline-block; - height: 12px; - width: 12px; + height: 16px; + width: 16px; background-position: 0 0; - background-size: 12px 12px; + background-size: 16px 16px; -webkit-filter: opacity(50%); background-repeat: no-repeat; background-image: url("data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="); margin-bottom: -5px; } -div.search_results { - background-color: antiquewhite; - margin: 3em; - padding: 1em; - border: 1px solid #4d4d4d; -} - -div#global-links ul { - margin-left: 0; - list-style-type: none; -} - span.pragmadots { /* Position: relative frees us up to make the dots look really nice without fucking up the layout and @@ -1178,18 +763,14 @@ span.pragmadots { position: relative; /* 1px down looks slightly nicer */ top: 1px; - padding: 2px; - background-color: #D3D3D3; + background-color: #e8e8e8; border-radius: 4px; margin: 0 2px; cursor: pointer; - - /* For some reason on Chrome, making the font size - smaller than 1em is causing the parent container to - bulge slightly. So, we're stuck with inheriting 1em, - which is sad, because 0.8em looks better... */ + font-size: 0.8em; } + span.pragmadots:hover { background-color: #DBDBDB; } @@ -1197,6 +778,10 @@ span.pragmawrap { display: none; } +span.attachedType { + display: none; + visibility: hidden; +} @@ -1245,9 +830,9 @@ function main() { title="Symbol = object name*: string parent*: string - kind*: NimSymKind">Symbol + kind*: NimSymKind">Symbol
    • OnSymbol
    • + title="OnSymbol = proc (sym: var Symbol) {.cdecl.}">OnSymbol
    @@ -1257,6 +842,7 @@ function main() {
    +

    Types

    @@ -1270,12 +856,14 @@ function main() {
    +
    OnSymbol = proc (sym: var Symbol) {...}{.cdecl.}
    +
    @@ -1287,7 +875,7 @@ function main() {
    diff --git a/theindex.html b/theindex.html index e69ee32..25d0083 100644 --- a/theindex.html +++ b/theindex.html @@ -27,232 +27,130 @@ customize this style sheet. Modified from Chad Skeeters' rst2html-style https://bitbucket.org/cskeeters/rst2html-style/ -Modified by Boyd Greenfield +Modified by Boyd Greenfield and narimiran */ -/* SCSS variables */ -/* Text weights */ -/* Body colors */ -/* Text colors */ -/* Link colors */ -/* Syntax highlighting colors */ -/* Pct changes */ -/* Mixins */ -/* Body/layout */ + html { font-size: 100%; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; } -/* Where we want fancier font if available */ -h1, h2, h3, h4, h5, h6, p.module-desc, table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; } - -h1.title { - font-weight: 900; } - body { font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: 400; - font-size: 16px; - line-height: 20px; - color: #444; - letter-spacing: 0.15px; - background-color: #FDFBFA; } + font-size: 1.125em; + line-height: 1.5; + color: #222; + background-color: #FCFCFC; } /* Skeleton grid */ .container { position: relative; width: 100%; - max-width: 960px; + max-width: 1050px; margin: 0 auto; - padding: 0 20px; + padding: 0; box-sizing: border-box; } .column, .columns { width: 100%; float: left; - box-sizing: border-box; } + box-sizing: border-box; + margin-left: 1%; +} -/* For devices larger than 400px */ -@media (min-width: 400px) { - .container { - width: 100%; - padding: 0; } } -/* For devices larger than 650px */ -@media (min-width: 650px) { - .container { - width: 100%; } +.column:first-child, +.columns:first-child { + margin-left: 0; } - .column, - .columns { - margin-left: 4%; } +.three.columns { + width: 19%; } - .column:first-child, - .columns:first-child { - margin-left: 0; } +.nine.columns { + width: 80.0%; } - .one.column, - .one.columns { - width: 4.66666666667%; } - - .two.columns { - width: 13.3333333333%; } +.twelve.columns { + width: 100%; + margin-left: 0; } +@media screen and (max-width: 860px) { .three.columns { - width: 22%; } - - .four.columns { - width: 30.6666666667%; } - - .five.columns { - width: 39.3333333333%; } - - .six.columns { - width: 48%; } - - .seven.columns { - width: 56.6666666667%; } - - .eight.columns { - width: 65.3333333333%; } - + display: none; + } .nine.columns { - width: 74.0%; } - - .ten.columns { - width: 82.6666666667%; } - - .eleven.columns { - width: 91.3333333333%; } - - .twelve.columns { - width: 100%; - margin-left: 0; } - - .one-third.column { - width: 30.6666666667%; } - - .two-thirds.column { - width: 65.3333333333%; } } -/* Customer Overrides */ -.footer { - text-align: center; - color: #969696; - padding-top: 10%; } - -p.module-desc { - font-size: 1.1em; - color: #666666; } - -a.link-seesrc { - color: #aec7d2; - font-style: italic; } - -a.link-seesrc:hover { - color: #6c9aae; } - -#toc-list { - word-wrap: break-word; } - -ul.simple-toc { - list-style: none; } - -ul.simple-toc a.reference-toplevel { - font-weight: bold; - color: #0077b3; } - -ul.simple-toc-section { - list-style-type: circle; - color: #6c9aae; } - -ul.simple-toc-section a.reference { - color: #0077b3; } + width: 98.0%; + } + body { + font-size: 1em; + line-height: 1.35; + } +} cite { font-style: italic !important; } -dt > pre { - border-color: rgba(0, 0, 0, 0.1); - background-color: rgba(255, 255, 255, 0.3); - margin: 15px 0px 5px; } - -dd > pre { - border-color: rgba(0, 0, 0, 0.1); - background-color: whitesmoke; - margin-top: 8px; } - -.item > dd { - margin-left: 10px; - margin-bottom: 30px; } - -/* Nim line-numbered tables */ -.line-nums-table { - width: 100%; - table-layout: fixed; } /* Nim search input */ div#searchInputDiv { - margin-bottom: 8px; + margin-bottom: 1em; } -div#searchInputDiv input#searchInput { - width: 10em; -} -div.search-groupby { - margin-bottom: 8px; +input#searchInput { + width: 80%; } -table.line-nums-table { - border-radius: 4px; - border: 1px solid #cccccc; - background-color: whitesmoke; - border-collapse: separate; - margin-top: 15px; - margin-bottom: 25px; } - -.line-nums-table tbody { - border: none; } - -.line-nums-table td pre { - border: none; - background-color: transparent; } - -.line-nums-table td.blob-line-nums { - width: 28px; } - -.line-nums-table td.blob-line-nums pre { - color: #b0b0b0; - -webkit-filter: opacity(75%); - text-align: right; - border-color: transparent; - background-color: transparent; - padding-left: 0px; - margin-left: 0px; - padding-right: 0px; - margin-right: 0px; } +/* + * Some custom formatting for input forms. + * This also fixes input form colors on Firefox with a dark system theme on Linux. + */ +input { + -moz-appearance: none; + color: #333; + background-color: #f8f8f8; + border: 1px solid #aaa; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-size: 0.9em; + padding: 6px; +} +input:focus { + border: 1px solid #1fa0eb; + box-shadow: 0 0 2px #1fa0eb; +} /* Docgen styles */ /* Links */ a { - color: #0077b3; - text-decoration: none; } + color: #07b; + text-decoration: none; +} + +a span.Identifier { + text-decoration: underline; + text-decoration-color: #aab; +} + +a.reference-toplevel { + font-weight: bold; +} + +a.toc-backref { + text-decoration: none; + color: #222; } + +a.link-seesrc { + color: #607c9f; + font-size: 0.9em; + font-style: italic; } a:hover, a:focus { - color: #00334d; + color: #607c9f; text-decoration: underline; } -a:visited { - color: #00334d; } +a:hover span.Identifier { + color: #607c9f; +} -a:focus { - outline: thin dotted #2d2d2d; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; } - -a:hover, -a:active { - outline: 0; } sub, sup { @@ -329,379 +227,258 @@ img { h2, h3 { - page-break-after: avoid; } } -.img-rounded { - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; } + page-break-after: avoid; } +} -.img-polaroid { - padding: 4px; - background-color: rgba(252, 248, 244, 0.75); - border: 1px solid #ccc; - border: 1px solid rgba(0, 0, 0, 0.2); - -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); - -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); } p { - margin: 0 0 8px; } + margin-top: 0.5em; + margin-bottom: 0.5em; +} small { font-size: 85%; } strong { - font-weight: 600; } + font-weight: 600; + font-size: 0.95em; + color: #3c3c3c; +} em { font-style: italic; } -cite { - font-style: normal; } - -h1, -h2, -h3, -h4, -h5, -h6 { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-weight: 600; - line-height: 20px; - color: inherit; - text-rendering: optimizelegibility; } - h1 { - font-size: 2em; + font-size: 1.8em; font-weight: 400; - padding-bottom: .15em; - border-bottom: 1px solid #aaaaaa; - margin-top: 1.0em; + padding-bottom: .25em; + border-bottom: 1px solid #aaa; + margin-top: 2.5em; + margin-bottom: 1em; line-height: 1.2em; } h1.title { padding-bottom: 1em; border-bottom: 0px; - font-size: 2.75em; } + font-size: 2.5em; + text-align: center; + font-weight: 900; + margin-top: 0.75em; + margin-bottom: 0em; +} h2 { - font-size: 1.5em; - margin-top: 1.5em; } + font-size: 1.3em; + margin-top: 2em; } + +h2.subtitle { + text-align: center; } h3 { - font-size: 1.3em; + font-size: 1.125em; font-style: italic; - margin-top: 0.75em; } + margin-top: 1.5em; } h4 { - font-size: 1.3em; - margin-top: 0.5em; } + font-size: 1.125em; + margin-top: 1em; } h5 { - font-size: 1.2em; - margin-top: 0.25em; } + font-size: 1.125em; + margin-top: 0.75em; } h6 { font-size: 1.1em; } + ul, ol { padding: 0; - margin: 0 0 0px 15px; } + margin-top: 0.5em; + margin-left: 0.75em; } ul ul, ul ol, ol ol, ol ul { - margin-bottom: 0; } + margin-bottom: 0; + margin-left: 1.25em; } li { - line-height: 20px; } - -dl { - margin-bottom: 20px; } - -dt, -dd { - line-height: 20px; } - -dt { - font-weight: bold; } - -dd { - margin-left: 10px; - margin-bottom: 26px; } - -hr { - margin: 20px 0; - border: 0; - border-top: 1px solid #eeeeee; - border-bottom: 1px solid #ffffff; } - -abbr[title], -abbr[data-original-title] { - cursor: help; - border-bottom: 1px dotted #999999; } - -abbr.initialism { - font-size: 90%; - text-transform: uppercase; } - -blockquote { - padding: 0 0 0 15px; - margin: 0 0 20px; - border-left: 5px solid #EFEBE0; } - -table.docinfo + blockquote, table.docinfo blockquote, h1 + blockquote { - border-left: 5px solid #c9c9c9; + list-style-type: circle; } -table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { - margin-bottom: 0; - font-size: 15px; - font-weight: 200; - line-height: 1.5; - font-style: italic; } +ul.simple-boot li { + list-style-type: none; + margin-left: 0em; + margin-bottom: 0.5em; +} -q:before, -q:after, -blockquote:before, -blockquote:after { - content: ""; } +ol.simple > li, ul.simple > li { + margin-bottom: 0.25em; + margin-left: 0.4em } -address { - display: block; - margin-bottom: 20px; - font-style: normal; - line-height: 20px; } +ul.simple.simple-toc > li { + margin-top: 1em; +} -code, -pre { - font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - padding: 0 3px 2px; - font-weight: 500; - font-size: 12px; - color: #444444; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; } +ul.simple-toc { + list-style: none; + font-size: 0.9em; + margin-left: -0.3em; + margin-top: 1em; } + +ul.simple-toc > li { + list-style-type: none; +} + +ul.simple-toc-section { + list-style-type: circle; + margin-left: 1em; + color: #6c9aae; } + + +ol.arabic { + list-style: decimal; } + +ol.loweralpha { + list-style: lower-alpha; } + +ol.upperalpha { + list-style: upper-alpha; } + +ol.lowerroman { + list-style: lower-roman; } + +ol.upperroman { + list-style: upper-roman; } + +ul.auto-toc { + list-style-type: none; } + + +dl { + margin-bottom: 1.5em; } + +dt { + margin-bottom: -0.5em; + margin-left: 0.0em; } + +dd { + margin-left: 2.0em; + margin-bottom: 3.0em; + margin-top: 0.5em; } + + +hr { + margin: 2em 0; + border: 0; + border-top: 1px solid #aaa; } + +blockquote { + font-size: 0.9em; + font-style: italic; + padding-left: 0.5em; + margin-left: 0; + border-left: 5px solid #bbc; +} .pre { font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - font-weight: 600; - /*color: #504da6;*/ + font-weight: 500; + font-size: 0.85em; + background-color: #f0f3ff; + padding-left: 3px; + padding-right: 3px; + border-radius: 4px; } -code { - padding: 2px 4px; - color: #444444; - white-space: nowrap; - background-color: white; - border: 1px solid #777777; } - pre { + font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; + color: #222; + font-weight: 500; display: inline-block; box-sizing: border-box; - min-width: calc(100% - 19.5px); - padding: 9.5px; - margin: 0.25em 10px 10px 10px; - font-size: 15px; - line-height: 20px; + min-width: 100%; + padding: 0.5em; + margin-top: 0.5em; + margin-bottom: 0.5em; + font-size: 0.85em; white-space: pre !important; overflow-y: hidden; overflow-x: visible; - background-color: rgba(0, 0, 0, 0.01); - border: 1px solid #cccccc; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; } - -pre.prettyprint { - margin-bottom: 20px; } - -pre code { - padding: 0; - color: inherit; - white-space: pre; - overflow-x: visible; - background-color: transparent; - border: 0; } + background-color: ghostwhite; + border: 1px solid #dde; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; } .pre-scrollable { max-height: 340px; overflow-y: scroll; } + +/* Nim line-numbered tables */ +.line-nums-table { + width: 100%; + table-layout: fixed; } + +table.line-nums-table { + border-radius: 4px; + border: 1px solid #cccccc; + background-color: ghostwhite; + border-collapse: separate; + margin-top: 15px; + margin-bottom: 25px; } + +.line-nums-table tbody { + border: none; } + +.line-nums-table td pre { + border: none; + background-color: transparent; } + +.line-nums-table td.blob-line-nums { + width: 28px; } + +.line-nums-table td.blob-line-nums pre { + color: #b0b0b0; + -webkit-filter: opacity(75%); + text-align: right; + border-color: transparent; + background-color: transparent; + padding-left: 0px; + margin-left: 0px; + padding-right: 0px; + margin-right: 0px; } + + table { max-width: 100%; background-color: transparent; + margin-top: 0.5em; + margin-bottom: 1.5em; border-collapse: collapse; - border-spacing: 0; } - -table th, table td { - padding: 0px 8px 0px; + border-color: #ccc; + border-spacing: 0; + font-size: 0.9em; } -.table { - width: 100%; - margin-bottom: 20px; } +table th, table td { + padding: 0px 0.5em 0px; +} -.table th, -.table td { - padding: 8px; - line-height: 20px; - text-align: left; - vertical-align: top; - border-top: 1px solid #444444; } - -.table th { +table th { + background-color: #e8e8e8; font-weight: bold; } -.table thead th { - vertical-align: bottom; } +table th.docinfo-name { + background-color: transparent; +} -.table caption + thead tr:first-child th, -.table caption + thead tr:first-child td, -.table colgroup + thead tr:first-child th, -.table colgroup + thead tr:first-child td, -.table thead:first-child tr:first-child th, -.table thead:first-child tr:first-child td { - border-top: 0; } +table tr:hover { + background-color: ghostwhite; } -.table tbody + tbody { - border-top: 2px solid #444444; } - -.table .table { - background-color: rgba(252, 248, 244, 0.75); } - -.table-condensed th, -.table-condensed td { - padding: 4px 5px; } - -.table-bordered { - border: 1px solid #444444; - border-collapse: separate; - *border-collapse: collapse; - border-left: 0; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; } - -.table-bordered th, -.table-bordered td { - border-left: 1px solid #444444; } - -.table-bordered caption + thead tr:first-child th, -.table-bordered caption + tbody tr:first-child th, -.table-bordered caption + tbody tr:first-child td, -.table-bordered colgroup + thead tr:first-child th, -.table-bordered colgroup + tbody tr:first-child th, -.table-bordered colgroup + tbody tr:first-child td, -.table-bordered thead:first-child tr:first-child th, -.table-bordered tbody:first-child tr:first-child th, -.table-bordered tbody:first-child tr:first-child td { - border-top: 0; } - -.table-bordered thead:first-child tr:first-child > th:first-child, -.table-bordered tbody:first-child tr:first-child > td:first-child, -.table-bordered tbody:first-child tr:first-child > th:first-child { - -webkit-border-top-left-radius: 4px; - border-top-left-radius: 4px; - -moz-border-radius-topleft: 4px; } - -.table-bordered thead:first-child tr:first-child > th:last-child, -.table-bordered tbody:first-child tr:first-child > td:last-child, -.table-bordered tbody:first-child tr:first-child > th:last-child { - -webkit-border-top-right-radius: 4px; - border-top-right-radius: 4px; - -moz-border-radius-topright: 4px; } - -.table-bordered thead:last-child tr:last-child > th:first-child, -.table-bordered tbody:last-child tr:last-child > td:first-child, -.table-bordered tbody:last-child tr:last-child > th:first-child, -.table-bordered tfoot:last-child tr:last-child > td:first-child, -.table-bordered tfoot:last-child tr:last-child > th:first-child { - -webkit-border-bottom-left-radius: 4px; - border-bottom-left-radius: 4px; - -moz-border-radius-bottomleft: 4px; } - -.table-bordered thead:last-child tr:last-child > th:last-child, -.table-bordered tbody:last-child tr:last-child > td:last-child, -.table-bordered tbody:last-child tr:last-child > th:last-child, -.table-bordered tfoot:last-child tr:last-child > td:last-child, -.table-bordered tfoot:last-child tr:last-child > th:last-child { - -webkit-border-bottom-right-radius: 4px; - border-bottom-right-radius: 4px; - -moz-border-radius-bottomright: 4px; } - -.table-bordered tfoot + tbody:last-child tr:last-child td:first-child { - -webkit-border-bottom-left-radius: 0; - border-bottom-left-radius: 0; - -moz-border-radius-bottomleft: 0; } - -.table-bordered tfoot + tbody:last-child tr:last-child td:last-child { - -webkit-border-bottom-right-radius: 0; - border-bottom-right-radius: 0; - -moz-border-radius-bottomright: 0; } - -.table-bordered caption + thead tr:first-child th:first-child, -.table-bordered caption + tbody tr:first-child td:first-child, -.table-bordered colgroup + thead tr:first-child th:first-child, -.table-bordered colgroup + tbody tr:first-child td:first-child { - -webkit-border-top-left-radius: 4px; - border-top-left-radius: 4px; - -moz-border-radius-topleft: 4px; } - -.table-bordered caption + thead tr:first-child th:last-child, -.table-bordered caption + tbody tr:first-child td:last-child, -.table-bordered colgroup + thead tr:first-child th:last-child, -.table-bordered colgroup + tbody tr:first-child td:last-child { - -webkit-border-top-right-radius: 4px; - border-top-right-radius: 4px; - -moz-border-radius-topright: 4px; } - -table.docutils th { - background-color: #e8e8e8; } - -table.docutils tr:hover { - background-color: whitesmoke; } - -.table-striped tbody > tr:nth-child(odd) > td, -.table-striped tbody > tr:nth-child(odd) > th { - background-color: rgba(252, 248, 244, 0.75); } - -.table-hover tbody tr:hover > td, -.table-hover tbody tr:hover > th { - background-color: rgba(241, 222, 204, 0.75); } - -table td[class*="span"], -table th[class*="span"], -.row-fluid table td[class*="span"], -.row-fluid table th[class*="span"] { - display: table-cell; - float: none; - margin-left: 0; } - -.hero-unit { - padding: 60px; - margin-bottom: 30px; - font-size: 18px; - font-weight: 200; - line-height: 30px; - color: inherit; - background-color: rgba(230, 197, 164, 0.75); - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; } - -.hero-unit h1 { - margin-bottom: 0; - font-size: 60px; - line-height: 1; - letter-spacing: -1px; - color: inherit; } - -.hero-unit li { - line-height: 30px; } /* rst2html default used to remove borders from tables and images */ .borderless, table.borderless td, table.borderless th { @@ -722,10 +499,6 @@ table.borderless td, table.borderless th { .hidden { display: none; } -a.toc-backref { - text-decoration: none; - color: #444444; } - blockquote.epigraph { margin: 2em 5em; } @@ -735,85 +508,6 @@ dl.docutils dd { object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] { overflow: hidden; } -/* Uncomment (and remove this text!) to get bold-faced definition list terms -dl.docutils dt { - font-weight: bold } -*/ -div.abstract { - margin: 2em 5em; } - -div.abstract p.topic-title { - font-weight: bold; - text-align: center; } - -div.admonition, div.attention, div.caution, div.danger, div.error, -div.hint, div.important, div.note, div.tip, div.warning { - margin: 2em; - border: medium outset; - padding: 1em; } - -div.note, div.warning { - margin: 1.5em 0px; - border: none; } - -div.note p.admonition-title, -div.warning p.admonition-title { - display: none; } - -/* Clearfix - * http://css-tricks.com/snippets/css/clear-fix/ - */ -div.note:after, -div.warning:after { - content: ""; - display: table; - clear: both; } - -div.note p:before, -div.warning p:before { - display: block; - float: left; - font-size: 4em; - line-height: 1em; - margin-right: 20px; - margin-left: 0em; - margin-top: -10px; - content: '\0270D'; - /*handwriting*/ } - -div.warning p:before { - content: '\026A0'; - /*warning*/ } - -div.admonition p.admonition-title, div.hint p.admonition-title, -div.important p.admonition-title, div.note p.admonition-title, -div.tip p.admonition-title { - font-weight: bold; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } - -div.attention p.admonition-title, div.caution p.admonition-title, -div.danger p.admonition-title, div.error p.admonition-title, -div.warning p.admonition-title, .code .error { - color: #b30000; - font-weight: bold; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } - -/* Uncomment (and remove this text!) to get reduced vertical space in - compound paragraphs. -div.compound .compound-first, div.compound .compound-middle { - margin-bottom: 0.5em } - -div.compound .compound-last, div.compound .compound-middle { - margin-top: 0.5em } -*/ -div.dedication { - margin: 2em 5em; - text-align: center; - font-style: italic; } - -div.dedication p.topic-title { - font-weight: bold; - font-style: normal; } div.figure { margin-left: 2em; @@ -821,8 +515,14 @@ div.figure { div.footer, div.header { clear: both; + text-align: center; + color: #666; font-size: smaller; } +div.footer { + padding-top: 5em; +} + div.line-block { display: block; margin-top: 1em; @@ -833,45 +533,24 @@ div.line-block div.line-block { margin-bottom: 0; margin-left: 1.5em; } -div.sidebar { - margin: 0 0 0.5em 1em; - border: medium outset; - padding: 1em; - background-color: rgba(252, 248, 244, 0.75); - width: 40%; - float: right; - clear: right; } - -div.sidebar p.rubric { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-size: medium; } - -div.system-messages { - margin: 5em; } - -div.system-messages h1 { - color: #b30000; } - -div.system-message { - border: medium outset; - padding: 1em; } - -div.system-message p.system-message-title { - color: #b30000; - font-weight: bold; } - div.topic { margin: 2em; } -h1.section-subtitle, h2.section-subtitle, h3.section-subtitle, -h4.section-subtitle, h5.section-subtitle, h6.section-subtitle { - margin-top: 0.4em; } +div.search_results { + background-color: antiquewhite; + margin: 3em; + padding: 1em; + border: 1px solid #4d4d4d; +} -h1.title { - text-align: center; } +div#global-links ul { + margin-left: 0; + list-style-type: none; +} -h2.subtitle { - text-align: center; } +div#global-links > simple-boot { + margin-left: 3em; +} hr.docutils { width: 75%; } @@ -905,30 +584,6 @@ img.align-center, .figure.align-center, object.align-center { div.align-right { text-align: inherit; } -/* div.align-center * { */ -/* text-align: left } */ - -ul.simple > li { - margin-bottom: 0.5em } - -ol.simple, ul.simple { - margin-bottom: 1em; } - -ol.arabic { - list-style: decimal; } - -ol.loweralpha { - list-style: lower-alpha; } - -ol.upperalpha { - list-style: upper-alpha; } - -ol.lowerroman { - list-style: lower-roman; } - -ol.upperroman { - list-style: upper-roman; } - p.attribution { text-align: right; margin-left: 50%; } @@ -949,15 +604,6 @@ p.rubric { color: maroon; text-align: center; } -p.sidebar-title { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-weight: bold; - font-size: larger; } - -p.sidebar-subtitle { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-weight: bold; } - p.topic-title { font-weight: bold; } @@ -997,22 +643,14 @@ pre.code .inserted, code .inserted { background-color: #A3D289; } span.classifier { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-style: oblique; } span.classifier-delimiter { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: bold; } -span.interpreted { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } - span.option { white-space: nowrap; } -span.pre { - white-space: pre; } - span.problematic { color: #b30000; } @@ -1020,44 +658,6 @@ span.section-subtitle { /* font-size relative to parent (h1..h6 element) */ font-size: 80%; } -table.citation { - border-left: solid 1px #666666; - margin-left: 1px; } - -table.docinfo { - margin: 0em; - margin-top: 2em; - margin-bottom: 2em; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; - color: #444444; } - -table.docutils { - margin-top: 0.5em; - margin-bottom: 0.5em; } - -table.footnote { - border-left: solid 1px #2d2d2d; - margin-left: 1px; } - -table.docutils td, table.docutils th, -table.docinfo td, table.docinfo th { - padding-left: 0.5em; - padding-right: 0.5em; - vertical-align: top; } - -table.docutils th.field-name, table.docinfo th.docinfo-name { - font-weight: 700; - text-align: left; - white-space: nowrap; - padding-left: 0; } - -h1 tt.docutils, h2 tt.docutils, h3 tt.docutils, -h4 tt.docutils, h5 tt.docutils, h6 tt.docutils { - font-size: 100%; } - -ul.auto-toc { - list-style-type: none; } - span.DecNumber { color: #252dbe; } @@ -1074,7 +674,7 @@ span.FloatNumber { color: #252dbe; } span.Identifier { - color: #3b3b3b; } + color: #222; } span.Keyword { font-weight: 600; @@ -1139,38 +739,23 @@ dt pre > span.Identifier, dt pre > span.Operator { color: #155da4; font-weight: 700; } -dt pre > span.Identifier ~ span.Identifier, dt pre > span.Operator ~ span.Identifier { - color: inherit; - font-weight: inherit; } - -dt pre > span.Operator ~ span.Identifier { +dt pre > span.Keyword ~ span.Identifier, dt pre > span.Identifier ~ span.Identifier, +dt pre > span.Operator ~ span.Identifier, dt pre > span.Other ~ span.Identifier { color: inherit; font-weight: inherit; } /* Nim sprite for the footer (taken from main page favicon) */ .nim-sprite { display: inline-block; - height: 12px; - width: 12px; + height: 16px; + width: 16px; background-position: 0 0; - background-size: 12px 12px; + background-size: 16px 16px; -webkit-filter: opacity(50%); background-repeat: no-repeat; background-image: url("data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="); margin-bottom: -5px; } -div.search_results { - background-color: antiquewhite; - margin: 3em; - padding: 1em; - border: 1px solid #4d4d4d; -} - -div#global-links ul { - margin-left: 0; - list-style-type: none; -} - span.pragmadots { /* Position: relative frees us up to make the dots look really nice without fucking up the layout and @@ -1178,18 +763,14 @@ span.pragmadots { position: relative; /* 1px down looks slightly nicer */ top: 1px; - padding: 2px; - background-color: #D3D3D3; + background-color: #e8e8e8; border-radius: 4px; margin: 0 2px; cursor: pointer; - - /* For some reason on Chrome, making the font size - smaller than 1em is causing the parent container to - bulge slightly. So, we're stuck with inheriting 1em, - which is sad, because 0.8em looks better... */ + font-size: 0.8em; } + span.pragmadots:hover { background-color: #DBDBDB; } @@ -1197,6 +778,10 @@ span.pragmawrap { display: none; } +span.attachedType { + display: none; + visibility: hidden; +} @@ -1241,7 +826,7 @@ function main() {
cDebug:
  • cimport: cDebug()
  • + data-doc-search-tag="cimport: cDebug()" href="cimport.html#cDebug">cimport: cDebug()
cDefine:
cDisableCaching:
  • cimport: cDisableCaching()
  • + data-doc-search-tag="cimport: cDisableCaching()" href="cimport.html#cDisableCaching">cimport: cDisableCaching()
cImport:
cIncludeDir:
cmake:
cOverride:
cpFile:
cPlugin:
cSearchPath:
cSkipSymbol:
  • cimport: cSkipSymbol(skips: seq[string])
  • + data-doc-search-tag="cimport: cSkipSymbol(skips: seq[string])" href="cimport.html#cSkipSymbol%2Cseq%5BT%5D%5Bstring%5D">cimport: cSkipSymbol(skips: seq[string])
defineEnum:
  • types: defineEnum(typ)
  • + data-doc-search-tag="types: defineEnum(typ)" href="types.html#defineEnum.t">types: defineEnum(typ)
downloadUrl:
incDir:
  • paths: incDir(): string
  • + data-doc-search-tag="paths: incDir(): string" href="paths.html#incDir">paths: incDir(): string
make:
nimteropBuildDir:
nimteropRoot:
  • paths: nimteropRoot(): string
  • + data-doc-search-tag="paths: nimteropRoot(): string" href="paths.html#nimteropRoot">paths: nimteropRoot(): string
nimteropSrcDir:
OnSymbol:
testsIncludeDir:
time_t:
toastExePath:
  • paths: toastExePath(): string
  • + data-doc-search-tag="paths: toastExePath(): string" href="paths.html#toastExePath">paths: toastExePath(): string
va_list:

  • - Made with Nim. Generated: 2019-07-29 14:17:11 UTC + Made with Nim. Generated: 2019-07-30 00:08:28 UTC diff --git a/types.html b/types.html index a15d2da..f92679b 100644 --- a/types.html +++ b/types.html @@ -27,232 +27,130 @@ customize this style sheet. Modified from Chad Skeeters' rst2html-style https://bitbucket.org/cskeeters/rst2html-style/ -Modified by Boyd Greenfield +Modified by Boyd Greenfield and narimiran */ -/* SCSS variables */ -/* Text weights */ -/* Body colors */ -/* Text colors */ -/* Link colors */ -/* Syntax highlighting colors */ -/* Pct changes */ -/* Mixins */ -/* Body/layout */ + html { font-size: 100%; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; } -/* Where we want fancier font if available */ -h1, h2, h3, h4, h5, h6, p.module-desc, table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; } - -h1.title { - font-weight: 900; } - body { font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: 400; - font-size: 16px; - line-height: 20px; - color: #444; - letter-spacing: 0.15px; - background-color: #FDFBFA; } + font-size: 1.125em; + line-height: 1.5; + color: #222; + background-color: #FCFCFC; } /* Skeleton grid */ .container { position: relative; width: 100%; - max-width: 960px; + max-width: 1050px; margin: 0 auto; - padding: 0 20px; + padding: 0; box-sizing: border-box; } .column, .columns { width: 100%; float: left; - box-sizing: border-box; } + box-sizing: border-box; + margin-left: 1%; +} -/* For devices larger than 400px */ -@media (min-width: 400px) { - .container { - width: 100%; - padding: 0; } } -/* For devices larger than 650px */ -@media (min-width: 650px) { - .container { - width: 100%; } +.column:first-child, +.columns:first-child { + margin-left: 0; } - .column, - .columns { - margin-left: 4%; } +.three.columns { + width: 19%; } - .column:first-child, - .columns:first-child { - margin-left: 0; } +.nine.columns { + width: 80.0%; } - .one.column, - .one.columns { - width: 4.66666666667%; } - - .two.columns { - width: 13.3333333333%; } +.twelve.columns { + width: 100%; + margin-left: 0; } +@media screen and (max-width: 860px) { .three.columns { - width: 22%; } - - .four.columns { - width: 30.6666666667%; } - - .five.columns { - width: 39.3333333333%; } - - .six.columns { - width: 48%; } - - .seven.columns { - width: 56.6666666667%; } - - .eight.columns { - width: 65.3333333333%; } - + display: none; + } .nine.columns { - width: 74.0%; } - - .ten.columns { - width: 82.6666666667%; } - - .eleven.columns { - width: 91.3333333333%; } - - .twelve.columns { - width: 100%; - margin-left: 0; } - - .one-third.column { - width: 30.6666666667%; } - - .two-thirds.column { - width: 65.3333333333%; } } -/* Customer Overrides */ -.footer { - text-align: center; - color: #969696; - padding-top: 10%; } - -p.module-desc { - font-size: 1.1em; - color: #666666; } - -a.link-seesrc { - color: #aec7d2; - font-style: italic; } - -a.link-seesrc:hover { - color: #6c9aae; } - -#toc-list { - word-wrap: break-word; } - -ul.simple-toc { - list-style: none; } - -ul.simple-toc a.reference-toplevel { - font-weight: bold; - color: #0077b3; } - -ul.simple-toc-section { - list-style-type: circle; - color: #6c9aae; } - -ul.simple-toc-section a.reference { - color: #0077b3; } + width: 98.0%; + } + body { + font-size: 1em; + line-height: 1.35; + } +} cite { font-style: italic !important; } -dt > pre { - border-color: rgba(0, 0, 0, 0.1); - background-color: rgba(255, 255, 255, 0.3); - margin: 15px 0px 5px; } - -dd > pre { - border-color: rgba(0, 0, 0, 0.1); - background-color: whitesmoke; - margin-top: 8px; } - -.item > dd { - margin-left: 10px; - margin-bottom: 30px; } - -/* Nim line-numbered tables */ -.line-nums-table { - width: 100%; - table-layout: fixed; } /* Nim search input */ div#searchInputDiv { - margin-bottom: 8px; + margin-bottom: 1em; } -div#searchInputDiv input#searchInput { - width: 10em; -} -div.search-groupby { - margin-bottom: 8px; +input#searchInput { + width: 80%; } -table.line-nums-table { - border-radius: 4px; - border: 1px solid #cccccc; - background-color: whitesmoke; - border-collapse: separate; - margin-top: 15px; - margin-bottom: 25px; } - -.line-nums-table tbody { - border: none; } - -.line-nums-table td pre { - border: none; - background-color: transparent; } - -.line-nums-table td.blob-line-nums { - width: 28px; } - -.line-nums-table td.blob-line-nums pre { - color: #b0b0b0; - -webkit-filter: opacity(75%); - text-align: right; - border-color: transparent; - background-color: transparent; - padding-left: 0px; - margin-left: 0px; - padding-right: 0px; - margin-right: 0px; } +/* + * Some custom formatting for input forms. + * This also fixes input form colors on Firefox with a dark system theme on Linux. + */ +input { + -moz-appearance: none; + color: #333; + background-color: #f8f8f8; + border: 1px solid #aaa; + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-size: 0.9em; + padding: 6px; +} +input:focus { + border: 1px solid #1fa0eb; + box-shadow: 0 0 2px #1fa0eb; +} /* Docgen styles */ /* Links */ a { - color: #0077b3; - text-decoration: none; } + color: #07b; + text-decoration: none; +} + +a span.Identifier { + text-decoration: underline; + text-decoration-color: #aab; +} + +a.reference-toplevel { + font-weight: bold; +} + +a.toc-backref { + text-decoration: none; + color: #222; } + +a.link-seesrc { + color: #607c9f; + font-size: 0.9em; + font-style: italic; } a:hover, a:focus { - color: #00334d; + color: #607c9f; text-decoration: underline; } -a:visited { - color: #00334d; } +a:hover span.Identifier { + color: #607c9f; +} -a:focus { - outline: thin dotted #2d2d2d; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; } - -a:hover, -a:active { - outline: 0; } sub, sup { @@ -329,379 +227,258 @@ img { h2, h3 { - page-break-after: avoid; } } -.img-rounded { - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; } + page-break-after: avoid; } +} -.img-polaroid { - padding: 4px; - background-color: rgba(252, 248, 244, 0.75); - border: 1px solid #ccc; - border: 1px solid rgba(0, 0, 0, 0.2); - -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); - -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); } p { - margin: 0 0 8px; } + margin-top: 0.5em; + margin-bottom: 0.5em; +} small { font-size: 85%; } strong { - font-weight: 600; } + font-weight: 600; + font-size: 0.95em; + color: #3c3c3c; +} em { font-style: italic; } -cite { - font-style: normal; } - -h1, -h2, -h3, -h4, -h5, -h6 { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-weight: 600; - line-height: 20px; - color: inherit; - text-rendering: optimizelegibility; } - h1 { - font-size: 2em; + font-size: 1.8em; font-weight: 400; - padding-bottom: .15em; - border-bottom: 1px solid #aaaaaa; - margin-top: 1.0em; + padding-bottom: .25em; + border-bottom: 1px solid #aaa; + margin-top: 2.5em; + margin-bottom: 1em; line-height: 1.2em; } h1.title { padding-bottom: 1em; border-bottom: 0px; - font-size: 2.75em; } + font-size: 2.5em; + text-align: center; + font-weight: 900; + margin-top: 0.75em; + margin-bottom: 0em; +} h2 { - font-size: 1.5em; - margin-top: 1.5em; } + font-size: 1.3em; + margin-top: 2em; } + +h2.subtitle { + text-align: center; } h3 { - font-size: 1.3em; + font-size: 1.125em; font-style: italic; - margin-top: 0.75em; } + margin-top: 1.5em; } h4 { - font-size: 1.3em; - margin-top: 0.5em; } + font-size: 1.125em; + margin-top: 1em; } h5 { - font-size: 1.2em; - margin-top: 0.25em; } + font-size: 1.125em; + margin-top: 0.75em; } h6 { font-size: 1.1em; } + ul, ol { padding: 0; - margin: 0 0 0px 15px; } + margin-top: 0.5em; + margin-left: 0.75em; } ul ul, ul ol, ol ol, ol ul { - margin-bottom: 0; } + margin-bottom: 0; + margin-left: 1.25em; } li { - line-height: 20px; } - -dl { - margin-bottom: 20px; } - -dt, -dd { - line-height: 20px; } - -dt { - font-weight: bold; } - -dd { - margin-left: 10px; - margin-bottom: 26px; } - -hr { - margin: 20px 0; - border: 0; - border-top: 1px solid #eeeeee; - border-bottom: 1px solid #ffffff; } - -abbr[title], -abbr[data-original-title] { - cursor: help; - border-bottom: 1px dotted #999999; } - -abbr.initialism { - font-size: 90%; - text-transform: uppercase; } - -blockquote { - padding: 0 0 0 15px; - margin: 0 0 20px; - border-left: 5px solid #EFEBE0; } - -table.docinfo + blockquote, table.docinfo blockquote, h1 + blockquote { - border-left: 5px solid #c9c9c9; + list-style-type: circle; } -table.docinfo + blockquote p, table.docinfo blockquote p, h1 + blockquote p { - margin-bottom: 0; - font-size: 15px; - font-weight: 200; - line-height: 1.5; - font-style: italic; } +ul.simple-boot li { + list-style-type: none; + margin-left: 0em; + margin-bottom: 0.5em; +} -q:before, -q:after, -blockquote:before, -blockquote:after { - content: ""; } +ol.simple > li, ul.simple > li { + margin-bottom: 0.25em; + margin-left: 0.4em } -address { - display: block; - margin-bottom: 20px; - font-style: normal; - line-height: 20px; } +ul.simple.simple-toc > li { + margin-top: 1em; +} -code, -pre { - font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - padding: 0 3px 2px; - font-weight: 500; - font-size: 12px; - color: #444444; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; } +ul.simple-toc { + list-style: none; + font-size: 0.9em; + margin-left: -0.3em; + margin-top: 1em; } + +ul.simple-toc > li { + list-style-type: none; +} + +ul.simple-toc-section { + list-style-type: circle; + margin-left: 1em; + color: #6c9aae; } + + +ol.arabic { + list-style: decimal; } + +ol.loweralpha { + list-style: lower-alpha; } + +ol.upperalpha { + list-style: upper-alpha; } + +ol.lowerroman { + list-style: lower-roman; } + +ol.upperroman { + list-style: upper-roman; } + +ul.auto-toc { + list-style-type: none; } + + +dl { + margin-bottom: 1.5em; } + +dt { + margin-bottom: -0.5em; + margin-left: 0.0em; } + +dd { + margin-left: 2.0em; + margin-bottom: 3.0em; + margin-top: 0.5em; } + + +hr { + margin: 2em 0; + border: 0; + border-top: 1px solid #aaa; } + +blockquote { + font-size: 0.9em; + font-style: italic; + padding-left: 0.5em; + margin-left: 0; + border-left: 5px solid #bbc; +} .pre { font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; - font-weight: 600; - /*color: #504da6;*/ + font-weight: 500; + font-size: 0.85em; + background-color: #f0f3ff; + padding-left: 3px; + padding-right: 3px; + border-radius: 4px; } -code { - padding: 2px 4px; - color: #444444; - white-space: nowrap; - background-color: white; - border: 1px solid #777777; } - pre { + font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; + color: #222; + font-weight: 500; display: inline-block; box-sizing: border-box; - min-width: calc(100% - 19.5px); - padding: 9.5px; - margin: 0.25em 10px 10px 10px; - font-size: 15px; - line-height: 20px; + min-width: 100%; + padding: 0.5em; + margin-top: 0.5em; + margin-bottom: 0.5em; + font-size: 0.85em; white-space: pre !important; overflow-y: hidden; overflow-x: visible; - background-color: rgba(0, 0, 0, 0.01); - border: 1px solid #cccccc; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; } - -pre.prettyprint { - margin-bottom: 20px; } - -pre code { - padding: 0; - color: inherit; - white-space: pre; - overflow-x: visible; - background-color: transparent; - border: 0; } + background-color: ghostwhite; + border: 1px solid #dde; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; } .pre-scrollable { max-height: 340px; overflow-y: scroll; } + +/* Nim line-numbered tables */ +.line-nums-table { + width: 100%; + table-layout: fixed; } + +table.line-nums-table { + border-radius: 4px; + border: 1px solid #cccccc; + background-color: ghostwhite; + border-collapse: separate; + margin-top: 15px; + margin-bottom: 25px; } + +.line-nums-table tbody { + border: none; } + +.line-nums-table td pre { + border: none; + background-color: transparent; } + +.line-nums-table td.blob-line-nums { + width: 28px; } + +.line-nums-table td.blob-line-nums pre { + color: #b0b0b0; + -webkit-filter: opacity(75%); + text-align: right; + border-color: transparent; + background-color: transparent; + padding-left: 0px; + margin-left: 0px; + padding-right: 0px; + margin-right: 0px; } + + table { max-width: 100%; background-color: transparent; + margin-top: 0.5em; + margin-bottom: 1.5em; border-collapse: collapse; - border-spacing: 0; } - -table th, table td { - padding: 0px 8px 0px; + border-color: #ccc; + border-spacing: 0; + font-size: 0.9em; } -.table { - width: 100%; - margin-bottom: 20px; } +table th, table td { + padding: 0px 0.5em 0px; +} -.table th, -.table td { - padding: 8px; - line-height: 20px; - text-align: left; - vertical-align: top; - border-top: 1px solid #444444; } - -.table th { +table th { + background-color: #e8e8e8; font-weight: bold; } -.table thead th { - vertical-align: bottom; } +table th.docinfo-name { + background-color: transparent; +} -.table caption + thead tr:first-child th, -.table caption + thead tr:first-child td, -.table colgroup + thead tr:first-child th, -.table colgroup + thead tr:first-child td, -.table thead:first-child tr:first-child th, -.table thead:first-child tr:first-child td { - border-top: 0; } +table tr:hover { + background-color: ghostwhite; } -.table tbody + tbody { - border-top: 2px solid #444444; } - -.table .table { - background-color: rgba(252, 248, 244, 0.75); } - -.table-condensed th, -.table-condensed td { - padding: 4px 5px; } - -.table-bordered { - border: 1px solid #444444; - border-collapse: separate; - *border-collapse: collapse; - border-left: 0; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; } - -.table-bordered th, -.table-bordered td { - border-left: 1px solid #444444; } - -.table-bordered caption + thead tr:first-child th, -.table-bordered caption + tbody tr:first-child th, -.table-bordered caption + tbody tr:first-child td, -.table-bordered colgroup + thead tr:first-child th, -.table-bordered colgroup + tbody tr:first-child th, -.table-bordered colgroup + tbody tr:first-child td, -.table-bordered thead:first-child tr:first-child th, -.table-bordered tbody:first-child tr:first-child th, -.table-bordered tbody:first-child tr:first-child td { - border-top: 0; } - -.table-bordered thead:first-child tr:first-child > th:first-child, -.table-bordered tbody:first-child tr:first-child > td:first-child, -.table-bordered tbody:first-child tr:first-child > th:first-child { - -webkit-border-top-left-radius: 4px; - border-top-left-radius: 4px; - -moz-border-radius-topleft: 4px; } - -.table-bordered thead:first-child tr:first-child > th:last-child, -.table-bordered tbody:first-child tr:first-child > td:last-child, -.table-bordered tbody:first-child tr:first-child > th:last-child { - -webkit-border-top-right-radius: 4px; - border-top-right-radius: 4px; - -moz-border-radius-topright: 4px; } - -.table-bordered thead:last-child tr:last-child > th:first-child, -.table-bordered tbody:last-child tr:last-child > td:first-child, -.table-bordered tbody:last-child tr:last-child > th:first-child, -.table-bordered tfoot:last-child tr:last-child > td:first-child, -.table-bordered tfoot:last-child tr:last-child > th:first-child { - -webkit-border-bottom-left-radius: 4px; - border-bottom-left-radius: 4px; - -moz-border-radius-bottomleft: 4px; } - -.table-bordered thead:last-child tr:last-child > th:last-child, -.table-bordered tbody:last-child tr:last-child > td:last-child, -.table-bordered tbody:last-child tr:last-child > th:last-child, -.table-bordered tfoot:last-child tr:last-child > td:last-child, -.table-bordered tfoot:last-child tr:last-child > th:last-child { - -webkit-border-bottom-right-radius: 4px; - border-bottom-right-radius: 4px; - -moz-border-radius-bottomright: 4px; } - -.table-bordered tfoot + tbody:last-child tr:last-child td:first-child { - -webkit-border-bottom-left-radius: 0; - border-bottom-left-radius: 0; - -moz-border-radius-bottomleft: 0; } - -.table-bordered tfoot + tbody:last-child tr:last-child td:last-child { - -webkit-border-bottom-right-radius: 0; - border-bottom-right-radius: 0; - -moz-border-radius-bottomright: 0; } - -.table-bordered caption + thead tr:first-child th:first-child, -.table-bordered caption + tbody tr:first-child td:first-child, -.table-bordered colgroup + thead tr:first-child th:first-child, -.table-bordered colgroup + tbody tr:first-child td:first-child { - -webkit-border-top-left-radius: 4px; - border-top-left-radius: 4px; - -moz-border-radius-topleft: 4px; } - -.table-bordered caption + thead tr:first-child th:last-child, -.table-bordered caption + tbody tr:first-child td:last-child, -.table-bordered colgroup + thead tr:first-child th:last-child, -.table-bordered colgroup + tbody tr:first-child td:last-child { - -webkit-border-top-right-radius: 4px; - border-top-right-radius: 4px; - -moz-border-radius-topright: 4px; } - -table.docutils th { - background-color: #e8e8e8; } - -table.docutils tr:hover { - background-color: whitesmoke; } - -.table-striped tbody > tr:nth-child(odd) > td, -.table-striped tbody > tr:nth-child(odd) > th { - background-color: rgba(252, 248, 244, 0.75); } - -.table-hover tbody tr:hover > td, -.table-hover tbody tr:hover > th { - background-color: rgba(241, 222, 204, 0.75); } - -table td[class*="span"], -table th[class*="span"], -.row-fluid table td[class*="span"], -.row-fluid table th[class*="span"] { - display: table-cell; - float: none; - margin-left: 0; } - -.hero-unit { - padding: 60px; - margin-bottom: 30px; - font-size: 18px; - font-weight: 200; - line-height: 30px; - color: inherit; - background-color: rgba(230, 197, 164, 0.75); - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; } - -.hero-unit h1 { - margin-bottom: 0; - font-size: 60px; - line-height: 1; - letter-spacing: -1px; - color: inherit; } - -.hero-unit li { - line-height: 30px; } /* rst2html default used to remove borders from tables and images */ .borderless, table.borderless td, table.borderless th { @@ -722,10 +499,6 @@ table.borderless td, table.borderless th { .hidden { display: none; } -a.toc-backref { - text-decoration: none; - color: #444444; } - blockquote.epigraph { margin: 2em 5em; } @@ -735,85 +508,6 @@ dl.docutils dd { object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] { overflow: hidden; } -/* Uncomment (and remove this text!) to get bold-faced definition list terms -dl.docutils dt { - font-weight: bold } -*/ -div.abstract { - margin: 2em 5em; } - -div.abstract p.topic-title { - font-weight: bold; - text-align: center; } - -div.admonition, div.attention, div.caution, div.danger, div.error, -div.hint, div.important, div.note, div.tip, div.warning { - margin: 2em; - border: medium outset; - padding: 1em; } - -div.note, div.warning { - margin: 1.5em 0px; - border: none; } - -div.note p.admonition-title, -div.warning p.admonition-title { - display: none; } - -/* Clearfix - * http://css-tricks.com/snippets/css/clear-fix/ - */ -div.note:after, -div.warning:after { - content: ""; - display: table; - clear: both; } - -div.note p:before, -div.warning p:before { - display: block; - float: left; - font-size: 4em; - line-height: 1em; - margin-right: 20px; - margin-left: 0em; - margin-top: -10px; - content: '\0270D'; - /*handwriting*/ } - -div.warning p:before { - content: '\026A0'; - /*warning*/ } - -div.admonition p.admonition-title, div.hint p.admonition-title, -div.important p.admonition-title, div.note p.admonition-title, -div.tip p.admonition-title { - font-weight: bold; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } - -div.attention p.admonition-title, div.caution p.admonition-title, -div.danger p.admonition-title, div.error p.admonition-title, -div.warning p.admonition-title, .code .error { - color: #b30000; - font-weight: bold; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } - -/* Uncomment (and remove this text!) to get reduced vertical space in - compound paragraphs. -div.compound .compound-first, div.compound .compound-middle { - margin-bottom: 0.5em } - -div.compound .compound-last, div.compound .compound-middle { - margin-top: 0.5em } -*/ -div.dedication { - margin: 2em 5em; - text-align: center; - font-style: italic; } - -div.dedication p.topic-title { - font-weight: bold; - font-style: normal; } div.figure { margin-left: 2em; @@ -821,8 +515,14 @@ div.figure { div.footer, div.header { clear: both; + text-align: center; + color: #666; font-size: smaller; } +div.footer { + padding-top: 5em; +} + div.line-block { display: block; margin-top: 1em; @@ -833,45 +533,24 @@ div.line-block div.line-block { margin-bottom: 0; margin-left: 1.5em; } -div.sidebar { - margin: 0 0 0.5em 1em; - border: medium outset; - padding: 1em; - background-color: rgba(252, 248, 244, 0.75); - width: 40%; - float: right; - clear: right; } - -div.sidebar p.rubric { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-size: medium; } - -div.system-messages { - margin: 5em; } - -div.system-messages h1 { - color: #b30000; } - -div.system-message { - border: medium outset; - padding: 1em; } - -div.system-message p.system-message-title { - color: #b30000; - font-weight: bold; } - div.topic { margin: 2em; } -h1.section-subtitle, h2.section-subtitle, h3.section-subtitle, -h4.section-subtitle, h5.section-subtitle, h6.section-subtitle { - margin-top: 0.4em; } +div.search_results { + background-color: antiquewhite; + margin: 3em; + padding: 1em; + border: 1px solid #4d4d4d; +} -h1.title { - text-align: center; } +div#global-links ul { + margin-left: 0; + list-style-type: none; +} -h2.subtitle { - text-align: center; } +div#global-links > simple-boot { + margin-left: 3em; +} hr.docutils { width: 75%; } @@ -905,30 +584,6 @@ img.align-center, .figure.align-center, object.align-center { div.align-right { text-align: inherit; } -/* div.align-center * { */ -/* text-align: left } */ - -ul.simple > li { - margin-bottom: 0.5em } - -ol.simple, ul.simple { - margin-bottom: 1em; } - -ol.arabic { - list-style: decimal; } - -ol.loweralpha { - list-style: lower-alpha; } - -ol.upperalpha { - list-style: upper-alpha; } - -ol.lowerroman { - list-style: lower-roman; } - -ol.upperroman { - list-style: upper-roman; } - p.attribution { text-align: right; margin-left: 50%; } @@ -949,15 +604,6 @@ p.rubric { color: maroon; text-align: center; } -p.sidebar-title { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-weight: bold; - font-size: larger; } - -p.sidebar-subtitle { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; - font-weight: bold; } - p.topic-title { font-weight: bold; } @@ -997,22 +643,14 @@ pre.code .inserted, code .inserted { background-color: #A3D289; } span.classifier { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-style: oblique; } span.classifier-delimiter { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; font-weight: bold; } -span.interpreted { - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; } - span.option { white-space: nowrap; } -span.pre { - white-space: pre; } - span.problematic { color: #b30000; } @@ -1020,44 +658,6 @@ span.section-subtitle { /* font-size relative to parent (h1..h6 element) */ font-size: 80%; } -table.citation { - border-left: solid 1px #666666; - margin-left: 1px; } - -table.docinfo { - margin: 0em; - margin-top: 2em; - margin-bottom: 2em; - font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif !important; - color: #444444; } - -table.docutils { - margin-top: 0.5em; - margin-bottom: 0.5em; } - -table.footnote { - border-left: solid 1px #2d2d2d; - margin-left: 1px; } - -table.docutils td, table.docutils th, -table.docinfo td, table.docinfo th { - padding-left: 0.5em; - padding-right: 0.5em; - vertical-align: top; } - -table.docutils th.field-name, table.docinfo th.docinfo-name { - font-weight: 700; - text-align: left; - white-space: nowrap; - padding-left: 0; } - -h1 tt.docutils, h2 tt.docutils, h3 tt.docutils, -h4 tt.docutils, h5 tt.docutils, h6 tt.docutils { - font-size: 100%; } - -ul.auto-toc { - list-style-type: none; } - span.DecNumber { color: #252dbe; } @@ -1074,7 +674,7 @@ span.FloatNumber { color: #252dbe; } span.Identifier { - color: #3b3b3b; } + color: #222; } span.Keyword { font-weight: 600; @@ -1139,38 +739,23 @@ dt pre > span.Identifier, dt pre > span.Operator { color: #155da4; font-weight: 700; } -dt pre > span.Identifier ~ span.Identifier, dt pre > span.Operator ~ span.Identifier { - color: inherit; - font-weight: inherit; } - -dt pre > span.Operator ~ span.Identifier { +dt pre > span.Keyword ~ span.Identifier, dt pre > span.Identifier ~ span.Identifier, +dt pre > span.Operator ~ span.Identifier, dt pre > span.Other ~ span.Identifier { color: inherit; font-weight: inherit; } /* Nim sprite for the footer (taken from main page favicon) */ .nim-sprite { display: inline-block; - height: 12px; - width: 12px; + height: 16px; + width: 16px; background-position: 0 0; - background-size: 12px 12px; + background-size: 16px 16px; -webkit-filter: opacity(50%); background-repeat: no-repeat; background-image: url("data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="); margin-bottom: -5px; } -div.search_results { - background-color: antiquewhite; - margin: 3em; - padding: 1em; - border: 1px solid #4d4d4d; -} - -div#global-links ul { - margin-left: 0; - list-style-type: none; -} - span.pragmadots { /* Position: relative frees us up to make the dots look really nice without fucking up the layout and @@ -1178,18 +763,14 @@ span.pragmadots { position: relative; /* 1px down looks slightly nicer */ top: 1px; - padding: 2px; - background-color: #D3D3D3; + background-color: #e8e8e8; border-radius: 4px; margin: 0 2px; cursor: pointer; - - /* For some reason on Chrome, making the font size - smaller than 1em is causing the parent container to - bulge slightly. So, we're stuck with inheriting 1em, - which is sad, because 0.8em looks better... */ + font-size: 0.8em; } + span.pragmadots:hover { background-color: #DBDBDB; } @@ -1197,6 +778,10 @@ span.pragmawrap { display: none; } +span.attachedType { + display: none; + visibility: hidden; +} @@ -1242,11 +827,11 @@ function main() {
    Types
    • time_t
    • + title="time_t = time_t_temp.Time">time_t
    • ptrdiff_t
    • + title="ptrdiff_t = ByteAddress">ptrdiff_t
    • va_list
    • + title="va_list {.importc, header: "<stdarg.h>".} = object">va_list
  • @@ -1254,9 +839,9 @@ function main() { Templates @@ -1266,27 +851,31 @@ function main() {
    +

    Types

    -
    time_t = Time
    +
    time_t = time_t_temp.Time
    +
    ptrdiff_t = ByteAddress
    +
    va_list {...}{.importc, header: "<stdarg.h>".} = object
    +
    @@ -1294,16 +883,18 @@ function main() {

    Templates

    -
    template enumOp(op, typ, typout)
    +
    template enumOp(op, typ, typout)
    +
    - -
    template defineEnum(typ)
    + +
    template defineEnum(typ)
    +
    @@ -1315,7 +906,7 @@ function main() { diff --git a/types.idx b/types.idx index d4ab217..5bc0938 100644 --- a/types.idx +++ b/types.idx @@ -2,4 +2,4 @@ time_t types.html#time_t types: time_t ptrdiff_t types.html#ptrdiff_t types: ptrdiff_t va_list types.html#va_list types: va_list enumOp types.html#enumOp.t,,, types: enumOp(op, typ, typout) -defineEnum types.html#defineEnum.t, types: defineEnum(typ) +defineEnum types.html#defineEnum.t types: defineEnum(typ) From 29f59eee99f72b9a7a2dde1e6fc22ff3c943f440 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 29 Jul 2019 23:24:03 -0500 Subject: [PATCH 234/593] Fix #131 - division in enums --- nimterop/types.nim | 5 +++++ tests/include/test.h | 10 ++++++++++ tests/tnimterop_c.nim | 6 ++++++ 3 files changed, 21 insertions(+) diff --git a/nimterop/types.nim b/nimterop/types.nim index d161ddb..5b4ad5f 100644 --- a/nimterop/types.nim +++ b/nimterop/types.nim @@ -70,4 +70,9 @@ template defineEnum*(typ) = proc `xor`*(x: int, y: typ): typ {.borrow.} proc `xor`*(x, y: typ): typ {.borrow.} + proc `/`(x, y: typ): typ = + return (x.float / y.float).int.typ + proc `/`*(x: typ, y: int): typ = `/`(x, y.typ) + proc `/`*(x: int, y: typ): typ = `/`(x.typ, y) + proc `$` *(x: typ): string {.borrow.} \ No newline at end of file diff --git a/tests/include/test.h b/tests/include/test.h index 91bfd75..cb4dd59 100644 --- a/tests/include/test.h +++ b/tests/include/test.h @@ -156,6 +156,16 @@ typedef struct dstruct2 { void **(*tcv)(int **param1); } DSTRUCT2; +// Issue #131 +enum +{ + TDEFL_LZ_CODE_BUF_SIZE = 64 * 1024, + TDEFL_OUT_BUF_SIZE = (TDEFL_LZ_CODE_BUF_SIZE * 13) / 10, + TDEFL_BOGUS_1 = (1024 * 128) / TDEFL_LZ_CODE_BUF_SIZE, + TDEFL_BOGUS_2 = TDEFL_LZ_CODE_BUF_SIZE / 64, + TDEFL_BOGUS_3 = TDEFL_OUT_BUF_SIZE / TDEFL_BOGUS_1 +}; + #ifdef __cplusplus } #endif diff --git a/tests/tnimterop_c.nim b/tests/tnimterop_c.nim index 9f37141..1c30387 100644 --- a/tests/tnimterop_c.nim +++ b/tests/tnimterop_c.nim @@ -172,3 +172,9 @@ ds.field1 = di ds2.field1 = addr cstr ds2.tcv = test_call10 check ds2.tcv(di) == nil + +# Issue #131 +check TDEFL_OUT_BUF_SIZE == 85196 +check TDEFL_BOGUS_1 == 2 +check TDEFL_BOGUS_2 == 1024 +check TDEFL_BOGUS_3 == (85196 / 2).int From 86ebf622e1946225914a02779f9d4c60b63b80ac Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 19 Aug 2019 20:25:09 -0700 Subject: [PATCH 235/593] findExe, use curl/wget if avail, mingw32-make, unused imports --- nimterop/ast.nim | 4 ++-- nimterop/cimport.nim | 2 +- nimterop/git.nim | 56 +++++++++++++++++++++++++++++++++++--------- nimterop/grammar.nim | 2 +- nimterop/lisp.nim | 3 --- 5 files changed, 49 insertions(+), 18 deletions(-) diff --git a/nimterop/ast.nim b/nimterop/ast.nim index f858043..240d5fd 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -1,8 +1,8 @@ -import os, sequtils, sets, strformat, strutils, tables, times +import os, sets, strformat, strutils, tables, times import regex -import "."/[getters, globals, grammar, treesitter/api] +import "."/[getters, globals, treesitter/api] proc saveNodeData(node: TSNode, nimState: NimState): bool = let name = $node.tsNodeType() diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index 8c3d6c7..506f18f 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -614,7 +614,7 @@ macro c2nImport*(filename: static string, recurse: static bool = false, dynlib: let (c2nimout, ret) = gorgeEx(cmd, cache=getCacheValue(hpath)) - doAssert ret == 0, "Command failed:\n " & cmd + doAssert ret == 0, "Command failed:\n " & cmd & "\n\n" & c2nimout var nimout = &"const {header} = \"{fullpath}\"\n\n" & readFile(npath) diff --git a/nimterop/git.nim b/nimterop/git.nim index 6566c0e..443f9a5 100644 --- a/nimterop/git.nim +++ b/nimterop/git.nim @@ -1,6 +1,6 @@ -import macros, os, osproc, regex, strformat, strutils +import os, osproc, strformat, strutils -import "."/[paths, compat] +import "."/[compat] proc execAction*(cmd: string, nostderr=false): string = ## Execute an external command - supported at compile time @@ -24,6 +24,21 @@ proc execAction*(cmd: string, nostderr=false): string = (result, ret) = execCmdEx(ccmd, opt) doAssert ret == 0, "Command failed: " & $(ret, nostderr) & "\nccmd: " & ccmd & "\nresult:\n" & result +proc findExe*(exe: string): string = + ## Find the specified executable using the which/where command - supported + ## at compile time + var + cmd = + when defined(windows): + "where " & exe + else: + "which " & exe + + (oup, code) = gorgeEx(cmd) + + if code == 0: + return oup.strip() + proc mkDir*(dir: string) = ## Create a directory at cmopile time ## @@ -70,8 +85,7 @@ proc extractZip*(zipfile, outdir: string) = discard execAction(&"cd {outdir.quoteShell} && {cmd % zipfile}") proc downloadUrl*(url, outdir: string) = - ## Download a file using powershell on Windows and curl on other - ## systems to the specified output directory + ## Download a file using curl or wget (or powershell on Windows) to the specified directory ## ## If a zip file, it is automatically extracted after download. let @@ -81,10 +95,17 @@ proc downloadUrl*(url, outdir: string) = if not (ext == ".zip" and fileExists(outdir/file)): echo "# Downloading " & file mkDir(outdir) - var cmd = if defined(Windows): - "powershell [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; wget $# -OutFile $#" + var cmd = findExe("curl") + if cmd.len != 0: + cmd &= " -L $# -o $#" else: - "curl -L $# -o $#" + cmd = findExe("wget") + if cmd.len != 0: + cmd &= " $# -o $#" + elif defined(Windows): + cmd = "powershell [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; wget $# -OutFile $#" + else: + doAssert false, "No download tool available - curl, wget" discard execAction(cmd % [url, (outdir/file).quoteShell]) if ext == ".zip": @@ -176,7 +197,7 @@ proc configure*(path, check: string, flags = "") = discard execAction(&"cd {path.quoteShell} && bash autogen.sh") if fileExists(path / "configure"): - echo "# Running configure" + echo "# Running configure " & flags var cmd = &"cd {path.quoteShell} && bash configure" @@ -202,7 +223,8 @@ proc cmake*(path, check, flags: string) = if (path / check).fileExists(): return - echo "# Running cmake " & path + echo "# Running cmake " & flags + echo "# Path: " & path mkDir(path) @@ -219,13 +241,25 @@ proc make*(path, check: string, flags = "") = ## is relative to the `path` and should not be an absolute path. ## ## `flags` are any flags that should be passed to the `make` command. + ## + ## If make.exe is missing and mingw32-make.exe is available, it will + ## be copied over to make.exe in the same location. if (path / check).fileExists(): return - echo "# Running make " & path + echo "# Running make " & flags + echo "# Path: " & path var - cmd = &"cd {path.quoteShell} && make" + cmd = findExe("make") + + if cmd.len == 0: + cmd = findExe("mingw32-make") + if cmd.len != 0: + cpFile(cmd, cmd.replace("mingw32-make", "make")) + doAssert cmd.len != 0, "Make not found" + + cmd = &"cd {path.quoteShell} && make" if flags.len != 0: cmd &= &" {flags}" diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index e40a4dc..a66442f 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -1,4 +1,4 @@ -import macros, sets, strformat, strutils, tables +import macros, strformat, strutils, tables import regex diff --git a/nimterop/lisp.nim b/nimterop/lisp.nim index 8a256be..5c7a02a 100644 --- a/nimterop/lisp.nim +++ b/nimterop/lisp.nim @@ -1,6 +1,3 @@ -import strutils -import strformat - import "."/[getters, globals] var From c3734587a174ea2fc7e19943e6d11d024f06e091 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 22 Aug 2019 14:34:52 -0700 Subject: [PATCH 236/593] rmFile/Dir, build/autogen, check if build command worked --- nimterop/git.nim | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/nimterop/git.nim b/nimterop/git.nim index 443f9a5..72315a6 100644 --- a/nimterop/git.nim +++ b/nimterop/git.nim @@ -72,6 +72,25 @@ proc mvFile*(source, dest: string) = ## Move a file from source to destination at compile time cpFile(source, dest, move=true) +proc rmFile*(source: string, dir = false) = + ## Remove a file or pattern at compile time + let + source = source.replace("/", $DirSep) + cmd = + when defined(Windows): + if dir: + "rd /s/q" + else: + "del /s/q/f" + else: + "rm -rf" + + discard execAction(&"{cmd} {source.quoteShell}") + +proc rmDir*(source: string) = + ## Remove a directory or pattern at compile time + rmFile(source, dir = true) + proc extractZip*(zipfile, outdir: string) = ## Extract a zip file using powershell on Windows and unzip on other ## systems to the specified output directory @@ -191,10 +210,13 @@ proc configure*(path, check: string, flags = "") = echo "# Configuring " & path if not fileExists(path / "configure"): - if fileExists(path / "autogen.sh"): - echo "# Running autogen.sh" + for i in @[path / "autogen.sh", path / "build" / "autogen.sh"]: + if fileExists(i): + echo "# Running autogen.sh" - discard execAction(&"cd {path.quoteShell} && bash autogen.sh") + discard execAction(&"cd {i.parentDir().quoteShell} && bash autogen.sh") + + break if fileExists(path / "configure"): echo "# Running configure " & flags @@ -206,6 +228,8 @@ proc configure*(path, check: string, flags = "") = echo execAction(cmd) + doAssert (path / check).fileExists(), "# Configure failed" + proc cmake*(path, check, flags: string) = ## Run the `cmake` command to generate all Makefiles or other ## build scripts in the specified path @@ -233,6 +257,8 @@ proc cmake*(path, check, flags: string) = echo execAction(cmd) + doAssert (path / check).fileExists(), "# cmake failed" + proc make*(path, check: string, flags = "") = ## Run the `make` command to build all binaries in the specified path ## @@ -263,4 +289,6 @@ proc make*(path, check: string, flags = "") = if flags.len != 0: cmd &= &" {flags}" - echo execAction(cmd) \ No newline at end of file + echo execAction(cmd) + + doAssert (path / check).fileExists(), "# make failed" From 5b0a5ab14611f0f562ae96c75ee5d7ca634ae2ea Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 22 Aug 2019 15:59:13 -0700 Subject: [PATCH 237/593] Rename git to build --- nimterop/all.nim | 2 +- nimterop/build.nim | 294 +++++++++++++++++++++++++++++++++++++++++ nimterop/cimport.nim | 2 +- nimterop/getters.nim | 2 +- nimterop/git.nim | 295 +----------------------------------------- nimterop/setup.nim | 2 +- nimterop/template.nim | 2 +- nimterop/templite.nim | 2 +- tests/tpcre.nim | 2 +- tests/tsoloud.nim | 2 +- 10 files changed, 303 insertions(+), 302 deletions(-) create mode 100644 nimterop/build.nim diff --git a/nimterop/all.nim b/nimterop/all.nim index 78249a1..c024d01 100644 --- a/nimterop/all.nim +++ b/nimterop/all.nim @@ -4,4 +4,4 @@ Module that should import everything so that `nim doc --project nimtero/all` run # TODO: make sure it does import everything. -import "."/[cimport, git, types, plugin, compat] +import "."/[cimport, build, types, plugin, compat] diff --git a/nimterop/build.nim b/nimterop/build.nim new file mode 100644 index 0000000..72315a6 --- /dev/null +++ b/nimterop/build.nim @@ -0,0 +1,294 @@ +import os, osproc, strformat, strutils + +import "."/[compat] + +proc execAction*(cmd: string, nostderr=false): string = + ## Execute an external command - supported at compile time + ## + ## Checks if command exits successfully before returning. If not, an + ## error is raised. + var + ccmd = "" + ret = 0 + when defined(Windows): + ccmd = "cmd /c " & cmd + elif defined(posix): + ccmd = cmd + else: + doAssert false + + when nimvm: + (result, ret) = gorgeEx(ccmd) + else: + let opt = if nostderr: {poUsePath} else: {poStdErrToStdOut, poUsePath} + (result, ret) = execCmdEx(ccmd, opt) + doAssert ret == 0, "Command failed: " & $(ret, nostderr) & "\nccmd: " & ccmd & "\nresult:\n" & result + +proc findExe*(exe: string): string = + ## Find the specified executable using the which/where command - supported + ## at compile time + var + cmd = + when defined(windows): + "where " & exe + else: + "which " & exe + + (oup, code) = gorgeEx(cmd) + + if code == 0: + return oup.strip() + +proc mkDir*(dir: string) = + ## Create a directory at cmopile time + ## + ## The `os` module is not available at compile time so a few + ## crucial helper functions are included with nimterop. + if not dirExists(dir): + let + flag = when not defined(Windows): "-p" else: "" + discard execAction(&"mkdir {flag} {dir.quoteShell}") + +proc cpFile*(source, dest: string, move=false) = + ## Copy a file from source to destination at compile time + let + source = source.replace("/", $DirSep) + dest = dest.replace("/", $DirSep) + cmd = + when defined(Windows): + if move: + "move /y" + else: + "copy /y" + else: + if move: + "mv -f" + else: + "cp -f" + + discard execAction(&"{cmd} {source.quoteShell} {dest.quoteShell}") + +proc mvFile*(source, dest: string) = + ## Move a file from source to destination at compile time + cpFile(source, dest, move=true) + +proc rmFile*(source: string, dir = false) = + ## Remove a file or pattern at compile time + let + source = source.replace("/", $DirSep) + cmd = + when defined(Windows): + if dir: + "rd /s/q" + else: + "del /s/q/f" + else: + "rm -rf" + + discard execAction(&"{cmd} {source.quoteShell}") + +proc rmDir*(source: string) = + ## Remove a directory or pattern at compile time + rmFile(source, dir = true) + +proc extractZip*(zipfile, outdir: string) = + ## Extract a zip file using powershell on Windows and unzip on other + ## systems to the specified output directory + var cmd = "unzip -o $#" + if defined(Windows): + cmd = "powershell -nologo -noprofile -command \"& { Add-Type -A " & + "'System.IO.Compression.FileSystem'; " & + "[IO.Compression.ZipFile]::ExtractToDirectory('$#', '.'); }\"" + + echo "# Extracting " & zipfile + discard execAction(&"cd {outdir.quoteShell} && {cmd % zipfile}") + +proc downloadUrl*(url, outdir: string) = + ## Download a file using curl or wget (or powershell on Windows) to the specified directory + ## + ## If a zip file, it is automatically extracted after download. + let + file = url.extractFilename() + ext = file.splitFile().ext.toLowerAscii() + + if not (ext == ".zip" and fileExists(outdir/file)): + echo "# Downloading " & file + mkDir(outdir) + var cmd = findExe("curl") + if cmd.len != 0: + cmd &= " -L $# -o $#" + else: + cmd = findExe("wget") + if cmd.len != 0: + cmd &= " $# -o $#" + elif defined(Windows): + cmd = "powershell [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; wget $# -OutFile $#" + else: + doAssert false, "No download tool available - curl, wget" + discard execAction(cmd % [url, (outdir/file).quoteShell]) + + if ext == ".zip": + extractZip(file, outdir) + +proc gitReset*(outdir: string) = + ## Hard reset the git repository at the specified directory + echo "# Resetting " & outdir + + let cmd = &"cd {outdir.quoteShell} && git reset --hard" + while execAction(cmd).contains("Permission denied"): + sleep(1000) + echo "# Retrying ..." + +proc gitCheckout*(file, outdir: string) = + ## Checkout the specified file in the git repository specified + ## + ## This effectively resets all changes in the file and can be + ## used to undo any changes that were made to source files to enable + ## successful wrapping with `cImport()` or `c2nImport()`. + echo "# Resetting " & file + let file2 = file.relativePath outdir + let cmd = &"cd {outdir.quoteShell} && git checkout {file2.quoteShell}" + while execAction(cmd).contains("Permission denied"): + sleep(500) + echo "# Retrying ..." + +proc gitPull*(url: string, outdir = "", plist = "", checkout = "") = + ## Pull the specified git repository to the output directory + ## + ## `plist` is the list of specific files and directories or wildcards + ## to sparsely checkout. Multiple values can be specified one entry per + ## line. It is optional and if omitted, the entire repository will be + ## checked out. + ## + ## `checkout` is the git tag, branch or commit hash to checkout once + ## the repository is downloaded. This allows for pinning to a specific + ## version of the code. + if dirExists(outdir/".git"): + gitReset(outdir) + return + + let + outdirQ = outdir.quoteShell + + mkDir(outdir) + + echo "# Setting up Git repo: " & url + discard execAction(&"cd {outdirQ} && git init .") + discard execAction(&"cd {outdirQ} && git remote add origin {url}") + + if plist.len != 0: + # If a specific list of files is required, create a sparse checkout + # file for git in its config directory + let sparsefile = outdir / ".git/info/sparse-checkout" + + discard execAction(&"cd {outdirQ} && git config core.sparsecheckout true") + writeFile(sparsefile, plist) + + if checkout.len != 0: + echo "# Checking out " & checkout + discard execAction(&"cd {outdirQ} && git pull --tags origin master") + discard execAction(&"cd {outdirQ} && git checkout {checkout}") + else: + echo "# Pulling repository" + discard execAction(&"cd {outdirQ} && git pull --depth=1 origin master") + +proc configure*(path, check: string, flags = "") = + ## Run the GNU `configure` command to generate all Makefiles or other + ## build scripts in the specified path + ## + ## If a `configure` script is not present and an `autogen.sh` script + ## is present, it will be run before attempting `configure`. + ## + ## `check` is a file that will be generated by the `configure` command. + ## This is required to prevent configure from running on every build. It + ## is relative to the `path` and should not be an absolute path. + ## + ## `flags` are any flags that should be passed to the `configure` command. + if (path / check).fileExists(): + return + + echo "# Configuring " & path + + if not fileExists(path / "configure"): + for i in @[path / "autogen.sh", path / "build" / "autogen.sh"]: + if fileExists(i): + echo "# Running autogen.sh" + + discard execAction(&"cd {i.parentDir().quoteShell} && bash autogen.sh") + + break + + if fileExists(path / "configure"): + echo "# Running configure " & flags + + var + cmd = &"cd {path.quoteShell} && bash configure" + if flags.len != 0: + cmd &= &" {flags}" + + echo execAction(cmd) + + doAssert (path / check).fileExists(), "# Configure failed" + +proc cmake*(path, check, flags: string) = + ## Run the `cmake` command to generate all Makefiles or other + ## build scripts in the specified path + ## + ## `path` will be created since typically `cmake` is run in an + ## empty directory. + ## + ## `check` is a file that will be generated by the `cmake` command. + ## This is required to prevent `cmake` from running on every build. It + ## is relative to the `path` and should not be an absolute path. + ## + ## `flags` are any flags that should be passed to the `cmake` command. + ## Unlike `configure`, it is required since typically it will be the + ## path to the repository, typically `..` when `path` is a subdir. + if (path / check).fileExists(): + return + + echo "# Running cmake " & flags + echo "# Path: " & path + + mkDir(path) + + var + cmd = &"cd {path.quoteShell} && cmake {flags}" + + echo execAction(cmd) + + doAssert (path / check).fileExists(), "# cmake failed" + +proc make*(path, check: string, flags = "") = + ## Run the `make` command to build all binaries in the specified path + ## + ## `check` is a file that will be generated by the `make` command. + ## This is required to prevent `make` from running on every build. It + ## is relative to the `path` and should not be an absolute path. + ## + ## `flags` are any flags that should be passed to the `make` command. + ## + ## If make.exe is missing and mingw32-make.exe is available, it will + ## be copied over to make.exe in the same location. + if (path / check).fileExists(): + return + + echo "# Running make " & flags + echo "# Path: " & path + + var + cmd = findExe("make") + + if cmd.len == 0: + cmd = findExe("mingw32-make") + if cmd.len != 0: + cpFile(cmd, cmd.replace("mingw32-make", "make")) + doAssert cmd.len != 0, "Make not found" + + cmd = &"cd {path.quoteShell} && make" + if flags.len != 0: + cmd &= &" {flags}" + + echo execAction(cmd) + + doAssert (path / check).fileExists(), "# make failed" diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index 506f18f..0e875ed 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -21,7 +21,7 @@ const CIMPORT {.used.} = 1 include "."/globals -import "."/[git, paths, types] +import "."/[build, paths, types] export types proc interpPath(dir: string): string= diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 51d63a7..04ed5cf 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -2,7 +2,7 @@ import dynlib, macros, os, sequtils, sets, strformat, strutils, tables, times import regex -import "."/[git, globals, plugin, treesitter/api] +import "."/[build, globals, plugin, treesitter/api] const gReserved = """ addr and as asm diff --git a/nimterop/git.nim b/nimterop/git.nim index 72315a6..7a0cf2a 100644 --- a/nimterop/git.nim +++ b/nimterop/git.nim @@ -1,294 +1 @@ -import os, osproc, strformat, strutils - -import "."/[compat] - -proc execAction*(cmd: string, nostderr=false): string = - ## Execute an external command - supported at compile time - ## - ## Checks if command exits successfully before returning. If not, an - ## error is raised. - var - ccmd = "" - ret = 0 - when defined(Windows): - ccmd = "cmd /c " & cmd - elif defined(posix): - ccmd = cmd - else: - doAssert false - - when nimvm: - (result, ret) = gorgeEx(ccmd) - else: - let opt = if nostderr: {poUsePath} else: {poStdErrToStdOut, poUsePath} - (result, ret) = execCmdEx(ccmd, opt) - doAssert ret == 0, "Command failed: " & $(ret, nostderr) & "\nccmd: " & ccmd & "\nresult:\n" & result - -proc findExe*(exe: string): string = - ## Find the specified executable using the which/where command - supported - ## at compile time - var - cmd = - when defined(windows): - "where " & exe - else: - "which " & exe - - (oup, code) = gorgeEx(cmd) - - if code == 0: - return oup.strip() - -proc mkDir*(dir: string) = - ## Create a directory at cmopile time - ## - ## The `os` module is not available at compile time so a few - ## crucial helper functions are included with nimterop. - if not dirExists(dir): - let - flag = when not defined(Windows): "-p" else: "" - discard execAction(&"mkdir {flag} {dir.quoteShell}") - -proc cpFile*(source, dest: string, move=false) = - ## Copy a file from source to destination at compile time - let - source = source.replace("/", $DirSep) - dest = dest.replace("/", $DirSep) - cmd = - when defined(Windows): - if move: - "move /y" - else: - "copy /y" - else: - if move: - "mv -f" - else: - "cp -f" - - discard execAction(&"{cmd} {source.quoteShell} {dest.quoteShell}") - -proc mvFile*(source, dest: string) = - ## Move a file from source to destination at compile time - cpFile(source, dest, move=true) - -proc rmFile*(source: string, dir = false) = - ## Remove a file or pattern at compile time - let - source = source.replace("/", $DirSep) - cmd = - when defined(Windows): - if dir: - "rd /s/q" - else: - "del /s/q/f" - else: - "rm -rf" - - discard execAction(&"{cmd} {source.quoteShell}") - -proc rmDir*(source: string) = - ## Remove a directory or pattern at compile time - rmFile(source, dir = true) - -proc extractZip*(zipfile, outdir: string) = - ## Extract a zip file using powershell on Windows and unzip on other - ## systems to the specified output directory - var cmd = "unzip -o $#" - if defined(Windows): - cmd = "powershell -nologo -noprofile -command \"& { Add-Type -A " & - "'System.IO.Compression.FileSystem'; " & - "[IO.Compression.ZipFile]::ExtractToDirectory('$#', '.'); }\"" - - echo "# Extracting " & zipfile - discard execAction(&"cd {outdir.quoteShell} && {cmd % zipfile}") - -proc downloadUrl*(url, outdir: string) = - ## Download a file using curl or wget (or powershell on Windows) to the specified directory - ## - ## If a zip file, it is automatically extracted after download. - let - file = url.extractFilename() - ext = file.splitFile().ext.toLowerAscii() - - if not (ext == ".zip" and fileExists(outdir/file)): - echo "# Downloading " & file - mkDir(outdir) - var cmd = findExe("curl") - if cmd.len != 0: - cmd &= " -L $# -o $#" - else: - cmd = findExe("wget") - if cmd.len != 0: - cmd &= " $# -o $#" - elif defined(Windows): - cmd = "powershell [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; wget $# -OutFile $#" - else: - doAssert false, "No download tool available - curl, wget" - discard execAction(cmd % [url, (outdir/file).quoteShell]) - - if ext == ".zip": - extractZip(file, outdir) - -proc gitReset*(outdir: string) = - ## Hard reset the git repository at the specified directory - echo "# Resetting " & outdir - - let cmd = &"cd {outdir.quoteShell} && git reset --hard" - while execAction(cmd).contains("Permission denied"): - sleep(1000) - echo "# Retrying ..." - -proc gitCheckout*(file, outdir: string) = - ## Checkout the specified file in the git repository specified - ## - ## This effectively resets all changes in the file and can be - ## used to undo any changes that were made to source files to enable - ## successful wrapping with `cImport()` or `c2nImport()`. - echo "# Resetting " & file - let file2 = file.relativePath outdir - let cmd = &"cd {outdir.quoteShell} && git checkout {file2.quoteShell}" - while execAction(cmd).contains("Permission denied"): - sleep(500) - echo "# Retrying ..." - -proc gitPull*(url: string, outdir = "", plist = "", checkout = "") = - ## Pull the specified git repository to the output directory - ## - ## `plist` is the list of specific files and directories or wildcards - ## to sparsely checkout. Multiple values can be specified one entry per - ## line. It is optional and if omitted, the entire repository will be - ## checked out. - ## - ## `checkout` is the git tag, branch or commit hash to checkout once - ## the repository is downloaded. This allows for pinning to a specific - ## version of the code. - if dirExists(outdir/".git"): - gitReset(outdir) - return - - let - outdirQ = outdir.quoteShell - - mkDir(outdir) - - echo "# Setting up Git repo: " & url - discard execAction(&"cd {outdirQ} && git init .") - discard execAction(&"cd {outdirQ} && git remote add origin {url}") - - if plist.len != 0: - # If a specific list of files is required, create a sparse checkout - # file for git in its config directory - let sparsefile = outdir / ".git/info/sparse-checkout" - - discard execAction(&"cd {outdirQ} && git config core.sparsecheckout true") - writeFile(sparsefile, plist) - - if checkout.len != 0: - echo "# Checking out " & checkout - discard execAction(&"cd {outdirQ} && git pull --tags origin master") - discard execAction(&"cd {outdirQ} && git checkout {checkout}") - else: - echo "# Pulling repository" - discard execAction(&"cd {outdirQ} && git pull --depth=1 origin master") - -proc configure*(path, check: string, flags = "") = - ## Run the GNU `configure` command to generate all Makefiles or other - ## build scripts in the specified path - ## - ## If a `configure` script is not present and an `autogen.sh` script - ## is present, it will be run before attempting `configure`. - ## - ## `check` is a file that will be generated by the `configure` command. - ## This is required to prevent configure from running on every build. It - ## is relative to the `path` and should not be an absolute path. - ## - ## `flags` are any flags that should be passed to the `configure` command. - if (path / check).fileExists(): - return - - echo "# Configuring " & path - - if not fileExists(path / "configure"): - for i in @[path / "autogen.sh", path / "build" / "autogen.sh"]: - if fileExists(i): - echo "# Running autogen.sh" - - discard execAction(&"cd {i.parentDir().quoteShell} && bash autogen.sh") - - break - - if fileExists(path / "configure"): - echo "# Running configure " & flags - - var - cmd = &"cd {path.quoteShell} && bash configure" - if flags.len != 0: - cmd &= &" {flags}" - - echo execAction(cmd) - - doAssert (path / check).fileExists(), "# Configure failed" - -proc cmake*(path, check, flags: string) = - ## Run the `cmake` command to generate all Makefiles or other - ## build scripts in the specified path - ## - ## `path` will be created since typically `cmake` is run in an - ## empty directory. - ## - ## `check` is a file that will be generated by the `cmake` command. - ## This is required to prevent `cmake` from running on every build. It - ## is relative to the `path` and should not be an absolute path. - ## - ## `flags` are any flags that should be passed to the `cmake` command. - ## Unlike `configure`, it is required since typically it will be the - ## path to the repository, typically `..` when `path` is a subdir. - if (path / check).fileExists(): - return - - echo "# Running cmake " & flags - echo "# Path: " & path - - mkDir(path) - - var - cmd = &"cd {path.quoteShell} && cmake {flags}" - - echo execAction(cmd) - - doAssert (path / check).fileExists(), "# cmake failed" - -proc make*(path, check: string, flags = "") = - ## Run the `make` command to build all binaries in the specified path - ## - ## `check` is a file that will be generated by the `make` command. - ## This is required to prevent `make` from running on every build. It - ## is relative to the `path` and should not be an absolute path. - ## - ## `flags` are any flags that should be passed to the `make` command. - ## - ## If make.exe is missing and mingw32-make.exe is available, it will - ## be copied over to make.exe in the same location. - if (path / check).fileExists(): - return - - echo "# Running make " & flags - echo "# Path: " & path - - var - cmd = findExe("make") - - if cmd.len == 0: - cmd = findExe("mingw32-make") - if cmd.len != 0: - cpFile(cmd, cmd.replace("mingw32-make", "make")) - doAssert cmd.len != 0, "Make not found" - - cmd = &"cd {path.quoteShell} && make" - if flags.len != 0: - cmd &= &" {flags}" - - echo execAction(cmd) - - doAssert (path / check).fileExists(), "# make failed" +include build \ No newline at end of file diff --git a/nimterop/setup.nim b/nimterop/setup.nim index 8e70e64..4ee375b 100644 --- a/nimterop/setup.nim +++ b/nimterop/setup.nim @@ -1,6 +1,6 @@ import os, strutils -import "."/[git, paths] +import "."/[build, paths] proc treesitterSetup*() = gitPull("https://github.com/tree-sitter/tree-sitter", incDir() / "treesitter", """ diff --git a/nimterop/template.nim b/nimterop/template.nim index 1c9fc7c..b8b894a 100644 --- a/nimterop/template.nim +++ b/nimterop/template.nim @@ -1,6 +1,6 @@ import os, strutils -import nimterop/[cimport, git, paths] +import nimterop/[cimport, build, paths] # Documentation: # https://github.com/nimterop/nimterop diff --git a/nimterop/templite.nim b/nimterop/templite.nim index 71262df..7d8eb5b 100644 --- a/nimterop/templite.nim +++ b/nimterop/templite.nim @@ -1,6 +1,6 @@ import os, strutils -import nimterop/[cimport, git, paths] +import nimterop/[cimport, build, paths] const baseDir = currentSourcePath.parentDir()/"build" diff --git a/tests/tpcre.nim b/tests/tpcre.nim index 705525f..5588850 100644 --- a/tests/tpcre.nim +++ b/tests/tpcre.nim @@ -1,6 +1,6 @@ import os -import nimterop/[cimport, git, paths] +import nimterop/[cimport, build, paths] const baseDir = nimteropBuildDir()/"pcre" diff --git a/tests/tsoloud.nim b/tests/tsoloud.nim index f46dd10..12966a8 100644 --- a/tests/tsoloud.nim +++ b/tests/tsoloud.nim @@ -1,4 +1,4 @@ -import os, nimterop/[cimport, git, paths] +import os, nimterop/[cimport, build, paths] const baseDir = nimteropBuildDir()/"soloud" From 7ef73147a69f224f3df36081afcc7a235cd70b33 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Fri, 23 Aug 2019 07:10:54 -0700 Subject: [PATCH 238/593] getHeader and supporting procs --- nimterop/build.nim | 197 ++++++++++++++++++++++++++++++++++++++++++- nimterop/cimport.nim | 42 +++------ 2 files changed, 210 insertions(+), 29 deletions(-) diff --git a/nimterop/build.nim b/nimterop/build.nim index 72315a6..342e6bc 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -1,4 +1,6 @@ -import os, osproc, strformat, strutils +import macros, osproc, sequtils, strformat, strutils + +import os except findExe import "."/[compat] @@ -292,3 +294,196 @@ proc make*(path, check: string, flags = "") = echo execAction(cmd) doAssert (path / check).fileExists(), "# make failed" + +proc findFile*(file, dir: string): string = + ## Find the file in the specified directory + for f in walkDirRec(dir): + if f.extractFilename() == file: + if result.len == 0 or result.len > f.len: + result = f + +proc getGccPaths*(mode = "c"): seq[string] = + var + nul = when defined(Windows): "nul" else: "/dev/null" + mmode = if mode == "cpp": "c++" else: mode + inc = false + + (outp, ret) = gorgeEx(&"""{getEnv("CC", "gcc")} -Wp,-v -x{mmode} {nul}""") + + for line in outp.splitLines(): + if "#include <...> search starts here" in line: + inc = true + continue + elif "End of search list" in line: + break + if inc: + result.add line.strip() + +proc getStdPath(header: string): string = + for inc in getGccPaths(): + result = findFile(header, inc) + if result.len != 0: + break + +proc getGitPath(header, url, outdir, version: string): string = + doAssert url.len != 0, "No git url setup for " & header + doAssert findExe("git").len != 0, "git executable missing" + + gitPull(url, outdir, checkout = version) + + result = findFile(header, outdir) + +proc getDlPath(header, url, outdir, version: string): string = + doAssert url.len != 0, "No download url setup for " & header + + var + dlurl = url + if "$#" in url or "$1" in url: + doAssert version.len != 0, "Need version for download url" + dlurl = url % version + else: + doAssert version.len == 0, "Download url does not contain version" + + downloadUrl(dlurl, outdir) + + var + dirname = "" + for kind, path in walkDir(outdir, relative = true): + if kind == pcFile and path != dlurl.extractFilename(): + dirname = "" + break + elif kind == pcDir: + if dirname.len == 0: + dirname = path + else: + dirname = "" + break + + if dirname.len != 0: + for kind, path in walkDir(outdir / dirname, relative = true): + mvFile(outdir / dirname / path, outdir / path) + + result = findFile(header, outdir) + +proc getLocalPath(header, outdir: string): string = + if outdir.len != 0: + result = findFile(header, outdir) + +proc buildLibrary(outdir, conFlags, conStaticLib, conDynLib, cmakeFlags, cmakeStaticLib, cmakeDynLib, makeFlags: string) = + var + conDeps = false + conDepStr = "" + cmakeDeps = false + cmakeDepStr = "" + + if fileExists(outdir / "CMakeLists.txt"): + if findExe("cmake").len != 0: + if cmakeStaticLib.len != 0 or cmakeDynLib.len != 0: + var + gen = "" + when defined(windows): + if findExe("sh").len != 0: + gen = "MSYS Makefiles" + else: + gen = "MinGW Makefiles" + else: + gen = "Unix Makefiles" + cmake(outdir / "build", "Makefile", &".. -G {gen.quoteShell} {cmakeFlags}") + cmakeDeps = true + let + check = if cmakeStaticLib.len != 0: cmakeStaticLib else: cmakeDynLib + make(outdir / "build", check, makeFlags) + else: + cmakeDepStr &= "cmakeStatibLib / cmakeDynLib not specified" + else: + cmakeDepStr &= "cmake executable missing" + + template cfgCommon() {.dirty.} = + if (conStaticLib.len != 0 or conDynLib.len != 0): + configure(outdir, "Makefile", conFlags) + conDeps = true + let + check = if conStaticLib.len != 0: conStaticLib else: conDynLib + make(outdir, check, makeFlags) + else: + conDepStr &= "conStaticLib / conDynLib not specified" + + if not cmakeDeps: + if not fileExists(outdir / "configure"): + if fileExists(outdir / "autogen.sh") or fileExists(outdir / "build" / "autogen.sh"): + if findExe("aclocal").len != 0: + if findExe("autoconf").len != 0: + if findExe("libtoolize").len != 0: + cfgCommon() + else: + conDepStr &= "libtoolize executable missing" + else: + conDepStr &= "autoconf executable missing" + else: + conDepStr &= "aclocal executable missing" + else: + if findExe("bash").len != 0: + cfgCommon() + else: + conDepStr &= "bash executable missing" + + var + error = "" + if not cmakeDeps and cmakeDepStr.len != 0: + error &= &"cmake capable but {cmakeDepStr}\n" + if not conDeps and conDepStr.len != 0: + error &= &"configure capable but {conDepStr}\n" + if error.len == 0: + error = "No build files found in " & outdir + doAssert cmakeDeps or conDeps, &"\n# Build configuration failed - {error}\n" + +macro getHeader*(header: static[string], giturl: static[string] = "", dlurl: static[string] = "", outdir: static[string] = "", + conFlags: static[string] = "", conStaticLib: static[string] = "", conDynLib: static[string] = "", + cmakeFlags: static[string] = "", cmakeStaticLib: static[string] = "", cmakeDynLib: static[string] = "", + makeFlags: static[string] = ""): untyped = + ## Get the path to a header file for wrapping with + ## `cImport() `_ or + ## `c2nImport() `_. + ## + ## Checks defines based on the header name (e.g. lzma from lzma.h), to use different + ## ways to obtain the source. + ## + ## ``-d:xxxStd`` - search standard system paths. E.g. ``/usr/include`` and ``/usr/lib`` on Linux + ## ``-d:xxxGit`` - clone source from a git repo specified in ``giturl`` + ## ``-d:xxxDL`` - download source from ``dlurl`` and extract if required + ## + ## This allows a single wrapper to be used in different ways depending on the user's needs. + ## If no defines are specified, ``outdir`` will be searched for the header. + ## + ## The library is then configured (either with cmake or autotools if possible) and then built + ## using make. + var + name = header.split(".")[0] + + stdName = newIdentNode(name & "Std") + gitName = newIdentNode(name & "Git") + dlName = newIdentNode(name & "DL") + + path = newIdentNode(name & "Path") + version = newIdentNode(name & "Version") + + result = newNimNode(nnkStmtList) + result.add(quote do: + const `version`* {.strdefine.} = "" + + when defined(`stdName`): + const `path`* = getStdPath(`header`) + else: + const `path`* = + when defined(`gitName`): + getGitPath(`header`, `giturl`, `outdir`, `version`) + elif defined(`dlName`): + getDlPath(`header`, `dlurl`, `outdir`, `version`) + else: + getLocalPath(`header`, `outdir`) + + static: + doAssert `path`.len != 0, "\nHeader " & `header` & " not found - " & "missing/empty outdir or -d:$1Std -d:$1Git or -d:$1DL not specified" % `name` + + buildLibrary(`outdir`, `conFlags`, `conStaticLib`, `conDynLib`, `cmakeFlags`, `cmakeStaticLib`, `cmakeDynLib`, `makeFlags`) + ) diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index 0e875ed..fc03bc5 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -168,14 +168,6 @@ proc getToast(fullpath: string, recurse: bool = false, dynlib: string = "", (result, ret) = gorgeEx(cmd, cache=getCacheValue(fullpath)) doAssert ret == 0, getToastError(result) -proc getGccPaths(mode = "c"): string = - var - ret = 0 - nul = when defined(Windows): "nul" else: "/dev/null" - mmode = if mode == "cpp": "c++" else: mode - - (result, ret) = gorgeEx(&"""{getEnv("CC", "gcc")} -Wp,-v -x{mmode} {nul}""") - macro cOverride*(body): untyped = ## When the wrapper code generated by nimterop is missing certain symbols or not ## accurate, it may be required to hand wrap them. Define them in a @@ -236,7 +228,8 @@ proc cSkipSymbol*(skips: seq[string]) {.compileTime.} = gStateCT.symOverride.add skips macro cPlugin*(body): untyped = - ## When `cOverride() `_ and `cSkipSymbol() `_ + ## When `cOverride() `_ and + ## `cSkipSymbol() `_ ## are not adequate, the `cPlugin() `_ macro can be used ## to customize the generated Nim output. The following callbacks are available at ## this time. @@ -322,7 +315,8 @@ proc cDebug*() {.compileTime.} = proc cDisableCaching*() {.compileTime.} = ## Disable caching of generated Nim code - useful during wrapper development ## - ## If files included by header being processed by `cImport() `_ + ## If files included by header being processed by + ## `cImport() `_ ## change and affect the generated content, they will be ignored and the cached ## value will continue to be used . Use `cDisableCaching() `_ ## to avoid this scenario during development. @@ -334,8 +328,8 @@ proc cDisableCaching*() {.compileTime.} = macro cDefine*(name: static string, val: static string = ""): untyped = ## ``#define`` an identifer that is forwarded to the C/C++ preprocessor if ## called within `cImport() `_ - ## or `c2nImport() `_ as well as to the - ## C/C++ compiler during Nim compilation using ``{.passC: "-DXXX".}`` + ## or `c2nImport() `_ + ## as well as to the C/C++ compiler during Nim compilation using ``{.passC: "-DXXX".}`` result = newNimNode(nnkStmtList) @@ -370,8 +364,8 @@ proc cAddSearchDir*(dir: string) {.compileTime.} = macro cIncludeDir*(dir: static string): untyped = ## Add an include directory that is forwarded to the C/C++ preprocessor if ## called within `cImport() `_ - ## or `c2nImport() `_ as well as to the - ## C/C++ compiler during Nim compilation using ``{.passC: "-IXXX".}``. + ## or `c2nImport() `_ + ## as well as to the C/C++ compiler during Nim compilation using ``{.passC: "-IXXX".}``. var dir = interpPath(dir) result = newNimNode(nnkStmtList) @@ -392,16 +386,8 @@ proc cAddStdDir*(mode = "c") {.compileTime.} = static: cAddStdDir() import os doAssert cSearchPath("math.h").existsFile - var - inc = false - for line in getGccPaths(mode).splitLines(): - if "#include <...> search starts here" in line: - inc = true - continue - elif "End of search list" in line: - break - if inc: - cAddSearchDir line.strip() + for inc in getGccPaths(mode): + cAddSearchDir inc macro cCompile*(path: static string, mode = "c", exclude = ""): untyped = ## Compile and link C/C++ implementation into resulting binary using ``{.compile.}`` @@ -528,8 +514,8 @@ macro cImport*(filename: static string, recurse: static bool = false, dynlib: st ## cImport("pcre.h", dynlib="dynpcre") ## ## If ``dynlib`` is not specified, the C/C++ implementation files can be compiled in - ## with `cCompile() `_, or the ``{.passL.}`` pragma - ## can be used to specify the static lib to link. + ## with `cCompile() `_, or the + ## ``{.passL.}`` pragma can be used to specify the static lib to link. ## ## ``mode`` is purely for forward compatibility when toast adds C++ support. It can ## be ignored for the foreseeable future. @@ -562,8 +548,8 @@ macro c2nImport*(filename: static string, recurse: static bool = false, dynlib: mode: static string = "c", flags: static string = ""): untyped = ## Import all supported definitions from specified header file using ``c2nim`` ## - ## Similar to `cImport() `_ but uses ``c2nim`` to generate - ## the Nim wrapper instead of ``toast``. Note that neither + ## Similar to `cImport() `_ + ## but uses ``c2nim`` to generate the Nim wrapper instead of ``toast``. Note that neither ## `cOverride() `_, `cSkipSymbol() `_ ## nor `cPlugin() `_ have any impact on ``c2nim``. ## From 182d473973294585a5348d6fc1d01dd209136a4c Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Fri, 23 Aug 2019 16:00:43 -0500 Subject: [PATCH 239/593] findFile w/regex, make -j, lib support for getHeader, noexcept / throw --- nimterop.nimble | 6 +- nimterop/build.nim | 210 ++++++++++++++++++++++++++++++------------- nimterop/grammar.nim | 1 + 3 files changed, 153 insertions(+), 64 deletions(-) diff --git a/nimterop.nimble b/nimterop.nimble index 9910444..1014e66 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -36,12 +36,16 @@ proc testAll() = execCmd "nim cpp -r tests/tnimterop_cpp.nim" execTest "tests/tpcre.nim" - ## platform specific tests + # platform specific tests when defined(Windows): execTest "tests/tmath.nim" if defined(OSX) or defined(Windows) or not existsEnv("TRAVIS"): tsoloud() # requires some libraries on linux, need them installed in TRAVIS + # getHeader tests + withDir("tests"): + execCmd("nim e getheader.nims") + const htmldocsDir = "build/htmldocs" when (NimMajor, NimMinor, NimPatch) >= (0, 19, 9): diff --git a/nimterop/build.nim b/nimterop/build.nim index 342e6bc..53237c0 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -1,4 +1,4 @@ -import macros, osproc, sequtils, strformat, strutils +import macros, osproc, regex, sequtils, strformat, strutils import os except findExe @@ -194,6 +194,29 @@ proc gitPull*(url: string, outdir = "", plist = "", checkout = "") = echo "# Pulling repository" discard execAction(&"cd {outdirQ} && git pull --depth=1 origin master") +proc findFile*(file: string|Regex, dir: string, recurse = true, first = false): string = + ## Find the file in the specified directory + ## + ## ``file`` can be a string or a regex object + ## + ## Turn off recursive search with ``recurse`` and stop on first match with + ## ``first``. Without it, the shortest match is returned. + when file is Regex: + var + rm: RegexMatch + + for f in walkDirRec(dir, followFilter = if recurse: {pcDir} else: {}): + let + fn = f.extractFilename() + when file is string: + if (result.len == 0 or result.len > f.len) and fn == file: + result = f + if first: break + else: + if (result.len == 0 or result.len > f.len) and fn.match(file, rm): + result = f + if first: break + proc configure*(path, check: string, flags = "") = ## Run the GNU `configure` command to generate all Makefiles or other ## build scripts in the specified path @@ -261,7 +284,7 @@ proc cmake*(path, check, flags: string) = doAssert (path / check).fileExists(), "# cmake failed" -proc make*(path, check: string, flags = "") = +proc make*(path, check: string|Regex, flags = "") = ## Run the `make` command to build all binaries in the specified path ## ## `check` is a file that will be generated by the `make` command. @@ -272,7 +295,7 @@ proc make*(path, check: string, flags = "") = ## ## If make.exe is missing and mingw32-make.exe is available, it will ## be copied over to make.exe in the same location. - if (path / check).fileExists(): + if findFile(check, path).len != 0: return echo "# Running make " & flags @@ -293,14 +316,7 @@ proc make*(path, check: string, flags = "") = echo execAction(cmd) - doAssert (path / check).fileExists(), "# make failed" - -proc findFile*(file, dir: string): string = - ## Find the file in the specified directory - for f in walkDirRec(dir): - if f.extractFilename() == file: - if result.len == 0 or result.len > f.len: - result = f + doAssert findFile(check, path).len != 0, "# make failed" proc getGccPaths*(mode = "c"): seq[string] = var @@ -308,7 +324,7 @@ proc getGccPaths*(mode = "c"): seq[string] = mmode = if mode == "cpp": "c++" else: mode inc = false - (outp, ret) = gorgeEx(&"""{getEnv("CC", "gcc")} -Wp,-v -x{mmode} {nul}""") + (outp, _) = gorgeEx(&"""{getEnv("CC", "gcc")} -Wp,-v -x{mmode} {nul}""") for line in outp.splitLines(): if "#include <...> search starts here" in line: @@ -317,11 +333,38 @@ proc getGccPaths*(mode = "c"): seq[string] = elif "End of search list" in line: break if inc: - result.add line.strip() + var + path = line.strip() + path.normalizePath() + if path notin result: + result.add path + +proc getGccLibPaths*(mode = "c"): seq[string] = + var + nul = when defined(Windows): "nul" else: "/dev/null" + mmode = if mode == "cpp": "c++" else: mode + + (outp, _) = gorgeEx(&"""{getEnv("CC", "gcc")} -v -x{mmode} {nul}""") + + for line in outp.splitLines(): + if "LIBRARY_PATH=" in line: + for path in line[13 .. ^1].split(PathSep): + var + path = path.strip() + path.normalizePath() + if path notin result: + result.add path + break proc getStdPath(header: string): string = for inc in getGccPaths(): - result = findFile(header, inc) + result = findFile(header, inc, recurse = false, first = true) + if result.len != 0: + break + +proc getStdLibPath(lname: string): string = + for lib in getGccLibPaths(): + result = findFile(re(lname), lib, recurse = false, first = true) if result.len != 0: break @@ -369,44 +412,49 @@ proc getLocalPath(header, outdir: string): string = if outdir.len != 0: result = findFile(header, outdir) -proc buildLibrary(outdir, conFlags, conStaticLib, conDynLib, cmakeFlags, cmakeStaticLib, cmakeDynLib, makeFlags: string) = +proc getNumProcs(): string = + when defined(windows): + getEnv("NUMBER_OF_PROCESSORS").strip() + elif defined(linux): + execAction("nproc").strip() + elif defined(macosx): + execAction("sysctl -n hw.ncpu").strip() + else: + "1" + +proc buildLibrary(lname, outdir, conFlags, cmakeFlags, makeFlags: string): string = var conDeps = false conDepStr = "" cmakeDeps = false cmakeDepStr = "" + lpath = findFile(re(lname), outdir) + makeFlagsProc = &"-j {getNumProcs()} {makeFlags}" + + if lpath.len != 0: + return lpath if fileExists(outdir / "CMakeLists.txt"): if findExe("cmake").len != 0: - if cmakeStaticLib.len != 0 or cmakeDynLib.len != 0: - var - gen = "" - when defined(windows): - if findExe("sh").len != 0: - gen = "MSYS Makefiles" - else: - gen = "MinGW Makefiles" + var + gen = "" + when defined(windows): + if findExe("sh").len != 0: + gen = "MSYS Makefiles" else: - gen = "Unix Makefiles" - cmake(outdir / "build", "Makefile", &".. -G {gen.quoteShell} {cmakeFlags}") - cmakeDeps = true - let - check = if cmakeStaticLib.len != 0: cmakeStaticLib else: cmakeDynLib - make(outdir / "build", check, makeFlags) + gen = "MinGW Makefiles" else: - cmakeDepStr &= "cmakeStatibLib / cmakeDynLib not specified" + gen = "Unix Makefiles" + cmake(outdir / "build", "Makefile", &".. -G {gen.quoteShell} {cmakeFlags}") + cmakeDeps = true + make(outdir / "build", re(lname), makeFlagsProc) else: cmakeDepStr &= "cmake executable missing" template cfgCommon() {.dirty.} = - if (conStaticLib.len != 0 or conDynLib.len != 0): - configure(outdir, "Makefile", conFlags) - conDeps = true - let - check = if conStaticLib.len != 0: conStaticLib else: conDynLib - make(outdir, check, makeFlags) - else: - conDepStr &= "conStaticLib / conDynLib not specified" + configure(outdir, "Makefile", conFlags) + conDeps = true + make(outdir, re(lname), makeFlagsProc) if not cmakeDeps: if not fileExists(outdir / "configure"): @@ -437,53 +485,89 @@ proc buildLibrary(outdir, conFlags, conStaticLib, conDynLib, cmakeFlags, cmakeSt error = "No build files found in " & outdir doAssert cmakeDeps or conDeps, &"\n# Build configuration failed - {error}\n" + result = findFile(re(lname), outdir) + +proc getDynlibExt(): string = + when defined(windows): + result = ".dll" + elif defined(linux): + result = ".so[0-9.]*" + elif defined(macosx): + result = ".dylib[0-9.]*" + macro getHeader*(header: static[string], giturl: static[string] = "", dlurl: static[string] = "", outdir: static[string] = "", - conFlags: static[string] = "", conStaticLib: static[string] = "", conDynLib: static[string] = "", - cmakeFlags: static[string] = "", cmakeStaticLib: static[string] = "", cmakeDynLib: static[string] = "", - makeFlags: static[string] = ""): untyped = + conFlags: static[string] = "", cmakeFlags: static[string] = "", makeFlags: static[string] = ""): untyped = ## Get the path to a header file for wrapping with ## `cImport() `_ or ## `c2nImport() `_. ## - ## Checks defines based on the header name (e.g. lzma from lzma.h), to use different - ## ways to obtain the source. + ## This proc checks -d:xxx defines based on the header name (e.g. lzma from lzma.h), + ## and accordingly employs different ways to obtain the source. ## ## ``-d:xxxStd`` - search standard system paths. E.g. ``/usr/include`` and ``/usr/lib`` on Linux ## ``-d:xxxGit`` - clone source from a git repo specified in ``giturl`` ## ``-d:xxxDL`` - download source from ``dlurl`` and extract if required ## ## This allows a single wrapper to be used in different ways depending on the user's needs. - ## If no defines are specified, ``outdir`` will be searched for the header. + ## If no -d:xxx defines are specified, ``outdir`` will be searched for the header. ## - ## The library is then configured (either with cmake or autotools if possible) and then built - ## using make. + ## The library is then configured (with cmake or autotools if possible) and built + ## using make, unless using ``-d:xxxStd`` which presumes that the system package + ## manager was used to install prebuilt headers and binaries. + ## + ## The header path is stored in ``const xxxPath`` and can be used in a ``cImport()`` call + ## in the calling wrapper. The dynamic library path is stored in ``const xxxLPath`` and can + ## be used for the ``dynlib`` parameter (within quotes). + ## + ## ``-d:xxxStatic`` can be specified to statically link with the library instead. This + ## will automatically add a ``{.passL.}`` call to the static library for convenience. var name = header.split(".")[0] - stdName = newIdentNode(name & "Std") - gitName = newIdentNode(name & "Git") - dlName = newIdentNode(name & "DL") + nameStd = newIdentNode(name & "Std") + nameGit = newIdentNode(name & "Git") + nameDL = newIdentNode(name & "DL") + + nameStatic = newIdentNode(name & "Static") path = newIdentNode(name & "Path") + lpath = newIdentNode(name & "LPath") version = newIdentNode(name & "Version") + lname = newIdentNode(name & "LName") + + lre = "(lib)?$1[0-9.\\-]*\\" % name result = newNimNode(nnkStmtList) result.add(quote do: - const `version`* {.strdefine.} = "" - - when defined(`stdName`): - const `path`* = getStdPath(`header`) - else: - const `path`* = - when defined(`gitName`): - getGitPath(`header`, `giturl`, `outdir`, `version`) - elif defined(`dlName`): - getDlPath(`header`, `dlurl`, `outdir`, `version`) + const + `version`* {.strdefine.} = "" + `lname` = + when defined(`nameStatic`): + `lre` & ".a" else: - getLocalPath(`header`, `outdir`) + `lre` & getDynlibExt() - static: - doAssert `path`.len != 0, "\nHeader " & `header` & " not found - " & "missing/empty outdir or -d:$1Std -d:$1Git or -d:$1DL not specified" % `name` + when defined(`nameStd`): + const + `path`* = getStdPath(`header`) + `lpath`* = getStdLibPath(`lname`) + else: + const + `path`* = + when defined(`nameGit`): + getGitPath(`header`, `giturl`, `outdir`, `version`) + elif defined(`nameDL`): + getDlPath(`header`, `dlurl`, `outdir`, `version`) + else: + getLocalPath(`header`, `outdir`) - buildLibrary(`outdir`, `conFlags`, `conStaticLib`, `conDynLib`, `cmakeFlags`, `cmakeStaticLib`, `cmakeDynLib`, `makeFlags`) + `lpath`* = buildLibrary(`lname`, `outdir`, `conFlags`, `cmakeFlags`, `makeFlags`) + + static: + doAssert `path`.len != 0, "\nHeader " & `header` & " not found - " & "missing/empty outdir or -d:$1Std -d:$1Git or -d:$1DL not specified" % `name` + doAssert `lpath`.len != 0, "\nLibrary " & `lname` & " not found" + echo "# Including library " & `lpath` + + when defined(`nameStatic`): + {.passL: `lpath`.} ) diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index a66442f..6e2db16 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -73,6 +73,7 @@ proc initGrammar(): Grammar = (type_identifier) ) {paramListGrammar} + (noexcept|throw_specifier?) ) """ From ba2bd6e40a1a4b954fd0d508f5cc98d0f06d62bc Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Fri, 23 Aug 2019 16:16:00 -0500 Subject: [PATCH 240/593] Add getheader test --- .travis.yml | 4 ++-- nimterop/types.nim | 24 ++++++++++++++---------- tests/getheader.nims | 42 ++++++++++++++++++++++++++++++++++++++++++ tests/lzma.nim | 41 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 99 insertions(+), 12 deletions(-) create mode 100644 tests/getheader.nims create mode 100644 tests/lzma.nim diff --git a/.travis.yml b/.travis.yml index f323941..e56a392 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,13 +6,13 @@ language: c env: - BRANCH=0.19.6 - - BRANCH=0.20.0 + - BRANCH=0.20.2 - BRANCH=devel cache: directories: - "$HOME/.choosenim/toolchains/nim-0.19.6" - - "$HOME/.choosenim/toolchains/nim-0.20.0" + - "$HOME/.choosenim/toolchains/nim-0.20.2" install: # `set -u` failed for ubuntu: /home/travis/.travis/job_stages: line 107: secure: unbound variable diff --git a/nimterop/types.nim b/nimterop/types.nim index 5b4ad5f..709aa79 100644 --- a/nimterop/types.nim +++ b/nimterop/types.nim @@ -13,25 +13,29 @@ when (NimMajor, NimMinor, NimPatch) < (0, 19, 9): type Time {.importc: "time_t", header: "".} = distinct int64 elif defined(posix): import posix - type time_t* = Time + type + time_t* = Time + wchar_t* {.importc.} = object else: import std/time_t as time_t_temp type time_t* = time_t_temp.Time + when defined(c): + # http://www.cplusplus.com/reference/cwchar/wchar_t/ + # In C++, wchar_t is a distinct fundamental type (and thus it is + # not defined in nor any other header). + type + wchar_t* {.importc, header:"".} = object + elif defined(cpp): + type + wchar_t* {.importc.} = object + type ptrdiff_t* = ByteAddress type va_list* {.importc, header:"".} = object -when defined(c): - # http://www.cplusplus.com/reference/cwchar/wchar_t/ In C++, wchar_t is a distinct fundamental type (and thus it is not defined in nor any other header). - type - wchar_t* {.importc, header:"".} = object -elif defined(cpp): - type - wchar_t* {.importc.} = object - template enumOp*(op, typ, typout) = proc op*(x: typ, y: int): typout {.borrow.} proc op*(x: int, y: typ): typout {.borrow.} @@ -75,4 +79,4 @@ template defineEnum*(typ) = proc `/`*(x: typ, y: int): typ = `/`(x, y.typ) proc `/`*(x: int, y: typ): typ = `/`(x.typ, y) - proc `$` *(x: typ): string {.borrow.} \ No newline at end of file + proc `$` *(x: typ): string {.borrow.} diff --git a/tests/getheader.nims b/tests/getheader.nims new file mode 100644 index 0000000..57584a6 --- /dev/null +++ b/tests/getheader.nims @@ -0,0 +1,42 @@ +import strutils + +proc testCall(cmd, output: string, exitCode: int, delete = true) = + if delete: + rmDir("build/liblzma") + echo cmd + var + ccmd = + when defined(windows): + "cmd /c " & cmd + else: + cmd + (outp, exitC) = gorgeEx(ccmd) + echo outp + doAssert exitC == exitCode, $exitC + doAssert outp.contains(output), outp + +var + cmd = "nim c -f" + rcmd = " -r lzma.nim" + exp = "liblzma version = " + +when defined(linux): + testCall(cmd & rcmd, "No build files found", 1) + + # stdlib + testCall(cmd & " -d:lzmaStd" & rcmd, exp, 0) + testCall(cmd & " -d:lzmaStd -d:lzmaStatic" & rcmd, exp, 0) + + # git + testCall(cmd & " -d:lzmaGit" & rcmd, exp, 0) + testCall(cmd & " -d:lzmaGit -d:lzmaStatic" & rcmd, exp, 0, delete = false) + + # git tag + testCall(cmd & " -d:lzmaGit -d:lzmaVersion=v5.2.0" & rcmd, exp & "5.2.0", 0) + testCall(cmd & " -d:lzmaGit -d:lzmaStatic -d:lzmaVersion=v5.2.0" & rcmd, exp & "5.2.0", 0, delete = false) + testCall("cd build/liblzma && git branch", "v5.2.0", 0, delete = false) + + # dl + testCall(cmd & " -d:lzmaDL" & rcmd, "Need version", 1) + testCall(cmd & " -d:lzmaDL -d:lzmaVersion=v5.2.4" & rcmd, exp & "5.2.4", 0) + testCall(cmd & " -d:lzmaDL -d:lzmaStatic -d:lzmaVersion=v5.2.4" & rcmd, exp & "5.2.4", 0, delete = false) diff --git a/tests/lzma.nim b/tests/lzma.nim new file mode 100644 index 0000000..0cb92f5 --- /dev/null +++ b/tests/lzma.nim @@ -0,0 +1,41 @@ +import os, strutils + +import nimterop/[build, cimport] + +const + baseDir = currentSourcePath.parentDir()/"build/liblzma" + +static: + cDebug() + +getHeader( + "lzma.h", + giturl = "https://github.com/xz-mirror/xz", + dlurl = "https://github.com/xz-mirror/xz/archive/$1.zip", + outdir = baseDir, + conFlags = "--disable-xz --disable-xzdec --disable-lzmadec --disable-lzmainfo" +) + +cPlugin: + import strutils + + proc onSymbol*(sym: var Symbol) {.exportc, dynlib.} = + sym.name = sym.name.strip(chars = {'_'}) + +cOverride: + type + lzma_internal = object + lzma_index = object + lzma_index_hash = object + + lzma_options_lzma = object + lzma_stream_flags = object + lzma_block = object + lzma_index_iter = object + +when not defined(lzmaStatic): + cImport(lzmaPath, recurse = true, dynlib = "lzmaLPath") +else: + cImport(lzmaPath, recurse = true) + +echo "liblzma version = " & $lzma_version_string() \ No newline at end of file From 9c51c824182a1b3180cecdd86b5af6c9dbc958ab Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Fri, 30 Aug 2019 19:08:35 -0500 Subject: [PATCH 241/593] Add autopoint detection --- .travis.yml | 6 +++++- appveyor.yml | 4 +++- nimterop/build.nim | 5 ++++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index e56a392..564c34d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,6 +2,11 @@ os: - linux - osx +addons: + apt: + packages: + - autopoint + language: c env: @@ -15,7 +20,6 @@ cache: - "$HOME/.choosenim/toolchains/nim-0.20.2" install: - # `set -u` failed for ubuntu: /home/travis/.travis/job_stages: line 107: secure: unbound variable - set -e - export CHOOSENIM_CHOOSE_VERSION=$BRANCH - | diff --git a/appveyor.yml b/appveyor.yml index 9525673..5386bbc 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -10,7 +10,7 @@ matrix: environment: matrix: - NIM_VERSION: 0.19.6 - - NIM_VERSION: 0.20.0 + - NIM_VERSION: 0.20.2 for: - @@ -54,6 +54,8 @@ for: - image: Ubuntu install: + - sudo apt-get update + - sudo apt-get --yes --force-yes install liblzma-dev liblzma5 autopoint - if [ ! -e /home/appveyor/binaries ]; then echo $NIM_VERSION && mkdir /home/appveyor/binaries && diff --git a/nimterop/build.nim b/nimterop/build.nim index 53237c0..dfeb2d4 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -462,7 +462,10 @@ proc buildLibrary(lname, outdir, conFlags, cmakeFlags, makeFlags: string): strin if findExe("aclocal").len != 0: if findExe("autoconf").len != 0: if findExe("libtoolize").len != 0: - cfgCommon() + if findExe("autopoint").len != 0: + cfgCommon() + else: + conDepStr &= "autopoint executable missing" else: conDepStr &= "libtoolize executable missing" else: From 6bc0c4aa3b82a0ccd3144530b81a5cd922dc1bb3 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 4 Sep 2019 00:35:33 -0500 Subject: [PATCH 242/593] OSX support for getHeader, handle symlinks --- .travis.yml | 2 +- nimterop/build.nim | 14 +++++++++++--- nimterop/getters.nim | 6 ++++++ nimterop/toast.nim | 2 +- tests/getheader.nims | 2 +- 5 files changed, 20 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 564c34d..d866260 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,7 +25,7 @@ install: - | curl https://nim-lang.org/choosenim/init.sh -sSf > init.sh sh init.sh -y - - export PATH=$HOME/.nimble/bin:$PATH + - export PATH="$HOME/.nimble/bin:/usr/local/opt/gettext/bin:$PATH" script: - set -e diff --git a/nimterop/build.nim b/nimterop/build.nim index dfeb2d4..0585d36 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -205,7 +205,8 @@ proc findFile*(file: string|Regex, dir: string, recurse = true, first = false): var rm: RegexMatch - for f in walkDirRec(dir, followFilter = if recurse: {pcDir} else: {}): + for f in walkDirRec(dir, yieldFilter = {pcFile, pcLinkToFile}, + followFilter = if recurse: {pcDir} else: {}): let fn = f.extractFilename() when file is string: @@ -343,8 +344,9 @@ proc getGccLibPaths*(mode = "c"): seq[string] = var nul = when defined(Windows): "nul" else: "/dev/null" mmode = if mode == "cpp": "c++" else: mode + linker = when defined(OSX): "-Xlinker" else: "" - (outp, _) = gorgeEx(&"""{getEnv("CC", "gcc")} -v -x{mmode} {nul}""") + (outp, _) = gorgeEx(&"""{getEnv("CC", "gcc")} {linker} -v -x{mmode} {nul}""") for line in outp.splitLines(): if "LIBRARY_PATH=" in line: @@ -355,6 +357,12 @@ proc getGccLibPaths*(mode = "c"): seq[string] = if path notin result: result.add path break + elif '\t' in line: + var + path = line.strip() + path.normalizePath() + if path notin result: + result.add path proc getStdPath(header: string): string = for inc in getGccPaths(): @@ -461,7 +469,7 @@ proc buildLibrary(lname, outdir, conFlags, cmakeFlags, makeFlags: string): strin if fileExists(outdir / "autogen.sh") or fileExists(outdir / "build" / "autogen.sh"): if findExe("aclocal").len != 0: if findExe("autoconf").len != 0: - if findExe("libtoolize").len != 0: + if findExe("libtoolize").len != 0 or findExe("glibtoolize").len != 0: if findExe("autopoint").len != 0: cfgCommon() else: diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 04ed5cf..f1559db 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -403,3 +403,9 @@ proc loadPlugin*(gState: State, sourcePath: string) = gState.onSymbol = cast[OnSymbol](lib.symAddr("onSymbol")) doAssert gState.onSymbol != nil, "onSymbol() load failed from " & pdll + +proc expandSymlinkAbs*(path: string): string = + try: + result = path.expandSymlink().absolutePath(path.parentDir()) + except: + result = path diff --git a/nimterop/toast.nim b/nimterop/toast.nim index 6e38670..b66a3c6 100644 --- a/nimterop/toast.nim +++ b/nimterop/toast.nim @@ -145,7 +145,7 @@ proc main( if gState.pnim: printNimHeader() for src in source: - gState.process(src, astTable) + gState.process(src.expandSymlinkAbs(), astTable) when isMainModule: import cligen diff --git a/tests/getheader.nims b/tests/getheader.nims index 57584a6..6d0f73a 100644 --- a/tests/getheader.nims +++ b/tests/getheader.nims @@ -20,7 +20,7 @@ var rcmd = " -r lzma.nim" exp = "liblzma version = " -when defined(linux): +when defined(posix): testCall(cmd & rcmd, "No build files found", 1) # stdlib From 5bf5c7445da4849dc7bf01086ed2b7117a79ed41 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 5 Sep 2019 16:04:37 -0500 Subject: [PATCH 243/593] autoreconf, don't find tools --- nimterop/build.nim | 87 ++++++++++++++++++++++++---------------------- 1 file changed, 45 insertions(+), 42 deletions(-) diff --git a/nimterop/build.nim b/nimterop/build.nim index 0585d36..15581eb 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -225,6 +225,9 @@ proc configure*(path, check: string, flags = "") = ## If a `configure` script is not present and an `autogen.sh` script ## is present, it will be run before attempting `configure`. ## + ## Next, if `configure.ac` or `configure.in` exist, `autoreconf` will + ## be executed. + ## ## `check` is a file that will be generated by the `configure` command. ## This is required to prevent configure from running on every build. It ## is relative to the `path` and should not be an absolute path. @@ -236,11 +239,20 @@ proc configure*(path, check: string, flags = "") = echo "# Configuring " & path if not fileExists(path / "configure"): - for i in @[path / "autogen.sh", path / "build" / "autogen.sh"]: - if fileExists(i): + for i in @["autogen.sh", "build" / "autogen.sh"]: + if fileExists(path / i): echo "# Running autogen.sh" - discard execAction(&"cd {i.parentDir().quoteShell} && bash autogen.sh") + echo execAction(&"cd {(path / i).parentDir().quoteShell} && bash autogen.sh") + + break + + if not fileExists(path / "configure"): + for i in @["configure.ac", "configure.in"]: + if fileExists(path / i): + echo "# Running autoreconf" + + echo execAction(&"cd {path.quoteShell} && autoreconf -fi") break @@ -438,54 +450,45 @@ proc buildLibrary(lname, outdir, conFlags, cmakeFlags, makeFlags: string): strin cmakeDepStr = "" lpath = findFile(re(lname), outdir) makeFlagsProc = &"-j {getNumProcs()} {makeFlags}" + made = false + makePath = outdir if lpath.len != 0: return lpath - if fileExists(outdir / "CMakeLists.txt"): - if findExe("cmake").len != 0: - var - gen = "" - when defined(windows): - if findExe("sh").len != 0: - gen = "MSYS Makefiles" - else: - gen = "MinGW Makefiles" - else: - gen = "Unix Makefiles" - cmake(outdir / "build", "Makefile", &".. -G {gen.quoteShell} {cmakeFlags}") - cmakeDeps = true - make(outdir / "build", re(lname), makeFlagsProc) - else: - cmakeDepStr &= "cmake executable missing" - - template cfgCommon() {.dirty.} = - configure(outdir, "Makefile", conFlags) - conDeps = true - make(outdir, re(lname), makeFlagsProc) - - if not cmakeDeps: - if not fileExists(outdir / "configure"): - if fileExists(outdir / "autogen.sh") or fileExists(outdir / "build" / "autogen.sh"): - if findExe("aclocal").len != 0: - if findExe("autoconf").len != 0: - if findExe("libtoolize").len != 0 or findExe("glibtoolize").len != 0: - if findExe("autopoint").len != 0: - cfgCommon() - else: - conDepStr &= "autopoint executable missing" - else: - conDepStr &= "libtoolize executable missing" + if not fileExists(outdir / "Makefile"): + if fileExists(outdir / "CMakeLists.txt"): + if findExe("cmake").len != 0: + var + gen = "" + when defined(windows): + if findExe("sh").len != 0: + gen = "MSYS Makefiles" else: - conDepStr &= "autoconf executable missing" + gen = "MinGW Makefiles" else: - conDepStr &= "aclocal executable missing" - else: + gen = "Unix Makefiles" + cmake(outdir / "build", "Makefile", &".. -G {gen.quoteShell} {cmakeFlags}") + cmakeDeps = true + makePath = outdir / "build" + else: + cmakeDepStr &= "cmake executable missing" + + if not cmakeDeps: if findExe("bash").len != 0: - cfgCommon() + for file in @["configure", "configure.ac", "configure.in", "autogen.sh", "build/autogen.sh"]: + if fileExists(outdir / file): + configure(outdir, "Makefile", conFlags) + conDeps = true + + break else: conDepStr &= "bash executable missing" + if fileExists(makePath / "Makefile"): + make(makePath, re(lname), makeFlagsProc) + made = true + var error = "" if not cmakeDeps and cmakeDepStr.len != 0: @@ -494,7 +497,7 @@ proc buildLibrary(lname, outdir, conFlags, cmakeFlags, makeFlags: string): strin error &= &"configure capable but {conDepStr}\n" if error.len == 0: error = "No build files found in " & outdir - doAssert cmakeDeps or conDeps, &"\n# Build configuration failed - {error}\n" + doAssert cmakeDeps or conDeps or made, &"\n# Build configuration failed - {error}\n" result = findFile(re(lname), outdir) From 2049787f435440a51c7989ca9939a89d9b2aeff6 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Fri, 6 Sep 2019 11:57:14 -0700 Subject: [PATCH 244/593] More archive support, Windows lzma test --- nimterop/build.nim | 40 ++++++++++++++++++++++++++++++++++++++-- tests/getheader.nims | 8 ++++---- tests/lzma.nim | 2 +- 3 files changed, 43 insertions(+), 7 deletions(-) diff --git a/nimterop/build.nim b/nimterop/build.nim index 15581eb..ee7c4ee 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -1,4 +1,4 @@ -import macros, osproc, regex, sequtils, strformat, strutils +import macros, osproc, regex, strformat, strutils import os except findExe @@ -105,6 +105,39 @@ proc extractZip*(zipfile, outdir: string) = echo "# Extracting " & zipfile discard execAction(&"cd {outdir.quoteShell} && {cmd % zipfile}") +proc extractTar*(tarfile, outdir: string) = + ## Extract a tar file using tar, 7z or 7za to the specified output directory + var + cmd = "" + name = "" + + if findExe("tar").len != 0: + let + ext = tarfile.splitFile().ext.toLowerAscii() + typ = + case ext + of ".gz", ".tgz": "z" + of ".xz": "J" + of ".bz2": "j" + else: "" + + cmd = "tar xvf" & typ & " " & tarfile.quoteShell + else: + for i in ["7z", "7za"]: + if findExe(i).len != 0: + cmd = i & " x $#" % tarfile.quoteShell + + name = tarfile.splitFile().name + if ".tar" in name.toLowerAscii(): + cmd &= " && " & i & " x $#" % name.quoteShell + + break + + echo "# Extracting " & tarfile + discard execAction(&"cd {outdir.quoteShell} && {cmd}") + if name.len != 0: + rmFile(outdir / name) + proc downloadUrl*(url, outdir: string) = ## Download a file using curl or wget (or powershell on Windows) to the specified directory ## @@ -112,8 +145,9 @@ proc downloadUrl*(url, outdir: string) = let file = url.extractFilename() ext = file.splitFile().ext.toLowerAscii() + archives = @[".zip", ".xz", ".gz", ".bz2", ".tgz", ".tar"] - if not (ext == ".zip" and fileExists(outdir/file)): + if not (ext in archives and fileExists(outdir/file)): echo "# Downloading " & file mkDir(outdir) var cmd = findExe("curl") @@ -131,6 +165,8 @@ proc downloadUrl*(url, outdir: string) = if ext == ".zip": extractZip(file, outdir) + elif ext in archives: + extractTar(file, outdir) proc gitReset*(outdir: string) = ## Hard reset the git repository at the specified directory diff --git a/tests/getheader.nims b/tests/getheader.nims index 6d0f73a..840a114 100644 --- a/tests/getheader.nims +++ b/tests/getheader.nims @@ -36,7 +36,7 @@ when defined(posix): testCall(cmd & " -d:lzmaGit -d:lzmaStatic -d:lzmaVersion=v5.2.0" & rcmd, exp & "5.2.0", 0, delete = false) testCall("cd build/liblzma && git branch", "v5.2.0", 0, delete = false) - # dl - testCall(cmd & " -d:lzmaDL" & rcmd, "Need version", 1) - testCall(cmd & " -d:lzmaDL -d:lzmaVersion=v5.2.4" & rcmd, exp & "5.2.4", 0) - testCall(cmd & " -d:lzmaDL -d:lzmaStatic -d:lzmaVersion=v5.2.4" & rcmd, exp & "5.2.4", 0, delete = false) +# dl +testCall(cmd & " -d:lzmaDL" & rcmd, "Need version", 1) +testCall(cmd & " -d:lzmaDL -d:lzmaVersion=5.2.4" & rcmd, exp & "5.2.4", 0) +testCall(cmd & " -d:lzmaDL -d:lzmaStatic -d:lzmaVersion=5.2.4" & rcmd, exp & "5.2.4", 0, delete = false) diff --git a/tests/lzma.nim b/tests/lzma.nim index 0cb92f5..422f94d 100644 --- a/tests/lzma.nim +++ b/tests/lzma.nim @@ -11,7 +11,7 @@ static: getHeader( "lzma.h", giturl = "https://github.com/xz-mirror/xz", - dlurl = "https://github.com/xz-mirror/xz/archive/$1.zip", + dlurl = "https://tukaani.org/xz/xz-$1.tar.gz", outdir = baseDir, conFlags = "--disable-xz --disable-xzdec --disable-lzmadec --disable-lzmainfo" ) From 9f196e3f77be2728ec7cd5e8caa51b7b882637cd Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Fri, 6 Sep 2019 23:10:28 -0500 Subject: [PATCH 245/593] Fix paths, git for Windows build --- appveyor.yml | 42 +++++++++++++++------------- nimterop/build.nim | 56 ++++++++++++++++++++----------------- nimterop/cimport.nim | 20 ++++++------- nimterop/compat.nim | 12 ++++++-- nimterop/getters.nim | 17 +++++------ nimterop/treesitter/api.nim | 12 ++++---- nimterop/treesitter/c.nim | 2 +- nimterop/treesitter/cpp.nim | 2 +- 8 files changed, 87 insertions(+), 76 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 5386bbc..50d9813 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,8 +1,8 @@ version: '{build}' image: + - Visual Studio 2015 - Ubuntu - - Visual Studio 2017 matrix: fast_finish: true @@ -16,13 +16,12 @@ for: - matrix: only: - - image: Visual Studio 2017 + - image: Visual Studio 2015 environment: - ARCH: 32 - MINGW_URL: https://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win32/Personal%20Builds/mingw-builds/8.1.0/threads-posix/dwarf - MINGW_ARCHIVE: i686-8.1.0-release-posix-dwarf-rt_v6-rev0.7z - SFNET_URL: https://sourceforge.net/projects/msys2/files/REPOS/MINGW/i686 + ARCH: 64 + GIT_URL: https://github.com/git-for-windows/git/releases/download/v2.23.0.windows.1/ + GIT_ARCHIVE: PortableGit-2.23.0-64-bit.7z.exe install: - CD c:\ @@ -30,20 +29,23 @@ for: echo %NIM_VERSION% && MKDIR binaries && CD binaries && - appveyor DownloadFile "%MINGW_URL%/%MINGW_ARCHIVE%/download" -FileName "%MINGW_ARCHIVE%" && - 7z x -y "%MINGW_ARCHIVE%"> nul && - del "%MINGW_ARCHIVE%" && + MKDIR git && + CD git && + appveyor DownloadFile "%GIT_URL%/%GIT_ARCHIVE%" -FileName "%GIT_ARCHIVE%" && + 7z x -y -bd "%GIT_ARCHIVE%"> nul && + del "%GIT_ARCHIVE%" && + CD .. && appveyor DownloadFile "https://nim-lang.org/download/nim-%NIM_VERSION%_x%ARCH%.zip" -FileName "nim-%NIM_VERSION%_x%ARCH%.zip" && 7z x -y "nim-%NIM_VERSION%_x%ARCH%.zip"> nul && del "nim-%NIM_VERSION%_x%ARCH%.zip") - - SET PATH=c:\binaries\mingw%ARCH%\bin;c:\binaries\nim-%NIM_VERSION%\bin;%USERPROFILE%\.nimble\bin;%PATH% + - SET PATH=c:\binaries\git\bin;C:\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\bin;c:\binaries\nim-%NIM_VERSION%\bin;%USERPROFILE%\.nimble\bin;%PATH% - CD %APPVEYOR_BUILD_FOLDER% - on_finish: - - 7z a -r buildlogs-win-pkgs.zip %USERPROFILE%\.nimble\pkgs - - appveyor PushArtifact buildlogs-win-pkgs.zip - - 7z a -r buildlogs-win-projects.zip c:\projects\* - - appveyor PushArtifact buildlogs-win-projects.zip +# on_finish: +# - 7z a -r buildlogs-win-pkgs.zip %USERPROFILE%\.nimble\pkgs +# - appveyor PushArtifact buildlogs-win-pkgs.zip +# - 7z a -r buildlogs-win-projects.zip c:\projects\* +# - appveyor PushArtifact buildlogs-win-projects.zip cache: - c:\binaries @@ -71,11 +73,11 @@ for: - export PATH=/home/appveyor/binaries/nim-$NIM_VERSION/bin:~/.nimble/bin:$PATH - cd $APPVEYOR_BUILD_FOLDER - on_finish: - - zip -r -q buildlogs-lin-pkgs.zip ~/.nimble/pkgs - - appveyor PushArtifact buildlogs-lin-pkgs.zip - - zip -r -q buildlogs-lin-projects.zip /home/appveyor/projects - - appveyor PushArtifact buildlogs-lin-projects.zip +# on_finish: +# - zip -r -q buildlogs-lin-pkgs.zip ~/.nimble/pkgs +# - appveyor PushArtifact buildlogs-lin-pkgs.zip +# - zip -r -q buildlogs-lin-projects.zip /home/appveyor/projects +# - appveyor PushArtifact buildlogs-lin-projects.zip cache: - /home/appveyor/binaries diff --git a/nimterop/build.nim b/nimterop/build.nim index ee7c4ee..7a1aaf9 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -4,6 +4,11 @@ import os except findExe import "."/[compat] +proc sanitizePath*(path: string, noQuote = false): string = + result = path.multiReplace([("\\\\", $DirSep), ("\\", $DirSep), ("/", $DirSep)]) + if not noQuote: + result = result.quoteShell + proc execAction*(cmd: string, nostderr=false): string = ## Execute an external command - supported at compile time ## @@ -39,7 +44,7 @@ proc findExe*(exe: string): string = (oup, code) = gorgeEx(cmd) if code == 0: - return oup.strip() + return oup.splitLines()[0].strip() proc mkDir*(dir: string) = ## Create a directory at cmopile time @@ -49,7 +54,7 @@ proc mkDir*(dir: string) = if not dirExists(dir): let flag = when not defined(Windows): "-p" else: "" - discard execAction(&"mkdir {flag} {dir.quoteShell}") + discard execAction(&"mkdir {flag} {dir.sanitizePath}") proc cpFile*(source, dest: string, move=false) = ## Copy a file from source to destination at compile time @@ -68,7 +73,7 @@ proc cpFile*(source, dest: string, move=false) = else: "cp -f" - discard execAction(&"{cmd} {source.quoteShell} {dest.quoteShell}") + discard execAction(&"{cmd} {source.sanitizePath} {dest.sanitizePath}") proc mvFile*(source, dest: string) = ## Move a file from source to destination at compile time @@ -87,7 +92,7 @@ proc rmFile*(source: string, dir = false) = else: "rm -rf" - discard execAction(&"{cmd} {source.quoteShell}") + discard execAction(&"{cmd} {source.sanitizePath}") proc rmDir*(source: string) = ## Remove a directory or pattern at compile time @@ -103,7 +108,7 @@ proc extractZip*(zipfile, outdir: string) = "[IO.Compression.ZipFile]::ExtractToDirectory('$#', '.'); }\"" echo "# Extracting " & zipfile - discard execAction(&"cd {outdir.quoteShell} && {cmd % zipfile}") + discard execAction(&"cd {outdir.sanitizePath} && {cmd % zipfile}") proc extractTar*(tarfile, outdir: string) = ## Extract a tar file using tar, 7z or 7za to the specified output directory @@ -121,20 +126,22 @@ proc extractTar*(tarfile, outdir: string) = of ".bz2": "j" else: "" - cmd = "tar xvf" & typ & " " & tarfile.quoteShell + cmd = "tar xvf" & typ & " " & tarfile.sanitizePath else: for i in ["7z", "7za"]: if findExe(i).len != 0: - cmd = i & " x $#" % tarfile.quoteShell + cmd = i & " x $#" % tarfile.sanitizePath name = tarfile.splitFile().name if ".tar" in name.toLowerAscii(): - cmd &= " && " & i & " x $#" % name.quoteShell + cmd &= " && " & i & " x $#" % name.sanitizePath break + doAssert cmd.len != 0, "No extraction tool - tar, 7z, 7za - available for " & tarfile.sanitizePath + echo "# Extracting " & tarfile - discard execAction(&"cd {outdir.quoteShell} && {cmd}") + discard execAction(&"cd {outdir.sanitizePath} && {cmd}") if name.len != 0: rmFile(outdir / name) @@ -152,7 +159,7 @@ proc downloadUrl*(url, outdir: string) = mkDir(outdir) var cmd = findExe("curl") if cmd.len != 0: - cmd &= " -L $# -o $#" + cmd &= " -Lk $# -o $#" else: cmd = findExe("wget") if cmd.len != 0: @@ -161,7 +168,7 @@ proc downloadUrl*(url, outdir: string) = cmd = "powershell [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; wget $# -OutFile $#" else: doAssert false, "No download tool available - curl, wget" - discard execAction(cmd % [url, (outdir/file).quoteShell]) + discard execAction(cmd % [url, (outdir/file).sanitizePath]) if ext == ".zip": extractZip(file, outdir) @@ -172,7 +179,7 @@ proc gitReset*(outdir: string) = ## Hard reset the git repository at the specified directory echo "# Resetting " & outdir - let cmd = &"cd {outdir.quoteShell} && git reset --hard" + let cmd = &"cd {outdir.sanitizePath} && git reset --hard" while execAction(cmd).contains("Permission denied"): sleep(1000) echo "# Retrying ..." @@ -185,7 +192,7 @@ proc gitCheckout*(file, outdir: string) = ## successful wrapping with `cImport()` or `c2nImport()`. echo "# Resetting " & file let file2 = file.relativePath outdir - let cmd = &"cd {outdir.quoteShell} && git checkout {file2.quoteShell}" + let cmd = &"cd {outdir.sanitizePath} && git checkout {file2.sanitizePath}" while execAction(cmd).contains("Permission denied"): sleep(500) echo "# Retrying ..." @@ -206,7 +213,7 @@ proc gitPull*(url: string, outdir = "", plist = "", checkout = "") = return let - outdirQ = outdir.quoteShell + outdirQ = outdir.sanitizePath mkDir(outdir) @@ -279,7 +286,7 @@ proc configure*(path, check: string, flags = "") = if fileExists(path / i): echo "# Running autogen.sh" - echo execAction(&"cd {(path / i).parentDir().quoteShell} && bash autogen.sh") + echo execAction(&"cd {(path / i).parentDir().sanitizePath} && bash autogen.sh") break @@ -288,7 +295,7 @@ proc configure*(path, check: string, flags = "") = if fileExists(path / i): echo "# Running autoreconf" - echo execAction(&"cd {path.quoteShell} && autoreconf -fi") + echo execAction(&"cd {path.sanitizePath} && autoreconf -fi") break @@ -296,7 +303,7 @@ proc configure*(path, check: string, flags = "") = echo "# Running configure " & flags var - cmd = &"cd {path.quoteShell} && bash configure" + cmd = &"cd {path.sanitizePath} && bash configure" if flags.len != 0: cmd &= &" {flags}" @@ -327,7 +334,7 @@ proc cmake*(path, check, flags: string) = mkDir(path) var - cmd = &"cd {path.quoteShell} && cmake {flags}" + cmd = &"cd {path.sanitizePath} && cmake {flags}" echo execAction(cmd) @@ -359,7 +366,7 @@ proc make*(path, check: string|Regex, flags = "") = cpFile(cmd, cmd.replace("mingw32-make", "make")) doAssert cmd.len != 0, "Make not found" - cmd = &"cd {path.quoteShell} && make" + cmd = &"cd {path.sanitizePath} && make" if flags.len != 0: cmd &= &" {flags}" @@ -383,8 +390,7 @@ proc getGccPaths*(mode = "c"): seq[string] = break if inc: var - path = line.strip() - path.normalizePath() + path = line.strip().myNormalizedPath() if path notin result: result.add path @@ -400,15 +406,13 @@ proc getGccLibPaths*(mode = "c"): seq[string] = if "LIBRARY_PATH=" in line: for path in line[13 .. ^1].split(PathSep): var - path = path.strip() - path.normalizePath() + path = path.strip().myNormalizedPath() if path notin result: result.add path break elif '\t' in line: var - path = line.strip() - path.normalizePath() + path = line.strip().myNormalizedPath() if path notin result: result.add path @@ -504,7 +508,7 @@ proc buildLibrary(lname, outdir, conFlags, cmakeFlags, makeFlags: string): strin gen = "MinGW Makefiles" else: gen = "Unix Makefiles" - cmake(outdir / "build", "Makefile", &".. -G {gen.quoteShell} {cmakeFlags}") + cmake(outdir / "build", "Makefile", &".. -G {gen.sanitizePath} {cmakeFlags}") cmakeDeps = true makePath = outdir / "build" else: diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index fc03bc5..3c99c81 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -79,11 +79,11 @@ proc getFileDate(fullpath: string): string = ret = 0 cmd = when defined(Windows): - &"cmd /c for %a in ({fullpath.quoteShell}) do echo %~ta" + &"cmd /c for %a in ({fullpath.sanitizePath}) do echo %~ta" elif defined(Linux): - &"stat -c %y {fullpath.quoteShell}" + &"stat -c %y {fullpath.sanitizePath}" elif defined(OSX): - &"stat -f %m {fullpath.quoteShell}" + &"stat -f %m {fullpath.sanitizePath}" (result, ret) = gorgeEx(cmd) @@ -120,7 +120,7 @@ proc getNimCheckError(output: string): tuple[tmpFile, errors: string] = getCurrentCompilerExe() else: "nim" - (check, _) = gorgeEx(&"{nim} check {result.tmpFile.quoteShell}") + (check, _) = gorgeEx(&"{nim} check {result.tmpFile.sanitizePath}") result.errors = "\n\n" & check @@ -131,7 +131,7 @@ proc getToast(fullpath: string, recurse: bool = false, dynlib: string = "", cmd = when defined(Windows): "cmd /c " else: "" let toastExe = toastExePath() - doAssert fileExists(toastExe), "toast not compiled: " & toastExe.quoteShell & + doAssert fileExists(toastExe), "toast not compiled: " & toastExe.sanitizePath & " make sure 'nimble build' or 'nimble install' built it" cmd &= &"{toastExe} --preprocess" @@ -145,7 +145,7 @@ proc getToast(fullpath: string, recurse: bool = false, dynlib: string = "", cmd.add &" --defines+={i.quoteShell}" for i in gStateCT.includeDirs: - cmd.add &" --includeDirs+={i.quoteShell}" + cmd.add &" --includeDirs+={i.sanitizePath}" if not noNimout: cmd.add &" --pnim" @@ -157,12 +157,12 @@ proc getToast(fullpath: string, recurse: bool = false, dynlib: string = "", cmd.add &" --symOverride={gStateCT.symOverride.join(\",\")}" when (NimMajor, NimMinor, NimPatch) >= (0, 19, 9): - cmd.add &" --nim:{getCurrentCompilerExe().quoteShell}" + cmd.add &" --nim:{getCurrentCompilerExe().sanitizePath}" if gStateCT.pluginSourcePath.nBl: - cmd.add &" --pluginSourcePath={gStateCT.pluginSourcePath.quoteShell}" + cmd.add &" --pluginSourcePath={gStateCT.pluginSourcePath.sanitizePath}" - cmd.add &" {fullpath.quoteShell}" + cmd.add &" {fullpath.sanitizePath}" # see https://github.com/nimterop/nimterop/issues/69 (result, ret) = gorgeEx(cmd, cache=getCacheValue(fullpath)) @@ -527,7 +527,7 @@ macro cImport*(filename: static string, recurse: static bool = false, dynlib: st let fullpath = findPath(filename) - echo "# Importing " & fullpath + echo "# Importing " & fullpath.sanitizePath let output = getToast(fullpath, recurse, dynlib, mode, flags) diff --git a/nimterop/compat.nim b/nimterop/compat.nim index 7f89358..1115252 100644 --- a/nimterop/compat.nim +++ b/nimterop/compat.nim @@ -6,10 +6,18 @@ put everything that requires `when (NimMajor, NimMinor, NimPatch)` here import os when (NimMajor, NimMinor, NimPatch) >= (0, 19, 9): + proc myNormalizedPath*(path: string): string = path.normalizedPath() + export relativePath + else: import std/[ospaths,strutils] + proc myNormalizedPath*(path: string): string = + result = path.normalizedPath() + when defined(windows): + result = result.strip(trailing = false, chars = {'\\'}) + proc relativePath*(file, base: string): string = ## naive version of `os.relativePath` ; remove after nim >= 0.19.9 runnableExamples: @@ -17,8 +25,8 @@ else: check: "/foo/bar/baz/log.txt".unixToNativePath.relativePath("/foo/bar".unixToNativePath) == "baz/log.txt".unixToNativePath "foo/bar/baz/log.txt".unixToNativePath.relativePath("foo/bar".unixToNativePath) == "baz/log.txt".unixToNativePath - var base = base.normalizedPath - var file = file.normalizedPath + var base = base.myNormalizedPath + var file = file.myNormalizedPath if not base.endsWith DirSep: base.add DirSep doAssert file.startsWith base result = file[base.len .. ^1] diff --git a/nimterop/getters.nim b/nimterop/getters.nim index f1559db..c5c839d 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -73,9 +73,6 @@ const gTypeMap = { "long double": "clongdouble" }.toTable() -proc sanitizePath*(path: string): string = - path.multiReplace([("\\\\", $DirSep), ("\\", $DirSep), ("/", $DirSep)]) - proc getType*(str: string): string = if str == "void": return "object" @@ -205,15 +202,15 @@ proc getPreprocessor*(gState: State, fullpath: string, mode = "cpp"): string = rdata: seq[string] = @[] start = false - sfile = fullpath.sanitizePath + sfile = fullpath.sanitizePath(noQuote = true) for inc in gState.includeDirs: - cmd &= &"-I{inc.quoteShell} " + cmd &= &"-I{inc.sanitizePath} " for def in gState.defines: cmd &= &"-D{def} " - cmd &= &"{fullpath.quoteShell}" + cmd &= &"{fullpath.sanitizePath}" # Include content only from file for line in execAction(cmd).splitLines(): @@ -221,19 +218,19 @@ proc getPreprocessor*(gState: State, fullpath: string, mode = "cpp"): string = if line.len > 1 and line[0 .. 1] == "# ": start = false let - saniLine = line.sanitizePath + saniLine = line.sanitizePath(noQuote = true) if sfile in saniLine: start = true elif not ("\\" in line) and not ("/" in line) and extractFilename(sfile) in line: start = true elif gState.recurse: let - pDir = sfile.expandFilename().parentDir().sanitizePath() + pDir = sfile.expandFilename().parentDir().sanitizePath(noQuote = true) if pDir.len == 0 or pDir in saniLine: start = true else: for inc in gState.includeDirs: - if inc.absolutePath().sanitizePath in saniLine: + if inc.absolutePath().sanitizePath(noQuote = true) in saniLine: start = true break else: @@ -395,7 +392,7 @@ proc loadPlugin*(gState: State, sourcePath: string) = pdll = sourcePath.dll if not fileExists(pdll) or sourcePath.getLastModificationTime() > pdll.getLastModificationTime(): - discard execAction(&"{gState.nim.quoteShell} c --app:lib {sourcePath.quoteShell}") + discard execAction(&"{gState.nim.sanitizePath} c --app:lib {sourcePath.sanitizePath}") doAssert fileExists(pdll), "No plugin binary generated for " & sourcePath let lib = loadLib(pdll) diff --git a/nimterop/treesitter/api.nim b/nimterop/treesitter/api.nim index 62ebe3b..2c11a60 100644 --- a/nimterop/treesitter/api.nim +++ b/nimterop/treesitter/api.nim @@ -7,17 +7,17 @@ import ".."/[setup, paths, types] static: treesitterSetup() -const sourcePath = incDir() / "treesitter/lib" +const sourcePath = incDir() / "treesitter" / "lib" when defined(Linux): {.passC: "-std=c11".} {.passC: "-DUTF8PROC_STATIC".} -{.passC: "-I$1/include" % sourcePath.} -{.passC: "-I$1/src" % sourcePath.} -{.passC: "-I$1/../../utf8proc" % sourcePath.} +{.passC: "-I$1" % (sourcePath / "include").} +{.passC: "-I$1" % (sourcePath / "src").} +{.passC: "-I$1" % (sourcePath / ".." / ".." / "utf8proc").} -{.compile: sourcePath / "src/lib.c".} +{.compile: sourcePath / "src" / "lib.c".} ### Generated below @@ -27,7 +27,7 @@ defineEnum(TSInputEncoding) defineEnum(TSSymbolType) defineEnum(TSLogType) const - headerapi {.used.} = sourcePath / "include/tree_sitter/api.h" + headerapi {.used.} = sourcePath / "include" / "tree_sitter" / "api.h" TREE_SITTER_LANGUAGE_VERSION* = 9 TSInputEncodingUTF8* = 0.TSInputEncoding TSInputEncodingUTF16* = 1.TSInputEncoding diff --git a/nimterop/treesitter/c.nim b/nimterop/treesitter/c.nim index a39ee65..38fa003 100644 --- a/nimterop/treesitter/c.nim +++ b/nimterop/treesitter/c.nim @@ -5,7 +5,7 @@ import ".."/[setup, paths] static: treesitterCSetup() -const srcDir = incDir() / "treesitter_c/src" +const srcDir = incDir() / "treesitter_c" / "src" import "."/api diff --git a/nimterop/treesitter/cpp.nim b/nimterop/treesitter/cpp.nim index 1b47206..131e57f 100644 --- a/nimterop/treesitter/cpp.nim +++ b/nimterop/treesitter/cpp.nim @@ -5,7 +5,7 @@ import ".."/[setup, paths] static: treesitterCppSetup() -const srcDir = incDir() / "treesitter_cpp/src" +const srcDir = incDir() / "treesitter_cpp" / "src" {.passC: "-I$1" % srcDir.} From 1ccf4c8e41c9aeb60f0a611d8a0d2ed06e4f96eb Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Sun, 8 Sep 2019 18:52:24 -0500 Subject: [PATCH 246/593] Readme update --- README.md | 39 +++++++++++++++++++++++++++++++++++---- nimterop/template.nim | 5 ++++- 2 files changed, 39 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 6dfcb04..982a2e7 100644 --- a/README.md +++ b/README.md @@ -11,14 +11,15 @@ Nim has one of the best FFI you can find - importing C/C++ is supported out of t The goal of nimterop is to leverage the [tree-sitter](http://tree-sitter.github.io/tree-sitter/) engine to parse C/C++ code and then convert relevant portions of the AST into Nim definitions. [tree-sitter](https://github.com/tree-sitter) is a Github sponsored project that can parse a variety of languages into an AST which is then leveraged by the [Atom](https://atom.io/) editor for syntax highlighting and code folding. The advantages of this approach are multifold: - Benefit from the tree-sitter community's investment into language parsing - Wrap what is recognized in the AST rather than completely failing due to parsing errors -- Avoid depending on Nim compiler API which is evolving constantly and makes backwards compatibility a bit challenging -Most of the functionality is contained within the `toast` binary that is built when nimterop is installed and can be used standalone similar to how c2nim can be used today. In addition, nimterop also offers an API to pull in the generated Nim content directly into an application. +Most of the wrapping functionality is contained within the `toast` binary that is built when nimterop is installed and can be used standalone similar to how c2nim can be used today. In addition, nimterop also offers an API to pull in the generated Nim content directly into an application and other nimgen functionality that helps in automating the wrapping process. There is also support to statically or dynamically link to system installed libraries or downloading and building them with `autoconf` or `cmake` from a Git repo or source archive. -The nimterop feature set is still limited to C but is expanding rapidly. C++ support will be added once most popular C libraries can be wrapped seamlessly. +The nimterop wrapping functionality is still limited to C but is constantly expanding. C++ support will be added once most popular C libraries can be wrapped seamlessly. Meanwhile, `c2nim` can also be used in place of `toast` with the `c2nImport()` API call. Nimterop has seen some adoption within the community and the simplicity and success of this approach justifies additional investment of time and effort. Regardless, the goal is to make interop seamless so nimterop will focus on wrapping headers and not the outright conversion of C/C++ implementation. +Also, given tree-sitter can parse a variety of other languages, there might also be value in investigating how to wrap Rust and Go libraries. + __Installation__ Nimterop can be installed via [Nimble](https://github.com/nim-lang/nimble): @@ -37,8 +38,37 @@ This will download and install nimterop in the standard Nimble package location, __Usage__ +Detailed documentation can be found [here](https://nimterop.github.io/nimterop/theindex.html). + Check out the [wiki](https://github.com/nimterop/nimterop/wiki/Wrappers) for a list of all known wrappers that have been created using nimterop. Please do add your project once you are done so that others can benefit from your work. +Using the high-level `getHeader` API to perform all building and linking automatically: +```nim +import nimterop/[build, cimport] + +static: + cDebug() + +getHeader( + "header.h", + giturl = "https://github.com/username/repo", + dlurl = "https://website.org/download/repo-$1.tar.gz", + outdir = "build", + conFlags = "--disable-comp --enable-feature" +) + +when not defined(headerStatic): + cImport(headerPath, recurse = true, dynlib = "headerLPath") +else: + cImport(headerPath, recurse = true) +``` +This allows the user to control how the wrapper works - either pass `-d:headerStd` to search for `header.h` in the standard system path, `-d:headerGit` to clone the source from the specified git URL or `-d:headerDL` to get the source from download URL. Further, the `-d:headerVersion=X.Y.Z` flag can be used to specify which version to use. It is used as the tag name for Git whereas for DL, it replaces `$1` in the URL defined. + +The `-d:headerStatic` attempts to statically link the library. If it is omitted, the library is dynamically linked instead. + +[lzma.nim](https://github.com/nimterop/nimterop/blob/master/tests/lzma.nim) is an example of a library using this high-level API. + +The traditional approach is to manually compile in the code: ```nim import nimterop/cimport @@ -52,10 +82,11 @@ cImport("clib.h") cCompile("clib/src/*.c") ``` -Check out [template.nim](https://github.com/nimterop/nimterop/blob/master/nimterop/template.nim) as a starting point for wrapping a new library. The template can be copied and trimmed down and modified as required. [templite.nim](https://github.com/nimterop/nimterop/blob/master/nimterop/templite.nim) is a shorter version for more experienced users. +Check out [template.nim](https://github.com/nimterop/nimterop/blob/master/nimterop/template.nim) as a starting point for wrapping a library using the traditional approach. The template can be copied and trimmed down and modified as required. [templite.nim](https://github.com/nimterop/nimterop/blob/master/nimterop/templite.nim) is a shorter version for more experienced users. Refer to the ```tests``` directory for examples on how the library can be used. + The `toast` binary can also be used directly on the CLI: ``` diff --git a/nimterop/template.nim b/nimterop/template.nim index b8b894a..f625280 100644 --- a/nimterop/template.nim +++ b/nimterop/template.nim @@ -33,7 +33,10 @@ src/*.c # Run GNU configure on the source when defined(posix): - configure(srcDir, fileThatShouldGetGenerated) + configure(srcDir, fileThatShouldGetGenerated, flagsToConfigure) + + # Run cmake on the source + cmake(srcDir/"build", fileThatShouldGetGenerated, flagsToCmake) # Run standard file/directory operations with mkDir(), cpFile(), mvFile() From a867c726a937c3f44219a5264980f6e3ccf789f4 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Sat, 7 Sep 2019 23:36:16 -0500 Subject: [PATCH 247/593] Normalize symlinks --- nimterop/getters.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimterop/getters.nim b/nimterop/getters.nim index c5c839d..1954623 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -403,6 +403,6 @@ proc loadPlugin*(gState: State, sourcePath: string) = proc expandSymlinkAbs*(path: string): string = try: - result = path.expandSymlink().absolutePath(path.parentDir()) + result = path.expandSymlink().absolutePath(path.parentDir()).normalizedPath() except: result = path From 3a2395360712d2c6f27221e0887b7e3cad0be7a1 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Sun, 8 Sep 2019 18:54:48 -0500 Subject: [PATCH 248/593] Update to v0.2.0 --- nimterop.nimble | 2 +- nimterop/getters.nim | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/nimterop.nimble b/nimterop.nimble index 1014e66..565c3e4 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -1,6 +1,6 @@ # Package -version = "0.1.0" +version = "0.2.0" author = "genotrance" description = "C/C++ interop for Nim" license = "MIT" diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 1954623..54040c0 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -2,7 +2,7 @@ import dynlib, macros, os, sequtils, sets, strformat, strutils, tables, times import regex -import "."/[build, globals, plugin, treesitter/api] +import "."/[build, compat, globals, plugin, treesitter/api] const gReserved = """ addr and as asm @@ -403,6 +403,6 @@ proc loadPlugin*(gState: State, sourcePath: string) = proc expandSymlinkAbs*(path: string): string = try: - result = path.expandSymlink().absolutePath(path.parentDir()).normalizedPath() + result = path.expandSymlink().absolutePath(path.parentDir()).myNormalizedPath() except: result = path From b0447677f1e02ec7d6b070e374e5e92b3ad0ce51 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 9 Sep 2019 15:33:44 -0700 Subject: [PATCH 249/593] Build pre-hook, altNames, uInt, getType() calls, add zlib test Fix subdir header, static lib name, [u]int[\d]+ --- .travis.yml | 2 - README.md | 2 +- nimterop/build.nim | 163 ++++++++++++++++++++++++++++++++++--------- nimterop/cimport.nim | 68 +++++++++--------- nimterop/getters.nim | 12 +++- nimterop/grammar.nim | 8 +-- tests/getheader.nims | 46 ++++++++---- tests/zlib.nim | 68 ++++++++++++++++++ 8 files changed, 279 insertions(+), 90 deletions(-) create mode 100644 tests/zlib.nim diff --git a/.travis.yml b/.travis.yml index d866260..d48afd0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,7 +20,6 @@ cache: - "$HOME/.choosenim/toolchains/nim-0.20.2" install: - - set -e - export CHOOSENIM_CHOOSE_VERSION=$BRANCH - | curl https://nim-lang.org/choosenim/init.sh -sSf > init.sh @@ -28,7 +27,6 @@ install: - export PATH="$HOME/.nimble/bin:/usr/local/opt/gettext/bin:$PATH" script: - - set -e - nimble --verbose install -y - nimble --verbose test - nimble --verbose --nimbleDir:`pwd`/build/fakenimble install nimterop -y diff --git a/README.md b/README.md index 982a2e7..fcab924 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,7 @@ when not defined(headerStatic): else: cImport(headerPath, recurse = true) ``` -This allows the user to control how the wrapper works - either pass `-d:headerStd` to search for `header.h` in the standard system path, `-d:headerGit` to clone the source from the specified git URL or `-d:headerDL` to get the source from download URL. Further, the `-d:headerVersion=X.Y.Z` flag can be used to specify which version to use. It is used as the tag name for Git whereas for DL, it replaces `$1` in the URL defined. +This allows the user to control how the wrapper works - either pass `-d:headerStd` to search for `header.h` in the standard system path, `-d:headerGit` to clone the source from the specified git URL or `-d:headerDL` to get the source from download URL. Further, the `-d:headerSetVer=X.Y.Z` flag can be used to specify which version to use. It is used as the tag name for Git whereas for DL, it replaces `$1` in the URL defined. The `-d:headerStatic` attempts to statically link the library. If it is omitted, the library is dynamically linked instead. diff --git a/nimterop/build.nim b/nimterop/build.nim index 7a1aaf9..2563bb8 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -32,7 +32,7 @@ proc execAction*(cmd: string, nostderr=false): string = doAssert ret == 0, "Command failed: " & $(ret, nostderr) & "\nccmd: " & ccmd & "\nresult:\n" & result proc findExe*(exe: string): string = - ## Find the specified executable using the which/where command - supported + ## Find the specified executable using the `which`/`where` command - supported ## at compile time var cmd = @@ -47,7 +47,7 @@ proc findExe*(exe: string): string = return oup.splitLines()[0].strip() proc mkDir*(dir: string) = - ## Create a directory at cmopile time + ## Create a directory at compile time ## ## The `os` module is not available at compile time so a few ## crucial helper functions are included with nimterop. @@ -57,7 +57,7 @@ proc mkDir*(dir: string) = discard execAction(&"mkdir {flag} {dir.sanitizePath}") proc cpFile*(source, dest: string, move=false) = - ## Copy a file from source to destination at compile time + ## Copy a file from `source` to `dest` at compile time let source = source.replace("/", $DirSep) dest = dest.replace("/", $DirSep) @@ -76,7 +76,7 @@ proc cpFile*(source, dest: string, move=false) = discard execAction(&"{cmd} {source.sanitizePath} {dest.sanitizePath}") proc mvFile*(source, dest: string) = - ## Move a file from source to destination at compile time + ## Move a file from `source` to `dest` at compile time cpFile(source, dest, move=true) proc rmFile*(source: string, dir = false) = @@ -99,7 +99,7 @@ proc rmDir*(source: string) = rmFile(source, dir = true) proc extractZip*(zipfile, outdir: string) = - ## Extract a zip file using powershell on Windows and unzip on other + ## Extract a zip file using `powershell` on Windows and `unzip` on other ## systems to the specified output directory var cmd = "unzip -o $#" if defined(Windows): @@ -111,7 +111,7 @@ proc extractZip*(zipfile, outdir: string) = discard execAction(&"cd {outdir.sanitizePath} && {cmd % zipfile}") proc extractTar*(tarfile, outdir: string) = - ## Extract a tar file using tar, 7z or 7za to the specified output directory + ## Extract a tar file using `tar`, `7z` or `7za` to the specified output directory var cmd = "" name = "" @@ -146,9 +146,9 @@ proc extractTar*(tarfile, outdir: string) = rmFile(outdir / name) proc downloadUrl*(url, outdir: string) = - ## Download a file using curl or wget (or powershell on Windows) to the specified directory + ## Download a file using `curl` or `wget` (or `powershell` on Windows) to the specified directory ## - ## If a zip file, it is automatically extracted after download. + ## If an archive file, it is automatically extracted after download. let file = url.extractFilename() ext = file.splitFile().ext.toLowerAscii() @@ -185,7 +185,7 @@ proc gitReset*(outdir: string) = echo "# Retrying ..." proc gitCheckout*(file, outdir: string) = - ## Checkout the specified file in the git repository specified + ## Checkout the specified `file` in the git repository at `outdir` ## ## This effectively resets all changes in the file and can be ## used to undo any changes that were made to source files to enable @@ -240,13 +240,17 @@ proc gitPull*(url: string, outdir = "", plist = "", checkout = "") = proc findFile*(file: string|Regex, dir: string, recurse = true, first = false): string = ## Find the file in the specified directory ## - ## ``file`` can be a string or a regex object + ## `file` can be a string or a regex object ## - ## Turn off recursive search with ``recurse`` and stop on first match with - ## ``first``. Without it, the shortest match is returned. + ## Turn off recursive search with `recurse` and stop on first match with + ## `first`. Without it, the shortest match is returned. when file is Regex: var rm: RegexMatch + else: + let + dir = dir / file.parentDir() + file = file.extractFilename for f in walkDirRec(dir, yieldFilter = {pcFile, pcLinkToFile}, followFilter = if recurse: {pcDir} else: {}): @@ -311,6 +315,52 @@ proc configure*(path, check: string, flags = "") = doAssert (path / check).fileExists(), "# Configure failed" +proc getCmakePropertyStr(name, property, value: string): string = + &"\nset_target_properties({name} PROPERTIES {property} \"{value}\")\n" + +proc setCmakeProperty*(outdir, name, property, value: string) = + ## Set a `cmake` property in `outdir / CMakeLists.txt` - usable in the `xxxPreBuild` hook + ## for `getHeader()` + ## + ## `set_target_properties(name PROPERTIES property "value")` + let + cm = outdir / "CMakeLists.txt" + if cm.fileExists(): + cm.writeFile( + cm.readFile() & getCmakePropertyStr(name, property, value) + ) + +proc setCmakeLibName*(outdir, name, prefix = "", oname = "", suffix = "") = + ## Set a `cmake` property in `outdir / CMakeLists.txt` to specify a custom library output + ## name - usable in the `xxxPreBuild` hook for `getHeader()` + ## + ## `prefix` is typically `lib` + ## `oname` is the library name + ## `suffix` is typically `.a` + ## + ## Sometimes, `cmake` generates non-standard library names - e.g. zlib compiles to + ## `libzlibstatic.a` on Windows. This proc can help rename it to `libzlib.a` so that `getHeader()` + ## can find it after the library is compiled. + ## + ## ``` + ## set_target_properties(name PROPERTIES PREFIX "prefix") + ## set_target_properties(name PROPERTIES OUTPUT_NAME "oname") + ## set_target_properties(name PROPERTIES SUFFIX "suffix") + ## ``` + let + cm = outdir / "CMakeLists.txt" + if cm.fileExists(): + var + str = "" + if prefix.len != 0: + str &= getCmakePropertyStr(name, "PREFIX", prefix) + if oname.len != 0: + str &= getCmakePropertyStr(name, "OUTPUT_NAME", oname) + if suffix.len != 0: + str &= getCmakePropertyStr(name, "SUFFIX", suffix) + if str.len != 0: + cm.writeFile(cm.readFile() & str) + proc cmake*(path, check, flags: string) = ## Run the `cmake` command to generate all Makefiles or other ## build scripts in the specified path @@ -349,7 +399,7 @@ proc make*(path, check: string|Regex, flags = "") = ## ## `flags` are any flags that should be passed to the `make` command. ## - ## If make.exe is missing and mingw32-make.exe is available, it will + ## If `make.exe` is missing and `mingw32-make.exe` is available, it will ## be copied over to make.exe in the same location. if findFile(check, path).len != 0: return @@ -394,6 +444,9 @@ proc getGccPaths*(mode = "c"): seq[string] = if path notin result: result.add path + when defined(osx): + result.add execAction("xcrun --show-sdk-path").strip() & "/usr/include" + proc getGccLibPaths*(mode = "c"): seq[string] = var nul = when defined(Windows): "nul" else: "/dev/null" @@ -416,6 +469,9 @@ proc getGccLibPaths*(mode = "c"): seq[string] = if path notin result: result.add path + when defined(osx): + result.add "/usr/lib" + proc getStdPath(header: string): string = for inc in getGccPaths(): result = findFile(header, inc, recurse = false, first = true) @@ -503,12 +559,19 @@ proc buildLibrary(lname, outdir, conFlags, cmakeFlags, makeFlags: string): strin gen = "" when defined(windows): if findExe("sh").len != 0: - gen = "MSYS Makefiles" + let + uname = execAction("sh -c uname -a").toLowerAscii() + if uname.contains("msys"): + gen = "MSYS Makefiles".quoteShell + elif uname.contains("mingw"): + gen = "MinGW Makefiles".quoteShell & " -DCMAKE_SH=\"CMAKE_SH-NOTFOUND\"" + else: + echo "Unsupported system: " & uname else: - gen = "MinGW Makefiles" + gen = "MinGW Makefiles".quoteShell else: - gen = "Unix Makefiles" - cmake(outdir / "build", "Makefile", &".. -G {gen.sanitizePath} {cmakeFlags}") + gen = "Unix Makefiles".quoteShell + cmake(outdir / "build", "Makefile", &".. -G {gen} {cmakeFlags}") cmakeDeps = true makePath = outdir / "build" else: @@ -550,33 +613,54 @@ proc getDynlibExt(): string = result = ".dylib[0-9.]*" macro getHeader*(header: static[string], giturl: static[string] = "", dlurl: static[string] = "", outdir: static[string] = "", - conFlags: static[string] = "", cmakeFlags: static[string] = "", makeFlags: static[string] = ""): untyped = + conFlags: static[string] = "", cmakeFlags: static[string] = "", makeFlags: static[string] = "", + altNames: static[string] = ""): untyped = ## Get the path to a header file for wrapping with ## `cImport() `_ or ## `c2nImport() `_. ## - ## This proc checks -d:xxx defines based on the header name (e.g. lzma from lzma.h), + ## This proc checks `-d:xxx` defines based on the header name (e.g. lzma from lzma.h), ## and accordingly employs different ways to obtain the source. ## - ## ``-d:xxxStd`` - search standard system paths. E.g. ``/usr/include`` and ``/usr/lib`` on Linux - ## ``-d:xxxGit`` - clone source from a git repo specified in ``giturl`` - ## ``-d:xxxDL`` - download source from ``dlurl`` and extract if required + ## `-d:xxxStd` - search standard system paths. E.g. `/usr/include` and `/usr/lib` on Linux + ## `-d:xxxGit` - clone source from a git repo specified in `giturl` + ## `-d:xxxDL` - download source from `dlurl` and extract if required ## ## This allows a single wrapper to be used in different ways depending on the user's needs. - ## If no -d:xxx defines are specified, ``outdir`` will be searched for the header. + ## If no `-d:xxx` defines are specified, `outdir` will be searched for the header as is. ## - ## The library is then configured (with cmake or autotools if possible) and built - ## using make, unless using ``-d:xxxStd`` which presumes that the system package + ## `-d:xxxSetVer=x.y.z` can be used to specify which version to use. It is used as a tag + ## name for Git whereas for DL, it replaces `$1` in the URL defined. + ## + ## The library is then configured (with `cmake` or `autotools` if possible) and built + ## using `make`, unless using `-d:xxxStd` which presumes that the system package ## manager was used to install prebuilt headers and binaries. ## - ## The header path is stored in ``const xxxPath`` and can be used in a ``cImport()`` call - ## in the calling wrapper. The dynamic library path is stored in ``const xxxLPath`` and can - ## be used for the ``dynlib`` parameter (within quotes). + ## The header path is stored in `const xxxPath` and can be used in a `cImport()` call + ## in the calling wrapper. The dynamic library path is stored in `const xxxLPath` and can + ## be used for the `dynlib` parameter (within quotes) or with `{.passL.}`. ## - ## ``-d:xxxStatic`` can be specified to statically link with the library instead. This - ## will automatically add a ``{.passL.}`` call to the static library for convenience. + ## `-d:xxxStatic` can be specified to statically link with the library instead. This + ## will automatically add a `{.passL.}` call to the static library for convenience. + ## + ## `conFlags`, `cmakeFlags` and `makeFlags` allow sending custom parameters to `configure`, + ## `cmake` and `make` in case additional configuration is required as part of the build process. + ## + ## `altNames` is a list of alternate names for the library - e.g. zlib uses `zlib.h` for the header but + ## the typical lib name is `libz.so` and not `libzlib.so`. In this case, `altNames = "z"`. Comma + ## separate for multiple alternate names. + ## + ## `xxxPreBuild` is a hook that is called after the source code is pulled from Git or downloaded but + ## before the library is built. This might be needed if some initial prep needs to be done before + ## compilation. A few values are provided to the hook to help provide context: + ## + ## `outdir` is the same `outdir` passed in and `header` is the discovered header path in the + ## downloaded source code. + ## + ## Simply define `proc xxxPreBuild(outdir, header: string)` in the wrapper and it will get called + ## prior to the build process. var - name = header.split(".")[0] + name = header.extractFilename().split(".")[0] nameStd = newIdentNode(name & "Std") nameGit = newIdentNode(name & "Git") @@ -586,10 +670,18 @@ macro getHeader*(header: static[string], giturl: static[string] = "", dlurl: sta path = newIdentNode(name & "Path") lpath = newIdentNode(name & "LPath") - version = newIdentNode(name & "Version") + version = newIdentNode(name & "SetVer") lname = newIdentNode(name & "LName") + preBuild = newIdentNode(name & "PreBuild") - lre = "(lib)?$1[0-9.\\-]*\\" % name + lre = "(lib)?$1[_]?(static)?[0-9.\\-]*\\" + + if altNames.len != 0: + let + names = "(" & name & "|" & altNames.replace(",", "|") & ")" + lre = lre % names + else: + lre = lre % name result = newNimNode(nnkStmtList) result.add(quote do: @@ -615,6 +707,11 @@ macro getHeader*(header: static[string], giturl: static[string] = "", dlurl: sta else: getLocalPath(`header`, `outdir`) + when declared(`preBuild`): + static: + `preBuild`(`outdir`, `path`) + + const `lpath`* = buildLibrary(`lname`, `outdir`, `conFlags`, `cmakeFlags`, `makeFlags`) static: diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index 3c99c81..b295344 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -6,7 +6,7 @@ as a starting point for wrapping a new library. The template can be copied and trimmed down and modified as required. `templite.nim `_ is a shorter version for more experienced users. -All ``{.compileTime.}`` procs must be used in a compile time context, e.g. using: +All `{.compileTime.}` procs must be used in a compile time context, e.g. using: .. code-block:: c @@ -194,7 +194,7 @@ macro cOverride*(body): untyped = ## proc svGetCallerInfo(fileName: var cstring; lineNumber: var cint) ## ## Using the `cOverride() `_ block, nimterop - ## can be instructed to skip over ``svGetCallerInfo()``. This works for procs, + ## can be instructed to skip over `svGetCallerInfo()`. This works for procs, ## consts and types. ## ## `cOverride() `_ only affects calls to @@ -254,7 +254,7 @@ macro cPlugin*(body): untyped = ## - `nskEnumField` for enum (field) names, though they are in the global namespace as `nskConst` ## - `nskProc` - for proc names ## - ## ``nimterop/plugins`` is implicitly imported to provide access to standard plugin facilities. + ## `nimterop/plugins` is implicitly imported to provide access to standard plugin facilities. ## ## `cPlugin() `_ only affects calls to ## `cImport() `_ that follow it. @@ -288,7 +288,7 @@ macro cPlugin*(body): untyped = gStateCT.pluginSourcePath = path proc cSearchPath*(path: string): string {.compileTime.}= - ## Get full path to file or directory ``path`` in search path configured + ## Get full path to file or directory `path` in search path configured ## using `cAddSearchDir() `_ and ## `cAddStdDir() `_. ## @@ -321,15 +321,15 @@ proc cDisableCaching*() {.compileTime.} = ## value will continue to be used . Use `cDisableCaching() `_ ## to avoid this scenario during development. ## - ## ``nim -f`` was broken prior to 0.19.4 but can also be used to flush the cached content. + ## `nim -f` was broken prior to 0.19.4 but can also be used to flush the cached content. gStateCT.nocache = true macro cDefine*(name: static string, val: static string = ""): untyped = - ## ``#define`` an identifer that is forwarded to the C/C++ preprocessor if + ## `#define` an identifer that is forwarded to the C/C++ preprocessor if ## called within `cImport() `_ ## or `c2nImport() `_ - ## as well as to the C/C++ compiler during Nim compilation using ``{.passC: "-DXXX".}`` + ## as well as to the C/C++ compiler during Nim compilation using `{.passC: "-DXXX".}` result = newNimNode(nnkStmtList) @@ -350,7 +350,7 @@ macro cDefine*(name: static string, val: static string = ""): untyped = echo result.repr & "\n" proc cAddSearchDir*(dir: string) {.compileTime.} = - ## Add directory ``dir`` to the search path used in calls to + ## Add directory `dir` to the search path used in calls to ## `cSearchPath() `_. runnableExamples: import paths, os @@ -365,7 +365,7 @@ macro cIncludeDir*(dir: static string): untyped = ## Add an include directory that is forwarded to the C/C++ preprocessor if ## called within `cImport() `_ ## or `c2nImport() `_ - ## as well as to the C/C++ compiler during Nim compilation using ``{.passC: "-IXXX".}``. + ## as well as to the C/C++ compiler during Nim compilation using `{.passC: "-IXXX".}`. var dir = interpPath(dir) result = newNimNode(nnkStmtList) @@ -380,7 +380,7 @@ macro cIncludeDir*(dir: static string): untyped = echo result.repr proc cAddStdDir*(mode = "c") {.compileTime.} = - ## Add the standard ``c`` [default] or ``cpp`` include paths to search + ## Add the standard `c` [default] or `cpp` include paths to search ## path used in calls to `cSearchPath() `_ runnableExamples: static: cAddStdDir() @@ -390,24 +390,24 @@ proc cAddStdDir*(mode = "c") {.compileTime.} = cAddSearchDir inc macro cCompile*(path: static string, mode = "c", exclude = ""): untyped = - ## Compile and link C/C++ implementation into resulting binary using ``{.compile.}`` + ## Compile and link C/C++ implementation into resulting binary using `{.compile.}` ## - ## ``path`` can be a specific file or contain wildcards: + ## `path` can be a specific file or contain wildcards: ## ## .. code-block:: nim ## ## cCompile("file.c") ## cCompile("path/to/*.c") ## - ## ``mode`` recursively searches for code files in ``path``. + ## `mode` recursively searches for code files in `path`. ## - ## ``c`` searches for ``*.c`` whereas ``cpp`` searches for ``*.C *.cpp *.c++ *.cc *.cxx`` + ## `c` searches for `*.c` whereas `cpp` searches for `*.C *.cpp *.c++ *.cc *.cxx` ## ## .. code-block:: nim ## ## cCompile("path/to/dir", "cpp") ## - ## ``exclude`` can be used to exclude files by partial string match. Comma separated to + ## `exclude` can be used to exclude files by partial string match. Comma separated to ## specify multiple exclude strings ## ## .. code-block:: nim @@ -485,16 +485,16 @@ macro cCompile*(path: static string, mode = "c", exclude = ""): untyped = macro cImport*(filename: static string, recurse: static bool = false, dynlib: static string = "", mode: static string = "c", flags: static string = ""): untyped = ## Import all supported definitions from specified header file. Generated - ## content is cached in ``nimcache`` until ``filename`` changes unless - ## `cDisableCaching() `_ is set. ``nim -f`` + ## content is cached in `nimcache` until `filename` changes unless + ## `cDisableCaching() `_ is set. `nim -f` ## can also be used after Nim v0.19.4 to flush the cache. ## - ## ``recurse`` can be used to generate Nim wrappers from ``#include`` files - ## referenced in ``filename``. This is only done for files in the same - ## directory as ``filename`` or in a directory added using + ## `recurse` can be used to generate Nim wrappers from `#include` files + ## referenced in `filename`. This is only done for files in the same + ## directory as `filename` or in a directory added using ## `cIncludeDir() `_ ## - ## ``dynlib`` can be used to specify the Nim string to use to specify the dynamic + ## `dynlib` can be used to specify the Nim string to use to specify the dynamic ## library to load the imported symbols from. For example: ## ## .. code-block:: nim @@ -513,14 +513,14 @@ macro cImport*(filename: static string, recurse: static bool = false, dynlib: st ## ## cImport("pcre.h", dynlib="dynpcre") ## - ## If ``dynlib`` is not specified, the C/C++ implementation files can be compiled in + ## If `dynlib` is not specified, the C/C++ implementation files can be compiled in ## with `cCompile() `_, or the - ## ``{.passL.}`` pragma can be used to specify the static lib to link. + ## `{.passL.}` pragma can be used to specify the static lib to link. ## - ## ``mode`` is purely for forward compatibility when toast adds C++ support. It can + ## `mode` is purely for forward compatibility when toast adds C++ support. It can ## be ignored for the foreseeable future. ## - ## ``flags`` can be used to pass any other command line arguments to ``toast``. + ## `flags` can be used to pass any other command line arguments to `toast`. result = newNimNode(nnkStmtList) @@ -546,24 +546,24 @@ macro cImport*(filename: static string, recurse: static bool = false, dynlib: st macro c2nImport*(filename: static string, recurse: static bool = false, dynlib: static string = "", mode: static string = "c", flags: static string = ""): untyped = - ## Import all supported definitions from specified header file using ``c2nim`` + ## Import all supported definitions from specified header file using `c2nim` ## ## Similar to `cImport() `_ - ## but uses ``c2nim`` to generate the Nim wrapper instead of ``toast``. Note that neither + ## but uses `c2nim` to generate the Nim wrapper instead of `toast`. Note that neither ## `cOverride() `_, `cSkipSymbol() `_ - ## nor `cPlugin() `_ have any impact on ``c2nim``. + ## nor `cPlugin() `_ have any impact on `c2nim`. ## - ## ``toast`` is only used to preprocess the header file and recurse + ## `toast` is only used to preprocess the header file and recurse ## if specified. ## - ## ``mode`` should be set to ``cpp`` for c2nim to wrap C++ headers. + ## `mode` should be set to `cpp` for c2nim to wrap C++ headers. ## - ## ``flags`` can be used to pass other command line arguments to ``c2nim``. + ## `flags` can be used to pass other command line arguments to `c2nim`. ## - ## ``nimterop`` does not depend on ``c2nim`` as a ``nimble`` dependency so it + ## `nimterop` does not depend on `c2nim` as a `nimble` dependency so it ## does not get installed automatically. Any wrapper or library that requires this proc - ## needs to install ``c2nim`` with ``nimble install c2nim`` or add it as a dependency in - ## its own ``.nimble`` file. + ## needs to install `c2nim` with `nimble install c2nim` or add it as a dependency in + ## its own `.nimble` file. result = newNimNode(nnkStmtList) diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 54040c0..20fd8b3 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -26,7 +26,7 @@ when while xor yield""".split(Whitespace).toSet() -const gTypeMap = { +const gTypeMap* = { # char "char": "cchar", "signed char": "cschar", @@ -39,6 +39,8 @@ const gTypeMap = { "signed short int": "cshort", "unsigned short": "cushort", "unsigned short int": "cushort", + "uShort": "cushort", + "u_short": "cushort", # int "int": "cint", @@ -47,6 +49,8 @@ const gTypeMap = { "ssize_t": "cint", "unsigned": "cuint", "unsigned int": "cuint", + "uInt": "cuint", + "u_int": "cuint", "size_t": "cuint", # long @@ -57,6 +61,8 @@ const gTypeMap = { "off_t": "clong", "unsigned long": "culong", "unsigned long int": "culong", + "uLong": "culong", + "u_long": "culong", # long long "long long": "clonglong", @@ -79,8 +85,8 @@ proc getType*(str: string): string = result = str.strip(chars={'_'}). replace(re"\s+", " "). - replace(re"([u]?int[\d]+)_t", "$1"). - replace(re"([u]?int)ptr_t", "ptr $1") + replace(re"^([u]?int[\d]+)_t$", "$1"). + replace(re"^([u]?int)ptr_t$", "ptr $1") if gTypeMap.hasKey(result): result = gTypeMap[result] diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index 6e2db16..bfc5def 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -91,7 +91,7 @@ proc initGrammar(): Grammar = """ template funcParamCommon(fname, pname, ptyp, pptr, pout, count, i: untyped): untyped = - ptyp = nimState.getIdentifier(nimState.data[i].val, nskType, fname) + ptyp = nimState.getIdentifier(nimState.data[i].val, nskType, fname).getType() pptr = "" while i+1 < nimState.data.len and nimState.data[i+1].name == "pointer_declarator": @@ -137,7 +137,7 @@ proc initGrammar(): Grammar = var i = 0 - typ = nimState.getIdentifier(nimState.data[i].val, nskType) + typ = nimState.getIdentifier(nimState.data[i].val, nskType).getType() name = "" nname = "" tptr = "" @@ -161,7 +161,7 @@ proc initGrammar(): Grammar = let pragma = nimState.getPragma(nimState.getImportC(name, nname)) - if typ.nBl and nname.nBl and nimState.addNewIdentifer(nname): + if nname notin gTypeMap and typ.nBl and nname.nBl and nimState.addNewIdentifer(nname): if i < nimState.data.len and nimState.data[^1].name == "function_declarator": var fname = nname @@ -575,7 +575,7 @@ proc initGrammar(): Grammar = if fnname.nBl and nimState.addNewIdentifer(fnname): let - ftyp = nimState.getIdentifier(nimState.data[0].val, nskType, fnname) + ftyp = nimState.getIdentifier(nimState.data[0].val, nskType, fnname).getType() pragma = nimState.getPragma(nimState.getImportC(fname, fnname), "cdecl") if fptr.len != 0 or ftyp != "object": diff --git a/tests/getheader.nims b/tests/getheader.nims index 840a114..e489380 100644 --- a/tests/getheader.nims +++ b/tests/getheader.nims @@ -3,6 +3,7 @@ import strutils proc testCall(cmd, output: string, exitCode: int, delete = true) = if delete: rmDir("build/liblzma") + rmDir("build/zlib") echo cmd var ccmd = @@ -17,26 +18,45 @@ proc testCall(cmd, output: string, exitCode: int, delete = true) = var cmd = "nim c -f" - rcmd = " -r lzma.nim" - exp = "liblzma version = " + lrcmd = " -r lzma.nim" + zrcmd = " -r zlib.nim" + lexp = "liblzma version = " + zexp = "zlib version = " + +testCall(cmd & lrcmd, "No build files found", 1) when defined(posix): - testCall(cmd & rcmd, "No build files found", 1) - # stdlib - testCall(cmd & " -d:lzmaStd" & rcmd, exp, 0) - testCall(cmd & " -d:lzmaStd -d:lzmaStatic" & rcmd, exp, 0) + testCall(cmd & " -d:lzmaStd" & lrcmd, lexp, 0) + testCall(cmd & " -d:lzmaStd -d:lzmaStatic" & lrcmd, lexp, 0) + + when not defined(osx): + testCall(cmd & " -d:zlibStd" & zrcmd, zexp, 0) + testCall(cmd & " -d:zlibStd -d:zlibStatic" & zrcmd, zexp, 0) # git - testCall(cmd & " -d:lzmaGit" & rcmd, exp, 0) - testCall(cmd & " -d:lzmaGit -d:lzmaStatic" & rcmd, exp, 0, delete = false) + testCall(cmd & " -d:lzmaGit" & lrcmd, lexp, 0) + testCall(cmd & " -d:lzmaGit -d:lzmaStatic" & lrcmd, lexp, 0, delete = false) # git tag - testCall(cmd & " -d:lzmaGit -d:lzmaVersion=v5.2.0" & rcmd, exp & "5.2.0", 0) - testCall(cmd & " -d:lzmaGit -d:lzmaStatic -d:lzmaVersion=v5.2.0" & rcmd, exp & "5.2.0", 0, delete = false) + testCall(cmd & " -d:lzmaGit -d:lzmaSetVer=v5.2.0" & lrcmd, lexp & "5.2.0", 0) + testCall(cmd & " -d:lzmaGit -d:lzmaStatic -d:lzmaSetVer=v5.2.0" & lrcmd, lexp & "5.2.0", 0, delete = false) testCall("cd build/liblzma && git branch", "v5.2.0", 0, delete = false) +# git +testCall(cmd & " -d:zlibGit" & zrcmd, zexp, 0) +testCall(cmd & " -d:zlibGit -d:zlibStatic" & zrcmd, zexp, 0, delete = false) + +# git tag +testCall(cmd & " -d:zlibGit -d:zlibSetVer=v1.2.10" & zrcmd, zexp & "1.2.10", 0) +testCall(cmd & " -d:zlibGit -d:zlibStatic -d:zlibSetVer=v1.2.10" & zrcmd, zexp & "1.2.10", 0, delete = false) +testCall("cd build/zlib && git branch", "v1.2.10", 0, delete = false) + # dl -testCall(cmd & " -d:lzmaDL" & rcmd, "Need version", 1) -testCall(cmd & " -d:lzmaDL -d:lzmaVersion=5.2.4" & rcmd, exp & "5.2.4", 0) -testCall(cmd & " -d:lzmaDL -d:lzmaStatic -d:lzmaVersion=5.2.4" & rcmd, exp & "5.2.4", 0, delete = false) +testCall(cmd & " -d:lzmaDL" & lrcmd, "Need version", 1) +testCall(cmd & " -d:lzmaDL -d:lzmaSetVer=5.2.4" & lrcmd, lexp & "5.2.4", 0) +testCall(cmd & " -d:lzmaDL -d:lzmaStatic -d:lzmaSetVer=5.2.4" & lrcmd, lexp & "5.2.4", 0, delete = false) + +# dl +testCall(cmd & " -d:zlibDL -d:zlibSetVer=1.2.11" & zrcmd, zexp & "1.2.11", 0) +testCall(cmd & " -d:zlibDL -d:zlibStatic -d:zlibSetVer=1.2.11" & zrcmd, zexp & "1.2.11", 0, delete = false) diff --git a/tests/zlib.nim b/tests/zlib.nim new file mode 100644 index 0000000..f2cc16a --- /dev/null +++ b/tests/zlib.nim @@ -0,0 +1,68 @@ +import os, strutils + +import nimterop/[build, cimport] + +const + baseDir = currentSourcePath.parentDir()/"build"/"zlib" + +static: + cDebug() + +proc zlibPreBuild(outdir, path: string) = + let + mf = outdir / "Makefile" + if mf.fileExists(): + # Delete default Makefile + if mf.readFile().contains("configure first"): + mf.rmFile() + when defined(windows): + # Fix static lib name on Windows + setCmakeLibName(outdir, "zlibstatic", prefix = "lib", oname = "zlib", suffix = ".a") + +getHeader( + "zlib.h", + giturl = "https://github.com/madler/zlib", + dlurl = "http://zlib.net/zlib-$1.tar.gz", + outdir = baseDir, + altNames = "z" +) + +cPlugin: + import regex, strutils + + proc onSymbol*(sym: var Symbol) {.exportc, dynlib.} = + sym.name = sym.name.replace(re"_[_]+", "_").strip(chars = {'_'}) + +cOverride: + type + voidpf = ptr object + voidpc = ptr object + voidp = ptr object + uLongf = culong + z_size_t = culong + z_crc_t = culong + alloc_func* {.importc.} = proc(opaque: voidpf, items, size: uint) {.cdecl.} + Bytef {.importc.} = object + + when defined(posix): + type + pthread_mutex_s = object + pthread_cond_s = object + pthread_rwlock_arch_t = object + extension = object + fd_set = object + +when defined(posix): + static: + cSkipSymbol(@["u_int8_t", "u_int16_t", "u_int32_t", "u_int64_t"]) + +when defined(zlibGit) or defined(zlibDL): + when dirExists(baseDir / "build"): + cIncludeDir(baseDir / "build") + +when not defined(zlibStatic): + cImport(zlibPath, recurse = true, dynlib = "zlibLPath") +else: + cImport(zlibPath, recurse = true) + +echo "zlib version = " & $zlibVersion() From 4ed751ad5a64c868cf5cc087114827b426a9c07e Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Fri, 13 Sep 2019 21:56:29 -0700 Subject: [PATCH 250/593] Add ccache support --- nimterop/build.nim | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/nimterop/build.nim b/nimterop/build.nim index 2563bb8..f2d4692 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -571,9 +571,11 @@ proc buildLibrary(lname, outdir, conFlags, cmakeFlags, makeFlags: string): strin gen = "MinGW Makefiles".quoteShell else: gen = "Unix Makefiles".quoteShell - cmake(outdir / "build", "Makefile", &".. -G {gen} {cmakeFlags}") + if findExe("ccache").len != 0: + gen &= " -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache" + makePath = outdir / "buildcache" + cmake(makePath, "Makefile", &".. -G {gen} {cmakeFlags}") cmakeDeps = true - makePath = outdir / "build" else: cmakeDepStr &= "cmake executable missing" From f21315ff1747ce0814f3a1e480f7b2e01ad9a278 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 23 Sep 2019 14:52:34 -0500 Subject: [PATCH 251/593] More build helpers --- nimterop/build.nim | 40 ++++++++++++++++++++++++++++++++++++++-- tests/zlib.nim | 4 ++-- 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/nimterop/build.nim b/nimterop/build.nim index f2d4692..494bc48 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -4,8 +4,8 @@ import os except findExe import "."/[compat] -proc sanitizePath*(path: string, noQuote = false): string = - result = path.multiReplace([("\\\\", $DirSep), ("\\", $DirSep), ("/", $DirSep)]) +proc sanitizePath*(path: string, noQuote = false, sep = $DirSep): string = + result = path.multiReplace([("\\\\", sep), ("\\", sep), ("/", sep)]) if not noQuote: result = result.quoteShell @@ -265,6 +265,20 @@ proc findFile*(file: string|Regex, dir: string, recurse = true, first = false): result = f if first: break +proc flagBuild*(base: string, flags: openArray[string]): string = + ## Simple helper proc to generate flags for `configure`, `cmake`, etc. + ## + ## Every entry in `flags` is replaced into the `base` string and + ## concatenated to the result. + ## + ## E.g. + ## `base = "--disable-$#"` + ## `flags = @["one", "two"]` + ## + ## `flagBuild(base, flags) => " --disable-one --disable-two"` + for i in flags: + result &= " " & base % i + proc configure*(path, check: string, flags = "") = ## Run the GNU `configure` command to generate all Makefiles or other ## build scripts in the specified path @@ -318,6 +332,15 @@ proc configure*(path, check: string, flags = "") = proc getCmakePropertyStr(name, property, value: string): string = &"\nset_target_properties({name} PROPERTIES {property} \"{value}\")\n" +proc getCmakeIncludePath*(paths: openArray[string]): string = + ## Create a `cmake` flag to specify custom include paths + ## + ## Result can be included in the `flag` parameter for `cmake()` or + ## the `cmakeFlags` parameter for `getHeader()`. + for path in paths: + result &= path & ";" + result = " -DCMAKE_INCLUDE_PATH=" & result[0 .. ^2].sanitizePath(sep = "/") + proc setCmakeProperty*(outdir, name, property, value: string) = ## Set a `cmake` property in `outdir / CMakeLists.txt` - usable in the `xxxPreBuild` hook ## for `getHeader()` @@ -361,6 +384,19 @@ proc setCmakeLibName*(outdir, name, prefix = "", oname = "", suffix = "") = if str.len != 0: cm.writeFile(cm.readFile() & str) +proc setCmakePositionIndependentCode*(outdir: string) = + ## Set a `cmake` directive to create libraries with -fPIC enabled + let + cm = outdir / "CMakeLists.txt" + if cm.fileExists(): + let + pic = "set(CMAKE_POSITION_INDEPENDENT_CODE ON)" + cmd = cm.readFile() + if not cmd.contains(pic): + cm.writeFile( + pic & "\n" & cmd + ) + proc cmake*(path, check, flags: string) = ## Run the `cmake` command to generate all Makefiles or other ## build scripts in the specified path diff --git a/tests/zlib.nim b/tests/zlib.nim index f2cc16a..6da7cdc 100644 --- a/tests/zlib.nim +++ b/tests/zlib.nim @@ -57,8 +57,8 @@ when defined(posix): cSkipSymbol(@["u_int8_t", "u_int16_t", "u_int32_t", "u_int64_t"]) when defined(zlibGit) or defined(zlibDL): - when dirExists(baseDir / "build"): - cIncludeDir(baseDir / "build") + when dirExists(baseDir / "buildcache"): + cIncludeDir(baseDir / "buildcache") when not defined(zlibStatic): cImport(zlibPath, recurse = true, dynlib = "zlibLPath") From fad9fd78f30eda750e615f69dd88f28158effbce Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 25 Sep 2019 21:15:14 -0500 Subject: [PATCH 252/593] Add env var support for defines --- .travis.yml | 2 + appveyor.yml | 1 + nimterop/build.nim | 90 ++++++++++++++++++++++++++++++++++++++------ tests/getheader.nims | 8 ++-- tests/lzma.nim | 9 ++++- tests/zlib.nim | 9 ++++- 6 files changed, 99 insertions(+), 20 deletions(-) diff --git a/.travis.yml b/.travis.yml index d48afd0..b347f73 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,12 +12,14 @@ language: c env: - BRANCH=0.19.6 - BRANCH=0.20.2 + - BRANCH=1.0.0 - BRANCH=devel cache: directories: - "$HOME/.choosenim/toolchains/nim-0.19.6" - "$HOME/.choosenim/toolchains/nim-0.20.2" + - "$HOME/.choosenim/toolchains/nim-1.0.0" install: - export CHOOSENIM_CHOOSE_VERSION=$BRANCH diff --git a/appveyor.yml b/appveyor.yml index 50d9813..0d9ba77 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -11,6 +11,7 @@ environment: matrix: - NIM_VERSION: 0.19.6 - NIM_VERSION: 0.20.2 + - NIM_VERSION: 1.0.0 for: - diff --git a/nimterop/build.nim b/nimterop/build.nim index 494bc48..24ae87c 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -1,4 +1,4 @@ -import macros, osproc, regex, strformat, strutils +import macros, osproc, regex, strformat, strutils, tables import os except findExe @@ -650,6 +650,48 @@ proc getDynlibExt(): string = elif defined(macosx): result = ".dylib[0-9.]*" +var + gDefines {.compileTime.} = initTable[string, string]() + +macro setDefines*(defs: static openArray[string]): untyped = + ## Specify `-d:xxx` values in code instead of having to rely on the command + ## line or `cfg` or `nims` files. + ## + ## At this time, Nim does not allow creation of `-d:xxx` defines in code. In + ## addition, Nim only loads config files for the module being compiled but not + ## for imported packages. This becomes a challenge when wanting to ship a wrapper + ## library that wants to control `getHeader()` for an underlying package. + ## + ## E.g. nimarchive wanting to set `-d:lzmaStatic` + ## + ## The consumer of nimarchive would need to set such defines as part of their + ## project, making it inconvenient. + ## + ## By calling this proc with the defines preferred before importing such a module, + ## the caller can set the behavior in code instead. + ## + ## .. code-block:: nim + ## + ## setDefines(@["lzmaStatic", "lzmaDL", "lzmaSetVer=5.2.4"]) + ## + ## import lzma + for def in defs: + let + nv = def.strip().split("=", maxsplit = 1) + if nv.len != 0: + let + n = nv[0] + v = + if nv.len == 2: + nv[1] + else: + "" + gDefines[n] = v + +macro clearDefines*(): untyped = + ## Clear all defines set using `setDefines()`. + gDefines.clear() + macro getHeader*(header: static[string], giturl: static[string] = "", dlurl: static[string] = "", outdir: static[string] = "", conFlags: static[string] = "", cmakeFlags: static[string] = "", makeFlags: static[string] = "", altNames: static[string] = ""): untyped = @@ -670,6 +712,8 @@ macro getHeader*(header: static[string], giturl: static[string] = "", dlurl: sta ## `-d:xxxSetVer=x.y.z` can be used to specify which version to use. It is used as a tag ## name for Git whereas for DL, it replaces `$1` in the URL defined. ## + ## All defines can also be set in code using `setDefines()`. + ## ## The library is then configured (with `cmake` or `autotools` if possible) and built ## using `make`, unless using `-d:xxxStd` which presumes that the system package ## manager was used to install prebuilt headers and binaries. @@ -700,20 +744,37 @@ macro getHeader*(header: static[string], giturl: static[string] = "", dlurl: sta var name = header.extractFilename().split(".")[0] - nameStd = newIdentNode(name & "Std") - nameGit = newIdentNode(name & "Git") - nameDL = newIdentNode(name & "DL") + stdStr = name & "Std" + gitStr = name & "Git" + dlStr = name & "DL" - nameStatic = newIdentNode(name & "Static") + staticStr = name & "Static" + verStr = name & "SetVer" + + nameStd = newIdentNode(stdStr) + nameGit = newIdentNode(gitStr) + nameDL = newIdentNode(dlStr) + + nameStatic = newIdentNode(staticStr) path = newIdentNode(name & "Path") lpath = newIdentNode(name & "LPath") - version = newIdentNode(name & "SetVer") + version = newIdentNode(verStr) lname = newIdentNode(name & "LName") preBuild = newIdentNode(name & "PreBuild") lre = "(lib)?$1[_]?(static)?[0-9.\\-]*\\" + stdVal = gDefines.hasKey(stdStr) + gitVal = gDefines.hasKey(gitStr) + dlVal = gDefines.hasKey(dlStr) + staticVal = gDefines.hasKey(staticStr) + verVal = + if gDefines.hasKey(verStr): + gDefines[verStr] + else: + "" + if altNames.len != 0: let names = "(" & name & "|" & altNames.replace(",", "|") & ")" @@ -724,23 +785,28 @@ macro getHeader*(header: static[string], giturl: static[string] = "", dlurl: sta result = newNimNode(nnkStmtList) result.add(quote do: const - `version`* {.strdefine.} = "" + `nameStd`* = when defined(`nameStd`): true else: `stdVal` == 1 + `nameGit`* = when defined(`nameGit`): true else: `gitVal` == 1 + `nameDL`* = when defined(`nameDL`): true else: `dlVal` == 1 + `nameStatic`* = when defined(`nameStatic`): true else: `staticVal` == 1 + + `version`* {.strdefine.} = `verVal` `lname` = - when defined(`nameStatic`): + when `nameStatic`: `lre` & ".a" else: `lre` & getDynlibExt() - when defined(`nameStd`): + when `nameStd`: const `path`* = getStdPath(`header`) `lpath`* = getStdLibPath(`lname`) else: const `path`* = - when defined(`nameGit`): + when `nameGit`: getGitPath(`header`, `giturl`, `outdir`, `version`) - elif defined(`nameDL`): + elif `nameDL`: getDlPath(`header`, `dlurl`, `outdir`, `version`) else: getLocalPath(`header`, `outdir`) @@ -757,6 +823,6 @@ macro getHeader*(header: static[string], giturl: static[string] = "", dlurl: sta doAssert `lpath`.len != 0, "\nLibrary " & `lname` & " not found" echo "# Including library " & `lpath` - when defined(`nameStatic`): + when `nameStatic`: {.passL: `lpath`.} ) diff --git a/tests/getheader.nims b/tests/getheader.nims index e489380..c122484 100644 --- a/tests/getheader.nims +++ b/tests/getheader.nims @@ -27,8 +27,8 @@ testCall(cmd & lrcmd, "No build files found", 1) when defined(posix): # stdlib - testCall(cmd & " -d:lzmaStd" & lrcmd, lexp, 0) - testCall(cmd & " -d:lzmaStd -d:lzmaStatic" & lrcmd, lexp, 0) + testCall(cmd & " -d:envTest" & lrcmd, lexp, 0) + testCall(cmd & " -d:envTestStatic" & lrcmd, lexp, 0) when not defined(osx): testCall(cmd & " -d:zlibStd" & zrcmd, zexp, 0) @@ -44,8 +44,8 @@ when defined(posix): testCall("cd build/liblzma && git branch", "v5.2.0", 0, delete = false) # git -testCall(cmd & " -d:zlibGit" & zrcmd, zexp, 0) -testCall(cmd & " -d:zlibGit -d:zlibStatic" & zrcmd, zexp, 0, delete = false) +testCall(cmd & " -d:envTest" & zrcmd, zexp, 0) +testCall(cmd & " -d:envTestStatic" & zrcmd, zexp, 0, delete = false) # git tag testCall(cmd & " -d:zlibGit -d:zlibSetVer=v1.2.10" & zrcmd, zexp & "1.2.10", 0) diff --git a/tests/lzma.nim b/tests/lzma.nim index 422f94d..32f9fa0 100644 --- a/tests/lzma.nim +++ b/tests/lzma.nim @@ -8,6 +8,11 @@ const static: cDebug() +when defined(envTest): + setDefines(@["lzmaStd"]) +elif defined(envTestStatic): + setDefines(@["lzmaStd", "lzmaStatic"]) + getHeader( "lzma.h", giturl = "https://github.com/xz-mirror/xz", @@ -33,9 +38,9 @@ cOverride: lzma_block = object lzma_index_iter = object -when not defined(lzmaStatic): +when not lzmaStatic: cImport(lzmaPath, recurse = true, dynlib = "lzmaLPath") else: cImport(lzmaPath, recurse = true) -echo "liblzma version = " & $lzma_version_string() \ No newline at end of file +echo "liblzma version = " & $lzma_version_string() diff --git a/tests/zlib.nim b/tests/zlib.nim index 6da7cdc..371d41f 100644 --- a/tests/zlib.nim +++ b/tests/zlib.nim @@ -19,6 +19,11 @@ proc zlibPreBuild(outdir, path: string) = # Fix static lib name on Windows setCmakeLibName(outdir, "zlibstatic", prefix = "lib", oname = "zlib", suffix = ".a") +when defined(envTest): + setDefines(@["zlibGit"]) +elif defined(envTestStatic): + setDefines(@["zlibGit", "zlibStatic"]) + getHeader( "zlib.h", giturl = "https://github.com/madler/zlib", @@ -56,11 +61,11 @@ when defined(posix): static: cSkipSymbol(@["u_int8_t", "u_int16_t", "u_int32_t", "u_int64_t"]) -when defined(zlibGit) or defined(zlibDL): +when zlibGit or zlibDL: when dirExists(baseDir / "buildcache"): cIncludeDir(baseDir / "buildcache") -when not defined(zlibStatic): +when not zlibStatic: cImport(zlibPath, recurse = true, dynlib = "zlibLPath") else: cImport(zlibPath, recurse = true) From 86aea481ac3433ddeae7832fc9749f99e12d5f7b Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 1 Oct 2019 11:33:24 -0500 Subject: [PATCH 253/593] Add retries for file ops --- nimterop/build.nim | 15 ++++++++++----- tests/lzma.nim | 2 +- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/nimterop/build.nim b/nimterop/build.nim index 24ae87c..e36324a 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -9,7 +9,7 @@ proc sanitizePath*(path: string, noQuote = false, sep = $DirSep): string = if not noQuote: result = result.quoteShell -proc execAction*(cmd: string, nostderr=false): string = +proc execAction*(cmd: string, retry = 0, nostderr = false): string = ## Execute an external command - supported at compile time ## ## Checks if command exits successfully before returning. If not, an @@ -29,7 +29,12 @@ proc execAction*(cmd: string, nostderr=false): string = else: let opt = if nostderr: {poUsePath} else: {poStdErrToStdOut, poUsePath} (result, ret) = execCmdEx(ccmd, opt) - doAssert ret == 0, "Command failed: " & $(ret, nostderr) & "\nccmd: " & ccmd & "\nresult:\n" & result + if ret != 0: + if retry > 0: + sleep(500) + result = execAction(cmd, retry = retry - 1) + else: + doAssert true, "Command failed: " & $(ret, nostderr) & "\nccmd: " & ccmd & "\nresult:\n" & result proc findExe*(exe: string): string = ## Find the specified executable using the `which`/`where` command - supported @@ -54,7 +59,7 @@ proc mkDir*(dir: string) = if not dirExists(dir): let flag = when not defined(Windows): "-p" else: "" - discard execAction(&"mkdir {flag} {dir.sanitizePath}") + discard execAction(&"mkdir {flag} {dir.sanitizePath}", retry = 2) proc cpFile*(source, dest: string, move=false) = ## Copy a file from `source` to `dest` at compile time @@ -73,7 +78,7 @@ proc cpFile*(source, dest: string, move=false) = else: "cp -f" - discard execAction(&"{cmd} {source.sanitizePath} {dest.sanitizePath}") + discard execAction(&"{cmd} {source.sanitizePath} {dest.sanitizePath}", retry = 2) proc mvFile*(source, dest: string) = ## Move a file from `source` to `dest` at compile time @@ -92,7 +97,7 @@ proc rmFile*(source: string, dir = false) = else: "rm -rf" - discard execAction(&"{cmd} {source.sanitizePath}") + discard execAction(&"{cmd} {source.sanitizePath}", retry = 2) proc rmDir*(source: string) = ## Remove a directory or pattern at compile time diff --git a/tests/lzma.nim b/tests/lzma.nim index 32f9fa0..2368b55 100644 --- a/tests/lzma.nim +++ b/tests/lzma.nim @@ -3,7 +3,7 @@ import os, strutils import nimterop/[build, cimport] const - baseDir = currentSourcePath.parentDir()/"build/liblzma" + baseDir = currentSourcePath.parentDir()/"build"/"liblzma" static: cDebug() From 4994e56a3f625995db43f3c31502311192a4c125 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 1 Oct 2019 12:38:22 -0500 Subject: [PATCH 254/593] Fix sleep --- nimterop/build.nim | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/nimterop/build.nim b/nimterop/build.nim index e36324a..a3dd95f 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -1,6 +1,6 @@ import macros, osproc, regex, strformat, strutils, tables -import os except findExe +import os except findExe, sleep import "."/[compat] @@ -9,6 +9,17 @@ proc sanitizePath*(path: string, noQuote = false, sep = $DirSep): string = if not noQuote: result = result.quoteShell +proc sleep*(milsecs: int) = + ## Sleep at compile time + let + cmd = + when defined(windows): + "cmd /c timeout " + else: + "sleep " + + (oup, ret) = gorgeEx(cmd & $(milsecs / 1000)) + proc execAction*(cmd: string, retry = 0, nostderr = false): string = ## Execute an external command - supported at compile time ## From 23d2b869553f41b4676607cfd32178b24288259c Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 3 Oct 2019 10:54:51 -0500 Subject: [PATCH 255/593] Fix wchar_t for nimdoc --- nimterop/types.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimterop/types.nim b/nimterop/types.nim index 709aa79..8492f00 100644 --- a/nimterop/types.nim +++ b/nimterop/types.nim @@ -20,7 +20,7 @@ else: import std/time_t as time_t_temp type time_t* = time_t_temp.Time - when defined(c): + when defined(c) or defined(nimdoc): # http://www.cplusplus.com/reference/cwchar/wchar_t/ # In C++, wchar_t is a distinct fundamental type (and thus it is # not defined in nor any other header). From dee898dc51c4fddebd16f27af88443edaa46a95a Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 3 Oct 2019 13:45:56 -0500 Subject: [PATCH 256/593] Move docs generation to module --- nimterop.nimble | 56 ++++++++++------------------------------------- nimterop/docs.nim | 42 +++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 45 deletions(-) create mode 100644 nimterop/docs.nim diff --git a/nimterop.nimble b/nimterop.nimble index 565c3e4..5825f5a 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -14,7 +14,7 @@ installFiles = @["config.nims"] # Dependencies requires "nim >= 0.19.2", "regex >= 0.10.0", "cligen >= 0.9.17" -import strformat +import nimterop/docs proc execCmd(cmd: string) = echo "execCmd:" & cmd @@ -24,61 +24,27 @@ proc execTest(test: string) = execCmd "nim c -r " & test execCmd "nim cpp -r " & test -proc tsoloud() = - execTest "tests/tsoloud.nim" - task buildToast, "build toast": - # If need to manually rebuild (automatically built on 1st need) - execCmd(&"nim c -d:release nimterop/toast.nim") + execCmd("nim c -d:danger nimterop/toast.nim") + +task docs, "Generate docs": + buildDocs(@["nimterop/all.nim"], "build/htmldocs") + +task test, "Test": + buildToastTask() -proc testAll() = execTest "tests/tnimterop_c.nim" execCmd "nim cpp -r tests/tnimterop_cpp.nim" execTest "tests/tpcre.nim" - # platform specific tests + # Platform specific tests when defined(Windows): execTest "tests/tmath.nim" if defined(OSX) or defined(Windows) or not existsEnv("TRAVIS"): - tsoloud() # requires some libraries on linux, need them installed in TRAVIS + execTest "tests/tsoloud.nim" # getHeader tests withDir("tests"): execCmd("nim e getheader.nims") -const htmldocsDir = "build/htmldocs" - -when (NimMajor, NimMinor, NimPatch) >= (0, 19, 9): - import os - proc getNimRootDir(): string = - #[ - hack, but works - alternatively (but more complex), use (from a nim file, not nims otherwise - you get Error: ambiguous call; both system.fileExists): - import "$nim/testament/lib/stdtest/specialpaths.nim" - nimRootDir - ]# - fmt"{currentSourcePath}".parentDir.parentDir.parentDir - -proc runNimDoc() = - execCmd &"nim doc -o:{htmldocsDir} --project --index:on nimterop/all.nim" - execCmd &"nim buildIndex -o:{htmldocsDir}/theindex.html {htmldocsDir}" - when declared(getNimRootDir): - #[ - this enables doc search, works at least locally with: - cd {htmldocsDir} && python -m SimpleHTTPServer 9009 - ]# - execCmd &"nim js -o:{htmldocsDir}/dochack.js {getNimRootDir()}/tools/dochack/dochack.nim" - -task test, "Test": - buildToastTask() - testAll() - runNimDoc() - -task docs, "Generate docs": - runNimDoc() - -task docsPublish, "Generate and publish docs": - # Uses: pip install ghp-import - runNimDoc() - execCmd &"ghp-import --no-jekyll -fp {htmldocsDir}" + docsTask() diff --git a/nimterop/docs.nim b/nimterop/docs.nim new file mode 100644 index 0000000..d7cb1a7 --- /dev/null +++ b/nimterop/docs.nim @@ -0,0 +1,42 @@ +import macros, strformat + +when (NimMajor, NimMinor, NimPatch) >= (0, 19, 9): + from os import parentDir + proc getNimRootDir(): string = + #[ + hack, but works + alternatively (but more complex), use (from a nim file, not nims otherwise + you get Error: ambiguous call; both system.fileExists): + import "$nim/testament/lib/stdtest/specialpaths.nim" + nimRootDir + ]# + fmt"{currentSourcePath}".parentDir.parentDir.parentDir + +proc buildDocs*(files: seq[string], path: string, baseDir = getProjectPath() & "/") = + ## Generate docs for all specified nim `files` to the specified `path` + ## + ## `baseDir` is the project path by default and `files` and `path` are relative + ## to that directory. Set to "" if using absolute paths. + ## + ## Use the `--publish` flag with nimble to publish docs contained in + ## `path` to Github in the `gh-pages` branch. This requires the ghp-import + ## package for Python: `pip install ghp-import` + ## + ## WARNING: `--publish` will destroy any existing content in this branch. + let + path = baseDir & path + for file in files: + echo gorge(&"nim doc -o:{path} --project --index:on {baseDir & file}") + + echo gorge(&"nim buildIndex -o:{path}/theindex.html {path}") + when declared(getNimRootDir): + #[ + this enables doc search, works at least locally with: + cd {path} && python -m SimpleHTTPServer 9009 + ]# + echo gorge(&"nim js -o:{path}/dochack.js {getNimRootDir()}/tools/dochack/dochack.nim") + + for i in 0 .. paramCount(): + if paramStr(i) == "--publish": + echo gorge(&"ghp-import --no-jekyll -fp {path}") + break From b12d77c98d6cb4f6a8ad29c47e8964831cb1990d Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 3 Oct 2019 16:29:01 -0500 Subject: [PATCH 257/593] Fix empty project path --- nimterop/docs.nim | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/nimterop/docs.nim b/nimterop/docs.nim index d7cb1a7..0b46967 100644 --- a/nimterop/docs.nim +++ b/nimterop/docs.nim @@ -24,6 +24,11 @@ proc buildDocs*(files: seq[string], path: string, baseDir = getProjectPath() & " ## ## WARNING: `--publish` will destroy any existing content in this branch. let + baseDir = + if baseDir == "/": + getCurrentDir() & "/" + else: + baseDir path = baseDir & path for file in files: echo gorge(&"nim doc -o:{path} --project --index:on {baseDir & file}") From 3d52e60b8b97c5f18e06c817f1831eb63d617a23 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 3 Oct 2019 20:43:50 -0500 Subject: [PATCH 258/593] Update documentation --- all.html | 4 +- build.html | 1241 +++++++++++++++++++++++++++++++++ build.idx | 29 + cimport.html | 6 +- compat.html | 29 +- compat.idx | 2 +- dochack.js | 1824 +++++++++++++++++++++++++------------------------ git.html | 62 +- git.idx | 3 + paths.html | 2 +- plugin.html | 2 +- theindex.html | 116 +++- types.html | 11 +- types.idx | 1 + 14 files changed, 2412 insertions(+), 920 deletions(-) create mode 100644 build.html create mode 100644 build.idx diff --git a/all.html b/all.html index 1403afc..9b6a1fa 100644 --- a/all.html +++ b/all.html @@ -840,7 +840,7 @@ function main() { @@ -850,7 +850,7 @@ function main() { diff --git a/build.html b/build.html new file mode 100644 index 0000000..d470cfd --- /dev/null +++ b/build.html @@ -0,0 +1,1241 @@ + + + + + + + + + + + + + + + + + +build + + + + + + + + +
    +
    +

    build

    +
    + +
    +
    + +

    + +
    +

    Procs

    +
    + +
    proc sanitizePath(path: string; noQuote = false; sep = $'/'): string {...}{.raises: [], tags: [].}
    +
    + + + +
    + +
    proc sleep(milsecs: int) {...}{.raises: [], tags: [].}
    +
    + +Sleep at compile time + +
    + +
    proc execAction(cmd: string; retry = 0; nostderr = false): string {...}{.
    +    raises: [OSError, Exception, IOError, Defect],
    +    tags: [ExecIOEffect, ReadIOEffect, RootEffect].}
    +
    + +

    Execute an external command - supported at compile time

    +

    Checks if command exits successfully before returning. If not, an error is raised.

    + + +
    + +
    proc findExe(exe: string): string {...}{.raises: [], tags: [].}
    +
    + +Find the specified executable using the which/where command - supported at compile time + +
    + +
    proc mkDir(dir: string) {...}{.raises: [OSError, Exception, IOError, Defect, ValueError], tags: [
    +    ReadDirEffect, ExecIOEffect, ReadIOEffect, RootEffect].}
    +
    + +

    Create a directory at compile time

    +

    The os module is not available at compile time so a few crucial helper functions are included with nimterop.

    + + +
    + +
    proc cpFile(source, dest: string; move = false) {...}{.
    +    raises: [OSError, Exception, IOError, Defect, ValueError],
    +    tags: [ExecIOEffect, ReadIOEffect, RootEffect].}
    +
    + +Copy a file from source to dest at compile time + +
    + +
    proc mvFile(source, dest: string) {...}{.raises: [OSError, Exception, IOError, Defect,
    +                                        ValueError],
    +                                tags: [ExecIOEffect, ReadIOEffect, RootEffect].}
    +
    + +Move a file from source to dest at compile time + +
    + +
    proc rmFile(source: string; dir = false) {...}{.raises: [OSError, Exception, IOError, Defect,
    +    ValueError], tags: [ExecIOEffect, ReadIOEffect, RootEffect].}
    +
    + +Remove a file or pattern at compile time + +
    + +
    proc rmDir(source: string) {...}{.raises: [OSError, Exception, IOError, Defect, ValueError],
    +                          tags: [ExecIOEffect, ReadIOEffect, RootEffect].}
    +
    + +Remove a directory or pattern at compile time + +
    + +
    proc extractZip(zipfile, outdir: string) {...}{.raises: [OSError, Exception, IOError, Defect,
    +    ValueError], tags: [ExecIOEffect, ReadIOEffect, RootEffect].}
    +
    + +Extract a zip file using powershell on Windows and unzip on other systems to the specified output directory + +
    + +
    proc extractTar(tarfile, outdir: string) {...}{.raises: [ValueError, OSError, Exception,
    +    IOError, Defect], tags: [ExecIOEffect, ReadIOEffect, RootEffect].}
    +
    + +Extract a tar file using tar, 7z or 7za to the specified output directory + +
    + +
    proc downloadUrl(url, outdir: string) {...}{.raises: [OSError, Exception, IOError, Defect,
    +    ValueError], tags: [ReadDirEffect, ExecIOEffect, ReadIOEffect, RootEffect].}
    +
    + +

    Download a file using curl or wget (or powershell on Windows) to the specified directory

    +

    If an archive file, it is automatically extracted after download.

    + + +
    + +
    proc gitReset(outdir: string) {...}{.raises: [ValueError, OSError, Exception, IOError, Defect],
    +                             tags: [ExecIOEffect, ReadIOEffect, RootEffect].}
    +
    + +Hard reset the git repository at the specified directory + +
    + +
    proc gitCheckout(file, outdir: string) {...}{.raises: [ValueError, OSError, Exception,
    +    IOError, Defect], tags: [ExecIOEffect, ReadIOEffect, RootEffect].}
    +
    + +

    Checkout the specified file in the git repository at outdir

    +

    This effectively resets all changes in the file and can be used to undo any changes that were made to source files to enable successful wrapping with cImport() or c2nImport().

    + + +
    + +
    proc gitPull(url: string; outdir = ""; plist = ""; checkout = "") {...}{.
    +    raises: [ValueError, OSError, Exception, IOError, Defect], tags: [ReadDirEffect,
    +    ExecIOEffect, ReadIOEffect, RootEffect, WriteIOEffect].}
    +
    + +

    Pull the specified git repository to the output directory

    +

    plist is the list of specific files and directories or wildcards to sparsely checkout. Multiple values can be specified one entry per line. It is optional and if omitted, the entire repository will be checked out.

    +

    checkout is the git tag, branch or commit hash to checkout once the repository is downloaded. This allows for pinning to a specific version of the code.

    + + +
    + +
    proc findFile(file: string | Regex; dir: string; recurse = true; first = false): string
    +
    + +

    Find the file in the specified directory

    +

    file can be a string or a regex object

    +

    Turn off recursive search with recurse and stop on first match with first. Without it, the shortest match is returned.

    + + +
    + +
    proc flagBuild(base: string; flags: openArray[string]): string {...}{.raises: [ValueError],
    +    tags: [].}
    +
    + +

    Simple helper proc to generate flags for configure, cmake, etc.

    +

    Every entry in flags is replaced into the base string and concatenated to the result.

    +
    E.g.
    +
    base = "--disable-$#" flags = @["one", "two"]
    +
    +

    flagBuild(base, flags) => " --disable-one --disable-two"

    + + +
    + +
    proc configure(path, check: string; flags = "") {...}{.
    +    raises: [OSError, Exception, IOError, Defect, ValueError],
    +    tags: [ReadDirEffect, ExecIOEffect, ReadIOEffect, RootEffect].}
    +
    + +

    Run the GNU configure command to generate all Makefiles or other build scripts in the specified path

    +

    If a configure script is not present and an autogen.sh script is present, it will be run before attempting configure.

    +

    Next, if configure.ac or configure.in exist, autoreconf will be executed.

    +

    check is a file that will be generated by the configure command. This is required to prevent configure from running on every build. It is relative to the path and should not be an absolute path.

    +

    flags are any flags that should be passed to the configure command.

    + + +
    + +
    proc getCmakeIncludePath(paths: openArray[string]): string {...}{.raises: [], tags: [].}
    +
    + +

    Create a cmake flag to specify custom include paths

    +

    Result can be included in the flag parameter for cmake() or the cmakeFlags parameter for getHeader().

    + + +
    + +
    proc setCmakeProperty(outdir, name, property, value: string) {...}{.
    +    raises: [IOError, ValueError],
    +    tags: [ReadDirEffect, WriteIOEffect, ReadIOEffect].}
    +
    + +

    Set a cmake property in outdir / CMakeLists.txt - usable in the xxxPreBuild hook for getHeader()

    +

    set_target_properties(name PROPERTIES property "value")

    + + +
    + +
    proc setCmakeLibName(outdir, name, prefix = ""; oname = ""; suffix = "") {...}{.
    +    raises: [ValueError, IOError],
    +    tags: [ReadDirEffect, WriteIOEffect, ReadIOEffect].}
    +
    + +

    Set a cmake property in outdir / CMakeLists.txt to specify a custom library output name - usable in the xxxPreBuild hook for getHeader()

    +

    prefix is typically lib oname is the library name suffix is typically .a

    +

    Sometimes, cmake generates non-standard library names - e.g. zlib compiles to libzlibstatic.a on Windows. This proc can help rename it to libzlib.a so that getHeader() can find it after the library is compiled.

    +

    +set_target_properties(name PROPERTIES PREFIX "prefix")
    +set_target_properties(name PROPERTIES OUTPUT_NAME "oname")
    +set_target_properties(name PROPERTIES SUFFIX "suffix")
    +

    + + +
    + +
    proc setCmakePositionIndependentCode(outdir: string) {...}{.raises: [IOError],
    +    tags: [ReadDirEffect, ReadIOEffect, WriteIOEffect].}
    +
    + +Set a cmake directive to create libraries with -fPIC enabled + +
    + +
    proc cmake(path, check, flags: string) {...}{.raises: [OSError, Exception, IOError, Defect,
    +    ValueError], tags: [ReadDirEffect, ExecIOEffect, ReadIOEffect, RootEffect].}
    +
    + +

    Run the cmake command to generate all Makefiles or other build scripts in the specified path

    +

    path will be created since typically cmake is run in an empty directory.

    +

    check is a file that will be generated by the cmake command. This is required to prevent cmake from running on every build. It is relative to the path and should not be an absolute path.

    +

    flags are any flags that should be passed to the cmake command. Unlike configure, it is required since typically it will be the path to the repository, typically .. when path is a subdir.

    + + +
    + +
    proc make(path, check: string | Regex; flags = "")
    +
    + +

    Run the make command to build all binaries in the specified path

    +

    check is a file that will be generated by the make command. This is required to prevent make from running on every build. It is relative to the path and should not be an absolute path.

    +

    flags are any flags that should be passed to the make command.

    +

    If make.exe is missing and mingw32-make.exe is available, it will be copied over to make.exe in the same location.

    + + +
    + +
    proc getGccPaths(mode = "c"): seq[string] {...}{.raises: [ValueError], tags: [ReadEnvEffect].}
    +
    + + + +
    + +
    proc getGccLibPaths(mode = "c"): seq[string] {...}{.raises: [ValueError],
    +    tags: [ReadEnvEffect].}
    +
    + + + +
    + +
    +
    +

    Macros

    +
    + +
    macro setDefines(defs: static openArray[string]): untyped
    +
    + +

    Specify -d:xxx values in code instead of having to rely on the command line or cfg or nims files.

    +

    At this time, Nim does not allow creation of -d:xxx defines in code. In addition, Nim only loads config files for the module being compiled but not for imported packages. This becomes a challenge when wanting to ship a wrapper library that wants to control getHeader() for an underlying package.

    +

    E.g. nimarchive wanting to set -d:lzmaStatic

    +

    The consumer of nimarchive would need to set such defines as part of their project, making it inconvenient.

    +

    By calling this proc with the defines preferred before importing such a module, the caller can set the behavior in code instead.

    +
    setDefines(@["lzmaStatic", "lzmaDL", "lzmaSetVer=5.2.4"])
    +
    +import lzma
    + +
    + +
    macro clearDefines(): untyped
    +
    + +Clear all defines set using setDefines(). + +
    + +
    macro getHeader(header: static[string]; giturl: static[string] = "";
    +               dlurl: static[string] = ""; outdir: static[string] = "";
    +               conFlags: static[string] = ""; cmakeFlags: static[string] = "";
    +               makeFlags: static[string] = ""; altNames: static[string] = ""): untyped
    +
    + +

    Get the path to a header file for wrapping with cImport() or c2nImport().

    +

    This proc checks -d:xxx defines based on the header name (e.g. lzma from lzma.h), and accordingly employs different ways to obtain the source.

    +

    -d:xxxStd - search standard system paths. E.g. /usr/include and /usr/lib on Linux -d:xxxGit - clone source from a git repo specified in giturl -d:xxxDL - download source from dlurl and extract if required

    +

    This allows a single wrapper to be used in different ways depending on the user's needs. If no -d:xxx defines are specified, outdir will be searched for the header as is.

    +

    -d:xxxSetVer=x.y.z can be used to specify which version to use. It is used as a tag name for Git whereas for DL, it replaces $1 in the URL defined.

    +

    All defines can also be set in code using setDefines().

    +

    The library is then configured (with cmake or autotools if possible) and built using make, unless using -d:xxxStd which presumes that the system package manager was used to install prebuilt headers and binaries.

    +

    The header path is stored in const xxxPath and can be used in a cImport() call in the calling wrapper. The dynamic library path is stored in const xxxLPath and can be used for the dynlib parameter (within quotes) or with {.passL.}.

    +

    -d:xxxStatic can be specified to statically link with the library instead. This will automatically add a {.passL.} call to the static library for convenience.

    +

    conFlags, cmakeFlags and makeFlags allow sending custom parameters to configure, cmake and make in case additional configuration is required as part of the build process.

    +

    altNames is a list of alternate names for the library - e.g. zlib uses zlib.h for the header but the typical lib name is libz.so and not libzlib.so. In this case, altNames = "z". Comma separate for multiple alternate names.

    +

    xxxPreBuild is a hook that is called after the source code is pulled from Git or downloaded but before the library is built. This might be needed if some initial prep needs to be done before compilation. A few values are provided to the hook to help provide context:

    +

    outdir is the same outdir passed in and header is the discovered header path in the downloaded source code.

    +

    Simply define proc xxxPreBuild(outdir, header: string) in the wrapper and it will get called prior to the build process.

    + + +
    + +
    + +
    +
    + +
    + +
    +
    +
    + + + diff --git a/build.idx b/build.idx new file mode 100644 index 0000000..157a2da --- /dev/null +++ b/build.idx @@ -0,0 +1,29 @@ +sanitizePath build.html#sanitizePath,string build: sanitizePath(path: string; noQuote = false; sep = $'/'): string +sleep build.html#sleep,int build: sleep(milsecs: int) +execAction build.html#execAction,string,int build: execAction(cmd: string; retry = 0; nostderr = false): string +findExe build.html#findExe,string build: findExe(exe: string): string +mkDir build.html#mkDir,string build: mkDir(dir: string) +cpFile build.html#cpFile,string,string build: cpFile(source, dest: string; move = false) +mvFile build.html#mvFile,string,string build: mvFile(source, dest: string) +rmFile build.html#rmFile,string build: rmFile(source: string; dir = false) +rmDir build.html#rmDir,string build: rmDir(source: string) +extractZip build.html#extractZip,string,string build: extractZip(zipfile, outdir: string) +extractTar build.html#extractTar,string,string build: extractTar(tarfile, outdir: string) +downloadUrl build.html#downloadUrl,string,string build: downloadUrl(url, outdir: string) +gitReset build.html#gitReset,string build: gitReset(outdir: string) +gitCheckout build.html#gitCheckout,string,string build: gitCheckout(file, outdir: string) +gitPull build.html#gitPull,string,string,string,string build: gitPull(url: string; outdir = ""; plist = ""; checkout = "") +findFile build.html#findFile,,string build: findFile(file: string | Regex; dir: string; recurse = true; first = false): string +flagBuild build.html#flagBuild,string,openArray[string] build: flagBuild(base: string; flags: openArray[string]): string +configure build.html#configure,string,string,string build: configure(path, check: string; flags = "") +getCmakeIncludePath build.html#getCmakeIncludePath,openArray[string] build: getCmakeIncludePath(paths: openArray[string]): string +setCmakeProperty build.html#setCmakeProperty,string,string,string,string build: setCmakeProperty(outdir, name, property, value: string) +setCmakeLibName build.html#setCmakeLibName,string,string,string,string,string build: setCmakeLibName(outdir, name, prefix = ""; oname = ""; suffix = "") +setCmakePositionIndependentCode build.html#setCmakePositionIndependentCode,string build: setCmakePositionIndependentCode(outdir: string) +cmake build.html#cmake,string,string,string build: cmake(path, check, flags: string) +make build.html#make,,,string build: make(path, check: string | Regex; flags = "") +getGccPaths build.html#getGccPaths,string build: getGccPaths(mode = "c"): seq[string] +getGccLibPaths build.html#getGccLibPaths,string build: getGccLibPaths(mode = "c"): seq[string] +setDefines build.html#setDefines.m build: setDefines(defs: static openArray[string]): untyped +clearDefines build.html#clearDefines.m build: clearDefines(): untyped +getHeader build.html#getHeader.m,static[string],static[string],static[string],static[string],static[string],static[string],static[string],static[string] build: getHeader(header: static[string]; giturl: static[string] = "";\n dlurl: static[string] = ""; outdir: static[string] = "";\n conFlags: static[string] = ""; cmakeFlags: static[string] = "";\n makeFlags: static[string] = ""; altNames: static[string] = ""): untyped diff --git a/cimport.html b/cimport.html index fa57ca3..b48d03c 100644 --- a/cimport.html +++ b/cimport.html @@ -890,7 +890,7 @@ function main() {

    Procs

    @@ -1090,7 +1090,7 @@ Add an include directory that is forwarded to the C/C++ preprocessor if called w
    @@ -1100,7 +1100,7 @@ Add an include directory that is forwarded to the C/C++ preprocessor if called w diff --git a/compat.html b/compat.html index 85b8e0e..b718728 100644 --- a/compat.html +++ b/compat.html @@ -822,13 +822,36 @@ function main() { - + +

    - +
    +

    Procs

    +
    + +
    proc myNormalizedPath(path: string): string {...}{.raises: [], tags: [].}
    +
    + + + +
    + +
    +
    @@ -836,7 +859,7 @@ function main() { diff --git a/compat.idx b/compat.idx index 826a528..8dd5329 100644 --- a/compat.idx +++ b/compat.idx @@ -1 +1 @@ -relativePath compat.html#relativePath,string,string compat: relativePath(file, base: string): string +myNormalizedPath compat.html#myNormalizedPath,string compat: myNormalizedPath(path: string): string diff --git a/dochack.js b/dochack.js index b960a56..2ce5f19 100644 --- a/dochack.js +++ b/dochack.js @@ -1,4 +1,4 @@ -/* Generated by the Nim Compiler v0.20.2 */ +/* Generated by the Nim Compiler v1.0.99 */ /* (c) 2019 Andreas Rumpf */ var framePtr = null; @@ -12,247 +12,248 @@ if (typeof Uint16Array === 'undefined') Uint16Array = Array; if (typeof Uint32Array === 'undefined') Uint32Array = Array; if (typeof Float32Array === 'undefined') Float32Array = Array; if (typeof Float64Array === 'undefined') Float64Array = Array; -var NTI130 = {size: 0,kind: 1,base: null,node: null,finalizer: null}; -var NTI162074 = {size: 0, kind: 18, base: null, node: null, finalizer: null}; -var NTI4062 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI164579 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; -var NTI42448 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI42444 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI42440 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI42436 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI42432 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI42428 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI42424 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI42420 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI42416 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI42412 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI42408 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI42404 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI42400 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI42396 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI42392 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI42388 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI42384 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI42380 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI42376 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI42372 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI42205 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI42283 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI42281 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; -var NTI42227 = {size: 0, kind: 14, base: null, node: null, finalizer: null}; -var NTI42565 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; -var NTI42563 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; -var NTI42561 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; -var NTI42231 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI42229 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; -var NTI44305 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; -var NTI4050 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI4058 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI104 = {size: 0,kind: 31,base: null,node: null,finalizer: null}; -var NTI21156 = {size: 0, kind: 18, base: null, node: null, finalizer: null}; -var NTI4008 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI4114 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; -var NTI114 = {size: 0,kind: 40,base: null,node: null,finalizer: null}; -var NTI138 = {size: 0,kind: 28,base: null,node: null,finalizer: null}; -var NTI140 = {size: 0,kind: 29,base: null,node: null,finalizer: null}; -var NTI4108 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; -var NTI4026 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI4028 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI4042 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI4046 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NNI4046 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; -NTI4046.node = NNI4046; -var NNI4042 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; -NTI4042.node = NNI4042; -var NNI4028 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; -NTI4028.node = NNI4028; -NTI4108.base = NTI4026; -NTI4114.base = NTI4026; -var NNI4026 = {kind: 2, len: 6, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "parent", len: 0, typ: NTI4108, name: "parent", sons: null}, -{kind: 1, offset: "name", len: 0, typ: NTI140, name: "name", sons: null}, -{kind: 1, offset: "message", len: 0, typ: NTI138, name: "msg", sons: null}, -{kind: 1, offset: "trace", len: 0, typ: NTI138, name: "trace", sons: null}, -{kind: 1, offset: "raiseId", len: 0, typ: NTI114, name: "raiseId", sons: null}, -{kind: 1, offset: "up", len: 0, typ: NTI4114, name: "up", sons: null}]}; -NTI4026.node = NNI4026; -var NNI4008 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; -NTI4008.node = NNI4008; -NTI4026.base = NTI4008; -NTI4028.base = NTI4026; -NTI4042.base = NTI4028; -NTI4046.base = NTI4042; -var NNI21156 = {kind: 2, len: 2, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "Field0", len: 0, typ: NTI140, name: "Field0", sons: null}, -{kind: 1, offset: "Field1", len: 0, typ: NTI104, name: "Field1", sons: null}]}; -NTI21156.node = NNI21156; -var NNI4058 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; -NTI4058.node = NNI4058; -NTI4058.base = NTI4028; -var NNI4050 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; -NTI4050.node = NNI4050; -NTI4050.base = NTI4028; -NTI42561.base = NTI42229; -NTI42563.base = NTI42229; -NTI42565.base = NTI42229; -var NNI42227 = {kind: 2, offset: 0, typ: null, name: null, len: 12, sons: {"1": {kind: 1, offset: 1, typ: NTI42227, name: "ElementNode", len: 0, sons: null}, -"2": {kind: 1, offset: 2, typ: NTI42227, name: "AttributeNode", len: 0, sons: null}, -"3": {kind: 1, offset: 3, typ: NTI42227, name: "TextNode", len: 0, sons: null}, -"4": {kind: 1, offset: 4, typ: NTI42227, name: "CDATANode", len: 0, sons: null}, -"5": {kind: 1, offset: 5, typ: NTI42227, name: "EntityRefNode", len: 0, sons: null}, -"6": {kind: 1, offset: 6, typ: NTI42227, name: "EntityNode", len: 0, sons: null}, -"7": {kind: 1, offset: 7, typ: NTI42227, name: "ProcessingInstructionNode", len: 0, sons: null}, -"8": {kind: 1, offset: 8, typ: NTI42227, name: "CommentNode", len: 0, sons: null}, -"9": {kind: 1, offset: 9, typ: NTI42227, name: "DocumentNode", len: 0, sons: null}, -"10": {kind: 1, offset: 10, typ: NTI42227, name: "DocumentTypeNode", len: 0, sons: null}, -"11": {kind: 1, offset: 11, typ: NTI42227, name: "DocumentFragmentNode", len: 0, sons: null}, -"12": {kind: 1, offset: 12, typ: NTI42227, name: "NotationNode", len: 0, sons: null}}}; -NTI42227.node = NNI42227; -var NNI42283 = {kind: 2, len: 91, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "background", len: 0, typ: NTI140, name: "background", sons: null}, -{kind: 1, offset: "backgroundAttachment", len: 0, typ: NTI140, name: "backgroundAttachment", sons: null}, -{kind: 1, offset: "backgroundColor", len: 0, typ: NTI140, name: "backgroundColor", sons: null}, -{kind: 1, offset: "backgroundImage", len: 0, typ: NTI140, name: "backgroundImage", sons: null}, -{kind: 1, offset: "backgroundPosition", len: 0, typ: NTI140, name: "backgroundPosition", sons: null}, -{kind: 1, offset: "backgroundRepeat", len: 0, typ: NTI140, name: "backgroundRepeat", sons: null}, -{kind: 1, offset: "border", len: 0, typ: NTI140, name: "border", sons: null}, -{kind: 1, offset: "borderBottom", len: 0, typ: NTI140, name: "borderBottom", sons: null}, -{kind: 1, offset: "borderBottomColor", len: 0, typ: NTI140, name: "borderBottomColor", sons: null}, -{kind: 1, offset: "borderBottomStyle", len: 0, typ: NTI140, name: "borderBottomStyle", sons: null}, -{kind: 1, offset: "borderBottomWidth", len: 0, typ: NTI140, name: "borderBottomWidth", sons: null}, -{kind: 1, offset: "borderColor", len: 0, typ: NTI140, name: "borderColor", sons: null}, -{kind: 1, offset: "borderLeft", len: 0, typ: NTI140, name: "borderLeft", sons: null}, -{kind: 1, offset: "borderLeftColor", len: 0, typ: NTI140, name: "borderLeftColor", sons: null}, -{kind: 1, offset: "borderLeftStyle", len: 0, typ: NTI140, name: "borderLeftStyle", sons: null}, -{kind: 1, offset: "borderLeftWidth", len: 0, typ: NTI140, name: "borderLeftWidth", sons: null}, -{kind: 1, offset: "borderRight", len: 0, typ: NTI140, name: "borderRight", sons: null}, -{kind: 1, offset: "borderRightColor", len: 0, typ: NTI140, name: "borderRightColor", sons: null}, -{kind: 1, offset: "borderRightStyle", len: 0, typ: NTI140, name: "borderRightStyle", sons: null}, -{kind: 1, offset: "borderRightWidth", len: 0, typ: NTI140, name: "borderRightWidth", sons: null}, -{kind: 1, offset: "borderStyle", len: 0, typ: NTI140, name: "borderStyle", sons: null}, -{kind: 1, offset: "borderTop", len: 0, typ: NTI140, name: "borderTop", sons: null}, -{kind: 1, offset: "borderTopColor", len: 0, typ: NTI140, name: "borderTopColor", sons: null}, -{kind: 1, offset: "borderTopStyle", len: 0, typ: NTI140, name: "borderTopStyle", sons: null}, -{kind: 1, offset: "borderTopWidth", len: 0, typ: NTI140, name: "borderTopWidth", sons: null}, -{kind: 1, offset: "borderWidth", len: 0, typ: NTI140, name: "borderWidth", sons: null}, -{kind: 1, offset: "bottom", len: 0, typ: NTI140, name: "bottom", sons: null}, -{kind: 1, offset: "captionSide", len: 0, typ: NTI140, name: "captionSide", sons: null}, -{kind: 1, offset: "clear", len: 0, typ: NTI140, name: "clear", sons: null}, -{kind: 1, offset: "clip", len: 0, typ: NTI140, name: "clip", sons: null}, -{kind: 1, offset: "color", len: 0, typ: NTI140, name: "color", sons: null}, -{kind: 1, offset: "cursor", len: 0, typ: NTI140, name: "cursor", sons: null}, -{kind: 1, offset: "direction", len: 0, typ: NTI140, name: "direction", sons: null}, -{kind: 1, offset: "display", len: 0, typ: NTI140, name: "display", sons: null}, -{kind: 1, offset: "emptyCells", len: 0, typ: NTI140, name: "emptyCells", sons: null}, -{kind: 1, offset: "cssFloat", len: 0, typ: NTI140, name: "cssFloat", sons: null}, -{kind: 1, offset: "font", len: 0, typ: NTI140, name: "font", sons: null}, -{kind: 1, offset: "fontFamily", len: 0, typ: NTI140, name: "fontFamily", sons: null}, -{kind: 1, offset: "fontSize", len: 0, typ: NTI140, name: "fontSize", sons: null}, -{kind: 1, offset: "fontStretch", len: 0, typ: NTI140, name: "fontStretch", sons: null}, -{kind: 1, offset: "fontStyle", len: 0, typ: NTI140, name: "fontStyle", sons: null}, -{kind: 1, offset: "fontVariant", len: 0, typ: NTI140, name: "fontVariant", sons: null}, -{kind: 1, offset: "fontWeight", len: 0, typ: NTI140, name: "fontWeight", sons: null}, -{kind: 1, offset: "height", len: 0, typ: NTI140, name: "height", sons: null}, -{kind: 1, offset: "left", len: 0, typ: NTI140, name: "left", sons: null}, -{kind: 1, offset: "letterSpacing", len: 0, typ: NTI140, name: "letterSpacing", sons: null}, -{kind: 1, offset: "lineHeight", len: 0, typ: NTI140, name: "lineHeight", sons: null}, -{kind: 1, offset: "listStyle", len: 0, typ: NTI140, name: "listStyle", sons: null}, -{kind: 1, offset: "listStyleImage", len: 0, typ: NTI140, name: "listStyleImage", sons: null}, -{kind: 1, offset: "listStylePosition", len: 0, typ: NTI140, name: "listStylePosition", sons: null}, -{kind: 1, offset: "listStyleType", len: 0, typ: NTI140, name: "listStyleType", sons: null}, -{kind: 1, offset: "margin", len: 0, typ: NTI140, name: "margin", sons: null}, -{kind: 1, offset: "marginBottom", len: 0, typ: NTI140, name: "marginBottom", sons: null}, -{kind: 1, offset: "marginLeft", len: 0, typ: NTI140, name: "marginLeft", sons: null}, -{kind: 1, offset: "marginRight", len: 0, typ: NTI140, name: "marginRight", sons: null}, -{kind: 1, offset: "marginTop", len: 0, typ: NTI140, name: "marginTop", sons: null}, -{kind: 1, offset: "maxHeight", len: 0, typ: NTI140, name: "maxHeight", sons: null}, -{kind: 1, offset: "maxWidth", len: 0, typ: NTI140, name: "maxWidth", sons: null}, -{kind: 1, offset: "minHeight", len: 0, typ: NTI140, name: "minHeight", sons: null}, -{kind: 1, offset: "minWidth", len: 0, typ: NTI140, name: "minWidth", sons: null}, -{kind: 1, offset: "overflow", len: 0, typ: NTI140, name: "overflow", sons: null}, -{kind: 1, offset: "padding", len: 0, typ: NTI140, name: "padding", sons: null}, -{kind: 1, offset: "paddingBottom", len: 0, typ: NTI140, name: "paddingBottom", sons: null}, -{kind: 1, offset: "paddingLeft", len: 0, typ: NTI140, name: "paddingLeft", sons: null}, -{kind: 1, offset: "paddingRight", len: 0, typ: NTI140, name: "paddingRight", sons: null}, -{kind: 1, offset: "paddingTop", len: 0, typ: NTI140, name: "paddingTop", sons: null}, -{kind: 1, offset: "pageBreakAfter", len: 0, typ: NTI140, name: "pageBreakAfter", sons: null}, -{kind: 1, offset: "pageBreakBefore", len: 0, typ: NTI140, name: "pageBreakBefore", sons: null}, -{kind: 1, offset: "pointerEvents", len: 0, typ: NTI140, name: "pointerEvents", sons: null}, -{kind: 1, offset: "position", len: 0, typ: NTI140, name: "position", sons: null}, -{kind: 1, offset: "right", len: 0, typ: NTI140, name: "right", sons: null}, -{kind: 1, offset: "scrollbar3dLightColor", len: 0, typ: NTI140, name: "scrollbar3dLightColor", sons: null}, -{kind: 1, offset: "scrollbarArrowColor", len: 0, typ: NTI140, name: "scrollbarArrowColor", sons: null}, -{kind: 1, offset: "scrollbarBaseColor", len: 0, typ: NTI140, name: "scrollbarBaseColor", sons: null}, -{kind: 1, offset: "scrollbarDarkshadowColor", len: 0, typ: NTI140, name: "scrollbarDarkshadowColor", sons: null}, -{kind: 1, offset: "scrollbarFaceColor", len: 0, typ: NTI140, name: "scrollbarFaceColor", sons: null}, -{kind: 1, offset: "scrollbarHighlightColor", len: 0, typ: NTI140, name: "scrollbarHighlightColor", sons: null}, -{kind: 1, offset: "scrollbarShadowColor", len: 0, typ: NTI140, name: "scrollbarShadowColor", sons: null}, -{kind: 1, offset: "scrollbarTrackColor", len: 0, typ: NTI140, name: "scrollbarTrackColor", sons: null}, -{kind: 1, offset: "tableLayout", len: 0, typ: NTI140, name: "tableLayout", sons: null}, -{kind: 1, offset: "textAlign", len: 0, typ: NTI140, name: "textAlign", sons: null}, -{kind: 1, offset: "textDecoration", len: 0, typ: NTI140, name: "textDecoration", sons: null}, -{kind: 1, offset: "textIndent", len: 0, typ: NTI140, name: "textIndent", sons: null}, -{kind: 1, offset: "textTransform", len: 0, typ: NTI140, name: "textTransform", sons: null}, -{kind: 1, offset: "transform", len: 0, typ: NTI140, name: "transform", sons: null}, -{kind: 1, offset: "top", len: 0, typ: NTI140, name: "top", sons: null}, -{kind: 1, offset: "verticalAlign", len: 0, typ: NTI140, name: "verticalAlign", sons: null}, -{kind: 1, offset: "visibility", len: 0, typ: NTI140, name: "visibility", sons: null}, -{kind: 1, offset: "width", len: 0, typ: NTI140, name: "width", sons: null}, -{kind: 1, offset: "wordSpacing", len: 0, typ: NTI140, name: "wordSpacing", sons: null}, -{kind: 1, offset: "zIndex", len: 0, typ: NTI104, name: "zIndex", sons: null}]}; -NTI42283.node = NNI42283; -NTI42283.base = NTI4008; -NTI42281.base = NTI42283; -var NNI42231 = {kind: 2, len: 14, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "attributes", len: 0, typ: NTI42561, name: "attributes", sons: null}, -{kind: 1, offset: "childNodes", len: 0, typ: NTI42563, name: "childNodes", sons: null}, -{kind: 1, offset: "children", len: 0, typ: NTI42565, name: "children", sons: null}, -{kind: 1, offset: "data", len: 0, typ: NTI140, name: "data", sons: null}, -{kind: 1, offset: "firstChild", len: 0, typ: NTI42229, name: "firstChild", sons: null}, -{kind: 1, offset: "lastChild", len: 0, typ: NTI42229, name: "lastChild", sons: null}, -{kind: 1, offset: "nextSibling", len: 0, typ: NTI42229, name: "nextSibling", sons: null}, -{kind: 1, offset: "nodeName", len: 0, typ: NTI140, name: "nodeName", sons: null}, -{kind: 1, offset: "nodeType", len: 0, typ: NTI42227, name: "nodeType", sons: null}, -{kind: 1, offset: "nodeValue", len: 0, typ: NTI140, name: "nodeValue", sons: null}, -{kind: 1, offset: "parentNode", len: 0, typ: NTI42229, name: "parentNode", sons: null}, -{kind: 1, offset: "previousSibling", len: 0, typ: NTI42229, name: "previousSibling", sons: null}, -{kind: 1, offset: "innerHTML", len: 0, typ: NTI140, name: "innerHTML", sons: null}, -{kind: 1, offset: "style", len: 0, typ: NTI42281, name: "style", sons: null}]}; -NTI42231.node = NNI42231; -var NNI42205 = {kind: 2, len: 20, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "onabort", len: 0, typ: NTI42372, name: "onabort", sons: null}, -{kind: 1, offset: "onblur", len: 0, typ: NTI42376, name: "onblur", sons: null}, -{kind: 1, offset: "onchange", len: 0, typ: NTI42380, name: "onchange", sons: null}, -{kind: 1, offset: "onclick", len: 0, typ: NTI42384, name: "onclick", sons: null}, -{kind: 1, offset: "ondblclick", len: 0, typ: NTI42388, name: "ondblclick", sons: null}, -{kind: 1, offset: "onerror", len: 0, typ: NTI42392, name: "onerror", sons: null}, -{kind: 1, offset: "onfocus", len: 0, typ: NTI42396, name: "onfocus", sons: null}, -{kind: 1, offset: "onkeydown", len: 0, typ: NTI42400, name: "onkeydown", sons: null}, -{kind: 1, offset: "onkeypress", len: 0, typ: NTI42404, name: "onkeypress", sons: null}, -{kind: 1, offset: "onkeyup", len: 0, typ: NTI42408, name: "onkeyup", sons: null}, -{kind: 1, offset: "onload", len: 0, typ: NTI42412, name: "onload", sons: null}, -{kind: 1, offset: "onmousedown", len: 0, typ: NTI42416, name: "onmousedown", sons: null}, -{kind: 1, offset: "onmousemove", len: 0, typ: NTI42420, name: "onmousemove", sons: null}, -{kind: 1, offset: "onmouseout", len: 0, typ: NTI42424, name: "onmouseout", sons: null}, -{kind: 1, offset: "onmouseover", len: 0, typ: NTI42428, name: "onmouseover", sons: null}, -{kind: 1, offset: "onmouseup", len: 0, typ: NTI42432, name: "onmouseup", sons: null}, -{kind: 1, offset: "onreset", len: 0, typ: NTI42436, name: "onreset", sons: null}, -{kind: 1, offset: "onselect", len: 0, typ: NTI42440, name: "onselect", sons: null}, -{kind: 1, offset: "onsubmit", len: 0, typ: NTI42444, name: "onsubmit", sons: null}, -{kind: 1, offset: "onunload", len: 0, typ: NTI42448, name: "onunload", sons: null}]}; -NTI42205.node = NNI42205; -NTI42205.base = NTI4008; -NTI42231.base = NTI42205; -NTI42229.base = NTI42231; -NTI44305.base = NTI42229; -NTI164579.base = NTI140; -var NNI4062 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; -NTI4062.node = NNI4062; -NTI4062.base = NTI4028; -var NNI162074 = {kind: 2, len: 2, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "Field0", len: 0, typ: NTI104, name: "Field0", sons: null}, -{kind: 1, offset: "Field1", len: 0, typ: NTI130, name: "Field1", sons: null}]}; -NTI162074.node = NNI162074; +var NTI43032 = {size: 0,kind: 1,base: null,node: null,finalizer: null}; +var NTI201074 = {size: 0, kind: 18, base: null, node: null, finalizer: null}; +var NTI46462 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI203578 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; +var NTI83448 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI83444 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI83440 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI83436 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI83432 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI83428 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI83424 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI83420 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI83416 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI83412 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI83408 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI83404 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI83400 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI83396 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI83392 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI83388 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI83384 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI83380 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI83376 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI83372 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI83205 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI83283 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI83281 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; +var NTI83227 = {size: 0, kind: 14, base: null, node: null, finalizer: null}; +var NTI83565 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; +var NTI83563 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; +var NTI83561 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; +var NTI83231 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI83229 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; +var NTI85305 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; +var NTI46450 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI46458 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI43006 = {size: 0,kind: 31,base: null,node: null,finalizer: null}; +var NTI62156 = {size: 0, kind: 18, base: null, node: null, finalizer: null}; +var NTI46408 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI46514 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; +var NTI43016 = {size: 0,kind: 40,base: null,node: null,finalizer: null}; +var NTI43040 = {size: 0,kind: 28,base: null,node: null,finalizer: null}; +var NTI43042 = {size: 0,kind: 29,base: null,node: null,finalizer: null}; +var NTI46508 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; +var NTI46426 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI46428 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI46442 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI46446 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NNI46446 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI46446.node = NNI46446; +var NNI46442 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI46442.node = NNI46442; +var NNI46428 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI46428.node = NNI46428; +NTI46508.base = NTI46426; +NTI46514.base = NTI46426; +var NNI46426 = {kind: 2, len: 6, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "parent", len: 0, typ: NTI46508, name: "parent", sons: null}, +{kind: 1, offset: "name", len: 0, typ: NTI43042, name: "name", sons: null}, +{kind: 1, offset: "message", len: 0, typ: NTI43040, name: "msg", sons: null}, +{kind: 1, offset: "trace", len: 0, typ: NTI43040, name: "trace", sons: null}, +{kind: 1, offset: "raiseId", len: 0, typ: NTI43016, name: "raiseId", sons: null}, +{kind: 1, offset: "up", len: 0, typ: NTI46514, name: "up", sons: null}]}; +NTI46426.node = NNI46426; +var NNI46408 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI46408.node = NNI46408; +NTI46426.base = NTI46408; +NTI46428.base = NTI46426; +NTI46442.base = NTI46428; +NTI46446.base = NTI46442; +var NNI62156 = {kind: 2, len: 2, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "Field0", len: 0, typ: NTI43042, name: "Field0", sons: null}, +{kind: 1, offset: "Field1", len: 0, typ: NTI43006, name: "Field1", sons: null}]}; +NTI62156.node = NNI62156; +var NNI46458 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI46458.node = NNI46458; +NTI46458.base = NTI46428; +var NNI46450 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI46450.node = NNI46450; +NTI46450.base = NTI46428; +NTI83561.base = NTI83229; +NTI83563.base = NTI83229; +NTI83565.base = NTI83229; +var NNI83227 = {kind: 2, offset: 0, typ: null, name: null, len: 12, sons: {"1": {kind: 1, offset: 1, typ: NTI83227, name: "ElementNode", len: 0, sons: null}, +"2": {kind: 1, offset: 2, typ: NTI83227, name: "AttributeNode", len: 0, sons: null}, +"3": {kind: 1, offset: 3, typ: NTI83227, name: "TextNode", len: 0, sons: null}, +"4": {kind: 1, offset: 4, typ: NTI83227, name: "CDATANode", len: 0, sons: null}, +"5": {kind: 1, offset: 5, typ: NTI83227, name: "EntityRefNode", len: 0, sons: null}, +"6": {kind: 1, offset: 6, typ: NTI83227, name: "EntityNode", len: 0, sons: null}, +"7": {kind: 1, offset: 7, typ: NTI83227, name: "ProcessingInstructionNode", len: 0, sons: null}, +"8": {kind: 1, offset: 8, typ: NTI83227, name: "CommentNode", len: 0, sons: null}, +"9": {kind: 1, offset: 9, typ: NTI83227, name: "DocumentNode", len: 0, sons: null}, +"10": {kind: 1, offset: 10, typ: NTI83227, name: "DocumentTypeNode", len: 0, sons: null}, +"11": {kind: 1, offset: 11, typ: NTI83227, name: "DocumentFragmentNode", len: 0, sons: null}, +"12": {kind: 1, offset: 12, typ: NTI83227, name: "NotationNode", len: 0, sons: null}}}; +NTI83227.node = NNI83227; +var NNI83283 = {kind: 2, len: 92, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "background", len: 0, typ: NTI43042, name: "background", sons: null}, +{kind: 1, offset: "backgroundAttachment", len: 0, typ: NTI43042, name: "backgroundAttachment", sons: null}, +{kind: 1, offset: "backgroundColor", len: 0, typ: NTI43042, name: "backgroundColor", sons: null}, +{kind: 1, offset: "backgroundImage", len: 0, typ: NTI43042, name: "backgroundImage", sons: null}, +{kind: 1, offset: "backgroundPosition", len: 0, typ: NTI43042, name: "backgroundPosition", sons: null}, +{kind: 1, offset: "backgroundRepeat", len: 0, typ: NTI43042, name: "backgroundRepeat", sons: null}, +{kind: 1, offset: "border", len: 0, typ: NTI43042, name: "border", sons: null}, +{kind: 1, offset: "borderBottom", len: 0, typ: NTI43042, name: "borderBottom", sons: null}, +{kind: 1, offset: "borderBottomColor", len: 0, typ: NTI43042, name: "borderBottomColor", sons: null}, +{kind: 1, offset: "borderBottomStyle", len: 0, typ: NTI43042, name: "borderBottomStyle", sons: null}, +{kind: 1, offset: "borderBottomWidth", len: 0, typ: NTI43042, name: "borderBottomWidth", sons: null}, +{kind: 1, offset: "borderColor", len: 0, typ: NTI43042, name: "borderColor", sons: null}, +{kind: 1, offset: "borderLeft", len: 0, typ: NTI43042, name: "borderLeft", sons: null}, +{kind: 1, offset: "borderLeftColor", len: 0, typ: NTI43042, name: "borderLeftColor", sons: null}, +{kind: 1, offset: "borderLeftStyle", len: 0, typ: NTI43042, name: "borderLeftStyle", sons: null}, +{kind: 1, offset: "borderLeftWidth", len: 0, typ: NTI43042, name: "borderLeftWidth", sons: null}, +{kind: 1, offset: "borderRight", len: 0, typ: NTI43042, name: "borderRight", sons: null}, +{kind: 1, offset: "borderRightColor", len: 0, typ: NTI43042, name: "borderRightColor", sons: null}, +{kind: 1, offset: "borderRightStyle", len: 0, typ: NTI43042, name: "borderRightStyle", sons: null}, +{kind: 1, offset: "borderRightWidth", len: 0, typ: NTI43042, name: "borderRightWidth", sons: null}, +{kind: 1, offset: "borderStyle", len: 0, typ: NTI43042, name: "borderStyle", sons: null}, +{kind: 1, offset: "borderTop", len: 0, typ: NTI43042, name: "borderTop", sons: null}, +{kind: 1, offset: "borderTopColor", len: 0, typ: NTI43042, name: "borderTopColor", sons: null}, +{kind: 1, offset: "borderTopStyle", len: 0, typ: NTI43042, name: "borderTopStyle", sons: null}, +{kind: 1, offset: "borderTopWidth", len: 0, typ: NTI43042, name: "borderTopWidth", sons: null}, +{kind: 1, offset: "borderWidth", len: 0, typ: NTI43042, name: "borderWidth", sons: null}, +{kind: 1, offset: "bottom", len: 0, typ: NTI43042, name: "bottom", sons: null}, +{kind: 1, offset: "captionSide", len: 0, typ: NTI43042, name: "captionSide", sons: null}, +{kind: 1, offset: "clear", len: 0, typ: NTI43042, name: "clear", sons: null}, +{kind: 1, offset: "clip", len: 0, typ: NTI43042, name: "clip", sons: null}, +{kind: 1, offset: "color", len: 0, typ: NTI43042, name: "color", sons: null}, +{kind: 1, offset: "cursor", len: 0, typ: NTI43042, name: "cursor", sons: null}, +{kind: 1, offset: "direction", len: 0, typ: NTI43042, name: "direction", sons: null}, +{kind: 1, offset: "display", len: 0, typ: NTI43042, name: "display", sons: null}, +{kind: 1, offset: "emptyCells", len: 0, typ: NTI43042, name: "emptyCells", sons: null}, +{kind: 1, offset: "cssFloat", len: 0, typ: NTI43042, name: "cssFloat", sons: null}, +{kind: 1, offset: "font", len: 0, typ: NTI43042, name: "font", sons: null}, +{kind: 1, offset: "fontFamily", len: 0, typ: NTI43042, name: "fontFamily", sons: null}, +{kind: 1, offset: "fontSize", len: 0, typ: NTI43042, name: "fontSize", sons: null}, +{kind: 1, offset: "fontStretch", len: 0, typ: NTI43042, name: "fontStretch", sons: null}, +{kind: 1, offset: "fontStyle", len: 0, typ: NTI43042, name: "fontStyle", sons: null}, +{kind: 1, offset: "fontVariant", len: 0, typ: NTI43042, name: "fontVariant", sons: null}, +{kind: 1, offset: "fontWeight", len: 0, typ: NTI43042, name: "fontWeight", sons: null}, +{kind: 1, offset: "height", len: 0, typ: NTI43042, name: "height", sons: null}, +{kind: 1, offset: "left", len: 0, typ: NTI43042, name: "left", sons: null}, +{kind: 1, offset: "letterSpacing", len: 0, typ: NTI43042, name: "letterSpacing", sons: null}, +{kind: 1, offset: "lineHeight", len: 0, typ: NTI43042, name: "lineHeight", sons: null}, +{kind: 1, offset: "listStyle", len: 0, typ: NTI43042, name: "listStyle", sons: null}, +{kind: 1, offset: "listStyleImage", len: 0, typ: NTI43042, name: "listStyleImage", sons: null}, +{kind: 1, offset: "listStylePosition", len: 0, typ: NTI43042, name: "listStylePosition", sons: null}, +{kind: 1, offset: "listStyleType", len: 0, typ: NTI43042, name: "listStyleType", sons: null}, +{kind: 1, offset: "margin", len: 0, typ: NTI43042, name: "margin", sons: null}, +{kind: 1, offset: "marginBottom", len: 0, typ: NTI43042, name: "marginBottom", sons: null}, +{kind: 1, offset: "marginLeft", len: 0, typ: NTI43042, name: "marginLeft", sons: null}, +{kind: 1, offset: "marginRight", len: 0, typ: NTI43042, name: "marginRight", sons: null}, +{kind: 1, offset: "marginTop", len: 0, typ: NTI43042, name: "marginTop", sons: null}, +{kind: 1, offset: "maxHeight", len: 0, typ: NTI43042, name: "maxHeight", sons: null}, +{kind: 1, offset: "maxWidth", len: 0, typ: NTI43042, name: "maxWidth", sons: null}, +{kind: 1, offset: "minHeight", len: 0, typ: NTI43042, name: "minHeight", sons: null}, +{kind: 1, offset: "minWidth", len: 0, typ: NTI43042, name: "minWidth", sons: null}, +{kind: 1, offset: "opacity", len: 0, typ: NTI43042, name: "opacity", sons: null}, +{kind: 1, offset: "overflow", len: 0, typ: NTI43042, name: "overflow", sons: null}, +{kind: 1, offset: "padding", len: 0, typ: NTI43042, name: "padding", sons: null}, +{kind: 1, offset: "paddingBottom", len: 0, typ: NTI43042, name: "paddingBottom", sons: null}, +{kind: 1, offset: "paddingLeft", len: 0, typ: NTI43042, name: "paddingLeft", sons: null}, +{kind: 1, offset: "paddingRight", len: 0, typ: NTI43042, name: "paddingRight", sons: null}, +{kind: 1, offset: "paddingTop", len: 0, typ: NTI43042, name: "paddingTop", sons: null}, +{kind: 1, offset: "pageBreakAfter", len: 0, typ: NTI43042, name: "pageBreakAfter", sons: null}, +{kind: 1, offset: "pageBreakBefore", len: 0, typ: NTI43042, name: "pageBreakBefore", sons: null}, +{kind: 1, offset: "pointerEvents", len: 0, typ: NTI43042, name: "pointerEvents", sons: null}, +{kind: 1, offset: "position", len: 0, typ: NTI43042, name: "position", sons: null}, +{kind: 1, offset: "right", len: 0, typ: NTI43042, name: "right", sons: null}, +{kind: 1, offset: "scrollbar3dLightColor", len: 0, typ: NTI43042, name: "scrollbar3dLightColor", sons: null}, +{kind: 1, offset: "scrollbarArrowColor", len: 0, typ: NTI43042, name: "scrollbarArrowColor", sons: null}, +{kind: 1, offset: "scrollbarBaseColor", len: 0, typ: NTI43042, name: "scrollbarBaseColor", sons: null}, +{kind: 1, offset: "scrollbarDarkshadowColor", len: 0, typ: NTI43042, name: "scrollbarDarkshadowColor", sons: null}, +{kind: 1, offset: "scrollbarFaceColor", len: 0, typ: NTI43042, name: "scrollbarFaceColor", sons: null}, +{kind: 1, offset: "scrollbarHighlightColor", len: 0, typ: NTI43042, name: "scrollbarHighlightColor", sons: null}, +{kind: 1, offset: "scrollbarShadowColor", len: 0, typ: NTI43042, name: "scrollbarShadowColor", sons: null}, +{kind: 1, offset: "scrollbarTrackColor", len: 0, typ: NTI43042, name: "scrollbarTrackColor", sons: null}, +{kind: 1, offset: "tableLayout", len: 0, typ: NTI43042, name: "tableLayout", sons: null}, +{kind: 1, offset: "textAlign", len: 0, typ: NTI43042, name: "textAlign", sons: null}, +{kind: 1, offset: "textDecoration", len: 0, typ: NTI43042, name: "textDecoration", sons: null}, +{kind: 1, offset: "textIndent", len: 0, typ: NTI43042, name: "textIndent", sons: null}, +{kind: 1, offset: "textTransform", len: 0, typ: NTI43042, name: "textTransform", sons: null}, +{kind: 1, offset: "transform", len: 0, typ: NTI43042, name: "transform", sons: null}, +{kind: 1, offset: "top", len: 0, typ: NTI43042, name: "top", sons: null}, +{kind: 1, offset: "verticalAlign", len: 0, typ: NTI43042, name: "verticalAlign", sons: null}, +{kind: 1, offset: "visibility", len: 0, typ: NTI43042, name: "visibility", sons: null}, +{kind: 1, offset: "width", len: 0, typ: NTI43042, name: "width", sons: null}, +{kind: 1, offset: "wordSpacing", len: 0, typ: NTI43042, name: "wordSpacing", sons: null}, +{kind: 1, offset: "zIndex", len: 0, typ: NTI43006, name: "zIndex", sons: null}]}; +NTI83283.node = NNI83283; +NTI83283.base = NTI46408; +NTI83281.base = NTI83283; +var NNI83231 = {kind: 2, len: 14, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "attributes", len: 0, typ: NTI83561, name: "attributes", sons: null}, +{kind: 1, offset: "childNodes", len: 0, typ: NTI83563, name: "childNodes", sons: null}, +{kind: 1, offset: "children", len: 0, typ: NTI83565, name: "children", sons: null}, +{kind: 1, offset: "data", len: 0, typ: NTI43042, name: "data", sons: null}, +{kind: 1, offset: "firstChild", len: 0, typ: NTI83229, name: "firstChild", sons: null}, +{kind: 1, offset: "lastChild", len: 0, typ: NTI83229, name: "lastChild", sons: null}, +{kind: 1, offset: "nextSibling", len: 0, typ: NTI83229, name: "nextSibling", sons: null}, +{kind: 1, offset: "nodeName", len: 0, typ: NTI43042, name: "nodeName", sons: null}, +{kind: 1, offset: "nodeType", len: 0, typ: NTI83227, name: "nodeType", sons: null}, +{kind: 1, offset: "nodeValue", len: 0, typ: NTI43042, name: "nodeValue", sons: null}, +{kind: 1, offset: "parentNode", len: 0, typ: NTI83229, name: "parentNode", sons: null}, +{kind: 1, offset: "previousSibling", len: 0, typ: NTI83229, name: "previousSibling", sons: null}, +{kind: 1, offset: "innerHTML", len: 0, typ: NTI43042, name: "innerHTML", sons: null}, +{kind: 1, offset: "style", len: 0, typ: NTI83281, name: "style", sons: null}]}; +NTI83231.node = NNI83231; +var NNI83205 = {kind: 2, len: 20, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "onabort", len: 0, typ: NTI83372, name: "onabort", sons: null}, +{kind: 1, offset: "onblur", len: 0, typ: NTI83376, name: "onblur", sons: null}, +{kind: 1, offset: "onchange", len: 0, typ: NTI83380, name: "onchange", sons: null}, +{kind: 1, offset: "onclick", len: 0, typ: NTI83384, name: "onclick", sons: null}, +{kind: 1, offset: "ondblclick", len: 0, typ: NTI83388, name: "ondblclick", sons: null}, +{kind: 1, offset: "onerror", len: 0, typ: NTI83392, name: "onerror", sons: null}, +{kind: 1, offset: "onfocus", len: 0, typ: NTI83396, name: "onfocus", sons: null}, +{kind: 1, offset: "onkeydown", len: 0, typ: NTI83400, name: "onkeydown", sons: null}, +{kind: 1, offset: "onkeypress", len: 0, typ: NTI83404, name: "onkeypress", sons: null}, +{kind: 1, offset: "onkeyup", len: 0, typ: NTI83408, name: "onkeyup", sons: null}, +{kind: 1, offset: "onload", len: 0, typ: NTI83412, name: "onload", sons: null}, +{kind: 1, offset: "onmousedown", len: 0, typ: NTI83416, name: "onmousedown", sons: null}, +{kind: 1, offset: "onmousemove", len: 0, typ: NTI83420, name: "onmousemove", sons: null}, +{kind: 1, offset: "onmouseout", len: 0, typ: NTI83424, name: "onmouseout", sons: null}, +{kind: 1, offset: "onmouseover", len: 0, typ: NTI83428, name: "onmouseover", sons: null}, +{kind: 1, offset: "onmouseup", len: 0, typ: NTI83432, name: "onmouseup", sons: null}, +{kind: 1, offset: "onreset", len: 0, typ: NTI83436, name: "onreset", sons: null}, +{kind: 1, offset: "onselect", len: 0, typ: NTI83440, name: "onselect", sons: null}, +{kind: 1, offset: "onsubmit", len: 0, typ: NTI83444, name: "onsubmit", sons: null}, +{kind: 1, offset: "onunload", len: 0, typ: NTI83448, name: "onunload", sons: null}]}; +NTI83205.node = NNI83205; +NTI83205.base = NTI46408; +NTI83231.base = NTI83205; +NTI83229.base = NTI83231; +NTI85305.base = NTI83229; +NTI203578.base = NTI43042; +var NNI46462 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI46462.node = NNI46462; +NTI46462.base = NTI46428; +var NNI201074 = {kind: 2, len: 2, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "Field0", len: 0, typ: NTI43006, name: "Field0", sons: null}, +{kind: 1, offset: "Field1", len: 0, typ: NTI43032, name: "Field1", sons: null}]}; +NTI201074.node = NNI201074; -function makeNimstrLit(c_23254) { - var ln = c_23254.length; +function makeNimstrLit(c_64270) { + var ln = c_64270.length; var result = new Array(ln); for (var i = 0; i < ln; ++i) { - result[i] = c_23254.charCodeAt(i); + result[i] = c_64270.charCodeAt(i); } return result; @@ -279,99 +280,99 @@ function setConstr() { } var ConstSet1 = setConstr(17, 16, 4, 18, 27, 19, 23, 22, 21); -function nimCopy(dest_24427, src_24428, ti_24429) { - var result_24619 = null; +function nimCopy(dest_65827, src_65828, ti_65829) { + var result_66019 = null; - switch (ti_24429.kind) { + switch (ti_65829.kind) { case 21: case 22: case 23: case 5: - if (!(is_fat_pointer_24401(ti_24429))) { - result_24619 = src_24428; + if (!(is_fat_pointer_65801(ti_65829))) { + result_66019 = src_65828; } else { - result_24619 = [src_24428[0], src_24428[1]]; + result_66019 = [src_65828[0], src_65828[1]]; } break; case 19: - if (dest_24427 === null || dest_24427 === undefined) { - dest_24427 = {}; + if (dest_65827 === null || dest_65827 === undefined) { + dest_65827 = {}; } else { - for (var key in dest_24427) { delete dest_24427[key]; } + for (var key in dest_65827) { delete dest_65827[key]; } } - for (var key in src_24428) { dest_24427[key] = src_24428[key]; } - result_24619 = dest_24427; + for (var key in src_65828) { dest_65827[key] = src_65828[key]; } + result_66019 = dest_65827; break; case 18: case 17: - if (!((ti_24429.base == null))) { - result_24619 = nimCopy(dest_24427, src_24428, ti_24429.base); + if (!((ti_65829.base == null))) { + result_66019 = nimCopy(dest_65827, src_65828, ti_65829.base); } else { - if ((ti_24429.kind == 17)) { - result_24619 = (dest_24427 === null || dest_24427 === undefined) ? {m_type: ti_24429} : dest_24427; + if ((ti_65829.kind == 17)) { + result_66019 = (dest_65827 === null || dest_65827 === undefined) ? {m_type: ti_65829} : dest_65827; } else { - result_24619 = (dest_24427 === null || dest_24427 === undefined) ? {} : dest_24427; + result_66019 = (dest_65827 === null || dest_65827 === undefined) ? {} : dest_65827; } } - nimCopyAux(result_24619, src_24428, ti_24429.node); + nimCopyAux(result_66019, src_65828, ti_65829.node); break; case 24: case 4: case 27: case 16: - if (src_24428 === null) { - result_24619 = null; + if (src_65828 === null) { + result_66019 = null; } else { - if (dest_24427 === null || dest_24427 === undefined) { - dest_24427 = new Array(src_24428.length); + if (dest_65827 === null || dest_65827 === undefined) { + dest_65827 = new Array(src_65828.length); } else { - dest_24427.length = src_24428.length; + dest_65827.length = src_65828.length; } - result_24619 = dest_24427; - for (var i = 0; i < src_24428.length; ++i) { - result_24619[i] = nimCopy(result_24619[i], src_24428[i], ti_24429.base); + result_66019 = dest_65827; + for (var i = 0; i < src_65828.length; ++i) { + result_66019[i] = nimCopy(result_66019[i], src_65828[i], ti_65829.base); } } break; case 28: - if (src_24428 !== null) { - result_24619 = src_24428.slice(0); + if (src_65828 !== null) { + result_66019 = src_65828.slice(0); } break; default: - result_24619 = src_24428; + result_66019 = src_65828; break; } - return result_24619; + return result_66019; } -function arrayConstr(len_24686, value_24687, typ_24688) { - var result = new Array(len_24686); - for (var i = 0; i < len_24686; ++i) result[i] = nimCopy(null, value_24687, typ_24688); +function arrayConstr(len_66086, value_66087, typ_66088) { + var result = new Array(len_66086); + for (var i = 0; i < len_66086; ++i) result[i] = nimCopy(null, value_66087, typ_66088); return result; } -function cstrToNimstr(c_23271) { - var ln = c_23271.length; +function cstrToNimstr(c_64287) { + var ln = c_64287.length; var result = new Array(ln); var r = 0; for (var i = 0; i < ln; ++i) { - var ch = c_23271.charCodeAt(i); + var ch = c_64287.charCodeAt(i); if (ch < 128) { result[r] = ch; @@ -386,7 +387,7 @@ function cstrToNimstr(c_23271) { } else { ++i; - ch = 65536 + (((ch & 1023) << 10) | (c_23271.charCodeAt(i) & 1023)); + ch = 65536 + (((ch & 1023) << 10) | (c_64287.charCodeAt(i) & 1023)); result[r] = (ch >> 18) | 240; ++r; result[r] = ((ch >> 12) & 63) | 128; @@ -405,54 +406,88 @@ function cstrToNimstr(c_23271) { } -function toJSStr(s_23288) { - if (s_23288 === null) return ""; - var len = s_23288.length; - var asciiPart = new Array(len); - var fcc = String.fromCharCode; - var nonAsciiPart = null; - var nonAsciiOffset = 0; - for (var i = 0; i < len; ++i) { - if (nonAsciiPart !== null) { - var offset = (i - nonAsciiOffset) * 2; - var code = s_23288[i].toString(16); - if (code.length == 1) { - code = "0"+code; - } - nonAsciiPart[offset] = "%"; - nonAsciiPart[offset + 1] = code; - } - else if (s_23288[i] < 128) - asciiPart[i] = fcc(s_23288[i]); - else { - asciiPart.length = i; - nonAsciiOffset = i; - nonAsciiPart = new Array((len - i) * 2); - --i; - } - } - asciiPart = asciiPart.join(""); - return (nonAsciiPart === null) ? - asciiPart : asciiPart + decodeURIComponent(nonAsciiPart.join("")); - +function toJSStr(s_64304) { + var Tmp5; + var Tmp7; + + var result_64305 = null; + + var res_64363 = new_seq_64336((s_64304 != null ? s_64304.length : 0)); + var i_64365 = 0; + var j_64367 = 0; + L1: do { + L2: while (true) { + if (!(i_64365 < (s_64304 != null ? s_64304.length : 0))) break L2; + var c_64368 = s_64304[i_64365]; + if ((c_64368 < 128)) { + res_64363[j_64367] = String.fromCharCode(c_64368); + i_64365 += 1; + } + else { + var helper_64391 = new_seq_64336(0); + L3: do { + L4: while (true) { + if (!true) break L4; + var code_64392 = c_64368.toString(16); + if (((code_64392 != null ? code_64392.length : 0) == 1)) { + if (helper_64391 != null) { helper_64391.push("%0"); } else { helper_64391 = ["%0"]; }; + } + else { + if (helper_64391 != null) { helper_64391.push("%"); } else { helper_64391 = ["%"]; }; + } + + if (helper_64391 != null) { helper_64391.push(code_64392); } else { helper_64391 = [code_64392]; }; + i_64365 += 1; + if (((s_64304 != null ? s_64304.length : 0) <= i_64365)) Tmp5 = true; else { Tmp5 = (s_64304[i_64365] < 128); } if (Tmp5) { + break L3; + } + + c_64368 = s_64304[i_64365]; + } + } while(false); +++excHandler; + Tmp7 = framePtr; + try { + res_64363[j_64367] = decodeURIComponent(helper_64391.join("")); +--excHandler; +} catch (EXC) { + var prevJSError = lastJSError; + lastJSError = EXC; + --excHandler; + framePtr = Tmp7; + res_64363[j_64367] = helper_64391.join(""); + lastJSError = prevJSError; + } finally { + framePtr = Tmp7; + } + } + + j_64367 += 1; + } + } while(false); + if (res_64363 === null) res_64363 = []; + if (res_64363.length < j_64367) { for (var i=res_64363.length;i 2147483647 || result < -2147483648) raiseOverflow(); return result; @@ -460,28 +495,28 @@ function addInt(a_23603, b_23604) { } -function chckIndx(i_24705, a_24706, b_24707) { +function chckIndx(i_66105, a_66106, b_66107) { var Tmp1; - var result_24708 = 0; + var result_66108 = 0; BeforeRet: do { - if (!(a_24706 <= i_24705)) Tmp1 = false; else { Tmp1 = (i_24705 <= b_24707); } if (Tmp1) { - result_24708 = i_24705; + if (!(a_66106 <= i_66105)) Tmp1 = false; else { Tmp1 = (i_66105 <= b_66107); } if (Tmp1) { + result_66108 = i_66105; break BeforeRet; } else { - raiseIndexError(i_24705, a_24706, b_24707); + raiseIndexError(i_66105, a_66106, b_66107); } } while (false); - return result_24708; + return result_66108; } -function subInt(a_23621, b_23622) { - var result = a_23621 - b_23622; +function subInt(a_64821, b_64822) { + var result = a_64821 - b_64822; if (result > 2147483647 || result < -2147483648) raiseOverflow(); return result; @@ -490,14 +525,14 @@ function subInt(a_23621, b_23622) { } var ConstSet2 = setConstr([65, 90]); -function chckRange(i_24724, a_24725, b_24726) { +function chckRange(i_66124, a_66125, b_66126) { var Tmp1; - var result_24727 = 0; + var result_66127 = 0; BeforeRet: do { - if (!(a_24725 <= i_24724)) Tmp1 = false; else { Tmp1 = (i_24724 <= b_24726); } if (Tmp1) { - result_24727 = i_24724; + if (!(a_66125 <= i_66124)) Tmp1 = false; else { Tmp1 = (i_66124 <= b_66126); } if (Tmp1) { + result_66127 = i_66124; break BeforeRet; } else { @@ -506,14 +541,14 @@ function chckRange(i_24724, a_24725, b_24726) { } while (false); - return result_24727; + return result_66127; } var ConstSet3 = setConstr(95, 32, 46); var ConstSet4 = setConstr(95, 32, 46); -function mulInt(a_23639, b_23640) { - var result = a_23639 * b_23640; +function mulInt(a_64839, b_64840) { + var result = a_64839 * b_64840; if (result > 2147483647 || result < -2147483648) raiseOverflow(); return result; @@ -525,51 +560,52 @@ var ConstSet6 = setConstr([65, 90], [97, 122]); var ConstSet7 = setConstr([97, 122]); var ConstSet8 = setConstr([65, 90]); -function nimMax(a_24021, b_24022) { +function nimMax(a_65221, b_65222) { var Tmp1; - var result_24023 = 0; + var result_65223 = 0; BeforeRet: do { - if ((b_24022 <= a_24021)) { - Tmp1 = a_24021; + if ((b_65222 <= a_65221)) { + Tmp1 = a_65221; } else { - Tmp1 = b_24022; + Tmp1 = b_65222; } - result_24023 = Tmp1; + result_65223 = Tmp1; break BeforeRet; } while (false); - return result_24023; + return result_65223; } -function nimMin(a_24003, b_24004) { +function nimMin(a_65203, b_65204) { var Tmp1; - var result_24005 = 0; + var result_65205 = 0; BeforeRet: do { - if ((a_24003 <= b_24004)) { - Tmp1 = a_24003; + if ((a_65203 <= b_65204)) { + Tmp1 = a_65203; } else { - Tmp1 = b_24004; + Tmp1 = b_65204; } - result_24005 = Tmp1; + result_65205 = Tmp1; break BeforeRet; } while (false); - return result_24005; + return result_65205; } +var nimvm_49710 = false; var nim_program_result = 0; -var global_raise_hook_18618 = [null]; -var local_raise_hook_18623 = [null]; -var out_of_mem_hook_18626 = [null]; +var global_raise_hook_59618 = [null]; +var local_raise_hook_59623 = [null]; +var out_of_mem_hook_59626 = [null]; if (!Math.trunc) { Math.trunc = function(v) { v = +v; @@ -578,38 +614,38 @@ var out_of_mem_hook_18626 = [null]; return (v - v % 1) || (v < 0 ? -0 : v === 0 ? v : 0); }; } -var alternative_164315 = [null]; +var alternative_203319 = [null]; -function is_fat_pointer_24401(ti_24403) { - var result_24404 = false; +function is_fat_pointer_65801(ti_65803) { + var result_65804 = false; BeforeRet: do { - result_24404 = !((ConstSet1[ti_24403.base.kind] != undefined)); + result_65804 = !((ConstSet1[ti_65803.base.kind] != undefined)); break BeforeRet; } while (false); - return result_24404; + return result_65804; } -function nimCopyAux(dest_24432, src_24433, n_24435) { - switch (n_24435.kind) { +function nimCopyAux(dest_65832, src_65833, n_65835) { + switch (n_65835.kind) { case 0: break; case 1: - dest_24432[n_24435.offset] = nimCopy(dest_24432[n_24435.offset], src_24433[n_24435.offset], n_24435.typ); + dest_65832[n_65835.offset] = nimCopy(dest_65832[n_65835.offset], src_65833[n_65835.offset], n_65835.typ); break; case 2: - for (var i = 0; i < n_24435.sons.length; i++) { - nimCopyAux(dest_24432, src_24433, n_24435.sons[i]); + for (var i = 0; i < n_65835.sons.length; i++) { + nimCopyAux(dest_65832, src_65833, n_65835.sons[i]); } break; case 3: - dest_24432[n_24435.offset] = nimCopy(dest_24432[n_24435.offset], src_24433[n_24435.offset], n_24435.typ); - for (var i = 0; i < n_24435.sons.length; ++i) { - nimCopyAux(dest_24432, src_24433, n_24435.sons[i][1]); + dest_65832[n_65835.offset] = nimCopy(dest_65832[n_65835.offset], src_65833[n_65835.offset], n_65835.typ); + for (var i = 0; i < n_65835.sons.length; ++i) { + nimCopyAux(dest_65832, src_65833, n_65835.sons[i][1]); } break; @@ -618,112 +654,124 @@ function nimCopyAux(dest_24432, src_24433, n_24435) { } -function add_18638(x_18641, x_18641_Idx, y_18642) { - if (x_18641[x_18641_Idx] === null) { x_18641[x_18641_Idx] = []; } - var off = x_18641[x_18641_Idx].length; - x_18641[x_18641_Idx].length += y_18642.length; - for (var i = 0; i < y_18642.length; ++i) { - x_18641[x_18641_Idx][off+i] = y_18642.charCodeAt(i); +function add_59638(x_59641, x_59641_Idx, y_59642) { + if (x_59641[x_59641_Idx] === null) { x_59641[x_59641_Idx] = []; } + var off = x_59641[x_59641_Idx].length; + x_59641[x_59641_Idx].length += y_59642.length; + for (var i = 0; i < y_59642.length; ++i) { + x_59641[x_59641_Idx][off+i] = y_59642.charCodeAt(i); } } -function aux_write_stack_trace_21151(f_21153) { +function aux_write_stack_trace_62151(f_62153) { var Tmp3; - var result_21154 = [null]; + var result_62154 = [null]; - var it_21162 = f_21153; - var i_21164 = 0; - var total_21166 = 0; - var temp_frames_21173 = arrayConstr(64, {Field0: null, Field1: 0}, NTI21156); + var it_62162 = f_62153; + var i_62164 = 0; + var total_62166 = 0; + var temp_frames_62173 = arrayConstr(64, {Field0: null, Field1: 0}, NTI62156); L1: do { L2: while (true) { - if (!!((it_21162 == null))) Tmp3 = false; else { Tmp3 = (i_21164 <= 63); } if (!Tmp3) break L2; - temp_frames_21173[i_21164].Field0 = it_21162.procname; - temp_frames_21173[i_21164].Field1 = it_21162.line; - i_21164 += 1; - total_21166 += 1; - it_21162 = it_21162.prev; + if (!!((it_62162 == null))) Tmp3 = false; else { Tmp3 = (i_62164 <= 63); } if (!Tmp3) break L2; + temp_frames_62173[i_62164].Field0 = it_62162.procname; + temp_frames_62173[i_62164].Field1 = it_62162.line; + i_62164 += 1; + total_62166 += 1; + it_62162 = it_62162.prev; } } while(false); L4: do { L5: while (true) { - if (!!((it_21162 == null))) break L5; - total_21166 += 1; - it_21162 = it_21162.prev; + if (!!((it_62162 == null))) break L5; + total_62166 += 1; + it_62162 = it_62162.prev; } } while(false); - result_21154[0] = nimCopy(null, [], NTI138); - if (!((total_21166 == i_21164))) { - if (result_21154[0] != null) { result_21154[0] = (result_21154[0]).concat(makeNimstrLit("(")); } else { result_21154[0] = makeNimstrLit("("); }; - if (result_21154[0] != null) { result_21154[0] = (result_21154[0]).concat(cstrToNimstr(((total_21166 - i_21164))+"")); } else { result_21154[0] = cstrToNimstr(((total_21166 - i_21164))+"").slice(); }; - if (result_21154[0] != null) { result_21154[0] = (result_21154[0]).concat(makeNimstrLit(" calls omitted) ...\x0A")); } else { result_21154[0] = makeNimstrLit(" calls omitted) ...\x0A"); }; + result_62154[0] = nimCopy(null, [], NTI43040); + if (!((total_62166 == i_62164))) { + if (result_62154[0] != null) { result_62154[0] = (result_62154[0]).concat(makeNimstrLit("(")); } else { result_62154[0] = makeNimstrLit("("); }; + if (result_62154[0] != null) { result_62154[0] = (result_62154[0]).concat(cstrToNimstr(((total_62166 - i_62164))+"")); } else { result_62154[0] = cstrToNimstr(((total_62166 - i_62164))+"").slice(); }; + if (result_62154[0] != null) { result_62154[0] = (result_62154[0]).concat(makeNimstrLit(" calls omitted) ...\x0A")); } else { result_62154[0] = makeNimstrLit(" calls omitted) ...\x0A"); }; } L6: do { - var j_21421 = 0; - var colontmp__164456 = 0; - colontmp__164456 = (i_21164 - 1); - var res_164461 = colontmp__164456; + var j_62421 = 0; + var colontmp__203466 = 0; + colontmp__203466 = (i_62164 - 1); + var res_203471 = colontmp__203466; L7: do { L8: while (true) { - if (!(0 <= res_164461)) break L8; - j_21421 = res_164461; - add_18638(result_21154, 0, temp_frames_21173[j_21421].Field0); - if ((0 < temp_frames_21173[j_21421].Field1)) { - if (result_21154[0] != null) { result_21154[0] = (result_21154[0]).concat(makeNimstrLit(", line: ")); } else { result_21154[0] = makeNimstrLit(", line: "); }; - if (result_21154[0] != null) { result_21154[0] = (result_21154[0]).concat(cstrToNimstr((temp_frames_21173[j_21421].Field1)+"")); } else { result_21154[0] = cstrToNimstr((temp_frames_21173[j_21421].Field1)+"").slice(); }; + if (!(0 <= res_203471)) break L8; + j_62421 = res_203471; + add_59638(result_62154, 0, temp_frames_62173[j_62421].Field0); + if ((0 < temp_frames_62173[j_62421].Field1)) { + if (result_62154[0] != null) { result_62154[0] = (result_62154[0]).concat(makeNimstrLit(", line: ")); } else { result_62154[0] = makeNimstrLit(", line: "); }; + if (result_62154[0] != null) { result_62154[0] = (result_62154[0]).concat(cstrToNimstr((temp_frames_62173[j_62421].Field1)+"")); } else { result_62154[0] = cstrToNimstr((temp_frames_62173[j_62421].Field1)+"").slice(); }; } - if (result_21154[0] != null) { result_21154[0] = (result_21154[0]).concat(makeNimstrLit("\x0A")); } else { result_21154[0] = makeNimstrLit("\x0A"); }; - res_164461 -= 1; + if (result_62154[0] != null) { result_62154[0] = (result_62154[0]).concat(makeNimstrLit("\x0A")); } else { result_62154[0] = makeNimstrLit("\x0A"); }; + res_203471 -= 1; } } while(false); } while(false); - return result_21154[0]; + return result_62154[0]; } -function raw_write_stack_trace_21468() { - var result_21470 = null; +function raw_write_stack_trace_62468() { + var result_62470 = null; if (!((framePtr == null))) { - result_21470 = nimCopy(null, (makeNimstrLit("Traceback (most recent call last)\x0A") || []).concat(aux_write_stack_trace_21151(framePtr) || []), NTI138); + result_62470 = nimCopy(null, (makeNimstrLit("Traceback (most recent call last)\x0A") || []).concat(aux_write_stack_trace_62151(framePtr) || []), NTI43040); } else { - result_21470 = nimCopy(null, makeNimstrLit("No stack traceback available\x0A"), NTI138); + result_62470 = nimCopy(null, makeNimstrLit("No stack traceback available\x0A"), NTI43040); } - return result_21470; + return result_62470; } -function unhandledException(e_21529) { - var buf_21530 = [[]]; - if (!(((e_21529.message != null ? e_21529.message.length : 0) == 0))) { - if (buf_21530[0] != null) { buf_21530[0] = (buf_21530[0]).concat(makeNimstrLit("Error: unhandled exception: ")); } else { buf_21530[0] = makeNimstrLit("Error: unhandled exception: "); }; - if (buf_21530[0] != null) { buf_21530[0] = (buf_21530[0]).concat(e_21529.message); } else { buf_21530[0] = e_21529.message.slice(); }; +function new_seq_64336(len_64339) { + var result_64341 = null; + + var F={procname:"newSeq.newSeq",prev:framePtr,filename:"system.nim",line:0}; + framePtr = F; + F.line = 996; + result_64341 = new Array(len_64339); for (var i=0;i", "text/html"); - stuff_164566 = doc.documentElement; + stuff_203563 = doc.documentElement; F.line = 286; - db_164523[0] = nimCopy(null, stuff_164566.getElementsByClassName("reference"), NTI44305); + db_203535[0] = nimCopy(null, stuff_203563.getElementsByClassName("reference"), NTI85305); F.line = 287; - contents_164525[0] = nimCopy(null, [], NTI164579); + contents_203537[0] = nimCopy(null, [], NTI203578); L1: do { F.line = 288; - var ahref_164814 = null; + var ahref_203814 = null; + F.line = 184; + var i_204045 = 0; F.line = 185; - var i_165043 = 0; - F.line = 186; - var l_165044 = (db_164523[0] != null ? db_164523[0].length : 0); + var l_204046 = (db_203535[0] != null ? db_203535[0].length : 0); L2: do { - F.line = 187; + F.line = 186; L3: while (true) { - if (!(i_165043 < l_165044)) break L3; + if (!(i_204045 < l_204046)) break L3; F.line = 288; - ahref_164814 = db_164523[0][chckIndx(i_165043, 0, db_164523[0].length+0-1)-0]; + ahref_203814 = db_203535[0][chckIndx(i_204045, 0, db_203535[0].length+0-1)-0]; F.line = 289; - if (contents_164525[0] != null) { contents_164525[0].push(ahref_164814.getAttribute("data-doc-search-tag")); } else { contents_164525[0] = [ahref_164814.getAttribute("data-doc-search-tag")]; }; + if (contents_203537[0] != null) { contents_203537[0].push(ahref_203814.getAttribute("data-doc-search-tag")); } else { contents_203537[0] = [ahref_203814.getAttribute("data-doc-search-tag")]; }; + F.line = 188; + i_204045 = addInt(i_204045, 1); + if (!(((db_203535[0] != null ? db_203535[0].length : 0) == l_204046))) { F.line = 189; - i_165043 = addInt(i_165043, 1); - if (!(((db_164523[0] != null ? db_164523[0].length : 0) == l_165044))) { - F.line = 190; - failed_assert_impl_15051(makeNimstrLit("/home/genotrance/.choosenim/toolchains/nim-0.20.2/lib/system/iterators.nim(190, 11) `len(a) == L` the length of the seq changed while iterating over it")); + failed_assert_impl_56866(makeNimstrLit("/home/genotrance/programming/nimdevel/lib/system/iterators.nim(189, 11) `len(a) == L` the length of the seq changed while iterating over it")); } } @@ -1841,126 +1889,126 @@ function dosearch_164557(value_164559) { } F.line = 290; - var ul_164825 = tree_163020(makeNimstrLit("UL"), []); + var ul_203825 = tree_202020(makeNimstrLit("UL"), []); F.line = 291; - result_164560 = tree_163020(makeNimstrLit("DIV"), []); + result_203557 = tree_202020(makeNimstrLit("DIV"), []); F.line = 292; - set_class_163103(result_164560, makeNimstrLit("search_results")); + set_class_202103(result_203557, makeNimstrLit("search_results")); F.line = 293; - var matches_164844 = []; + var matches_203846 = []; L4: do { F.line = 294; - var i_164857 = 0; - F.line = 2716; - var colontmp__165050 = 0; + var i_203859 = 0; + F.line = 2718; + var colontmp__204052 = 0; F.line = 294; - colontmp__165050 = (db_164523[0] != null ? db_164523[0].length : 0); - F.line = 2717; - var i_165051 = 0; + colontmp__204052 = (db_203535[0] != null ? db_203535[0].length : 0); + F.line = 2720; + var i_204053 = 0; L5: do { - F.line = 2718; + F.line = 2721; L6: while (true) { - if (!(i_165051 < colontmp__165050)) break L6; + if (!(i_204053 < colontmp__204052)) break L6; F.line = 294; - i_164857 = i_165051; + i_203859 = i_204053; L7: do { F.line = 295; - var c_164858 = contents_164525[0][chckIndx(i_164857, 0, contents_164525[0].length+0-1)-0]; - if (((c_164858 == "Examples") || (c_164858 == "PEG construction"))) { + var c_203860 = contents_203537[0][chckIndx(i_203859, 0, contents_203537[0].length+0-1)-0]; + if (((c_203860 == "Examples") || (c_203860 == "PEG construction"))) { F.line = 300; break L7; } F.line = 301; - var colontmp__165060 = {Field0: 0, Field1: false}; + var colontmp__204062 = {Field0: 0, Field1: false}; F.line = 301; - var score_164859 = 0; + var score_203861 = 0; F.line = 301; - var matched_164860 = false; + var matched_203862 = false; F.line = 301; - nimCopy(colontmp__165060, fuzzy_match_162070(value_164559, c_164858), NTI162074); + nimCopy(colontmp__204062, fuzzy_match_201070(value_203556, c_203860), NTI201074); F.line = 301; - score_164859 = colontmp__165060["Field0"]; + score_203861 = colontmp__204062["Field0"]; F.line = 301; - matched_164860 = colontmp__165060["Field1"]; - if (matched_164860) { + matched_203862 = colontmp__204062["Field1"]; + if (matched_203862) { F.line = 303; - if (matches_164844 != null) { matches_164844.push({Field0: db_164523[0][chckIndx(i_164857, 0, db_164523[0].length+0-1)-0], Field1: score_164859}); } else { matches_164844 = [{Field0: db_164523[0][chckIndx(i_164857, 0, db_164523[0].length+0-1)-0], Field1: score_164859}]; }; + if (matches_203846 != null) { matches_203846.push({Field0: db_203535[0][chckIndx(i_203859, 0, db_203535[0].length+0-1)-0], Field1: score_203861}); } else { matches_203846 = [{Field0: db_203535[0][chckIndx(i_203859, 0, db_203535[0].length+0-1)-0], Field1: score_203861}]; }; } } while(false); - F.line = 2720; - i_165051 = addInt(i_165051, 1); + F.line = 2723; + i_204053 = addInt(i_204053, 1); } } while(false); } while(false); F.line = 305; - matches_164844.sort(HEX3Aanonymous_164871); + matches_203846.sort(HEX3Aanonymous_203873); L8: do { F.line = 306; - var i_164924 = 0; - F.line = 2716; - var colontmp__165056 = 0; + var i_203926 = 0; + F.line = 2718; + var colontmp__204058 = 0; F.line = 306; - colontmp__165056 = nimMin((matches_164844 != null ? matches_164844.length : 0), 19); - F.line = 2717; - var i_165057 = 0; + colontmp__204058 = nimMin((matches_203846 != null ? matches_203846.length : 0), 19); + F.line = 2720; + var i_204059 = 0; L9: do { - F.line = 2718; + F.line = 2721; L10: while (true) { - if (!(i_165057 < colontmp__165056)) break L10; + if (!(i_204059 < colontmp__204058)) break L10; F.line = 306; - i_164924 = i_165057; + i_203926 = i_204059; F.line = 307; - matches_164844[chckIndx(i_164924, 0, matches_164844.length+0-1)-0]["Field0"].innerHTML = matches_164844[chckIndx(i_164924, 0, matches_164844.length+0-1)-0]["Field0"].getAttribute("data-doc-search-tag"); + matches_203846[chckIndx(i_203926, 0, matches_203846.length+0-1)-0]["Field0"].innerHTML = matches_203846[chckIndx(i_203926, 0, matches_203846.length+0-1)-0]["Field0"].getAttribute("data-doc-search-tag"); F.line = 308; - add_163085(ul_164825, tree_163020(makeNimstrLit("LI"), [matches_164844[chckIndx(i_164924, 0, matches_164844.length+0-1)-0]["Field0"]])); - F.line = 2720; - i_165057 = addInt(i_165057, 1); + add_202085(ul_203825, tree_202020(makeNimstrLit("LI"), [matches_203846[chckIndx(i_203926, 0, matches_203846.length+0-1)-0]["Field0"]])); + F.line = 2723; + i_204059 = addInt(i_204059, 1); } } while(false); } while(false); - if ((ul_164825.childNodes.length == 0)) { + if ((ul_203825.childNodes.length == 0)) { F.line = 310; - add_163085(result_164560, tree_163020(makeNimstrLit("B"), [text_163120(makeNimstrLit("no search results"))])); + add_202085(result_203557, tree_202020(makeNimstrLit("B"), [text_202120(makeNimstrLit("no search results"))])); } else { F.line = 312; - add_163085(result_164560, tree_163020(makeNimstrLit("B"), [text_163120(makeNimstrLit("search results"))])); + add_202085(result_203557, tree_202020(makeNimstrLit("B"), [text_202120(makeNimstrLit("search results"))])); F.line = 313; - add_163085(result_164560, ul_164825); + add_202085(result_203557, ul_203825); } framePtr = F.prev; - return result_164560; + return result_203557; } function search() { - function wrapper_164991() { + function wrapper_203993() { var F={procname:"search.wrapper",prev:framePtr,filename:"dochack.nim",line:0}; framePtr = F; F.line = 320; - var elem_164993 = document.getElementById("searchInput"); + var elem_203995 = document.getElementById("searchInput"); F.line = 321; - var value_164994 = elem_164993.value; - if (!(((value_164994 != null ? value_164994.length : 0) == 0))) { - if ((oldtoc_164959[0] == null)) { + var value_203996 = elem_203995.value; + if (!(((value_203996 != null ? value_203996.length : 0) == 0))) { + if ((oldtoc_203961[0] == null)) { F.line = 324; - oldtoc_164959[0] = document.getElementById("tocRoot"); + oldtoc_203961[0] = document.getElementById("tocRoot"); } F.line = 325; - var results_165000 = dosearch_164557(value_164994); + var results_204002 = dosearch_203554(value_203996); F.line = 326; - replace_by_id_163172("tocRoot", results_165000); + replace_by_id_202172("tocRoot", results_204002); } else { - if (!((oldtoc_164959[0] == null))) { + if (!((oldtoc_203961[0] == null))) { F.line = 328; - replace_by_id_163172("tocRoot", oldtoc_164959[0]); + replace_by_id_202172("tocRoot", oldtoc_203961[0]); } } framePtr = F.prev; @@ -1970,13 +2018,13 @@ function search() { var F={procname:"dochack.search",prev:framePtr,filename:"dochack.nim",line:0}; framePtr = F; - if (!((timer_164960[0] == null))) { + if (!((timer_203962[0] == null))) { F.line = 330; - clearTimeout(timer_164960[0]); + clearTimeout(timer_203962[0]); } F.line = 331; - timer_164960[0] = setTimeout(wrapper_164991, 400); + timer_203962[0] = setTimeout(wrapper_203993, 400); framePtr = F.prev; diff --git a/git.html b/git.html index a78d383..e5f05dd 100644 --- a/git.html +++ b/git.html @@ -834,12 +834,18 @@ function main() {
    • execAction
    • +
    • findExe
    • mkDir
    • cpFile
    • mvFile
    • +
    • rmFile
    • +
    • rmDir
    • extractZip
    • Imports

      -paths, compat +compat

      Procs

      proc execAction(cmd: string; nostderr = false): string {...}{.
      -    raises: [OSError, Exception, IOError, Defect],
      +    raises: [OSError, Exception, ValueError, IOError, Defect],
           tags: [ExecIOEffect, ReadIOEffect, RootEffect].}
      @@ -885,9 +891,16 @@ function main() {

      Checks if command exits successfully before returning. If not, an error is raised.

      +
      + +
      proc findExe(exe: string): string {...}{.raises: [], tags: [].}
      +
      + +Find the specified executable using the which/where command - supported at compile time +
      -
      proc mkDir(dir: string) {...}{.raises: [OSError, Exception, IOError, Defect, ValueError], tags: [
      +
      proc mkDir(dir: string) {...}{.raises: [OSError, Exception, ValueError, IOError, Defect], tags: [
           ReadDirEffect, ExecIOEffect, ReadIOEffect, RootEffect].}
      @@ -898,7 +911,7 @@ function main() {
      proc cpFile(source, dest: string; move = false) {...}{.
      -    raises: [OSError, Exception, IOError, Defect, ValueError],
      +    raises: [OSError, Exception, ValueError, IOError, Defect],
           tags: [ExecIOEffect, ReadIOEffect, RootEffect].}
      @@ -906,28 +919,44 @@ Copy a file from source to destination at compile time
      -
      proc mvFile(source, dest: string) {...}{.raises: [OSError, Exception, IOError, Defect,
      -                                        ValueError],
      +
      proc mvFile(source, dest: string) {...}{.raises: [OSError, Exception, ValueError, IOError,
      +                                        Defect],
                                       tags: [ExecIOEffect, ReadIOEffect, RootEffect].}
      Move a file from source to destination at compile time +
      + +
      proc rmFile(source: string; dir = false) {...}{.raises: [OSError, Exception, ValueError,
      +    IOError, Defect], tags: [ExecIOEffect, ReadIOEffect, RootEffect].}
      +
      + +Remove a file or pattern at compile time + +
      + +
      proc rmDir(source: string) {...}{.raises: [OSError, Exception, ValueError, IOError, Defect],
      +                          tags: [ExecIOEffect, ReadIOEffect, RootEffect].}
      +
      + +Remove a directory or pattern at compile time +
      -
      proc extractZip(zipfile, outdir: string) {...}{.raises: [OSError, Exception, IOError, Defect,
      -    ValueError], tags: [ExecIOEffect, ReadIOEffect, RootEffect].}
      +
      proc extractZip(zipfile, outdir: string) {...}{.raises: [OSError, Exception, ValueError,
      +    IOError, Defect], tags: [ExecIOEffect, ReadIOEffect, RootEffect].}
      Extract a zip file using powershell on Windows and unzip on other systems to the specified output directory
      -
      proc downloadUrl(url, outdir: string) {...}{.raises: [OSError, Exception, IOError, Defect,
      -    ValueError], tags: [ReadDirEffect, ExecIOEffect, ReadIOEffect, RootEffect].}
      +
      proc downloadUrl(url, outdir: string) {...}{.raises: [OSError, Exception, ValueError,
      +    IOError, Defect], tags: [ReadDirEffect, ExecIOEffect, ReadIOEffect, RootEffect].}
      -

      Download a file using powershell on Windows and curl on other systems to the specified output directory

      +

      Download a file using curl or wget (or powershell on Windows) to the specified directory

      If a zip file, it is automatically extracted after download.

      @@ -964,7 +993,7 @@ Hard reset the git repository at the specified directory
      proc configure(path, check: string; flags = "") {...}{.
      -    raises: [OSError, Exception, IOError, Defect, ValueError],
      +    raises: [OSError, Exception, ValueError, IOError, Defect],
           tags: [ReadDirEffect, ExecIOEffect, ReadIOEffect, RootEffect].}
      @@ -976,8 +1005,8 @@ Hard reset the git repository at the specified directory
      -
      proc cmake(path, check, flags: string) {...}{.raises: [OSError, Exception, IOError, Defect,
      -    ValueError], tags: [ReadDirEffect, ExecIOEffect, ReadIOEffect, RootEffect].}
      +
      proc cmake(path, check, flags: string) {...}{.raises: [OSError, Exception, ValueError,
      +    IOError, Defect], tags: [ReadDirEffect, ExecIOEffect, ReadIOEffect, RootEffect].}

      Run the cmake command to generate all Makefiles or other build scripts in the specified path

      @@ -988,13 +1017,14 @@ Hard reset the git repository at the specified directory
      -
      proc make(path, check: string; flags = "") {...}{.raises: [ValueError, OSError, Exception,
      +
      proc make(path, check: string; flags = "") {...}{.raises: [OSError, Exception, ValueError,
           IOError, Defect], tags: [ReadDirEffect, ExecIOEffect, ReadIOEffect, RootEffect].}

      Run the make command to build all binaries in the specified path

      check is a file that will be generated by the make command. This is required to prevent make from running on every build. It is relative to the path and should not be an absolute path.

      flags are any flags that should be passed to the make command.

      +

      If make.exe is missing and mingw32-make.exe is available, it will be copied over to make.exe in the same location.

      @@ -1008,7 +1038,7 @@ Hard reset the git repository at the specified directory
      diff --git a/git.idx b/git.idx index 7cc5775..aea3d3b 100644 --- a/git.idx +++ b/git.idx @@ -1,7 +1,10 @@ execAction git.html#execAction,string git: execAction(cmd: string; nostderr = false): string +findExe git.html#findExe,string git: findExe(exe: string): string mkDir git.html#mkDir,string git: mkDir(dir: string) cpFile git.html#cpFile,string,string git: cpFile(source, dest: string; move = false) mvFile git.html#mvFile,string,string git: mvFile(source, dest: string) +rmFile git.html#rmFile,string git: rmFile(source: string; dir = false) +rmDir git.html#rmDir,string git: rmDir(source: string) extractZip git.html#extractZip,string,string git: extractZip(zipfile, outdir: string) downloadUrl git.html#downloadUrl,string,string git: downloadUrl(url, outdir: string) gitReset git.html#gitReset,string git: gitReset(outdir: string) diff --git a/paths.html b/paths.html index 60d9e43..d7a180d 100644 --- a/paths.html +++ b/paths.html @@ -904,7 +904,7 @@ all nimterop generated files go under here (gitignored) diff --git a/plugin.html b/plugin.html index 1b5f4cc..320d144 100644 --- a/plugin.html +++ b/plugin.html @@ -875,7 +875,7 @@ function main() { diff --git a/theindex.html b/theindex.html index 25d0083..fb6b90e 100644 --- a/theindex.html +++ b/theindex.html @@ -805,7 +805,7 @@ function main() {

      Index

      - Modules: cimport, compat, git, paths, plugin, types.

      API symbols

      + Modules: build, cimport, compat, git, paths, plugin, types.

      API symbols

      c2nImport:
      +
      clearDefines:
      cmake:
      configure:
      cOverride:
        @@ -860,6 +868,8 @@ function main() {
      cpFile:
      cPlugin:
        @@ -880,6 +890,8 @@ function main() {
      downloadUrl:
      enumOp:
        @@ -888,22 +900,72 @@ function main() {
      execAction:
      +
      extractTar:
      extractZip:
      +
      findExe:
      +
      findFile:
      +
      flagBuild:
      +
      getCmakeIncludePath:
      +
      getGccLibPaths:
      +
      getGccPaths:
      +
      getHeader:
      gitCheckout:
      gitPull:
      gitReset:
      incDir:
        @@ -912,16 +974,26 @@ function main() {
      make:
      mkDir:
      mvFile:
      +
      myNormalizedPath:
      nimteropBuildDir:
      -
      relativePath:
      diff --git a/types.html b/types.html index f92679b..ec4562d 100644 --- a/types.html +++ b/types.html @@ -828,6 +828,8 @@ function main() {
      • time_t
      • +
      • wchar_t
      • ptrdiff_t
      • + +
        wchar_t {...}{.importc, header: "<cwchar>".} = object
        +
        + + +
        ptrdiff_t = ByteAddress
        @@ -906,7 +915,7 @@ function main() {
      diff --git a/types.idx b/types.idx index 5bc0938..d895171 100644 --- a/types.idx +++ b/types.idx @@ -1,4 +1,5 @@ time_t types.html#time_t types: time_t +wchar_t types.html#wchar_t types: wchar_t ptrdiff_t types.html#ptrdiff_t types: ptrdiff_t va_list types.html#va_list types: va_list enumOp types.html#enumOp.t,,, types: enumOp(op, typ, typout) From 366569f55e177251cb91211e6bd3a785ce7abb49 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 7 Oct 2019 11:37:21 -0700 Subject: [PATCH 259/593] findFile speed improvement, defines in buildDoc, nim compiler path --- nimterop/build.nim | 69 +++++++++++++++++++++++++++++--------------- nimterop/docs.nim | 20 +++++++++---- nimterop/getters.nim | 4 ++- nimterop/grammar.nim | 10 +++---- 4 files changed, 69 insertions(+), 34 deletions(-) diff --git a/nimterop/build.nim b/nimterop/build.nim index a3dd95f..bcbd96a 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -1,4 +1,4 @@ -import macros, osproc, regex, strformat, strutils, tables +import macros, osproc, strformat, strutils, tables import os except findExe, sleep @@ -253,31 +253,52 @@ proc gitPull*(url: string, outdir = "", plist = "", checkout = "") = echo "# Pulling repository" discard execAction(&"cd {outdirQ} && git pull --depth=1 origin master") -proc findFile*(file: string|Regex, dir: string, recurse = true, first = false): string = +proc findFile*(file: string, dir: string, recurse = true, first = false, regex = false): string = ## Find the file in the specified directory ## - ## `file` can be a string or a regex object + ## `file` is a regular expression if `regex` is true ## ## Turn off recursive search with `recurse` and stop on first match with ## `first`. Without it, the shortest match is returned. - when file is Regex: - var - rm: RegexMatch + var + cmd = + when defined(windows): + "nimgrep --filenames --oneline --nocolor $1 $2 $3" + elif defined(linux): + "find $3 $1 -regextype egrep -regex $2" + elif defined(osx): + "find -E $3 $1 -regex $2" + + recursive = "" + + if recurse: + when defined(windows): + recursive = "--recursive" else: + when not defined(windows): + recursive = "-maxdepth 1" + + if not regex: let dir = dir / file.parentDir() file = file.extractFilename - for f in walkDirRec(dir, yieldFilter = {pcFile, pcLinkToFile}, - followFilter = if recurse: {pcDir} else: {}): - let - fn = f.extractFilename() - when file is string: - if (result.len == 0 or result.len > f.len) and fn == file: - result = f - if first: break - else: - if (result.len == 0 or result.len > f.len) and fn.match(file, rm): + cmd = cmd % [recursive, (".*[\\\\/]" & file & "$").quoteShell, dir.sanitizePath] + + let + (files, ret) = gorgeEx(cmd) + if ret == 0: + for line in files.splitLines(): + let f = + when defined(windows): + if ": " in line: + line.split(": ", maxsplit = 1)[1] + else: + "" + else: + line + + if (f.len != 0 and (result.len == 0 or result.len > f.len)): result = f if first: break @@ -442,7 +463,7 @@ proc cmake*(path, check, flags: string) = doAssert (path / check).fileExists(), "# cmake failed" -proc make*(path, check: string|Regex, flags = "") = +proc make*(path, check: string, flags = "", regex = false) = ## Run the `make` command to build all binaries in the specified path ## ## `check` is a file that will be generated by the `make` command. @@ -451,9 +472,11 @@ proc make*(path, check: string|Regex, flags = "") = ## ## `flags` are any flags that should be passed to the `make` command. ## + ## `regex` can be set to true if `check` is a regular expression. + ## ## If `make.exe` is missing and `mingw32-make.exe` is available, it will ## be copied over to make.exe in the same location. - if findFile(check, path).len != 0: + if findFile(check, path, regex = regex).len != 0: return echo "# Running make " & flags @@ -474,7 +497,7 @@ proc make*(path, check: string|Regex, flags = "") = echo execAction(cmd) - doAssert findFile(check, path).len != 0, "# make failed" + doAssert findFile(check, path, regex = regex).len != 0, "# make failed" proc getGccPaths*(mode = "c"): seq[string] = var @@ -532,7 +555,7 @@ proc getStdPath(header: string): string = proc getStdLibPath(lname: string): string = for lib in getGccLibPaths(): - result = findFile(re(lname), lib, recurse = false, first = true) + result = findFile(lname, lib, recurse = false, first = true, regex = true) if result.len != 0: break @@ -596,7 +619,7 @@ proc buildLibrary(lname, outdir, conFlags, cmakeFlags, makeFlags: string): strin conDepStr = "" cmakeDeps = false cmakeDepStr = "" - lpath = findFile(re(lname), outdir) + lpath = findFile(lname, outdir, regex = true) makeFlagsProc = &"-j {getNumProcs()} {makeFlags}" made = false makePath = outdir @@ -643,7 +666,7 @@ proc buildLibrary(lname, outdir, conFlags, cmakeFlags, makeFlags: string): strin conDepStr &= "bash executable missing" if fileExists(makePath / "Makefile"): - make(makePath, re(lname), makeFlagsProc) + make(makePath, lname, makeFlagsProc, regex = true) made = true var @@ -656,7 +679,7 @@ proc buildLibrary(lname, outdir, conFlags, cmakeFlags, makeFlags: string): strin error = "No build files found in " & outdir doAssert cmakeDeps or conDeps or made, &"\n# Build configuration failed - {error}\n" - result = findFile(re(lname), outdir) + result = findFile(lname, outdir, regex = true) proc getDynlibExt(): string = when defined(windows): diff --git a/nimterop/docs.nim b/nimterop/docs.nim index 0b46967..8fd396b 100644 --- a/nimterop/docs.nim +++ b/nimterop/docs.nim @@ -1,7 +1,7 @@ import macros, strformat when (NimMajor, NimMinor, NimPatch) >= (0, 19, 9): - from os import parentDir + from os import parentDir, getCurrentCompilerExe proc getNimRootDir(): string = #[ hack, but works @@ -11,8 +11,12 @@ when (NimMajor, NimMinor, NimPatch) >= (0, 19, 9): nimRootDir ]# fmt"{currentSourcePath}".parentDir.parentDir.parentDir +else: + proc getCurrentCompilerExe*(): string = + "nim" -proc buildDocs*(files: seq[string], path: string, baseDir = getProjectPath() & "/") = +proc buildDocs*(files: openArray[string], path: string, baseDir = getProjectPath() & "/", + defines: openArray[string] = @[]) = ## Generate docs for all specified nim `files` to the specified `path` ## ## `baseDir` is the project path by default and `files` and `path` are relative @@ -30,16 +34,22 @@ proc buildDocs*(files: seq[string], path: string, baseDir = getProjectPath() & " else: baseDir path = baseDir & path + defStr = block: + var defStr = "" + for def in defines: + defStr &= " -d:" & def + defStr + nim = getCurrentCompilerExe() for file in files: - echo gorge(&"nim doc -o:{path} --project --index:on {baseDir & file}") + echo gorge(&"{nim} doc {defStr} -o:{path} --project --index:on {baseDir & file}") - echo gorge(&"nim buildIndex -o:{path}/theindex.html {path}") + echo gorge(&"{nim} buildIndex -o:{path}/theindex.html {path}") when declared(getNimRootDir): #[ this enables doc search, works at least locally with: cd {path} && python -m SimpleHTTPServer 9009 ]# - echo gorge(&"nim js -o:{path}/dochack.js {getNimRootDir()}/tools/dochack/dochack.nim") + echo gorge(&"{nim} js -o:{path}/dochack.js {getNimRootDir()}/tools/dochack/dochack.nim") for i in 0 .. paramCount(): if paramStr(i) == "--publish": diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 20fd8b3..d08b318 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -380,9 +380,11 @@ proc getPragma*(nimState: NimState, pragmas: varargs[string]): string = if ", cdecl" in result and dy.len != 0: result = result.replace(".}", dy & ".}") -proc getComments*(nimState: NimState): string = +proc getComments*(nimState: NimState, strip = false): string = if not nimState.gState.nocomments and nimState.commentStr.len != 0: result = "\n" & nimState.commentStr + if strip: + result = result.replace("\n ", "\n") nimState.commentStr = "" proc dll*(path: string): string = diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index bfc5def..b14a208 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -212,7 +212,7 @@ proc initGrammar(): Grammar = if ndname.nBl and ndname != nname: if isEnum: if nimState.addNewIdentifer(ndname): - nimState.enumStr &= &"{nimState.getComments()}\ntype {ndname}* = {dptr}{nname}" + nimState.enumStr &= &"{nimState.getComments(true)}\ntype {ndname}* = {dptr}{nname}" else: if nimState.addNewIdentifer(ndname): let @@ -434,7 +434,7 @@ proc initGrammar(): Grammar = nimState.getIdentifier(name, nskType) if nname.nBl and nimState.addNewIdentifer(nname): - nimState.enumStr &= &"{nimState.getComments()}\ndefineEnum({nname})" + nimState.enumStr &= &"{nimState.getComments(true)}\ndefineEnum({nname})" var i = fstart @@ -579,9 +579,9 @@ proc initGrammar(): Grammar = pragma = nimState.getPragma(nimState.getImportC(fname, fnname), "cdecl") if fptr.len != 0 or ftyp != "object": - nimState.procStr &= &"{nimState.getComments()}\nproc {fnname}*({pout}): {getPtrType(fptr&ftyp)}{pragma}" + nimState.procStr &= &"{nimState.getComments(true)}\nproc {fnname}*({pout}): {getPtrType(fptr&ftyp)}{pragma}" else: - nimState.procStr &= &"{nimState.getComments()}\nproc {fnname}*({pout}){pragma}" + nimState.procStr &= &"{nimState.getComments(true)}\nproc {fnname}*({pout}){pragma}" )) # // comment @@ -597,7 +597,7 @@ proc initGrammar(): Grammar = let line = line.multiReplace([("//", ""), ("/*", ""), ("*/", "")]) - nimState.commentStr &= &"\n# {line.strip(leading=false)}" + nimState.commentStr &= &"\n # {line.strip(leading=false)}" )) proc initRegex(ast: ref Ast) = From c21a334ec1800b20248eb4e32c6234df800e31e0 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 8 Oct 2019 10:53:07 -0700 Subject: [PATCH 260/593] Fix #134, time64_t, buildDocs error on Win --- nimterop/build.nim | 14 +++++--- nimterop/docs.nim | 82 +++++++++++++++++++++++++++++--------------- nimterop/grammar.nim | 15 ++++++-- nimterop/types.nim | 5 ++- 4 files changed, 81 insertions(+), 35 deletions(-) diff --git a/nimterop/build.nim b/nimterop/build.nim index bcbd96a..843db42 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -45,7 +45,7 @@ proc execAction*(cmd: string, retry = 0, nostderr = false): string = sleep(500) result = execAction(cmd, retry = retry - 1) else: - doAssert true, "Command failed: " & $(ret, nostderr) & "\nccmd: " & ccmd & "\nresult:\n" & result + doAssert true, "Command failed: " & $(ret, nostderr) & "\ncmd: " & ccmd & "\nresult:\n" & result proc findExe*(exe: string): string = ## Find the specified executable using the `which`/`where` command - supported @@ -278,10 +278,16 @@ proc findFile*(file: string, dir: string, recurse = true, first = false, regex = when not defined(windows): recursive = "-maxdepth 1" - if not regex: + var + dir = dir + file = file + if not recurse: let - dir = dir / file.parentDir() - file = file.extractFilename + pdir = file.parentDir() + if pdir.len != 0: + dir = dir / pdir + + file = file.extractFilename cmd = cmd % [recursive, (".*[\\\\/]" & file & "$").quoteShell, dir.sanitizePath] diff --git a/nimterop/docs.nim b/nimterop/docs.nim index 8fd396b..57c806b 100644 --- a/nimterop/docs.nim +++ b/nimterop/docs.nim @@ -1,7 +1,7 @@ import macros, strformat when (NimMajor, NimMinor, NimPatch) >= (0, 19, 9): - from os import parentDir, getCurrentCompilerExe + from os import parentDir, getCurrentCompilerExe, DirSep proc getNimRootDir(): string = #[ hack, but works @@ -15,43 +15,69 @@ else: proc getCurrentCompilerExe*(): string = "nim" -proc buildDocs*(files: openArray[string], path: string, baseDir = getProjectPath() & "/", + const + DirSep = when defined(windows): '\\' else: '/' + +proc execAction(cmd: string): string = + var + ccmd = "" + ret = 0 + when defined(Windows): + ccmd = "cmd /c " & cmd + elif defined(posix): + ccmd = cmd + else: + doAssert false + + (result, ret) = gorgeEx(ccmd) + doAssert ret == 0, "Command failed: " & $ret & "\ncmd: " & ccmd & "\nresult:\n" & result + +proc buildDocs*(files: openArray[string], path: string, baseDir = getProjectPath() & $DirSep, defines: openArray[string] = @[]) = ## Generate docs for all specified nim `files` to the specified `path` ## ## `baseDir` is the project path by default and `files` and `path` are relative ## to that directory. Set to "" if using absolute paths. ## + ## `defines` is a list of `-d:xxx` define flags (the `xxx` part) that should be passed + ## to `nim doc` so that `getHeader()` is invoked correctly. + ## ## Use the `--publish` flag with nimble to publish docs contained in ## `path` to Github in the `gh-pages` branch. This requires the ghp-import ## package for Python: `pip install ghp-import` ## ## WARNING: `--publish` will destroy any existing content in this branch. - let - baseDir = - if baseDir == "/": - getCurrentDir() & "/" - else: - baseDir - path = baseDir & path - defStr = block: - var defStr = "" - for def in defines: - defStr &= " -d:" & def - defStr - nim = getCurrentCompilerExe() - for file in files: - echo gorge(&"{nim} doc {defStr} -o:{path} --project --index:on {baseDir & file}") + ## + ## NOTE: `buildDocs()` only works correctly on Windows with Nim 1.0+ since + ## https://github.com/nim-lang/Nim/pull/11814 is required. + when defined(windows) and (NimMajor, NimMinor, NimPatch) < (1, 0, 0): + echo "buildDocs() unsupported on Windows for Nim < 1.0 - requires PR #11814" + else: + let + baseDir = + if baseDir == $DirSep: + getCurrentDir() & $DirSep + else: + baseDir + path = baseDir & path + defStr = block: + var defStr = "" + for def in defines: + defStr &= " -d:" & def + defStr + nim = getCurrentCompilerExe() + for file in files: + echo execAction(&"{nim} doc {defStr} -o:{path} --project --index:on {baseDir & file}") - echo gorge(&"{nim} buildIndex -o:{path}/theindex.html {path}") - when declared(getNimRootDir): - #[ - this enables doc search, works at least locally with: - cd {path} && python -m SimpleHTTPServer 9009 - ]# - echo gorge(&"{nim} js -o:{path}/dochack.js {getNimRootDir()}/tools/dochack/dochack.nim") + echo execAction(&"{nim} buildIndex -o:{path}/theindex.html {path}") + when declared(getNimRootDir): + #[ + this enables doc search, works at least locally with: + cd {path} && python -m SimpleHTTPServer 9009 + ]# + echo execAction(&"{nim} js -o:{path}/dochack.js {getNimRootDir()}/tools/dochack/dochack.nim") - for i in 0 .. paramCount(): - if paramStr(i) == "--publish": - echo gorge(&"ghp-import --no-jekyll -fp {path}") - break + for i in 0 .. paramCount(): + if paramStr(i) == "--publish": + echo execAction(&"ghp-import --no-jekyll -fp {path}") + break \ No newline at end of file diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index b14a208..57cbbdd 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -142,6 +142,7 @@ proc initGrammar(): Grammar = nname = "" tptr = "" aptr = "" + pragmas: seq[string] = @[] i += 1 while i < nimState.data.len and "pointer" in nimState.data[i].name: @@ -158,8 +159,11 @@ proc initGrammar(): Grammar = nname = nimState.getIdentifier(name, nskType) i += 1 + if nimState.gState.dynlib.len == 0: + pragmas.add nimState.getImportC(name, nname) + let - pragma = nimState.getPragma(nimState.getImportC(name, nname)) + pragma = nimState.getPragma(pragmas) if nname notin gTypeMap and typ.nBl and nname.nBl and nimState.addNewIdentifer(nname): if i < nimState.data.len and nimState.data[^1].name == "function_declarator": @@ -255,8 +259,15 @@ proc initGrammar(): Grammar = if nimState.data.len == 1: nimState.typeStr &= &"{nimState.getComments()}\n {nname}* {{.bycopy.}} = object{union}" else: + var + pragmas: seq[string] = @[] + if nimState.gState.dynlib.len == 0: + pragmas.add nimState.getImportC(prefix & name, nname) + pragmas.add "bycopy" + let - pragma = nimState.getPragma(nimState.getImportC(prefix & name, nname), "bycopy") + pragma = nimState.getPragma(pragmas) + nimState.typeStr &= &"{nimState.getComments()}\n {nname}*{pragma} = object{union}" var diff --git a/nimterop/types.nim b/nimterop/types.nim index 8492f00..3dd8f39 100644 --- a/nimterop/types.nim +++ b/nimterop/types.nim @@ -15,10 +15,13 @@ when (NimMajor, NimMinor, NimPatch) < (0, 19, 9): import posix type time_t* = Time + time64_t* = Time wchar_t* {.importc.} = object else: import std/time_t as time_t_temp - type time_t* = time_t_temp.Time + type + time_t* = time_t_temp.Time + time64_t* = time_t_temp.Time when defined(c) or defined(nimdoc): # http://www.cplusplus.com/reference/cwchar/wchar_t/ From f2a0d4b0c9ed29ad83f3cc87ad8f4f02bde34dee Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 8 Oct 2019 15:19:36 -0500 Subject: [PATCH 261/593] Add linkLibs and isDefined --- nimterop/build.nim | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/nimterop/build.nim b/nimterop/build.nim index 843db42..620f83e 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -1,4 +1,4 @@ -import macros, osproc, strformat, strutils, tables +import macros, osproc, sets, strformat, strutils, tables import os except findExe, sleep @@ -322,6 +322,28 @@ proc flagBuild*(base: string, flags: openArray[string]): string = for i in flags: result &= " " & base % i +proc linkLibs*(names: openArray[string], staticLink = true): string = + ## Create linker flags for specified libraries + ## + ## Prepends `lib` to the name so you only need `ssl` for `libssl`. + var + stat = if staticLink: "--static" else: "" + resSet: OrderedSet[string] + resSet.init() + + for name in names: + let + cmd = &"pkg-config --libs --silence-errors {stat} lib{name}" + libs = gorge(cmd) + for lib in libs.split(" "): + resSet.incl lib + + if staticLink: + resSet.incl "--static" + + for res in resSet: + result &= " " & res + proc configure*(path, check: string, flags = "") = ## Run the GNU `configure` command to generate all Makefiles or other ## build scripts in the specified path @@ -737,6 +759,18 @@ macro clearDefines*(): untyped = ## Clear all defines set using `setDefines()`. gDefines.clear() +macro isDefined*(def: untyped): untyped = + ## Check if `-d:xxx` is set globally or via `setDefines()` + let + sdef = gDefines.hasKey(def.strVal()) + result = newNimNode(nnkStmtList) + result.add(quote do: + when defined(`def`) or `sdef` != 0: + true + else: + false + ) + macro getHeader*(header: static[string], giturl: static[string] = "", dlurl: static[string] = "", outdir: static[string] = "", conFlags: static[string] = "", cmakeFlags: static[string] = "", makeFlags: static[string] = "", altNames: static[string] = ""): untyped = From 6db698ea7a57a9fb9e4790ec768340a36b9e90e3 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 10 Oct 2019 07:56:47 -0500 Subject: [PATCH 262/593] Move all artifacts to nimcache --- nimterop.nimble | 7 ++++-- nimterop/build.nim | 40 +++++++++++++++++++++++++++++++++-- nimterop/cimport.nim | 4 ++-- nimterop/paths.nim | 12 +++++------ nimterop/setup.nim | 30 +++++++++++--------------- nimterop/treesitter/api.nim | 2 +- nimterop/treesitter/c.nim | 2 +- nimterop/treesitter/cpp.nim | 14 +++++------- nimterop/treesitter/tsgen.nim | 2 +- tests/getheader.nims | 11 +++++----- tests/lzma.nim | 2 +- tests/tpcre.nim | 4 ++-- tests/tsoloud.nim | 2 +- tests/zlib.nim | 2 +- 14 files changed, 80 insertions(+), 54 deletions(-) diff --git a/nimterop.nimble b/nimterop.nimble index 5825f5a..8e27d8e 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -21,10 +21,13 @@ proc execCmd(cmd: string) = exec cmd proc execTest(test: string) = - execCmd "nim c -r " & test + execCmd "nim c -f -r " & test execCmd "nim cpp -r " & test task buildToast, "build toast": + execCmd("nim c -f -d:danger nimterop/toast.nim") + +task bt, "build toast": execCmd("nim c -d:danger nimterop/toast.nim") task docs, "Generate docs": @@ -34,7 +37,7 @@ task test, "Test": buildToastTask() execTest "tests/tnimterop_c.nim" - execCmd "nim cpp -r tests/tnimterop_cpp.nim" + execCmd "nim cpp -f -r tests/tnimterop_cpp.nim" execTest "tests/tpcre.nim" # Platform specific tests diff --git a/nimterop/build.nim b/nimterop/build.nim index 620f83e..91daee0 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -110,9 +110,45 @@ proc rmFile*(source: string, dir = false) = discard execAction(&"{cmd} {source.sanitizePath}", retry = 2) -proc rmDir*(source: string) = +proc rmDir*(dir: string) = ## Remove a directory or pattern at compile time - rmFile(source, dir = true) + rmFile(dir, dir = true) + +proc getOsCacheDir(): string = + when defined(posix): + result = getEnv("XDG_CACHE_HOME", getHomeDir() / ".cache") / "nim" + else: + result = getHomeDir() / "nimcache" + +proc getNimteropCacheDir(): string = + result = getOsCacheDir() / "nimterop" + +proc getProjectCacheDir*(name: string, forceClean = true): string = + ## Get a cache directory where all nimterop artifacts can be stored + ## + ## Projects can use this location to download source code and build binaries + ## that can be then accessed by multiple apps. This is created under the + ## per-user Nim cache directory. + ## + ## Use `name` to specify the subdirectory name for a project. + ## + ## `forceClean` is enabled by default and effectively deletes the folder + ## if Nim is compiled with the `-f` or `--forceBuild` flag. This allows + ## any project to start out with a clean cache dir on a forced build. + ## + ## NOTE: avoid calling `getProjectCacheDir()` multiple times on the same + ## `name` when `forceClean = true` else checked out source might get deleted + ## at the wrong time during build. + ## + ## E.g. + ## `nimgit2` downloads `libgit2` source so `name = "libgit2"` + ## + ## `nimarchive` downloads `libarchive`, `bzlib`, `liblzma` and `zlib` so + ## `name = "nimarchive" / "libarchive"` for `libarchive`, etc. + result = getNimteropCacheDir() / name + + if forceClean and compileOption("forceBuild"): + rmDir(result) proc extractZip*(zipfile, outdir: string) = ## Extract a zip file using `powershell` on Windows and `unzip` on other diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index b295344..4380311 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -107,12 +107,12 @@ proc getNimCheckError(output: string): tuple[tmpFile, errors: string] = let hash = output.hash().abs() - result.tmpFile = getTempDir() / "nimterop_" & $hash & ".nim" + result.tmpFile = getProjectCacheDir("cPlugins", forceClean = false) / "nimterop_" & $hash & ".nim" if not fileExists(result.tmpFile) or gStateCT.nocache or compileOption("forceBuild"): writeFile(result.tmpFile, output) - doAssert fileExists(result.tmpFile), "Bad codegen - unable to write to TEMP: " & result.tmpFile + doAssert fileExists(result.tmpFile), "Failed to write to cache dir: " & result.tmpFile let nim = diff --git a/nimterop/paths.nim b/nimterop/paths.nim index 5a2bb73..d55276e 100644 --- a/nimterop/paths.nim +++ b/nimterop/paths.nim @@ -1,21 +1,19 @@ import os +import "."/build + +const + cacheDir* = getProjectCacheDir("nimterop") + proc nimteropRoot*(): string = currentSourcePath.parentDir.parentDir -proc nimteropBuildDir*(): string = - ## all nimterop generated files go under here (gitignored) - nimteropRoot() / "build" - proc nimteropSrcDir*(): string = nimteropRoot() / "nimterop" proc toastExePath*(): string = nimteropSrcDir() / ("toast".addFileExt ExeExt) -proc incDir*(): string = - nimteropBuildDir() / "inc" - proc testsIncludeDir*(): string = nimteropRoot() / "tests" / "include" diff --git a/nimterop/setup.nim b/nimterop/setup.nim index 4ee375b..3f16dd7 100644 --- a/nimterop/setup.nim +++ b/nimterop/setup.nim @@ -3,24 +3,24 @@ import os, strutils import "."/[build, paths] proc treesitterSetup*() = - gitPull("https://github.com/tree-sitter/tree-sitter", incDir() / "treesitter", """ + gitPull("https://github.com/tree-sitter/tree-sitter", cacheDir / "treesitter", """ lib/include/* lib/src/* """, "0.15.5") - gitPull("https://github.com/JuliaStrings/utf8proc", incDir() / "utf8proc", """ + gitPull("https://github.com/JuliaStrings/utf8proc", cacheDir / "utf8proc", """ *.c *.h """) let - tbase = incDir() / "treesitter/lib" - stack = tbase / "src/stack.c" - parser = tbase / "include/tree_sitter/parser.h" + tbase = cacheDir / "treesitter" / "lib" + stack = tbase / "src" / "stack.c" + parser = tbase / "include" / "tree_sitter" / "parser.h" tparser = parser.replace("parser", "tparser") - language = tbase / "src/language.h" - lexer = tbase / "src/lexer.h" - subtree = tbase / "src/subtree.h" + language = tbase / "src" / "language.h" + lexer = tbase / "src" / "lexer.h" + subtree = tbase / "src" / "subtree.h" stack.writeFile(stack.readFile().replace("inline Stack", "Stack")) @@ -31,31 +31,25 @@ lib/src/* subtree.writeFile(subtree.readFile().replace("parser.h", "tparser.h")) proc treesitterCSetup*() = - gitPull("https://github.com/tree-sitter/tree-sitter-c", incDir() / "treesitter_c", """ + gitPull("https://github.com/tree-sitter/tree-sitter-c", cacheDir / "treesitter_c", """ src/*.h src/*.c src/*.cc src/tree_sitter/parser.h """, "v0.15.0") - let - headerc = incDir() / "treesitter_c/src/api.h" - - headerc.writeFile(""" + writeFile(cacheDir / "treesitter_c" / "src" / "api.h", """ const TSLanguage *tree_sitter_c(); """) proc treesitterCppSetup*() = - gitPull("https://github.com/tree-sitter/tree-sitter-cpp", incDir() / "treesitter_cpp", """ + gitPull("https://github.com/tree-sitter/tree-sitter-cpp", cacheDir / "treesitter_cpp", """ src/*.h src/*.c src/*.cc src/tree_sitter/parser.h """, "v0.15.0") - let - headercpp = incDir() / "treesitter_cpp/src/api.h" - - headercpp.writeFile(""" + writeFile(cacheDir / "treesitter_cpp" / "src" / "api.h", """ const TSLanguage *tree_sitter_cpp(); """) diff --git a/nimterop/treesitter/api.nim b/nimterop/treesitter/api.nim index 2c11a60..09e328d 100644 --- a/nimterop/treesitter/api.nim +++ b/nimterop/treesitter/api.nim @@ -7,7 +7,7 @@ import ".."/[setup, paths, types] static: treesitterSetup() -const sourcePath = incDir() / "treesitter" / "lib" +const sourcePath = cacheDir / "treesitter" / "lib" when defined(Linux): {.passC: "-std=c11".} diff --git a/nimterop/treesitter/c.nim b/nimterop/treesitter/c.nim index 38fa003..d779bfd 100644 --- a/nimterop/treesitter/c.nim +++ b/nimterop/treesitter/c.nim @@ -5,7 +5,7 @@ import ".."/[setup, paths] static: treesitterCSetup() -const srcDir = incDir() / "treesitter_c" / "src" +const srcDir = cacheDir / "treesitter_c" / "src" import "."/api diff --git a/nimterop/treesitter/cpp.nim b/nimterop/treesitter/cpp.nim index 131e57f..2fe3128 100644 --- a/nimterop/treesitter/cpp.nim +++ b/nimterop/treesitter/cpp.nim @@ -1,24 +1,20 @@ import strutils, os -import ".."/[setup, paths] +import ".."/[build, setup, paths] static: treesitterCppSetup() -const srcDir = incDir() / "treesitter_cpp" / "src" +const srcDir = cacheDir / "treesitter_cpp" / "src" {.passC: "-I$1" % srcDir.} import "."/api -when (NimMajor, NimMinor, NimPatch) < (0, 19, 9): - const srcDirRel = "../../build/inc/treesitter_cpp/src" -else: - const srcDirRel = srcDir.relativePath(currentSourcePath.parentDir) +static: + cpFile(srcDir / "parser.c", srcDir / "parser_cpp.c") -# pending https://github.com/nim-lang/Nim/issues/9370 we need srcDirRel instead -# of srcDir -{.compile: (srcDirRel / "parser.c", "nimtero_cpp_parser.c.o").} +{.compile: srcDir / "parser_cpp.c".} {.compile: srcDir / "scanner.cc".} proc treeSitterCpp*(): ptr TSLanguage {.importc: "tree_sitter_cpp", header: srcDir / "api.h".} diff --git a/nimterop/treesitter/tsgen.nim b/nimterop/treesitter/tsgen.nim index 335f28f..484483c 100644 --- a/nimterop/treesitter/tsgen.nim +++ b/nimterop/treesitter/tsgen.nim @@ -15,4 +15,4 @@ cPlugin: static: cDebug() -cImport(incDir()/"treesitter/lib/include/tree_sitter/api.h") \ No newline at end of file +cImport(cacheDir / "treesitter" /"lib" / "include" / "tree_sitter" / "api.h") diff --git a/tests/getheader.nims b/tests/getheader.nims index c122484..5a08429 100644 --- a/tests/getheader.nims +++ b/tests/getheader.nims @@ -1,16 +1,17 @@ import strutils proc testCall(cmd, output: string, exitCode: int, delete = true) = - if delete: - rmDir("build/liblzma") - rmDir("build/zlib") - echo cmd var ccmd = when defined(windows): "cmd /c " & cmd else: cmd + + if not delete: + ccmd = ccmd.replace(" -f ", " ") + + var (outp, exitC) = gorgeEx(ccmd) echo outp doAssert exitC == exitCode, $exitC @@ -41,7 +42,6 @@ when defined(posix): # git tag testCall(cmd & " -d:lzmaGit -d:lzmaSetVer=v5.2.0" & lrcmd, lexp & "5.2.0", 0) testCall(cmd & " -d:lzmaGit -d:lzmaStatic -d:lzmaSetVer=v5.2.0" & lrcmd, lexp & "5.2.0", 0, delete = false) - testCall("cd build/liblzma && git branch", "v5.2.0", 0, delete = false) # git testCall(cmd & " -d:envTest" & zrcmd, zexp, 0) @@ -50,7 +50,6 @@ testCall(cmd & " -d:envTestStatic" & zrcmd, zexp, 0, delete = false) # git tag testCall(cmd & " -d:zlibGit -d:zlibSetVer=v1.2.10" & zrcmd, zexp & "1.2.10", 0) testCall(cmd & " -d:zlibGit -d:zlibStatic -d:zlibSetVer=v1.2.10" & zrcmd, zexp & "1.2.10", 0, delete = false) -testCall("cd build/zlib && git branch", "v1.2.10", 0, delete = false) # dl testCall(cmd & " -d:lzmaDL" & lrcmd, "Need version", 1) diff --git a/tests/lzma.nim b/tests/lzma.nim index 2368b55..785e0bb 100644 --- a/tests/lzma.nim +++ b/tests/lzma.nim @@ -3,7 +3,7 @@ import os, strutils import nimterop/[build, cimport] const - baseDir = currentSourcePath.parentDir()/"build"/"liblzma" + baseDir = getProjectCacheDir("nimterop" / "tests" / "liblzma") static: cDebug() diff --git a/tests/tpcre.nim b/tests/tpcre.nim index 5588850..5bc97da 100644 --- a/tests/tpcre.nim +++ b/tests/tpcre.nim @@ -3,7 +3,7 @@ import os import nimterop/[cimport, build, paths] const - baseDir = nimteropBuildDir()/"pcre" + baseDir = getProjectCacheDir("nimterop" / "tests" / "pcre") pcreH = baseDir/"pcre.h.in" static: @@ -32,4 +32,4 @@ cPlugin: cImport(pcreH, dynlib="dynpcre") -echo version() \ No newline at end of file +echo version() diff --git a/tests/tsoloud.nim b/tests/tsoloud.nim index 12966a8..9281236 100644 --- a/tests/tsoloud.nim +++ b/tests/tsoloud.nim @@ -1,7 +1,7 @@ import os, nimterop/[cimport, build, paths] const - baseDir = nimteropBuildDir()/"soloud" + baseDir = getProjectCacheDir("nimterop" / "tests" / "soloud") incl = baseDir/"include" src = baseDir/"src" diff --git a/tests/zlib.nim b/tests/zlib.nim index 371d41f..572580c 100644 --- a/tests/zlib.nim +++ b/tests/zlib.nim @@ -3,7 +3,7 @@ import os, strutils import nimterop/[build, cimport] const - baseDir = currentSourcePath.parentDir()/"build"/"zlib" + baseDir = getProjectCacheDir("nimterop" / "tests" / "zlib") static: cDebug() From ff8c7330cd3d48dce1526b01bd78b19767d3857b Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 10 Oct 2019 09:33:09 -0500 Subject: [PATCH 263/593] Nimcache fixes, Std + fallback --- nimterop/build.nim | 45 ++++++++++++++++++++++++++------------------ nimterop/cimport.nim | 9 ++++++--- 2 files changed, 33 insertions(+), 21 deletions(-) diff --git a/nimterop/build.nim b/nimterop/build.nim index 91daee0..943e91e 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -824,6 +824,10 @@ macro getHeader*(header: static[string], giturl: static[string] = "", dlurl: sta ## This allows a single wrapper to be used in different ways depending on the user's needs. ## If no `-d:xxx` defines are specified, `outdir` will be searched for the header as is. ## + ## If multiple `-d:xxx` defines are specified, precedence is `Std` and then `Git` or `DL`. + ## This allows using a system installed library if available before falling back to manual + ## building. + ## ## `-d:xxxSetVer=x.y.z` can be used to specify which version to use. It is used as a tag ## name for Git whereas for DL, it replaces `$1` in the URL defined. ## @@ -912,26 +916,31 @@ macro getHeader*(header: static[string], giturl: static[string] = "", dlurl: sta else: `lre` & getDynlibExt() - when `nameStd`: - const - `path`* = getStdPath(`header`) - `lpath`* = getStdLibPath(`lname`) - else: - const - `path`* = - when `nameGit`: - getGitPath(`header`, `giturl`, `outdir`, `version`) - elif `nameDL`: - getDlPath(`header`, `dlurl`, `outdir`, `version`) - else: - getLocalPath(`header`, `outdir`) + stdPath = + when `nameStd`: getStdPath(`header`) else: "" + stdLPath = + when `nameStd`: getStdLibPath(`lname`) else: "" - when declared(`preBuild`): - static: - `preBuild`(`outdir`, `path`) + `path`* = + when stdPath.len != 0: + stdPath + elif `nameGit`: + getGitPath(`header`, `giturl`, `outdir`, `version`) + elif `nameDL`: + getDlPath(`header`, `dlurl`, `outdir`, `version`) + else: + getLocalPath(`header`, `outdir`) - const - `lpath`* = buildLibrary(`lname`, `outdir`, `conFlags`, `cmakeFlags`, `makeFlags`) + when stdPath.len == 0 and declared(`preBuild`): + static: + `preBuild`(`outdir`, `path`) + + const + `lpath`* = + when stdPath.len != 0 and stdLPath.len != 0: + stdLPath + else: + buildLibrary(`lname`, `outdir`, `conFlags`, `cmakeFlags`, `makeFlags`) static: doAssert `path`.len != 0, "\nHeader " & `header` & " not found - " & "missing/empty outdir or -d:$1Std -d:$1Git or -d:$1DL not specified" % `name` diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index 4380311..cea859a 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -107,9 +107,10 @@ proc getNimCheckError(output: string): tuple[tmpFile, errors: string] = let hash = output.hash().abs() - result.tmpFile = getProjectCacheDir("cPlugins", forceClean = false) / "nimterop_" & $hash & ".nim" + result.tmpFile = getProjectCacheDir("failed", forceClean = false) / "nimterop_" & $hash & ".nim" if not fileExists(result.tmpFile) or gStateCT.nocache or compileOption("forceBuild"): + mkDir(result.tmpFile.parentDir()) writeFile(result.tmpFile, output) doAssert fileExists(result.tmpFile), "Failed to write to cache dir: " & result.tmpFile @@ -278,9 +279,10 @@ macro cPlugin*(body): untyped = let data = "import macros, nimterop/plugin\n\n" & body.repr hash = data.hash().abs() - path = getTempDir() / "nimterop_" & $hash & ".nim" + path = getProjectCacheDir("cPlugins", forceClean = false) / "nimterop_" & $hash & ".nim" if not fileExists(path) or gStateCT.nocache or compileOption("forceBuild"): + mkDir(path.parentDir()) writeFile(path, data) doAssert fileExists(path), "Unable to write plugin file: " & path @@ -575,11 +577,12 @@ macro c2nImport*(filename: static string, recurse: static bool = false, dynlib: let output = getToast(fullpath, recurse, dynlib, noNimout = true) hash = output.hash().abs() - hpath = getTempDir() / "nimterop_" & $hash & ".h" + hpath = getProjectCacheDir("c2nimCache", forceClean = false) / "nimterop_" & $hash & ".h" npath = hpath[0 .. hpath.rfind('.')] & "nim" header = ("header" & fullpath.splitFile().name.replace(re"[-.]+", "")) if not fileExists(hpath) or gStateCT.nocache or compileOption("forceBuild"): + mkDir(hpath.parentDir()) writeFile(hpath, output) doAssert fileExists(hpath), "Unable to write temporary header file: " & hpath From 3e9dc2fb0fd6257fd86897c1b13f10ed2a5279b4 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 10 Oct 2019 14:45:26 -0700 Subject: [PATCH 264/593] Fix std fallback and docs publish --- nimterop/build.nim | 4 ++-- nimterop/docs.nim | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/nimterop/build.nim b/nimterop/build.nim index 943e91e..81e7445 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -922,7 +922,7 @@ macro getHeader*(header: static[string], giturl: static[string] = "", dlurl: sta when `nameStd`: getStdLibPath(`lname`) else: "" `path`* = - when stdPath.len != 0: + when stdPath.len != 0 and stdLPath.len != 0: stdPath elif `nameGit`: getGitPath(`header`, `giturl`, `outdir`, `version`) @@ -931,7 +931,7 @@ macro getHeader*(header: static[string], giturl: static[string] = "", dlurl: sta else: getLocalPath(`header`, `outdir`) - when stdPath.len == 0 and declared(`preBuild`): + when `path` != stdPath and declared(`preBuild`): static: `preBuild`(`outdir`, `path`) diff --git a/nimterop/docs.nim b/nimterop/docs.nim index 57c806b..17089ec 100644 --- a/nimterop/docs.nim +++ b/nimterop/docs.nim @@ -79,5 +79,5 @@ proc buildDocs*(files: openArray[string], path: string, baseDir = getProjectPath for i in 0 .. paramCount(): if paramStr(i) == "--publish": - echo execAction(&"ghp-import --no-jekyll -fp {path}") + echo execAction(&"cd {path} && ghp-import --no-jekyll -fp {path}") break \ No newline at end of file From edc1366f1410a2c254772c2baf9eb6d8c8fd6e18 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 10 Oct 2019 18:38:17 -0500 Subject: [PATCH 265/593] Update documentation --- all.html | 2 +- build.html | 73 +++- build.idx | 9 +- cimport.html | 4 +- compat.html | 2 +- dochack.js | 1 - git.html | 1048 ------------------------------------------------- git.idx | 15 - paths.html | 53 ++- paths.idx | 3 +- plugin.html | 2 +- theindex.html | 64 ++- types.html | 11 +- types.idx | 1 + 14 files changed, 139 insertions(+), 1149 deletions(-) delete mode 100644 git.html delete mode 100644 git.idx diff --git a/all.html b/all.html index 9b6a1fa..618ff78 100644 --- a/all.html +++ b/all.html @@ -850,7 +850,7 @@ function main() { diff --git a/build.html b/build.html index d470cfd..f1880f7 100644 --- a/build.html +++ b/build.html @@ -849,7 +849,9 @@ function main() {
    • rmFile
    • rmDir
    • + title="rmDir(dir: string)">rmDir +
    • getProjectCacheDir
    • extractZip
    • gitCheckout
    • gitPull
    • -
    • findFile
    • +
    • findFile
    • flagBuild
    • +
    • linkLibs
    • configure
    • setCmakePositionIndependentCode
    • cmake
    • -
    • make
    • +
    • make
    • getGccPaths
    • setDefines
    • clearDefines
    • +
    • isDefined
    • -
      proc rmDir(source: string) {...}{.raises: [OSError, Exception, IOError, Defect, ValueError],
      -                          tags: [ExecIOEffect, ReadIOEffect, RootEffect].}
      +
      proc rmDir(dir: string) {...}{.raises: [OSError, Exception, IOError, Defect, ValueError],
      +                       tags: [ExecIOEffect, ReadIOEffect, RootEffect].}
      Remove a directory or pattern at compile time +
      + +
      proc getProjectCacheDir(name: string; forceClean = true): string {...}{.
      +    raises: [OSError, Exception, IOError, Defect, ValueError],
      +    tags: [ReadEnvEffect, ReadIOEffect, ExecIOEffect, RootEffect].}
      +
      + +

      Get a cache directory where all nimterop artifacts can be stored

      +

      Projects can use this location to download source code and build binaries that can be then accessed by multiple apps. This is created under the per-user Nim cache directory.

      +

      Use name to specify the subdirectory name for a project.

      +

      forceClean is enabled by default and effectively deletes the folder if Nim is compiled with the -f or --forceBuild flag. This allows any project to start out with a clean cache dir on a forced build.

      +

      NOTE: avoid calling getProjectCacheDir() multiple times on the same name when forceClean = true else checked out source might get deleted at the wrong time during build.

      +
      E.g.
      +

      nimgit2 downloads libgit2 source so name = "libgit2"

      +

      nimarchive downloads libarchive, bzlib, liblzma and zlib so name = "nimarchive" / "libarchive" for libarchive, etc.

      +
      +
      + +
      proc extractZip(zipfile, outdir: string) {...}{.raises: [OSError, Exception, IOError, Defect,
      @@ -1050,12 +1075,13 @@ Hard reset the git repository at the specified directory
       
       
       
- -
proc findFile(file: string | Regex; dir: string; recurse = true; first = false): string
+ +
proc findFile(file: string; dir: string; recurse = true; first = false; regex = false): string {...}{.
+    raises: [ValueError], tags: [].}

Find the file in the specified directory

-

file can be a string or a regex object

+

file is a regular expression if regex is true

Turn off recursive search with recurse and stop on first match with first. Without it, the shortest match is returned.

@@ -1073,6 +1099,16 @@ Hard reset the git repository at the specified directory

flagBuild(base, flags) => " --disable-one --disable-two"

+
+ +
proc linkLibs(names: openArray[string]; staticLink = true): string {...}{.
+    raises: [ValueError], tags: [].}
+
+ +

Create linker flags for specified libraries

+

Prepends lib to the name so you only need ssl for libssl.

+ +
proc configure(path, check: string; flags = "") {...}{.
@@ -1145,13 +1181,16 @@ Set a cmake directive
 
 
 
-
-
proc make(path, check: string | Regex; flags = "")
+ +
proc make(path, check: string; flags = ""; regex = false) {...}{.
+    raises: [ValueError, OSError, Exception, IOError, Defect],
+    tags: [ExecIOEffect, ReadIOEffect, RootEffect].}

Run the make command to build all binaries in the specified path

check is a file that will be generated by the make command. This is required to prevent make from running on every build. It is relative to the path and should not be an absolute path.

flags are any flags that should be passed to the make command.

+

regex can be set to true if check is a regular expression.

If make.exe is missing and mingw32-make.exe is available, it will be copied over to make.exe in the same location.

@@ -1196,6 +1235,13 @@ Set a cmake directive Clear all defines set using setDefines(). +
+ +
macro isDefined(def: untyped): untyped
+
+ +Check if -d:xxx is set globally or via setDefines() +
macro getHeader(header: static[string]; giturl: static[string] = "";
@@ -1208,6 +1254,7 @@ Clear all defines set using setDe
 

This proc checks -d:xxx defines based on the header name (e.g. lzma from lzma.h), and accordingly employs different ways to obtain the source.

-d:xxxStd - search standard system paths. E.g. /usr/include and /usr/lib on Linux -d:xxxGit - clone source from a git repo specified in giturl -d:xxxDL - download source from dlurl and extract if required

This allows a single wrapper to be used in different ways depending on the user's needs. If no -d:xxx defines are specified, outdir will be searched for the header as is.

+

If multiple -d:xxx defines are specified, precedence is Std and then Git or DL. This allows using a system installed library if available before falling back to manual building.

-d:xxxSetVer=x.y.z can be used to specify which version to use. It is used as a tag name for Git whereas for DL, it replaces $1 in the URL defined.

All defines can also be set in code using setDefines().

The library is then configured (with cmake or autotools if possible) and built using make, unless using -d:xxxStd which presumes that the system package manager was used to install prebuilt headers and binaries.

@@ -1231,7 +1278,7 @@ Clear all defines set using setDe diff --git a/build.idx b/build.idx index 157a2da..326c09e 100644 --- a/build.idx +++ b/build.idx @@ -6,24 +6,27 @@ mkDir build.html#mkDir,string build: mkDir(dir: string) cpFile build.html#cpFile,string,string build: cpFile(source, dest: string; move = false) mvFile build.html#mvFile,string,string build: mvFile(source, dest: string) rmFile build.html#rmFile,string build: rmFile(source: string; dir = false) -rmDir build.html#rmDir,string build: rmDir(source: string) +rmDir build.html#rmDir,string build: rmDir(dir: string) +getProjectCacheDir build.html#getProjectCacheDir,string build: getProjectCacheDir(name: string; forceClean = true): string extractZip build.html#extractZip,string,string build: extractZip(zipfile, outdir: string) extractTar build.html#extractTar,string,string build: extractTar(tarfile, outdir: string) downloadUrl build.html#downloadUrl,string,string build: downloadUrl(url, outdir: string) gitReset build.html#gitReset,string build: gitReset(outdir: string) gitCheckout build.html#gitCheckout,string,string build: gitCheckout(file, outdir: string) gitPull build.html#gitPull,string,string,string,string build: gitPull(url: string; outdir = ""; plist = ""; checkout = "") -findFile build.html#findFile,,string build: findFile(file: string | Regex; dir: string; recurse = true; first = false): string +findFile build.html#findFile,string,string build: findFile(file: string; dir: string; recurse = true; first = false; regex = false): string flagBuild build.html#flagBuild,string,openArray[string] build: flagBuild(base: string; flags: openArray[string]): string +linkLibs build.html#linkLibs,openArray[string] build: linkLibs(names: openArray[string]; staticLink = true): string configure build.html#configure,string,string,string build: configure(path, check: string; flags = "") getCmakeIncludePath build.html#getCmakeIncludePath,openArray[string] build: getCmakeIncludePath(paths: openArray[string]): string setCmakeProperty build.html#setCmakeProperty,string,string,string,string build: setCmakeProperty(outdir, name, property, value: string) setCmakeLibName build.html#setCmakeLibName,string,string,string,string,string build: setCmakeLibName(outdir, name, prefix = ""; oname = ""; suffix = "") setCmakePositionIndependentCode build.html#setCmakePositionIndependentCode,string build: setCmakePositionIndependentCode(outdir: string) cmake build.html#cmake,string,string,string build: cmake(path, check, flags: string) -make build.html#make,,,string build: make(path, check: string | Regex; flags = "") +make build.html#make,string,string,string build: make(path, check: string; flags = ""; regex = false) getGccPaths build.html#getGccPaths,string build: getGccPaths(mode = "c"): seq[string] getGccLibPaths build.html#getGccLibPaths,string build: getGccLibPaths(mode = "c"): seq[string] setDefines build.html#setDefines.m build: setDefines(defs: static openArray[string]): untyped clearDefines build.html#clearDefines.m build: clearDefines(): untyped +isDefined build.html#isDefined.m,untyped build: isDefined(def: untyped): untyped getHeader build.html#getHeader.m,static[string],static[string],static[string],static[string],static[string],static[string],static[string],static[string] build: getHeader(header: static[string]; giturl: static[string] = "";\n dlurl: static[string] = ""; outdir: static[string] = "";\n conFlags: static[string] = ""; cmakeFlags: static[string] = "";\n makeFlags: static[string] = ""; altNames: static[string] = ""): untyped diff --git a/cimport.html b/cimport.html index b48d03c..916fde6 100644 --- a/cimport.html +++ b/cimport.html @@ -1090,7 +1090,7 @@ Add an include directory that is forwarded to the C/C++ preprocessor if called w @@ -1100,7 +1100,7 @@ Add an include directory that is forwarded to the C/C++ preprocessor if called w diff --git a/compat.html b/compat.html index b718728..2ef05e0 100644 --- a/compat.html +++ b/compat.html @@ -859,7 +859,7 @@ function main() { diff --git a/dochack.js b/dochack.js index 2ce5f19..23d9eb7 100644 --- a/dochack.js +++ b/dochack.js @@ -601,7 +601,6 @@ function nimMin(a_65203, b_65204) { return result_65205; } -var nimvm_49710 = false; var nim_program_result = 0; var global_raise_hook_59618 = [null]; var local_raise_hook_59623 = [null]; diff --git a/git.html b/git.html deleted file mode 100644 index e5f05dd..0000000 --- a/git.html +++ /dev/null @@ -1,1048 +0,0 @@ - - - - - - - - - - - - - - - - - -git - - - - - - - - -
-
-

git

-
-
- -
- Search: -
-
- Group by: - -
- - -
-
-
- -

- -
-

Procs

-
- -
proc execAction(cmd: string; nostderr = false): string {...}{.
-    raises: [OSError, Exception, ValueError, IOError, Defect],
-    tags: [ExecIOEffect, ReadIOEffect, RootEffect].}
-
- -

Execute an external command - supported at compile time

-

Checks if command exits successfully before returning. If not, an error is raised.

- - -
- -
proc findExe(exe: string): string {...}{.raises: [], tags: [].}
-
- -Find the specified executable using the which/where command - supported at compile time - -
- -
proc mkDir(dir: string) {...}{.raises: [OSError, Exception, ValueError, IOError, Defect], tags: [
-    ReadDirEffect, ExecIOEffect, ReadIOEffect, RootEffect].}
-
- -

Create a directory at cmopile time

-

The os module is not available at compile time so a few crucial helper functions are included with nimterop.

- - -
- -
proc cpFile(source, dest: string; move = false) {...}{.
-    raises: [OSError, Exception, ValueError, IOError, Defect],
-    tags: [ExecIOEffect, ReadIOEffect, RootEffect].}
-
- -Copy a file from source to destination at compile time - -
- -
proc mvFile(source, dest: string) {...}{.raises: [OSError, Exception, ValueError, IOError,
-                                        Defect],
-                                tags: [ExecIOEffect, ReadIOEffect, RootEffect].}
-
- -Move a file from source to destination at compile time - -
- -
proc rmFile(source: string; dir = false) {...}{.raises: [OSError, Exception, ValueError,
-    IOError, Defect], tags: [ExecIOEffect, ReadIOEffect, RootEffect].}
-
- -Remove a file or pattern at compile time - -
- -
proc rmDir(source: string) {...}{.raises: [OSError, Exception, ValueError, IOError, Defect],
-                          tags: [ExecIOEffect, ReadIOEffect, RootEffect].}
-
- -Remove a directory or pattern at compile time - -
- -
proc extractZip(zipfile, outdir: string) {...}{.raises: [OSError, Exception, ValueError,
-    IOError, Defect], tags: [ExecIOEffect, ReadIOEffect, RootEffect].}
-
- -Extract a zip file using powershell on Windows and unzip on other systems to the specified output directory - -
- -
proc downloadUrl(url, outdir: string) {...}{.raises: [OSError, Exception, ValueError,
-    IOError, Defect], tags: [ReadDirEffect, ExecIOEffect, ReadIOEffect, RootEffect].}
-
- -

Download a file using curl or wget (or powershell on Windows) to the specified directory

-

If a zip file, it is automatically extracted after download.

- - -
- -
proc gitReset(outdir: string) {...}{.raises: [ValueError, OSError, Exception, IOError, Defect], tags: [
-    ExecIOEffect, ReadIOEffect, RootEffect, TimeEffect].}
-
- -Hard reset the git repository at the specified directory - -
- -
proc gitCheckout(file, outdir: string) {...}{.raises: [ValueError, OSError, Exception,
-    IOError, Defect], tags: [ExecIOEffect, ReadIOEffect, RootEffect, TimeEffect].}
-
- -

Checkout the specified file in the git repository specified

-

This effectively resets all changes in the file and can be used to undo any changes that were made to source files to enable successful wrapping with cImport() or c2nImport().

- - -
- -
proc gitPull(url: string; outdir = ""; plist = ""; checkout = "") {...}{.
-    raises: [ValueError, OSError, Exception, IOError, Defect], tags: [ReadDirEffect,
-    ExecIOEffect, ReadIOEffect, RootEffect, TimeEffect, WriteIOEffect].}
-
- -

Pull the specified git repository to the output directory

-

plist is the list of specific files and directories or wildcards to sparsely checkout. Multiple values can be specified one entry per line. It is optional and if omitted, the entire repository will be checked out.

-

checkout is the git tag, branch or commit hash to checkout once the repository is downloaded. This allows for pinning to a specific version of the code.

- - -
- -
proc configure(path, check: string; flags = "") {...}{.
-    raises: [OSError, Exception, ValueError, IOError, Defect],
-    tags: [ReadDirEffect, ExecIOEffect, ReadIOEffect, RootEffect].}
-
- -

Run the GNU configure command to generate all Makefiles or other build scripts in the specified path

-

If a configure script is not present and an autogen.sh script is present, it will be run before attempting configure.

-

check is a file that will be generated by the configure command. This is required to prevent configure from running on every build. It is relative to the path and should not be an absolute path.

-

flags are any flags that should be passed to the configure command.

- - -
- -
proc cmake(path, check, flags: string) {...}{.raises: [OSError, Exception, ValueError,
-    IOError, Defect], tags: [ReadDirEffect, ExecIOEffect, ReadIOEffect, RootEffect].}
-
- -

Run the cmake command to generate all Makefiles or other build scripts in the specified path

-

path will be created since typically cmake is run in an empty directory.

-

check is a file that will be generated by the cmake command. This is required to prevent cmake from running on every build. It is relative to the path and should not be an absolute path.

-

flags are any flags that should be passed to the cmake command. Unlike configure, it is required since typically it will be the path to the repository, typically .. when path is a subdir.

- - -
- -
proc make(path, check: string; flags = "") {...}{.raises: [OSError, Exception, ValueError,
-    IOError, Defect], tags: [ReadDirEffect, ExecIOEffect, ReadIOEffect, RootEffect].}
-
- -

Run the make command to build all binaries in the specified path

-

check is a file that will be generated by the make command. This is required to prevent make from running on every build. It is relative to the path and should not be an absolute path.

-

flags are any flags that should be passed to the make command.

-

If make.exe is missing and mingw32-make.exe is available, it will be copied over to make.exe in the same location.

- - -
- -
- -
-
- -
- -
-
-
- - - diff --git a/git.idx b/git.idx deleted file mode 100644 index aea3d3b..0000000 --- a/git.idx +++ /dev/null @@ -1,15 +0,0 @@ -execAction git.html#execAction,string git: execAction(cmd: string; nostderr = false): string -findExe git.html#findExe,string git: findExe(exe: string): string -mkDir git.html#mkDir,string git: mkDir(dir: string) -cpFile git.html#cpFile,string,string git: cpFile(source, dest: string; move = false) -mvFile git.html#mvFile,string,string git: mvFile(source, dest: string) -rmFile git.html#rmFile,string git: rmFile(source: string; dir = false) -rmDir git.html#rmDir,string git: rmDir(source: string) -extractZip git.html#extractZip,string,string git: extractZip(zipfile, outdir: string) -downloadUrl git.html#downloadUrl,string,string git: downloadUrl(url, outdir: string) -gitReset git.html#gitReset,string git: gitReset(outdir: string) -gitCheckout git.html#gitCheckout,string,string git: gitCheckout(file, outdir: string) -gitPull git.html#gitPull,string,string,string,string git: gitPull(url: string; outdir = ""; plist = ""; checkout = "") -configure git.html#configure,string,string,string git: configure(path, check: string; flags = "") -cmake git.html#cmake,string,string,string git: cmake(path, check, flags: string) -make git.html#make,string,string,string git: make(path, check: string; flags = "") diff --git a/paths.html b/paths.html index d7a180d..e2e5787 100644 --- a/paths.html +++ b/paths.html @@ -823,19 +823,29 @@ function main() {
cPlugin:
enumOp:
  • execAction:
    extractTar:
    • extractZip:
      findExe:
      findFile:
      flagBuild:
      +
      getProjectCacheDir:
      gitCheckout:
      gitPull:
      gitReset:
      -
      incDir:
        +
        isDefined:
        • paths: incDir(): string
        • + data-doc-search-tag="build: isDefined(def: untyped): untyped" href="build.html#isDefined.m%2Cuntyped">build: isDefined(def: untyped): untyped +
        +
        linkLibs:
        make:
        mkDir:
        mvFile:
        myNormalizedPath:
        -
        nimteropBuildDir:
        nimteropRoot:
        rmDir:
        rmFile:
        sanitizePath:
        +
        time64_t:
        time_t:
        • types: time_t
        • @@ -1079,7 +1061,7 @@ function main() { diff --git a/types.html b/types.html index ec4562d..d01868d 100644 --- a/types.html +++ b/types.html @@ -828,6 +828,8 @@ function main() {
          • time_t
          • +
          • time64_t
          • wchar_t
          • + +
            time64_t = time_t_temp.Time
            +
            + + +
            wchar_t {...}{.importc, header: "<cwchar>".} = object
            @@ -915,7 +924,7 @@ function main() { diff --git a/types.idx b/types.idx index d895171..5f5fb02 100644 --- a/types.idx +++ b/types.idx @@ -1,4 +1,5 @@ time_t types.html#time_t types: time_t +time64_t types.html#time64_t types: time64_t wchar_t types.html#wchar_t types: wchar_t ptrdiff_t types.html#ptrdiff_t types: ptrdiff_t va_list types.html#va_list types: va_list From e293172cf29d45f6c85e982b5ba9df57cb208bbc Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 14 Oct 2019 22:55:01 -0500 Subject: [PATCH 266/593] Fix execAction, enum expressions, union cleanup, no forceClean --- nimterop/build.nim | 3 ++- nimterop/getters.nim | 54 +++++++++++++++++++++++++++++++++++++++----- nimterop/grammar.nim | 16 +++++++------ nimterop/paths.nim | 2 +- tests/include/test.h | 2 +- 5 files changed, 61 insertions(+), 16 deletions(-) diff --git a/nimterop/build.nim b/nimterop/build.nim index 81e7445..f3f1b48 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -45,7 +45,7 @@ proc execAction*(cmd: string, retry = 0, nostderr = false): string = sleep(500) result = execAction(cmd, retry = retry - 1) else: - doAssert true, "Command failed: " & $(ret, nostderr) & "\ncmd: " & ccmd & "\nresult:\n" & result + doAssert false, "Command failed: " & $(ret, nostderr) & "\ncmd: " & ccmd & "\nresult:\n" & result proc findExe*(exe: string): string = ## Find the specified executable using the `which`/`where` command - supported @@ -148,6 +148,7 @@ proc getProjectCacheDir*(name: string, forceClean = true): string = result = getNimteropCacheDir() / name if forceClean and compileOption("forceBuild"): + echo "# Removing " & result rmDir(result) proc extractZip*(zipfile, outdir: string) = diff --git a/nimterop/getters.nim b/nimterop/getters.nim index d08b318..62dc132 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -332,12 +332,54 @@ proc getPxName*(node: TSNode, offset: int): string = if count == offset and not np.tsNodeIsNull(): return $np.tsNodeType() -proc getNimExpression*(expr: string): string = - return expr.multiReplace([ - (" ", ""), - ("<<", " shl "), (">>", " shr "), - ("^", " xor "), ("&", " and "), ("|", " or "), - ("~", " not "), ("\n", " "), ("\r", "") +proc getNimExpression*(nimState: NimState, expr: string): string = + var + clean = expr.multiReplace([("\n", " "), ("\r", "")]) + ident = "" + gen = "" + hex = false + + for i in 0 .. clean.len: + if i != clean.len: + if clean[i] == '_' and ident.len == 0: + gen = $clean[i] + elif clean[i] in IdentChars: + if clean[i] in Digits and ident.len == 0: + gen = $clean[i] + elif clean[i] in HexDigits and hex == true: + gen = $clean[i] + elif i > 0 and i < clean.len-1 and clean[i] in ['x', 'X'] and + clean[i-1] == '0' and clean[i+1] in HexDigits: + gen = $clean[i] + hex = true + else: + ident &= clean[i] + hex = false + else: + gen = (block: + if (i == 0 or clean[i-1] != '\'') or + (i == clean.len - 1 or clean[i+1] != '\''): + case clean[i] + of '^': " xor " + of '&': " and " + of '|': " or " + of '~': " not " + else: $clean[i] + else: + $clean[i] + ) + hex = false + + if i == clean.len or gen.len != 0: + if ident.len != 0: + ident = nimState.getIdentifier(ident, nskConst) + result &= ident + ident = "" + result &= gen + gen = "" + + result = result.multiReplace([ + ("<<", " shl "), (">>", " shr ") ]) proc getSplitComma*(joined: seq[string]): seq[string] = diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index 57cbbdd..8ddd8c1 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -238,7 +238,7 @@ proc initGrammar(): Grammar = prefix = "struct " of "union_specifier": prefix = "union " - union = " {.union.}" + union = ", union" of "type_definition": if node.getTSNodeNamedChildCountSansComments() != 0: for i in 0 .. node.tsNodeNamedChildCount()-1: @@ -252,23 +252,25 @@ proc initGrammar(): Grammar = of "union_specifier": if fstart == 1: prefix = "union " - union = " {.union.}" + union = ", union" break if nname.nBl and nimState.addNewIdentifer(nname): if nimState.data.len == 1: - nimState.typeStr &= &"{nimState.getComments()}\n {nname}* {{.bycopy.}} = object{union}" + nimState.typeStr &= &"{nimState.getComments()}\n {nname}* {{.bycopy{union}.}} = object" else: var pragmas: seq[string] = @[] if nimState.gState.dynlib.len == 0: pragmas.add nimState.getImportC(prefix & name, nname) pragmas.add "bycopy" + if union.len != 0: + pragmas.add "union" let pragma = nimState.getPragma(pragmas) - nimState.typeStr &= &"{nimState.getComments()}\n {nname}*{pragma} = object{union}" + nimState.typeStr &= &"{nimState.getComments()}\n {nname}*{pragma} = object" var i = fstart @@ -283,7 +285,7 @@ proc initGrammar(): Grammar = continue if nimState.data[i].name notin ["field_identifier", "pointer_declarator", "array_pointer_declarator"]: - ftyp = nimState.data[i].val.getType() + ftyp = nimState.getIdentifier(nimState.data[i].val, nskType, nname).getType() i += 1 while i < nimState.data.len-fend and "pointer" in nimState.data[i].name: @@ -299,7 +301,7 @@ proc initGrammar(): Grammar = if i+1 < nimState.data.len-fend and nimState.data[i+1].name in gEnumVals: let - flen = nimState.data[i+1].val.getNimExpression() + flen = nimState.getNimExpression(nimState.data[i+1].val) nimState.typeStr &= &"{nimState.getComments()}\n {fname}*: {aptr}array[{flen}, {getPtrType(fptr&ftyp)}]" i += 2 elif i+1 < nimState.data.len-fend and nimState.data[i+1].name == "bitfield_clause": @@ -461,7 +463,7 @@ proc initGrammar(): Grammar = if i+1 < nimState.data.len-fend and nimState.data[i+1].name in gEnumVals: if fname.nBl and nimState.addNewIdentifer(fname): - nimState.constStr &= &"{nimState.getComments()}\n {fname}* = ({nimState.data[i+1].val.getNimExpression()}).{nname}" + nimState.constStr &= &"{nimState.getComments()}\n {fname}* = ({nimState.getNimExpression(nimState.data[i+1].val)}).{nname}" try: count = nimState.data[i+1].val.parseInt() + 1 except: diff --git a/nimterop/paths.nim b/nimterop/paths.nim index d55276e..0ae461f 100644 --- a/nimterop/paths.nim +++ b/nimterop/paths.nim @@ -3,7 +3,7 @@ import os import "."/build const - cacheDir* = getProjectCacheDir("nimterop") + cacheDir* = getProjectCacheDir("nimterop", forceClean = false) proc nimteropRoot*(): string = currentSourcePath.parentDir.parentDir diff --git a/tests/include/test.h b/tests/include/test.h index cb4dd59..df48cd0 100644 --- a/tests/include/test.h +++ b/tests/include/test.h @@ -87,7 +87,7 @@ typedef struct { int field2[TEST_INT]; enum ENUM field3[TEST_INT]; int *field4[TEST_INT]; - ENUM4 *field5[TEST_INT+TEST_INT]; + ENUM4 *field5[TEST_INT + TEST_INT]; int field6 : 1; } STRUCT4; From f4d863d3ddb8ac8b6295476d33351e8db0e4d90a Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 15 Oct 2019 21:37:45 -0500 Subject: [PATCH 267/593] rm only if exists --- nimterop/build.nim | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/nimterop/build.nim b/nimterop/build.nim index f3f1b48..49bc15d 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -107,8 +107,14 @@ proc rmFile*(source: string, dir = false) = "del /s/q/f" else: "rm -rf" + exists = + if dir: + dirExists(source) + else: + fileExists(source) - discard execAction(&"{cmd} {source.sanitizePath}", retry = 2) + if exists: + discard execAction(&"{cmd} {source.sanitizePath}", retry = 2) proc rmDir*(dir: string) = ## Remove a directory or pattern at compile time From c40b25d2a29c467121b515739b5f67f9c7774927 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 15 Oct 2019 23:04:23 -0500 Subject: [PATCH 268/593] Fix altNames behavior --- nimterop/build.nim | 13 ++++++++----- tests/zlib.nim | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/nimterop/build.nim b/nimterop/build.nim index 49bc15d..72f80b9 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -855,8 +855,13 @@ macro getHeader*(header: static[string], giturl: static[string] = "", dlurl: sta ## `cmake` and `make` in case additional configuration is required as part of the build process. ## ## `altNames` is a list of alternate names for the library - e.g. zlib uses `zlib.h` for the header but - ## the typical lib name is `libz.so` and not `libzlib.so`. In this case, `altNames = "z"`. Comma - ## separate for multiple alternate names. + ## the typical lib name is `libz.so` and not `libzlib.so`. However, it is libzlib.dll on Windows if built + ## with cmake. In this case, `altNames = "z,zlib"`. Comma separate for multiple alternate names without + ## spaces. + ## + ## The original header name is not included by default if `altNames` is set since it could cause the + ## wrong lib to be selected. E.g. `SDL2/SDL.h` could pick `libSDL.so` even if `altNames = "SDL2"`. + ## Explicitly include it in `altNames` like the `zlib` example when required. ## ## `xxxPreBuild` is a hook that is called after the source code is pulled from Git or downloaded but ## before the library is built. This might be needed if some initial prep needs to be done before @@ -902,9 +907,7 @@ macro getHeader*(header: static[string], giturl: static[string] = "", dlurl: sta "" if altNames.len != 0: - let - names = "(" & name & "|" & altNames.replace(",", "|") & ")" - lre = lre % names + lre = lre % ("(" & altNames.replace(",", "|") & ")") else: lre = lre % name diff --git a/tests/zlib.nim b/tests/zlib.nim index 572580c..036b50c 100644 --- a/tests/zlib.nim +++ b/tests/zlib.nim @@ -29,7 +29,7 @@ getHeader( giturl = "https://github.com/madler/zlib", dlurl = "http://zlib.net/zlib-$1.tar.gz", outdir = baseDir, - altNames = "z" + altNames = "z,zlib" ) cPlugin: From 531843a82a5efe59c15a675d9c3c8c5f28d4cab0 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 16 Oct 2019 14:21:53 -0500 Subject: [PATCH 269/593] Improve static inline handling --- nimterop/getters.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 62dc132..660f69f 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -191,7 +191,7 @@ proc removeStatic(content: string): string = ## Replace static function bodies with a semicolon and commented ## out body return content.replace( - re"(?ms)static inline(.*?\))(\s*\{(\s*?.*?$)*?[\n\r]\})", + re"(?msU)static inline ([^)]+\))([^}]+\})", proc (m: RegexMatch, s: string): string = let funcDecl = s[m.group(0)[0]] let body = s[m.group(1)[0]].strip() From c6b70d9c04264c65c9b5b4683d6f72d75cb4efc5 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 16 Oct 2019 15:06:08 -0500 Subject: [PATCH 270/593] Update documentation --- all.html | 2 +- build.html | 17 +- cimport.html | 2 +- compat.html | 2 +- dochack.js | 1750 ++++++++++++++++++++++++------------------------- paths.html | 2 +- plugin.html | 2 +- theindex.html | 2 +- types.html | 2 +- 9 files changed, 891 insertions(+), 890 deletions(-) diff --git a/all.html b/all.html index 618ff78..ba03064 100644 --- a/all.html +++ b/all.html @@ -850,7 +850,7 @@ function main() { diff --git a/build.html b/build.html index f1880f7..e623caa 100644 --- a/build.html +++ b/build.html @@ -986,15 +986,15 @@ Move a file from source
            proc rmFile(source: string; dir = false) {...}{.raises: [OSError, Exception, IOError, Defect,
            -    ValueError], tags: [ExecIOEffect, ReadIOEffect, RootEffect].}
            + ValueError], tags: [ReadDirEffect, ExecIOEffect, ReadIOEffect, RootEffect].}
            Remove a file or pattern at compile time
            -
            proc rmDir(dir: string) {...}{.raises: [OSError, Exception, IOError, Defect, ValueError],
            -                       tags: [ExecIOEffect, ReadIOEffect, RootEffect].}
            +
            proc rmDir(dir: string) {...}{.raises: [OSError, Exception, IOError, Defect, ValueError], tags: [
            +    ReadDirEffect, ExecIOEffect, ReadIOEffect, RootEffect].}
            Remove a directory or pattern at compile time @@ -1002,8 +1002,8 @@ Remove a directory or pattern at compile time
            proc getProjectCacheDir(name: string; forceClean = true): string {...}{.
            -    raises: [OSError, Exception, IOError, Defect, ValueError],
            -    tags: [ReadEnvEffect, ReadIOEffect, ExecIOEffect, RootEffect].}
            + raises: [OSError, Exception, IOError, Defect, ValueError], tags: [ReadEnvEffect, + ReadIOEffect, ReadDirEffect, ExecIOEffect, RootEffect].}

            Get a cache directory where all nimterop artifacts can be stored

            @@ -1029,7 +1029,7 @@ Extract a zip file using powershe
            proc extractTar(tarfile, outdir: string) {...}{.raises: [ValueError, OSError, Exception,
            -    IOError, Defect], tags: [ExecIOEffect, ReadIOEffect, RootEffect].}
            + IOError, Defect], tags: [ExecIOEffect, ReadIOEffect, RootEffect, ReadDirEffect].}
            Extract a tar file using tar, 7z or 7za to the specified output directory @@ -1261,7 +1261,8 @@ Check if -d:xxx is se

            The header path is stored in const xxxPath and can be used in a cImport() call in the calling wrapper. The dynamic library path is stored in const xxxLPath and can be used for the dynlib parameter (within quotes) or with {.passL.}.

            -d:xxxStatic can be specified to statically link with the library instead. This will automatically add a {.passL.} call to the static library for convenience.

            conFlags, cmakeFlags and makeFlags allow sending custom parameters to configure, cmake and make in case additional configuration is required as part of the build process.

            -

            altNames is a list of alternate names for the library - e.g. zlib uses zlib.h for the header but the typical lib name is libz.so and not libzlib.so. In this case, altNames = "z". Comma separate for multiple alternate names.

            +

            altNames is a list of alternate names for the library - e.g. zlib uses zlib.h for the header but the typical lib name is libz.so and not libzlib.so. However, it is libzlib.dll on Windows if built with cmake. In this case, altNames = "z,zlib". Comma separate for multiple alternate names without spaces.

            +

            The original header name is not included by default if altNames is set since it could cause the wrong lib to be selected. E.g. SDL2/SDL.h could pick libSDL.so even if altNames = "SDL2". Explicitly include it in altNames like the zlib example when required.

            xxxPreBuild is a hook that is called after the source code is pulled from Git or downloaded but before the library is built. This might be needed if some initial prep needs to be done before compilation. A few values are provided to the hook to help provide context:

            outdir is the same outdir passed in and header is the discovered header path in the downloaded source code.

            Simply define proc xxxPreBuild(outdir, header: string) in the wrapper and it will get called prior to the build process.

            @@ -1278,7 +1279,7 @@ Check if -d:xxx is se diff --git a/cimport.html b/cimport.html index 916fde6..6957a44 100644 --- a/cimport.html +++ b/cimport.html @@ -1100,7 +1100,7 @@ Add an include directory that is forwarded to the C/C++ preprocessor if called w diff --git a/compat.html b/compat.html index 2ef05e0..1da36d4 100644 --- a/compat.html +++ b/compat.html @@ -859,7 +859,7 @@ function main() { diff --git a/dochack.js b/dochack.js index 23d9eb7..d068800 100644 --- a/dochack.js +++ b/dochack.js @@ -12,248 +12,248 @@ if (typeof Uint16Array === 'undefined') Uint16Array = Array; if (typeof Uint32Array === 'undefined') Uint32Array = Array; if (typeof Float32Array === 'undefined') Float32Array = Array; if (typeof Float64Array === 'undefined') Float64Array = Array; -var NTI43032 = {size: 0,kind: 1,base: null,node: null,finalizer: null}; -var NTI201074 = {size: 0, kind: 18, base: null, node: null, finalizer: null}; -var NTI46462 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI203578 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; -var NTI83448 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI83444 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI83440 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI83436 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI83432 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI83428 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI83424 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI83420 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI83416 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI83412 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI83408 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI83404 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI83400 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI83396 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI83392 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI83388 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI83384 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI83380 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI83376 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI83372 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI83205 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI83283 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI83281 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; -var NTI83227 = {size: 0, kind: 14, base: null, node: null, finalizer: null}; -var NTI83565 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; -var NTI83563 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; -var NTI83561 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; -var NTI83231 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI83229 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; -var NTI85305 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; -var NTI46450 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI46458 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI43006 = {size: 0,kind: 31,base: null,node: null,finalizer: null}; -var NTI62156 = {size: 0, kind: 18, base: null, node: null, finalizer: null}; -var NTI46408 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI46514 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; -var NTI43016 = {size: 0,kind: 40,base: null,node: null,finalizer: null}; -var NTI43040 = {size: 0,kind: 28,base: null,node: null,finalizer: null}; -var NTI43042 = {size: 0,kind: 29,base: null,node: null,finalizer: null}; -var NTI46508 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; -var NTI46426 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI46428 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI46442 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI46446 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NNI46446 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; -NTI46446.node = NNI46446; -var NNI46442 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; -NTI46442.node = NNI46442; -var NNI46428 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; -NTI46428.node = NNI46428; -NTI46508.base = NTI46426; -NTI46514.base = NTI46426; -var NNI46426 = {kind: 2, len: 6, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "parent", len: 0, typ: NTI46508, name: "parent", sons: null}, -{kind: 1, offset: "name", len: 0, typ: NTI43042, name: "name", sons: null}, -{kind: 1, offset: "message", len: 0, typ: NTI43040, name: "msg", sons: null}, -{kind: 1, offset: "trace", len: 0, typ: NTI43040, name: "trace", sons: null}, -{kind: 1, offset: "raiseId", len: 0, typ: NTI43016, name: "raiseId", sons: null}, -{kind: 1, offset: "up", len: 0, typ: NTI46514, name: "up", sons: null}]}; -NTI46426.node = NNI46426; -var NNI46408 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; -NTI46408.node = NNI46408; -NTI46426.base = NTI46408; -NTI46428.base = NTI46426; -NTI46442.base = NTI46428; -NTI46446.base = NTI46442; -var NNI62156 = {kind: 2, len: 2, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "Field0", len: 0, typ: NTI43042, name: "Field0", sons: null}, -{kind: 1, offset: "Field1", len: 0, typ: NTI43006, name: "Field1", sons: null}]}; -NTI62156.node = NNI62156; -var NNI46458 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; -NTI46458.node = NNI46458; -NTI46458.base = NTI46428; -var NNI46450 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; -NTI46450.node = NNI46450; -NTI46450.base = NTI46428; -NTI83561.base = NTI83229; -NTI83563.base = NTI83229; -NTI83565.base = NTI83229; -var NNI83227 = {kind: 2, offset: 0, typ: null, name: null, len: 12, sons: {"1": {kind: 1, offset: 1, typ: NTI83227, name: "ElementNode", len: 0, sons: null}, -"2": {kind: 1, offset: 2, typ: NTI83227, name: "AttributeNode", len: 0, sons: null}, -"3": {kind: 1, offset: 3, typ: NTI83227, name: "TextNode", len: 0, sons: null}, -"4": {kind: 1, offset: 4, typ: NTI83227, name: "CDATANode", len: 0, sons: null}, -"5": {kind: 1, offset: 5, typ: NTI83227, name: "EntityRefNode", len: 0, sons: null}, -"6": {kind: 1, offset: 6, typ: NTI83227, name: "EntityNode", len: 0, sons: null}, -"7": {kind: 1, offset: 7, typ: NTI83227, name: "ProcessingInstructionNode", len: 0, sons: null}, -"8": {kind: 1, offset: 8, typ: NTI83227, name: "CommentNode", len: 0, sons: null}, -"9": {kind: 1, offset: 9, typ: NTI83227, name: "DocumentNode", len: 0, sons: null}, -"10": {kind: 1, offset: 10, typ: NTI83227, name: "DocumentTypeNode", len: 0, sons: null}, -"11": {kind: 1, offset: 11, typ: NTI83227, name: "DocumentFragmentNode", len: 0, sons: null}, -"12": {kind: 1, offset: 12, typ: NTI83227, name: "NotationNode", len: 0, sons: null}}}; -NTI83227.node = NNI83227; -var NNI83283 = {kind: 2, len: 92, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "background", len: 0, typ: NTI43042, name: "background", sons: null}, -{kind: 1, offset: "backgroundAttachment", len: 0, typ: NTI43042, name: "backgroundAttachment", sons: null}, -{kind: 1, offset: "backgroundColor", len: 0, typ: NTI43042, name: "backgroundColor", sons: null}, -{kind: 1, offset: "backgroundImage", len: 0, typ: NTI43042, name: "backgroundImage", sons: null}, -{kind: 1, offset: "backgroundPosition", len: 0, typ: NTI43042, name: "backgroundPosition", sons: null}, -{kind: 1, offset: "backgroundRepeat", len: 0, typ: NTI43042, name: "backgroundRepeat", sons: null}, -{kind: 1, offset: "border", len: 0, typ: NTI43042, name: "border", sons: null}, -{kind: 1, offset: "borderBottom", len: 0, typ: NTI43042, name: "borderBottom", sons: null}, -{kind: 1, offset: "borderBottomColor", len: 0, typ: NTI43042, name: "borderBottomColor", sons: null}, -{kind: 1, offset: "borderBottomStyle", len: 0, typ: NTI43042, name: "borderBottomStyle", sons: null}, -{kind: 1, offset: "borderBottomWidth", len: 0, typ: NTI43042, name: "borderBottomWidth", sons: null}, -{kind: 1, offset: "borderColor", len: 0, typ: NTI43042, name: "borderColor", sons: null}, -{kind: 1, offset: "borderLeft", len: 0, typ: NTI43042, name: "borderLeft", sons: null}, -{kind: 1, offset: "borderLeftColor", len: 0, typ: NTI43042, name: "borderLeftColor", sons: null}, -{kind: 1, offset: "borderLeftStyle", len: 0, typ: NTI43042, name: "borderLeftStyle", sons: null}, -{kind: 1, offset: "borderLeftWidth", len: 0, typ: NTI43042, name: "borderLeftWidth", sons: null}, -{kind: 1, offset: "borderRight", len: 0, typ: NTI43042, name: "borderRight", sons: null}, -{kind: 1, offset: "borderRightColor", len: 0, typ: NTI43042, name: "borderRightColor", sons: null}, -{kind: 1, offset: "borderRightStyle", len: 0, typ: NTI43042, name: "borderRightStyle", sons: null}, -{kind: 1, offset: "borderRightWidth", len: 0, typ: NTI43042, name: "borderRightWidth", sons: null}, -{kind: 1, offset: "borderStyle", len: 0, typ: NTI43042, name: "borderStyle", sons: null}, -{kind: 1, offset: "borderTop", len: 0, typ: NTI43042, name: "borderTop", sons: null}, -{kind: 1, offset: "borderTopColor", len: 0, typ: NTI43042, name: "borderTopColor", sons: null}, -{kind: 1, offset: "borderTopStyle", len: 0, typ: NTI43042, name: "borderTopStyle", sons: null}, -{kind: 1, offset: "borderTopWidth", len: 0, typ: NTI43042, name: "borderTopWidth", sons: null}, -{kind: 1, offset: "borderWidth", len: 0, typ: NTI43042, name: "borderWidth", sons: null}, -{kind: 1, offset: "bottom", len: 0, typ: NTI43042, name: "bottom", sons: null}, -{kind: 1, offset: "captionSide", len: 0, typ: NTI43042, name: "captionSide", sons: null}, -{kind: 1, offset: "clear", len: 0, typ: NTI43042, name: "clear", sons: null}, -{kind: 1, offset: "clip", len: 0, typ: NTI43042, name: "clip", sons: null}, -{kind: 1, offset: "color", len: 0, typ: NTI43042, name: "color", sons: null}, -{kind: 1, offset: "cursor", len: 0, typ: NTI43042, name: "cursor", sons: null}, -{kind: 1, offset: "direction", len: 0, typ: NTI43042, name: "direction", sons: null}, -{kind: 1, offset: "display", len: 0, typ: NTI43042, name: "display", sons: null}, -{kind: 1, offset: "emptyCells", len: 0, typ: NTI43042, name: "emptyCells", sons: null}, -{kind: 1, offset: "cssFloat", len: 0, typ: NTI43042, name: "cssFloat", sons: null}, -{kind: 1, offset: "font", len: 0, typ: NTI43042, name: "font", sons: null}, -{kind: 1, offset: "fontFamily", len: 0, typ: NTI43042, name: "fontFamily", sons: null}, -{kind: 1, offset: "fontSize", len: 0, typ: NTI43042, name: "fontSize", sons: null}, -{kind: 1, offset: "fontStretch", len: 0, typ: NTI43042, name: "fontStretch", sons: null}, -{kind: 1, offset: "fontStyle", len: 0, typ: NTI43042, name: "fontStyle", sons: null}, -{kind: 1, offset: "fontVariant", len: 0, typ: NTI43042, name: "fontVariant", sons: null}, -{kind: 1, offset: "fontWeight", len: 0, typ: NTI43042, name: "fontWeight", sons: null}, -{kind: 1, offset: "height", len: 0, typ: NTI43042, name: "height", sons: null}, -{kind: 1, offset: "left", len: 0, typ: NTI43042, name: "left", sons: null}, -{kind: 1, offset: "letterSpacing", len: 0, typ: NTI43042, name: "letterSpacing", sons: null}, -{kind: 1, offset: "lineHeight", len: 0, typ: NTI43042, name: "lineHeight", sons: null}, -{kind: 1, offset: "listStyle", len: 0, typ: NTI43042, name: "listStyle", sons: null}, -{kind: 1, offset: "listStyleImage", len: 0, typ: NTI43042, name: "listStyleImage", sons: null}, -{kind: 1, offset: "listStylePosition", len: 0, typ: NTI43042, name: "listStylePosition", sons: null}, -{kind: 1, offset: "listStyleType", len: 0, typ: NTI43042, name: "listStyleType", sons: null}, -{kind: 1, offset: "margin", len: 0, typ: NTI43042, name: "margin", sons: null}, -{kind: 1, offset: "marginBottom", len: 0, typ: NTI43042, name: "marginBottom", sons: null}, -{kind: 1, offset: "marginLeft", len: 0, typ: NTI43042, name: "marginLeft", sons: null}, -{kind: 1, offset: "marginRight", len: 0, typ: NTI43042, name: "marginRight", sons: null}, -{kind: 1, offset: "marginTop", len: 0, typ: NTI43042, name: "marginTop", sons: null}, -{kind: 1, offset: "maxHeight", len: 0, typ: NTI43042, name: "maxHeight", sons: null}, -{kind: 1, offset: "maxWidth", len: 0, typ: NTI43042, name: "maxWidth", sons: null}, -{kind: 1, offset: "minHeight", len: 0, typ: NTI43042, name: "minHeight", sons: null}, -{kind: 1, offset: "minWidth", len: 0, typ: NTI43042, name: "minWidth", sons: null}, -{kind: 1, offset: "opacity", len: 0, typ: NTI43042, name: "opacity", sons: null}, -{kind: 1, offset: "overflow", len: 0, typ: NTI43042, name: "overflow", sons: null}, -{kind: 1, offset: "padding", len: 0, typ: NTI43042, name: "padding", sons: null}, -{kind: 1, offset: "paddingBottom", len: 0, typ: NTI43042, name: "paddingBottom", sons: null}, -{kind: 1, offset: "paddingLeft", len: 0, typ: NTI43042, name: "paddingLeft", sons: null}, -{kind: 1, offset: "paddingRight", len: 0, typ: NTI43042, name: "paddingRight", sons: null}, -{kind: 1, offset: "paddingTop", len: 0, typ: NTI43042, name: "paddingTop", sons: null}, -{kind: 1, offset: "pageBreakAfter", len: 0, typ: NTI43042, name: "pageBreakAfter", sons: null}, -{kind: 1, offset: "pageBreakBefore", len: 0, typ: NTI43042, name: "pageBreakBefore", sons: null}, -{kind: 1, offset: "pointerEvents", len: 0, typ: NTI43042, name: "pointerEvents", sons: null}, -{kind: 1, offset: "position", len: 0, typ: NTI43042, name: "position", sons: null}, -{kind: 1, offset: "right", len: 0, typ: NTI43042, name: "right", sons: null}, -{kind: 1, offset: "scrollbar3dLightColor", len: 0, typ: NTI43042, name: "scrollbar3dLightColor", sons: null}, -{kind: 1, offset: "scrollbarArrowColor", len: 0, typ: NTI43042, name: "scrollbarArrowColor", sons: null}, -{kind: 1, offset: "scrollbarBaseColor", len: 0, typ: NTI43042, name: "scrollbarBaseColor", sons: null}, -{kind: 1, offset: "scrollbarDarkshadowColor", len: 0, typ: NTI43042, name: "scrollbarDarkshadowColor", sons: null}, -{kind: 1, offset: "scrollbarFaceColor", len: 0, typ: NTI43042, name: "scrollbarFaceColor", sons: null}, -{kind: 1, offset: "scrollbarHighlightColor", len: 0, typ: NTI43042, name: "scrollbarHighlightColor", sons: null}, -{kind: 1, offset: "scrollbarShadowColor", len: 0, typ: NTI43042, name: "scrollbarShadowColor", sons: null}, -{kind: 1, offset: "scrollbarTrackColor", len: 0, typ: NTI43042, name: "scrollbarTrackColor", sons: null}, -{kind: 1, offset: "tableLayout", len: 0, typ: NTI43042, name: "tableLayout", sons: null}, -{kind: 1, offset: "textAlign", len: 0, typ: NTI43042, name: "textAlign", sons: null}, -{kind: 1, offset: "textDecoration", len: 0, typ: NTI43042, name: "textDecoration", sons: null}, -{kind: 1, offset: "textIndent", len: 0, typ: NTI43042, name: "textIndent", sons: null}, -{kind: 1, offset: "textTransform", len: 0, typ: NTI43042, name: "textTransform", sons: null}, -{kind: 1, offset: "transform", len: 0, typ: NTI43042, name: "transform", sons: null}, -{kind: 1, offset: "top", len: 0, typ: NTI43042, name: "top", sons: null}, -{kind: 1, offset: "verticalAlign", len: 0, typ: NTI43042, name: "verticalAlign", sons: null}, -{kind: 1, offset: "visibility", len: 0, typ: NTI43042, name: "visibility", sons: null}, -{kind: 1, offset: "width", len: 0, typ: NTI43042, name: "width", sons: null}, -{kind: 1, offset: "wordSpacing", len: 0, typ: NTI43042, name: "wordSpacing", sons: null}, -{kind: 1, offset: "zIndex", len: 0, typ: NTI43006, name: "zIndex", sons: null}]}; -NTI83283.node = NNI83283; -NTI83283.base = NTI46408; -NTI83281.base = NTI83283; -var NNI83231 = {kind: 2, len: 14, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "attributes", len: 0, typ: NTI83561, name: "attributes", sons: null}, -{kind: 1, offset: "childNodes", len: 0, typ: NTI83563, name: "childNodes", sons: null}, -{kind: 1, offset: "children", len: 0, typ: NTI83565, name: "children", sons: null}, -{kind: 1, offset: "data", len: 0, typ: NTI43042, name: "data", sons: null}, -{kind: 1, offset: "firstChild", len: 0, typ: NTI83229, name: "firstChild", sons: null}, -{kind: 1, offset: "lastChild", len: 0, typ: NTI83229, name: "lastChild", sons: null}, -{kind: 1, offset: "nextSibling", len: 0, typ: NTI83229, name: "nextSibling", sons: null}, -{kind: 1, offset: "nodeName", len: 0, typ: NTI43042, name: "nodeName", sons: null}, -{kind: 1, offset: "nodeType", len: 0, typ: NTI83227, name: "nodeType", sons: null}, -{kind: 1, offset: "nodeValue", len: 0, typ: NTI43042, name: "nodeValue", sons: null}, -{kind: 1, offset: "parentNode", len: 0, typ: NTI83229, name: "parentNode", sons: null}, -{kind: 1, offset: "previousSibling", len: 0, typ: NTI83229, name: "previousSibling", sons: null}, -{kind: 1, offset: "innerHTML", len: 0, typ: NTI43042, name: "innerHTML", sons: null}, -{kind: 1, offset: "style", len: 0, typ: NTI83281, name: "style", sons: null}]}; -NTI83231.node = NNI83231; -var NNI83205 = {kind: 2, len: 20, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "onabort", len: 0, typ: NTI83372, name: "onabort", sons: null}, -{kind: 1, offset: "onblur", len: 0, typ: NTI83376, name: "onblur", sons: null}, -{kind: 1, offset: "onchange", len: 0, typ: NTI83380, name: "onchange", sons: null}, -{kind: 1, offset: "onclick", len: 0, typ: NTI83384, name: "onclick", sons: null}, -{kind: 1, offset: "ondblclick", len: 0, typ: NTI83388, name: "ondblclick", sons: null}, -{kind: 1, offset: "onerror", len: 0, typ: NTI83392, name: "onerror", sons: null}, -{kind: 1, offset: "onfocus", len: 0, typ: NTI83396, name: "onfocus", sons: null}, -{kind: 1, offset: "onkeydown", len: 0, typ: NTI83400, name: "onkeydown", sons: null}, -{kind: 1, offset: "onkeypress", len: 0, typ: NTI83404, name: "onkeypress", sons: null}, -{kind: 1, offset: "onkeyup", len: 0, typ: NTI83408, name: "onkeyup", sons: null}, -{kind: 1, offset: "onload", len: 0, typ: NTI83412, name: "onload", sons: null}, -{kind: 1, offset: "onmousedown", len: 0, typ: NTI83416, name: "onmousedown", sons: null}, -{kind: 1, offset: "onmousemove", len: 0, typ: NTI83420, name: "onmousemove", sons: null}, -{kind: 1, offset: "onmouseout", len: 0, typ: NTI83424, name: "onmouseout", sons: null}, -{kind: 1, offset: "onmouseover", len: 0, typ: NTI83428, name: "onmouseover", sons: null}, -{kind: 1, offset: "onmouseup", len: 0, typ: NTI83432, name: "onmouseup", sons: null}, -{kind: 1, offset: "onreset", len: 0, typ: NTI83436, name: "onreset", sons: null}, -{kind: 1, offset: "onselect", len: 0, typ: NTI83440, name: "onselect", sons: null}, -{kind: 1, offset: "onsubmit", len: 0, typ: NTI83444, name: "onsubmit", sons: null}, -{kind: 1, offset: "onunload", len: 0, typ: NTI83448, name: "onunload", sons: null}]}; -NTI83205.node = NNI83205; -NTI83205.base = NTI46408; -NTI83231.base = NTI83205; -NTI83229.base = NTI83231; -NTI85305.base = NTI83229; -NTI203578.base = NTI43042; -var NNI46462 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; -NTI46462.node = NNI46462; -NTI46462.base = NTI46428; -var NNI201074 = {kind: 2, len: 2, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "Field0", len: 0, typ: NTI43006, name: "Field0", sons: null}, -{kind: 1, offset: "Field1", len: 0, typ: NTI43032, name: "Field1", sons: null}]}; -NTI201074.node = NNI201074; +var NTI42032 = {size: 0,kind: 1,base: null,node: null,finalizer: null}; +var NTI193071 = {size: 0, kind: 18, base: null, node: null, finalizer: null}; +var NTI45462 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI195578 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; +var NTI82448 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI82444 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI82440 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI82436 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI82432 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI82428 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI82424 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI82420 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI82416 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI82412 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI82408 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI82404 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI82400 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI82396 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI82392 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI82388 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI82384 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI82380 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI82376 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI82372 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI82205 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI82283 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI82281 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; +var NTI82227 = {size: 0, kind: 14, base: null, node: null, finalizer: null}; +var NTI82565 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; +var NTI82563 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; +var NTI82561 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; +var NTI82231 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI82229 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; +var NTI84305 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; +var NTI45450 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI45458 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI42006 = {size: 0,kind: 31,base: null,node: null,finalizer: null}; +var NTI61156 = {size: 0, kind: 18, base: null, node: null, finalizer: null}; +var NTI45408 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI45514 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; +var NTI42016 = {size: 0,kind: 40,base: null,node: null,finalizer: null}; +var NTI42040 = {size: 0,kind: 28,base: null,node: null,finalizer: null}; +var NTI42042 = {size: 0,kind: 29,base: null,node: null,finalizer: null}; +var NTI45508 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; +var NTI45426 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI45428 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI45442 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI45446 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NNI45446 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI45446.node = NNI45446; +var NNI45442 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI45442.node = NNI45442; +var NNI45428 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI45428.node = NNI45428; +NTI45508.base = NTI45426; +NTI45514.base = NTI45426; +var NNI45426 = {kind: 2, len: 6, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "parent", len: 0, typ: NTI45508, name: "parent", sons: null}, +{kind: 1, offset: "name", len: 0, typ: NTI42042, name: "name", sons: null}, +{kind: 1, offset: "message", len: 0, typ: NTI42040, name: "msg", sons: null}, +{kind: 1, offset: "trace", len: 0, typ: NTI42040, name: "trace", sons: null}, +{kind: 1, offset: "raiseId", len: 0, typ: NTI42016, name: "raiseId", sons: null}, +{kind: 1, offset: "up", len: 0, typ: NTI45514, name: "up", sons: null}]}; +NTI45426.node = NNI45426; +var NNI45408 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI45408.node = NNI45408; +NTI45426.base = NTI45408; +NTI45428.base = NTI45426; +NTI45442.base = NTI45428; +NTI45446.base = NTI45442; +var NNI61156 = {kind: 2, len: 2, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "Field0", len: 0, typ: NTI42042, name: "Field0", sons: null}, +{kind: 1, offset: "Field1", len: 0, typ: NTI42006, name: "Field1", sons: null}]}; +NTI61156.node = NNI61156; +var NNI45458 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI45458.node = NNI45458; +NTI45458.base = NTI45428; +var NNI45450 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI45450.node = NNI45450; +NTI45450.base = NTI45428; +NTI82561.base = NTI82229; +NTI82563.base = NTI82229; +NTI82565.base = NTI82229; +var NNI82227 = {kind: 2, offset: 0, typ: null, name: null, len: 12, sons: {"1": {kind: 1, offset: 1, typ: NTI82227, name: "ElementNode", len: 0, sons: null}, +"2": {kind: 1, offset: 2, typ: NTI82227, name: "AttributeNode", len: 0, sons: null}, +"3": {kind: 1, offset: 3, typ: NTI82227, name: "TextNode", len: 0, sons: null}, +"4": {kind: 1, offset: 4, typ: NTI82227, name: "CDATANode", len: 0, sons: null}, +"5": {kind: 1, offset: 5, typ: NTI82227, name: "EntityRefNode", len: 0, sons: null}, +"6": {kind: 1, offset: 6, typ: NTI82227, name: "EntityNode", len: 0, sons: null}, +"7": {kind: 1, offset: 7, typ: NTI82227, name: "ProcessingInstructionNode", len: 0, sons: null}, +"8": {kind: 1, offset: 8, typ: NTI82227, name: "CommentNode", len: 0, sons: null}, +"9": {kind: 1, offset: 9, typ: NTI82227, name: "DocumentNode", len: 0, sons: null}, +"10": {kind: 1, offset: 10, typ: NTI82227, name: "DocumentTypeNode", len: 0, sons: null}, +"11": {kind: 1, offset: 11, typ: NTI82227, name: "DocumentFragmentNode", len: 0, sons: null}, +"12": {kind: 1, offset: 12, typ: NTI82227, name: "NotationNode", len: 0, sons: null}}}; +NTI82227.node = NNI82227; +var NNI82283 = {kind: 2, len: 92, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "background", len: 0, typ: NTI42042, name: "background", sons: null}, +{kind: 1, offset: "backgroundAttachment", len: 0, typ: NTI42042, name: "backgroundAttachment", sons: null}, +{kind: 1, offset: "backgroundColor", len: 0, typ: NTI42042, name: "backgroundColor", sons: null}, +{kind: 1, offset: "backgroundImage", len: 0, typ: NTI42042, name: "backgroundImage", sons: null}, +{kind: 1, offset: "backgroundPosition", len: 0, typ: NTI42042, name: "backgroundPosition", sons: null}, +{kind: 1, offset: "backgroundRepeat", len: 0, typ: NTI42042, name: "backgroundRepeat", sons: null}, +{kind: 1, offset: "border", len: 0, typ: NTI42042, name: "border", sons: null}, +{kind: 1, offset: "borderBottom", len: 0, typ: NTI42042, name: "borderBottom", sons: null}, +{kind: 1, offset: "borderBottomColor", len: 0, typ: NTI42042, name: "borderBottomColor", sons: null}, +{kind: 1, offset: "borderBottomStyle", len: 0, typ: NTI42042, name: "borderBottomStyle", sons: null}, +{kind: 1, offset: "borderBottomWidth", len: 0, typ: NTI42042, name: "borderBottomWidth", sons: null}, +{kind: 1, offset: "borderColor", len: 0, typ: NTI42042, name: "borderColor", sons: null}, +{kind: 1, offset: "borderLeft", len: 0, typ: NTI42042, name: "borderLeft", sons: null}, +{kind: 1, offset: "borderLeftColor", len: 0, typ: NTI42042, name: "borderLeftColor", sons: null}, +{kind: 1, offset: "borderLeftStyle", len: 0, typ: NTI42042, name: "borderLeftStyle", sons: null}, +{kind: 1, offset: "borderLeftWidth", len: 0, typ: NTI42042, name: "borderLeftWidth", sons: null}, +{kind: 1, offset: "borderRight", len: 0, typ: NTI42042, name: "borderRight", sons: null}, +{kind: 1, offset: "borderRightColor", len: 0, typ: NTI42042, name: "borderRightColor", sons: null}, +{kind: 1, offset: "borderRightStyle", len: 0, typ: NTI42042, name: "borderRightStyle", sons: null}, +{kind: 1, offset: "borderRightWidth", len: 0, typ: NTI42042, name: "borderRightWidth", sons: null}, +{kind: 1, offset: "borderStyle", len: 0, typ: NTI42042, name: "borderStyle", sons: null}, +{kind: 1, offset: "borderTop", len: 0, typ: NTI42042, name: "borderTop", sons: null}, +{kind: 1, offset: "borderTopColor", len: 0, typ: NTI42042, name: "borderTopColor", sons: null}, +{kind: 1, offset: "borderTopStyle", len: 0, typ: NTI42042, name: "borderTopStyle", sons: null}, +{kind: 1, offset: "borderTopWidth", len: 0, typ: NTI42042, name: "borderTopWidth", sons: null}, +{kind: 1, offset: "borderWidth", len: 0, typ: NTI42042, name: "borderWidth", sons: null}, +{kind: 1, offset: "bottom", len: 0, typ: NTI42042, name: "bottom", sons: null}, +{kind: 1, offset: "captionSide", len: 0, typ: NTI42042, name: "captionSide", sons: null}, +{kind: 1, offset: "clear", len: 0, typ: NTI42042, name: "clear", sons: null}, +{kind: 1, offset: "clip", len: 0, typ: NTI42042, name: "clip", sons: null}, +{kind: 1, offset: "color", len: 0, typ: NTI42042, name: "color", sons: null}, +{kind: 1, offset: "cursor", len: 0, typ: NTI42042, name: "cursor", sons: null}, +{kind: 1, offset: "direction", len: 0, typ: NTI42042, name: "direction", sons: null}, +{kind: 1, offset: "display", len: 0, typ: NTI42042, name: "display", sons: null}, +{kind: 1, offset: "emptyCells", len: 0, typ: NTI42042, name: "emptyCells", sons: null}, +{kind: 1, offset: "cssFloat", len: 0, typ: NTI42042, name: "cssFloat", sons: null}, +{kind: 1, offset: "font", len: 0, typ: NTI42042, name: "font", sons: null}, +{kind: 1, offset: "fontFamily", len: 0, typ: NTI42042, name: "fontFamily", sons: null}, +{kind: 1, offset: "fontSize", len: 0, typ: NTI42042, name: "fontSize", sons: null}, +{kind: 1, offset: "fontStretch", len: 0, typ: NTI42042, name: "fontStretch", sons: null}, +{kind: 1, offset: "fontStyle", len: 0, typ: NTI42042, name: "fontStyle", sons: null}, +{kind: 1, offset: "fontVariant", len: 0, typ: NTI42042, name: "fontVariant", sons: null}, +{kind: 1, offset: "fontWeight", len: 0, typ: NTI42042, name: "fontWeight", sons: null}, +{kind: 1, offset: "height", len: 0, typ: NTI42042, name: "height", sons: null}, +{kind: 1, offset: "left", len: 0, typ: NTI42042, name: "left", sons: null}, +{kind: 1, offset: "letterSpacing", len: 0, typ: NTI42042, name: "letterSpacing", sons: null}, +{kind: 1, offset: "lineHeight", len: 0, typ: NTI42042, name: "lineHeight", sons: null}, +{kind: 1, offset: "listStyle", len: 0, typ: NTI42042, name: "listStyle", sons: null}, +{kind: 1, offset: "listStyleImage", len: 0, typ: NTI42042, name: "listStyleImage", sons: null}, +{kind: 1, offset: "listStylePosition", len: 0, typ: NTI42042, name: "listStylePosition", sons: null}, +{kind: 1, offset: "listStyleType", len: 0, typ: NTI42042, name: "listStyleType", sons: null}, +{kind: 1, offset: "margin", len: 0, typ: NTI42042, name: "margin", sons: null}, +{kind: 1, offset: "marginBottom", len: 0, typ: NTI42042, name: "marginBottom", sons: null}, +{kind: 1, offset: "marginLeft", len: 0, typ: NTI42042, name: "marginLeft", sons: null}, +{kind: 1, offset: "marginRight", len: 0, typ: NTI42042, name: "marginRight", sons: null}, +{kind: 1, offset: "marginTop", len: 0, typ: NTI42042, name: "marginTop", sons: null}, +{kind: 1, offset: "maxHeight", len: 0, typ: NTI42042, name: "maxHeight", sons: null}, +{kind: 1, offset: "maxWidth", len: 0, typ: NTI42042, name: "maxWidth", sons: null}, +{kind: 1, offset: "minHeight", len: 0, typ: NTI42042, name: "minHeight", sons: null}, +{kind: 1, offset: "minWidth", len: 0, typ: NTI42042, name: "minWidth", sons: null}, +{kind: 1, offset: "opacity", len: 0, typ: NTI42042, name: "opacity", sons: null}, +{kind: 1, offset: "overflow", len: 0, typ: NTI42042, name: "overflow", sons: null}, +{kind: 1, offset: "padding", len: 0, typ: NTI42042, name: "padding", sons: null}, +{kind: 1, offset: "paddingBottom", len: 0, typ: NTI42042, name: "paddingBottom", sons: null}, +{kind: 1, offset: "paddingLeft", len: 0, typ: NTI42042, name: "paddingLeft", sons: null}, +{kind: 1, offset: "paddingRight", len: 0, typ: NTI42042, name: "paddingRight", sons: null}, +{kind: 1, offset: "paddingTop", len: 0, typ: NTI42042, name: "paddingTop", sons: null}, +{kind: 1, offset: "pageBreakAfter", len: 0, typ: NTI42042, name: "pageBreakAfter", sons: null}, +{kind: 1, offset: "pageBreakBefore", len: 0, typ: NTI42042, name: "pageBreakBefore", sons: null}, +{kind: 1, offset: "pointerEvents", len: 0, typ: NTI42042, name: "pointerEvents", sons: null}, +{kind: 1, offset: "position", len: 0, typ: NTI42042, name: "position", sons: null}, +{kind: 1, offset: "right", len: 0, typ: NTI42042, name: "right", sons: null}, +{kind: 1, offset: "scrollbar3dLightColor", len: 0, typ: NTI42042, name: "scrollbar3dLightColor", sons: null}, +{kind: 1, offset: "scrollbarArrowColor", len: 0, typ: NTI42042, name: "scrollbarArrowColor", sons: null}, +{kind: 1, offset: "scrollbarBaseColor", len: 0, typ: NTI42042, name: "scrollbarBaseColor", sons: null}, +{kind: 1, offset: "scrollbarDarkshadowColor", len: 0, typ: NTI42042, name: "scrollbarDarkshadowColor", sons: null}, +{kind: 1, offset: "scrollbarFaceColor", len: 0, typ: NTI42042, name: "scrollbarFaceColor", sons: null}, +{kind: 1, offset: "scrollbarHighlightColor", len: 0, typ: NTI42042, name: "scrollbarHighlightColor", sons: null}, +{kind: 1, offset: "scrollbarShadowColor", len: 0, typ: NTI42042, name: "scrollbarShadowColor", sons: null}, +{kind: 1, offset: "scrollbarTrackColor", len: 0, typ: NTI42042, name: "scrollbarTrackColor", sons: null}, +{kind: 1, offset: "tableLayout", len: 0, typ: NTI42042, name: "tableLayout", sons: null}, +{kind: 1, offset: "textAlign", len: 0, typ: NTI42042, name: "textAlign", sons: null}, +{kind: 1, offset: "textDecoration", len: 0, typ: NTI42042, name: "textDecoration", sons: null}, +{kind: 1, offset: "textIndent", len: 0, typ: NTI42042, name: "textIndent", sons: null}, +{kind: 1, offset: "textTransform", len: 0, typ: NTI42042, name: "textTransform", sons: null}, +{kind: 1, offset: "transform", len: 0, typ: NTI42042, name: "transform", sons: null}, +{kind: 1, offset: "top", len: 0, typ: NTI42042, name: "top", sons: null}, +{kind: 1, offset: "verticalAlign", len: 0, typ: NTI42042, name: "verticalAlign", sons: null}, +{kind: 1, offset: "visibility", len: 0, typ: NTI42042, name: "visibility", sons: null}, +{kind: 1, offset: "width", len: 0, typ: NTI42042, name: "width", sons: null}, +{kind: 1, offset: "wordSpacing", len: 0, typ: NTI42042, name: "wordSpacing", sons: null}, +{kind: 1, offset: "zIndex", len: 0, typ: NTI42006, name: "zIndex", sons: null}]}; +NTI82283.node = NNI82283; +NTI82283.base = NTI45408; +NTI82281.base = NTI82283; +var NNI82231 = {kind: 2, len: 14, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "attributes", len: 0, typ: NTI82561, name: "attributes", sons: null}, +{kind: 1, offset: "childNodes", len: 0, typ: NTI82563, name: "childNodes", sons: null}, +{kind: 1, offset: "children", len: 0, typ: NTI82565, name: "children", sons: null}, +{kind: 1, offset: "data", len: 0, typ: NTI42042, name: "data", sons: null}, +{kind: 1, offset: "firstChild", len: 0, typ: NTI82229, name: "firstChild", sons: null}, +{kind: 1, offset: "lastChild", len: 0, typ: NTI82229, name: "lastChild", sons: null}, +{kind: 1, offset: "nextSibling", len: 0, typ: NTI82229, name: "nextSibling", sons: null}, +{kind: 1, offset: "nodeName", len: 0, typ: NTI42042, name: "nodeName", sons: null}, +{kind: 1, offset: "nodeType", len: 0, typ: NTI82227, name: "nodeType", sons: null}, +{kind: 1, offset: "nodeValue", len: 0, typ: NTI42042, name: "nodeValue", sons: null}, +{kind: 1, offset: "parentNode", len: 0, typ: NTI82229, name: "parentNode", sons: null}, +{kind: 1, offset: "previousSibling", len: 0, typ: NTI82229, name: "previousSibling", sons: null}, +{kind: 1, offset: "innerHTML", len: 0, typ: NTI42042, name: "innerHTML", sons: null}, +{kind: 1, offset: "style", len: 0, typ: NTI82281, name: "style", sons: null}]}; +NTI82231.node = NNI82231; +var NNI82205 = {kind: 2, len: 20, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "onabort", len: 0, typ: NTI82372, name: "onabort", sons: null}, +{kind: 1, offset: "onblur", len: 0, typ: NTI82376, name: "onblur", sons: null}, +{kind: 1, offset: "onchange", len: 0, typ: NTI82380, name: "onchange", sons: null}, +{kind: 1, offset: "onclick", len: 0, typ: NTI82384, name: "onclick", sons: null}, +{kind: 1, offset: "ondblclick", len: 0, typ: NTI82388, name: "ondblclick", sons: null}, +{kind: 1, offset: "onerror", len: 0, typ: NTI82392, name: "onerror", sons: null}, +{kind: 1, offset: "onfocus", len: 0, typ: NTI82396, name: "onfocus", sons: null}, +{kind: 1, offset: "onkeydown", len: 0, typ: NTI82400, name: "onkeydown", sons: null}, +{kind: 1, offset: "onkeypress", len: 0, typ: NTI82404, name: "onkeypress", sons: null}, +{kind: 1, offset: "onkeyup", len: 0, typ: NTI82408, name: "onkeyup", sons: null}, +{kind: 1, offset: "onload", len: 0, typ: NTI82412, name: "onload", sons: null}, +{kind: 1, offset: "onmousedown", len: 0, typ: NTI82416, name: "onmousedown", sons: null}, +{kind: 1, offset: "onmousemove", len: 0, typ: NTI82420, name: "onmousemove", sons: null}, +{kind: 1, offset: "onmouseout", len: 0, typ: NTI82424, name: "onmouseout", sons: null}, +{kind: 1, offset: "onmouseover", len: 0, typ: NTI82428, name: "onmouseover", sons: null}, +{kind: 1, offset: "onmouseup", len: 0, typ: NTI82432, name: "onmouseup", sons: null}, +{kind: 1, offset: "onreset", len: 0, typ: NTI82436, name: "onreset", sons: null}, +{kind: 1, offset: "onselect", len: 0, typ: NTI82440, name: "onselect", sons: null}, +{kind: 1, offset: "onsubmit", len: 0, typ: NTI82444, name: "onsubmit", sons: null}, +{kind: 1, offset: "onunload", len: 0, typ: NTI82448, name: "onunload", sons: null}]}; +NTI82205.node = NNI82205; +NTI82205.base = NTI45408; +NTI82231.base = NTI82205; +NTI82229.base = NTI82231; +NTI84305.base = NTI82229; +NTI195578.base = NTI42042; +var NNI45462 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI45462.node = NNI45462; +NTI45462.base = NTI45428; +var NNI193071 = {kind: 2, len: 2, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "Field0", len: 0, typ: NTI42006, name: "Field0", sons: null}, +{kind: 1, offset: "Field1", len: 0, typ: NTI42032, name: "Field1", sons: null}]}; +NTI193071.node = NNI193071; -function makeNimstrLit(c_64270) { - var ln = c_64270.length; +function makeNimstrLit(c_63270) { + var ln = c_63270.length; var result = new Array(ln); for (var i = 0; i < ln; ++i) { - result[i] = c_64270.charCodeAt(i); + result[i] = c_63270.charCodeAt(i); } return result; @@ -280,99 +280,99 @@ function setConstr() { } var ConstSet1 = setConstr(17, 16, 4, 18, 27, 19, 23, 22, 21); -function nimCopy(dest_65827, src_65828, ti_65829) { - var result_66019 = null; +function nimCopy(dest_64827, src_64828, ti_64829) { + var result_65019 = null; - switch (ti_65829.kind) { + switch (ti_64829.kind) { case 21: case 22: case 23: case 5: - if (!(is_fat_pointer_65801(ti_65829))) { - result_66019 = src_65828; + if (!(is_fat_pointer_64801(ti_64829))) { + result_65019 = src_64828; } else { - result_66019 = [src_65828[0], src_65828[1]]; + result_65019 = [src_64828[0], src_64828[1]]; } break; case 19: - if (dest_65827 === null || dest_65827 === undefined) { - dest_65827 = {}; + if (dest_64827 === null || dest_64827 === undefined) { + dest_64827 = {}; } else { - for (var key in dest_65827) { delete dest_65827[key]; } + for (var key in dest_64827) { delete dest_64827[key]; } } - for (var key in src_65828) { dest_65827[key] = src_65828[key]; } - result_66019 = dest_65827; + for (var key in src_64828) { dest_64827[key] = src_64828[key]; } + result_65019 = dest_64827; break; case 18: case 17: - if (!((ti_65829.base == null))) { - result_66019 = nimCopy(dest_65827, src_65828, ti_65829.base); + if (!((ti_64829.base == null))) { + result_65019 = nimCopy(dest_64827, src_64828, ti_64829.base); } else { - if ((ti_65829.kind == 17)) { - result_66019 = (dest_65827 === null || dest_65827 === undefined) ? {m_type: ti_65829} : dest_65827; + if ((ti_64829.kind == 17)) { + result_65019 = (dest_64827 === null || dest_64827 === undefined) ? {m_type: ti_64829} : dest_64827; } else { - result_66019 = (dest_65827 === null || dest_65827 === undefined) ? {} : dest_65827; + result_65019 = (dest_64827 === null || dest_64827 === undefined) ? {} : dest_64827; } } - nimCopyAux(result_66019, src_65828, ti_65829.node); + nimCopyAux(result_65019, src_64828, ti_64829.node); break; case 24: case 4: case 27: case 16: - if (src_65828 === null) { - result_66019 = null; + if (src_64828 === null) { + result_65019 = null; } else { - if (dest_65827 === null || dest_65827 === undefined) { - dest_65827 = new Array(src_65828.length); + if (dest_64827 === null || dest_64827 === undefined) { + dest_64827 = new Array(src_64828.length); } else { - dest_65827.length = src_65828.length; + dest_64827.length = src_64828.length; } - result_66019 = dest_65827; - for (var i = 0; i < src_65828.length; ++i) { - result_66019[i] = nimCopy(result_66019[i], src_65828[i], ti_65829.base); + result_65019 = dest_64827; + for (var i = 0; i < src_64828.length; ++i) { + result_65019[i] = nimCopy(result_65019[i], src_64828[i], ti_64829.base); } } break; case 28: - if (src_65828 !== null) { - result_66019 = src_65828.slice(0); + if (src_64828 !== null) { + result_65019 = src_64828.slice(0); } break; default: - result_66019 = src_65828; + result_65019 = src_64828; break; } - return result_66019; + return result_65019; } -function arrayConstr(len_66086, value_66087, typ_66088) { - var result = new Array(len_66086); - for (var i = 0; i < len_66086; ++i) result[i] = nimCopy(null, value_66087, typ_66088); +function arrayConstr(len_65086, value_65087, typ_65088) { + var result = new Array(len_65086); + for (var i = 0; i < len_65086; ++i) result[i] = nimCopy(null, value_65087, typ_65088); return result; } -function cstrToNimstr(c_64287) { - var ln = c_64287.length; +function cstrToNimstr(c_63287) { + var ln = c_63287.length; var result = new Array(ln); var r = 0; for (var i = 0; i < ln; ++i) { - var ch = c_64287.charCodeAt(i); + var ch = c_63287.charCodeAt(i); if (ch < 128) { result[r] = ch; @@ -387,7 +387,7 @@ function cstrToNimstr(c_64287) { } else { ++i; - ch = 65536 + (((ch & 1023) << 10) | (c_64287.charCodeAt(i) & 1023)); + ch = 65536 + (((ch & 1023) << 10) | (c_63287.charCodeAt(i) & 1023)); result[r] = (ch >> 18) | 240; ++r; result[r] = ((ch >> 12) & 63) | 128; @@ -406,88 +406,88 @@ function cstrToNimstr(c_64287) { } -function toJSStr(s_64304) { +function toJSStr(s_63304) { var Tmp5; var Tmp7; - var result_64305 = null; + var result_63305 = null; - var res_64363 = new_seq_64336((s_64304 != null ? s_64304.length : 0)); - var i_64365 = 0; - var j_64367 = 0; + var res_63363 = new_seq_63336((s_63304 != null ? s_63304.length : 0)); + var i_63365 = 0; + var j_63367 = 0; L1: do { L2: while (true) { - if (!(i_64365 < (s_64304 != null ? s_64304.length : 0))) break L2; - var c_64368 = s_64304[i_64365]; - if ((c_64368 < 128)) { - res_64363[j_64367] = String.fromCharCode(c_64368); - i_64365 += 1; + if (!(i_63365 < (s_63304 != null ? s_63304.length : 0))) break L2; + var c_63368 = s_63304[i_63365]; + if ((c_63368 < 128)) { + res_63363[j_63367] = String.fromCharCode(c_63368); + i_63365 += 1; } else { - var helper_64391 = new_seq_64336(0); + var helper_63391 = new_seq_63336(0); L3: do { L4: while (true) { if (!true) break L4; - var code_64392 = c_64368.toString(16); - if (((code_64392 != null ? code_64392.length : 0) == 1)) { - if (helper_64391 != null) { helper_64391.push("%0"); } else { helper_64391 = ["%0"]; }; + var code_63392 = c_63368.toString(16); + if (((code_63392 != null ? code_63392.length : 0) == 1)) { + if (helper_63391 != null) { helper_63391.push("%0"); } else { helper_63391 = ["%0"]; }; } else { - if (helper_64391 != null) { helper_64391.push("%"); } else { helper_64391 = ["%"]; }; + if (helper_63391 != null) { helper_63391.push("%"); } else { helper_63391 = ["%"]; }; } - if (helper_64391 != null) { helper_64391.push(code_64392); } else { helper_64391 = [code_64392]; }; - i_64365 += 1; - if (((s_64304 != null ? s_64304.length : 0) <= i_64365)) Tmp5 = true; else { Tmp5 = (s_64304[i_64365] < 128); } if (Tmp5) { + if (helper_63391 != null) { helper_63391.push(code_63392); } else { helper_63391 = [code_63392]; }; + i_63365 += 1; + if (((s_63304 != null ? s_63304.length : 0) <= i_63365)) Tmp5 = true; else { Tmp5 = (s_63304[i_63365] < 128); } if (Tmp5) { break L3; } - c_64368 = s_64304[i_64365]; + c_63368 = s_63304[i_63365]; } } while(false); ++excHandler; Tmp7 = framePtr; try { - res_64363[j_64367] = decodeURIComponent(helper_64391.join("")); + res_63363[j_63367] = decodeURIComponent(helper_63391.join("")); --excHandler; } catch (EXC) { var prevJSError = lastJSError; lastJSError = EXC; --excHandler; framePtr = Tmp7; - res_64363[j_64367] = helper_64391.join(""); + res_63363[j_63367] = helper_63391.join(""); lastJSError = prevJSError; } finally { framePtr = Tmp7; } } - j_64367 += 1; + j_63367 += 1; } } while(false); - if (res_64363 === null) res_64363 = []; - if (res_64363.length < j_64367) { for (var i=res_64363.length;i 2147483647 || result < -2147483648) raiseOverflow(); return result; @@ -495,28 +495,28 @@ function addInt(a_64803, b_64804) { } -function chckIndx(i_66105, a_66106, b_66107) { +function chckIndx(i_65105, a_65106, b_65107) { var Tmp1; - var result_66108 = 0; + var result_65108 = 0; BeforeRet: do { - if (!(a_66106 <= i_66105)) Tmp1 = false; else { Tmp1 = (i_66105 <= b_66107); } if (Tmp1) { - result_66108 = i_66105; + if (!(a_65106 <= i_65105)) Tmp1 = false; else { Tmp1 = (i_65105 <= b_65107); } if (Tmp1) { + result_65108 = i_65105; break BeforeRet; } else { - raiseIndexError(i_66105, a_66106, b_66107); + raiseIndexError(i_65105, a_65106, b_65107); } } while (false); - return result_66108; + return result_65108; } -function subInt(a_64821, b_64822) { - var result = a_64821 - b_64822; +function subInt(a_63821, b_63822) { + var result = a_63821 - b_63822; if (result > 2147483647 || result < -2147483648) raiseOverflow(); return result; @@ -525,14 +525,14 @@ function subInt(a_64821, b_64822) { } var ConstSet2 = setConstr([65, 90]); -function chckRange(i_66124, a_66125, b_66126) { +function chckRange(i_65124, a_65125, b_65126) { var Tmp1; - var result_66127 = 0; + var result_65127 = 0; BeforeRet: do { - if (!(a_66125 <= i_66124)) Tmp1 = false; else { Tmp1 = (i_66124 <= b_66126); } if (Tmp1) { - result_66127 = i_66124; + if (!(a_65125 <= i_65124)) Tmp1 = false; else { Tmp1 = (i_65124 <= b_65126); } if (Tmp1) { + result_65127 = i_65124; break BeforeRet; } else { @@ -541,14 +541,14 @@ function chckRange(i_66124, a_66125, b_66126) { } while (false); - return result_66127; + return result_65127; } var ConstSet3 = setConstr(95, 32, 46); var ConstSet4 = setConstr(95, 32, 46); -function mulInt(a_64839, b_64840) { - var result = a_64839 * b_64840; +function mulInt(a_63839, b_63840) { + var result = a_63839 * b_63840; if (result > 2147483647 || result < -2147483648) raiseOverflow(); return result; @@ -560,51 +560,51 @@ var ConstSet6 = setConstr([65, 90], [97, 122]); var ConstSet7 = setConstr([97, 122]); var ConstSet8 = setConstr([65, 90]); -function nimMax(a_65221, b_65222) { +function nimMax(a_64221, b_64222) { var Tmp1; - var result_65223 = 0; + var result_64223 = 0; BeforeRet: do { - if ((b_65222 <= a_65221)) { - Tmp1 = a_65221; + if ((b_64222 <= a_64221)) { + Tmp1 = a_64221; } else { - Tmp1 = b_65222; + Tmp1 = b_64222; } - result_65223 = Tmp1; + result_64223 = Tmp1; break BeforeRet; } while (false); - return result_65223; + return result_64223; } -function nimMin(a_65203, b_65204) { +function nimMin(a_64203, b_64204) { var Tmp1; - var result_65205 = 0; + var result_64205 = 0; BeforeRet: do { - if ((a_65203 <= b_65204)) { - Tmp1 = a_65203; + if ((a_64203 <= b_64204)) { + Tmp1 = a_64203; } else { - Tmp1 = b_65204; + Tmp1 = b_64204; } - result_65205 = Tmp1; + result_64205 = Tmp1; break BeforeRet; } while (false); - return result_65205; + return result_64205; } var nim_program_result = 0; -var global_raise_hook_59618 = [null]; -var local_raise_hook_59623 = [null]; -var out_of_mem_hook_59626 = [null]; +var global_raise_hook_58618 = [null]; +var local_raise_hook_58623 = [null]; +var out_of_mem_hook_58626 = [null]; if (!Math.trunc) { Math.trunc = function(v) { v = +v; @@ -613,38 +613,38 @@ var out_of_mem_hook_59626 = [null]; return (v - v % 1) || (v < 0 ? -0 : v === 0 ? v : 0); }; } -var alternative_203319 = [null]; +var alternative_195319 = [null]; -function is_fat_pointer_65801(ti_65803) { - var result_65804 = false; +function is_fat_pointer_64801(ti_64803) { + var result_64804 = false; BeforeRet: do { - result_65804 = !((ConstSet1[ti_65803.base.kind] != undefined)); + result_64804 = !((ConstSet1[ti_64803.base.kind] != undefined)); break BeforeRet; } while (false); - return result_65804; + return result_64804; } -function nimCopyAux(dest_65832, src_65833, n_65835) { - switch (n_65835.kind) { +function nimCopyAux(dest_64832, src_64833, n_64835) { + switch (n_64835.kind) { case 0: break; case 1: - dest_65832[n_65835.offset] = nimCopy(dest_65832[n_65835.offset], src_65833[n_65835.offset], n_65835.typ); + dest_64832[n_64835.offset] = nimCopy(dest_64832[n_64835.offset], src_64833[n_64835.offset], n_64835.typ); break; case 2: - for (var i = 0; i < n_65835.sons.length; i++) { - nimCopyAux(dest_65832, src_65833, n_65835.sons[i]); + for (var i = 0; i < n_64835.sons.length; i++) { + nimCopyAux(dest_64832, src_64833, n_64835.sons[i]); } break; case 3: - dest_65832[n_65835.offset] = nimCopy(dest_65832[n_65835.offset], src_65833[n_65835.offset], n_65835.typ); - for (var i = 0; i < n_65835.sons.length; ++i) { - nimCopyAux(dest_65832, src_65833, n_65835.sons[i][1]); + dest_64832[n_64835.offset] = nimCopy(dest_64832[n_64835.offset], src_64833[n_64835.offset], n_64835.typ); + for (var i = 0; i < n_64835.sons.length; ++i) { + nimCopyAux(dest_64832, src_64833, n_64835.sons[i][1]); } break; @@ -653,124 +653,124 @@ function nimCopyAux(dest_65832, src_65833, n_65835) { } -function add_59638(x_59641, x_59641_Idx, y_59642) { - if (x_59641[x_59641_Idx] === null) { x_59641[x_59641_Idx] = []; } - var off = x_59641[x_59641_Idx].length; - x_59641[x_59641_Idx].length += y_59642.length; - for (var i = 0; i < y_59642.length; ++i) { - x_59641[x_59641_Idx][off+i] = y_59642.charCodeAt(i); +function add_58638(x_58641, x_58641_Idx, y_58642) { + if (x_58641[x_58641_Idx] === null) { x_58641[x_58641_Idx] = []; } + var off = x_58641[x_58641_Idx].length; + x_58641[x_58641_Idx].length += y_58642.length; + for (var i = 0; i < y_58642.length; ++i) { + x_58641[x_58641_Idx][off+i] = y_58642.charCodeAt(i); } } -function aux_write_stack_trace_62151(f_62153) { +function aux_write_stack_trace_61151(f_61153) { var Tmp3; - var result_62154 = [null]; + var result_61154 = [null]; - var it_62162 = f_62153; - var i_62164 = 0; - var total_62166 = 0; - var temp_frames_62173 = arrayConstr(64, {Field0: null, Field1: 0}, NTI62156); + var it_61162 = f_61153; + var i_61164 = 0; + var total_61166 = 0; + var temp_frames_61173 = arrayConstr(64, {Field0: null, Field1: 0}, NTI61156); L1: do { L2: while (true) { - if (!!((it_62162 == null))) Tmp3 = false; else { Tmp3 = (i_62164 <= 63); } if (!Tmp3) break L2; - temp_frames_62173[i_62164].Field0 = it_62162.procname; - temp_frames_62173[i_62164].Field1 = it_62162.line; - i_62164 += 1; - total_62166 += 1; - it_62162 = it_62162.prev; + if (!!((it_61162 == null))) Tmp3 = false; else { Tmp3 = (i_61164 <= 63); } if (!Tmp3) break L2; + temp_frames_61173[i_61164].Field0 = it_61162.procname; + temp_frames_61173[i_61164].Field1 = it_61162.line; + i_61164 += 1; + total_61166 += 1; + it_61162 = it_61162.prev; } } while(false); L4: do { L5: while (true) { - if (!!((it_62162 == null))) break L5; - total_62166 += 1; - it_62162 = it_62162.prev; + if (!!((it_61162 == null))) break L5; + total_61166 += 1; + it_61162 = it_61162.prev; } } while(false); - result_62154[0] = nimCopy(null, [], NTI43040); - if (!((total_62166 == i_62164))) { - if (result_62154[0] != null) { result_62154[0] = (result_62154[0]).concat(makeNimstrLit("(")); } else { result_62154[0] = makeNimstrLit("("); }; - if (result_62154[0] != null) { result_62154[0] = (result_62154[0]).concat(cstrToNimstr(((total_62166 - i_62164))+"")); } else { result_62154[0] = cstrToNimstr(((total_62166 - i_62164))+"").slice(); }; - if (result_62154[0] != null) { result_62154[0] = (result_62154[0]).concat(makeNimstrLit(" calls omitted) ...\x0A")); } else { result_62154[0] = makeNimstrLit(" calls omitted) ...\x0A"); }; + result_61154[0] = nimCopy(null, [], NTI42040); + if (!((total_61166 == i_61164))) { + if (result_61154[0] != null) { result_61154[0] = (result_61154[0]).concat(makeNimstrLit("(")); } else { result_61154[0] = makeNimstrLit("("); }; + if (result_61154[0] != null) { result_61154[0] = (result_61154[0]).concat(cstrToNimstr(((total_61166 - i_61164))+"")); } else { result_61154[0] = cstrToNimstr(((total_61166 - i_61164))+"").slice(); }; + if (result_61154[0] != null) { result_61154[0] = (result_61154[0]).concat(makeNimstrLit(" calls omitted) ...\x0A")); } else { result_61154[0] = makeNimstrLit(" calls omitted) ...\x0A"); }; } L6: do { - var j_62421 = 0; - var colontmp__203466 = 0; - colontmp__203466 = (i_62164 - 1); - var res_203471 = colontmp__203466; + var j_61421 = 0; + var colontmp__195466 = 0; + colontmp__195466 = (i_61164 - 1); + var res_195471 = colontmp__195466; L7: do { L8: while (true) { - if (!(0 <= res_203471)) break L8; - j_62421 = res_203471; - add_59638(result_62154, 0, temp_frames_62173[j_62421].Field0); - if ((0 < temp_frames_62173[j_62421].Field1)) { - if (result_62154[0] != null) { result_62154[0] = (result_62154[0]).concat(makeNimstrLit(", line: ")); } else { result_62154[0] = makeNimstrLit(", line: "); }; - if (result_62154[0] != null) { result_62154[0] = (result_62154[0]).concat(cstrToNimstr((temp_frames_62173[j_62421].Field1)+"")); } else { result_62154[0] = cstrToNimstr((temp_frames_62173[j_62421].Field1)+"").slice(); }; + if (!(0 <= res_195471)) break L8; + j_61421 = res_195471; + add_58638(result_61154, 0, temp_frames_61173[j_61421].Field0); + if ((0 < temp_frames_61173[j_61421].Field1)) { + if (result_61154[0] != null) { result_61154[0] = (result_61154[0]).concat(makeNimstrLit(", line: ")); } else { result_61154[0] = makeNimstrLit(", line: "); }; + if (result_61154[0] != null) { result_61154[0] = (result_61154[0]).concat(cstrToNimstr((temp_frames_61173[j_61421].Field1)+"")); } else { result_61154[0] = cstrToNimstr((temp_frames_61173[j_61421].Field1)+"").slice(); }; } - if (result_62154[0] != null) { result_62154[0] = (result_62154[0]).concat(makeNimstrLit("\x0A")); } else { result_62154[0] = makeNimstrLit("\x0A"); }; - res_203471 -= 1; + if (result_61154[0] != null) { result_61154[0] = (result_61154[0]).concat(makeNimstrLit("\x0A")); } else { result_61154[0] = makeNimstrLit("\x0A"); }; + res_195471 -= 1; } } while(false); } while(false); - return result_62154[0]; + return result_61154[0]; } -function raw_write_stack_trace_62468() { - var result_62470 = null; +function raw_write_stack_trace_61467() { + var result_61469 = null; if (!((framePtr == null))) { - result_62470 = nimCopy(null, (makeNimstrLit("Traceback (most recent call last)\x0A") || []).concat(aux_write_stack_trace_62151(framePtr) || []), NTI43040); + result_61469 = nimCopy(null, (makeNimstrLit("Traceback (most recent call last)\x0A") || []).concat(aux_write_stack_trace_61151(framePtr) || []), NTI42040); } else { - result_62470 = nimCopy(null, makeNimstrLit("No stack traceback available\x0A"), NTI43040); + result_61469 = nimCopy(null, makeNimstrLit("No stack traceback available\x0A"), NTI42040); } - return result_62470; + return result_61469; } -function new_seq_64336(len_64339) { - var result_64341 = null; +function new_seq_63336(len_63339) { + var result_63341 = null; var F={procname:"newSeq.newSeq",prev:framePtr,filename:"system.nim",line:0}; framePtr = F; F.line = 996; - result_64341 = new Array(len_64339); for (var i=0;i", "text/html"); - stuff_203563 = doc.documentElement; + stuff_195563 = doc.documentElement; F.line = 286; - db_203535[0] = nimCopy(null, stuff_203563.getElementsByClassName("reference"), NTI85305); + db_195535[0] = nimCopy(null, stuff_195563.getElementsByClassName("reference"), NTI84305); F.line = 287; - contents_203537[0] = nimCopy(null, [], NTI203578); + contents_195537[0] = nimCopy(null, [], NTI195578); L1: do { F.line = 288; - var ahref_203814 = null; + var ahref_195814 = null; F.line = 184; - var i_204045 = 0; + var i_196045 = 0; F.line = 185; - var l_204046 = (db_203535[0] != null ? db_203535[0].length : 0); + var l_196046 = (db_195535[0] != null ? db_195535[0].length : 0); L2: do { F.line = 186; L3: while (true) { - if (!(i_204045 < l_204046)) break L3; + if (!(i_196045 < l_196046)) break L3; F.line = 288; - ahref_203814 = db_203535[0][chckIndx(i_204045, 0, db_203535[0].length+0-1)-0]; + ahref_195814 = db_195535[0][chckIndx(i_196045, 0, db_195535[0].length+0-1)-0]; F.line = 289; - if (contents_203537[0] != null) { contents_203537[0].push(ahref_203814.getAttribute("data-doc-search-tag")); } else { contents_203537[0] = [ahref_203814.getAttribute("data-doc-search-tag")]; }; + if (contents_195537[0] != null) { contents_195537[0].push(ahref_195814.getAttribute("data-doc-search-tag")); } else { contents_195537[0] = [ahref_195814.getAttribute("data-doc-search-tag")]; }; F.line = 188; - i_204045 = addInt(i_204045, 1); - if (!(((db_203535[0] != null ? db_203535[0].length : 0) == l_204046))) { + i_196045 = addInt(i_196045, 1); + if (!(((db_195535[0] != null ? db_195535[0].length : 0) == l_196046))) { F.line = 189; - failed_assert_impl_56866(makeNimstrLit("/home/genotrance/programming/nimdevel/lib/system/iterators.nim(189, 11) `len(a) == L` the length of the seq changed while iterating over it")); + failed_assert_impl_55666(makeNimstrLit("/home/genotrance/programming/nimdevel/lib/system/iterators.nim(189, 11) `len(a) ==\x0A L` the length of the seq changed while iterating over it")); } } @@ -1888,126 +1888,126 @@ function dosearch_203554(value_203556) { } F.line = 290; - var ul_203825 = tree_202020(makeNimstrLit("UL"), []); + var ul_195825 = tree_194020(makeNimstrLit("UL"), []); F.line = 291; - result_203557 = tree_202020(makeNimstrLit("DIV"), []); + result_195557 = tree_194020(makeNimstrLit("DIV"), []); F.line = 292; - set_class_202103(result_203557, makeNimstrLit("search_results")); + set_class_194103(result_195557, makeNimstrLit("search_results")); F.line = 293; - var matches_203846 = []; + var matches_195846 = []; L4: do { F.line = 294; - var i_203859 = 0; - F.line = 2718; - var colontmp__204052 = 0; + var i_195859 = 0; + F.line = 2755; + var colontmp__196052 = 0; F.line = 294; - colontmp__204052 = (db_203535[0] != null ? db_203535[0].length : 0); - F.line = 2720; - var i_204053 = 0; + colontmp__196052 = (db_195535[0] != null ? db_195535[0].length : 0); + F.line = 2757; + var i_196053 = 0; L5: do { - F.line = 2721; + F.line = 2758; L6: while (true) { - if (!(i_204053 < colontmp__204052)) break L6; + if (!(i_196053 < colontmp__196052)) break L6; F.line = 294; - i_203859 = i_204053; + i_195859 = i_196053; L7: do { F.line = 295; - var c_203860 = contents_203537[0][chckIndx(i_203859, 0, contents_203537[0].length+0-1)-0]; - if (((c_203860 == "Examples") || (c_203860 == "PEG construction"))) { + var c_195860 = contents_195537[0][chckIndx(i_195859, 0, contents_195537[0].length+0-1)-0]; + if (((c_195860 == "Examples") || (c_195860 == "PEG construction"))) { F.line = 300; break L7; } F.line = 301; - var colontmp__204062 = {Field0: 0, Field1: false}; + var colontmp__196062 = {Field0: 0, Field1: false}; F.line = 301; - var score_203861 = 0; + var score_195861 = 0; F.line = 301; - var matched_203862 = false; + var matched_195862 = false; F.line = 301; - nimCopy(colontmp__204062, fuzzy_match_201070(value_203556, c_203860), NTI201074); + nimCopy(colontmp__196062, fuzzy_match_193067(value_195556, c_195860), NTI193071); F.line = 301; - score_203861 = colontmp__204062["Field0"]; + score_195861 = colontmp__196062["Field0"]; F.line = 301; - matched_203862 = colontmp__204062["Field1"]; - if (matched_203862) { + matched_195862 = colontmp__196062["Field1"]; + if (matched_195862) { F.line = 303; - if (matches_203846 != null) { matches_203846.push({Field0: db_203535[0][chckIndx(i_203859, 0, db_203535[0].length+0-1)-0], Field1: score_203861}); } else { matches_203846 = [{Field0: db_203535[0][chckIndx(i_203859, 0, db_203535[0].length+0-1)-0], Field1: score_203861}]; }; + if (matches_195846 != null) { matches_195846.push({Field0: db_195535[0][chckIndx(i_195859, 0, db_195535[0].length+0-1)-0], Field1: score_195861}); } else { matches_195846 = [{Field0: db_195535[0][chckIndx(i_195859, 0, db_195535[0].length+0-1)-0], Field1: score_195861}]; }; } } while(false); - F.line = 2723; - i_204053 = addInt(i_204053, 1); + F.line = 2760; + i_196053 = addInt(i_196053, 1); } } while(false); } while(false); F.line = 305; - matches_203846.sort(HEX3Aanonymous_203873); + matches_195846.sort(HEX3Aanonymous_195873); L8: do { F.line = 306; - var i_203926 = 0; - F.line = 2718; - var colontmp__204058 = 0; + var i_195926 = 0; + F.line = 2755; + var colontmp__196058 = 0; F.line = 306; - colontmp__204058 = nimMin((matches_203846 != null ? matches_203846.length : 0), 19); - F.line = 2720; - var i_204059 = 0; + colontmp__196058 = nimMin((matches_195846 != null ? matches_195846.length : 0), 19); + F.line = 2757; + var i_196059 = 0; L9: do { - F.line = 2721; + F.line = 2758; L10: while (true) { - if (!(i_204059 < colontmp__204058)) break L10; + if (!(i_196059 < colontmp__196058)) break L10; F.line = 306; - i_203926 = i_204059; + i_195926 = i_196059; F.line = 307; - matches_203846[chckIndx(i_203926, 0, matches_203846.length+0-1)-0]["Field0"].innerHTML = matches_203846[chckIndx(i_203926, 0, matches_203846.length+0-1)-0]["Field0"].getAttribute("data-doc-search-tag"); + matches_195846[chckIndx(i_195926, 0, matches_195846.length+0-1)-0]["Field0"].innerHTML = matches_195846[chckIndx(i_195926, 0, matches_195846.length+0-1)-0]["Field0"].getAttribute("data-doc-search-tag"); F.line = 308; - add_202085(ul_203825, tree_202020(makeNimstrLit("LI"), [matches_203846[chckIndx(i_203926, 0, matches_203846.length+0-1)-0]["Field0"]])); - F.line = 2723; - i_204059 = addInt(i_204059, 1); + add_194085(ul_195825, tree_194020(makeNimstrLit("LI"), [matches_195846[chckIndx(i_195926, 0, matches_195846.length+0-1)-0]["Field0"]])); + F.line = 2760; + i_196059 = addInt(i_196059, 1); } } while(false); } while(false); - if ((ul_203825.childNodes.length == 0)) { + if ((ul_195825.childNodes.length == 0)) { F.line = 310; - add_202085(result_203557, tree_202020(makeNimstrLit("B"), [text_202120(makeNimstrLit("no search results"))])); + add_194085(result_195557, tree_194020(makeNimstrLit("B"), [text_194120(makeNimstrLit("no search results"))])); } else { F.line = 312; - add_202085(result_203557, tree_202020(makeNimstrLit("B"), [text_202120(makeNimstrLit("search results"))])); + add_194085(result_195557, tree_194020(makeNimstrLit("B"), [text_194120(makeNimstrLit("search results"))])); F.line = 313; - add_202085(result_203557, ul_203825); + add_194085(result_195557, ul_195825); } framePtr = F.prev; - return result_203557; + return result_195557; } function search() { - function wrapper_203993() { + function wrapper_195993() { var F={procname:"search.wrapper",prev:framePtr,filename:"dochack.nim",line:0}; framePtr = F; F.line = 320; - var elem_203995 = document.getElementById("searchInput"); + var elem_195995 = document.getElementById("searchInput"); F.line = 321; - var value_203996 = elem_203995.value; - if (!(((value_203996 != null ? value_203996.length : 0) == 0))) { - if ((oldtoc_203961[0] == null)) { + var value_195996 = elem_195995.value; + if (!(((value_195996 != null ? value_195996.length : 0) == 0))) { + if ((oldtoc_195961[0] == null)) { F.line = 324; - oldtoc_203961[0] = document.getElementById("tocRoot"); + oldtoc_195961[0] = document.getElementById("tocRoot"); } F.line = 325; - var results_204002 = dosearch_203554(value_203996); + var results_196002 = dosearch_195554(value_195996); F.line = 326; - replace_by_id_202172("tocRoot", results_204002); + replace_by_id_194172("tocRoot", results_196002); } else { - if (!((oldtoc_203961[0] == null))) { + if (!((oldtoc_195961[0] == null))) { F.line = 328; - replace_by_id_202172("tocRoot", oldtoc_203961[0]); + replace_by_id_194172("tocRoot", oldtoc_195961[0]); } } framePtr = F.prev; @@ -2017,13 +2017,13 @@ function search() { var F={procname:"dochack.search",prev:framePtr,filename:"dochack.nim",line:0}; framePtr = F; - if (!((timer_203962[0] == null))) { + if (!((timer_195962[0] == null))) { F.line = 330; - clearTimeout(timer_203962[0]); + clearTimeout(timer_195962[0]); } F.line = 331; - timer_203962[0] = setTimeout(wrapper_203993, 400); + timer_195962[0] = setTimeout(wrapper_195993, 400); framePtr = F.prev; diff --git a/paths.html b/paths.html index e2e5787..f190a22 100644 --- a/paths.html +++ b/paths.html @@ -917,7 +917,7 @@ function main() { diff --git a/plugin.html b/plugin.html index 41686c2..b3e0e5c 100644 --- a/plugin.html +++ b/plugin.html @@ -875,7 +875,7 @@ function main() { diff --git a/theindex.html b/theindex.html index 082f9c1..9611f5a 100644 --- a/theindex.html +++ b/theindex.html @@ -1061,7 +1061,7 @@ function main() { diff --git a/types.html b/types.html index d01868d..5dd9194 100644 --- a/types.html +++ b/types.html @@ -924,7 +924,7 @@ function main() { From 48955b3aa140ee7a903e5bf6bb6e36527a0a8359 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 16 Oct 2019 17:13:27 -0500 Subject: [PATCH 271/593] Partial fix for #139 --- nimterop/ast.nim | 15 +++++++++++++ nimterop/globals.nim | 2 ++ nimterop/grammar.nim | 49 +++++++++++++++++++++++++++---------------- tests/include/test.c | 4 ++++ tests/include/test.h | 1 + tests/tnimterop_c.nim | 5 +++++ 6 files changed, 58 insertions(+), 18 deletions(-) diff --git a/nimterop/ast.nim b/nimterop/ast.nim index 240d5fd..b5176fb 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -86,15 +86,30 @@ proc searchAstForNode(ast: ref Ast, node: TSNode, nimState: NimState): bool = ast.getAstChildByName($nodeChild.tsNodeType()) else: ast + + if nimState.gState.debug: + nimState.nodeBranch.add $node.tsNodeType() + echo "#" & spaces(nimState.nodeBranch.len) & nimState.nodeBranch[^1] + if not searchAstForNode(astChild, nodeChild, nimState): + if nimState.gState.debug: + echo "#" & spaces(nimState.nodeBranch.len) & &" {$nodeChild.tsNodeType()} unexpected" + discard nimState.nodeBranch.pop() flag = false break + if nimState.gState.debug: + discard nimState.nodeBranch.pop() + if nimState.nodeBranch.len == 0: + echo "" + if flag: return node.saveNodeData(nimState) else: + echo "#" & spaces(nimState.nodeBranch.len+1) & $node.tsNodeType() return node.saveNodeData(nimState) elif node.getTSNodeNamedChildCountSansComments() == 0: + echo "#" & spaces(nimState.nodeBranch.len+1) & $node.tsNodeType() return node.saveNodeData(nimState) proc searchAst(root: TSNode, astTable: AstTable, nimState: NimState) = diff --git a/nimterop/globals.nim b/nimterop/globals.nim index 32a461c..8fd8fe9 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -72,6 +72,8 @@ type data*: seq[tuple[name, val: string]] + nodeBranch*: seq[string] + var gStateCT {.compiletime, used.} = new(State) diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index 8ddd8c1..bd9a851 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -43,6 +43,19 @@ proc initGrammar(): Grammar = ) """ + arrGrammar = &""" + (array_declarator! + (pointer_declarator! + (pointer_declarator! + (type_identifier) + ) + (type_identifier) + ) + (type_identifier|identifier) + (identifier|number_literal) + ) + """ + paramListGrammar = &""" (parameter_list (parameter_declaration* @@ -52,10 +65,13 @@ proc initGrammar(): Grammar = (type_qualifier?) (pointer_declarator! (type_qualifier?) + {arrGrammar} (identifier|type_identifier) ) + {arrGrammar} (identifier|type_identifier) ) + {arrGrammar} (abstract_pointer_declarator? (abstract_pointer_declarator?) ) @@ -77,20 +93,7 @@ proc initGrammar(): Grammar = ) """ - arrGrammar = &""" - (array_declarator! - (pointer_declarator! - (pointer_declarator! - (type_identifier) - ) - (type_identifier) - ) - (type_identifier) - (identifier|number_literal) - ) - """ - - template funcParamCommon(fname, pname, ptyp, pptr, pout, count, i: untyped): untyped = + template funcParamCommon(fname, pname, ptyp, pptr, pout, count, i, flen: untyped): untyped = ptyp = nimState.getIdentifier(nimState.data[i].val, nskType, fname).getType() pptr = "" @@ -106,7 +109,14 @@ proc initGrammar(): Grammar = count += 1 i += 1 - if pptr.len != 0 or ptyp != "object": + if i < nimState.data.len and nimState.data[i].name in ["identifier", "number_literal"]: + flen = nimState.data[i].val + if nimState.data[i].name == "identifier": + flen = nimState.getIdentifier(flen, nskConst, fname) + + pout &= &"{pname}: array[{flen}, {getPtrType(pptr&ptyp)}], " + i += 1 + elif pptr.len != 0 or ptyp != "object": pout &= &"{pname}: {getPtrType(pptr&ptyp)}, " # typedef int X @@ -171,12 +181,13 @@ proc initGrammar(): Grammar = fname = nname pout, pname, ptyp, pptr = "" count = 1 + flen = "" while i < nimState.data.len: if nimState.data[i].name == "function_declarator": break - funcParamCommon(fname, pname, ptyp, pptr, pout, count, i) + funcParamCommon(fname, pname, ptyp, pptr, pout, count, i, flen) if pout.len != 0 and pout[^2 .. ^1] == ", ": pout = pout[0 .. ^3] @@ -277,6 +288,7 @@ proc initGrammar(): Grammar = ftyp, fname: string fptr = "" aptr = "" + flen = "" while i < nimState.data.len-fend: fptr = "" aptr = "" @@ -323,7 +335,7 @@ proc initGrammar(): Grammar = if nimState.data[i].name == "field_declaration": break - funcParamCommon(fname, pname, ptyp, pptr, pout, count, i) + funcParamCommon(fname, pname, ptyp, pptr, pout, count, i, flen) if pout.len != 0 and pout[^2 .. ^1] == ", ": pout = pout[0 .. ^3] @@ -575,13 +587,14 @@ proc initGrammar(): Grammar = fnname = nimState.getIdentifier(fname, nskProc) pout, pname, ptyp, pptr = "" count = 1 + flen = "" i += 1 while i < nimState.data.len: if nimState.data[i].name == "function_declarator": break - funcParamCommon(fnname, pname, ptyp, pptr, pout, count, i) + funcParamCommon(fnname, pname, ptyp, pptr, pout, count, i, flen) if pout.len != 0 and pout[^2 .. ^1] == ", ": pout = pout[0 .. ^3] diff --git a/tests/include/test.c b/tests/include/test.c index 8990df9..18e444f 100644 --- a/tests/include/test.c +++ b/tests/include/test.c @@ -64,6 +64,10 @@ void **test_call10(int **param1) { return NULL; } +char *test_array_param(int arr[5]) { + return NULL; +} + void multiline1(void) {} void *multiline2(void) { diff --git a/tests/include/test.h b/tests/include/test.h index df48cd0..d062277 100644 --- a/tests/include/test.h +++ b/tests/include/test.h @@ -119,6 +119,7 @@ int test_call_param7(union UNION1 param1); float test_call_param8(int *param1); void *test_call9(); void **test_call10(int **param1); +char *test_array_param(int arr[5]); // Issue #58 void diff --git a/tests/tnimterop_c.nim b/tests/tnimterop_c.nim index 1c30387..a289303 100644 --- a/tests/tnimterop_c.nim +++ b/tests/tnimterop_c.nim @@ -178,3 +178,8 @@ check TDEFL_OUT_BUF_SIZE == 85196 check TDEFL_BOGUS_1 == 2 check TDEFL_BOGUS_2 == 1024 check TDEFL_BOGUS_3 == (85196 / 2).int + +var + arr: array[5, cint] + +check test_array_param(arr) == nil From 8dc327d02b851a6447e971823cb440f973c5a146 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 16 Oct 2019 21:25:31 -0500 Subject: [PATCH 272/593] Implement var proc --- nimterop/ast.nim | 14 ++++++++------ nimterop/grammar.nim | 17 ++++++++++++++--- tests/tpcre.nim | 7 ++++++- 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/nimterop/ast.nim b/nimterop/ast.nim index b5176fb..128a7e6 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -47,14 +47,16 @@ proc saveNodeData(node: TSNode, nimState: NimState): bool = nimState.data.add((name, val)) - if name == "field_identifier" and - pname == "pointer_declarator" and + if pname == "pointer_declarator" and ppname == "function_declarator": - if pppname == "pointer_declarator": - nimState.data.insert(("pointer_declarator", ""), nimState.data.len-1) - if ppppname == "pointer_declarator": + if name == "field_identifier": + if pppname == "pointer_declarator": nimState.data.insert(("pointer_declarator", ""), nimState.data.len-1) - nimState.data.add(("function_declarator", "")) + if ppppname == "pointer_declarator": + nimState.data.insert(("pointer_declarator", ""), nimState.data.len-1) + nimState.data.add(("function_declarator", "")) + elif name == "identifier": + nimState.data.add(("pointer_declarator", "")) elif name in gExpressions and name != "escape_sequence": if $node.tsNodeParent.tsNodeType() notin gExpressions: diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index bd9a851..8d98dde 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -86,7 +86,7 @@ proc initGrammar(): Grammar = (pointer_declarator! (type_identifier) ) - (type_identifier) + (type_identifier|identifier) ) {paramListGrammar} (noexcept|throw_specifier?) @@ -588,8 +588,13 @@ proc initGrammar(): Grammar = pout, pname, ptyp, pptr = "" count = 1 flen = "" + fVar = false i += 1 + if i < nimState.data.len and nimState.data[i].name == "pointer_declarator": + fVar = true + i += 1 + while i < nimState.data.len: if nimState.data[i].name == "function_declarator": break @@ -605,9 +610,15 @@ proc initGrammar(): Grammar = pragma = nimState.getPragma(nimState.getImportC(fname, fnname), "cdecl") if fptr.len != 0 or ftyp != "object": - nimState.procStr &= &"{nimState.getComments(true)}\nproc {fnname}*({pout}): {getPtrType(fptr&ftyp)}{pragma}" + if fVar: + nimState.procStr &= &"{nimState.getComments(true)}\nvar {fnname}*: proc ({pout}): {getPtrType(fptr&ftyp)}{{.cdecl.}}" + else: + nimState.procStr &= &"{nimState.getComments(true)}\nproc {fnname}*({pout}): {getPtrType(fptr&ftyp)}{pragma}" else: - nimState.procStr &= &"{nimState.getComments(true)}\nproc {fnname}*({pout}){pragma}" + if fVar: + nimState.procStr &= &"{nimState.getComments(true)}\nvar {fnname}*: proc ({pout}){{.cdecl.}}" + else: + nimState.procStr &= &"{nimState.getComments(true)}\nproc {fnname}*({pout}){pragma}" )) # // comment diff --git a/tests/tpcre.nim b/tests/tpcre.nim index 5bc97da..41809cb 100644 --- a/tests/tpcre.nim +++ b/tests/tpcre.nim @@ -1,6 +1,6 @@ import os -import nimterop/[cimport, build, paths] +import nimterop/[cimport, build] const baseDir = getProjectCacheDir("nimterop" / "tests" / "pcre") @@ -33,3 +33,8 @@ cPlugin: cImport(pcreH, dynlib="dynpcre") echo version() + +proc my_malloc(a1: cuint) {.cdecl.} = + discard + +malloc = my_malloc From f7bc37f2b3345f5e04a4a7ba733751bf5ce41c6e Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 16 Oct 2019 22:56:50 -0500 Subject: [PATCH 273/593] Fix #141 --- nimterop/build.nim | 16 ++++++++++++++-- nimterop/getters.nim | 2 +- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/nimterop/build.nim b/nimterop/build.nim index 72f80b9..f96593e 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -570,13 +570,25 @@ proc make*(path, check: string, flags = "", regex = false) = doAssert findFile(check, path, regex = regex).len != 0, "# make failed" +proc getCompiler*(): string = + var + compiler = + when defined(gcc): + "gcc" + elif defined(clang): + "clang" + else: + doAssert false, "Nimterop only supports gcc and clang at this time" + + result = getEnv("CC", compiler) + proc getGccPaths*(mode = "c"): seq[string] = var nul = when defined(Windows): "nul" else: "/dev/null" mmode = if mode == "cpp": "c++" else: mode inc = false - (outp, _) = gorgeEx(&"""{getEnv("CC", "gcc")} -Wp,-v -x{mmode} {nul}""") + (outp, _) = gorgeEx(&"""{getCompiler()} -Wp,-v -x{mmode} {nul}""") for line in outp.splitLines(): if "#include <...> search starts here" in line: @@ -599,7 +611,7 @@ proc getGccLibPaths*(mode = "c"): seq[string] = mmode = if mode == "cpp": "c++" else: mode linker = when defined(OSX): "-Xlinker" else: "" - (outp, _) = gorgeEx(&"""{getEnv("CC", "gcc")} {linker} -v -x{mmode} {nul}""") + (outp, _) = gorgeEx(&"""{getCompiler()} {linker} -v -x{mmode} {nul}""") for line in outp.splitLines(): if "LIBRARY_PATH=" in line: diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 660f69f..a88895d 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -204,7 +204,7 @@ proc removeStatic(content: string): string = proc getPreprocessor*(gState: State, fullpath: string, mode = "cpp"): string = var mmode = if mode == "cpp": "c++" else: mode - cmd = &"""{getEnv("CC", "gcc")} -E -CC -dD -x{mmode} -w """ + cmd = &"""{getCompiler()} -E -CC -dD -x{mmode} -w """ rdata: seq[string] = @[] start = false From 8c57fbf6020e8da698076fd0cb72d3a49ea6cefc Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 17 Oct 2019 12:01:37 -0500 Subject: [PATCH 274/593] Fix debug output --- nimterop/ast.nim | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/nimterop/ast.nim b/nimterop/ast.nim index 128a7e6..c4294dc 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -74,11 +74,16 @@ proc searchAstForNode(ast: ref Ast, node: TSNode, nimState: NimState): bool = if ast.isNil: return + if nimState.gState.debug: + nimState.nodeBranch.add $node.tsNodeType() + echo "#" & spaces(nimState.nodeBranch.len * 2) & nimState.nodeBranch[^1] + if ast.children.len != 0: if childNames.contains(ast.regex) or (childNames.len == 0 and ast.recursive): if node.getTSNodeNamedChildCountSansComments() != 0: var flag = true + for i in 0 .. node.tsNodeNamedChildCount()-1: if $node.tsNodeNamedChild(i).tsNodeType() != "comment": let @@ -89,30 +94,24 @@ proc searchAstForNode(ast: ref Ast, node: TSNode, nimState: NimState): bool = else: ast - if nimState.gState.debug: - nimState.nodeBranch.add $node.tsNodeType() - echo "#" & spaces(nimState.nodeBranch.len) & nimState.nodeBranch[^1] - if not searchAstForNode(astChild, nodeChild, nimState): - if nimState.gState.debug: - echo "#" & spaces(nimState.nodeBranch.len) & &" {$nodeChild.tsNodeType()} unexpected" - discard nimState.nodeBranch.pop() flag = false break - if nimState.gState.debug: - discard nimState.nodeBranch.pop() - if nimState.nodeBranch.len == 0: - echo "" - if flag: - return node.saveNodeData(nimState) + result = node.saveNodeData(nimState) else: - echo "#" & spaces(nimState.nodeBranch.len+1) & $node.tsNodeType() - return node.saveNodeData(nimState) + result = node.saveNodeData(nimState) + else: + if nimState.gState.debug: + echo "#" & spaces(nimState.nodeBranch.len * 2) & &" {ast.getRegexForAstChildren()} !=~ {childNames}" elif node.getTSNodeNamedChildCountSansComments() == 0: - echo "#" & spaces(nimState.nodeBranch.len+1) & $node.tsNodeType() - return node.saveNodeData(nimState) + result = node.saveNodeData(nimState) + + if nimState.gState.debug: + discard nimState.nodeBranch.pop() + if nimstate.nodeBranch.len == 0: + echo "" proc searchAst(root: TSNode, astTable: AstTable, nimState: NimState) = var From e9120eee7840851bda8113afbc71062b29fff872 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 17 Oct 2019 15:09:34 -0500 Subject: [PATCH 275/593] Bump to 0.2.1 --- nimterop.nimble | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimterop.nimble b/nimterop.nimble index 8e27d8e..f78a010 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -1,6 +1,6 @@ # Package -version = "0.2.0" +version = "0.2.1" author = "genotrance" description = "C/C++ interop for Nim" license = "MIT" From 438160ac2a916ca0e8e18161d0a757e6bb338426 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 17 Oct 2019 15:41:24 -0500 Subject: [PATCH 276/593] Detect unknown --- nimterop/getters.nim | 3 +++ nimterop/grammar.nim | 19 ++++++++++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/nimterop/getters.nim b/nimterop/getters.nim index a88895d..7205213 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -320,6 +320,9 @@ proc getAstChildByName*(ast: ref Ast, name: string): ref Ast = if name in ast.children[i].name.split("|"): return ast.children[i] + if ast.children.len == 1 and ast.children[0].name == ".": + return ast.children[0] + proc getPxName*(node: TSNode, offset: int): string = var np = node diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index 8d98dde..89b3223 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -637,6 +637,23 @@ proc initGrammar(): Grammar = nimState.commentStr &= &"\n # {line.strip(leading=false)}" )) + # // unknown + result.add((&""" + (type_definition|struct_specifier|union_specifier|enum_specifier|declaration + (^.*) + ) + """, + proc (ast: ref Ast, node: TSNode, nimState: NimState) = + for i in nimState.data: + case $node.tsNodeType() + of "declaration": + if i.name == "identifier": + echo "# Unknown declaration " & i.val + else: + if i.name == "type_identifier": + echo "# Unknown type " & i.val + )) + proc initRegex(ast: ref Ast) = if ast.children.len != 0: if not ast.recursive: @@ -653,7 +670,7 @@ proc initRegex(ast: ref Ast) = raise newException(Exception, getCurrentExceptionMsg()) proc parseGrammar*(): AstTable = - let grammars = initGrammar() + const grammars = initGrammar() result = newTable[string, seq[ref Ast]]() for i in 0 .. grammars.len-1: From 3c7172983975a41d21e6aea7c4a0d6a7734926aa Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Fri, 18 Oct 2019 10:51:00 -0500 Subject: [PATCH 277/593] onSymbol for overrides --- nimterop/getters.nim | 11 +++++++++++ nimterop/grammar.nim | 16 ++++++++++++++-- nimterop/plugin.nim | 3 ++- 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 7205213..a3220ec 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -127,6 +127,17 @@ proc getIdentifier*(nimState: NimState, name: string, kind: NimSymKind, parent=" else: result = "" +proc getOverride*(nimState: NimState, name: string, kind: NimSymKind, parent=""): string = + doAssert name.len != 0, "Blank identifier error" + + if nimState.gState.onSymbol != nil: + var + nname = nimState.getIdentifier(name, kind, parent) + sym = Symbol(name: nname, parent: parent, kind: kind) + nimState.gState.onSymbol(sym) + + result = sym.override + proc getUniqueIdentifier*(nimState: NimState, prefix = ""): string = var name = prefix & "_" & nimState.sourceFile.extractFilename().multiReplace([(".", ""), ("-", "")]) diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index 89b3223..65b4935 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -648,10 +648,22 @@ proc initGrammar(): Grammar = case $node.tsNodeType() of "declaration": if i.name == "identifier": - echo "# Unknown declaration " & i.val + let + override = nimState.getOverride(i.val, nskProc) + + if override.len != 0: + nimState.procStr &= &"{nimState.getComments(true)}\n{override}" + else: + nimState.procStr &= &"{nimState.getComments(true)}\n# Unable to wrap declaration '{i.val}'" else: if i.name == "type_identifier": - echo "# Unknown type " & i.val + let + override = nimState.getOverride(i.val, nskType) + + if override.len != 0: + nimState.typeStr &= &"{nimState.getComments()}\n{override}" + else: + nimState.typeStr &= &"{nimState.getComments()}\n # Unable to wrap type '{i.val}'" )) proc initRegex(ast: ref Ast) = diff --git a/nimterop/plugin.nim b/nimterop/plugin.nim index 646c83c..333723f 100644 --- a/nimterop/plugin.nim +++ b/nimterop/plugin.nim @@ -5,5 +5,6 @@ type name*: string parent*: string kind*: NimSymKind + override*: string - OnSymbol* = proc(sym: var Symbol) {.cdecl.} \ No newline at end of file + OnSymbol* = proc(sym: var Symbol) {.cdecl.} From d3b558b291be1d6dd0885de2ef154b70ed2cfbac Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Fri, 18 Oct 2019 11:19:19 -0500 Subject: [PATCH 278/593] Fix wchar_t for nim check --- nimterop/types.nim | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/nimterop/types.nim b/nimterop/types.nim index 3dd8f39..a57252f 100644 --- a/nimterop/types.nim +++ b/nimterop/types.nim @@ -16,22 +16,21 @@ when (NimMajor, NimMinor, NimPatch) < (0, 19, 9): type time_t* = Time time64_t* = Time - wchar_t* {.importc.} = object else: import std/time_t as time_t_temp type time_t* = time_t_temp.Time time64_t* = time_t_temp.Time - when defined(c) or defined(nimdoc): - # http://www.cplusplus.com/reference/cwchar/wchar_t/ - # In C++, wchar_t is a distinct fundamental type (and thus it is - # not defined in nor any other header). - type - wchar_t* {.importc, header:"".} = object - elif defined(cpp): - type - wchar_t* {.importc.} = object +when defined(cpp): + # http://www.cplusplus.com/reference/cwchar/wchar_t/ + # In C++, wchar_t is a distinct fundamental type (and thus it is + # not defined in nor any other header). + type + wchar_t* {.importc.} = object +else: + type + wchar_t* {.importc, header:"".} = object type ptrdiff_t* = ByteAddress From 2696e900c0096b4450bd1130aa4d762a03c3177f Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Sun, 20 Oct 2019 22:54:20 -0500 Subject: [PATCH 279/593] getOverride and Final --- nimterop/ast.nim | 5 ++- nimterop/cimport.nim | 100 ++++++++++++++++++++++++++++++++----------- nimterop/getters.nim | 30 ++++++++++--- nimterop/globals.nim | 5 ++- nimterop/grammar.nim | 29 +++++++++---- nimterop/plugin.nim | 14 +++++- tests/zlib.nim | 5 ++- 7 files changed, 142 insertions(+), 46 deletions(-) diff --git a/nimterop/ast.nim b/nimterop/ast.nim index c4294dc..1617ea4 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -1,4 +1,4 @@ -import os, sets, strformat, strutils, tables, times +import macros, os, sets, strformat, strutils, tables, times import regex @@ -187,6 +187,7 @@ proc printNim*(gState: State, fullpath: string, root: TSNode, astTable: AstTable if nimState.enumStr.nBl: echo &"{nimState.enumStr}\n" + nimState.constStr = nimState.getOverrideFinal(nskConst) & nimState.constStr if nimState.constStr.nBl: echo &"const{nimState.constStr}\n" @@ -195,9 +196,11 @@ proc printNim*(gState: State, fullpath: string, root: TSNode, astTable: AstTable {{.pragma: {nimState.impShort}C, {nimState.impShort}, cdecl{nimState.getDynlib()}.}} """ + nimState.typeStr = nimState.getOverrideFinal(nskType) & nimState.typeStr if nimState.typeStr.nBl: echo &"type{nimState.typeStr}\n" + nimState.procStr = nimState.getOverrideFinal(nskProc) & nimState.procStr if nimState.procStr.nBl: echo &"{nimState.procStr}\n" diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index cea859a..6eddd0b 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -201,22 +201,64 @@ macro cOverride*(body): untyped = ## `cOverride() `_ only affects calls to ## `cImport() `_ that follow it. - proc recFindIdent(node: NimNode): seq[string] = - if node.kind != nnkIdent: - for child in node: - result.add recFindIdent(child) - if result.len != 0 and node.kind notin [nnkTypeSection, nnkConstSection]: - break - elif $node != "*": - result.add $node + iterator findOverrides(node: NimNode): tuple[name, override: string, kind: NimNodeKind] = + for child in node: + case child.kind + of nnkTypeSection, nnkConstSection: + # Types, const + for inst in child: + let name = + if inst[0].kind == nnkPragmaExpr: + $inst[0][0] + else: + $inst[0] - for sym in body: - gStateCT.symOverride.add recFindIdent(sym) + yield (name.strip(chars={'*'}), inst.repr, child.kind) + of nnkProcDef: + let + name = $child[0] - result = body + yield (name.strip(chars={'*'}), child.repr, child.kind) + else: + discard - if gStateCT.debug: - echo "# Overriding " & gStateCT.symOverride.join(" ") + if gStateCT.overrides.len == 0: + gStateCT.overrides = """ +import sets, tables + +proc onSymbolOverride*(sym: var Symbol) {.exportc, dynlib.} = +""" + + # If cPlugin called before cOverride + if gStateCT.pluginSourcePath.len != 0: + gStateCT.pluginSourcePath = "" + + var + names: seq[string] + for name, override, kind in body.findOverrides(): + let + typ = + case kind + of nnkTypeSection: "nskType" + of nnkConstSection: "nskConst" + of nnkProcDef: "nskProc" + else: "" + + gStateCT.overrides &= &""" + if sym.name == "{name}" and sym.kind == {typ} and "{name}" in cOverrides["{typ}"]: + sym.override = """ & "\"\"\"" & override & "\"\"\"\n" + + gStateCT.overrides &= &" cOverrides[\"{typ}\"].excl \"{name}\"\n" + + gStateCT.overrides = gStateCT.overrides.replace("proc onSymbolOverride", + &"cOverrides[\"{typ}\"].incl \"{name}\"\nproc onSymbolOverride") + + names.add name + + gStateCT.symOverride.add name + + if gStateCT.debug and names.len != 0: + echo "# Overriding " & names.join(" ") proc cSkipSymbol*(skips: seq[string]) {.compileTime.} = ## Similar to `cOverride() `_, this macro allows @@ -228,6 +270,22 @@ proc cSkipSymbol*(skips: seq[string]) {.compileTime.} = static: cSkipSymbol @["proc1", "Type2"] gStateCT.symOverride.add skips +proc cPluginHelper(body: string) = + gStateCT.pluginSource = body + + let + data = "import macros, nimterop/plugin\n\n" & body & gStateCT.overrides + hash = data.hash().abs() + path = getProjectCacheDir("cPlugins", forceClean = false) / "nimterop_" & $hash & ".nim" + + if not fileExists(path) or gStateCT.nocache or compileOption("forceBuild"): + mkDir(path.parentDir()) + writeFile(path, data) + + doAssert fileExists(path), "Unable to write plugin file: " & path + + gStateCT.pluginSourcePath = path + macro cPlugin*(body): untyped = ## When `cOverride() `_ and ## `cSkipSymbol() `_ @@ -276,18 +334,7 @@ macro cPlugin*(body): untyped = if sym.kind == nskProc and sym.name.contains("SDL_"): sym.name = sym.name.replace("SDL_", "") - let - data = "import macros, nimterop/plugin\n\n" & body.repr - hash = data.hash().abs() - path = getProjectCacheDir("cPlugins", forceClean = false) / "nimterop_" & $hash & ".nim" - - if not fileExists(path) or gStateCT.nocache or compileOption("forceBuild"): - mkDir(path.parentDir()) - writeFile(path, data) - - doAssert fileExists(path), "Unable to write plugin file: " & path - - gStateCT.pluginSourcePath = path + cPluginHelper(body.repr) proc cSearchPath*(path: string): string {.compileTime.}= ## Get full path to file or directory `path` in search path configured @@ -529,6 +576,9 @@ macro cImport*(filename: static string, recurse: static bool = false, dynlib: st let fullpath = findPath(filename) + if gStateCT.overrides.len != 0 and gStateCT.pluginSourcePath.len == 0: + cPluginHelper(gStateCT.pluginSource) + echo "# Importing " & fullpath.sanitizePath let diff --git a/nimterop/getters.nim b/nimterop/getters.nim index a3220ec..ff7053a 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -127,17 +127,28 @@ proc getIdentifier*(nimState: NimState, name: string, kind: NimSymKind, parent=" else: result = "" -proc getOverride*(nimState: NimState, name: string, kind: NimSymKind, parent=""): string = +proc getOverride*(nimState: NimState, name: string, kind: NimSymKind): string = doAssert name.len != 0, "Blank identifier error" - if nimState.gState.onSymbol != nil: + if nimState.gState.onSymbolOverride != nil: var - nname = nimState.getIdentifier(name, kind, parent) - sym = Symbol(name: nname, parent: parent, kind: kind) - nimState.gState.onSymbol(sym) + nname = nimState.getIdentifier(name, kind, "Parent") + sym = Symbol(name: nname, kind: kind) + nimState.gState.onSymbolOverride(sym) result = sym.override +proc getOverrideFinal*(nimState: NimState, kind: NimSymKind): string = + let + typ = $kind + + if nimState.gState.onSymbolOverrideFinal != nil: + for i in nimState.gState.onSymbolOverrideFinal(typ): + result &= "\n" & nimState.getOverride(i, kind) + + if kind != nskProc: + result = result.replace(re"(?m)^(.*?)$", " $1") + proc getUniqueIdentifier*(nimState: NimState, prefix = ""): string = var name = prefix & "_" & nimState.sourceFile.extractFilename().multiReplace([(".", ""), ("-", "")]) @@ -155,7 +166,9 @@ proc addNewIdentifer*(nimState: NimState, name: string): bool = nimName = name[0] & name[1 .. ^1].replace("_", "").toLowerAscii if nimState.identifiers.hasKey(nimName): - doAssert name == nimState.identifiers[nimName], &"Identifier '{name}' is a stylistic duplicate of identifier '{nimState.identifiers[nimName]}', use 'cPlugin:onSymbol()' to rename" + doAssert name == nimState.identifiers[nimName], + &"Identifier '{name}' is a stylistic duplicate of identifier " & + &"'{nimState.identifiers[nimName]}', use 'cPlugin:onSymbol()' to rename" result = false else: nimState.identifiers[nimName] = name @@ -463,7 +476,10 @@ proc loadPlugin*(gState: State, sourcePath: string) = doAssert lib != nil, "Plugin $1 compiled to $2 failed to load" % [sourcePath, pdll] gState.onSymbol = cast[OnSymbol](lib.symAddr("onSymbol")) - doAssert gState.onSymbol != nil, "onSymbol() load failed from " & pdll + + gState.onSymbolOverride = cast[OnSymbol](lib.symAddr("onSymbolOverride")) + + gState.onSymbolOverrideFinal = cast[OnSymbolOverrideFinal](lib.symAddr("onSymbolOverrideFinal")) proc expandSymlinkAbs*(path: string): string = try: diff --git a/nimterop/globals.nim b/nimterop/globals.nim index 8fd8fe9..428d927 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -57,9 +57,10 @@ type nocache*, nocomments*, debug*, past*, preprocess*, pnim*, pretty*, recurse*: bool - code*, dynlib*, mode*, nim*, pluginSourcePath*: string + code*, dynlib*, mode*, nim*, overrides*, pluginSource*, pluginSourcePath*: string - onSymbol*: OnSymbol + onSymbol*, onSymbolOverride*: OnSymbol + onSymbolOverrideFinal*: OnSymbolOverrideFinal NimState {.used.} = ref object identifiers*: TableRef[string, string] diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index 65b4935..5bd8cba 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -20,14 +20,22 @@ proc initGrammar(): Grammar = nimState.debugStr &= "\n# define X Y" let + name = nimState.getIdentifier(nimState.data[0].val, nskConst) val = nimState.data[1].val.getLit() - if val.nBl: - let - name = nimState.getIdentifier(nimState.data[0].val, nskConst) + if name.nBl: + if val.nBl: + if nimState.addNewIdentifer(name): + nimState.constStr &= &"{nimState.getComments()}\n {name}* = {val}" + else: + let + override = nimState.getOverride(name, nskConst) - if name.nBl and nimState.addNewIdentifer(name): - nimState.constStr &= &"{nimState.getComments()}\n {name}* = {val}" + if override.len != 0: + if nimState.addNewIdentifer(name): + nimState.constStr &= &"{nimState.getComments()}\n {override}" + else: + nimState.constStr &= &"{nimState.getComments()}\n # Const '{name}' skipped" )) let @@ -653,17 +661,22 @@ proc initGrammar(): Grammar = if override.len != 0: nimState.procStr &= &"{nimState.getComments(true)}\n{override}" + break else: - nimState.procStr &= &"{nimState.getComments(true)}\n# Unable to wrap declaration '{i.val}'" + nimState.procStr &= &"{nimState.getComments(true)}\n# Declaration '{i.val}' skipped" + else: if i.name == "type_identifier": let override = nimState.getOverride(i.val, nskType) if override.len != 0: - nimState.typeStr &= &"{nimState.getComments()}\n{override}" + let + override = override.replace(re"(?m)^(.*?)$", " $1") + nimState.typeStr &= &"{nimState.getComments()}\n{override} #" & $nimState.data else: - nimState.typeStr &= &"{nimState.getComments()}\n # Unable to wrap type '{i.val}'" + nimState.typeStr &= &"{nimState.getComments()}\n # Type '{i.val}' skipped" + )) proc initRegex(ast: ref Ast) = diff --git a/nimterop/plugin.nim b/nimterop/plugin.nim index 333723f..3769142 100644 --- a/nimterop/plugin.nim +++ b/nimterop/plugin.nim @@ -1,4 +1,4 @@ -import macros +import macros, sets, tables type Symbol* = object @@ -8,3 +8,15 @@ type override*: string OnSymbol* = proc(sym: var Symbol) {.cdecl.} + OnSymbolOverrideFinal* = proc(typ: string): HashSet[string] {.cdecl.} + +var + cOverrides*: Table[string, HashSet[string]] + +cOverrides = initTable[string, HashSet[string]]() +cOverrides["nskType"] = initSet[string]() +cOverrides["nskConst"] = initSet[string]() +cOverrides["nskProc"] = initSet[string]() + +proc onSymbolOverrideFinal*(typ: string): HashSet[string] {.exportc, dynlib.} = + result = cOverrides[typ] diff --git a/tests/zlib.nim b/tests/zlib.nim index 036b50c..ce26c9a 100644 --- a/tests/zlib.nim +++ b/tests/zlib.nim @@ -48,8 +48,9 @@ cOverride: z_crc_t = culong alloc_func* {.importc.} = proc(opaque: voidpf, items, size: uint) {.cdecl.} Bytef {.importc.} = object - - when defined(posix): + +when defined(posix): + cOverride: type pthread_mutex_s = object pthread_cond_s = object From 8eb950d46df86466798e239efc60e864da345921 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 21 Oct 2019 09:58:24 -0500 Subject: [PATCH 280/593] Fix tmath __ --- tests/tmath.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/tmath.nim b/tests/tmath.nim index b2f803b..9f3df79 100644 --- a/tests/tmath.nim +++ b/tests/tmath.nim @@ -20,7 +20,7 @@ cPlugin: import strutils proc onSymbol*(sym: var Symbol) {.exportc, dynlib.} = - sym.name = sym.name.strip(chars={'_'}) + sym.name = sym.name.strip(chars={'_'}).replace("__", "_") cImport cSearchPath("math.h") From 35cd391ecd62b6c0c4e9d28ebde0af0d9f68e5e0 Mon Sep 17 00:00:00 2001 From: matkuki Date: Mon, 21 Oct 2019 21:18:01 +0200 Subject: [PATCH 281/593] Fix for Windows drive changes This adds a drive change command to every Windows `execAction` call that starts with the `cd` command. Tested with the `libmodbus` C library (https://github.com/stephane/libmodbus). --- nimterop/build.nim | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/nimterop/build.nim b/nimterop/build.nim index f96593e..c1eb7ee 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -29,7 +29,14 @@ proc execAction*(cmd: string, retry = 0, nostderr = false): string = ccmd = "" ret = 0 when defined(Windows): - ccmd = "cmd /c " & cmd + var filteredCmd = cmd + if cmd.startsWith("cd"): + var + colonIndex = cmd.find(":") + driveLetter = cmd.substr(colonIndex-1, colonIndex) + if driveLetter[0].isAlphaAscii() and driveLetter[1] == ':': + filteredCmd = &"{driveLetter} && {cmd}" + ccmd = "cmd /c " & filteredCmd elif defined(posix): ccmd = cmd else: From 9b6469ca97b8614e6634379e8b7290b7dc4c8606 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 21 Oct 2019 18:43:53 -0500 Subject: [PATCH 282/593] Override known, addIdentifier --- nimterop/cimport.nim | 8 +++---- nimterop/getters.nim | 50 +++++++++++++++++++++++--------------------- nimterop/grammar.nim | 48 +++++++++++++++++++++++++----------------- 3 files changed, 59 insertions(+), 47 deletions(-) diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index 6eddd0b..87d5ba6 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -172,8 +172,8 @@ proc getToast(fullpath: string, recurse: bool = false, dynlib: string = "", macro cOverride*(body): untyped = ## When the wrapper code generated by nimterop is missing certain symbols or not ## accurate, it may be required to hand wrap them. Define them in a - ## `cOverride() `_ macro block so that Nimterop no - ## longer defines these symbols. + ## `cOverride() `_ macro block so that Nimterop uses + ## these definitions instead. ## ## For example: ## @@ -195,8 +195,8 @@ macro cOverride*(body): untyped = ## proc svGetCallerInfo(fileName: var cstring; lineNumber: var cint) ## ## Using the `cOverride() `_ block, nimterop - ## can be instructed to skip over `svGetCallerInfo()`. This works for procs, - ## consts and types. + ## can be instructed to use this definition of `svGetCallerInfo()` instead. + ## This works for procs, consts and types. ## ## `cOverride() `_ only affects calls to ## `cImport() `_ that follow it. diff --git a/nimterop/getters.nim b/nimterop/getters.nim index ff7053a..9970981 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -127,28 +127,6 @@ proc getIdentifier*(nimState: NimState, name: string, kind: NimSymKind, parent=" else: result = "" -proc getOverride*(nimState: NimState, name: string, kind: NimSymKind): string = - doAssert name.len != 0, "Blank identifier error" - - if nimState.gState.onSymbolOverride != nil: - var - nname = nimState.getIdentifier(name, kind, "Parent") - sym = Symbol(name: nname, kind: kind) - nimState.gState.onSymbolOverride(sym) - - result = sym.override - -proc getOverrideFinal*(nimState: NimState, kind: NimSymKind): string = - let - typ = $kind - - if nimState.gState.onSymbolOverrideFinal != nil: - for i in nimState.gState.onSymbolOverrideFinal(typ): - result &= "\n" & nimState.getOverride(i, kind) - - if kind != nskProc: - result = result.replace(re"(?m)^(.*?)$", " $1") - proc getUniqueIdentifier*(nimState: NimState, prefix = ""): string = var name = prefix & "_" & nimState.sourceFile.extractFilename().multiReplace([(".", ""), ("-", "")]) @@ -160,8 +138,8 @@ proc getUniqueIdentifier*(nimState: NimState, prefix = ""): string = return name & $count -proc addNewIdentifer*(nimState: NimState, name: string): bool = - if name notin nimState.gState.symOverride: +proc addNewIdentifer*(nimState: NimState, name: string, override = false): bool = + if override or name notin nimState.gState.symOverride: let nimName = name[0] & name[1 .. ^1].replace("_", "").toLowerAscii @@ -174,6 +152,30 @@ proc addNewIdentifer*(nimState: NimState, name: string): bool = nimState.identifiers[nimName] = name result = true +proc getOverride*(nimState: NimState, name: string, kind: NimSymKind): string = + doAssert name.len != 0, "Blank identifier error" + + if nimState.gState.onSymbolOverride != nil: + var + nname = nimState.getIdentifier(name, kind, "Override") + sym = Symbol(name: nname, kind: kind) + if nname.nBl: + nimState.gState.onSymbolOverride(sym) + + if sym.override.len != 0 and nimState.addNewIdentifer(nname, override = true): + result = sym.override + + if kind != nskProc: + result = result.replace(re"(?m)^(.*?)$", " $1") + +proc getOverrideFinal*(nimState: NimState, kind: NimSymKind): string = + let + typ = $kind + + if nimState.gState.onSymbolOverrideFinal != nil: + for i in nimState.gState.onSymbolOverrideFinal(typ): + result &= "\n" & nimState.getOverride(i, kind) + proc getPtrType*(str: string): string = result = case str: of "ptr cchar": diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index 5bd8cba..767c8f8 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -20,22 +20,19 @@ proc initGrammar(): Grammar = nimState.debugStr &= "\n# define X Y" let - name = nimState.getIdentifier(nimState.data[0].val, nskConst) + name = nimState.data[0].val + nname = nimState.getIdentifier(name, nskConst) val = nimState.data[1].val.getLit() - if name.nBl: - if val.nBl: - if nimState.addNewIdentifer(name): - nimState.constStr &= &"{nimState.getComments()}\n {name}* = {val}" + if not nname.nBl: + let + override = nimState.getOverride(name, nskConst) + if override.len != 0: + nimState.constStr &= &"{nimState.getComments()}\n{override}" else: - let - override = nimState.getOverride(name, nskConst) - - if override.len != 0: - if nimState.addNewIdentifer(name): - nimState.constStr &= &"{nimState.getComments()}\n {override}" - else: - nimState.constStr &= &"{nimState.getComments()}\n # Const '{name}' skipped" + nimState.constStr &= &"{nimState.getComments()}\n # Const '{name}' skipped" + elif val.nBl and nimState.addNewIdentifer(nname): + nimState.constStr &= &"{nimState.getComments()}\n {nname}* = {val}" )) let @@ -183,7 +180,12 @@ proc initGrammar(): Grammar = let pragma = nimState.getPragma(pragmas) - if nname notin gTypeMap and typ.nBl and nname.nBl and nimState.addNewIdentifer(nname): + if not nname.nBl: + let + override = nimState.getOverride(name, nskType) + if override.len != 0: + nimState.typeStr &= &"{nimState.getComments()}\n{override}" + elif nname notin gTypeMap and typ.nBl and nimState.addNewIdentifer(nname): if i < nimState.data.len and nimState.data[^1].name == "function_declarator": var fname = nname @@ -274,7 +276,12 @@ proc initGrammar(): Grammar = union = ", union" break - if nname.nBl and nimState.addNewIdentifer(nname): + if not nname.nBl: + let + override = nimState.getOverride(name, nskType) + if override.len != 0: + nimState.typeStr &= &"{nimState.getComments()}\n{override}" + elif nimState.addNewIdentifer(nname): if nimState.data.len == 1: nimState.typeStr &= &"{nimState.getComments()}\n {nname}* {{.bycopy{union}.}} = object" else: @@ -612,7 +619,12 @@ proc initGrammar(): Grammar = if pout.len != 0 and pout[^2 .. ^1] == ", ": pout = pout[0 .. ^3] - if fnname.nBl and nimState.addNewIdentifer(fnname): + if not fnname.nBl: + let + override = nimState.getOverride(fname, nskProc) + if override.len != 0: + nimState.typeStr &= &"{nimState.getComments()}\n{override}" + elif nimState.addNewIdentifer(fnname): let ftyp = nimState.getIdentifier(nimState.data[0].val, nskType, fnname).getType() pragma = nimState.getPragma(nimState.getImportC(fname, fnname), "cdecl") @@ -671,9 +683,7 @@ proc initGrammar(): Grammar = override = nimState.getOverride(i.val, nskType) if override.len != 0: - let - override = override.replace(re"(?m)^(.*?)$", " $1") - nimState.typeStr &= &"{nimState.getComments()}\n{override} #" & $nimState.data + nimState.typeStr &= &"{nimState.getComments()}\n{override}" else: nimState.typeStr &= &"{nimState.getComments()}\n # Type '{i.val}' skipped" From 5f9a59fcc676170bf465d95971e700ca16959385 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 21 Oct 2019 21:42:09 -0500 Subject: [PATCH 283/593] Test cases for cOverride --- tests/include/test.c | 8 ++++++++ tests/include/test.h | 25 +++++++++++++++++++++++++ tests/tnimterop_c.nim | 41 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+) diff --git a/tests/include/test.c b/tests/include/test.c index 18e444f..e9cb2aa 100644 --- a/tests/include/test.c +++ b/tests/include/test.c @@ -75,3 +75,11 @@ void *multiline2(void) { } void multiline3(void) {} + +int weirdfunc(char ***apple) { + return 1; +} + +int weirdfunc2(char **apple) { + return 2; +} diff --git a/tests/include/test.h b/tests/include/test.h index d062277..667f384 100644 --- a/tests/include/test.h +++ b/tests/include/test.h @@ -167,6 +167,31 @@ enum TDEFL_BOGUS_3 = TDEFL_OUT_BUF_SIZE / TDEFL_BOGUS_1 }; +// cOverride +struct foo { int foo[8][1]; }; + +typedef struct tagBITMAPINFOHEADER{ + int biClrImportant; +} BITMAPINFOHEADER, * pBITMAPINFOHEADER; + +#define BIT 123u + +#define BIT2 123u + +#define BIT3 123 + +typedef int ABC; + +typedef int DEF; + +typedef struct { + int **f1; +} GHI; + +struct JKL { + int **f1; +}; + #ifdef __cplusplus } #endif diff --git a/tests/tnimterop_c.nim b/tests/tnimterop_c.nim index a289303..fb1505a 100644 --- a/tests/tnimterop_c.nim +++ b/tests/tnimterop_c.nim @@ -20,6 +20,27 @@ cPlugin: else: sym.name = sym.name.strip(chars={'_'}) +cOverride: + type + BITMAPINFOHEADER* {.bycopy.} = object + biClrImportant*: int + + Random = object + + ABC = pointer + + GHI = object + f2: ptr ptr cint + + JKL = object + f2: ptr ptr cint + + const + BIT* = 1 + + proc weirdfunc(apple: ptr ptr ptr cchar): int {.importc.} + proc weirdfunc2(mango: ptr ptr cchar): int {.importc.} + cImport cSearchPath "test.h" check TEST_INT == 512 @@ -183,3 +204,23 @@ var arr: array[5, cint] check test_array_param(arr) == nil + +# cOverride + +var + ca = weirdfunc + cb: BITMAPINFOHEADER + cc = weirdfunc2 + cd: ABC + ce: DEF + cf: GHI + cg: JKL + +cd = nil +ce = 5 +cf.f2 = nil +cg.f2 = nil + +doAssert BIT == 1 +doAssert ca(nil) == 1 +doAssert cc(nil) == 2 From 37f5faa43d446a415e8934cc1a713bb7f5c5564f Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 22 Oct 2019 14:30:24 -0500 Subject: [PATCH 284/593] 0.3.0 --- nimterop.nimble | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimterop.nimble b/nimterop.nimble index f78a010..5b6da58 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -1,6 +1,6 @@ # Package -version = "0.2.1" +version = "0.3.0" author = "genotrance" description = "C/C++ interop for Nim" license = "MIT" From 36ef771ea82fe5c775100195d55e18e960fd5cc7 Mon Sep 17 00:00:00 2001 From: matkuki Date: Tue, 22 Oct 2019 23:36:49 +0200 Subject: [PATCH 285/593] Updated to search for "cd x:" Tested again with `libmodbus` and it works. --- nimterop/build.nim | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/nimterop/build.nim b/nimterop/build.nim index c1eb7ee..b2fbc48 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -1,4 +1,4 @@ -import macros, osproc, sets, strformat, strutils, tables +import macros, osproc, sets, strformat, strutils, regex, tables import os except findExe, sleep @@ -29,13 +29,13 @@ proc execAction*(cmd: string, retry = 0, nostderr = false): string = ccmd = "" ret = 0 when defined(Windows): - var filteredCmd = cmd - if cmd.startsWith("cd"): - var - colonIndex = cmd.find(":") - driveLetter = cmd.substr(colonIndex-1, colonIndex) - if driveLetter[0].isAlphaAscii() and driveLetter[1] == ':': - filteredCmd = &"{driveLetter} && {cmd}" + var + filteredCmd = cmd + matches: RegexMatch + if cmd.find(re"cd\s+(\D)\:", matches): + var driveLetter = cmd[matches.group(0)[0]] + filteredCmd = &"{driveLetter}: && {cmd}" + echo filteredCmd ccmd = "cmd /c " & filteredCmd elif defined(posix): ccmd = cmd From 3765862b6ee94ca661ca24a636af950bfc37d9c4 Mon Sep 17 00:00:00 2001 From: matkuki Date: Wed, 23 Oct 2019 16:53:43 +0200 Subject: [PATCH 286/593] Removed the regex stuff --- nimterop/build.nim | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/nimterop/build.nim b/nimterop/build.nim index b2fbc48..cbf9b25 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -1,4 +1,4 @@ -import macros, osproc, sets, strformat, strutils, regex, tables +import macros, osproc, sets, strformat, strutils, tables import os except findExe, sleep @@ -29,13 +29,15 @@ proc execAction*(cmd: string, retry = 0, nostderr = false): string = ccmd = "" ret = 0 when defined(Windows): - var - filteredCmd = cmd - matches: RegexMatch - if cmd.find(re"cd\s+(\D)\:", matches): - var driveLetter = cmd[matches.group(0)[0]] - filteredCmd = &"{driveLetter}: && {cmd}" - echo filteredCmd + var filteredCmd = cmd + if cmd.toLower().startsWith("cd"): + var + colonIndex = cmd.find(":") + driveLetter = cmd.substr(colonIndex-1, colonIndex) + if (driveLetter[0].isAlphaAscii() and + driveLetter[1] == ':' and + colonIndex == 4): + filteredCmd = &"{driveLetter} && {cmd}" ccmd = "cmd /c " & filteredCmd elif defined(posix): ccmd = cmd From 8e9bd0da0d321f5548d90c34debaaf7dec780bda Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 24 Oct 2019 18:56:46 -0500 Subject: [PATCH 287/593] Add incompleteStruct pragma --- nimterop/grammar.nim | 3 +++ 1 file changed, 3 insertions(+) diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index 767c8f8..2d5cefb 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -216,6 +216,9 @@ proc initGrammar(): Grammar = nimState.typeStr &= &"{nimState.getComments()}\n {nname}*{pragma} = {aptr}array[{flen}, {getPtrType(tptr&typ)}]" else: if nname == typ: + pragmas.add "incompleteStruct" + let + pragma = nimState.getPragma(pragmas) nimState.typeStr &= &"{nimState.getComments()}\n {nname}*{pragma} = object" else: nimState.typeStr &= &"{nimState.getComments()}\n {nname}*{pragma} = {getPtrType(tptr&typ)}" From b7c7f7a06a006ee07eb9f6adf1fd3e50b0758fc0 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Fri, 25 Oct 2019 14:30:38 -0500 Subject: [PATCH 288/593] Fix size_t conversion --- nimterop/getters.nim | 4 ++-- tests/tpcre.nim | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 9970981..558e687 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -46,12 +46,12 @@ const gTypeMap* = { "int": "cint", "signed": "cint", "signed int": "cint", - "ssize_t": "cint", + "ssize_t": "int", "unsigned": "cuint", "unsigned int": "cuint", "uInt": "cuint", "u_int": "cuint", - "size_t": "cuint", + "size_t": "uint", # long "long": "clong", diff --git a/tests/tpcre.nim b/tests/tpcre.nim index 41809cb..0aa5a3b 100644 --- a/tests/tpcre.nim +++ b/tests/tpcre.nim @@ -34,7 +34,7 @@ cImport(pcreH, dynlib="dynpcre") echo version() -proc my_malloc(a1: cuint) {.cdecl.} = +proc my_malloc(a1: uint) {.cdecl.} = discard malloc = my_malloc From 1bca308ac472796329c212410ae198c0e31d3acb Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Fri, 25 Oct 2019 15:11:07 -0500 Subject: [PATCH 289/593] v0.3.1 --- nimterop.nimble | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimterop.nimble b/nimterop.nimble index 5b6da58..0e9c402 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -1,6 +1,6 @@ # Package -version = "0.3.0" +version = "0.3.1" author = "genotrance" description = "C/C++ interop for Nim" license = "MIT" From 872873c07a0a85117da73c4a27a806d90029a4f7 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 28 Oct 2019 10:48:53 -0500 Subject: [PATCH 290/593] Regex improvements --- nimterop/getters.nim | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 558e687..d9eb478 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -102,7 +102,7 @@ proc checkIdentifier(name, kind, parent, origName: string) = doAssert name[0] != '_' and name[^1] != '_', errmsg & " leading/trailing underscores '_'" - doAssert (not name.contains(re"_[_]+")): errmsg & " more than one consecutive underscore '_'" + doAssert (not name.contains("__")): errmsg & " consecutive underscores '_'" if parent.nBl: doAssert name.nBl, &"Blank identifier, originally '{parentStr}{name}' ({kind}), cannot be empty" @@ -191,11 +191,10 @@ proc getPtrType*(str: string): string = proc getLit*(str: string): string = let - str = str.replace(re"//.*?$", "").replace(re"/\*.*?\*/", "").strip() + str = str.replace(re"/[/*].*?(?:\*/)?$", "").strip() - if str.contains(re"^[\-]?[\d]+$") or - str.contains(re"^[\-]?[\d]*\.[\d]+$") or - str.contains(re"^0x[\d]+$"): + if str.contains(re"^[\-]?[\d]*[.]?[\d]+$") or + str.contains(re"^0x[\da-fA-F]+$"): return str proc getNodeVal*(nimState: NimState, node: TSNode): string = @@ -211,7 +210,7 @@ proc getLineCol*(gState: State, node: TSNode): tuple[line, col: int] = result.col += 1 proc getCurrentHeader*(fullpath: string): string = - ("header" & fullpath.splitFile().name.replace(re"[-.]+", "")) + ("header" & fullpath.splitFile().name.multiReplace([(".", ""), ("-", "")])) proc removeStatic(content: string): string = ## Replace static function bodies with a semicolon and commented @@ -269,12 +268,11 @@ proc getPreprocessor*(gState: State, fullpath: string, mode = "cpp"): string = if start: if "#undef" in line: continue - rdata.add( - line. - replace("__restrict", ""). - replace(re"__attribute__[ ]*\(\(.*?\)\)([ ,;])", "$1") - ) - return rdata.join("\n").removeStatic() + rdata.add line + return rdata.join("\n"). + replace("__restrict", ""). + replace(re"__attribute__[ ]*\(\(.*?\)\)([ ,;])", "$1"). + removeStatic() converter toString*(kind: Kind): string = return case kind: From 1f09de2531f499160b2e766554aa1dfd8a376b95 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 28 Oct 2019 17:13:50 -0500 Subject: [PATCH 291/593] Save skipped symbols with -d --- nimterop/ast.nim | 14 +++++++++++--- nimterop/globals.nim | 2 +- nimterop/grammar.nim | 9 +++++++++ 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/nimterop/ast.nim b/nimterop/ast.nim index 1617ea4..ad724b9 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -1,4 +1,4 @@ -import macros, os, sets, strformat, strutils, tables, times +import hashes, macros, os, sets, strformat, strutils, tables, times import regex @@ -204,5 +204,13 @@ proc printNim*(gState: State, fullpath: string, root: TSNode, astTable: AstTable if nimState.procStr.nBl: echo &"{nimState.procStr}\n" - if nimState.debugStr.nBl: - echo nimState.debugStr + if nimState.gState.debug: + if nimState.debugStr.nBl: + echo nimState.debugStr + + if nimState.skipStr.nBl: + let + hash = nimState.skipStr.hash().abs() + sname = getTempDir() / &"nimterop_{$hash}.h" + echo &"# Writing skipped definitions to {sname}\n" + writeFile(sname, nimState.skipStr) diff --git a/nimterop/globals.nim b/nimterop/globals.nim index 428d927..b108a62 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -65,7 +65,7 @@ type NimState {.used.} = ref object identifiers*: TableRef[string, string] - commentStr*, constStr*, debugStr*, enumStr*, procStr*, typeStr*: string + commentStr*, constStr*, debugStr*, enumStr*, procStr*, skipStr*, typeStr*: string gState*: State diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index 2d5cefb..f942422 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -31,6 +31,8 @@ proc initGrammar(): Grammar = nimState.constStr &= &"{nimState.getComments()}\n{override}" else: nimState.constStr &= &"{nimState.getComments()}\n # Const '{name}' skipped" + if nimState.gState.debug: + nimState.skipStr &= &"\n{nimState.getNodeVal(node)}" elif val.nBl and nimState.addNewIdentifer(nname): nimState.constStr &= &"{nimState.getComments()}\n {nname}* = {val}" )) @@ -667,6 +669,8 @@ proc initGrammar(): Grammar = ) """, proc (ast: ref Ast, node: TSNode, nimState: NimState) = + var + done = false for i in nimState.data: case $node.tsNodeType() of "declaration": @@ -676,6 +680,7 @@ proc initGrammar(): Grammar = if override.len != 0: nimState.procStr &= &"{nimState.getComments(true)}\n{override}" + done = true break else: nimState.procStr &= &"{nimState.getComments(true)}\n# Declaration '{i.val}' skipped" @@ -687,9 +692,13 @@ proc initGrammar(): Grammar = if override.len != 0: nimState.typeStr &= &"{nimState.getComments()}\n{override}" + done = true + break else: nimState.typeStr &= &"{nimState.getComments()}\n # Type '{i.val}' skipped" + if nimState.gState.debug and not done: + nimState.skipStr &= &"\n{nimState.getNodeVal(node)}" )) proc initRegex(ast: ref Ast) = From 12cc08900d1bfd39579164567acad75ca021a86b Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 29 Oct 2019 09:31:59 -0500 Subject: [PATCH 292/593] v0.3.2 --- nimterop.nimble | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimterop.nimble b/nimterop.nimble index 0e9c402..d8d0676 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -1,6 +1,6 @@ # Package -version = "0.3.1" +version = "0.3.2" author = "genotrance" description = "C/C++ interop for Nim" license = "MIT" From 36726e2442f9e78afda7906b1765e02432ff9489 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Fri, 1 Nov 2019 16:26:57 -0500 Subject: [PATCH 293/593] Fix #149 - cOverride injecting multiple times --- nimterop/ast.nim | 8 +++---- nimterop/build.nim | 2 +- nimterop/cimport.nim | 54 ++++++++++++++++++++++++-------------------- nimterop/getters.nim | 30 ++++++++++++------------ nimterop/globals.nim | 6 ++++- nimterop/grammar.nim | 40 ++++++++++++++++---------------- nimterop/lisp.nim | 2 +- nimterop/toast.nim | 6 ++--- 8 files changed, 79 insertions(+), 69 deletions(-) diff --git a/nimterop/ast.nim b/nimterop/ast.nim index ad724b9..d810764 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -78,9 +78,9 @@ proc searchAstForNode(ast: ref Ast, node: TSNode, nimState: NimState): bool = nimState.nodeBranch.add $node.tsNodeType() echo "#" & spaces(nimState.nodeBranch.len * 2) & nimState.nodeBranch[^1] - if ast.children.len != 0: + if ast.children.nBl: if childNames.contains(ast.regex) or - (childNames.len == 0 and ast.recursive): + (childNames.Bl and ast.recursive): if node.getTSNodeNamedChildCountSansComments() != 0: var flag = true @@ -110,7 +110,7 @@ proc searchAstForNode(ast: ref Ast, node: TSNode, nimState: NimState): bool = if nimState.gState.debug: discard nimState.nodeBranch.pop() - if nimstate.nodeBranch.len == 0: + if nimstate.nodeBranch.Bl: echo "" proc searchAst(root: TSNode, astTable: AstTable, nimState: NimState) = @@ -179,7 +179,7 @@ proc printNim*(gState: State, fullpath: string, root: TSNode, astTable: AstTable nimState.impShort = nimState.currentHeader.replace("header", "imp") nimState.sourceFile = fullpath - if nimState.gState.dynlib.len == 0: + if nimState.gState.dynlib.Bl: nimState.constStr &= &"\n {nimState.currentHeader} {{.used.}} = \"{fp}\"" root.searchAst(astTable, nimState) diff --git a/nimterop/build.nim b/nimterop/build.nim index cbf9b25..6f9c47e 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -34,7 +34,7 @@ proc execAction*(cmd: string, retry = 0, nostderr = false): string = var colonIndex = cmd.find(":") driveLetter = cmd.substr(colonIndex-1, colonIndex) - if (driveLetter[0].isAlphaAscii() and + if (driveLetter[0].isAlphaAscii() and driveLetter[1] == ':' and colonIndex == 4): filteredCmd = &"{driveLetter} && {cmd}" diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index 87d5ba6..aabeadc 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -48,7 +48,7 @@ proc walkDirImpl(indir, inext: string, file=true): seq[string] = let dir = joinPathIfRel(getProjectPath(), indir) ext = - if inext.len != 0: + if inext.nBl: when not defined(Windows): "-name " & inext else: @@ -100,7 +100,7 @@ proc getToastError(output: string): string = result &= "\n\nERROR:$1\n" % line.split("fatal error:")[1] # Toast error - if result.len == 0: + if result.Bl: result = "\n\n" & output proc getNimCheckError(output: string): tuple[tmpFile, errors: string] = @@ -139,7 +139,7 @@ proc getToast(fullpath: string, recurse: bool = false, dynlib: string = "", if recurse: cmd.add " --recurse" - if flags.len != 0: + if flags.nBl: cmd.add flags for i in gStateCT.defines: @@ -151,10 +151,10 @@ proc getToast(fullpath: string, recurse: bool = false, dynlib: string = "", if not noNimout: cmd.add &" --pnim" - if dynlib.len != 0: + if dynlib.nBl: cmd.add &" --dynlib={dynlib}" - if gStateCT.symOverride.len != 0: + if gStateCT.symOverride.nBl: cmd.add &" --symOverride={gStateCT.symOverride.join(\",\")}" when (NimMajor, NimMinor, NimPatch) >= (0, 19, 9): @@ -222,7 +222,7 @@ macro cOverride*(body): untyped = else: discard - if gStateCT.overrides.len == 0: + if gStateCT.overrides.Bl: gStateCT.overrides = """ import sets, tables @@ -230,7 +230,7 @@ proc onSymbolOverride*(sym: var Symbol) {.exportc, dynlib.} = """ # If cPlugin called before cOverride - if gStateCT.pluginSourcePath.len != 0: + if gStateCT.pluginSourcePath.nBl: gStateCT.pluginSourcePath = "" var @@ -257,7 +257,7 @@ proc onSymbolOverride*(sym: var Symbol) {.exportc, dynlib.} = gStateCT.symOverride.add name - if gStateCT.debug and names.len != 0: + if gStateCT.debug and names.nBl: echo "# Overriding " & names.join(" ") proc cSkipSymbol*(skips: seq[string]) {.compileTime.} = @@ -273,18 +273,19 @@ proc cSkipSymbol*(skips: seq[string]) {.compileTime.} = proc cPluginHelper(body: string) = gStateCT.pluginSource = body - let - data = "import macros, nimterop/plugin\n\n" & body & gStateCT.overrides - hash = data.hash().abs() - path = getProjectCacheDir("cPlugins", forceClean = false) / "nimterop_" & $hash & ".nim" + if gStateCT.pluginSource.nBl or gStateCT.overrides.nBl: + let + data = "import macros, nimterop/plugin\n\n" & body & gStateCT.overrides + hash = data.hash().abs() + path = getProjectCacheDir("cPlugins", forceClean = false) / "nimterop_" & $hash & ".nim" - if not fileExists(path) or gStateCT.nocache or compileOption("forceBuild"): - mkDir(path.parentDir()) - writeFile(path, data) + if not fileExists(path) or gStateCT.nocache or compileOption("forceBuild"): + mkDir(path.parentDir()) + writeFile(path, data) - doAssert fileExists(path), "Unable to write plugin file: " & path + doAssert fileExists(path), "Unable to write plugin file: " & path - gStateCT.pluginSourcePath = path + gStateCT.pluginSourcePath = path macro cPlugin*(body): untyped = ## When `cOverride() `_ and @@ -347,11 +348,11 @@ proc cSearchPath*(path: string): string {.compileTime.}= ## `cImport() `_. result = findPath(path, fail = false) - if result.len == 0: + if result.Bl: var found = false for inc in gStateCT.searchDirs: result = findPath(inc / path, fail = false) - if result.len != 0: + if result.nBl: found = true break doAssert found, "File or directory not found: " & path & @@ -498,7 +499,7 @@ macro cCompile*(path: static string, mode = "c", exclude = ""): untyped = result = true if "_nimterop_" in file: result = false - elif exclude.len != 0: + elif exclude.nBl: for excl in exclude.split(","): if excl in file: result = false @@ -508,7 +509,7 @@ macro cCompile*(path: static string, mode = "c", exclude = ""): untyped = files = walkDirImpl(dir, ext) for f in files: - if f.len != 0 and f.notExcluded(exclude): + if f.nBl and f.notExcluded(exclude): result &= fcompile(f) if path.contains("*") or path.contains("?"): @@ -576,7 +577,8 @@ macro cImport*(filename: static string, recurse: static bool = false, dynlib: st let fullpath = findPath(filename) - if gStateCT.overrides.len != 0 and gStateCT.pluginSourcePath.len == 0: + # In case cOverride called after cPlugin + if gStateCT.pluginSourcePath.Bl: cPluginHelper(gStateCT.pluginSource) echo "# Importing " & fullpath.sanitizePath @@ -584,6 +586,10 @@ macro cImport*(filename: static string, recurse: static bool = false, dynlib: st let output = getToast(fullpath, recurse, dynlib, mode, flags) + # Reset plugin and overrides for next cImport + gStateCT.pluginSourcePath = "" + gStateCT.overrides = "" + if gStateCT.debug: echo output @@ -641,11 +647,11 @@ macro c2nImport*(filename: static string, recurse: static bool = false, dynlib: cmd = when defined(Windows): "cmd /c " else: "" cmd &= &"c2nim {hpath} --header:{header}" - if dynlib.len != 0: + if dynlib.nBl: cmd.add &" --dynlib:{dynlib}" if mode.contains("cpp"): cmd.add " --cpp" - if flags.len != 0: + if flags.nBl: cmd.add &" {flags}" for i in gStateCT.defines: diff --git a/nimterop/getters.nim b/nimterop/getters.nim index d9eb478..8e4a044 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -95,7 +95,7 @@ proc checkIdentifier(name, kind, parent, origName: string) = let parentStr = if parent.nBl: parent & ":" else: "" - if name.len != 0: + if name.nBl: let origStr = if name != origName: &", originally '{origName}' before 'cPlugin:onSymbol()', still" else: "" errmsg = &"Identifier '{parentStr}{name}' ({kind}){origStr} contains" @@ -108,7 +108,7 @@ proc checkIdentifier(name, kind, parent, origName: string) = doAssert name.nBl, &"Blank identifier, originally '{parentStr}{name}' ({kind}), cannot be empty" proc getIdentifier*(nimState: NimState, name: string, kind: NimSymKind, parent=""): string = - doAssert name.len != 0, "Blank identifier error" + doAssert name.nBl, "Blank identifier error" if name notin nimState.gState.symOverride or parent.nBl: if nimState.gState.onSymbol != nil: @@ -153,7 +153,7 @@ proc addNewIdentifer*(nimState: NimState, name: string, override = false): bool result = true proc getOverride*(nimState: NimState, name: string, kind: NimSymKind): string = - doAssert name.len != 0, "Blank identifier error" + doAssert name.nBl, "Blank identifier error" if nimState.gState.onSymbolOverride != nil: var @@ -162,7 +162,7 @@ proc getOverride*(nimState: NimState, name: string, kind: NimSymKind): string = if nname.nBl: nimState.gState.onSymbolOverride(sym) - if sym.override.len != 0 and nimState.addNewIdentifer(nname, override = true): + if sym.override.nBl and nimState.addNewIdentifer(nname, override = true): result = sym.override if kind != nskProc: @@ -257,7 +257,7 @@ proc getPreprocessor*(gState: State, fullpath: string, mode = "cpp"): string = elif gState.recurse: let pDir = sfile.expandFilename().parentDir().sanitizePath(noQuote = true) - if pDir.len == 0 or pDir in saniLine: + if pDir.Bl or pDir in saniLine: start = true else: for inc in gState.includeDirs: @@ -368,10 +368,10 @@ proc getNimExpression*(nimState: NimState, expr: string): string = for i in 0 .. clean.len: if i != clean.len: - if clean[i] == '_' and ident.len == 0: + if clean[i] == '_' and ident.Bl: gen = $clean[i] elif clean[i] in IdentChars: - if clean[i] in Digits and ident.len == 0: + if clean[i] in Digits and ident.Bl: gen = $clean[i] elif clean[i] in HexDigits and hex == true: gen = $clean[i] @@ -397,8 +397,8 @@ proc getNimExpression*(nimState: NimState, expr: string): string = ) hex = false - if i == clean.len or gen.len != 0: - if ident.len != 0: + if i == clean.len or gen.nBl: + if ident.nBl: ident = nimState.getIdentifier(ident, nskConst) result &= ident ident = "" @@ -415,14 +415,14 @@ proc getSplitComma*(joined: seq[string]): seq[string] = proc getHeader*(nimState: NimState): string = result = - if nimState.gState.dynlib.len == 0: + if nimState.gState.dynlib.Bl: &", header: {nimState.currentHeader}" else: "" proc getDynlib*(nimState: NimState): string = result = - if nimState.gState.dynlib.len != 0: + if nimState.gState.dynlib.nBl: &", dynlib: {nimState.gState.dynlib}" else: "" @@ -436,9 +436,9 @@ proc getImportC*(nimState: NimState, origName, nimName: string): string = proc getPragma*(nimState: NimState, pragmas: varargs[string]): string = result = "" for pragma in pragmas.items(): - if pragma.len != 0: + if pragma.nBl: result &= pragma & ", " - if result.len != 0: + if result.nBl: result = " {." & result[0 .. ^3] & ".}" result = result.replace(nimState.impShort & ", cdecl", nimState.impShort & "C") @@ -446,11 +446,11 @@ proc getPragma*(nimState: NimState, pragmas: varargs[string]): string = let dy = nimState.getDynlib() - if ", cdecl" in result and dy.len != 0: + if ", cdecl" in result and dy.nBl: result = result.replace(".}", dy & ".}") proc getComments*(nimState: NimState, strip = false): string = - if not nimState.gState.nocomments and nimState.commentStr.len != 0: + if not nimState.gState.nocomments and nimState.commentStr.nBl: result = "\n" & nimState.commentStr if strip: result = result.replace("\n ", "\n") diff --git a/nimterop/globals.nim b/nimterop/globals.nim index b108a62..de29385 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -81,6 +81,9 @@ var template nBl(s: typed): untyped {.used.} = (s.len != 0) +template Bl(s: typed): untyped {.used.} = + (s.len == 0) + type CompileMode = enum c, cpp, @@ -89,4 +92,5 @@ type CompileMode = enum const modeDefault {.used.} = $cpp # TODO: USE this everywhere relevant when not declared(CIMPORT): - export gAtoms, gExpressions, gEnumVals, Kind, Ast, AstTable, State, NimState, nBl, CompileMode, modeDefault + export gAtoms, gExpressions, gEnumVals, Kind, Ast, AstTable, State, NimState, + nBl, Bl, CompileMode, modeDefault diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index f942422..16e1b91 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -27,7 +27,7 @@ proc initGrammar(): Grammar = if not nname.nBl: let override = nimState.getOverride(name, nskConst) - if override.len != 0: + if override.nBl: nimState.constStr &= &"{nimState.getComments()}\n{override}" else: nimState.constStr &= &"{nimState.getComments()}\n # Const '{name}' skipped" @@ -123,7 +123,7 @@ proc initGrammar(): Grammar = pout &= &"{pname}: array[{flen}, {getPtrType(pptr&ptyp)}], " i += 1 - elif pptr.len != 0 or ptyp != "object": + elif pptr.nBl or ptyp != "object": pout &= &"{pname}: {getPtrType(pptr&ptyp)}, " # typedef int X @@ -176,7 +176,7 @@ proc initGrammar(): Grammar = nname = nimState.getIdentifier(name, nskType) i += 1 - if nimState.gState.dynlib.len == 0: + if nimState.gState.dynlib.Bl: pragmas.add nimState.getImportC(name, nname) let @@ -185,7 +185,7 @@ proc initGrammar(): Grammar = if not nname.nBl: let override = nimState.getOverride(name, nskType) - if override.len != 0: + if override.nBl: nimState.typeStr &= &"{nimState.getComments()}\n{override}" elif nname notin gTypeMap and typ.nBl and nimState.addNewIdentifer(nname): if i < nimState.data.len and nimState.data[^1].name == "function_declarator": @@ -201,10 +201,10 @@ proc initGrammar(): Grammar = funcParamCommon(fname, pname, ptyp, pptr, pout, count, i, flen) - if pout.len != 0 and pout[^2 .. ^1] == ", ": + if pout.nBl and pout[^2 .. ^1] == ", ": pout = pout[0 .. ^3] - if tptr.len != 0 or typ != "object": + if tptr.nBl or typ != "object": nimState.typeStr &= &"{nimState.getComments()}\n {nname}*{pragma} = proc({pout}): {getPtrType(tptr&typ)} {{.cdecl.}}" else: nimState.typeStr &= &"{nimState.getComments()}\n {nname}*{pragma} = proc({pout}) {{.cdecl.}}" @@ -284,7 +284,7 @@ proc initGrammar(): Grammar = if not nname.nBl: let override = nimState.getOverride(name, nskType) - if override.len != 0: + if override.nBl: nimState.typeStr &= &"{nimState.getComments()}\n{override}" elif nimState.addNewIdentifer(nname): if nimState.data.len == 1: @@ -292,10 +292,10 @@ proc initGrammar(): Grammar = else: var pragmas: seq[string] = @[] - if nimState.gState.dynlib.len == 0: + if nimState.gState.dynlib.Bl: pragmas.add nimState.getImportC(prefix & name, nname) pragmas.add "bycopy" - if union.len != 0: + if union.nBl: pragmas.add "union" let @@ -357,9 +357,9 @@ proc initGrammar(): Grammar = funcParamCommon(fname, pname, ptyp, pptr, pout, count, i, flen) - if pout.len != 0 and pout[^2 .. ^1] == ", ": + if pout.nBl and pout[^2 .. ^1] == ", ": pout = pout[0 .. ^3] - if fptr.len != 0 or ftyp != "object": + if fptr.nBl or ftyp != "object": nimState.typeStr &= &"{nimState.getComments()}\n {fname}*: proc({pout}): {getPtrType(fptr&ftyp)} {{.cdecl.}}" else: nimState.typeStr &= &"{nimState.getComments()}\n {fname}*: proc({pout}) {{.cdecl.}}" @@ -372,7 +372,7 @@ proc initGrammar(): Grammar = i += 1 if node.tsNodeType() == "type_definition" and - nimState.data[^1].name == "type_identifier" and nimState.data[^1].val.len != 0: + nimState.data[^1].name == "type_identifier" and nimState.data[^1].val.nBl: pDupTypeCommon(nname, fend, nimState, false) let @@ -473,7 +473,7 @@ proc initGrammar(): Grammar = nimState.debugStr &= "\n# pEnumCommon()" let nname = - if name.len == 0: + if name.Bl: getUniqueIdentifier(nimState, "Enum") else: nimState.getIdentifier(name, nskType) @@ -508,7 +508,7 @@ proc initGrammar(): Grammar = count += 1 if node.tsNodeType() == "type_definition" and - nimState.data[^1].name == "type_identifier" and nimState.data[^1].val.len != 0: + nimState.data[^1].name == "type_identifier" and nimState.data[^1].val.nBl: pDupTypeCommon(nname, fend, nimState, true) # enum X {} @@ -621,20 +621,20 @@ proc initGrammar(): Grammar = funcParamCommon(fnname, pname, ptyp, pptr, pout, count, i, flen) - if pout.len != 0 and pout[^2 .. ^1] == ", ": + if pout.nBl and pout[^2 .. ^1] == ", ": pout = pout[0 .. ^3] if not fnname.nBl: let override = nimState.getOverride(fname, nskProc) - if override.len != 0: + if override.nBl: nimState.typeStr &= &"{nimState.getComments()}\n{override}" elif nimState.addNewIdentifer(fnname): let ftyp = nimState.getIdentifier(nimState.data[0].val, nskType, fnname).getType() pragma = nimState.getPragma(nimState.getImportC(fname, fnname), "cdecl") - if fptr.len != 0 or ftyp != "object": + if fptr.nBl or ftyp != "object": if fVar: nimState.procStr &= &"{nimState.getComments(true)}\nvar {fnname}*: proc ({pout}): {getPtrType(fptr&ftyp)}{{.cdecl.}}" else: @@ -678,7 +678,7 @@ proc initGrammar(): Grammar = let override = nimState.getOverride(i.val, nskProc) - if override.len != 0: + if override.nBl: nimState.procStr &= &"{nimState.getComments(true)}\n{override}" done = true break @@ -690,7 +690,7 @@ proc initGrammar(): Grammar = let override = nimState.getOverride(i.val, nskType) - if override.len != 0: + if override.nBl: nimState.typeStr &= &"{nimState.getComments()}\n{override}" done = true break @@ -702,7 +702,7 @@ proc initGrammar(): Grammar = )) proc initRegex(ast: ref Ast) = - if ast.children.len != 0: + if ast.children.nBl: if not ast.recursive: for child in ast.children: child.initRegex() diff --git a/nimterop/lisp.nim b/nimterop/lisp.nim index 5c7a02a..fb488d8 100644 --- a/nimterop/lisp.nim +++ b/nimterop/lisp.nim @@ -45,7 +45,7 @@ proc readFromTokens(): ref Ast = proc printAst*(node: ref Ast, offset=""): string = result = offset & "(" & (if node.recursive: "^" else: "") & node.name & node.kind.toString() - if node.children.len != 0 and not node.recursive: + if node.children.nBl and not node.recursive: result &= "\n" for child in node.children: result &= printAst(child, offset & " ") diff --git a/nimterop/toast.nim b/nimterop/toast.nim index b66a3c6..9da8283 100644 --- a/nimterop/toast.nim +++ b/nimterop/toast.nim @@ -63,7 +63,7 @@ proc process(gState: State, path: string, astTable: AstTable) = defer: parser.tsParserDelete() - if gState.mode.len == 0: + if gState.mode.Bl: if ext in [".h", ".c"]: gState.mode = "c" elif ext in [".hxx", ".hpp", ".hh", ".H", ".h++", ".cpp", ".cxx", ".cc", ".C", ".c++"]: @@ -74,7 +74,7 @@ proc process(gState: State, path: string, astTable: AstTable) = else: gState.code = readFile(path) - doAssert gState.code.len != 0, "Empty file or preprocessor error" + doAssert gState.code.nBl, "Empty file or preprocessor error" if gState.mode == "c": doAssert parser.tsParserSetLanguage(treeSitterC()), "Failed to load C parser" @@ -141,7 +141,7 @@ proc main( astTable = parseGrammar() if pgrammar: astTable.printGrammar() - elif source.len != 0: + elif source.nBl: if gState.pnim: printNimHeader() for src in source: From 31527a82402efe58c3eef7e60b196861defe486c Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Fri, 1 Nov 2019 17:45:33 -0500 Subject: [PATCH 294/593] Update docs, minor optimization --- nimterop/cimport.nim | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index aabeadc..65a5401 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -198,8 +198,10 @@ macro cOverride*(body): untyped = ## can be instructed to use this definition of `svGetCallerInfo()` instead. ## This works for procs, consts and types. ## - ## `cOverride() `_ only affects calls to - ## `cImport() `_ that follow it. + ## `cOverride()` only affects the next `cImport()` call. This is because any + ## recognized symbols get overridden in place and any remaining symbols get + ## added to the top. If reused, the next `cImport()` would add those symbols + ## again leading to redefinition errors. iterator findOverrides(node: NimNode): tuple[name, override: string, kind: NimNodeKind] = for child in node: @@ -571,6 +573,10 @@ macro cImport*(filename: static string, recurse: static bool = false, dynlib: st ## be ignored for the foreseeable future. ## ## `flags` can be used to pass any other command line arguments to `toast`. + ## + ## `cImport()` consumes and resets preceding `cOverride()` calls. `cPlugin()` + ## is retained for the next `cImport()` call unless a new `cPlugin()` call is + ## defined. result = newNimNode(nnkStmtList) @@ -587,8 +593,9 @@ macro cImport*(filename: static string, recurse: static bool = false, dynlib: st output = getToast(fullpath, recurse, dynlib, mode, flags) # Reset plugin and overrides for next cImport - gStateCT.pluginSourcePath = "" - gStateCT.overrides = "" + if gStateCT.overrides.nBl: + gStateCT.pluginSourcePath = "" + gStateCT.overrides = "" if gStateCT.debug: echo output From 751128e75859de66e07be9888c8341fe3b553816 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Fri, 1 Nov 2019 18:13:00 -0500 Subject: [PATCH 295/593] v0.3.3 --- nimterop.nimble | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimterop.nimble b/nimterop.nimble index d8d0676..ea6a810 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -1,6 +1,6 @@ # Package -version = "0.3.2" +version = "0.3.3" author = "genotrance" description = "C/C++ interop for Nim" license = "MIT" From 41847b1ba973486f847bffbe1644ec04514d17d5 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 16 Dec 2019 11:31:30 -0600 Subject: [PATCH 296/593] nocomments passed to preprocessor, origName --- nimterop/getters.nim | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 8e4a044..53e04f8 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -105,7 +105,7 @@ proc checkIdentifier(name, kind, parent, origName: string) = doAssert (not name.contains("__")): errmsg & " consecutive underscores '_'" if parent.nBl: - doAssert name.nBl, &"Blank identifier, originally '{parentStr}{name}' ({kind}), cannot be empty" + doAssert name.nBl, &"Blank identifier, originally '{parentStr}{origName}' ({kind}), cannot be empty" proc getIdentifier*(nimState: NimState, name: string, kind: NimSymKind, parent=""): string = doAssert name.nBl, "Blank identifier error" @@ -229,7 +229,8 @@ proc removeStatic(content: string): string = proc getPreprocessor*(gState: State, fullpath: string, mode = "cpp"): string = var mmode = if mode == "cpp": "c++" else: mode - cmd = &"""{getCompiler()} -E -CC -dD -x{mmode} -w """ + cmts = if gState.nocomments: "" else: "-CC" + cmd = &"""{getCompiler()} -E {cmts} -dD -x{mmode} -w """ rdata: seq[string] = @[] start = false From c878a4be05cadd512db2182181b187de2a566ce8 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 16 Dec 2019 14:57:38 -0600 Subject: [PATCH 297/593] v0.3.4 --- nimterop.nimble | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimterop.nimble b/nimterop.nimble index ea6a810..cb45cb7 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -1,6 +1,6 @@ # Package -version = "0.3.3" +version = "0.3.4" author = "genotrance" description = "C/C++ interop for Nim" license = "MIT" From faeb43afbe8c8dfe13cada97ae2705db75246c85 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 16 Dec 2019 21:25:10 -0600 Subject: [PATCH 298/593] Fix getHeader - PCRE case where header is generated --- nimterop/build.nim | 41 +++++++++++++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/nimterop/build.nim b/nimterop/build.nim index 6f9c47e..bcc8b2b 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -896,6 +896,7 @@ macro getHeader*(header: static[string], giturl: static[string] = "", dlurl: sta var name = header.extractFilename().split(".")[0] + # -d:xxx for this header stdStr = name & "Std" gitStr = name & "Git" dlStr = name & "DL" @@ -903,20 +904,24 @@ macro getHeader*(header: static[string], giturl: static[string] = "", dlurl: sta staticStr = name & "Static" verStr = name & "SetVer" + # Ident nodes of the -d:xxx to check in when statements nameStd = newIdentNode(stdStr) nameGit = newIdentNode(gitStr) nameDL = newIdentNode(dlStr) nameStatic = newIdentNode(staticStr) + # Consts to generate path = newIdentNode(name & "Path") lpath = newIdentNode(name & "LPath") version = newIdentNode(verStr) lname = newIdentNode(name & "LName") preBuild = newIdentNode(name & "PreBuild") + # Regex for library search lre = "(lib)?$1[_]?(static)?[0-9.\\-]*\\" + # If -d:xxx set with setDefines() stdVal = gDefines.hasKey(stdStr) gitVal = gDefines.hasKey(gitStr) dlVal = gDefines.hasKey(dlStr) @@ -927,6 +932,7 @@ macro getHeader*(header: static[string], giturl: static[string] = "", dlurl: sta else: "" + # Use alternate library names if specified for regex search if altNames.len != 0: lre = lre % ("(" & altNames.replace(",", "|") & ")") else: @@ -934,12 +940,23 @@ macro getHeader*(header: static[string], giturl: static[string] = "", dlurl: sta result = newNimNode(nnkStmtList) result.add(quote do: + # Need to check -d:xxx or setDefines() const `nameStd`* = when defined(`nameStd`): true else: `stdVal` == 1 `nameGit`* = when defined(`nameGit`): true else: `gitVal` == 1 `nameDL`* = when defined(`nameDL`): true else: `dlVal` == 1 `nameStatic`* = when defined(`nameStatic`): true else: `staticVal` == 1 + # Search for header in outdir (after retrieving code) depending on -d:xxx mode + proc getPath(header, giturl, dlurl, outdir, version: string): string = + when `nameGit`: + getGitPath(header, giturl, outdir, version) + elif `nameDL`: + getDlPath(header, dlurl, outdir, version) + else: + getLocalPath(header, outdir) + + const `version`* {.strdefine.} = `verVal` `lname` = when `nameStatic`: @@ -947,37 +964,45 @@ macro getHeader*(header: static[string], giturl: static[string] = "", dlurl: sta else: `lre` & getDynlibExt() + # Look in standard path if requested by user stdPath = when `nameStd`: getStdPath(`header`) else: "" stdLPath = when `nameStd`: getStdLibPath(`lname`) else: "" - `path`* = + # Look elsewhere if requested while prioritizing standard paths + prePath = when stdPath.len != 0 and stdLPath.len != 0: stdPath - elif `nameGit`: - getGitPath(`header`, `giturl`, `outdir`, `version`) - elif `nameDL`: - getDlPath(`header`, `dlurl`, `outdir`, `version`) else: - getLocalPath(`header`, `outdir`) + getPath(`header`, `giturl`, `dlurl`, `outdir`, `version`) - when `path` != stdPath and declared(`preBuild`): + # Run preBuild hook before building library if not standard + when (prePath != stdPath or prePath.len == 0) and declared(`preBuild`): static: - `preBuild`(`outdir`, `path`) + `preBuild`(`outdir`, prePath) const + # Library binary path - build if not standard `lpath`* = when stdPath.len != 0 and stdLPath.len != 0: stdLPath else: buildLibrary(`lname`, `outdir`, `conFlags`, `cmakeFlags`, `makeFlags`) + # Header path - search again in case header is generated in build + `path`* = + if prePath.len != 0: + prePath + else: + getPath(`header`, `giturl`, `dlurl`, `outdir`, `version`) + static: doAssert `path`.len != 0, "\nHeader " & `header` & " not found - " & "missing/empty outdir or -d:$1Std -d:$1Git or -d:$1DL not specified" % `name` doAssert `lpath`.len != 0, "\nLibrary " & `lname` & " not found" echo "# Including library " & `lpath` + # Automatically link with static libary when `nameStatic`: {.passL: `lpath`.} ) From b426bc49bac77fdfc6c873c5c93702899a9794d7 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 17 Dec 2019 10:31:14 -0600 Subject: [PATCH 299/593] Print code in debug output --- nimterop/ast.nim | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/nimterop/ast.nim b/nimterop/ast.nim index d810764..fcd9411 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -6,6 +6,8 @@ import "."/[getters, globals, treesitter/api] proc saveNodeData(node: TSNode, nimState: NimState): bool = let name = $node.tsNodeType() + + # Atoms are nodes whose values are to be saved if name in gAtoms: let pname = node.getPxName(1) @@ -16,16 +18,20 @@ proc saveNodeData(node: TSNode, nimState: NimState): bool = var val = nimState.getNodeVal(node) + # Skip since value already obtained from parent atom if name == "primitive_type" and pname == "sized_type_specifier": return true + # Skip since value already obtained from parent expression if name in ["number_literal", "identifier"] and pname in gExpressions: return true + # Add reference point in saved data for bitfield_clause if name in ["number_literal"] and pname == "bitfield_clause": nimState.data.add(("bitfield_clause", val)) return true + # Process value as a type if name in ["primitive_type", "sized_type_specifier"]: val = val.getType() @@ -58,6 +64,7 @@ proc saveNodeData(node: TSNode, nimState: NimState): bool = elif name == "identifier": nimState.data.add(("pointer_declarator", "")) + # Save node value for a top-level expression elif name in gExpressions and name != "escape_sequence": if $node.tsNodeParent.tsNodeType() notin gExpressions: nimState.data.add((name, nimState.getNodeVal(node))) @@ -125,6 +132,8 @@ proc searchAst(root: TSNode, astTable: AstTable, nimState: NimState) = name = $node.tsNodeType() if name in astTable: for ast in astTable[name]: + if nimState.gState.debug: + echo "\n# " & nimState.getNodeVal(node).replace("\n", "\n# ") & "\n" if searchAstForNode(ast, node, nimState): ast.tonim(ast, node, nimState) if nimState.gState.debug: From 045065113bd87de5f155691302186997f4a47af0 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 17 Dec 2019 10:37:59 -0600 Subject: [PATCH 300/593] Bump test to 1.0.4 --- .travis.yml | 4 ++-- appveyor.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index b347f73..86e5fbc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,14 +12,14 @@ language: c env: - BRANCH=0.19.6 - BRANCH=0.20.2 - - BRANCH=1.0.0 + - BRANCH=1.0.4 - BRANCH=devel cache: directories: - "$HOME/.choosenim/toolchains/nim-0.19.6" - "$HOME/.choosenim/toolchains/nim-0.20.2" - - "$HOME/.choosenim/toolchains/nim-1.0.0" + - "$HOME/.choosenim/toolchains/nim-1.0.4" install: - export CHOOSENIM_CHOOSE_VERSION=$BRANCH diff --git a/appveyor.yml b/appveyor.yml index 0d9ba77..7678cf1 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -11,7 +11,7 @@ environment: matrix: - NIM_VERSION: 0.19.6 - NIM_VERSION: 0.20.2 - - NIM_VERSION: 1.0.0 + - NIM_VERSION: 1.0.4 for: - From c4b6a01878f0f72d428a24c26153723c60f6695f Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 17 Dec 2019 10:38:06 -0600 Subject: [PATCH 301/593] v0.3.5 --- nimterop.nimble | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimterop.nimble b/nimterop.nimble index cb45cb7..ddacfda 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -1,6 +1,6 @@ # Package -version = "0.3.4" +version = "0.3.5" author = "genotrance" description = "C/C++ interop for Nim" license = "MIT" From ad809242c839aba8fc13523d68cf99ea96817633 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 18 Dec 2019 20:49:39 -0600 Subject: [PATCH 302/593] Fix #157 - gitPull of branch --- nimterop/build.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimterop/build.nim b/nimterop/build.nim index bcc8b2b..5426548 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -299,7 +299,7 @@ proc gitPull*(url: string, outdir = "", plist = "", checkout = "") = if checkout.len != 0: echo "# Checking out " & checkout - discard execAction(&"cd {outdirQ} && git pull --tags origin master") + discard execAction(&"cd {outdirQ} && git fetch") discard execAction(&"cd {outdirQ} && git checkout {checkout}") else: echo "# Pulling repository" From 63c979ff928d60e8f28c544b091c252b9164bf65 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 18 Dec 2019 21:17:27 -0600 Subject: [PATCH 303/593] Fix #158 - array size with division --- nimterop/grammar.nim | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index 16e1b91..9f50ba4 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -332,8 +332,11 @@ proc initGrammar(): Grammar = fname = nimState.getIdentifier(nimState.data[i].val, nskField, nname) if i+1 < nimState.data.len-fend and nimState.data[i+1].name in gEnumVals: - let + # Struct field is an array where size is an expression + var flen = nimState.getNimExpression(nimState.data[i+1].val) + if "/" in flen: + flen = &"({flen}).int" nimState.typeStr &= &"{nimState.getComments()}\n {fname}*: {aptr}array[{flen}, {getPtrType(fptr&ftyp)}]" i += 2 elif i+1 < nimState.data.len-fend and nimState.data[i+1].name == "bitfield_clause": From bce8e0907368df20e04252635ab5994cfd579b7b Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 18 Dec 2019 23:49:25 -0600 Subject: [PATCH 304/593] Fix #146 - prefix/suffix for stripping --- README.md | 28 ++++++------ nimterop/cimport.nim | 29 +++++++----- nimterop/getters.nim | 13 ++++++ nimterop/globals.nim | 2 +- nimterop/toast.nim | 104 ++++++++++++++++++++++++------------------- tests/lzma.nim | 11 ++--- 6 files changed, 110 insertions(+), 77 deletions(-) diff --git a/README.md b/README.md index fcab924..502688e 100644 --- a/README.md +++ b/README.md @@ -93,23 +93,25 @@ The `toast` binary can also be used directly on the CLI: toast -h Usage: main [optional-params] C/C++ source/header - Options(opt-arg sep :|=|spc): +Options(opt-arg sep :|=|spc): -h, --help print this cligen-erated help - --help-syntax advanced: prepend, multi-val,.. - -p, --preprocess bool false run preprocessor on header - -a, --past bool false print AST output - -n, --pnim bool false print Nim output - -r, --recurse bool false process #include files - -c, --nocomments bool false exclude top-level comments from output - -D=, --defines= strings {} definitions to pass to preprocessor - -I=, --includeDirs= strings {} include directory to pass to preprocessor - -l=, --dynlib= string "" Import symbols from library in specified Nim string - -O=, --symOverride= strings {} skip generating specified symbols - --nim= string "nim" use a particular Nim executable (default: $PATH/nim) - --pluginSourcePath= string "" Nim file to build and load as a plugin + --help-syntax advanced: prepend,plurals,.. -d, --debug bool false enable debug output + -D=, --defines= strings {} definitions to pass to preprocessor + -l=, --dynlib= string "" Import symbols from library in specified Nim string + -I=, --includeDirs= strings {} include directory to pass to preprocessor -m=, --mode= string "cpp" language parser: c or cpp + --nim= string "nim" use a particular Nim executable (default: $PATH/nim) + -c, --nocomments bool false exclude top-level comments from output + -a, --past bool false print AST output -g, --pgrammar bool false print grammar + --pluginSourcePath= string "" Nim file to build and load as a plugin + -n, --pnim bool false print Nim output + -E=, --prefix= strings {} Strip prefix from identifiers + -p, --preprocess bool false run preprocessor on header + -r, --recurse bool false process #include files + -F=, --suffix= strings {} Strip suffix from identifiers + -O=, --symOverride= strings {} skip generating specified symbols ``` __Implementation Details__ diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index 65a5401..bebcf3d 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -140,7 +140,7 @@ proc getToast(fullpath: string, recurse: bool = false, dynlib: string = "", cmd.add " --recurse" if flags.nBl: - cmd.add flags + cmd.add " " & flags for i in gStateCT.defines: cmd.add &" --defines+={i.quoteShell}" @@ -300,13 +300,18 @@ macro cPlugin*(body): untyped = ## ## proc onSymbol(sym: var Symbol) {.exportc, dynlib.} ## - ## `onSymbol()` can be used to handle symbol name modifications required due to invalid - ## characters like leading/trailing `_` or rename symbols that would clash due to Nim's style - ## insensitivity. It can also be used to remove prefixes and suffixes like `SDL_`. The symbol - ## name and type is provided to the callback and the name can be modified. + ## `onSymbol()` can be used to handle symbol name modifications required due + ## to invalid characters in identifiers or to rename symbols that would clash + ## due to Nim's style insensitivity. The symbol name and type is provided to + ## the callback and the name can be modified. ## - ## Returning a blank name will result in the symbol being skipped. This will fail for `nskParam` - ## and `nskField` since the generated Nim code will be wrong. + ## While `cPlugin` can easily remove leading/trailing `_` or prefixes and + ## suffixes like `SDL_`, passing `--prefix` or `--suffix` flags to `cImport` + ## in the `flags` parameter is much easier. However, these flags will only be + ## considered when no `cPlugin` is specified. + ## + ## Returning a blank name will result in the symbol being skipped. This will + ## fail for `nskParam` and `nskField` since the generated Nim code will be wrong. ## ## Symbol types can be any of the following: ## - `nskConst` for constants @@ -316,10 +321,12 @@ macro cPlugin*(body): untyped = ## - `nskEnumField` for enum (field) names, though they are in the global namespace as `nskConst` ## - `nskProc` - for proc names ## - ## `nimterop/plugins` is implicitly imported to provide access to standard plugin facilities. + ## `nimterop/plugins` is implicitly imported to provide access to standard + ## plugin facilities. ## ## `cPlugin() `_ only affects calls to - ## `cImport() `_ that follow it. + ## `cImport() `_ that + ## follow it. runnableExamples: cPlugin: import strutils @@ -572,7 +579,9 @@ macro cImport*(filename: static string, recurse: static bool = false, dynlib: st ## `mode` is purely for forward compatibility when toast adds C++ support. It can ## be ignored for the foreseeable future. ## - ## `flags` can be used to pass any other command line arguments to `toast`. + ## `flags` can be used to pass any other command line arguments to `toast`. A + ## good example would be `--prefix` and `--suffix` which strip leading and + ## trailing strings from identifiers, `_` being quite common. ## ## `cImport()` consumes and resets preceding `cOverride()` calls. `cPlugin()` ## is retained for the next `cImport()` call unless a new `cPlugin()` call is diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 53e04f8..1c5f8aa 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -112,6 +112,7 @@ proc getIdentifier*(nimState: NimState, name: string, kind: NimSymKind, parent=" if name notin nimState.gState.symOverride or parent.nBl: if nimState.gState.onSymbol != nil: + # Use onSymbol from plugin provided by user var sym = Symbol(name: name, parent: parent, kind: kind) nimState.gState.onSymbol(sym) @@ -120,11 +121,23 @@ proc getIdentifier*(nimState: NimState, name: string, kind: NimSymKind, parent=" else: result = name + # Strip out --prefix from CLI if specified + for str in nimState.gState.prefix: + if result.startsWith(str): + result = result[str.len .. ^1] + + # Strip out --suffix from CLI if specified + for str in nimState.gState.suffix: + if result.endsWith(str): + result = result[0 .. ^(str.len+1)] + checkIdentifier(result, $kind, parent, name) if result in gReserved or (result == "object" and kind != nskType): + # Enclose in backticks since Nim reserved word result = &"`{result}`" else: + # Skip identifier since in symOverride result = "" proc getUniqueIdentifier*(nimState: NimState, prefix = ""): string = diff --git a/nimterop/globals.nim b/nimterop/globals.nim index de29385..7c512b1 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -53,7 +53,7 @@ type AstTable {.used.} = TableRef[string, seq[ref Ast]] State = ref object - compile*, defines*, headers*, includeDirs*, searchDirs*, symOverride*: seq[string] + compile*, defines*, headers*, includeDirs*, searchDirs*, prefix*, suffix*, symOverride*: seq[string] nocache*, nocomments*, debug*, past*, preprocess*, pnim*, pretty*, recurse*: bool diff --git a/nimterop/toast.nim b/nimterop/toast.nim index 9da8283..a27d415 100644 --- a/nimterop/toast.nim +++ b/nimterop/toast.nim @@ -97,42 +97,51 @@ proc process(gState: State, path: string, astTable: AstTable) = elif gState.preprocess: echo gState.code +# CLI processing with default values proc main( - preprocess = false, - past = false, - pnim = false, - recurse = false, - nocomments = false, - defines: seq[string] = @[], - includeDirs: seq[string] = @[], - dynlib: string = "", - symOverride: seq[string] = @[], - nim: string = "nim", - pluginSourcePath: string = "", debug = false, + defines: seq[string] = @[], + dynlib: string = "", + includeDirs: seq[string] = @[], mode = modeDefault, + nim: string = "nim", + nocomments = false, + past = false, pgrammar = false, + pluginSourcePath: string = "", + pnim = false, + prefix: seq[string] = @[], + preprocess = false, + recurse = false, + suffix: seq[string] = @[], + symOverride: seq[string] = @[], source: seq[string] ) = + # Setup global state with arguments var gState = State( - preprocess: preprocess, - past: past, - pnim: pnim, - recurse: recurse, - nocomments: nocomments, - defines: defines, - includeDirs: includeDirs, - dynlib: dynlib, - symOverride: symOverride, - nim: nim, - pluginSourcePath: pluginSourcePath, debug: debug, + defines: defines, + dynlib: dynlib, + includeDirs: includeDirs, mode: mode, - pretty: true + nim: nim, + nocomments: nocomments, + past: past, + pluginSourcePath: pluginSourcePath, + pnim: pnim, + prefix: prefix, + preprocess: preprocess, + pretty: true, + recurse: recurse, + suffix: suffix, + symOverride: symOverride ) + # Split some arguments with , gState.symOverride = gState.symOverride.getSplitComma() + gState.prefix = gState.prefix.getSplitComma() + gState.suffix = gState.suffix.getSplitComma() if pluginSourcePath.nBl: gState.loadPlugin(pluginSourcePath) @@ -148,33 +157,38 @@ proc main( gState.process(src.expandSymlinkAbs(), astTable) when isMainModule: + # Setup cligen command line help and short flags import cligen dispatch(main, help = { - "preprocess": "run preprocessor on header", - "past": "print AST output", - "pnim": "print Nim output", - "recurse": "process #include files", - "nocomments": "exclude top-level comments from output", - "defines": "definitions to pass to preprocessor", - "includeDirs": "include directory to pass to preprocessor", - "dynlib": "Import symbols from library in specified Nim string", - "symOverride": "skip generating specified symbols", - "nim": "use a particular Nim executable (default: $PATH/nim)", - "pluginSourcePath": "Nim file to build and load as a plugin", "debug": "enable debug output", + "defines": "definitions to pass to preprocessor", + "dynlib": "Import symbols from library in specified Nim string", + "includeDirs": "include directory to pass to preprocessor", "mode": "language parser: c or cpp", + "nim": "use a particular Nim executable (default: $PATH/nim)", + "nocomments": "exclude top-level comments from output", + "past": "print AST output", "pgrammar": "print grammar", - "source" : "C/C++ source/header" + "pluginSourcePath": "Nim file to build and load as a plugin", + "pnim": "print Nim output", + "preprocess": "run preprocessor on header", + "recurse": "process #include files", + "source" : "C/C++ source/header", + "prefix": "Strip prefix from identifiers", + "suffix": "Strip suffix from identifiers", + "symOverride": "skip generating specified symbols" }, short = { - "preprocess": 'p', - "past": 'a', - "pnim": 'n', - "recurse": 'r', - "nocomments": 'c', - "defines": 'D', - "includeDirs": 'I', - "dynlib": 'l', - "symOverride": 'O', "debug": 'd', - "pgrammar": 'g' + "defines": 'D', + "dynlib": 'l', + "includeDirs": 'I', + "nocomments": 'c', + "past": 'a', + "pgrammar": 'g', + "pnim": 'n', + "prefix": 'E', + "preprocess": 'p', + "recurse": 'r', + "suffix": 'F', + "symOverride": 'O' }) diff --git a/tests/lzma.nim b/tests/lzma.nim index 785e0bb..b207a46 100644 --- a/tests/lzma.nim +++ b/tests/lzma.nim @@ -4,6 +4,7 @@ import nimterop/[build, cimport] const baseDir = getProjectCacheDir("nimterop" / "tests" / "liblzma") + flags = "--prefix=__,_" static: cDebug() @@ -21,12 +22,6 @@ getHeader( conFlags = "--disable-xz --disable-xzdec --disable-lzmadec --disable-lzmainfo" ) -cPlugin: - import strutils - - proc onSymbol*(sym: var Symbol) {.exportc, dynlib.} = - sym.name = sym.name.strip(chars = {'_'}) - cOverride: type lzma_internal = object @@ -39,8 +34,8 @@ cOverride: lzma_index_iter = object when not lzmaStatic: - cImport(lzmaPath, recurse = true, dynlib = "lzmaLPath") + cImport(lzmaPath, recurse = true, dynlib = "lzmaLPath", flags = flags) else: - cImport(lzmaPath, recurse = true) + cImport(lzmaPath, recurse = true, flags = flags) echo "liblzma version = " & $lzma_version_string() From d032a2c107d7f342df79980e01a3cf35194764de Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 18 Dec 2019 23:52:06 -0600 Subject: [PATCH 305/593] v0.3.6 --- nimterop.nimble | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimterop.nimble b/nimterop.nimble index ddacfda..61076cc 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -1,6 +1,6 @@ # Package -version = "0.3.5" +version = "0.3.6" author = "genotrance" description = "C/C++ interop for Nim" license = "MIT" From ba77ee66d81afeb26d09a0f5aa78026f1de2cf17 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 19 Dec 2019 00:10:09 -0600 Subject: [PATCH 306/593] lzma needs --suffix --- tests/lzma.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/lzma.nim b/tests/lzma.nim index b207a46..1f0a1fb 100644 --- a/tests/lzma.nim +++ b/tests/lzma.nim @@ -4,7 +4,7 @@ import nimterop/[build, cimport] const baseDir = getProjectCacheDir("nimterop" / "tests" / "liblzma") - flags = "--prefix=__,_" + flags = "--prefix=__,_ --suffix=__,_" static: cDebug() From 51618c5bcd9cd305e1c4d4aa6d27b54134d18096 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 19 Dec 2019 09:55:26 -0600 Subject: [PATCH 307/593] Fix ____ in lzma --- tests/lzma.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/lzma.nim b/tests/lzma.nim index 1f0a1fb..4f6c41a 100644 --- a/tests/lzma.nim +++ b/tests/lzma.nim @@ -4,7 +4,7 @@ import nimterop/[build, cimport] const baseDir = getProjectCacheDir("nimterop" / "tests" / "liblzma") - flags = "--prefix=__,_ --suffix=__,_" + flags = "--prefix=___,__,_ --suffix=__,_" static: cDebug() From cf372eb0614e7990ba00ee7daeb1864c247ad57e Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 19 Dec 2019 15:11:59 -0600 Subject: [PATCH 308/593] Fix part of #127 - file output for toast --- nimterop/toast.nim | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/nimterop/toast.nim b/nimterop/toast.nim index a27d415..d155263 100644 --- a/nimterop/toast.nim +++ b/nimterop/toast.nim @@ -106,6 +106,7 @@ proc main( mode = modeDefault, nim: string = "nim", nocomments = false, + output = "", past = false, pgrammar = false, pluginSourcePath: string = "", @@ -146,6 +147,9 @@ proc main( if pluginSourcePath.nBl: gState.loadPlugin(pluginSourcePath) + if output.len != 0: + doAssert reopen(stdout, output, fmWrite), "Failed to write to " & output + let astTable = parseGrammar() if pgrammar: @@ -167,6 +171,7 @@ when isMainModule: "mode": "language parser: c or cpp", "nim": "use a particular Nim executable (default: $PATH/nim)", "nocomments": "exclude top-level comments from output", + "output": "file to output content - default stdout", "past": "print AST output", "pgrammar": "print grammar", "pluginSourcePath": "Nim file to build and load as a plugin", @@ -183,6 +188,7 @@ when isMainModule: "dynlib": 'l', "includeDirs": 'I', "nocomments": 'c', + "output": 'o', "past": 'a', "pgrammar": 'g', "pnim": 'n', From ea6785500ad697bb13a546ecf29ecf52421bc633 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 19 Dec 2019 21:20:27 -0600 Subject: [PATCH 309/593] Fix #160 - toast should check wrapper --- README.md | 2 ++ nimterop/cimport.nim | 12 +++--------- nimterop/compat.nim | 2 ++ nimterop/toast.nim | 44 ++++++++++++++++++++++++++++++++++++++++---- 4 files changed, 47 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 502688e..67689b3 100644 --- a/README.md +++ b/README.md @@ -96,6 +96,7 @@ Usage: Options(opt-arg sep :|=|spc): -h, --help print this cligen-erated help --help-syntax advanced: prepend,plurals,.. + -k, --check bool false check generated wrapper with compiler -d, --debug bool false enable debug output -D=, --defines= strings {} definitions to pass to preprocessor -l=, --dynlib= string "" Import symbols from library in specified Nim string @@ -103,6 +104,7 @@ Options(opt-arg sep :|=|spc): -m=, --mode= string "cpp" language parser: c or cpp --nim= string "nim" use a particular Nim executable (default: $PATH/nim) -c, --nocomments bool false exclude top-level comments from output + -o=, --output= string "" file to output content - default stdout -a, --past bool false print AST output -g, --pgrammar bool false print grammar --pluginSourcePath= string "" Nim file to build and load as a plugin diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index bebcf3d..c13ce1f 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -21,7 +21,7 @@ const CIMPORT {.used.} = 1 include "."/globals -import "."/[build, paths, types] +import "."/[build, compat, paths, types] export types proc interpPath(dir: string): string= @@ -116,12 +116,7 @@ proc getNimCheckError(output: string): tuple[tmpFile, errors: string] = doAssert fileExists(result.tmpFile), "Failed to write to cache dir: " & result.tmpFile let - nim = - when (NimMajor, NimMinor, NimPatch) >= (0, 19, 9): - getCurrentCompilerExe() - else: - "nim" - (check, _) = gorgeEx(&"{nim} check {result.tmpFile.sanitizePath}") + (check, _) = gorgeEx(&"{getCurrentCompilerExe()} check {result.tmpFile.sanitizePath}") result.errors = "\n\n" & check @@ -157,8 +152,7 @@ proc getToast(fullpath: string, recurse: bool = false, dynlib: string = "", if gStateCT.symOverride.nBl: cmd.add &" --symOverride={gStateCT.symOverride.join(\",\")}" - when (NimMajor, NimMinor, NimPatch) >= (0, 19, 9): - cmd.add &" --nim:{getCurrentCompilerExe().sanitizePath}" + cmd.add &" --nim:{getCurrentCompilerExe().sanitizePath}" if gStateCT.pluginSourcePath.nBl: cmd.add &" --pluginSourcePath={gStateCT.pluginSourcePath.sanitizePath}" diff --git a/nimterop/compat.nim b/nimterop/compat.nim index 1115252..7e2bc98 100644 --- a/nimterop/compat.nim +++ b/nimterop/compat.nim @@ -30,3 +30,5 @@ else: if not base.endsWith DirSep: base.add DirSep doAssert file.startsWith base result = file[base.len .. ^1] + + proc getCurrentCompilerExe*(): string = "nim" diff --git a/nimterop/toast.nim b/nimterop/toast.nim index d155263..614da83 100644 --- a/nimterop/toast.nim +++ b/nimterop/toast.nim @@ -1,8 +1,8 @@ -import os, strformat, strutils +import os, strformat, strutils, times import "."/treesitter/[api, c, cpp] -import "."/[ast, globals, getters, grammar] +import "."/[ast, compat, globals, getters, grammar] proc printLisp(gState: State, root: TSNode) = var @@ -99,6 +99,7 @@ proc process(gState: State, path: string, astTable: AstTable) = # CLI processing with default values proc main( + check = false, debug = false, defines: seq[string] = @[], dynlib: string = "", @@ -147,23 +148,57 @@ proc main( if pluginSourcePath.nBl: gState.loadPlugin(pluginSourcePath) - if output.len != 0: - doAssert reopen(stdout, output, fmWrite), "Failed to write to " & output + # Backup stdout + var + outputFile = output + outputHandle: File + stdoutBackup = stdout + # Check needs a file + if check and outputFile.len == 0: + outputFile = getTempDir() / "toast_" & ($getTime().toUnix()).addFileExt("nim") + + # Redirect output to file + if outputFile.len != 0: + doAssert outputHandle.open(outputFile, fmWrite), "Failed to write to " & outputFile + stdout = outputHandle + + # Process grammar into AST let astTable = parseGrammar() + if pgrammar: + # Print AST of grammar astTable.printGrammar() elif source.nBl: + # Print source after preprocess or Nim output if gState.pnim: printNimHeader() for src in source: gState.process(src.expandSymlinkAbs(), astTable) + # Restore stdout + stdout = stdoutBackup + + # Print wrapper if temporarily redirected to file + if check and output.len == 0: + stdout.write outputFile.readFile() + discard outputFile.tryRemoveFile() + + # Check Nim output + if gState.pnim and check: + var + (check, err) = gorgeEx(&"{getCurrentCompilerExe()} check {outputFile}") + if err == 0: + echo "# Checked wrapper successfully" + else: + doAssert err == 0, "# Nim check failed:\n\n" & check + when isMainModule: # Setup cligen command line help and short flags import cligen dispatch(main, help = { + "check": "check generated wrapper with compiler", "debug": "enable debug output", "defines": "definitions to pass to preprocessor", "dynlib": "Import symbols from library in specified Nim string", @@ -183,6 +218,7 @@ when isMainModule: "suffix": "Strip suffix from identifiers", "symOverride": "skip generating specified symbols" }, short = { + "check": 'k', "debug": 'd', "defines": 'D', "dynlib": 'l', From c352d678fd7ba766c97c12b2d2e6b02c8f343f83 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 19 Dec 2019 22:24:30 -0600 Subject: [PATCH 310/593] Fix for Windows --- nimterop/toast.nim | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/nimterop/toast.nim b/nimterop/toast.nim index 614da83..8f607ff 100644 --- a/nimterop/toast.nim +++ b/nimterop/toast.nim @@ -1,4 +1,4 @@ -import os, strformat, strutils, times +import os, osproc, strformat, strutils, times import "."/treesitter/[api, c, cpp] @@ -157,11 +157,17 @@ proc main( # Check needs a file if check and outputFile.len == 0: outputFile = getTempDir() / "toast_" & ($getTime().toUnix()).addFileExt("nim") + when defined(windows): + # https://github.com/nim-lang/Nim/issues/12939 + echo "Check cannot print wrapper on Windows, use --output or review " & outputFile # Redirect output to file if outputFile.len != 0: - doAssert outputHandle.open(outputFile, fmWrite), "Failed to write to " & outputFile - stdout = outputHandle + when defined(windows): + doAssert stdout.reopen(outputFile, fmWrite), "Failed to write to " & outputFile + else: + doAssert outputHandle.open(outputFile, fmWrite), "Failed to write to " & outputFile + stdout = outputHandle # Process grammar into AST let @@ -177,18 +183,18 @@ proc main( for src in source: gState.process(src.expandSymlinkAbs(), astTable) - # Restore stdout - stdout = stdoutBackup + when not defined(windows): + # Restore stdout + stdout = stdoutBackup - # Print wrapper if temporarily redirected to file - if check and output.len == 0: - stdout.write outputFile.readFile() - discard outputFile.tryRemoveFile() + # Print wrapper if temporarily redirected to file + if check and output.len == 0: + stdout.write outputFile.readFile() # Check Nim output if gState.pnim and check: var - (check, err) = gorgeEx(&"{getCurrentCompilerExe()} check {outputFile}") + (check, err) = execCmdEx(&"{getCurrentCompilerExe()} check {outputFile}") if err == 0: echo "# Checked wrapper successfully" else: From a2809b02d1c0696c0b7f5d767e79a947201a7c05 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 19 Dec 2019 22:47:06 -0600 Subject: [PATCH 311/593] Improve msg for Windows --- nimterop/toast.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimterop/toast.nim b/nimterop/toast.nim index 8f607ff..34409fc 100644 --- a/nimterop/toast.nim +++ b/nimterop/toast.nim @@ -159,7 +159,7 @@ proc main( outputFile = getTempDir() / "toast_" & ($getTime().toUnix()).addFileExt("nim") when defined(windows): # https://github.com/nim-lang/Nim/issues/12939 - echo "Check cannot print wrapper on Windows, use --output or review " & outputFile + echo "Cannot print wrapper with check on Windows, review " & outputFile & "\n" # Redirect output to file if outputFile.len != 0: From 54dfd61b1bda02f3ce0124e47192018c1e8b349f Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Fri, 20 Dec 2019 00:10:31 -0600 Subject: [PATCH 312/593] Fix #161 - enable stubbing in toast --- README.md | 1 + nimterop/toast.nim | 71 +++++++++++++++++++++++++++++++++++++--------- 2 files changed, 58 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 67689b3..ca16293 100644 --- a/README.md +++ b/README.md @@ -112,6 +112,7 @@ Options(opt-arg sep :|=|spc): -E=, --prefix= strings {} Strip prefix from identifiers -p, --preprocess bool false run preprocessor on header -r, --recurse bool false process #include files + -s, --stub bool false stub out undefined type references as objects -F=, --suffix= strings {} Strip suffix from identifiers -O=, --symOverride= strings {} skip generating specified symbols ``` diff --git a/nimterop/toast.nim b/nimterop/toast.nim index 34409fc..871230d 100644 --- a/nimterop/toast.nim +++ b/nimterop/toast.nim @@ -54,7 +54,7 @@ proc printLisp(gState: State, root: TSNode) = break proc process(gState: State, path: string, astTable: AstTable) = - doAssert existsFile(path), "Invalid path " & path + doAssert existsFile(path), &"Invalid path {path}" var parser = tsParserNew() @@ -81,7 +81,7 @@ proc process(gState: State, path: string, astTable: AstTable) = elif gState.mode == "cpp": doAssert parser.tsParserSetLanguage(treeSitterCpp()), "Failed to load C++ parser" else: - doAssert false, "Invalid parser " & gState.mode + doAssert false, &"Invalid parser {gState.mode}" var tree = parser.tsParserParseString(nil, gState.code.cstring, gState.code.len.uint32) @@ -115,6 +115,7 @@ proc main( prefix: seq[string] = @[], preprocess = false, recurse = false, + stub = false, suffix: seq[string] = @[], symOverride: seq[string] = @[], source: seq[string] @@ -153,20 +154,26 @@ proc main( outputFile = output outputHandle: File stdoutBackup = stdout + check = check or stub + + # Fix output file extention + if outputFile.len != 0: + if outputFile.splitFile().ext != ".nim": + outputFile = outputFile & ".nim" # Check needs a file if check and outputFile.len == 0: outputFile = getTempDir() / "toast_" & ($getTime().toUnix()).addFileExt("nim") when defined(windows): # https://github.com/nim-lang/Nim/issues/12939 - echo "Cannot print wrapper with check on Windows, review " & outputFile & "\n" + echo &"Cannot print wrapper with check on Windows, review {outputFile}\n" # Redirect output to file if outputFile.len != 0: when defined(windows): - doAssert stdout.reopen(outputFile, fmWrite), "Failed to write to " & outputFile + doAssert stdout.reopen(outputFile, fmWrite), &"Failed to write to {outputFile}" else: - doAssert outputHandle.open(outputFile, fmWrite), "Failed to write to " & outputFile + doAssert outputHandle.open(outputFile, fmWrite), &"Failed to write to {outputFile}" stdout = outputHandle # Process grammar into AST @@ -187,19 +194,53 @@ proc main( # Restore stdout stdout = stdoutBackup + # Check Nim output + if gState.pnim and check: + # Run nim check on generated wrapper + var + (check, err) = execCmdEx(&"{getCurrentCompilerExe()} check {outputFile}") + if err != 0: + # Failed check so try stubbing + if stub: + # Close output file to prepend stubs + when not defined(windows): + outputHandle.close() + else: + stdout.close() + + # Find undeclared identifiers in error + var + data = "" + stubData = "" + for line in check.splitLines: + if "undeclared identifier" in line: + try: + # Add stub of object type + stubData &= " " & line.split("'")[1] & " = object\n" + except: + discard + + # Include in wrapper file + data = outputFile.readFile() + if "type\n" in data: + # In existing type block + data = data.replace("type\n", "type\n" & stubData) + else: + # At the top if none already + data = "type\n" & stubData & data + outputFile.writeFile(data) + + # Rerun nim check on stubbed wrapper + (check, err) = execCmdEx(&"{getCurrentCompilerExe()} check {outputFile}") + doAssert err == 0, "# Nim check with stub failed:\n\n" & check + else: + doAssert err == 0, "# Nim check failed:\n\n" & check + + when not defined(windows): # Print wrapper if temporarily redirected to file if check and output.len == 0: stdout.write outputFile.readFile() - # Check Nim output - if gState.pnim and check: - var - (check, err) = execCmdEx(&"{getCurrentCompilerExe()} check {outputFile}") - if err == 0: - echo "# Checked wrapper successfully" - else: - doAssert err == 0, "# Nim check failed:\n\n" & check - when isMainModule: # Setup cligen command line help and short flags import cligen @@ -221,6 +262,7 @@ when isMainModule: "recurse": "process #include files", "source" : "C/C++ source/header", "prefix": "Strip prefix from identifiers", + "stub": "stub out undefined type references as objects", "suffix": "Strip suffix from identifiers", "symOverride": "skip generating specified symbols" }, short = { @@ -237,6 +279,7 @@ when isMainModule: "prefix": 'E', "preprocess": 'p', "recurse": 'r', + "stub": 's', "suffix": 'F', "symOverride": 'O' }) From 90e81aa47264093171d8267fa25659d00dd56a4d Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Fri, 20 Dec 2019 16:25:56 -0600 Subject: [PATCH 313/593] Fix stub addition to type block --- nimterop/toast.nim | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/nimterop/toast.nim b/nimterop/toast.nim index 871230d..5923e56 100644 --- a/nimterop/toast.nim +++ b/nimterop/toast.nim @@ -222,9 +222,11 @@ proc main( # Include in wrapper file data = outputFile.readFile() - if "type\n" in data: - # In existing type block - data = data.replace("type\n", "type\n" & stubData) + let + idx = data.find("\ntype\n") + if idx != -1: + # In first existing type block + data = data[0 ..< idx+6] & stubData & data[idx+6 .. ^1] else: # At the top if none already data = "type\n" & stubData & data From f71cf837d297192f8cddfa136e8c3cd84bbc81eb Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Fri, 20 Dec 2019 18:17:37 -0600 Subject: [PATCH 314/593] v0.4.0 --- nimterop.nimble | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimterop.nimble b/nimterop.nimble index 61076cc..6ada463 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -1,6 +1,6 @@ # Package -version = "0.3.6" +version = "0.4.0" author = "genotrance" description = "C/C++ interop for Nim" license = "MIT" From a06081f807e6cbb6922fa022a1a0340b263d7357 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Fri, 20 Dec 2019 19:03:50 -0600 Subject: [PATCH 315/593] Fix #163 - retries for network calls --- nimterop/build.nim | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/nimterop/build.nim b/nimterop/build.nim index 5426548..d91472c 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -231,12 +231,12 @@ proc downloadUrl*(url, outdir: string) = else: cmd = findExe("wget") if cmd.len != 0: - cmd &= " $# -o $#" + cmd &= " $# -O $#" elif defined(Windows): cmd = "powershell [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; wget $# -OutFile $#" else: doAssert false, "No download tool available - curl, wget" - discard execAction(cmd % [url, (outdir/file).sanitizePath]) + discard execAction(cmd % [url, (outdir/file).sanitizePath], retry = 1) if ext == ".zip": extractZip(file, outdir) @@ -299,11 +299,11 @@ proc gitPull*(url: string, outdir = "", plist = "", checkout = "") = if checkout.len != 0: echo "# Checking out " & checkout - discard execAction(&"cd {outdirQ} && git fetch") + discard execAction(&"cd {outdirQ} && git fetch", retry = 1) discard execAction(&"cd {outdirQ} && git checkout {checkout}") else: echo "# Pulling repository" - discard execAction(&"cd {outdirQ} && git pull --depth=1 origin master") + discard execAction(&"cd {outdirQ} && git pull --depth=1 origin master", retry = 1) proc findFile*(file: string, dir: string, recurse = true, first = false, regex = false): string = ## Find the file in the specified directory From 362b5498b1794aefc91e1d660b8bdb8401f1189f Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Fri, 20 Dec 2019 22:37:02 -0600 Subject: [PATCH 316/593] Fix #57 and #152 - clean ident in expressions --- nimterop.nimble | 1 + nimterop/getters.nim | 11 ++++++++--- tests/include/toast.h | 23 +++++++++++++++++++++++ 3 files changed, 32 insertions(+), 3 deletions(-) create mode 100644 tests/include/toast.h diff --git a/nimterop.nimble b/nimterop.nimble index 6ada463..8802d1b 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -38,6 +38,7 @@ task test, "Test": execTest "tests/tnimterop_c.nim" execCmd "nim cpp -f -r tests/tnimterop_cpp.nim" + execCmd "./nimterop/toast -pnk -E=_ tests/include/toast.h" execTest "tests/tpcre.nim" # Platform specific tests diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 1c5f8aa..af3dfa2 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -382,24 +382,27 @@ proc getNimExpression*(nimState: NimState, expr: string): string = for i in 0 .. clean.len: if i != clean.len: - if clean[i] == '_' and ident.Bl: - gen = $clean[i] - elif clean[i] in IdentChars: + if clean[i] in IdentChars: if clean[i] in Digits and ident.Bl: + # Identifiers cannot start with digits gen = $clean[i] elif clean[i] in HexDigits and hex == true: + # Part of a hex number gen = $clean[i] elif i > 0 and i < clean.len-1 and clean[i] in ['x', 'X'] and clean[i-1] == '0' and clean[i+1] in HexDigits: + # Found a hex number gen = $clean[i] hex = true else: + # Part of an identifier ident &= clean[i] hex = false else: gen = (block: if (i == 0 or clean[i-1] != '\'') or (i == clean.len - 1 or clean[i+1] != '\''): + # If unquoted, convert logical ops to Nim case clean[i] of '^': " xor " of '&': " and " @@ -412,6 +415,7 @@ proc getNimExpression*(nimState: NimState, expr: string): string = hex = false if i == clean.len or gen.nBl: + # Process identifier if ident.nBl: ident = nimState.getIdentifier(ident, nskConst) result &= ident @@ -419,6 +423,7 @@ proc getNimExpression*(nimState: NimState, expr: string): string = result &= gen gen = "" + # Convert shift ops to Nim result = result.multiReplace([ ("<<", " shl "), (">>", " shr ") ]) diff --git a/tests/include/toast.h b/tests/include/toast.h new file mode 100644 index 0000000..b6b11a8 --- /dev/null +++ b/tests/include/toast.h @@ -0,0 +1,23 @@ +// #57 +enum { + _SG_STRING_SIZE = 16, + _SG_SLOT_SHIFT = 16, + _SG_SLOT_MASK = (1<<_SG_SLOT_SHIFT)-1, + _SG_MAX_POOL_SIZE = (1<<_SG_SLOT_SHIFT), + _SG_DEFAULT_BUFFER_POOL_SIZE = 128, + _SG_DEFAULT_IMAGE_POOL_SIZE = 128, + _SG_DEFAULT_SHADER_POOL_SIZE = 32, + _SG_DEFAULT_PIPELINE_POOL_SIZE = 64, + _SG_DEFAULT_PASS_POOL_SIZE = 16, + _SG_DEFAULT_CONTEXT_POOL_SIZE = 16, + _SG_MTL_DEFAULT_UB_SIZE = 4 * 1024 * 1024, + _SG_MTL_DEFAULT_SAMPLER_CACHE_CAPACITY = 64, +}; + +// #152 +enum { + _ONE, + _TWO, + _MAX = _TWO, + _MORE +}; From 421bfdc53fd8f56e92827680253a6ddaaa53c8cf Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Sat, 21 Dec 2019 11:15:52 -0600 Subject: [PATCH 317/593] v0.4.1 --- nimterop.nimble | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimterop.nimble b/nimterop.nimble index 8802d1b..c3d7809 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -1,6 +1,6 @@ # Package -version = "0.4.0" +version = "0.4.1" author = "genotrance" description = "C/C++ interop for Nim" license = "MIT" From 3fcc3b9526a8afe4c8caa75b15ad074dde6dc63c Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Sat, 21 Dec 2019 12:20:33 -0600 Subject: [PATCH 318/593] Fix #75 - support char and char* #defines --- nimterop/getters.nim | 7 +++++-- tests/include/test.h | 2 ++ tests/lzma.nim | 5 +++++ tests/tnimterop_c.nim | 2 ++ 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/nimterop/getters.nim b/nimterop/getters.nim index af3dfa2..4cf5653 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -203,11 +203,14 @@ proc getPtrType*(str: string): string = str proc getLit*(str: string): string = + # Used to convert #define literals into const let str = str.replace(re"/[/*].*?(?:\*/)?$", "").strip() - if str.contains(re"^[\-]?[\d]*[.]?[\d]+$") or - str.contains(re"^0x[\da-fA-F]+$"): + if str.contains(re"^[\-]?[\d]*[.]?[\d]+$") or # decimal + str.contains(re"^0x[\da-fA-F]+$") or # hexadecimal + str.contains(re"^'[[:ascii:]]'$") or # char + str.contains(re"""^"[[:ascii:]]+"$"""): # char * return str proc getNodeVal*(nimState: NimState, node: TSNode): string = diff --git a/tests/include/test.h b/tests/include/test.h index 667f384..b22e2d8 100644 --- a/tests/include/test.h +++ b/tests/include/test.h @@ -9,6 +9,8 @@ extern "C" { #define TEST_INT 512 #define TEST_FLOAT 5.12 #define TEST_HEX 0x512 +#define TEST_CHAR 'a' +#define TEST_STR "hello world" #ifdef __APPLE__ #define OSDEF 10 diff --git a/tests/lzma.nim b/tests/lzma.nim index 4f6c41a..1cc6aa0 100644 --- a/tests/lzma.nim +++ b/tests/lzma.nim @@ -8,6 +8,11 @@ const static: cDebug() + cSkipSymbol(@[ + "PRIX8", "PRIX16", "PRIX32", + "PRIXLEAST8", "PRIXLEAST16", "PRIXLEAST32", + "PRIXFAST8" + ]) when defined(envTest): setDefines(@["lzmaStd"]) diff --git a/tests/tnimterop_c.nim b/tests/tnimterop_c.nim index fb1505a..319c766 100644 --- a/tests/tnimterop_c.nim +++ b/tests/tnimterop_c.nim @@ -46,6 +46,8 @@ cImport cSearchPath "test.h" check TEST_INT == 512 check TEST_FLOAT == 5.12 check TEST_HEX == 0x512 +check TEST_CHAR == 'a' +check TEST_STR == "hello world" when defined(osx): check OSDEF == 10 From 4754012cad1adaff40052445f8bebe80c9775b06 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Sat, 21 Dec 2019 13:09:17 -0600 Subject: [PATCH 319/593] Update documentation --- all.html | 808 +----------- build.html | 817 +----------- build.idx | 1 + cimport.html | 822 +----------- compat.html | 808 +----------- dochack.js | 3382 ++++++++++++++++++++++++------------------------- paths.html | 808 +----------- plugin.html | 862 ++----------- plugin.idx | 3 + theindex.html | 817 +----------- types.html | 808 +----------- 11 files changed, 2101 insertions(+), 7835 deletions(-) diff --git a/all.html b/all.html index ba03064..02c6c63 100644 --- a/all.html +++ b/all.html @@ -10,6 +10,7 @@ + @@ -17,772 +18,7 @@ all - + @@ -797,6 +33,37 @@ function main() { event.target.parentNode.nextElementSibling.style.display = "inline"; } } + + const toggleSwitch = document.querySelector('.theme-switch input[type="checkbox"]'); + function switchTheme(e) { + if (e.target.checked) { + document.documentElement.setAttribute('data-theme', 'dark'); + localStorage.setItem('theme', 'dark'); + } else { + document.documentElement.setAttribute('data-theme', 'light'); + localStorage.setItem('theme', 'light'); + } + } + + toggleSwitch.addEventListener('change', switchTheme, false); + + + if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { + document.documentElement.setAttribute('data-theme', "dark"); + toggleSwitch.checked = true; + } else if (window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches) { + document.documentElement.setAttribute('data-theme', "light"); + toggleSwitch.checked = false; + } else { + const currentTheme = localStorage.getItem('theme') ? localStorage.getItem('theme') : null; + if (currentTheme) { + document.documentElement.setAttribute('data-theme', currentTheme); + + if (currentTheme === 'dark') { + toggleSwitch.checked = true; + } + } + } } @@ -807,6 +74,13 @@ function main() {

            all

            +
            + +     Dark Mode +
            diff --git a/build.html b/build.html index e623caa..9a6e076 100644 --- a/build.html +++ b/build.html @@ -10,6 +10,7 @@ + @@ -17,772 +18,7 @@ build - + @@ -797,6 +33,37 @@ function main() { event.target.parentNode.nextElementSibling.style.display = "inline"; } } + + const toggleSwitch = document.querySelector('.theme-switch input[type="checkbox"]'); + function switchTheme(e) { + if (e.target.checked) { + document.documentElement.setAttribute('data-theme', 'dark'); + localStorage.setItem('theme', 'dark'); + } else { + document.documentElement.setAttribute('data-theme', 'light'); + localStorage.setItem('theme', 'light'); + } + } + + toggleSwitch.addEventListener('change', switchTheme, false); + + + if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { + document.documentElement.setAttribute('data-theme', "dark"); + toggleSwitch.checked = true; + } else if (window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches) { + document.documentElement.setAttribute('data-theme', "light"); + toggleSwitch.checked = false; + } else { + const currentTheme = localStorage.getItem('theme') ? localStorage.getItem('theme') : null; + if (currentTheme) { + document.documentElement.setAttribute('data-theme', currentTheme); + + if (currentTheme === 'dark') { + toggleSwitch.checked = true; + } + } + } } @@ -807,6 +74,13 @@ function main() {

            build

            +
            + +     Dark Mode +
          • make
          • +
          • getCompiler
          • getGccPaths
          • cmake directive

            If make.exe is missing and mingw32-make.exe is available, it will be copied over to make.exe in the same location.

            +
        + +
        proc getCompiler(): string {...}{.raises: [], tags: [ReadEnvEffect].}
        +
        + + +
        proc getGccPaths(mode = "c"): seq[string] {...}{.raises: [ValueError], tags: [ReadEnvEffect].}
        @@ -1279,7 +562,7 @@ Check if -d:xxx is se diff --git a/build.idx b/build.idx index 326c09e..8b67066 100644 --- a/build.idx +++ b/build.idx @@ -24,6 +24,7 @@ setCmakeLibName build.html#setCmakeLibName,string,string,string,string,string bu setCmakePositionIndependentCode build.html#setCmakePositionIndependentCode,string build: setCmakePositionIndependentCode(outdir: string) cmake build.html#cmake,string,string,string build: cmake(path, check, flags: string) make build.html#make,string,string,string build: make(path, check: string; flags = ""; regex = false) +getCompiler build.html#getCompiler build: getCompiler(): string getGccPaths build.html#getGccPaths,string build: getGccPaths(mode = "c"): seq[string] getGccLibPaths build.html#getGccLibPaths,string build: getGccLibPaths(mode = "c"): seq[string] setDefines build.html#setDefines.m build: setDefines(defs: static openArray[string]): untyped diff --git a/cimport.html b/cimport.html index 6957a44..09e1254 100644 --- a/cimport.html +++ b/cimport.html @@ -10,6 +10,7 @@ + @@ -17,772 +18,7 @@ cimport - + @@ -797,6 +33,37 @@ function main() { event.target.parentNode.nextElementSibling.style.display = "inline"; } } + + const toggleSwitch = document.querySelector('.theme-switch input[type="checkbox"]'); + function switchTheme(e) { + if (e.target.checked) { + document.documentElement.setAttribute('data-theme', 'dark'); + localStorage.setItem('theme', 'dark'); + } else { + document.documentElement.setAttribute('data-theme', 'light'); + localStorage.setItem('theme', 'light'); + } + } + + toggleSwitch.addEventListener('change', switchTheme, false); + + + if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { + document.documentElement.setAttribute('data-theme', "dark"); + toggleSwitch.checked = true; + } else if (window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches) { + document.documentElement.setAttribute('data-theme', "light"); + toggleSwitch.checked = false; + } else { + const currentTheme = localStorage.getItem('theme') ? localStorage.getItem('theme') : null; + if (currentTheme) { + document.documentElement.setAttribute('data-theme', currentTheme); + + if (currentTheme === 'dark') { + toggleSwitch.checked = true; + } + } + } } @@ -807,6 +74,13 @@ function main() {

        cimport

        +
        + +     Dark Mode +
        diff --git a/compat.html b/compat.html index 1da36d4..121e246 100644 --- a/compat.html +++ b/compat.html @@ -10,6 +10,7 @@ + @@ -17,772 +18,7 @@ compat - + @@ -797,6 +33,37 @@ function main() { event.target.parentNode.nextElementSibling.style.display = "inline"; } } + + const toggleSwitch = document.querySelector('.theme-switch input[type="checkbox"]'); + function switchTheme(e) { + if (e.target.checked) { + document.documentElement.setAttribute('data-theme', 'dark'); + localStorage.setItem('theme', 'dark'); + } else { + document.documentElement.setAttribute('data-theme', 'light'); + localStorage.setItem('theme', 'light'); + } + } + + toggleSwitch.addEventListener('change', switchTheme, false); + + + if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { + document.documentElement.setAttribute('data-theme', "dark"); + toggleSwitch.checked = true; + } else if (window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches) { + document.documentElement.setAttribute('data-theme', "light"); + toggleSwitch.checked = false; + } else { + const currentTheme = localStorage.getItem('theme') ? localStorage.getItem('theme') : null; + if (currentTheme) { + document.documentElement.setAttribute('data-theme', currentTheme); + + if (currentTheme === 'dark') { + toggleSwitch.checked = true; + } + } + } } @@ -807,6 +74,13 @@ function main() {

        compat

        +
        + +     Dark Mode +
        diff --git a/dochack.js b/dochack.js index d068800..e4d634a 100644 --- a/dochack.js +++ b/dochack.js @@ -1,6 +1,4 @@ -/* Generated by the Nim Compiler v1.0.99 */ -/* (c) 2019 Andreas Rumpf */ - +/* Generated by the Nim Compiler v1.1.1 */ var framePtr = null; var excHandler = 0; var lastJSError = null; @@ -12,257 +10,257 @@ if (typeof Uint16Array === 'undefined') Uint16Array = Array; if (typeof Uint32Array === 'undefined') Uint32Array = Array; if (typeof Float32Array === 'undefined') Float32Array = Array; if (typeof Float64Array === 'undefined') Float64Array = Array; -var NTI42032 = {size: 0,kind: 1,base: null,node: null,finalizer: null}; -var NTI193071 = {size: 0, kind: 18, base: null, node: null, finalizer: null}; -var NTI45462 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI195578 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; -var NTI82448 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI82444 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI82440 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI82436 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI82432 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI82428 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI82424 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI82420 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI82416 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI82412 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI82408 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI82404 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI82400 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI82396 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI82392 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI82388 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI82384 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI82380 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI82376 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI82372 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI82205 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI82283 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI82281 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; -var NTI82227 = {size: 0, kind: 14, base: null, node: null, finalizer: null}; -var NTI82565 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; -var NTI82563 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; -var NTI82561 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; -var NTI82231 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI82229 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; -var NTI84305 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; -var NTI45450 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI45458 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI42006 = {size: 0,kind: 31,base: null,node: null,finalizer: null}; -var NTI61156 = {size: 0, kind: 18, base: null, node: null, finalizer: null}; -var NTI45408 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI45514 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; -var NTI42016 = {size: 0,kind: 40,base: null,node: null,finalizer: null}; -var NTI42040 = {size: 0,kind: 28,base: null,node: null,finalizer: null}; -var NTI42042 = {size: 0,kind: 29,base: null,node: null,finalizer: null}; -var NTI45508 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; -var NTI45426 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI45428 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI45442 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI45446 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NNI45446 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; -NTI45446.node = NNI45446; -var NNI45442 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; -NTI45442.node = NNI45442; -var NNI45428 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; -NTI45428.node = NNI45428; -NTI45508.base = NTI45426; -NTI45514.base = NTI45426; -var NNI45426 = {kind: 2, len: 6, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "parent", len: 0, typ: NTI45508, name: "parent", sons: null}, -{kind: 1, offset: "name", len: 0, typ: NTI42042, name: "name", sons: null}, -{kind: 1, offset: "message", len: 0, typ: NTI42040, name: "msg", sons: null}, -{kind: 1, offset: "trace", len: 0, typ: NTI42040, name: "trace", sons: null}, -{kind: 1, offset: "raiseId", len: 0, typ: NTI42016, name: "raiseId", sons: null}, -{kind: 1, offset: "up", len: 0, typ: NTI45514, name: "up", sons: null}]}; -NTI45426.node = NNI45426; -var NNI45408 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; -NTI45408.node = NNI45408; -NTI45426.base = NTI45408; -NTI45428.base = NTI45426; -NTI45442.base = NTI45428; -NTI45446.base = NTI45442; -var NNI61156 = {kind: 2, len: 2, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "Field0", len: 0, typ: NTI42042, name: "Field0", sons: null}, -{kind: 1, offset: "Field1", len: 0, typ: NTI42006, name: "Field1", sons: null}]}; -NTI61156.node = NNI61156; -var NNI45458 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; -NTI45458.node = NNI45458; -NTI45458.base = NTI45428; -var NNI45450 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; -NTI45450.node = NNI45450; -NTI45450.base = NTI45428; -NTI82561.base = NTI82229; -NTI82563.base = NTI82229; -NTI82565.base = NTI82229; -var NNI82227 = {kind: 2, offset: 0, typ: null, name: null, len: 12, sons: {"1": {kind: 1, offset: 1, typ: NTI82227, name: "ElementNode", len: 0, sons: null}, -"2": {kind: 1, offset: 2, typ: NTI82227, name: "AttributeNode", len: 0, sons: null}, -"3": {kind: 1, offset: 3, typ: NTI82227, name: "TextNode", len: 0, sons: null}, -"4": {kind: 1, offset: 4, typ: NTI82227, name: "CDATANode", len: 0, sons: null}, -"5": {kind: 1, offset: 5, typ: NTI82227, name: "EntityRefNode", len: 0, sons: null}, -"6": {kind: 1, offset: 6, typ: NTI82227, name: "EntityNode", len: 0, sons: null}, -"7": {kind: 1, offset: 7, typ: NTI82227, name: "ProcessingInstructionNode", len: 0, sons: null}, -"8": {kind: 1, offset: 8, typ: NTI82227, name: "CommentNode", len: 0, sons: null}, -"9": {kind: 1, offset: 9, typ: NTI82227, name: "DocumentNode", len: 0, sons: null}, -"10": {kind: 1, offset: 10, typ: NTI82227, name: "DocumentTypeNode", len: 0, sons: null}, -"11": {kind: 1, offset: 11, typ: NTI82227, name: "DocumentFragmentNode", len: 0, sons: null}, -"12": {kind: 1, offset: 12, typ: NTI82227, name: "NotationNode", len: 0, sons: null}}}; -NTI82227.node = NNI82227; -var NNI82283 = {kind: 2, len: 92, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "background", len: 0, typ: NTI42042, name: "background", sons: null}, -{kind: 1, offset: "backgroundAttachment", len: 0, typ: NTI42042, name: "backgroundAttachment", sons: null}, -{kind: 1, offset: "backgroundColor", len: 0, typ: NTI42042, name: "backgroundColor", sons: null}, -{kind: 1, offset: "backgroundImage", len: 0, typ: NTI42042, name: "backgroundImage", sons: null}, -{kind: 1, offset: "backgroundPosition", len: 0, typ: NTI42042, name: "backgroundPosition", sons: null}, -{kind: 1, offset: "backgroundRepeat", len: 0, typ: NTI42042, name: "backgroundRepeat", sons: null}, -{kind: 1, offset: "border", len: 0, typ: NTI42042, name: "border", sons: null}, -{kind: 1, offset: "borderBottom", len: 0, typ: NTI42042, name: "borderBottom", sons: null}, -{kind: 1, offset: "borderBottomColor", len: 0, typ: NTI42042, name: "borderBottomColor", sons: null}, -{kind: 1, offset: "borderBottomStyle", len: 0, typ: NTI42042, name: "borderBottomStyle", sons: null}, -{kind: 1, offset: "borderBottomWidth", len: 0, typ: NTI42042, name: "borderBottomWidth", sons: null}, -{kind: 1, offset: "borderColor", len: 0, typ: NTI42042, name: "borderColor", sons: null}, -{kind: 1, offset: "borderLeft", len: 0, typ: NTI42042, name: "borderLeft", sons: null}, -{kind: 1, offset: "borderLeftColor", len: 0, typ: NTI42042, name: "borderLeftColor", sons: null}, -{kind: 1, offset: "borderLeftStyle", len: 0, typ: NTI42042, name: "borderLeftStyle", sons: null}, -{kind: 1, offset: "borderLeftWidth", len: 0, typ: NTI42042, name: "borderLeftWidth", sons: null}, -{kind: 1, offset: "borderRight", len: 0, typ: NTI42042, name: "borderRight", sons: null}, -{kind: 1, offset: "borderRightColor", len: 0, typ: NTI42042, name: "borderRightColor", sons: null}, -{kind: 1, offset: "borderRightStyle", len: 0, typ: NTI42042, name: "borderRightStyle", sons: null}, -{kind: 1, offset: "borderRightWidth", len: 0, typ: NTI42042, name: "borderRightWidth", sons: null}, -{kind: 1, offset: "borderStyle", len: 0, typ: NTI42042, name: "borderStyle", sons: null}, -{kind: 1, offset: "borderTop", len: 0, typ: NTI42042, name: "borderTop", sons: null}, -{kind: 1, offset: "borderTopColor", len: 0, typ: NTI42042, name: "borderTopColor", sons: null}, -{kind: 1, offset: "borderTopStyle", len: 0, typ: NTI42042, name: "borderTopStyle", sons: null}, -{kind: 1, offset: "borderTopWidth", len: 0, typ: NTI42042, name: "borderTopWidth", sons: null}, -{kind: 1, offset: "borderWidth", len: 0, typ: NTI42042, name: "borderWidth", sons: null}, -{kind: 1, offset: "bottom", len: 0, typ: NTI42042, name: "bottom", sons: null}, -{kind: 1, offset: "captionSide", len: 0, typ: NTI42042, name: "captionSide", sons: null}, -{kind: 1, offset: "clear", len: 0, typ: NTI42042, name: "clear", sons: null}, -{kind: 1, offset: "clip", len: 0, typ: NTI42042, name: "clip", sons: null}, -{kind: 1, offset: "color", len: 0, typ: NTI42042, name: "color", sons: null}, -{kind: 1, offset: "cursor", len: 0, typ: NTI42042, name: "cursor", sons: null}, -{kind: 1, offset: "direction", len: 0, typ: NTI42042, name: "direction", sons: null}, -{kind: 1, offset: "display", len: 0, typ: NTI42042, name: "display", sons: null}, -{kind: 1, offset: "emptyCells", len: 0, typ: NTI42042, name: "emptyCells", sons: null}, -{kind: 1, offset: "cssFloat", len: 0, typ: NTI42042, name: "cssFloat", sons: null}, -{kind: 1, offset: "font", len: 0, typ: NTI42042, name: "font", sons: null}, -{kind: 1, offset: "fontFamily", len: 0, typ: NTI42042, name: "fontFamily", sons: null}, -{kind: 1, offset: "fontSize", len: 0, typ: NTI42042, name: "fontSize", sons: null}, -{kind: 1, offset: "fontStretch", len: 0, typ: NTI42042, name: "fontStretch", sons: null}, -{kind: 1, offset: "fontStyle", len: 0, typ: NTI42042, name: "fontStyle", sons: null}, -{kind: 1, offset: "fontVariant", len: 0, typ: NTI42042, name: "fontVariant", sons: null}, -{kind: 1, offset: "fontWeight", len: 0, typ: NTI42042, name: "fontWeight", sons: null}, -{kind: 1, offset: "height", len: 0, typ: NTI42042, name: "height", sons: null}, -{kind: 1, offset: "left", len: 0, typ: NTI42042, name: "left", sons: null}, -{kind: 1, offset: "letterSpacing", len: 0, typ: NTI42042, name: "letterSpacing", sons: null}, -{kind: 1, offset: "lineHeight", len: 0, typ: NTI42042, name: "lineHeight", sons: null}, -{kind: 1, offset: "listStyle", len: 0, typ: NTI42042, name: "listStyle", sons: null}, -{kind: 1, offset: "listStyleImage", len: 0, typ: NTI42042, name: "listStyleImage", sons: null}, -{kind: 1, offset: "listStylePosition", len: 0, typ: NTI42042, name: "listStylePosition", sons: null}, -{kind: 1, offset: "listStyleType", len: 0, typ: NTI42042, name: "listStyleType", sons: null}, -{kind: 1, offset: "margin", len: 0, typ: NTI42042, name: "margin", sons: null}, -{kind: 1, offset: "marginBottom", len: 0, typ: NTI42042, name: "marginBottom", sons: null}, -{kind: 1, offset: "marginLeft", len: 0, typ: NTI42042, name: "marginLeft", sons: null}, -{kind: 1, offset: "marginRight", len: 0, typ: NTI42042, name: "marginRight", sons: null}, -{kind: 1, offset: "marginTop", len: 0, typ: NTI42042, name: "marginTop", sons: null}, -{kind: 1, offset: "maxHeight", len: 0, typ: NTI42042, name: "maxHeight", sons: null}, -{kind: 1, offset: "maxWidth", len: 0, typ: NTI42042, name: "maxWidth", sons: null}, -{kind: 1, offset: "minHeight", len: 0, typ: NTI42042, name: "minHeight", sons: null}, -{kind: 1, offset: "minWidth", len: 0, typ: NTI42042, name: "minWidth", sons: null}, -{kind: 1, offset: "opacity", len: 0, typ: NTI42042, name: "opacity", sons: null}, -{kind: 1, offset: "overflow", len: 0, typ: NTI42042, name: "overflow", sons: null}, -{kind: 1, offset: "padding", len: 0, typ: NTI42042, name: "padding", sons: null}, -{kind: 1, offset: "paddingBottom", len: 0, typ: NTI42042, name: "paddingBottom", sons: null}, -{kind: 1, offset: "paddingLeft", len: 0, typ: NTI42042, name: "paddingLeft", sons: null}, -{kind: 1, offset: "paddingRight", len: 0, typ: NTI42042, name: "paddingRight", sons: null}, -{kind: 1, offset: "paddingTop", len: 0, typ: NTI42042, name: "paddingTop", sons: null}, -{kind: 1, offset: "pageBreakAfter", len: 0, typ: NTI42042, name: "pageBreakAfter", sons: null}, -{kind: 1, offset: "pageBreakBefore", len: 0, typ: NTI42042, name: "pageBreakBefore", sons: null}, -{kind: 1, offset: "pointerEvents", len: 0, typ: NTI42042, name: "pointerEvents", sons: null}, -{kind: 1, offset: "position", len: 0, typ: NTI42042, name: "position", sons: null}, -{kind: 1, offset: "right", len: 0, typ: NTI42042, name: "right", sons: null}, -{kind: 1, offset: "scrollbar3dLightColor", len: 0, typ: NTI42042, name: "scrollbar3dLightColor", sons: null}, -{kind: 1, offset: "scrollbarArrowColor", len: 0, typ: NTI42042, name: "scrollbarArrowColor", sons: null}, -{kind: 1, offset: "scrollbarBaseColor", len: 0, typ: NTI42042, name: "scrollbarBaseColor", sons: null}, -{kind: 1, offset: "scrollbarDarkshadowColor", len: 0, typ: NTI42042, name: "scrollbarDarkshadowColor", sons: null}, -{kind: 1, offset: "scrollbarFaceColor", len: 0, typ: NTI42042, name: "scrollbarFaceColor", sons: null}, -{kind: 1, offset: "scrollbarHighlightColor", len: 0, typ: NTI42042, name: "scrollbarHighlightColor", sons: null}, -{kind: 1, offset: "scrollbarShadowColor", len: 0, typ: NTI42042, name: "scrollbarShadowColor", sons: null}, -{kind: 1, offset: "scrollbarTrackColor", len: 0, typ: NTI42042, name: "scrollbarTrackColor", sons: null}, -{kind: 1, offset: "tableLayout", len: 0, typ: NTI42042, name: "tableLayout", sons: null}, -{kind: 1, offset: "textAlign", len: 0, typ: NTI42042, name: "textAlign", sons: null}, -{kind: 1, offset: "textDecoration", len: 0, typ: NTI42042, name: "textDecoration", sons: null}, -{kind: 1, offset: "textIndent", len: 0, typ: NTI42042, name: "textIndent", sons: null}, -{kind: 1, offset: "textTransform", len: 0, typ: NTI42042, name: "textTransform", sons: null}, -{kind: 1, offset: "transform", len: 0, typ: NTI42042, name: "transform", sons: null}, -{kind: 1, offset: "top", len: 0, typ: NTI42042, name: "top", sons: null}, -{kind: 1, offset: "verticalAlign", len: 0, typ: NTI42042, name: "verticalAlign", sons: null}, -{kind: 1, offset: "visibility", len: 0, typ: NTI42042, name: "visibility", sons: null}, -{kind: 1, offset: "width", len: 0, typ: NTI42042, name: "width", sons: null}, -{kind: 1, offset: "wordSpacing", len: 0, typ: NTI42042, name: "wordSpacing", sons: null}, -{kind: 1, offset: "zIndex", len: 0, typ: NTI42006, name: "zIndex", sons: null}]}; -NTI82283.node = NNI82283; -NTI82283.base = NTI45408; -NTI82281.base = NTI82283; -var NNI82231 = {kind: 2, len: 14, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "attributes", len: 0, typ: NTI82561, name: "attributes", sons: null}, -{kind: 1, offset: "childNodes", len: 0, typ: NTI82563, name: "childNodes", sons: null}, -{kind: 1, offset: "children", len: 0, typ: NTI82565, name: "children", sons: null}, -{kind: 1, offset: "data", len: 0, typ: NTI42042, name: "data", sons: null}, -{kind: 1, offset: "firstChild", len: 0, typ: NTI82229, name: "firstChild", sons: null}, -{kind: 1, offset: "lastChild", len: 0, typ: NTI82229, name: "lastChild", sons: null}, -{kind: 1, offset: "nextSibling", len: 0, typ: NTI82229, name: "nextSibling", sons: null}, -{kind: 1, offset: "nodeName", len: 0, typ: NTI42042, name: "nodeName", sons: null}, -{kind: 1, offset: "nodeType", len: 0, typ: NTI82227, name: "nodeType", sons: null}, -{kind: 1, offset: "nodeValue", len: 0, typ: NTI42042, name: "nodeValue", sons: null}, -{kind: 1, offset: "parentNode", len: 0, typ: NTI82229, name: "parentNode", sons: null}, -{kind: 1, offset: "previousSibling", len: 0, typ: NTI82229, name: "previousSibling", sons: null}, -{kind: 1, offset: "innerHTML", len: 0, typ: NTI42042, name: "innerHTML", sons: null}, -{kind: 1, offset: "style", len: 0, typ: NTI82281, name: "style", sons: null}]}; -NTI82231.node = NNI82231; -var NNI82205 = {kind: 2, len: 20, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "onabort", len: 0, typ: NTI82372, name: "onabort", sons: null}, -{kind: 1, offset: "onblur", len: 0, typ: NTI82376, name: "onblur", sons: null}, -{kind: 1, offset: "onchange", len: 0, typ: NTI82380, name: "onchange", sons: null}, -{kind: 1, offset: "onclick", len: 0, typ: NTI82384, name: "onclick", sons: null}, -{kind: 1, offset: "ondblclick", len: 0, typ: NTI82388, name: "ondblclick", sons: null}, -{kind: 1, offset: "onerror", len: 0, typ: NTI82392, name: "onerror", sons: null}, -{kind: 1, offset: "onfocus", len: 0, typ: NTI82396, name: "onfocus", sons: null}, -{kind: 1, offset: "onkeydown", len: 0, typ: NTI82400, name: "onkeydown", sons: null}, -{kind: 1, offset: "onkeypress", len: 0, typ: NTI82404, name: "onkeypress", sons: null}, -{kind: 1, offset: "onkeyup", len: 0, typ: NTI82408, name: "onkeyup", sons: null}, -{kind: 1, offset: "onload", len: 0, typ: NTI82412, name: "onload", sons: null}, -{kind: 1, offset: "onmousedown", len: 0, typ: NTI82416, name: "onmousedown", sons: null}, -{kind: 1, offset: "onmousemove", len: 0, typ: NTI82420, name: "onmousemove", sons: null}, -{kind: 1, offset: "onmouseout", len: 0, typ: NTI82424, name: "onmouseout", sons: null}, -{kind: 1, offset: "onmouseover", len: 0, typ: NTI82428, name: "onmouseover", sons: null}, -{kind: 1, offset: "onmouseup", len: 0, typ: NTI82432, name: "onmouseup", sons: null}, -{kind: 1, offset: "onreset", len: 0, typ: NTI82436, name: "onreset", sons: null}, -{kind: 1, offset: "onselect", len: 0, typ: NTI82440, name: "onselect", sons: null}, -{kind: 1, offset: "onsubmit", len: 0, typ: NTI82444, name: "onsubmit", sons: null}, -{kind: 1, offset: "onunload", len: 0, typ: NTI82448, name: "onunload", sons: null}]}; -NTI82205.node = NNI82205; -NTI82205.base = NTI45408; -NTI82231.base = NTI82205; -NTI82229.base = NTI82231; -NTI84305.base = NTI82229; -NTI195578.base = NTI42042; -var NNI45462 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; -NTI45462.node = NNI45462; -NTI45462.base = NTI45428; -var NNI193071 = {kind: 2, len: 2, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "Field0", len: 0, typ: NTI42006, name: "Field0", sons: null}, -{kind: 1, offset: "Field1", len: 0, typ: NTI42032, name: "Field1", sons: null}]}; -NTI193071.node = NNI193071; +var NTI43032 = {size: 0,kind: 1,base: null,node: null,finalizer: null}; +var NTI195058 = {size: 0, kind: 18, base: null, node: null, finalizer: null}; +var NTI46462 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI197570 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; +var NTI83448 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI83444 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI83440 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI83436 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI83432 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI83428 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI83424 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI83420 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI83416 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI83412 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI83408 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI83404 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI83400 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI83396 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI83392 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI83388 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI83384 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI83380 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI83376 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI83372 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI83205 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI83283 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI83281 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; +var NTI83227 = {size: 0, kind: 14, base: null, node: null, finalizer: null}; +var NTI83565 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; +var NTI83563 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; +var NTI83561 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; +var NTI83231 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI83229 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; +var NTI85305 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; +var NTI46450 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI46458 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI43006 = {size: 0,kind: 31,base: null,node: null,finalizer: null}; +var NTI62156 = {size: 0, kind: 18, base: null, node: null, finalizer: null}; +var NTI46408 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI46514 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; +var NTI43016 = {size: 0,kind: 40,base: null,node: null,finalizer: null}; +var NTI43040 = {size: 0,kind: 28,base: null,node: null,finalizer: null}; +var NTI43042 = {size: 0,kind: 29,base: null,node: null,finalizer: null}; +var NTI46508 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; +var NTI46426 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI46428 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI46442 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI46446 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NNI46446 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI46446.node = NNI46446; +var NNI46442 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI46442.node = NNI46442; +var NNI46428 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI46428.node = NNI46428; +NTI46508.base = NTI46426; +NTI46514.base = NTI46426; +var NNI46426 = {kind: 2, len: 6, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "parent", len: 0, typ: NTI46508, name: "parent", sons: null}, +{kind: 1, offset: "name", len: 0, typ: NTI43042, name: "name", sons: null}, +{kind: 1, offset: "message", len: 0, typ: NTI43040, name: "msg", sons: null}, +{kind: 1, offset: "trace", len: 0, typ: NTI43040, name: "trace", sons: null}, +{kind: 1, offset: "raiseId", len: 0, typ: NTI43016, name: "raiseId", sons: null}, +{kind: 1, offset: "up", len: 0, typ: NTI46514, name: "up", sons: null}]}; +NTI46426.node = NNI46426; +var NNI46408 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI46408.node = NNI46408; +NTI46426.base = NTI46408; +NTI46428.base = NTI46426; +NTI46442.base = NTI46428; +NTI46446.base = NTI46442; +var NNI62156 = {kind: 2, len: 2, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "Field0", len: 0, typ: NTI43042, name: "Field0", sons: null}, +{kind: 1, offset: "Field1", len: 0, typ: NTI43006, name: "Field1", sons: null}]}; +NTI62156.node = NNI62156; +var NNI46458 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI46458.node = NNI46458; +NTI46458.base = NTI46428; +var NNI46450 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI46450.node = NNI46450; +NTI46450.base = NTI46428; +NTI83561.base = NTI83229; +NTI83563.base = NTI83229; +NTI83565.base = NTI83229; +var NNI83227 = {kind: 2, offset: 0, typ: null, name: null, len: 12, sons: {"1": {kind: 1, offset: 1, typ: NTI83227, name: "ElementNode", len: 0, sons: null}, +"2": {kind: 1, offset: 2, typ: NTI83227, name: "AttributeNode", len: 0, sons: null}, +"3": {kind: 1, offset: 3, typ: NTI83227, name: "TextNode", len: 0, sons: null}, +"4": {kind: 1, offset: 4, typ: NTI83227, name: "CDATANode", len: 0, sons: null}, +"5": {kind: 1, offset: 5, typ: NTI83227, name: "EntityRefNode", len: 0, sons: null}, +"6": {kind: 1, offset: 6, typ: NTI83227, name: "EntityNode", len: 0, sons: null}, +"7": {kind: 1, offset: 7, typ: NTI83227, name: "ProcessingInstructionNode", len: 0, sons: null}, +"8": {kind: 1, offset: 8, typ: NTI83227, name: "CommentNode", len: 0, sons: null}, +"9": {kind: 1, offset: 9, typ: NTI83227, name: "DocumentNode", len: 0, sons: null}, +"10": {kind: 1, offset: 10, typ: NTI83227, name: "DocumentTypeNode", len: 0, sons: null}, +"11": {kind: 1, offset: 11, typ: NTI83227, name: "DocumentFragmentNode", len: 0, sons: null}, +"12": {kind: 1, offset: 12, typ: NTI83227, name: "NotationNode", len: 0, sons: null}}}; +NTI83227.node = NNI83227; +var NNI83283 = {kind: 2, len: 92, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "background", len: 0, typ: NTI43042, name: "background", sons: null}, +{kind: 1, offset: "backgroundAttachment", len: 0, typ: NTI43042, name: "backgroundAttachment", sons: null}, +{kind: 1, offset: "backgroundColor", len: 0, typ: NTI43042, name: "backgroundColor", sons: null}, +{kind: 1, offset: "backgroundImage", len: 0, typ: NTI43042, name: "backgroundImage", sons: null}, +{kind: 1, offset: "backgroundPosition", len: 0, typ: NTI43042, name: "backgroundPosition", sons: null}, +{kind: 1, offset: "backgroundRepeat", len: 0, typ: NTI43042, name: "backgroundRepeat", sons: null}, +{kind: 1, offset: "border", len: 0, typ: NTI43042, name: "border", sons: null}, +{kind: 1, offset: "borderBottom", len: 0, typ: NTI43042, name: "borderBottom", sons: null}, +{kind: 1, offset: "borderBottomColor", len: 0, typ: NTI43042, name: "borderBottomColor", sons: null}, +{kind: 1, offset: "borderBottomStyle", len: 0, typ: NTI43042, name: "borderBottomStyle", sons: null}, +{kind: 1, offset: "borderBottomWidth", len: 0, typ: NTI43042, name: "borderBottomWidth", sons: null}, +{kind: 1, offset: "borderColor", len: 0, typ: NTI43042, name: "borderColor", sons: null}, +{kind: 1, offset: "borderLeft", len: 0, typ: NTI43042, name: "borderLeft", sons: null}, +{kind: 1, offset: "borderLeftColor", len: 0, typ: NTI43042, name: "borderLeftColor", sons: null}, +{kind: 1, offset: "borderLeftStyle", len: 0, typ: NTI43042, name: "borderLeftStyle", sons: null}, +{kind: 1, offset: "borderLeftWidth", len: 0, typ: NTI43042, name: "borderLeftWidth", sons: null}, +{kind: 1, offset: "borderRight", len: 0, typ: NTI43042, name: "borderRight", sons: null}, +{kind: 1, offset: "borderRightColor", len: 0, typ: NTI43042, name: "borderRightColor", sons: null}, +{kind: 1, offset: "borderRightStyle", len: 0, typ: NTI43042, name: "borderRightStyle", sons: null}, +{kind: 1, offset: "borderRightWidth", len: 0, typ: NTI43042, name: "borderRightWidth", sons: null}, +{kind: 1, offset: "borderStyle", len: 0, typ: NTI43042, name: "borderStyle", sons: null}, +{kind: 1, offset: "borderTop", len: 0, typ: NTI43042, name: "borderTop", sons: null}, +{kind: 1, offset: "borderTopColor", len: 0, typ: NTI43042, name: "borderTopColor", sons: null}, +{kind: 1, offset: "borderTopStyle", len: 0, typ: NTI43042, name: "borderTopStyle", sons: null}, +{kind: 1, offset: "borderTopWidth", len: 0, typ: NTI43042, name: "borderTopWidth", sons: null}, +{kind: 1, offset: "borderWidth", len: 0, typ: NTI43042, name: "borderWidth", sons: null}, +{kind: 1, offset: "bottom", len: 0, typ: NTI43042, name: "bottom", sons: null}, +{kind: 1, offset: "captionSide", len: 0, typ: NTI43042, name: "captionSide", sons: null}, +{kind: 1, offset: "clear", len: 0, typ: NTI43042, name: "clear", sons: null}, +{kind: 1, offset: "clip", len: 0, typ: NTI43042, name: "clip", sons: null}, +{kind: 1, offset: "color", len: 0, typ: NTI43042, name: "color", sons: null}, +{kind: 1, offset: "cursor", len: 0, typ: NTI43042, name: "cursor", sons: null}, +{kind: 1, offset: "direction", len: 0, typ: NTI43042, name: "direction", sons: null}, +{kind: 1, offset: "display", len: 0, typ: NTI43042, name: "display", sons: null}, +{kind: 1, offset: "emptyCells", len: 0, typ: NTI43042, name: "emptyCells", sons: null}, +{kind: 1, offset: "cssFloat", len: 0, typ: NTI43042, name: "cssFloat", sons: null}, +{kind: 1, offset: "font", len: 0, typ: NTI43042, name: "font", sons: null}, +{kind: 1, offset: "fontFamily", len: 0, typ: NTI43042, name: "fontFamily", sons: null}, +{kind: 1, offset: "fontSize", len: 0, typ: NTI43042, name: "fontSize", sons: null}, +{kind: 1, offset: "fontStretch", len: 0, typ: NTI43042, name: "fontStretch", sons: null}, +{kind: 1, offset: "fontStyle", len: 0, typ: NTI43042, name: "fontStyle", sons: null}, +{kind: 1, offset: "fontVariant", len: 0, typ: NTI43042, name: "fontVariant", sons: null}, +{kind: 1, offset: "fontWeight", len: 0, typ: NTI43042, name: "fontWeight", sons: null}, +{kind: 1, offset: "height", len: 0, typ: NTI43042, name: "height", sons: null}, +{kind: 1, offset: "left", len: 0, typ: NTI43042, name: "left", sons: null}, +{kind: 1, offset: "letterSpacing", len: 0, typ: NTI43042, name: "letterSpacing", sons: null}, +{kind: 1, offset: "lineHeight", len: 0, typ: NTI43042, name: "lineHeight", sons: null}, +{kind: 1, offset: "listStyle", len: 0, typ: NTI43042, name: "listStyle", sons: null}, +{kind: 1, offset: "listStyleImage", len: 0, typ: NTI43042, name: "listStyleImage", sons: null}, +{kind: 1, offset: "listStylePosition", len: 0, typ: NTI43042, name: "listStylePosition", sons: null}, +{kind: 1, offset: "listStyleType", len: 0, typ: NTI43042, name: "listStyleType", sons: null}, +{kind: 1, offset: "margin", len: 0, typ: NTI43042, name: "margin", sons: null}, +{kind: 1, offset: "marginBottom", len: 0, typ: NTI43042, name: "marginBottom", sons: null}, +{kind: 1, offset: "marginLeft", len: 0, typ: NTI43042, name: "marginLeft", sons: null}, +{kind: 1, offset: "marginRight", len: 0, typ: NTI43042, name: "marginRight", sons: null}, +{kind: 1, offset: "marginTop", len: 0, typ: NTI43042, name: "marginTop", sons: null}, +{kind: 1, offset: "maxHeight", len: 0, typ: NTI43042, name: "maxHeight", sons: null}, +{kind: 1, offset: "maxWidth", len: 0, typ: NTI43042, name: "maxWidth", sons: null}, +{kind: 1, offset: "minHeight", len: 0, typ: NTI43042, name: "minHeight", sons: null}, +{kind: 1, offset: "minWidth", len: 0, typ: NTI43042, name: "minWidth", sons: null}, +{kind: 1, offset: "opacity", len: 0, typ: NTI43042, name: "opacity", sons: null}, +{kind: 1, offset: "overflow", len: 0, typ: NTI43042, name: "overflow", sons: null}, +{kind: 1, offset: "padding", len: 0, typ: NTI43042, name: "padding", sons: null}, +{kind: 1, offset: "paddingBottom", len: 0, typ: NTI43042, name: "paddingBottom", sons: null}, +{kind: 1, offset: "paddingLeft", len: 0, typ: NTI43042, name: "paddingLeft", sons: null}, +{kind: 1, offset: "paddingRight", len: 0, typ: NTI43042, name: "paddingRight", sons: null}, +{kind: 1, offset: "paddingTop", len: 0, typ: NTI43042, name: "paddingTop", sons: null}, +{kind: 1, offset: "pageBreakAfter", len: 0, typ: NTI43042, name: "pageBreakAfter", sons: null}, +{kind: 1, offset: "pageBreakBefore", len: 0, typ: NTI43042, name: "pageBreakBefore", sons: null}, +{kind: 1, offset: "pointerEvents", len: 0, typ: NTI43042, name: "pointerEvents", sons: null}, +{kind: 1, offset: "position", len: 0, typ: NTI43042, name: "position", sons: null}, +{kind: 1, offset: "right", len: 0, typ: NTI43042, name: "right", sons: null}, +{kind: 1, offset: "scrollbar3dLightColor", len: 0, typ: NTI43042, name: "scrollbar3dLightColor", sons: null}, +{kind: 1, offset: "scrollbarArrowColor", len: 0, typ: NTI43042, name: "scrollbarArrowColor", sons: null}, +{kind: 1, offset: "scrollbarBaseColor", len: 0, typ: NTI43042, name: "scrollbarBaseColor", sons: null}, +{kind: 1, offset: "scrollbarDarkshadowColor", len: 0, typ: NTI43042, name: "scrollbarDarkshadowColor", sons: null}, +{kind: 1, offset: "scrollbarFaceColor", len: 0, typ: NTI43042, name: "scrollbarFaceColor", sons: null}, +{kind: 1, offset: "scrollbarHighlightColor", len: 0, typ: NTI43042, name: "scrollbarHighlightColor", sons: null}, +{kind: 1, offset: "scrollbarShadowColor", len: 0, typ: NTI43042, name: "scrollbarShadowColor", sons: null}, +{kind: 1, offset: "scrollbarTrackColor", len: 0, typ: NTI43042, name: "scrollbarTrackColor", sons: null}, +{kind: 1, offset: "tableLayout", len: 0, typ: NTI43042, name: "tableLayout", sons: null}, +{kind: 1, offset: "textAlign", len: 0, typ: NTI43042, name: "textAlign", sons: null}, +{kind: 1, offset: "textDecoration", len: 0, typ: NTI43042, name: "textDecoration", sons: null}, +{kind: 1, offset: "textIndent", len: 0, typ: NTI43042, name: "textIndent", sons: null}, +{kind: 1, offset: "textTransform", len: 0, typ: NTI43042, name: "textTransform", sons: null}, +{kind: 1, offset: "transform", len: 0, typ: NTI43042, name: "transform", sons: null}, +{kind: 1, offset: "top", len: 0, typ: NTI43042, name: "top", sons: null}, +{kind: 1, offset: "verticalAlign", len: 0, typ: NTI43042, name: "verticalAlign", sons: null}, +{kind: 1, offset: "visibility", len: 0, typ: NTI43042, name: "visibility", sons: null}, +{kind: 1, offset: "width", len: 0, typ: NTI43042, name: "width", sons: null}, +{kind: 1, offset: "wordSpacing", len: 0, typ: NTI43042, name: "wordSpacing", sons: null}, +{kind: 1, offset: "zIndex", len: 0, typ: NTI43006, name: "zIndex", sons: null}]}; +NTI83283.node = NNI83283; +NTI83283.base = NTI46408; +NTI83281.base = NTI83283; +var NNI83231 = {kind: 2, len: 14, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "attributes", len: 0, typ: NTI83561, name: "attributes", sons: null}, +{kind: 1, offset: "childNodes", len: 0, typ: NTI83563, name: "childNodes", sons: null}, +{kind: 1, offset: "children", len: 0, typ: NTI83565, name: "children", sons: null}, +{kind: 1, offset: "data", len: 0, typ: NTI43042, name: "data", sons: null}, +{kind: 1, offset: "firstChild", len: 0, typ: NTI83229, name: "firstChild", sons: null}, +{kind: 1, offset: "lastChild", len: 0, typ: NTI83229, name: "lastChild", sons: null}, +{kind: 1, offset: "nextSibling", len: 0, typ: NTI83229, name: "nextSibling", sons: null}, +{kind: 1, offset: "nodeName", len: 0, typ: NTI43042, name: "nodeName", sons: null}, +{kind: 1, offset: "nodeType", len: 0, typ: NTI83227, name: "nodeType", sons: null}, +{kind: 1, offset: "nodeValue", len: 0, typ: NTI43042, name: "nodeValue", sons: null}, +{kind: 1, offset: "parentNode", len: 0, typ: NTI83229, name: "parentNode", sons: null}, +{kind: 1, offset: "previousSibling", len: 0, typ: NTI83229, name: "previousSibling", sons: null}, +{kind: 1, offset: "innerHTML", len: 0, typ: NTI43042, name: "innerHTML", sons: null}, +{kind: 1, offset: "style", len: 0, typ: NTI83281, name: "style", sons: null}]}; +NTI83231.node = NNI83231; +var NNI83205 = {kind: 2, len: 20, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "onabort", len: 0, typ: NTI83372, name: "onabort", sons: null}, +{kind: 1, offset: "onblur", len: 0, typ: NTI83376, name: "onblur", sons: null}, +{kind: 1, offset: "onchange", len: 0, typ: NTI83380, name: "onchange", sons: null}, +{kind: 1, offset: "onclick", len: 0, typ: NTI83384, name: "onclick", sons: null}, +{kind: 1, offset: "ondblclick", len: 0, typ: NTI83388, name: "ondblclick", sons: null}, +{kind: 1, offset: "onerror", len: 0, typ: NTI83392, name: "onerror", sons: null}, +{kind: 1, offset: "onfocus", len: 0, typ: NTI83396, name: "onfocus", sons: null}, +{kind: 1, offset: "onkeydown", len: 0, typ: NTI83400, name: "onkeydown", sons: null}, +{kind: 1, offset: "onkeypress", len: 0, typ: NTI83404, name: "onkeypress", sons: null}, +{kind: 1, offset: "onkeyup", len: 0, typ: NTI83408, name: "onkeyup", sons: null}, +{kind: 1, offset: "onload", len: 0, typ: NTI83412, name: "onload", sons: null}, +{kind: 1, offset: "onmousedown", len: 0, typ: NTI83416, name: "onmousedown", sons: null}, +{kind: 1, offset: "onmousemove", len: 0, typ: NTI83420, name: "onmousemove", sons: null}, +{kind: 1, offset: "onmouseout", len: 0, typ: NTI83424, name: "onmouseout", sons: null}, +{kind: 1, offset: "onmouseover", len: 0, typ: NTI83428, name: "onmouseover", sons: null}, +{kind: 1, offset: "onmouseup", len: 0, typ: NTI83432, name: "onmouseup", sons: null}, +{kind: 1, offset: "onreset", len: 0, typ: NTI83436, name: "onreset", sons: null}, +{kind: 1, offset: "onselect", len: 0, typ: NTI83440, name: "onselect", sons: null}, +{kind: 1, offset: "onsubmit", len: 0, typ: NTI83444, name: "onsubmit", sons: null}, +{kind: 1, offset: "onunload", len: 0, typ: NTI83448, name: "onunload", sons: null}]}; +NTI83205.node = NNI83205; +NTI83205.base = NTI46408; +NTI83231.base = NTI83205; +NTI83229.base = NTI83231; +NTI85305.base = NTI83229; +NTI197570.base = NTI43042; +var NNI46462 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI46462.node = NNI46462; +NTI46462.base = NTI46428; +var NNI195058 = {kind: 2, len: 2, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "Field0", len: 0, typ: NTI43006, name: "Field0", sons: null}, +{kind: 1, offset: "Field1", len: 0, typ: NTI43032, name: "Field1", sons: null}]}; +NTI195058.node = NNI195058; -function makeNimstrLit(c_63270) { - var ln = c_63270.length; +function makeNimstrLit(c_64270) { + var ln = c_64270.length; var result = new Array(ln); for (var i = 0; i < ln; ++i) { - result[i] = c_63270.charCodeAt(i); + result[i] = c_64270.charCodeAt(i); } return result; - + } function setConstr() { - var result = {}; + var result = {}; for (var i = 0; i < arguments.length; ++i) { var x = arguments[i]; if (typeof(x) == "object") { @@ -276,103 +274,103 @@ function setConstr() { return result; - + } var ConstSet1 = setConstr(17, 16, 4, 18, 27, 19, 23, 22, 21); -function nimCopy(dest_64827, src_64828, ti_64829) { - var result_65019 = null; +function nimCopy(dest_65827, src_65828, ti_65829) { + var result_66019 = null; - switch (ti_64829.kind) { - case 21: - case 22: - case 23: - case 5: - if (!(is_fat_pointer_64801(ti_64829))) { - result_65019 = src_64828; - } - else { - result_65019 = [src_64828[0], src_64828[1]]; - } - - break; - case 19: - if (dest_64827 === null || dest_64827 === undefined) { - dest_64827 = {}; + switch (ti_65829.kind) { + case 21: + case 22: + case 23: + case 5: + if (!(is_fat_pointer_65801(ti_65829))) { + result_66019 = src_65828; } else { - for (var key in dest_64827) { delete dest_64827[key]; } + result_66019 = [src_65828[0], src_65828[1]]; } - for (var key in src_64828) { dest_64827[key] = src_64828[key]; } - result_65019 = dest_64827; + + break; + case 19: + if (dest_65827 === null || dest_65827 === undefined) { + dest_65827 = {}; + } + else { + for (var key in dest_65827) { delete dest_65827[key]; } + } + for (var key in src_65828) { dest_65827[key] = src_65828[key]; } + result_66019 = dest_65827; - break; - case 18: - case 17: - if (!((ti_64829.base == null))) { - result_65019 = nimCopy(dest_64827, src_64828, ti_64829.base); - } - else { - if ((ti_64829.kind == 17)) { - result_65019 = (dest_64827 === null || dest_64827 === undefined) ? {m_type: ti_64829} : dest_64827; - } - else { - result_65019 = (dest_64827 === null || dest_64827 === undefined) ? {} : dest_64827; - } - } - nimCopyAux(result_65019, src_64828, ti_64829.node); - break; - case 24: - case 4: - case 27: - case 16: - if (src_64828 === null) { - result_65019 = null; + break; + case 18: + case 17: + if (!((ti_65829.base == null))) { + result_66019 = nimCopy(dest_65827, src_65828, ti_65829.base); } else { - if (dest_64827 === null || dest_64827 === undefined) { - dest_64827 = new Array(src_64828.length); + if ((ti_65829.kind == 17)) { + result_66019 = (dest_65827 === null || dest_65827 === undefined) ? {m_type: ti_65829} : dest_65827; + } + else { + result_66019 = (dest_65827 === null || dest_65827 === undefined) ? {} : dest_65827; + } + } + nimCopyAux(result_66019, src_65828, ti_65829.node); + break; + case 24: + case 4: + case 27: + case 16: + if (src_65828 === null) { + result_66019 = null; + } + else { + if (dest_65827 === null || dest_65827 === undefined) { + dest_65827 = new Array(src_65828.length); } else { - dest_64827.length = src_64828.length; + dest_65827.length = src_65828.length; } - result_65019 = dest_64827; - for (var i = 0; i < src_64828.length; ++i) { - result_65019[i] = nimCopy(result_65019[i], src_64828[i], ti_64829.base); + result_66019 = dest_65827; + for (var i = 0; i < src_65828.length; ++i) { + result_66019[i] = nimCopy(result_66019[i], src_65828[i], ti_65829.base); } } - break; - case 28: - if (src_64828 !== null) { - result_65019 = src_64828.slice(0); + break; + case 28: + if (src_65828 !== null) { + result_66019 = src_65828.slice(0); } - break; - default: - result_65019 = src_64828; - break; - } + break; + default: + result_66019 = src_65828; + break; + } - return result_65019; + return result_66019; } -function arrayConstr(len_65086, value_65087, typ_65088) { - var result = new Array(len_65086); - for (var i = 0; i < len_65086; ++i) result[i] = nimCopy(null, value_65087, typ_65088); +function arrayConstr(len_66086, value_66087, typ_66088) { + var result = new Array(len_66086); + for (var i = 0; i < len_66086; ++i) result[i] = nimCopy(null, value_66087, typ_66088); return result; - + } -function cstrToNimstr(c_63287) { - var ln = c_63287.length; +function cstrToNimstr(c_64287) { + var ln = c_64287.length; var result = new Array(ln); var r = 0; for (var i = 0; i < ln; ++i) { - var ch = c_63287.charCodeAt(i); + var ch = c_64287.charCodeAt(i); if (ch < 128) { result[r] = ch; @@ -387,7 +385,7 @@ function cstrToNimstr(c_63287) { } else { ++i; - ch = 65536 + (((ch & 1023) << 10) | (c_63287.charCodeAt(i) & 1023)); + ch = 65536 + (((ch & 1023) << 10) | (c_64287.charCodeAt(i) & 1023)); result[r] = (ch >> 18) | 240; ++r; result[r] = ((ch >> 12) & 63) | 128; @@ -403,1448 +401,1448 @@ function cstrToNimstr(c_63287) { return result; - + } -function toJSStr(s_63304) { - var Tmp5; - var Tmp7; +function toJSStr(s_64304) { + var Tmp5; + var Tmp7; - var result_63305 = null; + var result_64305 = null; - var res_63363 = new_seq_63336((s_63304 != null ? s_63304.length : 0)); - var i_63365 = 0; - var j_63367 = 0; - L1: do { - L2: while (true) { - if (!(i_63365 < (s_63304 != null ? s_63304.length : 0))) break L2; - var c_63368 = s_63304[i_63365]; - if ((c_63368 < 128)) { - res_63363[j_63367] = String.fromCharCode(c_63368); - i_63365 += 1; - } - else { - var helper_63391 = new_seq_63336(0); - L3: do { - L4: while (true) { - if (!true) break L4; - var code_63392 = c_63368.toString(16); - if (((code_63392 != null ? code_63392.length : 0) == 1)) { - if (helper_63391 != null) { helper_63391.push("%0"); } else { helper_63391 = ["%0"]; }; - } - else { - if (helper_63391 != null) { helper_63391.push("%"); } else { helper_63391 = ["%"]; }; - } - - if (helper_63391 != null) { helper_63391.push(code_63392); } else { helper_63391 = [code_63392]; }; - i_63365 += 1; - if (((s_63304 != null ? s_63304.length : 0) <= i_63365)) Tmp5 = true; else { Tmp5 = (s_63304[i_63365] < 128); } if (Tmp5) { - break L3; - } - - c_63368 = s_63304[i_63365]; - } - } while(false); + var res_64378 = new_seq_64336((s_64304 != null ? s_64304.length : 0)); + var i_64380 = 0; + var j_64382 = 0; + L1: do { + L2: while (true) { + if (!(i_64380 < (s_64304 != null ? s_64304.length : 0))) break L2; + var c_64383 = s_64304[i_64380]; + if ((c_64383 < 128)) { + res_64378[j_64382] = String.fromCharCode(c_64383); + i_64380 += 1; + } + else { + var helper_64406 = new_seq_64336(0); + L3: do { + L4: while (true) { + if (!true) break L4; + var code_64407 = c_64383.toString(16); + if (((code_64407 != null ? code_64407.length : 0) == 1)) { + if (helper_64406 != null) { helper_64406.push("%0"); } else { helper_64406 = ["%0"]; }; + } + else { + if (helper_64406 != null) { helper_64406.push("%"); } else { helper_64406 = ["%"]; }; + } + + if (helper_64406 != null) { helper_64406.push(code_64407); } else { helper_64406 = [code_64407]; }; + i_64380 += 1; + if (((s_64304 != null ? s_64304.length : 0) <= i_64380)) Tmp5 = true; else { Tmp5 = (s_64304[i_64380] < 128); } if (Tmp5) { + break L3; + } + + c_64383 = s_64304[i_64380]; + } + } while(false); ++excHandler; - Tmp7 = framePtr; - try { - res_63363[j_63367] = decodeURIComponent(helper_63391.join("")); + Tmp7 = framePtr; + try { + res_64378[j_64382] = decodeURIComponent(helper_64406.join("")); --excHandler; } catch (EXC) { var prevJSError = lastJSError; lastJSError = EXC; --excHandler; - framePtr = Tmp7; - res_63363[j_63367] = helper_63391.join(""); - lastJSError = prevJSError; - } finally { - framePtr = Tmp7; - } - } - - j_63367 += 1; - } - } while(false); - if (res_63363 === null) res_63363 = []; - if (res_63363.length < j_63367) { for (var i=res_63363.length;i 2147483647 || result < -2147483648) raiseOverflow(); return result; - + } -function chckIndx(i_65105, a_65106, b_65107) { - var Tmp1; +function chckIndx(i_66105, a_66106, b_66107) { + var Tmp1; - var result_65108 = 0; + var result_66108 = 0; - BeforeRet: do { - if (!(a_65106 <= i_65105)) Tmp1 = false; else { Tmp1 = (i_65105 <= b_65107); } if (Tmp1) { - result_65108 = i_65105; - break BeforeRet; - } - else { - raiseIndexError(i_65105, a_65106, b_65107); - } - - } while (false); + BeforeRet: do { + if (!(a_66106 <= i_66105)) Tmp1 = false; else { Tmp1 = (i_66105 <= b_66107); } if (Tmp1) { + result_66108 = i_66105; + break BeforeRet; + } + else { + raiseIndexError(i_66105, a_66106, b_66107); + } + + } while (false); - return result_65108; + return result_66108; } -function subInt(a_63821, b_63822) { - var result = a_63821 - b_63822; +function subInt(a_64821, b_64822) { + var result = a_64821 - b_64822; if (result > 2147483647 || result < -2147483648) raiseOverflow(); return result; - + } var ConstSet2 = setConstr([65, 90]); -function chckRange(i_65124, a_65125, b_65126) { - var Tmp1; +function chckRange(i_66124, a_66125, b_66126) { + var Tmp1; - var result_65127 = 0; + var result_66127 = 0; - BeforeRet: do { - if (!(a_65125 <= i_65124)) Tmp1 = false; else { Tmp1 = (i_65124 <= b_65126); } if (Tmp1) { - result_65127 = i_65124; - break BeforeRet; - } - else { - raiseRangeError(); - } - - } while (false); + BeforeRet: do { + if (!(a_66125 <= i_66124)) Tmp1 = false; else { Tmp1 = (i_66124 <= b_66126); } if (Tmp1) { + result_66127 = i_66124; + break BeforeRet; + } + else { + raiseRangeError(); + } + + } while (false); - return result_65127; + return result_66127; } var ConstSet3 = setConstr(95, 32, 46); var ConstSet4 = setConstr(95, 32, 46); -function mulInt(a_63839, b_63840) { - var result = a_63839 * b_63840; +function mulInt(a_64839, b_64840) { + var result = a_64839 * b_64840; if (result > 2147483647 || result < -2147483648) raiseOverflow(); return result; - + } var ConstSet5 = setConstr([97, 122]); var ConstSet6 = setConstr([65, 90], [97, 122]); var ConstSet7 = setConstr([97, 122]); var ConstSet8 = setConstr([65, 90]); -function nimMax(a_64221, b_64222) { - var Tmp1; +function nimMax(a_65221, b_65222) { + var Tmp1; - var result_64223 = 0; + var result_65223 = 0; - BeforeRet: do { - if ((b_64222 <= a_64221)) { - Tmp1 = a_64221; - } - else { - Tmp1 = b_64222; - } - - result_64223 = Tmp1; - break BeforeRet; - } while (false); + BeforeRet: do { + if ((b_65222 <= a_65221)) { + Tmp1 = a_65221; + } + else { + Tmp1 = b_65222; + } + + result_65223 = Tmp1; + break BeforeRet; + } while (false); - return result_64223; + return result_65223; } -function nimMin(a_64203, b_64204) { - var Tmp1; +function nimMin(a_65203, b_65204) { + var Tmp1; - var result_64205 = 0; + var result_65205 = 0; - BeforeRet: do { - if ((a_64203 <= b_64204)) { - Tmp1 = a_64203; - } - else { - Tmp1 = b_64204; - } - - result_64205 = Tmp1; - break BeforeRet; - } while (false); + BeforeRet: do { + if ((a_65203 <= b_65204)) { + Tmp1 = a_65203; + } + else { + Tmp1 = b_65204; + } + + result_65205 = Tmp1; + break BeforeRet; + } while (false); - return result_64205; + return result_65205; } var nim_program_result = 0; -var global_raise_hook_58618 = [null]; -var local_raise_hook_58623 = [null]; -var out_of_mem_hook_58626 = [null]; - if (!Math.trunc) { - Math.trunc = function(v) { - v = +v; - if (!isFinite(v)) return v; +var global_raise_hook_59818 = [null]; +var local_raise_hook_59823 = [null]; +var out_of_mem_hook_59826 = [null]; +if (!Math.trunc) { + Math.trunc = function(v) { + v = +v; + if (!isFinite(v)) return v; + return (v - v % 1) || (v < 0 ? -0 : v === 0 ? v : 0); + }; +} - return (v - v % 1) || (v < 0 ? -0 : v === 0 ? v : 0); - }; - } -var alternative_195319 = [null]; +var alternative_197319 = [null]; -function is_fat_pointer_64801(ti_64803) { - var result_64804 = false; +function is_fat_pointer_65801(ti_65803) { + var result_65804 = false; - BeforeRet: do { - result_64804 = !((ConstSet1[ti_64803.base.kind] != undefined)); - break BeforeRet; - } while (false); + BeforeRet: do { + result_65804 = !((ConstSet1[ti_65803.base.kind] != undefined)); + break BeforeRet; + } while (false); - return result_64804; + return result_65804; } -function nimCopyAux(dest_64832, src_64833, n_64835) { - switch (n_64835.kind) { - case 0: - break; - case 1: - dest_64832[n_64835.offset] = nimCopy(dest_64832[n_64835.offset], src_64833[n_64835.offset], n_64835.typ); +function nimCopyAux(dest_65832, src_65833, n_65835) { + switch (n_65835.kind) { + case 0: + break; + case 1: + dest_65832[n_65835.offset] = nimCopy(dest_65832[n_65835.offset], src_65833[n_65835.offset], n_65835.typ); - break; - case 2: - for (var i = 0; i < n_64835.sons.length; i++) { - nimCopyAux(dest_64832, src_64833, n_64835.sons[i]); + break; + case 2: + for (var i = 0; i < n_65835.sons.length; i++) { + nimCopyAux(dest_65832, src_65833, n_65835.sons[i]); } - break; - case 3: - dest_64832[n_64835.offset] = nimCopy(dest_64832[n_64835.offset], src_64833[n_64835.offset], n_64835.typ); - for (var i = 0; i < n_64835.sons.length; ++i) { - nimCopyAux(dest_64832, src_64833, n_64835.sons[i][1]); + break; + case 3: + dest_65832[n_65835.offset] = nimCopy(dest_65832[n_65835.offset], src_65833[n_65835.offset], n_65835.typ); + for (var i = 0; i < n_65835.sons.length; ++i) { + nimCopyAux(dest_65832, src_65833, n_65835.sons[i][1]); } - break; - } + break; + } - + } -function add_58638(x_58641, x_58641_Idx, y_58642) { - if (x_58641[x_58641_Idx] === null) { x_58641[x_58641_Idx] = []; } - var off = x_58641[x_58641_Idx].length; - x_58641[x_58641_Idx].length += y_58642.length; - for (var i = 0; i < y_58642.length; ++i) { - x_58641[x_58641_Idx][off+i] = y_58642.charCodeAt(i); +function add_59838(x_59841, x_59841_Idx, y_59842) { + if (x_59841[x_59841_Idx] === null) { x_59841[x_59841_Idx] = []; } + var off = x_59841[x_59841_Idx].length; + x_59841[x_59841_Idx].length += y_59842.length; + for (var i = 0; i < y_59842.length; ++i) { + x_59841[x_59841_Idx][off+i] = y_59842.charCodeAt(i); } - + } -function aux_write_stack_trace_61151(f_61153) { - var Tmp3; +function aux_write_stack_trace_62151(f_62153) { + var Tmp3; - var result_61154 = [null]; + var result_62154 = [null]; - var it_61162 = f_61153; - var i_61164 = 0; - var total_61166 = 0; - var temp_frames_61173 = arrayConstr(64, {Field0: null, Field1: 0}, NTI61156); - L1: do { - L2: while (true) { - if (!!((it_61162 == null))) Tmp3 = false; else { Tmp3 = (i_61164 <= 63); } if (!Tmp3) break L2; - temp_frames_61173[i_61164].Field0 = it_61162.procname; - temp_frames_61173[i_61164].Field1 = it_61162.line; - i_61164 += 1; - total_61166 += 1; - it_61162 = it_61162.prev; - } - } while(false); - L4: do { - L5: while (true) { - if (!!((it_61162 == null))) break L5; - total_61166 += 1; - it_61162 = it_61162.prev; - } - } while(false); - result_61154[0] = nimCopy(null, [], NTI42040); - if (!((total_61166 == i_61164))) { - if (result_61154[0] != null) { result_61154[0] = (result_61154[0]).concat(makeNimstrLit("(")); } else { result_61154[0] = makeNimstrLit("("); }; - if (result_61154[0] != null) { result_61154[0] = (result_61154[0]).concat(cstrToNimstr(((total_61166 - i_61164))+"")); } else { result_61154[0] = cstrToNimstr(((total_61166 - i_61164))+"").slice(); }; - if (result_61154[0] != null) { result_61154[0] = (result_61154[0]).concat(makeNimstrLit(" calls omitted) ...\x0A")); } else { result_61154[0] = makeNimstrLit(" calls omitted) ...\x0A"); }; - } - - L6: do { - var j_61421 = 0; - var colontmp__195466 = 0; - colontmp__195466 = (i_61164 - 1); - var res_195471 = colontmp__195466; - L7: do { - L8: while (true) { - if (!(0 <= res_195471)) break L8; - j_61421 = res_195471; - add_58638(result_61154, 0, temp_frames_61173[j_61421].Field0); - if ((0 < temp_frames_61173[j_61421].Field1)) { - if (result_61154[0] != null) { result_61154[0] = (result_61154[0]).concat(makeNimstrLit(", line: ")); } else { result_61154[0] = makeNimstrLit(", line: "); }; - if (result_61154[0] != null) { result_61154[0] = (result_61154[0]).concat(cstrToNimstr((temp_frames_61173[j_61421].Field1)+"")); } else { result_61154[0] = cstrToNimstr((temp_frames_61173[j_61421].Field1)+"").slice(); }; - } - - if (result_61154[0] != null) { result_61154[0] = (result_61154[0]).concat(makeNimstrLit("\x0A")); } else { result_61154[0] = makeNimstrLit("\x0A"); }; - res_195471 -= 1; - } - } while(false); - } while(false); + var it_62162 = f_62153; + var i_62164 = 0; + var total_62166 = 0; + var temp_frames_62173 = arrayConstr(64, {Field0: null, Field1: 0}, NTI62156); + L1: do { + L2: while (true) { + if (!!((it_62162 == null))) Tmp3 = false; else { Tmp3 = (i_62164 <= 63); } if (!Tmp3) break L2; + temp_frames_62173[i_62164].Field0 = it_62162.procname; + temp_frames_62173[i_62164].Field1 = it_62162.line; + i_62164 += 1; + total_62166 += 1; + it_62162 = it_62162.prev; + } + } while(false); + L4: do { + L5: while (true) { + if (!!((it_62162 == null))) break L5; + total_62166 += 1; + it_62162 = it_62162.prev; + } + } while(false); + result_62154[0] = nimCopy(null, [], NTI43040); + if (!((total_62166 == i_62164))) { + if (result_62154[0] != null) { result_62154[0] = (result_62154[0]).concat(makeNimstrLit("(")); } else { result_62154[0] = makeNimstrLit("("); }; + if (result_62154[0] != null) { result_62154[0] = (result_62154[0]).concat(cstrToNimstr(((total_62166 - i_62164))+"")); } else { result_62154[0] = cstrToNimstr(((total_62166 - i_62164))+"").slice(); }; + if (result_62154[0] != null) { result_62154[0] = (result_62154[0]).concat(makeNimstrLit(" calls omitted) ...\x0A")); } else { result_62154[0] = makeNimstrLit(" calls omitted) ...\x0A"); }; + } + + L6: do { + var j_62421 = 0; + var colontmp__197462 = 0; + colontmp__197462 = (i_62164 - 1); + var res_197467 = colontmp__197462; + L7: do { + L8: while (true) { + if (!(0 <= res_197467)) break L8; + j_62421 = res_197467; + add_59838(result_62154, 0, temp_frames_62173[j_62421].Field0); + if ((0 < temp_frames_62173[j_62421].Field1)) { + if (result_62154[0] != null) { result_62154[0] = (result_62154[0]).concat(makeNimstrLit(", line: ")); } else { result_62154[0] = makeNimstrLit(", line: "); }; + if (result_62154[0] != null) { result_62154[0] = (result_62154[0]).concat(cstrToNimstr((temp_frames_62173[j_62421].Field1)+"")); } else { result_62154[0] = cstrToNimstr((temp_frames_62173[j_62421].Field1)+"").slice(); }; + } + + if (result_62154[0] != null) { result_62154[0] = (result_62154[0]).concat(makeNimstrLit("\x0A")); } else { result_62154[0] = makeNimstrLit("\x0A"); }; + res_197467 -= 1; + } + } while(false); + } while(false); - return result_61154[0]; + return result_62154[0]; } -function raw_write_stack_trace_61467() { - var result_61469 = null; +function raw_write_stack_trace_62481() { + var result_62483 = null; - if (!((framePtr == null))) { - result_61469 = nimCopy(null, (makeNimstrLit("Traceback (most recent call last)\x0A") || []).concat(aux_write_stack_trace_61151(framePtr) || []), NTI42040); - } - else { - result_61469 = nimCopy(null, makeNimstrLit("No stack traceback available\x0A"), NTI42040); - } - + if (!((framePtr == null))) { + result_62483 = nimCopy(null, (makeNimstrLit("Traceback (most recent call last)\x0A") || []).concat(aux_write_stack_trace_62151(framePtr) || []), NTI43040); + } + else { + result_62483 = nimCopy(null, makeNimstrLit("No stack traceback available\x0A"), NTI43040); + } + - return result_61469; + return result_62483; } -function new_seq_63336(len_63339) { - var result_63341 = null; +function new_seq_64336(len_64339) { + var result_64341 = null; - var F={procname:"newSeq.newSeq",prev:framePtr,filename:"system.nim",line:0}; - framePtr = F; - F.line = 996; - result_63341 = new Array(len_63339); for (var i=0;i", "text/html"); - stuff_195563 = doc.documentElement; + stuff_197555 = doc.documentElement; - F.line = 286; - db_195535[0] = nimCopy(null, stuff_195563.getElementsByClassName("reference"), NTI84305); - F.line = 287; - contents_195537[0] = nimCopy(null, [], NTI195578); - L1: do { - F.line = 288; - var ahref_195814 = null; - F.line = 184; - var i_196045 = 0; - F.line = 185; - var l_196046 = (db_195535[0] != null ? db_195535[0].length : 0); - L2: do { - F.line = 186; - L3: while (true) { - if (!(i_196045 < l_196046)) break L3; - F.line = 288; - ahref_195814 = db_195535[0][chckIndx(i_196045, 0, db_195535[0].length+0-1)-0]; - F.line = 289; - if (contents_195537[0] != null) { contents_195537[0].push(ahref_195814.getAttribute("data-doc-search-tag")); } else { contents_195537[0] = [ahref_195814.getAttribute("data-doc-search-tag")]; }; - F.line = 188; - i_196045 = addInt(i_196045, 1); - if (!(((db_195535[0] != null ? db_195535[0].length : 0) == l_196046))) { - F.line = 189; - failed_assert_impl_55666(makeNimstrLit("/home/genotrance/programming/nimdevel/lib/system/iterators.nim(189, 11) `len(a) ==\x0A L` the length of the seq changed while iterating over it")); - } - - } - } while(false); - } while(false); - } - - F.line = 290; - var ul_195825 = tree_194020(makeNimstrLit("UL"), []); - F.line = 291; - result_195557 = tree_194020(makeNimstrLit("DIV"), []); - F.line = 292; - set_class_194103(result_195557, makeNimstrLit("search_results")); - F.line = 293; - var matches_195846 = []; - L4: do { - F.line = 294; - var i_195859 = 0; - F.line = 2755; - var colontmp__196052 = 0; - F.line = 294; - colontmp__196052 = (db_195535[0] != null ? db_195535[0].length : 0); - F.line = 2757; - var i_196053 = 0; - L5: do { - F.line = 2758; - L6: while (true) { - if (!(i_196053 < colontmp__196052)) break L6; - F.line = 294; - i_195859 = i_196053; - L7: do { - F.line = 295; - var c_195860 = contents_195537[0][chckIndx(i_195859, 0, contents_195537[0].length+0-1)-0]; - if (((c_195860 == "Examples") || (c_195860 == "PEG construction"))) { - F.line = 300; - break L7; - } - - F.line = 301; - var colontmp__196062 = {Field0: 0, Field1: false}; - F.line = 301; - var score_195861 = 0; - F.line = 301; - var matched_195862 = false; - F.line = 301; - nimCopy(colontmp__196062, fuzzy_match_193067(value_195556, c_195860), NTI193071); - F.line = 301; - score_195861 = colontmp__196062["Field0"]; - F.line = 301; - matched_195862 = colontmp__196062["Field1"]; - if (matched_195862) { - F.line = 303; - if (matches_195846 != null) { matches_195846.push({Field0: db_195535[0][chckIndx(i_195859, 0, db_195535[0].length+0-1)-0], Field1: score_195861}); } else { matches_195846 = [{Field0: db_195535[0][chckIndx(i_195859, 0, db_195535[0].length+0-1)-0], Field1: score_195861}]; }; - } - - } while(false); - F.line = 2760; - i_196053 = addInt(i_196053, 1); - } - } while(false); - } while(false); - F.line = 305; - matches_195846.sort(HEX3Aanonymous_195873); - L8: do { - F.line = 306; - var i_195926 = 0; - F.line = 2755; - var colontmp__196058 = 0; - F.line = 306; - colontmp__196058 = nimMin((matches_195846 != null ? matches_195846.length : 0), 19); - F.line = 2757; - var i_196059 = 0; - L9: do { - F.line = 2758; - L10: while (true) { - if (!(i_196059 < colontmp__196058)) break L10; - F.line = 306; - i_195926 = i_196059; - F.line = 307; - matches_195846[chckIndx(i_195926, 0, matches_195846.length+0-1)-0]["Field0"].innerHTML = matches_195846[chckIndx(i_195926, 0, matches_195846.length+0-1)-0]["Field0"].getAttribute("data-doc-search-tag"); - F.line = 308; - add_194085(ul_195825, tree_194020(makeNimstrLit("LI"), [matches_195846[chckIndx(i_195926, 0, matches_195846.length+0-1)-0]["Field0"]])); - F.line = 2760; - i_196059 = addInt(i_196059, 1); - } - } while(false); - } while(false); - if ((ul_195825.childNodes.length == 0)) { - F.line = 310; - add_194085(result_195557, tree_194020(makeNimstrLit("B"), [text_194120(makeNimstrLit("no search results"))])); - } - else { - F.line = 312; - add_194085(result_195557, tree_194020(makeNimstrLit("B"), [text_194120(makeNimstrLit("search results"))])); - F.line = 313; - add_194085(result_195557, ul_195825); - } - - framePtr = F.prev; + F.line = 286; + db_197527[0] = nimCopy(null, stuff_197555.getElementsByClassName("reference"), NTI85305); + F.line = 287; + contents_197529[0] = nimCopy(null, [], NTI197570); + L1: do { + F.line = 288; + var ahref_197814 = null; + F.line = 184; + var i_198045 = 0; + F.line = 185; + var l_198046 = (db_197527[0] != null ? db_197527[0].length : 0); + L2: do { + F.line = 186; + L3: while (true) { + if (!(i_198045 < l_198046)) break L3; + F.line = 288; + ahref_197814 = db_197527[0][chckIndx(i_198045, 0, (db_197527[0] != null ? db_197527[0].length : 0)+0-1)-0]; + F.line = 289; + if (contents_197529[0] != null) { contents_197529[0].push(ahref_197814.getAttribute("data-doc-search-tag")); } else { contents_197529[0] = [ahref_197814.getAttribute("data-doc-search-tag")]; }; + F.line = 188; + i_198045 = addInt(i_198045, 1); + if (!(((db_197527[0] != null ? db_197527[0].length : 0) == l_198046))) { + F.line = 189; + failed_assert_impl_56666(makeNimstrLit("/home/genotrance/programming/nimdevel/lib/system/iterators.nim(189, 11) `len(a) ==\x0A L` the length of the seq changed while iterating over it")); + } + + } + } while(false); + } while(false); + } + + F.line = 290; + var ul_197825 = tree_196020(makeNimstrLit("UL"), []); + F.line = 291; + result_197549 = tree_196020(makeNimstrLit("DIV"), []); + F.line = 292; + set_class_196103(result_197549, makeNimstrLit("search_results")); + F.line = 293; + var matches_197846 = []; + L4: do { + F.line = 294; + var i_197859 = 0; + F.line = 2734; + var colontmp__198052 = 0; + F.line = 294; + colontmp__198052 = (db_197527[0] != null ? db_197527[0].length : 0); + F.line = 2736; + var i_198053 = 0; + L5: do { + F.line = 2737; + L6: while (true) { + if (!(i_198053 < colontmp__198052)) break L6; + F.line = 294; + i_197859 = i_198053; + L7: do { + F.line = 295; + var c_197860 = contents_197529[0][chckIndx(i_197859, 0, (contents_197529[0] != null ? contents_197529[0].length : 0)+0-1)-0]; + if (((c_197860 == "Examples") || (c_197860 == "PEG construction"))) { + F.line = 300; + break L7; + } + + F.line = 301; + var colontmp__198060 = {Field0: 0, Field1: false}; + F.line = 301; + var score_197861 = 0; + F.line = 301; + var matched_197862 = false; + F.line = 301; + nimCopy(colontmp__198060, fuzzy_match_195054(value_197548, c_197860), NTI195058); + F.line = 301; + score_197861 = colontmp__198060["Field0"]; + F.line = 301; + matched_197862 = colontmp__198060["Field1"]; + if (matched_197862) { + F.line = 303; + if (matches_197846 != null) { matches_197846.push({Field0: db_197527[0][chckIndx(i_197859, 0, (db_197527[0] != null ? db_197527[0].length : 0)+0-1)-0], Field1: score_197861}); } else { matches_197846 = [{Field0: db_197527[0][chckIndx(i_197859, 0, (db_197527[0] != null ? db_197527[0].length : 0)+0-1)-0], Field1: score_197861}]; }; + } + + } while(false); + F.line = 2739; + i_198053 = addInt(i_198053, 1); + } + } while(false); + } while(false); + F.line = 305; + matches_197846.sort(HEX3Aanonymous_197873); + L8: do { + F.line = 306; + var i_197926 = 0; + F.line = 2734; + var colontmp__198057 = 0; + F.line = 306; + colontmp__198057 = nimMin((matches_197846 != null ? matches_197846.length : 0), 19); + F.line = 2736; + var i_198058 = 0; + L9: do { + F.line = 2737; + L10: while (true) { + if (!(i_198058 < colontmp__198057)) break L10; + F.line = 306; + i_197926 = i_198058; + F.line = 307; + matches_197846[chckIndx(i_197926, 0, (matches_197846 != null ? matches_197846.length : 0)+0-1)-0]["Field0"].innerHTML = matches_197846[chckIndx(i_197926, 0, (matches_197846 != null ? matches_197846.length : 0)+0-1)-0]["Field0"].getAttribute("data-doc-search-tag"); + F.line = 308; + add_196085(ul_197825, tree_196020(makeNimstrLit("LI"), [matches_197846[chckIndx(i_197926, 0, (matches_197846 != null ? matches_197846.length : 0)+0-1)-0]["Field0"]])); + F.line = 2739; + i_198058 = addInt(i_198058, 1); + } + } while(false); + } while(false); + if ((ul_197825.childNodes.length == 0)) { + F.line = 310; + add_196085(result_197549, tree_196020(makeNimstrLit("B"), [text_196120(makeNimstrLit("no search results"))])); + } + else { + F.line = 312; + add_196085(result_197549, tree_196020(makeNimstrLit("B"), [text_196120(makeNimstrLit("search results"))])); + F.line = 313; + add_196085(result_197549, ul_197825); + } + + framePtr = F.prev; - return result_195557; + return result_197549; } function search() { - function wrapper_195993() { - var F={procname:"search.wrapper",prev:framePtr,filename:"dochack.nim",line:0}; - framePtr = F; - F.line = 320; - var elem_195995 = document.getElementById("searchInput"); - F.line = 321; - var value_195996 = elem_195995.value; - if (!(((value_195996 != null ? value_195996.length : 0) == 0))) { - if ((oldtoc_195961[0] == null)) { - F.line = 324; - oldtoc_195961[0] = document.getElementById("tocRoot"); - } - - F.line = 325; - var results_196002 = dosearch_195554(value_195996); - F.line = 326; - replace_by_id_194172("tocRoot", results_196002); - } - else { - if (!((oldtoc_195961[0] == null))) { - F.line = 328; - replace_by_id_194172("tocRoot", oldtoc_195961[0]); - } - } - framePtr = F.prev; + function wrapper_197993() { + var F={procname:"search.wrapper",prev:framePtr,filename:"dochack.nim",line:0}; + framePtr = F; + F.line = 320; + var elem_197995 = document.getElementById("searchInput"); + F.line = 321; + var value_197996 = elem_197995.value; + if (!(((value_197996 != null ? value_197996.length : 0) == 0))) { + if ((oldtoc_197961[0] == null)) { + F.line = 324; + oldtoc_197961[0] = document.getElementById("tocRoot"); + } + + F.line = 325; + var results_198002 = dosearch_197546(value_197996); + F.line = 326; + replace_by_id_196172("tocRoot", results_198002); + } + else { + if (!((oldtoc_197961[0] == null))) { + F.line = 328; + replace_by_id_196172("tocRoot", oldtoc_197961[0]); + } + } + framePtr = F.prev; - - } + + } - var F={procname:"dochack.search",prev:framePtr,filename:"dochack.nim",line:0}; - framePtr = F; - if (!((timer_195962[0] == null))) { - F.line = 330; - clearTimeout(timer_195962[0]); - } - - F.line = 331; - timer_195962[0] = setTimeout(wrapper_195993, 400); - framePtr = F.prev; + var F={procname:"dochack.search",prev:framePtr,filename:"dochack.nim",line:0}; + framePtr = F; + if (!((timer_197962[0] == null))) { + F.line = 330; + clearTimeout(timer_197962[0]); + } + + F.line = 331; + timer_197962[0] = setTimeout(wrapper_197993, 400); + framePtr = F.prev; - + } diff --git a/paths.html b/paths.html index f190a22..2d9463f 100644 --- a/paths.html +++ b/paths.html @@ -10,6 +10,7 @@ + @@ -17,772 +18,7 @@ paths - + @@ -797,6 +33,37 @@ function main() { event.target.parentNode.nextElementSibling.style.display = "inline"; } } + + const toggleSwitch = document.querySelector('.theme-switch input[type="checkbox"]'); + function switchTheme(e) { + if (e.target.checked) { + document.documentElement.setAttribute('data-theme', 'dark'); + localStorage.setItem('theme', 'dark'); + } else { + document.documentElement.setAttribute('data-theme', 'light'); + localStorage.setItem('theme', 'light'); + } + } + + toggleSwitch.addEventListener('change', switchTheme, false); + + + if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { + document.documentElement.setAttribute('data-theme', "dark"); + toggleSwitch.checked = true; + } else if (window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches) { + document.documentElement.setAttribute('data-theme', "light"); + toggleSwitch.checked = false; + } else { + const currentTheme = localStorage.getItem('theme') ? localStorage.getItem('theme') : null; + if (currentTheme) { + document.documentElement.setAttribute('data-theme', currentTheme); + + if (currentTheme === 'dark') { + toggleSwitch.checked = true; + } + } + } } @@ -807,6 +74,13 @@ function main() {

        paths

        +
        + +     Dark Mode +
        diff --git a/plugin.html b/plugin.html index b3e0e5c..38a7dd7 100644 --- a/plugin.html +++ b/plugin.html @@ -10,6 +10,7 @@ + @@ -17,772 +18,7 @@ plugin - + @@ -797,6 +33,37 @@ function main() { event.target.parentNode.nextElementSibling.style.display = "inline"; } } + + const toggleSwitch = document.querySelector('.theme-switch input[type="checkbox"]'); + function switchTheme(e) { + if (e.target.checked) { + document.documentElement.setAttribute('data-theme', 'dark'); + localStorage.setItem('theme', 'dark'); + } else { + document.documentElement.setAttribute('data-theme', 'light'); + localStorage.setItem('theme', 'light'); + } + } + + toggleSwitch.addEventListener('change', switchTheme, false); + + + if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { + document.documentElement.setAttribute('data-theme', "dark"); + toggleSwitch.checked = true; + } else if (window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches) { + document.documentElement.setAttribute('data-theme', "light"); + toggleSwitch.checked = false; + } else { + const currentTheme = localStorage.getItem('theme') ? localStorage.getItem('theme') : null; + if (currentTheme) { + document.documentElement.setAttribute('data-theme', currentTheme); + + if (currentTheme === 'dark') { + toggleSwitch.checked = true; + } + } + } } @@ -807,6 +74,13 @@ function main() {

        plugin

        +
        + +     Dark Mode +
      +
    • +
    • + Vars + +
    • +
    • + Procs +
    • @@ -852,6 +145,7 @@ function main() { name*: string parent*: string kind*: NimSymKind + override*: string
      @@ -864,6 +158,38 @@ function main() { +
      + +
      OnSymbolOverrideFinal = proc (typ: string): HashSet[string] {...}{.cdecl.}
      +
      + + + +
      + + +
      +

      Vars

      +
      + +
      cOverrides: Table[string, HashSet[string]]
      +
      + + + +
      + +
      +
      +

      Procs

      +
      + +
      proc onSymbolOverrideFinal(typ: string): HashSet[string] {...}{.exportc, dynlib,
      +    raises: [KeyError], tags: [].}
      +
      + + +
      @@ -875,7 +201,7 @@ function main() { diff --git a/plugin.idx b/plugin.idx index c5ac576..2cba6b6 100644 --- a/plugin.idx +++ b/plugin.idx @@ -1,2 +1,5 @@ Symbol plugin.html#Symbol plugin: Symbol OnSymbol plugin.html#OnSymbol plugin: OnSymbol +OnSymbolOverrideFinal plugin.html#OnSymbolOverrideFinal plugin: OnSymbolOverrideFinal +cOverrides plugin.html#cOverrides plugin: cOverrides +onSymbolOverrideFinal plugin.html#onSymbolOverrideFinal,string plugin: onSymbolOverrideFinal(typ: string): HashSet[string] diff --git a/theindex.html b/theindex.html index 9611f5a..64d2436 100644 --- a/theindex.html +++ b/theindex.html @@ -10,6 +10,7 @@ + @@ -17,772 +18,7 @@ Index - + @@ -797,6 +33,37 @@ function main() { event.target.parentNode.nextElementSibling.style.display = "inline"; } } + + const toggleSwitch = document.querySelector('.theme-switch input[type="checkbox"]'); + function switchTheme(e) { + if (e.target.checked) { + document.documentElement.setAttribute('data-theme', 'dark'); + localStorage.setItem('theme', 'dark'); + } else { + document.documentElement.setAttribute('data-theme', 'light'); + localStorage.setItem('theme', 'light'); + } + } + + toggleSwitch.addEventListener('change', switchTheme, false); + + + if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { + document.documentElement.setAttribute('data-theme', "dark"); + toggleSwitch.checked = true; + } else if (window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches) { + document.documentElement.setAttribute('data-theme', "light"); + toggleSwitch.checked = false; + } else { + const currentTheme = localStorage.getItem('theme') ? localStorage.getItem('theme') : null; + if (currentTheme) { + document.documentElement.setAttribute('data-theme', currentTheme); + + if (currentTheme === 'dark') { + toggleSwitch.checked = true; + } + } + } } @@ -866,6 +133,10 @@ function main() {
    • cimport: cOverride(body): untyped
    +
    cOverrides:
    cpFile:
    +
    getCompiler:
    getGccLibPaths:
    +
    OnSymbolOverrideFinal:
    +
    onSymbolOverrideFinal:
    ptrdiff_t:
    • types: ptrdiff_t
    • @@ -1061,7 +344,7 @@ function main() { diff --git a/types.html b/types.html index 5dd9194..165d512 100644 --- a/types.html +++ b/types.html @@ -10,6 +10,7 @@ + @@ -17,772 +18,7 @@ types - + @@ -797,6 +33,37 @@ function main() { event.target.parentNode.nextElementSibling.style.display = "inline"; } } + + const toggleSwitch = document.querySelector('.theme-switch input[type="checkbox"]'); + function switchTheme(e) { + if (e.target.checked) { + document.documentElement.setAttribute('data-theme', 'dark'); + localStorage.setItem('theme', 'dark'); + } else { + document.documentElement.setAttribute('data-theme', 'light'); + localStorage.setItem('theme', 'light'); + } + } + + toggleSwitch.addEventListener('change', switchTheme, false); + + + if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { + document.documentElement.setAttribute('data-theme', "dark"); + toggleSwitch.checked = true; + } else if (window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches) { + document.documentElement.setAttribute('data-theme', "light"); + toggleSwitch.checked = false; + } else { + const currentTheme = localStorage.getItem('theme') ? localStorage.getItem('theme') : null; + if (currentTheme) { + document.documentElement.setAttribute('data-theme', currentTheme); + + if (currentTheme === 'dark') { + toggleSwitch.checked = true; + } + } + } } @@ -807,6 +74,13 @@ function main() {

      types

      +
      + +     Dark Mode +
      From a2847d77f080c9c429db6ea9b0e5d9f34e4ce15b Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Sat, 21 Dec 2019 13:20:00 -0600 Subject: [PATCH 320/593] v0.4.2 --- nimterop.nimble | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimterop.nimble b/nimterop.nimble index c3d7809..4b1089b 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -1,6 +1,6 @@ # Package -version = "0.4.1" +version = "0.4.2" author = "genotrance" description = "C/C++ interop for Nim" license = "MIT" From 53cb044257bf8857caff3d5cbdfb06b6e43fd400 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Sat, 21 Dec 2019 23:29:57 -0600 Subject: [PATCH 321/593] Fix #144 - nimcheck/nimsuggest support --- nimterop/build.nim | 114 ++++++++++++++++++++++++++++--------------- nimterop/cimport.nim | 18 ++++--- nimterop/getters.nim | 2 +- 3 files changed, 86 insertions(+), 48 deletions(-) diff --git a/nimterop/build.nim b/nimterop/build.nim index d91472c..bd0a0b1 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -1,4 +1,4 @@ -import macros, osproc, sets, strformat, strutils, tables +import hashes, macros, osproc, sets, strformat, strutils, tables import os except findExe, sleep @@ -18,17 +18,33 @@ proc sleep*(milsecs: int) = else: "sleep " - (oup, ret) = gorgeEx(cmd & $(milsecs / 1000)) + discard gorgeEx(cmd & $(milsecs / 1000)) -proc execAction*(cmd: string, retry = 0, nostderr = false): string = +proc getOsCacheDir(): string = + when defined(posix): + result = getEnv("XDG_CACHE_HOME", getHomeDir() / ".cache") / "nim" + else: + result = getHomeDir() / "nimcache" + +proc getNimteropCacheDir(): string = + result = getOsCacheDir() / "nimterop" + +proc execAction*(cmd: string, retry = 0, die = true, cache = false, + cacheKey = ""): tuple[output: string, ret: int] = ## Execute an external command - supported at compile time ## ## Checks if command exits successfully before returning. If not, an - ## error is raised. + ## error is raised. Always caches results to be used in nimsuggest or nimcheck + ## mode. + ## + ## `retry` - number of times command should be retried before error + ## `die = false` - return on errors + ## `cache = true` - cache results unless cleared with -f + ## `cacheKey` - key to create unique cache entry var ccmd = "" - ret = 0 when defined(Windows): + # Replace 'cd d:\abc' with 'd: && cd d:\abc` var filteredCmd = cmd if cmd.toLower().startsWith("cd"): var @@ -45,16 +61,44 @@ proc execAction*(cmd: string, retry = 0, nostderr = false): string = doAssert false when nimvm: - (result, ret) = gorgeEx(ccmd) + # Cache results for speedup if cache = true + # Else cache for preserving functionality in nimsuggest and nimcheck + let + hash = (ccmd & cacheKey).hash().abs() + cacheFile = getNimteropCacheDir() / "execCache" / "nimterop_" & $hash & ".txt" + + when defined(nimsuggest) or defined(nimcheck): + # Load results from cache file if generated in previous run + if fileExists(cacheFile): + result.output = cacheFile.readFile() + elif die: + doAssert false, "Results not cached - run nim c/cpp at least once\n" & ccmd + else: + if cache and fileExists(cacheFile) and not compileOption("forceBuild"): + # Return from cache when requested + result.output = cacheFile.readFile() + else: + # Execute command and store results in cache + (result.output, result.ret) = gorgeEx(ccmd) + if result.ret == 0: + # mkdir for execCache dir (circular dependency) + let dir = cacheFile.parentDir() + if not dirExists(dir): + let flag = when not defined(Windows): "-p" else: "" + discard execAction(&"mkdir {flag} {dir.sanitizePath}") + cacheFile.writeFile(result.output) else: - let opt = if nostderr: {poUsePath} else: {poStdErrToStdOut, poUsePath} - (result, ret) = execCmdEx(ccmd, opt) - if ret != 0: + # Used by toast + (result.output, result.ret) = execCmdEx(ccmd) + + # On failure, retry or die as requested + if result.ret != 0: if retry > 0: sleep(500) - result = execAction(cmd, retry = retry - 1) - else: - doAssert false, "Command failed: " & $(ret, nostderr) & "\ncmd: " & ccmd & "\nresult:\n" & result + result = execAction(cmd, retry = retry - 1, die, cache, cacheKey) + elif die: + doAssert false, "Command failed: " & $result.ret & "\ncmd: " & ccmd & + "\nresult:\n" & result.output proc findExe*(exe: string): string = ## Find the specified executable using the `which`/`where` command - supported @@ -66,10 +110,10 @@ proc findExe*(exe: string): string = else: "which " & exe - (oup, code) = gorgeEx(cmd) + (output, ret) = execAction(cmd, die = false) - if code == 0: - return oup.splitLines()[0].strip() + if ret == 0: + return output.splitLines()[0].strip() proc mkDir*(dir: string) = ## Create a directory at compile time @@ -129,15 +173,6 @@ proc rmDir*(dir: string) = ## Remove a directory or pattern at compile time rmFile(dir, dir = true) -proc getOsCacheDir(): string = - when defined(posix): - result = getEnv("XDG_CACHE_HOME", getHomeDir() / ".cache") / "nim" - else: - result = getHomeDir() / "nimcache" - -proc getNimteropCacheDir(): string = - result = getOsCacheDir() / "nimterop" - proc getProjectCacheDir*(name: string, forceClean = true): string = ## Get a cache directory where all nimterop artifacts can be stored ## @@ -248,7 +283,7 @@ proc gitReset*(outdir: string) = echo "# Resetting " & outdir let cmd = &"cd {outdir.sanitizePath} && git reset --hard" - while execAction(cmd).contains("Permission denied"): + while execAction(cmd).output.contains("Permission denied"): sleep(1000) echo "# Retrying ..." @@ -261,7 +296,7 @@ proc gitCheckout*(file, outdir: string) = echo "# Resetting " & file let file2 = file.relativePath outdir let cmd = &"cd {outdir.sanitizePath} && git checkout {file2.sanitizePath}" - while execAction(cmd).contains("Permission denied"): + while execAction(cmd).output.contains("Permission denied"): sleep(500) echo "# Retrying ..." @@ -344,7 +379,7 @@ proc findFile*(file: string, dir: string, recurse = true, first = false, regex = cmd = cmd % [recursive, (".*[\\\\/]" & file & "$").quoteShell, dir.sanitizePath] let - (files, ret) = gorgeEx(cmd) + (files, ret) = execAction(cmd, die = false) if ret == 0: for line in files.splitLines(): let f = @@ -386,7 +421,7 @@ proc linkLibs*(names: openArray[string], staticLink = true): string = for name in names: let cmd = &"pkg-config --libs --silence-errors {stat} lib{name}" - libs = gorge(cmd) + (libs, _) = execAction(cmd, die = false) for lib in libs.split(" "): resSet.incl lib @@ -421,7 +456,8 @@ proc configure*(path, check: string, flags = "") = if fileExists(path / i): echo "# Running autogen.sh" - echo execAction(&"cd {(path / i).parentDir().sanitizePath} && bash autogen.sh") + echo execAction( + &"cd {(path / i).parentDir().sanitizePath} && bash autogen.sh").output break @@ -430,7 +466,7 @@ proc configure*(path, check: string, flags = "") = if fileExists(path / i): echo "# Running autoreconf" - echo execAction(&"cd {path.sanitizePath} && autoreconf -fi") + echo execAction(&"cd {path.sanitizePath} && autoreconf -fi").output break @@ -442,7 +478,7 @@ proc configure*(path, check: string, flags = "") = if flags.len != 0: cmd &= &" {flags}" - echo execAction(cmd) + echo execAction(cmd).output doAssert (path / check).fileExists(), "# Configure failed" @@ -539,7 +575,7 @@ proc cmake*(path, check, flags: string) = var cmd = &"cd {path.sanitizePath} && cmake {flags}" - echo execAction(cmd) + echo execAction(cmd).output doAssert (path / check).fileExists(), "# cmake failed" @@ -575,7 +611,7 @@ proc make*(path, check: string, flags = "", regex = false) = if flags.len != 0: cmd &= &" {flags}" - echo execAction(cmd) + echo execAction(cmd).output doAssert findFile(check, path, regex = regex).len != 0, "# make failed" @@ -597,7 +633,7 @@ proc getGccPaths*(mode = "c"): seq[string] = mmode = if mode == "cpp": "c++" else: mode inc = false - (outp, _) = gorgeEx(&"""{getCompiler()} -Wp,-v -x{mmode} {nul}""") + (outp, _) = execAction(&"""{getCompiler()} -Wp,-v -x{mmode} {nul}""", die = false) for line in outp.splitLines(): if "#include <...> search starts here" in line: @@ -612,7 +648,7 @@ proc getGccPaths*(mode = "c"): seq[string] = result.add path when defined(osx): - result.add execAction("xcrun --show-sdk-path").strip() & "/usr/include" + result.add(execAction("xcrun --show-sdk-path").output.strip() & "/usr/include") proc getGccLibPaths*(mode = "c"): seq[string] = var @@ -620,7 +656,7 @@ proc getGccLibPaths*(mode = "c"): seq[string] = mmode = if mode == "cpp": "c++" else: mode linker = when defined(OSX): "-Xlinker" else: "" - (outp, _) = gorgeEx(&"""{getCompiler()} {linker} -v -x{mmode} {nul}""") + (outp, _) = execAction(&"""{getCompiler()} {linker} -v -x{mmode} {nul}""", die = false) for line in outp.splitLines(): if "LIBRARY_PATH=" in line: @@ -699,9 +735,9 @@ proc getNumProcs(): string = when defined(windows): getEnv("NUMBER_OF_PROCESSORS").strip() elif defined(linux): - execAction("nproc").strip() + execAction("nproc").output.strip() elif defined(macosx): - execAction("sysctl -n hw.ncpu").strip() + execAction("sysctl -n hw.ncpu").output.strip() else: "1" @@ -727,7 +763,7 @@ proc buildLibrary(lname, outdir, conFlags, cmakeFlags, makeFlags: string): strin when defined(windows): if findExe("sh").len != 0: let - uname = execAction("sh -c uname -a").toLowerAscii() + uname = execAction("sh -c uname -a").output.toLowerAscii() if uname.contains("msys"): gen = "MSYS Makefiles".quoteShell elif uname.contains("mingw"): diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index c13ce1f..6b2d153 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -69,7 +69,7 @@ proc walkDirImpl(indir, inext: string, file=true): seq[string] = else: "find $1 -type d" % dir - (output, ret) = gorgeEx(cmd) + (output, ret) = execAction(cmd, die = false) if ret == 0: result = output.splitLines() @@ -85,9 +85,7 @@ proc getFileDate(fullpath: string): string = elif defined(OSX): &"stat -f %m {fullpath.sanitizePath}" - (result, ret) = gorgeEx(cmd) - - doAssert ret == 0, "File date error: " & fullpath & "\n" & result + (result, ret) = execAction(cmd) proc getCacheValue(fullpath: string): string = if not gStateCT.nocache: @@ -116,7 +114,10 @@ proc getNimCheckError(output: string): tuple[tmpFile, errors: string] = doAssert fileExists(result.tmpFile), "Failed to write to cache dir: " & result.tmpFile let - (check, _) = gorgeEx(&"{getCurrentCompilerExe()} check {result.tmpFile.sanitizePath}") + (check, _) = execAction( + &"{getCurrentCompilerExe()} check {result.tmpFile.sanitizePath}", + die = false + ) result.errors = "\n\n" & check @@ -160,7 +161,8 @@ proc getToast(fullpath: string, recurse: bool = false, dynlib: string = "", cmd.add &" {fullpath.sanitizePath}" # see https://github.com/nimterop/nimterop/issues/69 - (result, ret) = gorgeEx(cmd, cache=getCacheValue(fullpath)) + (result, ret) = execAction(cmd, die = false, cache = (not gStateCT.nocache), + cacheKey = getCacheValue(fullpath)) doAssert ret == 0, getToastError(result) macro cOverride*(body): untyped = @@ -668,8 +670,8 @@ macro c2nImport*(filename: static string, recurse: static bool = false, dynlib: cmd.add &" --assumedef:{i.quoteShell}" let - (c2nimout, ret) = gorgeEx(cmd, cache=getCacheValue(hpath)) - doAssert ret == 0, "Command failed:\n " & cmd & "\n\n" & c2nimout + (c2nimout, ret) = execAction(cmd, cache = not gStateCT.nocache, + cacheKey = getCacheValue(hpath)) var nimout = &"const {header} = \"{fullpath}\"\n\n" & readFile(npath) diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 4cf5653..ef647e6 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -261,7 +261,7 @@ proc getPreprocessor*(gState: State, fullpath: string, mode = "cpp"): string = cmd &= &"{fullpath.sanitizePath}" # Include content only from file - for line in execAction(cmd).splitLines(): + for line in execAction(cmd).output.splitLines(): if line.strip() != "": if line.len > 1 and line[0 .. 1] == "# ": start = false From 3d1dcb31a9a05d0363a76d8f2a913fae438e1c9a Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Sat, 21 Dec 2019 22:42:36 -0800 Subject: [PATCH 322/593] Fix execAction issue on Windows --- nimterop/build.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimterop/build.nim b/nimterop/build.nim index bd0a0b1..5a4dad7 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -350,7 +350,7 @@ proc findFile*(file: string, dir: string, recurse = true, first = false, regex = var cmd = when defined(windows): - "nimgrep --filenames --oneline --nocolor $1 $2 $3" + "nimgrep --filenames --oneline --nocolor $1 \"$2\" $3" elif defined(linux): "find $3 $1 -regextype egrep -regex $2" elif defined(osx): From 1cfcceddb4eb213daf7d190081336e72306a9f45 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 23 Dec 2019 13:38:21 -0600 Subject: [PATCH 323/593] Fix nimsuggest caching --- nimterop/build.nim | 5 +++++ nimterop/cimport.nim | 4 ++-- nimterop/toast.nim | 4 ++-- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/nimterop/build.nim b/nimterop/build.nim index bd0a0b1..69cbe95 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -29,6 +29,11 @@ proc getOsCacheDir(): string = proc getNimteropCacheDir(): string = result = getOsCacheDir() / "nimterop" +proc getCurrentNimCompiler*(): string = + result = getCurrentCompilerExe() + when defined(nimsuggest): + result = result.replace("nimsuggest", "nim") + proc execAction*(cmd: string, retry = 0, die = true, cache = false, cacheKey = ""): tuple[output: string, ret: int] = ## Execute an external command - supported at compile time diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index 6b2d153..4c63c31 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -115,7 +115,7 @@ proc getNimCheckError(output: string): tuple[tmpFile, errors: string] = let (check, _) = execAction( - &"{getCurrentCompilerExe()} check {result.tmpFile.sanitizePath}", + &"{getCurrentNimCompiler()} check {result.tmpFile.sanitizePath}", die = false ) @@ -153,7 +153,7 @@ proc getToast(fullpath: string, recurse: bool = false, dynlib: string = "", if gStateCT.symOverride.nBl: cmd.add &" --symOverride={gStateCT.symOverride.join(\",\")}" - cmd.add &" --nim:{getCurrentCompilerExe().sanitizePath}" + cmd.add &" --nim:{getCurrentNimCompiler().sanitizePath}" if gStateCT.pluginSourcePath.nBl: cmd.add &" --pluginSourcePath={gStateCT.pluginSourcePath.sanitizePath}" diff --git a/nimterop/toast.nim b/nimterop/toast.nim index 5923e56..c26b460 100644 --- a/nimterop/toast.nim +++ b/nimterop/toast.nim @@ -198,7 +198,7 @@ proc main( if gState.pnim and check: # Run nim check on generated wrapper var - (check, err) = execCmdEx(&"{getCurrentCompilerExe()} check {outputFile}") + (check, err) = execCmdEx(&"{gState.nim} check {outputFile}") if err != 0: # Failed check so try stubbing if stub: @@ -233,7 +233,7 @@ proc main( outputFile.writeFile(data) # Rerun nim check on stubbed wrapper - (check, err) = execCmdEx(&"{getCurrentCompilerExe()} check {outputFile}") + (check, err) = execCmdEx(&"{gState.nim} check {outputFile}") doAssert err == 0, "# Nim check with stub failed:\n\n" & check else: doAssert err == 0, "# Nim check failed:\n\n" & check From 64e38547372ff5a2be6e6f95731333114b280b30 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 23 Dec 2019 13:42:55 -0600 Subject: [PATCH 324/593] Update documentation --- all.html | 808 +++++++++++- build.html | 808 +++++++++++- cimport.html | 808 +++++++++++- compat.html | 808 +++++++++++- dochack.js | 3382 +++++++++++++++++++++++++------------------------ paths.html | 808 +++++++++++- plugin.html | 808 +++++++++++- theindex.html | 801 +++++++++++- types.html | 808 +++++++++++- 9 files changed, 7828 insertions(+), 2011 deletions(-) diff --git a/all.html b/all.html index 02c6c63..3724bee 100644 --- a/all.html +++ b/all.html @@ -10,7 +10,6 @@ - @@ -18,7 +17,772 @@ all - + @@ -33,37 +797,6 @@ function main() { event.target.parentNode.nextElementSibling.style.display = "inline"; } } - - const toggleSwitch = document.querySelector('.theme-switch input[type="checkbox"]'); - function switchTheme(e) { - if (e.target.checked) { - document.documentElement.setAttribute('data-theme', 'dark'); - localStorage.setItem('theme', 'dark'); - } else { - document.documentElement.setAttribute('data-theme', 'light'); - localStorage.setItem('theme', 'light'); - } - } - - toggleSwitch.addEventListener('change', switchTheme, false); - - - if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { - document.documentElement.setAttribute('data-theme', "dark"); - toggleSwitch.checked = true; - } else if (window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches) { - document.documentElement.setAttribute('data-theme', "light"); - toggleSwitch.checked = false; - } else { - const currentTheme = localStorage.getItem('theme') ? localStorage.getItem('theme') : null; - if (currentTheme) { - document.documentElement.setAttribute('data-theme', currentTheme); - - if (currentTheme === 'dark') { - toggleSwitch.checked = true; - } - } - } } @@ -74,13 +807,6 @@ function main() {

      all

      -
      - -     Dark Mode -
      diff --git a/build.html b/build.html index 9a6e076..2446361 100644 --- a/build.html +++ b/build.html @@ -10,7 +10,6 @@ - @@ -18,7 +17,772 @@ build - + @@ -33,37 +797,6 @@ function main() { event.target.parentNode.nextElementSibling.style.display = "inline"; } } - - const toggleSwitch = document.querySelector('.theme-switch input[type="checkbox"]'); - function switchTheme(e) { - if (e.target.checked) { - document.documentElement.setAttribute('data-theme', 'dark'); - localStorage.setItem('theme', 'dark'); - } else { - document.documentElement.setAttribute('data-theme', 'light'); - localStorage.setItem('theme', 'light'); - } - } - - toggleSwitch.addEventListener('change', switchTheme, false); - - - if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { - document.documentElement.setAttribute('data-theme', "dark"); - toggleSwitch.checked = true; - } else if (window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches) { - document.documentElement.setAttribute('data-theme', "light"); - toggleSwitch.checked = false; - } else { - const currentTheme = localStorage.getItem('theme') ? localStorage.getItem('theme') : null; - if (currentTheme) { - document.documentElement.setAttribute('data-theme', currentTheme); - - if (currentTheme === 'dark') { - toggleSwitch.checked = true; - } - } - } } @@ -74,13 +807,6 @@ function main() {

      build

      -
      - -     Dark Mode -
      diff --git a/cimport.html b/cimport.html index 09e1254..cf968cd 100644 --- a/cimport.html +++ b/cimport.html @@ -10,7 +10,6 @@ - @@ -18,7 +17,772 @@ cimport - + @@ -33,37 +797,6 @@ function main() { event.target.parentNode.nextElementSibling.style.display = "inline"; } } - - const toggleSwitch = document.querySelector('.theme-switch input[type="checkbox"]'); - function switchTheme(e) { - if (e.target.checked) { - document.documentElement.setAttribute('data-theme', 'dark'); - localStorage.setItem('theme', 'dark'); - } else { - document.documentElement.setAttribute('data-theme', 'light'); - localStorage.setItem('theme', 'light'); - } - } - - toggleSwitch.addEventListener('change', switchTheme, false); - - - if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { - document.documentElement.setAttribute('data-theme', "dark"); - toggleSwitch.checked = true; - } else if (window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches) { - document.documentElement.setAttribute('data-theme', "light"); - toggleSwitch.checked = false; - } else { - const currentTheme = localStorage.getItem('theme') ? localStorage.getItem('theme') : null; - if (currentTheme) { - document.documentElement.setAttribute('data-theme', currentTheme); - - if (currentTheme === 'dark') { - toggleSwitch.checked = true; - } - } - } } @@ -74,13 +807,6 @@ function main() {

      cimport

      -
      - -     Dark Mode -
      diff --git a/compat.html b/compat.html index 121e246..31badcf 100644 --- a/compat.html +++ b/compat.html @@ -10,7 +10,6 @@ - @@ -18,7 +17,772 @@ compat - + @@ -33,37 +797,6 @@ function main() { event.target.parentNode.nextElementSibling.style.display = "inline"; } } - - const toggleSwitch = document.querySelector('.theme-switch input[type="checkbox"]'); - function switchTheme(e) { - if (e.target.checked) { - document.documentElement.setAttribute('data-theme', 'dark'); - localStorage.setItem('theme', 'dark'); - } else { - document.documentElement.setAttribute('data-theme', 'light'); - localStorage.setItem('theme', 'light'); - } - } - - toggleSwitch.addEventListener('change', switchTheme, false); - - - if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { - document.documentElement.setAttribute('data-theme', "dark"); - toggleSwitch.checked = true; - } else if (window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches) { - document.documentElement.setAttribute('data-theme', "light"); - toggleSwitch.checked = false; - } else { - const currentTheme = localStorage.getItem('theme') ? localStorage.getItem('theme') : null; - if (currentTheme) { - document.documentElement.setAttribute('data-theme', currentTheme); - - if (currentTheme === 'dark') { - toggleSwitch.checked = true; - } - } - } } @@ -74,13 +807,6 @@ function main() {

      compat

      -
      - -     Dark Mode -
      diff --git a/dochack.js b/dochack.js index e4d634a..8cd4b61 100644 --- a/dochack.js +++ b/dochack.js @@ -1,4 +1,6 @@ -/* Generated by the Nim Compiler v1.1.1 */ +/* Generated by the Nim Compiler v1.0.4 */ +/* (c) 2019 Andreas Rumpf */ + var framePtr = null; var excHandler = 0; var lastJSError = null; @@ -10,257 +12,257 @@ if (typeof Uint16Array === 'undefined') Uint16Array = Array; if (typeof Uint32Array === 'undefined') Uint32Array = Array; if (typeof Float32Array === 'undefined') Float32Array = Array; if (typeof Float64Array === 'undefined') Float64Array = Array; -var NTI43032 = {size: 0,kind: 1,base: null,node: null,finalizer: null}; -var NTI195058 = {size: 0, kind: 18, base: null, node: null, finalizer: null}; -var NTI46462 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI197570 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; -var NTI83448 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI83444 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI83440 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI83436 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI83432 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI83428 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI83424 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI83420 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI83416 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI83412 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI83408 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI83404 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI83400 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI83396 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI83392 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI83388 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI83384 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI83380 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI83376 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI83372 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI83205 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI83283 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI83281 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; -var NTI83227 = {size: 0, kind: 14, base: null, node: null, finalizer: null}; -var NTI83565 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; -var NTI83563 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; -var NTI83561 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; -var NTI83231 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI83229 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; -var NTI85305 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; -var NTI46450 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI46458 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI43006 = {size: 0,kind: 31,base: null,node: null,finalizer: null}; -var NTI62156 = {size: 0, kind: 18, base: null, node: null, finalizer: null}; -var NTI46408 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI46514 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; -var NTI43016 = {size: 0,kind: 40,base: null,node: null,finalizer: null}; -var NTI43040 = {size: 0,kind: 28,base: null,node: null,finalizer: null}; -var NTI43042 = {size: 0,kind: 29,base: null,node: null,finalizer: null}; -var NTI46508 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; -var NTI46426 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI46428 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI46442 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI46446 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NNI46446 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; -NTI46446.node = NNI46446; -var NNI46442 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; -NTI46442.node = NNI46442; -var NNI46428 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; -NTI46428.node = NNI46428; -NTI46508.base = NTI46426; -NTI46514.base = NTI46426; -var NNI46426 = {kind: 2, len: 6, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "parent", len: 0, typ: NTI46508, name: "parent", sons: null}, -{kind: 1, offset: "name", len: 0, typ: NTI43042, name: "name", sons: null}, -{kind: 1, offset: "message", len: 0, typ: NTI43040, name: "msg", sons: null}, -{kind: 1, offset: "trace", len: 0, typ: NTI43040, name: "trace", sons: null}, -{kind: 1, offset: "raiseId", len: 0, typ: NTI43016, name: "raiseId", sons: null}, -{kind: 1, offset: "up", len: 0, typ: NTI46514, name: "up", sons: null}]}; -NTI46426.node = NNI46426; -var NNI46408 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; -NTI46408.node = NNI46408; -NTI46426.base = NTI46408; -NTI46428.base = NTI46426; -NTI46442.base = NTI46428; -NTI46446.base = NTI46442; -var NNI62156 = {kind: 2, len: 2, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "Field0", len: 0, typ: NTI43042, name: "Field0", sons: null}, -{kind: 1, offset: "Field1", len: 0, typ: NTI43006, name: "Field1", sons: null}]}; -NTI62156.node = NNI62156; -var NNI46458 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; -NTI46458.node = NNI46458; -NTI46458.base = NTI46428; -var NNI46450 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; -NTI46450.node = NNI46450; -NTI46450.base = NTI46428; -NTI83561.base = NTI83229; -NTI83563.base = NTI83229; -NTI83565.base = NTI83229; -var NNI83227 = {kind: 2, offset: 0, typ: null, name: null, len: 12, sons: {"1": {kind: 1, offset: 1, typ: NTI83227, name: "ElementNode", len: 0, sons: null}, -"2": {kind: 1, offset: 2, typ: NTI83227, name: "AttributeNode", len: 0, sons: null}, -"3": {kind: 1, offset: 3, typ: NTI83227, name: "TextNode", len: 0, sons: null}, -"4": {kind: 1, offset: 4, typ: NTI83227, name: "CDATANode", len: 0, sons: null}, -"5": {kind: 1, offset: 5, typ: NTI83227, name: "EntityRefNode", len: 0, sons: null}, -"6": {kind: 1, offset: 6, typ: NTI83227, name: "EntityNode", len: 0, sons: null}, -"7": {kind: 1, offset: 7, typ: NTI83227, name: "ProcessingInstructionNode", len: 0, sons: null}, -"8": {kind: 1, offset: 8, typ: NTI83227, name: "CommentNode", len: 0, sons: null}, -"9": {kind: 1, offset: 9, typ: NTI83227, name: "DocumentNode", len: 0, sons: null}, -"10": {kind: 1, offset: 10, typ: NTI83227, name: "DocumentTypeNode", len: 0, sons: null}, -"11": {kind: 1, offset: 11, typ: NTI83227, name: "DocumentFragmentNode", len: 0, sons: null}, -"12": {kind: 1, offset: 12, typ: NTI83227, name: "NotationNode", len: 0, sons: null}}}; -NTI83227.node = NNI83227; -var NNI83283 = {kind: 2, len: 92, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "background", len: 0, typ: NTI43042, name: "background", sons: null}, -{kind: 1, offset: "backgroundAttachment", len: 0, typ: NTI43042, name: "backgroundAttachment", sons: null}, -{kind: 1, offset: "backgroundColor", len: 0, typ: NTI43042, name: "backgroundColor", sons: null}, -{kind: 1, offset: "backgroundImage", len: 0, typ: NTI43042, name: "backgroundImage", sons: null}, -{kind: 1, offset: "backgroundPosition", len: 0, typ: NTI43042, name: "backgroundPosition", sons: null}, -{kind: 1, offset: "backgroundRepeat", len: 0, typ: NTI43042, name: "backgroundRepeat", sons: null}, -{kind: 1, offset: "border", len: 0, typ: NTI43042, name: "border", sons: null}, -{kind: 1, offset: "borderBottom", len: 0, typ: NTI43042, name: "borderBottom", sons: null}, -{kind: 1, offset: "borderBottomColor", len: 0, typ: NTI43042, name: "borderBottomColor", sons: null}, -{kind: 1, offset: "borderBottomStyle", len: 0, typ: NTI43042, name: "borderBottomStyle", sons: null}, -{kind: 1, offset: "borderBottomWidth", len: 0, typ: NTI43042, name: "borderBottomWidth", sons: null}, -{kind: 1, offset: "borderColor", len: 0, typ: NTI43042, name: "borderColor", sons: null}, -{kind: 1, offset: "borderLeft", len: 0, typ: NTI43042, name: "borderLeft", sons: null}, -{kind: 1, offset: "borderLeftColor", len: 0, typ: NTI43042, name: "borderLeftColor", sons: null}, -{kind: 1, offset: "borderLeftStyle", len: 0, typ: NTI43042, name: "borderLeftStyle", sons: null}, -{kind: 1, offset: "borderLeftWidth", len: 0, typ: NTI43042, name: "borderLeftWidth", sons: null}, -{kind: 1, offset: "borderRight", len: 0, typ: NTI43042, name: "borderRight", sons: null}, -{kind: 1, offset: "borderRightColor", len: 0, typ: NTI43042, name: "borderRightColor", sons: null}, -{kind: 1, offset: "borderRightStyle", len: 0, typ: NTI43042, name: "borderRightStyle", sons: null}, -{kind: 1, offset: "borderRightWidth", len: 0, typ: NTI43042, name: "borderRightWidth", sons: null}, -{kind: 1, offset: "borderStyle", len: 0, typ: NTI43042, name: "borderStyle", sons: null}, -{kind: 1, offset: "borderTop", len: 0, typ: NTI43042, name: "borderTop", sons: null}, -{kind: 1, offset: "borderTopColor", len: 0, typ: NTI43042, name: "borderTopColor", sons: null}, -{kind: 1, offset: "borderTopStyle", len: 0, typ: NTI43042, name: "borderTopStyle", sons: null}, -{kind: 1, offset: "borderTopWidth", len: 0, typ: NTI43042, name: "borderTopWidth", sons: null}, -{kind: 1, offset: "borderWidth", len: 0, typ: NTI43042, name: "borderWidth", sons: null}, -{kind: 1, offset: "bottom", len: 0, typ: NTI43042, name: "bottom", sons: null}, -{kind: 1, offset: "captionSide", len: 0, typ: NTI43042, name: "captionSide", sons: null}, -{kind: 1, offset: "clear", len: 0, typ: NTI43042, name: "clear", sons: null}, -{kind: 1, offset: "clip", len: 0, typ: NTI43042, name: "clip", sons: null}, -{kind: 1, offset: "color", len: 0, typ: NTI43042, name: "color", sons: null}, -{kind: 1, offset: "cursor", len: 0, typ: NTI43042, name: "cursor", sons: null}, -{kind: 1, offset: "direction", len: 0, typ: NTI43042, name: "direction", sons: null}, -{kind: 1, offset: "display", len: 0, typ: NTI43042, name: "display", sons: null}, -{kind: 1, offset: "emptyCells", len: 0, typ: NTI43042, name: "emptyCells", sons: null}, -{kind: 1, offset: "cssFloat", len: 0, typ: NTI43042, name: "cssFloat", sons: null}, -{kind: 1, offset: "font", len: 0, typ: NTI43042, name: "font", sons: null}, -{kind: 1, offset: "fontFamily", len: 0, typ: NTI43042, name: "fontFamily", sons: null}, -{kind: 1, offset: "fontSize", len: 0, typ: NTI43042, name: "fontSize", sons: null}, -{kind: 1, offset: "fontStretch", len: 0, typ: NTI43042, name: "fontStretch", sons: null}, -{kind: 1, offset: "fontStyle", len: 0, typ: NTI43042, name: "fontStyle", sons: null}, -{kind: 1, offset: "fontVariant", len: 0, typ: NTI43042, name: "fontVariant", sons: null}, -{kind: 1, offset: "fontWeight", len: 0, typ: NTI43042, name: "fontWeight", sons: null}, -{kind: 1, offset: "height", len: 0, typ: NTI43042, name: "height", sons: null}, -{kind: 1, offset: "left", len: 0, typ: NTI43042, name: "left", sons: null}, -{kind: 1, offset: "letterSpacing", len: 0, typ: NTI43042, name: "letterSpacing", sons: null}, -{kind: 1, offset: "lineHeight", len: 0, typ: NTI43042, name: "lineHeight", sons: null}, -{kind: 1, offset: "listStyle", len: 0, typ: NTI43042, name: "listStyle", sons: null}, -{kind: 1, offset: "listStyleImage", len: 0, typ: NTI43042, name: "listStyleImage", sons: null}, -{kind: 1, offset: "listStylePosition", len: 0, typ: NTI43042, name: "listStylePosition", sons: null}, -{kind: 1, offset: "listStyleType", len: 0, typ: NTI43042, name: "listStyleType", sons: null}, -{kind: 1, offset: "margin", len: 0, typ: NTI43042, name: "margin", sons: null}, -{kind: 1, offset: "marginBottom", len: 0, typ: NTI43042, name: "marginBottom", sons: null}, -{kind: 1, offset: "marginLeft", len: 0, typ: NTI43042, name: "marginLeft", sons: null}, -{kind: 1, offset: "marginRight", len: 0, typ: NTI43042, name: "marginRight", sons: null}, -{kind: 1, offset: "marginTop", len: 0, typ: NTI43042, name: "marginTop", sons: null}, -{kind: 1, offset: "maxHeight", len: 0, typ: NTI43042, name: "maxHeight", sons: null}, -{kind: 1, offset: "maxWidth", len: 0, typ: NTI43042, name: "maxWidth", sons: null}, -{kind: 1, offset: "minHeight", len: 0, typ: NTI43042, name: "minHeight", sons: null}, -{kind: 1, offset: "minWidth", len: 0, typ: NTI43042, name: "minWidth", sons: null}, -{kind: 1, offset: "opacity", len: 0, typ: NTI43042, name: "opacity", sons: null}, -{kind: 1, offset: "overflow", len: 0, typ: NTI43042, name: "overflow", sons: null}, -{kind: 1, offset: "padding", len: 0, typ: NTI43042, name: "padding", sons: null}, -{kind: 1, offset: "paddingBottom", len: 0, typ: NTI43042, name: "paddingBottom", sons: null}, -{kind: 1, offset: "paddingLeft", len: 0, typ: NTI43042, name: "paddingLeft", sons: null}, -{kind: 1, offset: "paddingRight", len: 0, typ: NTI43042, name: "paddingRight", sons: null}, -{kind: 1, offset: "paddingTop", len: 0, typ: NTI43042, name: "paddingTop", sons: null}, -{kind: 1, offset: "pageBreakAfter", len: 0, typ: NTI43042, name: "pageBreakAfter", sons: null}, -{kind: 1, offset: "pageBreakBefore", len: 0, typ: NTI43042, name: "pageBreakBefore", sons: null}, -{kind: 1, offset: "pointerEvents", len: 0, typ: NTI43042, name: "pointerEvents", sons: null}, -{kind: 1, offset: "position", len: 0, typ: NTI43042, name: "position", sons: null}, -{kind: 1, offset: "right", len: 0, typ: NTI43042, name: "right", sons: null}, -{kind: 1, offset: "scrollbar3dLightColor", len: 0, typ: NTI43042, name: "scrollbar3dLightColor", sons: null}, -{kind: 1, offset: "scrollbarArrowColor", len: 0, typ: NTI43042, name: "scrollbarArrowColor", sons: null}, -{kind: 1, offset: "scrollbarBaseColor", len: 0, typ: NTI43042, name: "scrollbarBaseColor", sons: null}, -{kind: 1, offset: "scrollbarDarkshadowColor", len: 0, typ: NTI43042, name: "scrollbarDarkshadowColor", sons: null}, -{kind: 1, offset: "scrollbarFaceColor", len: 0, typ: NTI43042, name: "scrollbarFaceColor", sons: null}, -{kind: 1, offset: "scrollbarHighlightColor", len: 0, typ: NTI43042, name: "scrollbarHighlightColor", sons: null}, -{kind: 1, offset: "scrollbarShadowColor", len: 0, typ: NTI43042, name: "scrollbarShadowColor", sons: null}, -{kind: 1, offset: "scrollbarTrackColor", len: 0, typ: NTI43042, name: "scrollbarTrackColor", sons: null}, -{kind: 1, offset: "tableLayout", len: 0, typ: NTI43042, name: "tableLayout", sons: null}, -{kind: 1, offset: "textAlign", len: 0, typ: NTI43042, name: "textAlign", sons: null}, -{kind: 1, offset: "textDecoration", len: 0, typ: NTI43042, name: "textDecoration", sons: null}, -{kind: 1, offset: "textIndent", len: 0, typ: NTI43042, name: "textIndent", sons: null}, -{kind: 1, offset: "textTransform", len: 0, typ: NTI43042, name: "textTransform", sons: null}, -{kind: 1, offset: "transform", len: 0, typ: NTI43042, name: "transform", sons: null}, -{kind: 1, offset: "top", len: 0, typ: NTI43042, name: "top", sons: null}, -{kind: 1, offset: "verticalAlign", len: 0, typ: NTI43042, name: "verticalAlign", sons: null}, -{kind: 1, offset: "visibility", len: 0, typ: NTI43042, name: "visibility", sons: null}, -{kind: 1, offset: "width", len: 0, typ: NTI43042, name: "width", sons: null}, -{kind: 1, offset: "wordSpacing", len: 0, typ: NTI43042, name: "wordSpacing", sons: null}, -{kind: 1, offset: "zIndex", len: 0, typ: NTI43006, name: "zIndex", sons: null}]}; -NTI83283.node = NNI83283; -NTI83283.base = NTI46408; -NTI83281.base = NTI83283; -var NNI83231 = {kind: 2, len: 14, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "attributes", len: 0, typ: NTI83561, name: "attributes", sons: null}, -{kind: 1, offset: "childNodes", len: 0, typ: NTI83563, name: "childNodes", sons: null}, -{kind: 1, offset: "children", len: 0, typ: NTI83565, name: "children", sons: null}, -{kind: 1, offset: "data", len: 0, typ: NTI43042, name: "data", sons: null}, -{kind: 1, offset: "firstChild", len: 0, typ: NTI83229, name: "firstChild", sons: null}, -{kind: 1, offset: "lastChild", len: 0, typ: NTI83229, name: "lastChild", sons: null}, -{kind: 1, offset: "nextSibling", len: 0, typ: NTI83229, name: "nextSibling", sons: null}, -{kind: 1, offset: "nodeName", len: 0, typ: NTI43042, name: "nodeName", sons: null}, -{kind: 1, offset: "nodeType", len: 0, typ: NTI83227, name: "nodeType", sons: null}, -{kind: 1, offset: "nodeValue", len: 0, typ: NTI43042, name: "nodeValue", sons: null}, -{kind: 1, offset: "parentNode", len: 0, typ: NTI83229, name: "parentNode", sons: null}, -{kind: 1, offset: "previousSibling", len: 0, typ: NTI83229, name: "previousSibling", sons: null}, -{kind: 1, offset: "innerHTML", len: 0, typ: NTI43042, name: "innerHTML", sons: null}, -{kind: 1, offset: "style", len: 0, typ: NTI83281, name: "style", sons: null}]}; -NTI83231.node = NNI83231; -var NNI83205 = {kind: 2, len: 20, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "onabort", len: 0, typ: NTI83372, name: "onabort", sons: null}, -{kind: 1, offset: "onblur", len: 0, typ: NTI83376, name: "onblur", sons: null}, -{kind: 1, offset: "onchange", len: 0, typ: NTI83380, name: "onchange", sons: null}, -{kind: 1, offset: "onclick", len: 0, typ: NTI83384, name: "onclick", sons: null}, -{kind: 1, offset: "ondblclick", len: 0, typ: NTI83388, name: "ondblclick", sons: null}, -{kind: 1, offset: "onerror", len: 0, typ: NTI83392, name: "onerror", sons: null}, -{kind: 1, offset: "onfocus", len: 0, typ: NTI83396, name: "onfocus", sons: null}, -{kind: 1, offset: "onkeydown", len: 0, typ: NTI83400, name: "onkeydown", sons: null}, -{kind: 1, offset: "onkeypress", len: 0, typ: NTI83404, name: "onkeypress", sons: null}, -{kind: 1, offset: "onkeyup", len: 0, typ: NTI83408, name: "onkeyup", sons: null}, -{kind: 1, offset: "onload", len: 0, typ: NTI83412, name: "onload", sons: null}, -{kind: 1, offset: "onmousedown", len: 0, typ: NTI83416, name: "onmousedown", sons: null}, -{kind: 1, offset: "onmousemove", len: 0, typ: NTI83420, name: "onmousemove", sons: null}, -{kind: 1, offset: "onmouseout", len: 0, typ: NTI83424, name: "onmouseout", sons: null}, -{kind: 1, offset: "onmouseover", len: 0, typ: NTI83428, name: "onmouseover", sons: null}, -{kind: 1, offset: "onmouseup", len: 0, typ: NTI83432, name: "onmouseup", sons: null}, -{kind: 1, offset: "onreset", len: 0, typ: NTI83436, name: "onreset", sons: null}, -{kind: 1, offset: "onselect", len: 0, typ: NTI83440, name: "onselect", sons: null}, -{kind: 1, offset: "onsubmit", len: 0, typ: NTI83444, name: "onsubmit", sons: null}, -{kind: 1, offset: "onunload", len: 0, typ: NTI83448, name: "onunload", sons: null}]}; -NTI83205.node = NNI83205; -NTI83205.base = NTI46408; -NTI83231.base = NTI83205; -NTI83229.base = NTI83231; -NTI85305.base = NTI83229; -NTI197570.base = NTI43042; -var NNI46462 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; -NTI46462.node = NNI46462; -NTI46462.base = NTI46428; -var NNI195058 = {kind: 2, len: 2, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "Field0", len: 0, typ: NTI43006, name: "Field0", sons: null}, -{kind: 1, offset: "Field1", len: 0, typ: NTI43032, name: "Field1", sons: null}]}; -NTI195058.node = NNI195058; +var NTI130 = {size: 0,kind: 1,base: null,node: null,finalizer: null}; +var NTI160074 = {size: 0, kind: 18, base: null, node: null, finalizer: null}; +var NTI3662 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI162578 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; +var NTI42448 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI42444 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI42440 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI42436 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI42432 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI42428 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI42424 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI42420 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI42416 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI42412 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI42408 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI42404 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI42400 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI42396 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI42392 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI42388 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI42384 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI42380 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI42376 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI42372 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI42205 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI42283 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI42281 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; +var NTI42227 = {size: 0, kind: 14, base: null, node: null, finalizer: null}; +var NTI42565 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; +var NTI42563 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; +var NTI42561 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; +var NTI42231 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI42229 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; +var NTI44305 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; +var NTI3650 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI3658 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI104 = {size: 0,kind: 31,base: null,node: null,finalizer: null}; +var NTI21156 = {size: 0, kind: 18, base: null, node: null, finalizer: null}; +var NTI3608 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI3714 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; +var NTI114 = {size: 0,kind: 40,base: null,node: null,finalizer: null}; +var NTI138 = {size: 0,kind: 28,base: null,node: null,finalizer: null}; +var NTI140 = {size: 0,kind: 29,base: null,node: null,finalizer: null}; +var NTI3708 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; +var NTI3626 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI3628 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI3642 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI3646 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NNI3646 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI3646.node = NNI3646; +var NNI3642 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI3642.node = NNI3642; +var NNI3628 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI3628.node = NNI3628; +NTI3708.base = NTI3626; +NTI3714.base = NTI3626; +var NNI3626 = {kind: 2, len: 6, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "parent", len: 0, typ: NTI3708, name: "parent", sons: null}, +{kind: 1, offset: "name", len: 0, typ: NTI140, name: "name", sons: null}, +{kind: 1, offset: "message", len: 0, typ: NTI138, name: "msg", sons: null}, +{kind: 1, offset: "trace", len: 0, typ: NTI138, name: "trace", sons: null}, +{kind: 1, offset: "raiseId", len: 0, typ: NTI114, name: "raiseId", sons: null}, +{kind: 1, offset: "up", len: 0, typ: NTI3714, name: "up", sons: null}]}; +NTI3626.node = NNI3626; +var NNI3608 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI3608.node = NNI3608; +NTI3626.base = NTI3608; +NTI3628.base = NTI3626; +NTI3642.base = NTI3628; +NTI3646.base = NTI3642; +var NNI21156 = {kind: 2, len: 2, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "Field0", len: 0, typ: NTI140, name: "Field0", sons: null}, +{kind: 1, offset: "Field1", len: 0, typ: NTI104, name: "Field1", sons: null}]}; +NTI21156.node = NNI21156; +var NNI3658 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI3658.node = NNI3658; +NTI3658.base = NTI3628; +var NNI3650 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI3650.node = NNI3650; +NTI3650.base = NTI3628; +NTI42561.base = NTI42229; +NTI42563.base = NTI42229; +NTI42565.base = NTI42229; +var NNI42227 = {kind: 2, offset: 0, typ: null, name: null, len: 12, sons: {"1": {kind: 1, offset: 1, typ: NTI42227, name: "ElementNode", len: 0, sons: null}, +"2": {kind: 1, offset: 2, typ: NTI42227, name: "AttributeNode", len: 0, sons: null}, +"3": {kind: 1, offset: 3, typ: NTI42227, name: "TextNode", len: 0, sons: null}, +"4": {kind: 1, offset: 4, typ: NTI42227, name: "CDATANode", len: 0, sons: null}, +"5": {kind: 1, offset: 5, typ: NTI42227, name: "EntityRefNode", len: 0, sons: null}, +"6": {kind: 1, offset: 6, typ: NTI42227, name: "EntityNode", len: 0, sons: null}, +"7": {kind: 1, offset: 7, typ: NTI42227, name: "ProcessingInstructionNode", len: 0, sons: null}, +"8": {kind: 1, offset: 8, typ: NTI42227, name: "CommentNode", len: 0, sons: null}, +"9": {kind: 1, offset: 9, typ: NTI42227, name: "DocumentNode", len: 0, sons: null}, +"10": {kind: 1, offset: 10, typ: NTI42227, name: "DocumentTypeNode", len: 0, sons: null}, +"11": {kind: 1, offset: 11, typ: NTI42227, name: "DocumentFragmentNode", len: 0, sons: null}, +"12": {kind: 1, offset: 12, typ: NTI42227, name: "NotationNode", len: 0, sons: null}}}; +NTI42227.node = NNI42227; +var NNI42283 = {kind: 2, len: 92, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "background", len: 0, typ: NTI140, name: "background", sons: null}, +{kind: 1, offset: "backgroundAttachment", len: 0, typ: NTI140, name: "backgroundAttachment", sons: null}, +{kind: 1, offset: "backgroundColor", len: 0, typ: NTI140, name: "backgroundColor", sons: null}, +{kind: 1, offset: "backgroundImage", len: 0, typ: NTI140, name: "backgroundImage", sons: null}, +{kind: 1, offset: "backgroundPosition", len: 0, typ: NTI140, name: "backgroundPosition", sons: null}, +{kind: 1, offset: "backgroundRepeat", len: 0, typ: NTI140, name: "backgroundRepeat", sons: null}, +{kind: 1, offset: "border", len: 0, typ: NTI140, name: "border", sons: null}, +{kind: 1, offset: "borderBottom", len: 0, typ: NTI140, name: "borderBottom", sons: null}, +{kind: 1, offset: "borderBottomColor", len: 0, typ: NTI140, name: "borderBottomColor", sons: null}, +{kind: 1, offset: "borderBottomStyle", len: 0, typ: NTI140, name: "borderBottomStyle", sons: null}, +{kind: 1, offset: "borderBottomWidth", len: 0, typ: NTI140, name: "borderBottomWidth", sons: null}, +{kind: 1, offset: "borderColor", len: 0, typ: NTI140, name: "borderColor", sons: null}, +{kind: 1, offset: "borderLeft", len: 0, typ: NTI140, name: "borderLeft", sons: null}, +{kind: 1, offset: "borderLeftColor", len: 0, typ: NTI140, name: "borderLeftColor", sons: null}, +{kind: 1, offset: "borderLeftStyle", len: 0, typ: NTI140, name: "borderLeftStyle", sons: null}, +{kind: 1, offset: "borderLeftWidth", len: 0, typ: NTI140, name: "borderLeftWidth", sons: null}, +{kind: 1, offset: "borderRight", len: 0, typ: NTI140, name: "borderRight", sons: null}, +{kind: 1, offset: "borderRightColor", len: 0, typ: NTI140, name: "borderRightColor", sons: null}, +{kind: 1, offset: "borderRightStyle", len: 0, typ: NTI140, name: "borderRightStyle", sons: null}, +{kind: 1, offset: "borderRightWidth", len: 0, typ: NTI140, name: "borderRightWidth", sons: null}, +{kind: 1, offset: "borderStyle", len: 0, typ: NTI140, name: "borderStyle", sons: null}, +{kind: 1, offset: "borderTop", len: 0, typ: NTI140, name: "borderTop", sons: null}, +{kind: 1, offset: "borderTopColor", len: 0, typ: NTI140, name: "borderTopColor", sons: null}, +{kind: 1, offset: "borderTopStyle", len: 0, typ: NTI140, name: "borderTopStyle", sons: null}, +{kind: 1, offset: "borderTopWidth", len: 0, typ: NTI140, name: "borderTopWidth", sons: null}, +{kind: 1, offset: "borderWidth", len: 0, typ: NTI140, name: "borderWidth", sons: null}, +{kind: 1, offset: "bottom", len: 0, typ: NTI140, name: "bottom", sons: null}, +{kind: 1, offset: "captionSide", len: 0, typ: NTI140, name: "captionSide", sons: null}, +{kind: 1, offset: "clear", len: 0, typ: NTI140, name: "clear", sons: null}, +{kind: 1, offset: "clip", len: 0, typ: NTI140, name: "clip", sons: null}, +{kind: 1, offset: "color", len: 0, typ: NTI140, name: "color", sons: null}, +{kind: 1, offset: "cursor", len: 0, typ: NTI140, name: "cursor", sons: null}, +{kind: 1, offset: "direction", len: 0, typ: NTI140, name: "direction", sons: null}, +{kind: 1, offset: "display", len: 0, typ: NTI140, name: "display", sons: null}, +{kind: 1, offset: "emptyCells", len: 0, typ: NTI140, name: "emptyCells", sons: null}, +{kind: 1, offset: "cssFloat", len: 0, typ: NTI140, name: "cssFloat", sons: null}, +{kind: 1, offset: "font", len: 0, typ: NTI140, name: "font", sons: null}, +{kind: 1, offset: "fontFamily", len: 0, typ: NTI140, name: "fontFamily", sons: null}, +{kind: 1, offset: "fontSize", len: 0, typ: NTI140, name: "fontSize", sons: null}, +{kind: 1, offset: "fontStretch", len: 0, typ: NTI140, name: "fontStretch", sons: null}, +{kind: 1, offset: "fontStyle", len: 0, typ: NTI140, name: "fontStyle", sons: null}, +{kind: 1, offset: "fontVariant", len: 0, typ: NTI140, name: "fontVariant", sons: null}, +{kind: 1, offset: "fontWeight", len: 0, typ: NTI140, name: "fontWeight", sons: null}, +{kind: 1, offset: "height", len: 0, typ: NTI140, name: "height", sons: null}, +{kind: 1, offset: "left", len: 0, typ: NTI140, name: "left", sons: null}, +{kind: 1, offset: "letterSpacing", len: 0, typ: NTI140, name: "letterSpacing", sons: null}, +{kind: 1, offset: "lineHeight", len: 0, typ: NTI140, name: "lineHeight", sons: null}, +{kind: 1, offset: "listStyle", len: 0, typ: NTI140, name: "listStyle", sons: null}, +{kind: 1, offset: "listStyleImage", len: 0, typ: NTI140, name: "listStyleImage", sons: null}, +{kind: 1, offset: "listStylePosition", len: 0, typ: NTI140, name: "listStylePosition", sons: null}, +{kind: 1, offset: "listStyleType", len: 0, typ: NTI140, name: "listStyleType", sons: null}, +{kind: 1, offset: "margin", len: 0, typ: NTI140, name: "margin", sons: null}, +{kind: 1, offset: "marginBottom", len: 0, typ: NTI140, name: "marginBottom", sons: null}, +{kind: 1, offset: "marginLeft", len: 0, typ: NTI140, name: "marginLeft", sons: null}, +{kind: 1, offset: "marginRight", len: 0, typ: NTI140, name: "marginRight", sons: null}, +{kind: 1, offset: "marginTop", len: 0, typ: NTI140, name: "marginTop", sons: null}, +{kind: 1, offset: "maxHeight", len: 0, typ: NTI140, name: "maxHeight", sons: null}, +{kind: 1, offset: "maxWidth", len: 0, typ: NTI140, name: "maxWidth", sons: null}, +{kind: 1, offset: "minHeight", len: 0, typ: NTI140, name: "minHeight", sons: null}, +{kind: 1, offset: "minWidth", len: 0, typ: NTI140, name: "minWidth", sons: null}, +{kind: 1, offset: "opacity", len: 0, typ: NTI140, name: "opacity", sons: null}, +{kind: 1, offset: "overflow", len: 0, typ: NTI140, name: "overflow", sons: null}, +{kind: 1, offset: "padding", len: 0, typ: NTI140, name: "padding", sons: null}, +{kind: 1, offset: "paddingBottom", len: 0, typ: NTI140, name: "paddingBottom", sons: null}, +{kind: 1, offset: "paddingLeft", len: 0, typ: NTI140, name: "paddingLeft", sons: null}, +{kind: 1, offset: "paddingRight", len: 0, typ: NTI140, name: "paddingRight", sons: null}, +{kind: 1, offset: "paddingTop", len: 0, typ: NTI140, name: "paddingTop", sons: null}, +{kind: 1, offset: "pageBreakAfter", len: 0, typ: NTI140, name: "pageBreakAfter", sons: null}, +{kind: 1, offset: "pageBreakBefore", len: 0, typ: NTI140, name: "pageBreakBefore", sons: null}, +{kind: 1, offset: "pointerEvents", len: 0, typ: NTI140, name: "pointerEvents", sons: null}, +{kind: 1, offset: "position", len: 0, typ: NTI140, name: "position", sons: null}, +{kind: 1, offset: "right", len: 0, typ: NTI140, name: "right", sons: null}, +{kind: 1, offset: "scrollbar3dLightColor", len: 0, typ: NTI140, name: "scrollbar3dLightColor", sons: null}, +{kind: 1, offset: "scrollbarArrowColor", len: 0, typ: NTI140, name: "scrollbarArrowColor", sons: null}, +{kind: 1, offset: "scrollbarBaseColor", len: 0, typ: NTI140, name: "scrollbarBaseColor", sons: null}, +{kind: 1, offset: "scrollbarDarkshadowColor", len: 0, typ: NTI140, name: "scrollbarDarkshadowColor", sons: null}, +{kind: 1, offset: "scrollbarFaceColor", len: 0, typ: NTI140, name: "scrollbarFaceColor", sons: null}, +{kind: 1, offset: "scrollbarHighlightColor", len: 0, typ: NTI140, name: "scrollbarHighlightColor", sons: null}, +{kind: 1, offset: "scrollbarShadowColor", len: 0, typ: NTI140, name: "scrollbarShadowColor", sons: null}, +{kind: 1, offset: "scrollbarTrackColor", len: 0, typ: NTI140, name: "scrollbarTrackColor", sons: null}, +{kind: 1, offset: "tableLayout", len: 0, typ: NTI140, name: "tableLayout", sons: null}, +{kind: 1, offset: "textAlign", len: 0, typ: NTI140, name: "textAlign", sons: null}, +{kind: 1, offset: "textDecoration", len: 0, typ: NTI140, name: "textDecoration", sons: null}, +{kind: 1, offset: "textIndent", len: 0, typ: NTI140, name: "textIndent", sons: null}, +{kind: 1, offset: "textTransform", len: 0, typ: NTI140, name: "textTransform", sons: null}, +{kind: 1, offset: "transform", len: 0, typ: NTI140, name: "transform", sons: null}, +{kind: 1, offset: "top", len: 0, typ: NTI140, name: "top", sons: null}, +{kind: 1, offset: "verticalAlign", len: 0, typ: NTI140, name: "verticalAlign", sons: null}, +{kind: 1, offset: "visibility", len: 0, typ: NTI140, name: "visibility", sons: null}, +{kind: 1, offset: "width", len: 0, typ: NTI140, name: "width", sons: null}, +{kind: 1, offset: "wordSpacing", len: 0, typ: NTI140, name: "wordSpacing", sons: null}, +{kind: 1, offset: "zIndex", len: 0, typ: NTI104, name: "zIndex", sons: null}]}; +NTI42283.node = NNI42283; +NTI42283.base = NTI3608; +NTI42281.base = NTI42283; +var NNI42231 = {kind: 2, len: 14, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "attributes", len: 0, typ: NTI42561, name: "attributes", sons: null}, +{kind: 1, offset: "childNodes", len: 0, typ: NTI42563, name: "childNodes", sons: null}, +{kind: 1, offset: "children", len: 0, typ: NTI42565, name: "children", sons: null}, +{kind: 1, offset: "data", len: 0, typ: NTI140, name: "data", sons: null}, +{kind: 1, offset: "firstChild", len: 0, typ: NTI42229, name: "firstChild", sons: null}, +{kind: 1, offset: "lastChild", len: 0, typ: NTI42229, name: "lastChild", sons: null}, +{kind: 1, offset: "nextSibling", len: 0, typ: NTI42229, name: "nextSibling", sons: null}, +{kind: 1, offset: "nodeName", len: 0, typ: NTI140, name: "nodeName", sons: null}, +{kind: 1, offset: "nodeType", len: 0, typ: NTI42227, name: "nodeType", sons: null}, +{kind: 1, offset: "nodeValue", len: 0, typ: NTI140, name: "nodeValue", sons: null}, +{kind: 1, offset: "parentNode", len: 0, typ: NTI42229, name: "parentNode", sons: null}, +{kind: 1, offset: "previousSibling", len: 0, typ: NTI42229, name: "previousSibling", sons: null}, +{kind: 1, offset: "innerHTML", len: 0, typ: NTI140, name: "innerHTML", sons: null}, +{kind: 1, offset: "style", len: 0, typ: NTI42281, name: "style", sons: null}]}; +NTI42231.node = NNI42231; +var NNI42205 = {kind: 2, len: 20, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "onabort", len: 0, typ: NTI42372, name: "onabort", sons: null}, +{kind: 1, offset: "onblur", len: 0, typ: NTI42376, name: "onblur", sons: null}, +{kind: 1, offset: "onchange", len: 0, typ: NTI42380, name: "onchange", sons: null}, +{kind: 1, offset: "onclick", len: 0, typ: NTI42384, name: "onclick", sons: null}, +{kind: 1, offset: "ondblclick", len: 0, typ: NTI42388, name: "ondblclick", sons: null}, +{kind: 1, offset: "onerror", len: 0, typ: NTI42392, name: "onerror", sons: null}, +{kind: 1, offset: "onfocus", len: 0, typ: NTI42396, name: "onfocus", sons: null}, +{kind: 1, offset: "onkeydown", len: 0, typ: NTI42400, name: "onkeydown", sons: null}, +{kind: 1, offset: "onkeypress", len: 0, typ: NTI42404, name: "onkeypress", sons: null}, +{kind: 1, offset: "onkeyup", len: 0, typ: NTI42408, name: "onkeyup", sons: null}, +{kind: 1, offset: "onload", len: 0, typ: NTI42412, name: "onload", sons: null}, +{kind: 1, offset: "onmousedown", len: 0, typ: NTI42416, name: "onmousedown", sons: null}, +{kind: 1, offset: "onmousemove", len: 0, typ: NTI42420, name: "onmousemove", sons: null}, +{kind: 1, offset: "onmouseout", len: 0, typ: NTI42424, name: "onmouseout", sons: null}, +{kind: 1, offset: "onmouseover", len: 0, typ: NTI42428, name: "onmouseover", sons: null}, +{kind: 1, offset: "onmouseup", len: 0, typ: NTI42432, name: "onmouseup", sons: null}, +{kind: 1, offset: "onreset", len: 0, typ: NTI42436, name: "onreset", sons: null}, +{kind: 1, offset: "onselect", len: 0, typ: NTI42440, name: "onselect", sons: null}, +{kind: 1, offset: "onsubmit", len: 0, typ: NTI42444, name: "onsubmit", sons: null}, +{kind: 1, offset: "onunload", len: 0, typ: NTI42448, name: "onunload", sons: null}]}; +NTI42205.node = NNI42205; +NTI42205.base = NTI3608; +NTI42231.base = NTI42205; +NTI42229.base = NTI42231; +NTI44305.base = NTI42229; +NTI162578.base = NTI140; +var NNI3662 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI3662.node = NNI3662; +NTI3662.base = NTI3628; +var NNI160074 = {kind: 2, len: 2, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "Field0", len: 0, typ: NTI104, name: "Field0", sons: null}, +{kind: 1, offset: "Field1", len: 0, typ: NTI130, name: "Field1", sons: null}]}; +NTI160074.node = NNI160074; -function makeNimstrLit(c_64270) { - var ln = c_64270.length; +function makeNimstrLit(c_23270) { + var ln = c_23270.length; var result = new Array(ln); for (var i = 0; i < ln; ++i) { - result[i] = c_64270.charCodeAt(i); + result[i] = c_23270.charCodeAt(i); } return result; - + } function setConstr() { - var result = {}; + var result = {}; for (var i = 0; i < arguments.length; ++i) { var x = arguments[i]; if (typeof(x) == "object") { @@ -274,103 +276,103 @@ function setConstr() { return result; - + } var ConstSet1 = setConstr(17, 16, 4, 18, 27, 19, 23, 22, 21); -function nimCopy(dest_65827, src_65828, ti_65829) { - var result_66019 = null; +function nimCopy(dest_24827, src_24828, ti_24829) { + var result_25019 = null; - switch (ti_65829.kind) { - case 21: - case 22: - case 23: - case 5: - if (!(is_fat_pointer_65801(ti_65829))) { - result_66019 = src_65828; + switch (ti_24829.kind) { + case 21: + case 22: + case 23: + case 5: + if (!(is_fat_pointer_24801(ti_24829))) { + result_25019 = src_24828; + } + else { + result_25019 = [src_24828[0], src_24828[1]]; + } + + break; + case 19: + if (dest_24827 === null || dest_24827 === undefined) { + dest_24827 = {}; } else { - result_66019 = [src_65828[0], src_65828[1]]; + for (var key in dest_24827) { delete dest_24827[key]; } } - - break; - case 19: - if (dest_65827 === null || dest_65827 === undefined) { - dest_65827 = {}; - } - else { - for (var key in dest_65827) { delete dest_65827[key]; } - } - for (var key in src_65828) { dest_65827[key] = src_65828[key]; } - result_66019 = dest_65827; + for (var key in src_24828) { dest_24827[key] = src_24828[key]; } + result_25019 = dest_24827; - break; - case 18: - case 17: - if (!((ti_65829.base == null))) { - result_66019 = nimCopy(dest_65827, src_65828, ti_65829.base); + break; + case 18: + case 17: + if (!((ti_24829.base == null))) { + result_25019 = nimCopy(dest_24827, src_24828, ti_24829.base); + } + else { + if ((ti_24829.kind == 17)) { + result_25019 = (dest_24827 === null || dest_24827 === undefined) ? {m_type: ti_24829} : dest_24827; + } + else { + result_25019 = (dest_24827 === null || dest_24827 === undefined) ? {} : dest_24827; + } + } + nimCopyAux(result_25019, src_24828, ti_24829.node); + break; + case 24: + case 4: + case 27: + case 16: + if (src_24828 === null) { + result_25019 = null; } else { - if ((ti_65829.kind == 17)) { - result_66019 = (dest_65827 === null || dest_65827 === undefined) ? {m_type: ti_65829} : dest_65827; - } - else { - result_66019 = (dest_65827 === null || dest_65827 === undefined) ? {} : dest_65827; - } - } - nimCopyAux(result_66019, src_65828, ti_65829.node); - break; - case 24: - case 4: - case 27: - case 16: - if (src_65828 === null) { - result_66019 = null; - } - else { - if (dest_65827 === null || dest_65827 === undefined) { - dest_65827 = new Array(src_65828.length); + if (dest_24827 === null || dest_24827 === undefined) { + dest_24827 = new Array(src_24828.length); } else { - dest_65827.length = src_65828.length; + dest_24827.length = src_24828.length; } - result_66019 = dest_65827; - for (var i = 0; i < src_65828.length; ++i) { - result_66019[i] = nimCopy(result_66019[i], src_65828[i], ti_65829.base); + result_25019 = dest_24827; + for (var i = 0; i < src_24828.length; ++i) { + result_25019[i] = nimCopy(result_25019[i], src_24828[i], ti_24829.base); } } - break; - case 28: - if (src_65828 !== null) { - result_66019 = src_65828.slice(0); + break; + case 28: + if (src_24828 !== null) { + result_25019 = src_24828.slice(0); } - break; - default: - result_66019 = src_65828; - break; - } + break; + default: + result_25019 = src_24828; + break; + } - return result_66019; + return result_25019; } -function arrayConstr(len_66086, value_66087, typ_66088) { - var result = new Array(len_66086); - for (var i = 0; i < len_66086; ++i) result[i] = nimCopy(null, value_66087, typ_66088); +function arrayConstr(len_25086, value_25087, typ_25088) { + var result = new Array(len_25086); + for (var i = 0; i < len_25086; ++i) result[i] = nimCopy(null, value_25087, typ_25088); return result; - + } -function cstrToNimstr(c_64287) { - var ln = c_64287.length; +function cstrToNimstr(c_23287) { + var ln = c_23287.length; var result = new Array(ln); var r = 0; for (var i = 0; i < ln; ++i) { - var ch = c_64287.charCodeAt(i); + var ch = c_23287.charCodeAt(i); if (ch < 128) { result[r] = ch; @@ -385,7 +387,7 @@ function cstrToNimstr(c_64287) { } else { ++i; - ch = 65536 + (((ch & 1023) << 10) | (c_64287.charCodeAt(i) & 1023)); + ch = 65536 + (((ch & 1023) << 10) | (c_23287.charCodeAt(i) & 1023)); result[r] = (ch >> 18) | 240; ++r; result[r] = ((ch >> 12) & 63) | 128; @@ -401,1448 +403,1448 @@ function cstrToNimstr(c_64287) { return result; - + } -function toJSStr(s_64304) { - var Tmp5; - var Tmp7; +function toJSStr(s_23304) { + var Tmp5; + var Tmp7; - var result_64305 = null; + var result_23305 = null; - var res_64378 = new_seq_64336((s_64304 != null ? s_64304.length : 0)); - var i_64380 = 0; - var j_64382 = 0; - L1: do { - L2: while (true) { - if (!(i_64380 < (s_64304 != null ? s_64304.length : 0))) break L2; - var c_64383 = s_64304[i_64380]; - if ((c_64383 < 128)) { - res_64378[j_64382] = String.fromCharCode(c_64383); - i_64380 += 1; - } - else { - var helper_64406 = new_seq_64336(0); - L3: do { - L4: while (true) { - if (!true) break L4; - var code_64407 = c_64383.toString(16); - if (((code_64407 != null ? code_64407.length : 0) == 1)) { - if (helper_64406 != null) { helper_64406.push("%0"); } else { helper_64406 = ["%0"]; }; - } - else { - if (helper_64406 != null) { helper_64406.push("%"); } else { helper_64406 = ["%"]; }; - } - - if (helper_64406 != null) { helper_64406.push(code_64407); } else { helper_64406 = [code_64407]; }; - i_64380 += 1; - if (((s_64304 != null ? s_64304.length : 0) <= i_64380)) Tmp5 = true; else { Tmp5 = (s_64304[i_64380] < 128); } if (Tmp5) { - break L3; - } - - c_64383 = s_64304[i_64380]; - } - } while(false); + var res_23363 = new_seq_23336((s_23304 != null ? s_23304.length : 0)); + var i_23365 = 0; + var j_23367 = 0; + L1: do { + L2: while (true) { + if (!(i_23365 < (s_23304 != null ? s_23304.length : 0))) break L2; + var c_23368 = s_23304[i_23365]; + if ((c_23368 < 128)) { + res_23363[j_23367] = String.fromCharCode(c_23368); + i_23365 += 1; + } + else { + var helper_23391 = new_seq_23336(0); + L3: do { + L4: while (true) { + if (!true) break L4; + var code_23392 = c_23368.toString(16); + if (((code_23392 != null ? code_23392.length : 0) == 1)) { + if (helper_23391 != null) { helper_23391.push("%0"); } else { helper_23391 = ["%0"]; }; + } + else { + if (helper_23391 != null) { helper_23391.push("%"); } else { helper_23391 = ["%"]; }; + } + + if (helper_23391 != null) { helper_23391.push(code_23392); } else { helper_23391 = [code_23392]; }; + i_23365 += 1; + if (((s_23304 != null ? s_23304.length : 0) <= i_23365)) Tmp5 = true; else { Tmp5 = (s_23304[i_23365] < 128); } if (Tmp5) { + break L3; + } + + c_23368 = s_23304[i_23365]; + } + } while(false); ++excHandler; - Tmp7 = framePtr; - try { - res_64378[j_64382] = decodeURIComponent(helper_64406.join("")); + Tmp7 = framePtr; + try { + res_23363[j_23367] = decodeURIComponent(helper_23391.join("")); --excHandler; } catch (EXC) { var prevJSError = lastJSError; lastJSError = EXC; --excHandler; - framePtr = Tmp7; - res_64378[j_64382] = helper_64406.join(""); - lastJSError = prevJSError; - } finally { - framePtr = Tmp7; - } - } - - j_64382 += 1; - } - } while(false); - if (res_64378 === null) res_64378 = []; - if (res_64378.length < j_64382) { for (var i=res_64378.length;i 2147483647 || result < -2147483648) raiseOverflow(); return result; - + } -function chckIndx(i_66105, a_66106, b_66107) { - var Tmp1; +function chckIndx(i_25105, a_25106, b_25107) { + var Tmp1; - var result_66108 = 0; + var result_25108 = 0; - BeforeRet: do { - if (!(a_66106 <= i_66105)) Tmp1 = false; else { Tmp1 = (i_66105 <= b_66107); } if (Tmp1) { - result_66108 = i_66105; - break BeforeRet; - } - else { - raiseIndexError(i_66105, a_66106, b_66107); - } - - } while (false); + BeforeRet: do { + if (!(a_25106 <= i_25105)) Tmp1 = false; else { Tmp1 = (i_25105 <= b_25107); } if (Tmp1) { + result_25108 = i_25105; + break BeforeRet; + } + else { + raiseIndexError(i_25105, a_25106, b_25107); + } + + } while (false); - return result_66108; + return result_25108; } -function subInt(a_64821, b_64822) { - var result = a_64821 - b_64822; +function subInt(a_23821, b_23822) { + var result = a_23821 - b_23822; if (result > 2147483647 || result < -2147483648) raiseOverflow(); return result; - + } var ConstSet2 = setConstr([65, 90]); -function chckRange(i_66124, a_66125, b_66126) { - var Tmp1; +function chckRange(i_25124, a_25125, b_25126) { + var Tmp1; - var result_66127 = 0; + var result_25127 = 0; - BeforeRet: do { - if (!(a_66125 <= i_66124)) Tmp1 = false; else { Tmp1 = (i_66124 <= b_66126); } if (Tmp1) { - result_66127 = i_66124; - break BeforeRet; - } - else { - raiseRangeError(); - } - - } while (false); + BeforeRet: do { + if (!(a_25125 <= i_25124)) Tmp1 = false; else { Tmp1 = (i_25124 <= b_25126); } if (Tmp1) { + result_25127 = i_25124; + break BeforeRet; + } + else { + raiseRangeError(); + } + + } while (false); - return result_66127; + return result_25127; } var ConstSet3 = setConstr(95, 32, 46); var ConstSet4 = setConstr(95, 32, 46); -function mulInt(a_64839, b_64840) { - var result = a_64839 * b_64840; +function mulInt(a_23839, b_23840) { + var result = a_23839 * b_23840; if (result > 2147483647 || result < -2147483648) raiseOverflow(); return result; - + } var ConstSet5 = setConstr([97, 122]); var ConstSet6 = setConstr([65, 90], [97, 122]); var ConstSet7 = setConstr([97, 122]); var ConstSet8 = setConstr([65, 90]); -function nimMax(a_65221, b_65222) { - var Tmp1; +function nimMax(a_24221, b_24222) { + var Tmp1; - var result_65223 = 0; + var result_24223 = 0; - BeforeRet: do { - if ((b_65222 <= a_65221)) { - Tmp1 = a_65221; - } - else { - Tmp1 = b_65222; - } - - result_65223 = Tmp1; - break BeforeRet; - } while (false); + BeforeRet: do { + if ((b_24222 <= a_24221)) { + Tmp1 = a_24221; + } + else { + Tmp1 = b_24222; + } + + result_24223 = Tmp1; + break BeforeRet; + } while (false); - return result_65223; + return result_24223; } -function nimMin(a_65203, b_65204) { - var Tmp1; +function nimMin(a_24203, b_24204) { + var Tmp1; - var result_65205 = 0; + var result_24205 = 0; - BeforeRet: do { - if ((a_65203 <= b_65204)) { - Tmp1 = a_65203; - } - else { - Tmp1 = b_65204; - } - - result_65205 = Tmp1; - break BeforeRet; - } while (false); + BeforeRet: do { + if ((a_24203 <= b_24204)) { + Tmp1 = a_24203; + } + else { + Tmp1 = b_24204; + } + + result_24205 = Tmp1; + break BeforeRet; + } while (false); - return result_65205; + return result_24205; } var nim_program_result = 0; -var global_raise_hook_59818 = [null]; -var local_raise_hook_59823 = [null]; -var out_of_mem_hook_59826 = [null]; -if (!Math.trunc) { - Math.trunc = function(v) { - v = +v; - if (!isFinite(v)) return v; - return (v - v % 1) || (v < 0 ? -0 : v === 0 ? v : 0); - }; -} +var global_raise_hook_18618 = [null]; +var local_raise_hook_18623 = [null]; +var out_of_mem_hook_18626 = [null]; + if (!Math.trunc) { + Math.trunc = function(v) { + v = +v; + if (!isFinite(v)) return v; -var alternative_197319 = [null]; + return (v - v % 1) || (v < 0 ? -0 : v === 0 ? v : 0); + }; + } +var alternative_162319 = [null]; -function is_fat_pointer_65801(ti_65803) { - var result_65804 = false; +function is_fat_pointer_24801(ti_24803) { + var result_24804 = false; - BeforeRet: do { - result_65804 = !((ConstSet1[ti_65803.base.kind] != undefined)); - break BeforeRet; - } while (false); + BeforeRet: do { + result_24804 = !((ConstSet1[ti_24803.base.kind] != undefined)); + break BeforeRet; + } while (false); - return result_65804; + return result_24804; } -function nimCopyAux(dest_65832, src_65833, n_65835) { - switch (n_65835.kind) { - case 0: - break; - case 1: - dest_65832[n_65835.offset] = nimCopy(dest_65832[n_65835.offset], src_65833[n_65835.offset], n_65835.typ); +function nimCopyAux(dest_24832, src_24833, n_24835) { + switch (n_24835.kind) { + case 0: + break; + case 1: + dest_24832[n_24835.offset] = nimCopy(dest_24832[n_24835.offset], src_24833[n_24835.offset], n_24835.typ); - break; - case 2: - for (var i = 0; i < n_65835.sons.length; i++) { - nimCopyAux(dest_65832, src_65833, n_65835.sons[i]); + break; + case 2: + for (var i = 0; i < n_24835.sons.length; i++) { + nimCopyAux(dest_24832, src_24833, n_24835.sons[i]); } - break; - case 3: - dest_65832[n_65835.offset] = nimCopy(dest_65832[n_65835.offset], src_65833[n_65835.offset], n_65835.typ); - for (var i = 0; i < n_65835.sons.length; ++i) { - nimCopyAux(dest_65832, src_65833, n_65835.sons[i][1]); + break; + case 3: + dest_24832[n_24835.offset] = nimCopy(dest_24832[n_24835.offset], src_24833[n_24835.offset], n_24835.typ); + for (var i = 0; i < n_24835.sons.length; ++i) { + nimCopyAux(dest_24832, src_24833, n_24835.sons[i][1]); } - break; - } + break; + } - + } -function add_59838(x_59841, x_59841_Idx, y_59842) { - if (x_59841[x_59841_Idx] === null) { x_59841[x_59841_Idx] = []; } - var off = x_59841[x_59841_Idx].length; - x_59841[x_59841_Idx].length += y_59842.length; - for (var i = 0; i < y_59842.length; ++i) { - x_59841[x_59841_Idx][off+i] = y_59842.charCodeAt(i); +function add_18638(x_18641, x_18641_Idx, y_18642) { + if (x_18641[x_18641_Idx] === null) { x_18641[x_18641_Idx] = []; } + var off = x_18641[x_18641_Idx].length; + x_18641[x_18641_Idx].length += y_18642.length; + for (var i = 0; i < y_18642.length; ++i) { + x_18641[x_18641_Idx][off+i] = y_18642.charCodeAt(i); } - + } -function aux_write_stack_trace_62151(f_62153) { - var Tmp3; +function aux_write_stack_trace_21151(f_21153) { + var Tmp3; - var result_62154 = [null]; + var result_21154 = [null]; - var it_62162 = f_62153; - var i_62164 = 0; - var total_62166 = 0; - var temp_frames_62173 = arrayConstr(64, {Field0: null, Field1: 0}, NTI62156); - L1: do { - L2: while (true) { - if (!!((it_62162 == null))) Tmp3 = false; else { Tmp3 = (i_62164 <= 63); } if (!Tmp3) break L2; - temp_frames_62173[i_62164].Field0 = it_62162.procname; - temp_frames_62173[i_62164].Field1 = it_62162.line; - i_62164 += 1; - total_62166 += 1; - it_62162 = it_62162.prev; - } - } while(false); - L4: do { - L5: while (true) { - if (!!((it_62162 == null))) break L5; - total_62166 += 1; - it_62162 = it_62162.prev; - } - } while(false); - result_62154[0] = nimCopy(null, [], NTI43040); - if (!((total_62166 == i_62164))) { - if (result_62154[0] != null) { result_62154[0] = (result_62154[0]).concat(makeNimstrLit("(")); } else { result_62154[0] = makeNimstrLit("("); }; - if (result_62154[0] != null) { result_62154[0] = (result_62154[0]).concat(cstrToNimstr(((total_62166 - i_62164))+"")); } else { result_62154[0] = cstrToNimstr(((total_62166 - i_62164))+"").slice(); }; - if (result_62154[0] != null) { result_62154[0] = (result_62154[0]).concat(makeNimstrLit(" calls omitted) ...\x0A")); } else { result_62154[0] = makeNimstrLit(" calls omitted) ...\x0A"); }; - } - - L6: do { - var j_62421 = 0; - var colontmp__197462 = 0; - colontmp__197462 = (i_62164 - 1); - var res_197467 = colontmp__197462; - L7: do { - L8: while (true) { - if (!(0 <= res_197467)) break L8; - j_62421 = res_197467; - add_59838(result_62154, 0, temp_frames_62173[j_62421].Field0); - if ((0 < temp_frames_62173[j_62421].Field1)) { - if (result_62154[0] != null) { result_62154[0] = (result_62154[0]).concat(makeNimstrLit(", line: ")); } else { result_62154[0] = makeNimstrLit(", line: "); }; - if (result_62154[0] != null) { result_62154[0] = (result_62154[0]).concat(cstrToNimstr((temp_frames_62173[j_62421].Field1)+"")); } else { result_62154[0] = cstrToNimstr((temp_frames_62173[j_62421].Field1)+"").slice(); }; - } - - if (result_62154[0] != null) { result_62154[0] = (result_62154[0]).concat(makeNimstrLit("\x0A")); } else { result_62154[0] = makeNimstrLit("\x0A"); }; - res_197467 -= 1; - } - } while(false); - } while(false); + var it_21162 = f_21153; + var i_21164 = 0; + var total_21166 = 0; + var temp_frames_21173 = arrayConstr(64, {Field0: null, Field1: 0}, NTI21156); + L1: do { + L2: while (true) { + if (!!((it_21162 == null))) Tmp3 = false; else { Tmp3 = (i_21164 <= 63); } if (!Tmp3) break L2; + temp_frames_21173[i_21164].Field0 = it_21162.procname; + temp_frames_21173[i_21164].Field1 = it_21162.line; + i_21164 += 1; + total_21166 += 1; + it_21162 = it_21162.prev; + } + } while(false); + L4: do { + L5: while (true) { + if (!!((it_21162 == null))) break L5; + total_21166 += 1; + it_21162 = it_21162.prev; + } + } while(false); + result_21154[0] = nimCopy(null, [], NTI138); + if (!((total_21166 == i_21164))) { + if (result_21154[0] != null) { result_21154[0] = (result_21154[0]).concat(makeNimstrLit("(")); } else { result_21154[0] = makeNimstrLit("("); }; + if (result_21154[0] != null) { result_21154[0] = (result_21154[0]).concat(cstrToNimstr(((total_21166 - i_21164))+"")); } else { result_21154[0] = cstrToNimstr(((total_21166 - i_21164))+"").slice(); }; + if (result_21154[0] != null) { result_21154[0] = (result_21154[0]).concat(makeNimstrLit(" calls omitted) ...\x0A")); } else { result_21154[0] = makeNimstrLit(" calls omitted) ...\x0A"); }; + } + + L6: do { + var j_21421 = 0; + var colontmp__162466 = 0; + colontmp__162466 = (i_21164 - 1); + var res_162471 = colontmp__162466; + L7: do { + L8: while (true) { + if (!(0 <= res_162471)) break L8; + j_21421 = res_162471; + add_18638(result_21154, 0, temp_frames_21173[j_21421].Field0); + if ((0 < temp_frames_21173[j_21421].Field1)) { + if (result_21154[0] != null) { result_21154[0] = (result_21154[0]).concat(makeNimstrLit(", line: ")); } else { result_21154[0] = makeNimstrLit(", line: "); }; + if (result_21154[0] != null) { result_21154[0] = (result_21154[0]).concat(cstrToNimstr((temp_frames_21173[j_21421].Field1)+"")); } else { result_21154[0] = cstrToNimstr((temp_frames_21173[j_21421].Field1)+"").slice(); }; + } + + if (result_21154[0] != null) { result_21154[0] = (result_21154[0]).concat(makeNimstrLit("\x0A")); } else { result_21154[0] = makeNimstrLit("\x0A"); }; + res_162471 -= 1; + } + } while(false); + } while(false); - return result_62154[0]; + return result_21154[0]; } -function raw_write_stack_trace_62481() { - var result_62483 = null; +function raw_write_stack_trace_21468() { + var result_21470 = null; - if (!((framePtr == null))) { - result_62483 = nimCopy(null, (makeNimstrLit("Traceback (most recent call last)\x0A") || []).concat(aux_write_stack_trace_62151(framePtr) || []), NTI43040); - } - else { - result_62483 = nimCopy(null, makeNimstrLit("No stack traceback available\x0A"), NTI43040); - } - + if (!((framePtr == null))) { + result_21470 = nimCopy(null, (makeNimstrLit("Traceback (most recent call last)\x0A") || []).concat(aux_write_stack_trace_21151(framePtr) || []), NTI138); + } + else { + result_21470 = nimCopy(null, makeNimstrLit("No stack traceback available\x0A"), NTI138); + } + - return result_62483; + return result_21470; } -function new_seq_64336(len_64339) { - var result_64341 = null; +function new_seq_23336(len_23339) { + var result_23341 = null; - var F={procname:"newSeq.newSeq",prev:framePtr,filename:"system.nim",line:0}; - framePtr = F; - F.line = 984; - result_64341 = new Array(len_64339); for (var i=0;i", "text/html"); - stuff_197555 = doc.documentElement; + stuff_162563 = doc.documentElement; - F.line = 286; - db_197527[0] = nimCopy(null, stuff_197555.getElementsByClassName("reference"), NTI85305); - F.line = 287; - contents_197529[0] = nimCopy(null, [], NTI197570); - L1: do { - F.line = 288; - var ahref_197814 = null; - F.line = 184; - var i_198045 = 0; - F.line = 185; - var l_198046 = (db_197527[0] != null ? db_197527[0].length : 0); - L2: do { - F.line = 186; - L3: while (true) { - if (!(i_198045 < l_198046)) break L3; - F.line = 288; - ahref_197814 = db_197527[0][chckIndx(i_198045, 0, (db_197527[0] != null ? db_197527[0].length : 0)+0-1)-0]; - F.line = 289; - if (contents_197529[0] != null) { contents_197529[0].push(ahref_197814.getAttribute("data-doc-search-tag")); } else { contents_197529[0] = [ahref_197814.getAttribute("data-doc-search-tag")]; }; - F.line = 188; - i_198045 = addInt(i_198045, 1); - if (!(((db_197527[0] != null ? db_197527[0].length : 0) == l_198046))) { - F.line = 189; - failed_assert_impl_56666(makeNimstrLit("/home/genotrance/programming/nimdevel/lib/system/iterators.nim(189, 11) `len(a) ==\x0A L` the length of the seq changed while iterating over it")); - } - - } - } while(false); - } while(false); - } - - F.line = 290; - var ul_197825 = tree_196020(makeNimstrLit("UL"), []); - F.line = 291; - result_197549 = tree_196020(makeNimstrLit("DIV"), []); - F.line = 292; - set_class_196103(result_197549, makeNimstrLit("search_results")); - F.line = 293; - var matches_197846 = []; - L4: do { - F.line = 294; - var i_197859 = 0; - F.line = 2734; - var colontmp__198052 = 0; - F.line = 294; - colontmp__198052 = (db_197527[0] != null ? db_197527[0].length : 0); - F.line = 2736; - var i_198053 = 0; - L5: do { - F.line = 2737; - L6: while (true) { - if (!(i_198053 < colontmp__198052)) break L6; - F.line = 294; - i_197859 = i_198053; - L7: do { - F.line = 295; - var c_197860 = contents_197529[0][chckIndx(i_197859, 0, (contents_197529[0] != null ? contents_197529[0].length : 0)+0-1)-0]; - if (((c_197860 == "Examples") || (c_197860 == "PEG construction"))) { - F.line = 300; - break L7; - } - - F.line = 301; - var colontmp__198060 = {Field0: 0, Field1: false}; - F.line = 301; - var score_197861 = 0; - F.line = 301; - var matched_197862 = false; - F.line = 301; - nimCopy(colontmp__198060, fuzzy_match_195054(value_197548, c_197860), NTI195058); - F.line = 301; - score_197861 = colontmp__198060["Field0"]; - F.line = 301; - matched_197862 = colontmp__198060["Field1"]; - if (matched_197862) { - F.line = 303; - if (matches_197846 != null) { matches_197846.push({Field0: db_197527[0][chckIndx(i_197859, 0, (db_197527[0] != null ? db_197527[0].length : 0)+0-1)-0], Field1: score_197861}); } else { matches_197846 = [{Field0: db_197527[0][chckIndx(i_197859, 0, (db_197527[0] != null ? db_197527[0].length : 0)+0-1)-0], Field1: score_197861}]; }; - } - - } while(false); - F.line = 2739; - i_198053 = addInt(i_198053, 1); - } - } while(false); - } while(false); - F.line = 305; - matches_197846.sort(HEX3Aanonymous_197873); - L8: do { - F.line = 306; - var i_197926 = 0; - F.line = 2734; - var colontmp__198057 = 0; - F.line = 306; - colontmp__198057 = nimMin((matches_197846 != null ? matches_197846.length : 0), 19); - F.line = 2736; - var i_198058 = 0; - L9: do { - F.line = 2737; - L10: while (true) { - if (!(i_198058 < colontmp__198057)) break L10; - F.line = 306; - i_197926 = i_198058; - F.line = 307; - matches_197846[chckIndx(i_197926, 0, (matches_197846 != null ? matches_197846.length : 0)+0-1)-0]["Field0"].innerHTML = matches_197846[chckIndx(i_197926, 0, (matches_197846 != null ? matches_197846.length : 0)+0-1)-0]["Field0"].getAttribute("data-doc-search-tag"); - F.line = 308; - add_196085(ul_197825, tree_196020(makeNimstrLit("LI"), [matches_197846[chckIndx(i_197926, 0, (matches_197846 != null ? matches_197846.length : 0)+0-1)-0]["Field0"]])); - F.line = 2739; - i_198058 = addInt(i_198058, 1); - } - } while(false); - } while(false); - if ((ul_197825.childNodes.length == 0)) { - F.line = 310; - add_196085(result_197549, tree_196020(makeNimstrLit("B"), [text_196120(makeNimstrLit("no search results"))])); - } - else { - F.line = 312; - add_196085(result_197549, tree_196020(makeNimstrLit("B"), [text_196120(makeNimstrLit("search results"))])); - F.line = 313; - add_196085(result_197549, ul_197825); - } - - framePtr = F.prev; + F.line = 286; + db_162535[0] = nimCopy(null, stuff_162563.getElementsByClassName("reference"), NTI44305); + F.line = 287; + contents_162537[0] = nimCopy(null, [], NTI162578); + L1: do { + F.line = 288; + var ahref_162814 = null; + F.line = 184; + var i_163045 = 0; + F.line = 185; + var l_163046 = (db_162535[0] != null ? db_162535[0].length : 0); + L2: do { + F.line = 186; + L3: while (true) { + if (!(i_163045 < l_163046)) break L3; + F.line = 288; + ahref_162814 = db_162535[0][chckIndx(i_163045, 0, (db_162535[0] != null ? db_162535[0].length : 0)+0-1)-0]; + F.line = 289; + if (contents_162537[0] != null) { contents_162537[0].push(ahref_162814.getAttribute("data-doc-search-tag")); } else { contents_162537[0] = [ahref_162814.getAttribute("data-doc-search-tag")]; }; + F.line = 188; + i_163045 = addInt(i_163045, 1); + if (!(((db_162535[0] != null ? db_162535[0].length : 0) == l_163046))) { + F.line = 189; + failed_assert_impl_15266(makeNimstrLit("/home/genotrance/.choosenim/toolchains/nim-1.0.4/lib/system/iterators.nim(189, 11) `len(a) == L` the length of the seq changed while iterating over it")); + } + + } + } while(false); + } while(false); + } + + F.line = 290; + var ul_162825 = tree_161020(makeNimstrLit("UL"), []); + F.line = 291; + result_162557 = tree_161020(makeNimstrLit("DIV"), []); + F.line = 292; + set_class_161103(result_162557, makeNimstrLit("search_results")); + F.line = 293; + var matches_162846 = []; + L4: do { + F.line = 294; + var i_162859 = 0; + F.line = 2737; + var colontmp__163052 = 0; + F.line = 294; + colontmp__163052 = (db_162535[0] != null ? db_162535[0].length : 0); + F.line = 2739; + var i_163053 = 0; + L5: do { + F.line = 2740; + L6: while (true) { + if (!(i_163053 < colontmp__163052)) break L6; + F.line = 294; + i_162859 = i_163053; + L7: do { + F.line = 295; + var c_162860 = contents_162537[0][chckIndx(i_162859, 0, (contents_162537[0] != null ? contents_162537[0].length : 0)+0-1)-0]; + if (((c_162860 == "Examples") || (c_162860 == "PEG construction"))) { + F.line = 300; + break L7; + } + + F.line = 301; + var colontmp__163062 = {Field0: 0, Field1: false}; + F.line = 301; + var score_162861 = 0; + F.line = 301; + var matched_162862 = false; + F.line = 301; + nimCopy(colontmp__163062, fuzzy_match_160070(value_162556, c_162860), NTI160074); + F.line = 301; + score_162861 = colontmp__163062["Field0"]; + F.line = 301; + matched_162862 = colontmp__163062["Field1"]; + if (matched_162862) { + F.line = 303; + if (matches_162846 != null) { matches_162846.push({Field0: db_162535[0][chckIndx(i_162859, 0, (db_162535[0] != null ? db_162535[0].length : 0)+0-1)-0], Field1: score_162861}); } else { matches_162846 = [{Field0: db_162535[0][chckIndx(i_162859, 0, (db_162535[0] != null ? db_162535[0].length : 0)+0-1)-0], Field1: score_162861}]; }; + } + + } while(false); + F.line = 2742; + i_163053 = addInt(i_163053, 1); + } + } while(false); + } while(false); + F.line = 305; + matches_162846.sort(HEX3Aanonymous_162873); + L8: do { + F.line = 306; + var i_162926 = 0; + F.line = 2737; + var colontmp__163058 = 0; + F.line = 306; + colontmp__163058 = nimMin((matches_162846 != null ? matches_162846.length : 0), 19); + F.line = 2739; + var i_163059 = 0; + L9: do { + F.line = 2740; + L10: while (true) { + if (!(i_163059 < colontmp__163058)) break L10; + F.line = 306; + i_162926 = i_163059; + F.line = 307; + matches_162846[chckIndx(i_162926, 0, (matches_162846 != null ? matches_162846.length : 0)+0-1)-0]["Field0"].innerHTML = matches_162846[chckIndx(i_162926, 0, (matches_162846 != null ? matches_162846.length : 0)+0-1)-0]["Field0"].getAttribute("data-doc-search-tag"); + F.line = 308; + add_161085(ul_162825, tree_161020(makeNimstrLit("LI"), [matches_162846[chckIndx(i_162926, 0, (matches_162846 != null ? matches_162846.length : 0)+0-1)-0]["Field0"]])); + F.line = 2742; + i_163059 = addInt(i_163059, 1); + } + } while(false); + } while(false); + if ((ul_162825.childNodes.length == 0)) { + F.line = 310; + add_161085(result_162557, tree_161020(makeNimstrLit("B"), [text_161120(makeNimstrLit("no search results"))])); + } + else { + F.line = 312; + add_161085(result_162557, tree_161020(makeNimstrLit("B"), [text_161120(makeNimstrLit("search results"))])); + F.line = 313; + add_161085(result_162557, ul_162825); + } + + framePtr = F.prev; - return result_197549; + return result_162557; } function search() { - function wrapper_197993() { - var F={procname:"search.wrapper",prev:framePtr,filename:"dochack.nim",line:0}; - framePtr = F; - F.line = 320; - var elem_197995 = document.getElementById("searchInput"); - F.line = 321; - var value_197996 = elem_197995.value; - if (!(((value_197996 != null ? value_197996.length : 0) == 0))) { - if ((oldtoc_197961[0] == null)) { - F.line = 324; - oldtoc_197961[0] = document.getElementById("tocRoot"); - } - - F.line = 325; - var results_198002 = dosearch_197546(value_197996); - F.line = 326; - replace_by_id_196172("tocRoot", results_198002); - } - else { - if (!((oldtoc_197961[0] == null))) { - F.line = 328; - replace_by_id_196172("tocRoot", oldtoc_197961[0]); - } - } - framePtr = F.prev; + function wrapper_162993() { + var F={procname:"search.wrapper",prev:framePtr,filename:"dochack.nim",line:0}; + framePtr = F; + F.line = 320; + var elem_162995 = document.getElementById("searchInput"); + F.line = 321; + var value_162996 = elem_162995.value; + if (!(((value_162996 != null ? value_162996.length : 0) == 0))) { + if ((oldtoc_162961[0] == null)) { + F.line = 324; + oldtoc_162961[0] = document.getElementById("tocRoot"); + } + + F.line = 325; + var results_163002 = dosearch_162554(value_162996); + F.line = 326; + replace_by_id_161172("tocRoot", results_163002); + } + else { + if (!((oldtoc_162961[0] == null))) { + F.line = 328; + replace_by_id_161172("tocRoot", oldtoc_162961[0]); + } + } + framePtr = F.prev; - - } + + } - var F={procname:"dochack.search",prev:framePtr,filename:"dochack.nim",line:0}; - framePtr = F; - if (!((timer_197962[0] == null))) { - F.line = 330; - clearTimeout(timer_197962[0]); - } - - F.line = 331; - timer_197962[0] = setTimeout(wrapper_197993, 400); - framePtr = F.prev; + var F={procname:"dochack.search",prev:framePtr,filename:"dochack.nim",line:0}; + framePtr = F; + if (!((timer_162962[0] == null))) { + F.line = 330; + clearTimeout(timer_162962[0]); + } + + F.line = 331; + timer_162962[0] = setTimeout(wrapper_162993, 400); + framePtr = F.prev; - + } diff --git a/paths.html b/paths.html index 2d9463f..6f7f98c 100644 --- a/paths.html +++ b/paths.html @@ -10,7 +10,6 @@ - @@ -18,7 +17,772 @@ paths - + @@ -33,37 +797,6 @@ function main() { event.target.parentNode.nextElementSibling.style.display = "inline"; } } - - const toggleSwitch = document.querySelector('.theme-switch input[type="checkbox"]'); - function switchTheme(e) { - if (e.target.checked) { - document.documentElement.setAttribute('data-theme', 'dark'); - localStorage.setItem('theme', 'dark'); - } else { - document.documentElement.setAttribute('data-theme', 'light'); - localStorage.setItem('theme', 'light'); - } - } - - toggleSwitch.addEventListener('change', switchTheme, false); - - - if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { - document.documentElement.setAttribute('data-theme', "dark"); - toggleSwitch.checked = true; - } else if (window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches) { - document.documentElement.setAttribute('data-theme', "light"); - toggleSwitch.checked = false; - } else { - const currentTheme = localStorage.getItem('theme') ? localStorage.getItem('theme') : null; - if (currentTheme) { - document.documentElement.setAttribute('data-theme', currentTheme); - - if (currentTheme === 'dark') { - toggleSwitch.checked = true; - } - } - } } @@ -74,13 +807,6 @@ function main() {

      paths

      -
      - -     Dark Mode -
      diff --git a/plugin.html b/plugin.html index 38a7dd7..ed37afd 100644 --- a/plugin.html +++ b/plugin.html @@ -10,7 +10,6 @@ - @@ -18,7 +17,772 @@ plugin - + @@ -33,37 +797,6 @@ function main() { event.target.parentNode.nextElementSibling.style.display = "inline"; } } - - const toggleSwitch = document.querySelector('.theme-switch input[type="checkbox"]'); - function switchTheme(e) { - if (e.target.checked) { - document.documentElement.setAttribute('data-theme', 'dark'); - localStorage.setItem('theme', 'dark'); - } else { - document.documentElement.setAttribute('data-theme', 'light'); - localStorage.setItem('theme', 'light'); - } - } - - toggleSwitch.addEventListener('change', switchTheme, false); - - - if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { - document.documentElement.setAttribute('data-theme', "dark"); - toggleSwitch.checked = true; - } else if (window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches) { - document.documentElement.setAttribute('data-theme', "light"); - toggleSwitch.checked = false; - } else { - const currentTheme = localStorage.getItem('theme') ? localStorage.getItem('theme') : null; - if (currentTheme) { - document.documentElement.setAttribute('data-theme', currentTheme); - - if (currentTheme === 'dark') { - toggleSwitch.checked = true; - } - } - } } @@ -74,13 +807,6 @@ function main() {

      plugin

      -
      - -     Dark Mode -
      diff --git a/theindex.html b/theindex.html index 64d2436..e37add3 100644 --- a/theindex.html +++ b/theindex.html @@ -10,7 +10,6 @@ - @@ -18,7 +17,772 @@ Index - + @@ -33,37 +797,6 @@ function main() { event.target.parentNode.nextElementSibling.style.display = "inline"; } } - - const toggleSwitch = document.querySelector('.theme-switch input[type="checkbox"]'); - function switchTheme(e) { - if (e.target.checked) { - document.documentElement.setAttribute('data-theme', 'dark'); - localStorage.setItem('theme', 'dark'); - } else { - document.documentElement.setAttribute('data-theme', 'light'); - localStorage.setItem('theme', 'light'); - } - } - - toggleSwitch.addEventListener('change', switchTheme, false); - - - if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { - document.documentElement.setAttribute('data-theme', "dark"); - toggleSwitch.checked = true; - } else if (window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches) { - document.documentElement.setAttribute('data-theme', "light"); - toggleSwitch.checked = false; - } else { - const currentTheme = localStorage.getItem('theme') ? localStorage.getItem('theme') : null; - if (currentTheme) { - document.documentElement.setAttribute('data-theme', currentTheme); - - if (currentTheme === 'dark') { - toggleSwitch.checked = true; - } - } - } } @@ -344,7 +1077,7 @@ function main() {
      diff --git a/types.html b/types.html index 165d512..06628f3 100644 --- a/types.html +++ b/types.html @@ -10,7 +10,6 @@ - @@ -18,7 +17,772 @@ types - + @@ -33,37 +797,6 @@ function main() { event.target.parentNode.nextElementSibling.style.display = "inline"; } } - - const toggleSwitch = document.querySelector('.theme-switch input[type="checkbox"]'); - function switchTheme(e) { - if (e.target.checked) { - document.documentElement.setAttribute('data-theme', 'dark'); - localStorage.setItem('theme', 'dark'); - } else { - document.documentElement.setAttribute('data-theme', 'light'); - localStorage.setItem('theme', 'light'); - } - } - - toggleSwitch.addEventListener('change', switchTheme, false); - - - if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { - document.documentElement.setAttribute('data-theme', "dark"); - toggleSwitch.checked = true; - } else if (window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches) { - document.documentElement.setAttribute('data-theme', "light"); - toggleSwitch.checked = false; - } else { - const currentTheme = localStorage.getItem('theme') ? localStorage.getItem('theme') : null; - if (currentTheme) { - document.documentElement.setAttribute('data-theme', currentTheme); - - if (currentTheme === 'dark') { - toggleSwitch.checked = true; - } - } - } } @@ -74,13 +807,6 @@ function main() {

      types

      -
      - -     Dark Mode -
      From bab37e95275f8ea5702d46139cf33e6149dab860 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 23 Dec 2019 14:54:59 -0600 Subject: [PATCH 325/593] v0.4.3 --- nimterop.nimble | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimterop.nimble b/nimterop.nimble index 4b1089b..101966e 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -1,6 +1,6 @@ # Package -version = "0.4.2" +version = "0.4.3" author = "genotrance" description = "C/C++ interop for Nim" license = "MIT" From 1b25c4e6cabd820a86572a6bd4df8b295a1b5039 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 23 Dec 2019 14:57:15 -0600 Subject: [PATCH 326/593] Update documentation --- all.html | 2 +- build.html | 118 +++++++++++++++++++++++++++++++------------------- build.idx | 3 +- cimport.html | 6 ++- compat.html | 2 +- paths.html | 2 +- plugin.html | 2 +- theindex.html | 10 ++++- types.html | 2 +- 9 files changed, 92 insertions(+), 55 deletions(-) diff --git a/all.html b/all.html index 3724bee..fc0f0db 100644 --- a/all.html +++ b/all.html @@ -850,7 +850,7 @@ function main() {
      diff --git a/build.html b/build.html index 2446361..8859919 100644 --- a/build.html +++ b/build.html @@ -836,8 +836,11 @@ function main() { title="sanitizePath(path: string; noQuote = false; sep = $'/'): string">sanitizePath
    • sleep
    • -
    • execAction
    • +
    • getCurrentNimCompiler
    • +
    • execAction
    • findExe
    • - -
      proc execAction(cmd: string; retry = 0; nostderr = false): string {...}{.
      -    raises: [OSError, Exception, IOError, Defect],
      -    tags: [ExecIOEffect, ReadIOEffect, RootEffect].}
      + +
      proc getCurrentNimCompiler(): string {...}{.raises: [], tags: [].}
      +
      + + + +
      + +
      proc execAction(cmd: string; retry = 0; die = true; cache = false; cacheKey = ""): tuple[
      +    output: string, ret: int] {...}{.raises: [IOError, ValueError, OSError, Exception, Defect], tags: [
      +    ReadEnvEffect, ReadIOEffect, ReadDirEffect, WriteIOEffect, ExecIOEffect,
      +    RootEffect].}

      Execute an external command - supported at compile time

      -

      Checks if command exits successfully before returning. If not, an error is raised.

      +

      Checks if command exits successfully before returning. If not, an error is raised. Always caches results to be used in nimsuggest or nimcheck mode.

      +

      retry - number of times command should be retried before error die = false - return on errors cache = true - cache results unless cleared with -f cacheKey - key to create unique cache entry

      -
      proc findExe(exe: string): string {...}{.raises: [], tags: [].}
      +
      proc findExe(exe: string): string {...}{.raises: [IOError, ValueError, OSError, Exception,
      +                                        Defect], tags: [ReadEnvEffect,
      +    ReadIOEffect, ReadDirEffect, WriteIOEffect, ExecIOEffect, RootEffect].}
      Find the specified executable using the which/where command - supported at compile time
      -
      proc mkDir(dir: string) {...}{.raises: [OSError, Exception, IOError, Defect, ValueError], tags: [
      -    ReadDirEffect, ExecIOEffect, ReadIOEffect, RootEffect].}
      +
      proc mkDir(dir: string) {...}{.raises: [IOError, ValueError, OSError, Exception, Defect], tags: [
      +    ReadDirEffect, ReadEnvEffect, ReadIOEffect, WriteIOEffect, ExecIOEffect,
      +    RootEffect].}

      Create a directory at compile time

      @@ -970,33 +985,35 @@ Find the specified executable using the
      proc cpFile(source, dest: string; move = false) {...}{.
      -    raises: [OSError, Exception, IOError, Defect, ValueError],
      -    tags: [ExecIOEffect, ReadIOEffect, RootEffect].}
      + raises: [IOError, ValueError, OSError, Exception, Defect], tags: [ReadEnvEffect, + ReadIOEffect, ReadDirEffect, WriteIOEffect, ExecIOEffect, RootEffect].}
      Copy a file from source to dest at compile time
      -
      proc mvFile(source, dest: string) {...}{.raises: [OSError, Exception, IOError, Defect,
      -                                        ValueError],
      -                                tags: [ExecIOEffect, ReadIOEffect, RootEffect].}
      +
      proc mvFile(source, dest: string) {...}{.raises: [IOError, ValueError, OSError, Exception,
      +                                        Defect], tags: [ReadEnvEffect,
      +    ReadIOEffect, ReadDirEffect, WriteIOEffect, ExecIOEffect, RootEffect].}
      Move a file from source to dest at compile time
      -
      proc rmFile(source: string; dir = false) {...}{.raises: [OSError, Exception, IOError, Defect,
      -    ValueError], tags: [ReadDirEffect, ExecIOEffect, ReadIOEffect, RootEffect].}
      +
      proc rmFile(source: string; dir = false) {...}{.raises: [IOError, ValueError, OSError,
      +    Exception, Defect], tags: [ReadDirEffect, ReadEnvEffect, ReadIOEffect,
      +                            WriteIOEffect, ExecIOEffect, RootEffect].}
      Remove a file or pattern at compile time
      -
      proc rmDir(dir: string) {...}{.raises: [OSError, Exception, IOError, Defect, ValueError], tags: [
      -    ReadDirEffect, ExecIOEffect, ReadIOEffect, RootEffect].}
      +
      proc rmDir(dir: string) {...}{.raises: [IOError, ValueError, OSError, Exception, Defect], tags: [
      +    ReadDirEffect, ReadEnvEffect, ReadIOEffect, WriteIOEffect, ExecIOEffect,
      +    RootEffect].}
      Remove a directory or pattern at compile time @@ -1004,8 +1021,8 @@ Remove a directory or pattern at compile time
      proc getProjectCacheDir(name: string; forceClean = true): string {...}{.
      -    raises: [OSError, Exception, IOError, Defect, ValueError], tags: [ReadEnvEffect,
      -    ReadIOEffect, ReadDirEffect, ExecIOEffect, RootEffect].}
      + raises: [IOError, ValueError, OSError, Exception, Defect], tags: [ReadEnvEffect, + ReadIOEffect, ReadDirEffect, WriteIOEffect, ExecIOEffect, RootEffect].}

      Get a cache directory where all nimterop artifacts can be stored

      @@ -1022,24 +1039,27 @@ Remove a directory or pattern at compile time
      -
      proc extractZip(zipfile, outdir: string) {...}{.raises: [OSError, Exception, IOError, Defect,
      -    ValueError], tags: [ExecIOEffect, ReadIOEffect, RootEffect].}
      +
      proc extractZip(zipfile, outdir: string) {...}{.raises: [IOError, ValueError, OSError,
      +    Exception, Defect], tags: [ReadEnvEffect, ReadIOEffect, ReadDirEffect,
      +                            WriteIOEffect, ExecIOEffect, RootEffect].}
      Extract a zip file using powershell on Windows and unzip on other systems to the specified output directory
      -
      proc extractTar(tarfile, outdir: string) {...}{.raises: [ValueError, OSError, Exception,
      -    IOError, Defect], tags: [ExecIOEffect, ReadIOEffect, RootEffect, ReadDirEffect].}
      +
      proc extractTar(tarfile, outdir: string) {...}{.raises: [IOError, ValueError, OSError,
      +    Exception, Defect], tags: [ReadEnvEffect, ReadIOEffect, ReadDirEffect,
      +                            WriteIOEffect, ExecIOEffect, RootEffect].}
      Extract a tar file using tar, 7z or 7za to the specified output directory
      -
      proc downloadUrl(url, outdir: string) {...}{.raises: [OSError, Exception, IOError, Defect,
      -    ValueError], tags: [ReadDirEffect, ExecIOEffect, ReadIOEffect, RootEffect].}
      +
      proc downloadUrl(url, outdir: string) {...}{.raises: [IOError, ValueError, OSError,
      +    Exception, Defect], tags: [ReadDirEffect, ReadEnvEffect, ReadIOEffect,
      +                            WriteIOEffect, ExecIOEffect, RootEffect].}

      Download a file using curl or wget (or powershell on Windows) to the specified directory

      @@ -1048,16 +1068,18 @@ Extract a tar file using tar -
      proc gitReset(outdir: string) {...}{.raises: [ValueError, OSError, Exception, IOError, Defect],
      -                             tags: [ExecIOEffect, ReadIOEffect, RootEffect].}
      +
      proc gitReset(outdir: string) {...}{.raises: [ValueError, IOError, OSError, Exception, Defect], tags: [
      +    ReadEnvEffect, ReadIOEffect, ReadDirEffect, WriteIOEffect, ExecIOEffect,
      +    RootEffect].}
      Hard reset the git repository at the specified directory
      -
      proc gitCheckout(file, outdir: string) {...}{.raises: [ValueError, OSError, Exception,
      -    IOError, Defect], tags: [ExecIOEffect, ReadIOEffect, RootEffect].}
      +
      proc gitCheckout(file, outdir: string) {...}{.raises: [ValueError, IOError, OSError,
      +    Exception, Defect], tags: [ReadEnvEffect, ReadIOEffect, ReadDirEffect,
      +                            WriteIOEffect, ExecIOEffect, RootEffect].}

      Checkout the specified file in the git repository at outdir

      @@ -1067,8 +1089,8 @@ Hard reset the git repository at the specified directory
      proc gitPull(url: string; outdir = ""; plist = ""; checkout = "") {...}{.
      -    raises: [ValueError, OSError, Exception, IOError, Defect], tags: [ReadDirEffect,
      -    ExecIOEffect, ReadIOEffect, RootEffect, WriteIOEffect].}
      + raises: [ValueError, IOError, OSError, Exception, Defect], tags: [ReadDirEffect, + ReadEnvEffect, ReadIOEffect, WriteIOEffect, ExecIOEffect, RootEffect].}

      Pull the specified git repository to the output directory

      @@ -1079,7 +1101,8 @@ Hard reset the git repository at the specified directory
      proc findFile(file: string; dir: string; recurse = true; first = false; regex = false): string {...}{.
      -    raises: [ValueError], tags: [].}
      + raises: [ValueError, IOError, OSError, Exception, Defect], tags: [ReadEnvEffect, + ReadIOEffect, ReadDirEffect, WriteIOEffect, ExecIOEffect, RootEffect].}

      Find the file in the specified directory

      @@ -1104,7 +1127,8 @@ Hard reset the git repository at the specified directory
      proc linkLibs(names: openArray[string]; staticLink = true): string {...}{.
      -    raises: [ValueError], tags: [].}
      + raises: [ValueError, IOError, OSError, Exception, Defect], tags: [ReadEnvEffect, + ReadIOEffect, ReadDirEffect, WriteIOEffect, ExecIOEffect, RootEffect].}

      Create linker flags for specified libraries

      @@ -1114,8 +1138,8 @@ Hard reset the git repository at the specified directory
      proc configure(path, check: string; flags = "") {...}{.
      -    raises: [OSError, Exception, IOError, Defect, ValueError],
      -    tags: [ReadDirEffect, ExecIOEffect, ReadIOEffect, RootEffect].}
      + raises: [IOError, ValueError, OSError, Exception, Defect], tags: [ReadDirEffect, + ReadEnvEffect, ReadIOEffect, WriteIOEffect, ExecIOEffect, RootEffect].}

      Run the GNU configure command to generate all Makefiles or other build scripts in the specified path

      @@ -1172,8 +1196,9 @@ Set a cmake directive
      -
      proc cmake(path, check, flags: string) {...}{.raises: [OSError, Exception, IOError, Defect,
      -    ValueError], tags: [ReadDirEffect, ExecIOEffect, ReadIOEffect, RootEffect].}
      +
      proc cmake(path, check, flags: string) {...}{.raises: [IOError, ValueError, OSError,
      +    Exception, Defect], tags: [ReadDirEffect, ReadEnvEffect, ReadIOEffect,
      +                            WriteIOEffect, ExecIOEffect, RootEffect].}

      Run the cmake command to generate all Makefiles or other build scripts in the specified path

      @@ -1185,8 +1210,8 @@ Set a cmake directive
      proc make(path, check: string; flags = ""; regex = false) {...}{.
      -    raises: [ValueError, OSError, Exception, IOError, Defect],
      -    tags: [ExecIOEffect, ReadIOEffect, RootEffect].}
      + raises: [ValueError, IOError, OSError, Exception, Defect], tags: [ReadEnvEffect, + ReadIOEffect, ReadDirEffect, WriteIOEffect, ExecIOEffect, RootEffect].}

      Run the make command to build all binaries in the specified path

      @@ -1205,15 +1230,18 @@ Set a cmake directive
      -
      proc getGccPaths(mode = "c"): seq[string] {...}{.raises: [ValueError], tags: [ReadEnvEffect].}
      +
      proc getGccPaths(mode = "c"): seq[string] {...}{.raises: [IOError, ValueError, OSError,
      +    Exception, Defect], tags: [ReadEnvEffect, ReadIOEffect, ReadDirEffect,
      +                            WriteIOEffect, ExecIOEffect, RootEffect].}
      -
      proc getGccLibPaths(mode = "c"): seq[string] {...}{.raises: [ValueError],
      -    tags: [ReadEnvEffect].}
      +
      proc getGccLibPaths(mode = "c"): seq[string] {...}{.
      +    raises: [IOError, ValueError, OSError, Exception, Defect], tags: [ReadEnvEffect,
      +    ReadIOEffect, ReadDirEffect, WriteIOEffect, ExecIOEffect, RootEffect].}
      @@ -1288,7 +1316,7 @@ Check if -d:xxx is se
    • diff --git a/build.idx b/build.idx index 8b67066..dbed146 100644 --- a/build.idx +++ b/build.idx @@ -1,6 +1,7 @@ sanitizePath build.html#sanitizePath,string build: sanitizePath(path: string; noQuote = false; sep = $'/'): string sleep build.html#sleep,int build: sleep(milsecs: int) -execAction build.html#execAction,string,int build: execAction(cmd: string; retry = 0; nostderr = false): string +getCurrentNimCompiler build.html#getCurrentNimCompiler build: getCurrentNimCompiler(): string +execAction build.html#execAction,string,int,string build: execAction(cmd: string; retry = 0; die = true; cache = false; cacheKey = ""): tuple[\n output: string, ret: int] findExe build.html#findExe,string build: findExe(exe: string): string mkDir build.html#mkDir,string build: mkDir(dir: string) cpFile build.html#cpFile,string,string build: cpFile(source, dest: string; move = false) diff --git a/cimport.html b/cimport.html index cf968cd..bbb467a 100644 --- a/cimport.html +++ b/cimport.html @@ -948,7 +948,9 @@ Add directory dir to
    -
    proc cAddStdDir(mode = "c") {...}{.compileTime, raises: [ValueError], tags: [ReadEnvEffect].}
    +
    proc cAddStdDir(mode = "c") {...}{.compileTime, raises: [IOError, ValueError, OSError,
    +    Exception, Defect], tags: [ReadEnvEffect, ReadIOEffect, ReadDirEffect,
    +                            WriteIOEffect, ExecIOEffect, RootEffect].}
    Add the standard c [default] or cpp include paths to search path used in calls to cSearchPath() @@ -1102,7 +1104,7 @@ Add an include directory that is forwarded to the C/C++ preprocessor if called w diff --git a/compat.html b/compat.html index 31badcf..16d342c 100644 --- a/compat.html +++ b/compat.html @@ -859,7 +859,7 @@ function main() { diff --git a/paths.html b/paths.html index 6f7f98c..d6558a0 100644 --- a/paths.html +++ b/paths.html @@ -917,7 +917,7 @@ function main() { diff --git a/plugin.html b/plugin.html index ed37afd..9b3a724 100644 --- a/plugin.html +++ b/plugin.html @@ -927,7 +927,7 @@ function main() { diff --git a/theindex.html b/theindex.html index e37add3..fd650e2 100644 --- a/theindex.html +++ b/theindex.html @@ -900,7 +900,9 @@ function main() {
execAction:
  • build: execAction(cmd: string; retry = 0; nostderr = false): string
  • + data-doc-search-tag="build: execAction(cmd: string; retry = 0; die = true; cache = false; cacheKey = ""): tuple[ + output: string, ret: int]" href="build.html#execAction%2Cstring%2Cint%2Cstring">build: execAction(cmd: string; retry = 0; die = true; cache = false; cacheKey = ""): tuple[ + output: string, ret: int]
extractTar:
+
getCurrentNimCompiler:
getGccLibPaths:
  • build: getGccLibPaths(mode = "c"): seq[string]
  • @@ -1077,7 +1083,7 @@ function main() { diff --git a/types.html b/types.html index 06628f3..39dc132 100644 --- a/types.html +++ b/types.html @@ -924,7 +924,7 @@ function main() { From 972297c50957000c693a40ed9f0846ee3f79ca81 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 23 Dec 2019 16:50:39 -0600 Subject: [PATCH 327/593] Restrict to OSX --- tests/tnimterop_c.nim | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/tnimterop_c.nim b/tests/tnimterop_c.nim index 319c766..c577c5d 100644 --- a/tests/tnimterop_c.nim +++ b/tests/tnimterop_c.nim @@ -96,7 +96,7 @@ s3.field1 = 7 s4.field2[2] = 5 # note: simplify with `defined(c)` for nim >= 0.19.9 -when defined(cpp): +when defined(cpp) and defined(OSX): discard else: s4.field3[3] = enum1 @@ -125,7 +125,7 @@ check test_call_int() == 5 check test_call_param(5).field1 == 5 check test_call_param2(5, s2).field1 == 11 check test_call_param3(5, s1).field1 == 10 -when defined(cpp): +when defined(cpp) and defined(OSX): # error: assigning to 'enum ENUM' from incompatible type 'NI' (aka 'long long') discard else: @@ -135,7 +135,7 @@ check test_call_param6(u2) == 'c' u.field1 = 4 check test_call_param7(u) == 4 -when defined(cpp): +when defined(cpp) and defined(OSX): # note: candidate function not viable: no known conversion from 'NI *' (aka 'long long *') to 'int *' for 1st argument # check test_call_param8(cast[ptr int](addr i)) == 25.0 discard From 359bc6e38a90696fe40b9265c62549af8200861d Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 14 Jan 2020 14:23:05 -0600 Subject: [PATCH 328/593] Fix stdout reopen issue --- nimterop/ast.nim | 26 +++++++++++----------- nimterop/build.nim | 4 ++-- nimterop/globals.nim | 13 +++++++++++ nimterop/grammar.nim | 4 ++-- nimterop/toast.nim | 52 +++++++++++++++----------------------------- 5 files changed, 48 insertions(+), 51 deletions(-) diff --git a/nimterop/ast.nim b/nimterop/ast.nim index fcd9411..8ffb850 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -83,7 +83,7 @@ proc searchAstForNode(ast: ref Ast, node: TSNode, nimState: NimState): bool = if nimState.gState.debug: nimState.nodeBranch.add $node.tsNodeType() - echo "#" & spaces(nimState.nodeBranch.len * 2) & nimState.nodeBranch[^1] + necho "#" & spaces(nimState.nodeBranch.len * 2) & nimState.nodeBranch[^1] if ast.children.nBl: if childNames.contains(ast.regex) or @@ -111,14 +111,14 @@ proc searchAstForNode(ast: ref Ast, node: TSNode, nimState: NimState): bool = result = node.saveNodeData(nimState) else: if nimState.gState.debug: - echo "#" & spaces(nimState.nodeBranch.len * 2) & &" {ast.getRegexForAstChildren()} !=~ {childNames}" + necho "#" & spaces(nimState.nodeBranch.len * 2) & &" {ast.getRegexForAstChildren()} !=~ {childNames}" elif node.getTSNodeNamedChildCountSansComments() == 0: result = node.saveNodeData(nimState) if nimState.gState.debug: discard nimState.nodeBranch.pop() if nimstate.nodeBranch.Bl: - echo "" + necho "" proc searchAst(root: TSNode, astTable: AstTable, nimState: NimState) = var @@ -133,7 +133,7 @@ proc searchAst(root: TSNode, astTable: AstTable, nimState: NimState) = if name in astTable: for ast in astTable[name]: if nimState.gState.debug: - echo "\n# " & nimState.getNodeVal(node).replace("\n", "\n# ") & "\n" + necho "\n# " & nimState.getNodeVal(node).replace("\n", "\n# ") & "\n" if searchAstForNode(ast, node, nimState): ast.tonim(ast, node, nimState) if nimState.gState.debug: @@ -166,8 +166,8 @@ proc searchAst(root: TSNode, astTable: AstTable, nimState: NimState) = if node == root: break -proc printNimHeader*() = - echo """# Generated at $1 +proc printNimHeader*(gState: State) = + gecho """# Generated at $1 # Command line: # $2 $3 @@ -194,32 +194,32 @@ proc printNim*(gState: State, fullpath: string, root: TSNode, astTable: AstTable root.searchAst(astTable, nimState) if nimState.enumStr.nBl: - echo &"{nimState.enumStr}\n" + necho &"{nimState.enumStr}\n" nimState.constStr = nimState.getOverrideFinal(nskConst) & nimState.constStr if nimState.constStr.nBl: - echo &"const{nimState.constStr}\n" + necho &"const{nimState.constStr}\n" - echo &""" + necho &""" {{.pragma: {nimState.impShort}, importc{nimState.getHeader()}.}} {{.pragma: {nimState.impShort}C, {nimState.impShort}, cdecl{nimState.getDynlib()}.}} """ nimState.typeStr = nimState.getOverrideFinal(nskType) & nimState.typeStr if nimState.typeStr.nBl: - echo &"type{nimState.typeStr}\n" + necho &"type{nimState.typeStr}\n" nimState.procStr = nimState.getOverrideFinal(nskProc) & nimState.procStr if nimState.procStr.nBl: - echo &"{nimState.procStr}\n" + necho &"{nimState.procStr}\n" if nimState.gState.debug: if nimState.debugStr.nBl: - echo nimState.debugStr + necho nimState.debugStr if nimState.skipStr.nBl: let hash = nimState.skipStr.hash().abs() sname = getTempDir() / &"nimterop_{$hash}.h" - echo &"# Writing skipped definitions to {sname}\n" + necho &"# Writing skipped definitions to {sname}\n" writeFile(sname, nimState.skipStr) diff --git a/nimterop/build.nim b/nimterop/build.nim index 6ac21e9..4b061cc 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -462,7 +462,7 @@ proc configure*(path, check: string, flags = "") = echo "# Running autogen.sh" echo execAction( - &"cd {(path / i).parentDir().sanitizePath} && bash autogen.sh").output + &"cd {(path / i).parentDir().sanitizePath} && bash ./autogen.sh").output break @@ -479,7 +479,7 @@ proc configure*(path, check: string, flags = "") = echo "# Running configure " & flags var - cmd = &"cd {path.sanitizePath} && bash configure" + cmd = &"cd {path.sanitizePath} && bash ./configure" if flags.len != 0: cmd &= &" {flags}" diff --git a/nimterop/globals.nim b/nimterop/globals.nim index 7c512b1..a868460 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -62,6 +62,8 @@ type onSymbol*, onSymbolOverride*: OnSymbol onSymbolOverrideFinal*: OnSymbolOverrideFinal + outputHandle*: File + NimState {.used.} = ref object identifiers*: TableRef[string, string] @@ -94,3 +96,14 @@ const modeDefault {.used.} = $cpp # TODO: USE this everywhere relevant when not declared(CIMPORT): export gAtoms, gExpressions, gEnumVals, Kind, Ast, AstTable, State, NimState, nBl, Bl, CompileMode, modeDefault + + # Redirect output to file when required + template gecho*(args: string) {.dirty.} = + if gState.outputHandle.isNil: + echo args + else: + gState.outputHandle.writeLine(args) + + template necho*(args: string) {.dirty.} = + let gState = nimState.gState + gecho args diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index 9f50ba4..ba0e9fc 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -735,7 +735,7 @@ proc parseGrammar*(): AstTable = else: result[n].add(ast) -proc printGrammar*(astTable: AstTable) = +proc printGrammar*(gState: State, astTable: AstTable) = for name in astTable.keys(): for ast in astTable[name]: - echo ast.printAst() + gecho ast.printAst() diff --git a/nimterop/toast.nim b/nimterop/toast.nim index c26b460..76604f1 100644 --- a/nimterop/toast.nim +++ b/nimterop/toast.nim @@ -22,12 +22,12 @@ proc printLisp(gState: State, root: TSNode) = if node.tsNodeNamedChildCount() != 0: if gState.pretty: - echo "" + gecho "" nextnode = node.tsNodeNamedChild(0) depth += 1 else: if gState.pretty: - echo ")" + gecho ")" else: stdout.write ")" nextnode = node.tsNodeNextNamedSibling() @@ -39,7 +39,7 @@ proc printLisp(gState: State, root: TSNode) = if depth == -1: break if gState.pretty: - echo spaces(depth) & ")" + gecho spaces(depth) & ")" else: stdout.write ")" if node == root: @@ -95,7 +95,7 @@ proc process(gState: State, path: string, astTable: AstTable) = elif gState.pnim: gState.printNim(path, root, astTable) elif gState.preprocess: - echo gState.code + gecho gState.code # CLI processing with default values proc main( @@ -149,32 +149,23 @@ proc main( if pluginSourcePath.nBl: gState.loadPlugin(pluginSourcePath) - # Backup stdout var outputFile = output - outputHandle: File - stdoutBackup = stdout check = check or stub - # Fix output file extention - if outputFile.len != 0: + # Fix output file extention for Nim mode + if outputFile.len != 0 and pnim: if outputFile.splitFile().ext != ".nim": outputFile = outputFile & ".nim" # Check needs a file if check and outputFile.len == 0: outputFile = getTempDir() / "toast_" & ($getTime().toUnix()).addFileExt("nim") - when defined(windows): - # https://github.com/nim-lang/Nim/issues/12939 - echo &"Cannot print wrapper with check on Windows, review {outputFile}\n" # Redirect output to file if outputFile.len != 0: - when defined(windows): - doAssert stdout.reopen(outputFile, fmWrite), &"Failed to write to {outputFile}" - else: - doAssert outputHandle.open(outputFile, fmWrite), &"Failed to write to {outputFile}" - stdout = outputHandle + doAssert gState.outputHandle.open(outputFile, fmWrite), + &"Failed to write to {outputFile}" # Process grammar into AST let @@ -182,17 +173,17 @@ proc main( if pgrammar: # Print AST of grammar - astTable.printGrammar() + gState.printGrammar(astTable) elif source.nBl: # Print source after preprocess or Nim output if gState.pnim: - printNimHeader() + gState.printNimHeader() for src in source: gState.process(src.expandSymlinkAbs(), astTable) - when not defined(windows): - # Restore stdout - stdout = stdoutBackup + # Close outputFile + if outputFile.len != 0: + gState.outputHandle.close() # Check Nim output if gState.pnim and check: @@ -202,12 +193,6 @@ proc main( if err != 0: # Failed check so try stubbing if stub: - # Close output file to prepend stubs - when not defined(windows): - outputHandle.close() - else: - stdout.close() - # Find undeclared identifiers in error var data = "" @@ -234,14 +219,13 @@ proc main( # Rerun nim check on stubbed wrapper (check, err) = execCmdEx(&"{gState.nim} check {outputFile}") - doAssert err == 0, "# Nim check with stub failed:\n\n" & check + doAssert err == 0, data & "# Nim check with stub failed:\n\n" & check else: - doAssert err == 0, "# Nim check failed:\n\n" & check + doAssert err == 0, outputFile.readFile() & "# Nim check failed:\n\n" & check - when not defined(windows): - # Print wrapper if temporarily redirected to file - if check and output.len == 0: - stdout.write outputFile.readFile() + # Print wrapper if temporarily redirected to file + if check and output.len == 0: + stdout.write outputFile.readFile() when isMainModule: # Setup cligen command line help and short flags From 9df8dabf5c0218cf065faa12096065ef4dc6715a Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 14 Jan 2020 21:59:12 -0600 Subject: [PATCH 329/593] Update requires --- nimterop.nimble | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimterop.nimble b/nimterop.nimble index 101966e..2e3bef1 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -12,7 +12,7 @@ installDirs = @["nimterop"] installFiles = @["config.nims"] # Dependencies -requires "nim >= 0.19.2", "regex >= 0.10.0", "cligen >= 0.9.17" +requires "nim >= 0.19.6", "regex >= 0.13.0", "cligen >= 0.9.41" import nimterop/docs From b863b1d170f6d442c93eb0774f4a66a2a1f2ba4b Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 14 Jan 2020 22:53:14 -0600 Subject: [PATCH 330/593] v0.4.4 --- nimterop.nimble | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimterop.nimble b/nimterop.nimble index 2e3bef1..3b6b7c1 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -1,6 +1,6 @@ # Package -version = "0.4.3" +version = "0.4.4" author = "genotrance" description = "C/C++ interop for Nim" license = "MIT" From 6130c04bd8b239c31398af7b79e068abfdbd43f3 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Thu, 16 Jan 2020 07:18:27 -0800 Subject: [PATCH 331/593] fix deprecations (#166) --- .travis.yml | 2 -- appveyor.yml | 1 - nimterop/getters.nim | 2 +- nimterop/globals.nim | 4 ++-- nimterop/plugin.nim | 16 ++++++++-------- 5 files changed, 11 insertions(+), 14 deletions(-) diff --git a/.travis.yml b/.travis.yml index 86e5fbc..359d07b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,14 +10,12 @@ addons: language: c env: - - BRANCH=0.19.6 - BRANCH=0.20.2 - BRANCH=1.0.4 - BRANCH=devel cache: directories: - - "$HOME/.choosenim/toolchains/nim-0.19.6" - "$HOME/.choosenim/toolchains/nim-0.20.2" - "$HOME/.choosenim/toolchains/nim-1.0.4" diff --git a/appveyor.yml b/appveyor.yml index 7678cf1..5651948 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -9,7 +9,6 @@ matrix: environment: matrix: - - NIM_VERSION: 0.19.6 - NIM_VERSION: 0.20.2 - NIM_VERSION: 1.0.4 diff --git a/nimterop/getters.nim b/nimterop/getters.nim index ef647e6..885ce2f 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -24,7 +24,7 @@ using var when while xor -yield""".split(Whitespace).toSet() +yield""".split(Whitespace).toHashSet() const gTypeMap* = { # char diff --git a/nimterop/globals.nim b/nimterop/globals.nim index a868460..52343de 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -17,7 +17,7 @@ const "primitive_type", "sized_type_specifier", "type_identifier" - ].toSet() + ].toHashSet() gExpressions {.used.} = @[ "parenthesized_expression", @@ -25,7 +25,7 @@ const "shift_expression", "math_expression", "escape_sequence" - ].toSet() + ].toHashSet() gEnumVals {.used.} = @[ "identifier", diff --git a/nimterop/plugin.nim b/nimterop/plugin.nim index 3769142..20d7b78 100644 --- a/nimterop/plugin.nim +++ b/nimterop/plugin.nim @@ -6,17 +6,17 @@ type parent*: string kind*: NimSymKind override*: string - + StringHash = HashSet[string] OnSymbol* = proc(sym: var Symbol) {.cdecl.} - OnSymbolOverrideFinal* = proc(typ: string): HashSet[string] {.cdecl.} + OnSymbolOverrideFinal* = proc(typ: string): StringHash {.cdecl.} var - cOverrides*: Table[string, HashSet[string]] + cOverrides*: Table[string, StringHash] -cOverrides = initTable[string, HashSet[string]]() -cOverrides["nskType"] = initSet[string]() -cOverrides["nskConst"] = initSet[string]() -cOverrides["nskProc"] = initSet[string]() +cOverrides = initTable[string, StringHash]() +cOverrides["nskType"] = StringHash() +cOverrides["nskConst"] = StringHash() +cOverrides["nskProc"] = StringHash() -proc onSymbolOverrideFinal*(typ: string): HashSet[string] {.exportc, dynlib.} = +proc onSymbolOverrideFinal*(typ: string): StringHash {.exportc, dynlib.} = result = cOverrides[typ] From 1b63a125c527668b2e75080b62435d0b888d457f Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 9 Mar 2020 21:20:24 -0500 Subject: [PATCH 332/593] Add feature flag capability --- config.nims | 9 ++++++++- nimterop.nimble | 2 +- nimterop/globals.nim | 15 +++++++++------ nimterop/toast.nim | 4 ++++ 4 files changed, 22 insertions(+), 8 deletions(-) diff --git a/config.nims b/config.nims index 54a9a06..7e7a6e1 100644 --- a/config.nims +++ b/config.nims @@ -9,4 +9,11 @@ when defined(Windows): switch("gc", "markAndSweep") # Retain stackTrace for clear errors -switch("stackTrace", "on") \ No newline at end of file +switch("stackTrace", "on") + +# Path to compiler +switch("path", "$nim") + +# Case objects +when not defined(danger): + switch("define", "nimOldCaseObjects") \ No newline at end of file diff --git a/nimterop.nimble b/nimterop.nimble index 3b6b7c1..37637f5 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -25,7 +25,7 @@ proc execTest(test: string) = execCmd "nim cpp -r " & test task buildToast, "build toast": - execCmd("nim c -f -d:danger nimterop/toast.nim") + execCmd("nim c -f nimterop/toast.nim") task bt, "build toast": execCmd("nim c -d:danger nimterop/toast.nim") diff --git a/nimterop/globals.nim b/nimterop/globals.nim index 52343de..9ee9de1 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -59,6 +59,8 @@ type code*, dynlib*, mode*, nim*, overrides*, pluginSource*, pluginSourcePath*: string + feature*: seq[Feature] + onSymbol*, onSymbolOverride*: OnSymbol onSymbolOverrideFinal*: OnSymbolOverrideFinal @@ -77,6 +79,12 @@ type nodeBranch*: seq[string] + CompileMode = enum + c, cpp + + Feature* = enum + ast2 + var gStateCT {.compiletime, used.} = new(State) @@ -86,12 +94,7 @@ template nBl(s: typed): untyped {.used.} = template Bl(s: typed): untyped {.used.} = (s.len == 0) -type CompileMode = enum - c, - cpp, - -# TODO: can cligen accept enum instead of string? -const modeDefault {.used.} = $cpp # TODO: USE this everywhere relevant +const modeDefault {.used.} = $cpp when not declared(CIMPORT): export gAtoms, gExpressions, gEnumVals, Kind, Ast, AstTable, State, NimState, diff --git a/nimterop/toast.nim b/nimterop/toast.nim index 76604f1..40cc704 100644 --- a/nimterop/toast.nim +++ b/nimterop/toast.nim @@ -103,6 +103,7 @@ proc main( debug = false, defines: seq[string] = @[], dynlib: string = "", + feature: seq[Feature] = @[], includeDirs: seq[string] = @[], mode = modeDefault, nim: string = "nim", @@ -126,6 +127,7 @@ proc main( debug: debug, defines: defines, dynlib: dynlib, + feature: feature, includeDirs: includeDirs, mode: mode, nim: nim, @@ -235,6 +237,7 @@ when isMainModule: "debug": "enable debug output", "defines": "definitions to pass to preprocessor", "dynlib": "Import symbols from library in specified Nim string", + "feature": "flags to enable experimental features", "includeDirs": "include directory to pass to preprocessor", "mode": "language parser: c or cpp", "nim": "use a particular Nim executable (default: $PATH/nim)", @@ -256,6 +259,7 @@ when isMainModule: "debug": 'd', "defines": 'D', "dynlib": 'l', + "feature": 'f', "includeDirs": 'I', "nocomments": 'c', "output": 'o', From da9a1c983b02a0829e5054e23aab99ceacd6c79c Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 9 Mar 2020 23:12:11 -0500 Subject: [PATCH 333/593] Drop 0.19.6, fix soloud test --- .travis.yml | 4 ++-- appveyor.yml | 2 +- nimterop.nimble | 2 +- nimterop/all.nim | 2 +- nimterop/build.nim | 8 +++----- nimterop/cimport.nim | 2 +- nimterop/docs.nim | 28 ++++++++++++---------------- nimterop/getters.nim | 4 ++-- nimterop/toast.nim | 2 +- nimterop/types.nim | 25 ++++--------------------- tests/tsoloud.nim | 2 +- 11 files changed, 29 insertions(+), 52 deletions(-) diff --git a/.travis.yml b/.travis.yml index 359d07b..d16b9fc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,13 +11,13 @@ language: c env: - BRANCH=0.20.2 - - BRANCH=1.0.4 + - BRANCH=1.0.6 - BRANCH=devel cache: directories: - "$HOME/.choosenim/toolchains/nim-0.20.2" - - "$HOME/.choosenim/toolchains/nim-1.0.4" + - "$HOME/.choosenim/toolchains/nim-1.0.6" install: - export CHOOSENIM_CHOOSE_VERSION=$BRANCH diff --git a/appveyor.yml b/appveyor.yml index 5651948..5275844 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -10,7 +10,7 @@ matrix: environment: matrix: - NIM_VERSION: 0.20.2 - - NIM_VERSION: 1.0.4 + - NIM_VERSION: 1.0.6 for: - diff --git a/nimterop.nimble b/nimterop.nimble index 37637f5..24bbb4f 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -12,7 +12,7 @@ installDirs = @["nimterop"] installFiles = @["config.nims"] # Dependencies -requires "nim >= 0.19.6", "regex >= 0.13.0", "cligen >= 0.9.41" +requires "nim >= 0.20.2", "regex >= 0.13.1", "cligen >= 0.9.43" import nimterop/docs diff --git a/nimterop/all.nim b/nimterop/all.nim index c024d01..dc22967 100644 --- a/nimterop/all.nim +++ b/nimterop/all.nim @@ -4,4 +4,4 @@ Module that should import everything so that `nim doc --project nimtero/all` run # TODO: make sure it does import everything. -import "."/[cimport, build, types, plugin, compat] +import "."/[cimport, build, types, plugin] diff --git a/nimterop/build.nim b/nimterop/build.nim index 4b061cc..7939afa 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -2,8 +2,6 @@ import hashes, macros, osproc, sets, strformat, strutils, tables import os except findExe, sleep -import "."/[compat] - proc sanitizePath*(path: string, noQuote = false, sep = $DirSep): string = result = path.multiReplace([("\\\\", sep), ("\\", sep), ("/", sep)]) if not noQuote: @@ -648,7 +646,7 @@ proc getGccPaths*(mode = "c"): seq[string] = break if inc: var - path = line.strip().myNormalizedPath() + path = line.strip().normalizedPath() if path notin result: result.add path @@ -667,13 +665,13 @@ proc getGccLibPaths*(mode = "c"): seq[string] = if "LIBRARY_PATH=" in line: for path in line[13 .. ^1].split(PathSep): var - path = path.strip().myNormalizedPath() + path = path.strip().normalizedPath() if path notin result: result.add path break elif '\t' in line: var - path = line.strip().myNormalizedPath() + path = line.strip().normalizedPath() if path notin result: result.add path diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index 4c63c31..84f7b4f 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -21,7 +21,7 @@ const CIMPORT {.used.} = 1 include "."/globals -import "."/[build, compat, paths, types] +import "."/[build, paths, types] export types proc interpPath(dir: string): string= diff --git a/nimterop/docs.nim b/nimterop/docs.nim index 17089ec..a194086 100644 --- a/nimterop/docs.nim +++ b/nimterop/docs.nim @@ -1,22 +1,18 @@ import macros, strformat -when (NimMajor, NimMinor, NimPatch) >= (0, 19, 9): - from os import parentDir, getCurrentCompilerExe, DirSep - proc getNimRootDir(): string = - #[ - hack, but works - alternatively (but more complex), use (from a nim file, not nims otherwise - you get Error: ambiguous call; both system.fileExists): - import "$nim/testament/lib/stdtest/specialpaths.nim" - nimRootDir - ]# - fmt"{currentSourcePath}".parentDir.parentDir.parentDir -else: - proc getCurrentCompilerExe*(): string = - "nim" +from os import parentDir, getCurrentCompilerExe, DirSep +proc getNimRootDir(): string = + #[ + hack, but works + alternatively (but more complex), use (from a nim file, not nims otherwise + you get Error: ambiguous call; both system.fileExists): + import "$nim/testament/lib/stdtest/specialpaths.nim" + nimRootDir + ]# + fmt"{currentSourcePath}".parentDir.parentDir.parentDir - const - DirSep = when defined(windows): '\\' else: '/' +const + DirSep = when defined(windows): '\\' else: '/' proc execAction(cmd: string): string = var diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 885ce2f..3d77e99 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -2,7 +2,7 @@ import dynlib, macros, os, sequtils, sets, strformat, strutils, tables, times import regex -import "."/[build, compat, globals, plugin, treesitter/api] +import "."/[build, globals, plugin, treesitter/api] const gReserved = """ addr and as asm @@ -505,6 +505,6 @@ proc loadPlugin*(gState: State, sourcePath: string) = proc expandSymlinkAbs*(path: string): string = try: - result = path.expandSymlink().absolutePath(path.parentDir()).myNormalizedPath() + result = path.expandSymlink().absolutePath(path.parentDir()).normalizedPath() except: result = path diff --git a/nimterop/toast.nim b/nimterop/toast.nim index 40cc704..7dda1dc 100644 --- a/nimterop/toast.nim +++ b/nimterop/toast.nim @@ -2,7 +2,7 @@ import os, osproc, strformat, strutils, times import "."/treesitter/[api, c, cpp] -import "."/[ast, compat, globals, getters, grammar] +import "."/[ast, globals, getters, grammar] proc printLisp(gState: State, root: TSNode) = var diff --git a/nimterop/types.nim b/nimterop/types.nim index a57252f..5209e7a 100644 --- a/nimterop/types.nim +++ b/nimterop/types.nim @@ -1,26 +1,9 @@ # see https://github.com/nimterop/nimterop/issues/79 -when (NimMajor, NimMinor, NimPatch) < (0, 19, 9): - # clean this up once upgraded; adapted from std/time_t - when defined(nimdoc): - type - impl = distinct int64 - Time = impl - elif defined(windows): - when defined(i386) and defined(gcc): - type Time {.importc: "time_t", header: "".} = distinct int32 - else: - type Time {.importc: "time_t", header: "".} = distinct int64 - elif defined(posix): - import posix - type - time_t* = Time - time64_t* = Time -else: - import std/time_t as time_t_temp - type - time_t* = time_t_temp.Time - time64_t* = time_t_temp.Time +import std/time_t as time_t_temp +type + time_t* = time_t_temp.Time + time64_t* = time_t_temp.Time when defined(cpp): # http://www.cplusplus.com/reference/cwchar/wchar_t/ diff --git a/tests/tsoloud.nim b/tests/tsoloud.nim index 9281236..90cf82d 100644 --- a/tests/tsoloud.nim +++ b/tests/tsoloud.nim @@ -39,7 +39,7 @@ else: cCompile(src/"c_api/soloud_c.cpp") cCompile(src/"core/*.cpp") -cCompile(src/"audiosource", "cpp") +cCompile(src/"audiosource", "cpp", exclude="ay/") cCompile(src/"audiosource", "c") cCompile(src/"filter/*.cpp") From a7aa69f71df6cacf6b4923c1f16c4a0aa8c47d7b Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 10 Mar 2020 14:12:18 -0500 Subject: [PATCH 334/593] Merge newalgo branch ast2 functionality --- nimterop.nimble | 2 + nimterop/ast.nim | 12 +- nimterop/ast2.nim | 895 ++++++++++++++++++++++++++++++++++++++++++ nimterop/compat.nim | 34 -- nimterop/getters.nim | 301 ++++++++++++-- nimterop/globals.nim | 17 +- nimterop/grammar.nim | 24 ++ nimterop/toast.nim | 62 +-- tests/include/tast2.h | 42 ++ tests/tast2.nim | 71 ++++ 10 files changed, 1320 insertions(+), 140 deletions(-) create mode 100644 nimterop/ast2.nim delete mode 100644 nimterop/compat.nim create mode 100644 tests/include/tast2.h create mode 100644 tests/tast2.nim diff --git a/nimterop.nimble b/nimterop.nimble index 24bbb4f..c33e78b 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -36,6 +36,8 @@ task docs, "Generate docs": task test, "Test": buildToastTask() + execTest "tests/tast2.nim" + execTest "tests/tnimterop_c.nim" execCmd "nim cpp -f -r tests/tnimterop_cpp.nim" execCmd "./nimterop/toast -pnk -E=_ tests/include/toast.h" diff --git a/nimterop/ast.nim b/nimterop/ast.nim index 8ffb850..a61e65a 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -1,4 +1,4 @@ -import hashes, macros, os, sets, strformat, strutils, tables, times +import hashes, macros, os, sets, strformat, strutils, tables import regex @@ -166,16 +166,6 @@ proc searchAst(root: TSNode, astTable: AstTable, nimState: NimState) = if node == root: break -proc printNimHeader*(gState: State) = - gecho """# Generated at $1 -# Command line: -# $2 $3 - -{.hint[ConvFromXtoItselfNotNeeded]: off.} - -import nimterop/types -""" % [$now(), getAppFilename(), commandLineParams().join(" ")] - proc printNim*(gState: State, fullpath: string, root: TSNode, astTable: AstTable) = var nimState = new(NimState) diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim new file mode 100644 index 0000000..697262f --- /dev/null +++ b/nimterop/ast2.nim @@ -0,0 +1,895 @@ +import macros, os, sets, strutils, tables, times + +import regex + +import compiler/[ast, idents, options, renderer] + +import "."/treesitter/api + +import "."/[globals, getters] + +# Move to getters after ast2 becomes default + +proc getPtrType*(str: string): string = + result = case str: + of "cchar": + "cstring" + of "object": + "pointer" + else: + str + +proc getLit*(str: string): PNode = + # Used to convert #define literals into const + let + str = str.replace(re"/[/*].*?(?:\*/)?$", "").strip() + + if str.contains(re"^[\-]?[\d]+$"): # decimal + result = newIntNode(nkIntLit, parseInt(str)) + + elif str.contains(re"^[\-]?[\d]*[.]?[\d]+$"): # float + result = newFloatNode(nkFloatLit, parseFloat(str)) + + # TODO - hex becomes int on render + elif str.contains(re"^0x[\da-fA-F]+$"): # hexadecimal + result = newIntNode(nkIntLit, parseHexInt(str)) + + elif str.contains(re"^'[[:ascii:]]'$"): # char + result = newNode(nkCharLit) + result.intVal = str[1].int64 + + elif str.contains(re"""^"[[:ascii:]]+"$"""): # char * + result = newStrNode(nkStrLit, str[1 .. ^2]) + + else: + result = newNode(nkNilLit) + +proc addConst(nimState: NimState, node: TSNode) = + # #define X Y + # + # (preproc_def + # (identifier) + # (preproc_arg) + # ) + decho("addConst()") + nimState.printDebug(node) + + if node[0].getName() == "identifier" and + node[1].getName() == "preproc_arg": + let + constDef = newNode(nkConstDef) + + # node[0] = identifier = const name + (name, info) = nimState.getNameInfo(node.getAtom(), nskConst) + # TODO - check blank and override + ident = nimState.getIdent(name, info) + + # node[1] = preproc_arg = value + val = nimState.getNodeVal(node[1]).getLit() + + # If supported literal + if val.kind != nkNilLit: + # const X* = Y + # + # nkConstDef( + # nkPostfix( + # nkIdent("*"), + # nkIdent("X") + # ), + # nkEmpty(), + # nkXLit(Y) + # ) + constDef.add ident + constDef.add newNode(nkEmpty) + constDef.add val + + # nkConstSection.add + nimState.constSection.add constDef + + nimState.printDebug(constDef) + +proc newTypeIdent(nimState: NimState, node: TSNode, override = ""): PNode = + # Create nkTypeDef PNode with first ident + # + # If `override`, use it instead of node.getAtom() for name + let + (name, info) = nimState.getNameInfo(node.getAtom(), nskType) + # TODO - check blank and override + ident = + if override.len != 0: + nimState.getIdent(override, info) + else: + nimState.getIdent(name, info) + + # type name* = + # + # nkTypeDef( + # nkPostfix( + # nkIdent("*"), + # nkIdent(name) + # ), + # nkEmpty() + # ) + result = newNode(nkTypeDef) + result.add ident + result.add newNode(nkEmpty) + +proc newPtrTree(nimState: NimState, count: int, typ: PNode): PNode = + # Create nkPtrTy tree depending on count + # + # Reduce by 1 if Nim type available for ptr X - e.g. ptr cchar = cstring + var + count = count + chng = false + if typ.kind == nkIdent: + let + tname = typ.ident.s + ptname = getPtrType(tname) + if tname != ptname: + # If Nim type available, use that ident + result = nimState.getIdent(ptname, typ.info, exported = false) + chng = true + # One ptr reduced + count -= 1 + if count > 0: + # Nested nkPtrTy(typ) depending on count + # + # [ptr ...] typ + # + # nkPtrTy( + # nkPtrTy( + # typ + # ) + # ) + result = newNode(nkPtrTy) + var + parent = result + child: PNode + for i in 1 ..< count: + child = newNode(nkPtrTy) + parent.add child + parent = child + parent.add typ + elif not chng: + # Either no ptr, or none left after Nim type adjustment + result = typ + +proc newArrayTree(nimState: NimState, node: TSNode, typ, size: PNode): PNode = + # Create nkBracketExpr tree depending on input + let + (_, info) = nimState.getNameInfo(node, nskType) + ident = nimState.getIdent("array", info, exported = false) + + # array[size, typ] + # + # nkBracketExpr( + # nkIdent("array"), + # size, + # typ + # ) + result = newNode(nkBracketExpr) + result.add ident + result.add size + result.add typ + +proc getTypeArray(nimState: NimState, node: TSNode): PNode +proc getTypeProc(nimState: NimState, name: string, node: TSNode): PNode + +proc newIdentDefs(nimState: NimState, name: string, node: TSNode, offset: SomeInteger, exported = false): PNode = + # Create nkIdentDefs tree for specified proc parameter or object field + # + # For proc, param should not be exported + # + # pname: [ptr ..] typ + # + # nkIdentDefs( + # nkIdent(pname), + # typ, + # nkEmpty() + # ) + # + # For object, field should be exported + # + # pname*: [ptr ..] typ + # + # nkIdentDefs( + # nkPostfix( + # nkIdent("*"), + # nkIdent(pname) + # ), + # typ, + # nkEmpty() + # ) + result = newNode(nkIdentDefs) + + let + start = getStartAtom(node) + + # node[start] - param type + (tname, tinfo) = nimState.getNameInfo(node[start], nskType) + tident = nimState.getIdent(tname, tinfo, exported = false) + + if start == node.len - 1: + # Only for proc with no named param - create a param name based on offset + # + # int func(char, int); + let + pname = "a" & $(offset+1) + pident = nimState.getIdent(pname, tinfo, exported) + result.add pident + result.add tident + result.add newNode(nkEmpty) + else: + let + fdecl = node[start+1].anyChildInTree("function_declarator") + adecl = node[start+1].anyChildInTree("array_declarator") + abst = node[start+1].getName() == "abstract_pointer_declarator" + if fdecl.isNil and adecl.isNil: + if abst: + # Only for proc with no named param with pointer type + # Create a param name based on offset + # + # int func(char *, int **); + let + pname = "a" & $(offset+1) + pident = nimState.getIdent(pname, tinfo, exported) + acount = node[start+1].getXCount("abstract_pointer_declarator") + result.add pident + result.add nimState.newPtrTree(acount, tident) + result.add newNode(nkEmpty) + else: + # Named param, simple type + let + (pname, pinfo) = nimState.getNameInfo(node[start+1].getAtom(), nskField, parent = name) + pident = nimState.getIdent(pname, pinfo, exported) + + count = node[start+1].getPtrCount() + result.add pident + if count > 0: + result.add nimState.newPtrTree(count, tident) + else: + result.add tident + result.add newNode(nkEmpty) + elif not fdecl.isNil: + # Named param, function pointer + let + (pname, pinfo) = nimState.getNameInfo(node[start+1].getAtom(), nskField, parent = name) + pident = nimState.getIdent(pname, pinfo, exported) + result.add pident + result.add nimState.getTypeProc(name, node) + result.add newNode(nkEmpty) + elif not adecl.isNil: + # Named param, array type + let + (pname, pinfo) = nimState.getNameInfo(node[start+1].getAtom(), nskField, parent = name) + pident = nimState.getIdent(pname, pinfo, exported) + result.add pident + result.add nimState.getTypeArray(node) + result.add newNode(nkEmpty) + else: + result = nil + +proc newProcTree(nimState: NimState, name: string, node: TSNode, rtyp: PNode): PNode = + # Create nkProcTy tree for specified proc type + let + fparam = newNode(nkFormalParams) + + # Add return type + fparam.add rtyp + + if not node.isNil: + for i in 0 ..< node.len: + # Add nkIdentDefs for each param + let + param = nimState.newIdentDefs(name, node[i], i, exported = false) + if not param.isNil: + fparam.add param + + # proc(pname: ptyp ..): rtyp + # + # nkProcTy( + # nkFormalParams( + # rtyp, + # nkIdentDefs( # multiple depending on params + # .. + # ) + # ), + # nkEmpty() + # ) + result = newNode(nkProcTy) + result.add fparam + result.add newNode(nkEmpty) + +proc newRecListTree(nimState: NimState, name: string, node: TSNode): PNode = + # Create nkRecList tree for specified object + if not node.isNil: + # fname*: ftyp + # .. + # + # nkRecList( + # nkIdentDefs( # multiple depending on fields + # .. + # ) + # ) + result = newNode(nkRecList) + + for i in 0 ..< node.len: + # Add nkIdentDefs for each field + let + field = nimState.newIdentDefs(name, node[i], i, exported = true) + if not field.isNil: + result.add field + +proc addTypeObject(nimState: NimState, node: TSNode, override = "", duplicate = "") = + # Add a type of object + # + # If `override` is set, use it as the name + # If `duplicate` is set, don't add the same name + decho("addTypeObject()") + let + # TODO - check blank and override + typeDef = nimState.newTypeIdent(node, override) + name = $typeDef[0][1] + + if name != duplicate: + # type X* = object + # + # nkTypeDef( + # nkPostfix( + # nkIdent("*"), + # nkIdent("X") + # ), + # nkEmpty(), + # nkObjectTy( + # nkEmpty(), + # nkEmpty(), + # nkEmpty() + # ) + # ) + let + obj = newNode(nkObjectTy) + obj.add newNode(nkEmpty) + obj.add newNode(nkEmpty) + + let + fdlist = node.anyChildInTree("field_declaration_list") + if not fdlist.isNil and fdlist.len > 0: + # Add fields to object if present + obj.add nimState.newRecListTree(name, fdlist) + else: + obj.add newNode(nkEmpty) + + typeDef.add obj + + # nkTypeSection.add + nimState.typeSection.add typeDef + + nimState.printDebug(typeDef) + +proc addTypeTyped(nimState: NimState, node: TSNode, toverride = "", duplicate = "") = + # Add a type of a specified type + # + # If `toverride` is set, use it as the type name + # If `duplicate` is set, don't add the same name + decho("addTypeTyped()") + let + start = getStartAtom(node) + for i in start+1 ..< node.len: + # Add a type of a specific type + let + # node[i] = identifer = name + # TODO - check blank and override + typeDef = nimState.newTypeIdent(node[i]) + + # node[start] = identifier = type name + (tname0, tinfo) = nimState.getNameInfo(node[start].getAtom(), nskType) + + # Override type name + tname = if toverride.len != 0: toverride else: tname0 + + ident = nimState.getIdent(tname, tinfo, exported = false) + + # node[i] could have nested pointers + count = node[i].getPtrCount() + + # Skip typedef X X; + if $typeDef[0][1] != tname: + if count > 0: + # If pointers + typeDef.add nimState.newPtrTree(count, ident) + else: + typeDef.add ident + + # type X* = [ptr ..] Y + # + # nkTypeDef( + # nkPostfix( + # nkIdent("*"), + # nkIdent("X") + # ), + # nkEmpty(), + # nkPtrTy( # optional, nested + # nkIdent("Y") + # ) + # ) + + # nkTypeSection.add + nimState.typeSection.add typeDef + + nimState.printDebug(typeDef) + else: + nimState.addTypeObject(node, duplicate = duplicate) + +proc getTypeArray(nimState: NimState, node: TSNode): PNode = + # Create array type tree + let + start = getStartAtom(node) + + # node[start] = identifier = type name + (name, info) = nimState.getNameInfo(node[start].getAtom(), nskType) + ident = nimState.getIdent(name, info, exported = false) + + # Top-most array declarator + adecl = node[start+1].firstChildInTree("array_declarator") + + # node[start+1] could have nested arrays + acount = adecl.getArrayCount() + innermost = adecl.mostNestedChildInTree() + + # node[start+1] could have nested pointers - type + tcount = node[start+1].getPtrCount() + + # Name could be nested pointer to array + # + # (.. + # (array_declarator + # (parenthesized_declarator + # (pointer_declarator .. + # (pointer_declarator <- search upwards from atom + # (type_identifier) <- atom + # ) + # ) + # ) + # ) + # ) + ncount = innermost[0].getAtom().tsNodeParent().getPtrCount(reverse = true) + + result = ident + var + cnode = adecl + + if tcount > 0: + # If pointers + result = nimState.newPtrTree(tcount, result) + + for i in 0 ..< acount: + let + size = nimState.getNodeVal(cnode[1]).getLit() + if size.kind != nkNilLit: + result = nimState.newArrayTree(cnode, result, size) + cnode = cnode[0] + + if ncount > 0: + result = nimState.newPtrTree(ncount, result) + +proc addTypeArray(nimState: NimState, node: TSNode) = + # Add a type of array type + decho("addTypeArray()") + let + # node[1] = identifer = name + # TODO - check blank and override + typeDef = nimState.newTypeIdent(node[1]) + + typ = nimState.getTypeArray(node) + + typeDef.add typ + + # type X* = [ptr] array[x, [ptr] Y] + # + # nkTypeDef( + # nkPostfix( + # nkIdent("*"), + # nkIdent("X") + # ), + # nkEmpty(), + # nkPtrTy( # optional, nested + # nkBracketExpr( + # nkIdent("array") + # nkXLit(x), + # nkPtrTy( # optional, nested + # nkIdent("Y") + # ) + # ) + # ) + # ) + + # nkTypeSection.add + nimState.typeSection.add typeDef + + nimState.printDebug(typeDef) + +proc getTypeProc(nimState: NimState, name: string, node: TSNode): PNode = + # Create proc type tree + let + # node[0] = identifier = return type name + (rname, rinfo) = nimState.getNameInfo(node[0].getAtom(), nskType) + + # Parameter list + plist = node[1].anyChildInTree("parameter_list") + + # node[1] could have nested pointers + tcount = node[1].getPtrCount() + + # Name could be nested pointer to function + # + # (.. + # (function_declarator + # (parenthesized_declarator + # (pointer_declarator .. + # (pointer_declarator <- search upwards from atom + # (type_identifier) <- atom + # ) + # ) + # ) + # ) + # ) + ncount = node[1].getAtom().tsNodeParent().getPtrCount(reverse = true) + + # Return type + var + retType = nimState.getIdent(rname, rinfo, exported = false) + if tcount > 0: + retType = nimState.newPtrTree(tcount, retType) + + # Proc with return type and params + result = nimState.newProcTree(name, plist, retType) + if ncount > 1: + result = nimState.newPtrTree(ncount-1, result) + +proc addTypeProc(nimState: NimState, node: TSNode) = + # Add a type of proc type + decho("addTypeProc()") + let + # node[1] = identifier = name + # TODO - check blank and override + typeDef = nimState.newTypeIdent(node[1]) + name = $typeDef[0][1] + + procTy = nimState.getTypeProc(name, node) + + typeDef.add procTy + + # type X* = proc(a1: Y, a2: Z): P + # + # nkTypeDef( + # nkPostfix( + # nkIdent("*"), + # nkIdent("X") + # ), + # nkEmpty(), + # nkPtrTy( # optional, nested + # nkProcTy( + # nkFormalParams( + # nkPtrTy( # optional, nested + # nkIdent(retType) + # ), + # nkIdentDefs( + # nkIdent(param), + # nkPtrTy( + # nkIdent(ptype) + # ), + # nkEmpty() + # ), + # ... + # ), + # nkEmpty() + # ) + # ) + # ) + + # nkTypeSection.add + nimState.typeSection.add typeDef + + nimState.printDebug(typeDef) + +proc addType(nimState: NimState, node: TSNode) = + decho("addType()") + nimState.printDebug(node) + + if node.getName() == "struct_specifier": + # struct X; + # + # (struct_specifier + # (type_identifier) + # ) + # + # struct X {}; + # + # (struct_specifier + # (type_identifier) + # (field_declaration_list = "{}") + # ) + # + # struct X { char *a1; }; + # + # (struct_specifier + # (type_identifier) + # (field_declaration_list + # (field_declaration + # (type_identifier|primitive_type|) + # (struct_specifier + # (type_identifier) + # ) + # + # (field_identifier) + # ) + # (field_declaration ...) + # ) + decho("addType(): case 1") + nimState.addTypeObject(node) + elif node.getName() == "type_definition": + if node.len >= 2: + let + fdlist = node[0].anyChildInTree("field_declaration_list") + if (fdlist.isNil or (not fdlist.isNil and fdlist.len == 0)) and + nimState.getNodeVal(node[1]) == "": + # typedef struct X; + # + # (type_definition + # (struct_specifier + # (type_identifier) + # ) + # (type_definition = "") + # ) + # + # typedef struct X {}; + # + # (type_definition + # (struct_specifier + # (type_identifier) + # (field_declaration_list = "{}") + # ) + # (type_definition = "") + # ) + decho("addType(): case 2") + nimState.addTypeObject(node[0]) + else: + let + fdecl = node[1].anyChildInTree("function_declarator") + adecl = node[1].anyChildInTree("array_declarator") + if fdlist.isNil(): + if adecl.isNil and fdecl.isNil: + # typedef X Y; + # typedef X *Y; + # typedef struct X Y; + # typedef struct X *Y; + # + # (type_definition + # (type_qualifier?) + # (type_identifier|primitive_type|) + # (struct_specifier + # (type_identifier) + # ) + # + # (pointer_declarator - optional, nested + # (type_identifier) + # ) + # ) + decho("addType(): case 3") + nimState.addTypeTyped(node) + elif not fdecl.isNil: + # typedef X (*Y)(a1, a2, a3); + # typedef X *(*Y)(a1, a2, a3); + # typedef struct X (*Y)(a1, a2, a3); + # typedef struct X *(*Y)(a1, a2, a3); + # + # (type_definition + # (type_qualifier?) + # (type_identifier|primitive_type|) + # (struct_specifier + # (type_identifier) + # ) + # + # (pointer_declarator - optional, nested + # (function_declarator + # (parenthesized_declarator + # (pointer_declarator + # (type_identifer) + # ) + # ) + # (parameter_list + # (parameter_declaration + # (struct_specifier|type_identifier|primitive_type|array_declarator|function_declarator) + # (identifier - optional) + # ) + # ) + # ) + # ) + # ) + decho("addType(): case 4") + nimState.addTypeProc(node) + elif not adecl.isNil: + # typedef struct X Y[a][..]; + # typedef struct X *Y[a][..]; + # typedef struct X *(*Y)[a][..]; + # + # (type_definition + # (type_qualifier?) + # (type_identifier|primitive_type|) + # (struct_specifier + # (type_identifier) + # ) + # + # (pointer_declarator - optional, nested + # (array_declarator - nested + # (pointer_declarator - optional, nested + # (type_identifier) + # ) + # (number_literal) + # ) + # ) + # ) + decho("addType(): case 5") + nimState.addTypeArray(node) + else: + if node.firstChildInTree("field_declaration_list").isNil: + # typedef struct X { .. } Y, *Z; + # + # (type_definition + # (struct_specifier + # (type_identifier) - named struct <==== + # (field_declaration_list + # (field_declaration - optional, multiple + # (type_identifier|primitive_type|) + # (function_declarator|array_declarator + # .. + # ) + # + # (field_identifier) + # ) + # ) + # ) + # + # (type_identifier) + # (pointer_declarator - optional, nested + # (type_identifier) + # ) + # ) + + # First add struct as object + decho("addType(): case 6") + nimState.addTypeObject(node[0]) + + if node.len > 1 and nimState.getNodeVal(node[1]) != "": + # Add any additional names + nimState.addTypeTyped(node, duplicate = nimState.getNodeVal(node[0].getAtom())) + else: + # Same as above except unnamed struct + # + # typedef struct { .. } Y, *Z; + + # Get any name that isn't a pointer + decho("addType(): case 7") + let + name = block: + var + name = "" + for i in 1 ..< node.len: + if node[i].getName() == "type_identifier": + name = nimState.getNodeVal(node[i].getAtom()) + + name + + # Now add struct as object with specified name + nimState.addTypeObject(node[0], override = name) + + if name.len != 0: + # Add any additional names except duplicate + nimState.addTypeTyped(node, toverride = name, duplicate = name) + +proc addEnum(nimState: NimState, node: TSNode) = + decho("addEnum()") + nimState.printDebug(node) + +proc addProc(nimState: NimState, node: TSNode) = + decho("addProc()") + nimState.printDebug(node) + +proc processNode(nimState: NimState, node: TSNode): bool = + result = true + + case node.getName() + of "preproc_def": + nimState.addConst(node) + of "type_definition": + if not node.firstChildInTree("enum_specifier").isNil(): + nimState.addEnum(node) + else: + nimState.addType(node) + of "struct_specifier": + nimState.addType(node) + of "enum_specifier": + nimState.addEnum(node) + of "declaration": + nimState.addProc(node) + else: + # Unknown + result = false + +proc searchTree(nimState: NimState, root: TSNode) = + # Search AST generated by tree-sitter for recognized elements + var + node = root + nextnode: TSNode + depth = 0 + processed = false + + while true: + if not node.isNil() and depth > -1: + processed = nimState.processNode(node) + else: + break + + if not processed and node.len() != 0: + nextnode = node[0] + depth += 1 + else: + nextnode = node.tsNodeNextNamedSibling() + + if nextnode.isNil(): + while true: + node = node.tsNodeParent() + depth -= 1 + if depth == -1: + break + if node == root: + break + if not node.tsNodeNextNamedSibling().isNil(): + node = node.tsNodeNextNamedSibling() + break + else: + node = nextnode + + if node == root: + break + +proc printNimHeader*(gState: State) = + gecho """# Generated at $1 +# Command line: +# $2 $3 + +{.hint[ConvFromXtoItselfNotNeeded]: off.} + +import nimterop/types +""" % [$now(), getAppFilename(), commandLineParams().join(" ")] + +proc printNim*(gState: State, fullpath: string, root: TSNode) = + var + nimState = new(NimState) + #fp = fullpath.replace("\\", "/") + + nimState.identifiers = newTable[string, string]() + + nimState.gState = gState + nimState.currentHeader = getCurrentHeader(fullpath) + nimState.sourceFile = fullpath + + # Nim compiler objects + nimState.identCache = newIdentCache() + nimState.config = newConfigRef() + + nimState.constSection = newNode(nkConstSection) + nimState.enumSection = newNode(nkStmtList) + nimState.procSection = newNode(nkStmtList) + nimState.typeSection = newNode(nkTypeSection) + + nimState.searchTree(root) + + var + tree = newNode(nkStmtList) + tree.add nimState.enumSection + tree.add nimState.constSection + tree.add nimState.typeSection + tree.add nimState.procSection + + gecho tree.renderTree() diff --git a/nimterop/compat.nim b/nimterop/compat.nim deleted file mode 100644 index 7e2bc98..0000000 --- a/nimterop/compat.nim +++ /dev/null @@ -1,34 +0,0 @@ -#[ -module for backward compatibility -put everything that requires `when (NimMajor, NimMinor, NimPatch)` here -]# - -import os - -when (NimMajor, NimMinor, NimPatch) >= (0, 19, 9): - proc myNormalizedPath*(path: string): string = path.normalizedPath() - - export relativePath - -else: - import std/[ospaths,strutils] - - proc myNormalizedPath*(path: string): string = - result = path.normalizedPath() - when defined(windows): - result = result.strip(trailing = false, chars = {'\\'}) - - proc relativePath*(file, base: string): string = - ## naive version of `os.relativePath` ; remove after nim >= 0.19.9 - runnableExamples: - import ospaths, unittest - check: - "/foo/bar/baz/log.txt".unixToNativePath.relativePath("/foo/bar".unixToNativePath) == "baz/log.txt".unixToNativePath - "foo/bar/baz/log.txt".unixToNativePath.relativePath("foo/bar".unixToNativePath) == "baz/log.txt".unixToNativePath - var base = base.myNormalizedPath - var file = file.myNormalizedPath - if not base.endsWith DirSep: base.add DirSep - doAssert file.startsWith base - result = file[base.len .. ^1] - - proc getCurrentCompilerExe*(): string = "nim" diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 3d77e99..4cd8c04 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -2,6 +2,8 @@ import dynlib, macros, os, sequtils, sets, strformat, strutils, tables, times import regex +import compiler/[ast, idents, lineinfos, msgs, pathutils, renderer] + import "."/[build, globals, plugin, treesitter/api] const gReserved = """ @@ -26,6 +28,8 @@ when while xor yield""".split(Whitespace).toHashSet() +# Types related + const gTypeMap* = { # char "char": "cchar", @@ -91,6 +95,8 @@ proc getType*(str: string): string = if gTypeMap.hasKey(result): result = gTypeMap[result] +# Identifier related + proc checkIdentifier(name, kind, parent, origName: string) = let parentStr = if parent.nBl: parent & ":" else: "" @@ -165,6 +171,8 @@ proc addNewIdentifer*(nimState: NimState, name: string, override = false): bool nimState.identifiers[nimName] = name result = true +# Overrides related + proc getOverride*(nimState: NimState, name: string, kind: NimSymKind): string = doAssert name.nBl, "Blank identifier error" @@ -189,34 +197,121 @@ proc getOverrideFinal*(nimState: NimState, kind: NimSymKind): string = for i in nimState.gState.onSymbolOverrideFinal(typ): result &= "\n" & nimState.getOverride(i, kind) -proc getPtrType*(str: string): string = - result = case str: - of "ptr cchar": - "cstring" - of "ptr ptr cchar": - "ptr cstring" - of "ptr object": - "pointer" - of "ptr ptr object": - "ptr pointer" - else: - str +# TSNode shortcuts -proc getLit*(str: string): string = - # Used to convert #define literals into const - let - str = str.replace(re"/[/*].*?(?:\*/)?$", "").strip() +proc isNil*(node: TSNode): bool = + node.tsNodeIsNull() - if str.contains(re"^[\-]?[\d]*[.]?[\d]+$") or # decimal - str.contains(re"^0x[\da-fA-F]+$") or # hexadecimal - str.contains(re"^'[[:ascii:]]'$") or # char - str.contains(re"""^"[[:ascii:]]+"$"""): # char * - return str +proc len*(node: TSNode): int = + if not node.isNil: + result = node.tsNodeNamedChildCount().int + +proc `[]`*(node: TSNode, i: SomeInteger): TSNode = + if i < node.len(): + result = node.tsNodeNamedChild(i.uint32) + +proc getName*(node: TSNode): string {.inline.} = + if not node.isNil: + return $node.tsNodeType() + +proc getNodeVal*(gState: State, node: TSNode): string = + if not node.isNil: + return gState.code[node.tsNodeStartByte() .. node.tsNodeEndByte()-1].strip() proc getNodeVal*(nimState: NimState, node: TSNode): string = - return nimState.gState.code[node.tsNodeStartByte() .. node.tsNodeEndByte()-1].strip() + nimState.gState.getNodeVal(node) + +proc getAtom*(node: TSNode): TSNode = + if not node.isNil: + # Get child node which is topmost atom + if node.getName() in gAtoms: + return node + elif node.len() != 0: + return node[0].getAtom() + +proc getStartAtom*(node: TSNode): int = + if not node.isNil: + # Skip const, volatile and other type qualifiers + for i in 0 .. node.len - 1: + if node[i].getAtom().getName() notin gAtoms: + result += 1 + else: + break + +proc getXCount*(node: TSNode, ntype: string, reverse = false): int = + if not node.isNil: + # Get number of ntype nodes nested in tree + var + cnode = node + while ntype in cnode.getName(): + result += 1 + if reverse: + cnode = cnode.tsNodeParent() + else: + if cnode.len() != 0: + cnode = cnode[0] + else: + break + +proc getPtrCount*(node: TSNode, reverse = false): int = + node.getXCount("pointer_declarator") + +proc getArrayCount*(node: TSNode, reverse = false): int = + node.getXCount("array_declarator") + +proc getDeclarator*(node: TSNode): TSNode = + if not node.isNil: + # Return if child is a function or array declarator + if node.getName() in ["function_declarator", "array_declarator"]: + return node + elif node.len() != 0: + return node[0].getDeclarator() + +proc firstChildInTree*(node: TSNode, ntype: string): TSNode = + # Search for node type in tree - first children + var + cnode = node + while not cnode.isNil: + if cnode.getName() == ntype: + return cnode + cnode = cnode[0] + +proc anyChildInTree*(node: TSNode, ntype: string): TSNode = + # Search for node type anywhere in tree - depth first + var + cnode = node + while not cnode.isNil: + if cnode.getName() == ntype: + return cnode + for i in 0 ..< cnode.len: + let + ccnode = cnode[i].anyChildInTree(ntype) + if not ccnode.isNil(): + return ccnode + if cnode != node: + cnode = cnode.tsNodeNextNamedSibling() + else: + break + +proc mostNestedChildInTree*(node: TSNode): TSNode = + # Search for the most nested child of node's type in tree + var + cnode = node + ntype = cnode.getName() + while not cnode.isNil and cnode.len != 0 and cnode[0].getName() == ntype: + cnode = cnode[0] + result = cnode + +proc inChildren*(node: TSNode, ntype: string): bool = + # Search for node type in immediate children + result = false + for i in 0 ..< node.len(): + if (node[i]).getName() == ntype: + result = true + break proc getLineCol*(gState: State, node: TSNode): tuple[line, col: int] = + # Get line number and column info for node result.line = 1 result.col = 1 for i in 0 .. node.tsNodeStartByte().int-1: @@ -225,6 +320,150 @@ proc getLineCol*(gState: State, node: TSNode): tuple[line, col: int] = result.line += 1 result.col += 1 +proc getTSNodeNamedChildCountSansComments*(node: TSNode): int = + for i in 0 ..< node.len(): + if node.getName() != "comment": + result += 1 + +proc getPxName*(node: TSNode, offset: int): string = + # Get the xth (grand)parent of the node + var + np = node + count = 0 + + while not np.isNil() and count < offset: + np = np.tsNodeParent() + count += 1 + + if count == offset and not np.isNil(): + return np.getName() + +proc printLisp*(gState: State, root: TSNode): string = + var + node = root + nextnode: TSNode + depth = 0 + + while true: + if not node.isNil() and depth > -1: + if gState.pretty: + result &= spaces(depth) + let + (line, col) = gState.getLineCol(node) + result &= &"({$node.tsNodeType()} {line} {col} {node.tsNodeEndByte() - node.tsNodeStartByte()}" + let + val = gState.getNodeVal(node) + if "\n" notin val and " " notin val: + result &= &" \"{val}\"" + else: + break + + if node.tsNodeNamedChildCount() != 0: + if gState.pretty: + result &= "\n" + nextnode = node.tsNodeNamedChild(0) + depth += 1 + else: + if gState.pretty: + result &= ")\n" + else: + result &= ")" + nextnode = node.tsNodeNextNamedSibling() + + if nextnode.isNil(): + while true: + node = node.tsNodeParent() + depth -= 1 + if depth == -1: + break + if gState.pretty: + result &= spaces(depth) & ")\n" + else: + result &= ")" + if node == root: + break + if not node.tsNodeNextNamedSibling().isNil(): + node = node.tsNodeNextNamedSibling() + break + else: + node = nextnode + + if node == root: + break + +proc getCommented*(str: string): string = + "\n# " & str.strip().replace("\n", "\n# ") + +proc printTree*(nimState: NimState, pnode: PNode, offset = "") = + if nimState.gState.debug and pnode.kind != nkNone: + stdout.write "\n# " & offset & $pnode.kind & "(" + case pnode.kind + of nkCharLit: + stdout.write "'" & pnode.intVal.char & "')" + of nkIntLit..nkUInt64Lit: + stdout.write $pnode.intVal & ")" + of nkFloatLit..nkFloat128Lit: + stdout.write $pnode.floatVal & ")" + of nkStrLit..nkTripleStrLit: + stdout.write "\"" & pnode.strVal & "\")" + of nkSym: + stdout.write $pnode.sym & ")" + of nkIdent: + stdout.write "\"" & $pnode.ident.s & "\")" + else: + if pnode.sons.len != 0: + for i in 0 ..< pnode.sons.len: + nimState.printTree(pnode.sons[i], offset & " ") + if i != pnode.sons.len - 1: + stdout.write "," + stdout.write "\n# " & offset & ")" + else: + stdout.write ")" + if offset.len == 0: + necho "" + +proc printDebug*(nimState: NimState, node: TSNode) = + if nimState.gState.debug: + necho ("Input => " & nimState.getNodeVal(node)).getCommented() & "\n" & + nimState.gState.printLisp(node).getCommented() + +proc printDebug*(nimState: NimState, pnode: PNode) = + if nimState.gState.debug: + necho ("Output => " & $pnode).getCommented() + nimState.printTree(pnode) + +# Compiler shortcuts + +proc getLineInfo*(nimState: NimState, node: TSNode): TLineInfo = + # Get Nim equivalent line:col info from node + let + (line, col) = nimState.gState.getLineCol(node) + + result = newLineInfo(nimState.config, nimState.sourceFile.AbsoluteFile, line, col) + +proc getIdent*(nimState: NimState, name: string, info: TLineInfo, exported = true): PNode = + # Get ident PNode for name + info + let + exp = getIdent(nimState.identCache, "*") + ident = getIdent(nimState.identCache, name) + + if exported: + result = newNode(nkPostfix) + result.add newIdentNode(exp, info) + result.add newIdentNode(ident, info) + else: + result = newIdentNode(ident, info) + +proc getNameInfo*(nimState: NimState, node: TSNode, kind: NimSymKind, parent = ""): + tuple[name: string, info: TLineInfo] = + # Shortcut to get identifier name and info (node value and line:col) + let + name = nimState.getNodeVal(node) + result.name = nimState.getIdentifier(name, kind, parent) + if kind == nskType: + result.name = result.name.getType() + result.info = nimState.getLineInfo(node) + proc getCurrentHeader*(fullpath: string): string = ("header" & fullpath.splitFile().name.multiReplace([(".", ""), ("-", "")])) @@ -328,12 +567,6 @@ proc getNameKind*(name: string): tuple[name: string, kind: Kind, recursive: bool if result.kind != exactlyOne: result.name = result.name[0 .. ^2] -proc getTSNodeNamedChildCountSansComments*(node: TSNode): int = - if node.tsNodeNamedChildCount() != 0: - for i in 0 .. node.tsNodeNamedChildCount()-1: - if $node.tsNodeType() != "comment": - result += 1 - proc getTSNodeNamedChildNames*(node: TSNode): seq[string] = if node.tsNodeNamedChildCount() != 0: for i in 0 .. node.tsNodeNamedChildCount()-1: @@ -364,18 +597,6 @@ proc getAstChildByName*(ast: ref Ast, name: string): ref Ast = if ast.children.len == 1 and ast.children[0].name == ".": return ast.children[0] -proc getPxName*(node: TSNode, offset: int): string = - var - np = node - count = 0 - - while not np.tsNodeIsNull() and count < offset: - np = np.tsNodeParent() - count += 1 - - if count == offset and not np.tsNodeIsNull(): - return $np.tsNodeType() - proc getNimExpression*(nimState: NimState, expr: string): string = var clean = expr.multiReplace([("\n", " "), ("\r", "")]) diff --git a/nimterop/globals.nim b/nimterop/globals.nim index 9ee9de1..b234c1f 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -5,6 +5,8 @@ import regex import "."/plugin when not declared(CIMPORT): + import compiler/[ast, idents, options] + import "."/treesitter/api const @@ -69,7 +71,16 @@ type NimState {.used.} = ref object identifiers*: TableRef[string, string] - commentStr*, constStr*, debugStr*, enumStr*, procStr*, skipStr*, typeStr*: string + # Legacy ast fields, remove when ast2 becomes default + constStr*, enumStr*, procStr*, typeStr*: string + + commentStr*, debugStr*, skipStr*: string + + # Nim compiler objects + when not declared(CIMPORT): + constSection*, enumSection*, procSection*, typeSection*: PNode + identCache*: IdentCache + config*: ConfigRef gState*: State @@ -110,3 +121,7 @@ when not declared(CIMPORT): template necho*(args: string) {.dirty.} = let gState = nimState.gState gecho args + + template decho*(str: untyped): untyped = + if nimState.gState.debug: + necho str.getCommented() \ No newline at end of file diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index ba0e9fc..c76844c 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -7,6 +7,30 @@ import "."/[getters, globals, lisp, treesitter/api] type Grammar = seq[tuple[grammar: string, call: proc(ast: ref Ast, node: TSNode, nimState: NimState) {.nimcall.}]] +proc getPtrType(str: string): string = + result = case str: + of "ptr cchar": + "cstring" + of "ptr ptr cchar": + "ptr cstring" + of "ptr object": + "pointer" + of "ptr ptr object": + "ptr pointer" + else: + str + +proc getLit(str: string): string = + # Used to convert #define literals into const + let + str = str.replace(re"/[/*].*?(?:\*/)?$", "").strip() + + if str.contains(re"^[\-]?[\d]*[.]?[\d]+$") or # decimal + str.contains(re"^0x[\da-fA-F]+$") or # hexadecimal + str.contains(re"^'[[:ascii:]]'$") or # char + str.contains(re"""^"[[:ascii:]]+"$"""): # char * + return str + proc initGrammar(): Grammar = # #define X Y result.add((""" diff --git a/nimterop/toast.nim b/nimterop/toast.nim index 7dda1dc..a4415d2 100644 --- a/nimterop/toast.nim +++ b/nimterop/toast.nim @@ -2,56 +2,7 @@ import os, osproc, strformat, strutils, times import "."/treesitter/[api, c, cpp] -import "."/[ast, globals, getters, grammar] - -proc printLisp(gState: State, root: TSNode) = - var - node = root - nextnode: TSNode - depth = 0 - - while true: - if not node.tsNodeIsNull() and depth > -1: - if gState.pretty: - stdout.write spaces(depth) - let - (line, col) = gState.getLineCol(node) - stdout.write &"({$node.tsNodeType()} {line} {col} {node.tsNodeEndByte() - node.tsNodeStartByte()}" - else: - break - - if node.tsNodeNamedChildCount() != 0: - if gState.pretty: - gecho "" - nextnode = node.tsNodeNamedChild(0) - depth += 1 - else: - if gState.pretty: - gecho ")" - else: - stdout.write ")" - nextnode = node.tsNodeNextNamedSibling() - - if nextnode.tsNodeIsNull(): - while true: - node = node.tsNodeParent() - depth -= 1 - if depth == -1: - break - if gState.pretty: - gecho spaces(depth) & ")" - else: - stdout.write ")" - if node == root: - break - if not node.tsNodeNextNamedSibling().tsNodeIsNull(): - node = node.tsNodeNextNamedSibling() - break - else: - node = nextnode - - if node == root: - break +import "."/[ast, ast2, globals, getters, grammar] proc process(gState: State, path: string, astTable: AstTable) = doAssert existsFile(path), &"Invalid path {path}" @@ -91,9 +42,12 @@ proc process(gState: State, path: string, astTable: AstTable) = tree.tsTreeDelete() if gState.past: - gState.printLisp(root) + gecho gState.printLisp(root) elif gState.pnim: - gState.printNim(path, root, astTable) + if Feature.ast2 in gState.feature: + ast2.printNim(gState, path, root) + else: + ast.printNim(gState, path, root, astTable) elif gState.preprocess: gecho gState.code @@ -221,9 +175,9 @@ proc main( # Rerun nim check on stubbed wrapper (check, err) = execCmdEx(&"{gState.nim} check {outputFile}") - doAssert err == 0, data & "# Nim check with stub failed:\n\n" & check + doAssert err == 0, data & "\n# Nim check with stub failed:\n\n" & check else: - doAssert err == 0, outputFile.readFile() & "# Nim check failed:\n\n" & check + doAssert err == 0, outputFile.readFile() & "\n# Nim check failed:\n\n" & check # Print wrapper if temporarily redirected to file if check and output.len == 0: diff --git a/tests/include/tast2.h b/tests/include/tast2.h new file mode 100644 index 0000000..1a2789b --- /dev/null +++ b/tests/include/tast2.h @@ -0,0 +1,42 @@ + +#define A 1 +#define B 1.0 +#define C 0x10 +#define D "hello" +#define E 'c' + +struct A0; +struct A1 {}; +typedef struct A2; +typedef struct A3 {}; +typedef struct A4 A4, *A4p; +typedef const int A5; +typedef int *A6; +typedef A0 **A7; +typedef void *A8; + +typedef char *A9[3]; +typedef char *A10[3][6]; +typedef char *(*A11)[3]; + +typedef int **(*A12)(int, int b, int *c, int *, int *count[4], int (*func)(int, int)); +typedef int A13(int, int); + +struct A14 { volatile char a1; }; +struct A15 { char *a1; const int *a2[1]; }; + +typedef struct A16 { char f1; }; +typedef struct A17 { char *a1; int *a2[1]; } A18, *A18p; +typedef struct { char *a1; int *a2[1]; } A19, *A19p; + +typedef struct A20 { char a1; } A20, A21, *A21p; + +//Expression +//typedef struct A21 { int **f1; int abc[123+132]; } A21; + +//Unions +//union UNION1 {int f1; }; +//typedef union UNION2 { int **f1; int abc[123+132]; } UNION2; + +// Anonymous +//typedef struct { char a1; }; diff --git a/tests/tast2.nim b/tests/tast2.nim new file mode 100644 index 0000000..ffdcd19 --- /dev/null +++ b/tests/tast2.nim @@ -0,0 +1,71 @@ +import tables + +import nimterop/[cimport] + +static: + cDebug() + +cImport("include/tast2.h", flags="-d -f:ast2") + +proc testFields(t: typedesc, fields: Table[string, string] = initTable[string, string]()) = + var + obj: t + count = 0 + for name, value in obj.fieldPairs(): + count += 1 + assert name in fields, $t & "." & name & " invalid" + assert $fields[name] == $typeof(value), + "typeof(" & $t & ":" & name & ") != " & fields[name] & ", is " & $typeof(value) + assert count == fields.len, "Failed for " & $t + +assert A == 1 +assert B == 1.0 +assert C == 0x10 +assert D == "hello" +assert E == 'c' + +assert A0 is object +testFields(A0) +assert A1 is object +testFields(A1) +assert A2 is object +testFields(A2) +assert A3 is object +testFields(A3) +assert A4 is object +testFields(A4) +assert A4p is ptr A4 +assert A5 is cint +assert A6 is ptr cint +assert A7 is ptr ptr A0 +assert A8 is pointer + +assert A9 is array[3, cstring] +assert A10 is array[3, array[6, cstring]] +assert A11 is ptr array[3, cstring] + +assert A12 is proc(a1: cint, b: cint, c: ptr cint, a4: ptr cint, count: array[4, ptr cint], `func`: proc(a1: cint, a2: cint): cint): ptr ptr cint +assert A13 is proc(a1: cint, a2: cint): cint + +assert A14 is object +testFields(A14, {"a1": "cchar"}.toTable()) + +assert A15 is object +testFields(A15, {"a1": "cstring", "a2": "array[0..0, ptr cint]"}.toTable()) + +assert A16 is object +testFields(A16, {"f1": "cchar"}.toTable()) + +assert A17 is object +testFields(A17, {"a1": "cstring", "a2": "array[0..0, ptr cint]"}.toTable()) +assert A18 is A17 +assert A18p is ptr A17 + +assert A19 is object +testFields(A19, {"a1": "cstring", "a2": "array[0..0, ptr cint]"}.toTable()) +assert A19p is ptr A19 + +assert A20 is object +testFields(A20, {"a1": "cchar"}.toTable()) +assert A21 is A20 +assert A21p is ptr A20 From d6e69dbf84e3f2c85e24a62c7bd3bb56090ca2da Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 10 Mar 2020 17:00:11 -0500 Subject: [PATCH 335/593] Add windows to Travis, use script --- .travis.yml | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index d16b9fc..3201c6c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,5 @@ os: + - windows - linux - osx @@ -16,15 +17,12 @@ env: cache: directories: - - "$HOME/.choosenim/toolchains/nim-0.20.2" - - "$HOME/.choosenim/toolchains/nim-1.0.6" + - "$HOME/.choosenim" install: - - export CHOOSENIM_CHOOSE_VERSION=$BRANCH - - | - curl https://nim-lang.org/choosenim/init.sh -sSf > init.sh - sh init.sh -y - - export PATH="$HOME/.nimble/bin:/usr/local/opt/gettext/bin:$PATH" + - export PATH="/usr/local/opt/gettext/bin:$PATH" + - curl https://gist.github.com/genotrance/fb53504a4fba88bc5201d3783df5c522/raw/travis.sh -LsSf -o travis.sh + - source travis.sh script: - nimble --verbose install -y From 4dd15aa7d7c2aae0e4d96e4ac0a4c1423afd396e Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 12 Mar 2020 18:36:38 -0500 Subject: [PATCH 336/593] Fix #169 - header pragma omitted by default --- nimterop/ast.nim | 4 ++-- nimterop/getters.nim | 22 +++++++--------------- nimterop/globals.nim | 2 +- nimterop/grammar.nim | 4 ++-- nimterop/toast.nim | 13 ++++++++----- tests/include/test2.hpp | 10 ++++++---- 6 files changed, 26 insertions(+), 29 deletions(-) diff --git a/nimterop/ast.nim b/nimterop/ast.nim index a61e65a..e28241f 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -178,7 +178,7 @@ proc printNim*(gState: State, fullpath: string, root: TSNode, astTable: AstTable nimState.impShort = nimState.currentHeader.replace("header", "imp") nimState.sourceFile = fullpath - if nimState.gState.dynlib.Bl: + if nimState.gState.dynlib.Bl and nimState.gState.includeHeader: nimState.constStr &= &"\n {nimState.currentHeader} {{.used.}} = \"{fp}\"" root.searchAst(astTable, nimState) @@ -191,7 +191,7 @@ proc printNim*(gState: State, fullpath: string, root: TSNode, astTable: AstTable necho &"const{nimState.constStr}\n" necho &""" -{{.pragma: {nimState.impShort}, importc{nimState.getHeader()}.}} +{{.pragma: {nimState.impShort}, importc{nimState.getHeaderPragma()}.}} {{.pragma: {nimState.impShort}C, {nimState.impShort}, cdecl{nimState.getDynlib()}.}} """ diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 4cd8c04..93c4000 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -346,8 +346,7 @@ proc printLisp*(gState: State, root: TSNode): string = while true: if not node.isNil() and depth > -1: - if gState.pretty: - result &= spaces(depth) + result &= spaces(depth) let (line, col) = gState.getLineCol(node) result &= &"({$node.tsNodeType()} {line} {col} {node.tsNodeEndByte() - node.tsNodeStartByte()}" @@ -359,15 +358,11 @@ proc printLisp*(gState: State, root: TSNode): string = break if node.tsNodeNamedChildCount() != 0: - if gState.pretty: - result &= "\n" + result &= "\n" nextnode = node.tsNodeNamedChild(0) depth += 1 else: - if gState.pretty: - result &= ")\n" - else: - result &= ")" + result &= ")\n" nextnode = node.tsNodeNextNamedSibling() if nextnode.isNil(): @@ -376,10 +371,7 @@ proc printLisp*(gState: State, root: TSNode): string = depth -= 1 if depth == -1: break - if gState.pretty: - result &= spaces(depth) & ")\n" - else: - result &= ")" + result &= spaces(depth) & ")\n" if node == root: break if not node.tsNodeNextNamedSibling().isNil(): @@ -656,9 +648,9 @@ proc getSplitComma*(joined: seq[string]): seq[string] = for i in joined: result = result.concat(i.split(",")) -proc getHeader*(nimState: NimState): string = +proc getHeaderPragma*(nimState: NimState): string = result = - if nimState.gState.dynlib.Bl: + if nimState.gState.dynlib.Bl and nimState.gState.includeHeader: &", header: {nimState.currentHeader}" else: "" @@ -672,7 +664,7 @@ proc getDynlib*(nimState: NimState): string = proc getImportC*(nimState: NimState, origName, nimName: string): string = if nimName != origName: - result = &"importc: \"{origName}\"{nimState.getHeader()}" + result = &"importc: \"{origName}\"{nimState.getHeaderPragma()}" else: result = nimState.impShort diff --git a/nimterop/globals.nim b/nimterop/globals.nim index b234c1f..35a5575 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -57,7 +57,7 @@ type State = ref object compile*, defines*, headers*, includeDirs*, searchDirs*, prefix*, suffix*, symOverride*: seq[string] - nocache*, nocomments*, debug*, past*, preprocess*, pnim*, pretty*, recurse*: bool + debug*, includeHeader*, nocache*, nocomments*, past*, preprocess*, pnim*, recurse*: bool code*, dynlib*, mode*, nim*, overrides*, pluginSource*, pluginSourcePath*: string diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index c76844c..f15c2f8 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -200,7 +200,7 @@ proc initGrammar(): Grammar = nname = nimState.getIdentifier(name, nskType) i += 1 - if nimState.gState.dynlib.Bl: + if nimState.gState.dynlib.Bl and nimState.gState.includeHeader: pragmas.add nimState.getImportC(name, nname) let @@ -316,7 +316,7 @@ proc initGrammar(): Grammar = else: var pragmas: seq[string] = @[] - if nimState.gState.dynlib.Bl: + if nimState.gState.dynlib.Bl and nimState.gState.includeHeader: pragmas.add nimState.getImportC(prefix & name, nname) pragmas.add "bycopy" if union.nBl: diff --git a/nimterop/toast.nim b/nimterop/toast.nim index a4415d2..323b4ec 100644 --- a/nimterop/toast.nim +++ b/nimterop/toast.nim @@ -58,6 +58,7 @@ proc main( defines: seq[string] = @[], dynlib: string = "", feature: seq[Feature] = @[], + includeHeader = false, includeDirs: seq[string] = @[], mode = modeDefault, nim: string = "nim", @@ -82,6 +83,7 @@ proc main( defines: defines, dynlib: dynlib, feature: feature, + includeHeader: includeHeader, includeDirs: includeDirs, mode: mode, nim: nim, @@ -91,7 +93,6 @@ proc main( pnim: pnim, prefix: prefix, preprocess: preprocess, - pretty: true, recurse: recurse, suffix: suffix, symOverride: symOverride @@ -190,8 +191,9 @@ when isMainModule: "check": "check generated wrapper with compiler", "debug": "enable debug output", "defines": "definitions to pass to preprocessor", - "dynlib": "Import symbols from library in specified Nim string", + "dynlib": "import symbols from library in specified Nim string", "feature": "flags to enable experimental features", + "includeHeader": "add {.header.} pragma to wrapper", "includeDirs": "include directory to pass to preprocessor", "mode": "language parser: c or cpp", "nim": "use a particular Nim executable (default: $PATH/nim)", @@ -199,14 +201,14 @@ when isMainModule: "output": "file to output content - default stdout", "past": "print AST output", "pgrammar": "print grammar", - "pluginSourcePath": "Nim file to build and load as a plugin", + "pluginSourcePath": "nim file to build and load as a plugin", "pnim": "print Nim output", "preprocess": "run preprocessor on header", "recurse": "process #include files", "source" : "C/C++ source/header", - "prefix": "Strip prefix from identifiers", + "prefix": "strip prefix from identifiers", "stub": "stub out undefined type references as objects", - "suffix": "Strip suffix from identifiers", + "suffix": "strip suffix from identifiers", "symOverride": "skip generating specified symbols" }, short = { "check": 'k', @@ -214,6 +216,7 @@ when isMainModule: "defines": 'D', "dynlib": 'l', "feature": 'f', + "includeHeader": 'H', "includeDirs": 'I', "nocomments": 'c', "output": 'o', diff --git a/tests/include/test2.hpp b/tests/include/test2.hpp index 0fd90ee..2f9a281 100644 --- a/tests/include/test2.hpp +++ b/tests/include/test2.hpp @@ -4,11 +4,13 @@ #define TEST_FLOAT 5.12 #define TEST_HEX 0x512 -int test_call_int(); +extern "C" { + int test_call_int(); -struct Foo{ - int bar; -}; + struct Foo{ + int bar; + }; +} class Foo1{ int bar1; From 077981c3a5e577029cf28bffc67648e73d4aafcc Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Sun, 15 Mar 2020 22:23:22 -0500 Subject: [PATCH 337/593] Readme update --- README.md | 48 +++++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index ca16293..b1fee44 100644 --- a/README.md +++ b/README.md @@ -90,31 +90,33 @@ Refer to the ```tests``` directory for examples on how the library can be used. The `toast` binary can also be used directly on the CLI: ``` -toast -h +> toast -h Usage: main [optional-params] C/C++ source/header -Options(opt-arg sep :|=|spc): - -h, --help print this cligen-erated help - --help-syntax advanced: prepend,plurals,.. - -k, --check bool false check generated wrapper with compiler - -d, --debug bool false enable debug output - -D=, --defines= strings {} definitions to pass to preprocessor - -l=, --dynlib= string "" Import symbols from library in specified Nim string - -I=, --includeDirs= strings {} include directory to pass to preprocessor - -m=, --mode= string "cpp" language parser: c or cpp - --nim= string "nim" use a particular Nim executable (default: $PATH/nim) - -c, --nocomments bool false exclude top-level comments from output - -o=, --output= string "" file to output content - default stdout - -a, --past bool false print AST output - -g, --pgrammar bool false print grammar - --pluginSourcePath= string "" Nim file to build and load as a plugin - -n, --pnim bool false print Nim output - -E=, --prefix= strings {} Strip prefix from identifiers - -p, --preprocess bool false run preprocessor on header - -r, --recurse bool false process #include files - -s, --stub bool false stub out undefined type references as objects - -F=, --suffix= strings {} Strip suffix from identifiers - -O=, --symOverride= strings {} skip generating specified symbols +Options: + -h, --help print this cligen-erated help + --help-syntax advanced: prepend,plurals,.. + -k, --check bool false check generated wrapper with compiler + -d, --debug bool false enable debug output + -D=, --defines= strings {} definitions to pass to preprocessor + -l=, --dynlib= string "" import symbols from library in specified Nim string + -f=, --feature= Features {} flags to enable experimental features + -H, --includeHeader bool false add {.header.} pragma to wrapper + -I=, --includeDirs= strings {} include directory to pass to preprocessor + -m=, --mode= string "cpp" language parser: c or cpp + --nim= string "nim" use a particular Nim executable (default: $PATH/nim) + -c, --nocomments bool false exclude top-level comments from output + -o=, --output= string "" file to output content - default stdout + -a, --past bool false print AST output + -g, --pgrammar bool false print grammar + --pluginSourcePath= string "" nim file to build and load as a plugin + -n, --pnim bool false print Nim output + -E=, --prefix= strings {} strip prefix from identifiers + -p, --preprocess bool false run preprocessor on header + -r, --recurse bool false process #include files + -s, --stub bool false stub out undefined type references as objects + -F=, --suffix= strings {} strip suffix from identifiers + -O=, --symOverride= strings {} skip generating specified symbols ``` __Implementation Details__ From 3f500898aa5b45b423348846d794463585ef34ee Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 16 Mar 2020 17:50:43 -0500 Subject: [PATCH 338/593] Add ast2 array expression support, cleanup debug output --- nimterop/ast2.nim | 24 +++++++++++++++--------- nimterop/getters.nim | 30 +++++++++++++++--------------- nimterop/globals.nim | 3 ++- tests/include/tast2.h | 2 +- tests/tast2.nim | 3 +++ 5 files changed, 36 insertions(+), 26 deletions(-) diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index 697262f..f418139 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -2,7 +2,7 @@ import macros, os, sets, strutils, tables, times import regex -import compiler/[ast, idents, options, renderer] +import compiler/[ast, idents, modulegraphs, options, parser, renderer] import "."/treesitter/api @@ -19,8 +19,9 @@ proc getPtrType*(str: string): string = else: str -proc getLit*(str: string): PNode = - # Used to convert #define literals into const +proc getLit*(nimState: NimState, str: string): PNode = + # Used to convert #define literals into const and expressions + # in array sizes let str = str.replace(re"/[/*].*?(?:\*/)?$", "").strip() @@ -30,9 +31,9 @@ proc getLit*(str: string): PNode = elif str.contains(re"^[\-]?[\d]*[.]?[\d]+$"): # float result = newFloatNode(nkFloatLit, parseFloat(str)) - # TODO - hex becomes int on render - elif str.contains(re"^0x[\da-fA-F]+$"): # hexadecimal - result = newIntNode(nkIntLit, parseHexInt(str)) + # # TODO - hex becomes int on render + # elif str.contains(re"^0x[\da-fA-F]+$"): # hexadecimal + # result = newIntNode(nkIntLit, parseHexInt(str)) elif str.contains(re"^'[[:ascii:]]'$"): # char result = newNode(nkCharLit) @@ -42,7 +43,11 @@ proc getLit*(str: string): PNode = result = newStrNode(nkStrLit, str[1 .. ^2]) else: - result = newNode(nkNilLit) + result = parseString( + nimState.getNimExpression(str), + nimState.identCache, nimState.config) + if result.isNil: + result = newNode(nkNilLit) proc addConst(nimState: NimState, node: TSNode) = # #define X Y @@ -65,7 +70,7 @@ proc addConst(nimState: NimState, node: TSNode) = ident = nimState.getIdent(name, info) # node[1] = preproc_arg = value - val = nimState.getNodeVal(node[1]).getLit() + val = nimState.getLit(nimState.getNodeVal(node[1])) # If supported literal if val.kind != nkNilLit: @@ -464,7 +469,7 @@ proc getTypeArray(nimState: NimState, node: TSNode): PNode = for i in 0 ..< acount: let - size = nimState.getNodeVal(cnode[1]).getLit() + size = nimState.getLit(nimState.getNodeVal(cnode[1])) if size.kind != nkNilLit: result = nimState.newArrayTree(cnode, result, size) cnode = cnode[0] @@ -877,6 +882,7 @@ proc printNim*(gState: State, fullpath: string, root: TSNode) = # Nim compiler objects nimState.identCache = newIdentCache() nimState.config = newConfigRef() + nimstate.graph = newModuleGraph(nimState.identCache, nimState.config) nimState.constSection = newNode(nkConstSection) nimState.enumSection = newNode(nkStmtList) diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 93c4000..2c7da75 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -386,33 +386,33 @@ proc printLisp*(gState: State, root: TSNode): string = proc getCommented*(str: string): string = "\n# " & str.strip().replace("\n", "\n# ") -proc printTree*(nimState: NimState, pnode: PNode, offset = "") = +proc printTree*(nimState: NimState, pnode: PNode, offset = ""): string = if nimState.gState.debug and pnode.kind != nkNone: - stdout.write "\n# " & offset & $pnode.kind & "(" + result &= "\n# " & offset & $pnode.kind & "(" case pnode.kind of nkCharLit: - stdout.write "'" & pnode.intVal.char & "')" + result &= "'" & pnode.intVal.char & "')" of nkIntLit..nkUInt64Lit: - stdout.write $pnode.intVal & ")" + result &= $pnode.intVal & ")" of nkFloatLit..nkFloat128Lit: - stdout.write $pnode.floatVal & ")" + result &= $pnode.floatVal & ")" of nkStrLit..nkTripleStrLit: - stdout.write "\"" & pnode.strVal & "\")" + result &= "\"" & pnode.strVal & "\")" of nkSym: - stdout.write $pnode.sym & ")" + result &= $pnode.sym & ")" of nkIdent: - stdout.write "\"" & $pnode.ident.s & "\")" + result &= "\"" & $pnode.ident.s & "\")" else: if pnode.sons.len != 0: for i in 0 ..< pnode.sons.len: - nimState.printTree(pnode.sons[i], offset & " ") + result &= nimState.printTree(pnode.sons[i], offset & " ") if i != pnode.sons.len - 1: - stdout.write "," - stdout.write "\n# " & offset & ")" + result &= "," + result &= "\n# " & offset & ")" else: - stdout.write ")" + result &= ")" if offset.len == 0: - necho "" + result &= "\n" proc printDebug*(nimState: NimState, node: TSNode) = if nimState.gState.debug: @@ -421,8 +421,8 @@ proc printDebug*(nimState: NimState, node: TSNode) = proc printDebug*(nimState: NimState, pnode: PNode) = if nimState.gState.debug: - necho ("Output => " & $pnode).getCommented() - nimState.printTree(pnode) + necho ("Output => " & $pnode).getCommented() & "\n" & + nimState.printTree(pnode) # Compiler shortcuts diff --git a/nimterop/globals.nim b/nimterop/globals.nim index 35a5575..ba63a76 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -5,7 +5,7 @@ import regex import "."/plugin when not declared(CIMPORT): - import compiler/[ast, idents, options] + import compiler/[ast, idents, modulegraphs, options] import "."/treesitter/api @@ -81,6 +81,7 @@ type constSection*, enumSection*, procSection*, typeSection*: PNode identCache*: IdentCache config*: ConfigRef + graph*: ModuleGraph gState*: State diff --git a/tests/include/tast2.h b/tests/include/tast2.h index 1a2789b..ced3a44 100644 --- a/tests/include/tast2.h +++ b/tests/include/tast2.h @@ -32,7 +32,7 @@ typedef struct { char *a1; int *a2[1]; } A19, *A19p; typedef struct A20 { char a1; } A20, A21, *A21p; //Expression -//typedef struct A21 { int **f1; int abc[123+132]; } A21; +typedef struct A22 { int **f1; int *f2[123+132]; } A22; //Unions //union UNION1 {int f1; }; diff --git a/tests/tast2.nim b/tests/tast2.nim index ffdcd19..dd8fae7 100644 --- a/tests/tast2.nim +++ b/tests/tast2.nim @@ -69,3 +69,6 @@ assert A20 is object testFields(A20, {"a1": "cchar"}.toTable()) assert A21 is A20 assert A21p is ptr A20 + +assert A22 is object +testFields(A22, {"f1": "ptr ptr cint", "f2": "array[0..254, ptr cint]"}.toTable()) \ No newline at end of file From 1a9911fc259a5dd5ac9a6097c4d41d6e3e50169b Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 16 Mar 2020 23:15:34 -0500 Subject: [PATCH 339/593] Add ast2 union support --- nimterop/ast2.nim | 77 +++++++++++++++++++++++++++++++++++++------ tests/include/tast2.h | 4 +-- tests/tast2.nim | 8 ++++- 3 files changed, 76 insertions(+), 13 deletions(-) diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index f418139..ca0fc51 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -93,7 +93,55 @@ proc addConst(nimState: NimState, node: TSNode) = nimState.printDebug(constDef) -proc newTypeIdent(nimState: NimState, node: TSNode, override = ""): PNode = +proc newPragma(nimState: NimState, node: TSNode, pragmas: Table[string, string]): PNode = + # Create nkPragma tree for name:value + # + # {.name1, name2: value2.} + # + # nkPragma( + # nkIdent(name1), + # nkExprColonExpr( + # nkIdent(name2), + # nkStrLit(value2) + # ) + # ) + result = newNode(nkPragma) + for name, value in pragmas.pairs: + let + (_, pinfo) = nimState.getNameInfo(node, nskUnknown) + pident = nimState.getIdent(name, pinfo, exported = false) + + if value.len == 0: + result.add pident + else: + let + colExpr = newNode(nkExprColonExpr) + pvalue = newStrNode(nkStrLit, value) + colExpr.add pident + colExpr.add pvalue + result.add colExpr + +proc newPragmaExpr(nimState: NimState, node: TSNode, ident: PNode, pragmas: Table[string, string]): PNode = + # Create nkPragmaExpr tree + # + # nkPragmaExpr( + # nkPostfix( + # nkIdent("*"), + # nkIdent("X") + # ), + # nkPragma( + # nkIdent(name1), + # nkExprColonExpr( + # nkIdent(name2), + # nkStrLit(value2) + # ) + # ) + # ) + result = newNode(nkPragmaExpr) + result.add ident + result.add nimState.newPragma(node, pragmas) + +proc newTypeIdent(nimState: NimState, node: TSNode, override = "", union = false): PNode = # Create nkTypeDef PNode with first ident # # If `override`, use it instead of node.getAtom() for name @@ -105,6 +153,11 @@ proc newTypeIdent(nimState: NimState, node: TSNode, override = ""): PNode = nimState.getIdent(override, info) else: nimState.getIdent(name, info) + prident = + if union: + nimState.newPragmaExpr(node, ident, {"union": ""}.toTable()) + else: + ident # type name* = # @@ -116,7 +169,7 @@ proc newTypeIdent(nimState: NimState, node: TSNode, override = ""): PNode = # nkEmpty() # ) result = newNode(nkTypeDef) - result.add ident + result.add prident result.add newNode(nkEmpty) proc newPtrTree(nimState: NimState, count: int, typ: PNode): PNode = @@ -325,7 +378,7 @@ proc newRecListTree(nimState: NimState, name: string, node: TSNode): PNode = if not field.isNil: result.add field -proc addTypeObject(nimState: NimState, node: TSNode, override = "", duplicate = "") = +proc addTypeObject(nimState: NimState, node: TSNode, override = "", duplicate = "", union = false) = # Add a type of object # # If `override` is set, use it as the name @@ -333,7 +386,7 @@ proc addTypeObject(nimState: NimState, node: TSNode, override = "", duplicate = decho("addTypeObject()") let # TODO - check blank and override - typeDef = nimState.newTypeIdent(node, override) + typeDef = nimState.newTypeIdent(node, override, union = union) name = $typeDef[0][1] if name != duplicate: @@ -597,11 +650,11 @@ proc addTypeProc(nimState: NimState, node: TSNode) = nimState.printDebug(typeDef) -proc addType(nimState: NimState, node: TSNode) = +proc addType(nimState: NimState, node: TSNode, union = false) = decho("addType()") nimState.printDebug(node) - if node.getName() == "struct_specifier": + if node.getName() in ["struct_specifier", "union_specifier"]: # struct X; # # (struct_specifier @@ -631,7 +684,7 @@ proc addType(nimState: NimState, node: TSNode) = # (field_declaration ...) # ) decho("addType(): case 1") - nimState.addTypeObject(node) + nimState.addTypeObject(node, union = union) elif node.getName() == "type_definition": if node.len >= 2: let @@ -657,7 +710,7 @@ proc addType(nimState: NimState, node: TSNode) = # (type_definition = "") # ) decho("addType(): case 2") - nimState.addTypeObject(node[0]) + nimState.addTypeObject(node[0], union = union) else: let fdecl = node[1].anyChildInTree("function_declarator") @@ -763,7 +816,7 @@ proc addType(nimState: NimState, node: TSNode) = # First add struct as object decho("addType(): case 6") - nimState.addTypeObject(node[0]) + nimState.addTypeObject(node[0], union = union) if node.len > 1 and nimState.getNodeVal(node[1]) != "": # Add any additional names @@ -786,7 +839,7 @@ proc addType(nimState: NimState, node: TSNode) = name # Now add struct as object with specified name - nimState.addTypeObject(node[0], override = name) + nimState.addTypeObject(node[0], override = name, union = union) if name.len != 0: # Add any additional names except duplicate @@ -809,10 +862,14 @@ proc processNode(nimState: NimState, node: TSNode): bool = of "type_definition": if not node.firstChildInTree("enum_specifier").isNil(): nimState.addEnum(node) + elif not node.firstChildInTree("union_specifier").isNil(): + nimState.addType(node, union = true) else: nimState.addType(node) of "struct_specifier": nimState.addType(node) + of "union_specifier": + nimState.addType(node, union = true) of "enum_specifier": nimState.addEnum(node) of "declaration": diff --git a/tests/include/tast2.h b/tests/include/tast2.h index ced3a44..90e96c6 100644 --- a/tests/include/tast2.h +++ b/tests/include/tast2.h @@ -35,8 +35,8 @@ typedef struct A20 { char a1; } A20, A21, *A21p; typedef struct A22 { int **f1; int *f2[123+132]; } A22; //Unions -//union UNION1 {int f1; }; -//typedef union UNION2 { int **f1; int abc[123+132]; } UNION2; +union U1 {int f1; float f2; }; +typedef union U2 { int **f1; int abc[123+132]; } U2; // Anonymous //typedef struct { char a1; }; diff --git a/tests/tast2.nim b/tests/tast2.nim index dd8fae7..d8d18a3 100644 --- a/tests/tast2.nim +++ b/tests/tast2.nim @@ -71,4 +71,10 @@ assert A21 is A20 assert A21p is ptr A20 assert A22 is object -testFields(A22, {"f1": "ptr ptr cint", "f2": "array[0..254, ptr cint]"}.toTable()) \ No newline at end of file +testFields(A22, {"f1": "ptr ptr cint", "f2": "array[0..254, ptr cint]"}.toTable()) + +assert U1 is object +assert sizeof(U1) == sizeof(cfloat) + +assert U2 is object +assert sizeof(U2) == 256 * sizeof(cint) \ No newline at end of file From 9d2626bb5fd1603ed0f6db1757b0184d9e5b29e4 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 17 Mar 2020 16:34:11 -0500 Subject: [PATCH 340/593] Initial ast2 proc support --- nimterop/ast2.nim | 121 +++++++++++++++++++++++++++++++++++------- tests/include/tast2.h | 2 + 2 files changed, 103 insertions(+), 20 deletions(-) diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index ca0fc51..8c2fc3f 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -1,4 +1,4 @@ -import macros, os, sets, strutils, tables, times +import macros, os, sets, strformat, strutils, tables, times import regex @@ -19,6 +19,9 @@ proc getPtrType*(str: string): string = else: str +proc parseString(nimState: NimState, str: string): PNode = + result = parseString(str, nimState.identCache, nimState.config) + proc getLit*(nimState: NimState, str: string): PNode = # Used to convert #define literals into const and expressions # in array sizes @@ -43,9 +46,7 @@ proc getLit*(nimState: NimState, str: string): PNode = result = newStrNode(nkStrLit, str[1 .. ^2]) else: - result = parseString( - nimState.getNimExpression(str), - nimState.identCache, nimState.config) + result = nimState.parseString(nimState.getNimExpression(str)) if result.isNil: result = newNode(nkNilLit) @@ -93,7 +94,7 @@ proc addConst(nimState: NimState, node: TSNode) = nimState.printDebug(constDef) -proc newPragma(nimState: NimState, node: TSNode, pragmas: Table[string, string]): PNode = +proc newPragma(nimState: NimState, node: TSNode, pragmas: OrderedTable[string, string]): PNode = # Create nkPragma tree for name:value # # {.name1, name2: value2.} @@ -108,7 +109,7 @@ proc newPragma(nimState: NimState, node: TSNode, pragmas: Table[string, string]) result = newNode(nkPragma) for name, value in pragmas.pairs: let - (_, pinfo) = nimState.getNameInfo(node, nskUnknown) + (_, pinfo) = nimState.getNameInfo(node.getAtom(), nskUnknown) pident = nimState.getIdent(name, pinfo, exported = false) if value.len == 0: @@ -121,7 +122,7 @@ proc newPragma(nimState: NimState, node: TSNode, pragmas: Table[string, string]) colExpr.add pvalue result.add colExpr -proc newPragmaExpr(nimState: NimState, node: TSNode, ident: PNode, pragmas: Table[string, string]): PNode = +proc newPragmaExpr(nimState: NimState, node: TSNode, ident: PNode, pragmas: OrderedTable[string, string]): PNode = # Create nkPragmaExpr tree # # nkPragmaExpr( @@ -155,7 +156,7 @@ proc newTypeIdent(nimState: NimState, node: TSNode, override = "", union = false nimState.getIdent(name, info) prident = if union: - nimState.newPragmaExpr(node, ident, {"union": ""}.toTable()) + nimState.newPragmaExpr(node, ident, {"union": ""}.toOrderedTable()) else: ident @@ -215,7 +216,7 @@ proc newPtrTree(nimState: NimState, count: int, typ: PNode): PNode = proc newArrayTree(nimState: NimState, node: TSNode, typ, size: PNode): PNode = # Create nkBracketExpr tree depending on input let - (_, info) = nimState.getNameInfo(node, nskType) + (_, info) = nimState.getNameInfo(node.getAtom(), nskType) ident = nimState.getIdent("array", info, exported = false) # array[size, typ] @@ -264,7 +265,7 @@ proc newIdentDefs(nimState: NimState, name: string, node: TSNode, offset: SomeIn start = getStartAtom(node) # node[start] - param type - (tname, tinfo) = nimState.getNameInfo(node[start], nskType) + (tname, tinfo) = nimState.getNameInfo(node[start].getAtom(), nskType) tident = nimState.getIdent(tname, tinfo, exported = false) if start == node.len - 1: @@ -327,13 +328,21 @@ proc newIdentDefs(nimState: NimState, name: string, node: TSNode, offset: SomeIn else: result = nil -proc newProcTree(nimState: NimState, name: string, node: TSNode, rtyp: PNode): PNode = - # Create nkProcTy tree for specified proc type - let - fparam = newNode(nkFormalParams) +proc newFormalParams(nimState: NimState, name: string, node: TSNode, rtyp: PNode): PNode = + # Create nkFormalParams tree for specified params and return type + # + # proc(pname: ptyp ..): rtyp + # + # nkFormalParams( + # rtyp, + # nkIdentDefs( # multiple depending on params + # .. + # ) + # ) + result = newNode(nkFormalParams) # Add return type - fparam.add rtyp + result.add rtyp if not node.isNil: for i in 0 ..< node.len: @@ -341,7 +350,10 @@ proc newProcTree(nimState: NimState, name: string, node: TSNode, rtyp: PNode): P let param = nimState.newIdentDefs(name, node[i], i, exported = false) if not param.isNil: - fparam.add param + result.add param + +proc newProcTy(nimState: NimState, name: string, node: TSNode, rtyp: PNode): PNode = + # Create nkProcTy tree for specified proc type # proc(pname: ptyp ..): rtyp # @@ -355,7 +367,7 @@ proc newProcTree(nimState: NimState, name: string, node: TSNode, rtyp: PNode): P # nkEmpty() # ) result = newNode(nkProcTy) - result.add fparam + result.add nimState.newFormalParams(name, node, rtyp) result.add newNode(nkEmpty) proc newRecListTree(nimState: NimState, name: string, node: TSNode): PNode = @@ -600,7 +612,7 @@ proc getTypeProc(nimState: NimState, name: string, node: TSNode): PNode = retType = nimState.newPtrTree(tcount, retType) # Proc with return type and params - result = nimState.newProcTree(name, plist, retType) + result = nimState.newProcTy(name, plist, retType) if ncount > 1: result = nimState.newPtrTree(ncount-1, result) @@ -850,9 +862,77 @@ proc addEnum(nimState: NimState, node: TSNode) = nimState.printDebug(node) proc addProc(nimState: NimState, node: TSNode) = + # Add a proc decho("addProc()") nimState.printDebug(node) + let + start = getStartAtom(node) + + # node[start] = identifier = return type name + (rname, rinfo) = nimState.getNameInfo(node[start].getAtom(), nskType) + + # Parameter list + plist = node[start+1].anyChildInTree("parameter_list") + + # node[start+1] = identifier = name + # TODO - check blank and override + ident = nimState.newTypeIdent(node[start+1]) + name = $ident[0][1] + + # node[start+1] could have nested pointers + tcount = node[start+1].getPtrCount() + + procDef = newNode(nkProcDef) + + # proc X(a1: Y, a2: Z): P {.pragma.} + # + # nkProcDef( + # nkPostfix( + # nkIdent("*"), + # nkIdent("X") + # ), + # nkEmpty(), + # nkEmpty(), + # nkFormalParams( + # nkPtrTy( # optional, nested + # nkIdent(retType) + # ), + # nkIdentDefs( + # nkIdent(param), + # nkPtrTy( + # nkIdent(ptype) + # ), + # nkEmpty() + # ), + # ... + # ), + # nkPragma(...), + # nkEmpty(), + # nkEmpty() + # ) + + procDef.add ident + procDef.add newNode(nkEmpty) + procDef.add newNode(nkEmpty) + + # Return type + var + retType = nimState.getIdent(rname, rinfo, exported = false) + if tcount > 0: + retType = nimState.newPtrTree(tcount, retType) + + # Proc with return type and params + procDef.add nimState.newFormalParams(name, plist, retType) + procDef.add newNode(nkEmpty) # Pragmas + procDef.add newNode(nkEmpty) + procDef.add newNode(nkEmpty) + + # nkProcSection.add + nimState.procSection.add procDef + + nimState.printDebug(procDef) + proc processNode(nimState: NimState, node: TSNode): bool = result = true @@ -926,14 +1006,15 @@ import nimterop/types """ % [$now(), getAppFilename(), commandLineParams().join(" ")] proc printNim*(gState: State, fullpath: string, root: TSNode) = - var + let nimState = new(NimState) - #fp = fullpath.replace("\\", "/") + fp = fullpath.replace("\\", "/") nimState.identifiers = newTable[string, string]() nimState.gState = gState nimState.currentHeader = getCurrentHeader(fullpath) + nimState.impShort = nimState.currentHeader.replace("header", "imp") nimState.sourceFile = fullpath # Nim compiler objects diff --git a/tests/include/tast2.h b/tests/include/tast2.h index 90e96c6..200b4c8 100644 --- a/tests/include/tast2.h +++ b/tests/include/tast2.h @@ -40,3 +40,5 @@ typedef union U2 { int **f1; int abc[123+132]; } U2; // Anonymous //typedef struct { char a1; }; + +struct A2 test_proc1(struct A0 a); \ No newline at end of file From 795f607e96a3228b9daa6dd6384fa63dab35c14e Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 17 Mar 2020 17:19:47 -0500 Subject: [PATCH 341/593] newConstDef for header --- nimterop/ast2.nim | 67 +++++++++++++++++++++++++++++------------------ 1 file changed, 42 insertions(+), 25 deletions(-) diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index 8c2fc3f..536ef9b 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -50,6 +50,42 @@ proc getLit*(nimState: NimState, str: string): PNode = if result.isNil: result = newNode(nkNilLit) +proc newConstDef(nimState: NimState, node: TSNode, name = "", val = ""): PNode = + let + # node[0] = identifier = const name + (cname, info) = nimState.getNameInfo(node.getAtom(), nskConst) + + # TODO - check blank and override + ident = + if name.len != 0: + nimState.getIdent(name, info) + else: + nimState.getIdent(cname, info) + + # node[1] = preproc_arg = value + nval = + if val.len != 0: + newStrNode(nkStrLit, val) + else: + nimState.getLit(nimState.getNodeVal(node[1])) + + # If supported literal + if nval.kind != nkNilLit: + # const X* = Y + # + # nkConstDef( + # nkPostfix( + # nkIdent("*"), + # nkIdent("X") + # ), + # nkEmpty(), + # nkXLit(Y) + # ) + result = newNode(nkConstDef) + result.add ident + result.add newNode(nkEmpty) + result.add nval + proc addConst(nimState: NimState, node: TSNode) = # #define X Y # @@ -63,32 +99,9 @@ proc addConst(nimState: NimState, node: TSNode) = if node[0].getName() == "identifier" and node[1].getName() == "preproc_arg": let - constDef = newNode(nkConstDef) - - # node[0] = identifier = const name - (name, info) = nimState.getNameInfo(node.getAtom(), nskConst) - # TODO - check blank and override - ident = nimState.getIdent(name, info) - - # node[1] = preproc_arg = value - val = nimState.getLit(nimState.getNodeVal(node[1])) - - # If supported literal - if val.kind != nkNilLit: - # const X* = Y - # - # nkConstDef( - # nkPostfix( - # nkIdent("*"), - # nkIdent("X") - # ), - # nkEmpty(), - # nkXLit(Y) - # ) - constDef.add ident - constDef.add newNode(nkEmpty) - constDef.add val + constDef = nimState.newConstDef(node) + if not constDef.isNil: # nkConstSection.add nimState.constSection.add constDef @@ -1027,6 +1040,10 @@ proc printNim*(gState: State, fullpath: string, root: TSNode) = nimState.procSection = newNode(nkStmtList) nimState.typeSection = newNode(nkTypeSection) + if nimState.gState.dynlib.Bl and nimState.gState.includeHeader: + nimState.constSection.add nimState.newConstDef( + root, name = nimState.currentHeader, val = fp) + nimState.searchTree(root) var From 2d45c6adf609994046396f8e574fab8534bcfa6e Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 17 Mar 2020 23:43:47 -0500 Subject: [PATCH 342/593] Initial ast2 pragma support --- nimterop/ast.nim | 38 ++++++++++++++++++++- nimterop/ast2.nim | 78 ++++++++++++++++++++++++++++++++------------ nimterop/getters.nim | 43 +++++------------------- nimterop/globals.nim | 2 +- nimterop/grammar.nim | 6 ++-- 5 files changed, 107 insertions(+), 60 deletions(-) diff --git a/nimterop/ast.nim b/nimterop/ast.nim index e28241f..06b0504 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -4,6 +4,42 @@ import regex import "."/[getters, globals, treesitter/api] +proc getHeaderPragma*(nimState: NimState): string = + result = + if nimState.includeHeader(): + &", header: {nimState.currentHeader}" + else: + "" + +proc getDynlib*(nimState: NimState): string = + result = + if nimState.gState.dynlib.nBl: + &", dynlib: {nimState.gState.dynlib}" + else: + "" + +proc getImportC*(nimState: NimState, origName, nimName: string): string = + if nimName != origName: + result = &"importc: \"{origName}\"{nimState.getHeaderPragma()}" + else: + result = nimState.impShort + +proc getPragma*(nimState: NimState, pragmas: varargs[string]): string = + result = "" + for pragma in pragmas.items(): + if pragma.nBl: + result &= pragma & ", " + if result.nBl: + result = " {." & result[0 .. ^3] & ".}" + + result = result.replace(nimState.impShort & ", cdecl", nimState.impShort & "C") + + let + dy = nimState.getDynlib() + + if ", cdecl" in result and dy.nBl: + result = result.replace(".}", dy & ".}") + proc saveNodeData(node: TSNode, nimState: NimState): bool = let name = $node.tsNodeType() @@ -178,7 +214,7 @@ proc printNim*(gState: State, fullpath: string, root: TSNode, astTable: AstTable nimState.impShort = nimState.currentHeader.replace("header", "imp") nimState.sourceFile = fullpath - if nimState.gState.dynlib.Bl and nimState.gState.includeHeader: + if nimState.includeHeader(): nimState.constStr &= &"\n {nimState.currentHeader} {{.used.}} = \"{fp}\"" root.searchAst(astTable, nimState) diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index 536ef9b..8804c53 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -107,7 +107,23 @@ proc addConst(nimState: NimState, node: TSNode) = nimState.printDebug(constDef) -proc newPragma(nimState: NimState, node: TSNode, pragmas: OrderedTable[string, string]): PNode = +proc addPragma(nimState: NimState, node: TSNode, pragma: PNode, pragmas: OrderedTable[string, PNode]) = + # Add pragmas to an existing nkPragma tree + for name, value in pragmas.pairs: + let + (_, pinfo) = nimState.getNameInfo(node.getAtom(), nskUnknown) + pident = nimState.getIdent(name, pinfo, exported = false) + + if value.isNil: + pragma.add pident + else: + let + colExpr = newNode(nkExprColonExpr) + colExpr.add pident + colExpr.add value + pragma.add colExpr + +proc newPragma(nimState: NimState, node: TSNode, pragmas: OrderedTable[string, PNode]): PNode = # Create nkPragma tree for name:value # # {.name1, name2: value2.} @@ -120,22 +136,9 @@ proc newPragma(nimState: NimState, node: TSNode, pragmas: OrderedTable[string, s # ) # ) result = newNode(nkPragma) - for name, value in pragmas.pairs: - let - (_, pinfo) = nimState.getNameInfo(node.getAtom(), nskUnknown) - pident = nimState.getIdent(name, pinfo, exported = false) - - if value.len == 0: - result.add pident - else: - let - colExpr = newNode(nkExprColonExpr) - pvalue = newStrNode(nkStrLit, value) - colExpr.add pident - colExpr.add pvalue - result.add colExpr + nimState.addPragma(node, result, pragmas) -proc newPragmaExpr(nimState: NimState, node: TSNode, ident: PNode, pragmas: OrderedTable[string, string]): PNode = +proc newPragmaExpr(nimState: NimState, node: TSNode, ident: PNode, pragmas: OrderedTable[string, PNode]): PNode = # Create nkPragmaExpr tree # # nkPragmaExpr( @@ -169,7 +172,9 @@ proc newTypeIdent(nimState: NimState, node: TSNode, override = "", union = false nimState.getIdent(name, info) prident = if union: - nimState.newPragmaExpr(node, ident, {"union": ""}.toOrderedTable()) + var + empty: PNode + nimState.newPragmaExpr(node, ident, {"union": empty}.toOrderedTable()) else: ident @@ -1008,6 +1013,39 @@ proc searchTree(nimState: NimState, root: TSNode) = if node == root: break +proc setupPragmas(nimState: NimState, root: TSNode, fullpath: string) = + var + impPragma = newNode(nkPragma) + impCPragma = newNode(nkPragma) + empty: PNode + + nimState.addPragma(root, impPragma, { + "pragma": nimState.getIdent(nimState.impShort), + "importc": empty + }.toOrderedTable()) + + if nimState.includeHeader(): + nimState.constSection.add nimState.newConstDef( + root, name = nimState.currentHeader, val = fullpath) + + nimState.addPragma(root, impPragma, { + "header": newStrNode(nkStrLit, nimState.currentHeader) + }.toOrderedTable()) + + nimState.addPragma(root, impCPragma, { + "pragma": nimState.getIdent(nimState.impShort & "C"), + nimState.impShort: empty, + "cdecl": empty + }.toOrderedTable()) + + if nimState.gState.dynlib.nBl: + nimState.addPragma(root, impCPragma, { + "dynlib": nimState.getIdent(nimState.gState.dynlib) + }.toOrderedTable()) + + nimState.pragmaSection.add impPragma + nimState.pragmaSection.add impCPragma + proc printNimHeader*(gState: State) = gecho """# Generated at $1 # Command line: @@ -1035,19 +1073,19 @@ proc printNim*(gState: State, fullpath: string, root: TSNode) = nimState.config = newConfigRef() nimstate.graph = newModuleGraph(nimState.identCache, nimState.config) + nimState.pragmaSection = newNode(nkStmtList) nimState.constSection = newNode(nkConstSection) nimState.enumSection = newNode(nkStmtList) nimState.procSection = newNode(nkStmtList) nimState.typeSection = newNode(nkTypeSection) - if nimState.gState.dynlib.Bl and nimState.gState.includeHeader: - nimState.constSection.add nimState.newConstDef( - root, name = nimState.currentHeader, val = fp) + nimState.setupPragmas(root, fp) nimState.searchTree(root) var tree = newNode(nkStmtList) + tree.add nimState.pragmaSection tree.add nimState.enumSection tree.add nimState.constSection tree.add nimState.typeSection diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 2c7da75..07ed194 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -426,6 +426,9 @@ proc printDebug*(nimState: NimState, pnode: PNode) = # Compiler shortcuts +proc getDefaultLineInfo*(nimState: NimState): TLineInfo = + result = newLineInfo(nimState.config, nimState.sourceFile.AbsoluteFile, -1, -1) + proc getLineInfo*(nimState: NimState, node: TSNode): TLineInfo = # Get Nim equivalent line:col info from node let @@ -446,6 +449,9 @@ proc getIdent*(nimState: NimState, name: string, info: TLineInfo, exported = tru else: result = newIdentNode(ident, info) +proc getIdent*(nimState: NimState, name: string): PNode = + nimState.getIdent(name, nimState.getDefaultLineInfo(), exported = false) + proc getNameInfo*(nimState: NimState, node: TSNode, kind: NimSymKind, parent = ""): tuple[name: string, info: TLineInfo] = # Shortcut to get identifier name and info (node value and line:col) @@ -648,41 +654,8 @@ proc getSplitComma*(joined: seq[string]): seq[string] = for i in joined: result = result.concat(i.split(",")) -proc getHeaderPragma*(nimState: NimState): string = - result = - if nimState.gState.dynlib.Bl and nimState.gState.includeHeader: - &", header: {nimState.currentHeader}" - else: - "" - -proc getDynlib*(nimState: NimState): string = - result = - if nimState.gState.dynlib.nBl: - &", dynlib: {nimState.gState.dynlib}" - else: - "" - -proc getImportC*(nimState: NimState, origName, nimName: string): string = - if nimName != origName: - result = &"importc: \"{origName}\"{nimState.getHeaderPragma()}" - else: - result = nimState.impShort - -proc getPragma*(nimState: NimState, pragmas: varargs[string]): string = - result = "" - for pragma in pragmas.items(): - if pragma.nBl: - result &= pragma & ", " - if result.nBl: - result = " {." & result[0 .. ^3] & ".}" - - result = result.replace(nimState.impShort & ", cdecl", nimState.impShort & "C") - - let - dy = nimState.getDynlib() - - if ", cdecl" in result and dy.nBl: - result = result.replace(".}", dy & ".}") +template includeHeader*(nimState: NimState): bool = + nimState.gState.dynlib.Bl and nimState.gState.includeHeader proc getComments*(nimState: NimState, strip = false): string = if not nimState.gState.nocomments and nimState.commentStr.nBl: diff --git a/nimterop/globals.nim b/nimterop/globals.nim index ba63a76..2fb543b 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -78,7 +78,7 @@ type # Nim compiler objects when not declared(CIMPORT): - constSection*, enumSection*, procSection*, typeSection*: PNode + pragmaSection*, constSection*, enumSection*, procSection*, typeSection*: PNode identCache*: IdentCache config*: ConfigRef graph*: ModuleGraph diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index f15c2f8..2e6b585 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -2,7 +2,7 @@ import macros, strformat, strutils, tables import regex -import "."/[getters, globals, lisp, treesitter/api] +import "."/[ast, getters, globals, lisp, treesitter/api] type Grammar = seq[tuple[grammar: string, call: proc(ast: ref Ast, node: TSNode, nimState: NimState) {.nimcall.}]] @@ -200,7 +200,7 @@ proc initGrammar(): Grammar = nname = nimState.getIdentifier(name, nskType) i += 1 - if nimState.gState.dynlib.Bl and nimState.gState.includeHeader: + if nimState.includeHeader(): pragmas.add nimState.getImportC(name, nname) let @@ -316,7 +316,7 @@ proc initGrammar(): Grammar = else: var pragmas: seq[string] = @[] - if nimState.gState.dynlib.Bl and nimState.gState.includeHeader: + if nimState.includeHeader(): pragmas.add nimState.getImportC(prefix & name, nname) pragmas.add "bycopy" if union.nBl: From 8fadeeb76c9101fa7333e684c1e65d19b4d03f99 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 18 Mar 2020 13:34:14 -0500 Subject: [PATCH 343/593] Clean up ast2 pragma procs --- nimterop/ast2.nim | 72 +++++++++++++++++++++++++---------------------- 1 file changed, 38 insertions(+), 34 deletions(-) diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index 8804c53..4539f79 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -107,23 +107,27 @@ proc addConst(nimState: NimState, node: TSNode) = nimState.printDebug(constDef) +proc addPragma(nimState: NimState, node: TSNode, pragma: PNode, name: string, value: PNode = nil) = + # Add pragma to an existing nkPragma tree + let + (_, pinfo) = nimState.getNameInfo(node.getAtom(), nskUnknown) + pident = nimState.getIdent(name, pinfo, exported = false) + + if value.isNil: + pragma.add pident + else: + let + colExpr = newNode(nkExprColonExpr) + colExpr.add pident + colExpr.add value + pragma.add colExpr + proc addPragma(nimState: NimState, node: TSNode, pragma: PNode, pragmas: OrderedTable[string, PNode]) = # Add pragmas to an existing nkPragma tree for name, value in pragmas.pairs: - let - (_, pinfo) = nimState.getNameInfo(node.getAtom(), nskUnknown) - pident = nimState.getIdent(name, pinfo, exported = false) - - if value.isNil: - pragma.add pident - else: - let - colExpr = newNode(nkExprColonExpr) - colExpr.add pident - colExpr.add value - pragma.add colExpr + nimState.addPragma(node, pragma, name, value) -proc newPragma(nimState: NimState, node: TSNode, pragmas: OrderedTable[string, PNode]): PNode = +proc newPragma(nimState: NimState, node: TSNode, name: string, value: PNode = nil): PNode = # Create nkPragma tree for name:value # # {.name1, name2: value2.} @@ -136,10 +140,15 @@ proc newPragma(nimState: NimState, node: TSNode, pragmas: OrderedTable[string, P # ) # ) result = newNode(nkPragma) + nimState.addPragma(node, result, name, value) + +proc newPragma(nimState: NimState, node: TSNode, pragmas: OrderedTable[string, PNode]): PNode = + # Create nkPragma tree for multiple name:value + result = newNode(nkPragma) nimState.addPragma(node, result, pragmas) -proc newPragmaExpr(nimState: NimState, node: TSNode, ident: PNode, pragmas: OrderedTable[string, PNode]): PNode = - # Create nkPragmaExpr tree +proc newPragmaExpr(nimState: NimState, node: TSNode, ident: PNode, name: string, value: PNode = nil): PNode = + # Create nkPragmaExpr tree for name:value # # nkPragmaExpr( # nkPostfix( @@ -156,6 +165,12 @@ proc newPragmaExpr(nimState: NimState, node: TSNode, ident: PNode, pragmas: Orde # ) result = newNode(nkPragmaExpr) result.add ident + result.add nimState.newPragma(node, name, value) + +proc newPragmaExpr(nimState: NimState, node: TSNode, ident: PNode, pragmas: OrderedTable[string, PNode]): PNode = + # Create nkPragmaExpr tree for multiple name:value + result = newNode(nkPragmaExpr) + result.add ident result.add nimState.newPragma(node, pragmas) proc newTypeIdent(nimState: NimState, node: TSNode, override = "", union = false): PNode = @@ -172,9 +187,7 @@ proc newTypeIdent(nimState: NimState, node: TSNode, override = "", union = false nimState.getIdent(name, info) prident = if union: - var - empty: PNode - nimState.newPragmaExpr(node, ident, {"union": empty}.toOrderedTable()) + nimState.newPragmaExpr(node, ident, "union") else: ident @@ -1017,31 +1030,22 @@ proc setupPragmas(nimState: NimState, root: TSNode, fullpath: string) = var impPragma = newNode(nkPragma) impCPragma = newNode(nkPragma) - empty: PNode - nimState.addPragma(root, impPragma, { - "pragma": nimState.getIdent(nimState.impShort), - "importc": empty - }.toOrderedTable()) + nimState.addPragma(root, impPragma, "pragma", nimState.getIdent(nimState.impShort)) + nimState.addPragma(root, impPragma, "importc") if nimState.includeHeader(): nimState.constSection.add nimState.newConstDef( root, name = nimState.currentHeader, val = fullpath) - nimState.addPragma(root, impPragma, { - "header": newStrNode(nkStrLit, nimState.currentHeader) - }.toOrderedTable()) + nimState.addPragma(root, impPragma, "header", newStrNode(nkStrLit, nimState.currentHeader)) - nimState.addPragma(root, impCPragma, { - "pragma": nimState.getIdent(nimState.impShort & "C"), - nimState.impShort: empty, - "cdecl": empty - }.toOrderedTable()) + nimState.addPragma(root, impCPragma, "pragma", nimState.getIdent(nimState.impShort & "C")) + nimState.addPragma(root, impCPragma, nimState.impShort) + nimState.addPragma(root, impCPragma, "cdecl") if nimState.gState.dynlib.nBl: - nimState.addPragma(root, impCPragma, { - "dynlib": nimState.getIdent(nimState.gState.dynlib) - }.toOrderedTable()) + nimState.addPragma(root, impCPragma, "dynlib", nimState.getIdent(nimState.gState.dynlib)) nimState.pragmaSection.add impPragma nimState.pragmaSection.add impCPragma From 0d1445a8ac26bd842edf491a780fffc515fa1066 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 18 Mar 2020 23:47:00 -0500 Subject: [PATCH 344/593] ast2 getNameInfo cleanup, initial skip/override support --- nimterop/ast2.nim | 155 +++++++++++++++++++++++++----------------- nimterop/getters.nim | 35 +++++----- tests/include/tast2.h | 4 +- tests/tast2.nim | 3 +- 4 files changed, 116 insertions(+), 81 deletions(-) diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index 4539f79..80e409e 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -50,27 +50,55 @@ proc getLit*(nimState: NimState, str: string): PNode = if result.isNil: result = newNode(nkNilLit) -proc newConstDef(nimState: NimState, node: TSNode, name = "", val = ""): PNode = +proc getOverrideOrSkip(nimState: NimState, node: TSNode, origname: string, kind: NimSymKind): PNode = + let + override = nimState.getOverride(origname, kind) + def = + if kind == nskConst: + nkConstDef + elif kind == nskType: + nkTypeDef + else: + nkEmpty + skind = + if kind == nskConst: + "const " + elif kind == nskType: + "type " + else: + "" + if override.nBl: + result = newNode(def) + result.add nimState.parseString(nimState.getComments()) + result.add nimState.parseString(skind & override)[0] + else: + result = nimState.parseString(nimState.getComments()) + result.add nimState.parseString(&" # $1'{origname}' skipped" % skind) + if nimState.gState.debug: + nimState.skipStr &= &"\n{nimState.getNodeVal(node)}" + +proc newConstDef(nimState: NimState, node: TSNode, fname = "", fval = ""): PNode = let # node[0] = identifier = const name - (cname, info) = nimState.getNameInfo(node.getAtom(), nskConst) + (name, origname, info) = nimState.getNameInfo(node.getAtom(), nskConst) - # TODO - check blank and override ident = - if name.len != 0: - nimState.getIdent(name, info) + if fname.nBl: + nimState.getIdent(fname, info) else: - nimState.getIdent(cname, info) + nimState.getIdent(name, info) # node[1] = preproc_arg = value - nval = - if val.len != 0: - newStrNode(nkStrLit, val) + val = + if fval.nBl: + newStrNode(nkStrLit, fval) else: nimState.getLit(nimState.getNodeVal(node[1])) - # If supported literal - if nval.kind != nkNilLit: + if name.Bl and fname.Bl: + # Name skipped or overridden since blank + result = nimState.getOverrideOrSkip(node, origname, nskConst) + elif val.kind != nkNilLit and nimState.addNewIdentifer(name): # const X* = Y # # nkConstDef( @@ -84,7 +112,7 @@ proc newConstDef(nimState: NimState, node: TSNode, name = "", val = ""): PNode = result = newNode(nkConstDef) result.add ident result.add newNode(nkEmpty) - result.add nval + result.add val proc addConst(nimState: NimState, node: TSNode) = # #define X Y @@ -110,7 +138,7 @@ proc addConst(nimState: NimState, node: TSNode) = proc addPragma(nimState: NimState, node: TSNode, pragma: PNode, name: string, value: PNode = nil) = # Add pragma to an existing nkPragma tree let - (_, pinfo) = nimState.getNameInfo(node.getAtom(), nskUnknown) + pinfo = nimState.getLineInfo(node.getAtom()) pident = nimState.getIdent(name, pinfo, exported = false) if value.isNil: @@ -173,36 +201,41 @@ proc newPragmaExpr(nimState: NimState, node: TSNode, ident: PNode, pragmas: Orde result.add ident result.add nimState.newPragma(node, pragmas) -proc newTypeIdent(nimState: NimState, node: TSNode, override = "", union = false): PNode = +proc newTypeIdent(nimState: NimState, node: TSNode, fname = "", union = false): PNode = # Create nkTypeDef PNode with first ident # - # If `override`, use it instead of node.getAtom() for name + # If `fname`, use it instead of node.getAtom() for name let - (name, info) = nimState.getNameInfo(node.getAtom(), nskType) - # TODO - check blank and override + (name, origname, info) = nimState.getNameInfo(node.getAtom(), nskType) + ident = - if override.len != 0: - nimState.getIdent(override, info) + if fname.nBl: + nimState.getIdent(fname, info) else: nimState.getIdent(name, info) + prident = if union: nimState.newPragmaExpr(node, ident, "union") else: ident - # type name* = - # - # nkTypeDef( - # nkPostfix( - # nkIdent("*"), - # nkIdent(name) - # ), - # nkEmpty() - # ) - result = newNode(nkTypeDef) - result.add prident - result.add newNode(nkEmpty) + if name.Bl and fname.Bl: + # Name skipped or overridden since blank + result = nimState.getOverrideOrSkip(node, origname, nskType) + else: + # type name* = + # + # nkTypeDef( + # nkPostfix( + # nkIdent("*"), + # nkIdent(name) + # ), + # nkEmpty() + # ) + result = newNode(nkTypeDef) + result.add prident + result.add newNode(nkEmpty) proc newPtrTree(nimState: NimState, count: int, typ: PNode): PNode = # Create nkPtrTy tree depending on count @@ -247,7 +280,7 @@ proc newPtrTree(nimState: NimState, count: int, typ: PNode): PNode = proc newArrayTree(nimState: NimState, node: TSNode, typ, size: PNode): PNode = # Create nkBracketExpr tree depending on input let - (_, info) = nimState.getNameInfo(node.getAtom(), nskType) + info = nimState.getLineInfo(node.getAtom()) ident = nimState.getIdent("array", info, exported = false) # array[size, typ] @@ -296,7 +329,7 @@ proc newIdentDefs(nimState: NimState, name: string, node: TSNode, offset: SomeIn start = getStartAtom(node) # node[start] - param type - (tname, tinfo) = nimState.getNameInfo(node[start].getAtom(), nskType) + (tname, _, tinfo) = nimState.getNameInfo(node[start].getAtom(), nskType, parent = name) tident = nimState.getIdent(tname, tinfo, exported = false) if start == node.len - 1: @@ -330,7 +363,7 @@ proc newIdentDefs(nimState: NimState, name: string, node: TSNode, offset: SomeIn else: # Named param, simple type let - (pname, pinfo) = nimState.getNameInfo(node[start+1].getAtom(), nskField, parent = name) + (pname, _, pinfo) = nimState.getNameInfo(node[start+1].getAtom(), nskField, parent = name) pident = nimState.getIdent(pname, pinfo, exported) count = node[start+1].getPtrCount() @@ -343,7 +376,7 @@ proc newIdentDefs(nimState: NimState, name: string, node: TSNode, offset: SomeIn elif not fdecl.isNil: # Named param, function pointer let - (pname, pinfo) = nimState.getNameInfo(node[start+1].getAtom(), nskField, parent = name) + (pname, _, pinfo) = nimState.getNameInfo(node[start+1].getAtom(), nskField, parent = name) pident = nimState.getIdent(pname, pinfo, exported) result.add pident result.add nimState.getTypeProc(name, node) @@ -351,7 +384,7 @@ proc newIdentDefs(nimState: NimState, name: string, node: TSNode, offset: SomeIn elif not adecl.isNil: # Named param, array type let - (pname, pinfo) = nimState.getNameInfo(node[start+1].getAtom(), nskField, parent = name) + (pname, _, pinfo) = nimState.getNameInfo(node[start+1].getAtom(), nskField, parent = name) pident = nimState.getIdent(pname, pinfo, exported) result.add pident result.add nimState.getTypeArray(node) @@ -421,15 +454,14 @@ proc newRecListTree(nimState: NimState, name: string, node: TSNode): PNode = if not field.isNil: result.add field -proc addTypeObject(nimState: NimState, node: TSNode, override = "", duplicate = "", union = false) = +proc addTypeObject(nimState: NimState, node: TSNode, fname = "", duplicate = "", union = false) = # Add a type of object # - # If `override` is set, use it as the name + # If `fname` is set, use it as the name # If `duplicate` is set, don't add the same name decho("addTypeObject()") let - # TODO - check blank and override - typeDef = nimState.newTypeIdent(node, override, union = union) + typeDef = nimState.newTypeIdent(node, fname, union = union) name = $typeDef[0][1] if name != duplicate: @@ -467,10 +499,10 @@ proc addTypeObject(nimState: NimState, node: TSNode, override = "", duplicate = nimState.printDebug(typeDef) -proc addTypeTyped(nimState: NimState, node: TSNode, toverride = "", duplicate = "") = +proc addTypeTyped(nimState: NimState, node: TSNode, ftname = "", duplicate = "") = # Add a type of a specified type # - # If `toverride` is set, use it as the type name + # If `ftname` is set, use it as the type name # If `duplicate` is set, don't add the same name decho("addTypeTyped()") let @@ -479,14 +511,18 @@ proc addTypeTyped(nimState: NimState, node: TSNode, toverride = "", duplicate = # Add a type of a specific type let # node[i] = identifer = name - # TODO - check blank and override typeDef = nimState.newTypeIdent(node[i]) + name = $typeDef[0][1] # node[start] = identifier = type name - (tname0, tinfo) = nimState.getNameInfo(node[start].getAtom(), nskType) + (tname0, _, tinfo) = nimState.getNameInfo(node[start].getAtom(), nskType, parent = name) # Override type name - tname = if toverride.len != 0: toverride else: tname0 + tname = + if ftname.nBl: + ftname + else: + tname0 ident = nimState.getIdent(tname, tinfo, exported = false) @@ -527,7 +563,7 @@ proc getTypeArray(nimState: NimState, node: TSNode): PNode = start = getStartAtom(node) # node[start] = identifier = type name - (name, info) = nimState.getNameInfo(node[start].getAtom(), nskType) + (name, origname, info) = nimState.getNameInfo(node[start].getAtom(), nskType) ident = nimState.getIdent(name, info, exported = false) # Top-most array declarator @@ -578,7 +614,6 @@ proc addTypeArray(nimState: NimState, node: TSNode) = decho("addTypeArray()") let # node[1] = identifer = name - # TODO - check blank and override typeDef = nimState.newTypeIdent(node[1]) typ = nimState.getTypeArray(node) @@ -613,7 +648,7 @@ proc getTypeProc(nimState: NimState, name: string, node: TSNode): PNode = # Create proc type tree let # node[0] = identifier = return type name - (rname, rinfo) = nimState.getNameInfo(node[0].getAtom(), nskType) + (rname, _, rinfo) = nimState.getNameInfo(node[0].getAtom(), nskType, parent = name) # Parameter list plist = node[1].anyChildInTree("parameter_list") @@ -652,7 +687,6 @@ proc addTypeProc(nimState: NimState, node: TSNode) = decho("addTypeProc()") let # node[1] = identifier = name - # TODO - check blank and override typeDef = nimState.newTypeIdent(node[1]) name = $typeDef[0][1] @@ -732,7 +766,7 @@ proc addType(nimState: NimState, node: TSNode, union = false) = if node.len >= 2: let fdlist = node[0].anyChildInTree("field_declaration_list") - if (fdlist.isNil or (not fdlist.isNil and fdlist.len == 0)) and + if (fdlist.isNil or (not fdlist.isNil and fdlist.Bl)) and nimState.getNodeVal(node[1]) == "": # typedef struct X; # @@ -882,11 +916,11 @@ proc addType(nimState: NimState, node: TSNode, union = false) = name # Now add struct as object with specified name - nimState.addTypeObject(node[0], override = name, union = union) + nimState.addTypeObject(node[0], fname = name, union = union) - if name.len != 0: + if name.nBl: # Add any additional names except duplicate - nimState.addTypeTyped(node, toverride = name, duplicate = name) + nimState.addTypeTyped(node, ftname = name, duplicate = name) proc addEnum(nimState: NimState, node: TSNode) = decho("addEnum()") @@ -900,20 +934,19 @@ proc addProc(nimState: NimState, node: TSNode) = let start = getStartAtom(node) - # node[start] = identifier = return type name - (rname, rinfo) = nimState.getNameInfo(node[start].getAtom(), nskType) - - # Parameter list - plist = node[start+1].anyChildInTree("parameter_list") - # node[start+1] = identifier = name - # TODO - check blank and override ident = nimState.newTypeIdent(node[start+1]) name = $ident[0][1] # node[start+1] could have nested pointers tcount = node[start+1].getPtrCount() + # node[start] = identifier = return type name + (rname, _, rinfo) = nimState.getNameInfo(node[start].getAtom(), nskType, parent = name) + + # Parameter list + plist = node[start+1].anyChildInTree("parameter_list") + procDef = newNode(nkProcDef) # proc X(a1: Y, a2: Z): P {.pragma.} @@ -1036,7 +1069,7 @@ proc setupPragmas(nimState: NimState, root: TSNode, fullpath: string) = if nimState.includeHeader(): nimState.constSection.add nimState.newConstDef( - root, name = nimState.currentHeader, val = fullpath) + root, fname = nimState.currentHeader, fval = fullpath) nimState.addPragma(root, impPragma, "header", newStrNode(nkStrLit, nimState.currentHeader)) diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 07ed194..736e0db 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -437,30 +437,31 @@ proc getLineInfo*(nimState: NimState, node: TSNode): TLineInfo = result = newLineInfo(nimState.config, nimState.sourceFile.AbsoluteFile, line, col) proc getIdent*(nimState: NimState, name: string, info: TLineInfo, exported = true): PNode = - # Get ident PNode for name + info - let - exp = getIdent(nimState.identCache, "*") - ident = getIdent(nimState.identCache, name) + if name.nBl: + # Get ident PNode for name + info + let + exp = getIdent(nimState.identCache, "*") + ident = getIdent(nimState.identCache, name) - if exported: - result = newNode(nkPostfix) - result.add newIdentNode(exp, info) - result.add newIdentNode(ident, info) - else: - result = newIdentNode(ident, info) + if exported: + result = newNode(nkPostfix) + result.add newIdentNode(exp, info) + result.add newIdentNode(ident, info) + else: + result = newIdentNode(ident, info) proc getIdent*(nimState: NimState, name: string): PNode = nimState.getIdent(name, nimState.getDefaultLineInfo(), exported = false) proc getNameInfo*(nimState: NimState, node: TSNode, kind: NimSymKind, parent = ""): - tuple[name: string, info: TLineInfo] = + tuple[name, origname: string, info: TLineInfo] = # Shortcut to get identifier name and info (node value and line:col) - let - name = nimState.getNodeVal(node) - result.name = nimState.getIdentifier(name, kind, parent) - if kind == nskType: - result.name = result.name.getType() - result.info = nimState.getLineInfo(node) + result.origname = nimState.getNodeVal(node) + result.name = nimState.getIdentifier(result.origname, kind, parent) + if result.name.nBl: + if kind == nskType: + result.name = result.name.getType() + result.info = nimState.getLineInfo(node) proc getCurrentHeader*(fullpath: string): string = ("header" & fullpath.splitFile().name.multiReplace([(".", ""), ("-", "")])) diff --git a/tests/include/tast2.h b/tests/include/tast2.h index 200b4c8..7c595e4 100644 --- a/tests/include/tast2.h +++ b/tests/include/tast2.h @@ -15,7 +15,7 @@ typedef int *A6; typedef A0 **A7; typedef void *A8; -typedef char *A9[3]; +typedef char *A9p[3]; //, A9[4]; typedef char *A10[3][6]; typedef char *(*A11)[3]; @@ -41,4 +41,4 @@ typedef union U2 { int **f1; int abc[123+132]; } U2; // Anonymous //typedef struct { char a1; }; -struct A2 test_proc1(struct A0 a); \ No newline at end of file +//struct A2 test_proc1(struct A0 a); \ No newline at end of file diff --git a/tests/tast2.nim b/tests/tast2.nim index d8d18a3..9e32f6e 100644 --- a/tests/tast2.nim +++ b/tests/tast2.nim @@ -40,7 +40,8 @@ assert A6 is ptr cint assert A7 is ptr ptr A0 assert A8 is pointer -assert A9 is array[3, cstring] +assert A9p is array[3, cstring] +#assert A9 is array[4, cchar] assert A10 is array[3, array[6, cstring]] assert A11 is ptr array[3, cstring] From f01c7ea60dab54c14a9d44b359dcb025812470bc Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Fri, 20 Mar 2020 01:31:54 -0500 Subject: [PATCH 345/593] ast2 improve override/skip, duplicates --- nimterop/ast2.nim | 442 +++++++++++++++++++++++------------------- nimterop/globals.nim | 3 +- tests/include/tast2.h | 53 +++++ tests/tast2.nim | 12 +- 4 files changed, 304 insertions(+), 206 deletions(-) diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index 80e409e..95ccdd6 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -8,8 +8,6 @@ import "."/treesitter/api import "."/[globals, getters] -# Move to getters after ast2 becomes default - proc getPtrType*(str: string): string = result = case str: of "cchar": @@ -20,6 +18,7 @@ proc getPtrType*(str: string): string = str proc parseString(nimState: NimState, str: string): PNode = + # Parse a string into Nim AST result = parseString(str, nimState.identCache, nimState.config) proc getLit*(nimState: NimState, str: string): PNode = @@ -51,70 +50,86 @@ proc getLit*(nimState: NimState, str: string): PNode = result = newNode(nkNilLit) proc getOverrideOrSkip(nimState: NimState, node: TSNode, origname: string, kind: NimSymKind): PNode = + # Check if symbol `origname` of `kind` and `origname` has any cOverride defined + # and use that if present + # + # If not, symbol needs to be skipped - only get here if `name` is blank let + # Get cleaned name for symbol, set parent so that cOverride is ignored + name = nimState.getIdentifier(origname, kind, parent = "override") + override = nimState.getOverride(origname, kind) - def = - if kind == nskConst: - nkConstDef - elif kind == nskType: - nkTypeDef - else: - nkEmpty skind = if kind == nskConst: "const " elif kind == nskType: "type " + elif kind == nskProc: + "proc " else: "" + if override.nBl: - result = newNode(def) - result.add nimState.parseString(nimState.getComments()) - result.add nimState.parseString(skind & override)[0] + result = nimState.parseString(skind & override.replace(origname, name))[0][0] else: - result = nimState.parseString(nimState.getComments()) - result.add nimState.parseString(&" # $1'{origname}' skipped" % skind) + necho &"\n# $1'{origname}' skipped" % skind if nimState.gState.debug: nimState.skipStr &= &"\n{nimState.getNodeVal(node)}" proc newConstDef(nimState: NimState, node: TSNode, fname = "", fval = ""): PNode = + # Create an nkConstDef PNode + # + # If `fname` or `fval` are set, use them as name and val let # node[0] = identifier = const name - (name, origname, info) = nimState.getNameInfo(node.getAtom(), nskConst) + (cname, origname, info) = nimState.getNameInfo(node.getAtom(), nskConst) - ident = + name = if fname.nBl: - nimState.getIdent(fname, info) + fname else: - nimState.getIdent(name, info) + cname + ident = nimState.getIdent(name, info) # node[1] = preproc_arg = value val = + if fval.nBl: + fval + else: + nimState.getNodeVal(node[1]) + valident = if fval.nBl: newStrNode(nkStrLit, fval) else: - nimState.getLit(nimState.getNodeVal(node[1])) + nimState.getLit(val) - if name.Bl and fname.Bl: + if name.Bl: # Name skipped or overridden since blank result = nimState.getOverrideOrSkip(node, origname, nskConst) - elif val.kind != nkNilLit and nimState.addNewIdentifer(name): - # const X* = Y - # - # nkConstDef( - # nkPostfix( - # nkIdent("*"), - # nkIdent("X") - # ), - # nkEmpty(), - # nkXLit(Y) - # ) - result = newNode(nkConstDef) - result.add ident - result.add newNode(nkEmpty) - result.add val + elif valident.kind != nkNilLit: + if nimState.addNewIdentifer(name): + # const X* = Y + # + # nkConstDef( + # nkPostfix( + # nkIdent("*"), + # nkIdent("X") + # ), + # nkEmpty(), + # nkXLit(Y) + # ) + result = newNode(nkConstDef) + result.add ident + result.add newNode(nkEmpty) + result.add valident + else: + necho &"# const '{origname}' is duplicate, skipped" + else: + necho &"# const '{origname}' has invalid value '{val}'" proc addConst(nimState: NimState, node: TSNode) = + # Add a const to the AST + # # #define X Y # # (preproc_def @@ -195,7 +210,7 @@ proc newPragmaExpr(nimState: NimState, node: TSNode, ident: PNode, name: string, result.add ident result.add nimState.newPragma(node, name, value) -proc newPragmaExpr(nimState: NimState, node: TSNode, ident: PNode, pragmas: OrderedTable[string, PNode]): PNode = +proc newPragmaExpr(nimState: NimState, node: TSNode, ident: PNode, pragmas: OrderedTable[string, PNode]): PNode {.used.} = # Create nkPragmaExpr tree for multiple name:value result = newNode(nkPragmaExpr) result.add ident @@ -206,13 +221,14 @@ proc newTypeIdent(nimState: NimState, node: TSNode, fname = "", union = false): # # If `fname`, use it instead of node.getAtom() for name let - (name, origname, info) = nimState.getNameInfo(node.getAtom(), nskType) + (tname, origname, info) = nimState.getNameInfo(node.getAtom(), nskType) - ident = + name = if fname.nBl: - nimState.getIdent(fname, info) + fname else: - nimState.getIdent(name, info) + tname + ident = nimState.getIdent(name, info) prident = if union: @@ -220,10 +236,10 @@ proc newTypeIdent(nimState: NimState, node: TSNode, fname = "", union = false): else: ident - if name.Bl and fname.Bl: + if name.Bl: # Name skipped or overridden since blank result = nimState.getOverrideOrSkip(node, origname, nskType) - else: + elif nimState.addNewIdentifer(name): # type name* = # # nkTypeDef( @@ -236,6 +252,8 @@ proc newTypeIdent(nimState: NimState, node: TSNode, fname = "", union = false): result = newNode(nkTypeDef) result.add prident result.add newNode(nkEmpty) + else: + necho &"# type '{origname}' is duplicate, skipped" proc newPtrTree(nimState: NimState, count: int, typ: PNode): PNode = # Create nkPtrTy tree depending on count @@ -295,7 +313,7 @@ proc newArrayTree(nimState: NimState, node: TSNode, typ, size: PNode): PNode = result.add size result.add typ -proc getTypeArray(nimState: NimState, node: TSNode): PNode +proc getTypeArray(nimState: NimState, node: TSNode, name: string): PNode proc getTypeProc(nimState: NimState, name: string, node: TSNode): PNode proc newIdentDefs(nimState: NimState, name: string, node: TSNode, offset: SomeInteger, exported = false): PNode = @@ -387,7 +405,7 @@ proc newIdentDefs(nimState: NimState, name: string, node: TSNode, offset: SomeIn (pname, _, pinfo) = nimState.getNameInfo(node[start+1].getAtom(), nskField, parent = name) pident = nimState.getIdent(pname, pinfo, exported) result.add pident - result.add nimState.getTypeArray(node) + result.add nimState.getTypeArray(node, name) result.add newNode(nkEmpty) else: result = nil @@ -454,17 +472,20 @@ proc newRecListTree(nimState: NimState, name: string, node: TSNode): PNode = if not field.isNil: result.add field -proc addTypeObject(nimState: NimState, node: TSNode, fname = "", duplicate = "", union = false) = +proc addTypeObject(nimState: NimState, node: TSNode, typeDef: PNode = nil, fname = "", union = false) = # Add a type of object # - # If `fname` is set, use it as the name - # If `duplicate` is set, don't add the same name + # If `typeDef` is set, use it instead of creating new PNode + # If `fname` is set, use it as the name when creating new PNode decho("addTypeObject()") let - typeDef = nimState.newTypeIdent(node, fname, union = union) - name = $typeDef[0][1] + typeDef = + if typeDef.isNil: + nimState.newTypeIdent(node, fname, union = union) + else: + typeDef - if name != duplicate: + if not typeDef.isNil: # type X* = object # # nkTypeDef( @@ -480,6 +501,7 @@ proc addTypeObject(nimState: NimState, node: TSNode, fname = "", duplicate = "", # ) # ) let + name = $typeDef[0][1] obj = newNode(nkObjectTy) obj.add newNode(nkEmpty) obj.add newNode(nkEmpty) @@ -499,72 +521,75 @@ proc addTypeObject(nimState: NimState, node: TSNode, fname = "", duplicate = "", nimState.printDebug(typeDef) -proc addTypeTyped(nimState: NimState, node: TSNode, ftname = "", duplicate = "") = +proc addTypeTyped(nimState: NimState, node: TSNode, ftname = "", offset = 0) = # Add a type of a specified type # # If `ftname` is set, use it as the type name - # If `duplicate` is set, don't add the same name + # If `offset` is set, skip `offset` names, since created already decho("addTypeTyped()") let start = getStartAtom(node) - for i in start+1 ..< node.len: + for i in start+1+offset ..< node.len: # Add a type of a specific type let # node[i] = identifer = name typeDef = nimState.newTypeIdent(node[i]) - name = $typeDef[0][1] + + if not typeDef.isNil: + let + name = $typeDef[0][1] - # node[start] = identifier = type name - (tname0, _, tinfo) = nimState.getNameInfo(node[start].getAtom(), nskType, parent = name) + # node[start] = identifier = type name + (tname0, _, tinfo) = nimState.getNameInfo(node[start].getAtom(), nskType, parent = name) - # Override type name - tname = - if ftname.nBl: - ftname + # Override type name + tname = + if ftname.nBl: + ftname + else: + tname0 + + ident = nimState.getIdent(tname, tinfo, exported = false) + + # node[i] could have nested pointers + count = node[i].getPtrCount() + + # Skip typedef X X; + if $typeDef[0][1] != tname: + if count > 0: + # If pointers + typeDef.add nimState.newPtrTree(count, ident) else: - tname0 + typeDef.add ident - ident = nimState.getIdent(tname, tinfo, exported = false) + # type X* = [ptr ..] Y + # + # nkTypeDef( + # nkPostfix( + # nkIdent("*"), + # nkIdent("X") + # ), + # nkEmpty(), + # nkPtrTy( # optional, nested + # nkIdent("Y") + # ) + # ) - # node[i] could have nested pointers - count = node[i].getPtrCount() + # nkTypeSection.add + nimState.typeSection.add typeDef - # Skip typedef X X; - if $typeDef[0][1] != tname: - if count > 0: - # If pointers - typeDef.add nimState.newPtrTree(count, ident) + nimState.printDebug(typeDef) else: - typeDef.add ident + nimState.addTypeObject(node, typeDef = typeDef) - # type X* = [ptr ..] Y - # - # nkTypeDef( - # nkPostfix( - # nkIdent("*"), - # nkIdent("X") - # ), - # nkEmpty(), - # nkPtrTy( # optional, nested - # nkIdent("Y") - # ) - # ) - - # nkTypeSection.add - nimState.typeSection.add typeDef - - nimState.printDebug(typeDef) - else: - nimState.addTypeObject(node, duplicate = duplicate) - -proc getTypeArray(nimState: NimState, node: TSNode): PNode = +proc getTypeArray(nimState: NimState, node: TSNode, name: string): PNode = # Create array type tree let start = getStartAtom(node) # node[start] = identifier = type name - (name, origname, info) = nimState.getNameInfo(node[start].getAtom(), nskType) - ident = nimState.getIdent(name, info, exported = false) + (tname, _, info) = nimState.getNameInfo(node[start].getAtom(), nskType, parent = name) + ident = nimState.getIdent(tname, info, exported = false) # Top-most array declarator adecl = node[start+1].firstChildInTree("array_declarator") @@ -616,33 +641,36 @@ proc addTypeArray(nimState: NimState, node: TSNode) = # node[1] = identifer = name typeDef = nimState.newTypeIdent(node[1]) - typ = nimState.getTypeArray(node) + if not typeDef.isNil: + let + name = $typeDef[0][1] + typ = nimState.getTypeArray(node, name) - typeDef.add typ + typeDef.add typ - # type X* = [ptr] array[x, [ptr] Y] - # - # nkTypeDef( - # nkPostfix( - # nkIdent("*"), - # nkIdent("X") - # ), - # nkEmpty(), - # nkPtrTy( # optional, nested - # nkBracketExpr( - # nkIdent("array") - # nkXLit(x), - # nkPtrTy( # optional, nested - # nkIdent("Y") - # ) - # ) - # ) - # ) + # type X* = [ptr] array[x, [ptr] Y] + # + # nkTypeDef( + # nkPostfix( + # nkIdent("*"), + # nkIdent("X") + # ), + # nkEmpty(), + # nkPtrTy( # optional, nested + # nkBracketExpr( + # nkIdent("array") + # nkXLit(x), + # nkPtrTy( # optional, nested + # nkIdent("Y") + # ) + # ) + # ) + # ) - # nkTypeSection.add - nimState.typeSection.add typeDef + # nkTypeSection.add + nimState.typeSection.add typeDef - nimState.printDebug(typeDef) + nimState.printDebug(typeDef) proc getTypeProc(nimState: NimState, name: string, node: TSNode): PNode = # Create proc type tree @@ -688,44 +716,47 @@ proc addTypeProc(nimState: NimState, node: TSNode) = let # node[1] = identifier = name typeDef = nimState.newTypeIdent(node[1]) - name = $typeDef[0][1] - procTy = nimState.getTypeProc(name, node) + if not typeDef.isNil: + let + name = $typeDef[0][1] - typeDef.add procTy + procTy = nimState.getTypeProc(name, node) - # type X* = proc(a1: Y, a2: Z): P - # - # nkTypeDef( - # nkPostfix( - # nkIdent("*"), - # nkIdent("X") - # ), - # nkEmpty(), - # nkPtrTy( # optional, nested - # nkProcTy( - # nkFormalParams( - # nkPtrTy( # optional, nested - # nkIdent(retType) - # ), - # nkIdentDefs( - # nkIdent(param), - # nkPtrTy( - # nkIdent(ptype) - # ), - # nkEmpty() - # ), - # ... - # ), - # nkEmpty() - # ) - # ) - # ) + typeDef.add procTy - # nkTypeSection.add - nimState.typeSection.add typeDef + # type X* = proc(a1: Y, a2: Z): P + # + # nkTypeDef( + # nkPostfix( + # nkIdent("*"), + # nkIdent("X") + # ), + # nkEmpty(), + # nkPtrTy( # optional, nested + # nkProcTy( + # nkFormalParams( + # nkPtrTy( # optional, nested + # nkIdent(retType) + # ), + # nkIdentDefs( + # nkIdent(param), + # nkPtrTy( + # nkIdent(ptype) + # ), + # nkEmpty() + # ), + # ... + # ), + # nkEmpty() + # ) + # ) + # ) - nimState.printDebug(typeDef) + # nkTypeSection.add + nimState.typeSection.add typeDef + + nimState.printDebug(typeDef) proc addType(nimState: NimState, node: TSNode, union = false) = decho("addType()") @@ -897,7 +928,7 @@ proc addType(nimState: NimState, node: TSNode, union = false) = if node.len > 1 and nimState.getNodeVal(node[1]) != "": # Add any additional names - nimState.addTypeTyped(node, duplicate = nimState.getNodeVal(node[0].getAtom())) + nimState.addTypeTyped(node) else: # Same as above except unnamed struct # @@ -919,8 +950,8 @@ proc addType(nimState: NimState, node: TSNode, union = false) = nimState.addTypeObject(node[0], fname = name, union = union) if name.nBl: - # Add any additional names except duplicate - nimState.addTypeTyped(node, ftname = name, duplicate = name) + # Add any additional names + nimState.addTypeTyped(node, ftname = name, offset = 1) proc addEnum(nimState: NimState, node: TSNode) = decho("addEnum()") @@ -935,67 +966,72 @@ proc addProc(nimState: NimState, node: TSNode) = start = getStartAtom(node) # node[start+1] = identifier = name - ident = nimState.newTypeIdent(node[start+1]) - name = $ident[0][1] + tident = nimState.newTypeIdent(node[start+1]) + + if not tident.isNil: + let + # Only need the ident tree, not nkTypeDef parent + ident = tident[0] + name = $tident[0][1] - # node[start+1] could have nested pointers - tcount = node[start+1].getPtrCount() + # node[start+1] could have nested pointers + tcount = node[start+1].getPtrCount() - # node[start] = identifier = return type name - (rname, _, rinfo) = nimState.getNameInfo(node[start].getAtom(), nskType, parent = name) + # node[start] = identifier = return type name + (rname, _, rinfo) = nimState.getNameInfo(node[start].getAtom(), nskType, parent = name) - # Parameter list - plist = node[start+1].anyChildInTree("parameter_list") + # Parameter list + plist = node[start+1].anyChildInTree("parameter_list") - procDef = newNode(nkProcDef) + procDef = newNode(nkProcDef) - # proc X(a1: Y, a2: Z): P {.pragma.} - # - # nkProcDef( - # nkPostfix( - # nkIdent("*"), - # nkIdent("X") - # ), - # nkEmpty(), - # nkEmpty(), - # nkFormalParams( - # nkPtrTy( # optional, nested - # nkIdent(retType) - # ), - # nkIdentDefs( - # nkIdent(param), - # nkPtrTy( - # nkIdent(ptype) - # ), - # nkEmpty() - # ), - # ... - # ), - # nkPragma(...), - # nkEmpty(), - # nkEmpty() - # ) + # proc X(a1: Y, a2: Z): P {.pragma.} + # + # nkProcDef( + # nkPostfix( + # nkIdent("*"), + # nkIdent("X") + # ), + # nkEmpty(), + # nkEmpty(), + # nkFormalParams( + # nkPtrTy( # optional, nested + # nkIdent(retType) + # ), + # nkIdentDefs( + # nkIdent(param), + # nkPtrTy( + # nkIdent(ptype) + # ), + # nkEmpty() + # ), + # ... + # ), + # nkPragma(...), + # nkEmpty(), + # nkEmpty() + # ) - procDef.add ident - procDef.add newNode(nkEmpty) - procDef.add newNode(nkEmpty) + procDef.add ident + procDef.add newNode(nkEmpty) + procDef.add newNode(nkEmpty) - # Return type - var - retType = nimState.getIdent(rname, rinfo, exported = false) - if tcount > 0: - retType = nimState.newPtrTree(tcount, retType) + # Return type + var + retType = nimState.getIdent(rname, rinfo, exported = false) + if tcount > 0: + retType = nimState.newPtrTree(tcount, retType) - # Proc with return type and params - procDef.add nimState.newFormalParams(name, plist, retType) - procDef.add newNode(nkEmpty) # Pragmas - procDef.add newNode(nkEmpty) - procDef.add newNode(nkEmpty) + # Proc with return type and params + procDef.add nimState.newFormalParams(name, plist, retType) + procDef.add newNode(nkEmpty) # Pragmas + procDef.add newNode(nkEmpty) + procDef.add newNode(nkEmpty) - # nkProcSection.add - nimState.procSection.add procDef + # nkProcSection.add + nimState.procSection.add procDef - nimState.printDebug(procDef) + nimState.printDebug(procDef) proc processNode(nimState: NimState, node: TSNode): bool = result = true diff --git a/nimterop/globals.nim b/nimterop/globals.nim index 2fb543b..12de6a7 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -120,7 +120,8 @@ when not declared(CIMPORT): gState.outputHandle.writeLine(args) template necho*(args: string) {.dirty.} = - let gState = nimState.gState + when not declared(gState): + let gState = nimState.gState gecho args template decho*(str: untyped): untyped = diff --git a/tests/include/tast2.h b/tests/include/tast2.h index 7c595e4..5cabfac 100644 --- a/tests/include/tast2.h +++ b/tests/include/tast2.h @@ -1,3 +1,55 @@ +#define A 1 +#define B 1.0 +#define C 0x10 +#define D "hello" +#define E 'c' + +struct A0; +struct A1 {}; +typedef struct A2; +typedef struct A3 {}; +typedef struct A4 A4, *A4p; +typedef const int A5; +typedef int *A6; +typedef A0 **A7; +typedef void *A8; + +typedef char *A9p[3]; //, A9[4]; +typedef char *A10[3][6]; +typedef char *(*A11)[3]; +typedef struct A1 *A111[12]; + +typedef int **(*A12)(int, int b, int *c, int *, int *count[4], int (*func)(int, int)); +typedef int A13(int, int); + +struct A14 { volatile char a1; }; +struct A15 { char *a1; const int *a2[1]; }; + +typedef struct A16 { char f1; }; +typedef struct A17 { char *a1; int *a2[1]; } A18, *A18p; +typedef struct { char *a1; int *a2[1]; } A19, *A19p; + +typedef struct A20 { char a1; } A20, A21, *A21p; + +//Expression +typedef struct A22 { int **f1; int *f2[123+132]; } A22; + +//Unions +union U1 {int f1; float f2; }; +typedef union U2 { int **f1; int abc[123+132]; } U2; + +// Anonymous +//typedef struct { char a1; }; + +//struct A2 test_proc1(struct A0 a); + + + + + + + +// DUPLICATES #define A 1 #define B 1.0 @@ -18,6 +70,7 @@ typedef void *A8; typedef char *A9p[3]; //, A9[4]; typedef char *A10[3][6]; typedef char *(*A11)[3]; +typedef struct A1 *A111[12]; typedef int **(*A12)(int, int b, int *c, int *, int *count[4], int (*func)(int, int)); typedef int A13(int, int); diff --git a/tests/tast2.nim b/tests/tast2.nim index 9e32f6e..40c7886 100644 --- a/tests/tast2.nim +++ b/tests/tast2.nim @@ -5,6 +5,13 @@ import nimterop/[cimport] static: cDebug() +cOverride: + const + A* = 2 + + type + A1* = A0 + cImport("include/tast2.h", flags="-d -f:ast2") proc testFields(t: typedesc, fields: Table[string, string] = initTable[string, string]()) = @@ -18,7 +25,7 @@ proc testFields(t: typedesc, fields: Table[string, string] = initTable[string, s "typeof(" & $t & ":" & name & ") != " & fields[name] & ", is " & $typeof(value) assert count == fields.len, "Failed for " & $t -assert A == 1 +assert A == 2 assert B == 1.0 assert C == 0x10 assert D == "hello" @@ -26,7 +33,7 @@ assert E == 'c' assert A0 is object testFields(A0) -assert A1 is object +assert A1 is A0 testFields(A1) assert A2 is object testFields(A2) @@ -44,6 +51,7 @@ assert A9p is array[3, cstring] #assert A9 is array[4, cchar] assert A10 is array[3, array[6, cstring]] assert A11 is ptr array[3, cstring] +assert A111 is array[12, ptr A1] assert A12 is proc(a1: cint, b: cint, c: ptr cint, a4: ptr cint, count: array[4, ptr cint], `func`: proc(a1: cint, a2: cint): cint): ptr ptr cint assert A13 is proc(a1: cint, a2: cint): cint From 4cfeea67a1152534e620db9832785f3ee5f9b259 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Fri, 20 Mar 2020 01:41:36 -0500 Subject: [PATCH 346/593] Fix for 0.20.2 --- nimterop/getters.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 736e0db..e1aa53e 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -427,7 +427,7 @@ proc printDebug*(nimState: NimState, pnode: PNode) = # Compiler shortcuts proc getDefaultLineInfo*(nimState: NimState): TLineInfo = - result = newLineInfo(nimState.config, nimState.sourceFile.AbsoluteFile, -1, -1) + result = newLineInfo(nimState.config, nimState.sourceFile.AbsoluteFile, 0, 0) proc getLineInfo*(nimState: NimState, node: TSNode): TLineInfo = # Get Nim equivalent line:col info from node From be1e85934d39b7d0d8ef481593c0c4cbae333310 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Sat, 21 Mar 2020 12:51:12 -0500 Subject: [PATCH 347/593] ast2 forward declaration support --- nimterop/ast2.nim | 21 +++++++++++++++++++++ nimterop/globals.nim | 4 ++++ tests/include/tast2.h | 10 ++++++++++ tests/tast2.nim | 4 ++-- 4 files changed, 37 insertions(+), 2 deletions(-) diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index 95ccdd6..c883537 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -252,6 +252,8 @@ proc newTypeIdent(nimState: NimState, node: TSNode, fname = "", union = false): result = newNode(nkTypeDef) result.add prident result.add newNode(nkEmpty) + + nimState.identifierNodes[name] = result else: necho &"# type '{origname}' is duplicate, skipped" @@ -520,6 +522,24 @@ proc addTypeObject(nimState: NimState, node: TSNode, typeDef: PNode = nil, fname nimState.typeSection.add typeDef nimState.printDebug(typeDef) + else: + # Forward declaration case + let + fdlist = node.anyChildInTree("field_declaration_list") + if not fdlist.isNil and fdlist.len > 0: + # Current node has fields + let + name = nimState.getNodeVal(node.getAtom()) + + if nimState.identifierNodes.hasKey(name): + let + def = nimState.identifierNodes[name] + # Duplicate nkTypeDef for `name` with empty fields + if def.kind == nkTypeDef and def.len == 3 and + def[2].kind == nkObjectTy and def[2].len == 3 and + def[2][2].kind == nkEmpty: + # Add fields to existing object + def[2][2] = nimState.newRecListTree(name, fdlist) proc addTypeTyped(nimState: NimState, node: TSNode, ftname = "", offset = 0) = # Add a type of a specified type @@ -1135,6 +1155,7 @@ proc printNim*(gState: State, fullpath: string, root: TSNode) = fp = fullpath.replace("\\", "/") nimState.identifiers = newTable[string, string]() + nimState.identifierNodes = newTable[string, PNode]() nimState.gState = gState nimState.currentHeader = getCurrentHeader(fullpath) diff --git a/nimterop/globals.nim b/nimterop/globals.nim index 12de6a7..e7ea4c0 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -69,6 +69,7 @@ type outputHandle*: File NimState {.used.} = ref object + # All symbols that have been declared so far indexed by nimName identifiers*: TableRef[string, string] # Legacy ast fields, remove when ast2 becomes default @@ -83,6 +84,9 @@ type config*: ConfigRef graph*: ModuleGraph + # Craeted symbols to generated AST - forward declaration tracking + identifierNodes*: TableRef[string, PNode] + gState*: State currentHeader*, impShort*, sourceFile*: string diff --git a/tests/include/tast2.h b/tests/include/tast2.h index 5cabfac..e9339ae 100644 --- a/tests/include/tast2.h +++ b/tests/include/tast2.h @@ -14,6 +14,11 @@ typedef int *A6; typedef A0 **A7; typedef void *A8; +// Forward declaration +struct A0 { + int f1; +}; + typedef char *A9p[3]; //, A9[4]; typedef char *A10[3][6]; typedef char *(*A11)[3]; @@ -67,6 +72,11 @@ typedef int *A6; typedef A0 **A7; typedef void *A8; +// Forward declaration +struct A0 { + int f1; +}; + typedef char *A9p[3]; //, A9[4]; typedef char *A10[3][6]; typedef char *(*A11)[3]; diff --git a/tests/tast2.nim b/tests/tast2.nim index 40c7886..6465acc 100644 --- a/tests/tast2.nim +++ b/tests/tast2.nim @@ -32,9 +32,9 @@ assert D == "hello" assert E == 'c' assert A0 is object -testFields(A0) +testFields(A0, {"f1": "cint"}.toTable()) assert A1 is A0 -testFields(A1) +testFields(A1, {"f1": "cint"}.toTable()) assert A2 is object testFields(A2) assert A3 is object From 6d1c428b6ebea47c7956c8580c26a810a9250db6 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Sat, 21 Mar 2020 21:29:15 -0500 Subject: [PATCH 348/593] Remove lzma test --- tests/getheader.nims | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tests/getheader.nims b/tests/getheader.nims index 5a08429..7a0fc80 100644 --- a/tests/getheader.nims +++ b/tests/getheader.nims @@ -35,10 +35,6 @@ when defined(posix): testCall(cmd & " -d:zlibStd" & zrcmd, zexp, 0) testCall(cmd & " -d:zlibStd -d:zlibStatic" & zrcmd, zexp, 0) - # git - testCall(cmd & " -d:lzmaGit" & lrcmd, lexp, 0) - testCall(cmd & " -d:lzmaGit -d:lzmaStatic" & lrcmd, lexp, 0, delete = false) - # git tag testCall(cmd & " -d:lzmaGit -d:lzmaSetVer=v5.2.0" & lrcmd, lexp & "5.2.0", 0) testCall(cmd & " -d:lzmaGit -d:lzmaStatic -d:lzmaSetVer=v5.2.0" & lrcmd, lexp & "5.2.0", 0, delete = false) From cadf16293d40bcd265d1bf8f366d351ba354a6f9 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 23 Mar 2020 14:02:40 -0500 Subject: [PATCH 349/593] ast2 enum support --- nimterop/ast2.nim | 84 ++++++++++++++++++++++++++++++++++--- nimterop/getters.nim | 5 ++- nimterop/globals.nim | 3 ++ tests/include/tast2.h | 96 +++++++++++++++++++++++++++++++++++++++++++ tests/tast2.nim | 21 +++++++++- 5 files changed, 200 insertions(+), 9 deletions(-) diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index c883537..23cddcb 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -98,10 +98,7 @@ proc newConstDef(nimState: NimState, node: TSNode, fname = "", fval = ""): PNode else: nimState.getNodeVal(node[1]) valident = - if fval.nBl: - newStrNode(nkStrLit, fval) - else: - nimState.getLit(val) + nimState.getLit(val) if name.Bl: # Name skipped or overridden since blank @@ -147,6 +144,7 @@ proc addConst(nimState: NimState, node: TSNode) = if not constDef.isNil: # nkConstSection.add nimState.constSection.add constDef + nimState.constIdentifiers.incl $constDef[0][1] nimState.printDebug(constDef) @@ -977,6 +975,80 @@ proc addEnum(nimState: NimState, node: TSNode) = decho("addEnum()") nimState.printDebug(node) + let + enumlist = node.anyChildInTree("enumerator_list") + if not enumlist.isNil: + var + name, origname = "" + offset = 0 + prev = "" + + if node.getAtom().getName() == "type_identifier": + # [typedef] enum X {} Y; + # Use X as name + origname = nimState.getNodeVal(node.getAtom()) + elif node.getName() == "type_definition" and node.len > 1: + # typedef enum {} Y; + # Use Y as name + origname = nimState.getNodeVal(node[1].getAtom()) + offset = 1 + + if origname.nBl: + name = nimState.getIdentifier(origname, nskType) + else: + # enum {}; + # Nameless so create a name + name = nimState.getUniqueIdentifier("Enum") + + if name.Bl: + # Name skipped or overridden since blank + let + eoverride = nimState.getOverrideOrSkip(node, origname, nskType) + if not eoverride.isNil: + nimState.typeSection.add eoverride + elif nimState.addNewIdentifer(name): + # Add enum definition and helpers + nimState.enumSection.add nimState.parseString(&"defineEnum({name})") + + # Create const for fields + var + fnames: HashSet[string] + for i in 0 .. enumlist.len - 1: + let + en = enumlist[i] + if en.getName() == "comment": + continue + let + fname = nimState.getIdentifier(nimState.getNodeVal(en.getAtom()), nskEnumField) + if fname.nBl: + var + fval = "" + if prev.Bl: + # Starting default value + fval = &"(0).{name}" + else: + # One greater than previous + fval = &"({prev} + 1).{name}" + + if en.len > 1 and en[1].getName() in gEnumVals: + # Explicit value + fval = "(" & nimState.getNimExpression(nimState.getNodeVal(en[1]), name) & ")." & name + + # Cannot use newConstDef() since parseString(fval) adds backticks to and/or + nimState.constSection.add nimState.parseString(&"const {fname}* = {fval}")[0][0] + + fnames.incl fname + + prev = fname + + # Add fields to list of consts after processing enum so that we don't cast + # enum field to itself + nimState.constIdentifiers.incl fnames + + # Add other names + if node.getName() == "type_definition" and node.len > 1: + nimState.addTypeTyped(node, ftname = name, offset = offset) + proc addProc(nimState: NimState, node: TSNode) = # Add a proc decho("addProc()") @@ -1060,9 +1132,9 @@ proc processNode(nimState: NimState, node: TSNode): bool = of "preproc_def": nimState.addConst(node) of "type_definition": - if not node.firstChildInTree("enum_specifier").isNil(): + if node.len > 0 and node[0].getName() == "enum_specifier": nimState.addEnum(node) - elif not node.firstChildInTree("union_specifier").isNil(): + elif node.len > 0 and node[0].getName() == "union_specifier": nimState.addType(node, union = true) else: nimState.addType(node) diff --git a/nimterop/getters.nim b/nimterop/getters.nim index e1aa53e..091174b 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -596,7 +596,8 @@ proc getAstChildByName*(ast: ref Ast, name: string): ref Ast = if ast.children.len == 1 and ast.children[0].name == ".": return ast.children[0] -proc getNimExpression*(nimState: NimState, expr: string): string = +proc getNimExpression*(nimState: NimState, expr: string, name = ""): string = + # Convert C/C++ expression into Nim - cast identifiers to `name` if specified var clean = expr.multiReplace([("\n", " "), ("\r", "")]) ident = "" @@ -641,6 +642,8 @@ proc getNimExpression*(nimState: NimState, expr: string): string = # Process identifier if ident.nBl: ident = nimState.getIdentifier(ident, nskConst) + if name.nBl and ident in nimState.constIdentifiers: + ident = ident & "." & name result &= ident ident = "" result &= gen diff --git a/nimterop/globals.nim b/nimterop/globals.nim index e7ea4c0..68f18b0 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -72,6 +72,9 @@ type # All symbols that have been declared so far indexed by nimName identifiers*: TableRef[string, string] + # All const names for enum casting + constIdentifiers*: HashSet[string] + # Legacy ast fields, remove when ast2 becomes default constStr*, enumStr*, procStr*, typeStr*: string diff --git a/tests/include/tast2.h b/tests/include/tast2.h index e9339ae..b867020 100644 --- a/tests/include/tast2.h +++ b/tests/include/tast2.h @@ -43,6 +43,54 @@ typedef struct A22 { int **f1; int *f2[123+132]; } A22; union U1 {int f1; float f2; }; typedef union U2 { int **f1; int abc[123+132]; } U2; +// Enums + +// Issue #159 +#define NK_FLAG(x) (1 << (x)) +enum nk_panel_type { + NK_PANEL_NONE = 0, + NK_PANEL_WINDOW = NK_FLAG(0), + NK_PANEL_GROUP = NK_FLAG(1), + NK_PANEL_POPUP = NK_FLAG(2), + NK_PANEL_CONTEXTUAL = NK_FLAG(4), + NK_PANEL_COMBO = NK_FLAG(5), + NK_PANEL_MENU = NK_FLAG(6), + NK_PANEL_TOOLTIP = NK_FLAG(7) +}; +enum nk_panel_set { + NK_PANEL_SET_NONBLOCK = NK_PANEL_CONTEXTUAL|NK_PANEL_COMBO|NK_PANEL_MENU|NK_PANEL_TOOLTIP, + NK_PANEL_SET_POPUP = NK_PANEL_SET_NONBLOCK|NK_PANEL_POPUP, + NK_PANEL_SET_SUB = NK_PANEL_SET_POPUP|NK_PANEL_GROUP +}; + +// Issue #171 +typedef enum VSColorFamily { + /* all planar formats */ + cmGray = 1000000, + cmRGB = 2000000, + cmYUV = 3000000, + cmYCoCg = 4000000, + /* special for compatibility */ + cmCompat = 9000000 +} VSColorFamily; + +typedef enum VSPresetFormat { + pfNone = 0, + + pfGray8 = cmGray + 10, + pfGray16, + + pfYUV420P8 = cmYUV + 10, + pfYUV422P8, + + pfRGB24 = cmRGB + 10, + pfRGB27, + /* test */ + + pfCompatBGR32 = cmCompat + 10, + pfCompatYUY2 +} VSPresetFormat; + // Anonymous //typedef struct { char a1; }; @@ -101,6 +149,54 @@ typedef struct A22 { int **f1; int *f2[123+132]; } A22; union U1 {int f1; float f2; }; typedef union U2 { int **f1; int abc[123+132]; } U2; +// Enums + +// Issue #159 +#define NK_FLAG(x) (1 << (x)) +enum nk_panel_type { + NK_PANEL_NONE = 0, + NK_PANEL_WINDOW = NK_FLAG(0), + NK_PANEL_GROUP = NK_FLAG(1), + NK_PANEL_POPUP = NK_FLAG(2), + NK_PANEL_CONTEXTUAL = NK_FLAG(4), + NK_PANEL_COMBO = NK_FLAG(5), + NK_PANEL_MENU = NK_FLAG(6), + NK_PANEL_TOOLTIP = NK_FLAG(7) +}; +enum nk_panel_set { + NK_PANEL_SET_NONBLOCK = NK_PANEL_CONTEXTUAL|NK_PANEL_COMBO|NK_PANEL_MENU|NK_PANEL_TOOLTIP, + NK_PANEL_SET_POPUP = NK_PANEL_SET_NONBLOCK|NK_PANEL_POPUP, + NK_PANEL_SET_SUB = NK_PANEL_SET_POPUP|NK_PANEL_GROUP +}; + +// Issue #171 +typedef enum VSColorFamily { + /* all planar formats */ + cmGray = 1000000, + cmRGB = 2000000, + cmYUV = 3000000, + cmYCoCg = 4000000, + /* special for compatibility */ + cmCompat = 9000000 +} VSColorFamily; + +typedef enum VSPresetFormat { + pfNone = 0, + + pfGray8 = cmGray + 10, + pfGray16, + + pfYUV420P8 = cmYUV + 10, + pfYUV422P8, + + pfRGB24 = cmRGB + 10, + pfRGB27, + /* test */ + + pfCompatBGR32 = cmCompat + 10, + pfCompatYUY2 +} VSPresetFormat; + // Anonymous //typedef struct { char a1; }; diff --git a/tests/tast2.nim b/tests/tast2.nim index 6465acc..914d40f 100644 --- a/tests/tast2.nim +++ b/tests/tast2.nim @@ -12,7 +12,7 @@ cOverride: type A1* = A0 -cImport("include/tast2.h", flags="-d -f:ast2") +cImport("include/tast2.h", flags="-d -f:ast2 -ENK_") proc testFields(t: typedesc, fields: Table[string, string] = initTable[string, string]()) = var @@ -86,4 +86,21 @@ assert U1 is object assert sizeof(U1) == sizeof(cfloat) assert U2 is object -assert sizeof(U2) == 256 * sizeof(cint) \ No newline at end of file +assert sizeof(U2) == 256 * sizeof(cint) + +assert PANEL_WINDOW == 1 +assert PANEL_GROUP == 2 +assert PANEL_POPUP == 4 +assert PANEL_CONTEXTUAL == 16 +assert PANEL_COMBO == 32 +assert PANEL_MENU == 64 +assert PANEL_TOOLTIP == 128 +assert PANEL_SET_NONBLOCK == 240 +assert PANEL_SET_POPUP == 244 +assert PANEL_SET_SUB == 246 + +assert cmGray == 1000000 +assert pfGray16 == 1000011 +assert pfYUV422P8 == pfYUV420P8 + 1 +assert pfRGB27 == cmRGB.VSPresetFormat + 11 +assert pfCompatYUY2 == pfCompatBGR32 + 1 \ No newline at end of file From c113ecec986e4790a98c5c73f61864fe18c49bfe Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 23 Mar 2020 16:06:28 -0500 Subject: [PATCH 350/593] ast2 bug fixes - getIdentName, ptr object, header const --- nimterop/ast2.nim | 40 +++++++++++++++++++--------------------- nimterop/getters.nim | 8 ++++++++ tests/tnimterop_c.nim | 2 +- 3 files changed, 28 insertions(+), 22 deletions(-) diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index 23cddcb..6c2589c 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -81,14 +81,15 @@ proc newConstDef(nimState: NimState, node: TSNode, fname = "", fval = ""): PNode # # If `fname` or `fval` are set, use them as name and val let - # node[0] = identifier = const name - (cname, origname, info) = nimState.getNameInfo(node.getAtom(), nskConst) - - name = + origname = if fname.nBl: fname else: - cname + # node[0] = identifier = const name + nimState.getNodeVal(node.getAtom()) + + name = nimState.getIdentifier(origname, nskConst) + info = nimState.getLineInfo(node) ident = nimState.getIdent(name, info) # node[1] = preproc_arg = value @@ -144,7 +145,7 @@ proc addConst(nimState: NimState, node: TSNode) = if not constDef.isNil: # nkConstSection.add nimState.constSection.add constDef - nimState.constIdentifiers.incl $constDef[0][1] + nimState.constIdentifiers.incl constDef.getIdentName() nimState.printDebug(constDef) @@ -259,9 +260,9 @@ proc newPtrTree(nimState: NimState, count: int, typ: PNode): PNode = # Create nkPtrTy tree depending on count # # Reduce by 1 if Nim type available for ptr X - e.g. ptr cchar = cstring + result = typ var count = count - chng = false if typ.kind == nkIdent: let tname = typ.ident.s @@ -269,7 +270,6 @@ proc newPtrTree(nimState: NimState, count: int, typ: PNode): PNode = if tname != ptname: # If Nim type available, use that ident result = nimState.getIdent(ptname, typ.info, exported = false) - chng = true # One ptr reduced count -= 1 if count > 0: @@ -282,18 +282,16 @@ proc newPtrTree(nimState: NimState, count: int, typ: PNode): PNode = # typ # ) # ) - result = newNode(nkPtrTy) var - parent = result + nresult = newNode(nkPtrTy) + parent = nresult child: PNode for i in 1 ..< count: child = newNode(nkPtrTy) parent.add child parent = child - parent.add typ - elif not chng: - # Either no ptr, or none left after Nim type adjustment - result = typ + parent.add result + result = nresult proc newArrayTree(nimState: NimState, node: TSNode, typ, size: PNode): PNode = # Create nkBracketExpr tree depending on input @@ -501,7 +499,7 @@ proc addTypeObject(nimState: NimState, node: TSNode, typeDef: PNode = nil, fname # ) # ) let - name = $typeDef[0][1] + name = typeDef.getIdentName() obj = newNode(nkObjectTy) obj.add newNode(nkEmpty) obj.add newNode(nkEmpty) @@ -555,7 +553,7 @@ proc addTypeTyped(nimState: NimState, node: TSNode, ftname = "", offset = 0) = if not typeDef.isNil: let - name = $typeDef[0][1] + name = typeDef.getIdentName() # node[start] = identifier = type name (tname0, _, tinfo) = nimState.getNameInfo(node[start].getAtom(), nskType, parent = name) @@ -573,7 +571,7 @@ proc addTypeTyped(nimState: NimState, node: TSNode, ftname = "", offset = 0) = count = node[i].getPtrCount() # Skip typedef X X; - if $typeDef[0][1] != tname: + if name != tname: if count > 0: # If pointers typeDef.add nimState.newPtrTree(count, ident) @@ -661,7 +659,7 @@ proc addTypeArray(nimState: NimState, node: TSNode) = if not typeDef.isNil: let - name = $typeDef[0][1] + name = typeDef.getIdentName() typ = nimState.getTypeArray(node, name) typeDef.add typ @@ -737,7 +735,7 @@ proc addTypeProc(nimState: NimState, node: TSNode) = if not typeDef.isNil: let - name = $typeDef[0][1] + name = typeDef.getIdentName() procTy = nimState.getTypeProc(name, node) @@ -1064,7 +1062,7 @@ proc addProc(nimState: NimState, node: TSNode) = let # Only need the ident tree, not nkTypeDef parent ident = tident[0] - name = $tident[0][1] + name = tident.getIdentName() # node[start+1] could have nested pointers tcount = node[start+1].getPtrCount() @@ -1197,7 +1195,7 @@ proc setupPragmas(nimState: NimState, root: TSNode, fullpath: string) = if nimState.includeHeader(): nimState.constSection.add nimState.newConstDef( - root, fname = nimState.currentHeader, fval = fullpath) + root, fname = nimState.currentHeader, fval = '"' & fullpath & '"') nimState.addPragma(root, impPragma, "header", newStrNode(nkStrLit, nimState.currentHeader)) diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 091174b..251955d 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -453,6 +453,14 @@ proc getIdent*(nimState: NimState, name: string, info: TLineInfo, exported = tru proc getIdent*(nimState: NimState, name: string): PNode = nimState.getIdent(name, nimState.getDefaultLineInfo(), exported = false) +proc getIdentName*(node: PNode): string = + if not node.isNil: + for i in 0 ..< node.len: + if node[i].kind == nkIdent and $node[i] != "*": + result = $node[i] + if result.Bl and node.len > 0: + result = node[0].getIdentName() + proc getNameInfo*(nimState: NimState, node: TSNode, kind: NimSymKind, parent = ""): tuple[name, origname: string, info: TLineInfo] = # Shortcut to get identifier name and info (node value and line:col) diff --git a/tests/tnimterop_c.nim b/tests/tnimterop_c.nim index c577c5d..732efbf 100644 --- a/tests/tnimterop_c.nim +++ b/tests/tnimterop_c.nim @@ -41,7 +41,7 @@ cOverride: proc weirdfunc(apple: ptr ptr ptr cchar): int {.importc.} proc weirdfunc2(mango: ptr ptr cchar): int {.importc.} -cImport cSearchPath "test.h" +cImport(cSearchPath("test.h")) check TEST_INT == 512 check TEST_FLOAT == 5.12 From c5e978c2efe8557862944a7471eb9a3356b0f3f4 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 23 Mar 2020 22:07:39 -0500 Subject: [PATCH 351/593] ast2 override final, void return and param fixes, multi proc support --- nimterop/ast2.nim | 192 ++++++++++++++++++++++++++---------------- nimterop/getters.nim | 7 ++ tests/include/tast2.h | 2 +- tests/tast2.nim | 2 +- 4 files changed, 128 insertions(+), 75 deletions(-) diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index 6c2589c..d3d32c3 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -1,4 +1,4 @@ -import macros, os, sets, strformat, strutils, tables, times +import macros, os, sequtils, sets, strformat, strutils, tables, times import regex @@ -59,23 +59,51 @@ proc getOverrideOrSkip(nimState: NimState, node: TSNode, origname: string, kind: name = nimState.getIdentifier(origname, kind, parent = "override") override = nimState.getOverride(origname, kind) - skind = - if kind == nskConst: - "const " - elif kind == nskType: - "type " - elif kind == nskProc: - "proc " - else: - "" + var + skind = getKeyword(kind) & " " if override.nBl: + if kind == nskProc: + skind = "" result = nimState.parseString(skind & override.replace(origname, name))[0][0] else: necho &"\n# $1'{origname}' skipped" % skind if nimState.gState.debug: nimState.skipStr &= &"\n{nimState.getNodeVal(node)}" +proc addOverrideFinal(nimState: NimState, kind: NimSymKind) = + # Add all unused cOverride symbols for `kind` to AST + var + syms = nimState.getOverrideFinal(kind) + skind = getKeyword(kind) & "\n" + if kind == nskProc: + skind = "" + + if syms.nBl: + var + nsyms = nimState.parseString(skind & syms) + if not nsyms.isNil: + let + list = + if kind == nskProc: + nsyms.sons + else: + nsyms[0].sons + case kind + of nskConst: + nimState.constSection.sons.insert(list, 0) + of nskType: + nimState.typeSection.sons.insert(list, 0) + of nskProc: + nimState.procSection.sons.insert(list, 0) + else: + discard + +proc addAllOverrideFinal(nimState: NimState) = + # Add all unused cOverride symbols to AST + for kind in [nskConst, nskType, nskProc]: + nimState.addOverrideFinal(kind) + proc newConstDef(nimState: NimState, node: TSNode, fname = "", fval = ""): PNode = # Create an nkConstDef PNode # @@ -352,12 +380,16 @@ proc newIdentDefs(nimState: NimState, name: string, node: TSNode, offset: SomeIn # Only for proc with no named param - create a param name based on offset # # int func(char, int); - let - pname = "a" & $(offset+1) - pident = nimState.getIdent(pname, tinfo, exported) - result.add pident - result.add tident - result.add newNode(nkEmpty) + if tname != "object": + let + pname = "a" & $(offset+1) + pident = nimState.getIdent(pname, tinfo, exported) + result.add pident + result.add tident + result.add newNode(nkEmpty) + else: + # int func(void) + result = nil else: let fdecl = node[start+1].anyChildInTree("function_declarator") @@ -717,7 +749,12 @@ proc getTypeProc(nimState: NimState, name: string, node: TSNode): PNode = # Return type var - retType = nimState.getIdent(rname, rinfo, exported = false) + retType = + if rname == "object" and tcount == 0: + # void (*func)(..) + newNode(nkEmpty) + else: + nimState.getIdent(rname, rinfo, exported = false) if tcount > 0: retType = nimState.newPtrTree(tcount, retType) @@ -1055,73 +1092,80 @@ proc addProc(nimState: NimState, node: TSNode) = let start = getStartAtom(node) - # node[start+1] = identifier = name - tident = nimState.newTypeIdent(node[start+1]) - - if not tident.isNil: + for i in start+1 ..< node.len: let - # Only need the ident tree, not nkTypeDef parent - ident = tident[0] - name = tident.getIdentName() + # node[i] = identifier = name + tident = nimState.newTypeIdent(node[i]) + + if not tident.isNil: + let + # Only need the ident tree, not nkTypeDef parent + ident = tident[0] + name = tident.getIdentName() - # node[start+1] could have nested pointers - tcount = node[start+1].getPtrCount() + # node[i] could have nested pointers + tcount = node[i].getPtrCount() - # node[start] = identifier = return type name - (rname, _, rinfo) = nimState.getNameInfo(node[start].getAtom(), nskType, parent = name) + # node[start] = identifier = return type name + (rname, _, rinfo) = nimState.getNameInfo(node[start].getAtom(), nskType, parent = name) - # Parameter list - plist = node[start+1].anyChildInTree("parameter_list") + # Parameter list + plist = node[i].anyChildInTree("parameter_list") - procDef = newNode(nkProcDef) + procDef = newNode(nkProcDef) - # proc X(a1: Y, a2: Z): P {.pragma.} - # - # nkProcDef( - # nkPostfix( - # nkIdent("*"), - # nkIdent("X") - # ), - # nkEmpty(), - # nkEmpty(), - # nkFormalParams( - # nkPtrTy( # optional, nested - # nkIdent(retType) - # ), - # nkIdentDefs( - # nkIdent(param), - # nkPtrTy( - # nkIdent(ptype) - # ), - # nkEmpty() - # ), - # ... - # ), - # nkPragma(...), - # nkEmpty(), - # nkEmpty() - # ) + # proc X(a1: Y, a2: Z): P {.pragma.} + # + # nkProcDef( + # nkPostfix( + # nkIdent("*"), + # nkIdent("X") + # ), + # nkEmpty(), + # nkEmpty(), + # nkFormalParams( + # nkPtrTy( # optional, nested + # nkIdent(retType) + # ), + # nkIdentDefs( + # nkIdent(param), + # nkPtrTy( + # nkIdent(ptype) + # ), + # nkEmpty() + # ), + # ... + # ), + # nkPragma(...), + # nkEmpty(), + # nkEmpty() + # ) - procDef.add ident - procDef.add newNode(nkEmpty) - procDef.add newNode(nkEmpty) + procDef.add ident + procDef.add newNode(nkEmpty) + procDef.add newNode(nkEmpty) - # Return type - var - retType = nimState.getIdent(rname, rinfo, exported = false) - if tcount > 0: - retType = nimState.newPtrTree(tcount, retType) + # Return type + var + retType = + if rname == "object" and tcount == 0: + # void func(..) + newNode(nkEmpty) + else: + nimState.getIdent(rname, rinfo, exported = false) + if tcount > 0: + retType = nimState.newPtrTree(tcount, retType) - # Proc with return type and params - procDef.add nimState.newFormalParams(name, plist, retType) - procDef.add newNode(nkEmpty) # Pragmas - procDef.add newNode(nkEmpty) - procDef.add newNode(nkEmpty) + # Proc with return type and params + procDef.add nimState.newFormalParams(name, plist, retType) + procDef.add newNode(nkEmpty) # Pragmas + procDef.add newNode(nkEmpty) + procDef.add newNode(nkEmpty) - # nkProcSection.add - nimState.procSection.add procDef + # nkProcSection.add + nimState.procSection.add procDef - nimState.printDebug(procDef) + nimState.printDebug(procDef) proc processNode(nimState: NimState, node: TSNode): bool = result = true @@ -1247,6 +1291,8 @@ proc printNim*(gState: State, fullpath: string, root: TSNode) = nimState.searchTree(root) + nimState.addAllOverrideFinal() + var tree = newNode(nkStmtList) tree.add nimState.pragmaSection diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 251955d..044cde7 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -174,6 +174,7 @@ proc addNewIdentifer*(nimState: NimState, name: string, override = false): bool # Overrides related proc getOverride*(nimState: NimState, name: string, kind: NimSymKind): string = + # Get cOverride for identifier `name` of `kind` if defined doAssert name.nBl, "Blank identifier error" if nimState.gState.onSymbolOverride != nil: @@ -190,6 +191,7 @@ proc getOverride*(nimState: NimState, name: string, kind: NimSymKind): string = result = result.replace(re"(?m)^(.*?)$", " $1") proc getOverrideFinal*(nimState: NimState, kind: NimSymKind): string = + # Get all unused cOverride symbols of `kind` let typ = $kind @@ -197,6 +199,11 @@ proc getOverrideFinal*(nimState: NimState, kind: NimSymKind): string = for i in nimState.gState.onSymbolOverrideFinal(typ): result &= "\n" & nimState.getOverride(i, kind) +proc getKeyword*(kind: NimSymKind): string = + # Convert `kind` into a Nim keyword + # cOverride procs already include `proc` keyword + result = ($kind).replace("nsk", "").toLowerAscii() + # TSNode shortcuts proc isNil*(node: TSNode): bool = diff --git a/tests/include/tast2.h b/tests/include/tast2.h index b867020..84505db 100644 --- a/tests/include/tast2.h +++ b/tests/include/tast2.h @@ -25,7 +25,7 @@ typedef char *(*A11)[3]; typedef struct A1 *A111[12]; typedef int **(*A12)(int, int b, int *c, int *, int *count[4], int (*func)(int, int)); -typedef int A13(int, int); +typedef int A13(int, int, void (*func)(void)); struct A14 { volatile char a1; }; struct A15 { char *a1; const int *a2[1]; }; diff --git a/tests/tast2.nim b/tests/tast2.nim index 914d40f..56b1868 100644 --- a/tests/tast2.nim +++ b/tests/tast2.nim @@ -54,7 +54,7 @@ assert A11 is ptr array[3, cstring] assert A111 is array[12, ptr A1] assert A12 is proc(a1: cint, b: cint, c: ptr cint, a4: ptr cint, count: array[4, ptr cint], `func`: proc(a1: cint, a2: cint): cint): ptr ptr cint -assert A13 is proc(a1: cint, a2: cint): cint +assert A13 is proc(a1: cint, a2: cint, `func`: proc()): cint assert A14 is object testFields(A14, {"a1": "cchar"}.toTable()) From e98564528ee8a9fc934bb2de31114b66673b3eaa Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 24 Mar 2020 15:48:54 -0500 Subject: [PATCH 352/593] ast2 pragmas for types --- nimterop/ast2.nim | 31 ++++++++++++++++++++++++------- nimterop/build.nim | 2 +- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index d3d32c3..62fdcf2 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -192,8 +192,13 @@ proc addPragma(nimState: NimState, node: TSNode, pragma: PNode, name: string, va colExpr.add value pragma.add colExpr +proc addPragma(nimState: NimState, node: TSNode, pragma: PNode, pragmas: seq[string]) = + # Add sequence of pragmas to an existing nkPragma tree + for name in pragmas: + nimState.addPragma(node, pragma, name) + proc addPragma(nimState: NimState, node: TSNode, pragma: PNode, pragmas: OrderedTable[string, PNode]) = - # Add pragmas to an existing nkPragma tree + # Add a table of name:value pragmas to an existing nkPragma tree for name, value in pragmas.pairs: nimState.addPragma(node, pragma, name, value) @@ -212,7 +217,7 @@ proc newPragma(nimState: NimState, node: TSNode, name: string, value: PNode = ni result = newNode(nkPragma) nimState.addPragma(node, result, name, value) -proc newPragma(nimState: NimState, node: TSNode, pragmas: OrderedTable[string, PNode]): PNode = +proc newPragma(nimState: NimState, node: TSNode, pragmas: seq[string] | OrderedTable[string, PNode]): PNode = # Create nkPragma tree for multiple name:value result = newNode(nkPragma) nimState.addPragma(node, result, pragmas) @@ -237,13 +242,13 @@ proc newPragmaExpr(nimState: NimState, node: TSNode, ident: PNode, name: string, result.add ident result.add nimState.newPragma(node, name, value) -proc newPragmaExpr(nimState: NimState, node: TSNode, ident: PNode, pragmas: OrderedTable[string, PNode]): PNode {.used.} = +proc newPragmaExpr(nimState: NimState, node: TSNode, ident: PNode, pragmas: seq[string] | OrderedTable[string, PNode]): PNode = # Create nkPragmaExpr tree for multiple name:value result = newNode(nkPragmaExpr) result.add ident result.add nimState.newPragma(node, pragmas) -proc newTypeIdent(nimState: NimState, node: TSNode, fname = "", union = false): PNode = +proc newTypeIdent(nimState: NimState, node: TSNode, fname = "", pragmas: seq[string] = @[]): PNode = # Create nkTypeDef PNode with first ident # # If `fname`, use it instead of node.getAtom() for name @@ -258,8 +263,8 @@ proc newTypeIdent(nimState: NimState, node: TSNode, fname = "", union = false): ident = nimState.getIdent(name, info) prident = - if union: - nimState.newPragmaExpr(node, ident, "union") + if pragmas.nBl and not ident.isNil: + nimState.newPragmaExpr(node, ident, pragmas) else: ident @@ -509,9 +514,15 @@ proc addTypeObject(nimState: NimState, node: TSNode, typeDef: PNode = nil, fname # If `fname` is set, use it as the name when creating new PNode decho("addTypeObject()") let + pragmas = + if union: + @["union", "bycopy"] + else: + @["bycopy"] + typeDef = if typeDef.isNil: - nimState.newTypeIdent(node, fname, union = union) + nimState.newTypeIdent(node, fname, pragmas) else: typeDef @@ -546,6 +557,12 @@ proc addTypeObject(nimState: NimState, node: TSNode, typeDef: PNode = nil, fname typeDef.add obj + # If typeDef was passed in, need to add pragmas if any + if pragmas.nBl and typeDef[0].kind != nkPragmaExpr: + let + npexpr = nimState.newPragmaExpr(node, typedef[0], pragmas) + typedef[0] = npexpr + # nkTypeSection.add nimState.typeSection.add typeDef diff --git a/nimterop/build.nim b/nimterop/build.nim index 7939afa..9594baa 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -958,7 +958,7 @@ macro getHeader*(header: static[string], giturl: static[string] = "", dlurl: sta preBuild = newIdentNode(name & "PreBuild") # Regex for library search - lre = "(lib)?$1[_]?(static)?[0-9.\\-]*\\" + lre = "(lib)?$1[_-]?(static)?[0-9.\\-]*\\" # If -d:xxx set with setDefines() stdVal = gDefines.hasKey(stdStr) From bf81af2da2251cc68364ea2c40d1e8e117d4a016 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 24 Mar 2020 15:54:26 -0500 Subject: [PATCH 353/593] Update documentation --- all.html | 810 +----------- build.html | 825 +----------- cimport.html | 832 +----------- cimport.idx | 2 + compat.html | 3 +- dochack.js | 3397 ++++++++++++++++++++++++------------------------ docs.html | 152 +++ docs.idx | 1 + nimdoc.out.css | 891 +++++++++++++ paths.html | 808 +----------- plugin.html | 820 +----------- plugin.idx | 2 +- theindex.html | 821 +----------- types.html | 808 +----------- 14 files changed, 3068 insertions(+), 7104 deletions(-) create mode 100644 docs.html create mode 100644 docs.idx create mode 100644 nimdoc.out.css diff --git a/all.html b/all.html index fc0f0db..4fde88f 100644 --- a/all.html +++ b/all.html @@ -10,6 +10,7 @@ + @@ -17,772 +18,7 @@ all - + @@ -797,6 +33,37 @@ function main() { event.target.parentNode.nextElementSibling.style.display = "inline"; } } + + const toggleSwitch = document.querySelector('.theme-switch input[type="checkbox"]'); + function switchTheme(e) { + if (e.target.checked) { + document.documentElement.setAttribute('data-theme', 'dark'); + localStorage.setItem('theme', 'dark'); + } else { + document.documentElement.setAttribute('data-theme', 'light'); + localStorage.setItem('theme', 'light'); + } + } + + toggleSwitch.addEventListener('change', switchTheme, false); + + + if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { + document.documentElement.setAttribute('data-theme', "dark"); + toggleSwitch.checked = true; + } else if (window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches) { + document.documentElement.setAttribute('data-theme', "light"); + toggleSwitch.checked = false; + } else { + const currentTheme = localStorage.getItem('theme') ? localStorage.getItem('theme') : null; + if (currentTheme) { + document.documentElement.setAttribute('data-theme', currentTheme); + + if (currentTheme === 'dark') { + toggleSwitch.checked = true; + } + } + } } @@ -807,6 +74,13 @@ function main() {

    all

    +
    + +     Dark Mode +
    @@ -850,7 +124,7 @@ function main() {
    diff --git a/build.html b/build.html index 8859919..4202b8d 100644 --- a/build.html +++ b/build.html @@ -10,6 +10,7 @@ + @@ -17,772 +18,7 @@ build - + @@ -797,6 +33,37 @@ function main() { event.target.parentNode.nextElementSibling.style.display = "inline"; } } + + const toggleSwitch = document.querySelector('.theme-switch input[type="checkbox"]'); + function switchTheme(e) { + if (e.target.checked) { + document.documentElement.setAttribute('data-theme', 'dark'); + localStorage.setItem('theme', 'dark'); + } else { + document.documentElement.setAttribute('data-theme', 'light'); + localStorage.setItem('theme', 'light'); + } + } + + toggleSwitch.addEventListener('change', switchTheme, false); + + + if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { + document.documentElement.setAttribute('data-theme', "dark"); + toggleSwitch.checked = true; + } else if (window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches) { + document.documentElement.setAttribute('data-theme', "light"); + toggleSwitch.checked = false; + } else { + const currentTheme = localStorage.getItem('theme') ? localStorage.getItem('theme') : null; + if (currentTheme) { + document.documentElement.setAttribute('data-theme', currentTheme); + + if (currentTheme === 'dark') { + toggleSwitch.checked = true; + } + } + } } @@ -807,6 +74,13 @@ function main() {

    build

    +
    + +     Dark Mode +
      -
    • - Imports -
        - -
      -
    • Procs
        @@ -921,12 +189,7 @@ function main() {

        - -
        +

        Procs

        @@ -1078,8 +341,8 @@ Hard reset the git repository at the specified directory
proc gitCheckout(file, outdir: string) {...}{.raises: [ValueError, IOError, OSError,
-    Exception, Defect], tags: [ReadEnvEffect, ReadIOEffect, ReadDirEffect,
-                            WriteIOEffect, ExecIOEffect, RootEffect].}
+ Exception, Defect], tags: [RootEffect, ReadEnvEffect, ReadIOEffect, ReadDirEffect, + WriteIOEffect, ExecIOEffect].}

Checkout the specified file in the git repository at outdir

@@ -1316,7 +579,7 @@ Check if -d:xxx is se diff --git a/cimport.html b/cimport.html index bbb467a..c4652d3 100644 --- a/cimport.html +++ b/cimport.html @@ -10,6 +10,7 @@ + @@ -17,772 +18,7 @@ cimport - + @@ -797,6 +33,37 @@ function main() { event.target.parentNode.nextElementSibling.style.display = "inline"; } } + + const toggleSwitch = document.querySelector('.theme-switch input[type="checkbox"]'); + function switchTheme(e) { + if (e.target.checked) { + document.documentElement.setAttribute('data-theme', 'dark'); + localStorage.setItem('theme', 'dark'); + } else { + document.documentElement.setAttribute('data-theme', 'light'); + localStorage.setItem('theme', 'light'); + } + } + + toggleSwitch.addEventListener('change', switchTheme, false); + + + if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { + document.documentElement.setAttribute('data-theme', "dark"); + toggleSwitch.checked = true; + } else if (window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches) { + document.documentElement.setAttribute('data-theme', "light"); + toggleSwitch.checked = false; + } else { + const currentTheme = localStorage.getItem('theme') ? localStorage.getItem('theme') : null; + if (currentTheme) { + document.documentElement.setAttribute('data-theme', currentTheme); + + if (currentTheme === 'dark') { + toggleSwitch.checked = true; + } + } + } } @@ -807,6 +74,13 @@ function main() {

cimport

+
+ +     Dark Mode +
diff --git a/cimport.idx b/cimport.idx index ac8ee27..1c392ae 100644 --- a/cimport.idx +++ b/cimport.idx @@ -1,3 +1,5 @@ +ast2 cimport.html#ast2 Feature.ast2 +Feature cimport.html#Feature cimport: Feature cOverride cimport.html#cOverride.m cimport: cOverride(body): untyped cSkipSymbol cimport.html#cSkipSymbol,seq[T][string] cimport: cSkipSymbol(skips: seq[string]) cPlugin cimport.html#cPlugin.m cimport: cPlugin(body): untyped diff --git a/compat.html b/compat.html index 16d342c..85fdf3b 100644 --- a/compat.html +++ b/compat.html @@ -10,6 +10,7 @@ + @@ -859,7 +860,7 @@ function main() {
diff --git a/dochack.js b/dochack.js index 8cd4b61..0fd6939 100644 --- a/dochack.js +++ b/dochack.js @@ -1,6 +1,4 @@ -/* Generated by the Nim Compiler v1.0.4 */ -/* (c) 2019 Andreas Rumpf */ - +/* Generated by the Nim Compiler v1.1.1 */ var framePtr = null; var excHandler = 0; var lastJSError = null; @@ -12,257 +10,274 @@ if (typeof Uint16Array === 'undefined') Uint16Array = Array; if (typeof Uint32Array === 'undefined') Uint32Array = Array; if (typeof Float32Array === 'undefined') Float32Array = Array; if (typeof Float64Array === 'undefined') Float64Array = Array; -var NTI130 = {size: 0,kind: 1,base: null,node: null,finalizer: null}; -var NTI160074 = {size: 0, kind: 18, base: null, node: null, finalizer: null}; -var NTI3662 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI162578 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; -var NTI42448 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI42444 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI42440 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI42436 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI42432 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI42428 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI42424 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI42420 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI42416 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI42412 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI42408 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI42404 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI42400 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI42396 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI42392 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI42388 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI42384 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI42380 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI42376 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI42372 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; -var NTI42205 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI42283 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI42281 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; -var NTI42227 = {size: 0, kind: 14, base: null, node: null, finalizer: null}; -var NTI42565 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; -var NTI42563 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; -var NTI42561 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; -var NTI42231 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI42229 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; -var NTI44305 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; -var NTI3650 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI3658 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI104 = {size: 0,kind: 31,base: null,node: null,finalizer: null}; -var NTI21156 = {size: 0, kind: 18, base: null, node: null, finalizer: null}; -var NTI3608 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI3714 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; -var NTI114 = {size: 0,kind: 40,base: null,node: null,finalizer: null}; -var NTI138 = {size: 0,kind: 28,base: null,node: null,finalizer: null}; -var NTI140 = {size: 0,kind: 29,base: null,node: null,finalizer: null}; -var NTI3708 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; -var NTI3626 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI3628 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI3642 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NTI3646 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; -var NNI3646 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; -NTI3646.node = NNI3646; -var NNI3642 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; -NTI3642.node = NNI3642; -var NNI3628 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; -NTI3628.node = NNI3628; -NTI3708.base = NTI3626; -NTI3714.base = NTI3626; -var NNI3626 = {kind: 2, len: 6, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "parent", len: 0, typ: NTI3708, name: "parent", sons: null}, -{kind: 1, offset: "name", len: 0, typ: NTI140, name: "name", sons: null}, -{kind: 1, offset: "message", len: 0, typ: NTI138, name: "msg", sons: null}, -{kind: 1, offset: "trace", len: 0, typ: NTI138, name: "trace", sons: null}, -{kind: 1, offset: "raiseId", len: 0, typ: NTI114, name: "raiseId", sons: null}, -{kind: 1, offset: "up", len: 0, typ: NTI3714, name: "up", sons: null}]}; -NTI3626.node = NNI3626; -var NNI3608 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; -NTI3608.node = NNI3608; -NTI3626.base = NTI3608; -NTI3628.base = NTI3626; -NTI3642.base = NTI3628; -NTI3646.base = NTI3642; -var NNI21156 = {kind: 2, len: 2, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "Field0", len: 0, typ: NTI140, name: "Field0", sons: null}, -{kind: 1, offset: "Field1", len: 0, typ: NTI104, name: "Field1", sons: null}]}; -NTI21156.node = NNI21156; -var NNI3658 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; -NTI3658.node = NNI3658; -NTI3658.base = NTI3628; -var NNI3650 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; -NTI3650.node = NNI3650; -NTI3650.base = NTI3628; -NTI42561.base = NTI42229; -NTI42563.base = NTI42229; -NTI42565.base = NTI42229; -var NNI42227 = {kind: 2, offset: 0, typ: null, name: null, len: 12, sons: {"1": {kind: 1, offset: 1, typ: NTI42227, name: "ElementNode", len: 0, sons: null}, -"2": {kind: 1, offset: 2, typ: NTI42227, name: "AttributeNode", len: 0, sons: null}, -"3": {kind: 1, offset: 3, typ: NTI42227, name: "TextNode", len: 0, sons: null}, -"4": {kind: 1, offset: 4, typ: NTI42227, name: "CDATANode", len: 0, sons: null}, -"5": {kind: 1, offset: 5, typ: NTI42227, name: "EntityRefNode", len: 0, sons: null}, -"6": {kind: 1, offset: 6, typ: NTI42227, name: "EntityNode", len: 0, sons: null}, -"7": {kind: 1, offset: 7, typ: NTI42227, name: "ProcessingInstructionNode", len: 0, sons: null}, -"8": {kind: 1, offset: 8, typ: NTI42227, name: "CommentNode", len: 0, sons: null}, -"9": {kind: 1, offset: 9, typ: NTI42227, name: "DocumentNode", len: 0, sons: null}, -"10": {kind: 1, offset: 10, typ: NTI42227, name: "DocumentTypeNode", len: 0, sons: null}, -"11": {kind: 1, offset: 11, typ: NTI42227, name: "DocumentFragmentNode", len: 0, sons: null}, -"12": {kind: 1, offset: 12, typ: NTI42227, name: "NotationNode", len: 0, sons: null}}}; -NTI42227.node = NNI42227; -var NNI42283 = {kind: 2, len: 92, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "background", len: 0, typ: NTI140, name: "background", sons: null}, -{kind: 1, offset: "backgroundAttachment", len: 0, typ: NTI140, name: "backgroundAttachment", sons: null}, -{kind: 1, offset: "backgroundColor", len: 0, typ: NTI140, name: "backgroundColor", sons: null}, -{kind: 1, offset: "backgroundImage", len: 0, typ: NTI140, name: "backgroundImage", sons: null}, -{kind: 1, offset: "backgroundPosition", len: 0, typ: NTI140, name: "backgroundPosition", sons: null}, -{kind: 1, offset: "backgroundRepeat", len: 0, typ: NTI140, name: "backgroundRepeat", sons: null}, -{kind: 1, offset: "border", len: 0, typ: NTI140, name: "border", sons: null}, -{kind: 1, offset: "borderBottom", len: 0, typ: NTI140, name: "borderBottom", sons: null}, -{kind: 1, offset: "borderBottomColor", len: 0, typ: NTI140, name: "borderBottomColor", sons: null}, -{kind: 1, offset: "borderBottomStyle", len: 0, typ: NTI140, name: "borderBottomStyle", sons: null}, -{kind: 1, offset: "borderBottomWidth", len: 0, typ: NTI140, name: "borderBottomWidth", sons: null}, -{kind: 1, offset: "borderColor", len: 0, typ: NTI140, name: "borderColor", sons: null}, -{kind: 1, offset: "borderLeft", len: 0, typ: NTI140, name: "borderLeft", sons: null}, -{kind: 1, offset: "borderLeftColor", len: 0, typ: NTI140, name: "borderLeftColor", sons: null}, -{kind: 1, offset: "borderLeftStyle", len: 0, typ: NTI140, name: "borderLeftStyle", sons: null}, -{kind: 1, offset: "borderLeftWidth", len: 0, typ: NTI140, name: "borderLeftWidth", sons: null}, -{kind: 1, offset: "borderRight", len: 0, typ: NTI140, name: "borderRight", sons: null}, -{kind: 1, offset: "borderRightColor", len: 0, typ: NTI140, name: "borderRightColor", sons: null}, -{kind: 1, offset: "borderRightStyle", len: 0, typ: NTI140, name: "borderRightStyle", sons: null}, -{kind: 1, offset: "borderRightWidth", len: 0, typ: NTI140, name: "borderRightWidth", sons: null}, -{kind: 1, offset: "borderStyle", len: 0, typ: NTI140, name: "borderStyle", sons: null}, -{kind: 1, offset: "borderTop", len: 0, typ: NTI140, name: "borderTop", sons: null}, -{kind: 1, offset: "borderTopColor", len: 0, typ: NTI140, name: "borderTopColor", sons: null}, -{kind: 1, offset: "borderTopStyle", len: 0, typ: NTI140, name: "borderTopStyle", sons: null}, -{kind: 1, offset: "borderTopWidth", len: 0, typ: NTI140, name: "borderTopWidth", sons: null}, -{kind: 1, offset: "borderWidth", len: 0, typ: NTI140, name: "borderWidth", sons: null}, -{kind: 1, offset: "bottom", len: 0, typ: NTI140, name: "bottom", sons: null}, -{kind: 1, offset: "captionSide", len: 0, typ: NTI140, name: "captionSide", sons: null}, -{kind: 1, offset: "clear", len: 0, typ: NTI140, name: "clear", sons: null}, -{kind: 1, offset: "clip", len: 0, typ: NTI140, name: "clip", sons: null}, -{kind: 1, offset: "color", len: 0, typ: NTI140, name: "color", sons: null}, -{kind: 1, offset: "cursor", len: 0, typ: NTI140, name: "cursor", sons: null}, -{kind: 1, offset: "direction", len: 0, typ: NTI140, name: "direction", sons: null}, -{kind: 1, offset: "display", len: 0, typ: NTI140, name: "display", sons: null}, -{kind: 1, offset: "emptyCells", len: 0, typ: NTI140, name: "emptyCells", sons: null}, -{kind: 1, offset: "cssFloat", len: 0, typ: NTI140, name: "cssFloat", sons: null}, -{kind: 1, offset: "font", len: 0, typ: NTI140, name: "font", sons: null}, -{kind: 1, offset: "fontFamily", len: 0, typ: NTI140, name: "fontFamily", sons: null}, -{kind: 1, offset: "fontSize", len: 0, typ: NTI140, name: "fontSize", sons: null}, -{kind: 1, offset: "fontStretch", len: 0, typ: NTI140, name: "fontStretch", sons: null}, -{kind: 1, offset: "fontStyle", len: 0, typ: NTI140, name: "fontStyle", sons: null}, -{kind: 1, offset: "fontVariant", len: 0, typ: NTI140, name: "fontVariant", sons: null}, -{kind: 1, offset: "fontWeight", len: 0, typ: NTI140, name: "fontWeight", sons: null}, -{kind: 1, offset: "height", len: 0, typ: NTI140, name: "height", sons: null}, -{kind: 1, offset: "left", len: 0, typ: NTI140, name: "left", sons: null}, -{kind: 1, offset: "letterSpacing", len: 0, typ: NTI140, name: "letterSpacing", sons: null}, -{kind: 1, offset: "lineHeight", len: 0, typ: NTI140, name: "lineHeight", sons: null}, -{kind: 1, offset: "listStyle", len: 0, typ: NTI140, name: "listStyle", sons: null}, -{kind: 1, offset: "listStyleImage", len: 0, typ: NTI140, name: "listStyleImage", sons: null}, -{kind: 1, offset: "listStylePosition", len: 0, typ: NTI140, name: "listStylePosition", sons: null}, -{kind: 1, offset: "listStyleType", len: 0, typ: NTI140, name: "listStyleType", sons: null}, -{kind: 1, offset: "margin", len: 0, typ: NTI140, name: "margin", sons: null}, -{kind: 1, offset: "marginBottom", len: 0, typ: NTI140, name: "marginBottom", sons: null}, -{kind: 1, offset: "marginLeft", len: 0, typ: NTI140, name: "marginLeft", sons: null}, -{kind: 1, offset: "marginRight", len: 0, typ: NTI140, name: "marginRight", sons: null}, -{kind: 1, offset: "marginTop", len: 0, typ: NTI140, name: "marginTop", sons: null}, -{kind: 1, offset: "maxHeight", len: 0, typ: NTI140, name: "maxHeight", sons: null}, -{kind: 1, offset: "maxWidth", len: 0, typ: NTI140, name: "maxWidth", sons: null}, -{kind: 1, offset: "minHeight", len: 0, typ: NTI140, name: "minHeight", sons: null}, -{kind: 1, offset: "minWidth", len: 0, typ: NTI140, name: "minWidth", sons: null}, -{kind: 1, offset: "opacity", len: 0, typ: NTI140, name: "opacity", sons: null}, -{kind: 1, offset: "overflow", len: 0, typ: NTI140, name: "overflow", sons: null}, -{kind: 1, offset: "padding", len: 0, typ: NTI140, name: "padding", sons: null}, -{kind: 1, offset: "paddingBottom", len: 0, typ: NTI140, name: "paddingBottom", sons: null}, -{kind: 1, offset: "paddingLeft", len: 0, typ: NTI140, name: "paddingLeft", sons: null}, -{kind: 1, offset: "paddingRight", len: 0, typ: NTI140, name: "paddingRight", sons: null}, -{kind: 1, offset: "paddingTop", len: 0, typ: NTI140, name: "paddingTop", sons: null}, -{kind: 1, offset: "pageBreakAfter", len: 0, typ: NTI140, name: "pageBreakAfter", sons: null}, -{kind: 1, offset: "pageBreakBefore", len: 0, typ: NTI140, name: "pageBreakBefore", sons: null}, -{kind: 1, offset: "pointerEvents", len: 0, typ: NTI140, name: "pointerEvents", sons: null}, -{kind: 1, offset: "position", len: 0, typ: NTI140, name: "position", sons: null}, -{kind: 1, offset: "right", len: 0, typ: NTI140, name: "right", sons: null}, -{kind: 1, offset: "scrollbar3dLightColor", len: 0, typ: NTI140, name: "scrollbar3dLightColor", sons: null}, -{kind: 1, offset: "scrollbarArrowColor", len: 0, typ: NTI140, name: "scrollbarArrowColor", sons: null}, -{kind: 1, offset: "scrollbarBaseColor", len: 0, typ: NTI140, name: "scrollbarBaseColor", sons: null}, -{kind: 1, offset: "scrollbarDarkshadowColor", len: 0, typ: NTI140, name: "scrollbarDarkshadowColor", sons: null}, -{kind: 1, offset: "scrollbarFaceColor", len: 0, typ: NTI140, name: "scrollbarFaceColor", sons: null}, -{kind: 1, offset: "scrollbarHighlightColor", len: 0, typ: NTI140, name: "scrollbarHighlightColor", sons: null}, -{kind: 1, offset: "scrollbarShadowColor", len: 0, typ: NTI140, name: "scrollbarShadowColor", sons: null}, -{kind: 1, offset: "scrollbarTrackColor", len: 0, typ: NTI140, name: "scrollbarTrackColor", sons: null}, -{kind: 1, offset: "tableLayout", len: 0, typ: NTI140, name: "tableLayout", sons: null}, -{kind: 1, offset: "textAlign", len: 0, typ: NTI140, name: "textAlign", sons: null}, -{kind: 1, offset: "textDecoration", len: 0, typ: NTI140, name: "textDecoration", sons: null}, -{kind: 1, offset: "textIndent", len: 0, typ: NTI140, name: "textIndent", sons: null}, -{kind: 1, offset: "textTransform", len: 0, typ: NTI140, name: "textTransform", sons: null}, -{kind: 1, offset: "transform", len: 0, typ: NTI140, name: "transform", sons: null}, -{kind: 1, offset: "top", len: 0, typ: NTI140, name: "top", sons: null}, -{kind: 1, offset: "verticalAlign", len: 0, typ: NTI140, name: "verticalAlign", sons: null}, -{kind: 1, offset: "visibility", len: 0, typ: NTI140, name: "visibility", sons: null}, -{kind: 1, offset: "width", len: 0, typ: NTI140, name: "width", sons: null}, -{kind: 1, offset: "wordSpacing", len: 0, typ: NTI140, name: "wordSpacing", sons: null}, -{kind: 1, offset: "zIndex", len: 0, typ: NTI104, name: "zIndex", sons: null}]}; -NTI42283.node = NNI42283; -NTI42283.base = NTI3608; -NTI42281.base = NTI42283; -var NNI42231 = {kind: 2, len: 14, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "attributes", len: 0, typ: NTI42561, name: "attributes", sons: null}, -{kind: 1, offset: "childNodes", len: 0, typ: NTI42563, name: "childNodes", sons: null}, -{kind: 1, offset: "children", len: 0, typ: NTI42565, name: "children", sons: null}, -{kind: 1, offset: "data", len: 0, typ: NTI140, name: "data", sons: null}, -{kind: 1, offset: "firstChild", len: 0, typ: NTI42229, name: "firstChild", sons: null}, -{kind: 1, offset: "lastChild", len: 0, typ: NTI42229, name: "lastChild", sons: null}, -{kind: 1, offset: "nextSibling", len: 0, typ: NTI42229, name: "nextSibling", sons: null}, -{kind: 1, offset: "nodeName", len: 0, typ: NTI140, name: "nodeName", sons: null}, -{kind: 1, offset: "nodeType", len: 0, typ: NTI42227, name: "nodeType", sons: null}, -{kind: 1, offset: "nodeValue", len: 0, typ: NTI140, name: "nodeValue", sons: null}, -{kind: 1, offset: "parentNode", len: 0, typ: NTI42229, name: "parentNode", sons: null}, -{kind: 1, offset: "previousSibling", len: 0, typ: NTI42229, name: "previousSibling", sons: null}, -{kind: 1, offset: "innerHTML", len: 0, typ: NTI140, name: "innerHTML", sons: null}, -{kind: 1, offset: "style", len: 0, typ: NTI42281, name: "style", sons: null}]}; -NTI42231.node = NNI42231; -var NNI42205 = {kind: 2, len: 20, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "onabort", len: 0, typ: NTI42372, name: "onabort", sons: null}, -{kind: 1, offset: "onblur", len: 0, typ: NTI42376, name: "onblur", sons: null}, -{kind: 1, offset: "onchange", len: 0, typ: NTI42380, name: "onchange", sons: null}, -{kind: 1, offset: "onclick", len: 0, typ: NTI42384, name: "onclick", sons: null}, -{kind: 1, offset: "ondblclick", len: 0, typ: NTI42388, name: "ondblclick", sons: null}, -{kind: 1, offset: "onerror", len: 0, typ: NTI42392, name: "onerror", sons: null}, -{kind: 1, offset: "onfocus", len: 0, typ: NTI42396, name: "onfocus", sons: null}, -{kind: 1, offset: "onkeydown", len: 0, typ: NTI42400, name: "onkeydown", sons: null}, -{kind: 1, offset: "onkeypress", len: 0, typ: NTI42404, name: "onkeypress", sons: null}, -{kind: 1, offset: "onkeyup", len: 0, typ: NTI42408, name: "onkeyup", sons: null}, -{kind: 1, offset: "onload", len: 0, typ: NTI42412, name: "onload", sons: null}, -{kind: 1, offset: "onmousedown", len: 0, typ: NTI42416, name: "onmousedown", sons: null}, -{kind: 1, offset: "onmousemove", len: 0, typ: NTI42420, name: "onmousemove", sons: null}, -{kind: 1, offset: "onmouseout", len: 0, typ: NTI42424, name: "onmouseout", sons: null}, -{kind: 1, offset: "onmouseover", len: 0, typ: NTI42428, name: "onmouseover", sons: null}, -{kind: 1, offset: "onmouseup", len: 0, typ: NTI42432, name: "onmouseup", sons: null}, -{kind: 1, offset: "onreset", len: 0, typ: NTI42436, name: "onreset", sons: null}, -{kind: 1, offset: "onselect", len: 0, typ: NTI42440, name: "onselect", sons: null}, -{kind: 1, offset: "onsubmit", len: 0, typ: NTI42444, name: "onsubmit", sons: null}, -{kind: 1, offset: "onunload", len: 0, typ: NTI42448, name: "onunload", sons: null}]}; -NTI42205.node = NNI42205; -NTI42205.base = NTI3608; -NTI42231.base = NTI42205; -NTI42229.base = NTI42231; -NTI44305.base = NTI42229; -NTI162578.base = NTI140; -var NNI3662 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; -NTI3662.node = NNI3662; -NTI3662.base = NTI3628; -var NNI160074 = {kind: 2, len: 2, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "Field0", len: 0, typ: NTI104, name: "Field0", sons: null}, -{kind: 1, offset: "Field1", len: 0, typ: NTI130, name: "Field1", sons: null}]}; -NTI160074.node = NNI160074; +var NTI163 = {size: 0,kind: 1,base: null,node: null,finalizer: null}; +var NTI9681058 = {size: 0, kind: 18, base: null, node: null, finalizer: null}; +var NTI6098 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI9835571 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; +var NTI622454 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI622450 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI622446 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI622442 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI622438 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI622434 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI622430 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI622426 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI622422 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI622418 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI622414 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI622410 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI622406 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI622402 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI622398 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI622394 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI622390 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI622386 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI622382 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI622378 = {size: 0,kind: 25,base: null,node: null,finalizer: null}; +var NTI622205 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI622289 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI622287 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; +var NTI622229 = {size: 0, kind: 14, base: null, node: null, finalizer: null}; +var NTI622574 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; +var NTI622572 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; +var NTI622570 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; +var NTI622233 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI622231 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; +var NTI624105 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; +var NTI6086 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI6094 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI143 = {size: 0,kind: 31,base: null,node: null,finalizer: null}; +var NTI160043 = {size: 0, kind: 18, base: null, node: null, finalizer: null}; +var NTI6008 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI6131 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; +var NTI112 = {size: 0,kind: 28,base: null,node: null,finalizer: null}; +var NTI114 = {size: 0,kind: 29,base: null,node: null,finalizer: null}; +var NTI6126 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; +var NTI6062 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI6064 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI6078 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NTI6082 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; +var NNI6082 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI6082.node = NNI6082; +var NNI6078 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI6078.node = NNI6078; +var NNI6064 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI6064.node = NNI6064; +NTI6126.base = NTI6062; +NTI6131.base = NTI6062; +var NNI6062 = {kind: 2, len: 5, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "parent", len: 0, typ: NTI6126, name: "parent", sons: null}, +{kind: 1, offset: "name", len: 0, typ: NTI114, name: "name", sons: null}, +{kind: 1, offset: "message", len: 0, typ: NTI112, name: "msg", sons: null}, +{kind: 1, offset: "trace", len: 0, typ: NTI112, name: "trace", sons: null}, +{kind: 1, offset: "up", len: 0, typ: NTI6131, name: "up", sons: null}]}; +NTI6062.node = NNI6062; +var NNI6008 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI6008.node = NNI6008; +NTI6062.base = NTI6008; +NTI6064.base = NTI6062; +NTI6078.base = NTI6064; +NTI6082.base = NTI6078; +var NNI160043 = {kind: 2, len: 2, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "Field0", len: 0, typ: NTI114, name: "Field0", sons: null}, +{kind: 1, offset: "Field1", len: 0, typ: NTI143, name: "Field1", sons: null}]}; +NTI160043.node = NNI160043; +var NNI6094 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI6094.node = NNI6094; +NTI6094.base = NTI6064; +var NNI6086 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI6086.node = NNI6086; +NTI6086.base = NTI6064; +NTI622570.base = NTI622231; +NTI622572.base = NTI622231; +NTI622574.base = NTI622231; +var NNI622229 = {kind: 2, offset: 0, typ: null, name: null, len: 12, sons: {"1": {kind: 1, offset: 1, typ: NTI622229, name: "ElementNode", len: 0, sons: null}, +"2": {kind: 1, offset: 2, typ: NTI622229, name: "AttributeNode", len: 0, sons: null}, +"3": {kind: 1, offset: 3, typ: NTI622229, name: "TextNode", len: 0, sons: null}, +"4": {kind: 1, offset: 4, typ: NTI622229, name: "CDATANode", len: 0, sons: null}, +"5": {kind: 1, offset: 5, typ: NTI622229, name: "EntityRefNode", len: 0, sons: null}, +"6": {kind: 1, offset: 6, typ: NTI622229, name: "EntityNode", len: 0, sons: null}, +"7": {kind: 1, offset: 7, typ: NTI622229, name: "ProcessingInstructionNode", len: 0, sons: null}, +"8": {kind: 1, offset: 8, typ: NTI622229, name: "CommentNode", len: 0, sons: null}, +"9": {kind: 1, offset: 9, typ: NTI622229, name: "DocumentNode", len: 0, sons: null}, +"10": {kind: 1, offset: 10, typ: NTI622229, name: "DocumentTypeNode", len: 0, sons: null}, +"11": {kind: 1, offset: 11, typ: NTI622229, name: "DocumentFragmentNode", len: 0, sons: null}, +"12": {kind: 1, offset: 12, typ: NTI622229, name: "NotationNode", len: 0, sons: null}}}; +NTI622229.node = NNI622229; +var NNI622289 = {kind: 2, len: 100, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "background", len: 0, typ: NTI114, name: "background", sons: null}, +{kind: 1, offset: "backgroundAttachment", len: 0, typ: NTI114, name: "backgroundAttachment", sons: null}, +{kind: 1, offset: "backgroundColor", len: 0, typ: NTI114, name: "backgroundColor", sons: null}, +{kind: 1, offset: "backgroundImage", len: 0, typ: NTI114, name: "backgroundImage", sons: null}, +{kind: 1, offset: "backgroundPosition", len: 0, typ: NTI114, name: "backgroundPosition", sons: null}, +{kind: 1, offset: "backgroundRepeat", len: 0, typ: NTI114, name: "backgroundRepeat", sons: null}, +{kind: 1, offset: "backgroundSize", len: 0, typ: NTI114, name: "backgroundSize", sons: null}, +{kind: 1, offset: "border", len: 0, typ: NTI114, name: "border", sons: null}, +{kind: 1, offset: "borderBottom", len: 0, typ: NTI114, name: "borderBottom", sons: null}, +{kind: 1, offset: "borderBottomColor", len: 0, typ: NTI114, name: "borderBottomColor", sons: null}, +{kind: 1, offset: "borderBottomStyle", len: 0, typ: NTI114, name: "borderBottomStyle", sons: null}, +{kind: 1, offset: "borderBottomWidth", len: 0, typ: NTI114, name: "borderBottomWidth", sons: null}, +{kind: 1, offset: "borderColor", len: 0, typ: NTI114, name: "borderColor", sons: null}, +{kind: 1, offset: "borderLeft", len: 0, typ: NTI114, name: "borderLeft", sons: null}, +{kind: 1, offset: "borderLeftColor", len: 0, typ: NTI114, name: "borderLeftColor", sons: null}, +{kind: 1, offset: "borderLeftStyle", len: 0, typ: NTI114, name: "borderLeftStyle", sons: null}, +{kind: 1, offset: "borderLeftWidth", len: 0, typ: NTI114, name: "borderLeftWidth", sons: null}, +{kind: 1, offset: "borderRadius", len: 0, typ: NTI114, name: "borderRadius", sons: null}, +{kind: 1, offset: "borderRight", len: 0, typ: NTI114, name: "borderRight", sons: null}, +{kind: 1, offset: "borderRightColor", len: 0, typ: NTI114, name: "borderRightColor", sons: null}, +{kind: 1, offset: "borderRightStyle", len: 0, typ: NTI114, name: "borderRightStyle", sons: null}, +{kind: 1, offset: "borderRightWidth", len: 0, typ: NTI114, name: "borderRightWidth", sons: null}, +{kind: 1, offset: "borderStyle", len: 0, typ: NTI114, name: "borderStyle", sons: null}, +{kind: 1, offset: "borderTop", len: 0, typ: NTI114, name: "borderTop", sons: null}, +{kind: 1, offset: "borderTopColor", len: 0, typ: NTI114, name: "borderTopColor", sons: null}, +{kind: 1, offset: "borderTopStyle", len: 0, typ: NTI114, name: "borderTopStyle", sons: null}, +{kind: 1, offset: "borderTopWidth", len: 0, typ: NTI114, name: "borderTopWidth", sons: null}, +{kind: 1, offset: "borderWidth", len: 0, typ: NTI114, name: "borderWidth", sons: null}, +{kind: 1, offset: "bottom", len: 0, typ: NTI114, name: "bottom", sons: null}, +{kind: 1, offset: "boxSizing", len: 0, typ: NTI114, name: "boxSizing", sons: null}, +{kind: 1, offset: "boxShadow", len: 0, typ: NTI114, name: "boxShadow", sons: null}, +{kind: 1, offset: "captionSide", len: 0, typ: NTI114, name: "captionSide", sons: null}, +{kind: 1, offset: "clear", len: 0, typ: NTI114, name: "clear", sons: null}, +{kind: 1, offset: "clip", len: 0, typ: NTI114, name: "clip", sons: null}, +{kind: 1, offset: "color", len: 0, typ: NTI114, name: "color", sons: null}, +{kind: 1, offset: "cursor", len: 0, typ: NTI114, name: "cursor", sons: null}, +{kind: 1, offset: "direction", len: 0, typ: NTI114, name: "direction", sons: null}, +{kind: 1, offset: "display", len: 0, typ: NTI114, name: "display", sons: null}, +{kind: 1, offset: "emptyCells", len: 0, typ: NTI114, name: "emptyCells", sons: null}, +{kind: 1, offset: "cssFloat", len: 0, typ: NTI114, name: "cssFloat", sons: null}, +{kind: 1, offset: "font", len: 0, typ: NTI114, name: "font", sons: null}, +{kind: 1, offset: "fontFamily", len: 0, typ: NTI114, name: "fontFamily", sons: null}, +{kind: 1, offset: "fontSize", len: 0, typ: NTI114, name: "fontSize", sons: null}, +{kind: 1, offset: "fontStretch", len: 0, typ: NTI114, name: "fontStretch", sons: null}, +{kind: 1, offset: "fontStyle", len: 0, typ: NTI114, name: "fontStyle", sons: null}, +{kind: 1, offset: "fontVariant", len: 0, typ: NTI114, name: "fontVariant", sons: null}, +{kind: 1, offset: "fontWeight", len: 0, typ: NTI114, name: "fontWeight", sons: null}, +{kind: 1, offset: "height", len: 0, typ: NTI114, name: "height", sons: null}, +{kind: 1, offset: "left", len: 0, typ: NTI114, name: "left", sons: null}, +{kind: 1, offset: "letterSpacing", len: 0, typ: NTI114, name: "letterSpacing", sons: null}, +{kind: 1, offset: "lineHeight", len: 0, typ: NTI114, name: "lineHeight", sons: null}, +{kind: 1, offset: "listStyle", len: 0, typ: NTI114, name: "listStyle", sons: null}, +{kind: 1, offset: "listStyleImage", len: 0, typ: NTI114, name: "listStyleImage", sons: null}, +{kind: 1, offset: "listStylePosition", len: 0, typ: NTI114, name: "listStylePosition", sons: null}, +{kind: 1, offset: "listStyleType", len: 0, typ: NTI114, name: "listStyleType", sons: null}, +{kind: 1, offset: "margin", len: 0, typ: NTI114, name: "margin", sons: null}, +{kind: 1, offset: "marginBottom", len: 0, typ: NTI114, name: "marginBottom", sons: null}, +{kind: 1, offset: "marginLeft", len: 0, typ: NTI114, name: "marginLeft", sons: null}, +{kind: 1, offset: "marginRight", len: 0, typ: NTI114, name: "marginRight", sons: null}, +{kind: 1, offset: "marginTop", len: 0, typ: NTI114, name: "marginTop", sons: null}, +{kind: 1, offset: "maxHeight", len: 0, typ: NTI114, name: "maxHeight", sons: null}, +{kind: 1, offset: "maxWidth", len: 0, typ: NTI114, name: "maxWidth", sons: null}, +{kind: 1, offset: "minHeight", len: 0, typ: NTI114, name: "minHeight", sons: null}, +{kind: 1, offset: "minWidth", len: 0, typ: NTI114, name: "minWidth", sons: null}, +{kind: 1, offset: "opacity", len: 0, typ: NTI114, name: "opacity", sons: null}, +{kind: 1, offset: "outline", len: 0, typ: NTI114, name: "outline", sons: null}, +{kind: 1, offset: "overflow", len: 0, typ: NTI114, name: "overflow", sons: null}, +{kind: 1, offset: "overflowX", len: 0, typ: NTI114, name: "overflowX", sons: null}, +{kind: 1, offset: "overflowY", len: 0, typ: NTI114, name: "overflowY", sons: null}, +{kind: 1, offset: "padding", len: 0, typ: NTI114, name: "padding", sons: null}, +{kind: 1, offset: "paddingBottom", len: 0, typ: NTI114, name: "paddingBottom", sons: null}, +{kind: 1, offset: "paddingLeft", len: 0, typ: NTI114, name: "paddingLeft", sons: null}, +{kind: 1, offset: "paddingRight", len: 0, typ: NTI114, name: "paddingRight", sons: null}, +{kind: 1, offset: "paddingTop", len: 0, typ: NTI114, name: "paddingTop", sons: null}, +{kind: 1, offset: "pageBreakAfter", len: 0, typ: NTI114, name: "pageBreakAfter", sons: null}, +{kind: 1, offset: "pageBreakBefore", len: 0, typ: NTI114, name: "pageBreakBefore", sons: null}, +{kind: 1, offset: "pointerEvents", len: 0, typ: NTI114, name: "pointerEvents", sons: null}, +{kind: 1, offset: "position", len: 0, typ: NTI114, name: "position", sons: null}, +{kind: 1, offset: "resize", len: 0, typ: NTI114, name: "resize", sons: null}, +{kind: 1, offset: "right", len: 0, typ: NTI114, name: "right", sons: null}, +{kind: 1, offset: "scrollbar3dLightColor", len: 0, typ: NTI114, name: "scrollbar3dLightColor", sons: null}, +{kind: 1, offset: "scrollbarArrowColor", len: 0, typ: NTI114, name: "scrollbarArrowColor", sons: null}, +{kind: 1, offset: "scrollbarBaseColor", len: 0, typ: NTI114, name: "scrollbarBaseColor", sons: null}, +{kind: 1, offset: "scrollbarDarkshadowColor", len: 0, typ: NTI114, name: "scrollbarDarkshadowColor", sons: null}, +{kind: 1, offset: "scrollbarFaceColor", len: 0, typ: NTI114, name: "scrollbarFaceColor", sons: null}, +{kind: 1, offset: "scrollbarHighlightColor", len: 0, typ: NTI114, name: "scrollbarHighlightColor", sons: null}, +{kind: 1, offset: "scrollbarShadowColor", len: 0, typ: NTI114, name: "scrollbarShadowColor", sons: null}, +{kind: 1, offset: "scrollbarTrackColor", len: 0, typ: NTI114, name: "scrollbarTrackColor", sons: null}, +{kind: 1, offset: "tableLayout", len: 0, typ: NTI114, name: "tableLayout", sons: null}, +{kind: 1, offset: "textAlign", len: 0, typ: NTI114, name: "textAlign", sons: null}, +{kind: 1, offset: "textDecoration", len: 0, typ: NTI114, name: "textDecoration", sons: null}, +{kind: 1, offset: "textIndent", len: 0, typ: NTI114, name: "textIndent", sons: null}, +{kind: 1, offset: "textTransform", len: 0, typ: NTI114, name: "textTransform", sons: null}, +{kind: 1, offset: "transform", len: 0, typ: NTI114, name: "transform", sons: null}, +{kind: 1, offset: "top", len: 0, typ: NTI114, name: "top", sons: null}, +{kind: 1, offset: "verticalAlign", len: 0, typ: NTI114, name: "verticalAlign", sons: null}, +{kind: 1, offset: "visibility", len: 0, typ: NTI114, name: "visibility", sons: null}, +{kind: 1, offset: "width", len: 0, typ: NTI114, name: "width", sons: null}, +{kind: 1, offset: "wordSpacing", len: 0, typ: NTI114, name: "wordSpacing", sons: null}, +{kind: 1, offset: "zIndex", len: 0, typ: NTI143, name: "zIndex", sons: null}]}; +NTI622289.node = NNI622289; +NTI622289.base = NTI6008; +NTI622287.base = NTI622289; +var NNI622233 = {kind: 2, len: 16, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "attributes", len: 0, typ: NTI622570, name: "attributes", sons: null}, +{kind: 1, offset: "childNodes", len: 0, typ: NTI622572, name: "childNodes", sons: null}, +{kind: 1, offset: "children", len: 0, typ: NTI622574, name: "children", sons: null}, +{kind: 1, offset: "data", len: 0, typ: NTI114, name: "data", sons: null}, +{kind: 1, offset: "firstChild", len: 0, typ: NTI622231, name: "firstChild", sons: null}, +{kind: 1, offset: "lastChild", len: 0, typ: NTI622231, name: "lastChild", sons: null}, +{kind: 1, offset: "nextSibling", len: 0, typ: NTI622231, name: "nextSibling", sons: null}, +{kind: 1, offset: "nodeName", len: 0, typ: NTI114, name: "nodeName", sons: null}, +{kind: 1, offset: "nodeType", len: 0, typ: NTI622229, name: "nodeType", sons: null}, +{kind: 1, offset: "nodeValue", len: 0, typ: NTI114, name: "nodeValue", sons: null}, +{kind: 1, offset: "parentNode", len: 0, typ: NTI622231, name: "parentNode", sons: null}, +{kind: 1, offset: "previousSibling", len: 0, typ: NTI622231, name: "previousSibling", sons: null}, +{kind: 1, offset: "innerHTML", len: 0, typ: NTI114, name: "innerHTML", sons: null}, +{kind: 1, offset: "innerText", len: 0, typ: NTI114, name: "innerText", sons: null}, +{kind: 1, offset: "textContent", len: 0, typ: NTI114, name: "textContent", sons: null}, +{kind: 1, offset: "style", len: 0, typ: NTI622287, name: "style", sons: null}]}; +NTI622233.node = NNI622233; +var NNI622205 = {kind: 2, len: 20, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "onabort", len: 0, typ: NTI622378, name: "onabort", sons: null}, +{kind: 1, offset: "onblur", len: 0, typ: NTI622382, name: "onblur", sons: null}, +{kind: 1, offset: "onchange", len: 0, typ: NTI622386, name: "onchange", sons: null}, +{kind: 1, offset: "onclick", len: 0, typ: NTI622390, name: "onclick", sons: null}, +{kind: 1, offset: "ondblclick", len: 0, typ: NTI622394, name: "ondblclick", sons: null}, +{kind: 1, offset: "onerror", len: 0, typ: NTI622398, name: "onerror", sons: null}, +{kind: 1, offset: "onfocus", len: 0, typ: NTI622402, name: "onfocus", sons: null}, +{kind: 1, offset: "onkeydown", len: 0, typ: NTI622406, name: "onkeydown", sons: null}, +{kind: 1, offset: "onkeypress", len: 0, typ: NTI622410, name: "onkeypress", sons: null}, +{kind: 1, offset: "onkeyup", len: 0, typ: NTI622414, name: "onkeyup", sons: null}, +{kind: 1, offset: "onload", len: 0, typ: NTI622418, name: "onload", sons: null}, +{kind: 1, offset: "onmousedown", len: 0, typ: NTI622422, name: "onmousedown", sons: null}, +{kind: 1, offset: "onmousemove", len: 0, typ: NTI622426, name: "onmousemove", sons: null}, +{kind: 1, offset: "onmouseout", len: 0, typ: NTI622430, name: "onmouseout", sons: null}, +{kind: 1, offset: "onmouseover", len: 0, typ: NTI622434, name: "onmouseover", sons: null}, +{kind: 1, offset: "onmouseup", len: 0, typ: NTI622438, name: "onmouseup", sons: null}, +{kind: 1, offset: "onreset", len: 0, typ: NTI622442, name: "onreset", sons: null}, +{kind: 1, offset: "onselect", len: 0, typ: NTI622446, name: "onselect", sons: null}, +{kind: 1, offset: "onsubmit", len: 0, typ: NTI622450, name: "onsubmit", sons: null}, +{kind: 1, offset: "onunload", len: 0, typ: NTI622454, name: "onunload", sons: null}]}; +NTI622205.node = NNI622205; +NTI622205.base = NTI6008; +NTI622233.base = NTI622205; +NTI622231.base = NTI622233; +NTI624105.base = NTI622231; +NTI9835571.base = NTI114; +var NNI6098 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; +NTI6098.node = NNI6098; +NTI6098.base = NTI6064; +var NNI9681058 = {kind: 2, len: 2, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "Field0", len: 0, typ: NTI143, name: "Field0", sons: null}, +{kind: 1, offset: "Field1", len: 0, typ: NTI163, name: "Field1", sons: null}]}; +NTI9681058.node = NNI9681058; -function makeNimstrLit(c_23270) { - var ln = c_23270.length; +function makeNimstrLit(c_225062) { + var ln = c_225062.length; var result = new Array(ln); for (var i = 0; i < ln; ++i) { - result[i] = c_23270.charCodeAt(i); + result[i] = c_225062.charCodeAt(i); } return result; - + +} + +function arrayConstr(len_250067, value_250068, typ_250069) { + var result = new Array(len_250067); + for (var i = 0; i < len_250067; ++i) result[i] = nimCopy(null, value_250068, typ_250069); + return result; + + + } function setConstr() { - var result = {}; + var result = {}; for (var i = 0; i < arguments.length; ++i) { var x = arguments[i]; if (typeof(x) == "object") { @@ -276,103 +291,94 @@ function setConstr() { return result; - + } var ConstSet1 = setConstr(17, 16, 4, 18, 27, 19, 23, 22, 21); -function nimCopy(dest_24827, src_24828, ti_24829) { - var result_25019 = null; +function nimCopy(dest_240023, src_240024, ti_240025) { + var result_245219 = null; - switch (ti_24829.kind) { - case 21: - case 22: - case 23: - case 5: - if (!(is_fat_pointer_24801(ti_24829))) { - result_25019 = src_24828; - } - else { - result_25019 = [src_24828[0], src_24828[1]]; - } - - break; - case 19: - if (dest_24827 === null || dest_24827 === undefined) { - dest_24827 = {}; + switch (ti_240025.kind) { + case 21: + case 22: + case 23: + case 5: + if (!(is_fat_pointer_235401(ti_240025))) { + result_245219 = src_240024; } else { - for (var key in dest_24827) { delete dest_24827[key]; } + result_245219 = [src_240024[0], src_240024[1]]; } - for (var key in src_24828) { dest_24827[key] = src_24828[key]; } - result_25019 = dest_24827; + + break; + case 19: + if (dest_240023 === null || dest_240023 === undefined) { + dest_240023 = {}; + } + else { + for (var key in dest_240023) { delete dest_240023[key]; } + } + for (var key in src_240024) { dest_240023[key] = src_240024[key]; } + result_245219 = dest_240023; - break; - case 18: - case 17: - if (!((ti_24829.base == null))) { - result_25019 = nimCopy(dest_24827, src_24828, ti_24829.base); - } - else { - if ((ti_24829.kind == 17)) { - result_25019 = (dest_24827 === null || dest_24827 === undefined) ? {m_type: ti_24829} : dest_24827; - } - else { - result_25019 = (dest_24827 === null || dest_24827 === undefined) ? {} : dest_24827; - } - } - nimCopyAux(result_25019, src_24828, ti_24829.node); - break; - case 24: - case 4: - case 27: - case 16: - if (src_24828 === null) { - result_25019 = null; + break; + case 18: + case 17: + if (!((ti_240025.base == null))) { + result_245219 = nimCopy(dest_240023, src_240024, ti_240025.base); } else { - if (dest_24827 === null || dest_24827 === undefined) { - dest_24827 = new Array(src_24828.length); + if ((ti_240025.kind == 17)) { + result_245219 = (dest_240023 === null || dest_240023 === undefined) ? {m_type: ti_240025} : dest_240023; + } + else { + result_245219 = (dest_240023 === null || dest_240023 === undefined) ? {} : dest_240023; + } + } + nimCopyAux(result_245219, src_240024, ti_240025.node); + break; + case 24: + case 4: + case 27: + case 16: + if (src_240024 === null) { + result_245219 = null; + } + else { + if (dest_240023 === null || dest_240023 === undefined) { + dest_240023 = new Array(src_240024.length); } else { - dest_24827.length = src_24828.length; + dest_240023.length = src_240024.length; } - result_25019 = dest_24827; - for (var i = 0; i < src_24828.length; ++i) { - result_25019[i] = nimCopy(result_25019[i], src_24828[i], ti_24829.base); + result_245219 = dest_240023; + for (var i = 0; i < src_240024.length; ++i) { + result_245219[i] = nimCopy(result_245219[i], src_240024[i], ti_240025.base); } } - break; - case 28: - if (src_24828 !== null) { - result_25019 = src_24828.slice(0); + break; + case 28: + if (src_240024 !== null) { + result_245219 = src_240024.slice(0); } - break; - default: - result_25019 = src_24828; - break; - } + break; + default: + result_245219 = src_240024; + break; + } - return result_25019; + return result_245219; } -function arrayConstr(len_25086, value_25087, typ_25088) { - var result = new Array(len_25086); - for (var i = 0; i < len_25086; ++i) result[i] = nimCopy(null, value_25087, typ_25088); - return result; - - - -} - -function cstrToNimstr(c_23287) { - var ln = c_23287.length; +function cstrToNimstr(c_225079) { + var ln = c_225079.length; var result = new Array(ln); var r = 0; for (var i = 0; i < ln; ++i) { - var ch = c_23287.charCodeAt(i); + var ch = c_225079.charCodeAt(i); if (ch < 128) { result[r] = ch; @@ -387,7 +393,7 @@ function cstrToNimstr(c_23287) { } else { ++i; - ch = 65536 + (((ch & 1023) << 10) | (c_23287.charCodeAt(i) & 1023)); + ch = 65536 + (((ch & 1023) << 10) | (c_225079.charCodeAt(i) & 1023)); result[r] = (ch >> 18) | 240; ++r; result[r] = ((ch >> 12) & 63) | 128; @@ -403,1448 +409,1429 @@ function cstrToNimstr(c_23287) { return result; - + } -function toJSStr(s_23304) { - var Tmp5; - var Tmp7; +function toJSStr(s_225096) { + var Tmp5; + var Tmp7; - var result_23305 = null; + var result_225097 = null; - var res_23363 = new_seq_23336((s_23304 != null ? s_23304.length : 0)); - var i_23365 = 0; - var j_23367 = 0; - L1: do { - L2: while (true) { - if (!(i_23365 < (s_23304 != null ? s_23304.length : 0))) break L2; - var c_23368 = s_23304[i_23365]; - if ((c_23368 < 128)) { - res_23363[j_23367] = String.fromCharCode(c_23368); - i_23365 += 1; - } - else { - var helper_23391 = new_seq_23336(0); - L3: do { - L4: while (true) { - if (!true) break L4; - var code_23392 = c_23368.toString(16); - if (((code_23392 != null ? code_23392.length : 0) == 1)) { - if (helper_23391 != null) { helper_23391.push("%0"); } else { helper_23391 = ["%0"]; }; - } - else { - if (helper_23391 != null) { helper_23391.push("%"); } else { helper_23391 = ["%"]; }; - } - - if (helper_23391 != null) { helper_23391.push(code_23392); } else { helper_23391 = [code_23392]; }; - i_23365 += 1; - if (((s_23304 != null ? s_23304.length : 0) <= i_23365)) Tmp5 = true; else { Tmp5 = (s_23304[i_23365] < 128); } if (Tmp5) { - break L3; - } - - c_23368 = s_23304[i_23365]; - } - } while(false); + var res_225170 = new_seq_225128((s_225096 != null ? s_225096.length : 0)); + var i_225172 = 0; + var j_225174 = 0; + L1: do { + L2: while (true) { + if (!(i_225172 < (s_225096 != null ? s_225096.length : 0))) break L2; + var c_225175 = s_225096[i_225172]; + if ((c_225175 < 128)) { + res_225170[j_225174] = String.fromCharCode(c_225175); + i_225172 += 1; + } + else { + var helper_225198 = new_seq_225128(0); + L3: do { + L4: while (true) { + if (!true) break L4; + var code_225199 = c_225175.toString(16); + if (((code_225199 != null ? code_225199.length : 0) == 1)) { + if (helper_225198 != null) { helper_225198.push("%0"); } else { helper_225198 = ["%0"]; }; + } + else { + if (helper_225198 != null) { helper_225198.push("%"); } else { helper_225198 = ["%"]; }; + } + + if (helper_225198 != null) { helper_225198.push(code_225199); } else { helper_225198 = [code_225199]; }; + i_225172 += 1; + if (((s_225096 != null ? s_225096.length : 0) <= i_225172)) Tmp5 = true; else { Tmp5 = (s_225096[i_225172] < 128); } if (Tmp5) { + break L3; + } + + c_225175 = s_225096[i_225172]; + } + } while(false); ++excHandler; - Tmp7 = framePtr; - try { - res_23363[j_23367] = decodeURIComponent(helper_23391.join("")); + Tmp7 = framePtr; + try { + res_225170[j_225174] = decodeURIComponent(helper_225198.join("")); --excHandler; } catch (EXC) { var prevJSError = lastJSError; lastJSError = EXC; --excHandler; - framePtr = Tmp7; - res_23363[j_23367] = helper_23391.join(""); - lastJSError = prevJSError; - } finally { - framePtr = Tmp7; - } - } - - j_23367 += 1; - } - } while(false); - if (res_23363 === null) res_23363 = []; - if (res_23363.length < j_23367) { for (var i=res_23363.length;i 2147483647 || result < -2147483648) raiseOverflow(); return result; - + } -function chckIndx(i_25105, a_25106, b_25107) { - var Tmp1; +function chckIndx(i_250086, a_250087, b_250088) { + var Tmp1; - var result_25108 = 0; + var result_250089 = 0; - BeforeRet: do { - if (!(a_25106 <= i_25105)) Tmp1 = false; else { Tmp1 = (i_25105 <= b_25107); } if (Tmp1) { - result_25108 = i_25105; - break BeforeRet; - } - else { - raiseIndexError(i_25105, a_25106, b_25107); - } - - } while (false); + BeforeRet: do { + if (!(a_250087 <= i_250086)) Tmp1 = false; else { Tmp1 = (i_250086 <= b_250088); } if (Tmp1) { + result_250089 = i_250086; + break BeforeRet; + } + else { + raiseIndexError(i_250086, a_250087, b_250088); + } + + } while (false); - return result_25108; + return result_250089; } -function subInt(a_23821, b_23822) { - var result = a_23821 - b_23822; +function subInt(a_230421, b_230422) { + var result = a_230421 - b_230422; if (result > 2147483647 || result < -2147483648) raiseOverflow(); return result; - + } var ConstSet2 = setConstr([65, 90]); -function chckRange(i_25124, a_25125, b_25126) { - var Tmp1; +function chckRange(i_255016, a_255017, b_255018) { + var Tmp1; - var result_25127 = 0; + var result_255019 = 0; - BeforeRet: do { - if (!(a_25125 <= i_25124)) Tmp1 = false; else { Tmp1 = (i_25124 <= b_25126); } if (Tmp1) { - result_25127 = i_25124; - break BeforeRet; - } - else { - raiseRangeError(); - } - - } while (false); + BeforeRet: do { + if (!(a_255017 <= i_255016)) Tmp1 = false; else { Tmp1 = (i_255016 <= b_255018); } if (Tmp1) { + result_255019 = i_255016; + break BeforeRet; + } + else { + raiseRangeError(); + } + + } while (false); - return result_25127; + return result_255019; } var ConstSet3 = setConstr(95, 32, 46); var ConstSet4 = setConstr(95, 32, 46); -function mulInt(a_23839, b_23840) { - var result = a_23839 * b_23840; +function mulInt(a_230439, b_230440) { + var result = a_230439 * b_230440; if (result > 2147483647 || result < -2147483648) raiseOverflow(); return result; - + } var ConstSet5 = setConstr([97, 122]); var ConstSet6 = setConstr([65, 90], [97, 122]); var ConstSet7 = setConstr([97, 122]); var ConstSet8 = setConstr([65, 90]); -function nimMax(a_24221, b_24222) { - var Tmp1; +function nimMax(a_230821, b_230822) { + var Tmp1; - var result_24223 = 0; + var result_230823 = 0; - BeforeRet: do { - if ((b_24222 <= a_24221)) { - Tmp1 = a_24221; - } - else { - Tmp1 = b_24222; - } - - result_24223 = Tmp1; - break BeforeRet; - } while (false); + BeforeRet: do { + if ((b_230822 <= a_230821)) { + Tmp1 = a_230821; + } + else { + Tmp1 = b_230822; + } + + result_230823 = Tmp1; + break BeforeRet; + } while (false); - return result_24223; + return result_230823; } -function nimMin(a_24203, b_24204) { - var Tmp1; +function nimMin(a_230803, b_230804) { + var Tmp1; - var result_24205 = 0; + var result_230805 = 0; - BeforeRet: do { - if ((a_24203 <= b_24204)) { - Tmp1 = a_24203; - } - else { - Tmp1 = b_24204; - } - - result_24205 = Tmp1; - break BeforeRet; - } while (false); + BeforeRet: do { + if ((a_230803 <= b_230804)) { + Tmp1 = a_230803; + } + else { + Tmp1 = b_230804; + } + + result_230805 = Tmp1; + break BeforeRet; + } while (false); - return result_24205; + return result_230805; } var nim_program_result = 0; -var global_raise_hook_18618 = [null]; -var local_raise_hook_18623 = [null]; -var out_of_mem_hook_18626 = [null]; - if (!Math.trunc) { - Math.trunc = function(v) { - v = +v; - if (!isFinite(v)) return v; +var global_raise_hook_142018 = [null]; +var local_raise_hook_142023 = [null]; +var out_of_mem_hook_142026 = [null]; +var unhandled_exception_hook_142031 = [null]; +if (!Math.trunc) { + Math.trunc = function(v) { + v = +v; + if (!isFinite(v)) return v; + return (v - v % 1) || (v < 0 ? -0 : v === 0 ? v : 0); + }; +} - return (v - v % 1) || (v < 0 ? -0 : v === 0 ? v : 0); - }; - } -var alternative_162319 = [null]; +var alternative_9835319 = [null]; -function is_fat_pointer_24801(ti_24803) { - var result_24804 = false; +function add_142042(x_142045, x_142045_Idx, y_142046) { + if (x_142045[x_142045_Idx] === null) { x_142045[x_142045_Idx] = []; } + var off = x_142045[x_142045_Idx].length; + x_142045[x_142045_Idx].length += y_142046.length; + for (var i = 0; i < y_142046.length; ++i) { + x_142045[x_142045_Idx][off+i] = y_142046.charCodeAt(i); + } + - BeforeRet: do { - result_24804 = !((ConstSet1[ti_24803.base.kind] != undefined)); - break BeforeRet; - } while (false); + +} - return result_24804; +function is_fat_pointer_235401(ti_235403) { + var result_235404 = false; + + BeforeRet: do { + result_235404 = !((ConstSet1[ti_235403.base.kind] != undefined)); + break BeforeRet; + } while (false); + + return result_235404; } -function nimCopyAux(dest_24832, src_24833, n_24835) { - switch (n_24835.kind) { - case 0: - break; - case 1: - dest_24832[n_24835.offset] = nimCopy(dest_24832[n_24835.offset], src_24833[n_24835.offset], n_24835.typ); +function nimCopyAux(dest_240028, src_240029, n_240031) { + switch (n_240031.kind) { + case 0: + break; + case 1: + dest_240028[n_240031.offset] = nimCopy(dest_240028[n_240031.offset], src_240029[n_240031.offset], n_240031.typ); - break; - case 2: - for (var i = 0; i < n_24835.sons.length; i++) { - nimCopyAux(dest_24832, src_24833, n_24835.sons[i]); + break; + case 2: + for (var i = 0; i < n_240031.sons.length; i++) { + nimCopyAux(dest_240028, src_240029, n_240031.sons[i]); } - break; - case 3: - dest_24832[n_24835.offset] = nimCopy(dest_24832[n_24835.offset], src_24833[n_24835.offset], n_24835.typ); - for (var i = 0; i < n_24835.sons.length; ++i) { - nimCopyAux(dest_24832, src_24833, n_24835.sons[i][1]); + break; + case 3: + dest_240028[n_240031.offset] = nimCopy(dest_240028[n_240031.offset], src_240029[n_240031.offset], n_240031.typ); + for (var i = 0; i < n_240031.sons.length; ++i) { + nimCopyAux(dest_240028, src_240029, n_240031.sons[i][1]); } - break; - } + break; + } - + } -function add_18638(x_18641, x_18641_Idx, y_18642) { - if (x_18641[x_18641_Idx] === null) { x_18641[x_18641_Idx] = []; } - var off = x_18641[x_18641_Idx].length; - x_18641[x_18641_Idx].length += y_18642.length; - for (var i = 0; i < y_18642.length; ++i) { - x_18641[x_18641_Idx][off+i] = y_18642.charCodeAt(i); - } +function aux_write_stack_trace_160038(f_160040) { + var Tmp3; + + var result_160041 = [null]; + + var it_160049 = f_160040; + var i_160051 = 0; + var total_160053 = 0; + var temp_frames_160060 = arrayConstr(64, {Field0: null, Field1: 0}, NTI160043); + L1: do { + L2: while (true) { + if (!!((it_160049 == null))) Tmp3 = false; else { Tmp3 = (i_160051 <= 63); } if (!Tmp3) break L2; + temp_frames_160060[i_160051].Field0 = it_160049.procname; + temp_frames_160060[i_160051].Field1 = it_160049.line; + i_160051 += 1; + total_160053 += 1; + it_160049 = it_160049.prev; + } + } while(false); + L4: do { + L5: while (true) { + if (!!((it_160049 == null))) break L5; + total_160053 += 1; + it_160049 = it_160049.prev; + } + } while(false); + result_160041[0] = nimCopy(null, [], NTI112); + if (!((total_160053 == i_160051))) { + if (result_160041[0] != null) { result_160041[0] = (result_160041[0]).concat(makeNimstrLit("(")); } else { result_160041[0] = makeNimstrLit("("); }; + if (result_160041[0] != null) { result_160041[0] = (result_160041[0]).concat(cstrToNimstr(((total_160053 - i_160051))+"")); } else { result_160041[0] = cstrToNimstr(((total_160053 - i_160051))+"").slice(); }; + if (result_160041[0] != null) { result_160041[0] = (result_160041[0]).concat(makeNimstrLit(" calls omitted) ...\x0A")); } else { result_160041[0] = makeNimstrLit(" calls omitted) ...\x0A"); }; + } + + L6: do { + var j_175236 = 0; + var colontmp__9835463 = 0; + colontmp__9835463 = (i_160051 - 1); + var res_9835468 = colontmp__9835463; + L7: do { + L8: while (true) { + if (!(0 <= res_9835468)) break L8; + j_175236 = res_9835468; + add_142042(result_160041, 0, temp_frames_160060[j_175236].Field0); + if ((0 < temp_frames_160060[j_175236].Field1)) { + if (result_160041[0] != null) { result_160041[0] = (result_160041[0]).concat(makeNimstrLit(", line: ")); } else { result_160041[0] = makeNimstrLit(", line: "); }; + if (result_160041[0] != null) { result_160041[0] = (result_160041[0]).concat(cstrToNimstr((temp_frames_160060[j_175236].Field1)+"")); } else { result_160041[0] = cstrToNimstr((temp_frames_160060[j_175236].Field1)+"").slice(); }; + } + + if (result_160041[0] != null) { result_160041[0] = (result_160041[0]).concat(makeNimstrLit("\x0A")); } else { result_160041[0] = makeNimstrLit("\x0A"); }; + res_9835468 -= 1; + } + } while(false); + } while(false); + + return result_160041[0]; + +} + +function raw_write_stack_trace_180059() { + var result_180061 = null; + + if (!((framePtr == null))) { + result_180061 = nimCopy(null, (makeNimstrLit("Traceback (most recent call last)\x0A") || []).concat(aux_write_stack_trace_160038(framePtr) || []), NTI112); + } + else { + result_180061 = nimCopy(null, makeNimstrLit("No stack traceback available\x0A"), NTI112); + } - -} - -function aux_write_stack_trace_21151(f_21153) { - var Tmp3; - - var result_21154 = [null]; - - var it_21162 = f_21153; - var i_21164 = 0; - var total_21166 = 0; - var temp_frames_21173 = arrayConstr(64, {Field0: null, Field1: 0}, NTI21156); - L1: do { - L2: while (true) { - if (!!((it_21162 == null))) Tmp3 = false; else { Tmp3 = (i_21164 <= 63); } if (!Tmp3) break L2; - temp_frames_21173[i_21164].Field0 = it_21162.procname; - temp_frames_21173[i_21164].Field1 = it_21162.line; - i_21164 += 1; - total_21166 += 1; - it_21162 = it_21162.prev; - } - } while(false); - L4: do { - L5: while (true) { - if (!!((it_21162 == null))) break L5; - total_21166 += 1; - it_21162 = it_21162.prev; - } - } while(false); - result_21154[0] = nimCopy(null, [], NTI138); - if (!((total_21166 == i_21164))) { - if (result_21154[0] != null) { result_21154[0] = (result_21154[0]).concat(makeNimstrLit("(")); } else { result_21154[0] = makeNimstrLit("("); }; - if (result_21154[0] != null) { result_21154[0] = (result_21154[0]).concat(cstrToNimstr(((total_21166 - i_21164))+"")); } else { result_21154[0] = cstrToNimstr(((total_21166 - i_21164))+"").slice(); }; - if (result_21154[0] != null) { result_21154[0] = (result_21154[0]).concat(makeNimstrLit(" calls omitted) ...\x0A")); } else { result_21154[0] = makeNimstrLit(" calls omitted) ...\x0A"); }; - } - - L6: do { - var j_21421 = 0; - var colontmp__162466 = 0; - colontmp__162466 = (i_21164 - 1); - var res_162471 = colontmp__162466; - L7: do { - L8: while (true) { - if (!(0 <= res_162471)) break L8; - j_21421 = res_162471; - add_18638(result_21154, 0, temp_frames_21173[j_21421].Field0); - if ((0 < temp_frames_21173[j_21421].Field1)) { - if (result_21154[0] != null) { result_21154[0] = (result_21154[0]).concat(makeNimstrLit(", line: ")); } else { result_21154[0] = makeNimstrLit(", line: "); }; - if (result_21154[0] != null) { result_21154[0] = (result_21154[0]).concat(cstrToNimstr((temp_frames_21173[j_21421].Field1)+"")); } else { result_21154[0] = cstrToNimstr((temp_frames_21173[j_21421].Field1)+"").slice(); }; - } - - if (result_21154[0] != null) { result_21154[0] = (result_21154[0]).concat(makeNimstrLit("\x0A")); } else { result_21154[0] = makeNimstrLit("\x0A"); }; - res_162471 -= 1; - } - } while(false); - } while(false); - - return result_21154[0]; + return result_180061; } -function raw_write_stack_trace_21468() { - var result_21470 = null; +function new_seq_225128(len_225131) { + var result_225133 = null; - if (!((framePtr == null))) { - result_21470 = nimCopy(null, (makeNimstrLit("Traceback (most recent call last)\x0A") || []).concat(aux_write_stack_trace_21151(framePtr) || []), NTI138); - } - else { - result_21470 = nimCopy(null, makeNimstrLit("No stack traceback available\x0A"), NTI138); - } - + var F={procname:"newSeq.newSeq",prev:framePtr,filename:"system.nim",line:0}; + framePtr = F; + F.line = 626; + result_225133 = new Array(len_225131); for (var i=0;i", "text/html"); - stuff_162563 = doc.documentElement; + stuff_9835556 = doc.documentElement; - F.line = 286; - db_162535[0] = nimCopy(null, stuff_162563.getElementsByClassName("reference"), NTI44305); - F.line = 287; - contents_162537[0] = nimCopy(null, [], NTI162578); - L1: do { - F.line = 288; - var ahref_162814 = null; - F.line = 184; - var i_163045 = 0; - F.line = 185; - var l_163046 = (db_162535[0] != null ? db_162535[0].length : 0); - L2: do { - F.line = 186; - L3: while (true) { - if (!(i_163045 < l_163046)) break L3; - F.line = 288; - ahref_162814 = db_162535[0][chckIndx(i_163045, 0, (db_162535[0] != null ? db_162535[0].length : 0)+0-1)-0]; - F.line = 289; - if (contents_162537[0] != null) { contents_162537[0].push(ahref_162814.getAttribute("data-doc-search-tag")); } else { contents_162537[0] = [ahref_162814.getAttribute("data-doc-search-tag")]; }; - F.line = 188; - i_163045 = addInt(i_163045, 1); - if (!(((db_162535[0] != null ? db_162535[0].length : 0) == l_163046))) { - F.line = 189; - failed_assert_impl_15266(makeNimstrLit("/home/genotrance/.choosenim/toolchains/nim-1.0.4/lib/system/iterators.nim(189, 11) `len(a) == L` the length of the seq changed while iterating over it")); - } - - } - } while(false); - } while(false); - } - - F.line = 290; - var ul_162825 = tree_161020(makeNimstrLit("UL"), []); - F.line = 291; - result_162557 = tree_161020(makeNimstrLit("DIV"), []); - F.line = 292; - set_class_161103(result_162557, makeNimstrLit("search_results")); - F.line = 293; - var matches_162846 = []; - L4: do { - F.line = 294; - var i_162859 = 0; - F.line = 2737; - var colontmp__163052 = 0; - F.line = 294; - colontmp__163052 = (db_162535[0] != null ? db_162535[0].length : 0); - F.line = 2739; - var i_163053 = 0; - L5: do { - F.line = 2740; - L6: while (true) { - if (!(i_163053 < colontmp__163052)) break L6; - F.line = 294; - i_162859 = i_163053; - L7: do { - F.line = 295; - var c_162860 = contents_162537[0][chckIndx(i_162859, 0, (contents_162537[0] != null ? contents_162537[0].length : 0)+0-1)-0]; - if (((c_162860 == "Examples") || (c_162860 == "PEG construction"))) { - F.line = 300; - break L7; - } - - F.line = 301; - var colontmp__163062 = {Field0: 0, Field1: false}; - F.line = 301; - var score_162861 = 0; - F.line = 301; - var matched_162862 = false; - F.line = 301; - nimCopy(colontmp__163062, fuzzy_match_160070(value_162556, c_162860), NTI160074); - F.line = 301; - score_162861 = colontmp__163062["Field0"]; - F.line = 301; - matched_162862 = colontmp__163062["Field1"]; - if (matched_162862) { - F.line = 303; - if (matches_162846 != null) { matches_162846.push({Field0: db_162535[0][chckIndx(i_162859, 0, (db_162535[0] != null ? db_162535[0].length : 0)+0-1)-0], Field1: score_162861}); } else { matches_162846 = [{Field0: db_162535[0][chckIndx(i_162859, 0, (db_162535[0] != null ? db_162535[0].length : 0)+0-1)-0], Field1: score_162861}]; }; - } - - } while(false); - F.line = 2742; - i_163053 = addInt(i_163053, 1); - } - } while(false); - } while(false); - F.line = 305; - matches_162846.sort(HEX3Aanonymous_162873); - L8: do { - F.line = 306; - var i_162926 = 0; - F.line = 2737; - var colontmp__163058 = 0; - F.line = 306; - colontmp__163058 = nimMin((matches_162846 != null ? matches_162846.length : 0), 19); - F.line = 2739; - var i_163059 = 0; - L9: do { - F.line = 2740; - L10: while (true) { - if (!(i_163059 < colontmp__163058)) break L10; - F.line = 306; - i_162926 = i_163059; - F.line = 307; - matches_162846[chckIndx(i_162926, 0, (matches_162846 != null ? matches_162846.length : 0)+0-1)-0]["Field0"].innerHTML = matches_162846[chckIndx(i_162926, 0, (matches_162846 != null ? matches_162846.length : 0)+0-1)-0]["Field0"].getAttribute("data-doc-search-tag"); - F.line = 308; - add_161085(ul_162825, tree_161020(makeNimstrLit("LI"), [matches_162846[chckIndx(i_162926, 0, (matches_162846 != null ? matches_162846.length : 0)+0-1)-0]["Field0"]])); - F.line = 2742; - i_163059 = addInt(i_163059, 1); - } - } while(false); - } while(false); - if ((ul_162825.childNodes.length == 0)) { - F.line = 310; - add_161085(result_162557, tree_161020(makeNimstrLit("B"), [text_161120(makeNimstrLit("no search results"))])); - } - else { - F.line = 312; - add_161085(result_162557, tree_161020(makeNimstrLit("B"), [text_161120(makeNimstrLit("search results"))])); - F.line = 313; - add_161085(result_162557, ul_162825); - } - - framePtr = F.prev; + F.line = 286; + db_9835528[0] = nimCopy(null, stuff_9835556.getElementsByClassName("reference"), NTI624105); + F.line = 287; + contents_9835530[0] = nimCopy(null, [], NTI9835571); + L1: do { + F.line = 288; + var ahref_9845214 = null; + F.line = 184; + var i_9855040 = 0; + F.line = 185; + var l_9855041 = (db_9835528[0] != null ? db_9835528[0].length : 0); + L2: do { + F.line = 186; + L3: while (true) { + if (!(i_9855040 < l_9855041)) break L3; + F.line = 288; + ahref_9845214 = db_9835528[0][chckIndx(i_9855040, 0, (db_9835528[0] != null ? db_9835528[0].length : 0)+0-1)-0]; + F.line = 289; + if (contents_9835530[0] != null) { contents_9835530[0].push(ahref_9845214.getAttribute("data-doc-search-tag")); } else { contents_9835530[0] = [ahref_9845214.getAttribute("data-doc-search-tag")]; }; + F.line = 188; + i_9855040 = addInt(i_9855040, 1); + if (!(((db_9835528[0] != null ? db_9835528[0].length : 0) == l_9855041))) { + F.line = 189; + failed_assert_impl_102680(makeNimstrLit("/home/genotrance/.choosenim/toolchains/nim-#devel/lib/system/iterators.nim(189, 11) `len(a) == L` the length of the seq changed while iterating over it")); + } + + } + } while(false); + } while(false); + } + + F.line = 290; + var ul_9845225 = tree_9756020(makeNimstrLit("UL"), []); + F.line = 291; + result_9835550 = tree_9756020(makeNimstrLit("DIV"), []); + F.line = 292; + set_class_9756118(result_9835550, makeNimstrLit("search_results")); + F.line = 293; + var matches_9845246 = []; + L4: do { + F.line = 294; + var i_9845259 = 0; + F.line = 104; + var colontmp__9855047 = 0; + F.line = 294; + colontmp__9855047 = (db_9835528[0] != null ? db_9835528[0].length : 0); + F.line = 106; + var i_9855048 = 0; + L5: do { + F.line = 107; + L6: while (true) { + if (!(i_9855048 < colontmp__9855047)) break L6; + F.line = 294; + i_9845259 = i_9855048; + L7: do { + F.line = 295; + var c_9845260 = contents_9835530[0][chckIndx(i_9845259, 0, (contents_9835530[0] != null ? contents_9835530[0].length : 0)+0-1)-0]; + if (((c_9845260 == "Examples") || (c_9845260 == "PEG construction"))) { + F.line = 300; + break L7; + } + + F.line = 301; + var colontmp__9855055 = fuzzy_match_9681054(value_9835549, c_9845260); + F.line = 301; + var score_9845261 = colontmp__9855055["Field0"]; + F.line = 301; + var matched_9845262 = colontmp__9855055["Field1"]; + if (matched_9845262) { + F.line = 303; + if (matches_9845246 != null) { matches_9845246.push({Field0: db_9835528[0][chckIndx(i_9845259, 0, (db_9835528[0] != null ? db_9835528[0].length : 0)+0-1)-0], Field1: score_9845261}); } else { matches_9845246 = [{Field0: db_9835528[0][chckIndx(i_9845259, 0, (db_9835528[0] != null ? db_9835528[0].length : 0)+0-1)-0], Field1: score_9845261}]; }; + } + + } while(false); + F.line = 109; + i_9855048 = addInt(i_9855048, 1); + } + } while(false); + } while(false); + F.line = 305; + matches_9845246.sort(HEX3Aanonymous_9845273); + L8: do { + F.line = 306; + var i_9845326 = 0; + F.line = 104; + var colontmp__9855052 = 0; + F.line = 306; + colontmp__9855052 = nimMin((matches_9845246 != null ? matches_9845246.length : 0), 19); + F.line = 106; + var i_9855053 = 0; + L9: do { + F.line = 107; + L10: while (true) { + if (!(i_9855053 < colontmp__9855052)) break L10; + F.line = 306; + i_9845326 = i_9855053; + F.line = 307; + matches_9845246[chckIndx(i_9845326, 0, (matches_9845246 != null ? matches_9845246.length : 0)+0-1)-0]["Field0"].innerHTML = matches_9845246[chckIndx(i_9845326, 0, (matches_9845246 != null ? matches_9845246.length : 0)+0-1)-0]["Field0"].getAttribute("data-doc-search-tag"); + F.line = 308; + add_9756100(ul_9845225, tree_9756020(makeNimstrLit("LI"), [matches_9845246[chckIndx(i_9845326, 0, (matches_9845246 != null ? matches_9845246.length : 0)+0-1)-0]["Field0"]])); + F.line = 109; + i_9855053 = addInt(i_9855053, 1); + } + } while(false); + } while(false); + if ((ul_9845225.childNodes.length == 0)) { + F.line = 310; + add_9756100(result_9835550, tree_9756020(makeNimstrLit("B"), [text_9756135(makeNimstrLit("no search results"))])); + } + else { + F.line = 312; + add_9756100(result_9835550, tree_9756020(makeNimstrLit("B"), [text_9756135(makeNimstrLit("search results"))])); + F.line = 313; + add_9756100(result_9835550, ul_9845225); + } + + framePtr = F.prev; - return result_162557; + return result_9835550; } function search() { - function wrapper_162993() { - var F={procname:"search.wrapper",prev:framePtr,filename:"dochack.nim",line:0}; - framePtr = F; - F.line = 320; - var elem_162995 = document.getElementById("searchInput"); - F.line = 321; - var value_162996 = elem_162995.value; - if (!(((value_162996 != null ? value_162996.length : 0) == 0))) { - if ((oldtoc_162961[0] == null)) { - F.line = 324; - oldtoc_162961[0] = document.getElementById("tocRoot"); - } - - F.line = 325; - var results_163002 = dosearch_162554(value_162996); - F.line = 326; - replace_by_id_161172("tocRoot", results_163002); - } - else { - if (!((oldtoc_162961[0] == null))) { - F.line = 328; - replace_by_id_161172("tocRoot", oldtoc_162961[0]); - } - } - framePtr = F.prev; + function wrapper_9845435() { + var F={procname:"search.wrapper",prev:framePtr,filename:"dochack.nim",line:0}; + framePtr = F; + F.line = 320; + var elem_9845437 = document.getElementById("searchInput"); + F.line = 321; + var value_9845438 = elem_9845437.value; + if (!(((value_9845438 != null ? value_9845438.length : 0) == 0))) { + if ((oldtoc_9845403[0] == null)) { + F.line = 324; + oldtoc_9845403[0] = document.getElementById("tocRoot"); + } + + F.line = 325; + var results_9850006 = dosearch_9835547(value_9845438); + F.line = 326; + replace_by_id_9756172("tocRoot", results_9850006); + } + else { + if (!((oldtoc_9845403[0] == null))) { + F.line = 328; + replace_by_id_9756172("tocRoot", oldtoc_9845403[0]); + } + } + framePtr = F.prev; - - } + + } - var F={procname:"dochack.search",prev:framePtr,filename:"dochack.nim",line:0}; - framePtr = F; - if (!((timer_162962[0] == null))) { - F.line = 330; - clearTimeout(timer_162962[0]); - } - - F.line = 331; - timer_162962[0] = setTimeout(wrapper_162993, 400); - framePtr = F.prev; + var F={procname:"dochack.search",prev:framePtr,filename:"dochack.nim",line:0}; + framePtr = F; + if (!((timer_9845404[0] == null))) { + F.line = 330; + clearTimeout(timer_9845404[0]); + } + + F.line = 331; + timer_9845404[0] = setTimeout(wrapper_9845435, 400); + framePtr = F.prev; - + } diff --git a/docs.html b/docs.html new file mode 100644 index 0000000..d7955c5 --- /dev/null +++ b/docs.html @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + +docs + + + + + + + + +
+
+

docs

+
+
+
+ +     Dark Mode +
+ +
+ Search: +
+
+ Group by: + +
+ + +
+
+
+ +

+
+

Procs

+
+ +
proc buildDocs(files: openArray[string]; path: string;
+              baseDir = getProjectPath() & "/"; defines: openArray[string] = @[]) {...}{.
+    raises: [OSError, ValueError], tags: [ReadIOEffect].}
+
+ +

Generate docs for all specified nim files to the specified path

+

baseDir is the project path by default and files and path are relative to that directory. Set to "" if using absolute paths.

+

defines is a list of -d:xxx define flags (the xxx part) that should be passed to nim doc so that getHeader() is invoked correctly.

+

Use the --publish flag with nimble to publish docs contained in path to Github in the gh-pages branch. This requires the ghp-import package for Python: pip install ghp-import

+

WARNING: --publish will destroy any existing content in this branch.

+

NOTE: buildDocs() only works correctly on Windows with Nim 1.0+ since https://github.com/nim-lang/Nim/pull/11814 is required.

+ + +
+ +
+ +
+
+ +
+ +
+
+
+ + + diff --git a/docs.idx b/docs.idx new file mode 100644 index 0000000..e494dcb --- /dev/null +++ b/docs.idx @@ -0,0 +1 @@ +buildDocs docs.html#buildDocs,openArray[string],string,openArray[string] docs: buildDocs(files: openArray[string]; path: string; baseDir = getProjectPath() & "/";\n defines: openArray[string] = @[]) diff --git a/nimdoc.out.css b/nimdoc.out.css new file mode 100644 index 0000000..4ee73ea --- /dev/null +++ b/nimdoc.out.css @@ -0,0 +1,891 @@ +/* +Stylesheet for use with Docutils/rst2html. + +See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to +customize this style sheet. + +Modified from Chad Skeeters' rst2html-style +https://bitbucket.org/cskeeters/rst2html-style/ + +Modified by Boyd Greenfield and narimiran +*/ + +:root { + --primary-background: #fff; + --secondary-background: ghostwhite; + --third-background: #e8e8e8; + --border: #dde; + --text: #222; + --anchor: #07b; + --anchor-focus: #607c9f; + --input-focus: #1fa0eb; + --strong: #3c3c3c; + --hint: #9A9A9A; + --nim-sprite-base64: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAN4AAAA9CAYAAADCt9ebAAAACXBIWXMAAAsTAAALEwEAmpwYAAAFFmlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDggNzkuMTY0MDM2LCAyMDE5LzA4LzEzLTAxOjA2OjU3ICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgMjEuMCAoV2luZG93cykiIHhtcDpDcmVhdGVEYXRlPSIyMDE5LTEyLTAzVDAxOjAzOjQ4KzAxOjAwIiB4bXA6TW9kaWZ5RGF0ZT0iMjAxOS0xMi0wM1QwMjoyODo0MSswMTowMCIgeG1wOk1ldGFkYXRhRGF0ZT0iMjAxOS0xMi0wM1QwMjoyODo0MSswMTowMCIgZGM6Zm9ybWF0PSJpbWFnZS9wbmciIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiIHBob3Rvc2hvcDpJQ0NQcm9maWxlPSJzUkdCIElFQzYxOTY2LTIuMSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDozMzM0ZjAxYS0yMDExLWE1NGQtOTVjNy1iOTgxMDFlMDFhMmEiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MzMzNGYwMWEtMjAxMS1hNTRkLTk1YzctYjk4MTAxZTAxYTJhIiB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9InhtcC5kaWQ6MzMzNGYwMWEtMjAxMS1hNTRkLTk1YzctYjk4MTAxZTAxYTJhIj4gPHhtcE1NOkhpc3Rvcnk+IDxyZGY6U2VxPiA8cmRmOmxpIHN0RXZ0OmFjdGlvbj0iY3JlYXRlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDozMzM0ZjAxYS0yMDExLWE1NGQtOTVjNy1iOTgxMDFlMDFhMmEiIHN0RXZ0OndoZW49IjIwMTktMTItMDNUMDE6MDM6NDgrMDE6MDAiIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCAyMS4wIChXaW5kb3dzKSIvPiA8L3JkZjpTZXE+IDwveG1wTU06SGlzdG9yeT4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz4PsixkAAAJ5klEQVR4nO2dfbBUZR3HP3vvxVD0zo0ACXxBuQMoQjJ1DfMl0NIhNcuSZqQhfGt6UWtK06xJexkrmywVRTQlHCIdtclC0zBJvYIvvEUgZpc3XyC7RVbKlQu1/fHdbc+uu2fPOfs85+y55/nMnBl2z+5zfnc5v/M8z+8119XVRYroAG4HfgvMT1YUR4MMAa4HLkhakCRoSVqAELwLeBY4C7gF+D6QS1QiR1ROAJ4Dzk9akKQwoXhtwL4GxvHjU8AKoNPz3leAu4HBFq+bAyZZHD9rDAK+BywDDklYlkQxoXhfAtYAEw2MVckQYBHwU6or99nA08BBFq49GngUeBIYaWH8rNEJdAOXA60Jy5I4jSreSOBKYDzwBPCJhiUqcSjwe2BWnc9NLnxuvMFrnwqsAqYBBwBfNzh2FpmNfs9jkhakWcg1aFxZiH5UL3cDnwf+Xue7BwFjgFHAOwuv24tyob3cO0LIshP4EbCn8Pq/wKvA9sLxMvCvOmPsA1yDZnHv/nEv2mM+F0IeR4m8z7lM7tMbUbzj0CxX7YfbAXwaWFJ4PRrNIu9FS9KJyEIZN68CG4DnkRJtLBw7gHHAYuDdNb77EDAjBhkHIk7xKoiqeK3IwjilzuceQJvoZjdQ/AMZaeoZiWYgBXSEwyleBW0Rv3cR9ZUO4LSI48fN2wN+bi5wJNBvUZaBSCaVy48oxpVhwDdMC5ISxpJRh6/DLGEUrxXt29YBQ+2IkwquR76ofZIWxJFegireNLSnm48skFmmDfmiVgJHJyuKI620ADOpbWEcDPwYOZKD7OmyxCTkXL+wzueOiEEWR8poQb60V4A7kLm/yFjgKeALuM1xLfYDbkX+zEGe98cAX0Oui6viF8vR7OS6urragW2UZr21wK+Aiwlu7XPoN3sYOAd4H6WH1SnA0qSEcjQnRT/e1bgnsw16kGPez4/lyCBF48oNwL+TFGSAsgCndI4qFBVvJ0owdZhjL3CnxfHzBo8+YBMyol0CHBijrKbHS/LoA7Yio9sPgJNr/QHekLGR6MffL+KP4SjnHmQxtoXNmbQP+CHyV75hYDzTIWNpWkU8iR5mq71vVsZqXgtcFqNQ/wG2IOtfD8oi6AX+Ujj+isKz8sBrnu+1okyGdmD/wnEgcDClTIdRyJRvI1cvCMciq7At4rj5eoCPAusbHCfLigda/VyKgi+AtyreMGAzykGzQQ/wO+BxSlkCuy1dq8hw5OieUjimYT+x9bHCdWwS1823Ez1EXmhgjKwrXpHzkduuanbCtzGX+NkPPAj8GincNkPjNkIO5dadUjiOB95m+BonopQpm8R58/0JJbHWy2eshVM8sRvdbyurKV4Hmoka2WA/iwwLP6d+QmzSdKC92GzK/W9R+Q3woQbHCELcN991wJcjftcpXolngKm18vFmoVonYcgDv0Qz5pqGREuOTuA8lPYUZbndh0LJNpkUqgZx33xvomim7RG+6xSvnOm1gqQXoyiMoKxFs8VZpFfpQHvQK4HDUPnAsBa9bxGP0tUjF+IYCkxFew+/G3owdq20pgjzt3uPRscs/o43IaOhH2f4ZaAPRyZQP6vgbuCbyGext87F0sgIZFI/N8BnlwBnolovcWAjq/uzwM0+55cBJ0UYN84ZL+rfbnLMM4FfUDv7Z1XlCe8FetETbleNL7+CZrnvMjCVDuTOOA84Hf+96ga0PC8qXY50FQsuMg+41+d8p885R4n7gdt8zo+qvDkmUF4fZQXwEbS+99KDMhlWkw0eALqQglXyDDCdcovf+4lv5jPNXJ9zWc/FDMMdPudGVCreRlTWwVtWbynwYVQQCFSp61Q042WJLUjB1nneuw8tvXo97x1Lugvg+j1Mo9boySLVHtJFWqsthx5GlbSGeN5bigrHdqPl52Zj4qWLXvTQWY4KOX2ccgPMBLRcuy9+0YzhguXN4GuYq2Zc2R/NZg+hfYt3/9ZCepdQthmB4vIWIYOTbWyWzGt2Y0izG1fqjlltxnsdpbPMRMmd3lqTTumqMw7FZY5G5mSHw5dalreiRWYGWjbZ7gYUlFa0xOtIWA4vk1E6zWEoI+FvyYrjSAO1FG8DCmQGKd+DJFsGogWVVFiP/GWbga9Svg9NgtPQvnd04fUNCcriSBF+vqZ5nn9PQ+Xs4q401oI6EP0R+BkyXoAeAtcgBfwidnvkVaMVFTO6n1JoWTfqiONw1MVP8e6l3GVwOPJZXW5VItGGiuduAu5CZdOrMQJ1CHqpIFccS+LxaD/3Hcr7vF0Xw7UdAwQ/xduLGkJ6aUMhVAuwU006B3wM+ZLmozJ5QRhWkGs9yjKw1fhwDsq8eE/F+y+i1CeHIxD1wppupXrA5xyUOjQHMzU3cyjTeS2aaaN2Fzoc1bhch3xspuqBTkDulQVUz1q4mYEbNuewQD3FexGFS1VjOLoRHwOOinj9HAooXY2CSidHHKeSI5GFcRWNdSxqR7VH1iHHeTV24R+X53C8hSCBvPPqnD8B+AOygn6OYAm0ORSGthLl8B0d4DtRmIKsoMsJF1U/Hi1dt6DusIN8PrsIlUdwOAITpDFlC6q3MTbgmHm011qGepOvQSXPipyOCujW6rxqk0dRWYsVFe8PRSn5JxWOoEvdfOGzfnF5tnCRK+bGi33MoB1hL0U5d1H5J5oVD6A5mp8sQS6KSWh5e0jEcR4BPmhKqJA4xTM3XuxjBlW8DuRacDU3y0myNbNTPHPjxT5m0GTN15A/zVFiI+HKYzgc/ydMlrRfgmQWuYn0F91xJEQYxVuDnMcOrQAWJi2EI72ErQviwqLEQpQ+5XBEIqzi3YWLwF+BMiMcjshEqYR1Gdk1KmxBsaR9SQviSDdRFK8fxVU+YliWZmcbcq7vSFoQR/qJWvuxD0WgLDYoSzPzAqowtjVhORwDhEaKru4GPoliGgcyy4Hj0DLT4TBCo9WO88jQ8Bns97lLghvRTOfqqDiMYqrM+HyUYdBtaLykeRmlK12C9rQOh1FM1vd/HqUIzaT5e+LVoh/VxByHShs6HFaw0VjjHhTxP5d0LT+fRnu5q3HuAodlbHW02Q5cDByM+sw1642cRylCx6PeZiuTFScUFxK+f19QovaRS+t4tsasxhvABbZbSfUCV6CM7qtQl6Fm4E1U22UqcAYqvZ42fgJMxH6vdYc5nkBlSW6Pq4fbS6hb6jg0u9yGug7FyS5U1+UcVBbwbFSuMM1sQ1bXK4A9CcviqM0e9H80HdUxCpwIa4McygA/GfgAcCJqmGKKXUixupEv7nHsLc2agWNQ0d9OzC+PHNHIo1XeLCoe8kkqXiUtwKFoWXoEKqk3BpWLaC8cXsV8HT1J+tFTZKvn+DMqFZi1knvtyKg1O2lBHADcCVxEedNSAP4HJcsr0NNWHVUAAAAASUVORK5CYII="); + + --keyword: #5e8f60; + --identifier: #222; + --comment: #484a86; + --operator: #155da4; + --punctuation: black; + --other: black; + --escapeSequence: #c4891b; + --number: #252dbe; + --literal: #a4255b; + --raw-data: #a4255b; +} + +[data-theme="dark"] { + --primary-background: #171921; + --secondary-background: #1e202a; + --third-background: #2b2e3b; + --border: #0e1014; + --text: #fff; + --anchor: #8be9fd; + --anchor-focus: #8be9fd; + --input-focus: #8be9fd; + --strong: #bd93f9; + --hint: #7A7C85; + --nim-sprite-base64: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAARMAAABMCAYAAABOBlMuAAAACXBIWXMAAAsTAAALEwEAmpwYAAAFFmlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDggNzkuMTY0MDM2LCAyMDE5LzA4LzEzLTAxOjA2OjU3ICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgMjEuMCAoV2luZG93cykiIHhtcDpDcmVhdGVEYXRlPSIyMDE5LTEyLTAzVDAxOjE4OjIyKzAxOjAwIiB4bXA6TW9kaWZ5RGF0ZT0iMjAxOS0xMi0wM1QwMToyMDoxMCswMTowMCIgeG1wOk1ldGFkYXRhRGF0ZT0iMjAxOS0xMi0wM1QwMToyMDoxMCswMTowMCIgZGM6Zm9ybWF0PSJpbWFnZS9wbmciIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiIHBob3Rvc2hvcDpJQ0NQcm9maWxlPSJzUkdCIElFQzYxOTY2LTIuMSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDplZGViMzU3MC1iNmZjLWQyNDQtYTExZi0yMjc5YmY4NDNhYTAiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6ZWRlYjM1NzAtYjZmYy1kMjQ0LWExMWYtMjI3OWJmODQzYWEwIiB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9InhtcC5kaWQ6ZWRlYjM1NzAtYjZmYy1kMjQ0LWExMWYtMjI3OWJmODQzYWEwIj4gPHhtcE1NOkhpc3Rvcnk+IDxyZGY6U2VxPiA8cmRmOmxpIHN0RXZ0OmFjdGlvbj0iY3JlYXRlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDplZGViMzU3MC1iNmZjLWQyNDQtYTExZi0yMjc5YmY4NDNhYTAiIHN0RXZ0OndoZW49IjIwMTktMTItMDNUMDE6MTg6MjIrMDE6MDAiIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCAyMS4wIChXaW5kb3dzKSIvPiA8L3JkZjpTZXE+IDwveG1wTU06SGlzdG9yeT4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz4JZNR8AAAfG0lEQVR4nO2deViTZ7r/7yxkJaxJ2MK+GCBAMCwS1kgUFQSKK4XWWqsz1jpjp3b0tDP1V+eqU391fqfT/mpPPd20drTFDS0KFEVWJSGAEgLIZpAICBJACIRs549Rj1WILAkBfD/XlevySp68z/0S3+/7vPdzLyidTgcLkU2bd+z39/f/q1gshsrKSoJELFCa2iaEuU9K6kb+8uXxv54/fzE8L/eswNT2zCfQpjbAGKS8lPFKSEjIXiaTCSEhIeDj4xNnapsQ5j6rktZGp6UlfxIdzQVzCplmanvmG1hTG2BIAtlc26CgoDfT0tL2e3l5AQCAjY0NkMnk/a9s2k6rrKw8UV8n1JjYTIQ5RlAw14KzmL3xze1vfJyUuMJaq9UCFovFm9qu+YbBxcSPFUYkk8l2Q0NDsvo6ocrQx5+I8Ih4bz6f/0l8fHyKlZXV4/dRKBQwmcwwMpn8A4FAoPgHhH9bV1sxa488wZxoaycnJ/a9e/duCa5fkc3WvAiTI4Ib77p+XdqHG9anbfLy8gAAgLGxMdBpF+bjvzExqJj4scKI0dHRnwQHB++orq7+AgDeMuTxJ2Jl4rqU9PT0EwEBAUQCgTDuGAaDAampqYepVKpHUHDk325Ulw0a266YuFW+Gzdu/MDPz29jfn7+XgA4aOw5ESZP6kvpCXv3vnM8NiaSamVl+fj9BepGNDoGFRN7e/slcXFxO1xcXMDJyWnH7j//H/fi4uJdgutXmgw5z5O8smn7X9euXbvf29sbMBjMhONQKBRYWVlBbGzsbjMzM3JoOG+/sKKwy1h2rd/4elpGRsYuLy+vaDweD2w2Oy1h5ZrCvEunEaeeiVnMiabyl/F2/+X9P+8JDPQHHA5napMWBAYTk6DgSNuEhIS9DAYDAP7tq1i6dOkqOp3OWbNu0wens44emeoxA9lcWwKBYEMkEm2JRKIdHo+3QKFQWJ1Op8ZgMER3d/dVq1evTnFycpr0MSkUCsTExGzH4/Gk1LTME/39/TI0Go1FoVCg1WrVY2NjipGRkcGRkRH5dPwrEZHLXMPCwjJSUlIy3dzcfB+97+rqGhYSEpIOAIiYmBguN3zL77dt3uPh4W5qUxYUBhMTb2/vjeHh4cvR6P/dILK0tITIyEg7BweHr363/Z3Ampqaf1Zcu/zMKiVsyVJvMplsRyKR7IhEor2FhYUbhUJhJCYm2pFIJB6JRAIymQx4PB7QaDRoNBowMzMDJycnwOOn7icjEokQGxu7icFgbLp///7jFY1WqwWlUgkjIyOgUCgO7Ni5Rz48PCwfHh7uGRkZeaBQKOSjo6ODCoVCXlNVKn/6uCsT13FXrVr1emho6BYKhfLMnP7+/omrU9LPX8g+UThloxEMxqJFXjxESAyPQcSEExrLWLNmzW57e/txP/fw8ABHR8cdDAaDt3xF2ru9vb03sVgs0cbGxs/FxWVZUlISj0aj+dna2oKtrS1M5PcwJCgUCry8vODRrs84vPfoH6OjoyCXy6Gvr+/R6+CWrX9s7evrk/b19bWr1Wqli4sLZ8OGDe95eXmxUSjUuAd0cHDwjoqK2sYKXFIhvnldYYTTQpgU4/8+jyASCYDGoCd+ZkYYF8OICYezl8PhuOkbQyAQIDo62s/NzS2np6cHbGxsgEajAYFAAAwGA1gsFia6CE0NgUAABwcHsLe3B61WC2q1eo9WqwWNRgNKpRLUajUQiUSgUCh6zwGHwwGTydzo5+eXBQBnZu8MEJ5keHhYPqyYWMtHR0ZBpVIhYj9FUDONgOUvT12+du3avMDAQJjssdRqNWCxCyrEZdLodDoQi8Ulx44de628NL/V1Pa8iERE8l2dHB2CJvpcq9Nqbt1qKURWj1Njxld0ZGTkAW9v70kLCQC8sEIC8O/HKx8fn2gmk8kHgCk7pRFmzrWyAikASE1tx0Jj2uH0EZHL/N7YtuvT4OBgzmz4OBYSeDweIiMjt2S++vtMP1YYEmmJsCCY8mNOIJtr6+zsHBcZGXmIw+G4mZubG8m0hU9HRwcUFxe/KxQKTyDRsQjznSmJCS9+dVRERMTfQ0NDo2xtbfUGiSFMjtHRUaitrc3Jzc09kHvxVLmp7UFAmC6oZQkvrZLL5RJhReHtiQb5scKIXC7371FRUX90dnYGIpE4JR8Jgn40Gg20t7fXFxYWfnr9+vWjz8sdYi+Osh4vzgUBwZSgtu94V+fs7Hx7YGCgra6u7khLS0u2RCwYeTQgKmYFh8fj/f/g4OAldnZ2prR1wdPd3Q1CofBQSUnJkdLi3N8E93FCY6k+Pj48FxcXjlar1ZSWlh65VvYr4kREmDNg79+/D3FxcW5OTk5uXl5evNbW1tL0jK3ZXV1d1ykUintycvInoaGhdkj+gvGxs7MDPp+/m0AgWMQvS/lyeHhYTqPRPJycnIJSU1NZ3t7eW2g0Gly/fv2oWq1Gij0hzClQ/gHhpLS0tEM8Hm/7I8Ho7++HlpYWsLa2Bg8PDxOb+OKhUCigqakJ7t+/D25ubuDu7g4oFAp0Oh08ePAAvv7666TTWUdzTG0nAsKTYMU3ryuSU18+4+bmFrZo0SIOAICVlRUsXrx4zkakLnRIJBI8CgJ8MtdJp9NBZ2enqL29XWRC8xAQxgUNAHD+3L8KGhoaCp78ABES04JCoX4jJAAAAwMDUFtbe96YpRMQEKbL41DU5ubmko6Ojj2PSgggzD36+/vrb9y4cX425zzw93/8EBjon2is44+NjSkePBjqGRwc7G5v7xBV19w8U5B/3qgrr9+/uWtXUuKKD/TZ9MXh/066/OuFmunO8dGBQ98HBbGSp/t9U6LRaDXK0dHBoeFhuVzeL22/0yFqamopufjLqRJ933ssJi0tLSXV1dWHGAzGbuObOzs8ubqa71vZKpUKOjo6blwpOF8zm/Mu5cVkLlkSaswprAHAaVihgK7O7oSGxltvfXLon3nXK4RHT2cdN4pfKDCAlZyUuMJan02nTmczAaBmunPw4qI3cbnh0/36XICq0+lgcPABp7OrK629vUP5z8++LLh2XXD05L++yxrvC4/F5EZ12WBS8saLS5Ys2U2lUufUY45SqQSlUgkqlQrUavXj19jYGGg0GtBoNKDT6UCn05VotVq1TqfToFAojFar1eh0Og0Wi8XhcDgeGo1+/PhgZmYGOBwOsFgsmJmZ/eY1F+nt7YXa2trs2Z73wdCQBgCMHp1IJpHA09MdPD3dLRIS+OtKisvWvbP7vf2lZdePVFwzbHTwyMiI3hidkZFRUKvUYzOZ48HQkBIA5nWqBAqFAktLC7C0tADmIh88Pz4uMSyUk7hn776DV4tKPn/6d/lNxp1MJqsRCASf8vn8XdMpOjRTVCoVjI2NgUqlAq1WCyMjI9DX1wf379+Hvr6+/Q8ePOgdGRmRKxSKx0WLFAqFXKlUKnQ6nUar1arHq47mxwrD4/F4Eg6HI2GxWDwej7cgkUjWFAqFam5uTjU3N6eRyeQPLSwswNraGqysrIBAIDwWFywW+zja11Qi29LSclIikeSZZPJZBovBAI8XA8HBQR9kZZ3lR8cmvFZSlGe00p8IkwONRkNERBj4+i7a4+XpHv307/IbMakWlciXJbx0nMPh7Jqo0JGh0el0MDo6Cl1dXSCVSkEmk7177969W319fe1DQ0M9KpVKoVarlWq1WjndNhUPG3ApAWDcOxLTLwSDwWAOotFoDBaLxRMIBAsrKysne3t7Xzqd7k2n0/c4OzsDlUoFHA4364IyMDAATU1NxdWikhcq6tXKyhJezljPJZKI2eERS5cZeoWCMD2srCwhPX0tVzk2djiCG//GtfLLUoBxShB0dHTU3Lx580sLC4vtJBLJKMZoNBqQSqUglUqPdnR01PT09DT19/fLHjx40DM0NNQ72933GiSVGgB4JFQK+LfoSAGgnL04yppEIh2xtLS0t7GxcaFSqR7Ozs4fMRgMcHR0nJX8pJs3b54Ui8UXjT7RHIRMIkFK8irfwcEHPwQELUmqvYHUGJkLmJubw8YNa/i9vfffY/px3myQiDTPiEl9nVDDX576jaenZ7SnpyfLUJNrNBqQyWRw+/bt4x0dHTdkMlltV1dXw/XygjkdEv4wB0YOAK0AUM70C8HQ6fSzdDrdm0qlejg6OrLc3Ny2MBiMadWjfR4PHjyAmzdvZs/1v5MxoVAokJK8iicWS95k+nH+s0EiQhqpzQGoVFtYk5a87ba0XQAA34xbpagg/5zoT7s/OGNnZ8eaaYkBuVwOnZ2d5VKpVNTS0lLS2NhYWFVZ3Dujg5qQh6uY+ocvCAiKIPn4+Jz19PSMdnV15VCpVL6Dg4NBViw6nQ5EItHRpqamqzM+2DzHzo4O69amftLQeKsAZrDLgmBY/PyYsCIhfs+SiKUFE5Y8EwqFx11cXDihoaFTjjFAoVAwPDwMHR0dourq6jNCofDHhZqUVnvjmgIAcgAgJyg40mLRokX8kJCQjT4+PussLS1n1JPl7t27UFxcfHguB6mNjY2B7G4naNRTWyygUCjAYDGAx+PB0sICSCSi3vFYLBbCwjjA8vddBQtATKb7d3saBwc7IJPJBpsHjUGDGRYLJBIJLK0sAfucmyIGg4FFi3y8AwNZtycUk5KiS02vvf7WWQaDkejg4DApQwAeh3xDaWnpPoFAcPxFqnP6sEvgGf+A8Bx3d/cvIyIiNi1evHjT8wpNj8fAwACUlZW9P9dD5+/ckcFbf9gd2dcnn9LNAovF4inmZHtXNxdOdBR3+/JlS33pdP29wolEInA4weuiYxOy5vvuTkeHDHb+8c8xvb33Z3R9/N+Df+uIjYk02DwkEsna2trS1d/fNyGeF7uTyw1/7g3R3t4O2OxA/TVghULhcQqFQk1JSfmYSNR/5wD4d6EfgUBwvLS09IhUKhW9qAV5H9YjKQwJi6uvrKw8ERoamhkSEpKp7w7yJEqlEiQSyZmysrJv53qjdaVSCZdyTk+3qFMrAJRHRPLPN95qeifj5fU7mYt8JhyMRqMhMJDFdnF25gDAvBYTpXIMWlpay2fq/8m5mDcIABYGnEcGAGI/VlhBZWX1yZdSkz55OX0dV5+7w9bGGvz8mPrFpK62QskJjf2GTqd7x8bGbpnID4BCoUAmk0lLSkqOiESik2UleS/MakQflYKrXQDQxY1a3tTe3i6KiIjY5OXlxX7e9+rr6wsuXbr0t4ffn9OgMWjghMZQRcLp+8GulRVI/QPC37Wxtnal0ajJtjY2E451ZjiBra31vE9lR2PQQKFQaAAwo98Yi8Xq9fpPd56HO6rlvKWJv/PwcK+JilyCmajWMw6HAzs7+rMFpQOCIn6zHywSFvXm5eUdFAqFZ9Rq9bgHa2trq79w4cK+zz49cAARkmcpL81v/a/Dhz49d+7c3qqqqjyVSjXuOJ1OBxKJpDw3N/fA5V+zax6978cKw/sHhM/raMrnUVdboSy4fPWQSFSjd5yFBQWIRNKEd2IEw1J4JUd88WL+R51d3XrHWVDMnxUTa2tr1zXrNiUGsrmPf7DS4tymCxcu7Kuurs55+kKQSqVN586d23vs+8NHDXUCC5Wzp3/Iy8rKeruysvLM2Nhvo7VVKhXU1tYWnj17du/T7UOdnZ2D7OzsfGGB09raVi4S1RzXl0eFw+EAj8chYjKLVFffyOrq1C8mJBLpWTFRKBRyDofzC4vFWvXk+1ev/CLOzs7eKxAIslQqFeh0Oujp6enKzs7em/XTd7OayTqfKb56sT4rK+sPAoHg5KO/o0KhAKFQmHXy5MkdF3/5+TeZmctXpIXZ29v7zqVcKWNRX1epuXu3U/y8pEw0GmndOZt0dnXVDw0P6/W5oNHoZ30mQ0NDPb29vfvj4+Pf3rR5B/7od188XnEUXr4gDgmL+0NfX5/U19d3d3l5+YGfTnyDtLmcIhXXLsu4UcvfR6PRGGtra9eysrIjYrE45+kt4Fheou/69es/unnz5vm7d+/Wmsre2WRkZGTQ1DYg/JYGiUiTm1ugBAC9IfHPiEmDpFITE7fqJI/H27lmzZpDq5LWtz55t6wUXO3ihMYerK+vz2tpaUFaM0yT8tL81ujYle+TSCTrvEunBU9/voTLd92wYcPHVCqV39XVdXCu7+oYCp1O90Kc50Jk3I5+xVcv1jc3N5d4enpSMzIyvkpK3sh78nORsKg3++yPBS/q1q+hKCm61DSekERGJ3ikp6d/ERsbm1xVVXWwtbX1hRFtFAqFPMLMUyZsDyoQCI7LZDKIiIjwzczM/GpV0vro2TTsRSUqZoX3+vXrP1u9enXi0NAQiESirIdRtggIc5oJ40zq6uryGhoa8ry8vBJCQ0O9USjU94mrN7yWc+EnvaXb5gJMvxCMp6cnl0Kh2Le1tZVXXLs8L1LXefGrWRkZGZ/x+XyeUqkEkUh0vqenZ14HZyG8OEwoJjdrygd37NxTEBkZmWBtbQ3BwcEeKBTq+/UbX3/355Pfzlmn66qk9dGbN29+k8PhbCSRSNDZ2Snb9ae/HCkpKTksEhbN2QTD5NSX+Vu3bj0cHBzsjcFg4O7du1BWVvbNwxB9BIQ5j94I2Fu3bhXW19cDl8sFLBYLHA7Hg0wmf/e77e84ffXlPz6fLSMnQ2paZkJ4eHjmtm3b+B4eHvZkMhlQKBTY29s72dvbfxgUFJT8x7ffP1NRUfHjXErnZ/qFYKKjo7dt3rz5g8DAQPtH/XHa2tpqGhsbC55/BASEuYFeMblz505NTU3NgfDw8PcwGAygUCjw9fW1IJPJn/1130Hv0tLSI4WXL4hny9inYS+Osvbz80tgMpn8jIwMPovFch2vpoiDgwM4ODhwfH19OYsWLeJv3/Hu+cbGxquzXZz5aZYlvMRJT0/fFhkZue3JZmfd3d0gEolOIr4ShPmEXjFpkFRqXlrzSnFnZ+d7Tk5OjzNfXVxcICMjY6ezszNnVdL6vU8HWhmbgKAIkrOzMyc1NTXz0YU4maAuOp0OK1as4EVFRfGEQqHg1dfePHzr1q2rs71S8WOF4f38/BLS09M/iIyM5DxdxLq5uVlcVVU1bgVwBIS5il4xAQCQyWRigUBwJikpKe3JVGQcDgdLly7l2tranti0ecf7IpEoy9hbxX6sMDydTvdevXr1ltjY2F3u7u6AxT73FJ7B3Nwc4uLiwthsdphQKCzZkL7l0/r6+oKbNeVG90+EhMXZL1++fFtycvKHrq6uz4igUqmE5ubmEiTHCWG+8dwrUXD9imz9xtd/jIuLS7N5KpsTjUZDUFCQE4PB+F4oFGYmJW888Mv5k4UTHGpGxC9LYaenp78VEhKyxdHRESgUyoyOh0KhwNraGuLi4qIDAgKi6+rqyjekb/mHMSN6N6RvSdu+ffseNpsdZm09ftuW+vp6EIvFSB9hhHnHpG7rUqm0orW1tdXS0tLj6TIEaDQaaDQaxMfH811dXTl/3Xfw+JUrVz411J01cfWG6IiIiC07d+5McHNzs7ewMGyOFw6HAwcHB6BSqVx3d/fwz7/4rkAgEBwXCoUnHpZonDGrU9J5MTEx27du3Zrm4uKC0beaqq6u/ry+vj7XEPMiIMwmkxKTimuXZe/u+fCkp6fnexPdUfF4PPj7+1szGIydLi4unF1/+kvenTt3RG1tbRXTqfma8lIG39/fP/HVV19NZrFYHpMpzjQTzMzMwNPTE+Pp6Zng6emZ4Ofnl5CesfV8bW1tznQe3/wDwvFeXl7Rvr6+Ca+88kpaUFCQh74GXzqdDrq7u6GpqankRQmdR1hYTNrhUFVVlcXj8d6ysrKy0OfstLS0hPj4eC6Xy+U2NzeDRCI5/sa2XeX37t1rGhwc7BoYGJBN1P+FFbiE5OzszGaxWImvvvrqpoCAAKfp+ERmCpPJBCaTmcnhcDJLS0u/TE59+YxUKhXoi/lg+oVgrKysGJaWlna2trYeaWlpXDabvTMgIGDSfp2KiorzbW1tL0zoPMLCYtJX6uVfs2u++PKowMPDgz+ZIslEIhECAgKAxWJlajSazJ6eHmhra4PW1tZvtmz9o6Czs7O+r6+vfWxsbFir1WosLCzsV6xYkcnj8d7z9vaelmPV0Hh5eYGnp+f2mJiY7UVFRZ/HL0v5tru7+5ZGo1FisVg8Docj4fF4CxsbG1c+nx/m7e39sYeHB7i4uIC5ufmU6r4ODQ1BZWXlifkSrYuA8DRTumIrKytPent78728vCb9HRQKBVgsFhwcHIBOpwObzd4yNja2RaVSwdDQEHR1dcHo6CjQaDRwdXWdsWPV0KBQKPDw8AA7O7udERERO2tra2FgYACoVCo4OTkBjUYDMpkMeDz+8WuqaLVaaGxsbL19+/YzSX8ICPOFqYrJidDQ0AwvLy/e80c/CwaDARKJBI86BdJoNHB3dwe1Wj0nViL6IJPJwGQywdnZGZRKJRAIBDBUx8OBgQEoLS39BtkORpjPTJg1PB61N64pmpqarvb39xvUiLkuJE9CJpPBxsbGYEICANDZ2SlHgtQQ5jtTEhMAgLq6ulyJRFJvDGNeREZGRkAikRSUFuci2cEI85opi0l+7hmBWCzOeV6dToTJcfv27cHr168jxbgR5j1TFhMAgObm5hKZDNl0MAQtLS3Xzpw6hkS8Isx7piUmUqlUIBAIJuyjgzA5Ojs7QSKRINGuCAuCaYmJsKKw68qVK59KJJIu5HFneiiVSigqKjouEolOmtoWBARDMC0xAQC4+MvPJadOnXq3ra1N8yL0dDEkOp0OSktLy/Pz8w8+3d4CAWG+Mm0xAQA4fuy/jl+8ePGju3fvGsqeBY9Wq4XKysrWU6dOvX31yi8mKyyFgGBoZiQmAAD/79D+fadPn96PCMrz0el0UFVV1frtt9+mj9fiAgFhPjNjMQEAyMvLO3Ds2LE/tLS0INmuerh27Vr9999//xoiJAgLEYOEntbVVigB4PNNm3cMpqSkfMRms50McdyFgkqlgqKiovJTp069nZ97BhEShAWJQePYj373xdF1GzbLFQrFx6Ghob766ne8KNy7dw+KiopO5ubmfmTK4tsICMbG4EkxWT99d35l4rre/v7+D0NCQvh0Ot3QU8wL1Go1SKVSTX5+/sH8/PyDSP8bhIWOUTLsLuVklQcFR65pbGzcvnLlyvfc3NwsCASCMaaac+h0OhgaGoLq6uqaCxcu/OV01tGcTw7uM7VZCAhGx2jpug/vxAd58atzoqKitq1cuXKnvb29saabE+h0Oqiurpbm5eUdrK6uPlspuDrvY0hmO4YIhUIBGq1/X2CmNqFQKL3/79HomZ/z82xEowyy9zFr80zGDqPn/hdeviBmL47ad+fOnRsRERGbQkNDo62srIw97azT2dkJxcXFx0tKSo7Mdh8hY4LD4TDPH2U4MFjMc6tLmZmZzaj+Aw6H0/t9PB4PGCxmRudNJBL0ngeZTAI0Gj3jv+1szfM88Hic8cUEAKCmqlQOAN/ELU2qkEgkySwWK3HRokVcBoMxG9MbDZ1OB83NzdDU1FRQW1t7XiAQHJ+ovu18pbr6Rg6L5ZtoM0EhcUPT0tJW8tWRb0vQqIkvgKqqmhnVfrl2TfANXo+gjKlUio4OWc1M5sjOzjnQUH8rbqLPu3t6moaGhmfc+3q25tGHUqmECoEIUKbIrVkcEkONiIh4jcvlvu7s7OxLo9GmVe7QVCgUCujq6oKGhoaCioqKo9XV1WeM3YDMVPDik1gpyas+XrVyeaKXl8czjyANjbcgI/MNmkg49Q4ECPOH3NyC4RUr+M8IcHt7B1y9WlKRl3/5kElKnD1sfXEoJCzueEBAQGJYWFgGk8nk2djYAIFAgLm4pTw6Ogqjo6Mgl8vhxo0b50tLS4/U19fnLvS2FIWXfxEDQNLmLW9ueW1TxtchHDaQyWRTm4VgYkZHR6G+vhF+/NfP+y5e+vVjiVgwZpKVydOwF0dZW1lZOTGZTD6bzU4LCAiIptPp8HTDL1MwOjoKLS0tUFdXd1IsFudIpdKKgYGB7tloJTrX4MUnsVJTEj9etzY10dHRAQAAGm81wcsZW5CVyQInL69gNCGBjwcAGBx8ANnncypOnTr3H9nn/reD55wovvrQpyIHAHFUzIocGo3mQaPRfBwdHVlubm7bXF1dgcFgABqNNvruglwuh7t374JMJoOOjo7P79y5I+ru7m7q7e1tXQi7MzOh8PIv4pCw2DdaWtte37Au7aPIyCWAxWABjUbPif9HCMbjURtKiaQBfvr5zH9evlJ0uLQ4r/nJMXNiZTIRrMAlJAcHB18HBweWo6Mjy8rKajeJRAJLS0uwtLQECwsLoFAogMfjAYvFgpmZ2XNXMyqVCoaHh2FoaAiGh4cfvwYGBqCvrw+6u7vfvnfvXlNvb29rT09Pq0QsUM7S6c4rNqS/lrZ5U+YPRBKR9M7u9xwqBUUvtNAudH766XSLE8PR49ixE78/8tVnX403Zk7fUR46NUUAIPIPCMdTKJTdNjY2QKPRgE6nA51OB1tbWyCRSIDD4YBAIAAejwcCgfDYUajVakGlUoFarQadTvfY79HX1wf9/f0gl8tBLpfDvXv3HvXw+dxQPYYXMj+d+P7Mmzv+5OHr6/OJWq1GBHeB09TcUiKuq/coKS3/eqIx/wPkiIXC3w6YjAAAAABJRU5ErkJggg=="); + + --keyword: #ff79c6; + --identifier: #f8f8f2; + --comment: #6272a4; + --operator: #ff79c6; + --punctuation: #f8f8f2; + --other: #f8f8f2; + --escapeSequence: #bd93f9; + --number: #bd93f9; + --literal: #f1fa8c; + --raw-data: #8be9fd; +} + +.theme-switch-wrapper { + display: flex; + align-items: center; + + em { + margin-left: 10px; + font-size: 1rem; + } +} +.theme-switch { + display: inline-block; + height: 22px; + position: relative; + width: 50px; +} + +.theme-switch input { + display: none; +} + +.slider { + background-color: #ccc; + bottom: 0; + cursor: pointer; + left: 0; + position: absolute; + right: 0; + top: 0; + transition: .4s; +} + +.slider:before { + background-color: #fff; + bottom: 4px; + content: ""; + height: 13px; + left: 4px; + position: absolute; + transition: .4s; + width: 13px; +} + +input:checked + .slider { + background-color: #66bb6a; +} + +input:checked + .slider:before { + transform: translateX(26px); +} + +.slider.round { + border-radius: 17px; +} + +.slider.round:before { + border-radius: 50%; +} + +html { + font-size: 100%; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; } + +body { + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-weight: 400; + font-size: 1.125em; + line-height: 1.5; + color: var(--text); + background-color: var(--primary-background); } + +/* Skeleton grid */ +.container { + position: relative; + width: 100%; + max-width: 1050px; + margin: 0 auto; + padding: 0; + box-sizing: border-box; } + +.column, +.columns { + width: 100%; + float: left; + box-sizing: border-box; + margin-left: 1%; +} + +.column:first-child, +.columns:first-child { + margin-left: 0; } + +.three.columns { + width: 19%; } + +.nine.columns { + width: 80.0%; } + +.twelve.columns { + width: 100%; + margin-left: 0; } + +@media screen and (max-width: 860px) { + .three.columns { + display: none; + } + .nine.columns { + width: 98.0%; + } + body { + font-size: 1em; + line-height: 1.35; + } +} + +cite { + font-style: italic !important; } + + +/* Nim search input */ +div#searchInputDiv { + margin-bottom: 1em; +} +input#searchInput { + width: 80%; +} + +/* + * Some custom formatting for input forms. + * This also fixes input form colors on Firefox with a dark system theme on Linux. + */ +input { + -moz-appearance: none; + background-color: var(--secondary-background); + color: var(--text); + border: 1px solid var(--border); + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-size: 0.9em; + padding: 6px; +} + +input:focus { + border: 1px solid var(--input-focus); + box-shadow: 0 0 3px var(--input-focus); +} + +select { + -moz-appearance: none; + background-color: var(--secondary-background); + color: var(--text); + border: 1px solid var(--border); + font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif; + font-size: 0.9em; + padding: 6px; +} + +select:focus { + border: 1px solid var(--input-focus); + box-shadow: 0 0 3px var(--input-focus); +} + +/* Docgen styles */ +/* Links */ +a { + color: var(--anchor); + text-decoration: none; +} + +a span.Identifier { + text-decoration: underline; + text-decoration-color: #aab; +} + +a.reference-toplevel { + font-weight: bold; +} + +a.toc-backref { + text-decoration: none; + color: var(--text); } + +a.link-seesrc { + color: #607c9f; + font-size: 0.9em; + font-style: italic; } + +a:hover, +a:focus { + color: var(--anchor-focus); + text-decoration: underline; } + +a:hover span.Identifier { + color: var(--anchor); +} + + +sub, +sup { + position: relative; + font-size: 75%; + line-height: 0; + vertical-align: baseline; } + +sup { + top: -0.5em; } + +sub { + bottom: -0.25em; } + +img { + width: auto; + height: auto; + max-width: 100%; + vertical-align: middle; + border: 0; + -ms-interpolation-mode: bicubic; } + +@media print { + * { + color: black !important; + text-shadow: none !important; + background: transparent !important; + box-shadow: none !important; } + + a, + a:visited { + text-decoration: underline; } + + a[href]:after { + content: " (" attr(href) ")"; } + + abbr[title]:after { + content: " (" attr(title) ")"; } + + .ir a:after, + a[href^="javascript:"]:after, + a[href^="#"]:after { + content: ""; } + + pre, + blockquote { + border: 1px solid #999; + page-break-inside: avoid; } + + thead { + display: table-header-group; } + + tr, + img { + page-break-inside: avoid; } + + img { + max-width: 100% !important; } + + @page { + margin: 0.5cm; } + + h1 { + page-break-before: always; } + + h1.title { + page-break-before: avoid; } + + p, + h2, + h3 { + orphans: 3; + widows: 3; } + + h2, + h3 { + page-break-after: avoid; } +} + + +p { + margin-top: 0.5em; + margin-bottom: 0.5em; +} + +small { + font-size: 85%; } + +strong { + font-weight: 600; + font-size: 0.95em; + color: var(--strong); +} + +em { + font-style: italic; } + +h1 { + font-size: 1.8em; + font-weight: 400; + padding-bottom: .25em; + border-bottom: 6px solid var(--third-background); + margin-top: 2.5em; + margin-bottom: 1em; + line-height: 1.2em; } + +h1.title { + padding-bottom: 1em; + border-bottom: 0px; + font-size: 2.5em; + text-align: center; + font-weight: 900; + margin-top: 0.75em; + margin-bottom: 0em; +} + +h2 { + font-size: 1.3em; + margin-top: 2em; } + +h2.subtitle { + text-align: center; } + +h3 { + font-size: 1.125em; + font-style: italic; + margin-top: 1.5em; } + +h4 { + font-size: 1.125em; + margin-top: 1em; } + +h5 { + font-size: 1.125em; + margin-top: 0.75em; } + +h6 { + font-size: 1.1em; } + + +ul, +ol { + padding: 0; + margin-top: 0.5em; + margin-left: 0.75em; } + +ul ul, +ul ol, +ol ol, +ol ul { + margin-bottom: 0; + margin-left: 1.25em; } + +li { + list-style-type: circle; +} + +ul.simple-boot li { + list-style-type: none; + margin-left: 0em; + margin-bottom: 0.5em; +} + +ol.simple > li, ul.simple > li { + margin-bottom: 0.25em; + margin-left: 0.4em } + +ul.simple.simple-toc > li { + margin-top: 1em; +} + +ul.simple-toc { + list-style: none; + font-size: 0.9em; + margin-left: -0.3em; + margin-top: 1em; } + +ul.simple-toc > li { + list-style-type: none; +} + +ul.simple-toc-section { + list-style-type: circle; + margin-left: 1em; + color: #6c9aae; } + + +ol.arabic { + list-style: decimal; } + +ol.loweralpha { + list-style: lower-alpha; } + +ol.upperalpha { + list-style: upper-alpha; } + +ol.lowerroman { + list-style: lower-roman; } + +ol.upperroman { + list-style: upper-roman; } + +ul.auto-toc { + list-style-type: none; } + + +dl { + margin-bottom: 1.5em; } + +dt { + margin-bottom: -0.5em; + margin-left: 0.0em; } + +dd { + margin-left: 2.0em; + margin-bottom: 3.0em; + margin-top: 0.5em; } + + +hr { + margin: 2em 0; + border: 0; + border-top: 1px solid #aaa; } + +blockquote { + font-size: 0.9em; + font-style: italic; + padding-left: 0.5em; + margin-left: 0; + border-left: 5px solid #bbc; +} + +.pre { + font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; + font-weight: 500; + font-size: 0.85em; + color: var(--text); + background-color: var(--third-background); + padding-left: 3px; + padding-right: 3px; + border-radius: 4px; +} + +pre { + font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace; + color: var(--text); + font-weight: 500; + display: inline-block; + box-sizing: border-box; + min-width: 100%; + padding: 0.5em; + margin-top: 0.5em; + margin-bottom: 0.5em; + font-size: 0.85em; + white-space: pre !important; + overflow-y: hidden; + overflow-x: visible; + background-color: var(--secondary-background); + border: 1px solid var(--border); + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; } + +.pre-scrollable { + max-height: 340px; + overflow-y: scroll; } + + +/* Nim line-numbered tables */ +.line-nums-table { + width: 100%; + table-layout: fixed; } + +table.line-nums-table { + border-radius: 4px; + border: 1px solid #cccccc; + background-color: ghostwhite; + border-collapse: separate; + margin-top: 15px; + margin-bottom: 25px; } + +.line-nums-table tbody { + border: none; } + +.line-nums-table td pre { + border: none; + background-color: transparent; } + +.line-nums-table td.blob-line-nums { + width: 28px; } + +.line-nums-table td.blob-line-nums pre { + color: #b0b0b0; + -webkit-filter: opacity(75%); + text-align: right; + border-color: transparent; + background-color: transparent; + padding-left: 0px; + margin-left: 0px; + padding-right: 0px; + margin-right: 0px; } + + +table { + max-width: 100%; + background-color: transparent; + margin-top: 0.5em; + margin-bottom: 1.5em; + border-collapse: collapse; + border-color: var(--third-background); + border-spacing: 0; + font-size: 0.9em; +} + +table th, table td { + padding: 0px 0.5em 0px; + border-color: var(--third-background); +} + +table th { + background-color: var(--third-background); + border-color: var(--third-background); + font-weight: bold; } + +table th.docinfo-name { + background-color: transparent; +} + +table tr:hover { + background-color: var(--third-background); } + + +/* rst2html default used to remove borders from tables and images */ +.borderless, table.borderless td, table.borderless th { + border: 0; } + +table.borderless td, table.borderless th { + /* Override padding for "table.docutils td" with "! important". + The right padding separates the table cells. */ + padding: 0 0.5em 0 0 !important; } + +.first { + /* Override more specific margin styles with "! important". */ + margin-top: 0 !important; } + +.last, .with-subtitle { + margin-bottom: 0 !important; } + +.hidden { + display: none; } + +blockquote.epigraph { + margin: 2em 5em; } + +dl.docutils dd { + margin-bottom: 0.5em; } + +object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] { + overflow: hidden; } + + +div.figure { + margin-left: 2em; + margin-right: 2em; } + +div.footer, div.header { + clear: both; + text-align: center; + color: #666; + font-size: smaller; } + +div.footer { + padding-top: 5em; +} + +div.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; } + +div.line-block div.line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; } + +div.topic { + margin: 2em; } + +div.search_results { + background-color: antiquewhite; + margin: 3em; + padding: 1em; + border: 1px solid #4d4d4d; +} + +div#global-links ul { + margin-left: 0; + list-style-type: none; +} + +div#global-links > simple-boot { + margin-left: 3em; +} + +hr.docutils { + width: 75%; } + +img.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; } + +img.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; } + +img.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; } + +.align-left { + text-align: left; } + +.align-center { + clear: both; + text-align: center; } + +.align-right { + text-align: right; } + +/* reset inner alignment in figures */ +div.align-right { + text-align: inherit; } + +p.attribution { + text-align: right; + margin-left: 50%; } + +p.caption { + font-style: italic; } + +p.credits { + font-style: italic; + font-size: smaller; } + +p.label { + white-space: nowrap; } + +p.rubric { + font-weight: bold; + font-size: larger; + color: maroon; + text-align: center; } + +p.topic-title { + font-weight: bold; } + +pre.address { + margin-bottom: 0; + margin-top: 0; + font: inherit; } + +pre.literal-block, pre.doctest-block, pre.math, pre.code { + margin-left: 2em; + margin-right: 2em; } + +pre.code .ln { + color: grey; } + +/* line numbers */ +pre.code, code { + background-color: #eeeeee; } + +pre.code .comment, code .comment { + color: #5c6576; } + +pre.code .keyword, code .keyword { + color: #3B0D06; + font-weight: bold; } + +pre.code .literal.string, code .literal.string { + color: #0c5404; } + +pre.code .name.builtin, code .name.builtin { + color: #352b84; } + +pre.code .deleted, code .deleted { + background-color: #DEB0A1; } + +pre.code .inserted, code .inserted { + background-color: #A3D289; } + +span.classifier { + font-style: oblique; } + +span.classifier-delimiter { + font-weight: bold; } + +span.option { + white-space: nowrap; } + +span.problematic { + color: #b30000; } + +span.section-subtitle { + /* font-size relative to parent (h1..h6 element) */ + font-size: 80%; } + +span.DecNumber { + color: var(--number); } + +span.BinNumber { + color: var(--number); } + +span.HexNumber { + color: var(--number); } + +span.OctNumber { + color: var(--number); } + +span.FloatNumber { + color: var(--number); } + +span.Identifier { + color: var(--identifier); } + +span.Keyword { + font-weight: 600; + color: var(--keyword); } + +span.StringLit { + color: var(--literal); } + +span.LongStringLit { + color: var(--literal); } + +span.CharLit { + color: var(--literal); } + +span.EscapeSequence { + color: var(--escapeSequence); } + +span.Operator { + color: var(--operator); } + +span.Punctuation { + color: var(--punctuation); } + +span.Comment, span.LongComment { + font-style: italic; + font-weight: 400; + color: var(--comment); } + +span.RegularExpression { + color: darkviolet; } + +span.TagStart { + color: darkviolet; } + +span.TagEnd { + color: darkviolet; } + +span.Key { + color: #252dbe; } + +span.Value { + color: #252dbe; } + +span.RawData { + color: var(--raw-data); } + +span.Assembler { + color: #252dbe; } + +span.Preprocessor { + color: #252dbe; } + +span.Directive { + color: #252dbe; } + +span.Command, span.Rule, span.Hyperlink, span.Label, span.Reference, +span.Other { + color: var(--other); } + +/* Pop type, const, proc, and iterator defs in nim def blocks */ +dt pre > span.Identifier, dt pre > span.Operator { + color: var(--identifier); + font-weight: 700; } + +dt pre > span.Keyword ~ span.Identifier, dt pre > span.Identifier ~ span.Identifier, +dt pre > span.Operator ~ span.Identifier, dt pre > span.Other ~ span.Identifier { + color: var(--identifier); + font-weight: inherit; } + +/* Nim sprite for the footer (taken from main page favicon) */ +.nim-sprite { + display: inline-block; + width: 51px; + height: 14px; + background-position: 0 0; + background-size: 51px 14px; + -webkit-filter: opacity(50%); + background-repeat: no-repeat; + background-image: var(--nim-sprite-base64); + margin-bottom: 5px; } + +span.pragmadots { + /* Position: relative frees us up to make the dots + look really nice without fucking up the layout and + causing bulging in the parent container */ + position: relative; + /* 1px down looks slightly nicer */ + top: 1px; + padding: 2px; + background-color: var(--third-background); + border-radius: 4px; + margin: 0 2px; + cursor: pointer; + font-size: 0.8em; +} + +span.pragmadots:hover { + background-color: var(--hint); +} +span.pragmawrap { + display: none; +} + +span.attachedType { + display: none; + visibility: hidden; +} \ No newline at end of file diff --git a/paths.html b/paths.html index d6558a0..18fcf6a 100644 --- a/paths.html +++ b/paths.html @@ -10,6 +10,7 @@ + @@ -17,772 +18,7 @@ paths - + @@ -797,6 +33,37 @@ function main() { event.target.parentNode.nextElementSibling.style.display = "inline"; } } + + const toggleSwitch = document.querySelector('.theme-switch input[type="checkbox"]'); + function switchTheme(e) { + if (e.target.checked) { + document.documentElement.setAttribute('data-theme', 'dark'); + localStorage.setItem('theme', 'dark'); + } else { + document.documentElement.setAttribute('data-theme', 'light'); + localStorage.setItem('theme', 'light'); + } + } + + toggleSwitch.addEventListener('change', switchTheme, false); + + + if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { + document.documentElement.setAttribute('data-theme', "dark"); + toggleSwitch.checked = true; + } else if (window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches) { + document.documentElement.setAttribute('data-theme', "light"); + toggleSwitch.checked = false; + } else { + const currentTheme = localStorage.getItem('theme') ? localStorage.getItem('theme') : null; + if (currentTheme) { + document.documentElement.setAttribute('data-theme', currentTheme); + + if (currentTheme === 'dark') { + toggleSwitch.checked = true; + } + } + } } @@ -807,6 +74,13 @@ function main() {

paths

+
+ +     Dark Mode +
diff --git a/plugin.html b/plugin.html index 9b3a724..da0ff7e 100644 --- a/plugin.html +++ b/plugin.html @@ -10,6 +10,7 @@ + @@ -17,772 +18,7 @@ plugin - + @@ -797,6 +33,37 @@ function main() { event.target.parentNode.nextElementSibling.style.display = "inline"; } } + + const toggleSwitch = document.querySelector('.theme-switch input[type="checkbox"]'); + function switchTheme(e) { + if (e.target.checked) { + document.documentElement.setAttribute('data-theme', 'dark'); + localStorage.setItem('theme', 'dark'); + } else { + document.documentElement.setAttribute('data-theme', 'light'); + localStorage.setItem('theme', 'light'); + } + } + + toggleSwitch.addEventListener('change', switchTheme, false); + + + if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { + document.documentElement.setAttribute('data-theme', "dark"); + toggleSwitch.checked = true; + } else if (window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches) { + document.documentElement.setAttribute('data-theme', "light"); + toggleSwitch.checked = false; + } else { + const currentTheme = localStorage.getItem('theme') ? localStorage.getItem('theme') : null; + if (currentTheme) { + document.documentElement.setAttribute('data-theme', currentTheme); + + if (currentTheme === 'dark') { + toggleSwitch.checked = true; + } + } + } } @@ -807,6 +74,13 @@ function main() {

plugin

+
+ +     Dark Mode +
-
OnSymbolOverrideFinal = proc (typ: string): HashSet[string] {...}{.cdecl.}
+
OnSymbolOverrideFinal = proc (typ: string): StringHash {...}{.cdecl.}
@@ -898,7 +172,7 @@ function main() {

Vars

-
cOverrides: Table[string, HashSet[string]]
+
cOverrides: Table[string, StringHash]
@@ -910,7 +184,7 @@ function main() {

Procs

-
proc onSymbolOverrideFinal(typ: string): HashSet[string] {...}{.exportc, dynlib,
+
proc onSymbolOverrideFinal(typ: string): StringHash {...}{.exportc, dynlib,
     raises: [KeyError], tags: [].}
@@ -927,7 +201,7 @@ function main() { diff --git a/plugin.idx b/plugin.idx index 2cba6b6..94cbcd1 100644 --- a/plugin.idx +++ b/plugin.idx @@ -2,4 +2,4 @@ Symbol plugin.html#Symbol plugin: Symbol OnSymbol plugin.html#OnSymbol plugin: OnSymbol OnSymbolOverrideFinal plugin.html#OnSymbolOverrideFinal plugin: OnSymbolOverrideFinal cOverrides plugin.html#cOverrides plugin: cOverrides -onSymbolOverrideFinal plugin.html#onSymbolOverrideFinal,string plugin: onSymbolOverrideFinal(typ: string): HashSet[string] +onSymbolOverrideFinal plugin.html#onSymbolOverrideFinal,string plugin: onSymbolOverrideFinal(typ: string): StringHash diff --git a/theindex.html b/theindex.html index fd650e2..c04d88d 100644 --- a/theindex.html +++ b/theindex.html @@ -10,6 +10,7 @@ + @@ -17,772 +18,7 @@ Index - + @@ -797,6 +33,37 @@ function main() { event.target.parentNode.nextElementSibling.style.display = "inline"; } } + + const toggleSwitch = document.querySelector('.theme-switch input[type="checkbox"]'); + function switchTheme(e) { + if (e.target.checked) { + document.documentElement.setAttribute('data-theme', 'dark'); + localStorage.setItem('theme', 'dark'); + } else { + document.documentElement.setAttribute('data-theme', 'light'); + localStorage.setItem('theme', 'light'); + } + } + + toggleSwitch.addEventListener('change', switchTheme, false); + + + if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { + document.documentElement.setAttribute('data-theme', "dark"); + toggleSwitch.checked = true; + } else if (window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches) { + document.documentElement.setAttribute('data-theme', "light"); + toggleSwitch.checked = false; + } else { + const currentTheme = localStorage.getItem('theme') ? localStorage.getItem('theme') : null; + if (currentTheme) { + document.documentElement.setAttribute('data-theme', currentTheme); + + if (currentTheme === 'dark') { + toggleSwitch.checked = true; + } + } + } } @@ -805,8 +72,18 @@ function main() { diff --git a/types.html b/types.html index 39dc132..c01f926 100644 --- a/types.html +++ b/types.html @@ -10,6 +10,7 @@ + @@ -17,772 +18,7 @@ types - + @@ -797,6 +33,37 @@ function main() { event.target.parentNode.nextElementSibling.style.display = "inline"; } } + + const toggleSwitch = document.querySelector('.theme-switch input[type="checkbox"]'); + function switchTheme(e) { + if (e.target.checked) { + document.documentElement.setAttribute('data-theme', 'dark'); + localStorage.setItem('theme', 'dark'); + } else { + document.documentElement.setAttribute('data-theme', 'light'); + localStorage.setItem('theme', 'light'); + } + } + + toggleSwitch.addEventListener('change', switchTheme, false); + + + if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { + document.documentElement.setAttribute('data-theme', "dark"); + toggleSwitch.checked = true; + } else if (window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches) { + document.documentElement.setAttribute('data-theme', "light"); + toggleSwitch.checked = false; + } else { + const currentTheme = localStorage.getItem('theme') ? localStorage.getItem('theme') : null; + if (currentTheme) { + document.documentElement.setAttribute('data-theme', currentTheme); + + if (currentTheme === 'dark') { + toggleSwitch.checked = true; + } + } + } } @@ -807,6 +74,13 @@ function main() {

types

+
+ +     Dark Mode +
From 42071b7ac073f5a3c32df6dd089f8022c1d64881 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 24 Mar 2020 15:54:31 -0500 Subject: [PATCH 354/593] Update documentation --- docs.html | 2 +- theindex.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs.html b/docs.html index d7955c5..80ba4e0 100644 --- a/docs.html +++ b/docs.html @@ -142,7 +142,7 @@ function main() {
diff --git a/theindex.html b/theindex.html index c04d88d..9b0a2c7 100644 --- a/theindex.html +++ b/theindex.html @@ -364,7 +364,7 @@ function main() { From 78bc82644af9618ac57fd5882d1f78ec89e71675 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 24 Mar 2020 15:55:42 -0500 Subject: [PATCH 355/593] Update documentation --- all.html | 4 ++-- build.html | 2 +- cimport.html | 2 +- docs.html | 2 +- paths.html | 2 +- plugin.html | 2 +- theindex.html | 2 +- types.html | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) diff --git a/all.html b/all.html index 4fde88f..436ccbf 100644 --- a/all.html +++ b/all.html @@ -114,7 +114,7 @@ function main() {
@@ -124,7 +124,7 @@ function main() { diff --git a/build.html b/build.html index 4202b8d..47844fe 100644 --- a/build.html +++ b/build.html @@ -579,7 +579,7 @@ Check if -d:xxx is se diff --git a/cimport.html b/cimport.html index c4652d3..91c81f3 100644 --- a/cimport.html +++ b/cimport.html @@ -400,7 +400,7 @@ Add an include directory that is forwarded to the C/C++ preprocessor if called w diff --git a/docs.html b/docs.html index 80ba4e0..c5da9ef 100644 --- a/docs.html +++ b/docs.html @@ -142,7 +142,7 @@ function main() { diff --git a/paths.html b/paths.html index 18fcf6a..672c3eb 100644 --- a/paths.html +++ b/paths.html @@ -191,7 +191,7 @@ function main() { diff --git a/plugin.html b/plugin.html index da0ff7e..eae2f37 100644 --- a/plugin.html +++ b/plugin.html @@ -201,7 +201,7 @@ function main() { diff --git a/theindex.html b/theindex.html index 9b0a2c7..49925a5 100644 --- a/theindex.html +++ b/theindex.html @@ -364,7 +364,7 @@ function main() { diff --git a/types.html b/types.html index c01f926..8321d6f 100644 --- a/types.html +++ b/types.html @@ -198,7 +198,7 @@ function main() { From 8b9c39f42eec79607392c81538e08da1b814809a Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 25 Mar 2020 15:17:20 -0500 Subject: [PATCH 356/593] ast2 newTypeIdent cleanup, pragma tests, docs.nim docs --- nimterop.nimble | 1 + nimterop/all.nim | 2 +- nimterop/ast2.nim | 91 +++++++++++++++++++++++++++---------------- nimterop/docs.nim | 4 ++ tests/include/tast2.h | 12 ++++-- tests/tast2.nim | 85 +++++++++++++++++++++++++++++++++++++++- 6 files changed, 154 insertions(+), 41 deletions(-) diff --git a/nimterop.nimble b/nimterop.nimble index c33e78b..86ee029 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -37,6 +37,7 @@ task test, "Test": buildToastTask() execTest "tests/tast2.nim" + #execCmd "nim c -f -d:HEADER -r tests/tast2.nim" execTest "tests/tnimterop_c.nim" execCmd "nim cpp -f -r tests/tnimterop_cpp.nim" diff --git a/nimterop/all.nim b/nimterop/all.nim index dc22967..fef1bdd 100644 --- a/nimterop/all.nim +++ b/nimterop/all.nim @@ -4,4 +4,4 @@ Module that should import everything so that `nim doc --project nimtero/all` run # TODO: make sure it does import everything. -import "."/[cimport, build, types, plugin] +import "."/[docs, cimport, build, types, plugin] diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index 62fdcf2..93b26a1 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -248,12 +248,13 @@ proc newPragmaExpr(nimState: NimState, node: TSNode, ident: PNode, pragmas: seq[ result.add ident result.add nimState.newPragma(node, pragmas) -proc newTypeIdent(nimState: NimState, node: TSNode, fname = "", pragmas: seq[string] = @[]): PNode = - # Create nkTypeDef PNode with first ident +proc newTypeIdent(nimState: NimState, node: TSNode, kind = nskType, fname = "", pragmas: seq[string] = @[]): PNode = + # Create nkTypeDef PNode with first ident if `nskType` else just create an nkPostfix node for `nskProc` # # If `fname`, use it instead of node.getAtom() for name + # If `pragmas`, add as nkPragmaExpr but only if `nskType` since procs add pragmas elsewhere let - (tname, origname, info) = nimState.getNameInfo(node.getAtom(), nskType) + (tname, origname, info) = nimState.getNameInfo(node.getAtom(), kind) name = if fname.nBl: @@ -262,32 +263,49 @@ proc newTypeIdent(nimState: NimState, node: TSNode, fname = "", pragmas: seq[str tname ident = nimState.getIdent(name, info) - prident = - if pragmas.nBl and not ident.isNil: - nimState.newPragmaExpr(node, ident, pragmas) - else: - ident - if name.Bl: # Name skipped or overridden since blank - result = nimState.getOverrideOrSkip(node, origname, nskType) + result = nimState.getOverrideOrSkip(node, origname, kind) elif nimState.addNewIdentifer(name): - # type name* = - # - # nkTypeDef( - # nkPostfix( - # nkIdent("*"), - # nkIdent(name) - # ), - # nkEmpty() - # ) - result = newNode(nkTypeDef) - result.add prident - result.add newNode(nkEmpty) + if kind == nskType: + # type name* = + # + # nkTypeDef( + # nkPostfix( + # nkIdent("*"), + # nkIdent(name) + # ), + # nkEmpty() + # ) + let + pragmas = + if nimState.includeHeader and tname == origname: + # Need to add impShort + pragmas & nimState.impShort + else: + pragmas + + prident = + if pragmas.nBl and not ident.isNil: + nimState.newPragmaExpr(node, ident, pragmas) + else: + ident + + result = newNode(nkTypeDef) + result.add prident + result.add newNode(nkEmpty) + elif kind == nskProc: + # name* + # + # nkPostfix( + # nkIdent("*"), + # nkIdent(name) + # ) + result = ident nimState.identifierNodes[name] = result else: - necho &"# type '{origname}' is duplicate, skipped" + necho &"# $1 '{origname}' is duplicate, skipped" % getKeyword(kind) proc newPtrTree(nimState: NimState, count: int, typ: PNode): PNode = # Create nkPtrTy tree depending on count @@ -520,9 +538,11 @@ proc addTypeObject(nimState: NimState, node: TSNode, typeDef: PNode = nil, fname else: @["bycopy"] + typeDefExisting = not typeDef.isNil + typeDef = if typeDef.isNil: - nimState.newTypeIdent(node, fname, pragmas) + nimState.newTypeIdent(node, fname = fname, pragmas = pragmas) else: typeDef @@ -558,10 +578,14 @@ proc addTypeObject(nimState: NimState, node: TSNode, typeDef: PNode = nil, fname typeDef.add obj # If typeDef was passed in, need to add pragmas if any - if pragmas.nBl and typeDef[0].kind != nkPragmaExpr: - let - npexpr = nimState.newPragmaExpr(node, typedef[0], pragmas) - typedef[0] = npexpr + if pragmas.nBl and typeDefExisting: + if typeDef[0].kind != nkPragmaExpr: + # includeHeader already added impShort + let + npexpr = nimState.newPragmaExpr(node, typedef[0], pragmas) + typedef[0] = npexpr + else: + nimState.addPragma(node, typeDef[0][1], pragmas) # nkTypeSection.add nimState.typeSection.add typeDef @@ -1112,13 +1136,12 @@ proc addProc(nimState: NimState, node: TSNode) = for i in start+1 ..< node.len: let # node[i] = identifier = name - tident = nimState.newTypeIdent(node[i]) + ident = nimState.newTypeIdent(node[i], kind = nskProc) - if not tident.isNil: + if not ident.isNil: let # Only need the ident tree, not nkTypeDef parent - ident = tident[0] - name = tident.getIdentName() + name = ident.getIdentName() # node[i] could have nested pointers tcount = node[i].getPtrCount() @@ -1258,7 +1281,7 @@ proc setupPragmas(nimState: NimState, root: TSNode, fullpath: string) = nimState.constSection.add nimState.newConstDef( root, fname = nimState.currentHeader, fval = '"' & fullpath & '"') - nimState.addPragma(root, impPragma, "header", newStrNode(nkStrLit, nimState.currentHeader)) + nimState.addPragma(root, impPragma, "header", nimState.getIdent(nimState.currentHeader)) nimState.addPragma(root, impCPragma, "pragma", nimState.getIdent(nimState.impShort & "C")) nimState.addPragma(root, impCPragma, nimState.impShort) @@ -1312,9 +1335,9 @@ proc printNim*(gState: State, fullpath: string, root: TSNode) = var tree = newNode(nkStmtList) - tree.add nimState.pragmaSection tree.add nimState.enumSection tree.add nimState.constSection + tree.add nimState.pragmaSection tree.add nimState.typeSection tree.add nimState.procSection diff --git a/nimterop/docs.nim b/nimterop/docs.nim index a194086..97fab96 100644 --- a/nimterop/docs.nim +++ b/nimterop/docs.nim @@ -1,6 +1,10 @@ import macros, strformat from os import parentDir, getCurrentCompilerExe, DirSep + +when defined(nimdoc): + from os import getCurrentDir, paramCount, paramStr + proc getNimRootDir(): string = #[ hack, but works diff --git a/tests/include/tast2.h b/tests/include/tast2.h index 84505db..8e84b01 100644 --- a/tests/include/tast2.h +++ b/tests/include/tast2.h @@ -11,7 +11,7 @@ typedef struct A3 {}; typedef struct A4 A4, *A4p; typedef const int A5; typedef int *A6; -typedef A0 **A7; +typedef struct A0 **A7; typedef void *A8; // Forward declaration @@ -104,6 +104,8 @@ typedef enum VSPresetFormat { // DUPLICATES +#ifndef HEADER + #define A 1 #define B 1.0 #define C 0x10 @@ -117,7 +119,7 @@ typedef struct A3 {}; typedef struct A4 A4, *A4p; typedef const int A5; typedef int *A6; -typedef A0 **A7; +typedef struct A0 **A7; typedef void *A8; // Forward declaration @@ -131,7 +133,7 @@ typedef char *(*A11)[3]; typedef struct A1 *A111[12]; typedef int **(*A12)(int, int b, int *c, int *, int *count[4], int (*func)(int, int)); -typedef int A13(int, int); +typedef int A13(int, int, void (*func)(void)); struct A14 { volatile char a1; }; struct A15 { char *a1; const int *a2[1]; }; @@ -200,4 +202,6 @@ typedef enum VSPresetFormat { // Anonymous //typedef struct { char a1; }; -//struct A2 test_proc1(struct A0 a); \ No newline at end of file +//struct A2 test_proc1(struct A0 a); + +#endif \ No newline at end of file diff --git a/tests/tast2.nim b/tests/tast2.nim index 56b1868..76e4561 100644 --- a/tests/tast2.nim +++ b/tests/tast2.nim @@ -1,4 +1,4 @@ -import tables +import macros, sets, tables import nimterop/[cimport] @@ -12,7 +12,36 @@ cOverride: type A1* = A0 -cImport("include/tast2.h", flags="-d -f:ast2 -ENK_") +when defined(HEADER): + cDefine("HEADER") + const + flags = " -H" + imp = @["importc", "header:headertast2"] +else: + const + flags = "" + imp = @[] + +cImport("include/tast2.h", flags="-d -f:ast2 -ENK_" & flags) + +proc getPragmas(n: NimNode): HashSet[string] = + for i in 0 ..< n.len: + if n[i].kind == nnkPragma: + for j in 0 ..< n[i].len: + if n[i][j].kind == nnkIdent: + result.incl $n[i][j] + elif n[i][j].kind == nnkExprColonExpr: + result.incl $n[i][j][0] & ":" & $n[i][j][1] + else: + result.incl n[i].getPragmas() + +macro checkPragmas(t: typed, pragmas: static[seq[string]]): untyped = + let + ast = t.getImpl() + prag = ast.getPragmas() + exprag = pragmas.toHashSet() + doAssert symmetricDifference(prag, exprag).len == 0, + "\nWrong number of pragmas in " & $t & "\n" & $prag & " vs " & $exprag proc testFields(t: typedesc, fields: Table[string, string] = initTable[string, string]()) = var @@ -31,62 +60,114 @@ assert C == 0x10 assert D == "hello" assert E == 'c' +const + pragmas = @["bycopy"] & imp + assert A0 is object testFields(A0, {"f1": "cint"}.toTable()) +checkPragmas(A0, pragmas) + assert A1 is A0 testFields(A1, {"f1": "cint"}.toTable()) + assert A2 is object testFields(A2) +checkPragmas(A2, pragmas) + assert A3 is object testFields(A3) +checkPragmas(A3, pragmas) + assert A4 is object testFields(A4) +checkPragmas(A4, pragmas) + assert A4p is ptr A4 +checkPragmas(A4p, imp) + assert A5 is cint +checkPragmas(A5, imp) + assert A6 is ptr cint +checkPragmas(A6, imp) + assert A7 is ptr ptr A0 +checkPragmas(A7, imp) + assert A8 is pointer +checkPragmas(A8, imp) assert A9p is array[3, cstring] +checkPragmas(A9p, imp) + #assert A9 is array[4, cchar] +#checkPragmas(A9, imp) + assert A10 is array[3, array[6, cstring]] +checkPragmas(A10, imp) + assert A11 is ptr array[3, cstring] +checkPragmas(A11, imp) + assert A111 is array[12, ptr A1] +checkPragmas(A111, imp) assert A12 is proc(a1: cint, b: cint, c: ptr cint, a4: ptr cint, count: array[4, ptr cint], `func`: proc(a1: cint, a2: cint): cint): ptr ptr cint +checkPragmas(A12, imp) + assert A13 is proc(a1: cint, a2: cint, `func`: proc()): cint +checkPragmas(A13, imp) assert A14 is object testFields(A14, {"a1": "cchar"}.toTable()) +checkPragmas(A14, pragmas) assert A15 is object testFields(A15, {"a1": "cstring", "a2": "array[0..0, ptr cint]"}.toTable()) +checkPragmas(A15, pragmas) assert A16 is object testFields(A16, {"f1": "cchar"}.toTable()) +checkPragmas(A16, pragmas) assert A17 is object testFields(A17, {"a1": "cstring", "a2": "array[0..0, ptr cint]"}.toTable()) +checkPragmas(A17, pragmas) + assert A18 is A17 +checkPragmas(A18, imp) + assert A18p is ptr A17 +checkPragmas(A18p, imp) assert A19 is object testFields(A19, {"a1": "cstring", "a2": "array[0..0, ptr cint]"}.toTable()) +checkPragmas(A19, pragmas) + assert A19p is ptr A19 +checkPragmas(A19p, imp) assert A20 is object testFields(A20, {"a1": "cchar"}.toTable()) +checkPragmas(A20, pragmas) + assert A21 is A20 +checkPragmas(A21, imp) + assert A21p is ptr A20 +checkPragmas(A21p, imp) assert A22 is object testFields(A22, {"f1": "ptr ptr cint", "f2": "array[0..254, ptr cint]"}.toTable()) +checkPragmas(A22, pragmas) assert U1 is object assert sizeof(U1) == sizeof(cfloat) +checkPragmas(U1, pragmas & @["union"]) assert U2 is object assert sizeof(U2) == 256 * sizeof(cint) +checkPragmas(U2, pragmas & @["union"]) assert PANEL_WINDOW == 1 assert PANEL_GROUP == 2 From e06917f40f5bd3a4b4bec51d05d85dffa4eb5867 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 30 Mar 2020 15:46:34 -0500 Subject: [PATCH 357/593] c2nImport ret, del specials from header, cache if exec not die, ast2 type pragma improvements --- nimterop.nimble | 5 +- nimterop/ast2.nim | 138 +++++++++++++++++------ nimterop/build.nim | 9 +- nimterop/cimport.nim | 2 + tests/include/tast2.h | 8 ++ tests/tast2.nim | 249 +++++++++++++++++++++++++++++++----------- 6 files changed, 306 insertions(+), 105 deletions(-) diff --git a/nimterop.nimble b/nimterop.nimble index 86ee029..108d935 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -5,8 +5,6 @@ author = "genotrance" description = "C/C++ interop for Nim" license = "MIT" -# this gives Warning: Binary 'nimterop/toast' was already installed from source directory -# when running `nimble install --verbose -y` bin = @["nimterop/toast"] installDirs = @["nimterop"] installFiles = @["config.nims"] @@ -37,7 +35,7 @@ task test, "Test": buildToastTask() execTest "tests/tast2.nim" - #execCmd "nim c -f -d:HEADER -r tests/tast2.nim" + execCmd "nim c -f -d:HEADER -r tests/tast2.nim" execTest "tests/tnimterop_c.nim" execCmd "nim cpp -f -r tests/tnimterop_cpp.nim" @@ -53,5 +51,6 @@ task test, "Test": # getHeader tests withDir("tests"): execCmd("nim e getheader.nims") + execCmd("nim e wrappers.nims") docsTask() diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index 93b26a1..7eb22a1 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -57,7 +57,7 @@ proc getOverrideOrSkip(nimState: NimState, node: TSNode, origname: string, kind: let # Get cleaned name for symbol, set parent so that cOverride is ignored name = nimState.getIdentifier(origname, kind, parent = "override") - + override = nimState.getOverride(origname, kind) var @@ -115,7 +115,7 @@ proc newConstDef(nimState: NimState, node: TSNode, fname = "", fval = ""): PNode else: # node[0] = identifier = const name nimState.getNodeVal(node.getAtom()) - + name = nimState.getIdentifier(origname, nskConst) info = nimState.getLineInfo(node) ident = nimState.getIdent(name, info) @@ -182,7 +182,7 @@ proc addPragma(nimState: NimState, node: TSNode, pragma: PNode, name: string, va let pinfo = nimState.getLineInfo(node.getAtom()) pident = nimState.getIdent(name, pinfo, exported = false) - + if value.isNil: pragma.add pident else: @@ -248,19 +248,28 @@ proc newPragmaExpr(nimState: NimState, node: TSNode, ident: PNode, pragmas: seq[ result.add ident result.add nimState.newPragma(node, pragmas) -proc newTypeIdent(nimState: NimState, node: TSNode, kind = nskType, fname = "", pragmas: seq[string] = @[]): PNode = +proc newTypeIdent(nimState: NimState, node: TSNode, kind = nskType, fname = "", pragmas: seq[string] = @[], istype = false): PNode = # Create nkTypeDef PNode with first ident if `nskType` else just create an nkPostfix node for `nskProc` # # If `fname`, use it instead of node.getAtom() for name # If `pragmas`, add as nkPragmaExpr but only if `nskType` since procs add pragmas elsewhere + # If `istype` is set, this is a typedef, else struct/union so add {.importc: "struct/union X".} when includeHeader let - (tname, origname, info) = nimState.getNameInfo(node.getAtom(), kind) + (tname, torigname, info) = nimState.getNameInfo(node.getAtom(), kind) - name = + origname = if fname.nBl: fname + else: + torigname + + # Process name if forced, getNameInfo() already runs getIdentifier() + name = + if fname.nBl: + nimState.getIdentifier(fname, kind) else: tname + ident = nimState.getIdent(name, info) if name.Bl: @@ -277,20 +286,39 @@ proc newTypeIdent(nimState: NimState, node: TSNode, kind = nskType, fname = "", # ), # nkEmpty() # ) - let + var pragmas = - if nimState.includeHeader and tname == origname: - # Need to add impShort - pragmas & nimState.impShort + if nimState.includeHeader: + # Need to add header and importc + if istype and name == origname: + # Need to add impShort since neither struct/union nor name change + pragmas & nimState.impShort + else: + # Add header shortcut, additional pragmas added later + pragmas & (nimState.impShort & "H") else: pragmas prident = - if pragmas.nBl and not ident.isNil: + if pragmas.nBl: nimState.newPragmaExpr(node, ident, pragmas) else: ident - + + if nimState.includeHeader: + if not istype or name != origname: + # Add importc pragma since either struct/union or name changed + let + uors = + if not istype: + if "union" in pragmas: + "union " + else: + "struct " + else: + "" + nimState.addPragma(node, prident[1], "importc", newStrNode(nkStrLit, &"{uors}{origname}")) + result = newNode(nkTypeDef) result.add prident result.add newNode(nkEmpty) @@ -302,7 +330,7 @@ proc newTypeIdent(nimState: NimState, node: TSNode, kind = nskType, fname = "", # nkIdent(name) # ) result = ident - + nimState.identifierNodes[name] = result else: necho &"# $1 '{origname}' is duplicate, skipped" % getKeyword(kind) @@ -525,24 +553,37 @@ proc newRecListTree(nimState: NimState, name: string, node: TSNode): PNode = if not field.isNil: result.add field -proc addTypeObject(nimState: NimState, node: TSNode, typeDef: PNode = nil, fname = "", union = false) = +proc addTypeObject(nimState: NimState, node: TSNode, typeDef: PNode = nil, fname = "", istype = false, union = false) = # Add a type of object # # If `typeDef` is set, use it instead of creating new PNode # If `fname` is set, use it as the name when creating new PNode + # If `istype` is set, this is a typedef, else struct/union decho("addTypeObject()") let - pragmas = - if union: - @["union", "bycopy"] + # Object has fields or not + fdlist = node.anyChildInTree("field_declaration_list") + + pragmas = block: + var pragmas = + if union: + @["union"] + else: + @[] + if not fdlist.isNil and fdlist.len > 0: + # Object with fields should be bycopy + pragmas.add "bycopy" else: - @["bycopy"] + # Incomplete, might get forward declared + pragmas.add "incompleteStruct" + + pragmas typeDefExisting = not typeDef.isNil typeDef = if typeDef.isNil: - nimState.newTypeIdent(node, fname = fname, pragmas = pragmas) + nimState.newTypeIdent(node, fname = fname, pragmas = pragmas, istype = istype) else: typeDef @@ -567,8 +608,6 @@ proc addTypeObject(nimState: NimState, node: TSNode, typeDef: PNode = nil, fname obj.add newNode(nkEmpty) obj.add newNode(nkEmpty) - let - fdlist = node.anyChildInTree("field_declaration_list") if not fdlist.isNil and fdlist.len > 0: # Add fields to object if present obj.add nimState.newRecListTree(name, fdlist) @@ -580,11 +619,11 @@ proc addTypeObject(nimState: NimState, node: TSNode, typeDef: PNode = nil, fname # If typeDef was passed in, need to add pragmas if any if pragmas.nBl and typeDefExisting: if typeDef[0].kind != nkPragmaExpr: - # includeHeader already added impShort let npexpr = nimState.newPragmaExpr(node, typedef[0], pragmas) typedef[0] = npexpr else: + # includeHeader already added impShort in newTypeIdent() nimState.addPragma(node, typeDef[0][1], pragmas) # nkTypeSection.add @@ -610,6 +649,18 @@ proc addTypeObject(nimState: NimState, node: TSNode, typeDef: PNode = nil, fname # Add fields to existing object def[2][2] = nimState.newRecListTree(name, fdlist) + # Change incompleteStruct to bycopy pragma + if def[0].kind == nkPragmaExpr and def[0].len == 2 and + def[0][1].kind == nkPragma and def[0][1].len > 0: + for i in 0 ..< def[0][1].len: + if $def[0][1][i] == "incompleteStruct": + def[0][1][i] = nimState.getIdent( + "bycopy", nimState.getLineInfo(node.getAtom()), + exported = false + ) + + nimState.printDebug(def) + proc addTypeTyped(nimState: NimState, node: TSNode, ftname = "", offset = 0) = # Add a type of a specified type # @@ -622,8 +673,8 @@ proc addTypeTyped(nimState: NimState, node: TSNode, ftname = "", offset = 0) = # Add a type of a specific type let # node[i] = identifer = name - typeDef = nimState.newTypeIdent(node[i]) - + typeDef = nimState.newTypeIdent(node[i], istype = true) + if not typeDef.isNil: let name = typeDef.getIdentName() @@ -669,7 +720,7 @@ proc addTypeTyped(nimState: NimState, node: TSNode, ftname = "", offset = 0) = nimState.printDebug(typeDef) else: - nimState.addTypeObject(node, typeDef = typeDef) + nimState.addTypeObject(node, typeDef = typeDef, istype = true) proc getTypeArray(nimState: NimState, node: TSNode, name: string): PNode = # Create array type tree @@ -728,7 +779,7 @@ proc addTypeArray(nimState: NimState, node: TSNode) = decho("addTypeArray()") let # node[1] = identifer = name - typeDef = nimState.newTypeIdent(node[1]) + typeDef = nimState.newTypeIdent(node[1], istype = true) if not typeDef.isNil: let @@ -809,7 +860,7 @@ proc addTypeProc(nimState: NimState, node: TSNode) = decho("addTypeProc()") let # node[1] = identifier = name - typeDef = nimState.newTypeIdent(node[1]) + typeDef = nimState.newTypeIdent(node[1], istype = true) if not typeDef.isNil: let @@ -1018,7 +1069,7 @@ proc addType(nimState: NimState, node: TSNode, union = false) = # First add struct as object decho("addType(): case 6") - nimState.addTypeObject(node[0], union = union) + nimState.addTypeObject(node[0], istype = true, union = union) if node.len > 1 and nimState.getNodeVal(node[1]) != "": # Add any additional names @@ -1041,7 +1092,7 @@ proc addType(nimState: NimState, node: TSNode, union = false) = name # Now add struct as object with specified name - nimState.addTypeObject(node[0], fname = name, union = union) + nimState.addTypeObject(node[0], fname = name, istype = true, union = union) if name.nBl: # Add any additional names @@ -1068,7 +1119,7 @@ proc addEnum(nimState: NimState, node: TSNode) = # Use Y as name origname = nimState.getNodeVal(node[1].getAtom()) offset = 1 - + if origname.nBl: name = nimState.getIdentifier(origname, nskType) else: @@ -1120,7 +1171,7 @@ proc addEnum(nimState: NimState, node: TSNode) = # Add fields to list of consts after processing enum so that we don't cast # enum field to itself nimState.constIdentifiers.incl fnames - + # Add other names if node.getName() == "type_definition" and node.len > 1: nimState.addTypeTyped(node, ftname = name, offset = offset) @@ -1137,7 +1188,7 @@ proc addProc(nimState: NimState, node: TSNode) = let # node[i] = identifier = name ident = nimState.newTypeIdent(node[i], kind = nskProc) - + if not ident.isNil: let # Only need the ident tree, not nkTypeDef parent @@ -1270,10 +1321,13 @@ proc searchTree(nimState: NimState, root: TSNode) = break proc setupPragmas(nimState: NimState, root: TSNode, fullpath: string) = + # Create shortcut pragmas to reduce clutter var + hdrPragma: PNode impPragma = newNode(nkPragma) impCPragma = newNode(nkPragma) + # {.importc.} nimState.addPragma(root, impPragma, "pragma", nimState.getIdent(nimState.impShort)) nimState.addPragma(root, impPragma, "importc") @@ -1281,19 +1335,29 @@ proc setupPragmas(nimState: NimState, root: TSNode, fullpath: string) = nimState.constSection.add nimState.newConstDef( root, fname = nimState.currentHeader, fval = '"' & fullpath & '"') - nimState.addPragma(root, impPragma, "header", nimState.getIdent(nimState.currentHeader)) + # {.header: "xxx".} + hdrPragma = nimState.newPragma(root, "pragma", nimState.getIdent(nimState.impShort & "H")) + nimState.addPragma(root, hdrPragma, "header", nimState.getIdent(nimState.currentHeader)) + nimState.addPragma(root, impPragma, nimState.impShort & "H") + + # {.importc.} + {.cdecl.} for procs nimState.addPragma(root, impCPragma, "pragma", nimState.getIdent(nimState.impShort & "C")) nimState.addPragma(root, impCPragma, nimState.impShort) nimState.addPragma(root, impCPragma, "cdecl") if nimState.gState.dynlib.nBl: + # {.dynlib.} for DLLs nimState.addPragma(root, impCPragma, "dynlib", nimState.getIdent(nimState.gState.dynlib)) + # Add all pragma shortcuts to output + if not hdrPragma.isNil: + nimState.pragmaSection.add hdrPragma nimState.pragmaSection.add impPragma nimState.pragmaSection.add impCPragma proc printNimHeader*(gState: State) = + # Top level output with context info gecho """# Generated at $1 # Command line: # $2 $3 @@ -1304,13 +1368,16 @@ import nimterop/types """ % [$now(), getAppFilename(), commandLineParams().join(" ")] proc printNim*(gState: State, fullpath: string, root: TSNode) = + # Generate Nim from tree-sitter AST root node let nimState = new(NimState) fp = fullpath.replace("\\", "/") + # Track identifiers already rendered and corresponding PNodes nimState.identifiers = newTable[string, string]() nimState.identifierNodes = newTable[string, PNode]() + # toast objects nimState.gState = gState nimState.currentHeader = getCurrentHeader(fullpath) nimState.impShort = nimState.currentHeader.replace("header", "imp") @@ -1321,18 +1388,23 @@ proc printNim*(gState: State, fullpath: string, root: TSNode) = nimState.config = newConfigRef() nimstate.graph = newModuleGraph(nimState.identCache, nimState.config) + # Initialize all section PNodes nimState.pragmaSection = newNode(nkStmtList) nimState.constSection = newNode(nkConstSection) nimState.enumSection = newNode(nkStmtList) nimState.procSection = newNode(nkStmtList) nimState.typeSection = newNode(nkTypeSection) + # Setup pragmas nimState.setupPragmas(root, fp) + # Search root node and render Nim nimState.searchTree(root) + # Add any unused cOverride symbols to output nimState.addAllOverrideFinal() + # Create output to Nim using Nim compiler renderer var tree = newNode(nkStmtList) tree.add nimState.enumSection diff --git a/nimterop/build.nim b/nimterop/build.nim index 9594baa..c65ec2a 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -2,6 +2,8 @@ import hashes, macros, osproc, sets, strformat, strutils, tables import os except findExe, sleep +import regex + proc sanitizePath*(path: string, noQuote = false, sep = $DirSep): string = result = path.multiReplace([("\\\\", sep), ("\\", sep), ("/", sep)]) if not noQuote: @@ -83,7 +85,7 @@ proc execAction*(cmd: string, retry = 0, die = true, cache = false, else: # Execute command and store results in cache (result.output, result.ret) = gorgeEx(ccmd) - if result.ret == 0: + if result.ret == 0 or die == false: # mkdir for execCache dir (circular dependency) let dir = cacheFile.parentDir() if not dirExists(dir): @@ -933,7 +935,8 @@ macro getHeader*(header: static[string], giturl: static[string] = "", dlurl: sta ## Simply define `proc xxxPreBuild(outdir, header: string)` in the wrapper and it will get called ## prior to the build process. var - name = header.extractFilename().split(".")[0] + origname = header.extractFilename().split(".")[0] + name = origname.replace(re"[[:^alnum:]]", "") # -d:xxx for this header stdStr = name & "Std" @@ -975,7 +978,7 @@ macro getHeader*(header: static[string], giturl: static[string] = "", dlurl: sta if altNames.len != 0: lre = lre % ("(" & altNames.replace(",", "|") & ")") else: - lre = lre % name + lre = lre % origname result = newNimNode(nnkStmtList) result.add(quote do: diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index 84f7b4f..c4ebc3f 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -673,6 +673,8 @@ macro c2nImport*(filename: static string, recurse: static bool = false, dynlib: (c2nimout, ret) = execAction(cmd, cache = not gStateCT.nocache, cacheKey = getCacheValue(hpath)) + doAssert ret == 0, "\n\nc2nim codegen limitation or error - " & c2nimout + var nimout = &"const {header} = \"{fullpath}\"\n\n" & readFile(npath) diff --git a/tests/include/tast2.h b/tests/include/tast2.h index 8e84b01..db539c7 100644 --- a/tests/include/tast2.h +++ b/tests/include/tast2.h @@ -19,6 +19,10 @@ struct A0 { int f1; }; +struct A4 { + float f1; +}; + typedef char *A9p[3]; //, A9[4]; typedef char *A10[3][6]; typedef char *(*A11)[3]; @@ -127,6 +131,10 @@ struct A0 { int f1; }; +struct A4 { + float f1; +}; + typedef char *A9p[3]; //, A9[4]; typedef char *A10[3][6]; typedef char *(*A11)[3]; diff --git a/tests/tast2.nim b/tests/tast2.nim index 76e4561..4b19429 100644 --- a/tests/tast2.nim +++ b/tests/tast2.nim @@ -1,10 +1,30 @@ -import macros, sets, tables +import macros, os, sets, strutils import nimterop/[cimport] static: cDebug() +const + path = currentSourcePath.parentDir() / "include" / "tast2.h" + +when defined(HEADER): + cDefine("HEADER") + const + flags = " -H -d" + pHeader = @["header:" & path] + pHeaderImp = @["importc"] & pHeader +else: + const + flags = "" + pHeader: seq[string] = @[] + pHeaderImp: seq[string] = @[] + +const + pHeaderImpBy = @["bycopy"] & pHeaderImp + pHeaderBy = @["bycopy"] & pHeader + pHeaderInc = @["incompleteStruct"] & pHeader + cOverride: const A* = 2 @@ -12,19 +32,10 @@ cOverride: type A1* = A0 -when defined(HEADER): - cDefine("HEADER") - const - flags = " -H" - imp = @["importc", "header:headertast2"] -else: - const - flags = "" - imp = @[] - -cImport("include/tast2.h", flags="-d -f:ast2 -ENK_" & flags) +cImport(path, flags="-f:ast2 -ENK_" & flags) proc getPragmas(n: NimNode): HashSet[string] = + # Find all pragmas in AST, return as "name" or "name:value" in set for i in 0 ..< n.len: if n[i].kind == nnkPragma: for j in 0 ..< n[i].len: @@ -35,24 +46,54 @@ proc getPragmas(n: NimNode): HashSet[string] = else: result.incl n[i].getPragmas() -macro checkPragmas(t: typed, pragmas: static[seq[string]]): untyped = - let +proc getRecList(n: NimNode): NimNode = + # Find nnkRecList in AST + for i in 0 ..< n.len: + if n[i].kind == nnkRecList: + return n[i] + elif n[i].len != 0: + let + rl = getRecList(n[i]) + if not rl.isNil: + return rl + +macro checkPragmas(t: typed, pragmas: static[seq[string]], istype: static[bool] = true): untyped = + # Verify that type has expected pragmas defined + # `istype` is true when typedef X + var ast = t.getImpl() prag = ast.getPragmas() exprag = pragmas.toHashSet() + when defined(HEADER): + if not istype: + if "union" in exprag: + exprag.incl "importc:union " & $t + else: + exprag.incl "importc:struct " & $t doAssert symmetricDifference(prag, exprag).len == 0, "\nWrong number of pragmas in " & $t & "\n" & $prag & " vs " & $exprag -proc testFields(t: typedesc, fields: Table[string, string] = initTable[string, string]()) = +macro testFields(t: typed, fields: static[string] = "") = + # Verify that type has expected fields var - obj: t - count = 0 - for name, value in obj.fieldPairs(): - count += 1 - assert name in fields, $t & "." & name & " invalid" - assert $fields[name] == $typeof(value), - "typeof(" & $t & ":" & name & ") != " & fields[name] & ", is " & $typeof(value) - assert count == fields.len, "Failed for " & $t + ast = t.getImpl() + rl = ast.getRecList() + fsplit = fields.split(":") + names = fsplit[0].split("|") + types = + if fsplit.len > 1: + fsplit[1].split("|") + else: + @[] + if not rl.isNil: + for i in 0 ..< rl.len: + let + name = ($rl[i][0]).strip(chars = {'*'}) + typ = $(rl[i][1].repr()) + n = names.find(name) + assert n != -1, $t & "." & name & " invalid" + assert types[n] == typ, + "typeof(" & $t & ":" & name & ") != " & types[n] & ", is " & typ assert A == 2 assert B == 1.0 @@ -60,114 +101,190 @@ assert C == 0x10 assert D == "hello" assert E == 'c' -const - pragmas = @["bycopy"] & imp - assert A0 is object -testFields(A0, {"f1": "cint"}.toTable()) -checkPragmas(A0, pragmas) +testFields(A0, "f1:cint") +checkPragmas(A0, pHeaderBy, istype = false) +var a0: A0 +a0.f1 = 1 assert A1 is A0 -testFields(A1, {"f1": "cint"}.toTable()) +testFields(A1, "f1:cint") +var a1: A1 +a1.f1 = 2 assert A2 is object testFields(A2) -checkPragmas(A2, pragmas) +checkPragmas(A2, pHeaderInc, istype = false) +when not defined(HEADER): + # typedef struct X; is invalid + var a2: A2 assert A3 is object testFields(A3) -checkPragmas(A3, pragmas) +checkPragmas(A3, pHeaderInc, istype = false) +var a3: A3 assert A4 is object -testFields(A4) -checkPragmas(A4, pragmas) +testFields(A4, "f1:cfloat") +checkPragmas(A4, pHeaderImpBy) +var a4: A4 +a4.f1 = 4.1 assert A4p is ptr A4 -checkPragmas(A4p, imp) +testFields(A4p, "f1:cfloat") +checkPragmas(A4p, pHeaderImp) +var a4p: A4p +a4p = addr a4 assert A5 is cint -checkPragmas(A5, imp) +checkPragmas(A5, pHeaderImp) +const a5: A5 = 5 assert A6 is ptr cint -checkPragmas(A6, imp) +checkPragmas(A6, pHeaderImp) +var + a6: A6 + a6i = 6 +a6 = cast[A6](addr a6i) assert A7 is ptr ptr A0 -checkPragmas(A7, imp) +checkPragmas(A7, pHeaderImp) +var + a7: A7 + a7a = addr a0 +a7 = addr a7a assert A8 is pointer -checkPragmas(A8, imp) +checkPragmas(A8, pHeaderImp) +var a8: A8 +a8 = nil assert A9p is array[3, cstring] -checkPragmas(A9p, imp) +checkPragmas(A9p, pHeaderImp) +var a9p: A9p +a9p[1] = nil +a9p[2] = "hello".cstring +#Not implemented yet #assert A9 is array[4, cchar] -#checkPragmas(A9, imp) +#checkPragmas(A9, pHeaderImp) +#var a9: A9 assert A10 is array[3, array[6, cstring]] -checkPragmas(A10, imp) +checkPragmas(A10, pHeaderImp) +var a10: A10 +a10[2][5] = "12345".cstring assert A11 is ptr array[3, cstring] -checkPragmas(A11, imp) +checkPragmas(A11, pHeaderImp) +var a11: A11 +a11 = addr a9p assert A111 is array[12, ptr A1] -checkPragmas(A111, imp) +checkPragmas(A111, pHeaderImp) +var a111: A111 +a111[11] = addr a1 assert A12 is proc(a1: cint, b: cint, c: ptr cint, a4: ptr cint, count: array[4, ptr cint], `func`: proc(a1: cint, a2: cint): cint): ptr ptr cint -checkPragmas(A12, imp) +checkPragmas(A12, pHeaderImp) +when not defined(HEADER): + # Unclear why this fails + # request for member ‘ClE_0’ in something not a structure or union + var a12: A12 assert A13 is proc(a1: cint, a2: cint, `func`: proc()): cint -checkPragmas(A13, imp) +checkPragmas(A13, pHeaderImp) +when not defined(HEADER): + # Unclear why this fails + # request for member ‘ClE_0’ in something not a structure or union + var a13: A13 assert A14 is object -testFields(A14, {"a1": "cchar"}.toTable()) -checkPragmas(A14, pragmas) +testFields(A14, "a1:cchar") +checkPragmas(A14, pHeaderBy, istype = false) +var a14: A14 +a14.a1 = 'a' assert A15 is object -testFields(A15, {"a1": "cstring", "a2": "array[0..0, ptr cint]"}.toTable()) -checkPragmas(A15, pragmas) +testFields(A15, "a1|a2:cstring|array[1, ptr cint]") +checkPragmas(A15, pHeaderBy, istype = false) +var + a15: A15 + a15i = 15.cint +a15.a1 = "hello".cstring +a15.a2[0] = addr a15i assert A16 is object -testFields(A16, {"f1": "cchar"}.toTable()) -checkPragmas(A16, pragmas) +testFields(A16, "f1:cchar") +checkPragmas(A16, pHeaderImpBy) +when not defined(HEADER): + # Similar to A2 + var a16: A16 + a16.f1 = 's' assert A17 is object -testFields(A17, {"a1": "cstring", "a2": "array[0..0, ptr cint]"}.toTable()) -checkPragmas(A17, pragmas) +testFields(A17, "a1|a2:cstring|array[1, ptr cint]") +checkPragmas(A17, pHeaderImpBy) +when not defined(HEADER): + # Similar to A2 + var a17: A17 + a17.a1 = "hello".cstring + a17.a2[0] = addr a15i assert A18 is A17 -checkPragmas(A18, imp) +checkPragmas(A18, pHeaderImp) +var a18: A18 assert A18p is ptr A17 -checkPragmas(A18p, imp) +checkPragmas(A18p, pHeaderImp) +var a18p: A18p +a18p = addr a18 assert A19 is object -testFields(A19, {"a1": "cstring", "a2": "array[0..0, ptr cint]"}.toTable()) -checkPragmas(A19, pragmas) +testFields(A19, "a1|a2:cstring|array[1, ptr cint]") +checkPragmas(A19, pHeaderImpBy) +var a19: A19 +a19.a1 = "hello".cstring +a19.a2[0] = addr a15i assert A19p is ptr A19 -checkPragmas(A19p, imp) +checkPragmas(A19p, pHeaderImp) +var a19p: A19p +a19p = addr a19 assert A20 is object -testFields(A20, {"a1": "cchar"}.toTable()) -checkPragmas(A20, pragmas) +testFields(A20, "a1:cchar") +checkPragmas(A20, pHeaderImpBy) +var a20: A20 +a20.a1 = 'a' assert A21 is A20 -checkPragmas(A21, imp) +checkPragmas(A21, pHeaderImp) +var a21: A21 +a21 = a20 assert A21p is ptr A20 -checkPragmas(A21p, imp) +checkPragmas(A21p, pHeaderImp) +var a21p: A21p +a21p = addr a20 assert A22 is object -testFields(A22, {"f1": "ptr ptr cint", "f2": "array[0..254, ptr cint]"}.toTable()) -checkPragmas(A22, pragmas) +testFields(A22, "f1|f2:ptr ptr cint|array[123 + 132, ptr cint]") +checkPragmas(A22, pHeaderImpBy) +var a22: A22 +a22.f1 = addr a15.a2[0] assert U1 is object assert sizeof(U1) == sizeof(cfloat) -checkPragmas(U1, pragmas & @["union"]) +checkPragmas(U1, pHeaderBy & @["union"], istype = false) +var u1: U1 +u1.f1 = 5 assert U2 is object assert sizeof(U2) == 256 * sizeof(cint) -checkPragmas(U2, pragmas & @["union"]) +checkPragmas(U2, pHeaderImpBy & @["union"]) +var u2: U2 +u2.f1 = addr a15.a2[0] assert PANEL_WINDOW == 1 assert PANEL_GROUP == 2 From 36faf6226906fccf7232ef7b82102fcd7819b0ad Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 30 Mar 2020 15:56:05 -0500 Subject: [PATCH 358/593] Add wrapper test --- tests/tast2.nim | 2 +- tests/wrappers.nims | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 tests/wrappers.nims diff --git a/tests/tast2.nim b/tests/tast2.nim index 4b19429..d77ae39 100644 --- a/tests/tast2.nim +++ b/tests/tast2.nim @@ -12,7 +12,7 @@ when defined(HEADER): cDefine("HEADER") const flags = " -H -d" - pHeader = @["header:" & path] + pHeader = @["header:" & path.replace("\\", "/")] pHeaderImp = @["importc"] & pHeader else: const diff --git a/tests/wrappers.nims b/tests/wrappers.nims new file mode 100644 index 0000000..37ac686 --- /dev/null +++ b/tests/wrappers.nims @@ -0,0 +1,15 @@ +import os + +let + wrappers = @["genotrance/nimarchive", "genotrance/nimgit2"] + +rmDir("wrappers") +mkDir("wrappers") +withDir("wrappers"): + for wrapper in wrappers: + let + name = wrapper.extractFilename() + exec "git clone https://github.com/" & wrapper + withDir(name): + exec "nimble install -d" + exec "nimble test" \ No newline at end of file From 54854a356adfacdedb85054df7dd5fc3d4eb02da Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 30 Mar 2020 17:14:39 -0500 Subject: [PATCH 359/593] Skip wrapper test on AppVeyor --- nimterop.nimble | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nimterop.nimble b/nimterop.nimble index 108d935..8008b27 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -51,6 +51,7 @@ task test, "Test": # getHeader tests withDir("tests"): execCmd("nim e getheader.nims") - execCmd("nim e wrappers.nims") + if not existsEnv("APPVEYOR"): + execCmd("nim e wrappers.nims") docsTask() From ad8557d70e5c8ff3220582b7f78a2822f87d2476 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 1 Apr 2020 21:47:15 -0500 Subject: [PATCH 360/593] ast2 proc pragmas, fix typedef struct X importc, convention selection, ast2 bitfield support --- README.md | 48 ++++++++--------- nimterop.nimble | 12 +++-- nimterop/ast2.nim | 120 ++++++++++++++++++++++++++++++++++++------ nimterop/globals.nim | 2 +- nimterop/toast.nim | 8 ++- tests/include/tast2.h | 10 +++- tests/tast2.nim | 46 +++++++--------- tests/tnimterop_c.nim | 14 ++++- 8 files changed, 183 insertions(+), 77 deletions(-) diff --git a/README.md b/README.md index b1fee44..18f74ce 100644 --- a/README.md +++ b/README.md @@ -86,7 +86,6 @@ Check out [template.nim](https://github.com/nimterop/nimterop/blob/master/nimter Refer to the ```tests``` directory for examples on how the library can be used. - The `toast` binary can also be used directly on the CLI: ``` @@ -94,29 +93,30 @@ The `toast` binary can also be used directly on the CLI: Usage: main [optional-params] C/C++ source/header Options: - -h, --help print this cligen-erated help - --help-syntax advanced: prepend,plurals,.. - -k, --check bool false check generated wrapper with compiler - -d, --debug bool false enable debug output - -D=, --defines= strings {} definitions to pass to preprocessor - -l=, --dynlib= string "" import symbols from library in specified Nim string - -f=, --feature= Features {} flags to enable experimental features - -H, --includeHeader bool false add {.header.} pragma to wrapper - -I=, --includeDirs= strings {} include directory to pass to preprocessor - -m=, --mode= string "cpp" language parser: c or cpp - --nim= string "nim" use a particular Nim executable (default: $PATH/nim) - -c, --nocomments bool false exclude top-level comments from output - -o=, --output= string "" file to output content - default stdout - -a, --past bool false print AST output - -g, --pgrammar bool false print grammar - --pluginSourcePath= string "" nim file to build and load as a plugin - -n, --pnim bool false print Nim output - -E=, --prefix= strings {} strip prefix from identifiers - -p, --preprocess bool false run preprocessor on header - -r, --recurse bool false process #include files - -s, --stub bool false stub out undefined type references as objects - -F=, --suffix= strings {} strip suffix from identifiers - -O=, --symOverride= strings {} skip generating specified symbols + -h, --help print this cligen-erated help + --help-syntax advanced: prepend,plurals,.. + -k, --check bool false check generated wrapper with compiler + -C=, --convention= string "cdecl" calling convention for wrapped procs - default: cdecl + -d, --debug bool false enable debug output + -D=, --defines= strings {} definitions to pass to preprocessor + -l=, --dynlib= string "" import symbols from library in specified Nim string + -f=, --feature= Features {} flags to enable experimental features + -H, --includeHeader bool false add {.header.} pragma to wrapper + -I=, --includeDirs= strings {} include directory to pass to preprocessor + -m=, --mode= string "cpp" language parser: c or cpp + --nim= string "nim" use a particular Nim executable - default: $PATH/nim + -c, --nocomments bool false exclude top-level comments from output + -o=, --output= string "" file to output content - default: stdout + -a, --past bool false print AST output + -g, --pgrammar bool false print grammar + --pluginSourcePath= string "" nim file to build and load as a plugin + -n, --pnim bool false print Nim output + -E=, --prefix= strings {} strip prefix from identifiers + -p, --preprocess bool false run preprocessor on header + -r, --recurse bool false process #include files + -s, --stub bool false stub out undefined type references as objects + -F=, --suffix= strings {} strip suffix from identifiers + -O=, --symOverride= strings {} skip generating specified symbols ``` __Implementation Details__ diff --git a/nimterop.nimble b/nimterop.nimble index 8008b27..b20f6a7 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -18,9 +18,9 @@ proc execCmd(cmd: string) = echo "execCmd:" & cmd exec cmd -proc execTest(test: string) = - execCmd "nim c -f -r " & test - execCmd "nim cpp -r " & test +proc execTest(test: string, flags = "") = + execCmd "nim c -f " & flags & " -r " & test + execCmd "nim cpp " & flags & " -r " & test task buildToast, "build toast": execCmd("nim c -f nimterop/toast.nim") @@ -35,11 +35,15 @@ task test, "Test": buildToastTask() execTest "tests/tast2.nim" - execCmd "nim c -f -d:HEADER -r tests/tast2.nim" + execTest "tests/tast2.nim", "-d:HEADER" execTest "tests/tnimterop_c.nim" + execTest "tests/tnimterop_c.nim", "-d:AST2" + execTest "tests/tnimterop_c.nim", "-d:HEADER -d:AST2" + execCmd "nim cpp -f -r tests/tnimterop_cpp.nim" execCmd "./nimterop/toast -pnk -E=_ tests/include/toast.h" + execCmd "./nimterop/toast -pnk -E=_ -f:ast2 tests/include/toast.h" execTest "tests/tpcre.nim" # Platform specific tests diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index 7eb22a1..4c001f9 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -286,6 +286,24 @@ proc newTypeIdent(nimState: NimState, node: TSNode, kind = nskType, fname = "", # ), # nkEmpty() # ) + # + # type name* {.bycopy, importc: "abc".} = + # + # nkTypeDef( + # nkPragmaExpr( + # nkPostfix( + # nkIdent("*"), + # nkIdent(name) + # ), + # nkPragma( + # nkIdent("bycopy"), + # nkExprColonExpr( + # nkIdent("importc"), + # nkStrLit("abc") + # ) + # ) + # ) + # ) var pragmas = if nimState.includeHeader: @@ -329,6 +347,8 @@ proc newTypeIdent(nimState: NimState, node: TSNode, kind = nskType, fname = "", # nkIdent("*"), # nkIdent(name) # ) + # + # No pragmas here since proc pragmas are elsewhere in the AST result = ident nimState.identifierNodes[name] = result @@ -465,8 +485,17 @@ proc newIdentDefs(nimState: NimState, name: string, node: TSNode, offset: SomeIn (pname, _, pinfo) = nimState.getNameInfo(node[start+1].getAtom(), nskField, parent = name) pident = nimState.getIdent(pname, pinfo, exported) + # Bitfield support - typedef struct { int field: 1; }; + prident = + if node.len > start+1 and node[start+2].getName() == "bitfield_clause": + nimState.newPragmaExpr(node, pident, "bitsize", + newIntNode(nkIntLit, parseInt(nimState.getNodeVal(node[start+2].getAtom())))) + else: + pident + count = node[start+1].getPtrCount() - result.add pident + + result.add prident if count > 0: result.add nimState.newPtrTree(count, tident) else: @@ -527,11 +556,11 @@ proc newProcTy(nimState: NimState, name: string, node: TSNode, rtyp: PNode): PNo # .. # ) # ), - # nkEmpty() + # nkPragma(...) # ) result = newNode(nkProcTy) result.add nimState.newFormalParams(name, node, rtyp) - result.add newNode(nkEmpty) + result.add nimState.newPragma(node, nimState.gState.convention) proc newRecListTree(nimState: NimState, name: string, node: TSNode): PNode = # Create nkRecList tree for specified object @@ -602,6 +631,37 @@ proc addTypeObject(nimState: NimState, node: TSNode, typeDef: PNode = nil, fname # nkEmpty() # ) # ) + # + # type + # X* {.bycopy.} = object + # field1*: cint + # + # nkTypeDef( + # nkPragmaExpr( + # nkPostfix( + # nkIdent("*"), + # nkIdent("X") + # ), + # nkPragma( + # nkIdent("bycopy") + # ) + # ), + # nkEmpty(), + # nkObjectTy( + # nkEmpty(), + # nkEmpty(), + # nkRecList( + # nkIdentDefs( + # nkPostfix( + # nkIdent("*"), + # nkIdent("field1") + # ), + # nkIdent("cint"), + # nkEmpty() + # ) + # ) + # ) + # ) let name = typeDef.getIdentName() obj = newNode(nkObjectTy) @@ -893,7 +953,7 @@ proc addTypeProc(nimState: NimState, node: TSNode) = # ), # ... # ), - # nkEmpty() + # nkPragma(...) # ) # ) # ) @@ -1069,7 +1129,7 @@ proc addType(nimState: NimState, node: TSNode, union = false) = # First add struct as object decho("addType(): case 6") - nimState.addTypeObject(node[0], istype = true, union = union) + nimState.addTypeObject(node[0], union = union) if node.len > 1 and nimState.getNodeVal(node[1]) != "": # Add any additional names @@ -1193,6 +1253,7 @@ proc addProc(nimState: NimState, node: TSNode) = let # Only need the ident tree, not nkTypeDef parent name = ident.getIdentName() + origname = nimState.getNodeVal(node[i].getAtom()) # node[i] could have nested pointers tcount = node[i].getPtrCount() @@ -1249,7 +1310,27 @@ proc addProc(nimState: NimState, node: TSNode) = # Proc with return type and params procDef.add nimState.newFormalParams(name, plist, retType) - procDef.add newNode(nkEmpty) # Pragmas + + # Pragmas + let + prident = + if name != origname: + # Explicit {.importc: "origname".} + nimState.newPragma(node[i], "importc", newStrNode(nkStrLit, origname)) + else: + # {.impnameC.} shortcut + nimState.newPragma(node[i], nimState.impShort & "C") + + # Need {.convention.} and {.header.} if applicable + if name != origname: + if nimState.includeHeader(): + # {.impnameHC.} shortcut + nimState.addPragma(node[i], prident, nimState.impShort & "HC") + else: + # {.convention.} + nimState.addPragma(node[i], prident, nimState.gState.convention) + + procDef.add prident procDef.add newNode(nkEmpty) procDef.add newNode(nkEmpty) @@ -1324,37 +1405,46 @@ proc setupPragmas(nimState: NimState, root: TSNode, fullpath: string) = # Create shortcut pragmas to reduce clutter var hdrPragma: PNode + hdrConvPragma: PNode impPragma = newNode(nkPragma) - impCPragma = newNode(nkPragma) + impConvPragma = newNode(nkPragma) - # {.importc.} + # {.pragma: impname, importc.} nimState.addPragma(root, impPragma, "pragma", nimState.getIdent(nimState.impShort)) nimState.addPragma(root, impPragma, "importc") if nimState.includeHeader(): + # Path to header const nimState.constSection.add nimState.newConstDef( root, fname = nimState.currentHeader, fval = '"' & fullpath & '"') - # {.header: "xxx".} + # {.pragma: impnameH, header: "xxx".} for types when name != origname hdrPragma = nimState.newPragma(root, "pragma", nimState.getIdent(nimState.impShort & "H")) nimState.addPragma(root, hdrPragma, "header", nimState.getIdent(nimState.currentHeader)) + # Add {.impnameH.} to {.impname.} nimState.addPragma(root, impPragma, nimState.impShort & "H") - # {.importc.} + {.cdecl.} for procs - nimState.addPragma(root, impCPragma, "pragma", nimState.getIdent(nimState.impShort & "C")) - nimState.addPragma(root, impCPragma, nimState.impShort) - nimState.addPragma(root, impCPragma, "cdecl") + # {.pragma: impnameHC, impnameH, convention.} for procs when name != origname + hdrConvPragma = nimState.newPragma(root, "pragma", nimState.getIdent(nimState.impShort & "HC")) + nimState.addPragma(root, hdrConvPragma, nimState.impShort & "H") + nimState.addPragma(root, hdrConvPragma, nimState.gState.convention) + + # {.pragma: impnameC, impname, convention.} for procs + nimState.addPragma(root, impConvPragma, "pragma", nimState.getIdent(nimState.impShort & "C")) + nimState.addPragma(root, impConvPragma, nimState.impShort) + nimState.addPragma(root, impConvPragma, nimState.gState.convention) if nimState.gState.dynlib.nBl: # {.dynlib.} for DLLs - nimState.addPragma(root, impCPragma, "dynlib", nimState.getIdent(nimState.gState.dynlib)) + nimState.addPragma(root, impConvPragma, "dynlib", nimState.getIdent(nimState.gState.dynlib)) # Add all pragma shortcuts to output if not hdrPragma.isNil: nimState.pragmaSection.add hdrPragma + nimState.pragmaSection.add hdrConvPragma nimState.pragmaSection.add impPragma - nimState.pragmaSection.add impCPragma + nimState.pragmaSection.add impConvPragma proc printNimHeader*(gState: State) = # Top level output with context info diff --git a/nimterop/globals.nim b/nimterop/globals.nim index 68f18b0..0e4827f 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -59,7 +59,7 @@ type debug*, includeHeader*, nocache*, nocomments*, past*, preprocess*, pnim*, recurse*: bool - code*, dynlib*, mode*, nim*, overrides*, pluginSource*, pluginSourcePath*: string + code*, convention*, dynlib*, mode*, nim*, overrides*, pluginSource*, pluginSourcePath*: string feature*: seq[Feature] diff --git a/nimterop/toast.nim b/nimterop/toast.nim index 323b4ec..a82a4ea 100644 --- a/nimterop/toast.nim +++ b/nimterop/toast.nim @@ -54,6 +54,7 @@ proc process(gState: State, path: string, astTable: AstTable) = # CLI processing with default values proc main( check = false, + convention = "cdecl", debug = false, defines: seq[string] = @[], dynlib: string = "", @@ -79,6 +80,7 @@ proc main( # Setup global state with arguments var gState = State( + convention: convention, debug: debug, defines: defines, dynlib: dynlib, @@ -189,6 +191,7 @@ when isMainModule: import cligen dispatch(main, help = { "check": "check generated wrapper with compiler", + "convention": "calling convention for wrapped procs - default: cdecl", "debug": "enable debug output", "defines": "definitions to pass to preprocessor", "dynlib": "import symbols from library in specified Nim string", @@ -196,9 +199,9 @@ when isMainModule: "includeHeader": "add {.header.} pragma to wrapper", "includeDirs": "include directory to pass to preprocessor", "mode": "language parser: c or cpp", - "nim": "use a particular Nim executable (default: $PATH/nim)", + "nim": "use a particular Nim executable - default: $PATH/nim", "nocomments": "exclude top-level comments from output", - "output": "file to output content - default stdout", + "output": "file to output content - default: stdout", "past": "print AST output", "pgrammar": "print grammar", "pluginSourcePath": "nim file to build and load as a plugin", @@ -212,6 +215,7 @@ when isMainModule: "symOverride": "skip generating specified symbols" }, short = { "check": 'k', + "convention": 'C', "debug": 'd', "defines": 'D', "dynlib": 'l', diff --git a/tests/include/tast2.h b/tests/include/tast2.h index db539c7..1518a85 100644 --- a/tests/include/tast2.h +++ b/tests/include/tast2.h @@ -1,3 +1,7 @@ +#ifdef __cplusplus +extern "C" { +#endif + #define A 1 #define B 1.0 #define C 0x10 @@ -26,7 +30,7 @@ struct A4 { typedef char *A9p[3]; //, A9[4]; typedef char *A10[3][6]; typedef char *(*A11)[3]; -typedef struct A1 *A111[12]; +typedef struct A0 *A111[12]; typedef int **(*A12)(int, int b, int *c, int *, int *count[4], int (*func)(int, int)); typedef int A13(int, int, void (*func)(void)); @@ -212,4 +216,8 @@ typedef enum VSPresetFormat { //struct A2 test_proc1(struct A0 a); +#endif + +#ifdef __cplusplus +} #endif \ No newline at end of file diff --git a/tests/tast2.nim b/tests/tast2.nim index d77ae39..d98907f 100644 --- a/tests/tast2.nim +++ b/tests/tast2.nim @@ -11,7 +11,7 @@ const when defined(HEADER): cDefine("HEADER") const - flags = " -H -d" + flags = " -H" pHeader = @["header:" & path.replace("\\", "/")] pHeaderImp = @["importc"] & pHeader else: @@ -183,21 +183,15 @@ a11 = addr a9p assert A111 is array[12, ptr A1] checkPragmas(A111, pHeaderImp) var a111: A111 -a111[11] = addr a1 +a111[11] = addr a0 -assert A12 is proc(a1: cint, b: cint, c: ptr cint, a4: ptr cint, count: array[4, ptr cint], `func`: proc(a1: cint, a2: cint): cint): ptr ptr cint -checkPragmas(A12, pHeaderImp) -when not defined(HEADER): - # Unclear why this fails - # request for member ‘ClE_0’ in something not a structure or union - var a12: A12 +assert A12 is proc(a1: cint, b: cint, c: ptr cint, a4: ptr cint, count: array[4, ptr cint], `func`: proc(a1: cint, a2: cint): cint {.cdecl.}): ptr ptr cint {.cdecl.} +checkPragmas(A12, pHeaderImp & "cdecl") +var a12: A12 -assert A13 is proc(a1: cint, a2: cint, `func`: proc()): cint -checkPragmas(A13, pHeaderImp) -when not defined(HEADER): - # Unclear why this fails - # request for member ‘ClE_0’ in something not a structure or union - var a13: A13 +assert A13 is proc(a1: cint, a2: cint, `func`: proc() {.cdecl.}): cint {.cdecl.} +checkPragmas(A13, pHeaderImp & "cdecl") +var a13: A13 assert A14 is object testFields(A14, "a1:cchar") @@ -216,20 +210,16 @@ a15.a2[0] = addr a15i assert A16 is object testFields(A16, "f1:cchar") -checkPragmas(A16, pHeaderImpBy) -when not defined(HEADER): - # Similar to A2 - var a16: A16 - a16.f1 = 's' +checkPragmas(A16, pHeaderBy, istype = false) +var a16: A16 +a16.f1 = 's' assert A17 is object testFields(A17, "a1|a2:cstring|array[1, ptr cint]") -checkPragmas(A17, pHeaderImpBy) -when not defined(HEADER): - # Similar to A2 - var a17: A17 - a17.a1 = "hello".cstring - a17.a2[0] = addr a15i +checkPragmas(A17, pHeaderBy, istype = false) +var a17: A17 +a17.a1 = "hello".cstring +a17.a2[0] = addr a15i assert A18 is A17 checkPragmas(A18, pHeaderImp) @@ -254,7 +244,7 @@ a19p = addr a19 assert A20 is object testFields(A20, "a1:cchar") -checkPragmas(A20, pHeaderImpBy) +checkPragmas(A20, pHeaderBy, istype = false) var a20: A20 a20.a1 = 'a' @@ -270,7 +260,7 @@ a21p = addr a20 assert A22 is object testFields(A22, "f1|f2:ptr ptr cint|array[123 + 132, ptr cint]") -checkPragmas(A22, pHeaderImpBy) +checkPragmas(A22, pHeaderBy, istype = false) var a22: A22 a22.f1 = addr a15.a2[0] @@ -282,7 +272,7 @@ u1.f1 = 5 assert U2 is object assert sizeof(U2) == 256 * sizeof(cint) -checkPragmas(U2, pHeaderImpBy & @["union"]) +checkPragmas(U2, pHeaderBy & @["union"], istype = false) var u2: U2 u2.f1 = addr a15.a2[0] diff --git a/tests/tnimterop_c.nim b/tests/tnimterop_c.nim index 732efbf..afd73e2 100644 --- a/tests/tnimterop_c.nim +++ b/tests/tnimterop_c.nim @@ -41,7 +41,17 @@ cOverride: proc weirdfunc(apple: ptr ptr ptr cchar): int {.importc.} proc weirdfunc2(mango: ptr ptr cchar): int {.importc.} -cImport(cSearchPath("test.h")) +# includeHeader +const header = + when defined(HEADER): " -H" + else: "" + +# Test AST2 +const mode = + when defined(AST2): " -f:ast2" + else: "" + +cImport(cSearchPath("test.h"), flags = header & mode) check TEST_INT == 512 check TEST_FLOAT == 5.12 @@ -65,7 +75,7 @@ var ct: CUSTTYPE cct: CCUSTTYPE - s0: STRUCT0 + s0: ptr STRUCT0 s1: STRUCT1 s2: STRUCT2 s3: STRUCT3 From 5c20ce7b60225bcc5638c78a7632833f11b2aa83 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 2 Apr 2020 18:17:36 -0500 Subject: [PATCH 361/593] ast2 test fix for osx, catch parseString errors, handle type field comments --- nimterop.nimble | 20 +++++++++++------- nimterop/ast2.nim | 47 +++++++++++++++++++++++++++++-------------- tests/include/tast2.h | 4 ++-- tests/tnimterop_c.nim | 13 ++---------- tests/tpcre.nim | 3 ++- 5 files changed, 51 insertions(+), 36 deletions(-) diff --git a/nimterop.nimble b/nimterop.nimble index b20f6a7..be76135 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -19,14 +19,17 @@ proc execCmd(cmd: string) = exec cmd proc execTest(test: string, flags = "") = - execCmd "nim c -f " & flags & " -r " & test - execCmd "nim cpp " & flags & " -r " & test + execCmd "nim c --hints:off -f " & flags & " -r " & test + execCmd "nim cpp --hints:off " & flags & " -r " & test task buildToast, "build toast": - execCmd("nim c -f nimterop/toast.nim") + execCmd("nim c --hints:off -f nimterop/toast.nim") task bt, "build toast": - execCmd("nim c -d:danger nimterop/toast.nim") + execCmd("nim c --hints:off -d:danger nimterop/toast.nim") + +task btd, "build toast": + execCmd("nim c --hints:off nimterop/toast.nim") task docs, "Generate docs": buildDocs(@["nimterop/all.nim"], "build/htmldocs") @@ -38,13 +41,16 @@ task test, "Test": execTest "tests/tast2.nim", "-d:HEADER" execTest "tests/tnimterop_c.nim" - execTest "tests/tnimterop_c.nim", "-d:AST2" - execTest "tests/tnimterop_c.nim", "-d:HEADER -d:AST2" + execTest "tests/tnimterop_c.nim", "-d:FLAGS=\"-f:ast2\"" + execTest "tests/tnimterop_c.nim", "-d:FLAGS=\"-f:ast2 -H\"" - execCmd "nim cpp -f -r tests/tnimterop_cpp.nim" + execCmd "nim cpp --hints:off -f -r tests/tnimterop_cpp.nim" execCmd "./nimterop/toast -pnk -E=_ tests/include/toast.h" execCmd "./nimterop/toast -pnk -E=_ -f:ast2 tests/include/toast.h" + execTest "tests/tpcre.nim" + #execTest "tests/tpcre.nim", "-d:FLAGS=\"-f:ast2\"" + #execTest "tests/tpcre.nim", "-d:FLAGS=\"-f:ast2 -H\"" # Platform specific tests when defined(Windows): diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index 4c001f9..0509c7c 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -2,7 +2,7 @@ import macros, os, sequtils, sets, strformat, strutils, tables, times import regex -import compiler/[ast, idents, modulegraphs, options, parser, renderer] +import compiler/[ast, idents, lineinfos, modulegraphs, options, parser, renderer] import "."/treesitter/api @@ -17,9 +17,19 @@ proc getPtrType*(str: string): string = else: str +proc handleError*(conf: ConfigRef, info: TLineInfo, msg: TMsgKind, arg: string) = + # Raise exception in parseString() instead of exiting + raise newException(Exception, "") + proc parseString(nimState: NimState, str: string): PNode = - # Parse a string into Nim AST - result = parseString(str, nimState.identCache, nimState.config) + # Parse a string into Nim AST - use custom error handler that raises + # an exception rather than exiting on failure + try: + result = parseString( + str, nimState.identCache, nimState.config, errorHandler = handleError + ) + except: + discard proc getLit*(nimState: NimState, str: string): PNode = # Used to convert #define literals into const and expressions @@ -33,9 +43,8 @@ proc getLit*(nimState: NimState, str: string): PNode = elif str.contains(re"^[\-]?[\d]*[.]?[\d]+$"): # float result = newFloatNode(nkFloatLit, parseFloat(str)) - # # TODO - hex becomes int on render - # elif str.contains(re"^0x[\da-fA-F]+$"): # hexadecimal - # result = newIntNode(nkIntLit, parseHexInt(str)) + elif str.contains(re"^0x[\da-fA-F]+$"): # hexadecimal + result = nimState.parseString(str) elif str.contains(re"^'[[:ascii:]]'$"): # char result = newNode(nkCharLit) @@ -46,8 +55,9 @@ proc getLit*(nimState: NimState, str: string): PNode = else: result = nimState.parseString(nimState.getNimExpression(str)) - if result.isNil: - result = newNode(nkNilLit) + + if result.isNil: + result = newNode(nkNilLit) proc getOverrideOrSkip(nimState: NimState, node: TSNode, origname: string, kind: NimSymKind): PNode = # Check if symbol `origname` of `kind` and `origname` has any cOverride defined @@ -132,7 +142,9 @@ proc newConstDef(nimState: NimState, node: TSNode, fname = "", fval = ""): PNode if name.Bl: # Name skipped or overridden since blank result = nimState.getOverrideOrSkip(node, origname, nskConst) - elif valident.kind != nkNilLit: + elif valident.kind in {nkCharLit .. nkStrLit} or + (valident.kind == nkStmtList and valident.len > 0 and + valident[0].kind in {nkCharLit .. nkStrLit}): if nimState.addNewIdentifer(name): # const X* = Y # @@ -147,7 +159,11 @@ proc newConstDef(nimState: NimState, node: TSNode, fname = "", fval = ""): PNode result = newNode(nkConstDef) result.add ident result.add newNode(nkEmpty) - result.add valident + if valident.kind == nkStmtList and valident.len == 1: + # Collapse single line statement + result.add valident[0] + else: + result.add valident else: necho &"# const '{origname}' is duplicate, skipped" else: @@ -576,11 +592,12 @@ proc newRecListTree(nimState: NimState, name: string, node: TSNode): PNode = result = newNode(nkRecList) for i in 0 ..< node.len: - # Add nkIdentDefs for each field - let - field = nimState.newIdentDefs(name, node[i], i, exported = true) - if not field.isNil: - result.add field + if node[i].getName() == "field_declaration": + # Add nkIdentDefs for each field + let + field = nimState.newIdentDefs(name, node[i], i, exported = true) + if not field.isNil: + result.add field proc addTypeObject(nimState: NimState, node: TSNode, typeDef: PNode = nil, fname = "", istype = false, union = false) = # Add a type of object diff --git a/tests/include/tast2.h b/tests/include/tast2.h index 1518a85..e1d7b4e 100644 --- a/tests/include/tast2.h +++ b/tests/include/tast2.h @@ -157,11 +157,11 @@ typedef struct { char *a1; int *a2[1]; } A19, *A19p; typedef struct A20 { char a1; } A20, A21, *A21p; //Expression -typedef struct A22 { int **f1; int *f2[123+132]; } A22; +typedef struct A22 { const int **f1; int *f2[123+132]; } A22; //Unions union U1 {int f1; float f2; }; -typedef union U2 { int **f1; int abc[123+132]; } U2; +typedef union U2 { const int **f1; int abc[123+132]; } U2; // Enums diff --git a/tests/tnimterop_c.nim b/tests/tnimterop_c.nim index afd73e2..fe4e9ee 100644 --- a/tests/tnimterop_c.nim +++ b/tests/tnimterop_c.nim @@ -41,17 +41,8 @@ cOverride: proc weirdfunc(apple: ptr ptr ptr cchar): int {.importc.} proc weirdfunc2(mango: ptr ptr cchar): int {.importc.} -# includeHeader -const header = - when defined(HEADER): " -H" - else: "" - -# Test AST2 -const mode = - when defined(AST2): " -f:ast2" - else: "" - -cImport(cSearchPath("test.h"), flags = header & mode) +const FLAGS {.strdefine.} = "" +cImport(cSearchPath("test.h"), flags = FLAGS) check TEST_INT == 512 check TEST_FLOAT == 5.12 diff --git a/tests/tpcre.nim b/tests/tpcre.nim index 0aa5a3b..21f3388 100644 --- a/tests/tpcre.nim +++ b/tests/tpcre.nim @@ -30,7 +30,8 @@ cPlugin: proc onSymbol*(sym: var Symbol) {.exportc, dynlib.} = sym.name = sym.name.replace("pcre_", "") -cImport(pcreH, dynlib="dynpcre") +const FLAGS {.strdefine.} = "" +cImport(pcreH, dynlib="dynpcre", flags = FLAGS) echo version() From ced9c148287a50356eb5ace81ef6582cc0660163 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 2 Apr 2020 18:17:36 -0500 Subject: [PATCH 362/593] ast2 test fix for osx, catch parseString errors, handle type field comments --- nimterop.nimble | 20 +++++++++++------- nimterop/ast2.nim | 47 +++++++++++++++++++++++++++++-------------- tests/include/tast2.h | 10 ++++----- tests/tnimterop_c.nim | 13 ++---------- tests/tpcre.nim | 3 ++- 5 files changed, 54 insertions(+), 39 deletions(-) diff --git a/nimterop.nimble b/nimterop.nimble index b20f6a7..be76135 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -19,14 +19,17 @@ proc execCmd(cmd: string) = exec cmd proc execTest(test: string, flags = "") = - execCmd "nim c -f " & flags & " -r " & test - execCmd "nim cpp " & flags & " -r " & test + execCmd "nim c --hints:off -f " & flags & " -r " & test + execCmd "nim cpp --hints:off " & flags & " -r " & test task buildToast, "build toast": - execCmd("nim c -f nimterop/toast.nim") + execCmd("nim c --hints:off -f nimterop/toast.nim") task bt, "build toast": - execCmd("nim c -d:danger nimterop/toast.nim") + execCmd("nim c --hints:off -d:danger nimterop/toast.nim") + +task btd, "build toast": + execCmd("nim c --hints:off nimterop/toast.nim") task docs, "Generate docs": buildDocs(@["nimterop/all.nim"], "build/htmldocs") @@ -38,13 +41,16 @@ task test, "Test": execTest "tests/tast2.nim", "-d:HEADER" execTest "tests/tnimterop_c.nim" - execTest "tests/tnimterop_c.nim", "-d:AST2" - execTest "tests/tnimterop_c.nim", "-d:HEADER -d:AST2" + execTest "tests/tnimterop_c.nim", "-d:FLAGS=\"-f:ast2\"" + execTest "tests/tnimterop_c.nim", "-d:FLAGS=\"-f:ast2 -H\"" - execCmd "nim cpp -f -r tests/tnimterop_cpp.nim" + execCmd "nim cpp --hints:off -f -r tests/tnimterop_cpp.nim" execCmd "./nimterop/toast -pnk -E=_ tests/include/toast.h" execCmd "./nimterop/toast -pnk -E=_ -f:ast2 tests/include/toast.h" + execTest "tests/tpcre.nim" + #execTest "tests/tpcre.nim", "-d:FLAGS=\"-f:ast2\"" + #execTest "tests/tpcre.nim", "-d:FLAGS=\"-f:ast2 -H\"" # Platform specific tests when defined(Windows): diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index 4c001f9..0509c7c 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -2,7 +2,7 @@ import macros, os, sequtils, sets, strformat, strutils, tables, times import regex -import compiler/[ast, idents, modulegraphs, options, parser, renderer] +import compiler/[ast, idents, lineinfos, modulegraphs, options, parser, renderer] import "."/treesitter/api @@ -17,9 +17,19 @@ proc getPtrType*(str: string): string = else: str +proc handleError*(conf: ConfigRef, info: TLineInfo, msg: TMsgKind, arg: string) = + # Raise exception in parseString() instead of exiting + raise newException(Exception, "") + proc parseString(nimState: NimState, str: string): PNode = - # Parse a string into Nim AST - result = parseString(str, nimState.identCache, nimState.config) + # Parse a string into Nim AST - use custom error handler that raises + # an exception rather than exiting on failure + try: + result = parseString( + str, nimState.identCache, nimState.config, errorHandler = handleError + ) + except: + discard proc getLit*(nimState: NimState, str: string): PNode = # Used to convert #define literals into const and expressions @@ -33,9 +43,8 @@ proc getLit*(nimState: NimState, str: string): PNode = elif str.contains(re"^[\-]?[\d]*[.]?[\d]+$"): # float result = newFloatNode(nkFloatLit, parseFloat(str)) - # # TODO - hex becomes int on render - # elif str.contains(re"^0x[\da-fA-F]+$"): # hexadecimal - # result = newIntNode(nkIntLit, parseHexInt(str)) + elif str.contains(re"^0x[\da-fA-F]+$"): # hexadecimal + result = nimState.parseString(str) elif str.contains(re"^'[[:ascii:]]'$"): # char result = newNode(nkCharLit) @@ -46,8 +55,9 @@ proc getLit*(nimState: NimState, str: string): PNode = else: result = nimState.parseString(nimState.getNimExpression(str)) - if result.isNil: - result = newNode(nkNilLit) + + if result.isNil: + result = newNode(nkNilLit) proc getOverrideOrSkip(nimState: NimState, node: TSNode, origname: string, kind: NimSymKind): PNode = # Check if symbol `origname` of `kind` and `origname` has any cOverride defined @@ -132,7 +142,9 @@ proc newConstDef(nimState: NimState, node: TSNode, fname = "", fval = ""): PNode if name.Bl: # Name skipped or overridden since blank result = nimState.getOverrideOrSkip(node, origname, nskConst) - elif valident.kind != nkNilLit: + elif valident.kind in {nkCharLit .. nkStrLit} or + (valident.kind == nkStmtList and valident.len > 0 and + valident[0].kind in {nkCharLit .. nkStrLit}): if nimState.addNewIdentifer(name): # const X* = Y # @@ -147,7 +159,11 @@ proc newConstDef(nimState: NimState, node: TSNode, fname = "", fval = ""): PNode result = newNode(nkConstDef) result.add ident result.add newNode(nkEmpty) - result.add valident + if valident.kind == nkStmtList and valident.len == 1: + # Collapse single line statement + result.add valident[0] + else: + result.add valident else: necho &"# const '{origname}' is duplicate, skipped" else: @@ -576,11 +592,12 @@ proc newRecListTree(nimState: NimState, name: string, node: TSNode): PNode = result = newNode(nkRecList) for i in 0 ..< node.len: - # Add nkIdentDefs for each field - let - field = nimState.newIdentDefs(name, node[i], i, exported = true) - if not field.isNil: - result.add field + if node[i].getName() == "field_declaration": + # Add nkIdentDefs for each field + let + field = nimState.newIdentDefs(name, node[i], i, exported = true) + if not field.isNil: + result.add field proc addTypeObject(nimState: NimState, node: TSNode, typeDef: PNode = nil, fname = "", istype = false, union = false) = # Add a type of object diff --git a/tests/include/tast2.h b/tests/include/tast2.h index 1518a85..84a4604 100644 --- a/tests/include/tast2.h +++ b/tests/include/tast2.h @@ -45,11 +45,11 @@ typedef struct { char *a1; int *a2[1]; } A19, *A19p; typedef struct A20 { char a1; } A20, A21, *A21p; //Expression -typedef struct A22 { int **f1; int *f2[123+132]; } A22; +typedef struct A22 { const int **f1; int *f2[123+132]; } A22; //Unions union U1 {int f1; float f2; }; -typedef union U2 { int **f1; int abc[123+132]; } U2; +typedef union U2 { const int **f1; int abc[123+132]; } U2; // Enums @@ -157,11 +157,11 @@ typedef struct { char *a1; int *a2[1]; } A19, *A19p; typedef struct A20 { char a1; } A20, A21, *A21p; //Expression -typedef struct A22 { int **f1; int *f2[123+132]; } A22; +typedef struct A22 { const int **f1; int *f2[123+132]; } A22; //Unions union U1 {int f1; float f2; }; -typedef union U2 { int **f1; int abc[123+132]; } U2; +typedef union U2 { const int **f1; int abc[123+132]; } U2; // Enums @@ -220,4 +220,4 @@ typedef enum VSPresetFormat { #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/tests/tnimterop_c.nim b/tests/tnimterop_c.nim index afd73e2..fe4e9ee 100644 --- a/tests/tnimterop_c.nim +++ b/tests/tnimterop_c.nim @@ -41,17 +41,8 @@ cOverride: proc weirdfunc(apple: ptr ptr ptr cchar): int {.importc.} proc weirdfunc2(mango: ptr ptr cchar): int {.importc.} -# includeHeader -const header = - when defined(HEADER): " -H" - else: "" - -# Test AST2 -const mode = - when defined(AST2): " -f:ast2" - else: "" - -cImport(cSearchPath("test.h"), flags = header & mode) +const FLAGS {.strdefine.} = "" +cImport(cSearchPath("test.h"), flags = FLAGS) check TEST_INT == 512 check TEST_FLOAT == 5.12 diff --git a/tests/tpcre.nim b/tests/tpcre.nim index 0aa5a3b..21f3388 100644 --- a/tests/tpcre.nim +++ b/tests/tpcre.nim @@ -30,7 +30,8 @@ cPlugin: proc onSymbol*(sym: var Symbol) {.exportc, dynlib.} = sym.name = sym.name.replace("pcre_", "") -cImport(pcreH, dynlib="dynpcre") +const FLAGS {.strdefine.} = "" +cImport(pcreH, dynlib="dynpcre", flags = FLAGS) echo version() From 534acf9259a233eb5cf0e59ae754b4c036893f81 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Sun, 5 Apr 2020 19:26:38 -0500 Subject: [PATCH 363/593] ast2 var of proc type, multiple proc type block --- nimterop/ast2.nim | 423 +++++++++++++++++++++++++++--------------- nimterop/globals.nim | 2 +- tests/include/tast2.h | 12 +- tests/tast2.nim | 19 +- tests/tpcre.nim | 8 +- tests/tsoloud.nim | 4 +- 6 files changed, 310 insertions(+), 158 deletions(-) diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index 0509c7c..2182fec 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -264,11 +264,13 @@ proc newPragmaExpr(nimState: NimState, node: TSNode, ident: PNode, pragmas: seq[ result.add ident result.add nimState.newPragma(node, pragmas) -proc newTypeIdent(nimState: NimState, node: TSNode, kind = nskType, fname = "", pragmas: seq[string] = @[], istype = false): PNode = - # Create nkTypeDef PNode with first ident if `nskType` else just create an nkPostfix node for `nskProc` +proc newXIdent(nimState: NimState, node: TSNode, kind = nskType, fname = "", pragmas: seq[string] = @[], istype = false): PNode = + # Create nkTypeDef PNode with first ident if `nskType` + # Create nkIdentDefs PNode with first ident if `nskVar` + # Create an nkPostfix node for `nskProc` # # If `fname`, use it instead of node.getAtom() for name - # If `pragmas`, add as nkPragmaExpr but only if `nskType` since procs add pragmas elsewhere + # If `pragmas`, add as nkPragmaExpr but not for `nskProc` since procs add pragmas elsewhere # If `istype` is set, this is a typedef, else struct/union so add {.importc: "struct/union X".} when includeHeader let (tname, torigname, info) = nimState.getNameInfo(node.getAtom(), kind) @@ -318,7 +320,8 @@ proc newTypeIdent(nimState: NimState, node: TSNode, kind = nskType, fname = "", # nkStrLit("abc") # ) # ) - # ) + # ), + # nkEmpty() # ) var pragmas = @@ -356,6 +359,42 @@ proc newTypeIdent(nimState: NimState, node: TSNode, kind = nskType, fname = "", result = newNode(nkTypeDef) result.add prident result.add newNode(nkEmpty) + elif kind == nskVar: + # var name* {.importc: "abc".} + # + # nkIdentDefs( + # nkPragmaExpr( + # nkPostfix( + # nkIdent("*"), + # nkIdent(name) + # ), + # nkPragma( + # nkExprColonExpr( + # nkIdent("importc"), + # nkStrLit("abc") + # ) + # ) + # ) + # ) + let + prident = block: + var + prident: PNode + if name != origname: + # Add importc pragma since name changed + prident = nimState.newPragmaExpr(node, ident, "importc", newStrNode(nkStrLit, &"{origname}")) + if nimState.includeHeader(): + # Add header + nimState.addPragma(node, prident[1], nimState.impShort & "H") + else: + # Only need impShort since no name change + prident = nimState.newPragmaExpr(node, ident, nimState.impShort) + if pragmas.nBl: + nimState.addPragma(node, prident[1], pragmas) + prident + + result = newNode(nkIdentDefs) + result.add prident elif kind == nskProc: # name* # @@ -427,7 +466,7 @@ proc newArrayTree(nimState: NimState, node: TSNode, typ, size: PNode): PNode = result.add typ proc getTypeArray(nimState: NimState, node: TSNode, name: string): PNode -proc getTypeProc(nimState: NimState, name: string, node: TSNode): PNode +proc getTypeProc(nimState: NimState, name: string, node, rnode: TSNode): PNode proc newIdentDefs(nimState: NimState, name: string, node: TSNode, offset: SomeInteger, exported = false): PNode = # Create nkIdentDefs tree for specified proc parameter or object field @@ -523,7 +562,7 @@ proc newIdentDefs(nimState: NimState, name: string, node: TSNode, offset: SomeIn (pname, _, pinfo) = nimState.getNameInfo(node[start+1].getAtom(), nskField, parent = name) pident = nimState.getIdent(pname, pinfo, exported) result.add pident - result.add nimState.getTypeProc(name, node) + result.add nimState.getTypeProc(name, node[1], rnode = node[0]) result.add newNode(nkEmpty) elif not adecl.isNil: # Named param, array type @@ -629,7 +668,7 @@ proc addTypeObject(nimState: NimState, node: TSNode, typeDef: PNode = nil, fname typeDef = if typeDef.isNil: - nimState.newTypeIdent(node, fname = fname, pragmas = pragmas, istype = istype) + nimState.newXIdent(node, fname = fname, pragmas = pragmas, istype = istype) else: typeDef @@ -700,7 +739,7 @@ proc addTypeObject(nimState: NimState, node: TSNode, typeDef: PNode = nil, fname npexpr = nimState.newPragmaExpr(node, typedef[0], pragmas) typedef[0] = npexpr else: - # includeHeader already added impShort in newTypeIdent() + # includeHeader already added impShort in newXIdent() nimState.addPragma(node, typeDef[0][1], pragmas) # nkTypeSection.add @@ -750,7 +789,7 @@ proc addTypeTyped(nimState: NimState, node: TSNode, ftname = "", offset = 0) = # Add a type of a specific type let # node[i] = identifer = name - typeDef = nimState.newTypeIdent(node[i], istype = true) + typeDef = nimState.newXIdent(node[i], istype = true) if not typeDef.isNil: let @@ -856,7 +895,7 @@ proc addTypeArray(nimState: NimState, node: TSNode) = decho("addTypeArray()") let # node[1] = identifer = name - typeDef = nimState.newTypeIdent(node[1], istype = true) + typeDef = nimState.newXIdent(node[1], istype = true) if not typeDef.isNil: let @@ -889,17 +928,19 @@ proc addTypeArray(nimState: NimState, node: TSNode) = nimState.printDebug(typeDef) -proc getTypeProc(nimState: NimState, name: string, node: TSNode): PNode = +proc getTypeProc(nimState: NimState, name: string, node, rnode: TSNode): PNode = # Create proc type tree + # + # `rnode` is the return type let - # node[0] = identifier = return type name - (rname, _, rinfo) = nimState.getNameInfo(node[0].getAtom(), nskType, parent = name) + # rnode = identifier = return type name + (rname, _, rinfo) = nimState.getNameInfo(rnode.getAtom(), nskType, parent = name) # Parameter list - plist = node[1].anyChildInTree("parameter_list") + plist = node.anyChildInTree("parameter_list") # node[1] could have nested pointers - tcount = node[1].getPtrCount() + tcount = node.getPtrCount() # Name could be nested pointer to function # @@ -914,7 +955,7 @@ proc getTypeProc(nimState: NimState, name: string, node: TSNode): PNode = # ) # ) # ) - ncount = node[1].getAtom().tsNodeParent().getPtrCount(reverse = true) + ncount = node.getAtom().tsNodeParent().getPtrCount(reverse = true) # Return type var @@ -936,49 +977,57 @@ proc addTypeProc(nimState: NimState, node: TSNode) = # Add a type of proc type decho("addTypeProc()") let - # node[1] = identifier = name - typeDef = nimState.newTypeIdent(node[1], istype = true) + start = getStartAtom(node) - if not typeDef.isNil: + # node[start] = return type + rnode = node[start] + + # Could have multiple types, comma separated + for i in start+1 ..< node.len: let - name = typeDef.getIdentName() + # node[i] = identifier = name + typeDef = nimState.newXIdent(node[i], istype = true) - procTy = nimState.getTypeProc(name, node) + if not typeDef.isNil: + let + name = typeDef.getIdentName() - typeDef.add procTy + procTy = nimState.getTypeProc(name, node[i], rnode) - # type X* = proc(a1: Y, a2: Z): P - # - # nkTypeDef( - # nkPostfix( - # nkIdent("*"), - # nkIdent("X") - # ), - # nkEmpty(), - # nkPtrTy( # optional, nested - # nkProcTy( - # nkFormalParams( - # nkPtrTy( # optional, nested - # nkIdent(retType) - # ), - # nkIdentDefs( - # nkIdent(param), - # nkPtrTy( - # nkIdent(ptype) - # ), - # nkEmpty() - # ), - # ... - # ), - # nkPragma(...) - # ) - # ) - # ) + typeDef.add procTy - # nkTypeSection.add - nimState.typeSection.add typeDef + # type X* = proc(a1: Y, a2: Z): P + # + # nkTypeDef( + # nkPostfix( + # nkIdent("*"), + # nkIdent("X") + # ), + # nkEmpty(), + # nkPtrTy( # optional, nested + # nkProcTy( + # nkFormalParams( + # nkPtrTy( # optional, nested + # nkIdent(retType) + # ), + # nkIdentDefs( + # nkIdent(param), + # nkPtrTy( + # nkIdent(ptype) + # ), + # nkEmpty() + # ), + # ... + # ), + # nkPragma(...) + # ) + # ) + # ) - nimState.printDebug(typeDef) + # nkTypeSection.add + nimState.typeSection.add typeDef + + nimState.printDebug(typeDef) proc addType(nimState: NimState, node: TSNode, union = false) = decho("addType()") @@ -1253,108 +1302,184 @@ proc addEnum(nimState: NimState, node: TSNode) = if node.getName() == "type_definition" and node.len > 1: nimState.addTypeTyped(node, ftname = name, offset = offset) -proc addProc(nimState: NimState, node: TSNode) = +proc addProcVar(nimState: NimState, node, rnode: TSNode) = + # Add a proc variable + decho("addProcVar()") + let + # node = identifier = name + identDefs = nimState.newXIdent(node, kind = nskVar, istype = true) + + if not identDefs.isNil: + let + name = identDefs.getIdentName() + # origname = nimState.getNodeVal(node.getAtom()) + + procTy = nimState.getTypeProc(name, node, rnode) + + identDefs.add procTy + identDefs.add newNode(nkEmpty) + + # var X* {.importc: "_X": proc(a1: Y, a2: Z): P {.cdecl.} + # + # nkIdentDefs( + # nkPragmaExpr( + # nkPostfix( + # nkIdent("*"), + # nkIdent("X") + # ), + # nkPragma( + # nkExprColonExpr( + # nkIdent("importc"), + # nkStrLit("_X") + # ) + # ) + # ), + # nkProcTy( + # nkFormalParams( + # nkIdent("P"), + # nkIdentDefs( + # nkIdent("a1"), + # nkIdent("Y"), + # nkEmpty() + # ), + # nkIdentDefs( + # nkIdent("a2"), + # nkIdent("Z"), + # nkEmpty() + # ) + # ), + # nkPragma( + # nkIdent("cdecl") + # ) + # ), + # nkEmpty() + # ) + + # nkVarSection.add + nimState.varSection.add identDefs + + nimState.printDebug(identDefs) + +proc addProc(nimState: NimState, node, rnode: TSNode) = # Add a proc + # + # `node` is the `nth` child of (declaration) + # `rnode` is the return value node, the first child of (declaration) decho("addProc()") + let + # node = identifier = name + ident = nimState.newXIdent(node, kind = nskProc) + + if not ident.isNil: + let + # Only need the ident tree, not nkTypeDef parent + name = ident.getIdentName() + origname = nimState.getNodeVal(node.getAtom()) + + # node could have nested pointers + tcount = node.getPtrCount() + + # rnode = identifier = return type name + (rname, _, rinfo) = nimState.getNameInfo(rnode.getAtom(), nskType, parent = name) + + # Parameter list + plist = node.anyChildInTree("parameter_list") + + procDef = newNode(nkProcDef) + + # proc X(a1: Y, a2: Z): P {.pragma.} + # + # nkProcDef( + # nkPostfix( + # nkIdent("*"), + # nkIdent("X") + # ), + # nkEmpty(), + # nkEmpty(), + # nkFormalParams( + # nkPtrTy( # optional, nested + # nkIdent(retType) + # ), + # nkIdentDefs( + # nkIdent(param), + # nkPtrTy( + # nkIdent(ptype) + # ), + # nkEmpty() + # ), + # ... + # ), + # nkPragma(...), + # nkEmpty(), + # nkEmpty() + # ) + + procDef.add ident + procDef.add newNode(nkEmpty) + procDef.add newNode(nkEmpty) + + # Return type + var + retType = + if rname == "object" and tcount == 0: + # void func(..) + newNode(nkEmpty) + else: + nimState.getIdent(rname, rinfo, exported = false) + if tcount > 0: + retType = nimState.newPtrTree(tcount, retType) + + # Proc with return type and params + procDef.add nimState.newFormalParams(name, plist, retType) + + # Pragmas + let + prident = + if name != origname: + # Explicit {.importc: "origname".} + nimState.newPragma(node, "importc", newStrNode(nkStrLit, origname)) + else: + # {.impnameC.} shortcut + nimState.newPragma(node, nimState.impShort & "C") + + # Need {.convention.} and {.header.} if applicable + if name != origname: + if nimState.includeHeader(): + # {.impnameHC.} shortcut + nimState.addPragma(node, prident, nimState.impShort & "HC") + else: + # {.convention.} + nimState.addPragma(node, prident, nimState.gState.convention) + + procDef.add prident + procDef.add newNode(nkEmpty) + procDef.add newNode(nkEmpty) + + # nkProcSection.add + nimState.procSection.add procDef + + nimState.printDebug(procDef) + +proc addDecl(nimState: NimState, node: TSNode) = + # Add a declaration + decho("addDecl()") nimState.printDebug(node) let start = getStartAtom(node) for i in start+1 ..< node.len: - let - # node[i] = identifier = name - ident = nimState.newTypeIdent(node[i], kind = nskProc) - - if not ident.isNil: - let - # Only need the ident tree, not nkTypeDef parent - name = ident.getIdentName() - origname = nimState.getNodeVal(node[i].getAtom()) - - # node[i] could have nested pointers - tcount = node[i].getPtrCount() - - # node[start] = identifier = return type name - (rname, _, rinfo) = nimState.getNameInfo(node[start].getAtom(), nskType, parent = name) - - # Parameter list - plist = node[i].anyChildInTree("parameter_list") - - procDef = newNode(nkProcDef) - - # proc X(a1: Y, a2: Z): P {.pragma.} - # - # nkProcDef( - # nkPostfix( - # nkIdent("*"), - # nkIdent("X") - # ), - # nkEmpty(), - # nkEmpty(), - # nkFormalParams( - # nkPtrTy( # optional, nested - # nkIdent(retType) - # ), - # nkIdentDefs( - # nkIdent(param), - # nkPtrTy( - # nkIdent(ptype) - # ), - # nkEmpty() - # ), - # ... - # ), - # nkPragma(...), - # nkEmpty(), - # nkEmpty() - # ) - - procDef.add ident - procDef.add newNode(nkEmpty) - procDef.add newNode(nkEmpty) - - # Return type - var - retType = - if rname == "object" and tcount == 0: - # void func(..) - newNode(nkEmpty) - else: - nimState.getIdent(rname, rinfo, exported = false) - if tcount > 0: - retType = nimState.newPtrTree(tcount, retType) - - # Proc with return type and params - procDef.add nimState.newFormalParams(name, plist, retType) - - # Pragmas - let - prident = - if name != origname: - # Explicit {.importc: "origname".} - nimState.newPragma(node[i], "importc", newStrNode(nkStrLit, origname)) - else: - # {.impnameC.} shortcut - nimState.newPragma(node[i], nimState.impShort & "C") - - # Need {.convention.} and {.header.} if applicable - if name != origname: - if nimState.includeHeader(): - # {.impnameHC.} shortcut - nimState.addPragma(node[i], prident, nimState.impShort & "HC") - else: - # {.convention.} - nimState.addPragma(node[i], prident, nimState.gState.convention) - - procDef.add prident - procDef.add newNode(nkEmpty) - procDef.add newNode(nkEmpty) - - # nkProcSection.add - nimState.procSection.add procDef - - nimState.printDebug(procDef) + if not node[i].firstChildInTree("function_declarator").isNil: + # Proc declaration - var or actual proc + if node[i].getAtom().getPxName(1) == "pointer_declarator": + # proc var + nimState.addProcVar(node[i], node[start]) + else: + # proc + nimState.addProc(node[i], node[start]) + else: + # Regular var + discard proc processNode(nimState: NimState, node: TSNode): bool = result = true @@ -1376,7 +1501,7 @@ proc processNode(nimState: NimState, node: TSNode): bool = of "enum_specifier": nimState.addEnum(node) of "declaration": - nimState.addProc(node) + nimState.addDecl(node) else: # Unknown result = false @@ -1496,11 +1621,12 @@ proc printNim*(gState: State, fullpath: string, root: TSNode) = nimstate.graph = newModuleGraph(nimState.identCache, nimState.config) # Initialize all section PNodes - nimState.pragmaSection = newNode(nkStmtList) nimState.constSection = newNode(nkConstSection) nimState.enumSection = newNode(nkStmtList) + nimState.pragmaSection = newNode(nkStmtList) nimState.procSection = newNode(nkStmtList) nimState.typeSection = newNode(nkTypeSection) + nimState.varSection = newNode(nkVarSection) # Setup pragmas nimState.setupPragmas(root, fp) @@ -1518,6 +1644,7 @@ proc printNim*(gState: State, fullpath: string, root: TSNode) = tree.add nimState.constSection tree.add nimState.pragmaSection tree.add nimState.typeSection + tree.add nimState.varSection tree.add nimState.procSection gecho tree.renderTree() diff --git a/nimterop/globals.nim b/nimterop/globals.nim index 0e4827f..701db61 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -82,7 +82,7 @@ type # Nim compiler objects when not declared(CIMPORT): - pragmaSection*, constSection*, enumSection*, procSection*, typeSection*: PNode + constSection*, enumSection*, pragmaSection*, procSection*, typeSection*, varSection*: PNode identCache*: IdentCache config*: ConfigRef graph*: ModuleGraph diff --git a/tests/include/tast2.h b/tests/include/tast2.h index 84a4604..3f46849 100644 --- a/tests/include/tast2.h +++ b/tests/include/tast2.h @@ -32,7 +32,10 @@ typedef char *A10[3][6]; typedef char *(*A11)[3]; typedef struct A0 *A111[12]; -typedef int **(*A12)(int, int b, int *c, int *, int *count[4], int (*func)(int, int)); +typedef int + **(*A12)(int, int b, int *c, int *, int *count[4], int (*func)(int, int)), + **(*A121)(float, float b, float *c, float *, float *count[4], float (*func)(float, float)), + **(*A122)(char, char b, char *c, char *, char *count[4], char (*func)(char, char)); typedef int A13(int, int, void (*func)(void)); struct A14 { volatile char a1; }; @@ -104,8 +107,11 @@ typedef enum VSPresetFormat { //struct A2 test_proc1(struct A0 a); - - +// Proc vars +void + *(*pcre_malloc)(size_t), + (*pcre_free)(void *), + *(*pcre_stack_malloc)(size_t); diff --git a/tests/tast2.nim b/tests/tast2.nim index d98907f..28ea7c5 100644 --- a/tests/tast2.nim +++ b/tests/tast2.nim @@ -189,6 +189,14 @@ assert A12 is proc(a1: cint, b: cint, c: ptr cint, a4: ptr cint, count: array[4, checkPragmas(A12, pHeaderImp & "cdecl") var a12: A12 +assert A121 is proc(a1: cfloat, b: cfloat, c: ptr cfloat, a4: ptr cfloat, count: array[4, ptr cfloat], `func`: proc(a1: cfloat, a2: cfloat): cfloat {.cdecl.}): ptr ptr cint {.cdecl.} +checkPragmas(A121, pHeaderImp & "cdecl") +var a121: A121 + +assert A122 is proc(a1: cchar, b: cchar, c: cstring, a4: cstring, count: array[4, cstring], `func`: proc(a1: cchar, a2: cchar): cchar {.cdecl.}): ptr ptr cint {.cdecl.} +checkPragmas(A122, pHeaderImp & "cdecl") +var a122: A122 + assert A13 is proc(a1: cint, a2: cint, `func`: proc() {.cdecl.}): cint {.cdecl.} checkPragmas(A13, pHeaderImp & "cdecl") var a13: A13 @@ -291,4 +299,13 @@ assert cmGray == 1000000 assert pfGray16 == 1000011 assert pfYUV422P8 == pfYUV420P8 + 1 assert pfRGB27 == cmRGB.VSPresetFormat + 11 -assert pfCompatYUY2 == pfCompatBGR32 + 1 \ No newline at end of file +assert pfCompatYUY2 == pfCompatBGR32 + 1 + +assert pcre_malloc is proc(a1: uint): pointer {.cdecl.} +checkPragmas(pcre_malloc, @["importc", "cdecl"] & pHeader) + +assert pcre_free is proc(a1: pointer) {.cdecl.} +checkPragmas(pcre_free, @["importc", "cdecl"] & pHeader) + +assert pcre_stack_malloc is proc(a1: uint): pointer {.cdecl.} +checkPragmas(pcre_stack_malloc, @["importc", "cdecl"] & pHeader) \ No newline at end of file diff --git a/tests/tpcre.nim b/tests/tpcre.nim index 21f3388..f896e9c 100644 --- a/tests/tpcre.nim +++ b/tests/tpcre.nim @@ -35,7 +35,9 @@ cImport(pcreH, dynlib="dynpcre", flags = FLAGS) echo version() -proc my_malloc(a1: uint) {.cdecl.} = - discard +when FLAGS.len != 0: + # Legacy algorithm is broken - does not convert void * return to pointer + proc my_malloc(a1: uint): pointer {.cdecl.} = + discard -malloc = my_malloc + malloc = my_malloc diff --git a/tests/tsoloud.nim b/tests/tsoloud.nim index 90cf82d..9823531 100644 --- a/tests/tsoloud.nim +++ b/tests/tsoloud.nim @@ -1,4 +1,4 @@ -import os, nimterop/[cimport, build, paths] +import os, nimterop/[cimport, build] const baseDir = getProjectCacheDir("nimterop" / "tests" / "soloud") @@ -6,7 +6,7 @@ const src = baseDir/"src" static: - gitPull("https://github.com/jarikomppa/soloud", baseDir, "include/*\nsrc/*\n") + gitPull("https://github.com/jarikomppa/soloud", baseDir, "include/*\nsrc/*\n", checkout = "RELEASE_20200207") cDebug() cDisableCaching() From e911a9ee92a92beeb66bc716949c4f417fb0f816 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Sun, 5 Apr 2020 23:55:44 -0500 Subject: [PATCH 364/593] ast2 multiple array type block --- nimterop/ast2.nim | 86 +++++++++++++++++++++++-------------------- tests/include/tast2.h | 37 +++++++++++++++++-- tests/tast2.nim | 26 ++++++++++--- 3 files changed, 100 insertions(+), 49 deletions(-) diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index 2182fec..7becd04 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -465,7 +465,7 @@ proc newArrayTree(nimState: NimState, node: TSNode, typ, size: PNode): PNode = result.add size result.add typ -proc getTypeArray(nimState: NimState, node: TSNode, name: string): PNode +proc getTypeArray(nimState: NimState, node, tnode: TSNode, name: string): PNode proc getTypeProc(nimState: NimState, name: string, node, rnode: TSNode): PNode proc newIdentDefs(nimState: NimState, name: string, node: TSNode, offset: SomeInteger, exported = false): PNode = @@ -562,7 +562,7 @@ proc newIdentDefs(nimState: NimState, name: string, node: TSNode, offset: SomeIn (pname, _, pinfo) = nimState.getNameInfo(node[start+1].getAtom(), nskField, parent = name) pident = nimState.getIdent(pname, pinfo, exported) result.add pident - result.add nimState.getTypeProc(name, node[1], rnode = node[0]) + result.add nimState.getTypeProc(name, node[start+1], node[start]) result.add newNode(nkEmpty) elif not adecl.isNil: # Named param, array type @@ -570,7 +570,7 @@ proc newIdentDefs(nimState: NimState, name: string, node: TSNode, offset: SomeIn (pname, _, pinfo) = nimState.getNameInfo(node[start+1].getAtom(), nskField, parent = name) pident = nimState.getIdent(pname, pinfo, exported) result.add pident - result.add nimState.getTypeArray(node, name) + result.add nimState.getTypeArray(node[start+1], node[start], name) result.add newNode(nkEmpty) else: result = nil @@ -838,24 +838,22 @@ proc addTypeTyped(nimState: NimState, node: TSNode, ftname = "", offset = 0) = else: nimState.addTypeObject(node, typeDef = typeDef, istype = true) -proc getTypeArray(nimState: NimState, node: TSNode, name: string): PNode = +proc getTypeArray(nimState: NimState, node, tnode: TSNode, name: string): PNode = # Create array type tree let - start = getStartAtom(node) - - # node[start] = identifier = type name - (tname, _, info) = nimState.getNameInfo(node[start].getAtom(), nskType, parent = name) + # tnode = identifier = type name + (tname, _, info) = nimState.getNameInfo(tnode.getAtom(), nskType, parent = name) ident = nimState.getIdent(tname, info, exported = false) # Top-most array declarator - adecl = node[start+1].firstChildInTree("array_declarator") + adecl = node.firstChildInTree("array_declarator") - # node[start+1] could have nested arrays + # node could have nested arrays acount = adecl.getArrayCount() innermost = adecl.mostNestedChildInTree() - # node[start+1] could have nested pointers - type - tcount = node[start+1].getPtrCount() + # node could have nested pointers - type + tcount = node.getPtrCount() # Name could be nested pointer to array # @@ -894,39 +892,47 @@ proc addTypeArray(nimState: NimState, node: TSNode) = # Add a type of array type decho("addTypeArray()") let - # node[1] = identifer = name - typeDef = nimState.newXIdent(node[1], istype = true) + start = getStartAtom(node) - if not typeDef.isNil: + # node[start] = type name + tnode = node[start] + + # Could have multiple types, comma separated + for i in start+1 ..< node.len: let - name = typeDef.getIdentName() - typ = nimState.getTypeArray(node, name) + # node[i] = identifer = name + typeDef = nimState.newXIdent(node[i], istype = true) - typeDef.add typ + if not typeDef.isNil: + let + name = typeDef.getIdentName() + typ = nimState.getTypeArray(node[i], tnode, name) - # type X* = [ptr] array[x, [ptr] Y] - # - # nkTypeDef( - # nkPostfix( - # nkIdent("*"), - # nkIdent("X") - # ), - # nkEmpty(), - # nkPtrTy( # optional, nested - # nkBracketExpr( - # nkIdent("array") - # nkXLit(x), - # nkPtrTy( # optional, nested - # nkIdent("Y") - # ) - # ) - # ) - # ) + typeDef.add typ - # nkTypeSection.add - nimState.typeSection.add typeDef + # type X* = [ptr] array[x, [ptr] Y] + # + # nkTypeDef( + # nkPostfix( + # nkIdent("*"), + # nkIdent("X") + # ), + # nkEmpty(), + # nkPtrTy( # optional, nested + # nkBracketExpr( + # nkIdent("array") + # nkXLit(x), + # nkPtrTy( # optional, nested + # nkIdent("Y") + # ) + # ) + # ) + # ) - nimState.printDebug(typeDef) + # nkTypeSection.add + nimState.typeSection.add typeDef + + nimState.printDebug(typeDef) proc getTypeProc(nimState: NimState, name: string, node, rnode: TSNode): PNode = # Create proc type tree @@ -939,7 +945,7 @@ proc getTypeProc(nimState: NimState, name: string, node, rnode: TSNode): PNode = # Parameter list plist = node.anyChildInTree("parameter_list") - # node[1] could have nested pointers + # node could have nested pointers tcount = node.getPtrCount() # Name could be nested pointer to function diff --git a/tests/include/tast2.h b/tests/include/tast2.h index 3f46849..75e9446 100644 --- a/tests/include/tast2.h +++ b/tests/include/tast2.h @@ -27,7 +27,7 @@ struct A4 { float f1; }; -typedef char *A9p[3]; //, A9[4]; +typedef char *A9p[3], A9[4]; typedef char *A10[3][6]; typedef char *(*A11)[3]; typedef struct A0 *A111[12]; @@ -113,6 +113,16 @@ void (*pcre_free)(void *), *(*pcre_stack_malloc)(size_t); +typedef int ImageView, MagickBooleanType; +typedef MagickBooleanType + (*DuplexTransferImageViewMethod)(const ImageView *,const ImageView *, + ImageView *,const size_t,const int,void *), + (*GetImageViewMethod)(const ImageView *,const size_t,const int,void *), + (*SetImageViewMethod)(ImageView *,const size_t,const int,void *), + (*TransferImageViewMethod)(const ImageView *,ImageView *,const size_t, + const int,void *), +(*UpdateImageViewMethod)(ImageView *,const size_t,const int,void *); + @@ -145,12 +155,15 @@ struct A4 { float f1; }; -typedef char *A9p[3]; //, A9[4]; +typedef char *A9p[3], A9[4]; typedef char *A10[3][6]; typedef char *(*A11)[3]; -typedef struct A1 *A111[12]; +typedef struct A0 *A111[12]; -typedef int **(*A12)(int, int b, int *c, int *, int *count[4], int (*func)(int, int)); +typedef int + **(*A12)(int, int b, int *c, int *, int *count[4], int (*func)(int, int)), + **(*A121)(float, float b, float *c, float *, float *count[4], float (*func)(float, float)), + **(*A122)(char, char b, char *c, char *, char *count[4], char (*func)(char, char)); typedef int A13(int, int, void (*func)(void)); struct A14 { volatile char a1; }; @@ -222,6 +235,22 @@ typedef enum VSPresetFormat { //struct A2 test_proc1(struct A0 a); +// Proc vars +void + *(*pcre_malloc)(size_t), + (*pcre_free)(void *), + *(*pcre_stack_malloc)(size_t); + +typedef MagickBooleanType + (*DuplexTransferImageViewMethod)(const ImageView *,const ImageView *, + ImageView *,const size_t,const int,void *), + (*GetImageViewMethod)(const ImageView *,const size_t,const int,void *), + (*SetImageViewMethod)(ImageView *,const size_t,const int,void *), + (*TransferImageViewMethod)(const ImageView *,ImageView *,const size_t, + const int,void *), +(*UpdateImageViewMethod)(ImageView *,const size_t,const int,void *); + + #endif #ifdef __cplusplus diff --git a/tests/tast2.nim b/tests/tast2.nim index 28ea7c5..4e60172 100644 --- a/tests/tast2.nim +++ b/tests/tast2.nim @@ -165,10 +165,10 @@ var a9p: A9p a9p[1] = nil a9p[2] = "hello".cstring -#Not implemented yet -#assert A9 is array[4, cchar] -#checkPragmas(A9, pHeaderImp) -#var a9: A9 +assert A9 is array[4, cchar] +checkPragmas(A9, pHeaderImp) +var a9: A9 +a9[2] = 'c' assert A10 is array[3, array[6, cstring]] checkPragmas(A10, pHeaderImp) @@ -308,4 +308,20 @@ assert pcre_free is proc(a1: pointer) {.cdecl.} checkPragmas(pcre_free, @["importc", "cdecl"] & pHeader) assert pcre_stack_malloc is proc(a1: uint): pointer {.cdecl.} -checkPragmas(pcre_stack_malloc, @["importc", "cdecl"] & pHeader) \ No newline at end of file +checkPragmas(pcre_stack_malloc, @["importc", "cdecl"] & pHeader) + +assert DuplexTransferImageViewMethod is + proc (a1: ptr ImageView; a2: ptr ImageView; a3: ptr ImageView; a4: uint; + a5: cint; a6: pointer): MagickBooleanType {.cdecl.} + +assert GetImageViewMethod is + proc (a1: ptr ImageView; a2: uint; a3: cint; a4: pointer): MagickBooleanType {.cdecl.} + +assert SetImageViewMethod is + proc (a1: ptr ImageView; a2: uint; a3: cint; a4: pointer): MagickBooleanType {.cdecl.} + +assert TransferImageViewMethod is + proc (a1: ptr ImageView; a2: ptr ImageView; a3: uint; a4: cint; a5: pointer): MagickBooleanType {.cdecl.} + +assert UpdateImageViewMethod is + proc (a1: ptr ImageView; a2: uint; a3: cint; a4: pointer): MagickBooleanType {.cdecl.} \ No newline at end of file From e1c8ef2775fda98defbb7f70b976538f24af3b6d Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 6 Apr 2020 12:44:07 -0500 Subject: [PATCH 365/593] ast2 dynlib fix, add 1.2.0 testing --- .travis.yml | 1 + nimterop.nimble | 3 +-- nimterop/ast2.nim | 7 +++++++ nimterop/toast.nim | 4 ++++ tests/tsoloud.nim | 3 ++- 5 files changed, 15 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3201c6c..3b66a7e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,6 +13,7 @@ language: c env: - BRANCH=0.20.2 - BRANCH=1.0.6 + - BRANCH=1.2.0 - BRANCH=devel cache: diff --git a/nimterop.nimble b/nimterop.nimble index be76135..870322b 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -49,8 +49,7 @@ task test, "Test": execCmd "./nimterop/toast -pnk -E=_ -f:ast2 tests/include/toast.h" execTest "tests/tpcre.nim" - #execTest "tests/tpcre.nim", "-d:FLAGS=\"-f:ast2\"" - #execTest "tests/tpcre.nim", "-d:FLAGS=\"-f:ast2 -H\"" + execTest "tests/tpcre.nim", "-d:FLAGS=\"-f:ast2\"" # Platform specific tests when defined(Windows): diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index 7becd04..a6610cd 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -386,6 +386,9 @@ proc newXIdent(nimState: NimState, node: TSNode, kind = nskType, fname = "", pra if nimState.includeHeader(): # Add header nimState.addPragma(node, prident[1], nimState.impShort & "H") + elif nimState.gState.dynlib.nBl: + # Add dynlib + nimState.addPragma(node, prident[1], "dynlib", nimState.getIdent(nimState.gState.dynlib)) else: # Only need impShort since no name change prident = nimState.newPragmaExpr(node, ident, nimState.impShort) @@ -1457,6 +1460,10 @@ proc addProc(nimState: NimState, node, rnode: TSNode) = # {.convention.} nimState.addPragma(node, prident, nimState.gState.convention) + if nimState.gState.dynlib.nBl: + # {.dynlib.} for DLLs + nimState.addPragma(node, prident, "dynlib", nimState.getIdent(nimState.gState.dynlib)) + procDef.add prident procDef.add newNode(nkEmpty) procDef.add newNode(nkEmpty) diff --git a/nimterop/toast.nim b/nimterop/toast.nim index a82a4ea..fe63fb9 100644 --- a/nimterop/toast.nim +++ b/nimterop/toast.nim @@ -100,6 +100,10 @@ proc main( symOverride: symOverride ) + # Fail if both includeHeader and dynlib + doAssert not (includeHeader == true and dynlib.nBl), + "`includeHeader` and `dynlib` cannot be used simultaneously" + # Split some arguments with , gState.symOverride = gState.symOverride.getSplitComma() gState.prefix = gState.prefix.getSplitComma() diff --git a/tests/tsoloud.nim b/tests/tsoloud.nim index 9823531..afff0f1 100644 --- a/tests/tsoloud.nim +++ b/tests/tsoloud.nim @@ -43,7 +43,8 @@ cCompile(src/"audiosource", "cpp", exclude="ay/") cCompile(src/"audiosource", "c") cCompile(src/"filter/*.cpp") -cImport(incl/"soloud_c.h") +const FLAGS {.strdefine.} = "" +cImport(incl/"soloud_c.h", flags = FLAGS) var s = Soloud_create() From 4c513a50de64d7675b652e08deeb4c7c0db4124a Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 6 Apr 2020 22:38:12 -0500 Subject: [PATCH 366/593] ast2 ignore parseString warnings, optional getNimExpression, handle override nil, param comments --- nimterop.nimble | 4 +++- nimterop/ast2.nim | 38 +++++++++++++++++++++++++------------- 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/nimterop.nimble b/nimterop.nimble index 870322b..c296ab5 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -29,7 +29,7 @@ task bt, "build toast": execCmd("nim c --hints:off -d:danger nimterop/toast.nim") task btd, "build toast": - execCmd("nim c --hints:off nimterop/toast.nim") + execCmd("nim c -g --hints:off nimterop/toast.nim") task docs, "Generate docs": buildDocs(@["nimterop/all.nim"], "build/htmldocs") @@ -56,6 +56,8 @@ task test, "Test": execTest "tests/tmath.nim" if defined(OSX) or defined(Windows) or not existsEnv("TRAVIS"): execTest "tests/tsoloud.nim" + execTest "tests/tsoloud.nim", "-d:FLAGS=\"-f:ast2\"" + execTest "tests/tsoloud.nim", "-d:FLAGS=\"-f:ast2 -H\"" # getHeader tests withDir("tests"): diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index a6610cd..09f5e9d 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -2,7 +2,7 @@ import macros, os, sequtils, sets, strformat, strutils, tables, times import regex -import compiler/[ast, idents, lineinfos, modulegraphs, options, parser, renderer] +import compiler/[ast, idents, lineinfos, modulegraphs, msgs, options, parser, renderer] import "."/treesitter/api @@ -18,8 +18,9 @@ proc getPtrType*(str: string): string = str proc handleError*(conf: ConfigRef, info: TLineInfo, msg: TMsgKind, arg: string) = - # Raise exception in parseString() instead of exiting - raise newException(Exception, "") + # Raise exception in parseString() instead of exiting for errors + if msg < warnMin: + raise newException(Exception, msgKindToString(msg)) proc parseString(nimState: NimState, str: string): PNode = # Parse a string into Nim AST - use custom error handler that raises @@ -29,11 +30,13 @@ proc parseString(nimState: NimState, str: string): PNode = str, nimState.identCache, nimState.config, errorHandler = handleError ) except: - discard + decho getCurrentExceptionMsg() -proc getLit*(nimState: NimState, str: string): PNode = +proc getLit*(nimState: NimState, str: string, expression = false): PNode = # Used to convert #define literals into const and expressions # in array sizes + # + # `expression` is true when `str` should be converted into a Nim expression let str = str.replace(re"/[/*].*?(?:\*/)?$", "").strip() @@ -54,7 +57,11 @@ proc getLit*(nimState: NimState, str: string): PNode = result = newStrNode(nkStrLit, str[1 .. ^2]) else: - result = nimState.parseString(nimState.getNimExpression(str)) + let + str = + if expression: nimState.getNimExpression(str) + else: str + result = nimState.parseString(str) if result.isNil: result = newNode(nkNilLit) @@ -75,7 +82,10 @@ proc getOverrideOrSkip(nimState: NimState, node: TSNode, origname: string, kind: if override.nBl: if kind == nskProc: skind = "" - result = nimState.parseString(skind & override.replace(origname, name))[0][0] + let + pnode = nimState.parseString(skind & override.replace(origname, name)) + if not pnode.isNil: + result = pnode[0][0] else: necho &"\n# $1'{origname}' skipped" % skind if nimState.gState.debug: @@ -596,11 +606,12 @@ proc newFormalParams(nimState: NimState, name: string, node: TSNode, rtyp: PNode if not node.isNil: for i in 0 ..< node.len: - # Add nkIdentDefs for each param - let - param = nimState.newIdentDefs(name, node[i], i, exported = false) - if not param.isNil: - result.add param + if node[i].getName() == "parameter_declaration": + # Add nkIdentDefs for each param + let + param = nimState.newIdentDefs(name, node[i], i, exported = false) + if not param.isNil: + result.add param proc newProcTy(nimState: NimState, name: string, node: TSNode, rtyp: PNode): PNode = # Create nkProcTy tree for specified proc type @@ -883,7 +894,8 @@ proc getTypeArray(nimState: NimState, node, tnode: TSNode, name: string): PNode for i in 0 ..< acount: let - size = nimState.getLit(nimState.getNodeVal(cnode[1])) + # Size of array could be a Nim expression + size = nimState.getLit(nimState.getNodeVal(cnode[1]), expression = true) if size.kind != nkNilLit: result = nimState.newArrayTree(cnode, result, size) cnode = cnode[0] From 4ccde62d4f3ed699832c845fde83598027820d8e Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 7 Apr 2020 17:40:59 -0500 Subject: [PATCH 367/593] ast2 fix issue 156 - abstract function pointer --- nimterop.nimble | 2 +- nimterop/ast2.nim | 29 +++++++++++++++++++++++++---- tests/include/tast2.h | 24 ++++++++++++++++++++++++ tests/tast2.nim | 12 +++++++++++- tests/tmath.nim | 3 ++- 5 files changed, 63 insertions(+), 7 deletions(-) diff --git a/nimterop.nimble b/nimterop.nimble index c296ab5..58a99b0 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -10,7 +10,7 @@ installDirs = @["nimterop"] installFiles = @["config.nims"] # Dependencies -requires "nim >= 0.20.2", "regex >= 0.13.1", "cligen >= 0.9.43" +requires "nim >= 0.20.2", "regex#v0.13.1", "cligen >= 0.9.43" import nimterop/docs diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index 09f5e9d..7a4b70a 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -531,10 +531,11 @@ proc newIdentDefs(nimState: NimState, name: string, node: TSNode, offset: SomeIn result = nil else: let - fdecl = node[start+1].anyChildInTree("function_declarator") - adecl = node[start+1].anyChildInTree("array_declarator") + fdecl = node[start+1].firstChildInTree("function_declarator") + afdecl = node[start+1].firstChildInTree("abstract_function_declarator") + adecl = node[start+1].firstChildInTree("array_declarator") abst = node[start+1].getName() == "abstract_pointer_declarator" - if fdecl.isNil and adecl.isNil: + if fdecl.isNil and afdecl.isNil and adecl.isNil: if abst: # Only for proc with no named param with pointer type # Create a param name based on offset @@ -577,6 +578,18 @@ proc newIdentDefs(nimState: NimState, name: string, node: TSNode, offset: SomeIn result.add pident result.add nimState.getTypeProc(name, node[start+1], node[start]) result.add newNode(nkEmpty) + elif not afdecl.isNil: + # Only for proc with no named param with function pointer type + # Create a param name based on offset + # + # int func(int (*)(int *)); + let + pname = "a" & $(offset+1) + pident = nimState.getIdent(pname, tinfo, exported) + procTy = nimState.getTypeProc(name, node[start+1], node[start]) + result.add pident + result.add procTy + result.add newNode(nkEmpty) elif not adecl.isNil: # Named param, array type let @@ -963,6 +976,9 @@ proc getTypeProc(nimState: NimState, name: string, node, rnode: TSNode): PNode = # node could have nested pointers tcount = node.getPtrCount() + # Nameless function pointer + afdecl = node.firstChildInTree("abstract_function_declarator") + # Name could be nested pointer to function # # (.. @@ -976,7 +992,12 @@ proc getTypeProc(nimState: NimState, name: string, node, rnode: TSNode): PNode = # ) # ) # ) - ncount = node.getAtom().tsNodeParent().getPtrCount(reverse = true) + ncount = + if not afdecl.isNil: + # Pointer to function pointer + afdecl[0].getXCount("abstract_pointer_declarator") + else: + node.getAtom().tsNodeParent().getPtrCount(reverse = true) # Return type var diff --git a/tests/include/tast2.h b/tests/include/tast2.h index 75e9446..348e225 100644 --- a/tests/include/tast2.h +++ b/tests/include/tast2.h @@ -123,6 +123,17 @@ typedef MagickBooleanType const int,void *), (*UpdateImageViewMethod)(ImageView *,const size_t,const int,void *); +// Issue #156, math.h +void + *absfunptr1 (int (*)(struct A0 *)), + **absfunptr2 (int (**)(struct A1 *)), + absfunptr3 (int *(*)(struct A2 *)), + *absfunptr4 (int *(**)(struct A3 *)), + absfunptr5 (int (*a)(A4 *)); + +int sqlite3_bind_blob(struct A1*, int, const void*, int n, void(*)(void*)); + + @@ -241,6 +252,7 @@ void (*pcre_free)(void *), *(*pcre_stack_malloc)(size_t); +typedef int ImageView, MagickBooleanType; typedef MagickBooleanType (*DuplexTransferImageViewMethod)(const ImageView *,const ImageView *, ImageView *,const size_t,const int,void *), @@ -250,6 +262,18 @@ typedef MagickBooleanType const int,void *), (*UpdateImageViewMethod)(ImageView *,const size_t,const int,void *); +// Issue #156, math.h +void + *absfunptr1 (int (*)(struct A0 *)), + **absfunptr2 (int (**)(struct A1 *)), + absfunptr3 (int *(*)(struct A2 *)), + *absfunptr4 (int *(**)(struct A3 *)), + absfunptr5 (int (*a)(A4 *)); + +int sqlite3_bind_blob(struct A1*, int, const void*, int n, void(*)(void*)); + + + #endif diff --git a/tests/tast2.nim b/tests/tast2.nim index 4e60172..d1b0f26 100644 --- a/tests/tast2.nim +++ b/tests/tast2.nim @@ -324,4 +324,14 @@ assert TransferImageViewMethod is proc (a1: ptr ImageView; a2: ptr ImageView; a3: uint; a4: cint; a5: pointer): MagickBooleanType {.cdecl.} assert UpdateImageViewMethod is - proc (a1: ptr ImageView; a2: uint; a3: cint; a4: pointer): MagickBooleanType {.cdecl.} \ No newline at end of file + proc (a1: ptr ImageView; a2: uint; a3: cint; a4: pointer): MagickBooleanType {.cdecl.} + +# Issue #156, math.h +assert absfunptr1 is proc(a1: proc(a1: ptr A0): cint {.cdecl.}): pointer {.cdecl.} +assert absfunptr2 is proc(a1: ptr proc(a1: ptr A1): cint {.cdecl.}): ptr pointer {.cdecl.} +assert absfunptr3 is proc(a1: proc(a1: ptr A2): ptr cint {.cdecl.}) {.cdecl.} +assert absfunptr4 is proc(a1: ptr proc(a1: ptr A3): ptr cint {.cdecl.}): pointer {.cdecl.} +assert absfunptr5 is proc(a1: proc(a1: ptr A4): cint {.cdecl.}) {.cdecl.} + +assert sqlite3_bind_blob is + proc(a1: ptr A1, a2: cint, a3: pointer, n: cint, a5: proc(a1: pointer) {.cdecl.}): cint {.cdecl.} diff --git a/tests/tmath.nim b/tests/tmath.nim index 9f3df79..1f804ab 100644 --- a/tests/tmath.nim +++ b/tests/tmath.nim @@ -22,7 +22,8 @@ cPlugin: proc onSymbol*(sym: var Symbol) {.exportc, dynlib.} = sym.name = sym.name.strip(chars={'_'}).replace("__", "_") -cImport cSearchPath("math.h") +const FLAGS {.strdefine.} = "" +cImport(cSearchPath("math.h"), flags = FLAGS) check sin(5) == -0.9589242746631385 check abs(-5) == 5 From 31ed046e3b1d472c70959636114c737345197a44 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 7 Apr 2020 17:54:17 -0500 Subject: [PATCH 368/593] ast2 tmath tests --- nimterop.nimble | 2 ++ tests/tmath.nim | 9 +++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/nimterop.nimble b/nimterop.nimble index 58a99b0..cd36e1c 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -54,6 +54,8 @@ task test, "Test": # Platform specific tests when defined(Windows): execTest "tests/tmath.nim" + execTest "tests/tmath.nim", "-d:FLAGS=\"-f:ast2\"" + execTest "tests/tmath.nim", "-d:FLAGS=\"-f:ast2 -H\"" if defined(OSX) or defined(Windows) or not existsEnv("TRAVIS"): execTest "tests/tsoloud.nim" execTest "tests/tsoloud.nim", "-d:FLAGS=\"-f:ast2\"" diff --git a/tests/tmath.nim b/tests/tmath.nim index 1f804ab..5d84700 100644 --- a/tests/tmath.nim +++ b/tests/tmath.nim @@ -1,10 +1,11 @@ import unittest import nimterop/cimport -type - locale_t = object - mingw_ldbl_type_t = object - mingw_dbl_type_t = object +cOverride: + type + locale_t = object + mingw_ldbl_type_t = object + mingw_dbl_type_t = object when defined(windows): cOverride: From d877b204077c80422666e2f89418cdda64f0720f Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 7 Apr 2020 20:24:04 -0500 Subject: [PATCH 369/593] ast2 fix issue 174 - UncheckedArray --- nimterop/ast2.nim | 30 ++++++++++++++++++++++-------- tests/include/tast2.h | 10 ++++++++++ tests/tast2.nim | 12 ++++++++++++ 3 files changed, 44 insertions(+), 8 deletions(-) diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index 7a4b70a..a9624ac 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -460,11 +460,18 @@ proc newPtrTree(nimState: NimState, count: int, typ: PNode): PNode = parent.add result result = nresult -proc newArrayTree(nimState: NimState, node: TSNode, typ, size: PNode): PNode = +proc newArrayTree(nimState: NimState, node: TSNode, typ, size: PNode = nil): PNode = # Create nkBracketExpr tree depending on input + # + # If `size` is nil, create UncheckedArray[typ] let info = nimState.getLineInfo(node.getAtom()) - ident = nimState.getIdent("array", info, exported = false) + tname = + if size.isNil: + "UncheckedArray" + else: + "array" + ident = nimState.getIdent(tname, info, exported = false) # array[size, typ] # @@ -475,7 +482,8 @@ proc newArrayTree(nimState: NimState, node: TSNode, typ, size: PNode): PNode = # ) result = newNode(nkBracketExpr) result.add ident - result.add size + if not size.isNil: + result.add size result.add typ proc getTypeArray(nimState: NimState, node, tnode: TSNode, name: string): PNode @@ -906,11 +914,17 @@ proc getTypeArray(nimState: NimState, node, tnode: TSNode, name: string): PNode result = nimState.newPtrTree(tcount, result) for i in 0 ..< acount: - let - # Size of array could be a Nim expression - size = nimState.getLit(nimState.getNodeVal(cnode[1]), expression = true) - if size.kind != nkNilLit: - result = nimState.newArrayTree(cnode, result, size) + if cnode.len == 2: + # type name[X] => array[X, type] + let + # Size of array could be a Nim expression + size = nimState.getLit(nimState.getNodeVal(cnode[1]), expression = true) + if size.kind != nkNilLit: + result = nimState.newArrayTree(cnode, result, size) + cnode = cnode[0] + elif cnode.len == 1: + # type name[] = UncheckedArray[type] + result = nimState.newArrayTree(cnode, result) cnode = cnode[0] if ncount > 0: diff --git a/tests/include/tast2.h b/tests/include/tast2.h index 348e225..a819f5e 100644 --- a/tests/include/tast2.h +++ b/tests/include/tast2.h @@ -133,6 +133,16 @@ void int sqlite3_bind_blob(struct A1*, int, const void*, int n, void(*)(void*)); +// Issue #174 - type name[] => UncheckedArray[type] +int ucArrFunc1(int text[]); +int ucArrFunc2(int text[][5], int (*func)(int text[])); + +typedef int ucArrType1[][5]; +struct ucArrType2 { + float f1[5][5]; + int *f2[][5]; +}; + diff --git a/tests/tast2.nim b/tests/tast2.nim index d1b0f26..f2816eb 100644 --- a/tests/tast2.nim +++ b/tests/tast2.nim @@ -335,3 +335,15 @@ assert absfunptr5 is proc(a1: proc(a1: ptr A4): cint {.cdecl.}) {.cdecl.} assert sqlite3_bind_blob is proc(a1: ptr A1, a2: cint, a3: pointer, n: cint, a5: proc(a1: pointer) {.cdecl.}): cint {.cdecl.} + +# Issue #174 - type name[] => UncheckedArray[type] +assert ucArrFunc1 is proc(text: UncheckedArray[cint]): cint {.cdecl.} +assert ucArrFunc2 is + proc(text: UncheckedArray[array[5, cint]], `func`: proc(text: UncheckedArray[cint]): cint {.cdecl.}): cint {.cdecl.} + +assert ucArrType1 is UncheckedArray[array[5, cint]] +checkPragmas(ucArrType1, pHeaderImp) + +assert ucArrType2 is object +testFields(ucArrType2, "f1|f2:array[5, array[5, cfloat]]|UncheckedArray[array[5, ptr cint]]") +checkPragmas(ucArrType2, pHeaderBy, istype = false) From 058261c2037d277436d1dc64b53e669f90f0db0e Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 8 Apr 2020 17:21:23 -0500 Subject: [PATCH 370/593] ast2 tests and const bugfix --- nimterop/ast2.nim | 8 +++++++- tests/include/tast2.h | 22 ++++++++++++++++++++++ tests/tast2.nim | 38 ++++++++++++++++++++++++-------------- 3 files changed, 53 insertions(+), 15 deletions(-) diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index a9624ac..7bb4520 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -283,7 +283,13 @@ proc newXIdent(nimState: NimState, node: TSNode, kind = nskType, fname = "", pra # If `pragmas`, add as nkPragmaExpr but not for `nskProc` since procs add pragmas elsewhere # If `istype` is set, this is a typedef, else struct/union so add {.importc: "struct/union X".} when includeHeader let - (tname, torigname, info) = nimState.getNameInfo(node.getAtom(), kind) + atom = node.getAtom() + + (tname, torigname, info) = + if not atom.isNil: + nimState.getNameInfo(node.getAtom(), kind) + else: + ("", "", nimState.getLineInfo(node)) origname = if fname.nBl: diff --git a/tests/include/tast2.h b/tests/include/tast2.h index a819f5e..f4cd201 100644 --- a/tests/include/tast2.h +++ b/tests/include/tast2.h @@ -143,6 +143,17 @@ struct ucArrType2 { int *f2[][5]; }; +typedef struct fieldfuncfunc { + int *(*func1)(int f1, int *(*sfunc1)(int f1, int *(*ssfunc1)(int f1))); +}; + +int *func2(int f1, int *(*sfunc2)(int f1, int *(*ssfunc2)(int f1))); + +typedef struct { + const char *name; // description + const char *driver; // driver + int flags; +} BASS_DEVICEINFO; @@ -282,6 +293,17 @@ void int sqlite3_bind_blob(struct A1*, int, const void*, int n, void(*)(void*)); +typedef struct fieldfuncfunc { + int *(*func1)(int f1, int *(*sfunc1)(int f1, int *(*ssfunc1)(int f1))); +}; + +int *func2(int f1, int *(*sfunc2)(int f1, int *(*ssfunc2)(int f1))); + +typedef struct { + const char *name; // description + const char *driver; // driver + int flags; +} BASS_DEVICEINFO; diff --git a/tests/tast2.nim b/tests/tast2.nim index f2816eb..a88c29e 100644 --- a/tests/tast2.nim +++ b/tests/tast2.nim @@ -78,7 +78,7 @@ macro testFields(t: typed, fields: static[string] = "") = var ast = t.getImpl() rl = ast.getRecList() - fsplit = fields.split(":") + fsplit = fields.split("!") names = fsplit[0].split("|") types = if fsplit.len > 1: @@ -89,7 +89,7 @@ macro testFields(t: typed, fields: static[string] = "") = for i in 0 ..< rl.len: let name = ($rl[i][0]).strip(chars = {'*'}) - typ = $(rl[i][1].repr()) + typ = ($(rl[i][1].repr())).replace("\n", "").replace(" ", "") n = names.find(name) assert n != -1, $t & "." & name & " invalid" assert types[n] == typ, @@ -102,13 +102,13 @@ assert D == "hello" assert E == 'c' assert A0 is object -testFields(A0, "f1:cint") +testFields(A0, "f1!cint") checkPragmas(A0, pHeaderBy, istype = false) var a0: A0 a0.f1 = 1 assert A1 is A0 -testFields(A1, "f1:cint") +testFields(A1, "f1!cint") var a1: A1 a1.f1 = 2 @@ -125,13 +125,13 @@ checkPragmas(A3, pHeaderInc, istype = false) var a3: A3 assert A4 is object -testFields(A4, "f1:cfloat") +testFields(A4, "f1!cfloat") checkPragmas(A4, pHeaderImpBy) var a4: A4 a4.f1 = 4.1 assert A4p is ptr A4 -testFields(A4p, "f1:cfloat") +testFields(A4p, "f1!cfloat") checkPragmas(A4p, pHeaderImp) var a4p: A4p a4p = addr a4 @@ -202,13 +202,13 @@ checkPragmas(A13, pHeaderImp & "cdecl") var a13: A13 assert A14 is object -testFields(A14, "a1:cchar") +testFields(A14, "a1!cchar") checkPragmas(A14, pHeaderBy, istype = false) var a14: A14 a14.a1 = 'a' assert A15 is object -testFields(A15, "a1|a2:cstring|array[1, ptr cint]") +testFields(A15, "a1|a2!cstring|array[1, ptr cint]") checkPragmas(A15, pHeaderBy, istype = false) var a15: A15 @@ -217,13 +217,13 @@ a15.a1 = "hello".cstring a15.a2[0] = addr a15i assert A16 is object -testFields(A16, "f1:cchar") +testFields(A16, "f1!cchar") checkPragmas(A16, pHeaderBy, istype = false) var a16: A16 a16.f1 = 's' assert A17 is object -testFields(A17, "a1|a2:cstring|array[1, ptr cint]") +testFields(A17, "a1|a2!cstring|array[1, ptr cint]") checkPragmas(A17, pHeaderBy, istype = false) var a17: A17 a17.a1 = "hello".cstring @@ -239,7 +239,7 @@ var a18p: A18p a18p = addr a18 assert A19 is object -testFields(A19, "a1|a2:cstring|array[1, ptr cint]") +testFields(A19, "a1|a2!cstring|array[1, ptr cint]") checkPragmas(A19, pHeaderImpBy) var a19: A19 a19.a1 = "hello".cstring @@ -251,7 +251,7 @@ var a19p: A19p a19p = addr a19 assert A20 is object -testFields(A20, "a1:cchar") +testFields(A20, "a1!cchar") checkPragmas(A20, pHeaderBy, istype = false) var a20: A20 a20.a1 = 'a' @@ -267,7 +267,7 @@ var a21p: A21p a21p = addr a20 assert A22 is object -testFields(A22, "f1|f2:ptr ptr cint|array[123 + 132, ptr cint]") +testFields(A22, "f1|f2!ptr ptr cint|array[123 + 132, ptr cint]") checkPragmas(A22, pHeaderBy, istype = false) var a22: A22 a22.f1 = addr a15.a2[0] @@ -345,5 +345,15 @@ assert ucArrType1 is UncheckedArray[array[5, cint]] checkPragmas(ucArrType1, pHeaderImp) assert ucArrType2 is object -testFields(ucArrType2, "f1|f2:array[5, array[5, cfloat]]|UncheckedArray[array[5, ptr cint]]") +testFields(ucArrType2, "f1|f2!array[5, array[5, cfloat]]|UncheckedArray[array[5, ptr cint]]") checkPragmas(ucArrType2, pHeaderBy, istype = false) + +assert fieldfuncfunc is object +testFields(fieldfuncfunc, + "func1!proc (f1: cint; sfunc1: proc (f1: cint; ssfunc1: proc (f1: cint): ptr cint {.cdecl.}): ptr cint {.cdecl.}): ptr cint {.cdecl.}") + +assert func2 is proc (f1: cint; sfunc2: proc (f1: cint; ssfunc2: proc (f1: cint): ptr cint {.cdecl.}): ptr cint {.cdecl.}): ptr cint {.cdecl.} + +assert BASS_DEVICEINFO is object +testFields(BASS_DEVICEINFO, "name|driver|flags!cstring|cstring|cint") +checkPragmas(BASS_DEVICEINFO, pHeaderImpBy) \ No newline at end of file From f5dd89904d8866456c62f4bf6b57b6c264d6dea2 Mon Sep 17 00:00:00 2001 From: awr1 <41453959+awr1@users.noreply.github.com> Date: Thu, 9 Apr 2020 23:00:56 -0500 Subject: [PATCH 371/593] Preprocessor mode fixes (#176) --- nimterop/build.nim | 38 ++++++++++++++++++++++++++------------ nimterop/getters.nim | 5 ++--- nimterop/globals.nim | 9 ++------- nimterop/toast.nim | 13 ++++--------- tests/tpcre.nim | 3 +-- 5 files changed, 35 insertions(+), 33 deletions(-) diff --git a/nimterop/build.nim b/nimterop/build.nim index c65ec2a..cc6dc22 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -620,6 +620,21 @@ proc make*(path, check: string, flags = "", regex = false) = doAssert findFile(check, path, regex = regex).len != 0, "# make failed" +proc getCompilerMode*(path: string): string = + ## Determines a target language mode from an input filename, if one is not already specified. + let file = path.splitFile() + if file.ext in [".hxx", ".hpp", ".hh", ".H", ".h++", ".cpp", ".cxx", ".cc", ".C", ".c++"]: + result = "cpp" + elif file.ext in [".h", ".c"]: + result = "c" + +proc getGccModeArg*(mode: string): string = + ## Produces a GCC argument that explicitly sets the language mode to be used by the compiler. + if mode == "cpp": + result = "-xc++" + elif mode == "c": + result = "-xc" + proc getCompiler*(): string = var compiler = @@ -632,13 +647,12 @@ proc getCompiler*(): string = result = getEnv("CC", compiler) -proc getGccPaths*(mode = "c"): seq[string] = +proc getGccPaths*(mode: string): seq[string] = var nul = when defined(Windows): "nul" else: "/dev/null" - mmode = if mode == "cpp": "c++" else: mode inc = false - (outp, _) = execAction(&"""{getCompiler()} -Wp,-v -x{mmode} {nul}""", die = false) + (outp, _) = execAction(&"""{getCompiler()} -Wp,-v {getGccModeArg(mode)} {nul}""", die = false) for line in outp.splitLines(): if "#include <...> search starts here" in line: @@ -655,13 +669,12 @@ proc getGccPaths*(mode = "c"): seq[string] = when defined(osx): result.add(execAction("xcrun --show-sdk-path").output.strip() & "/usr/include") -proc getGccLibPaths*(mode = "c"): seq[string] = +proc getGccLibPaths*(mode: string): seq[string] = var nul = when defined(Windows): "nul" else: "/dev/null" - mmode = if mode == "cpp": "c++" else: mode linker = when defined(OSX): "-Xlinker" else: "" - (outp, _) = execAction(&"""{getCompiler()} {linker} -v -x{mmode} {nul}""", die = false) + (outp, _) = execAction(&"""{getCompiler()} {linker} -v {getGccModeArg(mode)} {nul}""", die = false) for line in outp.splitLines(): if "LIBRARY_PATH=" in line: @@ -680,14 +693,14 @@ proc getGccLibPaths*(mode = "c"): seq[string] = when defined(osx): result.add "/usr/lib" -proc getStdPath(header: string): string = - for inc in getGccPaths(): +proc getStdPath(header, mode: string): string = + for inc in getGccPaths(mode): result = findFile(header, inc, recurse = false, first = true) if result.len != 0: break -proc getStdLibPath(lname: string): string = - for lib in getGccLibPaths(): +proc getStdLibPath(lname, mode: string): string = + for lib in getGccLibPaths(mode): result = findFile(lname, lib, recurse = false, first = true, regex = true) if result.len != 0: break @@ -973,6 +986,7 @@ macro getHeader*(header: static[string], giturl: static[string] = "", dlurl: sta gDefines[verStr] else: "" + mode = getCompilerMode(header) # Use alternate library names if specified for regex search if altNames.len != 0: @@ -1008,9 +1022,9 @@ macro getHeader*(header: static[string], giturl: static[string] = "", dlurl: sta # Look in standard path if requested by user stdPath = - when `nameStd`: getStdPath(`header`) else: "" + when `nameStd`: getStdPath(`header`, `mode`) else: "" stdLPath = - when `nameStd`: getStdLibPath(`lname`) else: "" + when `nameStd`: getStdLibPath(`lname`, `mode`) else: "" # Look elsewhere if requested while prioritizing standard paths prePath = diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 044cde7..986c54d 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -495,11 +495,10 @@ proc removeStatic(content: string): string = result.add(body.replace(re"(?m)^(.*\n?)", "//$1")) ) -proc getPreprocessor*(gState: State, fullpath: string, mode = "cpp"): string = +proc getPreprocessor*(gState: State, fullpath: string): string = var - mmode = if mode == "cpp": "c++" else: mode cmts = if gState.nocomments: "" else: "-CC" - cmd = &"""{getCompiler()} -E {cmts} -dD -x{mmode} -w """ + cmd = &"""{getCompiler()} -E {cmts} -dD {getGccModeArg(gState.mode)} -w """ rdata: seq[string] = @[] start = false diff --git a/nimterop/globals.nim b/nimterop/globals.nim index 701db61..42f7cb7 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -98,9 +98,6 @@ type nodeBranch*: seq[string] - CompileMode = enum - c, cpp - Feature* = enum ast2 @@ -113,11 +110,9 @@ template nBl(s: typed): untyped {.used.} = template Bl(s: typed): untyped {.used.} = (s.len == 0) -const modeDefault {.used.} = $cpp - when not declared(CIMPORT): export gAtoms, gExpressions, gEnumVals, Kind, Ast, AstTable, State, NimState, - nBl, Bl, CompileMode, modeDefault + nBl, Bl # Redirect output to file when required template gecho*(args: string) {.dirty.} = @@ -133,4 +128,4 @@ when not declared(CIMPORT): template decho*(str: untyped): untyped = if nimState.gState.debug: - necho str.getCommented() \ No newline at end of file + necho str.getCommented() diff --git a/nimterop/toast.nim b/nimterop/toast.nim index fe63fb9..c3d6a3d 100644 --- a/nimterop/toast.nim +++ b/nimterop/toast.nim @@ -2,23 +2,18 @@ import os, osproc, strformat, strutils, times import "."/treesitter/[api, c, cpp] -import "."/[ast, ast2, globals, getters, grammar] +import "."/[ast, ast2, globals, getters, grammar, build] proc process(gState: State, path: string, astTable: AstTable) = doAssert existsFile(path), &"Invalid path {path}" - var - parser = tsParserNew() - ext = path.splitFile().ext + var parser = tsParserNew() defer: parser.tsParserDelete() if gState.mode.Bl: - if ext in [".h", ".c"]: - gState.mode = "c" - elif ext in [".hxx", ".hpp", ".hh", ".H", ".h++", ".cpp", ".cxx", ".cc", ".C", ".c++"]: - gState.mode = "cpp" + gState.mode = getCompilerMode(path) if gState.preprocess: gState.code = gState.getPreprocessor(path) @@ -61,7 +56,7 @@ proc main( feature: seq[Feature] = @[], includeHeader = false, includeDirs: seq[string] = @[], - mode = modeDefault, + mode = "", nim: string = "nim", nocomments = false, output = "", diff --git a/tests/tpcre.nim b/tests/tpcre.nim index f896e9c..c8e8059 100644 --- a/tests/tpcre.nim +++ b/tests/tpcre.nim @@ -31,8 +31,7 @@ cPlugin: sym.name = sym.name.replace("pcre_", "") const FLAGS {.strdefine.} = "" -cImport(pcreH, dynlib="dynpcre", flags = FLAGS) - +cImport(pcreH, dynlib="dynpcre", flags="--mode=c " & FLAGS) echo version() when FLAGS.len != 0: From f64fbb67b11ed6e48bf1585d14c1fded3c173944 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Fri, 10 Apr 2020 22:45:29 -0500 Subject: [PATCH 372/593] Fix #178 - single underscore --- nimterop/getters.nim | 4 +++- tests/include/test.h | 6 ++++++ tests/tnimterop_c.nim | 1 + 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 986c54d..48ed8f7 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -655,7 +655,9 @@ proc getNimExpression*(nimState: NimState, expr: string, name = ""): string = if i == clean.len or gen.nBl: # Process identifier if ident.nBl: - ident = nimState.getIdentifier(ident, nskConst) + # Issue #178 + if ident != "_": + ident = nimState.getIdentifier(ident, nskConst) if name.nBl and ident in nimState.constIdentifiers: ident = ident & "." & name result &= ident diff --git a/tests/include/test.h b/tests/include/test.h index b22e2d8..e9c281c 100644 --- a/tests/include/test.h +++ b/tests/include/test.h @@ -194,6 +194,12 @@ struct JKL { int **f1; }; +// Issue #178 +typedef enum +{ + SDLK_UNDERSCORE = '_' +} SDL_KeyCode; + #ifdef __cplusplus } #endif diff --git a/tests/tnimterop_c.nim b/tests/tnimterop_c.nim index fe4e9ee..e78e7f2 100644 --- a/tests/tnimterop_c.nim +++ b/tests/tnimterop_c.nim @@ -227,3 +227,4 @@ cg.f2 = nil doAssert BIT == 1 doAssert ca(nil) == 1 doAssert cc(nil) == 2 +doAssert SDLK_UNDERSCORE == 95 \ No newline at end of file From 894193eb43b81267f83bc722204d33df28478f79 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Fri, 10 Apr 2020 23:49:23 -0500 Subject: [PATCH 373/593] Fix type override issue --- nimterop/grammar.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index 2e6b585..8e1d290 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -178,7 +178,7 @@ proc initGrammar(): Grammar = var i = 0 - typ = nimState.getIdentifier(nimState.data[i].val, nskType).getType() + typ = nimState.getIdentifier(nimState.data[i].val, nskType, "Parent").getType() name = "" nname = "" tptr = "" From ecee58342ee53296eae98fcf4038e6f999b416a5 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Sat, 11 Apr 2020 14:54:19 -0500 Subject: [PATCH 374/593] Fix expression override issue --- nimterop/getters.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 48ed8f7..e47113d 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -657,7 +657,7 @@ proc getNimExpression*(nimState: NimState, expr: string, name = ""): string = if ident.nBl: # Issue #178 if ident != "_": - ident = nimState.getIdentifier(ident, nskConst) + ident = nimState.getIdentifier(ident, nskConst, name) if name.nBl and ident in nimState.constIdentifiers: ident = ident & "." & name result &= ident From 9cd39600d43c90045b0da6873900881449e6d609 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Sun, 12 Apr 2020 12:19:13 -0500 Subject: [PATCH 375/593] Partly fix issue #183, lineTrace:on --- config.nims | 1 + nimterop/ast2.nim | 161 +++++++++++++++++++++++------------------- tests/include/tast2.h | 13 ++++ tests/tast2.nim | 7 +- 4 files changed, 109 insertions(+), 73 deletions(-) diff --git a/config.nims b/config.nims index 7e7a6e1..6b475de 100644 --- a/config.nims +++ b/config.nims @@ -10,6 +10,7 @@ when defined(Windows): # Retain stackTrace for clear errors switch("stackTrace", "on") +switch("lineTrace", "on") # Path to compiler switch("path", "$nim") diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index 7bb4520..ed7c2a9 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -495,7 +495,7 @@ proc newArrayTree(nimState: NimState, node: TSNode, typ, size: PNode = nil): PNo proc getTypeArray(nimState: NimState, node, tnode: TSNode, name: string): PNode proc getTypeProc(nimState: NimState, name: string, node, rnode: TSNode): PNode -proc newIdentDefs(nimState: NimState, name: string, node: TSNode, offset: SomeInteger, exported = false): PNode = +iterator newIdentDefs(nimState: NimState, name: string, node: TSNode, offset: SomeInteger, exported = false): PNode = # Create nkIdentDefs tree for specified proc parameter or object field # # For proc, param should not be exported @@ -520,8 +520,13 @@ proc newIdentDefs(nimState: NimState, name: string, node: TSNode, offset: SomeIn # typ, # nkEmpty() # ) - result = newNode(nkIdentDefs) - + # + # Iterator since structs can have multiple comma separated fields for the + # same type so can yield multiple results. + # + # struct ABC { int w, h; }; + # + # This is not applicable for procs. let start = getStartAtom(node) @@ -533,6 +538,9 @@ proc newIdentDefs(nimState: NimState, name: string, node: TSNode, offset: SomeIn # Only for proc with no named param - create a param name based on offset # # int func(char, int); + var + result = newNode(nkIdentDefs) + if tname != "object": let pname = "a" & $(offset+1) @@ -543,77 +551,88 @@ proc newIdentDefs(nimState: NimState, name: string, node: TSNode, offset: SomeIn else: # int func(void) result = nil + + yield result else: - let - fdecl = node[start+1].firstChildInTree("function_declarator") - afdecl = node[start+1].firstChildInTree("abstract_function_declarator") - adecl = node[start+1].firstChildInTree("array_declarator") - abst = node[start+1].getName() == "abstract_pointer_declarator" - if fdecl.isNil and afdecl.isNil and adecl.isNil: - if abst: - # Only for proc with no named param with pointer type + for i in start+1 ..< node.len: + if node[i].getName() == "bitfield_clause": + continue + + var + result = newNode(nkIdentDefs) + + let + fdecl = node[i].firstChildInTree("function_declarator") + afdecl = node[i].firstChildInTree("abstract_function_declarator") + adecl = node[i].firstChildInTree("array_declarator") + abst = node[i].getName() == "abstract_pointer_declarator" + if fdecl.isNil and afdecl.isNil and adecl.isNil: + if abst: + # Only for proc with no named param with pointer type + # Create a param name based on offset + # + # int func(char *, int **); + let + pname = "a" & $(offset+1) + pident = nimState.getIdent(pname, tinfo, exported) + acount = node[i].getXCount("abstract_pointer_declarator") + result.add pident + result.add nimState.newPtrTree(acount, tident) + result.add newNode(nkEmpty) + else: + # Named param, simple type + let + (pname, _, pinfo) = nimState.getNameInfo(node[i].getAtom(), nskField, parent = name) + pident = nimState.getIdent(pname, pinfo, exported) + + # Bitfield support - typedef struct { int field: 1; }; + prident = + if node.len > i and node[i + 1].getName() == "bitfield_clause": + nimState.newPragmaExpr(node, pident, "bitsize", + newIntNode(nkIntLit, parseInt(nimState.getNodeVal(node[i + 1].getAtom())))) + else: + pident + + count = node[i].getPtrCount() + + result.add prident + if count > 0: + result.add nimState.newPtrTree(count, tident) + else: + result.add tident + result.add newNode(nkEmpty) + elif not fdecl.isNil: + # Named param, function pointer + let + (pname, _, pinfo) = nimState.getNameInfo(node[i].getAtom(), nskField, parent = name) + pident = nimState.getIdent(pname, pinfo, exported) + result.add pident + result.add nimState.getTypeProc(name, node[i], node[start]) + result.add newNode(nkEmpty) + elif not afdecl.isNil: + # Only for proc with no named param with function pointer type # Create a param name based on offset # - # int func(char *, int **); + # int func(int (*)(int *)); let pname = "a" & $(offset+1) pident = nimState.getIdent(pname, tinfo, exported) - acount = node[start+1].getXCount("abstract_pointer_declarator") + procTy = nimState.getTypeProc(name, node[i], node[start]) result.add pident - result.add nimState.newPtrTree(acount, tident) + result.add procTy + result.add newNode(nkEmpty) + elif not adecl.isNil: + # Named param, array type + let + (pname, _, pinfo) = nimState.getNameInfo(node[i].getAtom(), nskField, parent = name) + pident = nimState.getIdent(pname, pinfo, exported) + result.add pident + result.add nimState.getTypeArray(node[i], node[start], name) result.add newNode(nkEmpty) else: - # Named param, simple type - let - (pname, _, pinfo) = nimState.getNameInfo(node[start+1].getAtom(), nskField, parent = name) - pident = nimState.getIdent(pname, pinfo, exported) + result = nil - # Bitfield support - typedef struct { int field: 1; }; - prident = - if node.len > start+1 and node[start+2].getName() == "bitfield_clause": - nimState.newPragmaExpr(node, pident, "bitsize", - newIntNode(nkIntLit, parseInt(nimState.getNodeVal(node[start+2].getAtom())))) - else: - pident - - count = node[start+1].getPtrCount() - - result.add prident - if count > 0: - result.add nimState.newPtrTree(count, tident) - else: - result.add tident - result.add newNode(nkEmpty) - elif not fdecl.isNil: - # Named param, function pointer - let - (pname, _, pinfo) = nimState.getNameInfo(node[start+1].getAtom(), nskField, parent = name) - pident = nimState.getIdent(pname, pinfo, exported) - result.add pident - result.add nimState.getTypeProc(name, node[start+1], node[start]) - result.add newNode(nkEmpty) - elif not afdecl.isNil: - # Only for proc with no named param with function pointer type - # Create a param name based on offset - # - # int func(int (*)(int *)); - let - pname = "a" & $(offset+1) - pident = nimState.getIdent(pname, tinfo, exported) - procTy = nimState.getTypeProc(name, node[start+1], node[start]) - result.add pident - result.add procTy - result.add newNode(nkEmpty) - elif not adecl.isNil: - # Named param, array type - let - (pname, _, pinfo) = nimState.getNameInfo(node[start+1].getAtom(), nskField, parent = name) - pident = nimState.getIdent(pname, pinfo, exported) - result.add pident - result.add nimState.getTypeArray(node[start+1], node[start], name) - result.add newNode(nkEmpty) - else: - result = nil + yield result proc newFormalParams(nimState: NimState, name: string, node: TSNode, rtyp: PNode): PNode = # Create nkFormalParams tree for specified params and return type @@ -635,10 +654,9 @@ proc newFormalParams(nimState: NimState, name: string, node: TSNode, rtyp: PNode for i in 0 ..< node.len: if node[i].getName() == "parameter_declaration": # Add nkIdentDefs for each param - let - param = nimState.newIdentDefs(name, node[i], i, exported = false) - if not param.isNil: - result.add param + for param in nimState.newIdentDefs(name, node[i], i, exported = false): + if not param.isNil: + result.add param proc newProcTy(nimState: NimState, name: string, node: TSNode, rtyp: PNode): PNode = # Create nkProcTy tree for specified proc type @@ -674,10 +692,9 @@ proc newRecListTree(nimState: NimState, name: string, node: TSNode): PNode = for i in 0 ..< node.len: if node[i].getName() == "field_declaration": # Add nkIdentDefs for each field - let - field = nimState.newIdentDefs(name, node[i], i, exported = true) - if not field.isNil: - result.add field + for field in nimState.newIdentDefs(name, node[i], i, exported = true): + if not field.isNil: + result.add field proc addTypeObject(nimState: NimState, node: TSNode, typeDef: PNode = nil, fname = "", istype = false, union = false) = # Add a type of object diff --git a/tests/include/tast2.h b/tests/include/tast2.h index f4cd201..4854eb7 100644 --- a/tests/include/tast2.h +++ b/tests/include/tast2.h @@ -155,6 +155,12 @@ typedef struct { int flags; } BASS_DEVICEINFO; +// Issue #183 +struct GPU_Target +{ + int w, *h; + char *x, y, **z; +}; @@ -305,6 +311,13 @@ typedef struct { int flags; } BASS_DEVICEINFO; +// Issue #183 +struct GPU_Target +{ + int w, *h; + char *x, y, **z; +}; + #endif diff --git a/tests/tast2.nim b/tests/tast2.nim index a88c29e..de0e743 100644 --- a/tests/tast2.nim +++ b/tests/tast2.nim @@ -356,4 +356,9 @@ assert func2 is proc (f1: cint; sfunc2: proc (f1: cint; ssfunc2: proc (f1: cint) assert BASS_DEVICEINFO is object testFields(BASS_DEVICEINFO, "name|driver|flags!cstring|cstring|cint") -checkPragmas(BASS_DEVICEINFO, pHeaderImpBy) \ No newline at end of file +checkPragmas(BASS_DEVICEINFO, pHeaderImpBy) + +# Issue #183 +assert GPU_Target is object +testFields(GPU_Target, "w|h|x|y|z!cint|ptr cint|cstring|cchar|ptr cstring") +checkPragmas(GPU_Target, pHeaderBy, istype = false) \ No newline at end of file From 0afb634b59d55ff369bd25d85e13d156c6836db0 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Sun, 12 Apr 2020 12:56:50 -0500 Subject: [PATCH 376/593] Fix #181 - cPluginPath() --- nimterop/cimport.nim | 18 ++++++++++++++++-- tests/tnimterop_c.nim | 9 +-------- tests/tnimterop_c_plugin.nim | 7 +++++++ 3 files changed, 24 insertions(+), 10 deletions(-) create mode 100644 tests/tnimterop_c_plugin.nim diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index c4ebc3f..69aaf90 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -273,7 +273,7 @@ proc cPluginHelper(body: string) = if gStateCT.pluginSource.nBl or gStateCT.overrides.nBl: let - data = "import macros, nimterop/plugin\n\n" & body & gStateCT.overrides + data = "import macros, nimterop/plugin\n\n" & body & "\n\n" & gStateCT.overrides hash = data.hash().abs() path = getProjectCacheDir("cPlugins", forceClean = false) / "nimterop_" & $hash & ".nim" @@ -317,7 +317,7 @@ macro cPlugin*(body): untyped = ## - `nskEnumField` for enum (field) names, though they are in the global namespace as `nskConst` ## - `nskProc` - for proc names ## - ## `nimterop/plugins` is implicitly imported to provide access to standard + ## `macros` and `nimterop/plugins` are implicitly imported to provide access to standard ## plugin facilities. ## ## `cPlugin() `_ only affects calls to @@ -342,6 +342,20 @@ macro cPlugin*(body): untyped = cPluginHelper(body.repr) +macro cPluginPath*(path: static[string]): untyped = + ## Rather than embedding the `cPlugin()` code within the wrapper, it might be + ## preferable to have it stored in a separate source file. This allows for reuse + ## across multiple wrappers when applicable. + ## + ## The `cPluginPath()` macro enables this functionality - provide a path to the + ## plugin file and it will be consumed in the same way as `cPlugin()`. + ## + ## `path` is relative to the current dir and not necessarily relative to the + ## location of the wrapper file. Use `currentSourcePath.parentDir()` to specify + ## path relative to the wrapper file. + doAssert fileExists(path), "Plugin file not found: " & path + cPluginHelper(readFile(path)) + proc cSearchPath*(path: string): string {.compileTime.}= ## Get full path to file or directory `path` in search path configured ## using `cAddSearchDir() `_ and diff --git a/tests/tnimterop_c.nim b/tests/tnimterop_c.nim index e78e7f2..0360225 100644 --- a/tests/tnimterop_c.nim +++ b/tests/tnimterop_c.nim @@ -11,14 +11,7 @@ cDefine("FORCE") cIncludeDir testsIncludeDir() cCompile cSearchPath("test.c") -cPlugin: - import strutils - - proc onSymbol*(sym: var Symbol) {.exportc, dynlib.} = - if sym.name == "_Kernel": - sym.name = "uKernel" - else: - sym.name = sym.name.strip(chars={'_'}) +cPluginPath("tests/tnimterop_c_plugin.nim") cOverride: type diff --git a/tests/tnimterop_c_plugin.nim b/tests/tnimterop_c_plugin.nim new file mode 100644 index 0000000..68bb4d6 --- /dev/null +++ b/tests/tnimterop_c_plugin.nim @@ -0,0 +1,7 @@ +import strutils + +proc onSymbol*(sym: var Symbol) {.exportc, dynlib.} = + if sym.name == "_Kernel": + sym.name = "uKernel" + else: + sym.name = sym.name.strip(chars={'_'}) \ No newline at end of file From b2de34328a92c6c9a63e3db12d4f78e7e5831d8c Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Sun, 12 Apr 2020 23:12:38 -0500 Subject: [PATCH 377/593] No explicit imports for cPluginPath --- nimterop/cimport.nim | 16 ++++++++++------ tests/tnimterop_c_plugin.nim | 2 ++ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index 69aaf90..382c034 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -268,12 +268,12 @@ proc cSkipSymbol*(skips: seq[string]) {.compileTime.} = static: cSkipSymbol @["proc1", "Type2"] gStateCT.symOverride.add skips -proc cPluginHelper(body: string) = +proc cPluginHelper(body: string, imports = "import macros, nimterop/plugin\n\n") = gStateCT.pluginSource = body if gStateCT.pluginSource.nBl or gStateCT.overrides.nBl: let - data = "import macros, nimterop/plugin\n\n" & body & "\n\n" & gStateCT.overrides + data = imports & body & "\n\n" & gStateCT.overrides hash = data.hash().abs() path = getProjectCacheDir("cPlugins", forceClean = false) / "nimterop_" & $hash & ".nim" @@ -347,14 +347,18 @@ macro cPluginPath*(path: static[string]): untyped = ## preferable to have it stored in a separate source file. This allows for reuse ## across multiple wrappers when applicable. ## - ## The `cPluginPath()` macro enables this functionality - provide a path to the + ## The `cPluginPath()` macro enables this functionality - specify the path to the ## plugin file and it will be consumed in the same way as `cPlugin()`. ## ## `path` is relative to the current dir and not necessarily relative to the - ## location of the wrapper file. Use `currentSourcePath.parentDir()` to specify - ## path relative to the wrapper file. + ## location of the wrapper file. Use `currentSourcePath` to specify a path relative + ## to the wrapper file. + ## + ## Unlike `cPlugin()`, this macro also does not implicitly import any other modules + ## since the standalone plugin file will need explicit imports for `nim check` and + ## suggestions to work. `import nimterop/plugin` is required for all plugins. doAssert fileExists(path), "Plugin file not found: " & path - cPluginHelper(readFile(path)) + cPluginHelper(readFile(path), imports = "") proc cSearchPath*(path: string): string {.compileTime.}= ## Get full path to file or directory `path` in search path configured diff --git a/tests/tnimterop_c_plugin.nim b/tests/tnimterop_c_plugin.nim index 68bb4d6..90ac2ab 100644 --- a/tests/tnimterop_c_plugin.nim +++ b/tests/tnimterop_c_plugin.nim @@ -1,3 +1,5 @@ +import nimterop/plugin + import strutils proc onSymbol*(sym: var Symbol) {.exportc, dynlib.} = From f23d17d0b2f2e6bd66b0d685461d9dd1c2070918 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 13 Apr 2020 10:18:49 -0500 Subject: [PATCH 378/593] Fix #185 - forward decl symbol change --- nimterop/ast2.nim | 11 +++++++++-- tests/include/tast2.h | 16 ++++++++++++++++ tests/tast2.nim | 16 +++++++++++----- 3 files changed, 36 insertions(+), 7 deletions(-) diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index ed7c2a9..708b473 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -811,9 +811,16 @@ proc addTypeObject(nimState: NimState, node: TSNode, typeDef: PNode = nil, fname if not fdlist.isNil and fdlist.len > 0: # Current node has fields let - name = nimState.getNodeVal(node.getAtom()) + origname = nimState.getNodeVal(node.getAtom()) - if nimState.identifierNodes.hasKey(name): + # Fix issue #185 + name = + if origname.nBl: + nimState.getIdentifier(origname, nskType) + else: + "" + + if name.nBl and nimState.identifierNodes.hasKey(name): let def = nimState.identifierNodes[name] # Duplicate nkTypeDef for `name` with empty fields diff --git a/tests/include/tast2.h b/tests/include/tast2.h index 4854eb7..76aadc9 100644 --- a/tests/include/tast2.h +++ b/tests/include/tast2.h @@ -162,6 +162,14 @@ struct GPU_Target char *x, y, **z; }; +// Issue #185 +struct SDL_AudioCVT; + +typedef struct SDL_AudioCVT +{ + int needed; +} SDL_AudioCVT; + // DUPLICATES @@ -318,6 +326,14 @@ struct GPU_Target char *x, y, **z; }; +// Issue #185 +struct SDL_AudioCVT; + +typedef struct SDL_AudioCVT +{ + int needed; +} SDL_AudioCVT; + #endif diff --git a/tests/tast2.nim b/tests/tast2.nim index de0e743..4741062 100644 --- a/tests/tast2.nim +++ b/tests/tast2.nim @@ -32,7 +32,7 @@ cOverride: type A1* = A0 -cImport(path, flags="-f:ast2 -ENK_" & flags) +cImport(path, flags="-f:ast2 -ENK_,SDL_" & flags) proc getPragmas(n: NimNode): HashSet[string] = # Find all pragmas in AST, return as "name" or "name:value" in set @@ -57,7 +57,8 @@ proc getRecList(n: NimNode): NimNode = if not rl.isNil: return rl -macro checkPragmas(t: typed, pragmas: static[seq[string]], istype: static[bool] = true): untyped = +macro checkPragmas(t: typed, pragmas: static[seq[string]], istype: static[bool] = true, + prefix: static[string] = ""): untyped = # Verify that type has expected pragmas defined # `istype` is true when typedef X var @@ -67,9 +68,9 @@ macro checkPragmas(t: typed, pragmas: static[seq[string]], istype: static[bool] when defined(HEADER): if not istype: if "union" in exprag: - exprag.incl "importc:union " & $t + exprag.incl "importc:union " & $prefix & $t else: - exprag.incl "importc:struct " & $t + exprag.incl "importc:struct " & $prefix & $t doAssert symmetricDifference(prag, exprag).len == 0, "\nWrong number of pragmas in " & $t & "\n" & $prag & " vs " & $exprag @@ -361,4 +362,9 @@ checkPragmas(BASS_DEVICEINFO, pHeaderImpBy) # Issue #183 assert GPU_Target is object testFields(GPU_Target, "w|h|x|y|z!cint|ptr cint|cstring|cchar|ptr cstring") -checkPragmas(GPU_Target, pHeaderBy, istype = false) \ No newline at end of file +checkPragmas(GPU_Target, pHeaderBy, istype = false) + +# Issue #185 +assert AudioCVT is object +testFields(AudioCVT, "needed!cint") +checkPragmas(AudioCVT, pHeaderBy, istype = false, "SDL_") \ No newline at end of file From 08306b98020d5dcfd513b515f7955d44cfef1d6b Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 13 Apr 2020 20:18:37 -0500 Subject: [PATCH 379/593] Fix #172 - skip qualifiers --- nimterop.nimble | 2 +- nimterop/getters.nim | 18 ++++++++++++++++-- tests/include/tast2.h | 10 ++++++++++ tests/tast2.nim | 7 ++++++- 4 files changed, 33 insertions(+), 4 deletions(-) diff --git a/nimterop.nimble b/nimterop.nimble index cd36e1c..9600faa 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -23,7 +23,7 @@ proc execTest(test: string, flags = "") = execCmd "nim cpp --hints:off " & flags & " -r " & test task buildToast, "build toast": - execCmd("nim c --hints:off -f nimterop/toast.nim") + execCmd("nim c --hints:off nimterop/toast.nim") task bt, "build toast": execCmd("nim c --hints:off -d:danger nimterop/toast.nim") diff --git a/nimterop/getters.nim b/nimterop/getters.nim index e47113d..76b528d 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -234,7 +234,14 @@ proc getAtom*(node: TSNode): TSNode = if node.getName() in gAtoms: return node elif node.len() != 0: - return node[0].getAtom() + if node[0].getName() == "type_qualifier": + # Skip const, volatile + if node.len() > 1: + return node[1].getAtom() + else: + return + else: + return node[0].getAtom() proc getStartAtom*(node: TSNode): int = if not node.isNil: @@ -256,7 +263,14 @@ proc getXCount*(node: TSNode, ntype: string, reverse = false): int = cnode = cnode.tsNodeParent() else: if cnode.len() != 0: - cnode = cnode[0] + if cnode[0].getName() == "type_qualifier": + # Skip const, volatile + if cnode.len() > 1: + cnode = cnode[1] + else: + break + else: + cnode = cnode[0] else: break diff --git a/tests/include/tast2.h b/tests/include/tast2.h index 76aadc9..136784a 100644 --- a/tests/include/tast2.h +++ b/tests/include/tast2.h @@ -170,6 +170,11 @@ typedef struct SDL_AudioCVT int needed; } SDL_AudioCVT; +// Issue #172 +typedef struct { + const char* const* x; +} SomeType; + // DUPLICATES @@ -334,6 +339,11 @@ typedef struct SDL_AudioCVT int needed; } SDL_AudioCVT; +// Issue #172 +typedef struct { + const char* const* x; +} SomeType; + #endif diff --git a/tests/tast2.nim b/tests/tast2.nim index 4741062..6d749c6 100644 --- a/tests/tast2.nim +++ b/tests/tast2.nim @@ -367,4 +367,9 @@ checkPragmas(GPU_Target, pHeaderBy, istype = false) # Issue #185 assert AudioCVT is object testFields(AudioCVT, "needed!cint") -checkPragmas(AudioCVT, pHeaderBy, istype = false, "SDL_") \ No newline at end of file +checkPragmas(AudioCVT, pHeaderBy, istype = false, "SDL_") + +# Issue #172 +assert SomeType is object +testFields(SomeType, "x!ptr cstring") +checkPragmas(SomeType, pHeaderImpBy) \ No newline at end of file From 92fe90f834b1afc1098d4ed63760ca811ab48484 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 14 Apr 2020 19:40:46 -0500 Subject: [PATCH 380/593] ast2 nested struct support --- nimterop.nimble | 2 +- nimterop/ast2.nim | 77 +++++++++++++++++++++++++++++++++++++------- nimterop/getters.nim | 28 ++++++++-------- nimterop/lisp.nim | 2 +- 4 files changed, 82 insertions(+), 27 deletions(-) diff --git a/nimterop.nimble b/nimterop.nimble index 9600faa..37c395d 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -29,7 +29,7 @@ task bt, "build toast": execCmd("nim c --hints:off -d:danger nimterop/toast.nim") task btd, "build toast": - execCmd("nim c -g --hints:off nimterop/toast.nim") + execCmd("nim c -g nimterop/toast.nim") task docs, "Generate docs": buildDocs(@["nimterop/all.nim"], "build/htmldocs") diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index 708b473..8dba84a 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -495,10 +495,12 @@ proc newArrayTree(nimState: NimState, node: TSNode, typ, size: PNode = nil): PNo proc getTypeArray(nimState: NimState, node, tnode: TSNode, name: string): PNode proc getTypeProc(nimState: NimState, name: string, node, rnode: TSNode): PNode -iterator newIdentDefs(nimState: NimState, name: string, node: TSNode, offset: SomeInteger, exported = false): PNode = +iterator newIdentDefs(nimState: NimState, name: string, node: TSNode, offset: SomeInteger, ftname = "", exported = false): PNode = # Create nkIdentDefs tree for specified proc parameter or object field # - # For proc, param should not be exported + # For proc, param should not be `exported` + # + # If `ftname` is set, use it as the type name # # pname: [ptr ..] typ # @@ -531,7 +533,15 @@ iterator newIdentDefs(nimState: NimState, name: string, node: TSNode, offset: So start = getStartAtom(node) # node[start] - param type - (tname, _, tinfo) = nimState.getNameInfo(node[start].getAtom(), nskType, parent = name) + (tname0, _, tinfo) = nimState.getNameInfo(node[start].getAtom(), nskType, parent = name) + + # Override type name + tname = + if ftname.nBl: + ftname + else: + tname0 + tident = nimState.getIdent(tname, tinfo, exported = false) if start == node.len - 1: @@ -676,6 +686,7 @@ proc newProcTy(nimState: NimState, name: string, node: TSNode, rtyp: PNode): PNo result.add nimState.newFormalParams(name, node, rtyp) result.add nimState.newPragma(node, nimState.gState.convention) +proc processNode(nimState: NimState, node: TSNode): bool proc newRecListTree(nimState: NimState, name: string, node: TSNode): PNode = # Create nkRecList tree for specified object if not node.isNil: @@ -691,8 +702,34 @@ proc newRecListTree(nimState: NimState, name: string, node: TSNode): PNode = for i in 0 ..< node.len: if node[i].getName() == "field_declaration": + # Check for nested structs / unions / enums + let + fdecl = node[i].anyChildInTree("field_declaration_list") + edecl = node[i].anyChildInTree("enumerator_list") + + # `tname` is name of nested struct / union / enum just + # added, passed on as type name for field in `newIdentDefs()` + (processed, tname) = + if not fdecl.isNil: + # Nested struct / union + ( + nimState.processNode(fdecl.tsNodeParent()), + nimState.typeSection[^1].getIdentName() + ) + elif not edecl.isNil: + # Nested enum + ( + nimState.processNode(edecl.tsNodeParent()), + $nimState.enumSection[^1][0][1] + ) + else: + (true, "") + + if not processed: + return nil + # Add nkIdentDefs for each field - for field in nimState.newIdentDefs(name, node[i], i, exported = true): + for field in nimState.newIdentDefs(name, node[i], i, ftname = tname, exported = true): if not field.isNil: result.add field @@ -722,6 +759,16 @@ proc addTypeObject(nimState: NimState, node: TSNode, typeDef: PNode = nil, fname pragmas + fname = + if not node.firstChildInTree("field_declaration_list").isNil and + node.tsNodeParent().getName() == "field_declaration": + # If nested struct / union without a name + nimState.getUniqueIdentifier( + if union: "Union" else: "Type" + ) + else: + fname + typeDefExisting = not typeDef.isNil typeDef = @@ -784,7 +831,11 @@ proc addTypeObject(nimState: NimState, node: TSNode, typeDef: PNode = nil, fname if not fdlist.isNil and fdlist.len > 0: # Add fields to object if present - obj.add nimState.newRecListTree(name, fdlist) + let + fields = nimState.newRecListTree(name, fdlist) + if fields.isNil: + return + obj.add fields else: obj.add newNode(nkEmpty) @@ -828,7 +879,11 @@ proc addTypeObject(nimState: NimState, node: TSNode, typeDef: PNode = nil, fname def[2].kind == nkObjectTy and def[2].len == 3 and def[2][2].kind == nkEmpty: # Add fields to existing object - def[2][2] = nimState.newRecListTree(name, fdlist) + let + fields = nimState.newRecListTree(name, fdlist) + if fields.isNil: + return + def[2][2] = fields # Change incompleteStruct to bycopy pragma if def[0].kind == nkPragmaExpr and def[0].len == 2 and @@ -1180,7 +1235,7 @@ proc addType(nimState: NimState, node: TSNode, union = false) = let fdecl = node[1].anyChildInTree("function_declarator") adecl = node[1].anyChildInTree("array_declarator") - if fdlist.isNil(): + if fdlist.isNil: if adecl.isNil and fdecl.isNil: # typedef X Y; # typedef X *Y; @@ -1605,18 +1660,18 @@ proc searchTree(nimState: NimState, root: TSNode) = processed = false while true: - if not node.isNil() and depth > -1: + if not node.isNil and depth > -1: processed = nimState.processNode(node) else: break - if not processed and node.len() != 0: + if not processed and node.len != 0: nextnode = node[0] depth += 1 else: nextnode = node.tsNodeNextNamedSibling() - if nextnode.isNil(): + if nextnode.isNil: while true: node = node.tsNodeParent() depth -= 1 @@ -1624,7 +1679,7 @@ proc searchTree(nimState: NimState, root: TSNode) = break if node == root: break - if not node.tsNodeNextNamedSibling().isNil(): + if not node.tsNodeNextNamedSibling().isNil: node = node.tsNodeNextNamedSibling() break else: diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 76b528d..aeefbd8 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -214,7 +214,7 @@ proc len*(node: TSNode): int = result = node.tsNodeNamedChildCount().int proc `[]`*(node: TSNode, i: SomeInteger): TSNode = - if i < node.len(): + if i < node.len: result = node.tsNodeNamedChild(i.uint32) proc getName*(node: TSNode): string {.inline.} = @@ -233,10 +233,10 @@ proc getAtom*(node: TSNode): TSNode = # Get child node which is topmost atom if node.getName() in gAtoms: return node - elif node.len() != 0: + elif node.len != 0: if node[0].getName() == "type_qualifier": # Skip const, volatile - if node.len() > 1: + if node.len > 1: return node[1].getAtom() else: return @@ -262,10 +262,10 @@ proc getXCount*(node: TSNode, ntype: string, reverse = false): int = if reverse: cnode = cnode.tsNodeParent() else: - if cnode.len() != 0: + if cnode.len != 0: if cnode[0].getName() == "type_qualifier": # Skip const, volatile - if cnode.len() > 1: + if cnode.len > 1: cnode = cnode[1] else: break @@ -285,7 +285,7 @@ proc getDeclarator*(node: TSNode): TSNode = # Return if child is a function or array declarator if node.getName() in ["function_declarator", "array_declarator"]: return node - elif node.len() != 0: + elif node.len != 0: return node[0].getDeclarator() proc firstChildInTree*(node: TSNode, ntype: string): TSNode = @@ -307,7 +307,7 @@ proc anyChildInTree*(node: TSNode, ntype: string): TSNode = for i in 0 ..< cnode.len: let ccnode = cnode[i].anyChildInTree(ntype) - if not ccnode.isNil(): + if not ccnode.isNil: return ccnode if cnode != node: cnode = cnode.tsNodeNextNamedSibling() @@ -326,7 +326,7 @@ proc mostNestedChildInTree*(node: TSNode): TSNode = proc inChildren*(node: TSNode, ntype: string): bool = # Search for node type in immediate children result = false - for i in 0 ..< node.len(): + for i in 0 ..< node.len: if (node[i]).getName() == ntype: result = true break @@ -342,7 +342,7 @@ proc getLineCol*(gState: State, node: TSNode): tuple[line, col: int] = result.col += 1 proc getTSNodeNamedChildCountSansComments*(node: TSNode): int = - for i in 0 ..< node.len(): + for i in 0 ..< node.len: if node.getName() != "comment": result += 1 @@ -352,11 +352,11 @@ proc getPxName*(node: TSNode, offset: int): string = np = node count = 0 - while not np.isNil() and count < offset: + while not np.isNil and count < offset: np = np.tsNodeParent() count += 1 - if count == offset and not np.isNil(): + if count == offset and not np.isNil: return np.getName() proc printLisp*(gState: State, root: TSNode): string = @@ -366,7 +366,7 @@ proc printLisp*(gState: State, root: TSNode): string = depth = 0 while true: - if not node.isNil() and depth > -1: + if not node.isNil and depth > -1: result &= spaces(depth) let (line, col) = gState.getLineCol(node) @@ -386,7 +386,7 @@ proc printLisp*(gState: State, root: TSNode): string = result &= ")\n" nextnode = node.tsNodeNextNamedSibling() - if nextnode.isNil(): + if nextnode.isNil: while true: node = node.tsNodeParent() depth -= 1 @@ -395,7 +395,7 @@ proc printLisp*(gState: State, root: TSNode): string = result &= spaces(depth) & ")\n" if node == root: break - if not node.tsNodeNextNamedSibling().isNil(): + if not node.tsNodeNextNamedSibling().isNil: node = node.tsNodeNextNamedSibling() break else: diff --git a/nimterop/lisp.nim b/nimterop/lisp.nim index fb488d8..8287cf5 100644 --- a/nimterop/lisp.nim +++ b/nimterop/lisp.nim @@ -35,7 +35,7 @@ proc readFromTokens(): ref Ast = idx += 2 while gTokens[idx] != ")": var res = readFromTokens() - if not res.isNil(): + if not res.isNil: result.children.add(res) elif gTokens[idx] == ")": doAssert false, "Poor AST " & $(idx: idx) From 25b07a07fff0c15ddae2610016289368fe41f3e2 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 14 Apr 2020 22:47:33 -0500 Subject: [PATCH 381/593] ast2 nested array field --- nimterop/ast2.nim | 23 ++++++++++---------- tests/include/tast2.h | 46 ++++++++++++++++++++++++++++++++++++++++ tests/tast2.nim | 49 ++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 105 insertions(+), 13 deletions(-) diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index 8dba84a..5bb33ae 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -73,7 +73,7 @@ proc getOverrideOrSkip(nimState: NimState, node: TSNode, origname: string, kind: # If not, symbol needs to be skipped - only get here if `name` is blank let # Get cleaned name for symbol, set parent so that cOverride is ignored - name = nimState.getIdentifier(origname, kind, parent = "override") + name = nimState.getIdentifier(origname, kind, parent = "getOverrideOrSkip") override = nimState.getOverride(origname, kind) @@ -492,7 +492,7 @@ proc newArrayTree(nimState: NimState, node: TSNode, typ, size: PNode = nil): PNo result.add size result.add typ -proc getTypeArray(nimState: NimState, node, tnode: TSNode, name: string): PNode +proc getTypeArray(nimState: NimState, node: TSNode, tident: PNode, name: string): PNode proc getTypeProc(nimState: NimState, name: string, node, rnode: TSNode): PNode iterator newIdentDefs(nimState: NimState, name: string, node: TSNode, offset: SomeInteger, ftname = "", exported = false): PNode = @@ -637,7 +637,7 @@ iterator newIdentDefs(nimState: NimState, name: string, node: TSNode, offset: So (pname, _, pinfo) = nimState.getNameInfo(node[i].getAtom(), nskField, parent = name) pident = nimState.getIdent(pname, pinfo, exported) result.add pident - result.add nimState.getTypeArray(node[i], node[start], name) + result.add nimState.getTypeArray(node[i], tident, name) result.add newNode(nkEmpty) else: result = nil @@ -958,13 +958,11 @@ proc addTypeTyped(nimState: NimState, node: TSNode, ftname = "", offset = 0) = else: nimState.addTypeObject(node, typeDef = typeDef, istype = true) -proc getTypeArray(nimState: NimState, node, tnode: TSNode, name: string): PNode = +proc getTypeArray(nimState: NimState, node: TSNode, tident: PNode, name: string): PNode = # Create array type tree + # + # `tident` is type PNode let - # tnode = identifier = type name - (tname, _, info) = nimState.getNameInfo(tnode.getAtom(), nskType, parent = name) - ident = nimState.getIdent(tname, info, exported = false) - # Top-most array declarator adecl = node.firstChildInTree("array_declarator") @@ -990,7 +988,7 @@ proc getTypeArray(nimState: NimState, node, tnode: TSNode, name: string): PNode # ) ncount = innermost[0].getAtom().tsNodeParent().getPtrCount(reverse = true) - result = ident + result = tident var cnode = adecl @@ -1021,8 +1019,9 @@ proc addTypeArray(nimState: NimState, node: TSNode) = let start = getStartAtom(node) - # node[start] = type name - tnode = node[start] + # node[start] = identifier = type name + (tname, _, info) = nimState.getNameInfo(node[start].getAtom(), nskType, parent = "addTypeArray") + tident = nimState.getIdent(tname, info, exported = false) # Could have multiple types, comma separated for i in start+1 ..< node.len: @@ -1033,7 +1032,7 @@ proc addTypeArray(nimState: NimState, node: TSNode) = if not typeDef.isNil: let name = typeDef.getIdentName() - typ = nimState.getTypeArray(node[i], tnode, name) + typ = nimState.getTypeArray(node[i], tident, name) typeDef.add typ diff --git a/tests/include/tast2.h b/tests/include/tast2.h index 136784a..fe78146 100644 --- a/tests/include/tast2.h +++ b/tests/include/tast2.h @@ -175,6 +175,29 @@ typedef struct { const char* const* x; } SomeType; +// Nested #137 +typedef struct { + struct NT1 { int f1; } f1; + struct { int f1; } f2; + + struct NT3 { + struct { + int f1; + union NU1 { + float f1; + } f2; + enum { NEV1, NEV2, NEV3 } f3; + } f1; + } f3; + + struct { int f1; } f4; + + union NU2 { int f1; } f5; + union { int f1; } f6; + enum NE1 { NEV4 = 8, NEV5 } f7; + enum { NEV6 = 8 * 8, NEV7 } f8; +} nested; + // DUPLICATES @@ -344,6 +367,29 @@ typedef struct { const char* const* x; } SomeType; +// Nested #137 +typedef struct { + struct NT1 { int f1; } f1; + struct { int f1; } f2; + + struct NT3 { + struct { + int f1; + union NU1 { + float f1; + } f2; + enum { NEV1, NEV2, NEV3 } f3; + } f1; + } f3; + + struct { int f1; } f4; + + union NU2 { int f1; } f5; + union { int f1; } f6; + enum NE1 { NEV4 = 8, NEV5 } f7; + enum { NEV6 = 8 * 8, NEV7 } f8; +} nested; + #endif diff --git a/tests/tast2.nim b/tests/tast2.nim index 6d749c6..46101d5 100644 --- a/tests/tast2.nim +++ b/tests/tast2.nim @@ -372,4 +372,51 @@ checkPragmas(AudioCVT, pHeaderBy, istype = false, "SDL_") # Issue #172 assert SomeType is object testFields(SomeType, "x!ptr cstring") -checkPragmas(SomeType, pHeaderImpBy) \ No newline at end of file +checkPragmas(SomeType, pHeaderImpBy) + +# Nested #137 +assert NT1 is object +testFields(NT1, "f1!cint") +checkPragmas(NT1, pHeaderBy, istype = false) + +assert Type_tast2h1 is object +testFields(Type_tast2h1, "f1!cint") +checkPragmas(Type_tast2h1, pHeaderBy, istype = false) + +assert NU1 is object +testFields(NU1, "f1!cfloat") +checkPragmas(NU1, pHeaderBy & @["union"], istype = false) + +assert NEV1 == 0 +assert NEV2 == 1 +assert NEV3 == 2 + +assert Type_tast2h2 is object +testFields(Type_tast2h2, "f1|f2|f3!cint|NU1|Enum_tast2h1") +checkPragmas(Type_tast2h2, pHeaderBy, istype = false) + +assert NT3 is object +testFields(NT3, "f1!Type_tast2h2") +checkPragmas(NT3, pHeaderBy, istype = false) + +assert Type_tast2h3 is object +testFields(Type_tast2h3, "f1!cint") +checkPragmas(Type_tast2h3, pHeaderBy, istype = false) + +assert NU2 is object +testFields(NU2, "f1!cint") +checkPragmas(NU2, pHeaderBy & @["union"], istype = false) + +assert Union_tast2h1 is object +testFields(Union_tast2h1, "f1!cint") +checkPragmas(Union_tast2h1, pHeaderBy & @["union"], istype = false) + +assert NEV4 == 8 +assert NEV5 == 9 + +assert NEV6 == 64 +assert NEV7 == 65 + +assert nested is object +testFields(nested, "f1|f2|f3|f4|f5|f6|f7|f8!NT1|Type_tast2h1|NT3|Type_tast2h3|NU2|Union_tast2h1|NE1|Enum_tast2h2") +checkPragmas(nested, pHeaderImpBy) \ No newline at end of file From 6d08f6ed80ab1195b4d233a82f578d93c8611382 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 15 Apr 2020 12:47:30 -0500 Subject: [PATCH 382/593] Fix enum size to cint --- nimterop/types.nim | 47 ++++++++++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 20 deletions(-) diff --git a/nimterop/types.nim b/nimterop/types.nim index 5209e7a..38f95d1 100644 --- a/nimterop/types.nim +++ b/nimterop/types.nim @@ -22,14 +22,20 @@ type va_list* {.importc, header:"".} = object template enumOp*(op, typ, typout) = - proc op*(x: typ, y: int): typout {.borrow.} - proc op*(x: int, y: typ): typout {.borrow.} + proc op*(x: typ, y: cint): typout {.borrow.} + proc op*(x: cint, y: typ): typout {.borrow.} proc op*(x, y: typ): typout {.borrow.} -template defineEnum*(typ) = - type - typ* = distinct int + proc op*(x: typ, y: int): typout = op(x, y.cint) + proc op*(x: int, y: typ): typout = op(x.cint, y) +template defineEnum*(typ) = + # Create a `distinct cint` type for C enums since Nim enums + # need to be in order and cannot have duplicates. + type + typ* = distinct cint + + # Enum operations allowed enumOp(`+`, typ, typ) enumOp(`-`, typ, typ) enumOp(`*`, typ, typ) @@ -39,29 +45,30 @@ template defineEnum*(typ) = enumOp(`div`, typ, typ) enumOp(`mod`, typ, typ) - proc `shl`*(x: typ, y: int): typ {.borrow.} - proc `shl`*(x: int, y: typ): typ {.borrow.} + # These don't work with `enumOp()` for some reason + proc `shl`*(x: typ, y: cint): typ {.borrow.} + proc `shl`*(x: cint, y: typ): typ {.borrow.} proc `shl`*(x, y: typ): typ {.borrow.} - proc `shr`*(x: typ, y: int): typ {.borrow.} - proc `shr`*(x: int, y: typ): typ {.borrow.} + proc `shr`*(x: typ, y: cint): typ {.borrow.} + proc `shr`*(x: cint, y: typ): typ {.borrow.} proc `shr`*(x, y: typ): typ {.borrow.} - proc `or`*(x: typ, y: int): typ {.borrow.} - proc `or`*(x: int, y: typ): typ {.borrow.} + proc `or`*(x: typ, y: cint): typ {.borrow.} + proc `or`*(x: cint, y: typ): typ {.borrow.} proc `or`*(x, y: typ): typ {.borrow.} - proc `and`*(x: typ, y: int): typ {.borrow.} - proc `and`*(x: int, y: typ): typ {.borrow.} + proc `and`*(x: typ, y: cint): typ {.borrow.} + proc `and`*(x: cint, y: typ): typ {.borrow.} proc `and`*(x, y: typ): typ {.borrow.} - proc `xor`*(x: typ, y: int): typ {.borrow.} - proc `xor`*(x: int, y: typ): typ {.borrow.} + proc `xor`*(x: typ, y: cint): typ {.borrow.} + proc `xor`*(x: cint, y: typ): typ {.borrow.} proc `xor`*(x, y: typ): typ {.borrow.} - proc `/`(x, y: typ): typ = - return (x.float / y.float).int.typ - proc `/`*(x: typ, y: int): typ = `/`(x, y.typ) - proc `/`*(x: int, y: typ): typ = `/`(x.typ, y) + proc `/`*(x, y: typ): typ = + return (x.float / y.float).cint.typ + proc `/`*(x: typ, y: cint): typ = `/`(x, y.typ) + proc `/`*(x: cint, y: typ): typ = `/`(x.typ, y) - proc `$` *(x: typ): string {.borrow.} + proc `$`*(x: typ): string {.borrow.} From 6a9a35db61e1e47652fa667ff557555e87a6edeb Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 15 Apr 2020 23:42:22 -0500 Subject: [PATCH 383/593] ast2 varargs support --- nimterop/ast2.nim | 11 +++++++++++ nimterop/getters.nim | 14 ++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index 5bb33ae..554c507 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -686,6 +686,10 @@ proc newProcTy(nimState: NimState, name: string, node: TSNode, rtyp: PNode): PNo result.add nimState.newFormalParams(name, node, rtyp) result.add nimState.newPragma(node, nimState.gState.convention) + # Add varargs if ... + if node.getVarargs(): + nimState.addPragma(node, result[^1], "varargs") + proc processNode(nimState: NimState, node: TSNode): bool proc newRecListTree(nimState: NimState, name: string, node: TSNode): PNode = # Create nkRecList tree for specified object @@ -1582,6 +1586,9 @@ proc addProc(nimState: NimState, node, rnode: TSNode) = # {.impnameC.} shortcut nimState.newPragma(node, nimState.impShort & "C") + # Detect ... and add {.varargs.} + pvarargs = plist.getVarargs() + # Need {.convention.} and {.header.} if applicable if name != origname: if nimState.includeHeader(): @@ -1595,6 +1602,10 @@ proc addProc(nimState: NimState, node, rnode: TSNode) = # {.dynlib.} for DLLs nimState.addPragma(node, prident, "dynlib", nimState.getIdent(nimState.gState.dynlib)) + if pvarargs: + # Add {.varargs.} for ... + nimState.addPragma(node, prident, "varargs") + procDef.add prident procDef.add newNode(nkEmpty) procDef.add newNode(nkEmpty) diff --git a/nimterop/getters.nim b/nimterop/getters.nim index aeefbd8..c971bfc 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -288,6 +288,20 @@ proc getDeclarator*(node: TSNode): TSNode = elif node.len != 0: return node[0].getDeclarator() +proc getVarargs*(node: TSNode): bool = + # Detect ... and add {.varargs.} + # + # `node` is the param list + # + # ... is an unnamed node, second last node and ) is last node + let + nlen = node.tsNodeChildCount() + if nlen > 1: + let + nval = node.tsNodeChild(nlen - 2).getName() + if nval == "...": + result = true + proc firstChildInTree*(node: TSNode, ntype: string): TSNode = # Search for node type in tree - first children var From 281d2609122f0697b060c1608fa8df6b70d8edad Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 16 Apr 2020 08:39:52 -0500 Subject: [PATCH 384/593] Fix Travis, tests for varargs --- nimterop/getters.nim | 4 ++-- tests/include/tast2.h | 8 ++++---- tests/tast2.nim | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/nimterop/getters.nim b/nimterop/getters.nim index c971bfc..6cb7651 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -296,9 +296,9 @@ proc getVarargs*(node: TSNode): bool = # ... is an unnamed node, second last node and ) is last node let nlen = node.tsNodeChildCount() - if nlen > 1: + if nlen > 1.uint32: let - nval = node.tsNodeChild(nlen - 2).getName() + nval = node.tsNodeChild(nlen - 2.uint32).getName() if nval == "...": result = true diff --git a/tests/include/tast2.h b/tests/include/tast2.h index fe78146..1c1e935 100644 --- a/tests/include/tast2.h +++ b/tests/include/tast2.h @@ -109,7 +109,7 @@ typedef enum VSPresetFormat { // Proc vars void - *(*pcre_malloc)(size_t), + *(*pcre_malloc)(size_t, ...), (*pcre_free)(void *), *(*pcre_stack_malloc)(size_t); @@ -144,7 +144,7 @@ struct ucArrType2 { }; typedef struct fieldfuncfunc { - int *(*func1)(int f1, int *(*sfunc1)(int f1, int *(*ssfunc1)(int f1))); + int *(*func1)(int f1, int *(*sfunc1)(int f1, int *(*ssfunc1)(int f1, ...))); }; int *func2(int f1, int *(*sfunc2)(int f1, int *(*ssfunc2)(int f1))); @@ -311,7 +311,7 @@ typedef enum VSPresetFormat { // Proc vars void - *(*pcre_malloc)(size_t), + *(*pcre_malloc)(size_t, ...), (*pcre_free)(void *), *(*pcre_stack_malloc)(size_t); @@ -336,7 +336,7 @@ void int sqlite3_bind_blob(struct A1*, int, const void*, int n, void(*)(void*)); typedef struct fieldfuncfunc { - int *(*func1)(int f1, int *(*sfunc1)(int f1, int *(*ssfunc1)(int f1))); + int *(*func1)(int f1, int *(*sfunc1)(int f1, int *(*ssfunc1)(int f1, ...))); }; int *func2(int f1, int *(*sfunc2)(int f1, int *(*ssfunc2)(int f1))); diff --git a/tests/tast2.nim b/tests/tast2.nim index 46101d5..c49c008 100644 --- a/tests/tast2.nim +++ b/tests/tast2.nim @@ -302,8 +302,8 @@ assert pfYUV422P8 == pfYUV420P8 + 1 assert pfRGB27 == cmRGB.VSPresetFormat + 11 assert pfCompatYUY2 == pfCompatBGR32 + 1 -assert pcre_malloc is proc(a1: uint): pointer {.cdecl.} -checkPragmas(pcre_malloc, @["importc", "cdecl"] & pHeader) +assert pcre_malloc is proc(a1: uint): pointer {.cdecl, varargs.} +checkPragmas(pcre_malloc, @["importc", "cdecl", "varargs"] & pHeader) assert pcre_free is proc(a1: pointer) {.cdecl.} checkPragmas(pcre_free, @["importc", "cdecl"] & pHeader) @@ -351,7 +351,7 @@ checkPragmas(ucArrType2, pHeaderBy, istype = false) assert fieldfuncfunc is object testFields(fieldfuncfunc, - "func1!proc (f1: cint; sfunc1: proc (f1: cint; ssfunc1: proc (f1: cint): ptr cint {.cdecl.}): ptr cint {.cdecl.}): ptr cint {.cdecl.}") + "func1!proc (f1: cint; sfunc1: proc (f1: cint; ssfunc1: proc (f1: cint): ptr cint {.cdecl, varargs.}): ptr cint {.cdecl.}): ptr cint {.cdecl.}") assert func2 is proc (f1: cint; sfunc2: proc (f1: cint; ssfunc2: proc (f1: cint): ptr cint {.cdecl.}): ptr cint {.cdecl.}): ptr cint {.cdecl.} From e17d6edb5e87f4a74447d3376438dc0d35d95be8 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Fri, 17 Apr 2020 17:00:11 -0500 Subject: [PATCH 385/593] Update README --- README.md | 168 ++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 125 insertions(+), 43 deletions(-) diff --git a/README.md b/README.md index 18f74ce..3f42211 100644 --- a/README.md +++ b/README.md @@ -6,21 +6,13 @@ Detailed documentation [here](https://nimterop.github.io/nimterop/theindex.html) Nimterop is a [Nim](https://nim-lang.org/) package that aims to make C/C++ interop seamless -Nim has one of the best FFI you can find - importing C/C++ is supported out of the box. All you need to provide is type and proc definitions for Nim to interop with C/C++ binaries. Generation of these wrappers is easy for simple libraries but quickly gets out of hand. [c2nim](https://github.com/nim-lang/c2nim) greatly helps here by parsing and converting C/C++ into Nim but is limited due to the complex and constantly evolving C/C++ grammar. [nimgen](https://github.com/genotrance/nimgen) mainly focuses on automating the wrapping process and fills some holes but is again limited to c2nim's capabilities. - -The goal of nimterop is to leverage the [tree-sitter](http://tree-sitter.github.io/tree-sitter/) engine to parse C/C++ code and then convert relevant portions of the AST into Nim definitions. [tree-sitter](https://github.com/tree-sitter) is a Github sponsored project that can parse a variety of languages into an AST which is then leveraged by the [Atom](https://atom.io/) editor for syntax highlighting and code folding. The advantages of this approach are multifold: -- Benefit from the tree-sitter community's investment into language parsing -- Wrap what is recognized in the AST rather than completely failing due to parsing errors - -Most of the wrapping functionality is contained within the `toast` binary that is built when nimterop is installed and can be used standalone similar to how c2nim can be used today. In addition, nimterop also offers an API to pull in the generated Nim content directly into an application and other nimgen functionality that helps in automating the wrapping process. There is also support to statically or dynamically link to system installed libraries or downloading and building them with `autoconf` or `cmake` from a Git repo or source archive. +Most of the wrapping functionality is contained within the `toast` binary that is built when nimterop is installed and can be used standalone similar to how `c2nim` can be used today. In addition, nimterop also offers an API to pull in the generated Nim content directly into an application and other nimgen functionality that helps in automating the wrapping process. There is also support to statically or dynamically link to system installed libraries or downloading and building them with `autoconf` or `cmake` from a Git repo or source archive. The nimterop wrapping functionality is still limited to C but is constantly expanding. C++ support will be added once most popular C libraries can be wrapped seamlessly. Meanwhile, `c2nim` can also be used in place of `toast` with the `c2nImport()` API call. Nimterop has seen some adoption within the community and the simplicity and success of this approach justifies additional investment of time and effort. Regardless, the goal is to make interop seamless so nimterop will focus on wrapping headers and not the outright conversion of C/C++ implementation. -Also, given tree-sitter can parse a variety of other languages, there might also be value in investigating how to wrap Rust and Go libraries. - -__Installation__ +### Installation Nimterop can be installed via [Nimble](https://github.com/nim-lang/nimble): @@ -34,59 +26,137 @@ nimble develop -y nimble build ``` -This will download and install nimterop in the standard Nimble package location, typically `~/.nimble`. Once installed, it can be imported into any Nim program. Note that the `~/.nimble/bin` directory needs to be added to the `PATH` for nimterop to work. +This will download and install nimterop in the standard Nimble package location, typically `~/.nimble`. Once installed, it can be imported into any Nim program. -__Usage__ +### Usage -Detailed documentation can be found [here](https://nimterop.github.io/nimterop/theindex.html). +Detailed documentation can be found [here](https://nimterop.github.io/nimterop/theindex.html). Also, check out the [wiki](https://github.com/nimterop/nimterop/wiki/Wrappers) for a list of all known wrappers that have been created using nimterop. They will provide real world examples of how to wrap libraries. Please do add your project once you are done so that others can benefit from your work. -Check out the [wiki](https://github.com/nimterop/nimterop/wiki/Wrappers) for a list of all known wrappers that have been created using nimterop. Please do add your project once you are done so that others can benefit from your work. +#### Build API + +Creating a wrapper has two parts, the first is to setup the C library. This includes downloading it or finding it if already installed, and building it if applicable. The `getHeader()` high-level API provides all of this functionality as a convenience. Following is an example of using the high-level `getHeader()` API to perform all building and linking automatically: -Using the high-level `getHeader` API to perform all building and linking automatically: ```nim import nimterop/[build, cimport] static: - cDebug() + cDebug() # Print wrapper to stdout + +const + baseDir = getProjectCacheDir("testwrapper") # Download library within nimcache getHeader( - "header.h", - giturl = "https://github.com/username/repo", - dlurl = "https://website.org/download/repo-$1.tar.gz", - outdir = "build", - conFlags = "--disable-comp --enable-feature" + "header.h", # The header file to wrap, full path is returned in `headerPath` + giturl = "https://github.com/username/repo", # Git repo URL + dlurl = "https://website.org/download/repo-$1.tar.gz", # Download URL for archive or raw file + outdir = baseDir, # Where to download/build/search + conFlags = "--disable-comp --enable-feature", # Flags to pass configure script + cmakeFlags = "-DENABLE_STATIC_LIB=ON" # Flags to pass to Cmake + altNames = "hdr" # Alterate names of the library binary, full path returned in `headerLPath` ) +# Wrap headerPath as returned from getHeader() and link statically +# or dynamically depending on user input when not defined(headerStatic): - cImport(headerPath, recurse = true, dynlib = "headerLPath") + cImport(headerPath, recurse = true, dynlib = "headerLPath") # Pass dynlib if not static link else: cImport(headerPath, recurse = true) ``` -This allows the user to control how the wrapper works - either pass `-d:headerStd` to search for `header.h` in the standard system path, `-d:headerGit` to clone the source from the specified git URL or `-d:headerDL` to get the source from download URL. Further, the `-d:headerSetVer=X.Y.Z` flag can be used to specify which version to use. It is used as the tag name for Git whereas for DL, it replaces `$1` in the URL defined. -The `-d:headerStatic` attempts to statically link the library. If it is omitted, the library is dynamically linked instead. +__Download / Search__ -[lzma.nim](https://github.com/nimterop/nimterop/blob/master/tests/lzma.nim) is an example of a library using this high-level API. +The above wrapper is generic and allows the end user to control how it works. + +- If the library is already installed in `/usr/include` then the `-d:headerStd` define to Nim can be used to instruct `getHeader()` to search for `header.h` in the standard system path. +- If the library needs to be downloaded, the user can use `-d:headerGit` to clone the source from the specified git URL or `-d:headerDL` to get the source from download URL. + - The `-d:headerSetVer=X.Y.Z` flag can be used to specify which version to download. It is used as the tag name for Git whereas for DL, it replaces `$1` in the URL if defined. +- If no flag is provided, `getHeader()` simply looks for the library in `outdir`. The user could use Git submodules or manually download or check-in the library to that directory and `getHeader()` will use it directly. + +__Pre build__ + +`getHeader()` provides a `headerPreBuild()` hook that gets called after the library is downloaded but before it is built. This allows for any manipulations of the source files or build scripts before build. [archive](https://github.com/genotrance/nimarchive/blob/master/nimarchive/archive.nim) has such an example. + +The build API also includes various compile time helper procs that aid in file manipulation, Cmake shortcuts, library linking, etc. Refer to [build](https://nimterop.github.io/nimterop/build.html) for more details. + +__Build__ + +Nimterop currently supports `configure` and `cmake` based building of libraries, with `cmake` taking precedence if a project supports both. Nimterop verifies that the tool selected is available and notifies the user if any issues are found. Bash is required on Windows for `configure` and the binary shipped with Git has been tested. + +Flags can be specified to these tools via `getHeader()` or directly via the underlying `configure()` and `cmake()` calls. Once the build scripts are ready, `getHeader()` then calls `make()`. At every step, `getHeader()` checks for the presence of created artifacts and does not redo steps that have been successfully completed. + +__Linking__ + +- If `-d:headerStatic` is specified, `getHeader()` will return the static library path in `headerLPath`. The wrapper writer can check for this and call `cImport()` accordingly as in the example above. If it is omitted, the dynamic library is returned in `headerLPath`. +- `getHeader()` searches for libraries based on the header name by default: + - `libheader.so` or `libheader.a` on Linux + - `libheader.dylib` on OSX + - `header.dll` or `header.a` on Windows +- If a library has a different header and library binary name, `altNames` can be used to configure an alternate name of library binary. + - For example, Bzip2 has `bzlib.h` but the library is `libbz2.so` so `altNames = "bz2"`. + - In the example above, `altNames = "hdr"` so `getHeader()` will look for `libhdr.so`, `hdr.dll`, etc. + - See [bzlib.nim](https://github.com/genotrance/nimarchive/blob/master/nimarchive/bzlib.nim) for an example. +- [lzma.nim](https://github.com/nimterop/nimterop/blob/master/tests/lzma.nim) is an example of a library that allows both static and dynamic linking. + +__User control__ + +The `-d:xxxYYY` Nim define flags have already been described above and can be specified on the command line or in a nim.cfg file. It is also possible to specify them within the wrapper itself using `setDefines()` if required. Further, all defines, regardless of how they are specified, can be generically checked using `isDefined()`. + +If more fine-tuned control is desired over the build process, it is possible to manually control all steps that `getHeader()` performs by directly using the API provided by [build](https://nimterop.github.io/nimterop/build.html). Note also that there is no requirement to use these APIs to setup the library. Any other established mechanisms can be used to do so any limitations imposed by Nimterop are unintentional and feedback is most welcome. + +#### Wrapper API + +Once the C library is setup, the next step is to create wrappers that inform Nim of all the types and functions that are available. Following is a simple example covering the API: -The traditional approach is to manually compile in the code: ```nim import nimterop/cimport static: cDebug() -cDefine("HAS_ABC") -cDefine("HAS_ABC", "DEF") -cIncludeDir("clib/include") -cImport("clib.h") + cDisableCaching() # Regenerate Nim wrapper every time -cCompile("clib/src/*.c") +cDefine("HAS_ABC") # Set #defines for preprocessor and compiler +cDefine("HAS_ABC", "DEF") + +cIncludeDir("clib/include") # Setup any include directories + +cImport("clib.h") # Generate wrappers for header specified + +cCompile("clib/src/*.c") # Compile in any implementation source files ``` -Check out [template.nim](https://github.com/nimterop/nimterop/blob/master/nimterop/template.nim) as a starting point for wrapping a library using the traditional approach. The template can be copied and trimmed down and modified as required. [templite.nim](https://github.com/nimterop/nimterop/blob/master/nimterop/templite.nim) is a shorter version for more experienced users. +Refer to the ```tests``` directory for additional examples on how the library can be used. The [wiki](https://github.com/nimterop/nimterop/wiki/Wrappers) is also a good source of examples. -Refer to the ```tests``` directory for examples on how the library can be used. +__Preprocessing__ -The `toast` binary can also be used directly on the CLI: +In order to leverage the preprocessor, certain projects might need `cDefine()` calls to set `#define` values. Simpler library may have documentation that cover this but larger ones will rely on build tools that discover and set values in a `config.h` which is loaded with `#include`. Projects might also require some `cIncludeDir()` calls to specify paths to directories that contain other headers. This might be within the library or refer to another library. + +The wrapper API always runs headers through the C preprocessor before wrapping. Details on why are discussed further down. + +By default, the `$CC` environment variable is used for the compiler path. If not found, `toast` defaults to `gcc`. + +__Wrapping__ + +The `cImport()` call invokes the `toast` binary with appropriate command line flags including any `cDefine()` and `cInclude()` parameters configured. The output of `toast` is then pulled into the module as Nim code and printed if `cDebug()` is specified. This allows for an end user to simply import the wrapper into their code and access the library API as Nim types and procs. Output is cached to save time on subsequent runs. It is also possible to just redirect the output to a file and import that instead if preferred. + +The `recurse` flag can be set to enable the recursion capability which runs through all #include files in the header. If the library needs to be dyamically linked using Nim's `dynlib` pragma, the `dynlib = "constName"` attribute can be set to generate wrappers that load the DLL automatically. Without `dynlib`, static link is assumed so it is the user's responsibility to link the library. + +There may be cases where the wrapper generated by `toast` for certain types or procs is not preferred, or may be skipped or altogether wrong due to limitations or bugs. In these instances, the `cOverride()` macro can be used to define consts, types or procs to use in place of the wrapper generated output. `cImport()` will forward this information to `toast` and the values will be inserted in context in the generated wrapper. This allows wrapper authors to work around tool limitations or to improve the wrapper output - say change `ptr X` to `var X` or to create more Nim friendly types or proc signatures. + +Several C libraries also use leading and/or trailing `_` in identifiers and since Nim does not allow this, the `cPlugin()` macro can be used to modify such symbols or `cSkipSymbol()` them altogether. Instead of a full `cPlugin()` section, it might also be preferred to set `flags = "-E_ -F_"` to the `cImport()` call to trim out such characters. These features can also be used to remove common prefixes like `SDL_` to generate a cleaner wrapper. `cPlugin()` is real Nim code though so anything Nim allows is fair game. Note that `cPlugin()` overrides any `-E -F` flags. Also, behind the scenes, `cOverride()` is communicated to `toast` via `cPlugin()`. + +If the same `cPlugin()` is needed in multiple wrapper files, the code can be moved into a standalone file and be used with the `cPluginPath()` call. + +Lastly, `c2nImport()` provides access to calling `c2nim` from the wrapper instead of `toast`. Note that `c2nImport()` does not use any of the above described features like `cPlugin()` and needs to be controlled with the `flags` param. + +__Compiling source__ + +The job of building and compiling the underlying C library is best left to the build mechanism selected by the library author so using `getHeader()` is recommended. For simpler projects with a few `.c` files though, `cCompile()` should be more than enough. It is not recommended for larger projects which heavily rely on functionality offered by build tools. Recreating reliable logic in Nim can be tedious and one can expect minimal support from that author if their tested build mechanism is not used. + +#### Command line API + +The `toast` binary can also be used directly on the CLI, similar to `c2nim`. The `cPlugin()` interface + +Note: unlike the wrapper API, the `-p | --preprocess` flag is not enabled by default but is *highly* recommended. ``` > toast -h @@ -96,17 +166,17 @@ Options: -h, --help print this cligen-erated help --help-syntax advanced: prepend,plurals,.. -k, --check bool false check generated wrapper with compiler - -C=, --convention= string "cdecl" calling convention for wrapped procs - default: cdecl + -C=, --convention= string "cdecl" calling convention for wrapped procs -d, --debug bool false enable debug output -D=, --defines= strings {} definitions to pass to preprocessor -l=, --dynlib= string "" import symbols from library in specified Nim string -f=, --feature= Features {} flags to enable experimental features -H, --includeHeader bool false add {.header.} pragma to wrapper -I=, --includeDirs= strings {} include directory to pass to preprocessor - -m=, --mode= string "cpp" language parser: c or cpp - --nim= string "nim" use a particular Nim executable - default: $PATH/nim + -m=, --mode= string "" language parser: c or cpp + --nim= string "nim" use a particular Nim executable -c, --nocomments bool false exclude top-level comments from output - -o=, --output= string "" file to output content - default: stdout + -o=, --output= string "" file to output content -a, --past bool false print AST output -g, --pgrammar bool false print grammar --pluginSourcePath= string "" nim file to build and load as a plugin @@ -119,15 +189,27 @@ Options: -O=, --symOverride= strings {} skip generating specified symbols ``` -__Implementation Details__ +### Why nimterop -In order to use the tree-sitter C library, it has to be compiled into a separate binary called `toast` (to AST) since the Nim VM doesn't yet support FFI. `toast` takes a C/C++ file and runs it through the tree-sitter API which returns an AST data structure. This can then be printed out to stdout in a Lisp S-Expression format or the relevant Nim wrapper output. This content can be saved to a `.nim` file and imported if so desired. +Nim has one of the best FFI you can find - importing C/C++ is supported out of the box. All you need to provide is type and proc definitions for Nim to interop with C/C++ binaries. Generation of these wrappers is easy for simple libraries but can quickly get out of hand. [c2nim](https://github.com/nim-lang/c2nim) greatly helps here by parsing and converting C/C++ into Nim but is limited due to the complex and constantly evolving C/C++ grammar. [nimgen](https://github.com/genotrance/nimgen) mainly focused on automating the wrapping process with `c2nim` and filled some holes but is again limited to `c2nim` capabilities. -Alternatively, the `cImport()` macro allows easier creation of wrappers in code. It runs `toast` on the specified header file and injects the generated wrapper content into the application at compile time. A few other helper procs are provided to influence this process. Output is cached to save time on subsequent runs. +The goal of nimterop is to leverage the [tree-sitter](http://tree-sitter.github.io/tree-sitter/) engine to parse C/C++ code and then convert relevant portions of the AST into Nim definitions. [tree-sitter](https://github.com/tree-sitter) is a Github sponsored project that can parse a variety of languages into an AST which is then leveraged by the [Atom](https://atom.io/) editor for syntax highlighting and code folding. The advantages of this approach are multifold: +- Benefit from the tree-sitter community's ongoing investment into language parsing +- Wrap what is recognized in the AST rather than completely failing due to parsing errors -`toast` can also be used to run the header through the preprocessor which cleans up the code considerably. Along with the recursion capability which runs through all #include files, one large simpler header file can be created which can then be processed with `toast` or even `c2nim` if so desired. By default, the `$CC` environment variable is used. If not found, `toast` defaults to `gcc`. +The tree-sitter library is limited though - it may fail on some advanced language constructs but is designed to handle them gracefully since it is expected to have bad code while actively typing in an editor. When an error is detected, tree-sitter includes an ERROR node at that location in the AST. At this time, `cImport()` will complain and continue if it encounters any errors. Depending on how severe the errors are, compilation may succeed or fail. Glaring issues will be communicated to the tree-sitter team but their goals may not always align with those of this project. -The tree-sitter library is limited as well - it may fail on some advanced language constructs but is designed to handle them gracefully since it is expected to have bad code while actively typing in an editor. When an error is detected, tree-sitter includes an ERROR node at that location in the AST. At this time, `cImport()` will complain and continue if it encounters any errors. Depending on how severe the errors are, compilation may succeed or fail. Glaring issues will be communicated to the tree-sitter team but their goals may not always align with those of this project. +It is debatable whether a syntax highlighting engine like `tree-sitter` is the most reliable method to convert C code into AST. However, it is lightweight, cross-platform with no dependencies and handles error conditions gracefully. It has produced usable wrappers for C libraries though things could get murky when considering C++ but that will be a topic for another day. Nimterop relies heavily on the preprocessor, as discussed next, so having an engine which can run anywhere has been worth the compromise. Only time will tell though. + +__Preprocessing__ + +The wrapper API always runs headers through the C preprocessor before wrapping, unlike the command line interface where the `-p | --preprocess` flag is not set by default but *highly* recommended. This is because almost all platform, compiler and package discovery is handled by build tools like `configure` and `cmake` which then use preprocessor `#define` values to tweak what C code is applicable for that platform. While parsing preprocessor macros is possible in tools like `toast`, given how dependent the `#ifdef` branches are on values provided by these and many other build tools, preprocessing seems is best left to them than attempting to self-discover or intercept that information. + +Nimterop is still able to wrap most relevant `#define` like numbers and strings thanks to `gcc -E` providing the sufficient detail in its output. Many C libraries also use `#define` templates for some of their user facing API and providing that functionality in Nim is on the Nimterop roadmap. + +The con of this approach of delegating to the preprocessor is that the Nim wrapper generated by Nimterop is no longer portable despite being Nim code. A wrapper rendered on Linux might not work on Windows since some APIs may not be available or inappropriate, integer sizes might be wrong, types could be missing and many other possible issues. But none of this is easily or accurately known at the Nim level since it would require input from the build tools which already work well with the preprocessor or have to be completely reimplemented within Nim. Neither approach that bypasses such build tools would be supported by the library author. + +This is part of the reason why Nimterop provides a wrapper API so that the generation of wrappers is Nim code that can be rendered as part of the build process on the target platform. It helps to think of Nimterop as a build time tool like `cmake` that renders artifacts on the target rather than a tool whose generated artifacts should be checked into source control. Regardless, both the wrapper API and the `toast` command line still allow saving the wrapper output to a file to be stored in source control since it might work well enough for many projects. __Credits__ From 485c2f1ab2436094c28eabd97a3a1c02abcddf82 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Sun, 19 Apr 2020 00:50:14 -0500 Subject: [PATCH 386/593] ast2 static inline support --- nimterop/ast2.nim | 6 ++++++ nimterop/getters.nim | 3 +-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index 554c507..92d9fc8 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -1657,6 +1657,12 @@ proc processNode(nimState: NimState, node: TSNode): bool = nimState.addEnum(node) of "declaration": nimState.addDecl(node) + of "function_definition": + # Handle static inline + let + start = getStartAtom(node) + if node[start+1].getName() == "function_declarator": + nimState.addProc(node[start+1], node[start]) else: # Unknown result = false diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 6cb7651..502ec89 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -568,8 +568,7 @@ proc getPreprocessor*(gState: State, fullpath: string): string = rdata.add line return rdata.join("\n"). replace("__restrict", ""). - replace(re"__attribute__[ ]*\(\(.*?\)\)([ ,;])", "$1"). - removeStatic() + replace(re"__attribute__[ ]*\(\(.*?\)\)([ ,;])", "$1") converter toString*(kind: Kind): string = return case kind: From ab0439e60eab40a4e21d95261a8699690984b6a2 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 20 Apr 2020 12:28:14 -0500 Subject: [PATCH 387/593] ast2 static inline with -H, fix #188, --replace support --- README.md | 1 + nimterop/all.nim | 4 +--- nimterop/ast2.nim | 22 +++++++++++++++++----- nimterop/getters.nim | 9 ++++++++- nimterop/globals.nim | 2 ++ nimterop/toast.nim | 16 ++++++++++++++-- tests/include/tast2.h | 8 ++++++++ tests/tast2.nim | 15 ++++++++++----- 8 files changed, 61 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 3f42211..0036187 100644 --- a/README.md +++ b/README.md @@ -184,6 +184,7 @@ Options: -E=, --prefix= strings {} strip prefix from identifiers -p, --preprocess bool false run preprocessor on header -r, --recurse bool false process #include files + -G=, --replace= strings {} replace X with Y in identifiers, X1=Y1,X2=Y2, @X for regex -s, --stub bool false stub out undefined type references as objects -F=, --suffix= strings {} strip suffix from identifiers -O=, --symOverride= strings {} skip generating specified symbols diff --git a/nimterop/all.nim b/nimterop/all.nim index fef1bdd..6be6d11 100644 --- a/nimterop/all.nim +++ b/nimterop/all.nim @@ -1,7 +1,5 @@ ##[ -Module that should import everything so that `nim doc --project nimtero/all` runs docs on everything. +The following modules are available to users of Nimterop. ]## -# TODO: make sure it does import everything. - import "."/[docs, cimport, build, types, plugin] diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index 92d9fc8..23bf774 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -1636,6 +1636,22 @@ proc addDecl(nimState: NimState, node: TSNode) = # Regular var discard +proc addDef(nimState: NimState, node: TSNode) = + # Wrap static inline definition if {.header.} mode is specified + # + # Without {.header.} the definition will not be available to the C compiler + # and will fail at link time + decho("addDef()") + nimState.printDebug(node) + let + start = getStartAtom(node) + if node[start+1].getName() == "function_declarator": + if nimState.includeHeader(): + nimState.addProc(node[start+1], node[start]) + else: + necho &"\n# proc '$1' skipped - static inline procs require 'includeHeader'" % + nimState.getNodeVal(node[start+1].getAtom()) + proc processNode(nimState: NimState, node: TSNode): bool = result = true @@ -1658,11 +1674,7 @@ proc processNode(nimState: NimState, node: TSNode): bool = of "declaration": nimState.addDecl(node) of "function_definition": - # Handle static inline - let - start = getStartAtom(node) - if node[start+1].getName() == "function_declarator": - nimState.addProc(node[start+1], node[start]) + nimState.addDef(node) else: # Unknown result = false diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 502ec89..798ad24 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -137,6 +137,13 @@ proc getIdentifier*(nimState: NimState, name: string, kind: NimSymKind, parent=" if result.endsWith(str): result = result[0 .. ^(str.len+1)] + # --replace from CLI if specified + for name, value in nimState.gState.replace.pairs: + if name.len > 1 and name[0] == '@': + result = result.replace(re(name[1 .. ^1]), value) + else: + result = result.replace(name, value) + checkIdentifier(result, $kind, parent, name) if result in gReserved or (result == "object" and kind != nskType): @@ -738,6 +745,6 @@ proc loadPlugin*(gState: State, sourcePath: string) = proc expandSymlinkAbs*(path: string): string = try: - result = path.expandSymlink().absolutePath(path.parentDir()).normalizedPath() + result = path.expandFilename().expandSymlink().normalizedPath() except: result = path diff --git a/nimterop/globals.nim b/nimterop/globals.nim index 42f7cb7..47157d8 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -61,6 +61,8 @@ type code*, convention*, dynlib*, mode*, nim*, overrides*, pluginSource*, pluginSourcePath*: string + replace*: OrderedTableRef[string, string] + feature*: seq[Feature] onSymbol*, onSymbolOverride*: OnSymbol diff --git a/nimterop/toast.nim b/nimterop/toast.nim index c3d6a3d..3f886e1 100644 --- a/nimterop/toast.nim +++ b/nimterop/toast.nim @@ -1,4 +1,4 @@ -import os, osproc, strformat, strutils, times +import os, osproc, strformat, strutils, tables, times import "."/treesitter/[api, c, cpp] @@ -67,6 +67,7 @@ proc main( prefix: seq[string] = @[], preprocess = false, recurse = false, + replace: seq[string] = @[], stub = false, suffix: seq[string] = @[], symOverride: seq[string] = @[], @@ -91,6 +92,7 @@ proc main( prefix: prefix, preprocess: preprocess, recurse: recurse, + replace: newOrderedTable[string, string](), suffix: suffix, symOverride: symOverride ) @@ -104,6 +106,14 @@ proc main( gState.prefix = gState.prefix.getSplitComma() gState.suffix = gState.suffix.getSplitComma() + # Replace => Table + for i in replace.getSplitComma(): + let + nv = i.split("=", maxsplit = 1) + name = nv[0] + value = if nv.len == 2: nv[1] else: "" + gState.replace[name] = value + if pluginSourcePath.nBl: gState.loadPlugin(pluginSourcePath) @@ -205,10 +215,11 @@ when isMainModule: "pgrammar": "print grammar", "pluginSourcePath": "nim file to build and load as a plugin", "pnim": "print Nim output", + "prefix": "strip prefix from identifiers", "preprocess": "run preprocessor on header", "recurse": "process #include files", + "replace": "replace X with Y in identifiers, X1=Y1,X2=Y2, @X for regex", "source" : "C/C++ source/header", - "prefix": "strip prefix from identifiers", "stub": "stub out undefined type references as objects", "suffix": "strip suffix from identifiers", "symOverride": "skip generating specified symbols" @@ -229,6 +240,7 @@ when isMainModule: "prefix": 'E', "preprocess": 'p', "recurse": 'r', + "replace": 'G', "stub": 's', "suffix": 'F', "symOverride": 'O' diff --git a/tests/include/tast2.h b/tests/include/tast2.h index 1c1e935..bdf8823 100644 --- a/tests/include/tast2.h +++ b/tests/include/tast2.h @@ -198,6 +198,10 @@ typedef struct { enum { NEV6 = 8 * 8, NEV7 } f8; } nested; +static inline int sitest1(int f1) { + return f1 * 2; +} + // DUPLICATES @@ -390,6 +394,10 @@ typedef struct { enum { NEV6 = 8 * 8, NEV7 } f8; } nested; +static inline int sitest1(int f1) { + return f1 * 2; +} + #endif diff --git a/tests/tast2.nim b/tests/tast2.nim index c49c008..e9d9ced 100644 --- a/tests/tast2.nim +++ b/tests/tast2.nim @@ -32,7 +32,7 @@ cOverride: type A1* = A0 -cImport(path, flags="-f:ast2 -ENK_,SDL_" & flags) +cImport(path, flags="-f:ast2 -ENK_,SDL_ -GVICE=SLICE" & flags) proc getPragmas(n: NimNode): HashSet[string] = # Find all pragmas in AST, return as "name" or "name:value" in set @@ -355,9 +355,10 @@ testFields(fieldfuncfunc, assert func2 is proc (f1: cint; sfunc2: proc (f1: cint; ssfunc2: proc (f1: cint): ptr cint {.cdecl.}): ptr cint {.cdecl.}): ptr cint {.cdecl.} -assert BASS_DEVICEINFO is object -testFields(BASS_DEVICEINFO, "name|driver|flags!cstring|cstring|cint") -checkPragmas(BASS_DEVICEINFO, pHeaderImpBy) +# Test --replace VICE=SLICE +assert BASS_DESLICEINFO is object +testFields(BASS_DESLICEINFO, "name|driver|flags!cstring|cstring|cint") +checkPragmas(BASS_DESLICEINFO, pHeaderImpBy) # Issue #183 assert GPU_Target is object @@ -419,4 +420,8 @@ assert NEV7 == 65 assert nested is object testFields(nested, "f1|f2|f3|f4|f5|f6|f7|f8!NT1|Type_tast2h1|NT3|Type_tast2h3|NU2|Union_tast2h1|NE1|Enum_tast2h2") -checkPragmas(nested, pHeaderImpBy) \ No newline at end of file +checkPragmas(nested, pHeaderImpBy) + +when defined(HEADER): + assert sitest1(5) == 10 + assert sitest1(10) == 20 \ No newline at end of file From e7bf0f61ad3629db7806968526e0f2014bb3a045 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 20 Apr 2020 13:24:57 -0500 Subject: [PATCH 388/593] ast2 fix replace test --- tests/tast2.nim | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/tests/tast2.nim b/tests/tast2.nim index e9d9ced..e13c4ac 100644 --- a/tests/tast2.nim +++ b/tests/tast2.nim @@ -58,7 +58,7 @@ proc getRecList(n: NimNode): NimNode = return rl macro checkPragmas(t: typed, pragmas: static[seq[string]], istype: static[bool] = true, - prefix: static[string] = ""): untyped = + origname: static[string] = ""): untyped = # Verify that type has expected pragmas defined # `istype` is true when typedef X var @@ -68,9 +68,12 @@ macro checkPragmas(t: typed, pragmas: static[seq[string]], istype: static[bool] when defined(HEADER): if not istype: if "union" in exprag: - exprag.incl "importc:union " & $prefix & $t + exprag.incl "importc:union " & $t else: - exprag.incl "importc:struct " & $prefix & $t + exprag.incl "importc:struct " & $t + elif origname.len != 0: + exprag.incl "importc:" & $origname + doAssert symmetricDifference(prag, exprag).len == 0, "\nWrong number of pragmas in " & $t & "\n" & $prag & " vs " & $exprag @@ -358,7 +361,7 @@ assert func2 is proc (f1: cint; sfunc2: proc (f1: cint; ssfunc2: proc (f1: cint) # Test --replace VICE=SLICE assert BASS_DESLICEINFO is object testFields(BASS_DESLICEINFO, "name|driver|flags!cstring|cstring|cint") -checkPragmas(BASS_DESLICEINFO, pHeaderImpBy) +checkPragmas(BASS_DESLICEINFO, pHeaderBy, origname = "BASS_DEVICEINFO") # Issue #183 assert GPU_Target is object @@ -368,7 +371,7 @@ checkPragmas(GPU_Target, pHeaderBy, istype = false) # Issue #185 assert AudioCVT is object testFields(AudioCVT, "needed!cint") -checkPragmas(AudioCVT, pHeaderBy, istype = false, "SDL_") +checkPragmas(AudioCVT, pHeaderBy, origname = "struct SDL_AudioCVT") # Issue #172 assert SomeType is object From 40c8e757aa5188618b7bc8abf3e913b08269dd28 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 20 Apr 2020 19:00:55 -0500 Subject: [PATCH 389/593] Remove expandSymlink --- nimterop/getters.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 798ad24..654c7f3 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -745,6 +745,6 @@ proc loadPlugin*(gState: State, sourcePath: string) = proc expandSymlinkAbs*(path: string): string = try: - result = path.expandFilename().expandSymlink().normalizedPath() + result = path.expandFilename().normalizedPath() except: result = path From 82ca3bd37b1587e3c39708e51ed44375b322c111 Mon Sep 17 00:00:00 2001 From: BarrOff <58253563+BarrOff@users.noreply.github.com> Date: Tue, 21 Apr 2020 06:41:16 +0200 Subject: [PATCH 390/593] Some small compatibility fixes for FreeBSD (#190) --- nimterop/build.nim | 6 +++--- nimterop/cimport.nim | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/nimterop/build.nim b/nimterop/build.nim index cc6dc22..a025dc0 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -358,7 +358,7 @@ proc findFile*(file: string, dir: string, recurse = true, first = false, regex = "nimgrep --filenames --oneline --nocolor $1 \"$2\" $3" elif defined(linux): "find $3 $1 -regextype egrep -regex $2" - elif defined(osx): + elif defined(osx) or defined(FreeBSD): "find -E $3 $1 -regex $2" recursive = "" @@ -754,7 +754,7 @@ proc getNumProcs(): string = getEnv("NUMBER_OF_PROCESSORS").strip() elif defined(linux): execAction("nproc").output.strip() - elif defined(macosx): + elif defined(macosx) or defined(FreeBSD): execAction("sysctl -n hw.ncpu").output.strip() else: "1" @@ -830,7 +830,7 @@ proc buildLibrary(lname, outdir, conFlags, cmakeFlags, makeFlags: string): strin proc getDynlibExt(): string = when defined(windows): result = ".dll" - elif defined(linux): + elif defined(linux) or defined(FreeBSD): result = ".so[0-9.]*" elif defined(macosx): result = ".dylib[0-9.]*" diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index 382c034..52d1892 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -82,7 +82,7 @@ proc getFileDate(fullpath: string): string = &"cmd /c for %a in ({fullpath.sanitizePath}) do echo %~ta" elif defined(Linux): &"stat -c %y {fullpath.sanitizePath}" - elif defined(OSX): + elif defined(OSX) or defined(FreeBSD): &"stat -f %m {fullpath.sanitizePath}" (result, ret) = execAction(cmd) From 01bc01a30c25ccd6bc3e344adc1f6be38500b6b0 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 21 Apr 2020 13:39:20 -0500 Subject: [PATCH 391/593] Handle qualifiers after type --- nimterop/ast2.nim | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index 23bf774..7c32a21 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -529,9 +529,10 @@ iterator newIdentDefs(nimState: NimState, name: string, node: TSNode, offset: So # struct ABC { int w, h; }; # # This is not applicable for procs. - let + var start = getStartAtom(node) + let # node[start] - param type (tname0, _, tinfo) = nimState.getNameInfo(node[start].getAtom(), nskType, parent = name) @@ -544,6 +545,10 @@ iterator newIdentDefs(nimState: NimState, name: string, node: TSNode, offset: So tident = nimState.getIdent(tname, tinfo, exported = false) + # Skip qualifiers after type + while start < node.len - 1 and node[start+1].getName() == "type_qualifier": + start += 1 + if start == node.len - 1: # Only for proc with no named param - create a param name based on offset # From 183eabff83aa7c2cda6fcd41427ad95b3d4fd7ed Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 21 Apr 2020 14:53:26 -0500 Subject: [PATCH 392/593] Get rid of nimState --- nimterop/ast.nim | 156 ++++++------ nimterop/ast2.nim | 562 +++++++++++++++++++++---------------------- nimterop/getters.nim | 121 +++++----- nimterop/globals.nim | 17 +- nimterop/grammar.nim | 350 +++++++++++++-------------- 5 files changed, 595 insertions(+), 611 deletions(-) diff --git a/nimterop/ast.nim b/nimterop/ast.nim index 06b0504..6b21bc7 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -4,27 +4,27 @@ import regex import "."/[getters, globals, treesitter/api] -proc getHeaderPragma*(nimState: NimState): string = +proc getHeaderPragma*(gState: State): string = result = - if nimState.includeHeader(): - &", header: {nimState.currentHeader}" + if gState.isIncludeHeader(): + &", header: {gState.currentHeader}" else: "" -proc getDynlib*(nimState: NimState): string = +proc getDynlib*(gState: State): string = result = - if nimState.gState.dynlib.nBl: - &", dynlib: {nimState.gState.dynlib}" + if gState.dynlib.nBl: + &", dynlib: {gState.dynlib}" else: "" -proc getImportC*(nimState: NimState, origName, nimName: string): string = +proc getImportC*(gState: State, origName, nimName: string): string = if nimName != origName: - result = &"importc: \"{origName}\"{nimState.getHeaderPragma()}" + result = &"importc: \"{origName}\"{gState.getHeaderPragma()}" else: - result = nimState.impShort + result = gState.impShort -proc getPragma*(nimState: NimState, pragmas: varargs[string]): string = +proc getPragma*(gState: State, pragmas: varargs[string]): string = result = "" for pragma in pragmas.items(): if pragma.nBl: @@ -32,15 +32,15 @@ proc getPragma*(nimState: NimState, pragmas: varargs[string]): string = if result.nBl: result = " {." & result[0 .. ^3] & ".}" - result = result.replace(nimState.impShort & ", cdecl", nimState.impShort & "C") + result = result.replace(gState.impShort & ", cdecl", gState.impShort & "C") let - dy = nimState.getDynlib() + dy = gState.getDynlib() if ", cdecl" in result and dy.nBl: result = result.replace(".}", dy & ".}") -proc saveNodeData(node: TSNode, nimState: NimState): bool = +proc saveNodeData(node: TSNode, gState: State): bool = let name = $node.tsNodeType() # Atoms are nodes whose values are to be saved @@ -52,7 +52,7 @@ proc saveNodeData(node: TSNode, nimState: NimState): bool = ppppname = node.getPxName(4) var - val = nimState.getNodeVal(node) + val = gState.getNodeVal(node) # Skip since value already obtained from parent atom if name == "primitive_type" and pname == "sized_type_specifier": @@ -64,7 +64,7 @@ proc saveNodeData(node: TSNode, nimState: NimState): bool = # Add reference point in saved data for bitfield_clause if name in ["number_literal"] and pname == "bitfield_clause": - nimState.data.add(("bitfield_clause", val)) + gState.data.add(("bitfield_clause", val)) return true # Process value as a type @@ -74,52 +74,52 @@ proc saveNodeData(node: TSNode, nimState: NimState): bool = if node.tsNodePrevNamedSibling().tsNodeIsNull(): if pname == "pointer_declarator": if ppname notin ["function_declarator", "array_declarator"]: - nimState.data.add(("pointer_declarator", "")) + gState.data.add(("pointer_declarator", "")) elif ppname == "array_declarator": - nimState.data.add(("array_pointer_declarator", "")) + gState.data.add(("array_pointer_declarator", "")) # Double pointer if ppname == "pointer_declarator": - nimState.data.add(("pointer_declarator", "")) + gState.data.add(("pointer_declarator", "")) elif pname in ["function_declarator", "array_declarator"]: if ppname == "pointer_declarator": - nimState.data.add(("pointer_declarator", "")) + gState.data.add(("pointer_declarator", "")) if pppname == "pointer_declarator": - nimState.data.add(("pointer_declarator", "")) + gState.data.add(("pointer_declarator", "")) - nimState.data.add((name, val)) + gState.data.add((name, val)) if pname == "pointer_declarator" and ppname == "function_declarator": if name == "field_identifier": if pppname == "pointer_declarator": - nimState.data.insert(("pointer_declarator", ""), nimState.data.len-1) + gState.data.insert(("pointer_declarator", ""), gState.data.len-1) if ppppname == "pointer_declarator": - nimState.data.insert(("pointer_declarator", ""), nimState.data.len-1) - nimState.data.add(("function_declarator", "")) + gState.data.insert(("pointer_declarator", ""), gState.data.len-1) + gState.data.add(("function_declarator", "")) elif name == "identifier": - nimState.data.add(("pointer_declarator", "")) + gState.data.add(("pointer_declarator", "")) # Save node value for a top-level expression elif name in gExpressions and name != "escape_sequence": if $node.tsNodeParent.tsNodeType() notin gExpressions: - nimState.data.add((name, nimState.getNodeVal(node))) + gState.data.add((name, gState.getNodeVal(node))) elif name in ["abstract_pointer_declarator", "enumerator", "field_declaration", "function_declarator"]: - nimState.data.add((name.replace("abstract_", ""), "")) + gState.data.add((name.replace("abstract_", ""), "")) return true -proc searchAstForNode(ast: ref Ast, node: TSNode, nimState: NimState): bool = +proc searchAstForNode(ast: ref Ast, node: TSNode, gState: State): bool = let childNames = node.getTSNodeNamedChildNames().join() if ast.isNil: return - if nimState.gState.debug: - nimState.nodeBranch.add $node.tsNodeType() - necho "#" & spaces(nimState.nodeBranch.len * 2) & nimState.nodeBranch[^1] + if gState.debug: + gState.nodeBranch.add $node.tsNodeType() + gecho "#" & spaces(gState.nodeBranch.len * 2) & gState.nodeBranch[^1] if ast.children.nBl: if childNames.contains(ast.regex) or @@ -137,26 +137,26 @@ proc searchAstForNode(ast: ref Ast, node: TSNode, nimState: NimState): bool = else: ast - if not searchAstForNode(astChild, nodeChild, nimState): + if not searchAstForNode(astChild, nodeChild, gState): flag = false break if flag: - result = node.saveNodeData(nimState) + result = node.saveNodeData(gState) else: - result = node.saveNodeData(nimState) + result = node.saveNodeData(gState) else: - if nimState.gState.debug: - necho "#" & spaces(nimState.nodeBranch.len * 2) & &" {ast.getRegexForAstChildren()} !=~ {childNames}" + if gState.debug: + gecho "#" & spaces(gState.nodeBranch.len * 2) & &" {ast.getRegexForAstChildren()} !=~ {childNames}" elif node.getTSNodeNamedChildCountSansComments() == 0: - result = node.saveNodeData(nimState) + result = node.saveNodeData(gState) - if nimState.gState.debug: - discard nimState.nodeBranch.pop() - if nimstate.nodeBranch.Bl: - necho "" + if gState.debug: + discard gState.nodeBranch.pop() + if gState.nodeBranch.Bl: + gecho "" -proc searchAst(root: TSNode, astTable: AstTable, nimState: NimState) = +proc searchAst(root: TSNode, astTable: AstTable, gState: State) = var node = root nextnode: TSNode @@ -168,14 +168,14 @@ proc searchAst(root: TSNode, astTable: AstTable, nimState: NimState) = name = $node.tsNodeType() if name in astTable: for ast in astTable[name]: - if nimState.gState.debug: - necho "\n# " & nimState.getNodeVal(node).replace("\n", "\n# ") & "\n" - if searchAstForNode(ast, node, nimState): - ast.tonim(ast, node, nimState) - if nimState.gState.debug: - nimState.debugStr &= "\n# " & nimState.data.join("\n# ") & "\n" + if gState.debug: + gecho "\n# " & gState.getNodeVal(node).replace("\n", "\n# ") & "\n" + if searchAstForNode(ast, node, gState): + ast.tonim(ast, node, gState) + if gState.debug: + gState.debugStr &= "\n# " & gState.data.join("\n# ") & "\n" break - nimState.data = @[] + gState.data = @[] else: break @@ -204,48 +204,46 @@ proc searchAst(root: TSNode, astTable: AstTable, nimState: NimState) = proc printNim*(gState: State, fullpath: string, root: TSNode, astTable: AstTable) = var - nimState = new(NimState) fp = fullpath.replace("\\", "/") - nimState.identifiers = newTable[string, string]() + gState.identifiers = newTable[string, string]() - nimState.gState = gState - nimState.currentHeader = getCurrentHeader(fullpath) - nimState.impShort = nimState.currentHeader.replace("header", "imp") - nimState.sourceFile = fullpath + gState.currentHeader = getCurrentHeader(fullpath) + gState.impShort = gState.currentHeader.replace("header", "imp") + gState.sourceFile = fullpath - if nimState.includeHeader(): - nimState.constStr &= &"\n {nimState.currentHeader} {{.used.}} = \"{fp}\"" + if gState.isIncludeHeader(): + gState.constStr &= &"\n {gState.currentHeader} {{.used.}} = \"{fp}\"" - root.searchAst(astTable, nimState) + root.searchAst(astTable, gState) - if nimState.enumStr.nBl: - necho &"{nimState.enumStr}\n" + if gState.enumStr.nBl: + gecho &"{gState.enumStr}\n" - nimState.constStr = nimState.getOverrideFinal(nskConst) & nimState.constStr - if nimState.constStr.nBl: - necho &"const{nimState.constStr}\n" + gState.constStr = gState.getOverrideFinal(nskConst) & gState.constStr + if gState.constStr.nBl: + gecho &"const{gState.constStr}\n" - necho &""" -{{.pragma: {nimState.impShort}, importc{nimState.getHeaderPragma()}.}} -{{.pragma: {nimState.impShort}C, {nimState.impShort}, cdecl{nimState.getDynlib()}.}} + gecho &""" +{{.pragma: {gState.impShort}, importc{gState.getHeaderPragma()}.}} +{{.pragma: {gState.impShort}C, {gState.impShort}, cdecl{gState.getDynlib()}.}} """ - nimState.typeStr = nimState.getOverrideFinal(nskType) & nimState.typeStr - if nimState.typeStr.nBl: - necho &"type{nimState.typeStr}\n" + gState.typeStr = gState.getOverrideFinal(nskType) & gState.typeStr + if gState.typeStr.nBl: + gecho &"type{gState.typeStr}\n" - nimState.procStr = nimState.getOverrideFinal(nskProc) & nimState.procStr - if nimState.procStr.nBl: - necho &"{nimState.procStr}\n" + gState.procStr = gState.getOverrideFinal(nskProc) & gState.procStr + if gState.procStr.nBl: + gecho &"{gState.procStr}\n" - if nimState.gState.debug: - if nimState.debugStr.nBl: - necho nimState.debugStr + if gState.debug: + if gState.debugStr.nBl: + gecho gState.debugStr - if nimState.skipStr.nBl: + if gState.skipStr.nBl: let - hash = nimState.skipStr.hash().abs() + hash = gState.skipStr.hash().abs() sname = getTempDir() / &"nimterop_{$hash}.h" - necho &"# Writing skipped definitions to {sname}\n" - writeFile(sname, nimState.skipStr) + gecho &"# Writing skipped definitions to {sname}\n" + writeFile(sname, gState.skipStr) diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index 7c32a21..9e8f582 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -22,17 +22,17 @@ proc handleError*(conf: ConfigRef, info: TLineInfo, msg: TMsgKind, arg: string) if msg < warnMin: raise newException(Exception, msgKindToString(msg)) -proc parseString(nimState: NimState, str: string): PNode = +proc parseString(gState: State, str: string): PNode = # Parse a string into Nim AST - use custom error handler that raises # an exception rather than exiting on failure try: result = parseString( - str, nimState.identCache, nimState.config, errorHandler = handleError + str, gState.identCache, gState.config, errorHandler = handleError ) except: decho getCurrentExceptionMsg() -proc getLit*(nimState: NimState, str: string, expression = false): PNode = +proc getLit*(gState: State, str: string, expression = false): PNode = # Used to convert #define literals into const and expressions # in array sizes # @@ -47,7 +47,7 @@ proc getLit*(nimState: NimState, str: string, expression = false): PNode = result = newFloatNode(nkFloatLit, parseFloat(str)) elif str.contains(re"^0x[\da-fA-F]+$"): # hexadecimal - result = nimState.parseString(str) + result = gState.parseString(str) elif str.contains(re"^'[[:ascii:]]'$"): # char result = newNode(nkCharLit) @@ -59,23 +59,23 @@ proc getLit*(nimState: NimState, str: string, expression = false): PNode = else: let str = - if expression: nimState.getNimExpression(str) + if expression: gState.getNimExpression(str) else: str - result = nimState.parseString(str) + result = gState.parseString(str) if result.isNil: result = newNode(nkNilLit) -proc getOverrideOrSkip(nimState: NimState, node: TSNode, origname: string, kind: NimSymKind): PNode = +proc getOverrideOrSkip(gState: State, node: TSNode, origname: string, kind: NimSymKind): PNode = # Check if symbol `origname` of `kind` and `origname` has any cOverride defined # and use that if present # # If not, symbol needs to be skipped - only get here if `name` is blank let # Get cleaned name for symbol, set parent so that cOverride is ignored - name = nimState.getIdentifier(origname, kind, parent = "getOverrideOrSkip") + name = gState.getIdentifier(origname, kind, parent = "getOverrideOrSkip") - override = nimState.getOverride(origname, kind) + override = gState.getOverride(origname, kind) var skind = getKeyword(kind) & " " @@ -83,25 +83,25 @@ proc getOverrideOrSkip(nimState: NimState, node: TSNode, origname: string, kind: if kind == nskProc: skind = "" let - pnode = nimState.parseString(skind & override.replace(origname, name)) + pnode = gState.parseString(skind & override.replace(origname, name)) if not pnode.isNil: result = pnode[0][0] else: - necho &"\n# $1'{origname}' skipped" % skind - if nimState.gState.debug: - nimState.skipStr &= &"\n{nimState.getNodeVal(node)}" + gecho &"\n# $1'{origname}' skipped" % skind + if gState.debug: + gState.skipStr &= &"\n{gState.getNodeVal(node)}" -proc addOverrideFinal(nimState: NimState, kind: NimSymKind) = +proc addOverrideFinal(gState: State, kind: NimSymKind) = # Add all unused cOverride symbols for `kind` to AST var - syms = nimState.getOverrideFinal(kind) + syms = gState.getOverrideFinal(kind) skind = getKeyword(kind) & "\n" if kind == nskProc: skind = "" if syms.nBl: var - nsyms = nimState.parseString(skind & syms) + nsyms = gState.parseString(skind & syms) if not nsyms.isNil: let list = @@ -111,20 +111,20 @@ proc addOverrideFinal(nimState: NimState, kind: NimSymKind) = nsyms[0].sons case kind of nskConst: - nimState.constSection.sons.insert(list, 0) + gState.constSection.sons.insert(list, 0) of nskType: - nimState.typeSection.sons.insert(list, 0) + gState.typeSection.sons.insert(list, 0) of nskProc: - nimState.procSection.sons.insert(list, 0) + gState.procSection.sons.insert(list, 0) else: discard -proc addAllOverrideFinal(nimState: NimState) = +proc addAllOverrideFinal(gState: State) = # Add all unused cOverride symbols to AST for kind in [nskConst, nskType, nskProc]: - nimState.addOverrideFinal(kind) + gState.addOverrideFinal(kind) -proc newConstDef(nimState: NimState, node: TSNode, fname = "", fval = ""): PNode = +proc newConstDef(gState: State, node: TSNode, fname = "", fval = ""): PNode = # Create an nkConstDef PNode # # If `fname` or `fval` are set, use them as name and val @@ -134,28 +134,28 @@ proc newConstDef(nimState: NimState, node: TSNode, fname = "", fval = ""): PNode fname else: # node[0] = identifier = const name - nimState.getNodeVal(node.getAtom()) + gState.getNodeVal(node.getAtom()) - name = nimState.getIdentifier(origname, nskConst) - info = nimState.getLineInfo(node) - ident = nimState.getIdent(name, info) + name = gState.getIdentifier(origname, nskConst) + info = gState.getLineInfo(node) + ident = gState.getIdent(name, info) # node[1] = preproc_arg = value val = if fval.nBl: fval else: - nimState.getNodeVal(node[1]) + gState.getNodeVal(node[1]) valident = - nimState.getLit(val) + gState.getLit(val) if name.Bl: # Name skipped or overridden since blank - result = nimState.getOverrideOrSkip(node, origname, nskConst) + result = gState.getOverrideOrSkip(node, origname, nskConst) elif valident.kind in {nkCharLit .. nkStrLit} or (valident.kind == nkStmtList and valident.len > 0 and valident[0].kind in {nkCharLit .. nkStrLit}): - if nimState.addNewIdentifer(name): + if gState.addNewIdentifer(name): # const X* = Y # # nkConstDef( @@ -175,11 +175,11 @@ proc newConstDef(nimState: NimState, node: TSNode, fname = "", fval = ""): PNode else: result.add valident else: - necho &"# const '{origname}' is duplicate, skipped" + gecho &"# const '{origname}' is duplicate, skipped" else: - necho &"# const '{origname}' has invalid value '{val}'" + gecho &"# const '{origname}' has invalid value '{val}'" -proc addConst(nimState: NimState, node: TSNode) = +proc addConst(gState: State, node: TSNode) = # Add a const to the AST # # #define X Y @@ -189,25 +189,25 @@ proc addConst(nimState: NimState, node: TSNode) = # (preproc_arg) # ) decho("addConst()") - nimState.printDebug(node) + gState.printDebug(node) if node[0].getName() == "identifier" and node[1].getName() == "preproc_arg": let - constDef = nimState.newConstDef(node) + constDef = gState.newConstDef(node) if not constDef.isNil: # nkConstSection.add - nimState.constSection.add constDef - nimState.constIdentifiers.incl constDef.getIdentName() + gState.constSection.add constDef + gState.constIdentifiers.incl constDef.getIdentName() - nimState.printDebug(constDef) + gState.printDebug(constDef) -proc addPragma(nimState: NimState, node: TSNode, pragma: PNode, name: string, value: PNode = nil) = +proc addPragma(gState: State, node: TSNode, pragma: PNode, name: string, value: PNode = nil) = # Add pragma to an existing nkPragma tree let - pinfo = nimState.getLineInfo(node.getAtom()) - pident = nimState.getIdent(name, pinfo, exported = false) + pinfo = gState.getLineInfo(node.getAtom()) + pident = gState.getIdent(name, pinfo, exported = false) if value.isNil: pragma.add pident @@ -218,17 +218,17 @@ proc addPragma(nimState: NimState, node: TSNode, pragma: PNode, name: string, va colExpr.add value pragma.add colExpr -proc addPragma(nimState: NimState, node: TSNode, pragma: PNode, pragmas: seq[string]) = +proc addPragma(gState: State, node: TSNode, pragma: PNode, pragmas: seq[string]) = # Add sequence of pragmas to an existing nkPragma tree for name in pragmas: - nimState.addPragma(node, pragma, name) + gState.addPragma(node, pragma, name) -proc addPragma(nimState: NimState, node: TSNode, pragma: PNode, pragmas: OrderedTable[string, PNode]) = +proc addPragma(gState: State, node: TSNode, pragma: PNode, pragmas: OrderedTable[string, PNode]) = # Add a table of name:value pragmas to an existing nkPragma tree for name, value in pragmas.pairs: - nimState.addPragma(node, pragma, name, value) + gState.addPragma(node, pragma, name, value) -proc newPragma(nimState: NimState, node: TSNode, name: string, value: PNode = nil): PNode = +proc newPragma(gState: State, node: TSNode, name: string, value: PNode = nil): PNode = # Create nkPragma tree for name:value # # {.name1, name2: value2.} @@ -241,14 +241,14 @@ proc newPragma(nimState: NimState, node: TSNode, name: string, value: PNode = ni # ) # ) result = newNode(nkPragma) - nimState.addPragma(node, result, name, value) + gState.addPragma(node, result, name, value) -proc newPragma(nimState: NimState, node: TSNode, pragmas: seq[string] | OrderedTable[string, PNode]): PNode = +proc newPragma(gState: State, node: TSNode, pragmas: seq[string] | OrderedTable[string, PNode]): PNode = # Create nkPragma tree for multiple name:value result = newNode(nkPragma) - nimState.addPragma(node, result, pragmas) + gState.addPragma(node, result, pragmas) -proc newPragmaExpr(nimState: NimState, node: TSNode, ident: PNode, name: string, value: PNode = nil): PNode = +proc newPragmaExpr(gState: State, node: TSNode, ident: PNode, name: string, value: PNode = nil): PNode = # Create nkPragmaExpr tree for name:value # # nkPragmaExpr( @@ -266,15 +266,15 @@ proc newPragmaExpr(nimState: NimState, node: TSNode, ident: PNode, name: string, # ) result = newNode(nkPragmaExpr) result.add ident - result.add nimState.newPragma(node, name, value) + result.add gState.newPragma(node, name, value) -proc newPragmaExpr(nimState: NimState, node: TSNode, ident: PNode, pragmas: seq[string] | OrderedTable[string, PNode]): PNode = +proc newPragmaExpr(gState: State, node: TSNode, ident: PNode, pragmas: seq[string] | OrderedTable[string, PNode]): PNode = # Create nkPragmaExpr tree for multiple name:value result = newNode(nkPragmaExpr) result.add ident - result.add nimState.newPragma(node, pragmas) + result.add gState.newPragma(node, pragmas) -proc newXIdent(nimState: NimState, node: TSNode, kind = nskType, fname = "", pragmas: seq[string] = @[], istype = false): PNode = +proc newXIdent(gState: State, node: TSNode, kind = nskType, fname = "", pragmas: seq[string] = @[], istype = false): PNode = # Create nkTypeDef PNode with first ident if `nskType` # Create nkIdentDefs PNode with first ident if `nskVar` # Create an nkPostfix node for `nskProc` @@ -287,9 +287,9 @@ proc newXIdent(nimState: NimState, node: TSNode, kind = nskType, fname = "", pra (tname, torigname, info) = if not atom.isNil: - nimState.getNameInfo(node.getAtom(), kind) + gState.getNameInfo(node.getAtom(), kind) else: - ("", "", nimState.getLineInfo(node)) + ("", "", gState.getLineInfo(node)) origname = if fname.nBl: @@ -300,16 +300,16 @@ proc newXIdent(nimState: NimState, node: TSNode, kind = nskType, fname = "", pra # Process name if forced, getNameInfo() already runs getIdentifier() name = if fname.nBl: - nimState.getIdentifier(fname, kind) + gState.getIdentifier(fname, kind) else: tname - ident = nimState.getIdent(name, info) + ident = gState.getIdent(name, info) if name.Bl: # Name skipped or overridden since blank - result = nimState.getOverrideOrSkip(node, origname, kind) - elif nimState.addNewIdentifer(name): + result = gState.getOverrideOrSkip(node, origname, kind) + elif gState.addNewIdentifer(name): if kind == nskType: # type name* = # @@ -341,24 +341,24 @@ proc newXIdent(nimState: NimState, node: TSNode, kind = nskType, fname = "", pra # ) var pragmas = - if nimState.includeHeader: + if gState.isIncludeHeader(): # Need to add header and importc if istype and name == origname: # Need to add impShort since neither struct/union nor name change - pragmas & nimState.impShort + pragmas & gState.impShort else: # Add header shortcut, additional pragmas added later - pragmas & (nimState.impShort & "H") + pragmas & (gState.impShort & "H") else: pragmas prident = if pragmas.nBl: - nimState.newPragmaExpr(node, ident, pragmas) + gState.newPragmaExpr(node, ident, pragmas) else: ident - if nimState.includeHeader: + if gState.isIncludeHeader(): if not istype or name != origname: # Add importc pragma since either struct/union or name changed let @@ -370,7 +370,7 @@ proc newXIdent(nimState: NimState, node: TSNode, kind = nskType, fname = "", pra "struct " else: "" - nimState.addPragma(node, prident[1], "importc", newStrNode(nkStrLit, &"{uors}{origname}")) + gState.addPragma(node, prident[1], "importc", newStrNode(nkStrLit, &"{uors}{origname}")) result = newNode(nkTypeDef) result.add prident @@ -398,18 +398,18 @@ proc newXIdent(nimState: NimState, node: TSNode, kind = nskType, fname = "", pra prident: PNode if name != origname: # Add importc pragma since name changed - prident = nimState.newPragmaExpr(node, ident, "importc", newStrNode(nkStrLit, &"{origname}")) - if nimState.includeHeader(): + prident = gState.newPragmaExpr(node, ident, "importc", newStrNode(nkStrLit, &"{origname}")) + if gState.isIncludeHeader(): # Add header - nimState.addPragma(node, prident[1], nimState.impShort & "H") - elif nimState.gState.dynlib.nBl: + gState.addPragma(node, prident[1], gState.impShort & "H") + elif gState.dynlib.nBl: # Add dynlib - nimState.addPragma(node, prident[1], "dynlib", nimState.getIdent(nimState.gState.dynlib)) + gState.addPragma(node, prident[1], "dynlib", gState.getIdent(gState.dynlib)) else: # Only need impShort since no name change - prident = nimState.newPragmaExpr(node, ident, nimState.impShort) + prident = gState.newPragmaExpr(node, ident, gState.impShort) if pragmas.nBl: - nimState.addPragma(node, prident[1], pragmas) + gState.addPragma(node, prident[1], pragmas) prident result = newNode(nkIdentDefs) @@ -425,11 +425,11 @@ proc newXIdent(nimState: NimState, node: TSNode, kind = nskType, fname = "", pra # No pragmas here since proc pragmas are elsewhere in the AST result = ident - nimState.identifierNodes[name] = result + gState.identifierNodes[name] = result else: - necho &"# $1 '{origname}' is duplicate, skipped" % getKeyword(kind) + gecho &"# $1 '{origname}' is duplicate, skipped" % getKeyword(kind) -proc newPtrTree(nimState: NimState, count: int, typ: PNode): PNode = +proc newPtrTree(gState: State, count: int, typ: PNode): PNode = # Create nkPtrTy tree depending on count # # Reduce by 1 if Nim type available for ptr X - e.g. ptr cchar = cstring @@ -442,7 +442,7 @@ proc newPtrTree(nimState: NimState, count: int, typ: PNode): PNode = ptname = getPtrType(tname) if tname != ptname: # If Nim type available, use that ident - result = nimState.getIdent(ptname, typ.info, exported = false) + result = gState.getIdent(ptname, typ.info, exported = false) # One ptr reduced count -= 1 if count > 0: @@ -466,18 +466,18 @@ proc newPtrTree(nimState: NimState, count: int, typ: PNode): PNode = parent.add result result = nresult -proc newArrayTree(nimState: NimState, node: TSNode, typ, size: PNode = nil): PNode = +proc newArrayTree(gState: State, node: TSNode, typ, size: PNode = nil): PNode = # Create nkBracketExpr tree depending on input # # If `size` is nil, create UncheckedArray[typ] let - info = nimState.getLineInfo(node.getAtom()) + info = gState.getLineInfo(node.getAtom()) tname = if size.isNil: "UncheckedArray" else: "array" - ident = nimState.getIdent(tname, info, exported = false) + ident = gState.getIdent(tname, info, exported = false) # array[size, typ] # @@ -492,10 +492,10 @@ proc newArrayTree(nimState: NimState, node: TSNode, typ, size: PNode = nil): PNo result.add size result.add typ -proc getTypeArray(nimState: NimState, node: TSNode, tident: PNode, name: string): PNode -proc getTypeProc(nimState: NimState, name: string, node, rnode: TSNode): PNode +proc getTypeArray(gState: State, node: TSNode, tident: PNode, name: string): PNode +proc getTypeProc(gState: State, name: string, node, rnode: TSNode): PNode -iterator newIdentDefs(nimState: NimState, name: string, node: TSNode, offset: SomeInteger, ftname = "", exported = false): PNode = +iterator newIdentDefs(gState: State, name: string, node: TSNode, offset: SomeInteger, ftname = "", exported = false): PNode = # Create nkIdentDefs tree for specified proc parameter or object field # # For proc, param should not be `exported` @@ -534,7 +534,7 @@ iterator newIdentDefs(nimState: NimState, name: string, node: TSNode, offset: So let # node[start] - param type - (tname0, _, tinfo) = nimState.getNameInfo(node[start].getAtom(), nskType, parent = name) + (tname0, _, tinfo) = gState.getNameInfo(node[start].getAtom(), nskType, parent = name) # Override type name tname = @@ -543,7 +543,7 @@ iterator newIdentDefs(nimState: NimState, name: string, node: TSNode, offset: So else: tname0 - tident = nimState.getIdent(tname, tinfo, exported = false) + tident = gState.getIdent(tname, tinfo, exported = false) # Skip qualifiers after type while start < node.len - 1 and node[start+1].getName() == "type_qualifier": @@ -559,7 +559,7 @@ iterator newIdentDefs(nimState: NimState, name: string, node: TSNode, offset: So if tname != "object": let pname = "a" & $(offset+1) - pident = nimState.getIdent(pname, tinfo, exported) + pident = gState.getIdent(pname, tinfo, exported) result.add pident result.add tident result.add newNode(nkEmpty) @@ -589,22 +589,22 @@ iterator newIdentDefs(nimState: NimState, name: string, node: TSNode, offset: So # int func(char *, int **); let pname = "a" & $(offset+1) - pident = nimState.getIdent(pname, tinfo, exported) + pident = gState.getIdent(pname, tinfo, exported) acount = node[i].getXCount("abstract_pointer_declarator") result.add pident - result.add nimState.newPtrTree(acount, tident) + result.add gState.newPtrTree(acount, tident) result.add newNode(nkEmpty) else: # Named param, simple type let - (pname, _, pinfo) = nimState.getNameInfo(node[i].getAtom(), nskField, parent = name) - pident = nimState.getIdent(pname, pinfo, exported) + (pname, _, pinfo) = gState.getNameInfo(node[i].getAtom(), nskField, parent = name) + pident = gState.getIdent(pname, pinfo, exported) # Bitfield support - typedef struct { int field: 1; }; prident = if node.len > i and node[i + 1].getName() == "bitfield_clause": - nimState.newPragmaExpr(node, pident, "bitsize", - newIntNode(nkIntLit, parseInt(nimState.getNodeVal(node[i + 1].getAtom())))) + gState.newPragmaExpr(node, pident, "bitsize", + newIntNode(nkIntLit, parseInt(gState.getNodeVal(node[i + 1].getAtom())))) else: pident @@ -612,17 +612,17 @@ iterator newIdentDefs(nimState: NimState, name: string, node: TSNode, offset: So result.add prident if count > 0: - result.add nimState.newPtrTree(count, tident) + result.add gState.newPtrTree(count, tident) else: result.add tident result.add newNode(nkEmpty) elif not fdecl.isNil: # Named param, function pointer let - (pname, _, pinfo) = nimState.getNameInfo(node[i].getAtom(), nskField, parent = name) - pident = nimState.getIdent(pname, pinfo, exported) + (pname, _, pinfo) = gState.getNameInfo(node[i].getAtom(), nskField, parent = name) + pident = gState.getIdent(pname, pinfo, exported) result.add pident - result.add nimState.getTypeProc(name, node[i], node[start]) + result.add gState.getTypeProc(name, node[i], node[start]) result.add newNode(nkEmpty) elif not afdecl.isNil: # Only for proc with no named param with function pointer type @@ -631,25 +631,25 @@ iterator newIdentDefs(nimState: NimState, name: string, node: TSNode, offset: So # int func(int (*)(int *)); let pname = "a" & $(offset+1) - pident = nimState.getIdent(pname, tinfo, exported) - procTy = nimState.getTypeProc(name, node[i], node[start]) + pident = gState.getIdent(pname, tinfo, exported) + procTy = gState.getTypeProc(name, node[i], node[start]) result.add pident result.add procTy result.add newNode(nkEmpty) elif not adecl.isNil: # Named param, array type let - (pname, _, pinfo) = nimState.getNameInfo(node[i].getAtom(), nskField, parent = name) - pident = nimState.getIdent(pname, pinfo, exported) + (pname, _, pinfo) = gState.getNameInfo(node[i].getAtom(), nskField, parent = name) + pident = gState.getIdent(pname, pinfo, exported) result.add pident - result.add nimState.getTypeArray(node[i], tident, name) + result.add gState.getTypeArray(node[i], tident, name) result.add newNode(nkEmpty) else: result = nil yield result -proc newFormalParams(nimState: NimState, name: string, node: TSNode, rtyp: PNode): PNode = +proc newFormalParams(gState: State, name: string, node: TSNode, rtyp: PNode): PNode = # Create nkFormalParams tree for specified params and return type # # proc(pname: ptyp ..): rtyp @@ -669,11 +669,11 @@ proc newFormalParams(nimState: NimState, name: string, node: TSNode, rtyp: PNode for i in 0 ..< node.len: if node[i].getName() == "parameter_declaration": # Add nkIdentDefs for each param - for param in nimState.newIdentDefs(name, node[i], i, exported = false): + for param in gState.newIdentDefs(name, node[i], i, exported = false): if not param.isNil: result.add param -proc newProcTy(nimState: NimState, name: string, node: TSNode, rtyp: PNode): PNode = +proc newProcTy(gState: State, name: string, node: TSNode, rtyp: PNode): PNode = # Create nkProcTy tree for specified proc type # proc(pname: ptyp ..): rtyp @@ -688,15 +688,15 @@ proc newProcTy(nimState: NimState, name: string, node: TSNode, rtyp: PNode): PNo # nkPragma(...) # ) result = newNode(nkProcTy) - result.add nimState.newFormalParams(name, node, rtyp) - result.add nimState.newPragma(node, nimState.gState.convention) + result.add gState.newFormalParams(name, node, rtyp) + result.add gState.newPragma(node, gState.convention) # Add varargs if ... if node.getVarargs(): - nimState.addPragma(node, result[^1], "varargs") + gState.addPragma(node, result[^1], "varargs") -proc processNode(nimState: NimState, node: TSNode): bool -proc newRecListTree(nimState: NimState, name: string, node: TSNode): PNode = +proc processNode(gState: State, node: TSNode): bool +proc newRecListTree(gState: State, name: string, node: TSNode): PNode = # Create nkRecList tree for specified object if not node.isNil: # fname*: ftyp @@ -722,14 +722,14 @@ proc newRecListTree(nimState: NimState, name: string, node: TSNode): PNode = if not fdecl.isNil: # Nested struct / union ( - nimState.processNode(fdecl.tsNodeParent()), - nimState.typeSection[^1].getIdentName() + gState.processNode(fdecl.tsNodeParent()), + gState.typeSection[^1].getIdentName() ) elif not edecl.isNil: # Nested enum ( - nimState.processNode(edecl.tsNodeParent()), - $nimState.enumSection[^1][0][1] + gState.processNode(edecl.tsNodeParent()), + $gState.enumSection[^1][0][1] ) else: (true, "") @@ -738,11 +738,11 @@ proc newRecListTree(nimState: NimState, name: string, node: TSNode): PNode = return nil # Add nkIdentDefs for each field - for field in nimState.newIdentDefs(name, node[i], i, ftname = tname, exported = true): + for field in gState.newIdentDefs(name, node[i], i, ftname = tname, exported = true): if not field.isNil: result.add field -proc addTypeObject(nimState: NimState, node: TSNode, typeDef: PNode = nil, fname = "", istype = false, union = false) = +proc addTypeObject(gState: State, node: TSNode, typeDef: PNode = nil, fname = "", istype = false, union = false) = # Add a type of object # # If `typeDef` is set, use it instead of creating new PNode @@ -772,7 +772,7 @@ proc addTypeObject(nimState: NimState, node: TSNode, typeDef: PNode = nil, fname if not node.firstChildInTree("field_declaration_list").isNil and node.tsNodeParent().getName() == "field_declaration": # If nested struct / union without a name - nimState.getUniqueIdentifier( + gState.getUniqueIdentifier( if union: "Union" else: "Type" ) else: @@ -782,7 +782,7 @@ proc addTypeObject(nimState: NimState, node: TSNode, typeDef: PNode = nil, fname typeDef = if typeDef.isNil: - nimState.newXIdent(node, fname = fname, pragmas = pragmas, istype = istype) + gState.newXIdent(node, fname = fname, pragmas = pragmas, istype = istype) else: typeDef @@ -841,7 +841,7 @@ proc addTypeObject(nimState: NimState, node: TSNode, typeDef: PNode = nil, fname if not fdlist.isNil and fdlist.len > 0: # Add fields to object if present let - fields = nimState.newRecListTree(name, fdlist) + fields = gState.newRecListTree(name, fdlist) if fields.isNil: return obj.add fields @@ -854,16 +854,16 @@ proc addTypeObject(nimState: NimState, node: TSNode, typeDef: PNode = nil, fname if pragmas.nBl and typeDefExisting: if typeDef[0].kind != nkPragmaExpr: let - npexpr = nimState.newPragmaExpr(node, typedef[0], pragmas) + npexpr = gState.newPragmaExpr(node, typedef[0], pragmas) typedef[0] = npexpr else: # includeHeader already added impShort in newXIdent() - nimState.addPragma(node, typeDef[0][1], pragmas) + gState.addPragma(node, typeDef[0][1], pragmas) # nkTypeSection.add - nimState.typeSection.add typeDef + gState.typeSection.add typeDef - nimState.printDebug(typeDef) + gState.printDebug(typeDef) else: # Forward declaration case let @@ -871,25 +871,25 @@ proc addTypeObject(nimState: NimState, node: TSNode, typeDef: PNode = nil, fname if not fdlist.isNil and fdlist.len > 0: # Current node has fields let - origname = nimState.getNodeVal(node.getAtom()) + origname = gState.getNodeVal(node.getAtom()) # Fix issue #185 name = if origname.nBl: - nimState.getIdentifier(origname, nskType) + gState.getIdentifier(origname, nskType) else: "" - if name.nBl and nimState.identifierNodes.hasKey(name): + if name.nBl and gState.identifierNodes.hasKey(name): let - def = nimState.identifierNodes[name] + def = gState.identifierNodes[name] # Duplicate nkTypeDef for `name` with empty fields if def.kind == nkTypeDef and def.len == 3 and def[2].kind == nkObjectTy and def[2].len == 3 and def[2][2].kind == nkEmpty: # Add fields to existing object let - fields = nimState.newRecListTree(name, fdlist) + fields = gState.newRecListTree(name, fdlist) if fields.isNil: return def[2][2] = fields @@ -899,14 +899,14 @@ proc addTypeObject(nimState: NimState, node: TSNode, typeDef: PNode = nil, fname def[0][1].kind == nkPragma and def[0][1].len > 0: for i in 0 ..< def[0][1].len: if $def[0][1][i] == "incompleteStruct": - def[0][1][i] = nimState.getIdent( - "bycopy", nimState.getLineInfo(node.getAtom()), + def[0][1][i] = gState.getIdent( + "bycopy", gState.getLineInfo(node.getAtom()), exported = false ) - nimState.printDebug(def) + gState.printDebug(def) -proc addTypeTyped(nimState: NimState, node: TSNode, ftname = "", offset = 0) = +proc addTypeTyped(gState: State, node: TSNode, ftname = "", offset = 0) = # Add a type of a specified type # # If `ftname` is set, use it as the type name @@ -918,14 +918,14 @@ proc addTypeTyped(nimState: NimState, node: TSNode, ftname = "", offset = 0) = # Add a type of a specific type let # node[i] = identifer = name - typeDef = nimState.newXIdent(node[i], istype = true) + typeDef = gState.newXIdent(node[i], istype = true) if not typeDef.isNil: let name = typeDef.getIdentName() # node[start] = identifier = type name - (tname0, _, tinfo) = nimState.getNameInfo(node[start].getAtom(), nskType, parent = name) + (tname0, _, tinfo) = gState.getNameInfo(node[start].getAtom(), nskType, parent = name) # Override type name tname = @@ -934,7 +934,7 @@ proc addTypeTyped(nimState: NimState, node: TSNode, ftname = "", offset = 0) = else: tname0 - ident = nimState.getIdent(tname, tinfo, exported = false) + ident = gState.getIdent(tname, tinfo, exported = false) # node[i] could have nested pointers count = node[i].getPtrCount() @@ -943,7 +943,7 @@ proc addTypeTyped(nimState: NimState, node: TSNode, ftname = "", offset = 0) = if name != tname: if count > 0: # If pointers - typeDef.add nimState.newPtrTree(count, ident) + typeDef.add gState.newPtrTree(count, ident) else: typeDef.add ident @@ -961,13 +961,13 @@ proc addTypeTyped(nimState: NimState, node: TSNode, ftname = "", offset = 0) = # ) # nkTypeSection.add - nimState.typeSection.add typeDef + gState.typeSection.add typeDef - nimState.printDebug(typeDef) + gState.printDebug(typeDef) else: - nimState.addTypeObject(node, typeDef = typeDef, istype = true) + gState.addTypeObject(node, typeDef = typeDef, istype = true) -proc getTypeArray(nimState: NimState, node: TSNode, tident: PNode, name: string): PNode = +proc getTypeArray(gState: State, node: TSNode, tident: PNode, name: string): PNode = # Create array type tree # # `tident` is type PNode @@ -1003,45 +1003,45 @@ proc getTypeArray(nimState: NimState, node: TSNode, tident: PNode, name: string) if tcount > 0: # If pointers - result = nimState.newPtrTree(tcount, result) + result = gState.newPtrTree(tcount, result) for i in 0 ..< acount: if cnode.len == 2: # type name[X] => array[X, type] let # Size of array could be a Nim expression - size = nimState.getLit(nimState.getNodeVal(cnode[1]), expression = true) + size = gState.getLit(gState.getNodeVal(cnode[1]), expression = true) if size.kind != nkNilLit: - result = nimState.newArrayTree(cnode, result, size) + result = gState.newArrayTree(cnode, result, size) cnode = cnode[0] elif cnode.len == 1: # type name[] = UncheckedArray[type] - result = nimState.newArrayTree(cnode, result) + result = gState.newArrayTree(cnode, result) cnode = cnode[0] if ncount > 0: - result = nimState.newPtrTree(ncount, result) + result = gState.newPtrTree(ncount, result) -proc addTypeArray(nimState: NimState, node: TSNode) = +proc addTypeArray(gState: State, node: TSNode) = # Add a type of array type decho("addTypeArray()") let start = getStartAtom(node) # node[start] = identifier = type name - (tname, _, info) = nimState.getNameInfo(node[start].getAtom(), nskType, parent = "addTypeArray") - tident = nimState.getIdent(tname, info, exported = false) + (tname, _, info) = gState.getNameInfo(node[start].getAtom(), nskType, parent = "addTypeArray") + tident = gState.getIdent(tname, info, exported = false) # Could have multiple types, comma separated for i in start+1 ..< node.len: let # node[i] = identifer = name - typeDef = nimState.newXIdent(node[i], istype = true) + typeDef = gState.newXIdent(node[i], istype = true) if not typeDef.isNil: let name = typeDef.getIdentName() - typ = nimState.getTypeArray(node[i], tident, name) + typ = gState.getTypeArray(node[i], tident, name) typeDef.add typ @@ -1065,17 +1065,17 @@ proc addTypeArray(nimState: NimState, node: TSNode) = # ) # nkTypeSection.add - nimState.typeSection.add typeDef + gState.typeSection.add typeDef - nimState.printDebug(typeDef) + gState.printDebug(typeDef) -proc getTypeProc(nimState: NimState, name: string, node, rnode: TSNode): PNode = +proc getTypeProc(gState: State, name: string, node, rnode: TSNode): PNode = # Create proc type tree # # `rnode` is the return type let # rnode = identifier = return type name - (rname, _, rinfo) = nimState.getNameInfo(rnode.getAtom(), nskType, parent = name) + (rname, _, rinfo) = gState.getNameInfo(rnode.getAtom(), nskType, parent = name) # Parameter list plist = node.anyChildInTree("parameter_list") @@ -1113,16 +1113,16 @@ proc getTypeProc(nimState: NimState, name: string, node, rnode: TSNode): PNode = # void (*func)(..) newNode(nkEmpty) else: - nimState.getIdent(rname, rinfo, exported = false) + gState.getIdent(rname, rinfo, exported = false) if tcount > 0: - retType = nimState.newPtrTree(tcount, retType) + retType = gState.newPtrTree(tcount, retType) # Proc with return type and params - result = nimState.newProcTy(name, plist, retType) + result = gState.newProcTy(name, plist, retType) if ncount > 1: - result = nimState.newPtrTree(ncount-1, result) + result = gState.newPtrTree(ncount-1, result) -proc addTypeProc(nimState: NimState, node: TSNode) = +proc addTypeProc(gState: State, node: TSNode) = # Add a type of proc type decho("addTypeProc()") let @@ -1135,13 +1135,13 @@ proc addTypeProc(nimState: NimState, node: TSNode) = for i in start+1 ..< node.len: let # node[i] = identifier = name - typeDef = nimState.newXIdent(node[i], istype = true) + typeDef = gState.newXIdent(node[i], istype = true) if not typeDef.isNil: let name = typeDef.getIdentName() - procTy = nimState.getTypeProc(name, node[i], rnode) + procTy = gState.getTypeProc(name, node[i], rnode) typeDef.add procTy @@ -1174,13 +1174,13 @@ proc addTypeProc(nimState: NimState, node: TSNode) = # ) # nkTypeSection.add - nimState.typeSection.add typeDef + gState.typeSection.add typeDef - nimState.printDebug(typeDef) + gState.printDebug(typeDef) -proc addType(nimState: NimState, node: TSNode, union = false) = +proc addType(gState: State, node: TSNode, union = false) = decho("addType()") - nimState.printDebug(node) + gState.printDebug(node) if node.getName() in ["struct_specifier", "union_specifier"]: # struct X; @@ -1212,13 +1212,13 @@ proc addType(nimState: NimState, node: TSNode, union = false) = # (field_declaration ...) # ) decho("addType(): case 1") - nimState.addTypeObject(node, union = union) + gState.addTypeObject(node, union = union) elif node.getName() == "type_definition": if node.len >= 2: let fdlist = node[0].anyChildInTree("field_declaration_list") if (fdlist.isNil or (not fdlist.isNil and fdlist.Bl)) and - nimState.getNodeVal(node[1]) == "": + gState.getNodeVal(node[1]) == "": # typedef struct X; # # (type_definition @@ -1238,7 +1238,7 @@ proc addType(nimState: NimState, node: TSNode, union = false) = # (type_definition = "") # ) decho("addType(): case 2") - nimState.addTypeObject(node[0], union = union) + gState.addTypeObject(node[0], union = union) else: let fdecl = node[1].anyChildInTree("function_declarator") @@ -1262,7 +1262,7 @@ proc addType(nimState: NimState, node: TSNode, union = false) = # ) # ) decho("addType(): case 3") - nimState.addTypeTyped(node) + gState.addTypeTyped(node) elif not fdecl.isNil: # typedef X (*Y)(a1, a2, a3); # typedef X *(*Y)(a1, a2, a3); @@ -1293,7 +1293,7 @@ proc addType(nimState: NimState, node: TSNode, union = false) = # ) # ) decho("addType(): case 4") - nimState.addTypeProc(node) + gState.addTypeProc(node) elif not adecl.isNil: # typedef struct X Y[a][..]; # typedef struct X *Y[a][..]; @@ -1316,7 +1316,7 @@ proc addType(nimState: NimState, node: TSNode, union = false) = # ) # ) decho("addType(): case 5") - nimState.addTypeArray(node) + gState.addTypeArray(node) else: if node.firstChildInTree("field_declaration_list").isNil: # typedef struct X { .. } Y, *Z; @@ -1344,11 +1344,11 @@ proc addType(nimState: NimState, node: TSNode, union = false) = # First add struct as object decho("addType(): case 6") - nimState.addTypeObject(node[0], union = union) + gState.addTypeObject(node[0], union = union) - if node.len > 1 and nimState.getNodeVal(node[1]) != "": + if node.len > 1 and gState.getNodeVal(node[1]) != "": # Add any additional names - nimState.addTypeTyped(node) + gState.addTypeTyped(node) else: # Same as above except unnamed struct # @@ -1362,20 +1362,20 @@ proc addType(nimState: NimState, node: TSNode, union = false) = name = "" for i in 1 ..< node.len: if node[i].getName() == "type_identifier": - name = nimState.getNodeVal(node[i].getAtom()) + name = gState.getNodeVal(node[i].getAtom()) name # Now add struct as object with specified name - nimState.addTypeObject(node[0], fname = name, istype = true, union = union) + gState.addTypeObject(node[0], fname = name, istype = true, union = union) if name.nBl: # Add any additional names - nimState.addTypeTyped(node, ftname = name, offset = 1) + gState.addTypeTyped(node, ftname = name, offset = 1) -proc addEnum(nimState: NimState, node: TSNode) = +proc addEnum(gState: State, node: TSNode) = decho("addEnum()") - nimState.printDebug(node) + gState.printDebug(node) let enumlist = node.anyChildInTree("enumerator_list") @@ -1388,29 +1388,29 @@ proc addEnum(nimState: NimState, node: TSNode) = if node.getAtom().getName() == "type_identifier": # [typedef] enum X {} Y; # Use X as name - origname = nimState.getNodeVal(node.getAtom()) + origname = gState.getNodeVal(node.getAtom()) elif node.getName() == "type_definition" and node.len > 1: # typedef enum {} Y; # Use Y as name - origname = nimState.getNodeVal(node[1].getAtom()) + origname = gState.getNodeVal(node[1].getAtom()) offset = 1 if origname.nBl: - name = nimState.getIdentifier(origname, nskType) + name = gState.getIdentifier(origname, nskType) else: # enum {}; # Nameless so create a name - name = nimState.getUniqueIdentifier("Enum") + name = gState.getUniqueIdentifier("Enum") if name.Bl: # Name skipped or overridden since blank let - eoverride = nimState.getOverrideOrSkip(node, origname, nskType) + eoverride = gState.getOverrideOrSkip(node, origname, nskType) if not eoverride.isNil: - nimState.typeSection.add eoverride - elif nimState.addNewIdentifer(name): + gState.typeSection.add eoverride + elif gState.addNewIdentifer(name): # Add enum definition and helpers - nimState.enumSection.add nimState.parseString(&"defineEnum({name})") + gState.enumSection.add gState.parseString(&"defineEnum({name})") # Create const for fields var @@ -1421,7 +1421,7 @@ proc addEnum(nimState: NimState, node: TSNode) = if en.getName() == "comment": continue let - fname = nimState.getIdentifier(nimState.getNodeVal(en.getAtom()), nskEnumField) + fname = gState.getIdentifier(gState.getNodeVal(en.getAtom()), nskEnumField) if fname.nBl: var fval = "" @@ -1434,10 +1434,10 @@ proc addEnum(nimState: NimState, node: TSNode) = if en.len > 1 and en[1].getName() in gEnumVals: # Explicit value - fval = "(" & nimState.getNimExpression(nimState.getNodeVal(en[1]), name) & ")." & name + fval = "(" & gState.getNimExpression(gState.getNodeVal(en[1]), name) & ")." & name # Cannot use newConstDef() since parseString(fval) adds backticks to and/or - nimState.constSection.add nimState.parseString(&"const {fname}* = {fval}")[0][0] + gState.constSection.add gState.parseString(&"const {fname}* = {fval}")[0][0] fnames.incl fname @@ -1445,25 +1445,25 @@ proc addEnum(nimState: NimState, node: TSNode) = # Add fields to list of consts after processing enum so that we don't cast # enum field to itself - nimState.constIdentifiers.incl fnames + gState.constIdentifiers.incl fnames # Add other names if node.getName() == "type_definition" and node.len > 1: - nimState.addTypeTyped(node, ftname = name, offset = offset) + gState.addTypeTyped(node, ftname = name, offset = offset) -proc addProcVar(nimState: NimState, node, rnode: TSNode) = +proc addProcVar(gState: State, node, rnode: TSNode) = # Add a proc variable decho("addProcVar()") let # node = identifier = name - identDefs = nimState.newXIdent(node, kind = nskVar, istype = true) + identDefs = gState.newXIdent(node, kind = nskVar, istype = true) if not identDefs.isNil: let name = identDefs.getIdentName() - # origname = nimState.getNodeVal(node.getAtom()) + # origname = gState.getNodeVal(node.getAtom()) - procTy = nimState.getTypeProc(name, node, rnode) + procTy = gState.getTypeProc(name, node, rnode) identDefs.add procTy identDefs.add newNode(nkEmpty) @@ -1505,11 +1505,11 @@ proc addProcVar(nimState: NimState, node, rnode: TSNode) = # ) # nkVarSection.add - nimState.varSection.add identDefs + gState.varSection.add identDefs - nimState.printDebug(identDefs) + gState.printDebug(identDefs) -proc addProc(nimState: NimState, node, rnode: TSNode) = +proc addProc(gState: State, node, rnode: TSNode) = # Add a proc # # `node` is the `nth` child of (declaration) @@ -1517,19 +1517,19 @@ proc addProc(nimState: NimState, node, rnode: TSNode) = decho("addProc()") let # node = identifier = name - ident = nimState.newXIdent(node, kind = nskProc) + ident = gState.newXIdent(node, kind = nskProc) if not ident.isNil: let # Only need the ident tree, not nkTypeDef parent name = ident.getIdentName() - origname = nimState.getNodeVal(node.getAtom()) + origname = gState.getNodeVal(node.getAtom()) # node could have nested pointers tcount = node.getPtrCount() # rnode = identifier = return type name - (rname, _, rinfo) = nimState.getNameInfo(rnode.getAtom(), nskType, parent = name) + (rname, _, rinfo) = gState.getNameInfo(rnode.getAtom(), nskType, parent = name) # Parameter list plist = node.anyChildInTree("parameter_list") @@ -1574,56 +1574,56 @@ proc addProc(nimState: NimState, node, rnode: TSNode) = # void func(..) newNode(nkEmpty) else: - nimState.getIdent(rname, rinfo, exported = false) + gState.getIdent(rname, rinfo, exported = false) if tcount > 0: - retType = nimState.newPtrTree(tcount, retType) + retType = gState.newPtrTree(tcount, retType) # Proc with return type and params - procDef.add nimState.newFormalParams(name, plist, retType) + procDef.add gState.newFormalParams(name, plist, retType) # Pragmas let prident = if name != origname: # Explicit {.importc: "origname".} - nimState.newPragma(node, "importc", newStrNode(nkStrLit, origname)) + gState.newPragma(node, "importc", newStrNode(nkStrLit, origname)) else: # {.impnameC.} shortcut - nimState.newPragma(node, nimState.impShort & "C") + gState.newPragma(node, gState.impShort & "C") # Detect ... and add {.varargs.} pvarargs = plist.getVarargs() # Need {.convention.} and {.header.} if applicable if name != origname: - if nimState.includeHeader(): + if gState.isIncludeHeader(): # {.impnameHC.} shortcut - nimState.addPragma(node, prident, nimState.impShort & "HC") + gState.addPragma(node, prident, gState.impShort & "HC") else: # {.convention.} - nimState.addPragma(node, prident, nimState.gState.convention) + gState.addPragma(node, prident, gState.convention) - if nimState.gState.dynlib.nBl: + if gState.dynlib.nBl: # {.dynlib.} for DLLs - nimState.addPragma(node, prident, "dynlib", nimState.getIdent(nimState.gState.dynlib)) + gState.addPragma(node, prident, "dynlib", gState.getIdent(gState.dynlib)) if pvarargs: # Add {.varargs.} for ... - nimState.addPragma(node, prident, "varargs") + gState.addPragma(node, prident, "varargs") procDef.add prident procDef.add newNode(nkEmpty) procDef.add newNode(nkEmpty) # nkProcSection.add - nimState.procSection.add procDef + gState.procSection.add procDef - nimState.printDebug(procDef) + gState.printDebug(procDef) -proc addDecl(nimState: NimState, node: TSNode) = +proc addDecl(gState: State, node: TSNode) = # Add a declaration decho("addDecl()") - nimState.printDebug(node) + gState.printDebug(node) let start = getStartAtom(node) @@ -1633,58 +1633,58 @@ proc addDecl(nimState: NimState, node: TSNode) = # Proc declaration - var or actual proc if node[i].getAtom().getPxName(1) == "pointer_declarator": # proc var - nimState.addProcVar(node[i], node[start]) + gState.addProcVar(node[i], node[start]) else: # proc - nimState.addProc(node[i], node[start]) + gState.addProc(node[i], node[start]) else: # Regular var discard -proc addDef(nimState: NimState, node: TSNode) = +proc addDef(gState: State, node: TSNode) = # Wrap static inline definition if {.header.} mode is specified # # Without {.header.} the definition will not be available to the C compiler # and will fail at link time decho("addDef()") - nimState.printDebug(node) + gState.printDebug(node) let start = getStartAtom(node) if node[start+1].getName() == "function_declarator": - if nimState.includeHeader(): - nimState.addProc(node[start+1], node[start]) + if gState.isIncludeHeader(): + gState.addProc(node[start+1], node[start]) else: - necho &"\n# proc '$1' skipped - static inline procs require 'includeHeader'" % - nimState.getNodeVal(node[start+1].getAtom()) + gecho &"\n# proc '$1' skipped - static inline procs require 'includeHeader'" % + gState.getNodeVal(node[start+1].getAtom()) -proc processNode(nimState: NimState, node: TSNode): bool = +proc processNode(gState: State, node: TSNode): bool = result = true case node.getName() of "preproc_def": - nimState.addConst(node) + gState.addConst(node) of "type_definition": if node.len > 0 and node[0].getName() == "enum_specifier": - nimState.addEnum(node) + gState.addEnum(node) elif node.len > 0 and node[0].getName() == "union_specifier": - nimState.addType(node, union = true) + gState.addType(node, union = true) else: - nimState.addType(node) + gState.addType(node) of "struct_specifier": - nimState.addType(node) + gState.addType(node) of "union_specifier": - nimState.addType(node, union = true) + gState.addType(node, union = true) of "enum_specifier": - nimState.addEnum(node) + gState.addEnum(node) of "declaration": - nimState.addDecl(node) + gState.addDecl(node) of "function_definition": - nimState.addDef(node) + gState.addDef(node) else: # Unknown result = false -proc searchTree(nimState: NimState, root: TSNode) = +proc searchTree(gState: State, root: TSNode) = # Search AST generated by tree-sitter for recognized elements var node = root @@ -1694,7 +1694,7 @@ proc searchTree(nimState: NimState, root: TSNode) = while true: if not node.isNil and depth > -1: - processed = nimState.processNode(node) + processed = gState.processNode(node) else: break @@ -1721,7 +1721,7 @@ proc searchTree(nimState: NimState, root: TSNode) = if node == root: break -proc setupPragmas(nimState: NimState, root: TSNode, fullpath: string) = +proc setupPragmas(gState: State, root: TSNode, fullpath: string) = # Create shortcut pragmas to reduce clutter var hdrPragma: PNode @@ -1730,41 +1730,41 @@ proc setupPragmas(nimState: NimState, root: TSNode, fullpath: string) = impConvPragma = newNode(nkPragma) # {.pragma: impname, importc.} - nimState.addPragma(root, impPragma, "pragma", nimState.getIdent(nimState.impShort)) - nimState.addPragma(root, impPragma, "importc") + gState.addPragma(root, impPragma, "pragma", gState.getIdent(gState.impShort)) + gState.addPragma(root, impPragma, "importc") - if nimState.includeHeader(): + if gState.isIncludeHeader(): # Path to header const - nimState.constSection.add nimState.newConstDef( - root, fname = nimState.currentHeader, fval = '"' & fullpath & '"') + gState.constSection.add gState.newConstDef( + root, fname = gState.currentHeader, fval = '"' & fullpath & '"') # {.pragma: impnameH, header: "xxx".} for types when name != origname - hdrPragma = nimState.newPragma(root, "pragma", nimState.getIdent(nimState.impShort & "H")) - nimState.addPragma(root, hdrPragma, "header", nimState.getIdent(nimState.currentHeader)) + hdrPragma = gState.newPragma(root, "pragma", gState.getIdent(gState.impShort & "H")) + gState.addPragma(root, hdrPragma, "header", gState.getIdent(gState.currentHeader)) # Add {.impnameH.} to {.impname.} - nimState.addPragma(root, impPragma, nimState.impShort & "H") + gState.addPragma(root, impPragma, gState.impShort & "H") # {.pragma: impnameHC, impnameH, convention.} for procs when name != origname - hdrConvPragma = nimState.newPragma(root, "pragma", nimState.getIdent(nimState.impShort & "HC")) - nimState.addPragma(root, hdrConvPragma, nimState.impShort & "H") - nimState.addPragma(root, hdrConvPragma, nimState.gState.convention) + hdrConvPragma = gState.newPragma(root, "pragma", gState.getIdent(gState.impShort & "HC")) + gState.addPragma(root, hdrConvPragma, gState.impShort & "H") + gState.addPragma(root, hdrConvPragma, gState.convention) # {.pragma: impnameC, impname, convention.} for procs - nimState.addPragma(root, impConvPragma, "pragma", nimState.getIdent(nimState.impShort & "C")) - nimState.addPragma(root, impConvPragma, nimState.impShort) - nimState.addPragma(root, impConvPragma, nimState.gState.convention) + gState.addPragma(root, impConvPragma, "pragma", gState.getIdent(gState.impShort & "C")) + gState.addPragma(root, impConvPragma, gState.impShort) + gState.addPragma(root, impConvPragma, gState.convention) - if nimState.gState.dynlib.nBl: + if gState.dynlib.nBl: # {.dynlib.} for DLLs - nimState.addPragma(root, impConvPragma, "dynlib", nimState.getIdent(nimState.gState.dynlib)) + gState.addPragma(root, impConvPragma, "dynlib", gState.getIdent(gState.dynlib)) # Add all pragma shortcuts to output if not hdrPragma.isNil: - nimState.pragmaSection.add hdrPragma - nimState.pragmaSection.add hdrConvPragma - nimState.pragmaSection.add impPragma - nimState.pragmaSection.add impConvPragma + gState.pragmaSection.add hdrPragma + gState.pragmaSection.add hdrConvPragma + gState.pragmaSection.add impPragma + gState.pragmaSection.add impConvPragma proc printNimHeader*(gState: State) = # Top level output with context info @@ -1780,49 +1780,47 @@ import nimterop/types proc printNim*(gState: State, fullpath: string, root: TSNode) = # Generate Nim from tree-sitter AST root node let - nimState = new(NimState) fp = fullpath.replace("\\", "/") # Track identifiers already rendered and corresponding PNodes - nimState.identifiers = newTable[string, string]() - nimState.identifierNodes = newTable[string, PNode]() + gState.identifiers = newTable[string, string]() + gState.identifierNodes = newTable[string, PNode]() # toast objects - nimState.gState = gState - nimState.currentHeader = getCurrentHeader(fullpath) - nimState.impShort = nimState.currentHeader.replace("header", "imp") - nimState.sourceFile = fullpath + gState.currentHeader = getCurrentHeader(fullpath) + gState.impShort = gState.currentHeader.replace("header", "imp") + gState.sourceFile = fullpath # Nim compiler objects - nimState.identCache = newIdentCache() - nimState.config = newConfigRef() - nimstate.graph = newModuleGraph(nimState.identCache, nimState.config) + gState.identCache = newIdentCache() + gState.config = newConfigRef() + gState.graph = newModuleGraph(gState.identCache, gState.config) # Initialize all section PNodes - nimState.constSection = newNode(nkConstSection) - nimState.enumSection = newNode(nkStmtList) - nimState.pragmaSection = newNode(nkStmtList) - nimState.procSection = newNode(nkStmtList) - nimState.typeSection = newNode(nkTypeSection) - nimState.varSection = newNode(nkVarSection) + gState.constSection = newNode(nkConstSection) + gState.enumSection = newNode(nkStmtList) + gState.pragmaSection = newNode(nkStmtList) + gState.procSection = newNode(nkStmtList) + gState.typeSection = newNode(nkTypeSection) + gState.varSection = newNode(nkVarSection) # Setup pragmas - nimState.setupPragmas(root, fp) + gState.setupPragmas(root, fp) # Search root node and render Nim - nimState.searchTree(root) + gState.searchTree(root) # Add any unused cOverride symbols to output - nimState.addAllOverrideFinal() + gState.addAllOverrideFinal() # Create output to Nim using Nim compiler renderer var tree = newNode(nkStmtList) - tree.add nimState.enumSection - tree.add nimState.constSection - tree.add nimState.pragmaSection - tree.add nimState.typeSection - tree.add nimState.varSection - tree.add nimState.procSection + tree.add gState.enumSection + tree.add gState.constSection + tree.add gState.pragmaSection + tree.add gState.typeSection + tree.add gState.varSection + tree.add gState.procSection gecho tree.renderTree() diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 654c7f3..1cdd2ff 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -113,32 +113,32 @@ proc checkIdentifier(name, kind, parent, origName: string) = if parent.nBl: doAssert name.nBl, &"Blank identifier, originally '{parentStr}{origName}' ({kind}), cannot be empty" -proc getIdentifier*(nimState: NimState, name: string, kind: NimSymKind, parent=""): string = +proc getIdentifier*(gState: State, name: string, kind: NimSymKind, parent=""): string = doAssert name.nBl, "Blank identifier error" - if name notin nimState.gState.symOverride or parent.nBl: - if nimState.gState.onSymbol != nil: + if name notin gState.symOverride or parent.nBl: + if gState.onSymbol != nil: # Use onSymbol from plugin provided by user var sym = Symbol(name: name, parent: parent, kind: kind) - nimState.gState.onSymbol(sym) + gState.onSymbol(sym) result = sym.name else: result = name # Strip out --prefix from CLI if specified - for str in nimState.gState.prefix: + for str in gState.prefix: if result.startsWith(str): result = result[str.len .. ^1] # Strip out --suffix from CLI if specified - for str in nimState.gState.suffix: + for str in gState.suffix: if result.endsWith(str): result = result[0 .. ^(str.len+1)] # --replace from CLI if specified - for name, value in nimState.gState.replace.pairs: + for name, value in gState.replace.pairs: if name.len > 1 and name[0] == '@': result = result.replace(re(name[1 .. ^1]), value) else: @@ -153,58 +153,58 @@ proc getIdentifier*(nimState: NimState, name: string, kind: NimSymKind, parent=" # Skip identifier since in symOverride result = "" -proc getUniqueIdentifier*(nimState: NimState, prefix = ""): string = +proc getUniqueIdentifier*(gState: State, prefix = ""): string = var - name = prefix & "_" & nimState.sourceFile.extractFilename().multiReplace([(".", ""), ("-", "")]) + name = prefix & "_" & gState.sourceFile.extractFilename().multiReplace([(".", ""), ("-", "")]) nimName = name[0] & name[1 .. ^1].replace("_", "").toLowerAscii count = 1 - while (nimName & $count) in nimState.identifiers: + while (nimName & $count) in gState.identifiers: count += 1 return name & $count -proc addNewIdentifer*(nimState: NimState, name: string, override = false): bool = - if override or name notin nimState.gState.symOverride: +proc addNewIdentifer*(gState: State, name: string, override = false): bool = + if override or name notin gState.symOverride: let nimName = name[0] & name[1 .. ^1].replace("_", "").toLowerAscii - if nimState.identifiers.hasKey(nimName): - doAssert name == nimState.identifiers[nimName], + if gState.identifiers.hasKey(nimName): + doAssert name == gState.identifiers[nimName], &"Identifier '{name}' is a stylistic duplicate of identifier " & - &"'{nimState.identifiers[nimName]}', use 'cPlugin:onSymbol()' to rename" + &"'{gState.identifiers[nimName]}', use 'cPlugin:onSymbol()' to rename" result = false else: - nimState.identifiers[nimName] = name + gState.identifiers[nimName] = name result = true # Overrides related -proc getOverride*(nimState: NimState, name: string, kind: NimSymKind): string = +proc getOverride*(gState: State, name: string, kind: NimSymKind): string = # Get cOverride for identifier `name` of `kind` if defined doAssert name.nBl, "Blank identifier error" - if nimState.gState.onSymbolOverride != nil: + if gState.onSymbolOverride != nil: var - nname = nimState.getIdentifier(name, kind, "Override") + nname = gState.getIdentifier(name, kind, "Override") sym = Symbol(name: nname, kind: kind) if nname.nBl: - nimState.gState.onSymbolOverride(sym) + gState.onSymbolOverride(sym) - if sym.override.nBl and nimState.addNewIdentifer(nname, override = true): + if sym.override.nBl and gState.addNewIdentifer(nname, override = true): result = sym.override if kind != nskProc: result = result.replace(re"(?m)^(.*?)$", " $1") -proc getOverrideFinal*(nimState: NimState, kind: NimSymKind): string = +proc getOverrideFinal*(gState: State, kind: NimSymKind): string = # Get all unused cOverride symbols of `kind` let typ = $kind - if nimState.gState.onSymbolOverrideFinal != nil: - for i in nimState.gState.onSymbolOverrideFinal(typ): - result &= "\n" & nimState.getOverride(i, kind) + if gState.onSymbolOverrideFinal != nil: + for i in gState.onSymbolOverrideFinal(typ): + result &= "\n" & gState.getOverride(i, kind) proc getKeyword*(kind: NimSymKind): string = # Convert `kind` into a Nim keyword @@ -232,9 +232,6 @@ proc getNodeVal*(gState: State, node: TSNode): string = if not node.isNil: return gState.code[node.tsNodeStartByte() .. node.tsNodeEndByte()-1].strip() -proc getNodeVal*(nimState: NimState, node: TSNode): string = - nimState.gState.getNodeVal(node) - proc getAtom*(node: TSNode): TSNode = if not node.isNil: # Get child node which is topmost atom @@ -428,8 +425,8 @@ proc printLisp*(gState: State, root: TSNode): string = proc getCommented*(str: string): string = "\n# " & str.strip().replace("\n", "\n# ") -proc printTree*(nimState: NimState, pnode: PNode, offset = ""): string = - if nimState.gState.debug and pnode.kind != nkNone: +proc printTree*(gState: State, pnode: PNode, offset = ""): string = + if gState.debug and pnode.kind != nkNone: result &= "\n# " & offset & $pnode.kind & "(" case pnode.kind of nkCharLit: @@ -447,7 +444,7 @@ proc printTree*(nimState: NimState, pnode: PNode, offset = ""): string = else: if pnode.sons.len != 0: for i in 0 ..< pnode.sons.len: - result &= nimState.printTree(pnode.sons[i], offset & " ") + result &= gState.printTree(pnode.sons[i], offset & " ") if i != pnode.sons.len - 1: result &= "," result &= "\n# " & offset & ")" @@ -456,34 +453,34 @@ proc printTree*(nimState: NimState, pnode: PNode, offset = ""): string = if offset.len == 0: result &= "\n" -proc printDebug*(nimState: NimState, node: TSNode) = - if nimState.gState.debug: - necho ("Input => " & nimState.getNodeVal(node)).getCommented() & "\n" & - nimState.gState.printLisp(node).getCommented() +proc printDebug*(gState: State, node: TSNode) = + if gState.debug: + gecho ("Input => " & gState.getNodeVal(node)).getCommented() & "\n" & + gState.printLisp(node).getCommented() -proc printDebug*(nimState: NimState, pnode: PNode) = - if nimState.gState.debug: - necho ("Output => " & $pnode).getCommented() & "\n" & - nimState.printTree(pnode) +proc printDebug*(gState: State, pnode: PNode) = + if gState.debug: + gecho ("Output => " & $pnode).getCommented() & "\n" & + gState.printTree(pnode) # Compiler shortcuts -proc getDefaultLineInfo*(nimState: NimState): TLineInfo = - result = newLineInfo(nimState.config, nimState.sourceFile.AbsoluteFile, 0, 0) +proc getDefaultLineInfo*(gState: State): TLineInfo = + result = newLineInfo(gState.config, gState.sourceFile.AbsoluteFile, 0, 0) -proc getLineInfo*(nimState: NimState, node: TSNode): TLineInfo = +proc getLineInfo*(gState: State, node: TSNode): TLineInfo = # Get Nim equivalent line:col info from node let - (line, col) = nimState.gState.getLineCol(node) + (line, col) = gState.getLineCol(node) - result = newLineInfo(nimState.config, nimState.sourceFile.AbsoluteFile, line, col) + result = newLineInfo(gState.config, gState.sourceFile.AbsoluteFile, line, col) -proc getIdent*(nimState: NimState, name: string, info: TLineInfo, exported = true): PNode = +proc getIdent*(gState: State, name: string, info: TLineInfo, exported = true): PNode = if name.nBl: # Get ident PNode for name + info let - exp = getIdent(nimState.identCache, "*") - ident = getIdent(nimState.identCache, name) + exp = getIdent(gState.identCache, "*") + ident = getIdent(gState.identCache, name) if exported: result = newNode(nkPostfix) @@ -492,8 +489,8 @@ proc getIdent*(nimState: NimState, name: string, info: TLineInfo, exported = tru else: result = newIdentNode(ident, info) -proc getIdent*(nimState: NimState, name: string): PNode = - nimState.getIdent(name, nimState.getDefaultLineInfo(), exported = false) +proc getIdent*(gState: State, name: string): PNode = + gState.getIdent(name, gState.getDefaultLineInfo(), exported = false) proc getIdentName*(node: PNode): string = if not node.isNil: @@ -503,15 +500,15 @@ proc getIdentName*(node: PNode): string = if result.Bl and node.len > 0: result = node[0].getIdentName() -proc getNameInfo*(nimState: NimState, node: TSNode, kind: NimSymKind, parent = ""): +proc getNameInfo*(gState: State, node: TSNode, kind: NimSymKind, parent = ""): tuple[name, origname: string, info: TLineInfo] = # Shortcut to get identifier name and info (node value and line:col) - result.origname = nimState.getNodeVal(node) - result.name = nimState.getIdentifier(result.origname, kind, parent) + result.origname = gState.getNodeVal(node) + result.name = gState.getIdentifier(result.origname, kind, parent) if result.name.nBl: if kind == nskType: result.name = result.name.getType() - result.info = nimState.getLineInfo(node) + result.info = gState.getLineInfo(node) proc getCurrentHeader*(fullpath: string): string = ("header" & fullpath.splitFile().name.multiReplace([(".", ""), ("-", "")])) @@ -644,7 +641,7 @@ proc getAstChildByName*(ast: ref Ast, name: string): ref Ast = if ast.children.len == 1 and ast.children[0].name == ".": return ast.children[0] -proc getNimExpression*(nimState: NimState, expr: string, name = ""): string = +proc getNimExpression*(gState: State, expr: string, name = ""): string = # Convert C/C++ expression into Nim - cast identifiers to `name` if specified var clean = expr.multiReplace([("\n", " "), ("\r", "")]) @@ -691,8 +688,8 @@ proc getNimExpression*(nimState: NimState, expr: string, name = ""): string = if ident.nBl: # Issue #178 if ident != "_": - ident = nimState.getIdentifier(ident, nskConst, name) - if name.nBl and ident in nimState.constIdentifiers: + ident = gState.getIdentifier(ident, nskConst, name) + if name.nBl and ident in gState.constIdentifiers: ident = ident & "." & name result &= ident ident = "" @@ -708,15 +705,15 @@ proc getSplitComma*(joined: seq[string]): seq[string] = for i in joined: result = result.concat(i.split(",")) -template includeHeader*(nimState: NimState): bool = - nimState.gState.dynlib.Bl and nimState.gState.includeHeader +template isIncludeHeader*(gState: State): bool = + gState.dynlib.Bl and gState.includeHeader -proc getComments*(nimState: NimState, strip = false): string = - if not nimState.gState.nocomments and nimState.commentStr.nBl: - result = "\n" & nimState.commentStr +proc getComments*(gState: State, strip = false): string = + if not gState.nocomments and gState.commentStr.nBl: + result = "\n" & gState.commentStr if strip: result = result.replace("\n ", "\n") - nimState.commentStr = "" + gState.commentStr = "" proc dll*(path: string): string = let diff --git a/nimterop/globals.nim b/nimterop/globals.nim index 47157d8..f159124 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -49,7 +49,7 @@ type recursive*: bool children*: seq[ref Ast] when not declared(CIMPORT): - tonim*: proc (ast: ref Ast, node: TSNode, nimState: NimState) + tonim*: proc (ast: ref Ast, node: TSNode, gState: State) regex*: Regex AstTable {.used.} = TableRef[string, seq[ref Ast]] @@ -70,7 +70,6 @@ type outputHandle*: File - NimState {.used.} = ref object # All symbols that have been declared so far indexed by nimName identifiers*: TableRef[string, string] @@ -92,8 +91,6 @@ type # Craeted symbols to generated AST - forward declaration tracking identifierNodes*: TableRef[string, PNode] - gState*: State - currentHeader*, impShort*, sourceFile*: string data*: seq[tuple[name, val: string]] @@ -113,8 +110,7 @@ template Bl(s: typed): untyped {.used.} = (s.len == 0) when not declared(CIMPORT): - export gAtoms, gExpressions, gEnumVals, Kind, Ast, AstTable, State, NimState, - nBl, Bl + export gAtoms, gExpressions, gEnumVals, Kind, Ast, AstTable, State, nBl, Bl # Redirect output to file when required template gecho*(args: string) {.dirty.} = @@ -123,11 +119,6 @@ when not declared(CIMPORT): else: gState.outputHandle.writeLine(args) - template necho*(args: string) {.dirty.} = - when not declared(gState): - let gState = nimState.gState - gecho args - template decho*(str: untyped): untyped = - if nimState.gState.debug: - necho str.getCommented() + if gState.debug: + gecho str.getCommented() diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index 8e1d290..0d804d0 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -5,7 +5,7 @@ import regex import "."/[ast, getters, globals, lisp, treesitter/api] type - Grammar = seq[tuple[grammar: string, call: proc(ast: ref Ast, node: TSNode, nimState: NimState) {.nimcall.}]] + Grammar = seq[tuple[grammar: string, call: proc(ast: ref Ast, node: TSNode, gState: State) {.nimcall.}]] proc getPtrType(str: string): string = result = case str: @@ -39,26 +39,26 @@ proc initGrammar(): Grammar = (preproc_arg) ) """, - proc (ast: ref Ast, node: TSNode, nimState: NimState) = - if nimState.gState.debug: - nimState.debugStr &= "\n# define X Y" + proc (ast: ref Ast, node: TSNode, gState: State) = + if gState.debug: + gState.debugStr &= "\n# define X Y" let - name = nimState.data[0].val - nname = nimState.getIdentifier(name, nskConst) - val = nimState.data[1].val.getLit() + name = gState.data[0].val + nname = gState.getIdentifier(name, nskConst) + val = gState.data[1].val.getLit() if not nname.nBl: let - override = nimState.getOverride(name, nskConst) + override = gState.getOverride(name, nskConst) if override.nBl: - nimState.constStr &= &"{nimState.getComments()}\n{override}" + gState.constStr &= &"{gState.getComments()}\n{override}" else: - nimState.constStr &= &"{nimState.getComments()}\n # Const '{name}' skipped" - if nimState.gState.debug: - nimState.skipStr &= &"\n{nimState.getNodeVal(node)}" - elif val.nBl and nimState.addNewIdentifer(nname): - nimState.constStr &= &"{nimState.getComments()}\n {nname}* = {val}" + gState.constStr &= &"{gState.getComments()}\n # Const '{name}' skipped" + if gState.debug: + gState.skipStr &= &"\n{gState.getNodeVal(node)}" + elif val.nBl and gState.addNewIdentifer(nname): + gState.constStr &= &"{gState.getComments()}\n {nname}* = {val}" )) let @@ -125,25 +125,25 @@ proc initGrammar(): Grammar = """ template funcParamCommon(fname, pname, ptyp, pptr, pout, count, i, flen: untyped): untyped = - ptyp = nimState.getIdentifier(nimState.data[i].val, nskType, fname).getType() + ptyp = gState.getIdentifier(gState.data[i].val, nskType, fname).getType() pptr = "" - while i+1 < nimState.data.len and nimState.data[i+1].name == "pointer_declarator": + while i+1 < gState.data.len and gState.data[i+1].name == "pointer_declarator": pptr &= "ptr " i += 1 - if i+1 < nimState.data.len and nimState.data[i+1].name == "identifier": - pname = nimState.getIdentifier(nimState.data[i+1].val, nskParam, fname) + if i+1 < gState.data.len and gState.data[i+1].name == "identifier": + pname = gState.getIdentifier(gState.data[i+1].val, nskParam, fname) i += 2 else: pname = "a" & $count count += 1 i += 1 - if i < nimState.data.len and nimState.data[i].name in ["identifier", "number_literal"]: - flen = nimState.data[i].val - if nimState.data[i].name == "identifier": - flen = nimState.getIdentifier(flen, nskConst, fname) + if i < gState.data.len and gState.data[i].name in ["identifier", "number_literal"]: + flen = gState.data[i].val + if gState.data[i].name == "identifier": + flen = gState.getIdentifier(flen, nskConst, fname) pout &= &"{pname}: array[{flen}, {getPtrType(pptr&ptyp)}], " i += 1 @@ -172,13 +172,13 @@ proc initGrammar(): Grammar = {funcGrammar} ) """, - proc (ast: ref Ast, node: TSNode, nimState: NimState) = - if nimState.gState.debug: - nimState.debugStr &= "\n# typedef X Y" + proc (ast: ref Ast, node: TSNode, gState: State) = + if gState.debug: + gState.debugStr &= "\n# typedef X Y" var i = 0 - typ = nimState.getIdentifier(nimState.data[i].val, nskType, "Parent").getType() + typ = gState.getIdentifier(gState.data[i].val, nskType, "Parent").getType() name = "" nname = "" tptr = "" @@ -186,8 +186,8 @@ proc initGrammar(): Grammar = pragmas: seq[string] = @[] i += 1 - while i < nimState.data.len and "pointer" in nimState.data[i].name: - case nimState.data[i].name: + while i < gState.data.len and "pointer" in gState.data[i].name: + case gState.data[i].name: of "pointer_declarator": tptr &= "ptr " i += 1 @@ -195,32 +195,32 @@ proc initGrammar(): Grammar = aptr &= "ptr " i += 1 - if i < nimState.data.len: - name = nimState.data[i].val - nname = nimState.getIdentifier(name, nskType) + if i < gState.data.len: + name = gState.data[i].val + nname = gState.getIdentifier(name, nskType) i += 1 - if nimState.includeHeader(): - pragmas.add nimState.getImportC(name, nname) + if gState.isIncludeHeader(): + pragmas.add gState.getImportC(name, nname) let - pragma = nimState.getPragma(pragmas) + pragma = gState.getPragma(pragmas) if not nname.nBl: let - override = nimState.getOverride(name, nskType) + override = gState.getOverride(name, nskType) if override.nBl: - nimState.typeStr &= &"{nimState.getComments()}\n{override}" - elif nname notin gTypeMap and typ.nBl and nimState.addNewIdentifer(nname): - if i < nimState.data.len and nimState.data[^1].name == "function_declarator": + gState.typeStr &= &"{gState.getComments()}\n{override}" + elif nname notin gTypeMap and typ.nBl and gState.addNewIdentifer(nname): + if i < gState.data.len and gState.data[^1].name == "function_declarator": var fname = nname pout, pname, ptyp, pptr = "" count = 1 flen = "" - while i < nimState.data.len: - if nimState.data[i].name == "function_declarator": + while i < gState.data.len: + if gState.data[i].name == "function_declarator": break funcParamCommon(fname, pname, ptyp, pptr, pout, count, i, flen) @@ -229,34 +229,34 @@ proc initGrammar(): Grammar = pout = pout[0 .. ^3] if tptr.nBl or typ != "object": - nimState.typeStr &= &"{nimState.getComments()}\n {nname}*{pragma} = proc({pout}): {getPtrType(tptr&typ)} {{.cdecl.}}" + gState.typeStr &= &"{gState.getComments()}\n {nname}*{pragma} = proc({pout}): {getPtrType(tptr&typ)} {{.cdecl.}}" else: - nimState.typeStr &= &"{nimState.getComments()}\n {nname}*{pragma} = proc({pout}) {{.cdecl.}}" + gState.typeStr &= &"{gState.getComments()}\n {nname}*{pragma} = proc({pout}) {{.cdecl.}}" else: - if i < nimState.data.len and nimState.data[i].name in ["identifier", "number_literal"]: + if i < gState.data.len and gState.data[i].name in ["identifier", "number_literal"]: var - flen = nimState.data[i].val - if nimState.data[i].name == "identifier": - flen = nimState.getIdentifier(flen, nskConst, nname) + flen = gState.data[i].val + if gState.data[i].name == "identifier": + flen = gState.getIdentifier(flen, nskConst, nname) - nimState.typeStr &= &"{nimState.getComments()}\n {nname}*{pragma} = {aptr}array[{flen}, {getPtrType(tptr&typ)}]" + gState.typeStr &= &"{gState.getComments()}\n {nname}*{pragma} = {aptr}array[{flen}, {getPtrType(tptr&typ)}]" else: if nname == typ: pragmas.add "incompleteStruct" let - pragma = nimState.getPragma(pragmas) - nimState.typeStr &= &"{nimState.getComments()}\n {nname}*{pragma} = object" + pragma = gState.getPragma(pragmas) + gState.typeStr &= &"{gState.getComments()}\n {nname}*{pragma} = object" else: - nimState.typeStr &= &"{nimState.getComments()}\n {nname}*{pragma} = {getPtrType(tptr&typ)}" + gState.typeStr &= &"{gState.getComments()}\n {nname}*{pragma} = {getPtrType(tptr&typ)}" )) - proc pDupTypeCommon(nname: string, fend: int, nimState: NimState, isEnum=false) = - if nimState.gState.debug: - nimState.debugStr &= "\n# pDupTypeCommon()" + proc pDupTypeCommon(nname: string, fend: int, gState: State, isEnum=false) = + if gState.debug: + gState.debugStr &= "\n# pDupTypeCommon()" var - dname = nimState.data[^1].val - ndname = nimState.getIdentifier(dname, nskType) + dname = gState.data[^1].val + ndname = gState.getIdentifier(dname, nskType) dptr = if fend == 2: "ptr " @@ -265,21 +265,21 @@ proc initGrammar(): Grammar = if ndname.nBl and ndname != nname: if isEnum: - if nimState.addNewIdentifer(ndname): - nimState.enumStr &= &"{nimState.getComments(true)}\ntype {ndname}* = {dptr}{nname}" + if gState.addNewIdentifer(ndname): + gState.enumStr &= &"{gState.getComments(true)}\ntype {ndname}* = {dptr}{nname}" else: - if nimState.addNewIdentifer(ndname): + if gState.addNewIdentifer(ndname): let - pragma = nimState.getPragma(nimState.getImportc(dname, ndname), "bycopy") - nimState.typeStr &= - &"{nimState.getComments()}\n {ndname}*{pragma} = {dptr}{nname}" + pragma = gState.getPragma(gState.getImportc(dname, ndname), "bycopy") + gState.typeStr &= + &"{gState.getComments()}\n {ndname}*{pragma} = {dptr}{nname}" - proc pStructCommon(ast: ref Ast, node: TSNode, name: string, fstart, fend: int, nimState: NimState) = - if nimState.gState.debug: - nimState.debugStr &= "\n# pStructCommon" + proc pStructCommon(ast: ref Ast, node: TSNode, name: string, fstart, fend: int, gState: State) = + if gState.debug: + gState.debugStr &= "\n# pStructCommon" var - nname = nimState.getIdentifier(name, nskType) + nname = gState.getIdentifier(name, nskType) prefix = "" union = "" @@ -307,25 +307,25 @@ proc initGrammar(): Grammar = if not nname.nBl: let - override = nimState.getOverride(name, nskType) + override = gState.getOverride(name, nskType) if override.nBl: - nimState.typeStr &= &"{nimState.getComments()}\n{override}" - elif nimState.addNewIdentifer(nname): - if nimState.data.len == 1: - nimState.typeStr &= &"{nimState.getComments()}\n {nname}* {{.bycopy{union}.}} = object" + gState.typeStr &= &"{gState.getComments()}\n{override}" + elif gState.addNewIdentifer(nname): + if gState.data.len == 1: + gState.typeStr &= &"{gState.getComments()}\n {nname}* {{.bycopy{union}.}} = object" else: var pragmas: seq[string] = @[] - if nimState.includeHeader(): - pragmas.add nimState.getImportC(prefix & name, nname) + if gState.isIncludeHeader(): + pragmas.add gState.getImportC(prefix & name, nname) pragmas.add "bycopy" if union.nBl: pragmas.add "union" let - pragma = nimState.getPragma(pragmas) + pragma = gState.getPragma(pragmas) - nimState.typeStr &= &"{nimState.getComments()}\n {nname}*{pragma} = object" + gState.typeStr &= &"{gState.getComments()}\n {nname}*{pragma} = object" var i = fstart @@ -333,19 +333,19 @@ proc initGrammar(): Grammar = fptr = "" aptr = "" flen = "" - while i < nimState.data.len-fend: + while i < gState.data.len-fend: fptr = "" aptr = "" - if nimState.data[i].name == "field_declaration": + if gState.data[i].name == "field_declaration": i += 1 continue - if nimState.data[i].name notin ["field_identifier", "pointer_declarator", "array_pointer_declarator"]: - ftyp = nimState.getIdentifier(nimState.data[i].val, nskType, nname).getType() + if gState.data[i].name notin ["field_identifier", "pointer_declarator", "array_pointer_declarator"]: + ftyp = gState.getIdentifier(gState.data[i].val, nskType, nname).getType() i += 1 - while i < nimState.data.len-fend and "pointer" in nimState.data[i].name: - case nimState.data[i].name: + while i < gState.data.len-fend and "pointer" in gState.data[i].name: + case gState.data[i].name: of "pointer_declarator": fptr &= "ptr " i += 1 @@ -353,33 +353,33 @@ proc initGrammar(): Grammar = aptr &= "ptr " i += 1 - fname = nimState.getIdentifier(nimState.data[i].val, nskField, nname) + fname = gState.getIdentifier(gState.data[i].val, nskField, nname) - if i+1 < nimState.data.len-fend and nimState.data[i+1].name in gEnumVals: + if i+1 < gState.data.len-fend and gState.data[i+1].name in gEnumVals: # Struct field is an array where size is an expression var - flen = nimState.getNimExpression(nimState.data[i+1].val) + flen = gState.getNimExpression(gState.data[i+1].val) if "/" in flen: flen = &"({flen}).int" - nimState.typeStr &= &"{nimState.getComments()}\n {fname}*: {aptr}array[{flen}, {getPtrType(fptr&ftyp)}]" + gState.typeStr &= &"{gState.getComments()}\n {fname}*: {aptr}array[{flen}, {getPtrType(fptr&ftyp)}]" i += 2 - elif i+1 < nimState.data.len-fend and nimState.data[i+1].name == "bitfield_clause": + elif i+1 < gState.data.len-fend and gState.data[i+1].name == "bitfield_clause": let - size = nimState.data[i+1].val - nimState.typeStr &= &"{nimState.getComments()}\n {fname}* {{.bitsize: {size}.}} : {getPtrType(fptr&ftyp)} " + size = gState.data[i+1].val + gState.typeStr &= &"{gState.getComments()}\n {fname}* {{.bitsize: {size}.}} : {getPtrType(fptr&ftyp)} " i += 2 - elif i+1 < nimState.data.len-fend and nimState.data[i+1].name == "function_declarator": + elif i+1 < gState.data.len-fend and gState.data[i+1].name == "function_declarator": var pout, pname, ptyp, pptr = "" count = 1 i += 2 - while i < nimState.data.len-fend: - if nimState.data[i].name == "function_declarator": + while i < gState.data.len-fend: + if gState.data[i].name == "function_declarator": i += 1 continue - if nimState.data[i].name == "field_declaration": + if gState.data[i].name == "field_declaration": break funcParamCommon(fname, pname, ptyp, pptr, pout, count, i, flen) @@ -387,20 +387,20 @@ proc initGrammar(): Grammar = if pout.nBl and pout[^2 .. ^1] == ", ": pout = pout[0 .. ^3] if fptr.nBl or ftyp != "object": - nimState.typeStr &= &"{nimState.getComments()}\n {fname}*: proc({pout}): {getPtrType(fptr&ftyp)} {{.cdecl.}}" + gState.typeStr &= &"{gState.getComments()}\n {fname}*: proc({pout}): {getPtrType(fptr&ftyp)} {{.cdecl.}}" else: - nimState.typeStr &= &"{nimState.getComments()}\n {fname}*: proc({pout}) {{.cdecl.}}" + gState.typeStr &= &"{gState.getComments()}\n {fname}*: proc({pout}) {{.cdecl.}}" i += 1 else: if ftyp == "object": - nimState.typeStr &= &"{nimState.getComments()}\n {fname}*: pointer" + gState.typeStr &= &"{gState.getComments()}\n {fname}*: pointer" else: - nimState.typeStr &= &"{nimState.getComments()}\n {fname}*: {getPtrType(fptr&ftyp)}" + gState.typeStr &= &"{gState.getComments()}\n {fname}*: {getPtrType(fptr&ftyp)}" i += 1 if node.tsNodeType() == "type_definition" and - nimState.data[^1].name == "type_identifier" and nimState.data[^1].val.nBl: - pDupTypeCommon(nname, fend, nimState, false) + gState.data[^1].name == "type_identifier" and gState.data[^1].val.nBl: + pDupTypeCommon(nname, fend, gState, false) let fieldGrammar = &""" @@ -451,11 +451,11 @@ proc initGrammar(): Grammar = {fieldListGrammar} ) """, - proc (ast: ref Ast, node: TSNode, nimState: NimState) = - if nimState.gState.debug: - nimState.debugStr &= "\n# struct X {}" + proc (ast: ref Ast, node: TSNode, gState: State) = + if gState.debug: + gState.debugStr &= "\n# struct X {}" - pStructCommon(ast, node, nimState.data[0].val, 1, 1, nimState) + pStructCommon(ast, node, gState.data[0].val, 1, 1, gState) )) # typedef struct X {} @@ -474,69 +474,69 @@ proc initGrammar(): Grammar = ) ) """, - proc (ast: ref Ast, node: TSNode, nimState: NimState) = - if nimState.gState.debug: - nimState.debugStr &= "\n# typedef struct X {}" + proc (ast: ref Ast, node: TSNode, gState: State) = + if gState.debug: + gState.debugStr &= "\n# typedef struct X {}" var fstart = 0 fend = 1 - if nimState.data[^2].name == "pointer_declarator": + if gState.data[^2].name == "pointer_declarator": fend = 2 - if nimState.data.len > 1 and - nimState.data[0].name == "type_identifier" and - nimState.data[1].name notin ["field_identifier", "pointer_declarator"]: + if gState.data.len > 1 and + gState.data[0].name == "type_identifier" and + gState.data[1].name notin ["field_identifier", "pointer_declarator"]: fstart = 1 - pStructCommon(ast, node, nimState.data[0].val, fstart, fend, nimState) + pStructCommon(ast, node, gState.data[0].val, fstart, fend, gState) else: - pStructCommon(ast, node, nimState.data[^1].val, fstart, fend, nimState) + pStructCommon(ast, node, gState.data[^1].val, fstart, fend, gState) )) - proc pEnumCommon(ast: ref Ast, node: TSNode, name: string, fstart, fend: int, nimState: NimState) = - if nimState.gState.debug: - nimState.debugStr &= "\n# pEnumCommon()" + proc pEnumCommon(ast: ref Ast, node: TSNode, name: string, fstart, fend: int, gState: State) = + if gState.debug: + gState.debugStr &= "\n# pEnumCommon()" let nname = if name.Bl: - getUniqueIdentifier(nimState, "Enum") + getUniqueIdentifier(gState, "Enum") else: - nimState.getIdentifier(name, nskType) + gState.getIdentifier(name, nskType) - if nname.nBl and nimState.addNewIdentifer(nname): - nimState.enumStr &= &"{nimState.getComments(true)}\ndefineEnum({nname})" + if nname.nBl and gState.addNewIdentifer(nname): + gState.enumStr &= &"{gState.getComments(true)}\ndefineEnum({nname})" var i = fstart count = 0 - while i < nimState.data.len-fend: - if nimState.data[i].name == "enumerator": + while i < gState.data.len-fend: + if gState.data[i].name == "enumerator": i += 1 continue let - fname = nimState.getIdentifier(nimState.data[i].val, nskEnumField) + fname = gState.getIdentifier(gState.data[i].val, nskEnumField) - if i+1 < nimState.data.len-fend and - nimState.data[i+1].name in gEnumVals: - if fname.nBl and nimState.addNewIdentifer(fname): - nimState.constStr &= &"{nimState.getComments()}\n {fname}* = ({nimState.getNimExpression(nimState.data[i+1].val)}).{nname}" + if i+1 < gState.data.len-fend and + gState.data[i+1].name in gEnumVals: + if fname.nBl and gState.addNewIdentifer(fname): + gState.constStr &= &"{gState.getComments()}\n {fname}* = ({gState.getNimExpression(gState.data[i+1].val)}).{nname}" try: - count = nimState.data[i+1].val.parseInt() + 1 + count = gState.data[i+1].val.parseInt() + 1 except: count += 1 i += 2 else: - if fname.nBl and nimState.addNewIdentifer(fname): - nimState.constStr &= &"{nimState.getComments()}\n {fname}* = {count}.{nname}" + if fname.nBl and gState.addNewIdentifer(fname): + gState.constStr &= &"{gState.getComments()}\n {fname}* = {count}.{nname}" i += 1 count += 1 if node.tsNodeType() == "type_definition" and - nimState.data[^1].name == "type_identifier" and nimState.data[^1].val.nBl: - pDupTypeCommon(nname, fend, nimState, true) + gState.data[^1].name == "type_identifier" and gState.data[^1].val.nBl: + pDupTypeCommon(nname, fend, gState, true) # enum X {} result.add((""" @@ -550,19 +550,19 @@ proc initGrammar(): Grammar = ) ) """ % gEnumVals.join("|"), - proc (ast: ref Ast, node: TSNode, nimState: NimState) = - if nimState.gState.debug: - nimState.debugStr &= "\n# enum X {}" + proc (ast: ref Ast, node: TSNode, gState: State) = + if gState.debug: + gState.debugStr &= "\n# enum X {}" var name = "" offset = 0 - if nimState.data[0].name == "type_identifier": - name = nimState.data[0].val + if gState.data[0].name == "type_identifier": + name = gState.data[0].val offset = 1 - pEnumCommon(ast, node, name, offset, 0, nimState) + pEnumCommon(ast, node, name, offset, 0, gState) )) # typedef enum {} X @@ -578,23 +578,23 @@ proc initGrammar(): Grammar = ) ) """, - proc (ast: ref Ast, node: TSNode, nimState: NimState) = - if nimState.gState.debug: - nimState.debugStr &= "\n# typedef enum {}" + proc (ast: ref Ast, node: TSNode, gState: State) = + if gState.debug: + gState.debugStr &= "\n# typedef enum {}" var fstart = 0 fend = 1 - if nimState.data[^2].name == "pointer_declarator": + if gState.data[^2].name == "pointer_declarator": fend = 2 - if nimState.data[0].name == "type_identifier": + if gState.data[0].name == "type_identifier": fstart = 1 - pEnumCommon(ast, node, nimState.data[0].val, fstart, fend, nimState) + pEnumCommon(ast, node, gState.data[0].val, fstart, fend, gState) else: - pEnumCommon(ast, node, nimState.data[^1].val, fstart, fend, nimState) + pEnumCommon(ast, node, gState.data[^1].val, fstart, fend, gState) )) # typ function(typ param1, ...) @@ -611,39 +611,39 @@ proc initGrammar(): Grammar = {funcGrammar} ) """, - proc (ast: ref Ast, node: TSNode, nimState: NimState) = - if nimState.gState.debug: - nimState.debugStr &= "\n# typ function" + proc (ast: ref Ast, node: TSNode, gState: State) = + if gState.debug: + gState.debugStr &= "\n# typ function" var fptr = "" i = 1 - while i < nimState.data.len: - if nimState.data[i].name == "function_declarator": + while i < gState.data.len: + if gState.data[i].name == "function_declarator": i += 1 continue fptr = "" - while i < nimState.data.len and nimState.data[i].name == "pointer_declarator": + while i < gState.data.len and gState.data[i].name == "pointer_declarator": fptr &= "ptr " i += 1 var - fname = nimState.data[i].val - fnname = nimState.getIdentifier(fname, nskProc) + fname = gState.data[i].val + fnname = gState.getIdentifier(fname, nskProc) pout, pname, ptyp, pptr = "" count = 1 flen = "" fVar = false i += 1 - if i < nimState.data.len and nimState.data[i].name == "pointer_declarator": + if i < gState.data.len and gState.data[i].name == "pointer_declarator": fVar = true i += 1 - while i < nimState.data.len: - if nimState.data[i].name == "function_declarator": + while i < gState.data.len: + if gState.data[i].name == "function_declarator": break funcParamCommon(fnname, pname, ptyp, pptr, pout, count, i, flen) @@ -653,24 +653,24 @@ proc initGrammar(): Grammar = if not fnname.nBl: let - override = nimState.getOverride(fname, nskProc) + override = gState.getOverride(fname, nskProc) if override.nBl: - nimState.typeStr &= &"{nimState.getComments()}\n{override}" - elif nimState.addNewIdentifer(fnname): + gState.typeStr &= &"{gState.getComments()}\n{override}" + elif gState.addNewIdentifer(fnname): let - ftyp = nimState.getIdentifier(nimState.data[0].val, nskType, fnname).getType() - pragma = nimState.getPragma(nimState.getImportC(fname, fnname), "cdecl") + ftyp = gState.getIdentifier(gState.data[0].val, nskType, fnname).getType() + pragma = gState.getPragma(gState.getImportC(fname, fnname), "cdecl") if fptr.nBl or ftyp != "object": if fVar: - nimState.procStr &= &"{nimState.getComments(true)}\nvar {fnname}*: proc ({pout}): {getPtrType(fptr&ftyp)}{{.cdecl.}}" + gState.procStr &= &"{gState.getComments(true)}\nvar {fnname}*: proc ({pout}): {getPtrType(fptr&ftyp)}{{.cdecl.}}" else: - nimState.procStr &= &"{nimState.getComments(true)}\nproc {fnname}*({pout}): {getPtrType(fptr&ftyp)}{pragma}" + gState.procStr &= &"{gState.getComments(true)}\nproc {fnname}*({pout}): {getPtrType(fptr&ftyp)}{pragma}" else: if fVar: - nimState.procStr &= &"{nimState.getComments(true)}\nvar {fnname}*: proc ({pout}){{.cdecl.}}" + gState.procStr &= &"{gState.getComments(true)}\nvar {fnname}*: proc ({pout}){{.cdecl.}}" else: - nimState.procStr &= &"{nimState.getComments(true)}\nproc {fnname}*({pout}){pragma}" + gState.procStr &= &"{gState.getComments(true)}\nproc {fnname}*({pout}){pragma}" )) # // comment @@ -678,15 +678,15 @@ proc initGrammar(): Grammar = (comment ) """, - proc (ast: ref Ast, node: TSNode, nimState: NimState) = + proc (ast: ref Ast, node: TSNode, gState: State) = let - cmt = $nimState.getNodeVal(node) + cmt = $gState.getNodeVal(node) for line in cmt.splitLines(): let line = line.multiReplace([("//", ""), ("/*", ""), ("*/", "")]) - nimState.commentStr &= &"\n # {line.strip(leading=false)}" + gState.commentStr &= &"\n # {line.strip(leading=false)}" )) # // unknown @@ -695,37 +695,37 @@ proc initGrammar(): Grammar = (^.*) ) """, - proc (ast: ref Ast, node: TSNode, nimState: NimState) = + proc (ast: ref Ast, node: TSNode, gState: State) = var done = false - for i in nimState.data: + for i in gState.data: case $node.tsNodeType() of "declaration": if i.name == "identifier": let - override = nimState.getOverride(i.val, nskProc) + override = gState.getOverride(i.val, nskProc) if override.nBl: - nimState.procStr &= &"{nimState.getComments(true)}\n{override}" + gState.procStr &= &"{gState.getComments(true)}\n{override}" done = true break else: - nimState.procStr &= &"{nimState.getComments(true)}\n# Declaration '{i.val}' skipped" + gState.procStr &= &"{gState.getComments(true)}\n# Declaration '{i.val}' skipped" else: if i.name == "type_identifier": let - override = nimState.getOverride(i.val, nskType) + override = gState.getOverride(i.val, nskType) if override.nBl: - nimState.typeStr &= &"{nimState.getComments()}\n{override}" + gState.typeStr &= &"{gState.getComments()}\n{override}" done = true break else: - nimState.typeStr &= &"{nimState.getComments()}\n # Type '{i.val}' skipped" + gState.typeStr &= &"{gState.getComments()}\n # Type '{i.val}' skipped" - if nimState.gState.debug and not done: - nimState.skipStr &= &"\n{nimState.getNodeVal(node)}" + if gState.debug and not done: + gState.skipStr &= &"\n{gState.getNodeVal(node)}" )) proc initRegex(ast: ref Ast) = From f2870d8ba6fe9249f26d681b3f01cfb8b121d362 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 21 Apr 2020 23:37:37 -0500 Subject: [PATCH 393/593] Fix multi-header processing, perf improvements --- nimterop/ast.nim | 7 ++++--- nimterop/ast2.nim | 24 +++++++++++++++--------- nimterop/getters.nim | 23 +++++++++++++---------- nimterop/toast.nim | 23 +++++++++++++++++------ 4 files changed, 49 insertions(+), 28 deletions(-) diff --git a/nimterop/ast.nim b/nimterop/ast.nim index 6b21bc7..1f1cac6 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -202,12 +202,11 @@ proc searchAst(root: TSNode, astTable: AstTable, gState: State) = if node == root: break -proc printNim*(gState: State, fullpath: string, root: TSNode, astTable: AstTable) = +proc parseNim*(gState: State, fullpath: string, root: TSNode, astTable: AstTable) = + # Generate Nim from tree-sitter AST root node var fp = fullpath.replace("\\", "/") - gState.identifiers = newTable[string, string]() - gState.currentHeader = getCurrentHeader(fullpath) gState.impShort = gState.currentHeader.replace("header", "imp") gState.sourceFile = fullpath @@ -217,6 +216,8 @@ proc printNim*(gState: State, fullpath: string, root: TSNode, astTable: AstTable root.searchAst(astTable, gState) +proc printNim*(gState: State) = + # Print Nim generated by parseNim() if gState.enumStr.nBl: gecho &"{gState.enumStr}\n" diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index 9e8f582..0e7a7bb 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -1777,20 +1777,13 @@ proc printNimHeader*(gState: State) = import nimterop/types """ % [$now(), getAppFilename(), commandLineParams().join(" ")] -proc printNim*(gState: State, fullpath: string, root: TSNode) = - # Generate Nim from tree-sitter AST root node - let - fp = fullpath.replace("\\", "/") +proc initNim*(gState: State) = + # Initialize for parseNim() one time # Track identifiers already rendered and corresponding PNodes gState.identifiers = newTable[string, string]() gState.identifierNodes = newTable[string, PNode]() - # toast objects - gState.currentHeader = getCurrentHeader(fullpath) - gState.impShort = gState.currentHeader.replace("header", "imp") - gState.sourceFile = fullpath - # Nim compiler objects gState.identCache = newIdentCache() gState.config = newConfigRef() @@ -1804,12 +1797,25 @@ proc printNim*(gState: State, fullpath: string, root: TSNode) = gState.typeSection = newNode(nkTypeSection) gState.varSection = newNode(nkVarSection) +proc parseNim*(gState: State, fullpath: string, root: TSNode) = + # Generate Nim from tree-sitter AST root node + let + fp = fullpath.replace("\\", "/") + + # toast objects + gState.currentHeader = getCurrentHeader(fullpath) + gState.impShort = gState.currentHeader.replace("header", "imp") + gState.sourceFile = fullpath + # Setup pragmas gState.setupPragmas(root, fp) # Search root node and render Nim gState.searchTree(root) +proc printNim*(gState: State) = + # Print Nim generated by parseNim() + # Add any unused cOverride symbols to output gState.addAllOverrideFinal() diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 1cdd2ff..88786ce 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -351,13 +351,10 @@ proc inChildren*(node: TSNode, ntype: string): bool = proc getLineCol*(gState: State, node: TSNode): tuple[line, col: int] = # Get line number and column info for node - result.line = 1 - result.col = 1 - for i in 0 .. node.tsNodeStartByte().int-1: - if gState.code[i] == '\n': - result.col = 0 - result.line += 1 - result.col += 1 + let + point = node.tsNodeStartPoint() + result.line = point.row.int + 1 + result.col = point.column.int + 1 proc getTSNodeNamedChildCountSansComments*(node: TSNode): int = for i in 0 ..< node.len: @@ -542,6 +539,14 @@ proc getPreprocessor*(gState: State, fullpath: string): string = for def in gState.defines: cmd &= &"-D{def} " + # Remove gcc special calls + if defined(posix): + cmd &= "-D__attribute__\\(x\\)= " + else: + cmd &= "-D__attribute__(x)= " + + cmd &= "-D__restrict= " + cmd &= &"{fullpath.sanitizePath}" # Include content only from file @@ -570,9 +575,7 @@ proc getPreprocessor*(gState: State, fullpath: string): string = if "#undef" in line: continue rdata.add line - return rdata.join("\n"). - replace("__restrict", ""). - replace(re"__attribute__[ ]*\(\(.*?\)\)([ ,;])", "$1") + return rdata.join("\n") converter toString*(kind: Kind): string = return case kind: diff --git a/nimterop/toast.nim b/nimterop/toast.nim index 3f886e1..7dad591 100644 --- a/nimterop/toast.nim +++ b/nimterop/toast.nim @@ -1,4 +1,4 @@ -import os, osproc, strformat, strutils, tables, times +import os, osproc, segfaults, strformat, strutils, tables, times import "."/treesitter/[api, c, cpp] @@ -40,9 +40,9 @@ proc process(gState: State, path: string, astTable: AstTable) = gecho gState.printLisp(root) elif gState.pnim: if Feature.ast2 in gState.feature: - ast2.printNim(gState, path, root) + ast2.parseNim(gState, path, root) else: - ast.printNim(gState, path, root, astTable) + ast.parseNim(gState, path, root, astTable) elif gState.preprocess: gecho gState.code @@ -137,17 +137,28 @@ proc main( # Process grammar into AST let - astTable = parseGrammar() + astTable = + if Feature.ast2 notin gState.feature: + parseGrammar() + else: + nil if pgrammar: - # Print AST of grammar - gState.printGrammar(astTable) + if Feature.ast2 notin gState.feature: + # Print AST of grammar + gState.printGrammar(astTable) elif source.nBl: # Print source after preprocess or Nim output if gState.pnim: gState.printNimHeader() + gState.initNim() for src in source: gState.process(src.expandSymlinkAbs(), astTable) + if gState.pnim: + if Feature.ast2 in gState.feature: + ast2.printNim(gState) + else: + ast.printNim(gState) # Close outputFile if outputFile.len != 0: From 00b66bf92c8b566f6f0bd27595ea16a13acfa549 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 22 Apr 2020 09:25:23 -0500 Subject: [PATCH 394/593] Change FILE* to File --- nimterop/ast2.nim | 2 ++ nimterop/grammar.nim | 2 ++ tests/config.nims.disabled | 7 ------- tests/nim.cfg | 3 +-- 4 files changed, 5 insertions(+), 9 deletions(-) delete mode 100644 tests/config.nims.disabled diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index 0e7a7bb..ce45f1d 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -14,6 +14,8 @@ proc getPtrType*(str: string): string = "cstring" of "object": "pointer" + of "FILE": + "File" else: str diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index 0d804d0..eaa337a 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -17,6 +17,8 @@ proc getPtrType(str: string): string = "pointer" of "ptr ptr object": "ptr pointer" + of "ptr FILE": + "File" else: str diff --git a/tests/config.nims.disabled b/tests/config.nims.disabled deleted file mode 100644 index 06a791e..0000000 --- a/tests/config.nims.disabled +++ /dev/null @@ -1,7 +0,0 @@ -#[ -pending https://github.com/nim-lang/Nim/pull/10530 -note: nimble init installs something like this (maybe without src in this case) -switch("path", "$projectDir/../src") -but it doesn't seem robust in case tests have subdirs, so, changing to ../ seems better -]# -switch("path", "..") diff --git a/tests/nim.cfg b/tests/nim.cfg index 3936716..5bb1fab 100644 --- a/tests/nim.cfg +++ b/tests/nim.cfg @@ -1,2 +1 @@ -# TODO: pending https://github.com/nimterop/nimterop/issues/110 remove in favor of config.nims ---path:".." +--path:".." \ No newline at end of file From 79526221b7cd488043f545a903f65da736eea2c7 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 22 Apr 2020 11:28:16 -0500 Subject: [PATCH 395/593] Avoid building toast twice in CI --- .travis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3b66a7e..d4e9bde 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,6 +26,6 @@ install: - source travis.sh script: - - nimble --verbose install -y - - nimble --verbose test - - nimble --verbose --nimbleDir:`pwd`/build/fakenimble install nimterop -y + - nimble develop -y + - nimble test + - nimble --verbose --nimbleDir:`pwd`/build/fakenimble install nimterop@#head -y From da6a4e30ab9c88748e54e4cf0bdae248c8750cdd Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 22 Apr 2020 11:37:45 -0500 Subject: [PATCH 396/593] Remove segfaults --- nimterop/toast.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimterop/toast.nim b/nimterop/toast.nim index 7dad591..ab44970 100644 --- a/nimterop/toast.nim +++ b/nimterop/toast.nim @@ -1,4 +1,4 @@ -import os, osproc, segfaults, strformat, strutils, tables, times +import os, osproc, strformat, strutils, tables, times import "."/treesitter/[api, c, cpp] From f17b958f47686f41a20045ea089295841a6845d6 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 22 Apr 2020 12:01:20 -0500 Subject: [PATCH 397/593] markAndSweep, removeStatic --- config.nims | 4 ++-- nimterop/getters.nim | 16 +--------------- 2 files changed, 3 insertions(+), 17 deletions(-) diff --git a/config.nims b/config.nims index 6b475de..f5f7d21 100644 --- a/config.nims +++ b/config.nims @@ -5,8 +5,8 @@ else: switch("gcc.linkerexe", "g++") # Workaround for NilAccessError crash on Windows #98 -when defined(Windows): - switch("gc", "markAndSweep") +# Could also help for OSX/Linux crash +switch("gc", "markAndSweep") # Retain stackTrace for clear errors switch("stackTrace", "on") diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 88786ce..2d8d9bb 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -510,20 +510,6 @@ proc getNameInfo*(gState: State, node: TSNode, kind: NimSymKind, parent = ""): proc getCurrentHeader*(fullpath: string): string = ("header" & fullpath.splitFile().name.multiReplace([(".", ""), ("-", "")])) -proc removeStatic(content: string): string = - ## Replace static function bodies with a semicolon and commented - ## out body - return content.replace( - re"(?msU)static inline ([^)]+\))([^}]+\})", - proc (m: RegexMatch, s: string): string = - let funcDecl = s[m.group(0)[0]] - let body = s[m.group(1)[0]].strip() - result = "" - - result.add("$#;" % [funcDecl]) - result.add(body.replace(re"(?m)^(.*\n?)", "//$1")) - ) - proc getPreprocessor*(gState: State, fullpath: string): string = var cmts = if gState.nocomments: "" else: "-CC" @@ -731,7 +717,7 @@ proc loadPlugin*(gState: State, sourcePath: string) = pdll = sourcePath.dll if not fileExists(pdll) or sourcePath.getLastModificationTime() > pdll.getLastModificationTime(): - discard execAction(&"{gState.nim.sanitizePath} c --app:lib {sourcePath.sanitizePath}") + discard execAction(&"{gState.nim.sanitizePath} c --app:lib --gc:markAndSweep {sourcePath.sanitizePath}") doAssert fileExists(pdll), "No plugin binary generated for " & sourcePath let lib = loadLib(pdll) From c1f46680f77d077bfc7abebea8b289e9b8bac043 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 22 Apr 2020 22:11:30 -0500 Subject: [PATCH 398/593] Add cImport for multiple headers --- nimterop.nimble | 3 ++ nimterop/cimport.nim | 91 ++++++++++++++++++++++++++------------------ tests/rsa.nim | 42 ++++++++++++++++++++ 3 files changed, 99 insertions(+), 37 deletions(-) create mode 100644 tests/rsa.nim diff --git a/nimterop.nimble b/nimterop.nimble index 37c395d..9cb79b1 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -51,6 +51,9 @@ task test, "Test": execTest "tests/tpcre.nim" execTest "tests/tpcre.nim", "-d:FLAGS=\"-f:ast2\"" + execTest "tests/rsa.nim" + execTest "tests/rsa.nim", "-d:FLAGS=\"-H\"" + # Platform specific tests when defined(Windows): execTest "tests/tmath.nim" diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index 52d1892..3e58bc8 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -91,6 +91,11 @@ proc getCacheValue(fullpath: string): string = if not gStateCT.nocache: result = fullpath.getFileDate() +proc getCacheValue(fullpaths: seq[string]): string = + if not gStateCT.nocache: + for fullpath in fullpaths: + result &= getCacheValue(fullpath) + proc getToastError(output: string): string = # Filter out preprocessor errors for line in output.splitLines(): @@ -121,7 +126,7 @@ proc getNimCheckError(output: string): tuple[tmpFile, errors: string] = result.errors = "\n\n" & check -proc getToast(fullpath: string, recurse: bool = false, dynlib: string = "", +proc getToast(fullpaths: seq[string], recurse: bool = false, dynlib: string = "", mode = "c", flags = "", noNimout = false): string = var ret = 0 @@ -158,11 +163,12 @@ proc getToast(fullpath: string, recurse: bool = false, dynlib: string = "", if gStateCT.pluginSourcePath.nBl: cmd.add &" --pluginSourcePath={gStateCT.pluginSourcePath.sanitizePath}" - cmd.add &" {fullpath.sanitizePath}" + for fullpath in fullpaths: + cmd.add &" {fullpath.sanitizePath}" # see https://github.com/nimterop/nimterop/issues/69 (result, ret) = execAction(cmd, die = false, cache = (not gStateCT.nocache), - cacheKey = getCacheValue(fullpath)) + cacheKey = getCacheValue(fullpaths)) doAssert ret == 0, getToastError(result) macro cOverride*(body): untyped = @@ -555,6 +561,46 @@ macro cCompile*(path: static string, mode = "c", exclude = ""): untyped = if gStateCT.debug: echo result.repr +macro cImport*(filenames: static seq[string], recurse: static bool = false, dynlib: static string = "", + mode: static string = "c", flags: static string = ""): untyped = + ## Import multiple headers in one shot + ## + ## This macro is preferable over multiple individual `cImport()` calls, especially + ## when the headers might `#include` the same headers and result in duplicate symbols. + result = newNimNode(nnkStmtList) + + var + fullpaths: seq[string] + + for filename in filenames: + fullpaths.add findPath(filename) + + # In case cOverride called after cPlugin + if gStateCT.pluginSourcePath.Bl: + cPluginHelper(gStateCT.pluginSource) + + echo "# Importing " & fullpaths.join(", ").sanitizePath + + let + output = getToast(fullpaths, recurse, dynlib, mode, flags) + + # Reset plugin and overrides for next cImport + if gStateCT.overrides.nBl: + gStateCT.pluginSourcePath = "" + gStateCT.overrides = "" + + if gStateCT.debug: + echo output + + try: + let body = parseStmt(output) + + result.add body + except: + let + (tmpFile, errors) = getNimCheckError(output) + doAssert false, errors & "\n\nNimterop codegen limitation or error - review 'nim check' output above generated for " & tmpFile + macro cImport*(filename: static string, recurse: static bool = false, dynlib: static string = "", mode: static string = "c", flags: static string = ""): untyped = ## Import all supported definitions from specified header file. Generated @@ -590,8 +636,8 @@ macro cImport*(filename: static string, recurse: static bool = false, dynlib: st ## with `cCompile() `_, or the ## `{.passL.}` pragma can be used to specify the static lib to link. ## - ## `mode` is purely for forward compatibility when toast adds C++ support. It can - ## be ignored for the foreseeable future. + ## `mode` selects the preprocessor and tree-sitter parser to be used to process + ## the header. ## ## `flags` can be used to pass any other command line arguments to `toast`. A ## good example would be `--prefix` and `--suffix` which strip leading and @@ -600,37 +646,8 @@ macro cImport*(filename: static string, recurse: static bool = false, dynlib: st ## `cImport()` consumes and resets preceding `cOverride()` calls. `cPlugin()` ## is retained for the next `cImport()` call unless a new `cPlugin()` call is ## defined. - - result = newNimNode(nnkStmtList) - - let - fullpath = findPath(filename) - - # In case cOverride called after cPlugin - if gStateCT.pluginSourcePath.Bl: - cPluginHelper(gStateCT.pluginSource) - - echo "# Importing " & fullpath.sanitizePath - - let - output = getToast(fullpath, recurse, dynlib, mode, flags) - - # Reset plugin and overrides for next cImport - if gStateCT.overrides.nBl: - gStateCT.pluginSourcePath = "" - gStateCT.overrides = "" - - if gStateCT.debug: - echo output - - try: - let body = parseStmt(output) - - result.add body - except: - let - (tmpFile, errors) = getNimCheckError(output) - doAssert false, errors & "\n\nNimterop codegen limitation or error - review 'nim check' output above generated for " & tmpFile + return quote do: + cImport(@[`filename`], bool(`recurse`), `dynlib`, `mode`, `flags`) macro c2nImport*(filename: static string, recurse: static bool = false, dynlib: static string = "", mode: static string = "c", flags: static string = ""): untyped = @@ -661,7 +678,7 @@ macro c2nImport*(filename: static string, recurse: static bool = false, dynlib: echo "# Importing " & fullpath & " with c2nim" let - output = getToast(fullpath, recurse, dynlib, noNimout = true) + output = getToast(@[fullpath], recurse, dynlib, noNimout = true) hash = output.hash().abs() hpath = getProjectCacheDir("c2nimCache", forceClean = false) / "nimterop_" & $hash & ".h" npath = hpath[0 .. hpath.rfind('.')] & "nim" diff --git a/tests/rsa.nim b/tests/rsa.nim new file mode 100644 index 0000000..638c490 --- /dev/null +++ b/tests/rsa.nim @@ -0,0 +1,42 @@ +import os +import strutils + +import nimterop/[build, cimport] + +setDefines(@["cryptoStd"]) +getHeader("openssl/crypto.h") + +const + basePath = cryptoPath.parentDir + FLAGS {.strdefine.} = "" + +cPlugin: + import strutils + + proc onSymbol*(sym: var Symbol) {.exportc, dynlib.} = + sym.name = sym.name.strip(chars = {'_'}).replace("__", "_") + + if sym.name in [ + "AES_ENCRYPT", "AES_DECRYPT", + "BIO_CTRL_PENDING", "BIO_CTRL_WPENDING", + "BN_F_BNRAND", "BN_F_BNRAND_RANGE", + "CRYPTO_THREADID", + "EVP_CIPHER", + "OPENSSL_VERSION", + "PKCS7_ENCRYPT", "PKCS7_STREAM", + "SSL_TXT_ADH", "SSL_TXT_AECDH", "SSL_TXT_kECDHE" + ]: + sym.name = "C_" & sym.name + +cOverride: + proc OPENSSL_die*(assertion: cstring; file: cstring; line: cint) {.importc.} + +cImport(@[ + basePath / "rsa.h", + basePath / "err.h", +], recurse = true, flags = "-f:ast2 -s " & FLAGS) + +{.passL: cryptoLPath.} + +OpensslInit() +echo $OPENSSL_VERSION_TEXT \ No newline at end of file From 43dd43e3183178e71abd3319290c566cb4dd80a9 Mon Sep 17 00:00:00 2001 From: Travis CI User Date: Thu, 23 Apr 2020 14:34:41 +0000 Subject: [PATCH 399/593] Fix rsa test --- nimterop.nimble | 5 +++-- tests/rsa.nim | 8 ++++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/nimterop.nimble b/nimterop.nimble index 9cb79b1..a6fba1e 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -51,8 +51,9 @@ task test, "Test": execTest "tests/tpcre.nim" execTest "tests/tpcre.nim", "-d:FLAGS=\"-f:ast2\"" - execTest "tests/rsa.nim" - execTest "tests/rsa.nim", "-d:FLAGS=\"-H\"" + when defined(Linux): + execTest "tests/rsa.nim" + execTest "tests/rsa.nim", "-d:FLAGS=\"-H\"" # Platform specific tests when defined(Windows): diff --git a/tests/rsa.nim b/tests/rsa.nim index 638c490..e7bde89 100644 --- a/tests/rsa.nim +++ b/tests/rsa.nim @@ -10,6 +10,9 @@ const basePath = cryptoPath.parentDir FLAGS {.strdefine.} = "" +static: + cSkipSymbol(@["ERR_load_crypto_strings", "OpenSSLDie"]) + cPlugin: import strutils @@ -20,10 +23,11 @@ cPlugin: "AES_ENCRYPT", "AES_DECRYPT", "BIO_CTRL_PENDING", "BIO_CTRL_WPENDING", "BN_F_BNRAND", "BN_F_BNRAND_RANGE", - "CRYPTO_THREADID", + "CRYPTO_LOCK", "CRYPTO_NUM_LOCKS", "CRYPTO_THREADID", "EVP_CIPHER", "OPENSSL_VERSION", "PKCS7_ENCRYPT", "PKCS7_STREAM", + "SSLEAY_VERSION", "SSL_TXT_ADH", "SSL_TXT_AECDH", "SSL_TXT_kECDHE" ]: sym.name = "C_" & sym.name @@ -39,4 +43,4 @@ cImport(@[ {.passL: cryptoLPath.} OpensslInit() -echo $OPENSSL_VERSION_TEXT \ No newline at end of file +echo $OPENSSL_VERSION_TEXT From 80018f43cf35214e95c4fa777f65bb756be1db24 Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Tue, 14 Apr 2020 20:38:35 -0600 Subject: [PATCH 400/593] WIP Ast printing --- nimterop/ast2.nim | 30 +++++++++++++++++++++++++++++- nimterop/getters.nim | 21 +++++++++++++++------ 2 files changed, 44 insertions(+), 7 deletions(-) diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index ce45f1d..43b6b35 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -4,10 +4,35 @@ import regex import compiler/[ast, idents, lineinfos, modulegraphs, msgs, options, parser, renderer] -import "."/treesitter/api +import "."/treesitter/[api, c, cpp] import "."/[globals, getters] +proc getCCodeAst*(gState: State, code: string): string = + var parser = tsParserNew() + var code = code + + defer: + parser.tsParserDelete() + + + doAssert code.nBl, "Empty code" + if gState.mode == "c": + doAssert parser.tsParserSetLanguage(treeSitterC()), "Failed to load C parser" + elif gState.mode == "cpp": + doAssert parser.tsParserSetLanguage(treeSitterCpp()), "Failed to load C++ parser" + else: + doAssert false, &"Invalid parser {gState.mode}" + + var + tree = parser.tsParserParseString(nil, code.cstring, code.len.uint32) + root = tree.tsTreeRootNode() + + defer: + tree.tsTreeDelete() + + return code.printLisp(root) + proc getPtrType*(str: string): string = result = case str: of "cchar": @@ -59,6 +84,9 @@ proc getLit*(gState: State, str: string, expression = false): PNode = result = newStrNode(nkStrLit, str[1 .. ^2]) else: + decho "Macro AST:" + decho str + decho nimState.gState.getCCodeAst(str) let str = if expression: gState.getNimExpression(str) diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 2d8d9bb..4ffb5d7 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -228,9 +228,12 @@ proc getName*(node: TSNode): string {.inline.} = if not node.isNil: return $node.tsNodeType() -proc getNodeVal*(gState: State, node: TSNode): string = +proc getNodeVal*(code: var string, node: TSNode): string = if not node.isNil: - return gState.code[node.tsNodeStartByte() .. node.tsNodeEndByte()-1].strip() + return code[node.tsNodeStartByte() .. node.tsNodeEndByte()-1].strip() + +proc getNodeVal*(gState: State, node: TSNode): string = + gState.code.getNodeVal(node) proc getAtom*(node: TSNode): TSNode = if not node.isNil: @@ -349,13 +352,16 @@ proc inChildren*(node: TSNode, ntype: string): bool = result = true break -proc getLineCol*(gState: State, node: TSNode): tuple[line, col: int] = +proc getLineCol*(code: var string, node: TSNode): tuple[line, col: int] = # Get line number and column info for node let point = node.tsNodeStartPoint() result.line = point.row.int + 1 result.col = point.column.int + 1 +proc getLineCol*(gState: State, node: TSNode): tuple[line, col: int] = + getLineCol(gState.code, node) + proc getTSNodeNamedChildCountSansComments*(node: TSNode): int = for i in 0 ..< node.len: if node.getName() != "comment": @@ -374,7 +380,7 @@ proc getPxName*(node: TSNode, offset: int): string = if count == offset and not np.isNil: return np.getName() -proc printLisp*(gState: State, root: TSNode): string = +proc printLisp*(code: var string, root: TSNode): string = var node = root nextnode: TSNode @@ -384,10 +390,10 @@ proc printLisp*(gState: State, root: TSNode): string = if not node.isNil and depth > -1: result &= spaces(depth) let - (line, col) = gState.getLineCol(node) + (line, col) = code.getLineCol(node) result &= &"({$node.tsNodeType()} {line} {col} {node.tsNodeEndByte() - node.tsNodeStartByte()}" let - val = gState.getNodeVal(node) + val = code.getNodeVal(node) if "\n" notin val and " " notin val: result &= &" \"{val}\"" else: @@ -419,6 +425,9 @@ proc printLisp*(gState: State, root: TSNode): string = if node == root: break +proc printLisp*(gState: State, root: TSNode): string = + printLisp(gState.code, root) + proc getCommented*(str: string): string = "\n# " & str.strip().replace("\n", "\n# ") From 879c7e3c784b3debce068a93e7f9ee116eb7bc21 Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Thu, 16 Apr 2020 20:49:06 -0600 Subject: [PATCH 401/593] Add preliminary expression parsing --- nimterop/ast2.nim | 77 ++----------- nimterop/exprparser.nim | 245 ++++++++++++++++++++++++++++++++++++++++ nimterop/getters.nim | 2 +- 3 files changed, 253 insertions(+), 71 deletions(-) create mode 100644 nimterop/exprparser.nim diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index 43b6b35..04bb8eb 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -1,37 +1,10 @@ import macros, os, sequtils, sets, strformat, strutils, tables, times -import regex - import compiler/[ast, idents, lineinfos, modulegraphs, msgs, options, parser, renderer] -import "."/treesitter/[api, c, cpp] +import "."/treesitter/api -import "."/[globals, getters] - -proc getCCodeAst*(gState: State, code: string): string = - var parser = tsParserNew() - var code = code - - defer: - parser.tsParserDelete() - - - doAssert code.nBl, "Empty code" - if gState.mode == "c": - doAssert parser.tsParserSetLanguage(treeSitterC()), "Failed to load C parser" - elif gState.mode == "cpp": - doAssert parser.tsParserSetLanguage(treeSitterCpp()), "Failed to load C++ parser" - else: - doAssert false, &"Invalid parser {gState.mode}" - - var - tree = parser.tsParserParseString(nil, code.cstring, code.len.uint32) - root = tree.tsTreeRootNode() - - defer: - tree.tsTreeDelete() - - return code.printLisp(root) +import "."/[globals, getters, exprparser] proc getPtrType*(str: string): string = result = case str: @@ -59,42 +32,8 @@ proc parseString(gState: State, str: string): PNode = except: decho getCurrentExceptionMsg() -proc getLit*(gState: State, str: string, expression = false): PNode = - # Used to convert #define literals into const and expressions - # in array sizes - # - # `expression` is true when `str` should be converted into a Nim expression - let - str = str.replace(re"/[/*].*?(?:\*/)?$", "").strip() - - if str.contains(re"^[\-]?[\d]+$"): # decimal - result = newIntNode(nkIntLit, parseInt(str)) - - elif str.contains(re"^[\-]?[\d]*[.]?[\d]+$"): # float - result = newFloatNode(nkFloatLit, parseFloat(str)) - - elif str.contains(re"^0x[\da-fA-F]+$"): # hexadecimal - result = gState.parseString(str) - - elif str.contains(re"^'[[:ascii:]]'$"): # char - result = newNode(nkCharLit) - result.intVal = str[1].int64 - - elif str.contains(re"""^"[[:ascii:]]+"$"""): # char * - result = newStrNode(nkStrLit, str[1 .. ^2]) - - else: - decho "Macro AST:" - decho str - decho nimState.gState.getCCodeAst(str) - let - str = - if expression: gState.getNimExpression(str) - else: str - result = gState.parseString(str) - - if result.isNil: - result = newNode(nkNilLit) +proc getLit*(nimState: NimState, str: string, expression = false): PNode = + result = nimState.codeToNode(str) proc getOverrideOrSkip(gState: State, node: TSNode, origname: string, kind: NimSymKind): PNode = # Check if symbol `origname` of `kind` and `origname` has any cOverride defined @@ -181,11 +120,9 @@ proc newConstDef(gState: State, node: TSNode, fname = "", fval = ""): PNode = if name.Bl: # Name skipped or overridden since blank - result = gState.getOverrideOrSkip(node, origname, nskConst) - elif valident.kind in {nkCharLit .. nkStrLit} or - (valident.kind == nkStmtList and valident.len > 0 and - valident[0].kind in {nkCharLit .. nkStrLit}): - if gState.addNewIdentifer(name): + result = nimState.getOverrideOrSkip(node, origname, nskConst) + elif valident.kind != nkNilLit: + if nimState.addNewIdentifer(name): # const X* = Y # # nkConstDef( diff --git a/nimterop/exprparser.nim b/nimterop/exprparser.nim new file mode 100644 index 0000000..a4be5d0 --- /dev/null +++ b/nimterop/exprparser.nim @@ -0,0 +1,245 @@ +import strformat, strutils, macros + +import regex + +import compiler/[ast, renderer] + +import "."/treesitter/[api, c, cpp] + +import "."/[globals, getters] + +type + ExprParser* = ref object + state*: NimState + code*: string + +proc newExprParser*(state: NimState, code: string): ExprParser = + ExprParser(state: state, code: code) + +template decho(msg: varargs[string, `$`]) = + if exprParser.state.gState.debug: + let nimState {.inject.} = exprParser.state + necho "# " & join(msg, "") + +template val*(node: TSNode): string = + exprParser.code.getNodeVal(node) + +proc mode*(exprParser: ExprParser): string = + exprParser.state.gState.mode + +template withCodeAst(exprParser: ExprParser, body: untyped): untyped = + var parser = tsParserNew() + defer: + parser.tsParserDelete() + + doAssert exprParser.code.nBl, "Empty code" + if exprParser.mode == "c": + doAssert parser.tsParserSetLanguage(treeSitterC()), "Failed to load C parser" + elif exprParser.mode == "cpp": + doAssert parser.tsParserSetLanguage(treeSitterCpp()), "Failed to load C++ parser" + else: + doAssert false, &"Invalid parser {exprParser.mode}" + + var + tree = parser.tsParserParseString(nil, exprParser.code.cstring, exprParser.code.len.uint32) + root {.inject.} = tree.tsTreeRootNode() + + body + + defer: + tree.tsTreeDelete() + + +proc getNumNode(number, suffix: string): PNode {.inline.} = + result = newNode(nkNilLit) + if number.contains("."): + let floatSuffix = number[result.len-1] + case floatSuffix + of 'l', 'L': + # TODO: handle long double (128 bits) + # result = newNode(nkFloat128Lit) + result = newFloatNode(nkFloat64Lit, parseFloat(number[0 ..< number.len - 1])) + of 'f', 'F': + result = newFloatNode(nkFloat64Lit, parseFloat(number[0 ..< number.len - 1])) + else: + discard + return + + case suffix + of "u", "U": + result = newNode(nkUintLit) + of "l", "L": + result = newNode(nkInt32Lit) + of "ul", "UL": + result = newNode(nkUint32Lit) + of "ll", "LL": + result = newNode(nkInt64Lit) + of "ull", "ULL": + result = newNode(nkUint64Lit) + else: + result = newNode(nkIntLit) + + if number.contains(re"0[xX]"): + result.intVal = parseHexInt(number) + result.flags = {nfBase16} + elif number.contains(re"0[bB]"): + result.intVal = parseBinInt(number) + result.flags = {nfBase2} + elif number.contains(re"0[oO]"): + result.intVal = parseOctInt(number) + result.flags = {nfBase8} + else: + result.intVal = parseInt(number) + +proc processNumberLiteral*(exprParser: ExprParser, node: TSNode): PNode = + result = newNode(nkNilLit) + let nodeVal = node.val + + var match: RegexMatch + const reg = re"(\-)?(0\d+|0[xX][0-9a-fA-F]+|0[bB][01]+|\d+\.?\d*[fFlL]?|\d*\.?\d+[fFlL]?|\d+)([ulUL]*)" + let found = nodeVal.find(reg, match) + if found: + let + prefix = if match.group(0).len > 0: nodeVal[match.group(0)[0]] else: "" + number = nodeVal[match.group(1)[0]] + suffix = nodeVal[match.group(2)[0]] + + result = getNumNode(number, suffix) + + if result.kind != nkNilLit and prefix == "-": + result = nkPrefix.newTree( + exprParser.state.getIdent("-"), + result + ) + +proc processCharacterLiteral*(exprParser: ExprParser, node: TSNode): PNode = + result = newNode(nkCharLit) + result.intVal = node.val[1].int64 + +proc processStringLiteral*(exprParser: ExprParser, node: TSNode): PNode = + let nodeVal = node.val + result = newStrNode(nkStrLit, nodeVal[1 ..< nodeVal.len - 1]) + +proc processTSNode*(exprParser: ExprParser, node: TSNode): PNode + +proc processShiftExpression*(exprParser: ExprParser, node: TSNode): PNode = + result = newNode(nkInfix) + let + left = node[0] + right = node[1] + var shiftSym = exprParser.code[left.tsNodeEndByte() ..< right.tsNodeStartByte()].strip() + + case shiftSym + of "<<": + result.add exprParser.state.getIdent("shl") + of ">>": + result.add exprParser.state.getIdent("shr") + else: + discard + + result.add exprParser.processTSNode(left) + result.add exprParser.processTSNode(right) + +proc processParenthesizedExpr*(exprParser: ExprParser, node: TSNode): PNode = + result = newNode(nkPar) + for i in 0 ..< node.len(): + result.add(exprParser.processTSNode(node[i])) + +proc processLogicalExpression*(exprParser: ExprParser, node: TSNode): PNode = + result = newNode(nkPar) + let child = node[0] + var nimSym = "" + + var binarySym = exprParser.code[node.tsNodeStartByte() ..< child.tsNodeStartByte()].strip() + decho "LOG SYM: ", binarySym + + case binarySym + of "!": + nimSym = "not" + else: + return newNode(nkNilLit) + + decho "LOG CHILD: ", child.val, ", nim: ", nimSym + result.add nkPrefix.newTree( + exprParser.state.getIdent(nimSym), + exprParser.processTSNode(child) + ) + +proc processBitwiseExpression*(exprParser: ExprParser, node: TSNode): PNode = + if node.len() > 1: + result = newNode(nkInfix) + let left = node[0] + let right = node[1] + var nimSym = "" + + var binarySym = exprParser.code[left.tsNodeEndByte() ..< right.tsNodeStartByte()].strip() + decho "# BIN SYM: ", binarySym + + case binarySym + of "|", "||": + nimSym = "or" + of "&", "&&": + nimSym = "and" + of "^": + nimSym = "xor" + else: + return newNode(nkNilLit) + + result.add exprParser.state.getIdent(nimSym) + result.add exprParser.processTSNode(left) + result.add exprParser.processTSNode(right) + + elif node.len() == 1: + result = newNode(nkPar) + let child = node[0] + var nimSym = "" + + var binarySym = exprParser.code[node.tsNodeStartByte() ..< child.tsNodeStartByte()].strip() + decho "# BIN SYM: ", binarySym + + case binarySym + of "~": + nimSym = "not" + else: + return newNode(nkNilLit) + + result.add nkPrefix.newTree( + exprParser.state.getIdent(nimSym), + exprParser.processTSNode(child) + ) + +proc processTSNode*(exprParser: ExprParser, node: TSNode): PNode = + result = newNode(nkNilLit) + decho "# NODE: ", node.getName(), ", VAL: ", node.val + case node.getName() + of "number_literal": + result = exprParser.processNumberLiteral(node) + of "string_literal": + result = exprParser.processStringLiteral(node) + of "char_literal": + result = exprParser.processCharacterLiteral(node) + of "expression_statement", "ERROR", "translation_unit": + # This may be wrong. What can be in an expression? + result = exprParser.processTSNode(node[0]) + of "parenthesized_expression": + result = exprParser.processParenthesizedExpr(node) + of "bitwise_expression": + result = exprParser.processBitwiseExpression(node) + of "shift_expression": + result = exprParser.processShiftExpression(node) + of "logical_expression": + result = exprParser.processLogicalExpression(node) + of "identifier": + var ident = node.val + if ident != "_": + ident = exprParser.state.getIdentifier(ident, nskConst) + result = exprParser.state.getIdent(ident) + else: + result = newNode(nkNilLit) + + decho "# NODERES: ", result + +proc codeToNode*(state: NimState, code: string): PNode = + let exprParser = newExprParser(state, code) + withCodeAst(exprParser): + result = exprParser.processTSNode(root) \ No newline at end of file diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 4ffb5d7..b96ae70 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -221,7 +221,7 @@ proc len*(node: TSNode): int = result = node.tsNodeNamedChildCount().int proc `[]`*(node: TSNode, i: SomeInteger): TSNode = - if i < node.len: + if i < type(i)(node.len()): result = node.tsNodeNamedChild(i.uint32) proc getName*(node: TSNode): string {.inline.} = From c1520b4fd103da78c15c807092f7bcbb46d16012 Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Fri, 17 Apr 2020 06:33:02 -0600 Subject: [PATCH 402/593] Add better error handling for unimplemented types --- nimterop/exprparser.nim | 75 ++++++++++++++++++++++++++--------------- 1 file changed, 48 insertions(+), 27 deletions(-) diff --git a/nimterop/exprparser.nim b/nimterop/exprparser.nim index a4be5d0..9570788 100644 --- a/nimterop/exprparser.nim +++ b/nimterop/exprparser.nim @@ -13,13 +13,15 @@ type state*: NimState code*: string + ExprParseError* = object of CatchableError + proc newExprParser*(state: NimState, code: string): ExprParser = ExprParser(state: state, code: code) -template decho(msg: varargs[string, `$`]) = +template techo(msg: varargs[string, `$`]) = if exprParser.state.gState.debug: let nimState {.inject.} = exprParser.state - necho "# " & join(msg, "") + necho "# " & join(msg, "").replace("\n", "\n# ") template val*(node: TSNode): string = exprParser.code.getNodeVal(node) @@ -54,16 +56,19 @@ proc getNumNode(number, suffix: string): PNode {.inline.} = result = newNode(nkNilLit) if number.contains("."): let floatSuffix = number[result.len-1] - case floatSuffix - of 'l', 'L': - # TODO: handle long double (128 bits) - # result = newNode(nkFloat128Lit) - result = newFloatNode(nkFloat64Lit, parseFloat(number[0 ..< number.len - 1])) - of 'f', 'F': - result = newFloatNode(nkFloat64Lit, parseFloat(number[0 ..< number.len - 1])) - else: - discard - return + try: + case floatSuffix + of 'l', 'L': + # TODO: handle long double (128 bits) + # result = newNode(nkFloat128Lit) + result = newFloatNode(nkFloat64Lit, parseFloat(number[0 ..< number.len - 1])) + of 'f', 'F': + result = newFloatNode(nkFloat64Lit, parseFloat(number[0 ..< number.len - 1])) + else: + result = newFloatNode(nkFloatLit, parseFloat(number[0 ..< number.len - 1])) + return + except ValueError: + raise newException(ExprParseError, &"Could not parse float value \"{number}\".") case suffix of "u", "U": @@ -111,6 +116,8 @@ proc processNumberLiteral*(exprParser: ExprParser, node: TSNode): PNode = exprParser.state.getIdent("-"), result ) + else: + raise newException(ExprParseError, &"Could not find a number in number_literal: \"{nodeVal}\"") proc processCharacterLiteral*(exprParser: ExprParser, node: TSNode): PNode = result = newNode(nkCharLit) @@ -135,7 +142,7 @@ proc processShiftExpression*(exprParser: ExprParser, node: TSNode): PNode = of ">>": result.add exprParser.state.getIdent("shr") else: - discard + raise newException(ExprParseError, &"Unsupported shift symbol \"{shiftSym}\"") result.add exprParser.processTSNode(left) result.add exprParser.processTSNode(right) @@ -151,15 +158,15 @@ proc processLogicalExpression*(exprParser: ExprParser, node: TSNode): PNode = var nimSym = "" var binarySym = exprParser.code[node.tsNodeStartByte() ..< child.tsNodeStartByte()].strip() - decho "LOG SYM: ", binarySym + techo "LOG SYM: ", binarySym case binarySym of "!": nimSym = "not" else: - return newNode(nkNilLit) + raise newException(ExprParseError, &"Unsupported logical symbol \"{binarySym}\"") - decho "LOG CHILD: ", child.val, ", nim: ", nimSym + techo "LOG CHILD: ", child.val, ", nim: ", nimSym result.add nkPrefix.newTree( exprParser.state.getIdent(nimSym), exprParser.processTSNode(child) @@ -173,7 +180,7 @@ proc processBitwiseExpression*(exprParser: ExprParser, node: TSNode): PNode = var nimSym = "" var binarySym = exprParser.code[left.tsNodeEndByte() ..< right.tsNodeStartByte()].strip() - decho "# BIN SYM: ", binarySym + techo "BIN SYM: ", binarySym case binarySym of "|", "||": @@ -183,7 +190,7 @@ proc processBitwiseExpression*(exprParser: ExprParser, node: TSNode): PNode = of "^": nimSym = "xor" else: - return newNode(nkNilLit) + raise newException(ExprParseError, &"Unsupported binary symbol \"{binarySym}\"") result.add exprParser.state.getIdent(nimSym) result.add exprParser.processTSNode(left) @@ -195,23 +202,26 @@ proc processBitwiseExpression*(exprParser: ExprParser, node: TSNode): PNode = var nimSym = "" var binarySym = exprParser.code[node.tsNodeStartByte() ..< child.tsNodeStartByte()].strip() - decho "# BIN SYM: ", binarySym + techo "BIN SYM: ", binarySym case binarySym of "~": nimSym = "not" else: - return newNode(nkNilLit) + raise newException(ExprParseError, &"Unsupported unary symbol \"{binarySym}\"") result.add nkPrefix.newTree( exprParser.state.getIdent(nimSym), exprParser.processTSNode(child) ) + else: + raise newException(ExprParseError, &"Invalid bitwise_expression \"{node.val}\"") proc processTSNode*(exprParser: ExprParser, node: TSNode): PNode = result = newNode(nkNilLit) - decho "# NODE: ", node.getName(), ", VAL: ", node.val - case node.getName() + let nodeName = node.getName() + techo "NODE: ", nodeName, ", VAL: ", node.val + case nodeName of "number_literal": result = exprParser.processNumberLiteral(node) of "string_literal": @@ -220,7 +230,11 @@ proc processTSNode*(exprParser: ExprParser, node: TSNode): PNode = result = exprParser.processCharacterLiteral(node) of "expression_statement", "ERROR", "translation_unit": # This may be wrong. What can be in an expression? - result = exprParser.processTSNode(node[0]) + if node.len > 0: + result = exprParser.processTSNode(node[0]) + else: + raise newException(ExprParseError, &"Node type \"{nodeName}\" has no children") + of "parenthesized_expression": result = exprParser.processParenthesizedExpr(node) of "bitwise_expression": @@ -235,11 +249,18 @@ proc processTSNode*(exprParser: ExprParser, node: TSNode): PNode = ident = exprParser.state.getIdentifier(ident, nskConst) result = exprParser.state.getIdent(ident) else: - result = newNode(nkNilLit) + raise newException(ExprParseError, &"Unsupported node type \"{nodeName}\" for node \"{node.val}\"") - decho "# NODERES: ", result + techo "NODERES: ", result proc codeToNode*(state: NimState, code: string): PNode = let exprParser = newExprParser(state, code) - withCodeAst(exprParser): - result = exprParser.processTSNode(root) \ No newline at end of file + try: + withCodeAst(exprParser): + result = exprParser.processTSNode(root) + except ExprParseError as e: + techo e.msg + result = newNode(nkNilLit) + except Exception as e: + techo e.msg + result = newNode(nkNilLit) \ No newline at end of file From 305d90583e5dc7a8dde012c982047df9dee21f8e Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Fri, 17 Apr 2020 06:53:41 -0600 Subject: [PATCH 403/593] Add proper binary casting --- nimterop/exprparser.nim | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/nimterop/exprparser.nim b/nimterop/exprparser.nim index 9570788..1f72a9a 100644 --- a/nimterop/exprparser.nim +++ b/nimterop/exprparser.nim @@ -144,8 +144,18 @@ proc processShiftExpression*(exprParser: ExprParser, node: TSNode): PNode = else: raise newException(ExprParseError, &"Unsupported shift symbol \"{shiftSym}\"") - result.add exprParser.processTSNode(left) - result.add exprParser.processTSNode(right) + let + leftNode = exprParser.processTSNode(left) + rightNode = exprParser.processTSNode(right) + + result.add leftNode + result.add nkCast.newTree( + nkCall.newTree( + exprParser.state.getIdent("typeof"), + leftNode + ), + rightNode + ) proc processParenthesizedExpr*(exprParser: ExprParser, node: TSNode): PNode = result = newNode(nkPar) @@ -193,8 +203,18 @@ proc processBitwiseExpression*(exprParser: ExprParser, node: TSNode): PNode = raise newException(ExprParseError, &"Unsupported binary symbol \"{binarySym}\"") result.add exprParser.state.getIdent(nimSym) - result.add exprParser.processTSNode(left) - result.add exprParser.processTSNode(right) + let + leftNode = exprParser.processTSNode(left) + rightNode = exprParser.processTSNode(right) + + result.add leftNode + result.add nkCast.newTree( + nkCall.newTree( + exprParser.state.getIdent("typeof"), + leftNode + ), + rightNode + ) elif node.len() == 1: result = newNode(nkPar) From 055d6bee73eb988ae498a57d29dd3d80a8928721 Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Fri, 17 Apr 2020 07:37:17 -0600 Subject: [PATCH 404/593] Add math_expression and fix ast2 tests Update to include more expressions --- nimterop/ast2.nim | 24 +---- nimterop/exprparser.nim | 200 ++++++++++++++++++++++++++++++---------- nimterop/getters.nim | 22 +++-- nimterop/globals.nim | 2 +- tests/include/tast2.h | 18 ++++ tests/tast2.nim | 22 ++++- 6 files changed, 211 insertions(+), 77 deletions(-) diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index 04bb8eb..85b555f 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -1,10 +1,10 @@ import macros, os, sequtils, sets, strformat, strutils, tables, times -import compiler/[ast, idents, lineinfos, modulegraphs, msgs, options, parser, renderer] +import compiler/[ast, idents, lineinfos, modulegraphs, msgs, options, renderer] import "."/treesitter/api -import "."/[globals, getters, exprparser] +import "."/[globals, getters, exprparser, utils] proc getPtrType*(str: string): string = result = case str: @@ -17,21 +17,6 @@ proc getPtrType*(str: string): string = else: str -proc handleError*(conf: ConfigRef, info: TLineInfo, msg: TMsgKind, arg: string) = - # Raise exception in parseString() instead of exiting for errors - if msg < warnMin: - raise newException(Exception, msgKindToString(msg)) - -proc parseString(gState: State, str: string): PNode = - # Parse a string into Nim AST - use custom error handler that raises - # an exception rather than exiting on failure - try: - result = parseString( - str, gState.identCache, gState.config, errorHandler = handleError - ) - except: - decho getCurrentExceptionMsg() - proc getLit*(nimState: NimState, str: string, expression = false): PNode = result = nimState.codeToNode(str) @@ -121,7 +106,7 @@ proc newConstDef(gState: State, node: TSNode, fname = "", fval = ""): PNode = if name.Bl: # Name skipped or overridden since blank result = nimState.getOverrideOrSkip(node, origname, nskConst) - elif valident.kind != nkNilLit: + elif valident.kind != nkNone: if nimState.addNewIdentifer(name): # const X* = Y # @@ -179,7 +164,7 @@ proc addPragma(gState: State, node: TSNode, pragma: PNode, name: string, value: if value.isNil: pragma.add pident else: - let + var colExpr = newNode(nkExprColonExpr) colExpr.add pident colExpr.add value @@ -1501,6 +1486,7 @@ proc addProc(gState: State, node, rnode: TSNode) = # Parameter list plist = node.anyChildInTree("parameter_list") + var procDef = newNode(nkProcDef) # proc X(a1: Y, a2: Z): P {.pragma.} diff --git a/nimterop/exprparser.nim b/nimterop/exprparser.nim index 1f72a9a..505453c 100644 --- a/nimterop/exprparser.nim +++ b/nimterop/exprparser.nim @@ -6,7 +6,7 @@ import compiler/[ast, renderer] import "."/treesitter/[api, c, cpp] -import "."/[globals, getters] +import "."/[globals, getters, utils] type ExprParser* = ref object @@ -21,15 +21,16 @@ proc newExprParser*(state: NimState, code: string): ExprParser = template techo(msg: varargs[string, `$`]) = if exprParser.state.gState.debug: let nimState {.inject.} = exprParser.state - necho "# " & join(msg, "").replace("\n", "\n# ") + necho join(msg, "").getCommented -template val*(node: TSNode): string = +template val(node: TSNode): string = exprParser.code.getNodeVal(node) -proc mode*(exprParser: ExprParser): string = +proc mode(exprParser: ExprParser): string = exprParser.state.gState.mode template withCodeAst(exprParser: ExprParser, body: untyped): untyped = + ## A simple template to inject the TSNode into a body of code var parser = tsParserNew() defer: parser.tsParserDelete() @@ -51,9 +52,9 @@ template withCodeAst(exprParser: ExprParser, body: untyped): untyped = defer: tree.tsTreeDelete() - proc getNumNode(number, suffix: string): PNode {.inline.} = - result = newNode(nkNilLit) + ## Convert a C number to a Nim number PNode + result = newNode(nkNone) if number.contains("."): let floatSuffix = number[result.len-1] try: @@ -84,6 +85,8 @@ proc getNumNode(number, suffix: string): PNode {.inline.} = else: result = newNode(nkIntLit) + # I realize these regex are wasteful on performance, but + # couldn't come up with a better idea. if number.contains(re"0[xX]"): result.intVal = parseHexInt(number) result.flags = {nfBase16} @@ -97,11 +100,11 @@ proc getNumNode(number, suffix: string): PNode {.inline.} = result.intVal = parseInt(number) proc processNumberLiteral*(exprParser: ExprParser, node: TSNode): PNode = - result = newNode(nkNilLit) + result = newNode(nkNone) let nodeVal = node.val var match: RegexMatch - const reg = re"(\-)?(0\d+|0[xX][0-9a-fA-F]+|0[bB][01]+|\d+\.?\d*[fFlL]?|\d*\.?\d+[fFlL]?|\d+)([ulUL]*)" + const reg = re"(\-)?(0\d+|0[xX][0-9a-fA-F]+|0[bB][01]+|\d+|\d+\.?\d*[fFlL]?|\d*\.?\d+[fFlL]?)([ulUL]*)" let found = nodeVal.find(reg, match) if found: let @@ -111,7 +114,7 @@ proc processNumberLiteral*(exprParser: ExprParser, node: TSNode): PNode = result = getNumNode(number, suffix) - if result.kind != nkNilLit and prefix == "-": + if result.kind != nkNone and prefix == "-": result = nkPrefix.newTree( exprParser.state.getIdent("-"), result @@ -127,9 +130,9 @@ proc processStringLiteral*(exprParser: ExprParser, node: TSNode): PNode = let nodeVal = node.val result = newStrNode(nkStrLit, nodeVal[1 ..< nodeVal.len - 1]) -proc processTSNode*(exprParser: ExprParser, node: TSNode): PNode +proc processTSNode*(exprParser: ExprParser, node: TSNode, typeofNode: PNode = nil): PNode -proc processShiftExpression*(exprParser: ExprParser, node: TSNode): PNode = +proc processShiftExpression*(exprParser: ExprParser, node: TSNode, typeofNode: PNode = nil): PNode = result = newNode(nkInfix) let left = node[0] @@ -144,25 +147,29 @@ proc processShiftExpression*(exprParser: ExprParser, node: TSNode): PNode = else: raise newException(ExprParseError, &"Unsupported shift symbol \"{shiftSym}\"") - let - leftNode = exprParser.processTSNode(left) - rightNode = exprParser.processTSNode(right) + let leftNode = exprParser.processTSNode(left, typeofNode) + + var tnode = typeofNode + if tnode.isNil: + tnode = leftNode + + let rightNode = exprParser.processTSNode(right, tnode) result.add leftNode result.add nkCast.newTree( nkCall.newTree( exprParser.state.getIdent("typeof"), - leftNode + tnode ), rightNode ) -proc processParenthesizedExpr*(exprParser: ExprParser, node: TSNode): PNode = +proc processParenthesizedExpr*(exprParser: ExprParser, node: TSNode, typeofNode: PNode = nil): PNode = result = newNode(nkPar) for i in 0 ..< node.len(): - result.add(exprParser.processTSNode(node[i])) + result.add(exprParser.processTSNode(node[i], typeofNode)) -proc processLogicalExpression*(exprParser: ExprParser, node: TSNode): PNode = +proc processLogicalExpression*(exprParser: ExprParser, node: TSNode, typeofNode: PNode = nil): PNode = result = newNode(nkPar) let child = node[0] var nimSym = "" @@ -179,14 +186,96 @@ proc processLogicalExpression*(exprParser: ExprParser, node: TSNode): PNode = techo "LOG CHILD: ", child.val, ", nim: ", nimSym result.add nkPrefix.newTree( exprParser.state.getIdent(nimSym), - exprParser.processTSNode(child) + exprParser.processTSNode(child, typeofNode) ) -proc processBitwiseExpression*(exprParser: ExprParser, node: TSNode): PNode = +proc processMathExpression(exprParser: ExprParser, node: TSNode, typeofNode: PNode = nil): PNode = + if node.len > 1: + # Node has left and right children ie: (2 + 7) + var + res = newNode(nkInfix) + let + left = node[0] + right = node[1] + + let mathSym = exprParser.code[left.tsNodeEndByte() ..< right.tsNodeStartByte()].strip() + techo "MATH SYM: ", mathSym + + res.add exprParser.state.getIdent(mathSym) + let leftNode = exprParser.processTSNode(left, typeofNode) + + var tnode = typeofNode + if tnode.isNil: + tnode = leftNode + + let rightNode = exprParser.processTSNode(right, tnode) + + res.add leftNode + # res.add rightNode + res.add nkCast.newTree( + nkCall.newTree( + exprParser.state.getIdent("typeof"), + tnode + ), + rightNode + ) + + # Make sure the statement is of the same type as the left + # hand argument, since some expressions return a differing + # type than the input types (2/3 == float) + result = nkCall.newTree( + nkCall.newTree( + exprParser.state.getIdent("typeof"), + tnode + ), + res + ) + + elif node.len() == 1: + # Node has only one child, ie -(20 + 7) + result = newNode(nkPar) + let child = node[0] + var nimSym = "" + + let unarySym = exprParser.code[node.tsNodeStartByte() ..< child.tsNodeStartByte()].strip() + techo "MATH SYM: ", unarySym + + case unarySym + of "+": + nimSym = "+" + of "-": + # Special case. The minus symbol must be in front of an integer, + # so we have to make a gental cast here to coerce it to one. + # Might be bad because we are overwriting the type + # There's probably a better way of doing this + result.add nkPrefix.newTree( + exprParser.state.getIdent(unarySym), + nkPar.newTree( + nkCall.newTree( + exprParser.state.getIdent("int64"), + exprParser.processTSNode(child, typeofNode) + ) + ) + ) + return + else: + raise newException(ExprParseError, &"Unsupported unary symbol \"{unarySym}\"") + + result.add nkPrefix.newTree( + exprParser.state.getIdent(nimSym), + exprParser.processTSNode(child, typeofNode) + ) + else: + raise newException(ExprParseError, &"Invalid bitwise_expression \"{node.val}\"") + +proc processBitwiseExpression(exprParser: ExprParser, node: TSNode, typeofNode: PNode = nil): PNode = if node.len() > 1: result = newNode(nkInfix) - let left = node[0] - let right = node[1] + + let + left = node[0] + right = node[1] + var nimSym = "" var binarySym = exprParser.code[left.tsNodeEndByte() ..< right.tsNodeStartByte()].strip() @@ -203,15 +292,19 @@ proc processBitwiseExpression*(exprParser: ExprParser, node: TSNode): PNode = raise newException(ExprParseError, &"Unsupported binary symbol \"{binarySym}\"") result.add exprParser.state.getIdent(nimSym) - let - leftNode = exprParser.processTSNode(left) - rightNode = exprParser.processTSNode(right) + let leftNode = exprParser.processTSNode(left, typeofNode) + + var tnode = typeofNode + if tnode.isNil: + tnode = leftNode + + let rightNode = exprParser.processTSNode(right, tnode) result.add leftNode - result.add nkCast.newTree( + result.add nkCall.newTree( nkCall.newTree( exprParser.state.getIdent("typeof"), - leftNode + tnode ), rightNode ) @@ -221,24 +314,26 @@ proc processBitwiseExpression*(exprParser: ExprParser, node: TSNode): PNode = let child = node[0] var nimSym = "" - var binarySym = exprParser.code[node.tsNodeStartByte() ..< child.tsNodeStartByte()].strip() - techo "BIN SYM: ", binarySym + var unarySym = exprParser.code[node.tsNodeStartByte() ..< child.tsNodeStartByte()].strip() + techo "BIN SYM: ", unarySym - case binarySym + case unarySym of "~": nimSym = "not" else: - raise newException(ExprParseError, &"Unsupported unary symbol \"{binarySym}\"") + raise newException(ExprParseError, &"Unsupported unary symbol \"{unarySym}\"") result.add nkPrefix.newTree( exprParser.state.getIdent(nimSym), - exprParser.processTSNode(child) + exprParser.processTSNode(child, typeofNode) ) else: raise newException(ExprParseError, &"Invalid bitwise_expression \"{node.val}\"") -proc processTSNode*(exprParser: ExprParser, node: TSNode): PNode = - result = newNode(nkNilLit) +proc processTSNode(exprParser: ExprParser, node: TSNode, typeofNode: PNode = nil): PNode = + ## Handle all of the types of expressions here. This proc gets called recursively + ## in the processX procs and will drill down to sub nodes. + result = newNode(nkNone) let nodeName = node.getName() techo "NODE: ", nodeName, ", VAL: ", node.val case nodeName @@ -251,36 +346,47 @@ proc processTSNode*(exprParser: ExprParser, node: TSNode): PNode = of "expression_statement", "ERROR", "translation_unit": # This may be wrong. What can be in an expression? if node.len > 0: - result = exprParser.processTSNode(node[0]) + result = exprParser.processTSNode(node[0], typeofNode) else: raise newException(ExprParseError, &"Node type \"{nodeName}\" has no children") - of "parenthesized_expression": - result = exprParser.processParenthesizedExpr(node) + result = exprParser.processParenthesizedExpr(node, typeofNode) of "bitwise_expression": - result = exprParser.processBitwiseExpression(node) + result = exprParser.processBitwiseExpression(node, typeofNode) + of "math_expression": + result = exprParser.processMathExpression(node, typeofNode) of "shift_expression": - result = exprParser.processShiftExpression(node) + result = exprParser.processShiftExpression(node, typeofNode) of "logical_expression": - result = exprParser.processLogicalExpression(node) + result = exprParser.processLogicalExpression(node, typeofNode) + # Why are these node types named true/false? + of "true", "false": + result = exprParser.state.parseString(node.val) of "identifier": var ident = node.val if ident != "_": + # Process the identifier through cPlugin ident = exprParser.state.getIdentifier(ident, nskConst) - result = exprParser.state.getIdent(ident) + techo ident + if ident != "": + result = exprParser.state.getIdent(ident) + if result.kind == nkNone: + raise newException(ExprParseError, &"Could not get identifier \"{ident}\"") else: raise newException(ExprParseError, &"Unsupported node type \"{nodeName}\" for node \"{node.val}\"") - techo "NODERES: ", result + techo "NODE RES: ", result proc codeToNode*(state: NimState, code: string): PNode = - let exprParser = newExprParser(state, code) + ## Convert the C string to a nim PNode tree + result = newNode(nkNone) try: + let exprParser = newExprParser(state, code) withCodeAst(exprParser): result = exprParser.processTSNode(root) except ExprParseError as e: - techo e.msg - result = newNode(nkNilLit) + echo e.msg.getCommented + result = newNode(nkNone) except Exception as e: - techo e.msg - result = newNode(nkNilLit) \ No newline at end of file + echo e.msg.getCommented + result = newNode(nkNone) \ No newline at end of file diff --git a/nimterop/getters.nim b/nimterop/getters.nim index b96ae70..f43f199 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -399,7 +399,7 @@ proc printLisp*(code: var string, root: TSNode): string = else: break - if node.tsNodeNamedChildCount() != 0: + if node.len() != 0: result &= "\n" nextnode = node.tsNodeNamedChild(0) depth += 1 @@ -459,15 +459,19 @@ proc printTree*(gState: State, pnode: PNode, offset = ""): string = if offset.len == 0: result &= "\n" -proc printDebug*(gState: State, node: TSNode) = - if gState.debug: - gecho ("Input => " & gState.getNodeVal(node)).getCommented() & "\n" & - gState.printLisp(node).getCommented() +proc printDebug*(nimState: NimState, node: TSNode) = + discard + # This causes random segfaults for some reason on macOS Catalina + if nimState.gState.debug: + necho ("Input => " & nimState.getNodeVal(node)).getCommented() + necho nimState.gState.printLisp(node).getCommented() -proc printDebug*(gState: State, pnode: PNode) = - if gState.debug: - gecho ("Output => " & $pnode).getCommented() & "\n" & - gState.printTree(pnode) +proc printDebug*(nimState: NimState, pnode: PNode) = + discard + # This causes random segfaults for some reason on macOS Catalina + if nimState.gState.debug and pnode.kind != nkNone: + necho ("Output => " & $pnode).getCommented() + necho nimState.printTree(pnode) # Compiler shortcuts diff --git a/nimterop/globals.nim b/nimterop/globals.nim index f159124..b964da9 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -113,7 +113,7 @@ when not declared(CIMPORT): export gAtoms, gExpressions, gEnumVals, Kind, Ast, AstTable, State, nBl, Bl # Redirect output to file when required - template gecho*(args: string) {.dirty.} = + template gecho*(args: string) = if gState.outputHandle.isNil: echo args else: diff --git a/tests/include/tast2.h b/tests/include/tast2.h index bdf8823..7e15ac0 100644 --- a/tests/include/tast2.h +++ b/tests/include/tast2.h @@ -8,6 +8,24 @@ extern "C" { #define D "hello" #define E 'c' +#define UEXPR (1234u << 1) +#define ULEXPR (1234ul << 2) +#define ULLEXPR (1234ull << 3) +#define LEXPR (1234l << 4) +#define LLEXPR (1234ll << 5) + +#define SHL1 (1u << 1) +#define SHL2 (1u << 2) +#define SHL3 (1u << 3) +#define COERCE 645635634896ull + -35436 +#define COERCE2 645635634896 + -35436 +#define BINEXPR ~(-(1u << !-1)) ^ (10 >> 1) +#define BOOL true +#define MATHEXPR (1 + 2/3*20 - 100) +#define ANDEXPR (100 & 11000) + +#define ALLSHL (SHL1 | SHL2 | SHL3) + struct A0; struct A1 {}; typedef struct A2; diff --git a/tests/tast2.nim b/tests/tast2.nim index e13c4ac..d65e34a 100644 --- a/tests/tast2.nim +++ b/tests/tast2.nim @@ -105,6 +105,26 @@ assert C == 0x10 assert D == "hello" assert E == 'c' +assert UEXPR == (1234.uint shl 1) +assert ULEXPR == (1234.uint32 shl 2) +assert ULLEXPR == (1234.uint64 shl 3) +assert LEXPR == (1234.int32 shl 4) +assert LLEXPR == (1234.int64 shl 5) + +assert COERCE == 645635599460'u64 +assert COERCE2 == 645635599460'i64 + +assert BINEXPR == 5 +assert BOOL == true +assert MATHEXPR == -99 +assert ANDEXPR == 96 + +assert SHL1 == (1.uint shl 1) +assert SHL2 == (1.uint shl 2) +assert SHL3 == (1.uint shl 3) + +assert ALLSHL == (SHL1 or SHL2 or SHL3) + assert A0 is object testFields(A0, "f1!cint") checkPragmas(A0, pHeaderBy, istype = false) @@ -271,7 +291,7 @@ var a21p: A21p a21p = addr a20 assert A22 is object -testFields(A22, "f1|f2!ptr ptr cint|array[123 + 132, ptr cint]") +testFields(A22, "f1|f2!ptr ptr cint|array[typeof(123)(123 + cast[typeof(123)](132)), ptr cint]") checkPragmas(A22, pHeaderBy, istype = false) var a22: A22 a22.f1 = addr a15.a2[0] From 62c68d69ee0409558a846aae3a85cf1a29f9442b Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Sat, 18 Apr 2020 13:13:33 -0600 Subject: [PATCH 405/593] Add sizeof expression parser, fix nkNone issue, reduce size of typeof expressions Cleanup, fix bugs --- nimterop/ast2.nim | 2 +- nimterop/exprparser.nim | 149 +++++++++++++++++++++++++--------------- nimterop/getters.nim | 4 +- 3 files changed, 97 insertions(+), 58 deletions(-) diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index 85b555f..8c5da8c 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -963,7 +963,7 @@ proc getTypeArray(gState: State, node: TSNode, tident: PNode, name: string): PNo let # Size of array could be a Nim expression size = gState.getLit(gState.getNodeVal(cnode[1]), expression = true) - if size.kind != nkNilLit: + if size.kind != nkNone: result = gState.newArrayTree(cnode, result, size) cnode = cnode[0] elif cnode.len == 1: diff --git a/nimterop/exprparser.nim b/nimterop/exprparser.nim index 505453c..d27f23b 100644 --- a/nimterop/exprparser.nim +++ b/nimterop/exprparser.nim @@ -29,6 +29,24 @@ template val(node: TSNode): string = proc mode(exprParser: ExprParser): string = exprParser.state.gState.mode +proc getIdent(exprParser: ExprParser, identName: string, kind = nskConst, parent = ""): PNode = + ## Gets a cPlugin transformed identifier from `identName` + ## + ## Returns PNode(nkNone) if the identifier is blank + result = newNode(nkNone) + var ident = identName + if ident != "_": + # Process the identifier through cPlugin + ident = exprParser.state.getIdentifier(ident, kind, parent) + if ident != "": + result = exprParser.state.getIdent(ident) + +proc getIdent(exprParser: ExprParser, node: TSNode, kind = nskConst, parent = ""): PNode = + ## Gets a cPlugin transformed identifier from `identName` + ## + ## Returns PNode(nkNone) if the identifier is blank + exprParser.getIdent(node.val, kind, parent) + template withCodeAst(exprParser: ExprParser, body: untyped): untyped = ## A simple template to inject the TSNode into a body of code var parser = tsParserNew() @@ -56,7 +74,7 @@ proc getNumNode(number, suffix: string): PNode {.inline.} = ## Convert a C number to a Nim number PNode result = newNode(nkNone) if number.contains("."): - let floatSuffix = number[result.len-1] + let floatSuffix = number[number.len-1] try: case floatSuffix of 'l', 'L': @@ -66,7 +84,7 @@ proc getNumNode(number, suffix: string): PNode {.inline.} = of 'f', 'F': result = newFloatNode(nkFloat64Lit, parseFloat(number[0 ..< number.len - 1])) else: - result = newFloatNode(nkFloatLit, parseFloat(number[0 ..< number.len - 1])) + result = newFloatNode(nkFloatLit, parseFloat(number)) return except ValueError: raise newException(ExprParseError, &"Could not parse float value \"{number}\".") @@ -100,11 +118,12 @@ proc getNumNode(number, suffix: string): PNode {.inline.} = result.intVal = parseInt(number) proc processNumberLiteral*(exprParser: ExprParser, node: TSNode): PNode = + ## Parse a number literal from a TSNode. Can be a float, hex, long, etc result = newNode(nkNone) let nodeVal = node.val var match: RegexMatch - const reg = re"(\-)?(0\d+|0[xX][0-9a-fA-F]+|0[bB][01]+|\d+|\d+\.?\d*[fFlL]?|\d*\.?\d+[fFlL]?)([ulUL]*)" + const reg = re"(\-)?(0\d+|0[xX][0-9a-fA-F]+|0[bB][01]+|\d+\.\d*[fFlL]?|\d*\.\d+[fFlL]?|\d+)([ulUL]*)" let found = nodeVal.find(reg, match) if found: let @@ -130,9 +149,9 @@ proc processStringLiteral*(exprParser: ExprParser, node: TSNode): PNode = let nodeVal = node.val result = newStrNode(nkStrLit, nodeVal[1 ..< nodeVal.len - 1]) -proc processTSNode*(exprParser: ExprParser, node: TSNode, typeofNode: PNode = nil): PNode +proc processTSNode*(exprParser: ExprParser, node: TSNode, typeofNode: var PNode): PNode -proc processShiftExpression*(exprParser: ExprParser, node: TSNode, typeofNode: PNode = nil): PNode = +proc processShiftExpression*(exprParser: ExprParser, node: TSNode, typeofNode: var PNode): PNode = result = newNode(nkInfix) let left = node[0] @@ -149,27 +168,35 @@ proc processShiftExpression*(exprParser: ExprParser, node: TSNode, typeofNode: P let leftNode = exprParser.processTSNode(left, typeofNode) - var tnode = typeofNode - if tnode.isNil: - tnode = leftNode + # If the typeofNode is nil, set it + # to be the leftNode because C's type coercion + # happens left to right, and we want to emulate it + if typeofNode.isNil: + typeofNode = nkCall.newTree( + exprParser.state.getIdent("typeof"), + leftNode + ) - let rightNode = exprParser.processTSNode(right, tnode) + let rightNode = exprParser.processTSNode(right, typeofNode) result.add leftNode result.add nkCast.newTree( - nkCall.newTree( - exprParser.state.getIdent("typeof"), - tnode - ), + typeofNode, rightNode ) -proc processParenthesizedExpr*(exprParser: ExprParser, node: TSNode, typeofNode: PNode = nil): PNode = +proc processParenthesizedExpr*(exprParser: ExprParser, node: TSNode, typeofNode: var PNode): PNode = result = newNode(nkPar) for i in 0 ..< node.len(): result.add(exprParser.processTSNode(node[i], typeofNode)) -proc processLogicalExpression*(exprParser: ExprParser, node: TSNode, typeofNode: PNode = nil): PNode = +proc processCastExpression*(exprParser: ExprParser, node: TSNode, typeofNode: var PNode): PNode = + result = nkCast.newTree( + exprParser.processTSNode(node[0], typeofNode), + exprParser.processTSNode(node[1], typeofNode) + ) + +proc processLogicalExpression*(exprParser: ExprParser, node: TSNode, typeofNode: var PNode): PNode = result = newNode(nkPar) let child = node[0] var nimSym = "" @@ -189,7 +216,7 @@ proc processLogicalExpression*(exprParser: ExprParser, node: TSNode, typeofNode: exprParser.processTSNode(child, typeofNode) ) -proc processMathExpression(exprParser: ExprParser, node: TSNode, typeofNode: PNode = nil): PNode = +proc processMathExpression(exprParser: ExprParser, node: TSNode, typeofNode: var PNode): PNode = if node.len > 1: # Node has left and right children ie: (2 + 7) var @@ -204,19 +231,20 @@ proc processMathExpression(exprParser: ExprParser, node: TSNode, typeofNode: PNo res.add exprParser.state.getIdent(mathSym) let leftNode = exprParser.processTSNode(left, typeofNode) - var tnode = typeofNode - if tnode.isNil: - tnode = leftNode + # If the typeofNode is nil, set it + # to be the leftNode because C's type coercion + # happens left to right, and we want to emulate it + if typeofNode.isNil: + typeofNode = nkCall.newTree( + exprParser.state.getIdent("typeof"), + leftNode + ) - let rightNode = exprParser.processTSNode(right, tnode) + let rightNode = exprParser.processTSNode(right, typeofNode) res.add leftNode - # res.add rightNode res.add nkCast.newTree( - nkCall.newTree( - exprParser.state.getIdent("typeof"), - tnode - ), + typeofNode, rightNode ) @@ -224,10 +252,7 @@ proc processMathExpression(exprParser: ExprParser, node: TSNode, typeofNode: PNo # hand argument, since some expressions return a differing # type than the input types (2/3 == float) result = nkCall.newTree( - nkCall.newTree( - exprParser.state.getIdent("typeof"), - tnode - ), + typeofNode, res ) @@ -248,6 +273,8 @@ proc processMathExpression(exprParser: ExprParser, node: TSNode, typeofNode: PNo # so we have to make a gental cast here to coerce it to one. # Might be bad because we are overwriting the type # There's probably a better way of doing this + if typeofNode.isNil: + typeofNode = exprParser.state.getIdent("int64") result.add nkPrefix.newTree( exprParser.state.getIdent(unarySym), nkPar.newTree( @@ -268,7 +295,7 @@ proc processMathExpression(exprParser: ExprParser, node: TSNode, typeofNode: PNo else: raise newException(ExprParseError, &"Invalid bitwise_expression \"{node.val}\"") -proc processBitwiseExpression(exprParser: ExprParser, node: TSNode, typeofNode: PNode = nil): PNode = +proc processBitwiseExpression(exprParser: ExprParser, node: TSNode, typeofNode: var PNode): PNode = if node.len() > 1: result = newNode(nkInfix) @@ -288,24 +315,25 @@ proc processBitwiseExpression(exprParser: ExprParser, node: TSNode, typeofNode: nimSym = "and" of "^": nimSym = "xor" + of "==", "!=": + nimSym = binarySym else: raise newException(ExprParseError, &"Unsupported binary symbol \"{binarySym}\"") result.add exprParser.state.getIdent(nimSym) let leftNode = exprParser.processTSNode(left, typeofNode) - var tnode = typeofNode - if tnode.isNil: - tnode = leftNode + if typeofNode.isNil: + typeofNode = nkCall.newTree( + exprParser.state.getIdent("typeof"), + leftNode + ) - let rightNode = exprParser.processTSNode(right, tnode) + let rightNode = exprParser.processTSNode(right, typeofNode) result.add leftNode result.add nkCall.newTree( - nkCall.newTree( - exprParser.state.getIdent("typeof"), - tnode - ), + typeofNode, rightNode ) @@ -317,6 +345,7 @@ proc processBitwiseExpression(exprParser: ExprParser, node: TSNode, typeofNode: var unarySym = exprParser.code[node.tsNodeStartByte() ..< child.tsNodeStartByte()].strip() techo "BIN SYM: ", unarySym + # TODO: Support more symbols here case unarySym of "~": nimSym = "not" @@ -330,7 +359,13 @@ proc processBitwiseExpression(exprParser: ExprParser, node: TSNode, typeofNode: else: raise newException(ExprParseError, &"Invalid bitwise_expression \"{node.val}\"") -proc processTSNode(exprParser: ExprParser, node: TSNode, typeofNode: PNode = nil): PNode = +proc processSizeofExpression(exprParser: ExprParser, node: TSNode, typeofNode: var PNode): PNode = + result = nkCall.newTree( + exprParser.state.getIdent("sizeof"), + exprParser.processTSNode(node[0], typeofNode) + ) + +proc processTSNode(exprParser: ExprParser, node: TSNode, typeofNode: var PNode): PNode = ## Handle all of the types of expressions here. This proc gets called recursively ## in the processX procs and will drill down to sub nodes. result = newNode(nkNone) @@ -351,42 +386,48 @@ proc processTSNode(exprParser: ExprParser, node: TSNode, typeofNode: PNode = nil raise newException(ExprParseError, &"Node type \"{nodeName}\" has no children") of "parenthesized_expression": result = exprParser.processParenthesizedExpr(node, typeofNode) - of "bitwise_expression": + of "sizeof_expression": + result = exprParser.processSizeofExpression(node, typeofNode) + of "bitwise_expression", "equality_expression": result = exprParser.processBitwiseExpression(node, typeofNode) of "math_expression": result = exprParser.processMathExpression(node, typeofNode) of "shift_expression": result = exprParser.processShiftExpression(node, typeofNode) + of "cast_expression": + result = exprParser.processCastExpression(node, typeofNode) of "logical_expression": result = exprParser.processLogicalExpression(node, typeofNode) # Why are these node types named true/false? of "true", "false": result = exprParser.state.parseString(node.val) - of "identifier": - var ident = node.val - if ident != "_": - # Process the identifier through cPlugin - ident = exprParser.state.getIdentifier(ident, nskConst) - techo ident - if ident != "": - result = exprParser.state.getIdent(ident) + of "type_descriptor": + let ty = getType(node.val) + result = exprParser.getIdent(ty, nskType, parent=node.getName()) if result.kind == nkNone: - raise newException(ExprParseError, &"Could not get identifier \"{ident}\"") + result = exprParser.state.getIdent(ty) + of "identifier": + result = exprParser.getIdent(node, parent=node.getName()) + if result.kind == nkNone: + raise newException(ExprParseError, &"Could not get identifier \"{node.val}\"") else: raise newException(ExprParseError, &"Unsupported node type \"{nodeName}\" for node \"{node.val}\"") - techo "NODE RES: ", result + techo "NODE RESULT: ", result proc codeToNode*(state: NimState, code: string): PNode = ## Convert the C string to a nim PNode tree result = newNode(nkNone) + # This is used for keeping track of the type of the first + # symbol + var tnode: PNode = nil + let exprParser = newExprParser(state, code) try: - let exprParser = newExprParser(state, code) withCodeAst(exprParser): - result = exprParser.processTSNode(root) + result = exprParser.processTSNode(root, tnode) except ExprParseError as e: - echo e.msg.getCommented + techo e.msg result = newNode(nkNone) except Exception as e: - echo e.msg.getCommented + techo "UNEXPECTED EXCEPTION: ", e.msg result = newNode(nkNone) \ No newline at end of file diff --git a/nimterop/getters.nim b/nimterop/getters.nim index f43f199..216d2e6 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -460,18 +460,16 @@ proc printTree*(gState: State, pnode: PNode, offset = ""): string = result &= "\n" proc printDebug*(nimState: NimState, node: TSNode) = - discard # This causes random segfaults for some reason on macOS Catalina if nimState.gState.debug: necho ("Input => " & nimState.getNodeVal(node)).getCommented() necho nimState.gState.printLisp(node).getCommented() proc printDebug*(nimState: NimState, pnode: PNode) = - discard # This causes random segfaults for some reason on macOS Catalina if nimState.gState.debug and pnode.kind != nkNone: necho ("Output => " & $pnode).getCommented() - necho nimState.printTree(pnode) + necho nimState.printTree(pnode).getCommented() # Compiler shortcuts From 173e6d625c3ea96a95580303fedd011684635cc4 Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Sun, 19 Apr 2020 19:18:04 -0600 Subject: [PATCH 406/593] Add string and char support Update some comments Rename exprparser main proc Don't export parse procs Add missing utils module Try to fix array type test Try fix cast test error Disable cast test for now Revert back comment test. Have to figure out how to test without vm --- nimterop/ast2.nim | 6 +-- nimterop/exprparser.nim | 101 +++++++++++++++++++++++++++++++++------- nimterop/utils.nim | 18 +++++++ tests/include/tast2.h | 6 +++ tests/tast2.nim | 12 +++-- 5 files changed, 120 insertions(+), 23 deletions(-) create mode 100644 nimterop/utils.nim diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index 8c5da8c..08ea2d6 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -18,7 +18,7 @@ proc getPtrType*(str: string): string = str proc getLit*(nimState: NimState, str: string, expression = false): PNode = - result = nimState.codeToNode(str) + result = nimState.parseCExpression(str) proc getOverrideOrSkip(gState: State, node: TSNode, origname: string, kind: NimSymKind): PNode = # Check if symbol `origname` of `kind` and `origname` has any cOverride defined @@ -164,7 +164,7 @@ proc addPragma(gState: State, node: TSNode, pragma: PNode, name: string, value: if value.isNil: pragma.add pident else: - var + let colExpr = newNode(nkExprColonExpr) colExpr.add pident colExpr.add value @@ -1386,7 +1386,7 @@ proc addEnum(gState: State, node: TSNode) = if en.len > 1 and en[1].getName() in gEnumVals: # Explicit value - fval = "(" & gState.getNimExpression(gState.getNodeVal(en[1]), name) & ")." & name + fval = "(" & $gState.parseCExpression(gState.getNodeVal(en[1]), name) & ")." & name # Cannot use newConstDef() since parseString(fval) adds backticks to and/or gState.constSection.add gState.parseString(&"const {fname}* = {fval}")[0][0] diff --git a/nimterop/exprparser.nim b/nimterop/exprparser.nim index d27f23b..183bb18 100644 --- a/nimterop/exprparser.nim +++ b/nimterop/exprparser.nim @@ -1,4 +1,4 @@ -import strformat, strutils, macros +import strformat, strutils, macros, sets import regex @@ -12,11 +12,12 @@ type ExprParser* = ref object state*: NimState code*: string + name*: string ExprParseError* = object of CatchableError -proc newExprParser*(state: NimState, code: string): ExprParser = - ExprParser(state: state, code: code) +proc newExprParser*(state: NimState, code: string, name = ""): ExprParser = + ExprParser(state: state, code: code, name: name) template techo(msg: varargs[string, `$`]) = if exprParser.state.gState.debug: @@ -38,6 +39,8 @@ proc getIdent(exprParser: ExprParser, identName: string, kind = nskConst, parent if ident != "_": # Process the identifier through cPlugin ident = exprParser.state.getIdentifier(ident, kind, parent) + if exprParser.name.nBl and ident in exprParser.state.constIdentifiers: + ident = ident & "." & exprParser.name if ident != "": result = exprParser.state.getIdent(ident) @@ -70,6 +73,58 @@ template withCodeAst(exprParser: ExprParser, body: untyped): untyped = defer: tree.tsTreeDelete() +proc parseChar(charStr: string): uint8 {.inline.} = + ## Parses a character literal out of a string. This is needed + ## because treesitter gives unescaped characters when parsing + ## strings. + if charStr.len == 1: + return charStr[0].uint8 + + # Handle octal, hex, unicode? + if charStr.startsWith("\\x"): + result = parseHexInt(charStr.replace("\\x", "0x")).uint8 + elif charStr.len == 4: # Octal + result = parseOctInt("0o" & charStr[1 ..< charStr.len]).uint8 + + if result == 0: + case charStr + of "\\0": + result = ord('\0') + of "\\a": + result = 0x07 + of "\\b": + result = 0x08 + of "\\e": + result = 0x1B + of "\\f": + result = 0x0C + of "\\n": + result = '\n'.uint8 + of "\\r": + result = 0x0D + of "\\t": + result = 0x09 + of "\\v": + result = 0x0B + of "\\\\": + result = 0x5C + of "\\'": + result = '\''.uint8 + of "\\\"": + result = '\"'.uint8 + of "\\?": + result = 0x3F + else: + discard + + if result > uint8.high: + result = uint8.high + +proc getCharLit(charStr: string): PNode {.inline.} = + ## Convert a character string into a proper Nim char lit node + result = newNode(nkCharLit) + result.intVal = parseChar(charStr).int64 + proc getNumNode(number, suffix: string): PNode {.inline.} = ## Convert a C number to a Nim number PNode result = newNode(nkNone) @@ -117,7 +172,7 @@ proc getNumNode(number, suffix: string): PNode {.inline.} = else: result.intVal = parseInt(number) -proc processNumberLiteral*(exprParser: ExprParser, node: TSNode): PNode = +proc processNumberLiteral(exprParser: ExprParser, node: TSNode): PNode = ## Parse a number literal from a TSNode. Can be a float, hex, long, etc result = newNode(nkNone) let nodeVal = node.val @@ -141,17 +196,29 @@ proc processNumberLiteral*(exprParser: ExprParser, node: TSNode): PNode = else: raise newException(ExprParseError, &"Could not find a number in number_literal: \"{nodeVal}\"") -proc processCharacterLiteral*(exprParser: ExprParser, node: TSNode): PNode = - result = newNode(nkCharLit) - result.intVal = node.val[1].int64 +proc processCharacterLiteral(exprParser: ExprParser, node: TSNode): PNode = + let val = node.val + result = getCharLit(val[1 ..< val.len - 1]) -proc processStringLiteral*(exprParser: ExprParser, node: TSNode): PNode = - let nodeVal = node.val - result = newStrNode(nkStrLit, nodeVal[1 ..< nodeVal.len - 1]) +proc processStringLiteral(exprParser: ExprParser, node: TSNode): PNode = + let + nodeVal = node.val + strVal = nodeVal[1 ..< nodeVal.len - 1] -proc processTSNode*(exprParser: ExprParser, node: TSNode, typeofNode: var PNode): PNode + const + str = "(\\\\x[[:xdigit:]]{2}|\\\\\\d{3}|\\\\0|\\\\a|\\\\b|\\\\e|\\\\f|\\\\n|\\\\r|\\\\t|\\\\v|\\\\\\\\|\\\\'|\\\\\"|[[:ascii:]])" + reg = re(str) -proc processShiftExpression*(exprParser: ExprParser, node: TSNode, typeofNode: var PNode): PNode = + # Convert the c string escape sequences/etc to Nim chars + var nimStr = newStringOfCap(nodeVal.len) + for m in strVal.findAll(reg): + nimStr.add(parseChar(strVal[m.group(0)[0]]).chr) + + result = newStrNode(nkStrLit, nimStr) + +proc processTSNode(exprParser: ExprParser, node: TSNode, typeofNode: var PNode): PNode + +proc processShiftExpression(exprParser: ExprParser, node: TSNode, typeofNode: var PNode): PNode = result = newNode(nkInfix) let left = node[0] @@ -185,18 +252,18 @@ proc processShiftExpression*(exprParser: ExprParser, node: TSNode, typeofNode: v rightNode ) -proc processParenthesizedExpr*(exprParser: ExprParser, node: TSNode, typeofNode: var PNode): PNode = +proc processParenthesizedExpr(exprParser: ExprParser, node: TSNode, typeofNode: var PNode): PNode = result = newNode(nkPar) for i in 0 ..< node.len(): result.add(exprParser.processTSNode(node[i], typeofNode)) -proc processCastExpression*(exprParser: ExprParser, node: TSNode, typeofNode: var PNode): PNode = +proc processCastExpression(exprParser: ExprParser, node: TSNode, typeofNode: var PNode): PNode = result = nkCast.newTree( exprParser.processTSNode(node[0], typeofNode), exprParser.processTSNode(node[1], typeofNode) ) -proc processLogicalExpression*(exprParser: ExprParser, node: TSNode, typeofNode: var PNode): PNode = +proc processLogicalExpression(exprParser: ExprParser, node: TSNode, typeofNode: var PNode): PNode = result = newNode(nkPar) let child = node[0] var nimSym = "" @@ -415,13 +482,13 @@ proc processTSNode(exprParser: ExprParser, node: TSNode, typeofNode: var PNode): techo "NODE RESULT: ", result -proc codeToNode*(state: NimState, code: string): PNode = +proc parseCExpression*(state: NimState, code: string, name = ""): PNode = ## Convert the C string to a nim PNode tree result = newNode(nkNone) # This is used for keeping track of the type of the first # symbol var tnode: PNode = nil - let exprParser = newExprParser(state, code) + let exprParser = newExprParser(state, code, name) try: withCodeAst(exprParser): result = exprParser.processTSNode(root, tnode) diff --git a/nimterop/utils.nim b/nimterop/utils.nim new file mode 100644 index 0000000..025256a --- /dev/null +++ b/nimterop/utils.nim @@ -0,0 +1,18 @@ +import compiler/[ast, lineinfos, msgs, options, parser, renderer] + +import "."/[globals, getters] + +proc handleError*(conf: ConfigRef, info: TLineInfo, msg: TMsgKind, arg: string) = + # Raise exception in parseString() instead of exiting for errors + if msg < warnMin: + raise newException(Exception, msgKindToString(msg)) + +proc parseString*(nimState: NimState, str: string): PNode = + # Parse a string into Nim AST - use custom error handler that raises + # an exception rather than exiting on failure + try: + result = parseString( + str, nimState.identCache, nimState.config, errorHandler = handleError + ) + except: + decho getCurrentExceptionMsg() \ No newline at end of file diff --git a/tests/include/tast2.h b/tests/include/tast2.h index 7e15ac0..3c6148a 100644 --- a/tests/include/tast2.h +++ b/tests/include/tast2.h @@ -23,6 +23,12 @@ extern "C" { #define BOOL true #define MATHEXPR (1 + 2/3*20 - 100) #define ANDEXPR (100 & 11000) +#define CASTEXPR (int) 34 + +#define NULLCHAR '\0' +#define OCTCHAR '\012' +#define HEXCHAR '\xFE' +#define TRICKYSTR "\x4E\034\nfoo\0\'\"\r\v\a\b\e\f\t\\\?bar" #define ALLSHL (SHL1 | SHL2 | SHL3) diff --git a/tests/tast2.nim b/tests/tast2.nim index d65e34a..d00552c 100644 --- a/tests/tast2.nim +++ b/tests/tast2.nim @@ -93,11 +93,11 @@ macro testFields(t: typed, fields: static[string] = "") = for i in 0 ..< rl.len: let name = ($rl[i][0]).strip(chars = {'*'}) - typ = ($(rl[i][1].repr())).replace("\n", "").replace(" ", "") + typ = ($(rl[i][1].repr())).replace("\n", "").replace(" ", "").replace("typeof", "type") n = names.find(name) assert n != -1, $t & "." & name & " invalid" - assert types[n] == typ, - "typeof(" & $t & ":" & name & ") != " & types[n] & ", is " & typ + assert types[n].replace("typeof", "type") == typ, + "typeof(" & $t & ":" & name & ") != " & types[n].replace("typeof", "type") & ", is " & typ assert A == 2 assert B == 1.0 @@ -118,6 +118,12 @@ assert BINEXPR == 5 assert BOOL == true assert MATHEXPR == -99 assert ANDEXPR == 96 +assert CASTEXPR == 34.chr + +assert TRICKYSTR == "N\x1C\nfoo\x00\'\"\c\v\a\b\e\f\t\\\\?bar" +assert NULLCHAR == '\0' +assert OCTCHAR == '\n' +assert HEXCHAR.int == 0xFE assert SHL1 == (1.uint shl 1) assert SHL2 == (1.uint shl 2) From aa1086fae37999180b485ced323d35acec7868a1 Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Mon, 20 Apr 2020 09:08:08 -0600 Subject: [PATCH 407/593] Fix cast type only run tast2 on supported compilers Change cast to gentle type cast Re enable tests for Nim < 1.0.0 --- nimterop/exprparser.nim | 6 +++--- tests/include/tast2.h | 6 +++--- tests/tast2.nim | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/nimterop/exprparser.nim b/nimterop/exprparser.nim index 183bb18..ed287a3 100644 --- a/nimterop/exprparser.nim +++ b/nimterop/exprparser.nim @@ -247,7 +247,7 @@ proc processShiftExpression(exprParser: ExprParser, node: TSNode, typeofNode: va let rightNode = exprParser.processTSNode(right, typeofNode) result.add leftNode - result.add nkCast.newTree( + result.add nkCall.newTree( typeofNode, rightNode ) @@ -258,7 +258,7 @@ proc processParenthesizedExpr(exprParser: ExprParser, node: TSNode, typeofNode: result.add(exprParser.processTSNode(node[i], typeofNode)) proc processCastExpression(exprParser: ExprParser, node: TSNode, typeofNode: var PNode): PNode = - result = nkCast.newTree( + result = nkCall.newTree( exprParser.processTSNode(node[0], typeofNode), exprParser.processTSNode(node[1], typeofNode) ) @@ -310,7 +310,7 @@ proc processMathExpression(exprParser: ExprParser, node: TSNode, typeofNode: var let rightNode = exprParser.processTSNode(right, typeofNode) res.add leftNode - res.add nkCast.newTree( + res.add nkCall.newTree( typeofNode, rightNode ) diff --git a/tests/include/tast2.h b/tests/include/tast2.h index 3c6148a..53b4d64 100644 --- a/tests/include/tast2.h +++ b/tests/include/tast2.h @@ -17,13 +17,13 @@ extern "C" { #define SHL1 (1u << 1) #define SHL2 (1u << 2) #define SHL3 (1u << 3) -#define COERCE 645635634896ull + -35436 -#define COERCE2 645635634896 + -35436 +#define COERCE 645635634896ull + 35436 +#define COERCE2 645635634896 + 35436ul #define BINEXPR ~(-(1u << !-1)) ^ (10 >> 1) #define BOOL true #define MATHEXPR (1 + 2/3*20 - 100) #define ANDEXPR (100 & 11000) -#define CASTEXPR (int) 34 +#define CASTEXPR (char) 34 #define NULLCHAR '\0' #define OCTCHAR '\012' diff --git a/tests/tast2.nim b/tests/tast2.nim index d00552c..d43ce9f 100644 --- a/tests/tast2.nim +++ b/tests/tast2.nim @@ -111,8 +111,8 @@ assert ULLEXPR == (1234.uint64 shl 3) assert LEXPR == (1234.int32 shl 4) assert LLEXPR == (1234.int64 shl 5) -assert COERCE == 645635599460'u64 -assert COERCE2 == 645635599460'i64 +assert COERCE == 645635670332'u64 +assert COERCE2 == 645635670332'i64 assert BINEXPR == 5 assert BOOL == true @@ -297,7 +297,7 @@ var a21p: A21p a21p = addr a20 assert A22 is object -testFields(A22, "f1|f2!ptr ptr cint|array[typeof(123)(123 + cast[typeof(123)](132)), ptr cint]") +testFields(A22, "f1|f2!ptr ptr cint|array[type(123)(255), ptr cint]") checkPragmas(A22, pHeaderBy, istype = false) var a22: A22 a22.f1 = addr a15.a2[0] From 208098b3eb959e477a3625a8a48305ddaa1cec4f Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Mon, 20 Apr 2020 11:33:53 -0600 Subject: [PATCH 408/593] Make bitwise_expression forwards compatible Skip syms for tmath Skip more syms Add casting back for cast_expression. Disable cast test on Nim < 1.0.0 Skip more syms for cast expressions on Nim < 1.0.0 --- nimterop/exprparser.nim | 8 +++++--- tests/tast2.nim | 11 +++++++++-- tests/tmath.nim | 4 ++++ 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/nimterop/exprparser.nim b/nimterop/exprparser.nim index ed287a3..207d7fd 100644 --- a/nimterop/exprparser.nim +++ b/nimterop/exprparser.nim @@ -258,7 +258,7 @@ proc processParenthesizedExpr(exprParser: ExprParser, node: TSNode, typeofNode: result.add(exprParser.processTSNode(node[i], typeofNode)) proc processCastExpression(exprParser: ExprParser, node: TSNode, typeofNode: var PNode): PNode = - result = nkCall.newTree( + result = nkCast.newTree( exprParser.processTSNode(node[0], typeofNode), exprParser.processTSNode(node[1], typeofNode) ) @@ -455,7 +455,9 @@ proc processTSNode(exprParser: ExprParser, node: TSNode, typeofNode: var PNode): result = exprParser.processParenthesizedExpr(node, typeofNode) of "sizeof_expression": result = exprParser.processSizeofExpression(node, typeofNode) - of "bitwise_expression", "equality_expression": + # binary_expression from the new treesitter upgrade should work here + # once we upgrade + of "bitwise_expression", "equality_expression", "binary_expression": result = exprParser.processBitwiseExpression(node, typeofNode) of "math_expression": result = exprParser.processMathExpression(node, typeofNode) @@ -497,4 +499,4 @@ proc parseCExpression*(state: NimState, code: string, name = ""): PNode = result = newNode(nkNone) except Exception as e: techo "UNEXPECTED EXCEPTION: ", e.msg - result = newNode(nkNone) \ No newline at end of file + result = newNode(nkNone) diff --git a/tests/tast2.nim b/tests/tast2.nim index d43ce9f..0b3762a 100644 --- a/tests/tast2.nim +++ b/tests/tast2.nim @@ -3,11 +3,16 @@ import macros, os, sets, strutils import nimterop/[cimport] static: + # Skip casting on lower nim compilers because + # the VM does not support it + when (NimMajor, NimMinor, NimPatch) < (1, 0, 0): + cSkipSymbol @["CASTEXPR"] cDebug() const path = currentSourcePath.parentDir() / "include" / "tast2.h" + when defined(HEADER): cDefine("HEADER") const @@ -118,7 +123,9 @@ assert BINEXPR == 5 assert BOOL == true assert MATHEXPR == -99 assert ANDEXPR == 96 -assert CASTEXPR == 34.chr + +when (NimMajor, NimMinor, NimPatch) >= (1, 0, 0): + assert CASTEXPR == 34.chr assert TRICKYSTR == "N\x1C\nfoo\x00\'\"\c\v\a\b\e\f\t\\\\?bar" assert NULLCHAR == '\0' @@ -453,4 +460,4 @@ checkPragmas(nested, pHeaderImpBy) when defined(HEADER): assert sitest1(5) == 10 - assert sitest1(10) == 20 \ No newline at end of file + assert sitest1(10) == 20 diff --git a/tests/tmath.nim b/tests/tmath.nim index 5d84700..bbf7abd 100644 --- a/tests/tmath.nim +++ b/tests/tmath.nim @@ -13,6 +13,10 @@ when defined(windows): complex = object static: + when (NimMajor, NimMinor, NimPatch) < (1, 0, 0): + cSkipSymbol @["mingw_choose_expr", "EXCEPTION_DEFINED", "COMPLEX_DEFINED", "matherr", "HUGE", "FP_ILOGB0", "FP_ILOGBNAN"] + else: + cSkipSymbol @["mingw_choose_expr", "EXCEPTION_DEFINED", "COMPLEX_DEFINED", "matherr", "HUGE"] cDebug() cDisableCaching() cAddStdDir() From 1576127a6e1b5f429d3fb91cf924fc41e43346cf Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Mon, 20 Apr 2020 17:09:08 -0600 Subject: [PATCH 409/593] Use tsNodeChild --- nimterop/exprparser.nim | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/nimterop/exprparser.nim b/nimterop/exprparser.nim index 207d7fd..610c0cb 100644 --- a/nimterop/exprparser.nim +++ b/nimterop/exprparser.nim @@ -223,7 +223,8 @@ proc processShiftExpression(exprParser: ExprParser, node: TSNode, typeofNode: va let left = node[0] right = node[1] - var shiftSym = exprParser.code[left.tsNodeEndByte() ..< right.tsNodeStartByte()].strip() + + let shiftSym = node.tsNodeChild(1).val.strip() case shiftSym of "<<": @@ -268,7 +269,7 @@ proc processLogicalExpression(exprParser: ExprParser, node: TSNode, typeofNode: let child = node[0] var nimSym = "" - var binarySym = exprParser.code[node.tsNodeStartByte() ..< child.tsNodeStartByte()].strip() + let binarySym = node.tsNodeChild(0).val.strip() techo "LOG SYM: ", binarySym case binarySym @@ -292,7 +293,7 @@ proc processMathExpression(exprParser: ExprParser, node: TSNode, typeofNode: var left = node[0] right = node[1] - let mathSym = exprParser.code[left.tsNodeEndByte() ..< right.tsNodeStartByte()].strip() + let mathSym = node.tsNodeChild(1).val.strip() techo "MATH SYM: ", mathSym res.add exprParser.state.getIdent(mathSym) @@ -329,7 +330,7 @@ proc processMathExpression(exprParser: ExprParser, node: TSNode, typeofNode: var let child = node[0] var nimSym = "" - let unarySym = exprParser.code[node.tsNodeStartByte() ..< child.tsNodeStartByte()].strip() + let unarySym = node.tsNodeChild(0).val.strip() techo "MATH SYM: ", unarySym case unarySym @@ -372,7 +373,7 @@ proc processBitwiseExpression(exprParser: ExprParser, node: TSNode, typeofNode: var nimSym = "" - var binarySym = exprParser.code[left.tsNodeEndByte() ..< right.tsNodeStartByte()].strip() + let binarySym = node.tsNodeChild(1).val.strip() techo "BIN SYM: ", binarySym case binarySym @@ -409,7 +410,7 @@ proc processBitwiseExpression(exprParser: ExprParser, node: TSNode, typeofNode: let child = node[0] var nimSym = "" - var unarySym = exprParser.code[node.tsNodeStartByte() ..< child.tsNodeStartByte()].strip() + let unarySym = node.tsNodeChild(0).val.strip() techo "BIN SYM: ", unarySym # TODO: Support more symbols here @@ -437,7 +438,9 @@ proc processTSNode(exprParser: ExprParser, node: TSNode, typeofNode: var PNode): ## in the processX procs and will drill down to sub nodes. result = newNode(nkNone) let nodeName = node.getName() + techo "NODE: ", nodeName, ", VAL: ", node.val + case nodeName of "number_literal": result = exprParser.processNumberLiteral(node) From a84adfe1d8db39e91f4e0e0af4cd81f02cee2fd6 Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Mon, 20 Apr 2020 17:55:05 -0600 Subject: [PATCH 410/593] Add comments describing capabilities --- nimterop/exprparser.nim | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/nimterop/exprparser.nim b/nimterop/exprparser.nim index 610c0cb..1fc72ab 100644 --- a/nimterop/exprparser.nim +++ b/nimterop/exprparser.nim @@ -8,6 +8,27 @@ import "."/treesitter/[api, c, cpp] import "."/[globals, getters, utils] +# This version of exprparser should be able to handle: +# +# All integers + integer like expressions (hex, octal, suffixes) +# All floating point expressions (except for C++'s hex floating point stuff) +# Strings and character literals, including C's escape characters (not sure if this is the same as C++'s escape characters or not) +# Math operators (+, -, /, *) +# Some Unary operators (-, !, ~). ++, --, and & are yet to be implemented +# Any identifiers +# C type descriptors (int, char, etc) +# Boolean values (true, false) +# Shift expressions (containing anything in this list) +# Cast expressions (containing anything in this list) +# Math expressions (containing anything in this list) +# Sizeof expressions (containing anything in this list) +# Cast expressions (containing anything in this list) +# Parentheses expressions (containing anything in this list) +# Expressions containing other expressions +# +# In addition to the above, it should also handle most type coercions, except +# for where Nim can't (such as uint + -int) + type ExprParser* = ref object state*: NimState @@ -413,7 +434,7 @@ proc processBitwiseExpression(exprParser: ExprParser, node: TSNode, typeofNode: let unarySym = node.tsNodeChild(0).val.strip() techo "BIN SYM: ", unarySym - # TODO: Support more symbols here + # TODO: Support more symbols here. ++, --, & case unarySym of "~": nimSym = "not" From d83884a3917cf96b7df209d47c7301919cce3967 Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Mon, 20 Apr 2020 18:04:12 -0600 Subject: [PATCH 411/593] Add missing sized type specifier for 'long int', etc --- nimterop/exprparser.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimterop/exprparser.nim b/nimterop/exprparser.nim index 1fc72ab..44e59d6 100644 --- a/nimterop/exprparser.nim +++ b/nimterop/exprparser.nim @@ -494,7 +494,7 @@ proc processTSNode(exprParser: ExprParser, node: TSNode, typeofNode: var PNode): # Why are these node types named true/false? of "true", "false": result = exprParser.state.parseString(node.val) - of "type_descriptor": + of "type_descriptor", "sized_type_specifier": let ty = getType(node.val) result = exprParser.getIdent(ty, nskType, parent=node.getName()) if result.kind == nkNone: From 4794c076ffc7f46858dfebfdae47d8e3c47d1cf7 Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Mon, 20 Apr 2020 19:01:53 -0600 Subject: [PATCH 412/593] Fix pcre tests --- tests/tpcre.nim | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/tpcre.nim b/tests/tpcre.nim index c8e8059..3bbd1ba 100644 --- a/tests/tpcre.nim +++ b/tests/tpcre.nim @@ -7,6 +7,7 @@ const pcreH = baseDir/"pcre.h.in" static: + cSkipSymbol @["PCRE_UCHAR16", "PCRE_UCHAR32"] if not pcreH.fileExists(): downloadUrl("https://github.com/svn2github/pcre/raw/master/pcre.h.in", baseDir) cDebug() From b1a445c34dfff04d5c799b7c4ee0f7e806900e91 Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Wed, 22 Apr 2020 01:16:19 -0600 Subject: [PATCH 413/593] Update based on comments from review. Need to add more docs and reorg to use gstate --- nimterop/ast2.nim | 30 +- nimterop/{utils.nim => comphelp.nim} | 0 nimterop/exprparser.nim | 394 ++++++++++++--------------- nimterop/getters.nim | 20 +- nimterop/toast.nim | 20 +- nimterop/tshelp.nim | 30 ++ tests/tast2.nim | 1 - 7 files changed, 249 insertions(+), 246 deletions(-) rename nimterop/{utils.nim => comphelp.nim} (100%) create mode 100644 nimterop/tshelp.nim diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index 08ea2d6..1b7fb3d 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -1,10 +1,12 @@ import macros, os, sequtils, sets, strformat, strutils, tables, times +import options as opts + import compiler/[ast, idents, lineinfos, modulegraphs, msgs, options, renderer] import "."/treesitter/api -import "."/[globals, getters, exprparser, utils] +import "."/[globals, getters, exprparser, comphelp] proc getPtrType*(str: string): string = result = case str: @@ -17,9 +19,6 @@ proc getPtrType*(str: string): string = else: str -proc getLit*(nimState: NimState, str: string, expression = false): PNode = - result = nimState.parseCExpression(str) - proc getOverrideOrSkip(gState: State, node: TSNode, origname: string, kind: NimSymKind): PNode = # Check if symbol `origname` of `kind` and `origname` has any cOverride defined # and use that if present @@ -101,7 +100,7 @@ proc newConstDef(gState: State, node: TSNode, fname = "", fval = ""): PNode = else: gState.getNodeVal(node[1]) valident = - gState.getLit(val) + gState.parseCExpression(val) if name.Bl: # Name skipped or overridden since blank @@ -962,7 +961,7 @@ proc getTypeArray(gState: State, node: TSNode, tident: PNode, name: string): PNo # type name[X] => array[X, type] let # Size of array could be a Nim expression - size = gState.getLit(gState.getNodeVal(cnode[1]), expression = true) + size = gState.parseCExpression(gState.getNodeVal(cnode[1])) if size.kind != nkNone: result = gState.newArrayTree(cnode, result, size) cnode = cnode[0] @@ -1367,6 +1366,7 @@ proc addEnum(gState: State, node: TSNode) = # Create const for fields var fnames: HashSet[string] + fvalSections: seq[tuple[fname: string, fval: string, cexpr: Option[TSNode]]] for i in 0 .. enumlist.len - 1: let en = enumlist[i] @@ -1385,20 +1385,25 @@ proc addEnum(gState: State, node: TSNode) = fval = &"({prev} + 1).{name}" if en.len > 1 and en[1].getName() in gEnumVals: - # Explicit value - fval = "(" & $gState.parseCExpression(gState.getNodeVal(en[1]), name) & ")." & name - - # Cannot use newConstDef() since parseString(fval) adds backticks to and/or - gState.constSection.add gState.parseString(&"const {fname}* = {fval}")[0][0] + fvalSections.add((fname, "", some(en[1]))) + else: + fvalSections.add((fname, fval, none(TSNode))) fnames.incl fname - prev = fname # Add fields to list of consts after processing enum so that we don't cast # enum field to itself gState.constIdentifiers.incl fnames + # parseCExpression requires all const identifiers to be present for the enum + for (fname, fval, cexprNode) in fvalSections: + var fval = fval + if cexprNode.isSome: + fval = "(" & $nimState.parseCExpression(nimState.getNodeVal(cexprNode.get()), name) & ")." & name + # Cannot use newConstDef() since parseString(fval) adds backticks to and/or + nimState.constSection.add nimState.parseString(&"const {fname}* = {fval}")[0][0] + # Add other names if node.getName() == "type_definition" and node.len > 1: gState.addTypeTyped(node, ftname = name, offset = offset) @@ -1486,7 +1491,6 @@ proc addProc(gState: State, node, rnode: TSNode) = # Parameter list plist = node.anyChildInTree("parameter_list") - var procDef = newNode(nkProcDef) # proc X(a1: Y, a2: Z): P {.pragma.} diff --git a/nimterop/utils.nim b/nimterop/comphelp.nim similarity index 100% rename from nimterop/utils.nim rename to nimterop/comphelp.nim diff --git a/nimterop/exprparser.nim b/nimterop/exprparser.nim index 44e59d6..2ce4989 100644 --- a/nimterop/exprparser.nim +++ b/nimterop/exprparser.nim @@ -6,7 +6,7 @@ import compiler/[ast, renderer] import "."/treesitter/[api, c, cpp] -import "."/[globals, getters, utils] +import "."/[globals, getters, comphelp, tshelp] # This version of exprparser should be able to handle: # @@ -41,9 +41,9 @@ proc newExprParser*(state: NimState, code: string, name = ""): ExprParser = ExprParser(state: state, code: code, name: name) template techo(msg: varargs[string, `$`]) = - if exprParser.state.gState.debug: + block: let nimState {.inject.} = exprParser.state - necho join(msg, "").getCommented + decho join(msg, "") template val(node: TSNode): string = exprParser.code.getNodeVal(node) @@ -60,9 +60,11 @@ proc getIdent(exprParser: ExprParser, identName: string, kind = nskConst, parent if ident != "_": # Process the identifier through cPlugin ident = exprParser.state.getIdentifier(ident, kind, parent) - if exprParser.name.nBl and ident in exprParser.state.constIdentifiers: - ident = ident & "." & exprParser.name - if ident != "": + if kind == nskType: + result = exprParser.state.getIdent(ident) + elif ident.nBl and ident in exprParser.state.constIdentifiers: + if exprParser.name.nBl: + ident = ident & "." & exprParser.name result = exprParser.state.getIdent(ident) proc getIdent(exprParser: ExprParser, node: TSNode, kind = nskConst, parent = ""): PNode = @@ -71,29 +73,6 @@ proc getIdent(exprParser: ExprParser, node: TSNode, kind = nskConst, parent = "" ## Returns PNode(nkNone) if the identifier is blank exprParser.getIdent(node.val, kind, parent) -template withCodeAst(exprParser: ExprParser, body: untyped): untyped = - ## A simple template to inject the TSNode into a body of code - var parser = tsParserNew() - defer: - parser.tsParserDelete() - - doAssert exprParser.code.nBl, "Empty code" - if exprParser.mode == "c": - doAssert parser.tsParserSetLanguage(treeSitterC()), "Failed to load C parser" - elif exprParser.mode == "cpp": - doAssert parser.tsParserSetLanguage(treeSitterCpp()), "Failed to load C++ parser" - else: - doAssert false, &"Invalid parser {exprParser.mode}" - - var - tree = parser.tsParserParseString(nil, exprParser.code.cstring, exprParser.code.len.uint32) - root {.inject.} = tree.tsTreeRootNode() - - body - - defer: - tree.tsTreeDelete() - proc parseChar(charStr: string): uint8 {.inline.} = ## Parses a character literal out of a string. This is needed ## because treesitter gives unescaped characters when parsing @@ -161,37 +140,36 @@ proc getNumNode(number, suffix: string): PNode {.inline.} = result = newFloatNode(nkFloat64Lit, parseFloat(number[0 ..< number.len - 1])) else: result = newFloatNode(nkFloatLit, parseFloat(number)) - return except ValueError: raise newException(ExprParseError, &"Could not parse float value \"{number}\".") - - case suffix - of "u", "U": - result = newNode(nkUintLit) - of "l", "L": - result = newNode(nkInt32Lit) - of "ul", "UL": - result = newNode(nkUint32Lit) - of "ll", "LL": - result = newNode(nkInt64Lit) - of "ull", "ULL": - result = newNode(nkUint64Lit) else: - result = newNode(nkIntLit) + case suffix + of "u", "U": + result = newNode(nkUintLit) + of "l", "L": + result = newNode(nkInt32Lit) + of "ul", "UL": + result = newNode(nkUint32Lit) + of "ll", "LL": + result = newNode(nkInt64Lit) + of "ull", "ULL": + result = newNode(nkUint64Lit) + else: + result = newNode(nkIntLit) - # I realize these regex are wasteful on performance, but - # couldn't come up with a better idea. - if number.contains(re"0[xX]"): - result.intVal = parseHexInt(number) - result.flags = {nfBase16} - elif number.contains(re"0[bB]"): - result.intVal = parseBinInt(number) - result.flags = {nfBase2} - elif number.contains(re"0[oO]"): - result.intVal = parseOctInt(number) - result.flags = {nfBase8} - else: - result.intVal = parseInt(number) + # I realize these regex are wasteful on performance, but + # couldn't come up with a better idea. + if number.contains(re"0[xX]"): + result.intVal = parseHexInt(number) + result.flags = {nfBase16} + elif number.contains(re"0[bB]"): + result.intVal = parseBinInt(number) + result.flags = {nfBase2} + elif number.contains(re"0[oO]"): + result.intVal = parseOctInt(number) + result.flags = {nfBase8} + else: + result.intVal = parseInt(number) proc processNumberLiteral(exprParser: ExprParser, node: TSNode): PNode = ## Parse a number literal from a TSNode. Can be a float, hex, long, etc @@ -285,168 +263,112 @@ proc processCastExpression(exprParser: ExprParser, node: TSNode, typeofNode: var exprParser.processTSNode(node[1], typeofNode) ) -proc processLogicalExpression(exprParser: ExprParser, node: TSNode, typeofNode: var PNode): PNode = - result = newNode(nkPar) - let child = node[0] - var nimSym = "" - - let binarySym = node.tsNodeChild(0).val.strip() - techo "LOG SYM: ", binarySym - - case binarySym - of "!": - nimSym = "not" +proc getNimUnarySym(csymbol: string): string = + ## Get the Nim equivalent of a unary C symbol + ## + ## TODO: Add ++, --, + case csymbol + of "+", "-": + result = csymbol + of "~", "!": + result = "not" else: - raise newException(ExprParseError, &"Unsupported logical symbol \"{binarySym}\"") + raise newException(ExprParseError, &"Unsupported unary symbol \"{csymbol}\"") - techo "LOG CHILD: ", child.val, ", nim: ", nimSym - result.add nkPrefix.newTree( - exprParser.state.getIdent(nimSym), - exprParser.processTSNode(child, typeofNode) +proc getNimBinarySym(csymbol: string): string = + case csymbol + of "|", "||": + result = "or" + of "&", "&&": + result = "and" + of "^": + result = "xor" + of "==", "!=", + "+", "-", "/", "*", + ">", "<", ">=", "<=": + result = csymbol + of "%": + result = "mod" + else: + raise newException(ExprParseError, &"Unsupported binary symbol \"{csymbol}\"") + +proc processBinaryExpression(exprParser: ExprParser, node: TSNode, typeofNode: var PNode): PNode = + # Node has left and right children ie: (2 + 7) + result = newNode(nkInfix) + + let + left = node[0] + right = node[1] + binarySym = node.tsNodeChild(1).val.strip() + nimSym = getNimBinarySym(binarySym) + + result.add exprParser.state.getIdent(nimSym) + let leftNode = exprParser.processTSNode(left, typeofNode) + + if typeofNode.isNil: + typeofNode = nkCall.newTree( + exprParser.state.getIdent("typeof"), + leftNode + ) + + let rightNode = exprParser.processTSNode(right, typeofNode) + + result.add leftNode + result.add nkCall.newTree( + typeofNode, + rightNode ) -proc processMathExpression(exprParser: ExprParser, node: TSNode, typeofNode: var PNode): PNode = +proc processUnaryExpression(exprParser: ExprParser, node: TSNode, typeofNode: var PNode): PNode = + result = newNode(nkPar) + + let + child = node[0] + unarySym = node.tsNodeChild(0).val.strip() + nimSym = getNimUnarySym(unarySym) + + if nimSym == "-": + # Special case. The minus symbol must be in front of an integer, + # so we have to make a gentle cast here to coerce it to one. + # Might be bad because we are overwriting the type + # There's probably a better way of doing this + if typeofNode.isNil: + typeofNode = exprParser.state.getIdent("int64") + + result.add nkPrefix.newTree( + exprParser.state.getIdent(unarySym), + nkPar.newTree( + nkCall.newTree( + exprParser.state.getIdent("int64"), + exprParser.processTSNode(child, typeofNode) + ) + ) + ) + else: + result.add nkPrefix.newTree( + exprParser.state.getIdent(nimSym), + exprParser.processTSNode(child, typeofNode) + ) + +proc processUnaryOrBinaryExpression(exprParser: ExprParser, node: TSNode, typeofNode: var PNode): PNode = if node.len > 1: # Node has left and right children ie: (2 + 7) - var - res = newNode(nkInfix) - let - left = node[0] - right = node[1] - - let mathSym = node.tsNodeChild(1).val.strip() - techo "MATH SYM: ", mathSym - - res.add exprParser.state.getIdent(mathSym) - let leftNode = exprParser.processTSNode(left, typeofNode) - - # If the typeofNode is nil, set it - # to be the leftNode because C's type coercion - # happens left to right, and we want to emulate it - if typeofNode.isNil: - typeofNode = nkCall.newTree( - exprParser.state.getIdent("typeof"), - leftNode - ) - - let rightNode = exprParser.processTSNode(right, typeofNode) - - res.add leftNode - res.add nkCall.newTree( - typeofNode, - rightNode - ) # Make sure the statement is of the same type as the left # hand argument, since some expressions return a differing # type than the input types (2/3 == float) + let binExpr = processBinaryExpression(exprParser, node, typeofNode) + # Note that this temp var binExpr is needed for some reason, or else we get a segfault result = nkCall.newTree( typeofNode, - res + binexpr ) elif node.len() == 1: # Node has only one child, ie -(20 + 7) - result = newNode(nkPar) - let child = node[0] - var nimSym = "" - - let unarySym = node.tsNodeChild(0).val.strip() - techo "MATH SYM: ", unarySym - - case unarySym - of "+": - nimSym = "+" - of "-": - # Special case. The minus symbol must be in front of an integer, - # so we have to make a gental cast here to coerce it to one. - # Might be bad because we are overwriting the type - # There's probably a better way of doing this - if typeofNode.isNil: - typeofNode = exprParser.state.getIdent("int64") - result.add nkPrefix.newTree( - exprParser.state.getIdent(unarySym), - nkPar.newTree( - nkCall.newTree( - exprParser.state.getIdent("int64"), - exprParser.processTSNode(child, typeofNode) - ) - ) - ) - return - else: - raise newException(ExprParseError, &"Unsupported unary symbol \"{unarySym}\"") - - result.add nkPrefix.newTree( - exprParser.state.getIdent(nimSym), - exprParser.processTSNode(child, typeofNode) - ) + result = processUnaryExpression(exprParser, node, typeofNode) else: - raise newException(ExprParseError, &"Invalid bitwise_expression \"{node.val}\"") - -proc processBitwiseExpression(exprParser: ExprParser, node: TSNode, typeofNode: var PNode): PNode = - if node.len() > 1: - result = newNode(nkInfix) - - let - left = node[0] - right = node[1] - - var nimSym = "" - - let binarySym = node.tsNodeChild(1).val.strip() - techo "BIN SYM: ", binarySym - - case binarySym - of "|", "||": - nimSym = "or" - of "&", "&&": - nimSym = "and" - of "^": - nimSym = "xor" - of "==", "!=": - nimSym = binarySym - else: - raise newException(ExprParseError, &"Unsupported binary symbol \"{binarySym}\"") - - result.add exprParser.state.getIdent(nimSym) - let leftNode = exprParser.processTSNode(left, typeofNode) - - if typeofNode.isNil: - typeofNode = nkCall.newTree( - exprParser.state.getIdent("typeof"), - leftNode - ) - - let rightNode = exprParser.processTSNode(right, typeofNode) - - result.add leftNode - result.add nkCall.newTree( - typeofNode, - rightNode - ) - - elif node.len() == 1: - result = newNode(nkPar) - let child = node[0] - var nimSym = "" - - let unarySym = node.tsNodeChild(0).val.strip() - techo "BIN SYM: ", unarySym - - # TODO: Support more symbols here. ++, --, & - case unarySym - of "~": - nimSym = "not" - else: - raise newException(ExprParseError, &"Unsupported unary symbol \"{unarySym}\"") - - result.add nkPrefix.newTree( - exprParser.state.getIdent(nimSym), - exprParser.processTSNode(child, typeofNode) - ) - else: - raise newException(ExprParseError, &"Invalid bitwise_expression \"{node.val}\"") + raise newException(ExprParseError, &"Invalid {node.getName()} \"{node.val}\"") proc processSizeofExpression(exprParser: ExprParser, node: TSNode, typeofNode: var PNode): PNode = result = nkCall.newTree( @@ -464,45 +386,85 @@ proc processTSNode(exprParser: ExprParser, node: TSNode, typeofNode: var PNode): case nodeName of "number_literal": + # Input -> 0x1234FE, 1231, 123u, 123ul, 123ull, 1.334f + # Output -> 0x1234FE, 1231, 123'u, 123'u32, 123'u64, 1.334 result = exprParser.processNumberLiteral(node) of "string_literal": + # Input -> "foo\0\x42" + # Output -> "foo\0" result = exprParser.processStringLiteral(node) of "char_literal": + # Input -> 'F', '\034' // Octal, '\x5A' // Hex, '\r' // escape sequences + # Output -> result = exprParser.processCharacterLiteral(node) of "expression_statement", "ERROR", "translation_unit": - # This may be wrong. What can be in an expression? - if node.len > 0: + # Note that we're parsing partial expressions, so the TSNode might contain + # an ERROR node. If that's the case, they usually contain children with + # partial results, which will contain parsed expressions + # + # Input (top level statement) -> ((1 + 3 - IDENT) - (int)400.0) + # Output -> (1 + typeof(1)(3) - typeof(1)(IDENT) - typeof(1)(cast[int](400.0))) # Type casting in case some args differ + if node.len == 1: result = exprParser.processTSNode(node[0], typeofNode) + elif node.len > 1: + result = newNode(nkStmtListExpr) + for i in 0 ..< node.len: + result.add exprParser.processTSNode(node[i], typeofNode) else: raise newException(ExprParseError, &"Node type \"{nodeName}\" has no children") of "parenthesized_expression": + # Input -> (IDENT - OTHERIDENT) + # Output -> (IDENT - typeof(IDENT)(OTHERIDENT)) # Type casting in case OTHERIDENT is a slightly different type (uint vs int) result = exprParser.processParenthesizedExpr(node, typeofNode) of "sizeof_expression": + # Input -> sizeof(char) + # Output -> sizeof(cchar) result = exprParser.processSizeofExpression(node, typeofNode) # binary_expression from the new treesitter upgrade should work here # once we upgrade - of "bitwise_expression", "equality_expression", "binary_expression": - result = exprParser.processBitwiseExpression(node, typeofNode) - of "math_expression": - result = exprParser.processMathExpression(node, typeofNode) + of "math_expression", "logical_expression", "relational_expression", + "bitwise_expression", "equality_expression", "binary_expression": + # Input -> a == b, a != b, !a, ~a, a < b, a > b, a <= b, a >= b + # Output -> + # typeof(a)(a == typeof(a)(b)) + # typeof(a)(a != typeof(a)(b)) + # (not a) + # (not a) + # typeof(a)(a < typeof(a)(b)) + # typeof(a)(a > typeof(a)(b)) + # typeof(a)(a <= typeof(a)(b)) + # typeof(a)(a >= typeof(a)(b)) + result = exprParser.processUnaryOrBinaryExpression(node, typeofNode) of "shift_expression": + # Input -> a >> b, a << b + # Output -> a shr typeof(a)(b), a shl typeof(a)(b) result = exprParser.processShiftExpression(node, typeofNode) of "cast_expression": + # Input -> (int) a + # Output -> cast[cint](a) result = exprParser.processCastExpression(node, typeofNode) - of "logical_expression": - result = exprParser.processLogicalExpression(node, typeofNode) # Why are these node types named true/false? of "true", "false": + # Input -> true, false + # Output -> true, false result = exprParser.state.parseString(node.val) of "type_descriptor", "sized_type_specifier": + # Input -> int, unsigned int, long int, etc + # Output -> cint, cuint, clong, etc let ty = getType(node.val) - result = exprParser.getIdent(ty, nskType, parent=node.getName()) - if result.kind == nkNone: - result = exprParser.state.getIdent(ty) + if ty.len > 0: + # If ty is not empty, one of C's builtin types has been found + result = exprParser.getIdent(ty, nskType, parent=node.getName()) + else: + result = exprParser.getIdent(node.val, nskType, parent=node.getName()) + if result.kind == nkNone: + raise newException(ExprParseError, &"Missing type specifier \"{node.val}\"") of "identifier": + # Input -> IDENT + # Output -> IDENT (if found in sym table, else error) result = exprParser.getIdent(node, parent=node.getName()) if result.kind == nkNone: - raise newException(ExprParseError, &"Could not get identifier \"{node.val}\"") + raise newException(ExprParseError, &"Missing identifier \"{node.val}\"") else: raise newException(ExprParseError, &"Unsupported node type \"{nodeName}\" for node \"{node.val}\"") @@ -512,15 +474,15 @@ proc parseCExpression*(state: NimState, code: string, name = ""): PNode = ## Convert the C string to a nim PNode tree result = newNode(nkNone) # This is used for keeping track of the type of the first - # symbol + # symbol used for type casting var tnode: PNode = nil let exprParser = newExprParser(state, code, name) try: - withCodeAst(exprParser): + withCodeAst(exprParser.code, exprParser.mode): result = exprParser.processTSNode(root, tnode) except ExprParseError as e: techo e.msg result = newNode(nkNone) except Exception as e: techo "UNEXPECTED EXCEPTION: ", e.msg - result = newNode(nkNone) + result = newNode(nkNone) \ No newline at end of file diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 216d2e6..b7744ce 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -401,7 +401,7 @@ proc printLisp*(code: var string, root: TSNode): string = if node.len() != 0: result &= "\n" - nextnode = node.tsNodeNamedChild(0) + nextnode = node[0] depth += 1 else: result &= ")\n" @@ -432,7 +432,7 @@ proc getCommented*(str: string): string = "\n# " & str.strip().replace("\n", "\n# ") proc printTree*(gState: State, pnode: PNode, offset = ""): string = - if gState.debug and pnode.kind != nkNone: + if not pnode.isNil and gState.debug and pnode.kind != nkNone: result &= "\n# " & offset & $pnode.kind & "(" case pnode.kind of nkCharLit: @@ -459,17 +459,17 @@ proc printTree*(gState: State, pnode: PNode, offset = ""): string = if offset.len == 0: result &= "\n" -proc printDebug*(nimState: NimState, node: TSNode) = +proc printDebug*(gState: State, node: TSNode) = # This causes random segfaults for some reason on macOS Catalina - if nimState.gState.debug: - necho ("Input => " & nimState.getNodeVal(node)).getCommented() - necho nimState.gState.printLisp(node).getCommented() + if gState.debug: + gecho ("Input => " & gState.getNodeVal(node)).getCommented() + gecho gState.printLisp(node).getCommented() -proc printDebug*(nimState: NimState, pnode: PNode) = +proc printDebug*(gState: State, pnode: PNode) = # This causes random segfaults for some reason on macOS Catalina - if nimState.gState.debug and pnode.kind != nkNone: - necho ("Output => " & $pnode).getCommented() - necho nimState.printTree(pnode).getCommented() + if gState.debug and pnode.kind != nkNone: + gecho ("Output => " & $pnode).getCommented() + gecho gState.printTree(pnode).getCommented() # Compiler shortcuts diff --git a/nimterop/toast.nim b/nimterop/toast.nim index ab44970..afb511d 100644 --- a/nimterop/toast.nim +++ b/nimterop/toast.nim @@ -2,16 +2,11 @@ import os, osproc, strformat, strutils, tables, times import "."/treesitter/[api, c, cpp] -import "."/[ast, ast2, globals, getters, grammar, build] +import "."/[ast, ast2, globals, getters, grammar, build, tshelp] proc process(gState: State, path: string, astTable: AstTable) = doAssert existsFile(path), &"Invalid path {path}" - var parser = tsParserNew() - - defer: - parser.tsParserDelete() - if gState.mode.Bl: gState.mode = getCompilerMode(path) @@ -20,6 +15,7 @@ proc process(gState: State, path: string, astTable: AstTable) = else: gState.code = readFile(path) +<<<<<<< HEAD doAssert gState.code.nBl, "Empty file or preprocessor error" if gState.mode == "c": @@ -45,6 +41,18 @@ proc process(gState: State, path: string, astTable: AstTable) = ast.parseNim(gState, path, root, astTable) elif gState.preprocess: gecho gState.code +======= + withCodeAst(gState.code, gState.mode): + if gState.past: + gecho gState.printLisp(root) + elif gState.pnim: + if Feature.ast2 in gState.feature: + ast2.printNim(gState, path, root) + else: + ast.printNim(gState, path, root, astTable) + elif gState.preprocess: + gecho gState.code +>>>>>>> Update based on comments from review. Need to add more docs and reorg to use gstate # CLI processing with default values proc main( diff --git a/nimterop/tshelp.nim b/nimterop/tshelp.nim new file mode 100644 index 0000000..f234bc0 --- /dev/null +++ b/nimterop/tshelp.nim @@ -0,0 +1,30 @@ +template withCodeAst*(inputCode: string, inputMode: string, body: untyped): untyped = + ## A simple template to inject the TSNode into a body of code + + # This section is needed to be able to reference + # mode in strformat calls + let + code = inputCode + mode {.inject.} = inputMode + + var parser = tsParserNew() + defer: + parser.tsParserDelete() + + doAssert code.nBl, "Empty code or preprocessor error" + + if mode == "c": + doAssert parser.tsParserSetLanguage(treeSitterC()), "Failed to load C parser" + elif mode == "cpp": + doAssert parser.tsParserSetLanguage(treeSitterCpp()), "Failed to load C++ parser" + else: + doAssert false, &"Invalid parser {mode}" + + var + tree = parser.tsParserParseString(nil, code.cstring, code.len.uint32) + root {.inject.} = tree.tsTreeRootNode() + + body + + defer: + tree.tsTreeDelete() \ No newline at end of file diff --git a/tests/tast2.nim b/tests/tast2.nim index 0b3762a..e82430b 100644 --- a/tests/tast2.nim +++ b/tests/tast2.nim @@ -12,7 +12,6 @@ static: const path = currentSourcePath.parentDir() / "include" / "tast2.h" - when defined(HEADER): cDefine("HEADER") const From 8a0f7954ae3754258706796ccd018f79ddb0158d Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Wed, 22 Apr 2020 20:20:34 -0600 Subject: [PATCH 414/593] nimState -> gState --- nimterop/ast2.nim | 8 +- nimterop/comphelp.nim | 4 +- nimterop/exprparser.nim | 247 ++++++++++++++++++++-------------------- nimterop/globals.nim | 9 +- nimterop/toast.nim | 32 +----- 5 files changed, 136 insertions(+), 164 deletions(-) diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index 1b7fb3d..4fec237 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -104,9 +104,9 @@ proc newConstDef(gState: State, node: TSNode, fname = "", fval = ""): PNode = if name.Bl: # Name skipped or overridden since blank - result = nimState.getOverrideOrSkip(node, origname, nskConst) + result = gState.getOverrideOrSkip(node, origname, nskConst) elif valident.kind != nkNone: - if nimState.addNewIdentifer(name): + if gState.addNewIdentifer(name): # const X* = Y # # nkConstDef( @@ -1400,9 +1400,9 @@ proc addEnum(gState: State, node: TSNode) = for (fname, fval, cexprNode) in fvalSections: var fval = fval if cexprNode.isSome: - fval = "(" & $nimState.parseCExpression(nimState.getNodeVal(cexprNode.get()), name) & ")." & name + fval = "(" & $gState.parseCExpression(gState.getNodeVal(cexprNode.get()), name) & ")." & name # Cannot use newConstDef() since parseString(fval) adds backticks to and/or - nimState.constSection.add nimState.parseString(&"const {fname}* = {fval}")[0][0] + gState.constSection.add gState.parseString(&"const {fname}* = {fval}")[0][0] # Add other names if node.getName() == "type_definition" and node.len > 1: diff --git a/nimterop/comphelp.nim b/nimterop/comphelp.nim index 025256a..1709f8b 100644 --- a/nimterop/comphelp.nim +++ b/nimterop/comphelp.nim @@ -7,12 +7,12 @@ proc handleError*(conf: ConfigRef, info: TLineInfo, msg: TMsgKind, arg: string) if msg < warnMin: raise newException(Exception, msgKindToString(msg)) -proc parseString*(nimState: NimState, str: string): PNode = +proc parseString*(gState: State, str: string): PNode = # Parse a string into Nim AST - use custom error handler that raises # an exception rather than exiting on failure try: result = parseString( - str, nimState.identCache, nimState.config, errorHandler = handleError + str, gState.identCache, gState.config, errorHandler = handleError ) except: decho getCurrentExceptionMsg() \ No newline at end of file diff --git a/nimterop/exprparser.nim b/nimterop/exprparser.nim index 2ce4989..047a909 100644 --- a/nimterop/exprparser.nim +++ b/nimterop/exprparser.nim @@ -30,28 +30,12 @@ import "."/[globals, getters, comphelp, tshelp] # for where Nim can't (such as uint + -int) type - ExprParser* = ref object - state*: NimState - code*: string - name*: string - ExprParseError* = object of CatchableError -proc newExprParser*(state: NimState, code: string, name = ""): ExprParser = - ExprParser(state: state, code: code, name: name) - -template techo(msg: varargs[string, `$`]) = - block: - let nimState {.inject.} = exprParser.state - decho join(msg, "") - template val(node: TSNode): string = - exprParser.code.getNodeVal(node) + gState.currentExpr.getNodeVal(node) -proc mode(exprParser: ExprParser): string = - exprParser.state.gState.mode - -proc getIdent(exprParser: ExprParser, identName: string, kind = nskConst, parent = ""): PNode = +proc getExprIdent*(gState: State, identName: string, kind = nskConst, parent = ""): PNode = ## Gets a cPlugin transformed identifier from `identName` ## ## Returns PNode(nkNone) if the identifier is blank @@ -59,19 +43,19 @@ proc getIdent(exprParser: ExprParser, identName: string, kind = nskConst, parent var ident = identName if ident != "_": # Process the identifier through cPlugin - ident = exprParser.state.getIdentifier(ident, kind, parent) + ident = gState.getIdentifier(ident, kind, parent) if kind == nskType: - result = exprParser.state.getIdent(ident) - elif ident.nBl and ident in exprParser.state.constIdentifiers: - if exprParser.name.nBl: - ident = ident & "." & exprParser.name - result = exprParser.state.getIdent(ident) + result = gState.getIdent(ident) + elif ident.nBl and ident in gState.constIdentifiers: + if gState.currentTyCastName.nBl: + ident = ident & "." & gState.currentTyCastName + result = gState.getIdent(ident) -proc getIdent(exprParser: ExprParser, node: TSNode, kind = nskConst, parent = ""): PNode = +proc getExprIdent*(gState: State, node: TSNode, kind = nskConst, parent = ""): PNode = ## Gets a cPlugin transformed identifier from `identName` ## ## Returns PNode(nkNone) if the identifier is blank - exprParser.getIdent(node.val, kind, parent) + gState.getExprIdent(node.val, kind, parent) proc parseChar(charStr: string): uint8 {.inline.} = ## Parses a character literal out of a string. This is needed @@ -125,53 +109,60 @@ proc getCharLit(charStr: string): PNode {.inline.} = result = newNode(nkCharLit) result.intVal = parseChar(charStr).int64 +proc getFloatNode(number, suffix: string): PNode {.inline.} = + ## Get a Nim float node from a C float expression + suffix + let floatSuffix = number[number.len-1] + try: + case floatSuffix + of 'l', 'L': + # TODO: handle long double (128 bits) + # result = newNode(nkFloat128Lit) + result = newFloatNode(nkFloat64Lit, parseFloat(number[0 ..< number.len - 1])) + of 'f', 'F': + result = newFloatNode(nkFloat64Lit, parseFloat(number[0 ..< number.len - 1])) + else: + result = newFloatNode(nkFloatLit, parseFloat(number)) + except ValueError: + raise newException(ExprParseError, &"Could not parse float value \"{number}\".") + +proc getIntNode(number, suffix: string): PNode {.inline.} = + ## Get a Nim int node from a C integer expression + suffix + case suffix + of "u", "U": + result = newNode(nkUintLit) + of "l", "L": + result = newNode(nkInt32Lit) + of "ul", "UL": + result = newNode(nkUint32Lit) + of "ll", "LL": + result = newNode(nkInt64Lit) + of "ull", "ULL": + result = newNode(nkUint64Lit) + else: + result = newNode(nkIntLit) + + # I realize these regex are wasteful on performance, but + # couldn't come up with a better idea. + if number.contains(re"0[xX]"): + result.intVal = parseHexInt(number) + result.flags = {nfBase16} + elif number.contains(re"0[bB]"): + result.intVal = parseBinInt(number) + result.flags = {nfBase2} + elif number.contains(re"0[oO]"): + result.intVal = parseOctInt(number) + result.flags = {nfBase8} + else: + result.intVal = parseInt(number) + proc getNumNode(number, suffix: string): PNode {.inline.} = ## Convert a C number to a Nim number PNode - result = newNode(nkNone) if number.contains("."): - let floatSuffix = number[number.len-1] - try: - case floatSuffix - of 'l', 'L': - # TODO: handle long double (128 bits) - # result = newNode(nkFloat128Lit) - result = newFloatNode(nkFloat64Lit, parseFloat(number[0 ..< number.len - 1])) - of 'f', 'F': - result = newFloatNode(nkFloat64Lit, parseFloat(number[0 ..< number.len - 1])) - else: - result = newFloatNode(nkFloatLit, parseFloat(number)) - except ValueError: - raise newException(ExprParseError, &"Could not parse float value \"{number}\".") + getFloatNode(number, suffix) else: - case suffix - of "u", "U": - result = newNode(nkUintLit) - of "l", "L": - result = newNode(nkInt32Lit) - of "ul", "UL": - result = newNode(nkUint32Lit) - of "ll", "LL": - result = newNode(nkInt64Lit) - of "ull", "ULL": - result = newNode(nkUint64Lit) - else: - result = newNode(nkIntLit) + getIntNode(number, suffix) - # I realize these regex are wasteful on performance, but - # couldn't come up with a better idea. - if number.contains(re"0[xX]"): - result.intVal = parseHexInt(number) - result.flags = {nfBase16} - elif number.contains(re"0[bB]"): - result.intVal = parseBinInt(number) - result.flags = {nfBase2} - elif number.contains(re"0[oO]"): - result.intVal = parseOctInt(number) - result.flags = {nfBase8} - else: - result.intVal = parseInt(number) - -proc processNumberLiteral(exprParser: ExprParser, node: TSNode): PNode = +proc processNumberLiteral(gState: State, node: TSNode): PNode = ## Parse a number literal from a TSNode. Can be a float, hex, long, etc result = newNode(nkNone) let nodeVal = node.val @@ -189,17 +180,17 @@ proc processNumberLiteral(exprParser: ExprParser, node: TSNode): PNode = if result.kind != nkNone and prefix == "-": result = nkPrefix.newTree( - exprParser.state.getIdent("-"), + gState.getIdent("-"), result ) else: raise newException(ExprParseError, &"Could not find a number in number_literal: \"{nodeVal}\"") -proc processCharacterLiteral(exprParser: ExprParser, node: TSNode): PNode = +proc processCharacterLiteral(gState: State, node: TSNode): PNode = let val = node.val result = getCharLit(val[1 ..< val.len - 1]) -proc processStringLiteral(exprParser: ExprParser, node: TSNode): PNode = +proc processStringLiteral(gState: State, node: TSNode): PNode = let nodeVal = node.val strVal = nodeVal[1 ..< nodeVal.len - 1] @@ -215,9 +206,9 @@ proc processStringLiteral(exprParser: ExprParser, node: TSNode): PNode = result = newStrNode(nkStrLit, nimStr) -proc processTSNode(exprParser: ExprParser, node: TSNode, typeofNode: var PNode): PNode +proc processTSNode(gState: State, node: TSNode, typeofNode: var PNode): PNode -proc processShiftExpression(exprParser: ExprParser, node: TSNode, typeofNode: var PNode): PNode = +proc processShiftExpression(gState: State, node: TSNode, typeofNode: var PNode): PNode = result = newNode(nkInfix) let left = node[0] @@ -227,24 +218,24 @@ proc processShiftExpression(exprParser: ExprParser, node: TSNode, typeofNode: va case shiftSym of "<<": - result.add exprParser.state.getIdent("shl") + result.add gState.getIdent("shl") of ">>": - result.add exprParser.state.getIdent("shr") + result.add gState.getIdent("shr") else: raise newException(ExprParseError, &"Unsupported shift symbol \"{shiftSym}\"") - let leftNode = exprParser.processTSNode(left, typeofNode) + let leftNode = gState.processTSNode(left, typeofNode) # If the typeofNode is nil, set it # to be the leftNode because C's type coercion # happens left to right, and we want to emulate it if typeofNode.isNil: typeofNode = nkCall.newTree( - exprParser.state.getIdent("typeof"), + gState.getIdent("typeof"), leftNode ) - let rightNode = exprParser.processTSNode(right, typeofNode) + let rightNode = gState.processTSNode(right, typeofNode) result.add leftNode result.add nkCall.newTree( @@ -252,15 +243,15 @@ proc processShiftExpression(exprParser: ExprParser, node: TSNode, typeofNode: va rightNode ) -proc processParenthesizedExpr(exprParser: ExprParser, node: TSNode, typeofNode: var PNode): PNode = +proc processParenthesizedExpr(gState: State, node: TSNode, typeofNode: var PNode): PNode = result = newNode(nkPar) for i in 0 ..< node.len(): - result.add(exprParser.processTSNode(node[i], typeofNode)) + result.add(gState.processTSNode(node[i], typeofNode)) -proc processCastExpression(exprParser: ExprParser, node: TSNode, typeofNode: var PNode): PNode = +proc processCastExpression(gState: State, node: TSNode, typeofNode: var PNode): PNode = result = nkCast.newTree( - exprParser.processTSNode(node[0], typeofNode), - exprParser.processTSNode(node[1], typeofNode) + gState.processTSNode(node[0], typeofNode), + gState.processTSNode(node[1], typeofNode) ) proc getNimUnarySym(csymbol: string): string = @@ -292,7 +283,7 @@ proc getNimBinarySym(csymbol: string): string = else: raise newException(ExprParseError, &"Unsupported binary symbol \"{csymbol}\"") -proc processBinaryExpression(exprParser: ExprParser, node: TSNode, typeofNode: var PNode): PNode = +proc processBinaryExpression(gState: State, node: TSNode, typeofNode: var PNode): PNode = # Node has left and right children ie: (2 + 7) result = newNode(nkInfix) @@ -302,16 +293,16 @@ proc processBinaryExpression(exprParser: ExprParser, node: TSNode, typeofNode: v binarySym = node.tsNodeChild(1).val.strip() nimSym = getNimBinarySym(binarySym) - result.add exprParser.state.getIdent(nimSym) - let leftNode = exprParser.processTSNode(left, typeofNode) + result.add gState.getIdent(nimSym) + let leftNode = gState.processTSNode(left, typeofNode) if typeofNode.isNil: typeofNode = nkCall.newTree( - exprParser.state.getIdent("typeof"), + gState.getIdent("typeof"), leftNode ) - let rightNode = exprParser.processTSNode(right, typeofNode) + let rightNode = gState.processTSNode(right, typeofNode) result.add leftNode result.add nkCall.newTree( @@ -319,7 +310,7 @@ proc processBinaryExpression(exprParser: ExprParser, node: TSNode, typeofNode: v rightNode ) -proc processUnaryExpression(exprParser: ExprParser, node: TSNode, typeofNode: var PNode): PNode = +proc processUnaryExpression(gState: State, node: TSNode, typeofNode: var PNode): PNode = result = newNode(nkPar) let @@ -333,31 +324,31 @@ proc processUnaryExpression(exprParser: ExprParser, node: TSNode, typeofNode: va # Might be bad because we are overwriting the type # There's probably a better way of doing this if typeofNode.isNil: - typeofNode = exprParser.state.getIdent("int64") + typeofNode = gState.getIdent("int64") result.add nkPrefix.newTree( - exprParser.state.getIdent(unarySym), + gState.getIdent(unarySym), nkPar.newTree( nkCall.newTree( - exprParser.state.getIdent("int64"), - exprParser.processTSNode(child, typeofNode) + gState.getIdent("int64"), + gState.processTSNode(child, typeofNode) ) ) ) else: result.add nkPrefix.newTree( - exprParser.state.getIdent(nimSym), - exprParser.processTSNode(child, typeofNode) + gState.getIdent(nimSym), + gState.processTSNode(child, typeofNode) ) -proc processUnaryOrBinaryExpression(exprParser: ExprParser, node: TSNode, typeofNode: var PNode): PNode = +proc processUnaryOrBinaryExpression(gState: State, node: TSNode, typeofNode: var PNode): PNode = if node.len > 1: # Node has left and right children ie: (2 + 7) # Make sure the statement is of the same type as the left # hand argument, since some expressions return a differing # type than the input types (2/3 == float) - let binExpr = processBinaryExpression(exprParser, node, typeofNode) + let binExpr = processBinaryExpression(gState, node, typeofNode) # Note that this temp var binExpr is needed for some reason, or else we get a segfault result = nkCall.newTree( typeofNode, @@ -366,37 +357,37 @@ proc processUnaryOrBinaryExpression(exprParser: ExprParser, node: TSNode, typeof elif node.len() == 1: # Node has only one child, ie -(20 + 7) - result = processUnaryExpression(exprParser, node, typeofNode) + result = processUnaryExpression(gState, node, typeofNode) else: raise newException(ExprParseError, &"Invalid {node.getName()} \"{node.val}\"") -proc processSizeofExpression(exprParser: ExprParser, node: TSNode, typeofNode: var PNode): PNode = +proc processSizeofExpression(gState: State, node: TSNode, typeofNode: var PNode): PNode = result = nkCall.newTree( - exprParser.state.getIdent("sizeof"), - exprParser.processTSNode(node[0], typeofNode) + gState.getIdent("sizeof"), + gState.processTSNode(node[0], typeofNode) ) -proc processTSNode(exprParser: ExprParser, node: TSNode, typeofNode: var PNode): PNode = +proc processTSNode(gState: State, node: TSNode, typeofNode: var PNode): PNode = ## Handle all of the types of expressions here. This proc gets called recursively ## in the processX procs and will drill down to sub nodes. result = newNode(nkNone) let nodeName = node.getName() - techo "NODE: ", nodeName, ", VAL: ", node.val + decho "NODE: ", nodeName, ", VAL: ", node.val case nodeName of "number_literal": # Input -> 0x1234FE, 1231, 123u, 123ul, 123ull, 1.334f # Output -> 0x1234FE, 1231, 123'u, 123'u32, 123'u64, 1.334 - result = exprParser.processNumberLiteral(node) + result = gState.processNumberLiteral(node) of "string_literal": # Input -> "foo\0\x42" # Output -> "foo\0" - result = exprParser.processStringLiteral(node) + result = gState.processStringLiteral(node) of "char_literal": # Input -> 'F', '\034' // Octal, '\x5A' // Hex, '\r' // escape sequences # Output -> - result = exprParser.processCharacterLiteral(node) + result = gState.processCharacterLiteral(node) of "expression_statement", "ERROR", "translation_unit": # Note that we're parsing partial expressions, so the TSNode might contain # an ERROR node. If that's the case, they usually contain children with @@ -405,21 +396,21 @@ proc processTSNode(exprParser: ExprParser, node: TSNode, typeofNode: var PNode): # Input (top level statement) -> ((1 + 3 - IDENT) - (int)400.0) # Output -> (1 + typeof(1)(3) - typeof(1)(IDENT) - typeof(1)(cast[int](400.0))) # Type casting in case some args differ if node.len == 1: - result = exprParser.processTSNode(node[0], typeofNode) + result = gState.processTSNode(node[0], typeofNode) elif node.len > 1: result = newNode(nkStmtListExpr) for i in 0 ..< node.len: - result.add exprParser.processTSNode(node[i], typeofNode) + result.add gState.processTSNode(node[i], typeofNode) else: raise newException(ExprParseError, &"Node type \"{nodeName}\" has no children") of "parenthesized_expression": # Input -> (IDENT - OTHERIDENT) # Output -> (IDENT - typeof(IDENT)(OTHERIDENT)) # Type casting in case OTHERIDENT is a slightly different type (uint vs int) - result = exprParser.processParenthesizedExpr(node, typeofNode) + result = gState.processParenthesizedExpr(node, typeofNode) of "sizeof_expression": # Input -> sizeof(char) # Output -> sizeof(cchar) - result = exprParser.processSizeofExpression(node, typeofNode) + result = gState.processSizeofExpression(node, typeofNode) # binary_expression from the new treesitter upgrade should work here # once we upgrade of "math_expression", "logical_expression", "relational_expression", @@ -434,55 +425,61 @@ proc processTSNode(exprParser: ExprParser, node: TSNode, typeofNode: var PNode): # typeof(a)(a > typeof(a)(b)) # typeof(a)(a <= typeof(a)(b)) # typeof(a)(a >= typeof(a)(b)) - result = exprParser.processUnaryOrBinaryExpression(node, typeofNode) + result = gState.processUnaryOrBinaryExpression(node, typeofNode) of "shift_expression": # Input -> a >> b, a << b # Output -> a shr typeof(a)(b), a shl typeof(a)(b) - result = exprParser.processShiftExpression(node, typeofNode) + result = gState.processShiftExpression(node, typeofNode) of "cast_expression": # Input -> (int) a # Output -> cast[cint](a) - result = exprParser.processCastExpression(node, typeofNode) + result = gState.processCastExpression(node, typeofNode) # Why are these node types named true/false? of "true", "false": # Input -> true, false # Output -> true, false - result = exprParser.state.parseString(node.val) + result = gState.parseString(node.val) of "type_descriptor", "sized_type_specifier": # Input -> int, unsigned int, long int, etc # Output -> cint, cuint, clong, etc let ty = getType(node.val) if ty.len > 0: # If ty is not empty, one of C's builtin types has been found - result = exprParser.getIdent(ty, nskType, parent=node.getName()) + result = gState.getExprIdent(ty, nskType, parent=node.getName()) else: - result = exprParser.getIdent(node.val, nskType, parent=node.getName()) + result = gState.getExprIdent(node.val, nskType, parent=node.getName()) if result.kind == nkNone: raise newException(ExprParseError, &"Missing type specifier \"{node.val}\"") of "identifier": # Input -> IDENT # Output -> IDENT (if found in sym table, else error) - result = exprParser.getIdent(node, parent=node.getName()) + result = gState.getExprIdent(node, parent=node.getName()) if result.kind == nkNone: raise newException(ExprParseError, &"Missing identifier \"{node.val}\"") else: raise newException(ExprParseError, &"Unsupported node type \"{nodeName}\" for node \"{node.val}\"") - techo "NODE RESULT: ", result + decho "NODE RESULT: ", result -proc parseCExpression*(state: NimState, code: string, name = ""): PNode = +proc parseCExpression*(gState: State, code: string, name = ""): PNode = ## Convert the C string to a nim PNode tree + gState.currentExpr = code + gState.currentTyCastName = name + result = newNode(nkNone) # This is used for keeping track of the type of the first # symbol used for type casting var tnode: PNode = nil - let exprParser = newExprParser(state, code, name) try: - withCodeAst(exprParser.code, exprParser.mode): - result = exprParser.processTSNode(root, tnode) + withCodeAst(gState.currentExpr, gState.mode): + result = gState.processTSNode(root, tnode) except ExprParseError as e: - techo e.msg + decho e.msg result = newNode(nkNone) except Exception as e: - techo "UNEXPECTED EXCEPTION: ", e.msg - result = newNode(nkNone) \ No newline at end of file + decho "UNEXPECTED EXCEPTION: ", e.msg + result = newNode(nkNone) + + # Clear the state + gState.currentExpr = "" + gState.currentTyCastName = "" \ No newline at end of file diff --git a/nimterop/globals.nim b/nimterop/globals.nim index b964da9..0d0b4cd 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -1,4 +1,4 @@ -import sequtils, sets, tables +import sequtils, sets, tables, strutils import regex @@ -93,6 +93,9 @@ type currentHeader*, impShort*, sourceFile*: string + # Used for the exprparser.nim module + currentExpr*, currentTyCastName*: string + data*: seq[tuple[name, val: string]] nodeBranch*: seq[string] @@ -119,6 +122,6 @@ when not declared(CIMPORT): else: gState.outputHandle.writeLine(args) - template decho*(str: untyped): untyped = + template decho*(args: varargs[string, `$`]): untyped = if gState.debug: - gecho str.getCommented() + gecho join(args, "").getCommented() \ No newline at end of file diff --git a/nimterop/toast.nim b/nimterop/toast.nim index afb511d..98045bf 100644 --- a/nimterop/toast.nim +++ b/nimterop/toast.nim @@ -15,44 +15,16 @@ proc process(gState: State, path: string, astTable: AstTable) = else: gState.code = readFile(path) -<<<<<<< HEAD - doAssert gState.code.nBl, "Empty file or preprocessor error" - - if gState.mode == "c": - doAssert parser.tsParserSetLanguage(treeSitterC()), "Failed to load C parser" - elif gState.mode == "cpp": - doAssert parser.tsParserSetLanguage(treeSitterCpp()), "Failed to load C++ parser" - else: - doAssert false, &"Invalid parser {gState.mode}" - - var - tree = parser.tsParserParseString(nil, gState.code.cstring, gState.code.len.uint32) - root = tree.tsTreeRootNode() - - defer: - tree.tsTreeDelete() - - if gState.past: - gecho gState.printLisp(root) - elif gState.pnim: - if Feature.ast2 in gState.feature: - ast2.parseNim(gState, path, root) - else: - ast.parseNim(gState, path, root, astTable) - elif gState.preprocess: - gecho gState.code -======= withCodeAst(gState.code, gState.mode): if gState.past: gecho gState.printLisp(root) elif gState.pnim: if Feature.ast2 in gState.feature: - ast2.printNim(gState, path, root) + ast2.parseNim(gState, path, root) else: - ast.printNim(gState, path, root, astTable) + ast.parseNim(gState, path, root, astTable) elif gState.preprocess: gecho gState.code ->>>>>>> Update based on comments from review. Need to add more docs and reorg to use gstate # CLI processing with default values proc main( From c0977fa8271f462c20a29f4bb0976c638a534b45 Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Thu, 23 Apr 2020 16:15:40 -0600 Subject: [PATCH 415/593] Update code with comments and add debug expr proc --- nimterop/exprparser.nim | 143 +++++++++++++++++++++++++++++++++++++++- nimterop/getters.nim | 8 +-- 2 files changed, 144 insertions(+), 7 deletions(-) diff --git a/nimterop/exprparser.nim b/nimterop/exprparser.nim index 047a909..7acb375 100644 --- a/nimterop/exprparser.nim +++ b/nimterop/exprparser.nim @@ -35,6 +35,11 @@ type template val(node: TSNode): string = gState.currentExpr.getNodeVal(node) +proc printDebugExpr*(gState: State, node: TSNode) = + if gState.debug: + gecho ("Input => " & node.val).getCommented() + gecho gState.currentExpr.printLisp(node).getCommented() + proc getExprIdent*(gState: State, identName: string, kind = nskConst, parent = ""): PNode = ## Gets a cPlugin transformed identifier from `identName` ## @@ -187,10 +192,29 @@ proc processNumberLiteral(gState: State, node: TSNode): PNode = raise newException(ExprParseError, &"Could not find a number in number_literal: \"{nodeVal}\"") proc processCharacterLiteral(gState: State, node: TSNode): PNode = + # Input => 'G' + # + # (char_literal 1 1 3 "'G'") + # + # Output => 'G' + # + # nkCharLit("G") let val = node.val result = getCharLit(val[1 ..< val.len - 1]) proc processStringLiteral(gState: State, node: TSNode): PNode = + # Input => "\n\rfoobar\0\'" + # + # (string_literal 1 1 16 ""\n\rfoobar\0\'"" + # (escape_sequence 1 2 2 "\n") + # (escape_sequence 1 4 2 "\r") + # (escape_sequence 1 12 2 "\0") + # (escape_sequence 1 14 2 "\'") + # ) + # + # Output => "\n\cfoobar\x00\'" + # + # nkStrLit("\x0A\x0Dfoobar\x00\'") let nodeVal = node.val strVal = nodeVal[1 ..< nodeVal.len - 1] @@ -209,6 +233,26 @@ proc processStringLiteral(gState: State, node: TSNode): PNode = proc processTSNode(gState: State, node: TSNode, typeofNode: var PNode): PNode proc processShiftExpression(gState: State, node: TSNode, typeofNode: var PNode): PNode = + # Input => a >> b + # + # (shift_expression 1 2 6 + # (identifier 1 2 1 "a") + # (identifier 1 7 1 "b") + # ) + # + # Output => a shr typeof(a)(b) + # + # nkInfix( + # nkIdent("shr"), + # nkIdent("a"), + # nkCall( + # nkCall( + # nkIdent("typeof"), + # nkIdent("a") + # ), + # nkIdent("b") + # ) + # ) result = newNode(nkInfix) let left = node[0] @@ -244,11 +288,56 @@ proc processShiftExpression(gState: State, node: TSNode, typeofNode: var PNode): ) proc processParenthesizedExpr(gState: State, node: TSNode, typeofNode: var PNode): PNode = + # Input => (a + b) + # + # (parenthesized_expression 1 1 7 + # (math_expression 1 2 5 + # (identifier 1 2 1 "a") + # (identifier 1 6 1 "b") + # ) + # ) + # + # Output => (typeof(a)(a + typeof(a)(b))) + # + # nkPar( + # nkCall( + # nkCall( + # nkIdent("typeof"), + # nkIdent("a") + # ), + # nkInfix( + # nkIdent("+"), + # nkIdent("a"), + # nkCall( + # nkCall( + # nkIdent("typeof"), + # nkIdent("a") + # ), + # nkIdent("b") + # ) + # ) + # ) + # ) result = newNode(nkPar) for i in 0 ..< node.len(): result.add(gState.processTSNode(node[i], typeofNode)) proc processCastExpression(gState: State, node: TSNode, typeofNode: var PNode): PNode = + # Input => (int)a + # + # (cast_expression 1 1 6 "(int)a" + # (type_descriptor 1 2 3 "int" + # (primitive_type 1 2 3 "int") + # ) + # (identifier 1 6 1 "a") + # ) + # + # Output => cast[cint](a) + # + # nkCast( + # nkIdent("cint"), + # nkIdent("a") + # ) result = nkCast.newTree( gState.processTSNode(node[0], typeofNode), gState.processTSNode(node[1], typeofNode) @@ -285,6 +374,27 @@ proc getNimBinarySym(csymbol: string): string = proc processBinaryExpression(gState: State, node: TSNode, typeofNode: var PNode): PNode = # Node has left and right children ie: (2 + 7) + # + # Input => a == b + # + # (equality_expression 1 1 6 + # (identifier 1 1 1 "a") + # (identifier 1 6 1 "b") + # ) + # + # Output => a == typeof(a)(b) + # + # nkInfix( + # nkIdent("=="), + # nkIdent("a"), + # nkCall( + # nkCall( + # nkIdent("typeof"), + # nkIdent("a") + # ), + # nkIdent("b") + # ) + # ) result = newNode(nkInfix) let @@ -311,6 +421,20 @@ proc processBinaryExpression(gState: State, node: TSNode, typeofNode: var PNode) ) proc processUnaryExpression(gState: State, node: TSNode, typeofNode: var PNode): PNode = + # Input => !a + # + # (logical_expression 1 1 2 "!a" + # (identifier 1 2 1 "a") + # ) + # + # Output => (not a) + # + # nkPar( + # nkPrefix( + # nkIdent("not"), + # nkIdent("a") + # ) + # ) result = newNode(nkPar) let @@ -342,6 +466,7 @@ proc processUnaryExpression(gState: State, node: TSNode, typeofNode: var PNode): ) proc processUnaryOrBinaryExpression(gState: State, node: TSNode, typeofNode: var PNode): PNode = + ## Processes both unary (-1, ~true, !something) and binary (a + b, c * d) expressions if node.len > 1: # Node has left and right children ie: (2 + 7) @@ -362,6 +487,20 @@ proc processUnaryOrBinaryExpression(gState: State, node: TSNode, typeofNode: var raise newException(ExprParseError, &"Invalid {node.getName()} \"{node.val}\"") proc processSizeofExpression(gState: State, node: TSNode, typeofNode: var PNode): PNode = + # Input => sizeof(int) + # + # (sizeof_expression 1 1 11 "sizeof(int)" + # (type_descriptor 1 8 3 "int" + # (primitive_type 1 8 3 "int") + # ) + # ) + # + # Output => sizeof(cint) + # + # nkCall( + # nkIdent("sizeof"), + # nkIdent("cint") + # ) result = nkCall.newTree( gState.getIdent("sizeof"), gState.processTSNode(node[0], typeofNode) @@ -385,8 +524,8 @@ proc processTSNode(gState: State, node: TSNode, typeofNode: var PNode): PNode = # Output -> "foo\0" result = gState.processStringLiteral(node) of "char_literal": - # Input -> 'F', '\034' // Octal, '\x5A' // Hex, '\r' // escape sequences - # Output -> + # Input -> 'F', '\060' // Octal, '\x5A' // Hex, '\r' // escape sequences + # Output -> 'F', '0', 'Z', '\r' result = gState.processCharacterLiteral(node) of "expression_statement", "ERROR", "translation_unit": # Note that we're parsing partial expressions, so the TSNode might contain diff --git a/nimterop/getters.nim b/nimterop/getters.nim index b7744ce..121c8d5 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -436,13 +436,13 @@ proc printTree*(gState: State, pnode: PNode, offset = ""): string = result &= "\n# " & offset & $pnode.kind & "(" case pnode.kind of nkCharLit: - result &= "'" & pnode.intVal.char & "')" + result &= ($pnode.intVal.char).escape & ")" of nkIntLit..nkUInt64Lit: result &= $pnode.intVal & ")" of nkFloatLit..nkFloat128Lit: result &= $pnode.floatVal & ")" of nkStrLit..nkTripleStrLit: - result &= "\"" & pnode.strVal & "\")" + result &= pnode.strVal.escape & ")" of nkSym: result &= $pnode.sym & ")" of nkIdent: @@ -460,16 +460,14 @@ proc printTree*(gState: State, pnode: PNode, offset = ""): string = result &= "\n" proc printDebug*(gState: State, node: TSNode) = - # This causes random segfaults for some reason on macOS Catalina if gState.debug: gecho ("Input => " & gState.getNodeVal(node)).getCommented() gecho gState.printLisp(node).getCommented() proc printDebug*(gState: State, pnode: PNode) = - # This causes random segfaults for some reason on macOS Catalina if gState.debug and pnode.kind != nkNone: gecho ("Output => " & $pnode).getCommented() - gecho gState.printTree(pnode).getCommented() + gecho gState.printTree(pnode) # Compiler shortcuts From 2813dc61f22aecaaaa82054f144a48c4de520cf2 Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Thu, 23 Apr 2020 16:45:19 -0600 Subject: [PATCH 416/593] Consolidate shift_expression into binary_expression and write more tests --- nimterop/exprparser.nim | 91 +++++++++-------------------------------- tests/include/tast2.h | 10 +++++ tests/tast2.nim | 14 ++++++- 3 files changed, 42 insertions(+), 73 deletions(-) diff --git a/nimterop/exprparser.nim b/nimterop/exprparser.nim index 7acb375..a59a546 100644 --- a/nimterop/exprparser.nim +++ b/nimterop/exprparser.nim @@ -232,61 +232,6 @@ proc processStringLiteral(gState: State, node: TSNode): PNode = proc processTSNode(gState: State, node: TSNode, typeofNode: var PNode): PNode -proc processShiftExpression(gState: State, node: TSNode, typeofNode: var PNode): PNode = - # Input => a >> b - # - # (shift_expression 1 2 6 - # (identifier 1 2 1 "a") - # (identifier 1 7 1 "b") - # ) - # - # Output => a shr typeof(a)(b) - # - # nkInfix( - # nkIdent("shr"), - # nkIdent("a"), - # nkCall( - # nkCall( - # nkIdent("typeof"), - # nkIdent("a") - # ), - # nkIdent("b") - # ) - # ) - result = newNode(nkInfix) - let - left = node[0] - right = node[1] - - let shiftSym = node.tsNodeChild(1).val.strip() - - case shiftSym - of "<<": - result.add gState.getIdent("shl") - of ">>": - result.add gState.getIdent("shr") - else: - raise newException(ExprParseError, &"Unsupported shift symbol \"{shiftSym}\"") - - let leftNode = gState.processTSNode(left, typeofNode) - - # If the typeofNode is nil, set it - # to be the leftNode because C's type coercion - # happens left to right, and we want to emulate it - if typeofNode.isNil: - typeofNode = nkCall.newTree( - gState.getIdent("typeof"), - leftNode - ) - - let rightNode = gState.processTSNode(right, typeofNode) - - result.add leftNode - result.add nkCall.newTree( - typeofNode, - rightNode - ) - proc processParenthesizedExpr(gState: State, node: TSNode, typeofNode: var PNode): PNode = # Input => (a + b) # @@ -369,6 +314,10 @@ proc getNimBinarySym(csymbol: string): string = result = csymbol of "%": result = "mod" + of "<<": + result = "shl" + of ">>": + result = "shr" else: raise newException(ExprParseError, &"Unsupported binary symbol \"{csymbol}\"") @@ -419,6 +368,15 @@ proc processBinaryExpression(gState: State, node: TSNode, typeofNode: var PNode) typeofNode, rightNode ) + if binarySym == "/": + # Special case. Nim's operators generally output + # the same type they take in, except for division. + # So we need to emulate C here and cast the whole + # expression to the type of the first arg + result = nkCall.newTree( + typeofNode, + result + ) proc processUnaryExpression(gState: State, node: TSNode, typeofNode: var PNode): PNode = # Input => !a @@ -469,17 +427,7 @@ proc processUnaryOrBinaryExpression(gState: State, node: TSNode, typeofNode: var ## Processes both unary (-1, ~true, !something) and binary (a + b, c * d) expressions if node.len > 1: # Node has left and right children ie: (2 + 7) - - # Make sure the statement is of the same type as the left - # hand argument, since some expressions return a differing - # type than the input types (2/3 == float) - let binExpr = processBinaryExpression(gState, node, typeofNode) - # Note that this temp var binExpr is needed for some reason, or else we get a segfault - result = nkCall.newTree( - typeofNode, - binexpr - ) - + result = processBinaryExpression(gState, node, typeofNode) elif node.len() == 1: # Node has only one child, ie -(20 + 7) result = processUnaryExpression(gState, node, typeofNode) @@ -553,8 +501,9 @@ proc processTSNode(gState: State, node: TSNode, typeofNode: var PNode): PNode = # binary_expression from the new treesitter upgrade should work here # once we upgrade of "math_expression", "logical_expression", "relational_expression", - "bitwise_expression", "equality_expression", "binary_expression": - # Input -> a == b, a != b, !a, ~a, a < b, a > b, a <= b, a >= b + "bitwise_expression", "equality_expression", "binary_expression", + "shift_expression": + # Input -> a == b, a != b, !a, ~a, a < b, a > b, a <= b, a >= b, a >> b, a << b # Output -> # typeof(a)(a == typeof(a)(b)) # typeof(a)(a != typeof(a)(b)) @@ -564,11 +513,9 @@ proc processTSNode(gState: State, node: TSNode, typeofNode: var PNode): PNode = # typeof(a)(a > typeof(a)(b)) # typeof(a)(a <= typeof(a)(b)) # typeof(a)(a >= typeof(a)(b)) + # a shr typeof(a)(b) + # a shl typeof(a)(b) result = gState.processUnaryOrBinaryExpression(node, typeofNode) - of "shift_expression": - # Input -> a >> b, a << b - # Output -> a shr typeof(a)(b), a shl typeof(a)(b) - result = gState.processShiftExpression(node, typeofNode) of "cast_expression": # Input -> (int) a # Output -> cast[cint](a) diff --git a/tests/include/tast2.h b/tests/include/tast2.h index 53b4d64..e72a3b8 100644 --- a/tests/include/tast2.h +++ b/tests/include/tast2.h @@ -24,6 +24,16 @@ extern "C" { #define MATHEXPR (1 + 2/3*20 - 100) #define ANDEXPR (100 & 11000) #define CASTEXPR (char) 34 +#define a 100 +#define b 200 +#define EQ1 a <= b +#define EQ2 a >= b +#define EQ3 a > b +#define EQ4 a < b +#define EQ5 a != b +#define EQ6 a == b + +#define SIZEOF sizeof(char) #define NULLCHAR '\0' #define OCTCHAR '\012' diff --git a/tests/tast2.nim b/tests/tast2.nim index e82430b..57bfc90 100644 --- a/tests/tast2.nim +++ b/tests/tast2.nim @@ -115,6 +115,18 @@ assert ULLEXPR == (1234.uint64 shl 3) assert LEXPR == (1234.int32 shl 4) assert LLEXPR == (1234.int64 shl 5) +assert a == 100 +assert b == 200 + +assert EQ1 == (a <= b) +assert EQ2 == (a >= b) +assert EQ3 == (a > b) +assert EQ4 == (a < b) +assert EQ5 == (a != b) +assert EQ6 == (a == b) + +assert SIZEOF == 1 + assert COERCE == 645635670332'u64 assert COERCE2 == 645635670332'i64 @@ -303,7 +315,7 @@ var a21p: A21p a21p = addr a20 assert A22 is object -testFields(A22, "f1|f2!ptr ptr cint|array[type(123)(255), ptr cint]") +testFields(A22, "f1|f2!ptr ptr cint|array[123 + type(123)(132), ptr cint]") checkPragmas(A22, pHeaderBy, istype = false) var a22: A22 a22.f1 = addr a15.a2[0] From 9e799ee3b19ac152d1c2403c6af1e3806e1a31fe Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Thu, 23 Apr 2020 16:53:52 -0600 Subject: [PATCH 417/593] Fix tmath tests Modify tmath.nim to have one skip symbol Fix macro expansion with common value Fix tmath again --- tests/include/tast2.h | 16 ++++++++-------- tests/tast2.nim | 16 ++++++++-------- tests/tmath.nim | 6 ++++-- 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/tests/include/tast2.h b/tests/include/tast2.h index e72a3b8..815791f 100644 --- a/tests/include/tast2.h +++ b/tests/include/tast2.h @@ -24,14 +24,14 @@ extern "C" { #define MATHEXPR (1 + 2/3*20 - 100) #define ANDEXPR (100 & 11000) #define CASTEXPR (char) 34 -#define a 100 -#define b 200 -#define EQ1 a <= b -#define EQ2 a >= b -#define EQ3 a > b -#define EQ4 a < b -#define EQ5 a != b -#define EQ6 a == b +#define AVAL 100 +#define BVAL 200 +#define EQ1 AVAL <= BVAL +#define EQ2 AVAL >= BVAL +#define EQ3 AVAL > BVAL +#define EQ4 AVAL < BVAL +#define EQ5 AVAL != BVAL +#define EQ6 AVAL == BVAL #define SIZEOF sizeof(char) diff --git a/tests/tast2.nim b/tests/tast2.nim index 57bfc90..da7fafa 100644 --- a/tests/tast2.nim +++ b/tests/tast2.nim @@ -115,15 +115,15 @@ assert ULLEXPR == (1234.uint64 shl 3) assert LEXPR == (1234.int32 shl 4) assert LLEXPR == (1234.int64 shl 5) -assert a == 100 -assert b == 200 +assert AVAL == 100 +assert BVAL == 200 -assert EQ1 == (a <= b) -assert EQ2 == (a >= b) -assert EQ3 == (a > b) -assert EQ4 == (a < b) -assert EQ5 == (a != b) -assert EQ6 == (a == b) +assert EQ1 == (AVAL <= BVAL) +assert EQ2 == (AVAL >= BVAL) +assert EQ3 == (AVAL > BVAL) +assert EQ4 == (AVAL < BVAL) +assert EQ5 == (AVAL != BVAL) +assert EQ6 == (AVAL == BVAL) assert SIZEOF == 1 diff --git a/tests/tmath.nim b/tests/tmath.nim index bbf7abd..b8477c1 100644 --- a/tests/tmath.nim +++ b/tests/tmath.nim @@ -14,9 +14,11 @@ when defined(windows): static: when (NimMajor, NimMinor, NimPatch) < (1, 0, 0): - cSkipSymbol @["mingw_choose_expr", "EXCEPTION_DEFINED", "COMPLEX_DEFINED", "matherr", "HUGE", "FP_ILOGB0", "FP_ILOGBNAN"] + # FP_ILOGB0 and FP_ILOGBNAN are casts that are unsupported + # on lower Nim VMs + cSkipSymbol @["math_errhandling", "FP_ILOGB0", "FP_ILOGBNAN"] else: - cSkipSymbol @["mingw_choose_expr", "EXCEPTION_DEFINED", "COMPLEX_DEFINED", "matherr", "HUGE"] + cSkipSymbol @["math_errhandling"] cDebug() cDisableCaching() cAddStdDir() From 073dc5d35a70270c49234842bfbb7f3e608c539e Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Thu, 23 Apr 2020 19:21:57 -0600 Subject: [PATCH 418/593] Add hack for skipping types as root nodes --- nimterop/ast2.nim | 30 ++++++++++++++++++++++++++---- nimterop/exprparser.nim | 21 +++++++++++++-------- 2 files changed, 39 insertions(+), 12 deletions(-) diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index 4fec237..bb41ebe 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -4,9 +4,9 @@ import options as opts import compiler/[ast, idents, lineinfos, modulegraphs, msgs, options, renderer] -import "."/treesitter/api +import "."/treesitter/[api, c, cpp] -import "."/[globals, getters, exprparser, comphelp] +import "."/[globals, getters, exprparser, comphelp, tshelp] proc getPtrType*(str: string): string = result = case str: @@ -99,8 +99,30 @@ proc newConstDef(gState: State, node: TSNode, fname = "", fval = ""): PNode = fval else: gState.getNodeVal(node[1]) - valident = - gState.parseCExpression(val) + var valident = newNode(nkNone) + + withCodeAst(val, gState.mode): + # This section is a hack for determining that the first + # node is a type, which shouldn't be accepted by a const + # def section. Need to replace this with some other mechanism + # to handle type aliases + var maybeTyNode: TSNode + # Take the very first node, which may be 2 levels + # down if there is an error node + if root.len > 0 and root[0].getName() == "ERROR": + maybeTyNode = root[0][0] + elif root.len > 0: + maybeTyNode = root[0] + + if not maybeTyNode.isNil: + let name = maybeTyNode.getName() + case name + of "type_descriptor", "sized_type_specifier": + discard + else: + # Can't do gState.parseCExpression(root) here for some reason? + # get a SEGFAULT if we use root + valident = gState.parseCExpression(val) if name.Bl: # Name skipped or overridden since blank diff --git a/nimterop/exprparser.nim b/nimterop/exprparser.nim index a59a546..6e102ea 100644 --- a/nimterop/exprparser.nim +++ b/nimterop/exprparser.nim @@ -547,18 +547,15 @@ proc processTSNode(gState: State, node: TSNode, typeofNode: var PNode): PNode = decho "NODE RESULT: ", result -proc parseCExpression*(gState: State, code: string, name = ""): PNode = - ## Convert the C string to a nim PNode tree - gState.currentExpr = code - gState.currentTyCastName = name +proc parseCExpression*(gState: State, codeRoot: TSNode, name = ""): PNode = + ## Parse a c expression from a root ts node - result = newNode(nkNone) - # This is used for keeping track of the type of the first + # This var is used for keeping track of the type of the first # symbol used for type casting var tnode: PNode = nil + result = newNode(nkNone) try: - withCodeAst(gState.currentExpr, gState.mode): - result = gState.processTSNode(root, tnode) + result = gState.processTSNode(codeRoot, tnode) except ExprParseError as e: decho e.msg result = newNode(nkNone) @@ -566,6 +563,14 @@ proc parseCExpression*(gState: State, code: string, name = ""): PNode = decho "UNEXPECTED EXCEPTION: ", e.msg result = newNode(nkNone) +proc parseCExpression*(gState: State, code: string, name = ""): PNode = + ## Convert the C string to a nim PNode tree + gState.currentExpr = code + gState.currentTyCastName = name + + withCodeAst(gState.currentExpr, gState.mode): + result = gState.parseCExpression(root, name) + # Clear the state gState.currentExpr = "" gState.currentTyCastName = "" \ No newline at end of file From cc460b2779fc8b2035c19e0ba8f460cf124d474f Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Thu, 23 Apr 2020 20:20:05 -0600 Subject: [PATCH 419/593] Add skippedSymbols for determining if a type has been skipped --- nimterop/ast2.nim | 3 +++ nimterop/exprparser.nim | 25 +++++++++++++------------ nimterop/globals.nim | 3 +++ 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index bb41ebe..2ae4a70 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -41,6 +41,7 @@ proc getOverrideOrSkip(gState: State, node: TSNode, origname: string, kind: NimS result = pnode[0][0] else: gecho &"\n# $1'{origname}' skipped" % skind + gState.skippedSyms.incl origname if gState.debug: gState.skipStr &= &"\n{gState.getNodeVal(node)}" @@ -99,6 +100,7 @@ proc newConstDef(gState: State, node: TSNode, fname = "", fval = ""): PNode = fval else: gState.getNodeVal(node[1]) + var valident = newNode(nkNone) withCodeAst(val, gState.mode): @@ -151,6 +153,7 @@ proc newConstDef(gState: State, node: TSNode, fname = "", fval = ""): PNode = gecho &"# const '{origname}' is duplicate, skipped" else: gecho &"# const '{origname}' has invalid value '{val}'" + gState.skippedSyms.incl origname proc addConst(gState: State, node: TSNode) = # Add a const to the AST diff --git a/nimterop/exprparser.nim b/nimterop/exprparser.nim index 6e102ea..1f6decc 100644 --- a/nimterop/exprparser.nim +++ b/nimterop/exprparser.nim @@ -45,16 +45,17 @@ proc getExprIdent*(gState: State, identName: string, kind = nskConst, parent = " ## ## Returns PNode(nkNone) if the identifier is blank result = newNode(nkNone) - var ident = identName - if ident != "_": - # Process the identifier through cPlugin - ident = gState.getIdentifier(ident, kind, parent) - if kind == nskType: - result = gState.getIdent(ident) - elif ident.nBl and ident in gState.constIdentifiers: - if gState.currentTyCastName.nBl: - ident = ident & "." & gState.currentTyCastName - result = gState.getIdent(ident) + if identName notin gState.skippedSyms: + var ident = identName + if ident != "_": + # Process the identifier through cPlugin + ident = gState.getIdentifier(ident, kind, parent) + if kind == nskType: + result = gState.getIdent(ident) + elif ident.nBl and ident in gState.constIdentifiers: + if gState.currentTyCastName.nBl: + ident = ident & "." & gState.currentTyCastName + result = gState.getIdent(ident) proc getExprIdent*(gState: State, node: TSNode, kind = nskConst, parent = ""): PNode = ## Gets a cPlugin transformed identifier from `identName` @@ -534,8 +535,8 @@ proc processTSNode(gState: State, node: TSNode, typeofNode: var PNode): PNode = result = gState.getExprIdent(ty, nskType, parent=node.getName()) else: result = gState.getExprIdent(node.val, nskType, parent=node.getName()) - if result.kind == nkNone: - raise newException(ExprParseError, &"Missing type specifier \"{node.val}\"") + if result.kind == nkNone: + raise newException(ExprParseError, &"Missing type specifier \"{node.val}\"") of "identifier": # Input -> IDENT # Output -> IDENT (if found in sym table, else error) diff --git a/nimterop/globals.nim b/nimterop/globals.nim index 0d0b4cd..d433ab5 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -76,6 +76,9 @@ type # All const names for enum casting constIdentifiers*: HashSet[string] + # All symbols that have been skipped + skippedSyms*: HashSet[string] + # Legacy ast fields, remove when ast2 becomes default constStr*, enumStr*, procStr*, typeStr*: string From 3e28501826f5d655ad3797cbf29009082be126e1 Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Thu, 23 Apr 2020 20:59:21 -0600 Subject: [PATCH 420/593] Fix comments breaking code --- nimterop/exprparser.nim | 14 ++++++++++++-- tests/include/tast2.h | 4 ++-- tests/tpcre.nim | 1 - 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/nimterop/exprparser.nim b/nimterop/exprparser.nim index 1f6decc..e9ee502 100644 --- a/nimterop/exprparser.nim +++ b/nimterop/exprparser.nim @@ -486,9 +486,17 @@ proc processTSNode(gState: State, node: TSNode, typeofNode: var PNode): PNode = if node.len == 1: result = gState.processTSNode(node[0], typeofNode) elif node.len > 1: - result = newNode(nkStmtListExpr) + let res = newNode(nkStmtListExpr) for i in 0 ..< node.len: - result.add gState.processTSNode(node[i], typeofNode) + let node = gState.processTSNode(node[i], typeofNode) + if node.kind != nkNone: + res.add node + if res.len == 1: + result = res[0] + elif res.len > 1: + result = res + else: + result = newNode(nkNone) else: raise newException(ExprParseError, &"Node type \"{nodeName}\" has no children") of "parenthesized_expression": @@ -543,6 +551,8 @@ proc processTSNode(gState: State, node: TSNode, typeofNode: var PNode): PNode = result = gState.getExprIdent(node, parent=node.getName()) if result.kind == nkNone: raise newException(ExprParseError, &"Missing identifier \"{node.val}\"") + of "comment": + discard else: raise newException(ExprParseError, &"Unsupported node type \"{nodeName}\" for node \"{node.val}\"") diff --git a/tests/include/tast2.h b/tests/include/tast2.h index 815791f..42c852f 100644 --- a/tests/include/tast2.h +++ b/tests/include/tast2.h @@ -35,8 +35,8 @@ extern "C" { #define SIZEOF sizeof(char) -#define NULLCHAR '\0' -#define OCTCHAR '\012' +#define NULLCHAR '\0'/* comments should not break things*/ +#define OCTCHAR '\012' // nor should this comment #define HEXCHAR '\xFE' #define TRICKYSTR "\x4E\034\nfoo\0\'\"\r\v\a\b\e\f\t\\\?bar" diff --git a/tests/tpcre.nim b/tests/tpcre.nim index 3bbd1ba..c8e8059 100644 --- a/tests/tpcre.nim +++ b/tests/tpcre.nim @@ -7,7 +7,6 @@ const pcreH = baseDir/"pcre.h.in" static: - cSkipSymbol @["PCRE_UCHAR16", "PCRE_UCHAR32"] if not pcreH.fileExists(): downloadUrl("https://github.com/svn2github/pcre/raw/master/pcre.h.in", baseDir) cDebug() From 4e687dd80783e8ff7bca9ba8ba6ba61d3a933fc2 Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Thu, 23 Apr 2020 21:52:34 -0600 Subject: [PATCH 421/593] Don't support multiple base nodes yet --- nimterop/exprparser.nim | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/nimterop/exprparser.nim b/nimterop/exprparser.nim index e9ee502..c74f0b6 100644 --- a/nimterop/exprparser.nim +++ b/nimterop/exprparser.nim @@ -486,17 +486,17 @@ proc processTSNode(gState: State, node: TSNode, typeofNode: var PNode): PNode = if node.len == 1: result = gState.processTSNode(node[0], typeofNode) elif node.len > 1: - let res = newNode(nkStmtListExpr) + var nodes: seq[PNode] for i in 0 ..< node.len: - let node = gState.processTSNode(node[i], typeofNode) - if node.kind != nkNone: - res.add node - if res.len == 1: - result = res[0] - elif res.len > 1: - result = res - else: - result = newNode(nkNone) + let subNode = gState.processTSNode(node[i], typeofNode) + if subNode.kind != nkNone: + nodes.add(subNode) + # Multiple nodes can get tricky. Don't support them yet, unless they + # have at most one valid node + if nodes.len > 1: + raise newException(ExprParseError, &"Node type \"{nodeName}\" with val ({node.val}) has more than one non empty node") + if nodes.len == 1: + result = nodes[0] else: raise newException(ExprParseError, &"Node type \"{nodeName}\" has no children") of "parenthesized_expression": From 322a0031984cefc278d2a377daa27bffdcbcae73 Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Thu, 23 Apr 2020 22:11:39 -0600 Subject: [PATCH 422/593] Add test for not supported nodes --- tests/include/tast2.h | 2 ++ tests/tast2.nim | 2 ++ 2 files changed, 4 insertions(+) diff --git a/tests/include/tast2.h b/tests/include/tast2.h index 42c852f..b47a801 100644 --- a/tests/include/tast2.h +++ b/tests/include/tast2.h @@ -34,6 +34,8 @@ extern "C" { #define EQ6 AVAL == BVAL #define SIZEOF sizeof(char) +#define REG_STR "regular string" +#define NOTSUPPORTEDSTR "not a " REG_STR #define NULLCHAR '\0'/* comments should not break things*/ #define OCTCHAR '\012' // nor should this comment diff --git a/tests/tast2.nim b/tests/tast2.nim index da7fafa..4cfbeac 100644 --- a/tests/tast2.nim +++ b/tests/tast2.nim @@ -109,6 +109,8 @@ assert C == 0x10 assert D == "hello" assert E == 'c' +assert not defined(NOTSUPPORTEDSTR) + assert UEXPR == (1234.uint shl 1) assert ULEXPR == (1234.uint32 shl 2) assert ULLEXPR == (1234.uint64 shl 3) From 89c10c4b25226a88062d01e6bf57a9e9146920c5 Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Sat, 25 Apr 2020 14:25:42 -0600 Subject: [PATCH 423/593] Address some PR comments --- nimterop/ast2.nim | 12 +++++++----- nimterop/globals.nim | 4 +++- nimterop/tshelp.nim | 14 ++++++-------- 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index 2ae4a70..474ec69 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -4,7 +4,7 @@ import options as opts import compiler/[ast, idents, lineinfos, modulegraphs, msgs, options, renderer] -import "."/treesitter/[api, c, cpp] +import "."/treesitter/api import "."/[globals, getters, exprparser, comphelp, tshelp] @@ -1391,7 +1391,9 @@ proc addEnum(gState: State, node: TSNode) = # Create const for fields var fnames: HashSet[string] - fvalSections: seq[tuple[fname: string, fval: string, cexpr: Option[TSNode]]] + # Hold all of field information so that we can add all of them + # after the const identifiers has been updated + fieldDeclarations: seq[tuple[fname: string, fval: string, cexpr: Option[TSNode]]] for i in 0 .. enumlist.len - 1: let en = enumlist[i] @@ -1410,9 +1412,9 @@ proc addEnum(gState: State, node: TSNode) = fval = &"({prev} + 1).{name}" if en.len > 1 and en[1].getName() in gEnumVals: - fvalSections.add((fname, "", some(en[1]))) + fieldDeclarations.add((fname, "", some(en[1]))) else: - fvalSections.add((fname, fval, none(TSNode))) + fieldDeclarations.add((fname, fval, none(TSNode))) fnames.incl fname prev = fname @@ -1422,7 +1424,7 @@ proc addEnum(gState: State, node: TSNode) = gState.constIdentifiers.incl fnames # parseCExpression requires all const identifiers to be present for the enum - for (fname, fval, cexprNode) in fvalSections: + for (fname, fval, cexprNode) in fieldDeclarations: var fval = fval if cexprNode.isSome: fval = "(" & $gState.parseCExpression(gState.getNodeVal(cexprNode.get()), name) & ")." & name diff --git a/nimterop/globals.nim b/nimterop/globals.nim index d433ab5..5db17a3 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -76,7 +76,9 @@ type # All const names for enum casting constIdentifiers*: HashSet[string] - # All symbols that have been skipped + # All symbols that have been skipped due to + # being unwrappable or the user provided + # override is blank skippedSyms*: HashSet[string] # Legacy ast fields, remove when ast2 becomes default diff --git a/nimterop/tshelp.nim b/nimterop/tshelp.nim index f234bc0..109321c 100644 --- a/nimterop/tshelp.nim +++ b/nimterop/tshelp.nim @@ -1,11 +1,9 @@ -template withCodeAst*(inputCode: string, inputMode: string, body: untyped): untyped = - ## A simple template to inject the TSNode into a body of code +import "."/treesitter/[c, cpp] - # This section is needed to be able to reference - # mode in strformat calls - let - code = inputCode - mode {.inject.} = inputMode +template withCodeAst*(code: string, mode: string, body: untyped): untyped = + ## A simple template to inject the TSNode into a body of code + mixin treeSitterC + mixin treeSitterCpp var parser = tsParserNew() defer: @@ -18,7 +16,7 @@ template withCodeAst*(inputCode: string, inputMode: string, body: untyped): unty elif mode == "cpp": doAssert parser.tsParserSetLanguage(treeSitterCpp()), "Failed to load C++ parser" else: - doAssert false, &"Invalid parser {mode}" + doAssert false, "Invalid parser " & mode var tree = parser.tsParserParseString(nil, code.cstring, code.len.uint32) From 33d77f82e878c86c0edf3bd21d359e5f40492ad2 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 27 Apr 2020 22:38:49 -0500 Subject: [PATCH 424/593] Fix #151 and fix #153 - detect nim.cfg --- README.md | 16 ++-- nimterop/build.nim | 50 +++++------ nimterop/cimport.nim | 1 + nimterop/docs.nim | 5 +- nimterop/nimconf.nim | 199 +++++++++++++++++++++++++++++++++++++++++++ tests/getheader.nims | 1 + 6 files changed, 238 insertions(+), 34 deletions(-) create mode 100644 nimterop/nimconf.nim diff --git a/README.md b/README.md index 0036187..53b37e7 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ The nimterop wrapping functionality is still limited to C but is constantly expa Nimterop has seen some adoption within the community and the simplicity and success of this approach justifies additional investment of time and effort. Regardless, the goal is to make interop seamless so nimterop will focus on wrapping headers and not the outright conversion of C/C++ implementation. -### Installation +## Installation Nimterop can be installed via [Nimble](https://github.com/nim-lang/nimble): @@ -28,11 +28,11 @@ nimble build This will download and install nimterop in the standard Nimble package location, typically `~/.nimble`. Once installed, it can be imported into any Nim program. -### Usage +## Usage Detailed documentation can be found [here](https://nimterop.github.io/nimterop/theindex.html). Also, check out the [wiki](https://github.com/nimterop/nimterop/wiki/Wrappers) for a list of all known wrappers that have been created using nimterop. They will provide real world examples of how to wrap libraries. Please do add your project once you are done so that others can benefit from your work. -#### Build API +### Build API Creating a wrapper has two parts, the first is to setup the C library. This includes downloading it or finding it if already installed, and building it if applicable. The `getHeader()` high-level API provides all of this functionality as a convenience. Following is an example of using the high-level `getHeader()` API to perform all building and linking automatically: @@ -103,7 +103,7 @@ The `-d:xxxYYY` Nim define flags have already been described above and can be sp If more fine-tuned control is desired over the build process, it is possible to manually control all steps that `getHeader()` performs by directly using the API provided by [build](https://nimterop.github.io/nimterop/build.html). Note also that there is no requirement to use these APIs to setup the library. Any other established mechanisms can be used to do so any limitations imposed by Nimterop are unintentional and feedback is most welcome. -#### Wrapper API +### Wrapper API Once the C library is setup, the next step is to create wrappers that inform Nim of all the types and functions that are available. Following is a simple example covering the API: @@ -152,7 +152,7 @@ __Compiling source__ The job of building and compiling the underlying C library is best left to the build mechanism selected by the library author so using `getHeader()` is recommended. For simpler projects with a few `.c` files though, `cCompile()` should be more than enough. It is not recommended for larger projects which heavily rely on functionality offered by build tools. Recreating reliable logic in Nim can be tedious and one can expect minimal support from that author if their tested build mechanism is not used. -#### Command line API +### Command line API The `toast` binary can also be used directly on the CLI, similar to `c2nim`. The `cPlugin()` interface @@ -190,7 +190,7 @@ Options: -O=, --symOverride= strings {} skip generating specified symbols ``` -### Why nimterop +## Why nimterop Nim has one of the best FFI you can find - importing C/C++ is supported out of the box. All you need to provide is type and proc definitions for Nim to interop with C/C++ binaries. Generation of these wrappers is easy for simple libraries but can quickly get out of hand. [c2nim](https://github.com/nim-lang/c2nim) greatly helps here by parsing and converting C/C++ into Nim but is limited due to the complex and constantly evolving C/C++ grammar. [nimgen](https://github.com/genotrance/nimgen) mainly focused on automating the wrapping process with `c2nim` and filled some holes but is again limited to `c2nim` capabilities. @@ -212,10 +212,10 @@ The con of this approach of delegating to the preprocessor is that the Nim wrapp This is part of the reason why Nimterop provides a wrapper API so that the generation of wrappers is Nim code that can be rendered as part of the build process on the target platform. It helps to think of Nimterop as a build time tool like `cmake` that renders artifacts on the target rather than a tool whose generated artifacts should be checked into source control. Regardless, both the wrapper API and the `toast` command line still allow saving the wrapper output to a file to be stored in source control since it might work well enough for many projects. -__Credits__ +## Credits Nimterop depends on [tree-sitter](http://tree-sitter.github.io/tree-sitter/) and all licensing terms of [tree-sitter](https://github.com/tree-sitter/tree-sitter/blob/master/LICENSE) apply to the usage of this package. The tree-sitter functionality is pulled and wrapped using nimterop itself. -__Feedback__ +## Feedback Nimterop is a work in progress and any feedback or suggestions are welcome. It is hosted on [GitHub](https://github.com/nimterop/nimterop) with an MIT license so issues, forks and PRs are most appreciated. diff --git a/nimterop/build.nim b/nimterop/build.nim index a025dc0..e11cd7b 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -4,11 +4,32 @@ import os except findExe, sleep import regex +proc fixCmd(cmd: string): string = + when defined(Windows): + # Replace 'cd d:\abc' with 'd: && cd d:\abc` + var filteredCmd = cmd + if cmd.toLower().startsWith("cd"): + var + colonIndex = cmd.find(":") + driveLetter = cmd.substr(colonIndex-1, colonIndex) + if (driveLetter[0].isAlphaAscii() and + driveLetter[1] == ':' and + colonIndex == 4): + filteredCmd = &"{driveLetter} && {cmd}" + result = "cmd /c " & filteredCmd + elif defined(posix): + result = cmd + else: + doAssert false + proc sanitizePath*(path: string, noQuote = false, sep = $DirSep): string = result = path.multiReplace([("\\\\", sep), ("\\", sep), ("/", sep)]) if not noQuote: result = result.quoteShell +# Nim cfg file related functionality +include "."/nimconf + proc sleep*(milsecs: int) = ## Sleep at compile time let @@ -20,14 +41,9 @@ proc sleep*(milsecs: int) = discard gorgeEx(cmd & $(milsecs / 1000)) -proc getOsCacheDir(): string = - when defined(posix): - result = getEnv("XDG_CACHE_HOME", getHomeDir() / ".cache") / "nim" - else: - result = getHomeDir() / "nimcache" - proc getNimteropCacheDir(): string = - result = getOsCacheDir() / "nimterop" + # Get location to cache all nimterop artifacts + result = getNimcacheDir() / "nimterop" proc getCurrentNimCompiler*(): string = result = getCurrentCompilerExe() @@ -46,24 +62,8 @@ proc execAction*(cmd: string, retry = 0, die = true, cache = false, ## `die = false` - return on errors ## `cache = true` - cache results unless cleared with -f ## `cacheKey` - key to create unique cache entry - var - ccmd = "" - when defined(Windows): - # Replace 'cd d:\abc' with 'd: && cd d:\abc` - var filteredCmd = cmd - if cmd.toLower().startsWith("cd"): - var - colonIndex = cmd.find(":") - driveLetter = cmd.substr(colonIndex-1, colonIndex) - if (driveLetter[0].isAlphaAscii() and - driveLetter[1] == ':' and - colonIndex == 4): - filteredCmd = &"{driveLetter} && {cmd}" - ccmd = "cmd /c " & filteredCmd - elif defined(posix): - ccmd = cmd - else: - doAssert false + let + ccmd = fixCmd(cmd) when nimvm: # Cache results for speedup if cache = true diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index 3e58bc8..4afb27c 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -286,6 +286,7 @@ proc cPluginHelper(body: string, imports = "import macros, nimterop/plugin\n\n") if not fileExists(path) or gStateCT.nocache or compileOption("forceBuild"): mkDir(path.parentDir()) writeFile(path, data) + writeNimConfig(path & ".cfg") doAssert fileExists(path), "Unable to write plugin file: " & path diff --git a/nimterop/docs.nim b/nimterop/docs.nim index 97fab96..6eb812b 100644 --- a/nimterop/docs.nim +++ b/nimterop/docs.nim @@ -2,8 +2,11 @@ import macros, strformat from os import parentDir, getCurrentCompilerExe, DirSep +when defined(nimdoc) or (NimMajor, NimMinor) >= (1, 3): + from os import paramCount, paramStr + when defined(nimdoc): - from os import getCurrentDir, paramCount, paramStr + from os import getCurrentDir proc getNimRootDir(): string = #[ diff --git a/nimterop/nimconf.nim b/nimterop/nimconf.nim new file mode 100644 index 0000000..fdf2648 --- /dev/null +++ b/nimterop/nimconf.nim @@ -0,0 +1,199 @@ +import json, macros, os, osproc, sets, strformat, strutils + +when nimvm: + when (NimMajor, NimMinor, NimPatch) >= (1, 2, 0): + import std/compilesettings +else: + discard + +# Config detected with std/compilesettings or `nim dump` +type + Config* = ref object + NimMajor*: int + NimMinor*: int + NimPatch*: int + + paths*: OrderedSet[string] + nimblePaths*: OrderedSet[string] + nimcacheDir*: string + +proc getJson(projectDir: string): JsonNode = + # Get `nim dump` json value for `projectDir` + var + cmd = "nim --hints:off --dump.format:json dump dummy" + dump = "" + ret = 0 + + if projectDir.len != 0: + # Run `nim dump` in `projectDir` if specified + cmd = &"cd {projectDir.sanitizePath} && " & cmd + + cmd = fixCmd(cmd) + when nimvm: + (dump, ret) = gorgeEx(cmd) + else: + (dump, ret) = execCmdEx(cmd) + + try: + result = parseJson(dump) + except JsonParsingError as e: + echo "# Failed to parse `nim dump` output: " & e.msg + +proc getOsCacheDir(): string = + # OS default cache directory + when defined(posix): + result = getEnv("XDG_CACHE_HOME", getHomeDir() / ".cache") / "nim" + else: + result = getHomeDir() / "nimcache" + +proc getProjectDir*(): string = + ## Get project directory for this compilation - returns `""` at runtime + when nimvm: + when (NimMajor, NimMinor, NimPatch) >= (1, 2, 0): + # If nim v1.2.0+, get from `std/compilesettings` + result = querySetting(projectFull).parentDir() + else: + # Get from `macros` + result = getProjectPath() + else: + discard + +proc getNimcacheDir*(projectDir = ""): string = + ## Get nimcache directory for current compilation or specified `projectDir` + when nimvm: + when (NimMajor, NimMinor, NimPatch) >= (1, 2, 0): + # Get value at compile time from `std/compilesettings` + result = querySetting(SingleValueSetting.nimcacheDir) + else: + discard + + # Not Nim v1.2.0+ or runtime + if result.len == 0: + let + # Get project directory for < v1.2.0 at compile time + projectDir = if projectDir.len != 0: projectDir else: getProjectDir() + + # Use `nim dump` to figure out nimcache for `projectDir` + let + dumpJson = getJson(projectDir) + + if dumpJson != nil and dumpJson.hasKey("nimcache"): + result = dumpJson["nimcache"].getStr() + let + (head, tail) = result.splitPath() + if "dummy" in tail: + # Remove `dummy_d` subdir when default nimcache + result = head + + # Set to OS defaults if not detectable + if result.len == 0: + result = getOsCacheDir() + +proc jsonToSeq(node: JsonNode, key: string): seq[string] = + # Convert JsonArray to seq[string] for specified `key` + if node.hasKey(key): + for elem in node[key].getElems(): + result.add elem.getStr() + +proc getNimConfig*(projectDir = ""): Config = + # Get `paths` - list of paths to be forwarded to Nim + result = new(Config) + var + libPath, version: string + lazyPaths, searchPaths: seq[string] + + when nimvm: + result.NimMajor = NimMajor + result.NimMinor = NimMinor + result.NimPatch = NimPatch + + when (NimMajor, NimMinor, NimPatch) >= (1, 2, 0): + # Get value at compile time from `std/compilesettings` + libPath = getCurrentCompilerExe().parentDir().parentDir() / "lib" + lazyPaths = querySettingSeq(MultipleValueSetting.lazyPaths) + searchPaths = querySettingSeq(MultipleValueSetting.searchPaths) + result.nimcacheDir = querySetting(SingleValueSetting.nimcacheDir) + else: + discard + + let + # Get project directory for < v1.2.0 at compile time + projectDir = if projectDir.len != 0: projectDir else: getProjectDir() + + # Not Nim v1.2.0+ or runtime + if libPath.len == 0: + let + dumpJson = getJson(projectDir) + + if dumpJson != nil: + if dumpJson.hasKey("version"): + version = dumpJson["version"].getStr() + lazyPaths = jsonToSeq(dumpJson, "lazyPaths") + searchPaths = jsonToSeq(dumpJson, "lib_paths") + if dumpJson.hasKey("libpath"): + libPath = dumpJson["libpath"].getStr() + elif searchPaths.len != 0: + # Usually `libPath` is last entry in `searchPaths` + libPath = searchPaths[^1] + + # Parse version + if version.len != 0: + let + splversion = version.split({'.'}, maxsplit = 3) + result.NimMajor = splversion[0].parseInt() + result.NimMinor = splversion[1].parseInt() + result.NimPatch = splversion[2].parseInt() + + # Find non standard lib paths added to `searchPath` + for path in searchPaths: + if libPath notin path: + result.paths.incl path + + # Find `nimblePaths` in `lazyPaths` + for path in lazyPaths: + let + (_, tail) = path.strip(leading = false, chars = {'/', '\\'}).splitPath() + if tail == "pkgs": + # Nimble path probably + result.nimblePaths.incl path + + # Find `paths` in `lazyPaths` that aren't within `nimblePaths` + # Have to do this separately since `nimblePaths` could be after + # packages in `lazyPaths` + for path in lazyPaths: + var skip = false + for npath in result.nimblePaths: + if npath in path: + skip = true + break + if not skip: + result.paths.incl path + + result.nimcacheDir = getNimcacheDir(projectDir) + +proc writeNimConfig*(cfg: Config, cfgFile: string) = + # Write Nim configuration to file + var + cfgOut = &"--nimcache:\"{cfg.nimcacheDir}\"\n" + + if (cfg.NimMajor, cfg.NimMinor, cfg.NimPatch) >= (1, 2, 0): + # --clearNimbleCache if Nim v1.2.0+ + cfgOut &= "--clearNimblePath\n" + + # Add `nimblePaths` if detected - v1.2.0+ + for path in cfg.nimblePaths: + cfgOut &= &"--nimblePath:\"{path}\"\n" + + # Add `paths` in all cases if any detected + for path in cfg.paths: + cfgOut &= &"--path:\"{path}\"\n" + + when defined(windows): + cfgOut = cfgOut.replace("\\", "/") + + writeFile(cfgFile, cfgOut) + +proc writeNimConfig*(cfgFile: string, projectDir = "") = + let + cfg = getNimConfig(projectDir) + writeNimConfig(cfg, cfgFile) diff --git a/tests/getheader.nims b/tests/getheader.nims index 7a0fc80..ef501ab 100644 --- a/tests/getheader.nims +++ b/tests/getheader.nims @@ -11,6 +11,7 @@ proc testCall(cmd, output: string, exitCode: int, delete = true) = if not delete: ccmd = ccmd.replace(" -f ", " ") + echo ccmd var (outp, exitC) = gorgeEx(ccmd) echo outp From c57666d5dbafaf88c4a8b53149ce9b07f9391242 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 28 Apr 2020 10:30:24 -0500 Subject: [PATCH 425/593] Enable conf detection in toast standalone --- nimterop/getters.nim | 8 +++++++- nimterop/nimconf.nim | 36 ++++++++++++++++++++++++------------ 2 files changed, 31 insertions(+), 13 deletions(-) diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 121c8d5..d829cf0 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -726,7 +726,13 @@ proc loadPlugin*(gState: State, sourcePath: string) = pdll = sourcePath.dll if not fileExists(pdll) or sourcePath.getLastModificationTime() > pdll.getLastModificationTime(): - discard execAction(&"{gState.nim.sanitizePath} c --app:lib --gc:markAndSweep {sourcePath.sanitizePath}") + let + # Get Nim configuration flags if not already specified in a .cfg file + flags = + if fileExists(sourcePath & ".cfg"): "" + else: getNimConfigFlags(getCurrentDir()) + cmd = &"{gState.nim.sanitizePath} c --app:lib --gc:markAndSweep {flags} {sourcePath.sanitizePath}" + discard execAction(cmd) doAssert fileExists(pdll), "No plugin binary generated for " & sourcePath let lib = loadLib(pdll) diff --git a/nimterop/nimconf.nim b/nimterop/nimconf.nim index fdf2648..664675e 100644 --- a/nimterop/nimconf.nim +++ b/nimterop/nimconf.nim @@ -171,29 +171,41 @@ proc getNimConfig*(projectDir = ""): Config = result.nimcacheDir = getNimcacheDir(projectDir) -proc writeNimConfig*(cfg: Config, cfgFile: string) = - # Write Nim configuration to file - var - cfgOut = &"--nimcache:\"{cfg.nimcacheDir}\"\n" +proc getNimConfigFlags(cfg: Config): string = + # Convert configuration into Nim flags for cfg file or command line + result = &"--nimcache:\"{cfg.nimcacheDir}\"\n" if (cfg.NimMajor, cfg.NimMinor, cfg.NimPatch) >= (1, 2, 0): # --clearNimbleCache if Nim v1.2.0+ - cfgOut &= "--clearNimblePath\n" + result &= "--clearNimblePath\n" # Add `nimblePaths` if detected - v1.2.0+ for path in cfg.nimblePaths: - cfgOut &= &"--nimblePath:\"{path}\"\n" + result &= &"--nimblePath:\"{path}\"\n" # Add `paths` in all cases if any detected for path in cfg.paths: - cfgOut &= &"--path:\"{path}\"\n" + result &= &"--path:\"{path}\"\n" when defined(windows): - cfgOut = cfgOut.replace("\\", "/") + result = result.replace("\\", "/") - writeFile(cfgFile, cfgOut) - -proc writeNimConfig*(cfgFile: string, projectDir = "") = +proc getNimConfigFlags*(projectDir = ""): string = + ## Get Nim command line configuration flags for `projectDir` + ## + ## If `projectDir` is not specified, it is detected if compile time or + ## current directory is used. let cfg = getNimConfig(projectDir) - writeNimConfig(cfg, cfgFile) + cfgOut = getNimConfigFlags(cfg) + return cfgOut.replace("\n", " ") + +proc writeNimConfig*(cfgFile: string, projectDir = "") = + ## Write Nim configuration for `projectDir` to specified `cfgFile` + ## + ## If `projectDir` is not specified, it is detected if compile time or + ## current directory is used. + let + cfg = getNimConfig(projectDir) + cfgOut = getNimConfigFlags(cfg) + writeFile(cfgFile, cfgOut) \ No newline at end of file From 2060c8964d6960808b86f767ea3949da9b3341e6 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 28 Apr 2020 11:54:00 -0500 Subject: [PATCH 426/593] Prevent plugin outdir override by configuration --- nimterop.nimble | 2 +- nimterop/getters.nim | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/nimterop.nimble b/nimterop.nimble index a6fba1e..e520c71 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -10,7 +10,7 @@ installDirs = @["nimterop"] installFiles = @["config.nims"] # Dependencies -requires "nim >= 0.20.2", "regex#v0.13.1", "cligen >= 0.9.43" +requires "nim >= 0.20.2", "regex >= 0.14.1", "cligen >= 0.9.45" import nimterop/docs diff --git a/nimterop/getters.nim b/nimterop/getters.nim index d829cf0..ebd3432 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -731,7 +731,13 @@ proc loadPlugin*(gState: State, sourcePath: string) = flags = if fileExists(sourcePath & ".cfg"): "" else: getNimConfigFlags(getCurrentDir()) - cmd = &"{gState.nim.sanitizePath} c --app:lib --gc:markAndSweep {flags} {sourcePath.sanitizePath}" + + # Always set output to same directory as source, prevents override + outflags = &"--out:\"{pdll.extractFilename()}\" --outdir:\"{pdll.parentDir()}\"" + + # Compile plugin as library with `markAndSweep` GC + cmd = &"{gState.nim.sanitizePath} c --app:lib --gc:markAndSweep {flags} {outflags} {sourcePath.sanitizePath}" + discard execAction(cmd) doAssert fileExists(pdll), "No plugin binary generated for " & sourcePath From 76d9be756a540272cc7a910eb0730297643276f7 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 28 Apr 2020 12:52:08 -0500 Subject: [PATCH 427/593] Fix mode, toast output dir --- nimterop.nimble | 1 - nimterop/cimport.nim | 6 ++++-- nimterop/getters.nim | 2 +- config.nims => nimterop/toast.nims | 7 ++++++- tests/tsoloud.nims | 5 +++++ 5 files changed, 16 insertions(+), 5 deletions(-) rename config.nims => nimterop/toast.nims (75%) create mode 100644 tests/tsoloud.nims diff --git a/nimterop.nimble b/nimterop.nimble index e520c71..caaaf90 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -7,7 +7,6 @@ license = "MIT" bin = @["nimterop/toast"] installDirs = @["nimterop"] -installFiles = @["config.nims"] # Dependencies requires "nim >= 0.20.2", "regex >= 0.14.1", "cligen >= 0.9.45" diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index 4afb27c..47dc0eb 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -100,6 +100,8 @@ proc getToastError(output: string): string = # Filter out preprocessor errors for line in output.splitLines(): if "fatal error:" in line.toLowerAscii: + if result.len == 0: + result = "\n\nFailed in preprocessing, check if `cIncludeDir()` is needed or compiler `mode` is correct (c/cpp)" result &= "\n\nERROR:$1\n" % line.split("fatal error:")[1] # Toast error @@ -135,7 +137,7 @@ proc getToast(fullpaths: seq[string], recurse: bool = false, dynlib: string = "" let toastExe = toastExePath() doAssert fileExists(toastExe), "toast not compiled: " & toastExe.sanitizePath & " make sure 'nimble build' or 'nimble install' built it" - cmd &= &"{toastExe} --preprocess" + cmd &= &"{toastExe} --preprocess -m:{mode}" if recurse: cmd.add " --recurse" @@ -679,7 +681,7 @@ macro c2nImport*(filename: static string, recurse: static bool = false, dynlib: echo "# Importing " & fullpath & " with c2nim" let - output = getToast(@[fullpath], recurse, dynlib, noNimout = true) + output = getToast(@[fullpath], recurse, dynlib, mode, noNimout = true) hash = output.hash().abs() hpath = getProjectCacheDir("c2nimCache", forceClean = false) / "nimterop_" & $hash & ".h" npath = hpath[0 .. hpath.rfind('.')] & "nim" diff --git a/nimterop/getters.nim b/nimterop/getters.nim index ebd3432..42a5a57 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -733,7 +733,7 @@ proc loadPlugin*(gState: State, sourcePath: string) = else: getNimConfigFlags(getCurrentDir()) # Always set output to same directory as source, prevents override - outflags = &"--out:\"{pdll.extractFilename()}\" --outdir:\"{pdll.parentDir()}\"" + outflags = &"--out:\"{pdll}\"" # Compile plugin as library with `markAndSweep` GC cmd = &"{gState.nim.sanitizePath} c --app:lib --gc:markAndSweep {flags} {outflags} {sourcePath.sanitizePath}" diff --git a/config.nims b/nimterop/toast.nims similarity index 75% rename from config.nims rename to nimterop/toast.nims index f5f7d21..94c9f20 100644 --- a/config.nims +++ b/nimterop/toast.nims @@ -1,3 +1,5 @@ +import os + # Workaround for C++ scanner.cc causing link error with other C obj files when defined(MacOSX): switch("clang.linkerexe", "g++") @@ -17,4 +19,7 @@ switch("path", "$nim") # Case objects when not defined(danger): - switch("define", "nimOldCaseObjects") \ No newline at end of file + switch("define", "nimOldCaseObjects") + +# Prevent outdir override +switch("out", currentSourcePath.parentDir() / "toast".addFileExt(ExeExt)) \ No newline at end of file diff --git a/tests/tsoloud.nims b/tests/tsoloud.nims new file mode 100644 index 0000000..3b6174b --- /dev/null +++ b/tests/tsoloud.nims @@ -0,0 +1,5 @@ +# Workaround for C++ scanner.cc causing link error with other C obj files +when defined(MacOSX): + switch("clang.linkerexe", "g++") +else: + switch("gcc.linkerexe", "g++") \ No newline at end of file From 492eba8f22c6fb0070274590490f2977e357de2a Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 28 Apr 2020 20:48:21 -0500 Subject: [PATCH 428/593] Add timeit to measure test timings --- nimterop.nimble | 15 ++++++++++----- tests/getheader.nims | 7 +------ tests/timeit.nim | 22 ++++++++++++++++++++++ tests/wrappers.nims | 6 +++--- 4 files changed, 36 insertions(+), 14 deletions(-) create mode 100644 tests/timeit.nim diff --git a/nimterop.nimble b/nimterop.nimble index caaaf90..8b6a756 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -1,6 +1,6 @@ # Package -version = "0.4.4" +version = "0.5.0" author = "genotrance" description = "C/C++ interop for Nim" license = "MIT" @@ -14,8 +14,7 @@ requires "nim >= 0.20.2", "regex >= 0.14.1", "cligen >= 0.9.45" import nimterop/docs proc execCmd(cmd: string) = - echo "execCmd:" & cmd - exec cmd + exec "tests/timeit " & cmd proc execTest(test: string, flags = "") = execCmd "nim c --hints:off -f " & flags & " -r " & test @@ -24,6 +23,9 @@ proc execTest(test: string, flags = "") = task buildToast, "build toast": execCmd("nim c --hints:off nimterop/toast.nim") +task buildTimeit, "build timer": + exec "nim c -d:danger tests/timeit" + task bt, "build toast": execCmd("nim c --hints:off -d:danger nimterop/toast.nim") @@ -34,6 +36,7 @@ task docs, "Generate docs": buildDocs(@["nimterop/all.nim"], "build/htmldocs") task test, "Test": + buildTimeitTask() buildToastTask() execTest "tests/tast2.nim" @@ -66,8 +69,10 @@ task test, "Test": # getHeader tests withDir("tests"): - execCmd("nim e getheader.nims") + exec "nim e getheader.nims" if not existsEnv("APPVEYOR"): - execCmd("nim e wrappers.nims") + exec "nim e wrappers.nims" docsTask() + + echo readFile("tests/timeit.txt") \ No newline at end of file diff --git a/tests/getheader.nims b/tests/getheader.nims index ef501ab..72407f9 100644 --- a/tests/getheader.nims +++ b/tests/getheader.nims @@ -2,16 +2,11 @@ import strutils proc testCall(cmd, output: string, exitCode: int, delete = true) = var - ccmd = - when defined(windows): - "cmd /c " & cmd - else: - cmd + ccmd = "../tests/timeit " & cmd if not delete: ccmd = ccmd.replace(" -f ", " ") - echo ccmd var (outp, exitC) = gorgeEx(ccmd) echo outp diff --git a/tests/timeit.nim b/tests/timeit.nim new file mode 100644 index 0000000..b52eae5 --- /dev/null +++ b/tests/timeit.nim @@ -0,0 +1,22 @@ +import std/monotimes, os, osproc, sequtils, strformat, strutils, times + +when isMainModule: + var params = commandLineParams() + params.apply(quoteShell) + + let cmd = params.join(" ") + echo &"================\nRunning: {cmd}\n" + + let + + start = getMonoTime() + ret = execCmd(cmd) + endt = getMonoTime() + + outf = getAppDir() / "timeit.txt" + outd = if fileExists(outf): readFile(outf) else: "" + outp = &"\nRan: {cmd}\nTime taken: {$(endt - start)}\n" + + echo outp + writeFile(outf, outd & outp) + quit(ret) \ No newline at end of file diff --git a/tests/wrappers.nims b/tests/wrappers.nims index 37ac686..4687d7a 100644 --- a/tests/wrappers.nims +++ b/tests/wrappers.nims @@ -9,7 +9,7 @@ withDir("wrappers"): for wrapper in wrappers: let name = wrapper.extractFilename() - exec "git clone https://github.com/" & wrapper + exec "../../tests/timeit git clone https://github.com/" & wrapper withDir(name): - exec "nimble install -d" - exec "nimble test" \ No newline at end of file + exec "../../../tests/timeit nimble install -d" + exec "../../../tests/timeit nimble test" \ No newline at end of file From 9a93417ae21ddd11037505f58ad793aebea8644a Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 29 Apr 2020 00:07:15 -0500 Subject: [PATCH 429/593] Fix timeit for legacy, reduce Windows test matrix --- nimterop.nimble | 6 ++++-- nimterop/build.nim | 18 +++++++++--------- nimterop/cimport.nim | 2 +- nimterop/docs.nim | 4 ++-- nimterop/nimconf.nim | 2 +- nimterop/template.nim | 2 +- tests/getheader.nims | 10 +++++----- tests/timeit.nim | 13 ++++++++++--- tests/tmath.nim | 2 +- tests/tnimterop_c.nim | 2 +- tests/tpcre.nim | 2 +- tests/zlib.nim | 2 +- 12 files changed, 37 insertions(+), 28 deletions(-) diff --git a/nimterop.nimble b/nimterop.nimble index 8b6a756..579d315 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -70,8 +70,10 @@ task test, "Test": # getHeader tests withDir("tests"): exec "nim e getheader.nims" - if not existsEnv("APPVEYOR"): - exec "nim e wrappers.nims" + when not defined(Windows): + # Skip on Windows since very slow + if not existsEnv("APPVEYOR"): + exec "nim e wrappers.nims" docsTask() diff --git a/nimterop/build.nim b/nimterop/build.nim index e11cd7b..5bfec76 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -34,7 +34,7 @@ proc sleep*(milsecs: int) = ## Sleep at compile time let cmd = - when defined(windows): + when defined(Windows): "cmd /c timeout " else: "sleep " @@ -110,7 +110,7 @@ proc findExe*(exe: string): string = ## at compile time var cmd = - when defined(windows): + when defined(Windows): "where " & exe else: "which " & exe @@ -354,7 +354,7 @@ proc findFile*(file: string, dir: string, recurse = true, first = false, regex = ## `first`. Without it, the shortest match is returned. var cmd = - when defined(windows): + when defined(Windows): "nimgrep --filenames --oneline --nocolor $1 \"$2\" $3" elif defined(linux): "find $3 $1 -regextype egrep -regex $2" @@ -364,10 +364,10 @@ proc findFile*(file: string, dir: string, recurse = true, first = false, regex = recursive = "" if recurse: - when defined(windows): + when defined(Windows): recursive = "--recursive" else: - when not defined(windows): + when not defined(Windows): recursive = "-maxdepth 1" var @@ -388,7 +388,7 @@ proc findFile*(file: string, dir: string, recurse = true, first = false, regex = if ret == 0: for line in files.splitLines(): let f = - when defined(windows): + when defined(Windows): if ": " in line: line.split(": ", maxsplit = 1)[1] else: @@ -750,7 +750,7 @@ proc getLocalPath(header, outdir: string): string = result = findFile(header, outdir) proc getNumProcs(): string = - when defined(windows): + when defined(Windows): getEnv("NUMBER_OF_PROCESSORS").strip() elif defined(linux): execAction("nproc").output.strip() @@ -778,7 +778,7 @@ proc buildLibrary(lname, outdir, conFlags, cmakeFlags, makeFlags: string): strin if findExe("cmake").len != 0: var gen = "" - when defined(windows): + when defined(Windows): if findExe("sh").len != 0: let uname = execAction("sh -c uname -a").output.toLowerAscii() @@ -828,7 +828,7 @@ proc buildLibrary(lname, outdir, conFlags, cmakeFlags, makeFlags: string): strin result = findFile(lname, outdir, regex = true) proc getDynlibExt(): string = - when defined(windows): + when defined(Windows): result = ".dll" elif defined(linux) or defined(FreeBSD): result = ".so[0-9.]*" diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index 47dc0eb..4cb364d 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -623,7 +623,7 @@ macro cImport*(filename: static string, recurse: static bool = false, dynlib: st ## ## const ## dynpcre = - ## when defined(windows): + ## when defined(Windows): ## when defined(cpu64): ## "pcre64.dll" ## else: diff --git a/nimterop/docs.nim b/nimterop/docs.nim index 6eb812b..d808535 100644 --- a/nimterop/docs.nim +++ b/nimterop/docs.nim @@ -19,7 +19,7 @@ proc getNimRootDir(): string = fmt"{currentSourcePath}".parentDir.parentDir.parentDir const - DirSep = when defined(windows): '\\' else: '/' + DirSep = when defined(Windows): '\\' else: '/' proc execAction(cmd: string): string = var @@ -53,7 +53,7 @@ proc buildDocs*(files: openArray[string], path: string, baseDir = getProjectPath ## ## NOTE: `buildDocs()` only works correctly on Windows with Nim 1.0+ since ## https://github.com/nim-lang/Nim/pull/11814 is required. - when defined(windows) and (NimMajor, NimMinor, NimPatch) < (1, 0, 0): + when defined(Windows) and (NimMajor, NimMinor, NimPatch) < (1, 0, 0): echo "buildDocs() unsupported on Windows for Nim < 1.0 - requires PR #11814" else: let diff --git a/nimterop/nimconf.nim b/nimterop/nimconf.nim index 664675e..144a7e0 100644 --- a/nimterop/nimconf.nim +++ b/nimterop/nimconf.nim @@ -187,7 +187,7 @@ proc getNimConfigFlags(cfg: Config): string = for path in cfg.paths: result &= &"--path:\"{path}\"\n" - when defined(windows): + when defined(Windows): result = result.replace("\\", "/") proc getNimConfigFlags*(projectDir = ""): string = diff --git a/nimterop/template.nim b/nimterop/template.nim index f625280..c6e846f 100644 --- a/nimterop/template.nim +++ b/nimterop/template.nim @@ -70,7 +70,7 @@ cDefine("SYMBOL", "value") cCompile(srcDir/"file.c") # Perform OS specific tasks -when defined(windows): +when defined(Windows): # Windows specific symbols, options and files # Dynamic library to link against diff --git a/tests/getheader.nims b/tests/getheader.nims index 72407f9..2e6530f 100644 --- a/tests/getheader.nims +++ b/tests/getheader.nims @@ -35,6 +35,11 @@ when defined(posix): testCall(cmd & " -d:lzmaGit -d:lzmaSetVer=v5.2.0" & lrcmd, lexp & "5.2.0", 0) testCall(cmd & " -d:lzmaGit -d:lzmaStatic -d:lzmaSetVer=v5.2.0" & lrcmd, lexp & "5.2.0", 0, delete = false) + # dl - remove from Windows to save some time + testCall(cmd & " -d:lzmaDL" & lrcmd, "Need version", 1) + testCall(cmd & " -d:lzmaDL -d:lzmaSetVer=5.2.4" & lrcmd, lexp & "5.2.4", 0) + testCall(cmd & " -d:lzmaDL -d:lzmaStatic -d:lzmaSetVer=5.2.4" & lrcmd, lexp & "5.2.4", 0, delete = false) + # git testCall(cmd & " -d:envTest" & zrcmd, zexp, 0) testCall(cmd & " -d:envTestStatic" & zrcmd, zexp, 0, delete = false) @@ -43,11 +48,6 @@ testCall(cmd & " -d:envTestStatic" & zrcmd, zexp, 0, delete = false) testCall(cmd & " -d:zlibGit -d:zlibSetVer=v1.2.10" & zrcmd, zexp & "1.2.10", 0) testCall(cmd & " -d:zlibGit -d:zlibStatic -d:zlibSetVer=v1.2.10" & zrcmd, zexp & "1.2.10", 0, delete = false) -# dl -testCall(cmd & " -d:lzmaDL" & lrcmd, "Need version", 1) -testCall(cmd & " -d:lzmaDL -d:lzmaSetVer=5.2.4" & lrcmd, lexp & "5.2.4", 0) -testCall(cmd & " -d:lzmaDL -d:lzmaStatic -d:lzmaSetVer=5.2.4" & lrcmd, lexp & "5.2.4", 0, delete = false) - # dl testCall(cmd & " -d:zlibDL -d:zlibSetVer=1.2.11" & zrcmd, zexp & "1.2.11", 0) testCall(cmd & " -d:zlibDL -d:zlibStatic -d:zlibSetVer=1.2.11" & zrcmd, zexp & "1.2.11", 0, delete = false) diff --git a/tests/timeit.nim b/tests/timeit.nim index b52eae5..b448191 100644 --- a/tests/timeit.nim +++ b/tests/timeit.nim @@ -1,4 +1,11 @@ -import std/monotimes, os, osproc, sequtils, strformat, strutils, times +import os, osproc, sequtils, strformat, strutils, times + +when (NimMajor, NimMinor) >= (1, 0): + import std/monotimes + + template getTime(): MonoTime = getMonoTime() +else: + template getTime(): float = epochTime() when isMainModule: var params = commandLineParams() @@ -9,9 +16,9 @@ when isMainModule: let - start = getMonoTime() + start = getTime() ret = execCmd(cmd) - endt = getMonoTime() + endt = getTime() outf = getAppDir() / "timeit.txt" outd = if fileExists(outf): readFile(outf) else: "" diff --git a/tests/tmath.nim b/tests/tmath.nim index b8477c1..6c7999a 100644 --- a/tests/tmath.nim +++ b/tests/tmath.nim @@ -7,7 +7,7 @@ cOverride: mingw_ldbl_type_t = object mingw_dbl_type_t = object -when defined(windows): +when defined(Windows): cOverride: type complex = object diff --git a/tests/tnimterop_c.nim b/tests/tnimterop_c.nim index 0360225..8428489 100644 --- a/tests/tnimterop_c.nim +++ b/tests/tnimterop_c.nim @@ -45,7 +45,7 @@ check TEST_STR == "hello world" when defined(osx): check OSDEF == 10 -elif defined(windows): +elif defined(Windows): check OSDEF == 20 else: check OSDEF == 30 diff --git a/tests/tpcre.nim b/tests/tpcre.nim index c8e8059..4a426c4 100644 --- a/tests/tpcre.nim +++ b/tests/tpcre.nim @@ -14,7 +14,7 @@ static: const dynpcre = - when defined(windows): + when defined(Windows): when defined(cpu64): "pcre64.dll" else: diff --git a/tests/zlib.nim b/tests/zlib.nim index ce26c9a..09a6df2 100644 --- a/tests/zlib.nim +++ b/tests/zlib.nim @@ -15,7 +15,7 @@ proc zlibPreBuild(outdir, path: string) = # Delete default Makefile if mf.readFile().contains("configure first"): mf.rmFile() - when defined(windows): + when defined(Windows): # Fix static lib name on Windows setCmakeLibName(outdir, "zlibstatic", prefix = "lib", oname = "zlib", suffix = ".a") From 0098947a8161f4d832bffae34ac7a0b0a5341312 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 29 Apr 2020 13:02:06 -0500 Subject: [PATCH 430/593] Fix timeit ret for osx --- tests/timeit.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/timeit.nim b/tests/timeit.nim index b448191..cf9417f 100644 --- a/tests/timeit.nim +++ b/tests/timeit.nim @@ -26,4 +26,4 @@ when isMainModule: echo outp writeFile(outf, outd & outp) - quit(ret) \ No newline at end of file + quit(ret mod 255) From 2278f0e49d4da012370bb8e907640b9d89ae54fa Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 29 Apr 2020 14:38:35 -0500 Subject: [PATCH 431/593] Add -f:ast1, lesser debug output --- nimterop/globals.nim | 4 ++-- nimterop/toast.nim | 12 +++++++----- tests/lzma.nim | 1 - tests/tast2.nim | 1 - tests/tmath.nim | 1 - tests/tnimterop_c.nim | 1 - tests/tnimterop_cpp.nim | 1 - tests/tpcre.nim | 1 - tests/zlib.nim | 3 --- 9 files changed, 9 insertions(+), 16 deletions(-) diff --git a/nimterop/globals.nim b/nimterop/globals.nim index 5db17a3..b9352a4 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -106,7 +106,7 @@ type nodeBranch*: seq[string] Feature* = enum - ast2 + ast1, ast2 var gStateCT {.compiletime, used.} = new(State) @@ -123,7 +123,7 @@ when not declared(CIMPORT): # Redirect output to file when required template gecho*(args: string) = if gState.outputHandle.isNil: - echo args + stdout.writeLine(args) else: gState.outputHandle.writeLine(args) diff --git a/nimterop/toast.nim b/nimterop/toast.nim index 98045bf..7a41874 100644 --- a/nimterop/toast.nim +++ b/nimterop/toast.nim @@ -21,7 +21,7 @@ proc process(gState: State, path: string, astTable: AstTable) = elif gState.pnim: if Feature.ast2 in gState.feature: ast2.parseNim(gState, path, root) - else: + elif Feature.ast1 in gState.feature: ast.parseNim(gState, path, root, astTable) elif gState.preprocess: gecho gState.code @@ -33,7 +33,7 @@ proc main( debug = false, defines: seq[string] = @[], dynlib: string = "", - feature: seq[Feature] = @[], + feature: seq[Feature] = @[Feature.ast1], includeHeader = false, includeDirs: seq[string] = @[], mode = "", @@ -118,13 +118,13 @@ proc main( # Process grammar into AST let astTable = - if Feature.ast2 notin gState.feature: + if Feature.ast1 in gState.feature: parseGrammar() else: nil if pgrammar: - if Feature.ast2 notin gState.feature: + if Feature.ast1 in gState.feature: # Print AST of grammar gState.printGrammar(astTable) elif source.nBl: @@ -137,8 +137,10 @@ proc main( if gState.pnim: if Feature.ast2 in gState.feature: ast2.printNim(gState) - else: + elif Feature.ast1 in gState.feature: ast.printNim(gState) + gecho """{.hint: "The legacy wrapper generation algorithm is deprecated and will be removed in the next release of Nimterop.".}""" + gecho """{.hint: "Refer to CHANGES.md for details on migrating to the new backend.".}""" # Close outputFile if outputFile.len != 0: diff --git a/tests/lzma.nim b/tests/lzma.nim index 1cc6aa0..f30b974 100644 --- a/tests/lzma.nim +++ b/tests/lzma.nim @@ -7,7 +7,6 @@ const flags = "--prefix=___,__,_ --suffix=__,_" static: - cDebug() cSkipSymbol(@[ "PRIX8", "PRIX16", "PRIX32", "PRIXLEAST8", "PRIXLEAST16", "PRIXLEAST32", diff --git a/tests/tast2.nim b/tests/tast2.nim index 4cfbeac..273d3e3 100644 --- a/tests/tast2.nim +++ b/tests/tast2.nim @@ -7,7 +7,6 @@ static: # the VM does not support it when (NimMajor, NimMinor, NimPatch) < (1, 0, 0): cSkipSymbol @["CASTEXPR"] - cDebug() const path = currentSourcePath.parentDir() / "include" / "tast2.h" diff --git a/tests/tmath.nim b/tests/tmath.nim index 6c7999a..8f947b2 100644 --- a/tests/tmath.nim +++ b/tests/tmath.nim @@ -19,7 +19,6 @@ static: cSkipSymbol @["math_errhandling", "FP_ILOGB0", "FP_ILOGBNAN"] else: cSkipSymbol @["math_errhandling"] - cDebug() cDisableCaching() cAddStdDir() diff --git a/tests/tnimterop_c.nim b/tests/tnimterop_c.nim index 8428489..20c1678 100644 --- a/tests/tnimterop_c.nim +++ b/tests/tnimterop_c.nim @@ -3,7 +3,6 @@ import nimterop/cimport import nimterop/paths static: - cDebug() cDisableCaching() cAddSearchDir testsIncludeDir() diff --git a/tests/tnimterop_cpp.nim b/tests/tnimterop_cpp.nim index 14c8c8f..3f44e86 100644 --- a/tests/tnimterop_cpp.nim +++ b/tests/tnimterop_cpp.nim @@ -3,7 +3,6 @@ import nimterop/cimport import nimterop/paths static: - cDebug() cDisableCaching() cAddSearchDir testsIncludeDir() diff --git a/tests/tpcre.nim b/tests/tpcre.nim index 4a426c4..51530c1 100644 --- a/tests/tpcre.nim +++ b/tests/tpcre.nim @@ -9,7 +9,6 @@ const static: if not pcreH.fileExists(): downloadUrl("https://github.com/svn2github/pcre/raw/master/pcre.h.in", baseDir) - cDebug() cDisableCaching() const diff --git a/tests/zlib.nim b/tests/zlib.nim index 09a6df2..febc6b1 100644 --- a/tests/zlib.nim +++ b/tests/zlib.nim @@ -5,9 +5,6 @@ import nimterop/[build, cimport] const baseDir = getProjectCacheDir("nimterop" / "tests" / "zlib") -static: - cDebug() - proc zlibPreBuild(outdir, path: string) = let mf = outdir / "Makefile" From 4784616d987c3b7c73125af44bec999184444a22 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 30 Apr 2020 08:54:18 -0500 Subject: [PATCH 432/593] Clean globals, build debug --- nimterop.nimble | 2 +- nimterop/ast2.nim | 2 +- nimterop/build.nim | 24 ++++++++++++++++------ nimterop/cimport.nim | 7 +++---- nimterop/globals.nim | 47 +++++++++++++++++++++----------------------- nimterop/paths.nim | 1 - nimterop/toast.nim | 5 ++++- nimterop/toast.nims | 5 ++++- tests/getheader.nims | 2 +- tests/tsoloud.nim | 1 - 10 files changed, 54 insertions(+), 42 deletions(-) diff --git a/nimterop.nimble b/nimterop.nimble index 579d315..a6ece7c 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -24,7 +24,7 @@ task buildToast, "build toast": execCmd("nim c --hints:off nimterop/toast.nim") task buildTimeit, "build timer": - exec "nim c -d:danger tests/timeit" + exec "nim c --hints:off -d:danger tests/timeit" task bt, "build toast": execCmd("nim c --hints:off -d:danger nimterop/toast.nim") diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index 474ec69..13f2ba2 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -6,7 +6,7 @@ import compiler/[ast, idents, lineinfos, modulegraphs, msgs, options, renderer] import "."/treesitter/api -import "."/[globals, getters, exprparser, comphelp, tshelp] +import "."/[comphelp, exprparser, globals, getters, tshelp] proc getPtrType*(str: string): string = result = case str: diff --git a/nimterop/build.nim b/nimterop/build.nim index 5bfec76..6fa44cb 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -4,6 +4,18 @@ import os except findExe, sleep import regex +# build specific debug since we cannot import globals (yet) +var + gDebug* = false + gDebugCT* {.compileTime.} = false + +proc echoDebug(str: string) = + let str = "\n# " & str.strip().replace("\n", "\n# ") + when nimvm: + if gDebugCT: echo str + else: + if gDebug: echo str + proc fixCmd(cmd: string): string = when defined(Windows): # Replace 'cd d:\abc' with 'd: && cd d:\abc` @@ -461,7 +473,7 @@ proc configure*(path, check: string, flags = "") = if fileExists(path / i): echo "# Running autogen.sh" - echo execAction( + echoDebug execAction( &"cd {(path / i).parentDir().sanitizePath} && bash ./autogen.sh").output break @@ -471,7 +483,7 @@ proc configure*(path, check: string, flags = "") = if fileExists(path / i): echo "# Running autoreconf" - echo execAction(&"cd {path.sanitizePath} && autoreconf -fi").output + echoDebug execAction(&"cd {path.sanitizePath} && autoreconf -fi").output break @@ -483,7 +495,7 @@ proc configure*(path, check: string, flags = "") = if flags.len != 0: cmd &= &" {flags}" - echo execAction(cmd).output + echoDebug execAction(cmd).output doAssert (path / check).fileExists(), "# Configure failed" @@ -577,10 +589,10 @@ proc cmake*(path, check, flags: string) = mkDir(path) - var + let cmd = &"cd {path.sanitizePath} && cmake {flags}" - echo execAction(cmd).output + echoDebug execAction(cmd).output doAssert (path / check).fileExists(), "# cmake failed" @@ -616,7 +628,7 @@ proc make*(path, check: string, flags = "", regex = false) = if flags.len != 0: cmd &= &" {flags}" - echo execAction(cmd).output + echoDebug execAction(cmd).output doAssert findFile(check, path, regex = regex).len != 0, "# make failed" diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index 4cb364d..e081633 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -17,11 +17,9 @@ All `{.compileTime.}` procs must be used in a compile time context, e.g. using: import hashes, macros, os, strformat, strutils -const CIMPORT {.used.} = 1 +import regex -include "."/globals - -import "."/[build, paths, types] +import "."/[build, globals, paths, types] export types proc interpPath(dir: string): string= @@ -393,6 +391,7 @@ proc cSearchPath*(path: string): string {.compileTime.}= proc cDebug*() {.compileTime.} = ## Enable debug messages and display the generated Nim code gStateCT.debug = true + build.gDebugCT = true proc cDisableCaching*() {.compileTime.} = ## Disable caching of generated Nim code - useful during wrapper development diff --git a/nimterop/globals.nim b/nimterop/globals.nim index b9352a4..ae9a6d0 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -4,13 +4,13 @@ import regex import "."/plugin -when not declared(CIMPORT): +when defined(TOAST): import compiler/[ast, idents, modulegraphs, options] import "."/treesitter/api const - gAtoms {.used.} = @[ + gAtoms* {.used.} = @[ "field_identifier", "identifier", "number_literal", @@ -21,7 +21,7 @@ const "type_identifier" ].toHashSet() - gExpressions {.used.} = @[ + gExpressions* {.used.} = @[ "parenthesized_expression", "bitwise_expression", "shift_expression", @@ -29,32 +29,32 @@ const "escape_sequence" ].toHashSet() - gEnumVals {.used.} = @[ + gEnumVals* {.used.} = @[ "identifier", "number_literal", "char_literal" ].concat(toSeq(gExpressions.items)) type - Kind = enum + Kind* = enum exactlyOne oneOrMore # + zeroOrMore # * zeroOrOne # ? orWithNext # ! - Ast = object + Ast* = object name*: string kind*: Kind recursive*: bool children*: seq[ref Ast] - when not declared(CIMPORT): + when defined(TOAST): tonim*: proc (ast: ref Ast, node: TSNode, gState: State) regex*: Regex - AstTable {.used.} = TableRef[string, seq[ref Ast]] + AstTable* {.used.} = TableRef[string, seq[ref Ast]] - State = ref object + State* = ref object compile*, defines*, headers*, includeDirs*, searchDirs*, prefix*, suffix*, symOverride*: seq[string] debug*, includeHeader*, nocache*, nocomments*, past*, preprocess*, pnim*, recurse*: bool @@ -87,7 +87,7 @@ type commentStr*, debugStr*, skipStr*: string # Nim compiler objects - when not declared(CIMPORT): + when defined(TOAST): constSection*, enumSection*, pragmaSection*, procSection*, typeSection*, varSection*: PNode identCache*: IdentCache config*: ConfigRef @@ -109,24 +109,21 @@ type ast1, ast2 var - gStateCT {.compiletime, used.} = new(State) + gStateCT* {.compiletime, used.} = new(State) -template nBl(s: typed): untyped {.used.} = +template nBl*(s: typed): untyped {.used.} = (s.len != 0) -template Bl(s: typed): untyped {.used.} = +template Bl*(s: typed): untyped {.used.} = (s.len == 0) -when not declared(CIMPORT): - export gAtoms, gExpressions, gEnumVals, Kind, Ast, AstTable, State, nBl, Bl +# Redirect output to file when required +template gecho*(args: string) = + if gState.outputHandle.isNil: + stdout.writeLine(args) + else: + gState.outputHandle.writeLine(args) - # Redirect output to file when required - template gecho*(args: string) = - if gState.outputHandle.isNil: - stdout.writeLine(args) - else: - gState.outputHandle.writeLine(args) - - template decho*(args: varargs[string, `$`]): untyped = - if gState.debug: - gecho join(args, "").getCommented() \ No newline at end of file +template decho*(args: varargs[string, `$`]): untyped = + if gState.debug: + gecho join(args, "").getCommented() \ No newline at end of file diff --git a/nimterop/paths.nim b/nimterop/paths.nim index 0ae461f..fa245b3 100644 --- a/nimterop/paths.nim +++ b/nimterop/paths.nim @@ -16,4 +16,3 @@ proc toastExePath*(): string = proc testsIncludeDir*(): string = nimteropRoot() / "tests" / "include" - diff --git a/nimterop/toast.nim b/nimterop/toast.nim index 7a41874..78708f5 100644 --- a/nimterop/toast.nim +++ b/nimterop/toast.nim @@ -2,7 +2,7 @@ import os, osproc, strformat, strutils, tables, times import "."/treesitter/[api, c, cpp] -import "."/[ast, ast2, globals, getters, grammar, build, tshelp] +import "."/[ast, ast2, build, globals, getters, grammar, tshelp] proc process(gState: State, path: string, astTable: AstTable) = doAssert existsFile(path), &"Invalid path {path}" @@ -81,6 +81,9 @@ proc main( doAssert not (includeHeader == true and dynlib.nBl), "`includeHeader` and `dynlib` cannot be used simultaneously" + # Set gDebug in build.nim + build.gDebug = debug + # Split some arguments with , gState.symOverride = gState.symOverride.getSplitComma() gState.prefix = gState.prefix.getSplitComma() diff --git a/nimterop/toast.nims b/nimterop/toast.nims index 94c9f20..83d5cf4 100644 --- a/nimterop/toast.nims +++ b/nimterop/toast.nims @@ -22,4 +22,7 @@ when not defined(danger): switch("define", "nimOldCaseObjects") # Prevent outdir override -switch("out", currentSourcePath.parentDir() / "toast".addFileExt(ExeExt)) \ No newline at end of file +switch("out", currentSourcePath.parentDir() / "toast".addFileExt(ExeExt)) + +# Define TOAST for globals.nim +switch("define", "TOAST") \ No newline at end of file diff --git a/tests/getheader.nims b/tests/getheader.nims index 2e6530f..1e8027a 100644 --- a/tests/getheader.nims +++ b/tests/getheader.nims @@ -14,7 +14,7 @@ proc testCall(cmd, output: string, exitCode: int, delete = true) = doAssert outp.contains(output), outp var - cmd = "nim c -f" + cmd = "nim c -f --hints:off" lrcmd = " -r lzma.nim" zrcmd = " -r zlib.nim" lexp = "liblzma version = " diff --git a/tests/tsoloud.nim b/tests/tsoloud.nim index afff0f1..8dd197c 100644 --- a/tests/tsoloud.nim +++ b/tests/tsoloud.nim @@ -7,7 +7,6 @@ const static: gitPull("https://github.com/jarikomppa/soloud", baseDir, "include/*\nsrc/*\n", checkout = "RELEASE_20200207") - cDebug() cDisableCaching() cOverride: From 34043bd5af52d20df1e85f28c4369d5810248017 Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Fri, 1 May 2020 07:20:45 -0600 Subject: [PATCH 433/593] Fix #198: integer out of range --- nimterop/exprparser.nim | 44 +++++++++++++++++++++++++++-------------- tests/include/tast2.h | 3 +++ tests/tast2.nim | 2 ++ 3 files changed, 34 insertions(+), 15 deletions(-) diff --git a/nimterop/exprparser.nim b/nimterop/exprparser.nim index c74f0b6..e68c0b1 100644 --- a/nimterop/exprparser.nim +++ b/nimterop/exprparser.nim @@ -133,13 +133,38 @@ proc getFloatNode(number, suffix: string): PNode {.inline.} = proc getIntNode(number, suffix: string): PNode {.inline.} = ## Get a Nim int node from a C integer expression + suffix + var + val: BiggestInt + flags: TNodeFlags + # I realize these regex are wasteful on performance, but + # couldn't come up with a better idea. + if number.contains(re"0[xX]"): + val = parseHexInt(number) + flags = {nfBase16} + elif number.contains(re"0[bB]"): + val = parseBinInt(number) + flags = {nfBase2} + elif number.contains(re"0[oO]"): + val = parseOctInt(number) + flags = {nfBase8} + else: + val = parseInt(number) + case suffix of "u", "U": result = newNode(nkUintLit) of "l", "L": - result = newNode(nkInt32Lit) + # If the value doesn't fit, adjust + if val > int32.high or val < int32.low: + result = newNode(nkInt64Lit) + else: + result = newNode(nkInt32Lit) of "ul", "UL": - result = newNode(nkUint32Lit) + # If the value doesn't fit, adjust + if val > uint32.high.BiggestInt: + result = newNode(nkUInt64Lit) + else: + result = newNode(nkUInt32Lit) of "ll", "LL": result = newNode(nkInt64Lit) of "ull", "ULL": @@ -147,19 +172,8 @@ proc getIntNode(number, suffix: string): PNode {.inline.} = else: result = newNode(nkIntLit) - # I realize these regex are wasteful on performance, but - # couldn't come up with a better idea. - if number.contains(re"0[xX]"): - result.intVal = parseHexInt(number) - result.flags = {nfBase16} - elif number.contains(re"0[bB]"): - result.intVal = parseBinInt(number) - result.flags = {nfBase2} - elif number.contains(re"0[oO]"): - result.intVal = parseOctInt(number) - result.flags = {nfBase8} - else: - result.intVal = parseInt(number) + result.intVal = val + result.flags = flags proc getNumNode(number, suffix: string): PNode {.inline.} = ## Convert a C number to a Nim number PNode diff --git a/tests/include/tast2.h b/tests/include/tast2.h index b47a801..e1d4529 100644 --- a/tests/include/tast2.h +++ b/tests/include/tast2.h @@ -33,6 +33,9 @@ extern "C" { #define EQ5 AVAL != BVAL #define EQ6 AVAL == BVAL +// testing integer out of long int range +#define INT_FAST16_MIN (-9223372036854775807L-1) + #define SIZEOF sizeof(char) #define REG_STR "regular string" #define NOTSUPPORTEDSTR "not a " REG_STR diff --git a/tests/tast2.nim b/tests/tast2.nim index 273d3e3..54b89e5 100644 --- a/tests/tast2.nim +++ b/tests/tast2.nim @@ -131,6 +131,8 @@ assert SIZEOF == 1 assert COERCE == 645635670332'u64 assert COERCE2 == 645635670332'i64 +assert INT_FAST16_MIN == -9223372036854775807'i64 - 1 + assert BINEXPR == 5 assert BOOL == true assert MATHEXPR == -99 From 08f8ca32f41d16ade0b364e048a0a99b1a01eebe Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Fri, 1 May 2020 11:02:29 -0500 Subject: [PATCH 434/593] Fix #196 - more known types --- nimterop/ast2.nim | 4 +--- nimterop/getters.nim | 29 +++++++++++++++++++++++++---- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index 13f2ba2..3ffa3f6 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -42,8 +42,6 @@ proc getOverrideOrSkip(gState: State, node: TSNode, origname: string, kind: NimS else: gecho &"\n# $1'{origname}' skipped" % skind gState.skippedSyms.incl origname - if gState.debug: - gState.skipStr &= &"\n{gState.getNodeVal(node)}" proc addOverrideFinal(gState: State, kind: NimSymKind) = # Add all unused cOverride symbols for `kind` to AST @@ -285,7 +283,7 @@ proc newXIdent(gState: State, node: TSNode, kind = nskType, fname = "", pragmas: if name.Bl: # Name skipped or overridden since blank result = gState.getOverrideOrSkip(node, origname, kind) - elif gState.addNewIdentifer(name): + elif origname notin gTypeMap and gState.addNewIdentifer(name): if kind == nskType: # type name* = # diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 42a5a57..69628f5 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -57,6 +57,30 @@ const gTypeMap* = { "u_int": "cuint", "size_t": "uint", + "int8_t": "int8", + "int16_t": "int16", + "int32_t": "int32", + "int64_t": "int64", + + "intptr_t": "ptr int", + + "Int8": "int8", + "Int16": "int16", + "Int32": "int32", + "Int64": "int64", + + "uint8_t": "uint8", + "uint16_t": "uint16", + "uint32_t": "uint32", + "uint64_t": "uint64", + + "uintptr_t": "ptr uint", + + "Uint8": "uint8", + "Uint16": "uint16", + "Uint32": "uint32", + "Uint64": "uint64", + # long "long": "clong", "long int": "clong", @@ -87,10 +111,7 @@ proc getType*(str: string): string = if str == "void": return "object" - result = str.strip(chars={'_'}). - replace(re"\s+", " "). - replace(re"^([u]?int[\d]+)_t$", "$1"). - replace(re"^([u]?int)ptr_t$", "ptr $1") + result = str.strip(chars={'_'}).replace(re"\s+", " ") if gTypeMap.hasKey(result): result = gTypeMap[result] From 748998b0bd921a60f1c05aae7b47eb8de51b7e3e Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Fri, 1 May 2020 15:07:51 -0500 Subject: [PATCH 435/593] Fixes and test lzma/zlib with ast2 --- nimterop/ast2.nim | 6 +- nimterop/getters.nim | 134 ++++++++++++++++++++++--------------------- tests/getheader.nims | 2 +- tests/lzma.nim | 8 ++- tests/tsoloud.nim | 3 +- tests/zlib.nim | 6 +- 6 files changed, 85 insertions(+), 74 deletions(-) diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index 3ffa3f6..4d609cb 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -283,7 +283,9 @@ proc newXIdent(gState: State, node: TSNode, kind = nskType, fname = "", pragmas: if name.Bl: # Name skipped or overridden since blank result = gState.getOverrideOrSkip(node, origname, kind) - elif origname notin gTypeMap and gState.addNewIdentifer(name): + elif name notin gTypeMapValues and gState.addNewIdentifer(name): + # Add only if not an existing Nim type + if kind == nskType: # type name* = # @@ -1399,7 +1401,7 @@ proc addEnum(gState: State, node: TSNode) = continue let fname = gState.getIdentifier(gState.getNodeVal(en.getAtom()), nskEnumField) - if fname.nBl: + if fname.nBl and gState.addNewIdentifer(fname): var fval = "" if prev.Bl: diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 69628f5..d94fae8 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -30,82 +30,86 @@ yield""".split(Whitespace).toHashSet() # Types related -const gTypeMap* = { - # char - "char": "cchar", - "signed char": "cschar", - "unsigned char": "cuchar", +const + gTypeMap* = { + # char + "char": "cchar", + "signed char": "cschar", + "unsigned char": "cuchar", - # short - "short": "cshort", - "short int": "cshort", - "signed short": "cshort", - "signed short int": "cshort", - "unsigned short": "cushort", - "unsigned short int": "cushort", - "uShort": "cushort", - "u_short": "cushort", + # short + "short": "cshort", + "short int": "cshort", + "signed short": "cshort", + "signed short int": "cshort", + "unsigned short": "cushort", + "unsigned short int": "cushort", + "uShort": "cushort", + "u_short": "cushort", - # int - "int": "cint", - "signed": "cint", - "signed int": "cint", - "ssize_t": "int", - "unsigned": "cuint", - "unsigned int": "cuint", - "uInt": "cuint", - "u_int": "cuint", - "size_t": "uint", + # int + "int": "cint", + "signed": "cint", + "signed int": "cint", + "ssize_t": "int", + "unsigned": "cuint", + "unsigned int": "cuint", + "uInt": "cuint", + "u_int": "cuint", + "size_t": "uint", - "int8_t": "int8", - "int16_t": "int16", - "int32_t": "int32", - "int64_t": "int64", + "int8_t": "int8", + "int16_t": "int16", + "int32_t": "int32", + "int64_t": "int64", - "intptr_t": "ptr int", + "intptr_t": "ptr int", - "Int8": "int8", - "Int16": "int16", - "Int32": "int32", - "Int64": "int64", + "Int8": "int8", + "Int16": "int16", + "Int32": "int32", + "Int64": "int64", - "uint8_t": "uint8", - "uint16_t": "uint16", - "uint32_t": "uint32", - "uint64_t": "uint64", + "uint8_t": "uint8", + "uint16_t": "uint16", + "uint32_t": "uint32", + "uint64_t": "uint64", - "uintptr_t": "ptr uint", + "uintptr_t": "ptr uint", - "Uint8": "uint8", - "Uint16": "uint16", - "Uint32": "uint32", - "Uint64": "uint64", + "Uint8": "uint8", + "Uint16": "uint16", + "Uint32": "uint32", + "Uint64": "uint64", - # long - "long": "clong", - "long int": "clong", - "signed long": "clong", - "signed long int": "clong", - "off_t": "clong", - "unsigned long": "culong", - "unsigned long int": "culong", - "uLong": "culong", - "u_long": "culong", + # long + "long": "clong", + "long int": "clong", + "signed long": "clong", + "signed long int": "clong", + "off_t": "clong", + "unsigned long": "culong", + "unsigned long int": "culong", + "uLong": "culong", + "u_long": "culong", - # long long - "long long": "clonglong", - "long long int": "clonglong", - "signed long long": "clonglong", - "signed long long int": "clonglong", - "off64_t": "clonglong", - "unsigned long long": "culonglong", - "unsigned long long int": "culonglong", + # long long + "long long": "clonglong", + "long long int": "clonglong", + "signed long long": "clonglong", + "signed long long int": "clonglong", + "off64_t": "clonglong", + "unsigned long long": "culonglong", + "unsigned long long int": "culonglong", - # floating point - "float": "cfloat", - "double": "cdouble", - "long double": "clongdouble" -}.toTable() + # floating point + "float": "cfloat", + "double": "cdouble", + "long double": "clongdouble" + }.toTable() + + # Nim type names that shouldn't need to be wrapped again + gTypeMapValues* = toSeq(gTypeMap.values).toHashSet() proc getType*(str: string): string = if str == "void": diff --git a/tests/getheader.nims b/tests/getheader.nims index 1e8027a..987545a 100644 --- a/tests/getheader.nims +++ b/tests/getheader.nims @@ -14,7 +14,7 @@ proc testCall(cmd, output: string, exitCode: int, delete = true) = doAssert outp.contains(output), outp var - cmd = "nim c -f --hints:off" + cmd = "nim c -f --hints:off -d:FLAGS=\"-f:ast2\"" lrcmd = " -r lzma.nim" zrcmd = " -r zlib.nim" lexp = "liblzma version = " diff --git a/tests/lzma.nim b/tests/lzma.nim index f30b974..cff39de 100644 --- a/tests/lzma.nim +++ b/tests/lzma.nim @@ -3,8 +3,10 @@ import os, strutils import nimterop/[build, cimport] const + FLAGS {.strdefine.} = "" + baseDir = getProjectCacheDir("nimterop" / "tests" / "liblzma") - flags = "--prefix=___,__,_ --suffix=__,_" + tflags = "--prefix=___,__,_ --suffix=__,_ " & FLAGS static: cSkipSymbol(@[ @@ -38,8 +40,8 @@ cOverride: lzma_index_iter = object when not lzmaStatic: - cImport(lzmaPath, recurse = true, dynlib = "lzmaLPath", flags = flags) + cImport(lzmaPath, recurse = true, dynlib = "lzmaLPath", flags = tflags) else: - cImport(lzmaPath, recurse = true, flags = flags) + cImport(lzmaPath, recurse = true, flags = tflags) echo "liblzma version = " & $lzma_version_string() diff --git a/tests/tsoloud.nim b/tests/tsoloud.nim index 8dd197c..4d9a28b 100644 --- a/tests/tsoloud.nim +++ b/tests/tsoloud.nim @@ -1,6 +1,8 @@ import os, nimterop/[cimport, build] const + FLAGS {.strdefine.} = "" + baseDir = getProjectCacheDir("nimterop" / "tests" / "soloud") incl = baseDir/"include" src = baseDir/"src" @@ -42,7 +44,6 @@ cCompile(src/"audiosource", "cpp", exclude="ay/") cCompile(src/"audiosource", "c") cCompile(src/"filter/*.cpp") -const FLAGS {.strdefine.} = "" cImport(incl/"soloud_c.h", flags = FLAGS) var diff --git a/tests/zlib.nim b/tests/zlib.nim index febc6b1..852dca9 100644 --- a/tests/zlib.nim +++ b/tests/zlib.nim @@ -3,6 +3,8 @@ import os, strutils import nimterop/[build, cimport] const + FLAGS {.strdefine.} = "" + baseDir = getProjectCacheDir("nimterop" / "tests" / "zlib") proc zlibPreBuild(outdir, path: string) = @@ -64,8 +66,8 @@ when zlibGit or zlibDL: cIncludeDir(baseDir / "buildcache") when not zlibStatic: - cImport(zlibPath, recurse = true, dynlib = "zlibLPath") + cImport(zlibPath, recurse = true, dynlib = "zlibLPath", flags = FLAGS) else: - cImport(zlibPath, recurse = true) + cImport(zlibPath, recurse = true, flags = FLAGS) echo "zlib version = " & $zlibVersion() From 370f64d4e799f5441ffc7b5cb0f3b012c09a13db Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Fri, 1 May 2020 17:51:57 -0500 Subject: [PATCH 436/593] Fix for zlib --- nimterop/getters.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimterop/getters.nim b/nimterop/getters.nim index d94fae8..620c1ec 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -565,7 +565,7 @@ proc getPreprocessor*(gState: State, fullpath: string): string = else: cmd &= "-D__attribute__(x)= " - cmd &= "-D__restrict= " + cmd &= "-D__restrict= -D__extension__= " cmd &= &"{fullpath.sanitizePath}" From ad240abdecd50ee3f8836624f403aaa0f0ded230 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Sat, 2 May 2020 23:48:20 -0500 Subject: [PATCH 437/593] Update README based on feedback --- README.md | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 53b37e7..6fbc040 100644 --- a/README.md +++ b/README.md @@ -2,15 +2,13 @@ [![Build status](https://ci.appveyor.com/api/projects/status/hol1yvqbp6hq4ao8/branch/master?svg=true)](https://ci.appveyor.com/project/genotrance/nimterop-8jcj7/branch/master) [![Build Status](https://travis-ci.org/nimterop/nimterop.svg?branch=master)](https://travis-ci.org/nimterop/nimterop) -Detailed documentation [here](https://nimterop.github.io/nimterop/theindex.html). - Nimterop is a [Nim](https://nim-lang.org/) package that aims to make C/C++ interop seamless -Most of the wrapping functionality is contained within the `toast` binary that is built when nimterop is installed and can be used standalone similar to how `c2nim` can be used today. In addition, nimterop also offers an API to pull in the generated Nim content directly into an application and other nimgen functionality that helps in automating the wrapping process. There is also support to statically or dynamically link to system installed libraries or downloading and building them with `autoconf` or `cmake` from a Git repo or source archive. +Most of the wrapping functionality is contained within the `toast` binary that is built when nimterop is installed and can be used standalone similar to how `c2nim` can be used today. In addition, nimterop also offers an API to pull in the generated Nim content directly into an application and other functionality that helps in automating the wrapping process. There is also support to statically or dynamically link to system installed libraries or downloading and building them with `autoconf` or `cmake` from a Git repo or source archive. The nimterop wrapping functionality is still limited to C but is constantly expanding. C++ support will be added once most popular C libraries can be wrapped seamlessly. Meanwhile, `c2nim` can also be used in place of `toast` with the `c2nImport()` API call. -Nimterop has seen some adoption within the community and the simplicity and success of this approach justifies additional investment of time and effort. Regardless, the goal is to make interop seamless so nimterop will focus on wrapping headers and not the outright conversion of C/C++ implementation. +The goal is to make interop seamless so nimterop will focus on wrapping headers and not the outright conversion of C/C++ implementation. ## Installation @@ -23,18 +21,22 @@ or: ```bash git clone http://github.com/nimterop/nimterop && cd nimterop nimble develop -y -nimble build +nimble build -d:danger ``` This will download and install nimterop in the standard Nimble package location, typically `~/.nimble`. Once installed, it can be imported into any Nim program. ## Usage -Detailed documentation can be found [here](https://nimterop.github.io/nimterop/theindex.html). Also, check out the [wiki](https://github.com/nimterop/nimterop/wiki/Wrappers) for a list of all known wrappers that have been created using nimterop. They will provide real world examples of how to wrap libraries. Please do add your project once you are done so that others can benefit from your work. +Nimterop can be used in two ways: +- Creating a wrapper file - a `.nim` file that contains calls to the high-level API that can download and build the C library as well as generate the required Nim code to interface with the library. This wrapper file can then be imported into Nim code like any other module and it will be processed at compile time. +- Using the command line `toast` tool to generate the Nim code which can then be stored into a file and imported separately. + +Any combination of the above is possible - only download, build or wrapping and nimterop avoids imposing any particular workflow. ### Build API -Creating a wrapper has two parts, the first is to setup the C library. This includes downloading it or finding it if already installed, and building it if applicable. The `getHeader()` high-level API provides all of this functionality as a convenience. Following is an example of using the high-level `getHeader()` API to perform all building and linking automatically: +Creating a wrapper has two parts, the first is to setup the C library. This includes downloading it or finding it if already installed, and building it if applicable. The `getHeader()` high-level API provides all of this functionality as a convenience. The following `.nim` wrapper file is an example of using the high-level `getHeader()` API to perform all building, wrapping and linking automatically: ```nim import nimterop/[build, cimport] @@ -63,9 +65,11 @@ else: cImport(headerPath, recurse = true) ``` +Module documentation for the build API can be found [here](https://nimterop.github.io/nimterop/build.html). Refer to the ```tests``` directory for additional examples on how the library can be used. Also, check out the [wiki](https://github.com/nimterop/nimterop/wiki/Wrappers) for a list of all known wrappers that have been created using nimterop. They will provide real world examples of how to wrap libraries. Please do add your project once you are done so that others can benefit from your work. + __Download / Search__ -The above wrapper is generic and allows the end user to control how it works. +The above wrapper is generic and allows the end user to control how it works. Note that `headerPath` is derived from `header.h` so if you have `SDL.h` as the argument to `getHeader()`, it generates `SDLPath` and `SDLLPath` and is controlled by `-d:SDLStatic`, `-d:SDLGit` and so forth. - If the library is already installed in `/usr/include` then the `-d:headerStd` define to Nim can be used to instruct `getHeader()` to search for `header.h` in the standard system path. - If the library needs to be downloaded, the user can use `-d:headerGit` to clone the source from the specified git URL or `-d:headerDL` to get the source from download URL. @@ -105,7 +109,7 @@ If more fine-tuned control is desired over the build process, it is possible to ### Wrapper API -Once the C library is setup, the next step is to create wrappers that inform Nim of all the types and functions that are available. Following is a simple example covering the API: +Once the C library is setup, the next step is to generate code that inform Nim of all the types and functions that are available. Following is a simple example covering the API: ```nim import nimterop/cimport @@ -124,7 +128,7 @@ cImport("clib.h") # Generate wrappers for header specified cCompile("clib/src/*.c") # Compile in any implementation source files ``` -Refer to the ```tests``` directory for additional examples on how the library can be used. The [wiki](https://github.com/nimterop/nimterop/wiki/Wrappers) is also a good source of examples. +Module documentation for the wrapper API can be found [here](https://nimterop.github.io/nimterop/cimport.html). __Preprocessing__ @@ -152,6 +156,10 @@ __Compiling source__ The job of building and compiling the underlying C library is best left to the build mechanism selected by the library author so using `getHeader()` is recommended. For simpler projects with a few `.c` files though, `cCompile()` should be more than enough. It is not recommended for larger projects which heavily rely on functionality offered by build tools. Recreating reliable logic in Nim can be tedious and one can expect minimal support from that author if their tested build mechanism is not used. +### Docs API + +Nimterop also provides a [docs](https://nimterop.github.io/nimterop/docs.html) API which can be used to generate documentation from the generated wrappers. This can be added as a task in the `.nimble` or `.nims` file for convenience. See [nimarchive.nimble](https://github.com/genotrance/nimarchive/blob/master/nimarchive.nimble) for an example. + ### Command line API The `toast` binary can also be used directly on the CLI, similar to `c2nim`. The `cPlugin()` interface From 35b0b5eff7ea789afd4bde56344ffdaa75ce31b3 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 4 May 2020 12:01:05 -0500 Subject: [PATCH 438/593] Add change log --- CHANGES.md | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 CHANGES.md diff --git a/CHANGES.md b/CHANGES.md new file mode 100644 index 0000000..b02453c --- /dev/null +++ b/CHANGES.md @@ -0,0 +1,80 @@ +# Nimterop Change History + +## Version 0.5.0 + +This release introduces a new backend for wrapper generation dubbed `ast2` that leverages the Nim compiler AST and renderer. The new design simplifies feature development and already includes all the functionality of the legacy algorithm plus fixes for several open issues. + +The new backend can be leveraged with the `-f:ast2` flag to `toast` or `flags = "-f:ast2"` to `cImport()`. The legacy algorithm will be the default backend for this release but no new functionality or bugfixes are expected going forward. Usage of the legacy algorithm will display a *deprecated* hint to encourage users to test their wrappers with `-f:ast2` and remove any overrides that the new algorithm supports. + +Version 0.6.0 of Nimterop will make `ast2` the default backend and the legacy algorithm will be removed altogether. + +See the full list of changes here: + +https://github.com/nimterop/nimterop/compare/v0.4.4...v0.5.0 + +### Breaking changes + +- Nimterop now skips generating the `{.header.}` pragma by default in non-dynlib mode. This skips the header file `#include` in the generated code and allows creation of wrappers that do not require presence of the header during compile time. There are cases where this will not work so the `--includeHeader | -H` flag is available to revert to the legacy behavior when required. This change applies to both `ast2` and the legacy backend so if an existing wrapper breaks, test it with `-H` to see if it starts working again. [#169][i169] + +- Nimterop defaulted to C++ mode for preprocessing and tree-sitter parsing in all cases unless explicitly informed to use C mode. This has been changed and is now detected based on the file extension. This means some existing wrappers could break since they might contain C++ code or include C++ headers like `#include ` which will not work in C mode. Explicitly setting `mode = "cpp"` or `-mcpp` should fix such issues. [#176][i176] + +- Enums were originally being mapped to `distint int` - this has been changed to `distinct cint` since the sizes are incorrect on 64-bit and is especially noticeable when types or unions have enum fields. + +- `static inline` functions are no longer wrapped by the legacy backend. The `ast2` backend correctly generates wrappers for such functions but they are only generated when `--includeHeader | -H` is in effect. This is because such functions do not exist in the binary and can only be referenced when the header is compiled in. + +- Support for Nim v0.19.6 has been dropped and the test matrix now covers v0.20.2, v1.0.6, v1.2.0 and devel. + +### New functionality + +- `ast2` includes support for various C constructs that were issues with the legacy backend. These changes should reduce the reliance on `cOverride()` and existing wrappers should attempt to clean up such sections where possible. + - N-dimensional arrays and pointers - [#54][i54] + - Synomyms for types - [#74][i74] + - Varargs support - [#76][i76] + - Nested structs, unions and enums - [#137][i137] [#147][i147] + - Forward declarations of types - [#148][i148] + - Nested function pointers - [#155][i155] [#156][i156] + - Various enum fixes - [#159][i159] [#171][i171] + - Map `int arr[]` to `arr: UncheckedArray[cint]` - [#174][i174] + +- `ast2` also includes an advanced expression parser that can reliably handle constructs typically seen with `#define` statements and enumeration values: + - Integers + integer like expressions (hex, octal, suffixes) + - Floating point expressions + - Strings and character literals, including C's escape characters + - Math operators `+ - / *` + - Some Unary operators `- ! ~` + - Any identifiers + - C type descriptors `int char` etc + - Boolean values `true false` + - Shift, cast, math or sizeof expressions + - Most type coercions + +- Wrappers can now point to an external plugin file with `cPluginPath()` instead of having to declaring plugins inline with `cPlugin()`. This allows multiple wrappers to share the same plugin. [#181][i181] + +- `cImport()` adds support for importing multiple headers in a single call - this enables support for libraries that have many header files that include shared headers and typically cannot be imported in multiple `cImport()` calls since it results in duplicate symbols. Calling `toast` with multiple headers uses the same algorithm. + +- `ast2` now creates Nim doc comments instead of reqular comments which get rendered when the wrapper is run through `nim doc` or the `buildDocs()` API. [#197][i197] + +- `toast` now includes `--replace | -G` to manipulate identifier names beyond `--prefix` and `--suffix`. `-G:X=Y` replaces X with Y and `-G:@_[_]+=_` replaces multiple `_` with a single instance using the `@` prefix to enable regular expressions. + +- Nimterop is now able to detect Nim configuration of projects and can better handle cases where defaults such as `nimcacheDir` or `nimblePath` are overridden. This especially enables better interop with workflows that do not depend on Nimble. [#151][i151] [#153][i153] + +- Nimterop defaults to `cmake`, followed by `autoconf` for building libraries with `getHeader()`. It is now possible to change the order of discovery with the `buildType` value. [#200][i200] + +[i54]: https://github.com/nimterop/nimterop/issues/54 +[i74]: https://github.com/nimterop/nimterop/issues/74 +[i76]: https://github.com/nimterop/nimterop/issues/76 +[i137]: https://github.com/nimterop/nimterop/issues/137 +[i147]: https://github.com/nimterop/nimterop/issues/147 +[i148]: https://github.com/nimterop/nimterop/issues/148 +[i151]: https://github.com/nimterop/nimterop/issues/151 +[i153]: https://github.com/nimterop/nimterop/issues/153 +[i155]: https://github.com/nimterop/nimterop/issues/155 +[i156]: https://github.com/nimterop/nimterop/issues/156 +[i159]: https://github.com/nimterop/nimterop/issues/159 +[i169]: https://github.com/nimterop/nimterop/issues/169 +[i171]: https://github.com/nimterop/nimterop/issues/171 +[i174]: https://github.com/nimterop/nimterop/issues/174 +[i176]: https://github.com/nimterop/nimterop/issues/176 +[i181]: https://github.com/nimterop/nimterop/issues/181 +[i197]: https://github.com/nimterop/nimterop/issues/197 +[i200]: https://github.com/nimterop/nimterop/issues/200 \ No newline at end of file From 6cfe59debce37dccf1a118f83f3b15050bcbab09 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 4 May 2020 15:48:34 -0500 Subject: [PATCH 439/593] Update README with changelog, credits --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 6fbc040..8680048 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,8 @@ Nimterop can be used in two ways: Any combination of the above is possible - only download, build or wrapping and nimterop avoids imposing any particular workflow. +Refer to [CHANGES.md](CHANGES.md) for history and information around breaking changes. + ### Build API Creating a wrapper has two parts, the first is to setup the C library. This includes downloading it or finding it if already installed, and building it if applicable. The `getHeader()` high-level API provides all of this functionality as a convenience. The following `.nim` wrapper file is an example of using the high-level `getHeader()` API to perform all building, wrapping and linking automatically: @@ -224,6 +226,8 @@ This is part of the reason why Nimterop provides a wrapper API so that the gener Nimterop depends on [tree-sitter](http://tree-sitter.github.io/tree-sitter/) and all licensing terms of [tree-sitter](https://github.com/tree-sitter/tree-sitter/blob/master/LICENSE) apply to the usage of this package. The tree-sitter functionality is pulled and wrapped using nimterop itself. +Thank you to all the [contributors](https://github.com/nimterop/nimterop/graphs/contributors), issue submitters, various people in [#nim](irc://freenode.net/nim) and users for helping improve Nimterop over the years. + ## Feedback Nimterop is a work in progress and any feedback or suggestions are welcome. It is hosted on [GitHub](https://github.com/nimterop/nimterop) with an MIT license so issues, forks and PRs are most appreciated. From 0bf2021fd47f0c5ed53219dccfff1ad0d3a13650 Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Sat, 2 May 2020 12:36:55 -0600 Subject: [PATCH 440/593] Make getHeader specify which make strategy to use Fix make call Add comment --- nimterop/build.nim | 103 +++++++++++++++++++++++++++------------------ 1 file changed, 61 insertions(+), 42 deletions(-) diff --git a/nimterop/build.nim b/nimterop/build.nim index 6fa44cb..fe8f31a 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -4,6 +4,15 @@ import os except findExe, sleep import regex +type + MakeType* = enum + mtConfMake, mtCMake + + BuildStatus = object + built: bool + buildPath: string + error: string + # build specific debug since we cannot import globals (yet) var gDebug* = false @@ -771,20 +780,7 @@ proc getNumProcs(): string = else: "1" -proc buildLibrary(lname, outdir, conFlags, cmakeFlags, makeFlags: string): string = - var - conDeps = false - conDepStr = "" - cmakeDeps = false - cmakeDepStr = "" - lpath = findFile(lname, outdir, regex = true) - makeFlagsProc = &"-j {getNumProcs()} {makeFlags}" - made = false - makePath = outdir - - if lpath.len != 0: - return lpath - +proc buildWithCmake(outdir, flags: string): BuildStatus = if not fileExists(outdir / "Makefile"): if fileExists(outdir / "CMakeLists.txt"): if findExe("cmake").len != 0: @@ -806,36 +802,59 @@ proc buildLibrary(lname, outdir, conFlags, cmakeFlags, makeFlags: string): strin gen = "Unix Makefiles".quoteShell if findExe("ccache").len != 0: gen &= " -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache" - makePath = outdir / "buildcache" - cmake(makePath, "Makefile", &".. -G {gen} {cmakeFlags}") - cmakeDeps = true + result.buildPath = outdir / "buildcache" + cmake(result.buildPath, "Makefile", &".. -G {gen} {flags}") + result.built = true else: - cmakeDepStr &= "cmake executable missing" + result.error = "cmake capable but cmake executable missing" + else: + result.buildPath = outdir - if not cmakeDeps: - if findExe("bash").len != 0: - for file in @["configure", "configure.ac", "configure.in", "autogen.sh", "build/autogen.sh"]: - if fileExists(outdir / file): - configure(outdir, "Makefile", conFlags) - conDeps = true - - break - else: - conDepStr &= "bash executable missing" - - if fileExists(makePath / "Makefile"): - make(makePath, lname, makeFlagsProc, regex = true) - made = true +proc buildWithConfMake(outdir, flags: string): BuildStatus = + if not fileExists(outdir / "Makefile"): + if findExe("bash").len != 0: + for file in @["configure", "configure.ac", "configure.in", "autogen.sh", "build/autogen.sh"]: + if fileExists(outdir / file): + configure(outdir, "Makefile", flags) + result.buildPath = outdir + result.built = true + break + else: + result.error = "configure capable but bash executable missing" + else: + result.buildPath = outdir +proc buildLibrary(lname, outdir, conFlags, cmakeFlags, makeFlags: string, preferredMakeType: MakeType): string = var - error = "" - if not cmakeDeps and cmakeDepStr.len != 0: - error &= &"cmake capable but {cmakeDepStr}\n" - if not conDeps and conDepStr.len != 0: - error &= &"configure capable but {conDepStr}\n" - if error.len == 0: - error = "No build files found in " & outdir - doAssert cmakeDeps or conDeps or made, &"\n# Build configuration failed - {error}\n" + lpath = findFile(lname, outdir, regex = true) + makeFlagsProc = &"-j {getNumProcs()} {makeFlags}" + makePath = outdir + + if lpath.len != 0: + return lpath + + var buildStatus: BuildStatus + + # Simply reverse order if we want configure/make vs CMake/make + case preferredMakeType + of mtCMake: + buildStatus = buildWithCmake(makePath, cmakeFlags) + if not buildStatus.built: + buildStatus = buildWithConfMake(makePath, conFlags) + of mtConfMake: + buildStatus = buildWithConfMake(makePath, conFlags) + if not buildStatus.built: + buildStatus = buildWithCmake(makePath, cmakeFlags) + + if buildStatus.buildPath.len > 0: + buildStatus.built = findFile(lname, buildStatus.buildPath, regex = true).len > 0 + + if not buildStatus.built and fileExists(buildStatus.buildPath / "Makefile"): + make(buildStatus.buildPath, lname, makeFlagsProc, regex = true) + buildStatus.built = true + + let error = if buildStatus.error.len > 0: buildStatus.error else: "No build files found in " & outdir + doAssert buildStatus.built, &"\n# Build configuration failed - {error}\n" result = findFile(lname, outdir, regex = true) @@ -903,7 +922,7 @@ macro isDefined*(def: untyped): untyped = macro getHeader*(header: static[string], giturl: static[string] = "", dlurl: static[string] = "", outdir: static[string] = "", conFlags: static[string] = "", cmakeFlags: static[string] = "", makeFlags: static[string] = "", - altNames: static[string] = ""): untyped = + altNames: static[string] = "", preferredMakeType: static[MakeType] = mtCMake): untyped = ## Get the path to a header file for wrapping with ## `cImport() `_ or ## `c2nImport() `_. @@ -1056,7 +1075,7 @@ macro getHeader*(header: static[string], giturl: static[string] = "", dlurl: sta when stdPath.len != 0 and stdLPath.len != 0: stdLPath else: - buildLibrary(`lname`, `outdir`, `conFlags`, `cmakeFlags`, `makeFlags`) + buildLibrary(`lname`, `outdir`, `conFlags`, `cmakeFlags`, `makeFlags`, `preferredMakeType`.MakeType) # Header path - search again in case header is generated in build `path`* = From 4156a1effa38310f86efcbe140543e7df690ef82 Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Sat, 2 May 2020 21:14:19 -0600 Subject: [PATCH 441/593] Address PR issues --- nimterop/build.nim | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/nimterop/build.nim b/nimterop/build.nim index fe8f31a..882a3d3 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -5,8 +5,8 @@ import os except findExe, sleep import regex type - MakeType* = enum - mtConfMake, mtCMake + BuildType* = enum + btAutoconf, btCmake BuildStatus = object built: bool @@ -824,7 +824,7 @@ proc buildWithConfMake(outdir, flags: string): BuildStatus = else: result.buildPath = outdir -proc buildLibrary(lname, outdir, conFlags, cmakeFlags, makeFlags: string, preferredMakeType: MakeType): string = +proc buildLibrary(lname, outdir, conFlags, cmakeFlags, makeFlags: string, buildType: BuildType): string = var lpath = findFile(lname, outdir, regex = true) makeFlagsProc = &"-j {getNumProcs()} {makeFlags}" @@ -836,20 +836,20 @@ proc buildLibrary(lname, outdir, conFlags, cmakeFlags, makeFlags: string, prefer var buildStatus: BuildStatus # Simply reverse order if we want configure/make vs CMake/make - case preferredMakeType - of mtCMake: + case buildType + of btCmake: buildStatus = buildWithCmake(makePath, cmakeFlags) if not buildStatus.built: buildStatus = buildWithConfMake(makePath, conFlags) - of mtConfMake: + of btAutoconf: buildStatus = buildWithConfMake(makePath, conFlags) if not buildStatus.built: buildStatus = buildWithCmake(makePath, cmakeFlags) if buildStatus.buildPath.len > 0: - buildStatus.built = findFile(lname, buildStatus.buildPath, regex = true).len > 0 + let libraryExists = findFile(lname, buildStatus.buildPath, regex = true).len > 0 - if not buildStatus.built and fileExists(buildStatus.buildPath / "Makefile"): + if not libraryExists and fileExists(buildStatus.buildPath / "Makefile"): make(buildStatus.buildPath, lname, makeFlagsProc, regex = true) buildStatus.built = true @@ -922,7 +922,7 @@ macro isDefined*(def: untyped): untyped = macro getHeader*(header: static[string], giturl: static[string] = "", dlurl: static[string] = "", outdir: static[string] = "", conFlags: static[string] = "", cmakeFlags: static[string] = "", makeFlags: static[string] = "", - altNames: static[string] = "", preferredMakeType: static[MakeType] = mtCMake): untyped = + altNames: static[string] = "", buildType: static[BuildType] = btCmake): untyped = ## Get the path to a header file for wrapping with ## `cImport() `_ or ## `c2nImport() `_. @@ -1075,7 +1075,7 @@ macro getHeader*(header: static[string], giturl: static[string] = "", dlurl: sta when stdPath.len != 0 and stdLPath.len != 0: stdLPath else: - buildLibrary(`lname`, `outdir`, `conFlags`, `cmakeFlags`, `makeFlags`, `preferredMakeType`.MakeType) + buildLibrary(`lname`, `outdir`, `conFlags`, `cmakeFlags`, `makeFlags`, `buildType`.BuildType) # Header path - search again in case header is generated in build `path`* = From 742fc3d96a00b4a7e90eaac26c63d68fc647cd23 Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Mon, 4 May 2020 09:03:04 -0600 Subject: [PATCH 442/593] Add more maintainable build types Add buildTypes to docs --- nimterop/build.nim | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/nimterop/build.nim b/nimterop/build.nim index 882a3d3..ece2e33 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -810,7 +810,7 @@ proc buildWithCmake(outdir, flags: string): BuildStatus = else: result.buildPath = outdir -proc buildWithConfMake(outdir, flags: string): BuildStatus = +proc buildWithAutoConf(outdir, flags: string): BuildStatus = if not fileExists(outdir / "Makefile"): if findExe("bash").len != 0: for file in @["configure", "configure.ac", "configure.in", "autogen.sh", "build/autogen.sh"]: @@ -824,7 +824,7 @@ proc buildWithConfMake(outdir, flags: string): BuildStatus = else: result.buildPath = outdir -proc buildLibrary(lname, outdir, conFlags, cmakeFlags, makeFlags: string, buildType: BuildType): string = +proc buildLibrary(lname, outdir, conFlags, cmakeFlags, makeFlags: string, buildTypes: openArray[BuildType]): string = var lpath = findFile(lname, outdir, regex = true) makeFlagsProc = &"-j {getNumProcs()} {makeFlags}" @@ -835,16 +835,15 @@ proc buildLibrary(lname, outdir, conFlags, cmakeFlags, makeFlags: string, buildT var buildStatus: BuildStatus - # Simply reverse order if we want configure/make vs CMake/make - case buildType - of btCmake: - buildStatus = buildWithCmake(makePath, cmakeFlags) - if not buildStatus.built: - buildStatus = buildWithConfMake(makePath, conFlags) - of btAutoconf: - buildStatus = buildWithConfMake(makePath, conFlags) - if not buildStatus.built: + for buildType in buildTypes: + case buildType + of btCmake: buildStatus = buildWithCmake(makePath, cmakeFlags) + of btAutoconf: + buildStatus = buildWithAutoConf(makePath, conFlags) + + if buildStatus.built: + break if buildStatus.buildPath.len > 0: let libraryExists = findFile(lname, buildStatus.buildPath, regex = true).len > 0 @@ -922,7 +921,7 @@ macro isDefined*(def: untyped): untyped = macro getHeader*(header: static[string], giturl: static[string] = "", dlurl: static[string] = "", outdir: static[string] = "", conFlags: static[string] = "", cmakeFlags: static[string] = "", makeFlags: static[string] = "", - altNames: static[string] = "", buildType: static[BuildType] = btCmake): untyped = + altNames: static[string] = "", buildTypes: static[openArray[BuildType]] = [btCmake, btAutoconf]): untyped = ## Get the path to a header file for wrapping with ## `cImport() `_ or ## `c2nImport() `_. @@ -965,6 +964,9 @@ macro getHeader*(header: static[string], giturl: static[string] = "", dlurl: sta ## with cmake. In this case, `altNames = "z,zlib"`. Comma separate for multiple alternate names without ## spaces. ## + ## `buildTypes` specifies a list of in order build strategies to use when building the downloaded source + ## files. Default is [btCmake, btAutoconf] + ## ## The original header name is not included by default if `altNames` is set since it could cause the ## wrong lib to be selected. E.g. `SDL2/SDL.h` could pick `libSDL.so` even if `altNames = "SDL2"`. ## Explicitly include it in `altNames` like the `zlib` example when required. @@ -1075,7 +1077,7 @@ macro getHeader*(header: static[string], giturl: static[string] = "", dlurl: sta when stdPath.len != 0 and stdLPath.len != 0: stdLPath else: - buildLibrary(`lname`, `outdir`, `conFlags`, `cmakeFlags`, `makeFlags`, `buildType`.BuildType) + buildLibrary(`lname`, `outdir`, `conFlags`, `cmakeFlags`, `makeFlags`, `buildTypes`) # Header path - search again in case header is generated in build `path`* = From dc1c4bc1779e5e4bce50f566103648673e16aba8 Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Fri, 24 Apr 2020 20:42:30 -0600 Subject: [PATCH 443/593] Add comments for enums and procs --- nimterop/ast2.nim | 36 +++++++++++++++++++++++++----------- nimterop/getters.nim | 21 ++++++++++++++++++++- 2 files changed, 45 insertions(+), 12 deletions(-) diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index 4d609cb..17fe216 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -1393,14 +1393,18 @@ proc addEnum(gState: State, node: TSNode) = fnames: HashSet[string] # Hold all of field information so that we can add all of them # after the const identifiers has been updated - fieldDeclarations: seq[tuple[fname: string, fval: string, cexpr: Option[TSNode]]] + fieldDeclarations: seq[tuple[fname: string, fval: string, cexpr: Option[TSNode], comment: Option[TSNode]]] for i in 0 .. enumlist.len - 1: let en = enumlist[i] if en.getName() == "comment": continue + let - fname = gState.getIdentifier(gState.getNodeVal(en.getAtom()), nskEnumField) + atom = en.getAtom() + commentNode = en.getInlineCommentNode() + fname = gState.getIdentifier(gState.getNodeVal(atom), nskEnumField) + if fname.nBl and gState.addNewIdentifer(fname): var fval = "" @@ -1412,9 +1416,9 @@ proc addEnum(gState: State, node: TSNode) = fval = &"({prev} + 1).{name}" if en.len > 1 and en[1].getName() in gEnumVals: - fieldDeclarations.add((fname, "", some(en[1]))) + fieldDeclarations.add((fname, "", some(en[1]), commentNode)) else: - fieldDeclarations.add((fname, fval, none(TSNode))) + fieldDeclarations.add((fname, fval, none(TSNode), commentNode)) fnames.incl fname prev = fname @@ -1424,18 +1428,20 @@ proc addEnum(gState: State, node: TSNode) = gState.constIdentifiers.incl fnames # parseCExpression requires all const identifiers to be present for the enum - for (fname, fval, cexprNode) in fieldDeclarations: + for (fname, fval, cexprNode, commentNode) in fieldDeclarations: var fval = fval if cexprNode.isSome: fval = "(" & $gState.parseCExpression(gState.getNodeVal(cexprNode.get()), name) & ")." & name # Cannot use newConstDef() since parseString(fval) adds backticks to and/or - gState.constSection.add gState.parseString(&"const {fname}* = {fval}")[0][0] + let constNode = gState.parseString(&"const {fname}* = {fval}")[0][0] + constNode.comment = gState.getCommentVal(commentNode) + gState.constSection.add constNode # Add other names if node.getName() == "type_definition" and node.len > 1: gState.addTypeTyped(node, ftname = name, offset = offset) -proc addProcVar(gState: State, node, rnode: TSNode) = +proc addProcVar(gState: State, node, rnode: TSNode, commentNode: Option[TSNode]) = # Add a proc variable decho("addProcVar()") let @@ -1488,12 +1494,13 @@ proc addProcVar(gState: State, node, rnode: TSNode) = # nkEmpty() # ) + identDefs.comment = gState.getCommentVal(commentNode) # nkVarSection.add gState.varSection.add identDefs gState.printDebug(identDefs) -proc addProc(gState: State, node, rnode: TSNode) = +proc addProc(gState: State, node, rnode: TSNode, commentNode: Option[TSNode]) = # Add a proc # # `node` is the `nth` child of (declaration) @@ -1599,6 +1606,8 @@ proc addProc(gState: State, node, rnode: TSNode) = procDef.add newNode(nkEmpty) procDef.add newNode(nkEmpty) + procDef.comment = gState.getCommentVal(commentNode) + # nkProcSection.add gState.procSection.add procDef @@ -1609,18 +1618,20 @@ proc addDecl(gState: State, node: TSNode) = decho("addDecl()") gState.printDebug(node) + let start = getStartAtom(node) + commentNode = node.getCommentNode() for i in start+1 ..< node.len: if not node[i].firstChildInTree("function_declarator").isNil: # Proc declaration - var or actual proc if node[i].getAtom().getPxName(1) == "pointer_declarator": # proc var - gState.addProcVar(node[i], node[start]) + gState.addProcVar(node[i], node[start], commentNode) else: # proc - gState.addProc(node[i], node[start]) + gState.addProc(node[i], node[start], commentNode) else: # Regular var discard @@ -1632,11 +1643,14 @@ proc addDef(gState: State, node: TSNode) = # and will fail at link time decho("addDef()") gState.printDebug(node) + let start = getStartAtom(node) + commentNode = node.getCommentNode() + if node[start+1].getName() == "function_declarator": if gState.isIncludeHeader(): - gState.addProc(node[start+1], node[start]) + gState.addProc(node[start+1], node[start], commentNode) else: gecho &"\n# proc '$1' skipped - static inline procs require 'includeHeader'" % gState.getNodeVal(node[start+1].getAtom()) diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 620c1ec..d03e65b 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -1,4 +1,4 @@ -import dynlib, macros, os, sequtils, sets, strformat, strutils, tables, times +import dynlib, macros, os, sequtils, sets, strformat, strutils, tables, times, options import regex @@ -456,6 +456,9 @@ proc printLisp*(gState: State, root: TSNode): string = proc getCommented*(str: string): string = "\n# " & str.strip().replace("\n", "\n# ") +proc getDocStrCommented*(str: string): string = + "\n## " & str.strip().replace("\n", "\n## ") + proc printTree*(gState: State, pnode: PNode, offset = ""): string = if not pnode.isNil and gState.debug and pnode.kind != nkNone: result &= "\n# " & offset & $pnode.kind & "(" @@ -634,6 +637,22 @@ proc getNameKind*(name: string): tuple[name: string, kind: Kind, recursive: bool if result.kind != exactlyOne: result.name = result.name[0 .. ^2] +proc getCommentVal*(gState: State, commentNode: Option[TSNode]): string = + if commentNode.isSome(): + result = gState.getNodeVal(commentNode.get()).replace(re"( *(/\*\*|\*\*/|\*/|\*))", "").strip() + +proc getCommentNode*(node: TSNode): Option[TSNode] = + result = none(TSNode) + let prevSibling = node.tsNodePrevNamedSibling() + if not prevSibling.isNil and prevSibling.getName() == "comment": + result = some(prevSibling) + +proc getInlineCommentNode*(node: TSNode): Option[TSNode] = + result = none(TSNode) + let nextSibling = node.tsNodeNextNamedSibling() + if not nextSibling.isNil and nextSibling.getName() == "comment": + result = some(nextSibling) + proc getTSNodeNamedChildNames*(node: TSNode): seq[string] = if node.tsNodeNamedChildCount() != 0: for i in 0 .. node.tsNodeNamedChildCount()-1: From 5a4432bb683bc23909e575a28b1bce35b826a0ab Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Fri, 24 Apr 2020 22:50:14 -0600 Subject: [PATCH 444/593] Add comments for fields and objects --- nimterop/ast2.nim | 26 ++++++++++++++++++++++---- nimterop/getters.nim | 24 ++++++++++++++---------- 2 files changed, 36 insertions(+), 14 deletions(-) diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index 17fe216..2fb48c0 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -691,6 +691,7 @@ proc newRecListTree(gState: State, name: string, node: TSNode): PNode = let fdecl = node[i].anyChildInTree("field_declaration_list") edecl = node[i].anyChildInTree("enumerator_list") + commentNode = node[i].getNextCommentNode() # `tname` is name of nested struct / union / enum just # added, passed on as type name for field in `newIdentDefs()` @@ -716,6 +717,7 @@ proc newRecListTree(gState: State, name: string, node: TSNode): PNode = # Add nkIdentDefs for each field for field in gState.newIdentDefs(name, node[i], i, ftname = tname, exported = true): if not field.isNil: + field.comment = gState.getCommentVal(commentNode) result.add field proc addTypeObject(gState: State, node: TSNode, typeDef: PNode = nil, fname = "", istype = false, union = false) = @@ -725,6 +727,8 @@ proc addTypeObject(gState: State, node: TSNode, typeDef: PNode = nil, fname = "" # If `fname` is set, use it as the name when creating new PNode # If `istype` is set, this is a typedef, else struct/union decho("addTypeObject()") + let commentNode = node.tsNodeParent().getPrevCommentNode() + let # Object has fields or not fdlist = node.anyChildInTree("field_declaration_list") @@ -837,6 +841,7 @@ proc addTypeObject(gState: State, node: TSNode, typeDef: PNode = nil, fname = "" gState.addPragma(node, typeDef[0][1], pragmas) # nkTypeSection.add + typeDef.comment = gState.getCommentVal(commentNode) gState.typeSection.add typeDef gState.printDebug(typeDef) @@ -848,6 +853,7 @@ proc addTypeObject(gState: State, node: TSNode, typeDef: PNode = nil, fname = "" # Current node has fields let origname = gState.getNodeVal(node.getAtom()) + commentNode = node.getNextCommentNode() # Fix issue #185 name = @@ -859,6 +865,8 @@ proc addTypeObject(gState: State, node: TSNode, typeDef: PNode = nil, fname = "" if name.nBl and gState.identifierNodes.hasKey(name): let def = gState.identifierNodes[name] + def.comment = gState.getCommentVal(commentNode) + # Duplicate nkTypeDef for `name` with empty fields if def.kind == nkTypeDef and def.len == 3 and def[2].kind == nkObjectTy and def[2].len == 3 and @@ -890,6 +898,7 @@ proc addTypeTyped(gState: State, node: TSNode, ftname = "", offset = 0) = decho("addTypeTyped()") let start = getStartAtom(node) + commentNode = node.getPrevCommentNode() for i in start+1+offset ..< node.len: # Add a type of a specific type let @@ -897,6 +906,7 @@ proc addTypeTyped(gState: State, node: TSNode, ftname = "", offset = 0) = typeDef = gState.newXIdent(node[i], istype = true) if not typeDef.isNil: + typeDef.comment = gState.getCommentVal(commentNode) let name = typeDef.getIdentName() @@ -1386,7 +1396,15 @@ proc addEnum(gState: State, node: TSNode) = gState.typeSection.add eoverride elif gState.addNewIdentifer(name): # Add enum definition and helpers - gState.enumSection.add gState.parseString(&"defineEnum({name})") + let defineNode = gState.parseString(&"defineEnum({name})") + # nkStmtList( + # nkCall( + # nkIdent("defineEnum"), + # nkIdent(name) <- set the comment here + # ) + # ) + defineNode[0][1].comment = gState.getCommentVal(node.getPrevCommentNode()) + gState.enumSection.add defineNode # Create const for fields var @@ -1402,7 +1420,7 @@ proc addEnum(gState: State, node: TSNode) = let atom = en.getAtom() - commentNode = en.getInlineCommentNode() + commentNode = en.getNextCommentNode() fname = gState.getIdentifier(gState.getNodeVal(atom), nskEnumField) if fname.nBl and gState.addNewIdentifer(fname): @@ -1621,7 +1639,7 @@ proc addDecl(gState: State, node: TSNode) = let start = getStartAtom(node) - commentNode = node.getCommentNode() + commentNode = node.getPrevCommentNode() for i in start+1 ..< node.len: if not node[i].firstChildInTree("function_declarator").isNil: @@ -1646,7 +1664,7 @@ proc addDef(gState: State, node: TSNode) = let start = getStartAtom(node) - commentNode = node.getCommentNode() + commentNode = node.getPrevCommentNode() if node[start+1].getName() == "function_declarator": if gState.isIncludeHeader(): diff --git a/nimterop/getters.nim b/nimterop/getters.nim index d03e65b..5ad9e4e 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -639,19 +639,23 @@ proc getNameKind*(name: string): tuple[name: string, kind: Kind, recursive: bool proc getCommentVal*(gState: State, commentNode: Option[TSNode]): string = if commentNode.isSome(): - result = gState.getNodeVal(commentNode.get()).replace(re"( *(/\*\*|\*\*/|\*/|\*))", "").strip() + result = gState.getNodeVal(commentNode.get()).replace(re" *(/\*\*|\*\*/|\*/|\*)", "").strip() -proc getCommentNode*(node: TSNode): Option[TSNode] = +template findComment(procName: untyped): untyped = result = none(TSNode) - let prevSibling = node.tsNodePrevNamedSibling() - if not prevSibling.isNil and prevSibling.getName() == "comment": - result = some(prevSibling) + var sibling = node.`procName`() + var i = 0 + while not sibling.isNil and i < maxSearch: + if sibling.getName() == "comment": + return some(sibling) + sibling = sibling.`procName`() + i += 1 -proc getInlineCommentNode*(node: TSNode): Option[TSNode] = - result = none(TSNode) - let nextSibling = node.tsNodeNextNamedSibling() - if not nextSibling.isNil and nextSibling.getName() == "comment": - result = some(nextSibling) +proc getPrevCommentNode*(node: TSNode, maxSearch=4): Option[TSNode] = + findComment(tsNodePrevNamedSibling) + +proc getNextCommentNode*(node: TSNode, maxSearch=4): Option[TSNode] = + findComment(tsNodeNextNamedSibling) proc getTSNodeNamedChildNames*(node: TSNode): seq[string] = if node.tsNodeNamedChildCount() != 0: From f5ee979fa8238b9d165e7c46b4c715581ce032ed Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Fri, 24 Apr 2020 23:41:56 -0600 Subject: [PATCH 445/593] Fix comments not being valid rst --- nimterop/getters.nim | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 5ad9e4e..ed2cf73 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -639,7 +639,7 @@ proc getNameKind*(name: string): tuple[name: string, kind: Kind, recursive: bool proc getCommentVal*(gState: State, commentNode: Option[TSNode]): string = if commentNode.isSome(): - result = gState.getNodeVal(commentNode.get()).replace(re" *(/\*\*|\*\*/|\*/|\*)", "").strip() + result = "::\n " & gState.getNodeVal(commentNode.get()).replace(re" *(/\*\*|\*\*/|\*/|\*)", "").replace("\n", "\n ").strip() template findComment(procName: untyped): untyped = result = none(TSNode) @@ -651,10 +651,10 @@ template findComment(procName: untyped): untyped = sibling = sibling.`procName`() i += 1 -proc getPrevCommentNode*(node: TSNode, maxSearch=4): Option[TSNode] = +proc getPrevCommentNode*(node: TSNode, maxSearch=1): Option[TSNode] = findComment(tsNodePrevNamedSibling) -proc getNextCommentNode*(node: TSNode, maxSearch=4): Option[TSNode] = +proc getNextCommentNode*(node: TSNode, maxSearch=1): Option[TSNode] = findComment(tsNodeNextNamedSibling) proc getTSNodeNamedChildNames*(node: TSNode): seq[string] = From b26f92b0ff2ea4be497ea91b1c16d3b9b7665c73 Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Sat, 25 Apr 2020 13:08:52 -0600 Subject: [PATCH 446/593] Add ability to have multiple comments --- nimterop/ast2.nim | 49 ++++++++++++++++++++++---------------------- nimterop/getters.nim | 40 ++++++++++++++++++++++++++++-------- 2 files changed, 56 insertions(+), 33 deletions(-) diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index 2fb48c0..2e601db 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -691,7 +691,7 @@ proc newRecListTree(gState: State, name: string, node: TSNode): PNode = let fdecl = node[i].anyChildInTree("field_declaration_list") edecl = node[i].anyChildInTree("enumerator_list") - commentNode = node[i].getNextCommentNode() + commentNodes = node[i].getNextCommentNodes() # `tname` is name of nested struct / union / enum just # added, passed on as type name for field in `newIdentDefs()` @@ -717,7 +717,7 @@ proc newRecListTree(gState: State, name: string, node: TSNode): PNode = # Add nkIdentDefs for each field for field in gState.newIdentDefs(name, node[i], i, ftname = tname, exported = true): if not field.isNil: - field.comment = gState.getCommentVal(commentNode) + field.comment = gState.getCommentsStr(commentNodes) result.add field proc addTypeObject(gState: State, node: TSNode, typeDef: PNode = nil, fname = "", istype = false, union = false) = @@ -727,7 +727,7 @@ proc addTypeObject(gState: State, node: TSNode, typeDef: PNode = nil, fname = "" # If `fname` is set, use it as the name when creating new PNode # If `istype` is set, this is a typedef, else struct/union decho("addTypeObject()") - let commentNode = node.tsNodeParent().getPrevCommentNode() + let commentNodes = node.tsNodeParent().getPrevCommentNodes() let # Object has fields or not @@ -841,7 +841,7 @@ proc addTypeObject(gState: State, node: TSNode, typeDef: PNode = nil, fname = "" gState.addPragma(node, typeDef[0][1], pragmas) # nkTypeSection.add - typeDef.comment = gState.getCommentVal(commentNode) + typeDef.comment = gState.getCommentsStr(commentNodes) gState.typeSection.add typeDef gState.printDebug(typeDef) @@ -853,7 +853,7 @@ proc addTypeObject(gState: State, node: TSNode, typeDef: PNode = nil, fname = "" # Current node has fields let origname = gState.getNodeVal(node.getAtom()) - commentNode = node.getNextCommentNode() + commentNodes = node.getNextCommentNodes() # Fix issue #185 name = @@ -865,7 +865,7 @@ proc addTypeObject(gState: State, node: TSNode, typeDef: PNode = nil, fname = "" if name.nBl and gState.identifierNodes.hasKey(name): let def = gState.identifierNodes[name] - def.comment = gState.getCommentVal(commentNode) + def.comment = gState.getCommentsStr(commentNodes) # Duplicate nkTypeDef for `name` with empty fields if def.kind == nkTypeDef and def.len == 3 and @@ -898,7 +898,7 @@ proc addTypeTyped(gState: State, node: TSNode, ftname = "", offset = 0) = decho("addTypeTyped()") let start = getStartAtom(node) - commentNode = node.getPrevCommentNode() + commentNodes = node.getPrevCommentNodes() for i in start+1+offset ..< node.len: # Add a type of a specific type let @@ -906,7 +906,7 @@ proc addTypeTyped(gState: State, node: TSNode, ftname = "", offset = 0) = typeDef = gState.newXIdent(node[i], istype = true) if not typeDef.isNil: - typeDef.comment = gState.getCommentVal(commentNode) + typeDef.comment = gState.getCommentsStr(commentNodes) let name = typeDef.getIdentName() @@ -1403,7 +1403,7 @@ proc addEnum(gState: State, node: TSNode) = # nkIdent(name) <- set the comment here # ) # ) - defineNode[0][1].comment = gState.getCommentVal(node.getPrevCommentNode()) + defineNode[0][1].comment = gState.getCommentsStr(node.getPrevCommentNodes()) gState.enumSection.add defineNode # Create const for fields @@ -1411,7 +1411,7 @@ proc addEnum(gState: State, node: TSNode) = fnames: HashSet[string] # Hold all of field information so that we can add all of them # after the const identifiers has been updated - fieldDeclarations: seq[tuple[fname: string, fval: string, cexpr: Option[TSNode], comment: Option[TSNode]]] + fieldDeclarations: seq[tuple[fname: string, fval: string, cexpr: Option[TSNode], comment: seq[TSNode]]] for i in 0 .. enumlist.len - 1: let en = enumlist[i] @@ -1420,7 +1420,7 @@ proc addEnum(gState: State, node: TSNode) = let atom = en.getAtom() - commentNode = en.getNextCommentNode() + commentNodes = en.getNextCommentNodes() fname = gState.getIdentifier(gState.getNodeVal(atom), nskEnumField) if fname.nBl and gState.addNewIdentifer(fname): @@ -1434,9 +1434,9 @@ proc addEnum(gState: State, node: TSNode) = fval = &"({prev} + 1).{name}" if en.len > 1 and en[1].getName() in gEnumVals: - fieldDeclarations.add((fname, "", some(en[1]), commentNode)) + fieldDeclarations.add((fname, "", some(en[1]), commentNodes)) else: - fieldDeclarations.add((fname, fval, none(TSNode), commentNode)) + fieldDeclarations.add((fname, fval, none(TSNode), commentNodes)) fnames.incl fname prev = fname @@ -1446,20 +1446,20 @@ proc addEnum(gState: State, node: TSNode) = gState.constIdentifiers.incl fnames # parseCExpression requires all const identifiers to be present for the enum - for (fname, fval, cexprNode, commentNode) in fieldDeclarations: + for (fname, fval, cexprNode, commentNodes) in fieldDeclarations: var fval = fval if cexprNode.isSome: fval = "(" & $gState.parseCExpression(gState.getNodeVal(cexprNode.get()), name) & ")." & name # Cannot use newConstDef() since parseString(fval) adds backticks to and/or let constNode = gState.parseString(&"const {fname}* = {fval}")[0][0] - constNode.comment = gState.getCommentVal(commentNode) + constNode.comment = gState.getCommentsStr(commentNodes) gState.constSection.add constNode # Add other names if node.getName() == "type_definition" and node.len > 1: gState.addTypeTyped(node, ftname = name, offset = offset) -proc addProcVar(gState: State, node, rnode: TSNode, commentNode: Option[TSNode]) = +proc addProcVar(gState: State, node, rnode: TSNode, commentNodes: seq[TSNode]) = # Add a proc variable decho("addProcVar()") let @@ -1512,13 +1512,13 @@ proc addProcVar(gState: State, node, rnode: TSNode, commentNode: Option[TSNode]) # nkEmpty() # ) - identDefs.comment = gState.getCommentVal(commentNode) + identDefs.comment = gState.getCommentsStr(commentNodes) # nkVarSection.add gState.varSection.add identDefs gState.printDebug(identDefs) -proc addProc(gState: State, node, rnode: TSNode, commentNode: Option[TSNode]) = +proc addProc(gState: State, node, rnode: TSNode, commentNodes: seq[TSNode]) = # Add a proc # # `node` is the `nth` child of (declaration) @@ -1624,7 +1624,7 @@ proc addProc(gState: State, node, rnode: TSNode, commentNode: Option[TSNode]) = procDef.add newNode(nkEmpty) procDef.add newNode(nkEmpty) - procDef.comment = gState.getCommentVal(commentNode) + procDef.comment = gState.getCommentsStr(commentNodes) # nkProcSection.add gState.procSection.add procDef @@ -1636,20 +1636,19 @@ proc addDecl(gState: State, node: TSNode) = decho("addDecl()") gState.printDebug(node) - let start = getStartAtom(node) - commentNode = node.getPrevCommentNode() + commentNodes = node.getPrevCommentNodes() for i in start+1 ..< node.len: if not node[i].firstChildInTree("function_declarator").isNil: # Proc declaration - var or actual proc if node[i].getAtom().getPxName(1) == "pointer_declarator": # proc var - gState.addProcVar(node[i], node[start], commentNode) + gState.addProcVar(node[i], node[start], commentNodes) else: # proc - gState.addProc(node[i], node[start], commentNode) + gState.addProc(node[i], node[start], commentNodes) else: # Regular var discard @@ -1664,11 +1663,11 @@ proc addDef(gState: State, node: TSNode) = let start = getStartAtom(node) - commentNode = node.getPrevCommentNode() + commentNodes = node.getPrevCommentNodes() if node[start+1].getName() == "function_declarator": if gState.isIncludeHeader(): - gState.addProc(node[start+1], node[start], commentNode) + gState.addProc(node[start+1], node[start], commentNodes) else: gecho &"\n# proc '$1' skipped - static inline procs require 'includeHeader'" % gState.getNodeVal(node[start+1].getAtom()) diff --git a/nimterop/getters.nim b/nimterop/getters.nim index ed2cf73..1240130 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -1,4 +1,5 @@ import dynlib, macros, os, sequtils, sets, strformat, strutils, tables, times, options +import algorithm import regex @@ -637,12 +638,13 @@ proc getNameKind*(name: string): tuple[name: string, kind: Kind, recursive: bool if result.kind != exactlyOne: result.name = result.name[0 .. ^2] -proc getCommentVal*(gState: State, commentNode: Option[TSNode]): string = - if commentNode.isSome(): - result = "::\n " & gState.getNodeVal(commentNode.get()).replace(re" *(/\*\*|\*\*/|\*/|\*)", "").replace("\n", "\n ").strip() +proc getCommentsStr*(gState: State, commentNodes: seq[TSNode]): string = + if commentNodes.len > 0: + result = "::" + for commentNode in commentNodes: + result &= "\n " & gState.getNodeVal(commentNode).replace(re" *(//|/\*\*|\*\*/|/\*|\*/|\*)", "").replace("\n", "\n ").strip() template findComment(procName: untyped): untyped = - result = none(TSNode) var sibling = node.`procName`() var i = 0 while not sibling.isNil and i < maxSearch: @@ -651,11 +653,33 @@ template findComment(procName: untyped): untyped = sibling = sibling.`procName`() i += 1 -proc getPrevCommentNode*(node: TSNode, maxSearch=1): Option[TSNode] = - findComment(tsNodePrevNamedSibling) +proc getPrevCommentNodes*(node: TSNode, maxSearch=1): seq[TSNode] = + ## Here we want to go until the node we get is not a comment + ## for cases with multiple ``//`` comments instead of one ``/* */`` + ## section + var sibling = node.tsNodePrevNamedSibling() + var i = 0 + while not sibling.isNil and i < maxSearch: + while not sibling.isNil and sibling.getName() == "comment": + result.add(sibling) + sibling = sibling.tsNodePrevNamedSibling() + if sibling.isNil: + result.reverse + return + sibling = sibling.tsNodePrevNamedSibling() + i += 1 -proc getNextCommentNode*(node: TSNode, maxSearch=1): Option[TSNode] = - findComment(tsNodeNextNamedSibling) + result.reverse + +proc getNextCommentNodes*(node: TSNode, maxSearch=1): seq[TSNode] = + ## We only want to search for the next comment node (ie: inline) + var sibling = node.tsNodeNextNamedSibling() + var i = 0 + while not sibling.isNil and i < maxSearch: + if sibling.getName() == "comment": + return @[sibling] + sibling = sibling.tsNodeNextNamedSibling() + i += 1 proc getTSNodeNamedChildNames*(node: TSNode): seq[string] = if node.tsNodeNamedChildCount() != 0: From 4f1464bdfb0545f06edf23b2fc92a72733403a5c Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Sat, 25 Apr 2020 20:47:28 -0600 Subject: [PATCH 447/593] Remove unnecessary proc --- nimterop/getters.nim | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 1240130..281e3a4 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -1,4 +1,4 @@ -import dynlib, macros, os, sequtils, sets, strformat, strutils, tables, times, options +import dynlib, macros, os, sequtils, sets, strformat, strutils, tables, times import algorithm import regex @@ -644,15 +644,6 @@ proc getCommentsStr*(gState: State, commentNodes: seq[TSNode]): string = for commentNode in commentNodes: result &= "\n " & gState.getNodeVal(commentNode).replace(re" *(//|/\*\*|\*\*/|/\*|\*/|\*)", "").replace("\n", "\n ").strip() -template findComment(procName: untyped): untyped = - var sibling = node.`procName`() - var i = 0 - while not sibling.isNil and i < maxSearch: - if sibling.getName() == "comment": - return some(sibling) - sibling = sibling.`procName`() - i += 1 - proc getPrevCommentNodes*(node: TSNode, maxSearch=1): seq[TSNode] = ## Here we want to go until the node we get is not a comment ## for cases with multiple ``//`` comments instead of one ``/* */`` From c8c2efdc3054d4f4377a41f6e1894dec4ffd0607 Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Sun, 26 Apr 2020 09:28:58 -0600 Subject: [PATCH 448/593] Add comments explaining comment node procs --- nimterop/getters.nim | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 281e3a4..89fde10 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -639,6 +639,8 @@ proc getNameKind*(name: string): tuple[name: string, kind: Kind, recursive: bool result.name = result.name[0 .. ^2] proc getCommentsStr*(gState: State, commentNodes: seq[TSNode]): string = + ## Generate a comment from a set of comment nodes. Comment is guaranteed + ## to be able to be rendered using nim doc if commentNodes.len > 0: result = "::" for commentNode in commentNodes: @@ -650,25 +652,37 @@ proc getPrevCommentNodes*(node: TSNode, maxSearch=1): seq[TSNode] = ## section var sibling = node.tsNodePrevNamedSibling() var i = 0 + + # Search for the starting comment up to maxSearch nodes away while not sibling.isNil and i < maxSearch: + # Once a comment is found, find all of the comments right next to + # it so that we can get multiple // style comments while not sibling.isNil and sibling.getName() == "comment": result.add(sibling) sibling = sibling.tsNodePrevNamedSibling() + if sibling.isNil: - result.reverse - return + break + sibling = sibling.tsNodePrevNamedSibling() i += 1 + # reverse the comments because we got them in reverse order result.reverse proc getNextCommentNodes*(node: TSNode, maxSearch=1): seq[TSNode] = - ## We only want to search for the next comment node (ie: inline) + ## Searches the next nodes up to maxSearch nodes away for a comment + + # We only want to search for the next comment node (ie: inline) + # but we want to keep the same interface as getPrevCommentNodes, + # so we keep a returned seq but only store one element var sibling = node.tsNodeNextNamedSibling() var i = 0 + # Search for the comment up to maxSearch nodes away while not sibling.isNil and i < maxSearch: if sibling.getName() == "comment": - return @[sibling] + result.add sibling + break sibling = sibling.tsNodeNextNamedSibling() i += 1 From b81d51dc37f316c71a29b67a0750e3ce55990b91 Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Sun, 26 Apr 2020 09:56:18 -0600 Subject: [PATCH 449/593] Use gState.nocomments --- nimterop/ast2.nim | 16 ++++++++-------- nimterop/getters.nim | 12 +++++++++--- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index 2e601db..0fd5a9d 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -691,7 +691,7 @@ proc newRecListTree(gState: State, name: string, node: TSNode): PNode = let fdecl = node[i].anyChildInTree("field_declaration_list") edecl = node[i].anyChildInTree("enumerator_list") - commentNodes = node[i].getNextCommentNodes() + commentNodes = gState.getNextCommentNodes(node[i]) # `tname` is name of nested struct / union / enum just # added, passed on as type name for field in `newIdentDefs()` @@ -727,7 +727,7 @@ proc addTypeObject(gState: State, node: TSNode, typeDef: PNode = nil, fname = "" # If `fname` is set, use it as the name when creating new PNode # If `istype` is set, this is a typedef, else struct/union decho("addTypeObject()") - let commentNodes = node.tsNodeParent().getPrevCommentNodes() + let commentNodes = gState.getPrevCommentNodes(node.tsNodeParent()) let # Object has fields or not @@ -853,7 +853,7 @@ proc addTypeObject(gState: State, node: TSNode, typeDef: PNode = nil, fname = "" # Current node has fields let origname = gState.getNodeVal(node.getAtom()) - commentNodes = node.getNextCommentNodes() + commentNodes = gState.getNextCommentNodes(node) # Fix issue #185 name = @@ -898,7 +898,7 @@ proc addTypeTyped(gState: State, node: TSNode, ftname = "", offset = 0) = decho("addTypeTyped()") let start = getStartAtom(node) - commentNodes = node.getPrevCommentNodes() + commentNodes = gState.getPrevCommentNodes(node) for i in start+1+offset ..< node.len: # Add a type of a specific type let @@ -1403,7 +1403,7 @@ proc addEnum(gState: State, node: TSNode) = # nkIdent(name) <- set the comment here # ) # ) - defineNode[0][1].comment = gState.getCommentsStr(node.getPrevCommentNodes()) + defineNode[0][1].comment = gState.getCommentsStr(gState.getPrevCommentNodes(node)) gState.enumSection.add defineNode # Create const for fields @@ -1420,7 +1420,7 @@ proc addEnum(gState: State, node: TSNode) = let atom = en.getAtom() - commentNodes = en.getNextCommentNodes() + commentNodes = gState.getNextCommentNodes(en) fname = gState.getIdentifier(gState.getNodeVal(atom), nskEnumField) if fname.nBl and gState.addNewIdentifer(fname): @@ -1638,7 +1638,7 @@ proc addDecl(gState: State, node: TSNode) = let start = getStartAtom(node) - commentNodes = node.getPrevCommentNodes() + commentNodes = gState.getPrevCommentNodes(node) for i in start+1 ..< node.len: if not node[i].firstChildInTree("function_declarator").isNil: @@ -1663,7 +1663,7 @@ proc addDef(gState: State, node: TSNode) = let start = getStartAtom(node) - commentNodes = node.getPrevCommentNodes() + commentNodes = gState.getPrevCommentNodes(node) if node[start+1].getName() == "function_declarator": if gState.isIncludeHeader(): diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 89fde10..148c209 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -644,12 +644,16 @@ proc getCommentsStr*(gState: State, commentNodes: seq[TSNode]): string = if commentNodes.len > 0: result = "::" for commentNode in commentNodes: - result &= "\n " & gState.getNodeVal(commentNode).replace(re" *(//|/\*\*|\*\*/|/\*|\*/|\*)", "").replace("\n", "\n ").strip() + result &= "\n " & gState.getNodeVal(commentNode). + replace(re" *(//|/\*\*|\*\*/|/\*|\*/|\*)", "").replace("\n", "\n ").strip() -proc getPrevCommentNodes*(node: TSNode, maxSearch=1): seq[TSNode] = +proc getPrevCommentNodes*(gState: State, node: TSNode, maxSearch=1): seq[TSNode] = ## Here we want to go until the node we get is not a comment ## for cases with multiple ``//`` comments instead of one ``/* */`` ## section + if gState.nocomments: + return + var sibling = node.tsNodePrevNamedSibling() var i = 0 @@ -670,9 +674,11 @@ proc getPrevCommentNodes*(node: TSNode, maxSearch=1): seq[TSNode] = # reverse the comments because we got them in reverse order result.reverse -proc getNextCommentNodes*(node: TSNode, maxSearch=1): seq[TSNode] = +proc getNextCommentNodes*(gState: State, node: TSNode, maxSearch=1): seq[TSNode] = ## Searches the next nodes up to maxSearch nodes away for a comment + if gState.nocomments: + return # We only want to search for the next comment node (ie: inline) # but we want to keep the same interface as getPrevCommentNodes, # so we keep a returned seq but only store one element From f70f836af837376bcad9a76c7fd05b930b0e7506 Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Sun, 26 Apr 2020 10:47:32 -0600 Subject: [PATCH 450/593] Remove unused proc --- nimterop/getters.nim | 3 --- 1 file changed, 3 deletions(-) diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 148c209..28005e3 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -457,9 +457,6 @@ proc printLisp*(gState: State, root: TSNode): string = proc getCommented*(str: string): string = "\n# " & str.strip().replace("\n", "\n# ") -proc getDocStrCommented*(str: string): string = - "\n## " & str.strip().replace("\n", "\n## ") - proc printTree*(gState: State, pnode: PNode, offset = ""): string = if not pnode.isNil and gState.debug and pnode.kind != nkNone: result &= "\n# " & offset & $pnode.kind & "(" From 789af2b5cc05204e1cbfda009aaee005d4153248 Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Sun, 26 Apr 2020 11:07:30 -0600 Subject: [PATCH 451/593] Add comment gen for array type --- nimterop/ast2.nim | 2 ++ 1 file changed, 2 insertions(+) diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index 0fd5a9d..ab7bb72 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -1017,6 +1017,7 @@ proc addTypeArray(gState: State, node: TSNode) = # node[start] = identifier = type name (tname, _, info) = gState.getNameInfo(node[start].getAtom(), nskType, parent = "addTypeArray") tident = gState.getIdent(tname, info, exported = false) + commentNodes = gState.getPrevCommentNodes(node) # Could have multiple types, comma separated for i in start+1 ..< node.len: @@ -1050,6 +1051,7 @@ proc addTypeArray(gState: State, node: TSNode) = # ) # ) + typeDef.comment = gState.getCommentsStr(commentNodes) # nkTypeSection.add gState.typeSection.add typeDef From 31bea0f032adca25bcb836fcbd7f4cb2f00d78ba Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Tue, 28 Apr 2020 22:52:24 -0600 Subject: [PATCH 452/593] Add more robust comment extraction --- nimterop/ast2.nim | 18 +++--- nimterop/getters.nim | 134 ++++++++++++++++++++++++++++++------------- 2 files changed, 102 insertions(+), 50 deletions(-) diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index ab7bb72..b51b252 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -691,7 +691,7 @@ proc newRecListTree(gState: State, name: string, node: TSNode): PNode = let fdecl = node[i].anyChildInTree("field_declaration_list") edecl = node[i].anyChildInTree("enumerator_list") - commentNodes = gState.getNextCommentNodes(node[i]) + commentNodes = gState.getCommentNodes(node[i]) # `tname` is name of nested struct / union / enum just # added, passed on as type name for field in `newIdentDefs()` @@ -727,7 +727,7 @@ proc addTypeObject(gState: State, node: TSNode, typeDef: PNode = nil, fname = "" # If `fname` is set, use it as the name when creating new PNode # If `istype` is set, this is a typedef, else struct/union decho("addTypeObject()") - let commentNodes = gState.getPrevCommentNodes(node.tsNodeParent()) + let commentNodes = gState.getCommentNodes(node.tsNodeParent()) let # Object has fields or not @@ -853,7 +853,7 @@ proc addTypeObject(gState: State, node: TSNode, typeDef: PNode = nil, fname = "" # Current node has fields let origname = gState.getNodeVal(node.getAtom()) - commentNodes = gState.getNextCommentNodes(node) + commentNodes = gState.getCommentNodes(node) # Fix issue #185 name = @@ -898,7 +898,7 @@ proc addTypeTyped(gState: State, node: TSNode, ftname = "", offset = 0) = decho("addTypeTyped()") let start = getStartAtom(node) - commentNodes = gState.getPrevCommentNodes(node) + commentNodes = gState.getCommentNodes(node) for i in start+1+offset ..< node.len: # Add a type of a specific type let @@ -1017,7 +1017,7 @@ proc addTypeArray(gState: State, node: TSNode) = # node[start] = identifier = type name (tname, _, info) = gState.getNameInfo(node[start].getAtom(), nskType, parent = "addTypeArray") tident = gState.getIdent(tname, info, exported = false) - commentNodes = gState.getPrevCommentNodes(node) + commentNodes = gState.getCommentNodes(node) # Could have multiple types, comma separated for i in start+1 ..< node.len: @@ -1405,7 +1405,7 @@ proc addEnum(gState: State, node: TSNode) = # nkIdent(name) <- set the comment here # ) # ) - defineNode[0][1].comment = gState.getCommentsStr(gState.getPrevCommentNodes(node)) + defineNode[0][1].comment = gState.getCommentsStr(gState.getCommentNodes(node)) gState.enumSection.add defineNode # Create const for fields @@ -1422,7 +1422,7 @@ proc addEnum(gState: State, node: TSNode) = let atom = en.getAtom() - commentNodes = gState.getNextCommentNodes(en) + commentNodes = gState.getCommentNodes(en) fname = gState.getIdentifier(gState.getNodeVal(atom), nskEnumField) if fname.nBl and gState.addNewIdentifer(fname): @@ -1640,7 +1640,7 @@ proc addDecl(gState: State, node: TSNode) = let start = getStartAtom(node) - commentNodes = gState.getPrevCommentNodes(node) + commentNodes = gState.getCommentNodes(node) for i in start+1 ..< node.len: if not node[i].firstChildInTree("function_declarator").isNil: @@ -1665,7 +1665,7 @@ proc addDef(gState: State, node: TSNode) = let start = getStartAtom(node) - commentNodes = gState.getPrevCommentNodes(node) + commentNodes = gState.getCommentNodes(node) if node[start+1].getName() == "function_declarator": if gState.isIncludeHeader(): diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 28005e3..05d9448 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -1,5 +1,4 @@ import dynlib, macros, os, sequtils, sets, strformat, strutils, tables, times -import algorithm import regex @@ -572,30 +571,30 @@ proc getPreprocessor*(gState: State, fullpath: string): string = # Include content only from file for line in execAction(cmd).output.splitLines(): - if line.strip() != "": - if line.len > 1 and line[0 .. 1] == "# ": - start = false + # We want to keep blank lines here for comment processing + if line.len > 1 and line[0 .. 1] == "# ": + start = false + let + saniLine = line.sanitizePath(noQuote = true) + if sfile in saniLine: + start = true + elif not ("\\" in line) and not ("/" in line) and extractFilename(sfile) in line: + start = true + elif gState.recurse: let - saniLine = line.sanitizePath(noQuote = true) - if sfile in saniLine: + pDir = sfile.expandFilename().parentDir().sanitizePath(noQuote = true) + if pDir.Bl or pDir in saniLine: start = true - elif not ("\\" in line) and not ("/" in line) and extractFilename(sfile) in line: - start = true - elif gState.recurse: - let - pDir = sfile.expandFilename().parentDir().sanitizePath(noQuote = true) - if pDir.Bl or pDir in saniLine: - start = true - else: - for inc in gState.includeDirs: - if inc.absolutePath().sanitizePath(noQuote = true) in saniLine: - start = true - break - else: - if start: - if "#undef" in line: - continue - rdata.add line + else: + for inc in gState.includeDirs: + if inc.absolutePath().sanitizePath(noQuote = true) in saniLine: + start = true + break + else: + if start: + if "#undef" in line: + continue + rdata.add line return rdata.join("\n") converter toString*(kind: Kind): string = @@ -644,32 +643,85 @@ proc getCommentsStr*(gState: State, commentNodes: seq[TSNode]): string = result &= "\n " & gState.getNodeVal(commentNode). replace(re" *(//|/\*\*|\*\*/|/\*|\*/|\*)", "").replace("\n", "\n ").strip() -proc getPrevCommentNodes*(gState: State, node: TSNode, maxSearch=1): seq[TSNode] = - ## Here we want to go until the node we get is not a comment - ## for cases with multiple ``//`` comments instead of one ``/* */`` - ## section +proc getCommentNodes*(gState: State, node: TSNode, maxSearch=1): seq[TSNode] = + ## Get a set of comment nodes in order of priority. Will search up to ``maxSearch`` + ## nodes before and after the current node + ## + ## Priority is (closest line number) > comment before > comment after. + ## This priority might need to be changed based on the project, but + ## for now it is good enough + + # Skip this if we don't want comments if gState.nocomments: return - var sibling = node.tsNodePrevNamedSibling() - var i = 0 + let (line, _) = gState.getLineCol(node) - # Search for the starting comment up to maxSearch nodes away - while not sibling.isNil and i < maxSearch: - # Once a comment is found, find all of the comments right next to - # it so that we can get multiple // style comments - while not sibling.isNil and sibling.getName() == "comment": - result.add(sibling) - sibling = sibling.tsNodePrevNamedSibling() + # Keep track of both directions from a node + var + prevSibling = node.tsNodePrevNamedSibling() + nextSibling = node.tsNodeNextNamedSibling() + nilNode: TSNode - if sibling.isNil: + var + i = 0 + prevSiblingDistance, nextSiblingDistance: int + lowestDistance: int + commentsFound = false + + while not commentsFound and i < maxSearch: + + # Distance from the current node will tell us approximately if the + # comment belongs to the node. The closer it is in terms of line + # numbers, the more we can be sure it's the comment we want + if not prevSibling.isNil: + prevSiblingDistance = abs(gState.getLineCol(prevSibling)[0] - line) + if not nextSibling.isNil: + nextSiblingDistance = abs(gState.getLineCol(nextSibling)[0] - line) + + lowestDistance = min(prevSiblingDistance, nextSiblingDistance) + + if prevSiblingDistance > maxSearch: + # If the line is out of range, skip searching + prevSibling = nilNode # Can't do `= nil` + + if nextSiblingDistance > maxSearch: + # If the line is out of range, skip searching + prevSibling = nilNode + + while ( + not prevSibling.isNil and + prevSibling.getName() == "comment" and + prevSiblingDistance == lowestDistance + ): + # Put the previous nodes in reverse order so the comments + # make logical sense + result.insert(prevSibling, 0) + prevSibling = prevSibling.tsNodePrevNamedSibling() + commentsFound = true + + if commentsFound: break - sibling = sibling.tsNodePrevNamedSibling() - i += 1 + while ( + not nextSibling.isNil and + nextSibling.getName() == "comment" and + nextSiblingDistance == lowestDistance + ): + result.add(nextSibling) + nextSibling = nextSibling.tsNodeNextNamedSibling() + commentsFound = true - # reverse the comments because we got them in reverse order - result.reverse + if commentsFound: + break + + # Go to next sibling pair + if not prevSibling.isNil: + prevSibling = prevSibling.tsNodePrevNamedSibling() + if not nextSibling.isNil: + nextSibling = nextSibling.tsNodeNextNamedSibling() + + i += 1 proc getNextCommentNodes*(gState: State, node: TSNode, maxSearch=1): seq[TSNode] = ## Searches the next nodes up to maxSearch nodes away for a comment From 1e105d34a49469b9c37ecbd38032765dbef96049 Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Wed, 29 Apr 2020 19:15:11 -0600 Subject: [PATCH 453/593] Add docgen runs in tests Fix paths import Skip docgen for rsa for now --- nimterop.nimble | 13 ++++++++++--- nimterop/cimport.nim | 2 +- nimterop/docs.nim | 4 ++-- tests/tnimterop_c.nim | 4 +++- 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/nimterop.nimble b/nimterop.nimble index a6ece7c..8a47465 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -12,14 +12,21 @@ installDirs = @["nimterop"] requires "nim >= 0.20.2", "regex >= 0.14.1", "cligen >= 0.9.45" import nimterop/docs +import os proc execCmd(cmd: string) = exec "tests/timeit " & cmd -proc execTest(test: string, flags = "") = +proc execTest(test: string, flags = "", runDocs = true) = execCmd "nim c --hints:off -f " & flags & " -r " & test execCmd "nim cpp --hints:off " & flags & " -r " & test + if runDocs: + let docPath = "build/html_" & test.extractFileName.changeFileExt("") & "_docs" + rmDir docPath + mkDir docPath + buildDocs(@[test], docPath, compilerArgs = flags) + task buildToast, "build toast": execCmd("nim c --hints:off nimterop/toast.nim") @@ -54,8 +61,8 @@ task test, "Test": execTest "tests/tpcre.nim", "-d:FLAGS=\"-f:ast2\"" when defined(Linux): - execTest "tests/rsa.nim" - execTest "tests/rsa.nim", "-d:FLAGS=\"-H\"" + execTest "tests/rsa.nim", runDocs = false + execTest "tests/rsa.nim", "-d:FLAGS=\"-H\"", runDocs = false # Platform specific tests when defined(Windows): diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index e081633..99be1f5 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -434,7 +434,7 @@ proc cAddSearchDir*(dir: string) {.compileTime.} = ## Add directory `dir` to the search path used in calls to ## `cSearchPath() `_. runnableExamples: - import paths, os + import nimterop/paths, os static: cAddSearchDir testsIncludeDir() doAssert cSearchPath("test.h").existsFile diff --git a/nimterop/docs.nim b/nimterop/docs.nim index d808535..e0fef39 100644 --- a/nimterop/docs.nim +++ b/nimterop/docs.nim @@ -36,7 +36,7 @@ proc execAction(cmd: string): string = doAssert ret == 0, "Command failed: " & $ret & "\ncmd: " & ccmd & "\nresult:\n" & result proc buildDocs*(files: openArray[string], path: string, baseDir = getProjectPath() & $DirSep, - defines: openArray[string] = @[]) = + defines: openArray[string] = @[], compilerArgs = "") = ## Generate docs for all specified nim `files` to the specified `path` ## ## `baseDir` is the project path by default and `files` and `path` are relative @@ -70,7 +70,7 @@ proc buildDocs*(files: openArray[string], path: string, baseDir = getProjectPath defStr nim = getCurrentCompilerExe() for file in files: - echo execAction(&"{nim} doc {defStr} -o:{path} --project --index:on {baseDir & file}") + echo execAction(&"{nim} doc {defStr} {compilerArgs} -o:{path} --project --index:on {baseDir & file}") echo execAction(&"{nim} buildIndex -o:{path}/theindex.html {path}") when declared(getNimRootDir): diff --git a/tests/tnimterop_c.nim b/tests/tnimterop_c.nim index 20c1678..ef814ea 100644 --- a/tests/tnimterop_c.nim +++ b/tests/tnimterop_c.nim @@ -1,4 +1,6 @@ import std/unittest +import os +import macros import nimterop/cimport import nimterop/paths @@ -10,7 +12,7 @@ cDefine("FORCE") cIncludeDir testsIncludeDir() cCompile cSearchPath("test.c") -cPluginPath("tests/tnimterop_c_plugin.nim") +cPluginPath(getProjectPath() / "tnimterop_c_plugin.nim") cOverride: type From f5ddcb7f548d3291f1ca64760587f5d85904e2ec Mon Sep 17 00:00:00 2001 From: Joey Date: Thu, 30 Apr 2020 08:43:40 -0600 Subject: [PATCH 454/593] Change install to develop for appveyor --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 5275844..d67b01d 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -83,7 +83,7 @@ for: - /home/appveyor/binaries build_script: - - nimble --verbose install -y + - nimble --verbose develop -y test_script: - nimble --verbose test From 0d65bcdd52d7eda9d4e642d2ad7bb0e3f5a97e0a Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Thu, 30 Apr 2020 11:55:07 -0600 Subject: [PATCH 455/593] Run docs on rsa.nim --- nimterop.nimble | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nimterop.nimble b/nimterop.nimble index 8a47465..38a2d5d 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -61,8 +61,8 @@ task test, "Test": execTest "tests/tpcre.nim", "-d:FLAGS=\"-f:ast2\"" when defined(Linux): - execTest "tests/rsa.nim", runDocs = false - execTest "tests/rsa.nim", "-d:FLAGS=\"-H\"", runDocs = false + execTest "tests/rsa.nim" + execTest "tests/rsa.nim", "-d:FLAGS=\"-H\"" # Platform specific tests when defined(Windows): From 964209d5f855f5933f5d5aa8b4d18fa5fa1fbc03 Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Thu, 30 Apr 2020 12:45:00 -0600 Subject: [PATCH 456/593] Remove unneeded proc, add more comments --- nimterop/getters.nim | 26 +++++++------------------- 1 file changed, 7 insertions(+), 19 deletions(-) diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 05d9448..cae2d08 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -670,7 +670,6 @@ proc getCommentNodes*(gState: State, node: TSNode, maxSearch=1): seq[TSNode] = commentsFound = false while not commentsFound and i < maxSearch: - # Distance from the current node will tell us approximately if the # comment belongs to the node. The closer it is in terms of line # numbers, the more we can be sure it's the comment we want @@ -689,6 +688,9 @@ proc getCommentNodes*(gState: State, node: TSNode, maxSearch=1): seq[TSNode] = # If the line is out of range, skip searching prevSibling = nilNode + # Search above the current line for comments. When one is found + # keep going to retrieve successive comments for cases with multiple + # `//` style comments while ( not prevSibling.isNil and prevSibling.getName() == "comment" and @@ -700,9 +702,13 @@ proc getCommentNodes*(gState: State, node: TSNode, maxSearch=1): seq[TSNode] = prevSibling = prevSibling.tsNodePrevNamedSibling() commentsFound = true + # If we've already found comments above the current line, quit if commentsFound: break + # Search below or at the current line for comments. When one is found + # keep going to retrieve successive comments for cases with multiple + # `//` style comments while ( not nextSibling.isNil and nextSibling.getName() == "comment" and @@ -723,24 +729,6 @@ proc getCommentNodes*(gState: State, node: TSNode, maxSearch=1): seq[TSNode] = i += 1 -proc getNextCommentNodes*(gState: State, node: TSNode, maxSearch=1): seq[TSNode] = - ## Searches the next nodes up to maxSearch nodes away for a comment - - if gState.nocomments: - return - # We only want to search for the next comment node (ie: inline) - # but we want to keep the same interface as getPrevCommentNodes, - # so we keep a returned seq but only store one element - var sibling = node.tsNodeNextNamedSibling() - var i = 0 - # Search for the comment up to maxSearch nodes away - while not sibling.isNil and i < maxSearch: - if sibling.getName() == "comment": - result.add sibling - break - sibling = sibling.tsNodeNextNamedSibling() - i += 1 - proc getTSNodeNamedChildNames*(node: TSNode): seq[string] = if node.tsNodeNamedChildCount() != 0: for i in 0 .. node.tsNodeNamedChildCount()-1: From 461dde150ee5fe4350d593e5ca675b1a9438d534 Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Thu, 30 Apr 2020 17:23:10 -0600 Subject: [PATCH 457/593] Add escaping for rst --- nimterop/getters.nim | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nimterop/getters.nim b/nimterop/getters.nim index cae2d08..099faf4 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -638,9 +638,10 @@ proc getCommentsStr*(gState: State, commentNodes: seq[TSNode]): string = ## Generate a comment from a set of comment nodes. Comment is guaranteed ## to be able to be rendered using nim doc if commentNodes.len > 0: + const escapeRstReg = re"""(["!#$%&'()*+,-./:;<=>?@[\]^_`{|}~])""" result = "::" for commentNode in commentNodes: - result &= "\n " & gState.getNodeVal(commentNode). + result &= "\n " & gState.getNodeVal(commentNode).replace(escapeRstReg, r"\$1"). replace(re" *(//|/\*\*|\*\*/|/\*|\*/|\*)", "").replace("\n", "\n ").strip() proc getCommentNodes*(gState: State, node: TSNode, maxSearch=1): seq[TSNode] = From 5e7ec3d88c7cf817ec716f4b24e9564906f258f6 Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Thu, 30 Apr 2020 19:25:13 -0600 Subject: [PATCH 458/593] Fix bug with comment generation --- nimterop/getters.nim | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 099faf4..10c3b5e 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -387,6 +387,16 @@ proc getLineCol*(code: var string, node: TSNode): tuple[line, col: int] = proc getLineCol*(gState: State, node: TSNode): tuple[line, col: int] = getLineCol(gState.code, node) +proc getEndLineCol*(code: var string, node: TSNode): tuple[line, col: int] = + # Get line number and column info for node + let + point = node.tsNodeEndPoint() + result.line = point.row.int + 1 + result.col = point.column.int + 1 + +proc getEndLineCol*(gState: State, node: TSNode): tuple[line, col: int] = + getEndLineCol(gState.code, node) + proc getTSNodeNamedChildCountSansComments*(node: TSNode): int = for i in 0 ..< node.len: if node.getName() != "comment": @@ -638,11 +648,12 @@ proc getCommentsStr*(gState: State, commentNodes: seq[TSNode]): string = ## Generate a comment from a set of comment nodes. Comment is guaranteed ## to be able to be rendered using nim doc if commentNodes.len > 0: - const escapeRstReg = re"""(["!#$%&'()*+,-./:;<=>?@[\]^_`{|}~])""" result = "::" for commentNode in commentNodes: - result &= "\n " & gState.getNodeVal(commentNode).replace(escapeRstReg, r"\$1"). - replace(re" *(//|/\*\*|\*\*/|/\*|\*/|\*)", "").replace("\n", "\n ").strip() + result &= "\n " & gState.getNodeVal(commentNode).strip() + + result = result.replace(re" *(//|/\*\*|\*\*/|/\*|\*/|\*)", "") + result = result.multiReplace([("\n", "\n "), ("`", "")]).strip() proc getCommentNodes*(gState: State, node: TSNode, maxSearch=1): seq[TSNode] = ## Get a set of comment nodes in order of priority. Will search up to ``maxSearch`` @@ -666,7 +677,7 @@ proc getCommentNodes*(gState: State, node: TSNode, maxSearch=1): seq[TSNode] = var i = 0 - prevSiblingDistance, nextSiblingDistance: int + prevSiblingDistance, nextSiblingDistance: int = int.high lowestDistance: int commentsFound = false @@ -675,9 +686,15 @@ proc getCommentNodes*(gState: State, node: TSNode, maxSearch=1): seq[TSNode] = # comment belongs to the node. The closer it is in terms of line # numbers, the more we can be sure it's the comment we want if not prevSibling.isNil: - prevSiblingDistance = abs(gState.getLineCol(prevSibling)[0] - line) + if prevSibling.getName() == "comment": + prevSiblingDistance = abs(gState.getEndLineCol(prevSibling)[0] - line) + else: + prevSiblingDistance = int.high if not nextSibling.isNil: - nextSiblingDistance = abs(gState.getLineCol(nextSibling)[0] - line) + if nextSibling.getName() == "comment": + nextSiblingDistance = abs(gState.getLineCol(nextSibling)[0] - line) + else: + nextSiblingDistance = int.high lowestDistance = min(prevSiblingDistance, nextSiblingDistance) @@ -687,7 +704,7 @@ proc getCommentNodes*(gState: State, node: TSNode, maxSearch=1): seq[TSNode] = if nextSiblingDistance > maxSearch: # If the line is out of range, skip searching - prevSibling = nilNode + nextSibling = nilNode # Search above the current line for comments. When one is found # keep going to retrieve successive comments for cases with multiple From 5104eeb5c0da96509c621202ea9e94c371e20933 Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Sun, 3 May 2020 18:40:49 -0600 Subject: [PATCH 459/593] compilerArgs -> nimArgs, fix multi decl comments --- nimterop.nimble | 2 +- nimterop/ast2.nim | 17 ++++++++++++++++- nimterop/docs.nim | 4 ++-- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/nimterop.nimble b/nimterop.nimble index 38a2d5d..702c714 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -25,7 +25,7 @@ proc execTest(test: string, flags = "", runDocs = true) = let docPath = "build/html_" & test.extractFileName.changeFileExt("") & "_docs" rmDir docPath mkDir docPath - buildDocs(@[test], docPath, compilerArgs = flags) + buildDocs(@[test], docPath, nimArgs = flags) task buildToast, "build toast": execCmd("nim c --hints:off nimterop/toast.nim") diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index b51b252..759419c 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -1640,16 +1640,31 @@ proc addDecl(gState: State, node: TSNode) = let start = getStartAtom(node) - commentNodes = gState.getCommentNodes(node) + + var + firstDecl = true + commentNodes: seq[TSNode] for i in start+1 ..< node.len: if not node[i].firstChildInTree("function_declarator").isNil: # Proc declaration - var or actual proc if node[i].getAtom().getPxName(1) == "pointer_declarator": # proc var + if firstDecl: + # If + commentNodes = gState.getCommentNodes(node) + firstDecl = false + else: + commentNodes = gState.getCommentNodes(node[i]) gState.addProcVar(node[i], node[start], commentNodes) else: # proc + if firstDecl: + # If + commentNodes = gState.getCommentNodes(node) + firstDecl = false + else: + commentNodes = gState.getCommentNodes(node[i]) gState.addProc(node[i], node[start], commentNodes) else: # Regular var diff --git a/nimterop/docs.nim b/nimterop/docs.nim index e0fef39..798df52 100644 --- a/nimterop/docs.nim +++ b/nimterop/docs.nim @@ -36,7 +36,7 @@ proc execAction(cmd: string): string = doAssert ret == 0, "Command failed: " & $ret & "\ncmd: " & ccmd & "\nresult:\n" & result proc buildDocs*(files: openArray[string], path: string, baseDir = getProjectPath() & $DirSep, - defines: openArray[string] = @[], compilerArgs = "") = + defines: openArray[string] = @[], nimArgs = "") = ## Generate docs for all specified nim `files` to the specified `path` ## ## `baseDir` is the project path by default and `files` and `path` are relative @@ -70,7 +70,7 @@ proc buildDocs*(files: openArray[string], path: string, baseDir = getProjectPath defStr nim = getCurrentCompilerExe() for file in files: - echo execAction(&"{nim} doc {defStr} {compilerArgs} -o:{path} --project --index:on {baseDir & file}") + echo execAction(&"{nim} doc {defStr} {nimArgs} -o:{path} --project --index:on {baseDir & file}") echo execAction(&"{nim} buildIndex -o:{path}/theindex.html {path}") when declared(getNimRootDir): From 36c7331749a3f2ef87d64edf8dcaed4b79d434fb Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Mon, 4 May 2020 08:07:36 -0600 Subject: [PATCH 460/593] Add nimArgs to buildDocs docstring --- nimterop/docs.nim | 2 ++ 1 file changed, 2 insertions(+) diff --git a/nimterop/docs.nim b/nimterop/docs.nim index 798df52..d5bd50c 100644 --- a/nimterop/docs.nim +++ b/nimterop/docs.nim @@ -45,6 +45,8 @@ proc buildDocs*(files: openArray[string], path: string, baseDir = getProjectPath ## `defines` is a list of `-d:xxx` define flags (the `xxx` part) that should be passed ## to `nim doc` so that `getHeader()` is invoked correctly. ## + ## `nimArgs` is a string representing extra arguments to send to the `nim doc` call. + ## ## Use the `--publish` flag with nimble to publish docs contained in ## `path` to Github in the `gh-pages` branch. This requires the ghp-import ## package for Python: `pip install ghp-import` From 25660ac47532e4a6e0943e20f42ee34b1165a690 Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Mon, 4 May 2020 08:10:46 -0600 Subject: [PATCH 461/593] Fix missing comment in ast2 --- nimterop/ast2.nim | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index 759419c..fd70b46 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -1651,7 +1651,8 @@ proc addDecl(gState: State, node: TSNode) = if node[i].getAtom().getPxName(1) == "pointer_declarator": # proc var if firstDecl: - # If + # If it's the first declaration, use the whole node + # to get the comment above/below commentNodes = gState.getCommentNodes(node) firstDecl = false else: @@ -1660,7 +1661,8 @@ proc addDecl(gState: State, node: TSNode) = else: # proc if firstDecl: - # If + # If it's the first declaration, use the whole node + # to get the comment above/below commentNodes = gState.getCommentNodes(node) firstDecl = false else: From 1f2d7892adc6e63443526bbc263af644bf91893c Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 5 May 2020 11:04:17 -0500 Subject: [PATCH 462/593] Enable -d:checkAbi in tests --- nimterop.nimble | 7 +++++-- tests/getheader.nims | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/nimterop.nimble b/nimterop.nimble index 702c714..bd4521d 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -18,8 +18,11 @@ proc execCmd(cmd: string) = exec "tests/timeit " & cmd proc execTest(test: string, flags = "", runDocs = true) = - execCmd "nim c --hints:off -f " & flags & " -r " & test - execCmd "nim cpp --hints:off " & flags & " -r " & test + execCmd "nim c --hints:off -f -d:checkAbi " & flags & " -r " & test + let + # -d:checkAbi broken in cpp mode until post 1.2.0 + cppAbi = when (NimMajor, NimMinor) >= (1, 3): "-d:checkAbi " else: "" + execCmd "nim cpp --hints:off " & cppAbi & flags & " -r " & test if runDocs: let docPath = "build/html_" & test.extractFileName.changeFileExt("") & "_docs" diff --git a/tests/getheader.nims b/tests/getheader.nims index 987545a..be22967 100644 --- a/tests/getheader.nims +++ b/tests/getheader.nims @@ -14,7 +14,7 @@ proc testCall(cmd, output: string, exitCode: int, delete = true) = doAssert outp.contains(output), outp var - cmd = "nim c -f --hints:off -d:FLAGS=\"-f:ast2\"" + cmd = "nim c -f --hints:off -d:FLAGS=\"-f:ast2\" -d:checkAbi" lrcmd = " -r lzma.nim" zrcmd = " -r zlib.nim" lexp = "liblzma version = " From 3fe6e51780d9d5c789d83060793643c7d9c1ca8d Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 5 May 2020 12:23:16 -0500 Subject: [PATCH 463/593] Fix tast2.h --- nimterop.nimble | 2 +- tests/include/tast2.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/nimterop.nimble b/nimterop.nimble index bd4521d..984d0c5 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -28,7 +28,7 @@ proc execTest(test: string, flags = "", runDocs = true) = let docPath = "build/html_" & test.extractFileName.changeFileExt("") & "_docs" rmDir docPath mkDir docPath - buildDocs(@[test], docPath, nimArgs = flags) + buildDocs(@[test], docPath, nimArgs = "--hints:off " & flags) task buildToast, "build toast": execCmd("nim c --hints:off nimterop/toast.nim") diff --git a/tests/include/tast2.h b/tests/include/tast2.h index e1d4529..2ddb58e 100644 --- a/tests/include/tast2.h +++ b/tests/include/tast2.h @@ -75,7 +75,7 @@ typedef int **(*A12)(int, int b, int *c, int *, int *count[4], int (*func)(int, int)), **(*A121)(float, float b, float *c, float *, float *count[4], float (*func)(float, float)), **(*A122)(char, char b, char *c, char *, char *count[4], char (*func)(char, char)); -typedef int A13(int, int, void (*func)(void)); +typedef int (*A13)(int, int, void (*func)(void)); struct A14 { volatile char a1; }; struct A15 { char *a1; const int *a2[1]; }; From 87eef11ec17713c0eb6f5f17c419216efde79fa8 Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Tue, 5 May 2020 14:47:42 -0600 Subject: [PATCH 464/593] Fix pointer issue and test --- nimterop/exprparser.nim | 10 +++++++++- tests/include/tast2.h | 1 + tests/tast2.nim | 2 ++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/nimterop/exprparser.nim b/nimterop/exprparser.nim index e68c0b1..e85310a 100644 --- a/nimterop/exprparser.nim +++ b/nimterop/exprparser.nim @@ -548,7 +548,15 @@ proc processTSNode(gState: State, node: TSNode, typeofNode: var PNode): PNode = # Input -> true, false # Output -> true, false result = gState.parseString(node.val) - of "type_descriptor", "sized_type_specifier": + of "type_descriptor": + let pointerDecl = node.anyChildInTree("abstract_pointer_declarator") + if pointerDecl.isNil: + result = gState.processTSNode(node[0], typeofNode) + else: + result = nkPtrTy.newTree( + gState.processTSNode(node[0], typeofNode) + ) + of "sized_type_specifier", "primitive_type", "type_identifier": # Input -> int, unsigned int, long int, etc # Output -> cint, cuint, clong, etc let ty = getType(node.val) diff --git a/tests/include/tast2.h b/tests/include/tast2.h index 2ddb58e..c7b85c7 100644 --- a/tests/include/tast2.h +++ b/tests/include/tast2.h @@ -20,6 +20,7 @@ extern "C" { #define COERCE 645635634896ull + 35436 #define COERCE2 645635634896 + 35436ul #define BINEXPR ~(-(1u << !-1)) ^ (10 >> 1) +#define POINTEREXPR (int*)0 #define BOOL true #define MATHEXPR (1 + 2/3*20 - 100) #define ANDEXPR (100 & 11000) diff --git a/tests/tast2.nim b/tests/tast2.nim index 54b89e5..4254a9d 100644 --- a/tests/tast2.nim +++ b/tests/tast2.nim @@ -150,6 +150,8 @@ assert SHL1 == (1.uint shl 1) assert SHL2 == (1.uint shl 2) assert SHL3 == (1.uint shl 3) +assert typeof(POINTEREXPR) is (ptr cint) + assert ALLSHL == (SHL1 or SHL2 or SHL3) assert A0 is object From d5c15d0d3aebc1eced79faa0c1621351be56f60a Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Tue, 5 May 2020 20:36:02 -0600 Subject: [PATCH 465/593] Add multiple pointer support --- nimterop/ast2.nim | 48 --------------------------------------- nimterop/comphelp.nim | 50 ++++++++++++++++++++++++++++++++++++++++- nimterop/exprparser.nim | 6 ++--- tests/include/tast2.h | 1 + tests/tast2.nim | 1 + 5 files changed, 54 insertions(+), 52 deletions(-) diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index fd70b46..4c06cc6 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -8,17 +8,6 @@ import "."/treesitter/api import "."/[comphelp, exprparser, globals, getters, tshelp] -proc getPtrType*(str: string): string = - result = case str: - of "cchar": - "cstring" - of "object": - "pointer" - of "FILE": - "File" - else: - str - proc getOverrideOrSkip(gState: State, node: TSNode, origname: string, kind: NimSymKind): PNode = # Check if symbol `origname` of `kind` and `origname` has any cOverride defined # and use that if present @@ -405,43 +394,6 @@ proc newXIdent(gState: State, node: TSNode, kind = nskType, fname = "", pragmas: else: gecho &"# $1 '{origname}' is duplicate, skipped" % getKeyword(kind) -proc newPtrTree(gState: State, count: int, typ: PNode): PNode = - # Create nkPtrTy tree depending on count - # - # Reduce by 1 if Nim type available for ptr X - e.g. ptr cchar = cstring - result = typ - var - count = count - if typ.kind == nkIdent: - let - tname = typ.ident.s - ptname = getPtrType(tname) - if tname != ptname: - # If Nim type available, use that ident - result = gState.getIdent(ptname, typ.info, exported = false) - # One ptr reduced - count -= 1 - if count > 0: - # Nested nkPtrTy(typ) depending on count - # - # [ptr ...] typ - # - # nkPtrTy( - # nkPtrTy( - # typ - # ) - # ) - var - nresult = newNode(nkPtrTy) - parent = nresult - child: PNode - for i in 1 ..< count: - child = newNode(nkPtrTy) - parent.add child - parent = child - parent.add result - result = nresult - proc newArrayTree(gState: State, node: TSNode, typ, size: PNode = nil): PNode = # Create nkBracketExpr tree depending on input # diff --git a/nimterop/comphelp.nim b/nimterop/comphelp.nim index 1709f8b..18915b0 100644 --- a/nimterop/comphelp.nim +++ b/nimterop/comphelp.nim @@ -15,4 +15,52 @@ proc parseString*(gState: State, str: string): PNode = str, gState.identCache, gState.config, errorHandler = handleError ) except: - decho getCurrentExceptionMsg() \ No newline at end of file + decho getCurrentExceptionMsg() + +proc getPtrType*(str: string): string = + result = case str: + of "cchar": + "cstring" + of "object": + "pointer" + of "FILE": + "File" + else: + str + +proc newPtrTree*(gState: State, count: int, typ: PNode): PNode = + # Create nkPtrTy tree depending on count + # + # Reduce by 1 if Nim type available for ptr X - e.g. ptr cchar = cstring + result = typ + var + count = count + if typ.kind == nkIdent: + let + tname = typ.ident.s + ptname = getPtrType(tname) + if tname != ptname: + # If Nim type available, use that ident + result = gState.getIdent(ptname, typ.info, exported = false) + # One ptr reduced + count -= 1 + if count > 0: + # Nested nkPtrTy(typ) depending on count + # + # [ptr ...] typ + # + # nkPtrTy( + # nkPtrTy( + # typ + # ) + # ) + var + nresult = newNode(nkPtrTy) + parent = nresult + child: PNode + for i in 1 ..< count: + child = newNode(nkPtrTy) + parent.add child + parent = child + parent.add result + result = nresult \ No newline at end of file diff --git a/nimterop/exprparser.nim b/nimterop/exprparser.nim index e85310a..5372c2f 100644 --- a/nimterop/exprparser.nim +++ b/nimterop/exprparser.nim @@ -550,12 +550,12 @@ proc processTSNode(gState: State, node: TSNode, typeofNode: var PNode): PNode = result = gState.parseString(node.val) of "type_descriptor": let pointerDecl = node.anyChildInTree("abstract_pointer_declarator") + if pointerDecl.isNil: result = gState.processTSNode(node[0], typeofNode) else: - result = nkPtrTy.newTree( - gState.processTSNode(node[0], typeofNode) - ) + let pointerCount = pointerDecl.getXCount("abstract_pointer_declarator") + result = gState.newPtrTree(pointerCount, gState.processTSNode(node[0], typeofNode)) of "sized_type_specifier", "primitive_type", "type_identifier": # Input -> int, unsigned int, long int, etc # Output -> cint, cuint, clong, etc diff --git a/tests/include/tast2.h b/tests/include/tast2.h index c7b85c7..0b1fca2 100644 --- a/tests/include/tast2.h +++ b/tests/include/tast2.h @@ -21,6 +21,7 @@ extern "C" { #define COERCE2 645635634896 + 35436ul #define BINEXPR ~(-(1u << !-1)) ^ (10 >> 1) #define POINTEREXPR (int*)0 +#define POINTERPOINTERPOINTEREXPR (int***)0 #define BOOL true #define MATHEXPR (1 + 2/3*20 - 100) #define ANDEXPR (100 & 11000) diff --git a/tests/tast2.nim b/tests/tast2.nim index 4254a9d..6cdd606 100644 --- a/tests/tast2.nim +++ b/tests/tast2.nim @@ -151,6 +151,7 @@ assert SHL2 == (1.uint shl 2) assert SHL3 == (1.uint shl 3) assert typeof(POINTEREXPR) is (ptr cint) +assert typeof(POINTERPOINTERPOINTEREXPR) is (ptr ptr ptr cint) assert ALLSHL == (SHL1 or SHL2 or SHL3) From 4ffb49a531124d6219f594eff3eb6e192528d27a Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Wed, 6 May 2020 07:20:29 -0600 Subject: [PATCH 466/593] Add comment, potentially fix linux test --- nimterop/ast2.nim | 2 +- nimterop/exprparser.nim | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index 4c06cc6..aa0e8d8 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -106,7 +106,7 @@ proc newConstDef(gState: State, node: TSNode, fname = "", fval = ""): PNode = if not maybeTyNode.isNil: let name = maybeTyNode.getName() case name - of "type_descriptor", "sized_type_specifier": + of "type_descriptor", "sized_type_specifier", "primitive_type": discard else: # Can't do gState.parseCExpression(root) here for some reason? diff --git a/nimterop/exprparser.nim b/nimterop/exprparser.nim index 5372c2f..b0c34c1 100644 --- a/nimterop/exprparser.nim +++ b/nimterop/exprparser.nim @@ -549,6 +549,17 @@ proc processTSNode(gState: State, node: TSNode, typeofNode: var PNode): PNode = # Output -> true, false result = gState.parseString(node.val) of "type_descriptor": + # Input => int* + # (type_descriptor 1 2 4 "int*" + # (type_identifier 1 2 3 "int") + # (abstract_pointer_declarator 1 3 1 "*") + # ) + # + # Output => ptr int + # + # nkPtrTy( + # nkIdent("int") + # ) let pointerDecl = node.anyChildInTree("abstract_pointer_declarator") if pointerDecl.isNil: From c7060f4c5598228585f35057b57bc7435c7f09ce Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Wed, 6 May 2020 07:21:34 -0600 Subject: [PATCH 467/593] Add type identifier as ignored too --- nimterop/ast2.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index aa0e8d8..6f05a34 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -106,7 +106,7 @@ proc newConstDef(gState: State, node: TSNode, fname = "", fval = ""): PNode = if not maybeTyNode.isNil: let name = maybeTyNode.getName() case name - of "type_descriptor", "sized_type_specifier", "primitive_type": + of "type_descriptor", "sized_type_specifier", "primitive_type", "type_identifier": discard else: # Can't do gState.parseCExpression(root) here for some reason? From fabb46a639ad38c349e22f5fc0ab37b187772ec3 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 6 May 2020 13:06:18 -0500 Subject: [PATCH 468/593] Set nimconf paths to absolute --- nimterop/nimconf.nim | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/nimterop/nimconf.nim b/nimterop/nimconf.nim index 144a7e0..dca68a8 100644 --- a/nimterop/nimconf.nim +++ b/nimterop/nimconf.nim @@ -95,6 +95,13 @@ proc jsonToSeq(node: JsonNode, key: string): seq[string] = for elem in node[key].getElems(): result.add elem.getStr() +proc getAbsoluteDir(projectDir, path: string): string = + # Path is relative to `projectDir` if not absolute + if path.isAbsolute(): + result = path + else: + result = (projectDir / path).normalizedPath() + proc getNimConfig*(projectDir = ""): Config = # Get `paths` - list of paths to be forwarded to Nim result = new(Config) @@ -146,12 +153,15 @@ proc getNimConfig*(projectDir = ""): Config = # Find non standard lib paths added to `searchPath` for path in searchPaths: + let + path = getAbsoluteDir(projectDir, path) if libPath notin path: result.paths.incl path # Find `nimblePaths` in `lazyPaths` for path in lazyPaths: let + path = getAbsoluteDir(projectDir, path) (_, tail) = path.strip(leading = false, chars = {'/', '\\'}).splitPath() if tail == "pkgs": # Nimble path probably @@ -161,6 +171,8 @@ proc getNimConfig*(projectDir = ""): Config = # Have to do this separately since `nimblePaths` could be after # packages in `lazyPaths` for path in lazyPaths: + let + path = getAbsoluteDir(projectDir, path) var skip = false for npath in result.nimblePaths: if npath in path: From 5a6eb043d28fb03b19c14ce766f166f59fe269ab Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 6 May 2020 15:02:23 -0500 Subject: [PATCH 469/593] global.nim cleanup --- nimterop/globals.nim | 105 +++++++++++++++++++++++++++++++------------ 1 file changed, 76 insertions(+), 29 deletions(-) diff --git a/nimterop/globals.nim b/nimterop/globals.nim index ae9a6d0..21214f3 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -43,6 +43,39 @@ type zeroOrOne # ? orWithNext # ! + PragmaMode* = enum + # includeHeader = true, dynlib = false + # + # Types = {.header, .importc.} + # Static inline = {.header, .importc.} + # Procs = {.header, .importc.} + # Lib = {.compile.} or {.passL.} + useHeader + + # includeHeader = true, dynlib = true + # + # Types = {.header, .importc.} + # Static inline = {.header, .importc.} + # Procs = {.dynlib, importc.} + # Libs = loaded by dynlib + useHeaderDynlib + + # includeHeader = false, dynlib = false + # + # Types = {.bycopy.} + # Static inline = not available + # Procs = {.importc.} + # Lib = {.compile.} or {.passL.} + noHeader + + # includeHeader = false, dynlib = true + # + # Types = {.bycopy.} + # Static inline = not available + # Procs = {.dynlib, importc.} + # Libs = loaded by dynlib + noHeaderDynlib + Ast* = object name*: string kind*: Kind @@ -55,37 +88,51 @@ type AstTable* {.used.} = TableRef[string, seq[ref Ast]] State* = ref object - compile*, defines*, headers*, includeDirs*, searchDirs*, prefix*, suffix*, symOverride*: seq[string] - - debug*, includeHeader*, nocache*, nocomments*, past*, preprocess*, pnim*, recurse*: bool - - code*, convention*, dynlib*, mode*, nim*, overrides*, pluginSource*, pluginSourcePath*: string - + # Command line arguments to toast - some forwarded from cimport.nim + convention*: string # `--convention | -C` to change calling convention from cdecl default + debug*: bool # `cDebug()` or `--debug | -d` to enable debug mode + defines*: seq[string] # Symbols added by `cDefine()` and `--define | -D` for C/C++ preprocessor/compiler + dynlib*: string # `cImport(dynlib)` or `--dynlib | -l` to specify variable containing library name + feature*: seq[Feature] # `--feature | -f` feature flags enabled + includeDirs*: seq[string] # Paths added by `cIncludeDir()` and `--includeDirs | -I` for C/C++ preprocessor/compiler + includeHeader*: bool # `--includeHeader | -H` to include {.header.} pragma to wrapper + mode*: string # `cImport(mode)` or `--mode | -m` to override detected compiler mode - c or cpp + nim*: string # `--nim` to specify full path to Nim compiler + nocomments*: bool # `--nocomments | -c` to disable rendering comments in wrappers + past*: bool # `--past | -a` to print tree-sitter AST of code + pluginSourcePath*: string # `--pluginSourcePath` specified path to plugin file to compile and load + pnim*: bool # `--pnim | -n` to render Nim wrapper for header + preprocess*: bool # `--preprocess | -p` to enable preprocessing of code before wrapping + prefix*: seq[string] # `--prefix` strings to strip from start of identifiers + recurse*: bool # `--recurse | -r` to recurse into #include files in headers specified replace*: OrderedTableRef[string, string] + # `--replace | -G` replacement rules for identifiers + suffix*: seq[string] # `--suffix` strings to strip from end of identifiers + symOverride*: seq[string] # `cSkipSymbol()`, `cOverride()` and `--symOverride | -O` symbols to skip during wrapping - feature*: seq[Feature] + # cimport.nim specific + compile*: seq[string] # `cCompile()` list of files already processed + nocache*: bool # `cDisableCaching()` to disable caching of artifacts + overrides*: string # `cOverride()` code which gets added to `cPlugin()` output + pluginSource*: string # `cPlugin()` generated code to write to plugin file from + searchDirs*: seq[string] # `cSearchPath()` added directories for header search + # Data fields + code*: string # Contents of header file currently being processed + currentHeader*: string # Const name of header being currently processed + impShort*: string # Short base name for pragma in output + outputHandle*: File # `--output | -o` open file handle + sourceFile*: string # Full path of header being currently processed + + # Plugin callbacks onSymbol*, onSymbolOverride*: OnSymbol onSymbolOverrideFinal*: OnSymbolOverrideFinal - outputHandle*: File - - # All symbols that have been declared so far indexed by nimName - identifiers*: TableRef[string, string] - - # All const names for enum casting - constIdentifiers*: HashSet[string] - - # All symbols that have been skipped due to - # being unwrappable or the user provided - # override is blank - skippedSyms*: HashSet[string] - - # Legacy ast fields, remove when ast2 becomes default - constStr*, enumStr*, procStr*, typeStr*: string - - commentStr*, debugStr*, skipStr*: string - + # Symbol tables + constIdentifiers*: HashSet[string] # Const names for enum casting + identifiers*: TableRef[string, string] # Symbols that have been declared so far indexed by nimName + skippedSyms*: HashSet[string] # Symbols that have been skipped due to being unwrappable or + # the user provided override is blank # Nim compiler objects when defined(TOAST): constSection*, enumSection*, pragmaSection*, procSection*, typeSection*, varSection*: PNode @@ -93,16 +140,16 @@ type config*: ConfigRef graph*: ModuleGraph - # Craeted symbols to generated AST - forward declaration tracking + # Table of symbols to generated AST PNode - used to implement forward declarations identifierNodes*: TableRef[string, PNode] - currentHeader*, impShort*, sourceFile*: string - # Used for the exprparser.nim module currentExpr*, currentTyCastName*: string + # Legacy AST fields, remove when ast2 becomes default + constStr*, enumStr*, procStr*, typeStr*: string + commentStr*, debugStr*, skipStr*: string data*: seq[tuple[name, val: string]] - nodeBranch*: seq[string] Feature* = enum From 701a8793c2a30dfcecdf24023be3c8091e724d2c Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Sat, 9 May 2020 02:34:59 -0500 Subject: [PATCH 470/593] Fix #202 - implement noHeader --- CHANGES.md | 8 +- README.md | 61 ++++-- nimterop.nimble | 4 +- nimterop/ast.nim | 6 +- nimterop/ast2.nim | 105 +++++----- nimterop/comphelp.nim | 84 +++++++- nimterop/docs.nim | 4 +- nimterop/getters.nim | 459 ++---------------------------------------- nimterop/globals.nim | 37 +--- nimterop/grammar.nim | 8 +- nimterop/toast.nim | 24 +-- nimterop/tshelp.nim | 354 +++++++++++++++++++++++++++++++- tests/include/tast2.h | 2 +- tests/tast2.nim | 18 +- tests/tpcre.nim | 2 + 15 files changed, 583 insertions(+), 593 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index b02453c..ef66c79 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -14,18 +14,18 @@ https://github.com/nimterop/nimterop/compare/v0.4.4...v0.5.0 ### Breaking changes -- Nimterop now skips generating the `{.header.}` pragma by default in non-dynlib mode. This skips the header file `#include` in the generated code and allows creation of wrappers that do not require presence of the header during compile time. There are cases where this will not work so the `--includeHeader | -H` flag is available to revert to the legacy behavior when required. This change applies to both `ast2` and the legacy backend so if an existing wrapper breaks, test it with `-H` to see if it starts working again. [#169][i169] - -- Nimterop defaulted to C++ mode for preprocessing and tree-sitter parsing in all cases unless explicitly informed to use C mode. This has been changed and is now detected based on the file extension. This means some existing wrappers could break since they might contain C++ code or include C++ headers like `#include ` which will not work in C mode. Explicitly setting `mode = "cpp"` or `-mcpp` should fix such issues. [#176][i176] +- Nimterop used to default to C++ mode for preprocessing and tree-sitter parsing in all cases unless explicitly informed to use C mode. This has been changed and is now detected based on the file extension. This means some existing wrappers could break since they might contain C++ code or include C++ headers like `#include ` which will not work in C mode. Explicitly setting `mode = "cpp"` or `-mcpp` should fix such issues. [#176][i176] - Enums were originally being mapped to `distint int` - this has been changed to `distinct cint` since the sizes are incorrect on 64-bit and is especially noticeable when types or unions have enum fields. -- `static inline` functions are no longer wrapped by the legacy backend. The `ast2` backend correctly generates wrappers for such functions but they are only generated when `--includeHeader | -H` is in effect. This is because such functions do not exist in the binary and can only be referenced when the header is compiled in. +- `static inline` functions are no longer wrapped by the legacy backend. The `ast2` backend correctly generates wrappers for such functions but they are only generated when `--noHeader | -H` is not in effect. This is because such functions do not exist in the binary and can only be referenced when the header is compiled in. - Support for Nim v0.19.6 has been dropped and the test matrix now covers v0.20.2, v1.0.6, v1.2.0 and devel. ### New functionality +- Nimterop can now skip generating the `{.header.}` pragma when the `--noHeader | -H` flag is used. This skips the header file `#include` in the generated code and allows creation of wrappers that do not require presence of the header during compile time. Note that `static inline` functions will only be wrapped when the header is compiled in. This change applies to both `ast2` and the legacy backend, although `ast2` can also generate wrappers with both `{.header.}` and `{.dynlib.}` in effect enabling type size checking with `-d:checkAbi`. More information is available in the [README.md](README.md). [#169][i169] + - `ast2` includes support for various C constructs that were issues with the legacy backend. These changes should reduce the reliance on `cOverride()` and existing wrappers should attempt to clean up such sections where possible. - N-dimensional arrays and pointers - [#54][i54] - Synomyms for types - [#74][i74] diff --git a/README.md b/README.md index 8680048..869ac4e 100644 --- a/README.md +++ b/README.md @@ -69,7 +69,7 @@ else: Module documentation for the build API can be found [here](https://nimterop.github.io/nimterop/build.html). Refer to the ```tests``` directory for additional examples on how the library can be used. Also, check out the [wiki](https://github.com/nimterop/nimterop/wiki/Wrappers) for a list of all known wrappers that have been created using nimterop. They will provide real world examples of how to wrap libraries. Please do add your project once you are done so that others can benefit from your work. -__Download / Search__ +#### Download / Search The above wrapper is generic and allows the end user to control how it works. Note that `headerPath` is derived from `header.h` so if you have `SDL.h` as the argument to `getHeader()`, it generates `SDLPath` and `SDLLPath` and is controlled by `-d:SDLStatic`, `-d:SDLGit` and so forth. @@ -78,19 +78,19 @@ The above wrapper is generic and allows the end user to control how it works. No - The `-d:headerSetVer=X.Y.Z` flag can be used to specify which version to download. It is used as the tag name for Git whereas for DL, it replaces `$1` in the URL if defined. - If no flag is provided, `getHeader()` simply looks for the library in `outdir`. The user could use Git submodules or manually download or check-in the library to that directory and `getHeader()` will use it directly. -__Pre build__ +#### Pre build `getHeader()` provides a `headerPreBuild()` hook that gets called after the library is downloaded but before it is built. This allows for any manipulations of the source files or build scripts before build. [archive](https://github.com/genotrance/nimarchive/blob/master/nimarchive/archive.nim) has such an example. The build API also includes various compile time helper procs that aid in file manipulation, Cmake shortcuts, library linking, etc. Refer to [build](https://nimterop.github.io/nimterop/build.html) for more details. -__Build__ +#### Build Nimterop currently supports `configure` and `cmake` based building of libraries, with `cmake` taking precedence if a project supports both. Nimterop verifies that the tool selected is available and notifies the user if any issues are found. Bash is required on Windows for `configure` and the binary shipped with Git has been tested. Flags can be specified to these tools via `getHeader()` or directly via the underlying `configure()` and `cmake()` calls. Once the build scripts are ready, `getHeader()` then calls `make()`. At every step, `getHeader()` checks for the presence of created artifacts and does not redo steps that have been successfully completed. -__Linking__ +#### Linking - If `-d:headerStatic` is specified, `getHeader()` will return the static library path in `headerLPath`. The wrapper writer can check for this and call `cImport()` accordingly as in the example above. If it is omitted, the dynamic library is returned in `headerLPath`. - `getHeader()` searches for libraries based on the header name by default: @@ -103,7 +103,7 @@ __Linking__ - See [bzlib.nim](https://github.com/genotrance/nimarchive/blob/master/nimarchive/bzlib.nim) for an example. - [lzma.nim](https://github.com/nimterop/nimterop/blob/master/tests/lzma.nim) is an example of a library that allows both static and dynamic linking. -__User control__ +#### User control The `-d:xxxYYY` Nim define flags have already been described above and can be specified on the command line or in a nim.cfg file. It is also possible to specify them within the wrapper itself using `setDefines()` if required. Further, all defines, regardless of how they are specified, can be generically checked using `isDefined()`. @@ -132,7 +132,7 @@ cCompile("clib/src/*.c") # Compile in any implementation source files Module documentation for the wrapper API can be found [here](https://nimterop.github.io/nimterop/cimport.html). -__Preprocessing__ +#### Preprocessing In order to leverage the preprocessor, certain projects might need `cDefine()` calls to set `#define` values. Simpler library may have documentation that cover this but larger ones will rely on build tools that discover and set values in a `config.h` which is loaded with `#include`. Projects might also require some `cIncludeDir()` calls to specify paths to directories that contain other headers. This might be within the library or refer to another library. @@ -140,7 +140,7 @@ The wrapper API always runs headers through the C preprocessor before wrapping. By default, the `$CC` environment variable is used for the compiler path. If not found, `toast` defaults to `gcc`. -__Wrapping__ +#### Wrapping The `cImport()` call invokes the `toast` binary with appropriate command line flags including any `cDefine()` and `cInclude()` parameters configured. The output of `toast` is then pulled into the module as Nim code and printed if `cDebug()` is specified. This allows for an end user to simply import the wrapper into their code and access the library API as Nim types and procs. Output is cached to save time on subsequent runs. It is also possible to just redirect the output to a file and import that instead if preferred. @@ -148,13 +148,44 @@ The `recurse` flag can be set to enable the recursion capability which runs thro There may be cases where the wrapper generated by `toast` for certain types or procs is not preferred, or may be skipped or altogether wrong due to limitations or bugs. In these instances, the `cOverride()` macro can be used to define consts, types or procs to use in place of the wrapper generated output. `cImport()` will forward this information to `toast` and the values will be inserted in context in the generated wrapper. This allows wrapper authors to work around tool limitations or to improve the wrapper output - say change `ptr X` to `var X` or to create more Nim friendly types or proc signatures. -Several C libraries also use leading and/or trailing `_` in identifiers and since Nim does not allow this, the `cPlugin()` macro can be used to modify such symbols or `cSkipSymbol()` them altogether. Instead of a full `cPlugin()` section, it might also be preferred to set `flags = "-E_ -F_"` to the `cImport()` call to trim out such characters. These features can also be used to remove common prefixes like `SDL_` to generate a cleaner wrapper. `cPlugin()` is real Nim code though so anything Nim allows is fair game. Note that `cPlugin()` overrides any `-E -F` flags. Also, behind the scenes, `cOverride()` is communicated to `toast` via `cPlugin()`. +Several C libraries also use leading and/or trailing `_` in identifiers and since Nim does not allow this, the `cPlugin()` macro can be used to modify such symbols or `cSkipSymbol()` them altogether. Instead of a full `cPlugin()` section, it might also be preferred to set `flags = "-E_ -F_"` to the `cImport()` call to trim out such characters. These features can also be used to remove common prefixes like `SDL_` to generate a cleaner wrapper. The `--replace | -G` flag can be used for replacements. `cPlugin()` is real Nim code though so anything Nim allows is fair game. Note that `cPlugin()` overrides any `-E -F -G` flags. Also, behind the scenes, `cOverride()` is communicated to `toast` via `cPlugin()`. If the same `cPlugin()` is needed in multiple wrapper files, the code can be moved into a standalone file and be used with the `cPluginPath()` call. -Lastly, `c2nImport()` provides access to calling `c2nim` from the wrapper instead of `toast`. Note that `c2nImport()` does not use any of the above described features like `cPlugin()` and needs to be controlled with the `flags` param. +Lastly, `c2nImport()` provides access to calling `c2nim` from the wrapper instead of `toast`. Note that `c2nImport()` does not use any of the above described features like `cPlugin()` and needs to be controlled with `c2nim` specific flags via the `flags` param. -__Compiling source__ +#### Header vs. Dynlib + +Nim provides some flexibility when it comes to using C/C++ libraries. In order to understand this better, some Nim pragmas need to be introduced. The main one is `{.importc.}` which informs Nim to use a symbol defined in a C library. This applies to both types and procs but how Nim should find the symbol is slightly different for each. + +For types, `{.header: "header.h".}` informs Nim that `header.h` has the symbol and to `#include "header.h"` in the generated code. However, types can be mostly recreated in pure Nim so it is also possible to omit both `{.importc.}` and `{.header}` and it will work just fine except with a different name in the generated C code. This allows the user to compile the wrapper without requiring `header.h` to be present. + +For functions, `{.header.}` works the same as types and can be omitted if preferred. The `{.importc.}` pragma is still required, unlike types since functions need to be linked to the implementation in the library. The user will need to provide this information at link time with `{.passL.}` and linking to a library with `-lheader` or `path/to/libheader.a`. It is also possible to just use `cCompile()` or `{.compile.}` to compile some C source files which contain the implementation. + +While `{.header.}` can be omitted for convenience, it does prevent wrapping of `static inline` functions as well as type checking of the wrapper ABI with `-d:checkAbi` at compile time. The user will need to choose based on the library in question. + +Going further, the `{.dynlib: "path/to/libheader.so".}` pragma can be used to inform Nim to load the library at runtime and link the function instead of linking at compile time. This enables creation of a wrapper that does not need the library present at compile time. + +Now that this is understood, a user might want any combination of the above in the wrapper rendered by Nimterop. This can be controlled with various flags to `cImport()` and `toast`. +- By default, generated wrappers will include the `{.header, importc.}` pragmas for types and procs. This can be disabled with the `--noHeader | -H` flag to `toast` or `flags = "-H"` param to `cImport()` which will remove `{.header}` for both and `{.importc.}` for types only. +- By default, generated wrappers will assume that the user will link the library implementation themselves. The `--dynlib | -l` flag to `toast` or `dynlib = "headerLPath"` param to `cImport()` will configure the wrapper to generate `{.dynlib.}` pragmas for procs. + +This results in four cases: +1. Default: `{.header, importc.}` for both types and procs +2. With `--noHeader`, types will be pure Nim and procs will be just `{.importc.}` +3. With `--dynlib`, types will still be `{.header, importc.}` but procs will be `{.dynlib, importc.}` +4. With `--dynlib` and `--noHeader`, types will be pure Nim, procs will be `{.dynlib, importc.}` + +While `ast2` supports all these modes, the legacy backend does not support the third mixed case and will infer `--noHeader` when `--dynlib` is specified (case 4). Creation of a standalone wrapper (case 4) which does not require the header or library at compile time will require an explicit `--noHeader` and `--dynlib` for `ast2`. + +More documentation on on these pragmas can be found in the Nim manual: +- [{.importc.}](https://nim-lang.org/docs/manual.html#foreign-function-interface-importc-pragma) +- [{.header.}](https://nim-lang.org/docs/manual.html#implementation-specific-pragmas-header-pragma) +- [{.dynlib.}](https://nim-lang.org/docs/manual.html#foreign-function-interface-dynlib-pragma-for-import) +- [{.passL.}](https://nim-lang.org/docs/manual.html#implementation-specific-pragmas-passl-pragma) +- [{.compile.}](https://nim-lang.org/docs/manual.html#implementation-specific-pragmas-compile-pragma) + +#### Compiling the source The job of building and compiling the underlying C library is best left to the build mechanism selected by the library author so using `getHeader()` is recommended. For simpler projects with a few `.c` files though, `cCompile()` should be more than enough. It is not recommended for larger projects which heavily rely on functionality offered by build tools. Recreating reliable logic in Nim can be tedious and one can expect minimal support from that author if their tested build mechanism is not used. @@ -180,13 +211,13 @@ Options: -d, --debug bool false enable debug output -D=, --defines= strings {} definitions to pass to preprocessor -l=, --dynlib= string "" import symbols from library in specified Nim string - -f=, --feature= Features {} flags to enable experimental features - -H, --includeHeader bool false add {.header.} pragma to wrapper + -f=, --feature= Features ast1 flags to enable experimental features -I=, --includeDirs= strings {} include directory to pass to preprocessor -m=, --mode= string "" language parser: c or cpp --nim= string "nim" use a particular Nim executable - -c, --nocomments bool false exclude top-level comments from output - -o=, --output= string "" file to output content + -c, --noComments bool false exclude top-level comments from output + -H, --noHeader bool false skip {.header.} pragma in wrapper + -o=, --output= string "" file to output content - default: stdout -a, --past bool false print AST output -g, --pgrammar bool false print grammar --pluginSourcePath= string "" nim file to build and load as a plugin @@ -212,7 +243,7 @@ The tree-sitter library is limited though - it may fail on some advanced languag It is debatable whether a syntax highlighting engine like `tree-sitter` is the most reliable method to convert C code into AST. However, it is lightweight, cross-platform with no dependencies and handles error conditions gracefully. It has produced usable wrappers for C libraries though things could get murky when considering C++ but that will be a topic for another day. Nimterop relies heavily on the preprocessor, as discussed next, so having an engine which can run anywhere has been worth the compromise. Only time will tell though. -__Preprocessing__ +### Preprocessing The wrapper API always runs headers through the C preprocessor before wrapping, unlike the command line interface where the `-p | --preprocess` flag is not set by default but *highly* recommended. This is because almost all platform, compiler and package discovery is handled by build tools like `configure` and `cmake` which then use preprocessor `#define` values to tweak what C code is applicable for that platform. While parsing preprocessor macros is possible in tools like `toast`, given how dependent the `#ifdef` branches are on values provided by these and many other build tools, preprocessing seems is best left to them than attempting to self-discover or intercept that information. diff --git a/nimterop.nimble b/nimterop.nimble index 984d0c5..d60224f 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -46,11 +46,13 @@ task docs, "Generate docs": buildDocs(@["nimterop/all.nim"], "build/htmldocs") task test, "Test": + rmFile("tests/timeit.txt") + buildTimeitTask() buildToastTask() execTest "tests/tast2.nim" - execTest "tests/tast2.nim", "-d:HEADER" + execTest "tests/tast2.nim", "-d:NOHEADER" execTest "tests/tnimterop_c.nim" execTest "tests/tnimterop_c.nim", "-d:FLAGS=\"-f:ast2\"" diff --git a/nimterop/ast.nim b/nimterop/ast.nim index 1f1cac6..96116c7 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -2,11 +2,11 @@ import hashes, macros, os, sets, strformat, strutils, tables import regex -import "."/[getters, globals, treesitter/api] +import "."/[getters, globals, treesitter/api, tshelp] proc getHeaderPragma*(gState: State): string = result = - if gState.isIncludeHeader(): + if not gState.noHeader and gState.dynlib.Bl: &", header: {gState.currentHeader}" else: "" @@ -211,7 +211,7 @@ proc parseNim*(gState: State, fullpath: string, root: TSNode, astTable: AstTable gState.impShort = gState.currentHeader.replace("header", "imp") gState.sourceFile = fullpath - if gState.isIncludeHeader(): + if not gState.noHeader and gState.dynlib.Bl: gState.constStr &= &"\n {gState.currentHeader} {{.used.}} = \"{fp}\"" root.searchAst(astTable, gState) diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index 6f05a34..1230e06 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -15,7 +15,7 @@ proc getOverrideOrSkip(gState: State, node: TSNode, origname: string, kind: NimS # If not, symbol needs to be skipped - only get here if `name` is blank let # Get cleaned name for symbol, set parent so that cOverride is ignored - name = gState.getIdentifier(origname, kind, parent = "getOverrideOrSkip") + name = gState.getIdentifier(origname, kind, parent = "IgnoreSkipSymbol") override = gState.getOverride(origname, kind) @@ -244,7 +244,8 @@ proc newXIdent(gState: State, node: TSNode, kind = nskType, fname = "", pragmas: # # If `fname`, use it instead of node.getAtom() for name # If `pragmas`, add as nkPragmaExpr but not for `nskProc` since procs add pragmas elsewhere - # If `istype` is set, this is a typedef, else struct/union so add {.importc: "struct/union X".} when includeHeader + # If `istype` is set, this is a typedef, else struct/union so add {.importc: "struct/union X".} + # when `not noHeader` let atom = node.getAtom() @@ -306,14 +307,14 @@ proc newXIdent(gState: State, node: TSNode, kind = nskType, fname = "", pragmas: # ) var pragmas = - if gState.isIncludeHeader(): + if not gState.noHeader: # Need to add header and importc if istype and name == origname: - # Need to add impShort since neither struct/union nor name change - pragmas & gState.impShort + # Neither struct/union nor name change + pragmas & "importc" & (gState.impShort & "Hdr") else: # Add header shortcut, additional pragmas added later - pragmas & (gState.impShort & "H") + pragmas & (gState.impShort & "Hdr") else: pragmas @@ -323,7 +324,7 @@ proc newXIdent(gState: State, node: TSNode, kind = nskType, fname = "", pragmas: else: ident - if gState.isIncludeHeader(): + if not gState.noHeader: if not istype or name != origname: # Add importc pragma since either struct/union or name changed let @@ -361,18 +362,20 @@ proc newXIdent(gState: State, node: TSNode, kind = nskType, fname = "", pragmas: prident = block: var prident: PNode + # Add {.importc.} pragma if name != origname: - # Add importc pragma since name changed + # Name changed prident = gState.newPragmaExpr(node, ident, "importc", newStrNode(nkStrLit, &"{origname}")) - if gState.isIncludeHeader(): - # Add header - gState.addPragma(node, prident[1], gState.impShort & "H") - elif gState.dynlib.nBl: - # Add dynlib - gState.addPragma(node, prident[1], "dynlib", gState.getIdent(gState.dynlib)) else: - # Only need impShort since no name change - prident = gState.newPragmaExpr(node, ident, gState.impShort) + prident = gState.newPragmaExpr(node, ident, "importc") + + if gState.dynlib.nBl: + # Add {.dynlib.} + gState.addPragma(node, prident[1], gState.impShort & "Dyn") + elif not gState.noHeader: + # Add {.header.} + gState.addPragma(node, prident[1], gState.impShort & "Hdr") + if pragmas.nBl: gState.addPragma(node, prident[1], pragmas) prident @@ -789,7 +792,7 @@ proc addTypeObject(gState: State, node: TSNode, typeDef: PNode = nil, fname = "" npexpr = gState.newPragmaExpr(node, typedef[0], pragmas) typedef[0] = npexpr else: - # includeHeader already added impShort in newXIdent() + # `not gState.noHeader` already added pragmas in newXIdent() gState.addPragma(node, typeDef[0][1], pragmas) # nkTypeSection.add @@ -1552,23 +1555,20 @@ proc addProc(gState: State, node, rnode: TSNode, commentNodes: seq[TSNode]) = gState.newPragma(node, "importc", newStrNode(nkStrLit, origname)) else: # {.impnameC.} shortcut - gState.newPragma(node, gState.impShort & "C") + gState.newPragma(node, "importc") # Detect ... and add {.varargs.} pvarargs = plist.getVarargs() - # Need {.convention.} and {.header.} if applicable - if name != origname: - if gState.isIncludeHeader(): - # {.impnameHC.} shortcut - gState.addPragma(node, prident, gState.impShort & "HC") - else: - # {.convention.} - gState.addPragma(node, prident, gState.convention) + # Need {.convention.} + gState.addPragma(node, prident, gState.convention) - if gState.dynlib.nBl: - # {.dynlib.} for DLLs - gState.addPragma(node, prident, "dynlib", gState.getIdent(gState.dynlib)) + if gState.dynlib.nBl: + # Add {.dynlib.} + gState.addPragma(node, prident, gState.impShort & "Dyn") + elif not gState.noHeader: + # Add {.header.} + gState.addPragma(node, prident, gState.impShort & "Hdr") if pvarargs: # Add {.varargs.} for ... @@ -1637,10 +1637,10 @@ proc addDef(gState: State, node: TSNode) = commentNodes = gState.getCommentNodes(node) if node[start+1].getName() == "function_declarator": - if gState.isIncludeHeader(): + if not gState.noHeader: gState.addProc(node[start+1], node[start], commentNodes) else: - gecho &"\n# proc '$1' skipped - static inline procs require 'includeHeader'" % + gecho &"\n# proc '$1' skipped - static inline procs cannot work with '--noHeader | -H'" % gState.getNodeVal(node[start+1].getAtom()) proc processNode(gState: State, node: TSNode): bool = @@ -1707,50 +1707,35 @@ proc searchTree(gState: State, root: TSNode) = if node == root: break +### +# gState.addPragma(root, impPragma, "importc") +# gState.addPragma(root, impConvPragma, gState.convention) + proc setupPragmas(gState: State, root: TSNode, fullpath: string) = # Create shortcut pragmas to reduce clutter var hdrPragma: PNode - hdrConvPragma: PNode - impPragma = newNode(nkPragma) - impConvPragma = newNode(nkPragma) + dynPragma: PNode - # {.pragma: impname, importc.} - gState.addPragma(root, impPragma, "pragma", gState.getIdent(gState.impShort)) - gState.addPragma(root, impPragma, "importc") - - if gState.isIncludeHeader(): + if not gState.noHeader: # Path to header const gState.constSection.add gState.newConstDef( root, fname = gState.currentHeader, fval = '"' & fullpath & '"') - # {.pragma: impnameH, header: "xxx".} for types when name != origname - hdrPragma = gState.newPragma(root, "pragma", gState.getIdent(gState.impShort & "H")) + # {.pragma: impnameHdr, header: "xxx".} + hdrPragma = gState.newPragma(root, "pragma", gState.getIdent(gState.impShort & "Hdr")) gState.addPragma(root, hdrPragma, "header", gState.getIdent(gState.currentHeader)) - # Add {.impnameH.} to {.impname.} - gState.addPragma(root, impPragma, gState.impShort & "H") - - # {.pragma: impnameHC, impnameH, convention.} for procs when name != origname - hdrConvPragma = gState.newPragma(root, "pragma", gState.getIdent(gState.impShort & "HC")) - gState.addPragma(root, hdrConvPragma, gState.impShort & "H") - gState.addPragma(root, hdrConvPragma, gState.convention) - - # {.pragma: impnameC, impname, convention.} for procs - gState.addPragma(root, impConvPragma, "pragma", gState.getIdent(gState.impShort & "C")) - gState.addPragma(root, impConvPragma, gState.impShort) - gState.addPragma(root, impConvPragma, gState.convention) - if gState.dynlib.nBl: - # {.dynlib.} for DLLs - gState.addPragma(root, impConvPragma, "dynlib", gState.getIdent(gState.dynlib)) + # {.pragma: impnameDyn, dynlib: libname.} + dynPragma = gState.newPragma(root, "pragma", gState.getIdent(gState.impShort & "Dyn")) + gState.addPragma(root, dynPragma, "dynlib", gState.getIdent(gState.dynlib)) - # Add all pragma shortcuts to output + # Add pragma shortcuts to output if not hdrPragma.isNil: gState.pragmaSection.add hdrPragma - gState.pragmaSection.add hdrConvPragma - gState.pragmaSection.add impPragma - gState.pragmaSection.add impConvPragma + if not dynPragma.isNil: + gState.pragmaSection.add dynPragma proc printNimHeader*(gState: State) = # Top level output with context info diff --git a/nimterop/comphelp.nim b/nimterop/comphelp.nim index 18915b0..e577717 100644 --- a/nimterop/comphelp.nim +++ b/nimterop/comphelp.nim @@ -1,6 +1,8 @@ -import compiler/[ast, lineinfos, msgs, options, parser, renderer] +import macros, strutils -import "."/[globals, getters] +import compiler/[ast, idents, lineinfos, msgs, options, parser, pathutils, renderer] + +import "."/[globals, getters, treesitter/api, tshelp] proc handleError*(conf: ConfigRef, info: TLineInfo, msg: TMsgKind, arg: string) = # Raise exception in parseString() instead of exiting for errors @@ -17,6 +19,84 @@ proc parseString*(gState: State, str: string): PNode = except: decho getCurrentExceptionMsg() +proc printTree*(gState: State, pnode: PNode, offset = ""): string = + if not pnode.isNil and gState.debug and pnode.kind != nkNone: + result &= "\n# " & offset & $pnode.kind & "(" + case pnode.kind + of nkCharLit: + result &= ($pnode.intVal.char).escape & ")" + of nkIntLit..nkUInt64Lit: + result &= $pnode.intVal & ")" + of nkFloatLit..nkFloat128Lit: + result &= $pnode.floatVal & ")" + of nkStrLit..nkTripleStrLit: + result &= pnode.strVal.escape & ")" + of nkSym: + result &= $pnode.sym & ")" + of nkIdent: + result &= "\"" & $pnode.ident.s & "\")" + else: + if pnode.sons.len != 0: + for i in 0 ..< pnode.sons.len: + result &= gState.printTree(pnode.sons[i], offset & " ") + if i != pnode.sons.len - 1: + result &= "," + result &= "\n# " & offset & ")" + else: + result &= ")" + if offset.len == 0: + result &= "\n" + +proc printDebug*(gState: State, pnode: PNode) = + if gState.debug and pnode.kind != nkNone: + gecho ("Output => " & $pnode).getCommented() + gecho gState.printTree(pnode) + +proc getDefaultLineInfo*(gState: State): TLineInfo = + result = newLineInfo(gState.config, gState.sourceFile.AbsoluteFile, 0, 0) + +proc getLineInfo*(gState: State, node: TSNode): TLineInfo = + # Get Nim equivalent line:col info from node + let + (line, col) = gState.getLineCol(node) + + result = newLineInfo(gState.config, gState.sourceFile.AbsoluteFile, line, col) + +proc getIdent*(gState: State, name: string, info: TLineInfo, exported = true): PNode = + if name.nBl: + # Get ident PNode for name + info + let + exp = getIdent(gState.identCache, "*") + ident = getIdent(gState.identCache, name) + + if exported: + result = newNode(nkPostfix) + result.add newIdentNode(exp, info) + result.add newIdentNode(ident, info) + else: + result = newIdentNode(ident, info) + +proc getIdent*(gState: State, name: string): PNode = + gState.getIdent(name, gState.getDefaultLineInfo(), exported = false) + +proc getIdentName*(node: PNode): string = + if not node.isNil: + for i in 0 ..< node.len: + if node[i].kind == nkIdent and $node[i] != "*": + result = $node[i] + if result.Bl and node.len > 0: + result = node[0].getIdentName() + +proc getNameInfo*(gState: State, node: TSNode, kind: NimSymKind, parent = ""): + tuple[name, origname: string, info: TLineInfo] = + # Shortcut to get identifier name and info (node value and line:col) + result.origname = gState.getNodeVal(node) + result.name = gState.getIdentifier(result.origname, kind, parent) + if result.name.nBl: + if kind == nskType: + result.name = result.name.getType() + result.info = gState.getLineInfo(node) + proc getPtrType*(str: string): string = result = case str: of "cchar": diff --git a/nimterop/docs.nim b/nimterop/docs.nim index d5bd50c..6c2bbfd 100644 --- a/nimterop/docs.nim +++ b/nimterop/docs.nim @@ -74,13 +74,13 @@ proc buildDocs*(files: openArray[string], path: string, baseDir = getProjectPath for file in files: echo execAction(&"{nim} doc {defStr} {nimArgs} -o:{path} --project --index:on {baseDir & file}") - echo execAction(&"{nim} buildIndex -o:{path}/theindex.html {path}") + echo execAction(&"{nim} buildIndex {nimArgs} -o:{path}/theindex.html {path}") when declared(getNimRootDir): #[ this enables doc search, works at least locally with: cd {path} && python -m SimpleHTTPServer 9009 ]# - echo execAction(&"{nim} js -o:{path}/dochack.js {getNimRootDir()}/tools/dochack/dochack.nim") + echo execAction(&"{nim} js {nimArgs} -o:{path}/dochack.js {getNimRootDir()}/tools/dochack/dochack.nim") for i in 0 .. paramCount(): if paramStr(i) == "--publish": diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 10c3b5e..12d08eb 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -2,9 +2,7 @@ import dynlib, macros, os, sequtils, sets, strformat, strutils, tables, times import regex -import compiler/[ast, idents, lineinfos, msgs, pathutils, renderer] - -import "."/[build, globals, plugin, treesitter/api] +import "."/[build, globals, plugin] const gReserved = """ addr and as asm @@ -135,7 +133,12 @@ proc checkIdentifier(name, kind, parent, origName: string) = doAssert (not name.contains("__")): errmsg & " consecutive underscores '_'" - if parent.nBl: + # Cannot blank out symbols which are fields or params + # + # `IgnoreSkipSymbol` is used to `getIdentifier()` even if symbol is in `symOverride` list + # so that any prefix/suffix/replace or `onSymbol()` processing can occur. This is only used + # for `cOverride()` since it also depends on `symOverride`. + if parent.nBl and parent != "IgnoreSkipSymbol": doAssert name.nBl, &"Blank identifier, originally '{parentStr}{origName}' ({kind}), cannot be empty" proc getIdentifier*(gState: State, name: string, kind: NimSymKind, parent=""): string = @@ -211,7 +214,7 @@ proc getOverride*(gState: State, name: string, kind: NimSymKind): string = if gState.onSymbolOverride != nil: var - nname = gState.getIdentifier(name, kind, "Override") + nname = gState.getIdentifier(name, kind, "IgnoreSkipSymbol") sym = Symbol(name: nname, kind: kind) if nname.nBl: gState.onSymbolOverride(sym) @@ -236,327 +239,12 @@ proc getKeyword*(kind: NimSymKind): string = # cOverride procs already include `proc` keyword result = ($kind).replace("nsk", "").toLowerAscii() -# TSNode shortcuts - -proc isNil*(node: TSNode): bool = - node.tsNodeIsNull() - -proc len*(node: TSNode): int = - if not node.isNil: - result = node.tsNodeNamedChildCount().int - -proc `[]`*(node: TSNode, i: SomeInteger): TSNode = - if i < type(i)(node.len()): - result = node.tsNodeNamedChild(i.uint32) - -proc getName*(node: TSNode): string {.inline.} = - if not node.isNil: - return $node.tsNodeType() - -proc getNodeVal*(code: var string, node: TSNode): string = - if not node.isNil: - return code[node.tsNodeStartByte() .. node.tsNodeEndByte()-1].strip() - -proc getNodeVal*(gState: State, node: TSNode): string = - gState.code.getNodeVal(node) - -proc getAtom*(node: TSNode): TSNode = - if not node.isNil: - # Get child node which is topmost atom - if node.getName() in gAtoms: - return node - elif node.len != 0: - if node[0].getName() == "type_qualifier": - # Skip const, volatile - if node.len > 1: - return node[1].getAtom() - else: - return - else: - return node[0].getAtom() - -proc getStartAtom*(node: TSNode): int = - if not node.isNil: - # Skip const, volatile and other type qualifiers - for i in 0 .. node.len - 1: - if node[i].getAtom().getName() notin gAtoms: - result += 1 - else: - break - -proc getXCount*(node: TSNode, ntype: string, reverse = false): int = - if not node.isNil: - # Get number of ntype nodes nested in tree - var - cnode = node - while ntype in cnode.getName(): - result += 1 - if reverse: - cnode = cnode.tsNodeParent() - else: - if cnode.len != 0: - if cnode[0].getName() == "type_qualifier": - # Skip const, volatile - if cnode.len > 1: - cnode = cnode[1] - else: - break - else: - cnode = cnode[0] - else: - break - -proc getPtrCount*(node: TSNode, reverse = false): int = - node.getXCount("pointer_declarator") - -proc getArrayCount*(node: TSNode, reverse = false): int = - node.getXCount("array_declarator") - -proc getDeclarator*(node: TSNode): TSNode = - if not node.isNil: - # Return if child is a function or array declarator - if node.getName() in ["function_declarator", "array_declarator"]: - return node - elif node.len != 0: - return node[0].getDeclarator() - -proc getVarargs*(node: TSNode): bool = - # Detect ... and add {.varargs.} - # - # `node` is the param list - # - # ... is an unnamed node, second last node and ) is last node - let - nlen = node.tsNodeChildCount() - if nlen > 1.uint32: - let - nval = node.tsNodeChild(nlen - 2.uint32).getName() - if nval == "...": - result = true - -proc firstChildInTree*(node: TSNode, ntype: string): TSNode = - # Search for node type in tree - first children - var - cnode = node - while not cnode.isNil: - if cnode.getName() == ntype: - return cnode - cnode = cnode[0] - -proc anyChildInTree*(node: TSNode, ntype: string): TSNode = - # Search for node type anywhere in tree - depth first - var - cnode = node - while not cnode.isNil: - if cnode.getName() == ntype: - return cnode - for i in 0 ..< cnode.len: - let - ccnode = cnode[i].anyChildInTree(ntype) - if not ccnode.isNil: - return ccnode - if cnode != node: - cnode = cnode.tsNodeNextNamedSibling() - else: - break - -proc mostNestedChildInTree*(node: TSNode): TSNode = - # Search for the most nested child of node's type in tree - var - cnode = node - ntype = cnode.getName() - while not cnode.isNil and cnode.len != 0 and cnode[0].getName() == ntype: - cnode = cnode[0] - result = cnode - -proc inChildren*(node: TSNode, ntype: string): bool = - # Search for node type in immediate children - result = false - for i in 0 ..< node.len: - if (node[i]).getName() == ntype: - result = true - break - -proc getLineCol*(code: var string, node: TSNode): tuple[line, col: int] = - # Get line number and column info for node - let - point = node.tsNodeStartPoint() - result.line = point.row.int + 1 - result.col = point.column.int + 1 - -proc getLineCol*(gState: State, node: TSNode): tuple[line, col: int] = - getLineCol(gState.code, node) - -proc getEndLineCol*(code: var string, node: TSNode): tuple[line, col: int] = - # Get line number and column info for node - let - point = node.tsNodeEndPoint() - result.line = point.row.int + 1 - result.col = point.column.int + 1 - -proc getEndLineCol*(gState: State, node: TSNode): tuple[line, col: int] = - getEndLineCol(gState.code, node) - -proc getTSNodeNamedChildCountSansComments*(node: TSNode): int = - for i in 0 ..< node.len: - if node.getName() != "comment": - result += 1 - -proc getPxName*(node: TSNode, offset: int): string = - # Get the xth (grand)parent of the node - var - np = node - count = 0 - - while not np.isNil and count < offset: - np = np.tsNodeParent() - count += 1 - - if count == offset and not np.isNil: - return np.getName() - -proc printLisp*(code: var string, root: TSNode): string = - var - node = root - nextnode: TSNode - depth = 0 - - while true: - if not node.isNil and depth > -1: - result &= spaces(depth) - let - (line, col) = code.getLineCol(node) - result &= &"({$node.tsNodeType()} {line} {col} {node.tsNodeEndByte() - node.tsNodeStartByte()}" - let - val = code.getNodeVal(node) - if "\n" notin val and " " notin val: - result &= &" \"{val}\"" - else: - break - - if node.len() != 0: - result &= "\n" - nextnode = node[0] - depth += 1 - else: - result &= ")\n" - nextnode = node.tsNodeNextNamedSibling() - - if nextnode.isNil: - while true: - node = node.tsNodeParent() - depth -= 1 - if depth == -1: - break - result &= spaces(depth) & ")\n" - if node == root: - break - if not node.tsNodeNextNamedSibling().isNil: - node = node.tsNodeNextNamedSibling() - break - else: - node = nextnode - - if node == root: - break - -proc printLisp*(gState: State, root: TSNode): string = - printLisp(gState.code, root) - -proc getCommented*(str: string): string = - "\n# " & str.strip().replace("\n", "\n# ") - -proc printTree*(gState: State, pnode: PNode, offset = ""): string = - if not pnode.isNil and gState.debug and pnode.kind != nkNone: - result &= "\n# " & offset & $pnode.kind & "(" - case pnode.kind - of nkCharLit: - result &= ($pnode.intVal.char).escape & ")" - of nkIntLit..nkUInt64Lit: - result &= $pnode.intVal & ")" - of nkFloatLit..nkFloat128Lit: - result &= $pnode.floatVal & ")" - of nkStrLit..nkTripleStrLit: - result &= pnode.strVal.escape & ")" - of nkSym: - result &= $pnode.sym & ")" - of nkIdent: - result &= "\"" & $pnode.ident.s & "\")" - else: - if pnode.sons.len != 0: - for i in 0 ..< pnode.sons.len: - result &= gState.printTree(pnode.sons[i], offset & " ") - if i != pnode.sons.len - 1: - result &= "," - result &= "\n# " & offset & ")" - else: - result &= ")" - if offset.len == 0: - result &= "\n" - -proc printDebug*(gState: State, node: TSNode) = - if gState.debug: - gecho ("Input => " & gState.getNodeVal(node)).getCommented() - gecho gState.printLisp(node).getCommented() - -proc printDebug*(gState: State, pnode: PNode) = - if gState.debug and pnode.kind != nkNone: - gecho ("Output => " & $pnode).getCommented() - gecho gState.printTree(pnode) - -# Compiler shortcuts - -proc getDefaultLineInfo*(gState: State): TLineInfo = - result = newLineInfo(gState.config, gState.sourceFile.AbsoluteFile, 0, 0) - -proc getLineInfo*(gState: State, node: TSNode): TLineInfo = - # Get Nim equivalent line:col info from node - let - (line, col) = gState.getLineCol(node) - - result = newLineInfo(gState.config, gState.sourceFile.AbsoluteFile, line, col) - -proc getIdent*(gState: State, name: string, info: TLineInfo, exported = true): PNode = - if name.nBl: - # Get ident PNode for name + info - let - exp = getIdent(gState.identCache, "*") - ident = getIdent(gState.identCache, name) - - if exported: - result = newNode(nkPostfix) - result.add newIdentNode(exp, info) - result.add newIdentNode(ident, info) - else: - result = newIdentNode(ident, info) - -proc getIdent*(gState: State, name: string): PNode = - gState.getIdent(name, gState.getDefaultLineInfo(), exported = false) - -proc getIdentName*(node: PNode): string = - if not node.isNil: - for i in 0 ..< node.len: - if node[i].kind == nkIdent and $node[i] != "*": - result = $node[i] - if result.Bl and node.len > 0: - result = node[0].getIdentName() - -proc getNameInfo*(gState: State, node: TSNode, kind: NimSymKind, parent = ""): - tuple[name, origname: string, info: TLineInfo] = - # Shortcut to get identifier name and info (node value and line:col) - result.origname = gState.getNodeVal(node) - result.name = gState.getIdentifier(result.origname, kind, parent) - if result.name.nBl: - if kind == nskType: - result.name = result.name.getType() - result.info = gState.getLineInfo(node) - proc getCurrentHeader*(fullpath: string): string = ("header" & fullpath.splitFile().name.multiReplace([(".", ""), ("-", "")])) proc getPreprocessor*(gState: State, fullpath: string): string = var - cmts = if gState.nocomments: "" else: "-CC" + cmts = if gState.noComments: "" else: "-CC" cmd = &"""{getCompiler()} -E {cmts} -dD {getGccModeArg(gState.mode)} -w """ rdata: seq[string] = @[] @@ -644,118 +332,6 @@ proc getNameKind*(name: string): tuple[name: string, kind: Kind, recursive: bool if result.kind != exactlyOne: result.name = result.name[0 .. ^2] -proc getCommentsStr*(gState: State, commentNodes: seq[TSNode]): string = - ## Generate a comment from a set of comment nodes. Comment is guaranteed - ## to be able to be rendered using nim doc - if commentNodes.len > 0: - result = "::" - for commentNode in commentNodes: - result &= "\n " & gState.getNodeVal(commentNode).strip() - - result = result.replace(re" *(//|/\*\*|\*\*/|/\*|\*/|\*)", "") - result = result.multiReplace([("\n", "\n "), ("`", "")]).strip() - -proc getCommentNodes*(gState: State, node: TSNode, maxSearch=1): seq[TSNode] = - ## Get a set of comment nodes in order of priority. Will search up to ``maxSearch`` - ## nodes before and after the current node - ## - ## Priority is (closest line number) > comment before > comment after. - ## This priority might need to be changed based on the project, but - ## for now it is good enough - - # Skip this if we don't want comments - if gState.nocomments: - return - - let (line, _) = gState.getLineCol(node) - - # Keep track of both directions from a node - var - prevSibling = node.tsNodePrevNamedSibling() - nextSibling = node.tsNodeNextNamedSibling() - nilNode: TSNode - - var - i = 0 - prevSiblingDistance, nextSiblingDistance: int = int.high - lowestDistance: int - commentsFound = false - - while not commentsFound and i < maxSearch: - # Distance from the current node will tell us approximately if the - # comment belongs to the node. The closer it is in terms of line - # numbers, the more we can be sure it's the comment we want - if not prevSibling.isNil: - if prevSibling.getName() == "comment": - prevSiblingDistance = abs(gState.getEndLineCol(prevSibling)[0] - line) - else: - prevSiblingDistance = int.high - if not nextSibling.isNil: - if nextSibling.getName() == "comment": - nextSiblingDistance = abs(gState.getLineCol(nextSibling)[0] - line) - else: - nextSiblingDistance = int.high - - lowestDistance = min(prevSiblingDistance, nextSiblingDistance) - - if prevSiblingDistance > maxSearch: - # If the line is out of range, skip searching - prevSibling = nilNode # Can't do `= nil` - - if nextSiblingDistance > maxSearch: - # If the line is out of range, skip searching - nextSibling = nilNode - - # Search above the current line for comments. When one is found - # keep going to retrieve successive comments for cases with multiple - # `//` style comments - while ( - not prevSibling.isNil and - prevSibling.getName() == "comment" and - prevSiblingDistance == lowestDistance - ): - # Put the previous nodes in reverse order so the comments - # make logical sense - result.insert(prevSibling, 0) - prevSibling = prevSibling.tsNodePrevNamedSibling() - commentsFound = true - - # If we've already found comments above the current line, quit - if commentsFound: - break - - # Search below or at the current line for comments. When one is found - # keep going to retrieve successive comments for cases with multiple - # `//` style comments - while ( - not nextSibling.isNil and - nextSibling.getName() == "comment" and - nextSiblingDistance == lowestDistance - ): - result.add(nextSibling) - nextSibling = nextSibling.tsNodeNextNamedSibling() - commentsFound = true - - if commentsFound: - break - - # Go to next sibling pair - if not prevSibling.isNil: - prevSibling = prevSibling.tsNodePrevNamedSibling() - if not nextSibling.isNil: - nextSibling = nextSibling.tsNodeNextNamedSibling() - - i += 1 - -proc getTSNodeNamedChildNames*(node: TSNode): seq[string] = - if node.tsNodeNamedChildCount() != 0: - for i in 0 .. node.tsNodeNamedChildCount()-1: - let - name = $node.tsNodeNamedChild(i).tsNodeType() - - if name != "comment": - result.add(name) - proc getRegexForAstChildren*(ast: ref Ast): string = result = "^" for i in 0 .. ast.children.len-1: @@ -837,20 +413,15 @@ proc getNimExpression*(gState: State, expr: string, name = ""): string = ("<<", " shl "), (">>", " shr ") ]) -proc getSplitComma*(joined: seq[string]): seq[string] = - for i in joined: - result = result.concat(i.split(",")) - -template isIncludeHeader*(gState: State): bool = - gState.dynlib.Bl and gState.includeHeader - proc getComments*(gState: State, strip = false): string = - if not gState.nocomments and gState.commentStr.nBl: + if not gState.noComments and gState.commentStr.nBl: result = "\n" & gState.commentStr if strip: result = result.replace("\n ", "\n") gState.commentStr = "" +# Plugin related + proc dll*(path: string): string = let (dir, name, _) = path.splitFile() @@ -888,6 +459,12 @@ proc loadPlugin*(gState: State, sourcePath: string) = gState.onSymbolOverrideFinal = cast[OnSymbolOverrideFinal](lib.symAddr("onSymbolOverrideFinal")) +# Misc toast helpers + +proc getSplitComma*(joined: seq[string]): seq[string] = + for i in joined: + result = result.concat(i.split(",")) + proc expandSymlinkAbs*(path: string): string = try: result = path.expandFilename().normalizedPath() diff --git a/nimterop/globals.nim b/nimterop/globals.nim index 21214f3..05f507c 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -43,39 +43,6 @@ type zeroOrOne # ? orWithNext # ! - PragmaMode* = enum - # includeHeader = true, dynlib = false - # - # Types = {.header, .importc.} - # Static inline = {.header, .importc.} - # Procs = {.header, .importc.} - # Lib = {.compile.} or {.passL.} - useHeader - - # includeHeader = true, dynlib = true - # - # Types = {.header, .importc.} - # Static inline = {.header, .importc.} - # Procs = {.dynlib, importc.} - # Libs = loaded by dynlib - useHeaderDynlib - - # includeHeader = false, dynlib = false - # - # Types = {.bycopy.} - # Static inline = not available - # Procs = {.importc.} - # Lib = {.compile.} or {.passL.} - noHeader - - # includeHeader = false, dynlib = true - # - # Types = {.bycopy.} - # Static inline = not available - # Procs = {.dynlib, importc.} - # Libs = loaded by dynlib - noHeaderDynlib - Ast* = object name*: string kind*: Kind @@ -95,10 +62,10 @@ type dynlib*: string # `cImport(dynlib)` or `--dynlib | -l` to specify variable containing library name feature*: seq[Feature] # `--feature | -f` feature flags enabled includeDirs*: seq[string] # Paths added by `cIncludeDir()` and `--includeDirs | -I` for C/C++ preprocessor/compiler - includeHeader*: bool # `--includeHeader | -H` to include {.header.} pragma to wrapper mode*: string # `cImport(mode)` or `--mode | -m` to override detected compiler mode - c or cpp nim*: string # `--nim` to specify full path to Nim compiler - nocomments*: bool # `--nocomments | -c` to disable rendering comments in wrappers + noComments*: bool # `--noComments | -c` to disable rendering comments in wrappers + noHeader*: bool # `--noHeader | -H` to skip {.header.} pragma in wrapper past*: bool # `--past | -a` to print tree-sitter AST of code pluginSourcePath*: string # `--pluginSourcePath` specified path to plugin file to compile and load pnim*: bool # `--pnim | -n` to render Nim wrapper for header diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index eaa337a..e061a70 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -2,7 +2,7 @@ import macros, strformat, strutils, tables import regex -import "."/[ast, getters, globals, lisp, treesitter/api] +import "."/[ast, getters, globals, lisp, treesitter/api, tshelp] type Grammar = seq[tuple[grammar: string, call: proc(ast: ref Ast, node: TSNode, gState: State) {.nimcall.}]] @@ -180,7 +180,7 @@ proc initGrammar(): Grammar = var i = 0 - typ = gState.getIdentifier(gState.data[i].val, nskType, "Parent").getType() + typ = gState.getIdentifier(gState.data[i].val, nskType, "IgnoreSkipSymbol").getType() name = "" nname = "" tptr = "" @@ -202,7 +202,7 @@ proc initGrammar(): Grammar = nname = gState.getIdentifier(name, nskType) i += 1 - if gState.isIncludeHeader(): + if not gState.noHeader and gState.dynlib.Bl: pragmas.add gState.getImportC(name, nname) let @@ -318,7 +318,7 @@ proc initGrammar(): Grammar = else: var pragmas: seq[string] = @[] - if gState.isIncludeHeader(): + if not gState.noHeader and gState.dynlib.Bl: pragmas.add gState.getImportC(prefix & name, nname) pragmas.add "bycopy" if union.nBl: diff --git a/nimterop/toast.nim b/nimterop/toast.nim index 78708f5..d74838a 100644 --- a/nimterop/toast.nim +++ b/nimterop/toast.nim @@ -34,11 +34,11 @@ proc main( defines: seq[string] = @[], dynlib: string = "", feature: seq[Feature] = @[Feature.ast1], - includeHeader = false, includeDirs: seq[string] = @[], mode = "", nim: string = "nim", - nocomments = false, + noComments = false, + noHeader = false, output = "", past = false, pgrammar = false, @@ -61,11 +61,11 @@ proc main( defines: defines, dynlib: dynlib, feature: feature, - includeHeader: includeHeader, includeDirs: includeDirs, mode: mode, nim: nim, - nocomments: nocomments, + noComments: noComments, + noHeader: noHeader, past: past, pluginSourcePath: pluginSourcePath, pnim: pnim, @@ -77,10 +77,6 @@ proc main( symOverride: symOverride ) - # Fail if both includeHeader and dynlib - doAssert not (includeHeader == true and dynlib.nBl), - "`includeHeader` and `dynlib` cannot be used simultaneously" - # Set gDebug in build.nim build.gDebug = debug @@ -196,16 +192,16 @@ when isMainModule: import cligen dispatch(main, help = { "check": "check generated wrapper with compiler", - "convention": "calling convention for wrapped procs - default: cdecl", + "convention": "calling convention for wrapped procs", "debug": "enable debug output", "defines": "definitions to pass to preprocessor", "dynlib": "import symbols from library in specified Nim string", "feature": "flags to enable experimental features", - "includeHeader": "add {.header.} pragma to wrapper", "includeDirs": "include directory to pass to preprocessor", "mode": "language parser: c or cpp", - "nim": "use a particular Nim executable - default: $PATH/nim", - "nocomments": "exclude top-level comments from output", + "nim": "use a particular Nim executable", + "noComments": "exclude top-level comments from output", + "noHeader": "skip {.header.} pragma in wrapper", "output": "file to output content - default: stdout", "past": "print AST output", "pgrammar": "print grammar", @@ -226,9 +222,9 @@ when isMainModule: "defines": 'D', "dynlib": 'l', "feature": 'f', - "includeHeader": 'H', "includeDirs": 'I', - "nocomments": 'c', + "noComments": 'c', + "noHeader": 'H', "output": 'o', "past": 'a', "pgrammar": 'g', diff --git a/nimterop/tshelp.nim b/nimterop/tshelp.nim index 109321c..762cf7c 100644 --- a/nimterop/tshelp.nim +++ b/nimterop/tshelp.nim @@ -1,4 +1,9 @@ -import "."/treesitter/[c, cpp] +import sets, strformat, strutils + +import regex + +import "."/[getters, globals] +import "."/treesitter/[api, c, cpp] template withCodeAst*(code: string, mode: string, body: untyped): untyped = ## A simple template to inject the TSNode into a body of code @@ -25,4 +30,349 @@ template withCodeAst*(code: string, mode: string, body: untyped): untyped = body defer: - tree.tsTreeDelete() \ No newline at end of file + tree.tsTreeDelete() + +proc getCommented*(str: string): string = + "\n# " & str.strip().replace("\n", "\n# ") + +proc isNil*(node: TSNode): bool = + node.tsNodeIsNull() + +proc len*(node: TSNode): int = + if not node.isNil: + result = node.tsNodeNamedChildCount().int + +proc `[]`*(node: TSNode, i: SomeInteger): TSNode = + if i < type(i)(node.len()): + result = node.tsNodeNamedChild(i.uint32) + +proc getName*(node: TSNode): string {.inline.} = + if not node.isNil: + return $node.tsNodeType() + +proc getNodeVal*(code: var string, node: TSNode): string = + if not node.isNil: + return code[node.tsNodeStartByte() .. node.tsNodeEndByte()-1].strip() + +proc getNodeVal*(gState: State, node: TSNode): string = + gState.code.getNodeVal(node) + +proc getAtom*(node: TSNode): TSNode = + if not node.isNil: + # Get child node which is topmost atom + if node.getName() in gAtoms: + return node + elif node.len != 0: + if node[0].getName() == "type_qualifier": + # Skip const, volatile + if node.len > 1: + return node[1].getAtom() + else: + return + else: + return node[0].getAtom() + +proc getStartAtom*(node: TSNode): int = + if not node.isNil: + # Skip const, volatile and other type qualifiers + for i in 0 .. node.len - 1: + if node[i].getAtom().getName() notin gAtoms: + result += 1 + else: + break + +proc getXCount*(node: TSNode, ntype: string, reverse = false): int = + if not node.isNil: + # Get number of ntype nodes nested in tree + var + cnode = node + while ntype in cnode.getName(): + result += 1 + if reverse: + cnode = cnode.tsNodeParent() + else: + if cnode.len != 0: + if cnode[0].getName() == "type_qualifier": + # Skip const, volatile + if cnode.len > 1: + cnode = cnode[1] + else: + break + else: + cnode = cnode[0] + else: + break + +proc getPtrCount*(node: TSNode, reverse = false): int = + node.getXCount("pointer_declarator") + +proc getArrayCount*(node: TSNode, reverse = false): int = + node.getXCount("array_declarator") + +proc getDeclarator*(node: TSNode): TSNode = + if not node.isNil: + # Return if child is a function or array declarator + if node.getName() in ["function_declarator", "array_declarator"]: + return node + elif node.len != 0: + return node[0].getDeclarator() + +proc getVarargs*(node: TSNode): bool = + # Detect ... and add {.varargs.} + # + # `node` is the param list + # + # ... is an unnamed node, second last node and ) is last node + let + nlen = node.tsNodeChildCount() + if nlen > 1.uint32: + let + nval = node.tsNodeChild(nlen - 2.uint32).getName() + if nval == "...": + result = true + +proc firstChildInTree*(node: TSNode, ntype: string): TSNode = + # Search for node type in tree - first children + var + cnode = node + while not cnode.isNil: + if cnode.getName() == ntype: + return cnode + cnode = cnode[0] + +proc anyChildInTree*(node: TSNode, ntype: string): TSNode = + # Search for node type anywhere in tree - depth first + var + cnode = node + while not cnode.isNil: + if cnode.getName() == ntype: + return cnode + for i in 0 ..< cnode.len: + let + ccnode = cnode[i].anyChildInTree(ntype) + if not ccnode.isNil: + return ccnode + if cnode != node: + cnode = cnode.tsNodeNextNamedSibling() + else: + break + +proc mostNestedChildInTree*(node: TSNode): TSNode = + # Search for the most nested child of node's type in tree + var + cnode = node + ntype = cnode.getName() + while not cnode.isNil and cnode.len != 0 and cnode[0].getName() == ntype: + cnode = cnode[0] + result = cnode + +proc inChildren*(node: TSNode, ntype: string): bool = + # Search for node type in immediate children + result = false + for i in 0 ..< node.len: + if (node[i]).getName() == ntype: + result = true + break + +proc getLineCol*(code: var string, node: TSNode): tuple[line, col: int] = + # Get line number and column info for node + let + point = node.tsNodeStartPoint() + result.line = point.row.int + 1 + result.col = point.column.int + 1 + +proc getLineCol*(gState: State, node: TSNode): tuple[line, col: int] = + getLineCol(gState.code, node) + +proc getEndLineCol*(code: var string, node: TSNode): tuple[line, col: int] = + # Get line number and column info for node + let + point = node.tsNodeEndPoint() + result.line = point.row.int + 1 + result.col = point.column.int + 1 + +proc getEndLineCol*(gState: State, node: TSNode): tuple[line, col: int] = + getEndLineCol(gState.code, node) + +proc getTSNodeNamedChildCountSansComments*(node: TSNode): int = + for i in 0 ..< node.len: + if node.getName() != "comment": + result += 1 + +proc getPxName*(node: TSNode, offset: int): string = + # Get the xth (grand)parent of the node + var + np = node + count = 0 + + while not np.isNil and count < offset: + np = np.tsNodeParent() + count += 1 + + if count == offset and not np.isNil: + return np.getName() + +proc printLisp*(code: var string, root: TSNode): string = + var + node = root + nextnode: TSNode + depth = 0 + + while true: + if not node.isNil and depth > -1: + result &= spaces(depth) + let + (line, col) = code.getLineCol(node) + result &= &"({$node.tsNodeType()} {line} {col} {node.tsNodeEndByte() - node.tsNodeStartByte()}" + let + val = code.getNodeVal(node) + if "\n" notin val and " " notin val: + result &= &" \"{val}\"" + else: + break + + if node.len() != 0: + result &= "\n" + nextnode = node[0] + depth += 1 + else: + result &= ")\n" + nextnode = node.tsNodeNextNamedSibling() + + if nextnode.isNil: + while true: + node = node.tsNodeParent() + depth -= 1 + if depth == -1: + break + result &= spaces(depth) & ")\n" + if node == root: + break + if not node.tsNodeNextNamedSibling().isNil: + node = node.tsNodeNextNamedSibling() + break + else: + node = nextnode + + if node == root: + break + +proc printLisp*(gState: State, root: TSNode): string = + printLisp(gState.code, root) + +proc printDebug*(gState: State, node: TSNode) = + if gState.debug: + gecho ("Input => " & gState.getNodeVal(node)).getCommented() + gecho gState.printLisp(node).getCommented() + +proc getCommentsStr*(gState: State, commentNodes: seq[TSNode]): string = + ## Generate a comment from a set of comment nodes. Comment is guaranteed + ## to be able to be rendered using nim doc + if commentNodes.len > 0: + result = "::" + for commentNode in commentNodes: + result &= "\n " & gState.getNodeVal(commentNode).strip() + + result = result.replace(re" *(//|/\*\*|\*\*/|/\*|\*/|\*)", "") + result = result.multiReplace([("\n", "\n "), ("`", "")]).strip() + +proc getCommentNodes*(gState: State, node: TSNode, maxSearch=1): seq[TSNode] = + ## Get a set of comment nodes in order of priority. Will search up to ``maxSearch`` + ## nodes before and after the current node + ## + ## Priority is (closest line number) > comment before > comment after. + ## This priority might need to be changed based on the project, but + ## for now it is good enough + + # Skip this if we don't want comments + if gState.noComments: + return + + let (line, _) = gState.getLineCol(node) + + # Keep track of both directions from a node + var + prevSibling = node.tsNodePrevNamedSibling() + nextSibling = node.tsNodeNextNamedSibling() + nilNode: TSNode + + var + i = 0 + prevSiblingDistance, nextSiblingDistance: int = int.high + lowestDistance: int + commentsFound = false + + while not commentsFound and i < maxSearch: + # Distance from the current node will tell us approximately if the + # comment belongs to the node. The closer it is in terms of line + # numbers, the more we can be sure it's the comment we want + if not prevSibling.isNil: + if prevSibling.getName() == "comment": + prevSiblingDistance = abs(gState.getEndLineCol(prevSibling)[0] - line) + else: + prevSiblingDistance = int.high + if not nextSibling.isNil: + if nextSibling.getName() == "comment": + nextSiblingDistance = abs(gState.getLineCol(nextSibling)[0] - line) + else: + nextSiblingDistance = int.high + + lowestDistance = min(prevSiblingDistance, nextSiblingDistance) + + if prevSiblingDistance > maxSearch: + # If the line is out of range, skip searching + prevSibling = nilNode # Can't do `= nil` + + if nextSiblingDistance > maxSearch: + # If the line is out of range, skip searching + nextSibling = nilNode + + # Search above the current line for comments. When one is found + # keep going to retrieve successive comments for cases with multiple + # `//` style comments + while ( + not prevSibling.isNil and + prevSibling.getName() == "comment" and + prevSiblingDistance == lowestDistance + ): + # Put the previous nodes in reverse order so the comments + # make logical sense + result.insert(prevSibling, 0) + prevSibling = prevSibling.tsNodePrevNamedSibling() + commentsFound = true + + # If we've already found comments above the current line, quit + if commentsFound: + break + + # Search below or at the current line for comments. When one is found + # keep going to retrieve successive comments for cases with multiple + # `//` style comments + while ( + not nextSibling.isNil and + nextSibling.getName() == "comment" and + nextSiblingDistance == lowestDistance + ): + result.add(nextSibling) + nextSibling = nextSibling.tsNodeNextNamedSibling() + commentsFound = true + + if commentsFound: + break + + # Go to next sibling pair + if not prevSibling.isNil: + prevSibling = prevSibling.tsNodePrevNamedSibling() + if not nextSibling.isNil: + nextSibling = nextSibling.tsNodeNextNamedSibling() + + i += 1 + +proc getTSNodeNamedChildNames*(node: TSNode): seq[string] = + if node.tsNodeNamedChildCount() != 0: + for i in 0 .. node.tsNodeNamedChildCount()-1: + let + name = $node.tsNodeNamedChild(i).tsNodeType() + + if name != "comment": + result.add(name) diff --git a/tests/include/tast2.h b/tests/include/tast2.h index 0b1fca2..878a3a2 100644 --- a/tests/include/tast2.h +++ b/tests/include/tast2.h @@ -247,7 +247,7 @@ static inline int sitest1(int f1) { // DUPLICATES -#ifndef HEADER +#ifdef NOHEADER #define A 1 #define B 1.0 diff --git a/tests/tast2.nim b/tests/tast2.nim index 6cdd606..bd040e2 100644 --- a/tests/tast2.nim +++ b/tests/tast2.nim @@ -11,17 +11,17 @@ static: const path = currentSourcePath.parentDir() / "include" / "tast2.h" -when defined(HEADER): - cDefine("HEADER") +when defined(NOHEADER): + cDefine("NOHEADER") const flags = " -H" - pHeader = @["header:" & path.replace("\\", "/")] - pHeaderImp = @["importc"] & pHeader + pHeader: seq[string] = @[] + pHeaderImp: seq[string] = @[] else: const flags = "" - pHeader: seq[string] = @[] - pHeaderImp: seq[string] = @[] + pHeader = @["header:" & path.replace("\\", "/")] + pHeaderImp = @["importc"] & pHeader const pHeaderImpBy = @["bycopy"] & pHeaderImp @@ -68,7 +68,7 @@ macro checkPragmas(t: typed, pragmas: static[seq[string]], istype: static[bool] ast = t.getImpl() prag = ast.getPragmas() exprag = pragmas.toHashSet() - when defined(HEADER): + when not defined(NOHEADER): if not istype: if "union" in exprag: exprag.incl "importc:union " & $t @@ -169,7 +169,7 @@ a1.f1 = 2 assert A2 is object testFields(A2) checkPragmas(A2, pHeaderInc, istype = false) -when not defined(HEADER): +when defined(NOHEADER): # typedef struct X; is invalid var a2: A2 @@ -475,6 +475,6 @@ assert nested is object testFields(nested, "f1|f2|f3|f4|f5|f6|f7|f8!NT1|Type_tast2h1|NT3|Type_tast2h3|NU2|Union_tast2h1|NE1|Enum_tast2h2") checkPragmas(nested, pHeaderImpBy) -when defined(HEADER): +when not defined(NOHEADER): assert sitest1(5) == 10 assert sitest1(10) == 20 diff --git a/tests/tpcre.nim b/tests/tpcre.nim index 51530c1..4a3badb 100644 --- a/tests/tpcre.nim +++ b/tests/tpcre.nim @@ -28,6 +28,8 @@ cPlugin: proc onSymbol*(sym: var Symbol) {.exportc, dynlib.} = sym.name = sym.name.replace("pcre_", "") + if sym.name.startsWith("pcre16_") or sym.name.startsWith("pcre32_"): + sym.name = "" const FLAGS {.strdefine.} = "" cImport(pcreH, dynlib="dynpcre", flags="--mode=c " & FLAGS) From e2125768f4a1e03ee7acd11303a293b64e235b97 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Sat, 9 May 2020 17:40:49 -0500 Subject: [PATCH 471/593] Fix #207 - better error message --- nimterop/getters.nim | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 12d08eb..f1d1866 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -127,11 +127,12 @@ proc checkIdentifier(name, kind, parent, origName: string) = if name.nBl: let origStr = if name != origName: &", originally '{origName}' before 'cPlugin:onSymbol()', still" else: "" - errmsg = &"Identifier '{parentStr}{name}' ({kind}){origStr} contains" + errmsg = &"Identifier '{parentStr}{name}' ({kind}){origStr} contains $1 " & + "which Nim does not allow. Use toast flag '$2' or 'cPlugin()' to modify." - doAssert name[0] != '_' and name[^1] != '_', errmsg & " leading/trailing underscores '_'" + doAssert name[0] != '_' and name[^1] != '_', errmsg % ["leading/trailing underscores '_'", "--prefix or --suffix"] - doAssert (not name.contains("__")): errmsg & " consecutive underscores '_'" + doAssert (not name.contains("__")): errmsg % ["consecutive underscores '_'", "--replace"] # Cannot blank out symbols which are fields or params # From 865ac56c20c6683b2a352aec6263dc9c817899c5 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Sun, 10 May 2020 01:49:05 -0500 Subject: [PATCH 472/593] Fix lib version regex --- nimterop.nimble | 6 ++---- nimterop/build.nim | 8 ++++---- tests/getheader.nims | 10 +++++----- 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/nimterop.nimble b/nimterop.nimble index d60224f..21221a7 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -82,10 +82,8 @@ task test, "Test": # getHeader tests withDir("tests"): exec "nim e getheader.nims" - when not defined(Windows): - # Skip on Windows since very slow - if not existsEnv("APPVEYOR"): - exec "nim e wrappers.nims" + if not existsEnv("APPVEYOR"): + exec "nim e wrappers.nims" docsTask() diff --git a/nimterop/build.nim b/nimterop/build.nim index ece2e33..5978074 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -859,11 +859,11 @@ proc buildLibrary(lname, outdir, conFlags, cmakeFlags, makeFlags: string, buildT proc getDynlibExt(): string = when defined(Windows): - result = ".dll" + result = "[0-9.\\-]*\\.dll" elif defined(linux) or defined(FreeBSD): - result = ".so[0-9.]*" + result = "\\.so[0-9.]*" elif defined(macosx): - result = ".dylib[0-9.]*" + result = "\\.dylib[0-9.]*" var gDefines {.compileTime.} = initTable[string, string]() @@ -1007,7 +1007,7 @@ macro getHeader*(header: static[string], giturl: static[string] = "", dlurl: sta preBuild = newIdentNode(name & "PreBuild") # Regex for library search - lre = "(lib)?$1[_-]?(static)?[0-9.\\-]*\\" + lre = "(lib)?$1[_-]?(static)?" # If -d:xxx set with setDefines() stdVal = gDefines.hasKey(stdStr) diff --git a/tests/getheader.nims b/tests/getheader.nims index be22967..5d3b427 100644 --- a/tests/getheader.nims +++ b/tests/getheader.nims @@ -35,11 +35,6 @@ when defined(posix): testCall(cmd & " -d:lzmaGit -d:lzmaSetVer=v5.2.0" & lrcmd, lexp & "5.2.0", 0) testCall(cmd & " -d:lzmaGit -d:lzmaStatic -d:lzmaSetVer=v5.2.0" & lrcmd, lexp & "5.2.0", 0, delete = false) - # dl - remove from Windows to save some time - testCall(cmd & " -d:lzmaDL" & lrcmd, "Need version", 1) - testCall(cmd & " -d:lzmaDL -d:lzmaSetVer=5.2.4" & lrcmd, lexp & "5.2.4", 0) - testCall(cmd & " -d:lzmaDL -d:lzmaStatic -d:lzmaSetVer=5.2.4" & lrcmd, lexp & "5.2.4", 0, delete = false) - # git testCall(cmd & " -d:envTest" & zrcmd, zexp, 0) testCall(cmd & " -d:envTestStatic" & zrcmd, zexp, 0, delete = false) @@ -48,6 +43,11 @@ testCall(cmd & " -d:envTestStatic" & zrcmd, zexp, 0, delete = false) testCall(cmd & " -d:zlibGit -d:zlibSetVer=v1.2.10" & zrcmd, zexp & "1.2.10", 0) testCall(cmd & " -d:zlibGit -d:zlibStatic -d:zlibSetVer=v1.2.10" & zrcmd, zexp & "1.2.10", 0, delete = false) +# dl +testCall(cmd & " -d:lzmaDL" & lrcmd, "Need version", 1) +testCall(cmd & " -d:lzmaDL -d:lzmaSetVer=5.2.4" & lrcmd, lexp & "5.2.4", 0) +testCall(cmd & " -d:lzmaDL -d:lzmaStatic -d:lzmaSetVer=5.2.4" & lrcmd, lexp & "5.2.4", 0, delete = false) + # dl testCall(cmd & " -d:zlibDL -d:zlibSetVer=1.2.11" & zrcmd, zexp & "1.2.11", 0) testCall(cmd & " -d:zlibDL -d:zlibStatic -d:zlibSetVer=1.2.11" & zrcmd, zexp & "1.2.11", 0, delete = false) From 3719607355d7041d8f258280395b4830c9765f54 Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Sun, 10 May 2020 10:42:01 -0600 Subject: [PATCH 473/593] Don't call bash for unix because it can mess up the configure script --- nimterop/build.nim | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/nimterop/build.nim b/nimterop/build.nim index 5978074..48557f3 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -482,8 +482,12 @@ proc configure*(path, check: string, flags = "") = if fileExists(path / i): echo "# Running autogen.sh" - echoDebug execAction( - &"cd {(path / i).parentDir().sanitizePath} && bash ./autogen.sh").output + when defined(unix): + echoDebug execAction( + &"cd {(path / i).parentDir().sanitizePath} && ./autogen.sh").output + else: + echoDebug execAction( + &"cd {(path / i).parentDir().sanitizePath} && bash ./autogen.sh").output break @@ -499,8 +503,12 @@ proc configure*(path, check: string, flags = "") = if fileExists(path / "configure"): echo "# Running configure " & flags - var - cmd = &"cd {path.sanitizePath} && bash ./configure" + when defined(unix): + var + cmd = &"cd {path.sanitizePath} && ./configure" + else: + var + cmd = &"cd {path.sanitizePath} && bash ./configure" if flags.len != 0: cmd &= &" {flags}" From f693c3e30af162c2a2f377d8b540fe9c34e248fb Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Sun, 10 May 2020 20:08:07 -0500 Subject: [PATCH 474/593] Fix #209 - cache return val, fix nimcache dir --- nimterop/build.nim | 11 ++++++++--- nimterop/nimconf.nim | 21 ++++++++++++++------- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/nimterop/build.nim b/nimterop/build.nim index 48557f3..b02132d 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -91,18 +91,22 @@ proc execAction*(cmd: string, retry = 0, die = true, cache = false, # Else cache for preserving functionality in nimsuggest and nimcheck let hash = (ccmd & cacheKey).hash().abs() - cacheFile = getNimteropCacheDir() / "execCache" / "nimterop_" & $hash & ".txt" + cachePath = getNimteropCacheDir() / "execCache" / "nimterop_" & $hash + cacheFile = cachePath & ".txt" + retFile = cachePath & "_ret.txt" when defined(nimsuggest) or defined(nimcheck): # Load results from cache file if generated in previous run - if fileExists(cacheFile): + if fileExists(cacheFile) and fileExists(retFile): result.output = cacheFile.readFile() + result.ret = retFile.readFile().parseInt() elif die: doAssert false, "Results not cached - run nim c/cpp at least once\n" & ccmd else: - if cache and fileExists(cacheFile) and not compileOption("forceBuild"): + if cache and fileExists(cacheFile) and fileExists(retFile) and not compileOption("forceBuild"): # Return from cache when requested result.output = cacheFile.readFile() + result.ret = retFile.readFile().parseInt() else: # Execute command and store results in cache (result.output, result.ret) = gorgeEx(ccmd) @@ -113,6 +117,7 @@ proc execAction*(cmd: string, retry = 0, die = true, cache = false, let flag = when not defined(Windows): "-p" else: "" discard execAction(&"mkdir {flag} {dir.sanitizePath}") cacheFile.writeFile(result.output) + retFile.writeFile($result.ret) else: # Used by toast (result.output, result.ret) = execCmdEx(ccmd) diff --git a/nimterop/nimconf.nim b/nimterop/nimconf.nim index dca68a8..2a54d7e 100644 --- a/nimterop/nimconf.nim +++ b/nimterop/nimconf.nim @@ -58,12 +58,24 @@ proc getProjectDir*(): string = else: discard +proc stripName(path, projectName: string): string = + # Remove `pname_d|r` tail from path + let + (head, tail) = path.splitPath() + if projectName in tail: + result = head + else: + result = path + proc getNimcacheDir*(projectDir = ""): string = ## Get nimcache directory for current compilation or specified `projectDir` when nimvm: when (NimMajor, NimMinor, NimPatch) >= (1, 2, 0): # Get value at compile time from `std/compilesettings` - result = querySetting(SingleValueSetting.nimcacheDir) + result = stripName( + querySetting(SingleValueSetting.nimcacheDir), + querySetting(SingleValueSetting.projectName) + ) else: discard @@ -78,12 +90,7 @@ proc getNimcacheDir*(projectDir = ""): string = dumpJson = getJson(projectDir) if dumpJson != nil and dumpJson.hasKey("nimcache"): - result = dumpJson["nimcache"].getStr() - let - (head, tail) = result.splitPath() - if "dummy" in tail: - # Remove `dummy_d` subdir when default nimcache - result = head + result = stripName(dumpJson["nimcache"].getStr(), "dummy") # Set to OS defaults if not detectable if result.len == 0: From b14eedb541d76aa08066dbc3527ef89ce968e7c2 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 11 May 2020 11:38:09 -0500 Subject: [PATCH 475/593] Support Bool, print debug filename --- nimterop/getters.nim | 5 ++++- nimterop/toast.nim | 3 +++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/nimterop/getters.nim b/nimterop/getters.nim index f1d1866..f834370 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -103,7 +103,10 @@ const # floating point "float": "cfloat", "double": "cdouble", - "long double": "clongdouble" + "long double": "clongdouble", + + # Misc Nim types + "Bool": "bool" }.toTable() # Nim type names that shouldn't need to be wrapped again diff --git a/nimterop/toast.nim b/nimterop/toast.nim index d74838a..a4fe6fa 100644 --- a/nimterop/toast.nim +++ b/nimterop/toast.nim @@ -114,6 +114,9 @@ proc main( doAssert gState.outputHandle.open(outputFile, fmWrite), &"Failed to write to {outputFile}" + if gState.debug: + echo &"# Writing output to {outputFile}\n" + # Process grammar into AST let astTable = From 7daf32d654a2ef0d8751e486f16b306ee5cc22e4 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 11 May 2020 13:08:54 -0500 Subject: [PATCH 476/593] Add reorder pragma for #209, cleanup header pragma --- nimterop/ast2.nim | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index 1230e06..d1e691b 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -1718,13 +1718,9 @@ proc setupPragmas(gState: State, root: TSNode, fullpath: string) = dynPragma: PNode if not gState.noHeader: - # Path to header const - gState.constSection.add gState.newConstDef( - root, fname = gState.currentHeader, fval = '"' & fullpath & '"') - # {.pragma: impnameHdr, header: "xxx".} hdrPragma = gState.newPragma(root, "pragma", gState.getIdent(gState.impShort & "Hdr")) - gState.addPragma(root, hdrPragma, "header", gState.getIdent(gState.currentHeader)) + gState.addPragma(root, hdrPragma, "header", newStrNode(nkStrLit, fullpath)) if gState.dynlib.nBl: # {.pragma: impnameDyn, dynlib: libname.} @@ -1737,6 +1733,9 @@ proc setupPragmas(gState: State, root: TSNode, fullpath: string) = if not dynPragma.isNil: gState.pragmaSection.add dynPragma + # Add `{.experimental: "codeReordering".} for #206 + gState.pragmaSection.add gState.newPragma(root, "experimental", newStrNode(nkStrLit, "codeReordering")) + proc printNimHeader*(gState: State) = # Top level output with context info gecho """# Generated at $1 @@ -1793,9 +1792,9 @@ proc printNim*(gState: State) = # Create output to Nim using Nim compiler renderer var tree = newNode(nkStmtList) + tree.add gState.pragmaSection tree.add gState.enumSection tree.add gState.constSection - tree.add gState.pragmaSection tree.add gState.typeSection tree.add gState.varSection tree.add gState.procSection From ecb5f2ede6bbc793c81ce3bc0f1ea973deb95d2a Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 11 May 2020 14:31:54 -0500 Subject: [PATCH 477/593] v0.5.1 --- nimterop.nimble | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nimterop.nimble b/nimterop.nimble index 21221a7..6a5cced 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -1,6 +1,6 @@ # Package -version = "0.5.0" +version = "0.5.1" author = "genotrance" description = "C/C++ interop for Nim" license = "MIT" @@ -87,4 +87,4 @@ task test, "Test": docsTask() - echo readFile("tests/timeit.txt") \ No newline at end of file + echo readFile("tests/timeit.txt") From 8d4866160ef91084ea13b526694e56ce9c805dd2 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 11 May 2020 16:49:44 -0500 Subject: [PATCH 478/593] Fix #196 - allow remapping of types --- CHANGES.md | 2 ++ README.md | 1 + nimterop/getters.nim | 2 +- nimterop/globals.nim | 2 ++ nimterop/toast.nim | 17 ++++++++++++++--- tests/include/tast2.h | 12 ++++++++++++ tests/tast2.nim | 7 ++++++- 7 files changed, 38 insertions(+), 5 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index ef66c79..01080a6 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -56,6 +56,8 @@ https://github.com/nimterop/nimterop/compare/v0.4.4...v0.5.0 - `toast` now includes `--replace | -G` to manipulate identifier names beyond `--prefix` and `--suffix`. `-G:X=Y` replaces X with Y and `-G:@_[_]+=_` replaces multiple `_` with a single instance using the `@` prefix to enable regular expressions. +- `toast` also includes `--typeMap | -T` to map C types to another type. E.g. `--typeMap:GLint64=int64` generates a wrapper where all instances of `GLint64` are remapped to the Nim type `int64` and `GLint64` is not defined. (since v0.5.2) + - Nimterop is now able to detect Nim configuration of projects and can better handle cases where defaults such as `nimcacheDir` or `nimblePath` are overridden. This especially enables better interop with workflows that do not depend on Nimble. [#151][i151] [#153][i153] - Nimterop defaults to `cmake`, followed by `autoconf` for building libraries with `getHeader()`. It is now possible to change the order of discovery with the `buildType` value. [#200][i200] diff --git a/README.md b/README.md index 869ac4e..11952e8 100644 --- a/README.md +++ b/README.md @@ -229,6 +229,7 @@ Options: -s, --stub bool false stub out undefined type references as objects -F=, --suffix= strings {} strip suffix from identifiers -O=, --symOverride= strings {} skip generating specified symbols + -T=, --typeMap= strings {} map instances of type X to Y - e.g. ABC=cint ``` ## Why nimterop diff --git a/nimterop/getters.nim b/nimterop/getters.nim index f834370..e600b18 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -28,7 +28,7 @@ yield""".split(Whitespace).toHashSet() # Types related -const +var gTypeMap* = { # char "char": "cchar", diff --git a/nimterop/globals.nim b/nimterop/globals.nim index 05f507c..46203ea 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -76,6 +76,8 @@ type # `--replace | -G` replacement rules for identifiers suffix*: seq[string] # `--suffix` strings to strip from end of identifiers symOverride*: seq[string] # `cSkipSymbol()`, `cOverride()` and `--symOverride | -O` symbols to skip during wrapping + typeMap*: TableRef[string, string] + # `--typeMap | -T` to map instances of type X to Y - e.g. ABC=cint # cimport.nim specific compile*: seq[string] # `cCompile()` list of files already processed diff --git a/nimterop/toast.nim b/nimterop/toast.nim index a4fe6fa..3a58749 100644 --- a/nimterop/toast.nim +++ b/nimterop/toast.nim @@ -1,4 +1,4 @@ -import os, osproc, strformat, strutils, tables, times +import os, osproc, sets, strformat, strutils, tables, times import "."/treesitter/[api, c, cpp] @@ -51,6 +51,7 @@ proc main( stub = false, suffix: seq[string] = @[], symOverride: seq[string] = @[], + typeMap: seq[string] = @[], source: seq[string] ) = @@ -93,6 +94,14 @@ proc main( value = if nv.len == 2: nv[1] else: "" gState.replace[name] = value + # typeMap => getters.gTypeMap + for i in typeMap.getSplitComma(): + let + nv = i.split("=", maxsplit = 1) + doAssert nv.len == 2, "`--typeMap` requires X=Y format" + gTypeMap[nv[0]] = nv[1] + gTypeMapValues.incl nv[1] + if pluginSourcePath.nBl: gState.loadPlugin(pluginSourcePath) @@ -217,7 +226,8 @@ when isMainModule: "source" : "C/C++ source/header", "stub": "stub out undefined type references as objects", "suffix": "strip suffix from identifiers", - "symOverride": "skip generating specified symbols" + "symOverride": "skip generating specified symbols", + "typeMap": "map instances of type X to Y - e.g. ABC=cint" }, short = { "check": 'k', "convention": 'C', @@ -238,5 +248,6 @@ when isMainModule: "replace": 'G', "stub": 's', "suffix": 'F', - "symOverride": 'O' + "symOverride": 'O', + "typeMap": 'T' }) diff --git a/tests/include/tast2.h b/tests/include/tast2.h index 878a3a2..bbb3315 100644 --- a/tests/include/tast2.h +++ b/tests/include/tast2.h @@ -243,6 +243,12 @@ static inline int sitest1(int f1) { return f1 * 2; } +// Issue #196 +typedef int MyInt; +struct TestMyInt { + MyInt f1; +}; + // DUPLICATES @@ -439,6 +445,12 @@ static inline int sitest1(int f1) { return f1 * 2; } +// Issue #196 +typedef int MyInt; +struct TestMyInt { + MyInt f1; +}; + #endif diff --git a/tests/tast2.nim b/tests/tast2.nim index bd040e2..4fd16cc 100644 --- a/tests/tast2.nim +++ b/tests/tast2.nim @@ -35,7 +35,7 @@ cOverride: type A1* = A0 -cImport(path, flags="-f:ast2 -ENK_,SDL_ -GVICE=SLICE" & flags) +cImport(path, flags="-f:ast2 -ENK_,SDL_ -GVICE=SLICE -TMyInt=cint" & flags) proc getPragmas(n: NimNode): HashSet[string] = # Find all pragmas in AST, return as "name" or "name:value" in set @@ -478,3 +478,8 @@ checkPragmas(nested, pHeaderImpBy) when not defined(NOHEADER): assert sitest1(5) == 10 assert sitest1(10) == 20 + +when declared(MyInt): + assert false, "MyInt is defined!" +testFields(TestMyInt, "f1!cint") +checkPragmas(TestMyInt, pHeaderBy, isType = false) \ No newline at end of file From 8e052269c996ac1e50bce6643604ab8128e921c3 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 11 May 2020 23:58:18 -0500 Subject: [PATCH 479/593] v0.5.2 --- nimterop.nimble | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimterop.nimble b/nimterop.nimble index 6a5cced..2a8c269 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -1,6 +1,6 @@ # Package -version = "0.5.1" +version = "0.5.2" author = "genotrance" description = "C/C++ interop for Nim" license = "MIT" From 37fa2ad7fb69553ec37d5e4b46988feaca7f80f1 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 12 May 2020 22:01:42 -0500 Subject: [PATCH 480/593] Add CLI file feature --- CHANGES.md | 3 +++ README.md | 4 ++-- nimterop.nimble | 4 ++-- nimterop/ast2.nim | 14 ++------------ nimterop/toast.nim | 26 ++++++++++++++++++++++++-- tests/toast.cfg | 2 ++ 6 files changed, 35 insertions(+), 18 deletions(-) create mode 100644 tests/toast.cfg diff --git a/CHANGES.md b/CHANGES.md index 01080a6..ea3f427 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -58,6 +58,8 @@ https://github.com/nimterop/nimterop/compare/v0.4.4...v0.5.0 - `toast` also includes `--typeMap | -T` to map C types to another type. E.g. `--typeMap:GLint64=int64` generates a wrapper where all instances of `GLint64` are remapped to the Nim type `int64` and `GLint64` is not defined. (since v0.5.2) +- CLI flags can now be specified one or more per line in a file and path provided to `toast`. They will be expanded in place. [#196][i196] (since v0.5.3) + - Nimterop is now able to detect Nim configuration of projects and can better handle cases where defaults such as `nimcacheDir` or `nimblePath` are overridden. This especially enables better interop with workflows that do not depend on Nimble. [#151][i151] [#153][i153] - Nimterop defaults to `cmake`, followed by `autoconf` for building libraries with `getHeader()`. It is now possible to change the order of discovery with the `buildType` value. [#200][i200] @@ -78,5 +80,6 @@ https://github.com/nimterop/nimterop/compare/v0.4.4...v0.5.0 [i174]: https://github.com/nimterop/nimterop/issues/174 [i176]: https://github.com/nimterop/nimterop/issues/176 [i181]: https://github.com/nimterop/nimterop/issues/181 +[i196]: https://github.com/nimterop/nimterop/issues/196 [i197]: https://github.com/nimterop/nimterop/issues/197 [i200]: https://github.com/nimterop/nimterop/issues/200 \ No newline at end of file diff --git a/README.md b/README.md index 11952e8..48822ac 100644 --- a/README.md +++ b/README.md @@ -195,14 +195,14 @@ Nimterop also provides a [docs](https://nimterop.github.io/nimterop/docs.html) A ### Command line API -The `toast` binary can also be used directly on the CLI, similar to `c2nim`. The `cPlugin()` interface +The `toast` binary can also be used directly on the CLI, similar to `c2nim`. These flags can be specified on the command line or via a file, one or more flags per line, and the path provided to `toast` instead, or a combination. The file contents will be expanded in place. Note: unlike the wrapper API, the `-p | --preprocess` flag is not enabled by default but is *highly* recommended. ``` > toast -h Usage: - main [optional-params] C/C++ source/header + main [optional-params] C/C++ source/header(s) and command line file(s) Options: -h, --help print this cligen-erated help --help-syntax advanced: prepend,plurals,.. diff --git a/nimterop.nimble b/nimterop.nimble index 2a8c269..4ec024c 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -59,8 +59,8 @@ task test, "Test": execTest "tests/tnimterop_c.nim", "-d:FLAGS=\"-f:ast2 -H\"" execCmd "nim cpp --hints:off -f -r tests/tnimterop_cpp.nim" - execCmd "./nimterop/toast -pnk -E=_ tests/include/toast.h" - execCmd "./nimterop/toast -pnk -E=_ -f:ast2 tests/include/toast.h" + execCmd "./nimterop/toast tests/toast.cfg tests/include/toast.h" + execCmd "./nimterop/toast tests/toast.cfg -f:ast2 tests/include/toast.h" execTest "tests/tpcre.nim" execTest "tests/tpcre.nim", "-d:FLAGS=\"-f:ast2\"" diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index d1e691b..4a9b048 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -139,7 +139,7 @@ proc newConstDef(gState: State, node: TSNode, fname = "", fval = ""): PNode = else: gecho &"# const '{origname}' is duplicate, skipped" else: - gecho &"# const '{origname}' has invalid value '{val}'" + gecho &"# const '{origname}' has unsupported value '{val}'" gState.skippedSyms.incl origname proc addConst(gState: State, node: TSNode) = @@ -1736,19 +1736,9 @@ proc setupPragmas(gState: State, root: TSNode, fullpath: string) = # Add `{.experimental: "codeReordering".} for #206 gState.pragmaSection.add gState.newPragma(root, "experimental", newStrNode(nkStrLit, "codeReordering")) -proc printNimHeader*(gState: State) = - # Top level output with context info - gecho """# Generated at $1 -# Command line: -# $2 $3 - -{.hint[ConvFromXtoItselfNotNeeded]: off.} - -import nimterop/types -""" % [$now(), getAppFilename(), commandLineParams().join(" ")] - proc initNim*(gState: State) = # Initialize for parseNim() one time + gecho "import nimterop/types\n" # Track identifiers already rendered and corresponding PNodes gState.identifiers = newTable[string, string]() diff --git a/nimterop/toast.nim b/nimterop/toast.nim index 3a58749..b1f910c 100644 --- a/nimterop/toast.nim +++ b/nimterop/toast.nim @@ -141,7 +141,6 @@ proc main( elif source.nBl: # Print source after preprocess or Nim output if gState.pnim: - gState.printNimHeader() gState.initNim() for src in source: gState.process(src.expandSymlinkAbs(), astTable) @@ -199,6 +198,29 @@ proc main( if check and output.len == 0: stdout.write outputFile.readFile() +proc mergeParams(cmdNames: seq[string], cmdLine = commandLineParams()): seq[string] = + # Load command-line params from `source` if it is a .cfg file + if cmdNames.len != 0: + # https://github.com/c-blake/cligen/issues/149 + for param in cmdLine: + if param.fileExists() and param.splitFile().ext == ".cfg": + echo &"# Loading flags from '{param}'" + for line in param.readFile().splitLines(): + let + line = line.strip() + if line.len > 1 and line[0] != '#': + result.add line.parseCmdLine() + else: + result.add param + + if result.len != 0 and "-h" notin result and "--help" notin result: + echo &"""# Generated @ {$now()} +# Command line: +# {getAppFilename()} {result.join(" ")} +""" + else: + result = cmdLine + when isMainModule: # Setup cligen command line help and short flags import cligen @@ -223,7 +245,7 @@ when isMainModule: "preprocess": "run preprocessor on header", "recurse": "process #include files", "replace": "replace X with Y in identifiers, X1=Y1,X2=Y2, @X for regex", - "source" : "C/C++ source/header", + "source" : "C/C++ source/header(s) and command line file(s)", "stub": "stub out undefined type references as objects", "suffix": "strip suffix from identifiers", "symOverride": "skip generating specified symbols", diff --git a/tests/toast.cfg b/tests/toast.cfg new file mode 100644 index 0000000..8c37f3c --- /dev/null +++ b/tests/toast.cfg @@ -0,0 +1,2 @@ +--preprocess +-nk -E=_ \ No newline at end of file From fc587fae037c0443cc1a2ca64685ba1d3b9d62d3 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 13 May 2020 14:36:38 -0500 Subject: [PATCH 481/593] v0.5.3 --- nimterop.nimble | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimterop.nimble b/nimterop.nimble index 4ec024c..187b0ce 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -1,6 +1,6 @@ # Package -version = "0.5.2" +version = "0.5.3" author = "genotrance" description = "C/C++ interop for Nim" license = "MIT" From 32c98435486cff69f7ecbcfb2be3c8f1739fe177 Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Tue, 12 May 2020 16:22:53 -0600 Subject: [PATCH 482/593] Fix undefined identifiers resulting in incorrect types --- nimterop/ast2.nim | 14 ++++++++++++-- tests/include/tast2.h | 15 +++++++++++++++ tests/tast2.nim | 3 +++ 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index 4a9b048..574870f 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -573,8 +573,12 @@ iterator newIdentDefs(gState: State, name: string, node: TSNode, offset: SomeInt (pname, _, pinfo) = gState.getNameInfo(node[i].getAtom(), nskField, parent = name) pident = gState.getIdent(pname, pinfo, exported) result.add pident - result.add gState.getTypeArray(node[i], tident, name) - result.add newNode(nkEmpty) + let tyArray = gState.getTypeArray(node[i], tident, name) + if tyArray.kind != nkNone: + result.add tyArray + result.add newNode(nkEmpty) + else: + result = nil else: result = nil @@ -955,6 +959,8 @@ proc getTypeArray(gState: State, node: TSNode, tident: PNode, name: string): PNo if size.kind != nkNone: result = gState.newArrayTree(cnode, result, size) cnode = cnode[0] + else: + result = newNode(nkNone) elif cnode.len == 1: # type name[] = UncheckedArray[type] result = gState.newArrayTree(cnode, result) @@ -985,6 +991,10 @@ proc addTypeArray(gState: State, node: TSNode) = name = typeDef.getIdentName() typ = gState.getTypeArray(node[i], tident, name) + if typ.kind == nkNone: + gecho (&"{gState.getNodeVal(node)} skipped").getCommented() + continue + typeDef.add typ # type X* = [ptr] array[x, [ptr] Y] diff --git a/tests/include/tast2.h b/tests/include/tast2.h index bbb3315..f28c003 100644 --- a/tests/include/tast2.h +++ b/tests/include/tast2.h @@ -49,6 +49,21 @@ extern "C" { #define ALLSHL (SHL1 | SHL2 | SHL3) +// const not supported yet +const int SOME_CONST = 8; + +struct some_struct_s +{ + int x; +}; + +struct parent_struct_s +{ + struct some_struct_s s[SOME_CONST]; +}; + +typedef struct some_struct_s SOME_ARRAY[SOME_CONST]; + struct A0; struct A1 {}; typedef struct A2; diff --git a/tests/tast2.nim b/tests/tast2.nim index 4fd16cc..058ad0b 100644 --- a/tests/tast2.nim +++ b/tests/tast2.nim @@ -155,6 +155,9 @@ assert typeof(POINTERPOINTERPOINTEREXPR) is (ptr ptr ptr cint) assert ALLSHL == (SHL1 or SHL2 or SHL3) +assert not compiles(parent_struct_s().s) +assert not defined(SOME_ARRAY) + assert A0 is object testFields(A0, "f1!cint") checkPragmas(A0, pHeaderBy, istype = false) From 1df2943cf80147a7d32f1edff5572d92162c663e Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Tue, 12 May 2020 16:32:44 -0600 Subject: [PATCH 483/593] Change to static const --- tests/include/tast2.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/include/tast2.h b/tests/include/tast2.h index f28c003..d39e8ea 100644 --- a/tests/include/tast2.h +++ b/tests/include/tast2.h @@ -50,7 +50,7 @@ extern "C" { #define ALLSHL (SHL1 | SHL2 | SHL3) // const not supported yet -const int SOME_CONST = 8; +static const int SOME_CONST = 8; struct some_struct_s { From ed26911436a2107d287a8f1d4f4df7727d6de53d Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Tue, 12 May 2020 17:18:47 -0600 Subject: [PATCH 484/593] Disable windows check --- tests/include/tast2.h | 5 ++++- tests/tast2.nim | 5 +++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/tests/include/tast2.h b/tests/include/tast2.h index d39e8ea..57c060e 100644 --- a/tests/include/tast2.h +++ b/tests/include/tast2.h @@ -49,8 +49,10 @@ extern "C" { #define ALLSHL (SHL1 | SHL2 | SHL3) +// disable for windows for now +#ifndef _WIN32 // const not supported yet -static const int SOME_CONST = 8; +const int SOME_CONST = 8; struct some_struct_s { @@ -63,6 +65,7 @@ struct parent_struct_s }; typedef struct some_struct_s SOME_ARRAY[SOME_CONST]; +#endif struct A0; struct A1 {}; diff --git a/tests/tast2.nim b/tests/tast2.nim index 058ad0b..f132609 100644 --- a/tests/tast2.nim +++ b/tests/tast2.nim @@ -155,8 +155,9 @@ assert typeof(POINTERPOINTERPOINTEREXPR) is (ptr ptr ptr cint) assert ALLSHL == (SHL1 or SHL2 or SHL3) -assert not compiles(parent_struct_s().s) -assert not defined(SOME_ARRAY) +when not defined(windows): + assert not compiles(parent_struct_s().s) + assert not defined(SOME_ARRAY) assert A0 is object testFields(A0, "f1!cint") From 9895303578c5313a775b9226d051dfe63905495a Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Wed, 13 May 2020 17:29:26 -0600 Subject: [PATCH 485/593] Make undefined constants keep types --- nimterop/ast2.nim | 29 ++++++++++++----------------- nimterop/toast.nim | 2 ++ tests/include/tast2.h | 12 +++++------- tests/tast2.nim | 6 +++--- 4 files changed, 22 insertions(+), 27 deletions(-) diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index 574870f..3b708b5 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -574,11 +574,8 @@ iterator newIdentDefs(gState: State, name: string, node: TSNode, offset: SomeInt pident = gState.getIdent(pname, pinfo, exported) result.add pident let tyArray = gState.getTypeArray(node[i], tident, name) - if tyArray.kind != nkNone: - result.add tyArray - result.add newNode(nkEmpty) - else: - result = nil + result.add tyArray + result.add newNode(nkEmpty) else: result = nil @@ -953,14 +950,16 @@ proc getTypeArray(gState: State, node: TSNode, tident: PNode, name: string): PNo for i in 0 ..< acount: if cnode.len == 2: # type name[X] => array[X, type] - let - # Size of array could be a Nim expression - size = gState.parseCExpression(gState.getNodeVal(cnode[1])) - if size.kind != nkNone: - result = gState.newArrayTree(cnode, result, size) - cnode = cnode[0] - else: - result = newNode(nkNone) + var size: PNode + let cnodeVal = gState.getNodeVal(cnode[1]) + # Size of array could be a Nim expression + size = gState.parseCExpression(cnodeVal) + if size.kind == nkNone: + # If the size could not be parsed, leave it alone + size = gState.getIdent(cnodeVal) + + result = gState.newArrayTree(cnode, result, size) + cnode = cnode[0] elif cnode.len == 1: # type name[] = UncheckedArray[type] result = gState.newArrayTree(cnode, result) @@ -991,10 +990,6 @@ proc addTypeArray(gState: State, node: TSNode) = name = typeDef.getIdentName() typ = gState.getTypeArray(node[i], tident, name) - if typ.kind == nkNone: - gecho (&"{gState.getNodeVal(node)} skipped").getCommented() - continue - typeDef.add typ # type X* = [ptr] array[x, [ptr] Y] diff --git a/nimterop/toast.nim b/nimterop/toast.nim index b1f910c..f54aa67 100644 --- a/nimterop/toast.nim +++ b/nimterop/toast.nim @@ -4,6 +4,8 @@ import "."/treesitter/[api, c, cpp] import "."/[ast, ast2, build, globals, getters, grammar, tshelp] +{.passC: "-DNIMTEROP".} + proc process(gState: State, path: string, astTable: AstTable) = doAssert existsFile(path), &"Invalid path {path}" diff --git a/tests/include/tast2.h b/tests/include/tast2.h index 57c060e..b8433f9 100644 --- a/tests/include/tast2.h +++ b/tests/include/tast2.h @@ -42,17 +42,16 @@ extern "C" { #define REG_STR "regular string" #define NOTSUPPORTEDSTR "not a " REG_STR -#define NULLCHAR '\0'/* comments should not break things*/ -#define OCTCHAR '\012' // nor should this comment +#define NULLCHAR '\0' +#define OCTCHAR '\012' #define HEXCHAR '\xFE' #define TRICKYSTR "\x4E\034\nfoo\0\'\"\r\v\a\b\e\f\t\\\?bar" #define ALLSHL (SHL1 | SHL2 | SHL3) -// disable for windows for now -#ifndef _WIN32 -// const not supported yet -const int SOME_CONST = 8; +#ifdef NIMTEROP +#define SOME_CONST 8 +#endif struct some_struct_s { @@ -65,7 +64,6 @@ struct parent_struct_s }; typedef struct some_struct_s SOME_ARRAY[SOME_CONST]; -#endif struct A0; struct A1 {}; diff --git a/tests/tast2.nim b/tests/tast2.nim index f132609..8deb99e 100644 --- a/tests/tast2.nim +++ b/tests/tast2.nim @@ -35,6 +35,7 @@ cOverride: type A1* = A0 +cDefine("SOME_CONST=100") cImport(path, flags="-f:ast2 -ENK_,SDL_ -GVICE=SLICE -TMyInt=cint" & flags) proc getPragmas(n: NimNode): HashSet[string] = @@ -155,9 +156,8 @@ assert typeof(POINTERPOINTERPOINTEREXPR) is (ptr ptr ptr cint) assert ALLSHL == (SHL1 or SHL2 or SHL3) -when not defined(windows): - assert not compiles(parent_struct_s().s) - assert not defined(SOME_ARRAY) +assert typeof(parent_struct_s().s) is array[100, some_struct_s] +assert typeof(SOME_ARRAY) is array[100, some_struct_s] assert A0 is object testFields(A0, "f1!cint") From 1a7860d8f4ac5d2d2d453e75e05200cb34849954 Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Wed, 13 May 2020 18:31:07 -0600 Subject: [PATCH 486/593] Get rid of extra var --- nimterop/ast2.nim | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index 3b708b5..0d0883c 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -573,8 +573,7 @@ iterator newIdentDefs(gState: State, name: string, node: TSNode, offset: SomeInt (pname, _, pinfo) = gState.getNameInfo(node[i].getAtom(), nskField, parent = name) pident = gState.getIdent(pname, pinfo, exported) result.add pident - let tyArray = gState.getTypeArray(node[i], tident, name) - result.add tyArray + result.add gState.getTypeArray(node[i], tident, name) result.add newNode(nkEmpty) else: result = nil From 2098f6a471784b5c87c678ec9d79faf2cc467199 Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Wed, 13 May 2020 22:19:37 -0600 Subject: [PATCH 487/593] Preserve type array ast --- nimterop/ast2.nim | 5 +---- nimterop/exprparser.nim | 14 ++++++++------ nimterop/globals.nim | 3 +++ 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index 0d0883c..389d371 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -952,10 +952,7 @@ proc getTypeArray(gState: State, node: TSNode, tident: PNode, name: string): PNo var size: PNode let cnodeVal = gState.getNodeVal(cnode[1]) # Size of array could be a Nim expression - size = gState.parseCExpression(cnodeVal) - if size.kind == nkNone: - # If the size could not be parsed, leave it alone - size = gState.getIdent(cnodeVal) + size = gState.parseCExpression(cnodeVal, skipIdentValidation = true) result = gState.newArrayTree(cnode, result, size) cnode = cnode[0] diff --git a/nimterop/exprparser.nim b/nimterop/exprparser.nim index b0c34c1..e5e2150 100644 --- a/nimterop/exprparser.nim +++ b/nimterop/exprparser.nim @@ -45,14 +45,14 @@ proc getExprIdent*(gState: State, identName: string, kind = nskConst, parent = " ## ## Returns PNode(nkNone) if the identifier is blank result = newNode(nkNone) - if identName notin gState.skippedSyms: + if gState.currentExprSkipIdentValidation or identName notin gState.skippedSyms: var ident = identName if ident != "_": # Process the identifier through cPlugin ident = gState.getIdentifier(ident, kind, parent) if kind == nskType: result = gState.getIdent(ident) - elif ident.nBl and ident in gState.constIdentifiers: + elif gState.currentExprSkipIdentValidation or ident.nBl and ident in gState.constIdentifiers: if gState.currentTyCastName.nBl: ident = ident & "." & gState.currentTyCastName result = gState.getIdent(ident) @@ -591,7 +591,7 @@ proc processTSNode(gState: State, node: TSNode, typeofNode: var PNode): PNode = decho "NODE RESULT: ", result -proc parseCExpression*(gState: State, codeRoot: TSNode, name = ""): PNode = +proc parseCExpression*(gState: State, codeRoot: TSNode): PNode = ## Parse a c expression from a root ts node # This var is used for keeping track of the type of the first @@ -607,14 +607,16 @@ proc parseCExpression*(gState: State, codeRoot: TSNode, name = ""): PNode = decho "UNEXPECTED EXCEPTION: ", e.msg result = newNode(nkNone) -proc parseCExpression*(gState: State, code: string, name = ""): PNode = +proc parseCExpression*(gState: State, code: string, name = "", skipIdentValidation = false): PNode = ## Convert the C string to a nim PNode tree gState.currentExpr = code gState.currentTyCastName = name + gState.currentExprSkipIdentValidation = skipIdentValidation withCodeAst(gState.currentExpr, gState.mode): - result = gState.parseCExpression(root, name) + result = gState.parseCExpression(root) # Clear the state gState.currentExpr = "" - gState.currentTyCastName = "" \ No newline at end of file + gState.currentTyCastName = "" + gState.currentExprSkipIdentValidation = false \ No newline at end of file diff --git a/nimterop/globals.nim b/nimterop/globals.nim index 46203ea..039dd3c 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -114,6 +114,9 @@ type # Used for the exprparser.nim module currentExpr*, currentTyCastName*: string + # Controls whether or not the current expression + # should validate idents against currently defined idents + currentExprSkipIdentValidation*: bool # Legacy AST fields, remove when ast2 becomes default constStr*, enumStr*, procStr*, typeStr*: string From faab2924c8a6a48df65a4ee74363eb822c2c768f Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Wed, 13 May 2020 22:36:40 -0600 Subject: [PATCH 488/593] Cleanup code --- nimterop/ast2.nim | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index 389d371..dff355e 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -949,10 +949,9 @@ proc getTypeArray(gState: State, node: TSNode, tident: PNode, name: string): PNo for i in 0 ..< acount: if cnode.len == 2: # type name[X] => array[X, type] - var size: PNode - let cnodeVal = gState.getNodeVal(cnode[1]) - # Size of array could be a Nim expression - size = gState.parseCExpression(cnodeVal, skipIdentValidation = true) + let + # Size of array could be a Nim expression + size = gState.parseCExpression(gState.getNodeVal(cnode[1]), skipIdentValidation = true) result = gState.newArrayTree(cnode, result, size) cnode = cnode[0] From ffd6b9b5eb6be220b05178438aa622cda047d9d5 Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Thu, 14 May 2020 17:23:43 -0600 Subject: [PATCH 489/593] Rename currentExprSkipIdentValidation -> skipIdentValidation --- nimterop/exprparser.nim | 8 ++++---- nimterop/globals.nim | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/nimterop/exprparser.nim b/nimterop/exprparser.nim index e5e2150..b089fd2 100644 --- a/nimterop/exprparser.nim +++ b/nimterop/exprparser.nim @@ -45,14 +45,14 @@ proc getExprIdent*(gState: State, identName: string, kind = nskConst, parent = " ## ## Returns PNode(nkNone) if the identifier is blank result = newNode(nkNone) - if gState.currentExprSkipIdentValidation or identName notin gState.skippedSyms: + if gState.skipIdentValidation or identName notin gState.skippedSyms: var ident = identName if ident != "_": # Process the identifier through cPlugin ident = gState.getIdentifier(ident, kind, parent) if kind == nskType: result = gState.getIdent(ident) - elif gState.currentExprSkipIdentValidation or ident.nBl and ident in gState.constIdentifiers: + elif gState.skipIdentValidation or ident.nBl and ident in gState.constIdentifiers: if gState.currentTyCastName.nBl: ident = ident & "." & gState.currentTyCastName result = gState.getIdent(ident) @@ -611,7 +611,7 @@ proc parseCExpression*(gState: State, code: string, name = "", skipIdentValidati ## Convert the C string to a nim PNode tree gState.currentExpr = code gState.currentTyCastName = name - gState.currentExprSkipIdentValidation = skipIdentValidation + gState.skipIdentValidation = skipIdentValidation withCodeAst(gState.currentExpr, gState.mode): result = gState.parseCExpression(root) @@ -619,4 +619,4 @@ proc parseCExpression*(gState: State, code: string, name = "", skipIdentValidati # Clear the state gState.currentExpr = "" gState.currentTyCastName = "" - gState.currentExprSkipIdentValidation = false \ No newline at end of file + gState.skipIdentValidation = false \ No newline at end of file diff --git a/nimterop/globals.nim b/nimterop/globals.nim index 039dd3c..05284a9 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -116,7 +116,7 @@ type currentExpr*, currentTyCastName*: string # Controls whether or not the current expression # should validate idents against currently defined idents - currentExprSkipIdentValidation*: bool + skipIdentValidation*: bool # Legacy AST fields, remove when ast2 becomes default constStr*, enumStr*, procStr*, typeStr*: string From 5895db1d18e1d3c9f1e502f0a68f671d4e53e02b Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Mon, 18 May 2020 16:58:07 -0600 Subject: [PATCH 490/593] Remove regex from comment processing --- nimterop/tshelp.nim | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/nimterop/tshelp.nim b/nimterop/tshelp.nim index 762cf7c..9565a1f 100644 --- a/nimterop/tshelp.nim +++ b/nimterop/tshelp.nim @@ -1,7 +1,5 @@ import sets, strformat, strutils -import regex - import "."/[getters, globals] import "."/treesitter/[api, c, cpp] @@ -273,8 +271,14 @@ proc getCommentsStr*(gState: State, commentNodes: seq[TSNode]): string = for commentNode in commentNodes: result &= "\n " & gState.getNodeVal(commentNode).strip() - result = result.replace(re" *(//|/\*\*|\*\*/|/\*|\*/|\*)", "") - result = result.multiReplace([("\n", "\n "), ("`", "")]).strip() + result = result.multiReplace( + { + "/**": "", "**/": "", "/*": "", + "*/": "", "/*": "", "//": "", + "\n": "\n ", "`": "" + } + # need to replace this last otherwise it supercedes other replacements + ).replace(" *", "").strip() proc getCommentNodes*(gState: State, node: TSNode, maxSearch=1): seq[TSNode] = ## Get a set of comment nodes in order of priority. Will search up to ``maxSearch`` From 985741cc8de35ea36933ddb845f93316288c30b8 Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Mon, 18 May 2020 17:52:21 -0600 Subject: [PATCH 491/593] Remove more regex from exprparser --- nimterop/exprparser.nim | 61 ++++++++++++++++++++++++----------------- 1 file changed, 36 insertions(+), 25 deletions(-) diff --git a/nimterop/exprparser.nim b/nimterop/exprparser.nim index b089fd2..b2b8c2c 100644 --- a/nimterop/exprparser.nim +++ b/nimterop/exprparser.nim @@ -1,4 +1,4 @@ -import strformat, strutils, macros, sets +import strformat, strutils, macros, sets, sequtils import regex @@ -32,6 +32,10 @@ import "."/[globals, getters, comphelp, tshelp] type ExprParseError* = object of CatchableError +const + CharRegStr = "(\\\\x[[:xdigit:]]{2}|\\\\\\d{3}|\\\\0|\\\\a|\\\\b|\\\\e|\\\\f|\\\\n|\\\\r|\\\\t|\\\\v|\\\\\\\\|\\\\'|\\\\\"|[[:ascii:]])" + CharRegex = re(CharRegStr) + template val(node: TSNode): string = gState.currentExpr.getNodeVal(node) @@ -138,13 +142,13 @@ proc getIntNode(number, suffix: string): PNode {.inline.} = flags: TNodeFlags # I realize these regex are wasteful on performance, but # couldn't come up with a better idea. - if number.contains(re"0[xX]"): + if number.startsWith("0X") or number.startsWith("0x"): val = parseHexInt(number) flags = {nfBase16} - elif number.contains(re"0[bB]"): + elif number.startsWith("0B") or number.startsWith("0b"): val = parseBinInt(number) flags = {nfBase2} - elif number.contains(re"0[oO]"): + elif number.startsWith("0O") or number.startsWith("0o"): val = parseOctInt(number) flags = {nfBase8} else: @@ -186,25 +190,36 @@ proc processNumberLiteral(gState: State, node: TSNode): PNode = ## Parse a number literal from a TSNode. Can be a float, hex, long, etc result = newNode(nkNone) let nodeVal = node.val + var + prefix: string + number = nodeVal + suffix: string - var match: RegexMatch - const reg = re"(\-)?(0\d+|0[xX][0-9a-fA-F]+|0[bB][01]+|\d+\.\d*[fFlL]?|\d*\.\d+[fFlL]?|\d+)([ulUL]*)" - let found = nodeVal.find(reg, match) - if found: - let - prefix = if match.group(0).len > 0: nodeVal[match.group(0)[0]] else: "" - number = nodeVal[match.group(1)[0]] - suffix = nodeVal[match.group(2)[0]] + const + singleEndings = ["u", "l", "U", "L"] + doubleEndings = ["ul", "UL", "ll", "LL"] + tripleEndings = ["ull", "ULL"] - result = getNumNode(number, suffix) + if number.startsWith("-"): + number = number[1 ..< number.len] + prefix = "-" + if tripleEndings.any(proc (s: string): bool = number.endsWith(s)): + suffix = number[^3 .. ^1] + number = number[0 ..< ^3] + elif doubleEndings.any(proc (s: string): bool = number.endsWith(s)): + suffix = number[^2 .. ^1] + number = number[0 ..< ^2] + elif singleEndings.any(proc (s: string): bool = number.endsWith(s)): + suffix = $number[number.len - 1] + number = number[0 ..< ^1] - if result.kind != nkNone and prefix == "-": - result = nkPrefix.newTree( - gState.getIdent("-"), - result - ) - else: - raise newException(ExprParseError, &"Could not find a number in number_literal: \"{nodeVal}\"") + result = getNumNode(number, suffix) + + if result.kind != nkNone and prefix == "-": + result = nkPrefix.newTree( + gState.getIdent("-"), + result + ) proc processCharacterLiteral(gState: State, node: TSNode): PNode = # Input => 'G' @@ -234,13 +249,9 @@ proc processStringLiteral(gState: State, node: TSNode): PNode = nodeVal = node.val strVal = nodeVal[1 ..< nodeVal.len - 1] - const - str = "(\\\\x[[:xdigit:]]{2}|\\\\\\d{3}|\\\\0|\\\\a|\\\\b|\\\\e|\\\\f|\\\\n|\\\\r|\\\\t|\\\\v|\\\\\\\\|\\\\'|\\\\\"|[[:ascii:]])" - reg = re(str) - # Convert the c string escape sequences/etc to Nim chars var nimStr = newStringOfCap(nodeVal.len) - for m in strVal.findAll(reg): + for m in strVal.findAll(CharRegex): nimStr.add(parseChar(strVal[m.group(0)[0]]).chr) result = newStrNode(nkStrLit, nimStr) From 11f84d4d8075d96aed623d09972a79f2702486a8 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 18 May 2020 11:22:54 -0500 Subject: [PATCH 492/593] var support, interleaved #defines, fix ast1 default, misc performance --- nimterop/ast2.nim | 501 ++++++++++++++++++++++------------------ nimterop/exprparser.nim | 3 +- nimterop/getters.nim | 35 +-- nimterop/globals.nim | 2 +- nimterop/toast.nim | 8 +- nimterop/tshelp.nim | 2 +- tests/rsa.nim | 3 +- 7 files changed, 314 insertions(+), 240 deletions(-) diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index dff355e..3d52e02 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -1,7 +1,5 @@ import macros, os, sequtils, sets, strformat, strutils, tables, times -import options as opts - import compiler/[ast, idents, lineinfos, modulegraphs, msgs, options, renderer] import "."/treesitter/api @@ -136,6 +134,8 @@ proc newConstDef(gState: State, node: TSNode, fname = "", fval = ""): PNode = result.add valident[0] else: result.add valident + # In case symbol was skipped earlier + gState.skippedSyms.excl origname else: gecho &"# const '{origname}' is duplicate, skipped" else: @@ -251,7 +251,7 @@ proc newXIdent(gState: State, node: TSNode, kind = nskType, fname = "", pragmas: (tname, torigname, info) = if not atom.isNil: - gState.getNameInfo(node.getAtom(), kind) + gState.getNameInfo(atom, kind) else: ("", "", gState.getLineInfo(node)) @@ -342,46 +342,42 @@ proc newXIdent(gState: State, node: TSNode, kind = nskType, fname = "", pragmas: result.add prident result.add newNode(nkEmpty) elif kind == nskVar: - # var name* {.importc: "abc".} + # Used by `addVar()` for regular vars and proc vars # - # nkIdentDefs( - # nkPragmaExpr( - # nkPostfix( - # nkIdent("*"), - # nkIdent(name) - # ), - # nkPragma( - # nkExprColonExpr( - # nkIdent("importc"), - # nkStrLit("abc") - # ) + # name* {.importc: "abc".} + # + # nkPragmaExpr( + # nkPostfix( + # nkIdent("*"), + # nkIdent(name) + # ), + # nkPragma( + # nkExprColonExpr( + # nkIdent("importc"), + # nkStrLit("abc") # ) # ) # ) - let - prident = block: - var - prident: PNode - # Add {.importc.} pragma - if name != origname: - # Name changed - prident = gState.newPragmaExpr(node, ident, "importc", newStrNode(nkStrLit, &"{origname}")) - else: - prident = gState.newPragmaExpr(node, ident, "importc") + result = block: + var + prident: PNode + # Add {.importc.} pragma + if name != origname: + # Name changed + prident = gState.newPragmaExpr(node, ident, "importc", newStrNode(nkStrLit, &"{origname}")) + else: + prident = gState.newPragmaExpr(node, ident, "importc") - if gState.dynlib.nBl: - # Add {.dynlib.} - gState.addPragma(node, prident[1], gState.impShort & "Dyn") - elif not gState.noHeader: - # Add {.header.} - gState.addPragma(node, prident[1], gState.impShort & "Hdr") + if gState.dynlib.nBl: + # Add {.dynlib.} + gState.addPragma(node, prident[1], gState.impShort & "Dyn") + elif not gState.noHeader: + # Add {.header.} + gState.addPragma(node, prident[1], gState.impShort & "Hdr") - if pragmas.nBl: - gState.addPragma(node, prident[1], pragmas) - prident - - result = newNode(nkIdentDefs) - result.add prident + if pragmas.nBl: + gState.addPragma(node, prident[1], pragmas) + prident elif kind == nskProc: # name* # @@ -426,12 +422,39 @@ proc newArrayTree(gState: State, node: TSNode, typ, size: PNode = nil): PNode = proc getTypeArray(gState: State, node: TSNode, tident: PNode, name: string): PNode proc getTypeProc(gState: State, name: string, node, rnode: TSNode): PNode -iterator newIdentDefs(gState: State, name: string, node: TSNode, offset: SomeInteger, ftname = "", exported = false): PNode = - # Create nkIdentDefs tree for specified proc parameter or object field +proc getTypeAndStart(gState: State, name: string, node: TSNode, ftname = ""): + tuple[tname: string, tinfo: TLineInfo, tident: PNode, start: int] = + # Shortcut to get start node and type info from first node # - # For proc, param should not be `exported` + # `name` is the parent type or proc # - # If `ftname` is set, use it as the type name + # If `ftname` is set, use it as the type name instead + result.start = getStartAtom(node) + + let + # node[start] - param type + (tname0, _, tinfo) = gState.getNameInfo(node[result.start].getAtom(), nskType, parent = name) + + # Override type name + result.tname = + if ftname.nBl: + ftname + else: + tname0 + + result.tinfo = tinfo + result.tident = gState.getIdent(result.tname, tinfo, exported = false) + +proc newIdentDef(gState: State, name: string, node: TSNode, tname: string, tinfo: TLineInfo, tident: PNode, + start, offset, poffset: SomeInteger, exported = false): PNode = + # Create nkIdentDefs tree for specified proc parameter, object field or var/proc var + # + # `name` is the parent type or proc - if blank, this is a var so add pragmas + # `tname`, `tinfo` and `tident` are the type info for the node + # `start` is the `node` child where type is located + # `offset` is the nth `node` child where specified param/field/var is located - from `addVar()` + # `poffset` is the param number and used for unnamed params in procs - from `newIdentDefs()` iterator + # `isvar` when true adds pragmas # # pname: [ptr ..] typ # @@ -441,7 +464,7 @@ iterator newIdentDefs(gState: State, name: string, node: TSNode, offset: SomeInt # nkEmpty() # ) # - # For object, field should be exported + # For objects and vars/proc vars, field should be exported # # pname*: [ptr ..] typ # @@ -453,6 +476,125 @@ iterator newIdentDefs(gState: State, name: string, node: TSNode, offset: SomeInt # typ, # nkEmpty() # ) + result = newNode(nkIdentDefs) + + let + fdecl = node[offset].firstChildInTree("function_declarator") + afdecl = node[offset].firstChildInTree("abstract_function_declarator") + adecl = node[offset].firstChildInTree("array_declarator") + abst = node[offset].getName() == "abstract_pointer_declarator" + if fdecl.isNil and afdecl.isNil and adecl.isNil: + if abst: + # Only for proc with no named param with pointer type + # Create a param name based on poffset + # + # int func(char *, int **); + let + pname = "a" & $(poffset+1) + pident = gState.getIdent(pname, tinfo, exported) + acount = node[offset].getXCount("abstract_pointer_declarator") + result.add pident + result.add gState.newPtrTree(acount, tident) + result.add newNode(nkEmpty) + else: + # Named param, simple type + if name.nBl: + # Types and procs - `newIdentDefs()` iterator + let + (pname, _, pinfo) = gState.getNameInfo(node[offset].getAtom(), nskField, parent = name) + pident = gState.getIdent(pname, pinfo, exported) + + # Bitfield support - typedef struct { int field: 1; }; + prident = + if node.len > offset and node[offset + 1].getName() == "bitfield_clause": + gState.newPragmaExpr(node, pident, "bitsize", + newIntNode(nkIntLit, parseInt(gState.getNodeVal(node[offset + 1].getAtom())))) + else: + pident + + result.add prident + else: + # Vars - `addVar()` + let + pident = gState.newXIdent(node[offset], nskVar) + if pident.isNil: + return nil + + result.add pident + + let + count = node[offset].getPtrCount() + if count > 0: + result.add gState.newPtrTree(count, tident) + else: + result.add tident + result.add newNode(nkEmpty) + elif not fdecl.isNil: + # Named param, function pointer + var + name = name + pident: PNode + if name.nBl: + # Types and procs - `newIdentDefs()` iterator + let + (pname, _, pinfo) = gState.getNameInfo(node[offset].getAtom(), nskField, parent = name) + pident = gState.getIdent(pname, pinfo, exported) + else: + # Vars - `addVar()` + pident = gState.newXIdent(node[offset], nskVar) + if pident.isNil: + return nil + # The var is the parent + name = pident.getIdentName() + + result.add pident + result.add gState.getTypeProc(name, node[offset], node[start]) + result.add newNode(nkEmpty) + elif not afdecl.isNil: + # Only for proc with no named param with function pointer type + # Create a param name based on poffset + # + # int func(int (*)(int *)); + let + pname = "a" & $(poffset+1) + pident = gState.getIdent(pname, tinfo, exported) + procTy = gState.getTypeProc(name, node[offset], node[start]) + result.add pident + result.add procTy + result.add newNode(nkEmpty) + elif not adecl.isNil: + # Named param, array type + var + name = name + pident: PNode + if name.nBl: + # Types and procs - `newIdentDefs()` iterator + let + (pname, _, pinfo) = gState.getNameInfo(node[offset].getAtom(), nskField, parent = name) + pident = gState.getIdent(pname, pinfo, exported) + else: + # Vars - `addVar()` + pident = gState.newXIdent(node[offset], nskVar) + if pident.isNil: + return nil + # The var is the parent + name = pident.getIdentName() + + result.add pident + result.add gState.getTypeArray(node[offset], tident, name) + result.add newNode(nkEmpty) + else: + result = nil + +iterator newIdentDefs(gState: State, name: string, node: TSNode, offset: SomeInteger, ftname = "", exported = false): PNode = + # Create nkIdentDefs tree for specified proc parameter or object field + # + # `name` is the parent type or proc + # `offset` is the param number and used for unnamed params in procs + # + # For proc, param should not be `exported` + # + # If `ftname` is set, use it as the type name # # Iterator since structs can have multiple comma separated fields for the # same type so can yield multiple results. @@ -460,23 +602,12 @@ iterator newIdentDefs(gState: State, name: string, node: TSNode, offset: SomeInt # struct ABC { int w, h; }; # # This is not applicable for procs. - var - start = getStartAtom(node) - let - # node[start] - param type - (tname0, _, tinfo) = gState.getNameInfo(node[start].getAtom(), nskType, parent = name) - - # Override type name - tname = - if ftname.nBl: - ftname - else: - tname0 - - tident = gState.getIdent(tname, tinfo, exported = false) + (tname, tinfo, tident, start0) = gState.getTypeAndStart(name, node, ftname) # Skip qualifiers after type + var + start = start0 while start < node.len - 1 and node[start+1].getName() == "type_qualifier": start += 1 @@ -503,82 +634,7 @@ iterator newIdentDefs(gState: State, name: string, node: TSNode, offset: SomeInt for i in start+1 ..< node.len: if node[i].getName() == "bitfield_clause": continue - - var - result = newNode(nkIdentDefs) - - let - fdecl = node[i].firstChildInTree("function_declarator") - afdecl = node[i].firstChildInTree("abstract_function_declarator") - adecl = node[i].firstChildInTree("array_declarator") - abst = node[i].getName() == "abstract_pointer_declarator" - if fdecl.isNil and afdecl.isNil and adecl.isNil: - if abst: - # Only for proc with no named param with pointer type - # Create a param name based on offset - # - # int func(char *, int **); - let - pname = "a" & $(offset+1) - pident = gState.getIdent(pname, tinfo, exported) - acount = node[i].getXCount("abstract_pointer_declarator") - result.add pident - result.add gState.newPtrTree(acount, tident) - result.add newNode(nkEmpty) - else: - # Named param, simple type - let - (pname, _, pinfo) = gState.getNameInfo(node[i].getAtom(), nskField, parent = name) - pident = gState.getIdent(pname, pinfo, exported) - - # Bitfield support - typedef struct { int field: 1; }; - prident = - if node.len > i and node[i + 1].getName() == "bitfield_clause": - gState.newPragmaExpr(node, pident, "bitsize", - newIntNode(nkIntLit, parseInt(gState.getNodeVal(node[i + 1].getAtom())))) - else: - pident - - count = node[i].getPtrCount() - - result.add prident - if count > 0: - result.add gState.newPtrTree(count, tident) - else: - result.add tident - result.add newNode(nkEmpty) - elif not fdecl.isNil: - # Named param, function pointer - let - (pname, _, pinfo) = gState.getNameInfo(node[i].getAtom(), nskField, parent = name) - pident = gState.getIdent(pname, pinfo, exported) - result.add pident - result.add gState.getTypeProc(name, node[i], node[start]) - result.add newNode(nkEmpty) - elif not afdecl.isNil: - # Only for proc with no named param with function pointer type - # Create a param name based on offset - # - # int func(int (*)(int *)); - let - pname = "a" & $(offset+1) - pident = gState.getIdent(pname, tinfo, exported) - procTy = gState.getTypeProc(name, node[i], node[start]) - result.add pident - result.add procTy - result.add newNode(nkEmpty) - elif not adecl.isNil: - # Named param, array type - let - (pname, _, pinfo) = gState.getNameInfo(node[i].getAtom(), nskField, parent = name) - pident = gState.getIdent(pname, pinfo, exported) - result.add pident - result.add gState.getTypeArray(node[i], tident, name) - result.add newNode(nkEmpty) - else: - result = nil - - yield result + yield gState.newIdentDef(name, node, tname, tinfo, tident, start, i, offset, exported) proc newFormalParams(gState: State, name: string, node: TSNode, rtyp: PNode): PNode = # Create nkFormalParams tree for specified params and return type @@ -967,11 +1023,8 @@ proc addTypeArray(gState: State, node: TSNode) = # Add a type of array type decho("addTypeArray()") let - start = getStartAtom(node) + (_, _, tident, start) = gState.getTypeAndStart("addTypeArray", node) - # node[start] = identifier = type name - (tname, _, info) = gState.getNameInfo(node[start].getAtom(), nskType, parent = "addTypeArray") - tident = gState.getIdent(tname, info, exported = false) commentNodes = gState.getCommentNodes(node) # Could have multiple types, comma separated @@ -1015,6 +1068,7 @@ proc addTypeArray(gState: State, node: TSNode) = proc getTypeProc(gState: State, name: string, node, rnode: TSNode): PNode = # Create proc type tree # + # `name` is the parent type or proc # `rnode` is the return type let # rnode = identifier = return type name @@ -1368,7 +1422,7 @@ proc addEnum(gState: State, node: TSNode) = fnames: HashSet[string] # Hold all of field information so that we can add all of them # after the const identifiers has been updated - fieldDeclarations: seq[tuple[fname: string, fval: string, cexpr: Option[TSNode], comment: seq[TSNode]]] + fieldDeclarations: seq[tuple[fname, forigname, fval, cexpr: string, comment: seq[TSNode]]] for i in 0 .. enumlist.len - 1: let en = enumlist[i] @@ -1378,7 +1432,8 @@ proc addEnum(gState: State, node: TSNode) = let atom = en.getAtom() commentNodes = gState.getCommentNodes(en) - fname = gState.getIdentifier(gState.getNodeVal(atom), nskEnumField) + forigname = gState.getNodeVal(atom) + fname = gState.getIdentifier(forigname, nskEnumField) if fname.nBl and gState.addNewIdentifer(fname): var @@ -1391,9 +1446,9 @@ proc addEnum(gState: State, node: TSNode) = fval = &"({prev} + 1).{name}" if en.len > 1 and en[1].getName() in gEnumVals: - fieldDeclarations.add((fname, "", some(en[1]), commentNodes)) + fieldDeclarations.add((fname, forigname, "", gState.getNodeVal(en[1]), commentNodes)) else: - fieldDeclarations.add((fname, fval, none(TSNode), commentNodes)) + fieldDeclarations.add((fname, forigname, fval, "", commentNodes)) fnames.incl fname prev = fname @@ -1403,78 +1458,25 @@ proc addEnum(gState: State, node: TSNode) = gState.constIdentifiers.incl fnames # parseCExpression requires all const identifiers to be present for the enum - for (fname, fval, cexprNode, commentNodes) in fieldDeclarations: - var fval = fval - if cexprNode.isSome: - fval = "(" & $gState.parseCExpression(gState.getNodeVal(cexprNode.get()), name) & ")." & name - # Cannot use newConstDef() since parseString(fval) adds backticks to and/or - let constNode = gState.parseString(&"const {fname}* = {fval}")[0][0] + for (fname, forigname, fval, cexpr, commentNodes) in fieldDeclarations: + let + fval = + if fval.Bl: + "(" & $gState.parseCExpression(cexpr, name) & ")." & name + else: fval + + # Cannot use newConstDef() since parseString(fval) adds backticks to and/or + constNode = gState.parseString(&"const {fname}* = {fval}")[0][0] + constNode.comment = gState.getCommentsStr(commentNodes) gState.constSection.add constNode + # In case symbol was skipped earlier + gState.skippedSyms.excl forigname # Add other names if node.getName() == "type_definition" and node.len > 1: gState.addTypeTyped(node, ftname = name, offset = offset) -proc addProcVar(gState: State, node, rnode: TSNode, commentNodes: seq[TSNode]) = - # Add a proc variable - decho("addProcVar()") - let - # node = identifier = name - identDefs = gState.newXIdent(node, kind = nskVar, istype = true) - - if not identDefs.isNil: - let - name = identDefs.getIdentName() - # origname = gState.getNodeVal(node.getAtom()) - - procTy = gState.getTypeProc(name, node, rnode) - - identDefs.add procTy - identDefs.add newNode(nkEmpty) - - # var X* {.importc: "_X": proc(a1: Y, a2: Z): P {.cdecl.} - # - # nkIdentDefs( - # nkPragmaExpr( - # nkPostfix( - # nkIdent("*"), - # nkIdent("X") - # ), - # nkPragma( - # nkExprColonExpr( - # nkIdent("importc"), - # nkStrLit("_X") - # ) - # ) - # ), - # nkProcTy( - # nkFormalParams( - # nkIdent("P"), - # nkIdentDefs( - # nkIdent("a1"), - # nkIdent("Y"), - # nkEmpty() - # ), - # nkIdentDefs( - # nkIdent("a2"), - # nkIdent("Z"), - # nkEmpty() - # ) - # ), - # nkPragma( - # nkIdent("cdecl") - # ) - # ), - # nkEmpty() - # ) - - identDefs.comment = gState.getCommentsStr(commentNodes) - # nkVarSection.add - gState.varSection.add identDefs - - gState.printDebug(identDefs) - proc addProc(gState: State, node, rnode: TSNode, commentNodes: seq[TSNode]) = # Add a proc # @@ -1585,6 +1587,65 @@ proc addProc(gState: State, node, rnode: TSNode, commentNodes: seq[TSNode]) = gState.printDebug(procDef) +proc addVar(gState: State, node: TSNode, offset: SomeInteger, commentNodes: seq[TSNode]) = + # Add a regular variable + # + # `node` is the `nth` child of (declaration) + # `tnode` is the type node, the first child of (declaration) + decho("addVar()") + let + (tname, tinfo, tident, start) = gState.getTypeAndStart("", node) + + identDefs = gState.newIdentDef("", node, tname, tinfo, tident, start, offset, 0, exported = true) + + if not identDefs.isNil: + # proc var + # + # P (*_X)(Y a1, Z a2); + # + # var X* {.importc: "_X": proc(a1: Y, a2: Z): P {.cdecl.} + # + # nkIdentDefs( + # nkPragmaExpr( + # nkPostfix( + # nkIdent("*"), + # nkIdent("X") + # ), + # nkPragma( + # nkExprColonExpr( + # nkIdent("importc"), + # nkStrLit("_X") + # ) + # ) + # ), + # nkProcTy( + # nkFormalParams( + # nkIdent("P"), + # nkIdentDefs( + # nkIdent("a1"), + # nkIdent("Y"), + # nkEmpty() + # ), + # nkIdentDefs( + # nkIdent("a2"), + # nkIdent("Z"), + # nkEmpty() + # ) + # ), + # nkPragma( + # nkIdent("cdecl") + # ) + # ), + # nkEmpty() + # ) + + identDefs.comment = gState.getCommentsStr(commentNodes) + + # nkVarSection.add + gState.varSection.add identDefs + + gState.printDebug(identDefs) + proc addDecl(gState: State, node: TSNode) = # Add a declaration decho("addDecl()") @@ -1598,31 +1659,29 @@ proc addDecl(gState: State, node: TSNode) = commentNodes: seq[TSNode] for i in start+1 ..< node.len: + if node[i].getName() == "comment": + continue + + if firstDecl: + # If it's the first declaration, use the whole node + # to get the comment above/below + commentNodes = gState.getCommentNodes(node) + firstDecl = false + else: + commentNodes = gState.getCommentNodes(node[i]) + if not node[i].firstChildInTree("function_declarator").isNil: # Proc declaration - var or actual proc if node[i].getAtom().getPxName(1) == "pointer_declarator": # proc var - if firstDecl: - # If it's the first declaration, use the whole node - # to get the comment above/below - commentNodes = gState.getCommentNodes(node) - firstDecl = false - else: - commentNodes = gState.getCommentNodes(node[i]) - gState.addProcVar(node[i], node[start], commentNodes) + #gState.addProcVar(node[i], node[start], commentNodes) + gState.addVar(node, i, commentNodes) else: # proc - if firstDecl: - # If it's the first declaration, use the whole node - # to get the comment above/below - commentNodes = gState.getCommentNodes(node) - firstDecl = false - else: - commentNodes = gState.getCommentNodes(node[i]) gState.addProc(node[i], node[start], commentNodes) else: # Regular var - discard + gState.addVar(node, i, commentNodes) proc addDef(gState: State, node: TSNode) = # Wrap static inline definition if {.header.} mode is specified diff --git a/nimterop/exprparser.nim b/nimterop/exprparser.nim index b2b8c2c..0fea184 100644 --- a/nimterop/exprparser.nim +++ b/nimterop/exprparser.nim @@ -600,7 +600,8 @@ proc processTSNode(gState: State, node: TSNode, typeofNode: var PNode): PNode = else: raise newException(ExprParseError, &"Unsupported node type \"{nodeName}\" for node \"{node.val}\"") - decho "NODE RESULT: ", result + if result.kind != nkNone: + decho "NODE RESULT: ", result proc parseCExpression*(gState: State, codeRoot: TSNode): PNode = ## Parse a c expression from a root ts node diff --git a/nimterop/getters.nim b/nimterop/getters.nim index e600b18..825b1c4 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -116,7 +116,7 @@ proc getType*(str: string): string = if str == "void": return "object" - result = str.strip(chars={'_'}).replace(re"\s+", " ") + result = str.strip(chars={'_'}).splitWhitespace().join(" ") if gTypeMap.hasKey(result): result = gTypeMap[result] @@ -246,17 +246,23 @@ proc getKeyword*(kind: NimSymKind): string = proc getCurrentHeader*(fullpath: string): string = ("header" & fullpath.splitFile().name.multiReplace([(".", ""), ("-", "")])) -proc getPreprocessor*(gState: State, fullpath: string): string = +proc getPreprocessor*(gState: State, fullpath: string) = var cmts = if gState.noComments: "" else: "-CC" cmd = &"""{getCompiler()} -E {cmts} -dD {getGccModeArg(gState.mode)} -w """ - rdata: seq[string] = @[] + ddata: seq[string] + rdata: seq[string] start = false sfile = fullpath.sanitizePath(noQuote = true) + sfileName = sfile.extractFilename() + pDir = sfile.expandFilename().parentDir() + includeDirs: seq[string] + for inc in gState.includeDirs: cmd &= &"-I{inc.sanitizePath} " + includeDirs.add inc.absolutePath().sanitizePath(noQuote = true) for def in gState.defines: cmd &= &"-D{def} " @@ -267,7 +273,10 @@ proc getPreprocessor*(gState: State, fullpath: string): string = else: cmd &= "-D__attribute__(x)= " - cmd &= "-D__restrict= -D__extension__= " + cmd &= "-D__restrict= -D__extension__= -D__inline__=inline -D__inline=inline " + + # https://github.com/tree-sitter/tree-sitter-c/issues/43 + cmd &= "-D_Noreturn= " cmd &= &"{fullpath.sanitizePath}" @@ -278,26 +287,26 @@ proc getPreprocessor*(gState: State, fullpath: string): string = start = false let saniLine = line.sanitizePath(noQuote = true) - if sfile in saniLine: - start = true - elif not ("\\" in line) and not ("/" in line) and extractFilename(sfile) in line: + if sfile in saniLine or + (DirSep notin saniLine and sfileName in saniLine): start = true elif gState.recurse: - let - pDir = sfile.expandFilename().parentDir().sanitizePath(noQuote = true) if pDir.Bl or pDir in saniLine: start = true else: - for inc in gState.includeDirs: - if inc.absolutePath().sanitizePath(noQuote = true) in saniLine: + for inc in includeDirs: + if inc in saniLine: start = true break else: if start: if "#undef" in line: continue - rdata.add line - return rdata.join("\n") + elif line.startsWith("#define"): + ddata.add line + else: + rdata.add line + gState.code = ddata.join("\n") & "\n" & rdata.join("\n") converter toString*(kind: Kind): string = return case kind: diff --git a/nimterop/globals.nim b/nimterop/globals.nim index 05284a9..79b1637 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -139,7 +139,7 @@ template Bl*(s: typed): untyped {.used.} = # Redirect output to file when required template gecho*(args: string) = if gState.outputHandle.isNil: - stdout.writeLine(args) + echo args else: gState.outputHandle.writeLine(args) diff --git a/nimterop/toast.nim b/nimterop/toast.nim index f54aa67..02d6494 100644 --- a/nimterop/toast.nim +++ b/nimterop/toast.nim @@ -13,7 +13,7 @@ proc process(gState: State, path: string, astTable: AstTable) = gState.mode = getCompilerMode(path) if gState.preprocess: - gState.code = gState.getPreprocessor(path) + gState.getPreprocessor(path) else: gState.code = readFile(path) @@ -35,7 +35,7 @@ proc main( debug = false, defines: seq[string] = @[], dynlib: string = "", - feature: seq[Feature] = @[Feature.ast1], + feature: seq[Feature] = @[], includeDirs: seq[string] = @[], mode = "", nim: string = "nim", @@ -83,6 +83,10 @@ proc main( # Set gDebug in build.nim build.gDebug = debug + # Default `ast` mode + if gState.feature.Bl: + gState.feature.add Feature.ast1 + # Split some arguments with , gState.symOverride = gState.symOverride.getSplitComma() gState.prefix = gState.prefix.getSplitComma() diff --git a/nimterop/tshelp.nim b/nimterop/tshelp.nim index 9565a1f..6760aa9 100644 --- a/nimterop/tshelp.nim +++ b/nimterop/tshelp.nim @@ -50,7 +50,7 @@ proc getName*(node: TSNode): string {.inline.} = proc getNodeVal*(code: var string, node: TSNode): string = if not node.isNil: - return code[node.tsNodeStartByte() .. node.tsNodeEndByte()-1].strip() + return code[node.tsNodeStartByte() .. node.tsNodeEndByte()-1] proc getNodeVal*(gState: State, node: TSNode): string = gState.code.getNodeVal(node) diff --git a/tests/rsa.nim b/tests/rsa.nim index e7bde89..a4aa64b 100644 --- a/tests/rsa.nim +++ b/tests/rsa.nim @@ -35,10 +35,11 @@ cPlugin: cOverride: proc OPENSSL_die*(assertion: cstring; file: cstring; line: cint) {.importc.} +# Skip comments for https://github.com/tree-sitter/tree-sitter-c/issues/44 cImport(@[ basePath / "rsa.h", basePath / "err.h", -], recurse = true, flags = "-f:ast2 -s " & FLAGS) +], recurse = true, flags = "-f:ast2 -s -c " & FLAGS) {.passL: cryptoLPath.} From 6f96437f39572f3b01f4e61b684f2a74cb524bba Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 18 May 2020 16:39:18 -0500 Subject: [PATCH 493/593] Reduce regex for perf, reduce globals for CT --- nimterop.nimble | 8 +- nimterop/build.nim | 4 +- nimterop/cimport.nim | 8 +- nimterop/getters.nim | 2 +- nimterop/globals.nim | 200 ++++++++++++++++++++++--------------------- nimterop/toast.nim | 2 - nimterop/tshelp.nim | 17 ++++ tests/tast2.nim | 2 + 8 files changed, 128 insertions(+), 115 deletions(-) diff --git a/nimterop.nimble b/nimterop.nimble index 187b0ce..1eb605d 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -30,15 +30,15 @@ proc execTest(test: string, flags = "", runDocs = true) = mkDir docPath buildDocs(@[test], docPath, nimArgs = "--hints:off " & flags) -task buildToast, "build toast": - execCmd("nim c --hints:off nimterop/toast.nim") - task buildTimeit, "build timer": exec "nim c --hints:off -d:danger tests/timeit" -task bt, "build toast": +task buildToast, "build toast": execCmd("nim c --hints:off -d:danger nimterop/toast.nim") +task bt, "build toast": + buildToastTask() + task btd, "build toast": execCmd("nim c -g nimterop/toast.nim") diff --git a/nimterop/build.nim b/nimterop/build.nim index b02132d..6f13ac7 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -2,8 +2,6 @@ import hashes, macros, osproc, sets, strformat, strutils, tables import os except findExe, sleep -import regex - type BuildType* = enum btAutoconf, btCmake @@ -995,7 +993,7 @@ macro getHeader*(header: static[string], giturl: static[string] = "", dlurl: sta ## prior to the build process. var origname = header.extractFilename().split(".")[0] - name = origname.replace(re"[[:^alnum:]]", "") + name = origname.split(seps = AllChars-Letters-Digits).join() # -d:xxx for this header stdStr = name & "Std" diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index 99be1f5..0559db7 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -17,8 +17,6 @@ All `{.compileTime.}` procs must be used in a compile time context, e.g. using: import hashes, macros, os, strformat, strutils -import regex - import "."/[build, globals, paths, types] export types @@ -684,7 +682,7 @@ macro c2nImport*(filename: static string, recurse: static bool = false, dynlib: hash = output.hash().abs() hpath = getProjectCacheDir("c2nimCache", forceClean = false) / "nimterop_" & $hash & ".h" npath = hpath[0 .. hpath.rfind('.')] & "nim" - header = ("header" & fullpath.splitFile().name.replace(re"[-.]+", "")) + header = "header" & fullpath.splitFile().name.split(seps = {'-', '.'}).join() if not fileExists(hpath) or gStateCT.nocache or compileOption("forceBuild"): mkDir(hpath.parentDir()) @@ -715,10 +713,6 @@ macro c2nImport*(filename: static string, recurse: static bool = false, dynlib: var nimout = &"const {header} = \"{fullpath}\"\n\n" & readFile(npath) - nimout = nimout. - replace(re"([u]?int[\d]+)_t", "$1"). - replace(re"([u]?int)ptr_t", "ptr $1") - if gStateCT.debug: echo nimout diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 825b1c4..716c577 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -227,7 +227,7 @@ proc getOverride*(gState: State, name: string, kind: NimSymKind): string = result = sym.override if kind != nskProc: - result = result.replace(re"(?m)^(.*?)$", " $1") + result = " " & result.replace("\n", "\n ") proc getOverrideFinal*(gState: State, kind: NimSymKind): string = # Get all unused cOverride symbols of `kind` diff --git a/nimterop/globals.nim b/nimterop/globals.nim index 79b1637..ac25a40 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -1,58 +1,19 @@ -import sequtils, sets, tables, strutils - -import regex - -import "."/plugin +import tables when defined(TOAST): + import sets, sequtils, strutils + + import regex + + import "."/plugin + import compiler/[ast, idents, modulegraphs, options] import "."/treesitter/api -const - gAtoms* {.used.} = @[ - "field_identifier", - "identifier", - "number_literal", - "char_literal", - "preproc_arg", - "primitive_type", - "sized_type_specifier", - "type_identifier" - ].toHashSet() - - gExpressions* {.used.} = @[ - "parenthesized_expression", - "bitwise_expression", - "shift_expression", - "math_expression", - "escape_sequence" - ].toHashSet() - - gEnumVals* {.used.} = @[ - "identifier", - "number_literal", - "char_literal" - ].concat(toSeq(gExpressions.items)) - type - Kind* = enum - exactlyOne - oneOrMore # + - zeroOrMore # * - zeroOrOne # ? - orWithNext # ! - - Ast* = object - name*: string - kind*: Kind - recursive*: bool - children*: seq[ref Ast] - when defined(TOAST): - tonim*: proc (ast: ref Ast, node: TSNode, gState: State) - regex*: Regex - - AstTable* {.used.} = TableRef[string, seq[ref Ast]] + Feature* = enum + ast1, ast2 State* = ref object # Command line arguments to toast - some forwarded from cimport.nim @@ -79,31 +40,25 @@ type typeMap*: TableRef[string, string] # `--typeMap | -T` to map instances of type X to Y - e.g. ABC=cint - # cimport.nim specific - compile*: seq[string] # `cCompile()` list of files already processed - nocache*: bool # `cDisableCaching()` to disable caching of artifacts - overrides*: string # `cOverride()` code which gets added to `cPlugin()` output - pluginSource*: string # `cPlugin()` generated code to write to plugin file from - searchDirs*: seq[string] # `cSearchPath()` added directories for header search - - # Data fields - code*: string # Contents of header file currently being processed - currentHeader*: string # Const name of header being currently processed - impShort*: string # Short base name for pragma in output - outputHandle*: File # `--output | -o` open file handle - sourceFile*: string # Full path of header being currently processed - - # Plugin callbacks - onSymbol*, onSymbolOverride*: OnSymbol - onSymbolOverrideFinal*: OnSymbolOverrideFinal - - # Symbol tables - constIdentifiers*: HashSet[string] # Const names for enum casting - identifiers*: TableRef[string, string] # Symbols that have been declared so far indexed by nimName - skippedSyms*: HashSet[string] # Symbols that have been skipped due to being unwrappable or - # the user provided override is blank - # Nim compiler objects when defined(TOAST): + # Data fields + code*: string # Contents of header file currently being processed + currentHeader*: string # Const name of header being currently processed + impShort*: string # Short base name for pragma in output + outputHandle*: File # `--output | -o` open file handle + sourceFile*: string # Full path of header being currently processed + + # Plugin callbacks + onSymbol*, onSymbolOverride*: OnSymbol + onSymbolOverrideFinal*: OnSymbolOverrideFinal + + # Symbol tables + constIdentifiers*: HashSet[string] # Const names for enum casting + identifiers*: TableRef[string, string] # Symbols that have been declared so far indexed by nimName + skippedSyms*: HashSet[string] # Symbols that have been skipped due to being unwrappable or + # the user provided override is blank + + # Nim compiler objects constSection*, enumSection*, pragmaSection*, procSection*, typeSection*, varSection*: PNode identCache*: IdentCache config*: ConfigRef @@ -112,37 +67,86 @@ type # Table of symbols to generated AST PNode - used to implement forward declarations identifierNodes*: TableRef[string, PNode] - # Used for the exprparser.nim module - currentExpr*, currentTyCastName*: string - # Controls whether or not the current expression - # should validate idents against currently defined idents - skipIdentValidation*: bool + # Used for the exprparser.nim module + currentExpr*, currentTyCastName*: string + # Controls whether or not the current expression + # should validate idents against currently defined idents + skipIdentValidation*: bool - # Legacy AST fields, remove when ast2 becomes default - constStr*, enumStr*, procStr*, typeStr*: string - commentStr*, debugStr*, skipStr*: string - data*: seq[tuple[name, val: string]] - nodeBranch*: seq[string] + # Legacy AST fields, remove when ast2 becomes default + constStr*, enumStr*, procStr*, typeStr*: string + commentStr*, debugStr*, skipStr*: string + data*: seq[tuple[name, val: string]] + nodeBranch*: seq[string] + else: + # cimport.nim specific + compile*: seq[string] # `cCompile()` list of files already processed + nocache*: bool # `cDisableCaching()` to disable caching of artifacts + overrides*: string # `cOverride()` code which gets added to `cPlugin()` output + pluginSource*: string # `cPlugin()` generated code to write to plugin file from + searchDirs*: seq[string] # `cSearchPath()` added directories for header search - Feature* = enum - ast1, ast2 +when defined(TOAST): + const + gAtoms* {.used.} = @[ + "field_identifier", + "identifier", + "number_literal", + "char_literal", + "preproc_arg", + "primitive_type", + "sized_type_specifier", + "type_identifier" + ].toHashSet() -var - gStateCT* {.compiletime, used.} = new(State) + gExpressions* {.used.} = @[ + "parenthesized_expression", + "bitwise_expression", + "shift_expression", + "math_expression", + "escape_sequence" + ].toHashSet() + + gEnumVals* {.used.} = @[ + "identifier", + "number_literal", + "char_literal" + ].concat(toSeq(gExpressions.items)) + + type + Kind* = enum + exactlyOne + oneOrMore # + + zeroOrMore # * + zeroOrOne # ? + orWithNext # ! + + Ast* = object + name*: string + kind*: Kind + recursive*: bool + children*: seq[ref Ast] + tonim*: proc (ast: ref Ast, node: TSNode, gState: State) + regex*: Regex + + AstTable* {.used.} = TableRef[string, seq[ref Ast]] + + # Redirect output to file when required + template gecho*(args: string) = + if gState.outputHandle.isNil: + echo args + else: + gState.outputHandle.writeLine(args) + + template decho*(args: varargs[string, `$`]): untyped = + if gState.debug: + gecho join(args, "").getCommented() +else: + var + gStateCT* {.compiletime, used.} = new(State) template nBl*(s: typed): untyped {.used.} = (s.len != 0) template Bl*(s: typed): untyped {.used.} = - (s.len == 0) - -# Redirect output to file when required -template gecho*(args: string) = - if gState.outputHandle.isNil: - echo args - else: - gState.outputHandle.writeLine(args) - -template decho*(args: varargs[string, `$`]): untyped = - if gState.debug: - gecho join(args, "").getCommented() \ No newline at end of file + (s.len == 0) \ No newline at end of file diff --git a/nimterop/toast.nim b/nimterop/toast.nim index 02d6494..84835a3 100644 --- a/nimterop/toast.nim +++ b/nimterop/toast.nim @@ -4,8 +4,6 @@ import "."/treesitter/[api, c, cpp] import "."/[ast, ast2, build, globals, getters, grammar, tshelp] -{.passC: "-DNIMTEROP".} - proc process(gState: State, path: string, astTable: AstTable) = doAssert existsFile(path), &"Invalid path {path}" diff --git a/nimterop/tshelp.nim b/nimterop/tshelp.nim index 6760aa9..fa2a750 100644 --- a/nimterop/tshelp.nim +++ b/nimterop/tshelp.nim @@ -79,6 +79,23 @@ proc getStartAtom*(node: TSNode): int = else: break +proc getConstQualifier*(gState: State, node: TSNode): bool = + # Check if node siblings have type_qualifier = `const` + var + curr = node.tsNodePrevNamedSibling() + while not curr.isNil: + # Check previous siblings + if curr.getName() == "type_qualifier" and + gState.getNodeVal(curr) == "const": + return true + curr = curr.tsNodePrevNamedSibling() + + # Check immediate next sibling + curr = node.tsNodePrevNamedSibling() + if curr.getName() == "type_qualifier" and + gState.getNodeVal(curr) == "const": + return true + proc getXCount*(node: TSNode, ntype: string, reverse = false): int = if not node.isNil: # Get number of ntype nodes nested in tree diff --git a/tests/tast2.nim b/tests/tast2.nim index 8deb99e..fd0175a 100644 --- a/tests/tast2.nim +++ b/tests/tast2.nim @@ -2,6 +2,8 @@ import macros, os, sets, strutils import nimterop/[cimport] +{.passC: "-DNIMTEROP".} + static: # Skip casting on lower nim compilers because # the VM does not support it From f079d851db1db0dd64d7538a8b417b1e5c0985a1 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 19 May 2020 10:27:31 -0500 Subject: [PATCH 494/593] Changelog for variable support --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index ea3f427..e47974d 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -35,6 +35,7 @@ https://github.com/nimterop/nimterop/compare/v0.4.4...v0.5.0 - Nested function pointers - [#155][i155] [#156][i156] - Various enum fixes - [#159][i159] [#171][i171] - Map `int arr[]` to `arr: UncheckedArray[cint]` - [#174][i174] + - Global variables including arrays and procs (since v0.5.4) - `ast2` also includes an advanced expression parser that can reliably handle constructs typically seen with `#define` statements and enumeration values: - Integers + integer like expressions (hex, octal, suffixes) From 7d3f52f1dc0829bc8540a413925147b96b5298fe Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 19 May 2020 10:27:36 -0500 Subject: [PATCH 495/593] v0.5.4 --- nimterop.nimble | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimterop.nimble b/nimterop.nimble index 1eb605d..d1ad7ce 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -1,6 +1,6 @@ # Package -version = "0.5.3" +version = "0.5.4" author = "genotrance" description = "C/C++ interop for Nim" license = "MIT" From e32fd4d1d2542a6ffaeb8221a3da7ef136669651 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 20 May 2020 15:16:26 -0500 Subject: [PATCH 496/593] ast2 handle tree-sitter errors, multi-reorder --- nimterop/ast2.nim | 100 +++++++++++++++++++++++++------------------ nimterop/getters.nim | 8 +--- nimterop/globals.nim | 3 ++ 3 files changed, 64 insertions(+), 47 deletions(-) diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index 3d52e02..e2cdf8f 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -27,7 +27,7 @@ proc getOverrideOrSkip(gState: State, node: TSNode, origname: string, kind: NimS if not pnode.isNil: result = pnode[0][0] else: - gecho &"\n# $1'{origname}' skipped" % skind + gecho &"# {skind}'{origname}' skipped" gState.skippedSyms.incl origname proc addOverrideFinal(gState: State, kind: NimSymKind) = @@ -391,7 +391,7 @@ proc newXIdent(gState: State, node: TSNode, kind = nskType, fname = "", pragmas: gState.identifierNodes[name] = result else: - gecho &"# $1 '{origname}' is duplicate, skipped" % getKeyword(kind) + gecho &"# {getKeyword(kind)} '{origname}' is duplicate, skipped" proc newArrayTree(gState: State, node: TSNode, typ, size: PNode = nil): PNode = # Create nkBracketExpr tree depending on input @@ -682,7 +682,7 @@ proc newProcTy(gState: State, name: string, node: TSNode, rtyp: PNode): PNode = if node.getVarargs(): gState.addPragma(node, result[^1], "varargs") -proc processNode(gState: State, node: TSNode): bool +proc processNode(gState: State, node: TSNode): Status proc newRecListTree(gState: State, name: string, node: TSNode): PNode = # Create nkRecList tree for specified object if not node.isNil: @@ -720,9 +720,9 @@ proc newRecListTree(gState: State, name: string, node: TSNode): PNode = $gState.enumSection[^1][0][1] ) else: - (true, "") + (success, "") - if not processed: + if processed != success: return nil # Add nkIdentDefs for each field @@ -1699,35 +1699,52 @@ proc addDef(gState: State, node: TSNode) = if not gState.noHeader: gState.addProc(node[start+1], node[start], commentNodes) else: - gecho &"\n# proc '$1' skipped - static inline procs cannot work with '--noHeader | -H'" % + gecho "# proc '$1' skipped - static inline procs cannot work with '--noHeader | -H'" % gState.getNodeVal(node[start+1].getAtom()) -proc processNode(gState: State, node: TSNode): bool = - result = true +proc processNode(gState: State, node: TSNode): Status = + const + known = ["preproc_def", "type_definition", + "struct_specifier", "union_specifier", "enum_specifier", + "declaration", "function_definition"].toHashSet() - case node.getName() - of "preproc_def": - gState.addConst(node) - of "type_definition": - if node.len > 0 and node[0].getName() == "enum_specifier": - gState.addEnum(node) - elif node.len > 0 and node[0].getName() == "union_specifier": - gState.addType(node, union = true) + result = success + let + name = node.getName() + if name in known: + # Recognized top-level nodes + let + err = node.anyChildInTree("ERROR") + if not err.isNil: + # Bail on errors + gState.printDebug(node) + gecho &"# tree-sitter parse error: '{gState.getNodeVal(node).splitLines()[0]}', skipped" + result = Status.error else: - gState.addType(node) - of "struct_specifier": - gState.addType(node) - of "union_specifier": - gState.addType(node, union = true) - of "enum_specifier": - gState.addEnum(node) - of "declaration": - gState.addDecl(node) - of "function_definition": - gState.addDef(node) + # Process nodes + case name + of "preproc_def": + gState.addConst(node) + of "type_definition": + if node.len > 0 and node[0].getName() == "enum_specifier": + gState.addEnum(node) + elif node.len > 0 and node[0].getName() == "union_specifier": + gState.addType(node, union = true) + else: + gState.addType(node) + of "struct_specifier": + gState.addType(node) + of "union_specifier": + gState.addType(node, union = true) + of "enum_specifier": + gState.addEnum(node) + of "declaration": + gState.addDecl(node) + of "function_definition": + gState.addDef(node) else: - # Unknown - result = false + # Unknown, will check child nodes + result = unknown proc searchTree(gState: State, root: TSNode) = # Search AST generated by tree-sitter for recognized elements @@ -1735,7 +1752,7 @@ proc searchTree(gState: State, root: TSNode) = node = root nextnode: TSNode depth = 0 - processed = false + processed = success while true: if not node.isNil and depth > -1: @@ -1743,7 +1760,7 @@ proc searchTree(gState: State, root: TSNode) = else: break - if not processed and node.len != 0: + if processed == unknown and node.len != 0: nextnode = node[0] depth += 1 else: @@ -1773,27 +1790,28 @@ proc searchTree(gState: State, root: TSNode) = proc setupPragmas(gState: State, root: TSNode, fullpath: string) = # Create shortcut pragmas to reduce clutter var - hdrPragma: PNode - dynPragma: PNode + count = 0 if not gState.noHeader: # {.pragma: impnameHdr, header: "xxx".} - hdrPragma = gState.newPragma(root, "pragma", gState.getIdent(gState.impShort & "Hdr")) + let + hdrPragma = gState.newPragma(root, "pragma", gState.getIdent(gState.impShort & "Hdr")) gState.addPragma(root, hdrPragma, "header", newStrNode(nkStrLit, fullpath)) + gState.pragmaSection.add hdrPragma + count += 1 if gState.dynlib.nBl: # {.pragma: impnameDyn, dynlib: libname.} - dynPragma = gState.newPragma(root, "pragma", gState.getIdent(gState.impShort & "Dyn")) + let + dynPragma = gState.newPragma(root, "pragma", gState.getIdent(gState.impShort & "Dyn")) gState.addPragma(root, dynPragma, "dynlib", gState.getIdent(gState.dynlib)) - - # Add pragma shortcuts to output - if not hdrPragma.isNil: - gState.pragmaSection.add hdrPragma - if not dynPragma.isNil: gState.pragmaSection.add dynPragma + count += 1 # Add `{.experimental: "codeReordering".} for #206 - gState.pragmaSection.add gState.newPragma(root, "experimental", newStrNode(nkStrLit, "codeReordering")) + if gState.pragmaSection.len == count: + # Only if not already done + gState.pragmaSection.add gState.newPragma(root, "experimental", newStrNode(nkStrLit, "codeReordering")) proc initNim*(gState: State) = # Initialize for parseNim() one time diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 716c577..0906d56 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -251,7 +251,6 @@ proc getPreprocessor*(gState: State, fullpath: string) = cmts = if gState.noComments: "" else: "-CC" cmd = &"""{getCompiler()} -E {cmts} -dD {getGccModeArg(gState.mode)} -w """ - ddata: seq[string] rdata: seq[string] start = false sfile = fullpath.sanitizePath(noQuote = true) @@ -302,11 +301,8 @@ proc getPreprocessor*(gState: State, fullpath: string) = if start: if "#undef" in line: continue - elif line.startsWith("#define"): - ddata.add line - else: - rdata.add line - gState.code = ddata.join("\n") & "\n" & rdata.join("\n") + rdata.add line + gState.code = rdata.join("\n") converter toString*(kind: Kind): string = return case kind: diff --git a/nimterop/globals.nim b/nimterop/globals.nim index ac25a40..8062ac8 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -131,6 +131,9 @@ when defined(TOAST): AstTable* {.used.} = TableRef[string, seq[ref Ast]] + Status* = enum + success, unknown, error + # Redirect output to file when required template gecho*(args: string) = if gState.outputHandle.isNil: From 80cfc99dcd08a145569f28ad6b9999dbd9868bda Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 20 May 2020 16:58:52 -0500 Subject: [PATCH 497/593] Fix nimconf path to nim --- nimterop/ast2.nim | 2 +- nimterop/build.nim | 14 +++++++++----- nimterop/getters.nim | 2 +- nimterop/nimconf.nim | 2 +- nimterop/toast.nim | 5 +++-- 5 files changed, 15 insertions(+), 10 deletions(-) diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index e2cdf8f..b604f1b 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -139,7 +139,7 @@ proc newConstDef(gState: State, node: TSNode, fname = "", fval = ""): PNode = else: gecho &"# const '{origname}' is duplicate, skipped" else: - gecho &"# const '{origname}' has unsupported value '{val}'" + gecho &"# const '{origname}' has unsupported value '{val.strip()}'" gState.skippedSyms.incl origname proc addConst(gState: State, node: TSNode) = diff --git a/nimterop/build.nim b/nimterop/build.nim index 6f13ac7..58ecbd1 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -15,6 +15,7 @@ type var gDebug* = false gDebugCT* {.compileTime.} = false + gNimExe* = "" proc echoDebug(str: string) = let str = "\n# " & str.strip().replace("\n", "\n# ") @@ -46,6 +47,14 @@ proc sanitizePath*(path: string, noQuote = false, sep = $DirSep): string = if not noQuote: result = result.quoteShell +proc getCurrentNimCompiler*(): string = + when nimvm: + result = getCurrentCompilerExe() + when defined(nimsuggest): + result = result.replace("nimsuggest", "nim") + else: + result = gNimExe + # Nim cfg file related functionality include "."/nimconf @@ -64,11 +73,6 @@ proc getNimteropCacheDir(): string = # Get location to cache all nimterop artifacts result = getNimcacheDir() / "nimterop" -proc getCurrentNimCompiler*(): string = - result = getCurrentCompilerExe() - when defined(nimsuggest): - result = result.replace("nimsuggest", "nim") - proc execAction*(cmd: string, retry = 0, die = true, cache = false, cacheKey = ""): tuple[output: string, ret: int] = ## Execute an external command - supported at compile time diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 0906d56..b092663 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -454,7 +454,7 @@ proc loadPlugin*(gState: State, sourcePath: string) = outflags = &"--out:\"{pdll}\"" # Compile plugin as library with `markAndSweep` GC - cmd = &"{gState.nim.sanitizePath} c --app:lib --gc:markAndSweep {flags} {outflags} {sourcePath.sanitizePath}" + cmd = &"{gState.nim} c --app:lib --gc:markAndSweep {flags} {outflags} {sourcePath.sanitizePath}" discard execAction(cmd) doAssert fileExists(pdll), "No plugin binary generated for " & sourcePath diff --git a/nimterop/nimconf.nim b/nimterop/nimconf.nim index 2a54d7e..33215ef 100644 --- a/nimterop/nimconf.nim +++ b/nimterop/nimconf.nim @@ -20,7 +20,7 @@ type proc getJson(projectDir: string): JsonNode = # Get `nim dump` json value for `projectDir` var - cmd = "nim --hints:off --dump.format:json dump dummy" + cmd = &"{getCurrentNimCompiler()} --hints:off --dump.format:json dump dummy" dump = "" ret = 0 diff --git a/nimterop/toast.nim b/nimterop/toast.nim index 84835a3..4a9553b 100644 --- a/nimterop/toast.nim +++ b/nimterop/toast.nim @@ -64,7 +64,7 @@ proc main( feature: feature, includeDirs: includeDirs, mode: mode, - nim: nim, + nim: nim.sanitizePath, noComments: noComments, noHeader: noHeader, past: past, @@ -79,7 +79,8 @@ proc main( ) # Set gDebug in build.nim - build.gDebug = debug + build.gDebug = gState.debug + build.gNimExe = gState.nim # Default `ast` mode if gState.feature.Bl: From 6c01f5504771d2a3b013097007f16a5414baa5b7 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 21 May 2020 13:51:15 -0500 Subject: [PATCH 498/593] No pointless hints --- nimterop/ast.nim | 2 ++ nimterop/ast2.nim | 7 ++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/nimterop/ast.nim b/nimterop/ast.nim index 96116c7..78501fd 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -238,6 +238,8 @@ proc printNim*(gState: State) = if gState.procStr.nBl: gecho &"{gState.procStr}\n" + gecho "{.pop.}" + if gState.debug: if gState.debugStr.nBl: gecho gState.debugStr diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index e2cdf8f..f4e15db 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -1815,7 +1815,10 @@ proc setupPragmas(gState: State, root: TSNode, fullpath: string) = proc initNim*(gState: State) = # Initialize for parseNim() one time - gecho "import nimterop/types\n" + gecho """import nimterop/types + +{.push hint[ConvFromXtoItselfNotNeeded]: off.} +""" # Track identifiers already rendered and corresponding PNodes gState.identifiers = newTable[string, string]() @@ -1867,3 +1870,5 @@ proc printNim*(gState: State) = tree.add gState.procSection gecho tree.renderTree() + + gecho "{.pop.}" \ No newline at end of file From a54991122de7f586f3671316eaf079b25d1eae16 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 20 May 2020 16:58:52 -0500 Subject: [PATCH 499/593] Fix nimconf path to nim --- nimterop/ast2.nim | 2 +- nimterop/build.nim | 14 +++++++++----- nimterop/getters.nim | 2 +- nimterop/nimconf.nim | 2 +- nimterop/toast.nim | 5 +++-- 5 files changed, 15 insertions(+), 10 deletions(-) diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index f4e15db..759ddfd 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -139,7 +139,7 @@ proc newConstDef(gState: State, node: TSNode, fname = "", fval = ""): PNode = else: gecho &"# const '{origname}' is duplicate, skipped" else: - gecho &"# const '{origname}' has unsupported value '{val}'" + gecho &"# const '{origname}' has unsupported value '{val.strip()}'" gState.skippedSyms.incl origname proc addConst(gState: State, node: TSNode) = diff --git a/nimterop/build.nim b/nimterop/build.nim index 6f13ac7..58ecbd1 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -15,6 +15,7 @@ type var gDebug* = false gDebugCT* {.compileTime.} = false + gNimExe* = "" proc echoDebug(str: string) = let str = "\n# " & str.strip().replace("\n", "\n# ") @@ -46,6 +47,14 @@ proc sanitizePath*(path: string, noQuote = false, sep = $DirSep): string = if not noQuote: result = result.quoteShell +proc getCurrentNimCompiler*(): string = + when nimvm: + result = getCurrentCompilerExe() + when defined(nimsuggest): + result = result.replace("nimsuggest", "nim") + else: + result = gNimExe + # Nim cfg file related functionality include "."/nimconf @@ -64,11 +73,6 @@ proc getNimteropCacheDir(): string = # Get location to cache all nimterop artifacts result = getNimcacheDir() / "nimterop" -proc getCurrentNimCompiler*(): string = - result = getCurrentCompilerExe() - when defined(nimsuggest): - result = result.replace("nimsuggest", "nim") - proc execAction*(cmd: string, retry = 0, die = true, cache = false, cacheKey = ""): tuple[output: string, ret: int] = ## Execute an external command - supported at compile time diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 0906d56..b092663 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -454,7 +454,7 @@ proc loadPlugin*(gState: State, sourcePath: string) = outflags = &"--out:\"{pdll}\"" # Compile plugin as library with `markAndSweep` GC - cmd = &"{gState.nim.sanitizePath} c --app:lib --gc:markAndSweep {flags} {outflags} {sourcePath.sanitizePath}" + cmd = &"{gState.nim} c --app:lib --gc:markAndSweep {flags} {outflags} {sourcePath.sanitizePath}" discard execAction(cmd) doAssert fileExists(pdll), "No plugin binary generated for " & sourcePath diff --git a/nimterop/nimconf.nim b/nimterop/nimconf.nim index 2a54d7e..33215ef 100644 --- a/nimterop/nimconf.nim +++ b/nimterop/nimconf.nim @@ -20,7 +20,7 @@ type proc getJson(projectDir: string): JsonNode = # Get `nim dump` json value for `projectDir` var - cmd = "nim --hints:off --dump.format:json dump dummy" + cmd = &"{getCurrentNimCompiler()} --hints:off --dump.format:json dump dummy" dump = "" ret = 0 diff --git a/nimterop/toast.nim b/nimterop/toast.nim index 84835a3..4a9553b 100644 --- a/nimterop/toast.nim +++ b/nimterop/toast.nim @@ -64,7 +64,7 @@ proc main( feature: feature, includeDirs: includeDirs, mode: mode, - nim: nim, + nim: nim.sanitizePath, noComments: noComments, noHeader: noHeader, past: past, @@ -79,7 +79,8 @@ proc main( ) # Set gDebug in build.nim - build.gDebug = debug + build.gDebug = gState.debug + build.gNimExe = gState.nim # Default `ast` mode if gState.feature.Bl: From f1b5f5b8905a015c4e220c7689b7a05ac9375eee Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 21 May 2020 14:57:58 -0500 Subject: [PATCH 500/593] v0.5.5 --- nimterop.nimble | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimterop.nimble b/nimterop.nimble index d1ad7ce..76f05ea 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -1,6 +1,6 @@ # Package -version = "0.5.4" +version = "0.5.5" author = "genotrance" description = "C/C++ interop for Nim" license = "MIT" From ebf9018df85aa3385b19aed6273d80390753fdeb Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Sat, 23 May 2020 11:29:59 -0600 Subject: [PATCH 501/593] Try markdown code block --- nimterop/tshelp.nim | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/nimterop/tshelp.nim b/nimterop/tshelp.nim index fa2a750..ad3e89e 100644 --- a/nimterop/tshelp.nim +++ b/nimterop/tshelp.nim @@ -284,18 +284,17 @@ proc getCommentsStr*(gState: State, commentNodes: seq[TSNode]): string = ## Generate a comment from a set of comment nodes. Comment is guaranteed ## to be able to be rendered using nim doc if commentNodes.len > 0: - result = "::" for commentNode in commentNodes: result &= "\n " & gState.getNodeVal(commentNode).strip() - result = result.multiReplace( + result = "```\n " & result.multiReplace( { "/**": "", "**/": "", "/*": "", "*/": "", "/*": "", "//": "", "\n": "\n ", "`": "" } # need to replace this last otherwise it supercedes other replacements - ).replace(" *", "").strip() + ).replace(" *", "").strip() & "\n```" proc getCommentNodes*(gState: State, node: TSNode, maxSearch=1): seq[TSNode] = ## Get a set of comment nodes in order of priority. Will search up to ``maxSearch`` From 0e3c2d02f9566786d106687239fc39331e72cf41 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 25 May 2020 22:56:32 -0500 Subject: [PATCH 502/593] v0.5.6 --- nimterop.nimble | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimterop.nimble b/nimterop.nimble index 76f05ea..3c8e74c 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -1,6 +1,6 @@ # Package -version = "0.5.5" +version = "0.5.6" author = "genotrance" description = "C/C++ interop for Nim" license = "MIT" From e8baeb92294328d9750469f852816c5a47375954 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 27 May 2020 10:25:48 -0500 Subject: [PATCH 503/593] Fix #222 --- nimterop/ast2.nim | 2 +- nimterop/build.nim | 3 +++ tests/include/tast2.h | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index 759ddfd..de3b452 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -608,7 +608,7 @@ iterator newIdentDefs(gState: State, name: string, node: TSNode, offset: SomeInt # Skip qualifiers after type var start = start0 - while start < node.len - 1 and node[start+1].getName() == "type_qualifier": + while start < node.len - 1 and node[start+1].getName() in ["type_qualifier", "comment"]: start += 1 if start == node.len - 1: diff --git a/nimterop/build.nim b/nimterop/build.nim index 58ecbd1..e0d630a 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -365,6 +365,9 @@ proc gitPull*(url: string, outdir = "", plist = "", checkout = "") = discard execAction(&"cd {outdirQ} && git config core.sparsecheckout true") writeFile(sparsefile, plist) + # In case directory has old files from another run + discard execAction(&"cd {outdirQ} && git clean -fxd") + if checkout.len != 0: echo "# Checking out " & checkout discard execAction(&"cd {outdirQ} && git fetch", retry = 1) diff --git a/tests/include/tast2.h b/tests/include/tast2.h index b8433f9..019f7c4 100644 --- a/tests/include/tast2.h +++ b/tests/include/tast2.h @@ -90,7 +90,7 @@ typedef char *(*A11)[3]; typedef struct A0 *A111[12]; typedef int - **(*A12)(int, int b, int *c, int *, int *count[4], int (*func)(int, int)), + **(*A12)(int, int b, int *c, int *, int /*out*/ *count[4], int (*func)(int, int)), **(*A121)(float, float b, float *c, float *, float *count[4], float (*func)(float, float)), **(*A122)(char, char b, char *c, char *, char *count[4], char (*func)(char, char)); typedef int (*A13)(int, int, void (*func)(void)); From d875252238ceb6a8134b2c9429f8a6c383aff48a Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 27 May 2020 11:54:50 -0500 Subject: [PATCH 504/593] v0.5.7 --- nimterop.nimble | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimterop.nimble b/nimterop.nimble index 3c8e74c..eed70ba 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -1,6 +1,6 @@ # Package -version = "0.5.6" +version = "0.5.7" author = "genotrance" description = "C/C++ interop for Nim" license = "MIT" From fa02a6e0bc955042ac867c5a3a462a00d9cfe092 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 16 Jun 2020 17:42:31 -0500 Subject: [PATCH 505/593] Fix #227 - paramCount/Str revert --- nimterop/docs.nim | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/nimterop/docs.nim b/nimterop/docs.nim index 6c2bbfd..5fe87a1 100644 --- a/nimterop/docs.nim +++ b/nimterop/docs.nim @@ -2,11 +2,8 @@ import macros, strformat from os import parentDir, getCurrentCompilerExe, DirSep -when defined(nimdoc) or (NimMajor, NimMinor) >= (1, 3): - from os import paramCount, paramStr - when defined(nimdoc): - from os import getCurrentDir + from os import getCurrentDir, paramCount, paramStr proc getNimRootDir(): string = #[ From 2885753dca1acacd3bcebb299fb7fa2aa7a88fe4 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 16 Jun 2020 20:42:42 -0500 Subject: [PATCH 506/593] v0.5.8 --- nimterop.nimble | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimterop.nimble b/nimterop.nimble index eed70ba..b5fab89 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -1,6 +1,6 @@ # Package -version = "0.5.7" +version = "0.5.8" author = "genotrance" description = "C/C++ interop for Nim" license = "MIT" From eb2fd1c1dd40ad5ecb0ee6389f67c7704375ac85 Mon Sep 17 00:00:00 2001 From: Euan Date: Thu, 18 Jun 2020 19:08:29 +0100 Subject: [PATCH 507/593] Fix #229 - FreeBSD build error --- nimterop/toast.nims | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/nimterop/toast.nims b/nimterop/toast.nims index 83d5cf4..e9a3c99 100644 --- a/nimterop/toast.nims +++ b/nimterop/toast.nims @@ -1,10 +1,8 @@ import os # Workaround for C++ scanner.cc causing link error with other C obj files -when defined(MacOSX): - switch("clang.linkerexe", "g++") -else: - switch("gcc.linkerexe", "g++") +switch("clang.linkerexe", "clang++") +switch("gcc.linkerexe", "g++") # Workaround for NilAccessError crash on Windows #98 # Could also help for OSX/Linux crash @@ -25,4 +23,4 @@ when not defined(danger): switch("out", currentSourcePath.parentDir() / "toast".addFileExt(ExeExt)) # Define TOAST for globals.nim -switch("define", "TOAST") \ No newline at end of file +switch("define", "TOAST") From 68cb3ab0b449c6155d5a797bec4d715a80423f05 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 18 Jun 2020 15:10:49 -0500 Subject: [PATCH 508/593] v0.5.9 --- nimterop.nimble | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimterop.nimble b/nimterop.nimble index b5fab89..1657aed 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -1,6 +1,6 @@ # Package -version = "0.5.8" +version = "0.5.9" author = "genotrance" description = "C/C++ interop for Nim" license = "MIT" From 290ad2b96733170ad653abd9f3705b5f50c4dcca Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 9 Jun 2020 23:21:11 -0500 Subject: [PATCH 509/593] Initial conan.io support --- nimterop/build.nim | 111 ++++++++++++-- nimterop/conan.nim | 373 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 468 insertions(+), 16 deletions(-) create mode 100644 nimterop/conan.nim diff --git a/nimterop/build.nim b/nimterop/build.nim index e0d630a..d5ce59c 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -206,6 +206,14 @@ proc rmDir*(dir: string) = ## Remove a directory or pattern at compile time rmFile(dir, dir = true) +proc cleanDir*(dir: string) = + ## Remove all contents of a directory at compile time + for kind, path in walkDir(dir): + if kind == pcDir: + rmDir(path) + else: + rmFile(path) + proc getProjectCacheDir*(name: string, forceClean = true): string = ## Get a cache directory where all nimterop artifacts can be stored ## @@ -281,7 +289,7 @@ proc extractTar*(tarfile, outdir: string) = if name.len != 0: rmFile(outdir / name) -proc downloadUrl*(url, outdir: string) = +proc downloadUrl*(url, outdir: string, quiet = false) = ## Download a file using `curl` or `wget` (or `powershell` on Windows) to the specified directory ## ## If an archive file, it is automatically extracted after download. @@ -291,7 +299,8 @@ proc downloadUrl*(url, outdir: string) = archives = @[".zip", ".xz", ".gz", ".bz2", ".tgz", ".tar"] if not (ext in archives and fileExists(outdir/file)): - echo "# Downloading " & file + if not quiet: + echo "# Downloading " & file mkDir(outdir) var cmd = findExe("curl") if cmd.len != 0: @@ -304,7 +313,7 @@ proc downloadUrl*(url, outdir: string) = cmd = "powershell [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; wget $# -OutFile $#" else: doAssert false, "No download tool available - curl, wget" - discard execAction(cmd % [url, (outdir/file).sanitizePath], retry = 1) + discard execAction(cmd % [url.quoteShell, (outdir/file).sanitizePath], retry = 1) if ext == ".zip": extractZip(file, outdir) @@ -732,6 +741,36 @@ proc getGccLibPaths*(mode: string): seq[string] = when defined(osx): result.add "/usr/lib" +proc getGccInfo*(): tuple[arch, os, compiler, version: string] = + let + (outp, _) = execAction(&"{getCompiler()} -v") + for line in outp.splitLines(): + if line.startsWith("Target: "): + result.arch = line.split(' ')[1].split('-')[0] + result.os = + if "linux" in line: + "linux" + elif "android" in line: + "android" + elif "darwin" in line: + "macos" + elif "w64" in line or "mingw" in line: + "windows" + else: + "unknown" + elif " version " in line: + result.version = line.split(" version ")[1].split(' ')[0] + if "clang" in outp: + if result.os == "macos": + result.compiler = "apple-clang" + else: + result.compiler = "clang" + else: + result.compiler = "gcc" + +# Conan support +include conan + proc getStdPath(header, mode: string): string = for inc in getGccPaths(mode): result = findFile(header, inc, recurse = false, first = true) @@ -784,6 +823,28 @@ proc getDlPath(header, url, outdir, version: string): string = result = findFile(header, outdir) +proc getConanPath(header, uri, outdir, version: string, shared: bool): string = + var + uri = uri + + if "$#" in uri or "$1" in uri: + doAssert version.len != 0, "Need version for Conan uri" + uri = uri % version + else: + doAssert version.len == 0, "Conan uri does not contain version" + + let + pkg = newConanPackageFromUri(uri, shared) + downloadConan(pkg, outdir) + + result = findFile(header, outdir) + +proc getConanLPath(outdir: string): string = + let + pkg = loadConanInfo(outdir) + + result = pkg.getConanLibs(outdir).join(" ") + proc getLocalPath(header, outdir: string): string = if outdir.len != 0: result = findFile(header, outdir) @@ -937,7 +998,9 @@ macro isDefined*(def: untyped): untyped = false ) -macro getHeader*(header: static[string], giturl: static[string] = "", dlurl: static[string] = "", outdir: static[string] = "", +macro getHeader*( + header: static[string], giturl: static[string] = "", dlurl: static[string] = "", + conanuri: static[string] = "", outdir: static[string] = "", conFlags: static[string] = "", cmakeFlags: static[string] = "", makeFlags: static[string] = "", altNames: static[string] = "", buildTypes: static[openArray[BuildType]] = [btCmake, btAutoconf]): untyped = ## Get the path to a header file for wrapping with @@ -950,16 +1013,18 @@ macro getHeader*(header: static[string], giturl: static[string] = "", dlurl: sta ## `-d:xxxStd` - search standard system paths. E.g. `/usr/include` and `/usr/lib` on Linux ## `-d:xxxGit` - clone source from a git repo specified in `giturl` ## `-d:xxxDL` - download source from `dlurl` and extract if required + ## `-d:xxxConan` - download headers and binary from conan.io using `conanuri` + ## typically formatted as `name/version[@user/channel][:bhash]` ## ## This allows a single wrapper to be used in different ways depending on the user's needs. ## If no `-d:xxx` defines are specified, `outdir` will be searched for the header as is. ## - ## If multiple `-d:xxx` defines are specified, precedence is `Std` and then `Git` or `DL`. - ## This allows using a system installed library if available before falling back to manual - ## building. + ## If multiple `-d:xxx` defines are specified, precedence is `Std` and then `Git`, `DL` or + ## `Conan`. This allows using a system installed library if available before falling back + ## to manual building. ## ## `-d:xxxSetVer=x.y.z` can be used to specify which version to use. It is used as a tag - ## name for Git whereas for DL, it replaces `$1` in the URL defined. + ## name for Git whereas for DL and Conan, it replaces `$1` in the URL defined. ## ## All defines can also be set in code using `setDefines()`. ## @@ -1006,6 +1071,7 @@ macro getHeader*(header: static[string], giturl: static[string] = "", dlurl: sta stdStr = name & "Std" gitStr = name & "Git" dlStr = name & "DL" + conanStr = name & "Conan" staticStr = name & "Static" verStr = name & "SetVer" @@ -1014,6 +1080,7 @@ macro getHeader*(header: static[string], giturl: static[string] = "", dlurl: sta nameStd = newIdentNode(stdStr) nameGit = newIdentNode(gitStr) nameDL = newIdentNode(dlStr) + nameConan = newIdentNode(conanStr) nameStatic = newIdentNode(staticStr) @@ -1031,6 +1098,7 @@ macro getHeader*(header: static[string], giturl: static[string] = "", dlurl: sta stdVal = gDefines.hasKey(stdStr) gitVal = gDefines.hasKey(gitStr) dlVal = gDefines.hasKey(dlStr) + conanVal = gDefines.hasKey(conanStr) staticVal = gDefines.hasKey(staticStr) verVal = if gDefines.hasKey(verStr): @@ -1052,14 +1120,17 @@ macro getHeader*(header: static[string], giturl: static[string] = "", dlurl: sta `nameStd`* = when defined(`nameStd`): true else: `stdVal` == 1 `nameGit`* = when defined(`nameGit`): true else: `gitVal` == 1 `nameDL`* = when defined(`nameDL`): true else: `dlVal` == 1 + `nameConan`* = when defined(`nameConan`): true else: `conanVal` == 1 `nameStatic`* = when defined(`nameStatic`): true else: `staticVal` == 1 # Search for header in outdir (after retrieving code) depending on -d:xxx mode - proc getPath(header, giturl, dlurl, outdir, version: string): string = + proc getPath(header, giturl, dlurl, conanuri, outdir, version: string, shared: bool): string = when `nameGit`: getGitPath(header, giturl, outdir, version) elif `nameDL`: getDlPath(header, dlurl, outdir, version) + elif `nameConan`: + getConanPath(header, conanuri, outdir, version, shared) else: getLocalPath(header, outdir) @@ -1077,23 +1148,30 @@ macro getHeader*(header: static[string], giturl: static[string] = "", dlurl: sta stdLPath = when `nameStd`: getStdLibPath(`lname`, `mode`) else: "" + useStd = stdPath.len != 0 and stdLPath.len != 0 + # Look elsewhere if requested while prioritizing standard paths prePath = - when stdPath.len != 0 and stdLPath.len != 0: + when useStd: stdPath else: - getPath(`header`, `giturl`, `dlurl`, `outdir`, `version`) + getPath(`header`, `giturl`, `dlurl`, `conanuri`, `outdir`, `version`, not `nameStatic`) - # Run preBuild hook before building library if not standard - when (prePath != stdPath or prePath.len == 0) and declared(`preBuild`): + # Run preBuild hook before building library if not Std or Conan + when not (useStd or `nameConan`) and declared(`preBuild`): static: `preBuild`(`outdir`, prePath) const # Library binary path - build if not standard `lpath`* = - when stdPath.len != 0 and stdLPath.len != 0: + when useStd: stdLPath + elif `nameConan`: + when `nameStatic`: + getConanLPath(`outdir`) + else: + findFile(`lname`, `outdir`, regex = true) else: buildLibrary(`lname`, `outdir`, `conFlags`, `cmakeFlags`, `makeFlags`, `buildTypes`) @@ -1102,10 +1180,11 @@ macro getHeader*(header: static[string], giturl: static[string] = "", dlurl: sta if prePath.len != 0: prePath else: - getPath(`header`, `giturl`, `dlurl`, `outdir`, `version`) + getPath(`header`, `giturl`, `dlurl`, `conanuri`, `outdir`, `version`, not `nameStatic`) static: - doAssert `path`.len != 0, "\nHeader " & `header` & " not found - " & "missing/empty outdir or -d:$1Std -d:$1Git or -d:$1DL not specified" % `name` + doAssert `path`.len != 0, "\nHeader " & `header` & " not found - " & + "missing/empty outdir or -d:$1Std -d:$1Git -d:$1DL or -d:$1Conan not specified" % `name` doAssert `lpath`.len != 0, "\nLibrary " & `lname` & " not found" echo "# Including library " & `lpath` diff --git a/nimterop/conan.nim b/nimterop/conan.nim new file mode 100644 index 0000000..0707ecc --- /dev/null +++ b/nimterop/conan.nim @@ -0,0 +1,373 @@ +import json, marshal, os, strformat, strutils, tables + +type + ConanPackage* = ref object + ## ConanPackage type that stores conan uri and recipes/builds/revisions + name*: string + version*: string + user*: string + channel*: string + recipes*: OrderedTableRef[string, seq[ConanBuild]] + + bhash*: string + shared*: bool + headers*: seq[string] + libs*: seq[string] + requires*: seq[ConanPackage] + + ConanBuild* = ref object + ## Build type that stores build specific info and revisions + bhash*: string + settings*: TableRef[string, string] + options*: TableRef[string, string] + requires*: seq[string] + recipe_hash*: string + revisions*: seq[string] + +const + # Conan API urls + baseUrl = "https://conan.bintray.com/v2/conans" + searchUrl = baseUrl & "/search?q=$query" + pkgUrl = baseUrl & "/$name/$version/$user/$channel/search$query" + cfgUrl = baseUrl & "/$name/$version/$user/$channel/revisions/$recipe/packages/$build/revisions" + dlUrl = baseUrl & "/$name/$version/$user/$channel/revisions/$recipe/packages/$build/revisions/$revision/files/$file" + + # Bintray download sub-URL for explicit `user/channel` (not _/_) + dlAltUrl = "/download_file?file_path=$user%2F$name%2F$version%2F$channel%2F0%2Fpackage%2F$build%2F0%2F$file" + + # Strings + conanInfo = "conaninfo.json" + conanPackage = "conan_package.tgz" + conanManifest = "conanmanifest.txt" + +# https://github.com/kdheepak/binary-builder-downloader/blob/master/src/bbd.nim +# https://bintray.com/conan/conan-center +# https://bintray.com/bincrafters/public-conan/ + +# https://docs.conan.io/en/latest/howtos/manage_shared_libraries.html#manage-shared + +var + # Bintray download URL for explicit `user/channel` + baseAltUrl {.compiletime.} = { + "bincrafters": "https://bintray.com/bincrafters/public-conan", + "conan": "https://bintray.com/conan-community/conan" + }.toTable() + +template fixOutDir() {.dirty.} = + let + outdir = if outdir.isAbsolute(): outdir else: getProjectDir() / outdir + +proc addAltBaseUrl*(name, url: string) = + # Add an alternate base URL for a custom conan repo on bintray + baseAltUrl[name] = url + +proc jsonGet(url: string): JsonNode = + # Make HTTP call and return content as JSON + let + temp = getTempDir() + file = temp / url.extractFilename() + + downloadUrl(url, temp, quiet = true) + result = readFile(file).parseJson() + rmFile(file) + +proc `==`(pkg1, pkg2: ConanPackage): bool = + (not pkg1.isNil and not pkg2.isNil and + pkg1.name == pkg2.name and + pkg1.version == pkg2.version and + pkg1.user == pkg2.user and + pkg1.channel == pkg2.channel and + + pkg1.bhash == pkg2.bhash and + pkg1.shared == pkg2.shared) + +proc newConanPackage*(name, version, user = "_", channel = "_", bhash = "", shared = true): ConanPackage = + ## Create a new ConanPackage with specified name and version + result = new(ConanPackage) + result.name = name + result.version = version + result.user = user + result.channel = channel + result.recipes = newOrderedTable[string, seq[ConanBuild]](2) + + result.bhash = bhash + result.shared = shared + +proc newConanPackageFromUri*(uri: string, shared = true): ConanPackage = + ## Create a new ConanPackage from a conan uri + ## + ## name/version[@user/channel][:bhash] + var + name, version, user, channel, bhash: string + + spl = uri.split(":") + + if spl.len > 1: + bhash = spl[1] + + spl = spl[0].split('/') + + name = spl[0] + user = "_" + channel = "_" + + if spl.len > 2: + channel = spl[2] + if spl.len > 1: + spl = spl[1].split('@') + + version = spl[0] + if spl.len > 1: + user = spl[1] + + result = newConanPackage(name, version, user, channel, bhash, shared) + +proc getUriFromConanPackage*(pkg: ConanPackage): string = + ## Convert a ConanPackage to a conan uri + result = pkg.name + if pkg.version.len != 0: + result &= "/" & pkg.version + if pkg.user.len != 0: + result &= "@" & pkg.user + if pkg.channel.len != 0: + result &= "/" & pkg.channel + if pkg.bhash.len != 0: + result &= ":" & pkg.bhash + +proc searchConan*(name: string, version = "", user = "", channel = ""): ConanPackage = + ## Search for package by `name` and optional `version`, `user` and `channel` + var + query = name + if version.len != 0: + query &= "/" & version + if user.len != 0: + query &= "@" & user + if channel.len != 0: + query &= "/" & channel + + let + j1 = jsonGet(searchUrl % ["query", query]) + res = j1.getOrDefault("results").getElems() + + if res.len != 0: + # Return last entry - latest + result = newConanPackageFromUri(res[^1].getStr()) + +proc searchConan*(pkg: ConanPackage): ConanPackage = + ## Search for latest package based on incomplete package info + result = searchConan(pkg.name, pkg.version, pkg.user, pkg.channel) + +proc getConanBuilds*(pkg: ConanPackage, filter = "") = + ## Get all builds for a package based on the C compiler's target OS/arch info + ## + ## `filter` can be used to tweak search terms + ## e.g. build_type=Debug&compiler=clang + let + (arch, os, compiler, _) = getGccInfo() + + query = + if pkg.bhash.len == 0: + block: + var + query = &"?q=arch={arch}&os={os.capitalizeAscii()}" + if "build_type" notin filter: + query &= "&build_type=Release" + if "shared=" notin filter: + query &= &"&options.shared={($pkg.shared).capitalizeAscii()}" + if filter.len != 0: + query &= &"&{filter}" + if "compiler=" notin filter and os != "windows": + query &= &"&compiler={compiler}" + query.replace("&", "%20and%20") + else: "" + + url = pkgUrl % [ + "name", pkg.name, + "version", pkg.version, + "user", pkg.user, + "channel", pkg.channel, + "query", query + ] + + j1 = jsonGet(url) + + if not j1.isNil: + for bhash, bdata in j1.getFields(): + if pkg.bhash.len == 0 or pkg.bhash == bhash: + let + bld = new(ConanBuild) + settings = bdata.getOrDefault("settings") + options = bdata.getOrDefault("options") + requires = bdata.getOrDefault("requires") + bld.bhash = bhash + if not settings.isNil: + bld.settings = newTable[string, string](8) + for key, value in settings.getFields(): + bld.settings[key] = value.getStr() + if not options.isNil: + bld.options = newTable[string, string](8) + for key, value in options.getFields(): + bld.options[key] = value.getStr() + bld.requires = requires.to(seq[string]) + bld.recipe_hash = bdata.getOrDefault("recipe_hash").getStr() + + if pkg.recipes.hasKey(bld.recipe_hash): + pkg.recipes[bld.recipe_hash].add bld + else: + pkg.recipes[bld.recipe_hash] = @[bld] + + # Only need first or matching build + break + +proc getConanRevisions*(pkg: ConanPackage, bld: ConanBuild) = + ## Get all revisions of a build + let + url = cfgUrl % [ + "name", pkg.name, + "version", pkg.version, + "user", pkg.user, + "channel", pkg.channel, + "recipe", bld.recipe_hash, + "build", bld.bhash + ] + + j1 = jsonGet(url) + + if not j1.isNil: + let + revs = j1.getOrDefault("revisions") + for i in revs: + bld.revisions.add i.getOrDefault("revision").getStr() + +proc loadConanInfo*(outdir: string): ConanPackage = + ## Load cached package info from `outdir/conaninfo.txt` + fixOutDir() + let + file = outdir / conanInfo + + if fileExists(file): + result = to[ConanPackage](readFile(file)) + +proc saveConanInfo*(pkg: ConanPackage, outdir: string) = + ## Save downloaded package info to `outdir/conaninfo.txt` + fixOutDir() + let + file = outdir / conanInfo + + writeFile(file, $$pkg) + +proc parseConanManifest(pkg: ConanPackage, outdir: string) = + let + file = outdir / conanManifest + + if fileExists(file): + let + data = readFile(file) + for line in data.splitLines(): + let + line = line.split(':')[0] + if line.startsWith("include/"): + pkg.headers.add line + elif line.startsWith("lib/"): + pkg.libs.add line + elif line.startsWith("bin/") and line.endsWith("dll"): + pkg.libs.add line + +proc dlConanBuild*(pkg: ConanPackage, bld: ConanBuild, outdir: string, revision = "") = + ## Download specific `revision` of `bld` to `outdir` + ## + ## If omitted, the latest revision (first) is downloaded + fixOutDir() + let + revision = + if revision.len != 0: + revision + else: + bld.revisions[0] + + url = + if pkg.user == "_": + dlUrl % [ + "name", pkg.name, + "version", pkg.version, + "user", pkg.user, + "channel", pkg.channel, + "recipe", bld.recipe_hash, + "build", bld.bhash, + "revision", revision, + "file", conanPackage + ] + else: + baseAltUrl[pkg.user] & dlAltUrl % [ + "name", pkg.name, + "version", pkg.version, + "user", pkg.user, + "channel", pkg.channel, + "build", bld.bhash, + "file", conanPackage + ] + + downloadUrl(url, outdir, quiet = true) + downloadUrl(url.replace(conanPackage, conanManifest), outdir, quiet = true) + + pkg.parseConanManifest(outdir) + + rmFile(outdir / url.extractFilename()) + rmFile(outdir / conanManifest) + +proc dlConanRequires*(pkg: ConanPackage, bld: ConanBuild, outdir: string) +proc downloadConan*(pkg: ConanPackage, outdir: string, clean = true) = + ## Download latest recipe/build/revision of `pkg` to `outdir` + fixOutDir() + let + pkg = + if pkg.version.len == 0: + searchConan(pkg) + else: + pkg + + cpkg = loadConanInfo(outdir) + + if cpkg == pkg: + return + elif clean: + cleanDir(outdir) + + pkg.getConanBuilds() + + for recipe, builds in pkg.recipes: + for build in builds: + if pkg.bhash.len == 0 or pkg.bhash == build.bhash: + pkg.getConanRevisions(build) + pkg.dlConanBuild(build, outdir) + pkg.dlConanRequires(build, outdir) + break + break + + if clean: + pkg.saveConanInfo(outdir) + +proc dlConanRequires*(pkg: ConanPackage, bld: ConanBuild, outdir: string) = + ## Download all required dependencies of this `bld` + ## + ## This is not required for shared libs since conan builds them + ## with all dependencies statically linked in + fixOutDir() + if bld.options["shared"] == "False": + for req in bld.requires: + let + rpkg = newConanPackageFromUri(req) + + downloadConan(rpkg, outdir, clean = false) + pkg.requires.add rpkg + +proc getConanLibs*(pkg: ConanPackage, outdir: string): seq[string] = + ## Get all Conan libs (.so|.a|.lib|.dll) in pkg, including deps + ## in descending order + ## + ## `outdir` is prefixed to each entry + for lib in pkg.libs: + result.add outdir / lib + + for cpkg in pkg.requires: + result.add cpkg.getConanLibs(outdir) \ No newline at end of file From 6d256d127191e546b51c5707ae1bfebac43486c6 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Fri, 12 Jun 2020 17:45:06 -0500 Subject: [PATCH 510/593] Filter compiler version, Windows .lib detection --- nimterop/build.nim | 2 +- nimterop/conan.nim | 15 ++++++++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/nimterop/build.nim b/nimterop/build.nim index d5ce59c..fd7ad3a 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -1138,7 +1138,7 @@ macro getHeader*( `version`* {.strdefine.} = `verVal` `lname` = when `nameStatic`: - `lre` & ".a" + `lre` & "\\.(a|lib)" else: `lre` & getDynlibExt() diff --git a/nimterop/conan.nim b/nimterop/conan.nim index 0707ecc..1a9237a 100644 --- a/nimterop/conan.nim +++ b/nimterop/conan.nim @@ -163,7 +163,15 @@ proc getConanBuilds*(pkg: ConanPackage, filter = "") = ## `filter` can be used to tweak search terms ## e.g. build_type=Debug&compiler=clang let - (arch, os, compiler, _) = getGccInfo() + (arch, os, compiler, version) = getGccInfo() + + vsplit = version.split('.') + + vfilter = + when defined(OSX): + vsplit[0 .. 1].join(".") + else: + vsplit[0] query = if pkg.bhash.len == 0: @@ -177,7 +185,8 @@ proc getConanBuilds*(pkg: ConanPackage, filter = "") = if filter.len != 0: query &= &"&{filter}" if "compiler=" notin filter and os != "windows": - query &= &"&compiler={compiler}" + query &= &"&compiler={compiler}&compiler.version=" & vfilter + query.replace("&", "%20and%20") else: "" @@ -370,4 +379,4 @@ proc getConanLibs*(pkg: ConanPackage, outdir: string): seq[string] = result.add outdir / lib for cpkg in pkg.requires: - result.add cpkg.getConanLibs(outdir) \ No newline at end of file + result.add cpkg.getConanLibs(outdir) From c63d82bf77ca6245469586265950f6e2085546f0 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Sun, 14 Jun 2020 15:16:21 -0500 Subject: [PATCH 511/593] Add tests for conan, recurse implies preprocess --- nimterop/build.nim | 25 +++++++++++++++--------- nimterop/conan.nim | 2 ++ nimterop/toast.nim | 6 +++++- tests/getheader.nims | 8 ++++++++ tests/libssh2.nim | 46 ++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 77 insertions(+), 10 deletions(-) create mode 100644 tests/libssh2.nim diff --git a/nimterop/build.nim b/nimterop/build.nim index fd7ad3a..d534cf9 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -1018,26 +1018,33 @@ macro getHeader*( ## ## This allows a single wrapper to be used in different ways depending on the user's needs. ## If no `-d:xxx` defines are specified, `outdir` will be searched for the header as is. + ## The user can opt to download the sources to `outdir` using any other method such as + ## git sub-modules, vendoring or pointing to a repository that was already cloned. ## ## If multiple `-d:xxx` defines are specified, precedence is `Std` and then `Git`, `DL` or ## `Conan`. This allows using a system installed library if available before falling back - ## to manual building. + ## to manual building. The user would need to specify both `-d:xxxStd` and one of the other + ## methods. ## ## `-d:xxxSetVer=x.y.z` can be used to specify which version to use. It is used as a tag ## name for Git whereas for DL and Conan, it replaces `$1` in the URL defined. ## - ## All defines can also be set in code using `setDefines()`. + ## All defines can also be set in code using `setDefines()` and checked for using + ## `isDefined()` which checks for defines set from both `-d` and `setDefines()`. ## ## The library is then configured (with `cmake` or `autotools` if possible) and built ## using `make`, unless using `-d:xxxStd` which presumes that the system package - ## manager was used to install prebuilt headers and binaries. + ## manager was used to install prebuilt headers and binaries, or using `-d:xxxConan` + ## which downloads pre-built binaries. ## ## The header path is stored in `const xxxPath` and can be used in a `cImport()` call ## in the calling wrapper. The dynamic library path is stored in `const xxxLPath` and can ## be used for the `dynlib` parameter (within quotes) or with `{.passL.}`. ## ## `-d:xxxStatic` can be specified to statically link with the library instead. This - ## will automatically add a `{.passL.}` call to the static library for convenience. + ## will automatically add a `{.passL.}` call to the static library for convenience. Note + ## that `-d:xxxConan` downloads all dependency libs as well and the `xxxLPath` will + ## include all separated by space in the right order for linking. ## ## `conFlags`, `cmakeFlags` and `makeFlags` allow sending custom parameters to `configure`, ## `cmake` and `make` in case additional configuration is required as part of the build process. @@ -1047,19 +1054,19 @@ macro getHeader*( ## with cmake. In this case, `altNames = "z,zlib"`. Comma separate for multiple alternate names without ## spaces. ## - ## `buildTypes` specifies a list of in order build strategies to use when building the downloaded source - ## files. Default is [btCmake, btAutoconf] - ## ## The original header name is not included by default if `altNames` is set since it could cause the ## wrong lib to be selected. E.g. `SDL2/SDL.h` could pick `libSDL.so` even if `altNames = "SDL2"`. ## Explicitly include it in `altNames` like the `zlib` example when required. ## + ## `buildTypes` specifies a list of ordered build strategies to use when building the downloaded source + ## files. Default is [btCmake, btAutoconf] + ## ## `xxxPreBuild` is a hook that is called after the source code is pulled from Git or downloaded but ## before the library is built. This might be needed if some initial prep needs to be done before ## compilation. A few values are provided to the hook to help provide context: ## - ## `outdir` is the same `outdir` passed in and `header` is the discovered header path in the - ## downloaded source code. + ## `outdir` is the same `outdir` passed in and `header` is the discovered header path in the + ## downloaded source code. ## ## Simply define `proc xxxPreBuild(outdir, header: string)` in the wrapper and it will get called ## prior to the build process. diff --git a/nimterop/conan.nim b/nimterop/conan.nim index 1a9237a..e9d23cb 100644 --- a/nimterop/conan.nim +++ b/nimterop/conan.nim @@ -342,6 +342,8 @@ proc downloadConan*(pkg: ConanPackage, outdir: string, clean = true) = elif clean: cleanDir(outdir) + echo &"# Downloading {pkg.name} v{pkg.version} from Conan" + pkg.getConanBuilds() for recipe, builds in pkg.recipes: diff --git a/nimterop/toast.nim b/nimterop/toast.nim index 4a9553b..1844a56 100644 --- a/nimterop/toast.nim +++ b/nimterop/toast.nim @@ -123,6 +123,10 @@ proc main( if check and outputFile.len == 0: outputFile = getTempDir() / "toast_" & ($getTime().toUnix()).addFileExt("nim") + # Recurse implies preprocess + if gState.recurse: + gState.preprocess = true + # Redirect output to file if outputFile.len != 0: doAssert gState.outputHandle.open(outputFile, fmWrite), @@ -248,7 +252,7 @@ when isMainModule: "pnim": "print Nim output", "prefix": "strip prefix from identifiers", "preprocess": "run preprocessor on header", - "recurse": "process #include files", + "recurse": "process #include files - implies --preprocess", "replace": "replace X with Y in identifiers, X1=Y1,X2=Y2, @X for regex", "source" : "C/C++ source/header(s) and command line file(s)", "stub": "stub out undefined type references as objects", diff --git a/tests/getheader.nims b/tests/getheader.nims index 5d3b427..55d00f1 100644 --- a/tests/getheader.nims +++ b/tests/getheader.nims @@ -17,10 +17,12 @@ var cmd = "nim c -f --hints:off -d:FLAGS=\"-f:ast2\" -d:checkAbi" lrcmd = " -r lzma.nim" zrcmd = " -r zlib.nim" + sshcmd = " -r libssh2.nim" lexp = "liblzma version = " zexp = "zlib version = " testCall(cmd & lrcmd, "No build files found", 1) +testCall(cmd & " -d:libssh2Conan" & sshcmd, "Need version for Conan uri", 1) when defined(posix): # stdlib @@ -35,6 +37,9 @@ when defined(posix): testCall(cmd & " -d:lzmaGit -d:lzmaSetVer=v5.2.0" & lrcmd, lexp & "5.2.0", 0) testCall(cmd & " -d:lzmaGit -d:lzmaStatic -d:lzmaSetVer=v5.2.0" & lrcmd, lexp & "5.2.0", 0, delete = false) + # conan static + testCall(cmd & " -d:libssh2Conan -d:libssh2SetVer=1.9.0 -d:libssh2Static" & sshcmd, zexp, 0) + # git testCall(cmd & " -d:envTest" & zrcmd, zexp, 0) testCall(cmd & " -d:envTestStatic" & zrcmd, zexp, 0, delete = false) @@ -51,3 +56,6 @@ testCall(cmd & " -d:lzmaDL -d:lzmaStatic -d:lzmaSetVer=5.2.4" & lrcmd, lexp & "5 # dl testCall(cmd & " -d:zlibDL -d:zlibSetVer=1.2.11" & zrcmd, zexp & "1.2.11", 0) testCall(cmd & " -d:zlibDL -d:zlibStatic -d:zlibSetVer=1.2.11" & zrcmd, zexp & "1.2.11", 0, delete = false) + +# conan +testCall(cmd & " -d:libssh2Conan -d:libssh2SetVer=1.9.0" & sshcmd, zexp, 0) diff --git a/tests/libssh2.nim b/tests/libssh2.nim new file mode 100644 index 0000000..b7e591c --- /dev/null +++ b/tests/libssh2.nim @@ -0,0 +1,46 @@ +import nimterop/[build, cimport] + +const + outdir = getProjectCacheDir("libssh2") + +getHeader( + header = "libssh2.h", + conanuri = "libssh2/$1", + outdir = outdir +) + +cOverride: + type + stat = object + stat64 = object + SOCKET = object + +when not libssh2Static: + cImport(libssh2Path, recurse = true, dynlib = "libssh2LPath", flags = "-f:ast2 -c -E_ -F_") + + when not defined(Windows): + proc zlibVersion(): cstring {.importc, dynlib: libssh2LPath.} +else: + cImport(libssh2Path, recurse = true, flags = "-f:ast2 -c -E_ -F_") + + when not defined(Windows): + proc zlibVersion(): cstring {.importc.} + + {.passL: "-lpthread".} + +assert libssh2_init(0) == 0 + +let + session = libssh2_session_init_ex(nil, nil, nil, nil) + +if session == nil: + quit(1) + +libssh2_session_set_blocking(session, 0.cint) + +echo "zlib version = " & (block: + when not defined(Windows): + $zlibVersion() + else: + "" +) \ No newline at end of file From b6278280dcc5018f043a1112c003e31c8305edab Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Sun, 14 Jun 2020 16:10:34 -0500 Subject: [PATCH 512/593] Fix for Windows, README --- README.md | 11 ++++++----- nimterop/build.nim | 45 +++++++++++++++++++++++++++------------------ nimterop/conan.nim | 24 +++++++++++++++++------- 3 files changed, 50 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index 48822ac..3fd48e2 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,7 @@ getHeader( "header.h", # The header file to wrap, full path is returned in `headerPath` giturl = "https://github.com/username/repo", # Git repo URL dlurl = "https://website.org/download/repo-$1.tar.gz", # Download URL for archive or raw file + conanuri = "repo/$1", # Conan.io URI outdir = baseDir, # Where to download/build/search conFlags = "--disable-comp --enable-feature", # Flags to pass configure script cmakeFlags = "-DENABLE_STATIC_LIB=ON" # Flags to pass to Cmake @@ -61,7 +62,7 @@ getHeader( # Wrap headerPath as returned from getHeader() and link statically # or dynamically depending on user input -when not defined(headerStatic): +when not isDefined(headerStatic): cImport(headerPath, recurse = true, dynlib = "headerLPath") # Pass dynlib if not static link else: cImport(headerPath, recurse = true) @@ -74,8 +75,8 @@ Module documentation for the build API can be found [here](https://nimterop.gith The above wrapper is generic and allows the end user to control how it works. Note that `headerPath` is derived from `header.h` so if you have `SDL.h` as the argument to `getHeader()`, it generates `SDLPath` and `SDLLPath` and is controlled by `-d:SDLStatic`, `-d:SDLGit` and so forth. - If the library is already installed in `/usr/include` then the `-d:headerStd` define to Nim can be used to instruct `getHeader()` to search for `header.h` in the standard system path. -- If the library needs to be downloaded, the user can use `-d:headerGit` to clone the source from the specified git URL or `-d:headerDL` to get the source from download URL. - - The `-d:headerSetVer=X.Y.Z` flag can be used to specify which version to download. It is used as the tag name for Git whereas for DL, it replaces `$1` in the URL if defined. +- If the library needs to be downloaded, the user can use `-d:headerGit` to clone the source from the specified git URL, `-d:headerDL` to get the source from download URL or `-d:headerConan` to download from https://conan.io/center. + - The `-d:headerSetVer=X.Y.Z` flag can be used to specify which version to download. It is used as the tag name for Git and for DL and Conan, it replaces `$1` in the URL if specified. - If no flag is provided, `getHeader()` simply looks for the library in `outdir`. The user could use Git submodules or manually download or check-in the library to that directory and `getHeader()` will use it directly. #### Pre build @@ -92,7 +93,7 @@ Flags can be specified to these tools via `getHeader()` or directly via the unde #### Linking -- If `-d:headerStatic` is specified, `getHeader()` will return the static library path in `headerLPath`. The wrapper writer can check for this and call `cImport()` accordingly as in the example above. If it is omitted, the dynamic library is returned in `headerLPath`. +- If `-d:headerStatic` is specified, `getHeader()` will return the static library path in `headerLPath`. The wrapper writer can check for this and call `cImport()` accordingly as in the example above. If `-d:headerStatic` is omitted, the dynamic library is returned in `headerLPath`. - `getHeader()` searches for libraries based on the header name by default: - `libheader.so` or `libheader.a` on Linux - `libheader.dylib` on OSX @@ -224,7 +225,7 @@ Options: -n, --pnim bool false print Nim output -E=, --prefix= strings {} strip prefix from identifiers -p, --preprocess bool false run preprocessor on header - -r, --recurse bool false process #include files + -r, --recurse bool false process #include files, implies --preprocess -G=, --replace= strings {} replace X with Y in identifiers, X1=Y1,X2=Y2, @X for regex -s, --stub bool false stub out undefined type references as objects -F=, --suffix= strings {} strip suffix from identifiers diff --git a/nimterop/build.nim b/nimterop/build.nim index d534cf9..74e6a61 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -1044,32 +1044,41 @@ macro getHeader*( ## `-d:xxxStatic` can be specified to statically link with the library instead. This ## will automatically add a `{.passL.}` call to the static library for convenience. Note ## that `-d:xxxConan` downloads all dependency libs as well and the `xxxLPath` will - ## include all separated by space in the right order for linking. + ## include paths to all of them separated by space in the right order for linking. + ## + ## Note also that Conan currently builds all OSX binaries on 10.14 so older versions of + ## OSX will complain if statically linking to these binaries. Further, all Conan binaries + ## for Windows are built with Visual Studio so static linking the `.lib` files with gcc + ## or clang might lead to incompatibility issues if the library uses Visual Studio + ## specific compiler features. ## ## `conFlags`, `cmakeFlags` and `makeFlags` allow sending custom parameters to `configure`, - ## `cmake` and `make` in case additional configuration is required as part of the build process. + ## `cmake` and `make` in case additional configuration is required as part of the build + ## process. ## - ## `altNames` is a list of alternate names for the library - e.g. zlib uses `zlib.h` for the header but - ## the typical lib name is `libz.so` and not `libzlib.so`. However, it is libzlib.dll on Windows if built - ## with cmake. In this case, `altNames = "z,zlib"`. Comma separate for multiple alternate names without - ## spaces. + ## `altNames` is a list of alternate names for the library - e.g. zlib uses `zlib.h` for + ## the header but the typical lib name is `libz.so` and not `libzlib.so`. However, it is + ## libzlib.dll on Windows if built with cmake. In this case, `altNames = "z,zlib"`. Comma + ## separate for multiple alternate names without spaces. ## - ## The original header name is not included by default if `altNames` is set since it could cause the - ## wrong lib to be selected. E.g. `SDL2/SDL.h` could pick `libSDL.so` even if `altNames = "SDL2"`. - ## Explicitly include it in `altNames` like the `zlib` example when required. + ## The original header name is not included by default if `altNames` is set since it could + ## cause the wrong lib to be selected. E.g. `SDL2/SDL.h` could pick `libSDL.so` even if + ## `altNames = "SDL2"`. Explicitly include it in `altNames` like the `zlib` example when + ## required. ## - ## `buildTypes` specifies a list of ordered build strategies to use when building the downloaded source - ## files. Default is [btCmake, btAutoconf] + ## `buildTypes` specifies a list of ordered build strategies to use when building the + ## downloaded source files. Default is [btCmake, btAutoconf] ## - ## `xxxPreBuild` is a hook that is called after the source code is pulled from Git or downloaded but - ## before the library is built. This might be needed if some initial prep needs to be done before - ## compilation. A few values are provided to the hook to help provide context: + ## `xxxPreBuild` is a hook that is called after the source code is pulled from Git or + ## downloaded but before the library is built. This might be needed if some initial prep + ## needs to be done before compilation. A few values are provided to the hook to help + ## provide context: ## - ## `outdir` is the same `outdir` passed in and `header` is the discovered header path in the - ## downloaded source code. + ## `outdir` is the same `outdir` passed in and `header` is the discovered header path + ## in the downloaded source code. ## - ## Simply define `proc xxxPreBuild(outdir, header: string)` in the wrapper and it will get called - ## prior to the build process. + ## Simply define `proc xxxPreBuild(outdir, header: string)` in the wrapper and it will get + ## called prior to the build process. var origname = header.extractFilename().split(".")[0] name = origname.split(seps = AllChars-Letters-Digits).join() diff --git a/nimterop/conan.nim b/nimterop/conan.nim index e9d23cb..872d138 100644 --- a/nimterop/conan.nim +++ b/nimterop/conan.nim @@ -65,13 +65,19 @@ proc jsonGet(url: string): JsonNode = # Make HTTP call and return content as JSON let temp = getTempDir() - file = temp / url.extractFilename() + file = block: + var + file = temp / url.extractFilename() + when defined(Windows): + file = file.replace('?', '_') + file downloadUrl(url, temp, quiet = true) result = readFile(file).parseJson() rmFile(file) -proc `==`(pkg1, pkg2: ConanPackage): bool = +proc `==`*(pkg1, pkg2: ConanPackage): bool = + ## Check if two ConanPackage objects are equal (not pkg1.isNil and not pkg2.isNil and pkg1.name == pkg2.name and pkg1.version == pkg2.version and @@ -94,9 +100,7 @@ proc newConanPackage*(name, version, user = "_", channel = "_", bhash = "", shar result.shared = shared proc newConanPackageFromUri*(uri: string, shared = true): ConanPackage = - ## Create a new ConanPackage from a conan uri - ## - ## name/version[@user/channel][:bhash] + ## Create a new ConanPackage from a conan uri typically formatted as name/version[@user/channel][:bhash] var name, version, user, channel, bhash: string @@ -136,6 +140,8 @@ proc getUriFromConanPackage*(pkg: ConanPackage): string = proc searchConan*(name: string, version = "", user = "", channel = ""): ConanPackage = ## Search for package by `name` and optional `version`, `user` and `channel` + ## + ## Search is quite slow so it is preferable to specify a version and use `getConanBuilds()` var query = name if version.len != 0: @@ -249,7 +255,7 @@ proc getConanRevisions*(pkg: ConanPackage, bld: ConanBuild) = bld.revisions.add i.getOrDefault("revision").getStr() proc loadConanInfo*(outdir: string): ConanPackage = - ## Load cached package info from `outdir/conaninfo.txt` + ## Load cached package info from `outdir/conaninfo.json` fixOutDir() let file = outdir / conanInfo @@ -258,7 +264,7 @@ proc loadConanInfo*(outdir: string): ConanPackage = result = to[ConanPackage](readFile(file)) proc saveConanInfo*(pkg: ConanPackage, outdir: string) = - ## Save downloaded package info to `outdir/conaninfo.txt` + ## Save downloaded package info to `outdir/conaninfo.json` fixOutDir() let file = outdir / conanInfo @@ -266,6 +272,7 @@ proc saveConanInfo*(pkg: ConanPackage, outdir: string) = writeFile(file, $$pkg) proc parseConanManifest(pkg: ConanPackage, outdir: string) = + # Get all header and library info from downloaded conan package let file = outdir / conanManifest @@ -327,6 +334,9 @@ proc dlConanBuild*(pkg: ConanPackage, bld: ConanBuild, outdir: string, revision proc dlConanRequires*(pkg: ConanPackage, bld: ConanBuild, outdir: string) proc downloadConan*(pkg: ConanPackage, outdir: string, clean = true) = ## Download latest recipe/build/revision of `pkg` to `outdir` + ## + ## High-level API that handles the end to end Conan process flow to find + ## latest package binary and downloads and extracts it to `outdir`. fixOutDir() let pkg = From f21dab89caab28c20fa7db65969c8089fece55c9 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Sun, 14 Jun 2020 16:53:24 -0500 Subject: [PATCH 513/593] Handle bad conan uri, test Windows static --- nimterop/conan.nim | 16 +++++++--------- tests/getheader.nims | 3 +++ tests/zlib.nim | 1 + 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/nimterop/conan.nim b/nimterop/conan.nim index 872d138..95ab24f 100644 --- a/nimterop/conan.nim +++ b/nimterop/conan.nim @@ -40,12 +40,6 @@ const conanPackage = "conan_package.tgz" conanManifest = "conanmanifest.txt" -# https://github.com/kdheepak/binary-builder-downloader/blob/master/src/bbd.nim -# https://bintray.com/conan/conan-center -# https://bintray.com/bincrafters/public-conan/ - -# https://docs.conan.io/en/latest/howtos/manage_shared_libraries.html#manage-shared - var # Bintray download URL for explicit `user/channel` baseAltUrl {.compiletime.} = { @@ -73,7 +67,10 @@ proc jsonGet(url: string): JsonNode = file downloadUrl(url, temp, quiet = true) - result = readFile(file).parseJson() + try: + result = readFile(file).parseJson() + except JsonParsingError: + discard rmFile(file) proc `==`*(pkg1, pkg2: ConanPackage): bool = @@ -352,10 +349,11 @@ proc downloadConan*(pkg: ConanPackage, outdir: string, clean = true) = elif clean: cleanDir(outdir) - echo &"# Downloading {pkg.name} v{pkg.version} from Conan" - pkg.getConanBuilds() + doAssert pkg.recipes.len != 0, &"# Failed to download {pkg.name} v{pkg.version} from Conan - check https://conan.io/center" + + echo &"# Downloading {pkg.name} v{pkg.version} from Conan" for recipe, builds in pkg.recipes: for build in builds: if pkg.bhash.len == 0 or pkg.bhash == build.bhash: diff --git a/tests/getheader.nims b/tests/getheader.nims index 55d00f1..349b9bb 100644 --- a/tests/getheader.nims +++ b/tests/getheader.nims @@ -39,6 +39,9 @@ when defined(posix): # conan static testCall(cmd & " -d:libssh2Conan -d:libssh2SetVer=1.9.0 -d:libssh2Static" & sshcmd, zexp, 0) +else: + # conan static for Windows + testCall(cmd & " -d:zlibConan -d:zlibSetVer=1.2.11 -d:zlibStatic" & zrcmd, zexp, 0) # git testCall(cmd & " -d:envTest" & zrcmd, zexp, 0) diff --git a/tests/zlib.nim b/tests/zlib.nim index 852dca9..15400d4 100644 --- a/tests/zlib.nim +++ b/tests/zlib.nim @@ -27,6 +27,7 @@ getHeader( "zlib.h", giturl = "https://github.com/madler/zlib", dlurl = "http://zlib.net/zlib-$1.tar.gz", + conanuri = "zlib/$1", outdir = baseDir, altNames = "z,zlib" ) From 2b3b5e2bec8f7c39540f0da5b4331f5e90c46843 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 15 Jun 2020 21:37:35 -0500 Subject: [PATCH 514/593] Add binarybuilder.org support, conan improvements, headerLDeps --- README.md | 30 ++++--- nimterop/build.nim | 196 ++++++++++++++++++++++++++++++---------- nimterop/conan.nim | 78 ++++++++-------- nimterop/jbb.nim | 210 +++++++++++++++++++++++++++++++++++++++++++ tests/getheader.nims | 6 ++ tests/libssh2.nim | 14 +-- tests/zlib.nim | 4 + 7 files changed, 437 insertions(+), 101 deletions(-) create mode 100644 nimterop/jbb.nim diff --git a/README.md b/README.md index 3fd48e2..ca17b90 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,7 @@ getHeader( giturl = "https://github.com/username/repo", # Git repo URL dlurl = "https://website.org/download/repo-$1.tar.gz", # Download URL for archive or raw file conanuri = "repo/$1", # Conan.io URI + jbburi = "repo/$1", # BinaryBuilder.org URI outdir = baseDir, # Where to download/build/search conFlags = "--disable-comp --enable-feature", # Flags to pass configure script cmakeFlags = "-DENABLE_STATIC_LIB=ON" # Flags to pass to Cmake @@ -75,8 +76,8 @@ Module documentation for the build API can be found [here](https://nimterop.gith The above wrapper is generic and allows the end user to control how it works. Note that `headerPath` is derived from `header.h` so if you have `SDL.h` as the argument to `getHeader()`, it generates `SDLPath` and `SDLLPath` and is controlled by `-d:SDLStatic`, `-d:SDLGit` and so forth. - If the library is already installed in `/usr/include` then the `-d:headerStd` define to Nim can be used to instruct `getHeader()` to search for `header.h` in the standard system path. -- If the library needs to be downloaded, the user can use `-d:headerGit` to clone the source from the specified git URL, `-d:headerDL` to get the source from download URL or `-d:headerConan` to download from https://conan.io/center. - - The `-d:headerSetVer=X.Y.Z` flag can be used to specify which version to download. It is used as the tag name for Git and for DL and Conan, it replaces `$1` in the URL if specified. +- If the library needs to be downloaded, the user can use `-d:headerGit` to clone the source from the specified git URL, `-d:headerDL` to get the source from download URL, `-d:headerConan` to download from https://conan.io/center or `-d:headerJBB` to download from https://binarybuilder.org. + - The `-d:headerSetVer=X.Y.Z` flag can be used to specify which version to download. It is used as the tag name for Git and for DL, Conan and JBB, it replaces `$1` in the URL if specified. - If no flag is provided, `getHeader()` simply looks for the library in `outdir`. The user could use Git submodules or manually download or check-in the library to that directory and `getHeader()` will use it directly. #### Pre build @@ -93,16 +94,21 @@ Flags can be specified to these tools via `getHeader()` or directly via the unde #### Linking -- If `-d:headerStatic` is specified, `getHeader()` will return the static library path in `headerLPath`. The wrapper writer can check for this and call `cImport()` accordingly as in the example above. If `-d:headerStatic` is omitted, the dynamic library is returned in `headerLPath`. -- `getHeader()` searches for libraries based on the header name by default: - - `libheader.so` or `libheader.a` on Linux - - `libheader.dylib` on OSX - - `header.dll` or `header.a` on Windows -- If a library has a different header and library binary name, `altNames` can be used to configure an alternate name of library binary. - - For example, Bzip2 has `bzlib.h` but the library is `libbz2.so` so `altNames = "bz2"`. - - In the example above, `altNames = "hdr"` so `getHeader()` will look for `libhdr.so`, `hdr.dll`, etc. - - See [bzlib.nim](https://github.com/genotrance/nimarchive/blob/master/nimarchive/bzlib.nim) for an example. -- [lzma.nim](https://github.com/nimterop/nimterop/blob/master/tests/lzma.nim) is an example of a library that allows both static and dynamic linking. +If `-d:headerStatic` is specified, `getHeader()` will return the static library path in `headerLPath`. The wrapper writer can check for this and call `cImport()` accordingly as in the example above. If `-d:headerStatic` is omitted, the dynamic library is returned in `headerLPath`. + +All dependency libraries (supported by Conan and JBB) will be returned in `headerLDeps`. Static libraries and dependencies are automatically linked using `{.passL.}`. Conan shared libs include all dependencies whereas JBB shared libs expect the required dependencies to be in the same location or in `LD_LIBRARY_PATH`. + +`getHeader()` searches for libraries based on the header name by default: +- `libheader.so` or `libheader.a` on Linux +- `libheader.dylib` on OSX +- `header.dll`, `header.a` or `header.lib` on Windows + +If a library has a different header and library binary name, `altNames` can be used to configure an alternate name of library binary. +- For example, Bzip2 has `bzlib.h` but the library is `libbz2.so` so `altNames = "bz2"`. +- In the example above, `altNames = "hdr"` so `getHeader()` will look for `libhdr.so`, `hdr.dll`, etc. +- See [bzlib.nim](https://github.com/genotrance/nimarchive/blob/master/nimarchive/bzlib.nim) for an example. + +[lzma.nim](https://github.com/nimterop/nimterop/blob/master/tests/lzma.nim) is an example of a library that allows both static and dynamic linking. #### User control diff --git a/nimterop/build.nim b/nimterop/build.nim index 74e6a61..eda27e7 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -158,7 +158,7 @@ proc mkDir*(dir: string) = flag = when not defined(Windows): "-p" else: "" discard execAction(&"mkdir {flag} {dir.sanitizePath}", retry = 2) -proc cpFile*(source, dest: string, move=false) = +proc cpFile*(source, dest: string, move = false) = ## Copy a file from `source` to `dest` at compile time let source = source.replace("/", $DirSep) @@ -214,6 +214,25 @@ proc cleanDir*(dir: string) = else: rmFile(path) +proc cpTree*(source, dest: string, move = false) = + ## Copy contents of source dir to the destination, not the directory itself + for kind, path in walkDir(source, relative = true): + if kind == pcDir: + cpTree(source / path, dest / path, move) + if move: + rmDir(source / path) + else: + if not dirExists(dest): + mkDir(dest) + if move: + mvFile(source / path, dest / path) + else: + cpFile(source / path, dest / path) + +proc mvTree*(source, dest: string) = + ## Move contents of source dir to the destination, not the directory itself + cpTree(source, dest, move = true) + proc getProjectCacheDir*(name: string, forceClean = true): string = ## Get a cache directory where all nimterop artifacts can be stored ## @@ -242,7 +261,7 @@ proc getProjectCacheDir*(name: string, forceClean = true): string = echo "# Removing " & result rmDir(result) -proc extractZip*(zipfile, outdir: string) = +proc extractZip*(zipfile, outdir: string, quiet = false) = ## Extract a zip file using `powershell` on Windows and `unzip` on other ## systems to the specified output directory var cmd = "unzip -o $#" @@ -251,10 +270,11 @@ proc extractZip*(zipfile, outdir: string) = "'System.IO.Compression.FileSystem'; " & "[IO.Compression.ZipFile]::ExtractToDirectory('$#', '.'); }\"" - echo "# Extracting " & zipfile + if not quiet: + echo "# Extracting " & zipfile discard execAction(&"cd {outdir.sanitizePath} && {cmd % zipfile}") -proc extractTar*(tarfile, outdir: string) = +proc extractTar*(tarfile, outdir: string, quiet = false) = ## Extract a tar file using `tar`, `7z` or `7za` to the specified output directory var cmd = "" @@ -284,7 +304,8 @@ proc extractTar*(tarfile, outdir: string) = doAssert cmd.len != 0, "No extraction tool - tar, 7z, 7za - available for " & tarfile.sanitizePath - echo "# Extracting " & tarfile + if not quiet: + echo "# Extracting " & tarfile discard execAction(&"cd {outdir.sanitizePath} && {cmd}") if name.len != 0: rmFile(outdir / name) @@ -316,9 +337,9 @@ proc downloadUrl*(url, outdir: string, quiet = false) = discard execAction(cmd % [url.quoteShell, (outdir/file).sanitizePath], retry = 1) if ext == ".zip": - extractZip(file, outdir) + extractZip(file, outdir, quiet) elif ext in archives: - extractTar(file, outdir) + extractTar(file, outdir, quiet) proc gitReset*(outdir: string) = ## Hard reset the git repository at the specified directory @@ -342,7 +363,7 @@ proc gitCheckout*(file, outdir: string) = sleep(500) echo "# Retrying ..." -proc gitPull*(url: string, outdir = "", plist = "", checkout = "") = +proc gitPull*(url: string, outdir = "", plist = "", checkout = "", quiet = false) = ## Pull the specified git repository to the output directory ## ## `plist` is the list of specific files and directories or wildcards @@ -362,7 +383,8 @@ proc gitPull*(url: string, outdir = "", plist = "", checkout = "") = mkDir(outdir) - echo "# Setting up Git repo: " & url + if not quiet: + echo "# Setting up Git repo: " & url discard execAction(&"cd {outdirQ} && git init .") discard execAction(&"cd {outdirQ} && git remote add origin {url}") @@ -378,20 +400,32 @@ proc gitPull*(url: string, outdir = "", plist = "", checkout = "") = discard execAction(&"cd {outdirQ} && git clean -fxd") if checkout.len != 0: - echo "# Checking out " & checkout + if not quiet: + echo "# Checking out " & checkout discard execAction(&"cd {outdirQ} && git fetch", retry = 1) discard execAction(&"cd {outdirQ} && git checkout {checkout}") else: - echo "# Pulling repository" + if not quiet: + echo "# Pulling repository" discard execAction(&"cd {outdirQ} && git pull --depth=1 origin master", retry = 1) -proc findFile*(file: string, dir: string, recurse = true, first = false, regex = false): string = - ## Find the file in the specified directory +proc gitTags*(outdir: string): seq[string] = + ## Get all the git tags in the specified directory + let + cmd = &"cd {outdir.sanitizePath} && git tag" + tags = execAction(cmd).output.splitLines() + for tag in tags: + let + tag = tag.strip() + if tag.len != 0: + result.add tag + +proc findFiles*(file: string, dir: string, recurse = true, regex = false): seq[string] = + ## Find all matching files in the specified directory ## ## `file` is a regular expression if `regex` is true ## - ## Turn off recursive search with `recurse` and stop on first match with - ## `first`. Without it, the shortest match is returned. + ## Turn off recursive search with `recurse` var cmd = when defined(Windows): @@ -435,10 +469,22 @@ proc findFile*(file: string, dir: string, recurse = true, first = false, regex = "" else: line + if f.len != 0: + result.add f - if (f.len != 0 and (result.len == 0 or result.len > f.len)): - result = f - if first: break +proc findFile*(file: string, dir: string, recurse = true, first = false, regex = false): string = + ## Find the file in the specified directory + ## + ## `file` is a regular expression if `regex` is true + ## + ## Turn off recursive search with `recurse` and stop on first match with + ## `first`. Without it, the shortest match is returned. + let + matches = findFiles(file, dir, recurse, regex) + for match in matches: + if (result.len == 0 or result.len > match.len): + result = match + if first: break proc flagBuild*(base: string, flags: openArray[string]): string = ## Simple helper proc to generate flags for `configure`, `cmake`, etc. @@ -533,7 +579,7 @@ proc configure*(path, check: string, flags = "") = echoDebug execAction(cmd).output - doAssert (path / check).fileExists(), "# Configure failed" + doAssert (path / check).fileExists(), "Configure failed" proc getCmakePropertyStr(name, property, value: string): string = &"\nset_target_properties({name} PROPERTIES {property} \"{value}\")\n" @@ -630,7 +676,7 @@ proc cmake*(path, check, flags: string) = echoDebug execAction(cmd).output - doAssert (path / check).fileExists(), "# cmake failed" + doAssert (path / check).fileExists(), "cmake failed" proc make*(path, check: string, flags = "", regex = false) = ## Run the `make` command to build all binaries in the specified path @@ -666,7 +712,7 @@ proc make*(path, check: string, flags = "", regex = false) = echoDebug execAction(cmd).output - doAssert findFile(check, path, regex = regex).len != 0, "# make failed" + doAssert findFile(check, path, regex = regex).len != 0, "make failed" proc getCompilerMode*(path: string): string = ## Determines a target language mode from an input filename, if one is not already specified. @@ -768,9 +814,16 @@ proc getGccInfo*(): tuple[arch, os, compiler, version: string] = else: result.compiler = "gcc" +template fixOutDir() {.dirty.} = + let + outdir = if outdir.isAbsolute(): outdir else: getProjectDir() / outdir + # Conan support include conan +# Julia Binary Builder support +include jbb + proc getStdPath(header, mode: string): string = for inc in getGccPaths(mode): result = findFile(header, inc, recurse = false, first = true) @@ -839,11 +892,41 @@ proc getConanPath(header, uri, outdir, version: string, shared: bool): string = result = findFile(header, outdir) -proc getConanLPath(outdir: string): string = +proc getConanLDeps(outdir: string): seq[string] = let pkg = loadConanInfo(outdir) - - result = pkg.getConanLibs(outdir).join(" ") + + result = pkg.getConanLDeps(outdir) + +proc getJBBPath(header, uri, outdir, version: string): string = + let + spl = uri.split('/', 1) + name = spl[0] + + var + ver = + if spl.len == 2: + spl[1] + else: + "" + + if "$#" in ver or "$1" in ver: + doAssert version.len != 0, "Need version for BinaryBuilder.org uri" + ver = ver % version + else: + doAssert version.len == 0, "BinaryBuilder.org uri does not contain version" + + let + pkg = newJBBPackage(name, ver) + downloadJBB(pkg, outdir) + + result = findFile(header, outdir) + +proc getJBBLDeps(outdir: string, shared: bool): seq[string] = + let + pkg = loadJBBInfo(outdir) + + result = pkg.getJBBLDeps(outdir, shared) proc getLocalPath(header, outdir: string): string = if outdir.len != 0: @@ -932,7 +1015,7 @@ proc buildLibrary(lname, outdir, conFlags, cmakeFlags, makeFlags: string, buildT buildStatus.built = true let error = if buildStatus.error.len > 0: buildStatus.error else: "No build files found in " & outdir - doAssert buildStatus.built, &"\n# Build configuration failed - {error}\n" + doAssert buildStatus.built, &"\nBuild configuration failed - {error}\n" result = findFile(lname, outdir, regex = true) @@ -1000,7 +1083,7 @@ macro isDefined*(def: untyped): untyped = macro getHeader*( header: static[string], giturl: static[string] = "", dlurl: static[string] = "", - conanuri: static[string] = "", outdir: static[string] = "", + conanuri: static[string] = "", jbburi: static[string] = "", outdir: static[string] = "", conFlags: static[string] = "", cmakeFlags: static[string] = "", makeFlags: static[string] = "", altNames: static[string] = "", buildTypes: static[openArray[BuildType]] = [btCmake, btAutoconf]): untyped = ## Get the path to a header file for wrapping with @@ -1015,19 +1098,22 @@ macro getHeader*( ## `-d:xxxDL` - download source from `dlurl` and extract if required ## `-d:xxxConan` - download headers and binary from conan.io using `conanuri` ## typically formatted as `name/version[@user/channel][:bhash]` + ## `-d:xxxJBB` - download headers and binary from BinaryBuilder.org using `jbburi` + ## typically formatted as `name/version` ## ## This allows a single wrapper to be used in different ways depending on the user's needs. ## If no `-d:xxx` defines are specified, `outdir` will be searched for the header as is. ## The user can opt to download the sources to `outdir` using any other method such as ## git sub-modules, vendoring or pointing to a repository that was already cloned. ## - ## If multiple `-d:xxx` defines are specified, precedence is `Std` and then `Git`, `DL` or - ## `Conan`. This allows using a system installed library if available before falling back - ## to manual building. The user would need to specify both `-d:xxxStd` and one of the other - ## methods. + ## If multiple `-d:xxx` defines are specified, precedence is `Std` and then `Git`, `DL`, + ## `Conan` or `JBB`. This allows using a system installed library if available before + ## falling back to manual building. The user would need to specify both `-d:xxxStd` and + ## one of the other methods. ## ## `-d:xxxSetVer=x.y.z` can be used to specify which version to use. It is used as a tag - ## name for Git whereas for DL and Conan, it replaces `$1` in the URL defined. + ## name for Git whereas for DL, Conan and BinaryBuilder.org, it replaces `$1` in the URL + ## defined. ## ## All defines can also be set in code using `setDefines()` and checked for using ## `isDefined()` which checks for defines set from both `-d` and `setDefines()`. @@ -1035,7 +1121,7 @@ macro getHeader*( ## The library is then configured (with `cmake` or `autotools` if possible) and built ## using `make`, unless using `-d:xxxStd` which presumes that the system package ## manager was used to install prebuilt headers and binaries, or using `-d:xxxConan` - ## which downloads pre-built binaries. + ## or `-d:xxxJBB` which download pre-built binaries. ## ## The header path is stored in `const xxxPath` and can be used in a `cImport()` call ## in the calling wrapper. The dynamic library path is stored in `const xxxLPath` and can @@ -1043,9 +1129,10 @@ macro getHeader*( ## ## `-d:xxxStatic` can be specified to statically link with the library instead. This ## will automatically add a `{.passL.}` call to the static library for convenience. Note - ## that `-d:xxxConan` downloads all dependency libs as well and the `xxxLPath` will - ## include paths to all of them separated by space in the right order for linking. - ## + ## that `-d:xxxConan` and `-d:xxxJBB` download all dependency libs as well and the + ## `xxxLPath` will include paths to all of them separated by space in the right order for + ## linking. + ## ## Note also that Conan currently builds all OSX binaries on 10.14 so older versions of ## OSX will complain if statically linking to these binaries. Further, all Conan binaries ## for Windows are built with Visual Studio so static linking the `.lib` files with gcc @@ -1088,6 +1175,7 @@ macro getHeader*( gitStr = name & "Git" dlStr = name & "DL" conanStr = name & "Conan" + jbbStr = name & "JBB" staticStr = name & "Static" verStr = name & "SetVer" @@ -1097,12 +1185,14 @@ macro getHeader*( nameGit = newIdentNode(gitStr) nameDL = newIdentNode(dlStr) nameConan = newIdentNode(conanStr) + nameJBB = newIdentNode(jbbStr) nameStatic = newIdentNode(staticStr) # Consts to generate path = newIdentNode(name & "Path") lpath = newIdentNode(name & "LPath") + ldeps = newIdentNode(name & "LDeps") version = newIdentNode(verStr) lname = newIdentNode(name & "LName") preBuild = newIdentNode(name & "PreBuild") @@ -1115,6 +1205,7 @@ macro getHeader*( gitVal = gDefines.hasKey(gitStr) dlVal = gDefines.hasKey(dlStr) conanVal = gDefines.hasKey(conanStr) + jbbVal = gDefines.hasKey(jbbStr) staticVal = gDefines.hasKey(staticStr) verVal = if gDefines.hasKey(verStr): @@ -1137,16 +1228,19 @@ macro getHeader*( `nameGit`* = when defined(`nameGit`): true else: `gitVal` == 1 `nameDL`* = when defined(`nameDL`): true else: `dlVal` == 1 `nameConan`* = when defined(`nameConan`): true else: `conanVal` == 1 + `nameJBB`* = when defined(`nameJBB`): true else: `jbbVal` == 1 `nameStatic`* = when defined(`nameStatic`): true else: `staticVal` == 1 # Search for header in outdir (after retrieving code) depending on -d:xxx mode - proc getPath(header, giturl, dlurl, conanuri, outdir, version: string, shared: bool): string = + proc getPath(header, giturl, dlurl, conanuri, jbburi, outdir, version: string, shared: bool): string = when `nameGit`: getGitPath(header, giturl, outdir, version) elif `nameDL`: getDlPath(header, dlurl, outdir, version) elif `nameConan`: getConanPath(header, conanuri, outdir, version, shared) + elif `nameJBB`: + getJBBPath(header, jbburi, outdir, version) else: getLocalPath(header, outdir) @@ -1171,10 +1265,10 @@ macro getHeader*( when useStd: stdPath else: - getPath(`header`, `giturl`, `dlurl`, `conanuri`, `outdir`, `version`, not `nameStatic`) + getPath(`header`, `giturl`, `dlurl`, `conanuri`, `jbburi`, `outdir`, `version`, not `nameStatic`) - # Run preBuild hook before building library if not Std or Conan - when not (useStd or `nameConan`) and declared(`preBuild`): + # Run preBuild hook before building library if not Std, Conan or JBB + when not (useStd or `nameConan` or `nameJBB`) and declared(`preBuild`): static: `preBuild`(`outdir`, prePath) @@ -1183,28 +1277,36 @@ macro getHeader*( `lpath`* = when useStd: stdLPath - elif `nameConan`: - when `nameStatic`: - getConanLPath(`outdir`) - else: - findFile(`lname`, `outdir`, regex = true) + elif `nameConan` or `nameJBB`: + findFile(`lname`, `outdir`, regex = true) else: buildLibrary(`lname`, `outdir`, `conFlags`, `cmakeFlags`, `makeFlags`, `buildTypes`) + # Library dependecy paths + `ldeps`*: seq[string] = + when `nameConan`: + getConanLDeps(`outdir`) + elif `nameJBB`: + getJBBLDeps(`outdir`, not `nameStatic`) + else: + @[] + # Header path - search again in case header is generated in build `path`* = if prePath.len != 0: prePath else: - getPath(`header`, `giturl`, `dlurl`, `conanuri`, `outdir`, `version`, not `nameStatic`) + getPath(`header`, `giturl`, `dlurl`, `conanuri`, `jbburi`, `outdir`, `version`, not `nameStatic`) static: doAssert `path`.len != 0, "\nHeader " & `header` & " not found - " & - "missing/empty outdir or -d:$1Std -d:$1Git -d:$1DL or -d:$1Conan not specified" % `name` + "missing/empty outdir or -d:$1Std -d:$1Git -d:$1DL -d:$1Conan or -d:$1JBB not specified" % `name` doAssert `lpath`.len != 0, "\nLibrary " & `lname` & " not found" echo "# Including library " & `lpath` - # Automatically link with static libary + # Automatically link with static library and dependencies when `nameStatic`: {.passL: `lpath`.} + if `ldeps`.len != 0: + {.passL: `ldeps`.join(" ").} ) diff --git a/nimterop/conan.nim b/nimterop/conan.nim index 95ab24f..bfe2e94 100644 --- a/nimterop/conan.nim +++ b/nimterop/conan.nim @@ -11,8 +11,8 @@ type bhash*: string shared*: bool - headers*: seq[string] - libs*: seq[string] + sharedLibs*: seq[string] + staticLibs*: seq[string] requires*: seq[ConanPackage] ConanBuild* = ref object @@ -26,14 +26,14 @@ type const # Conan API urls - baseUrl = "https://conan.bintray.com/v2/conans" - searchUrl = baseUrl & "/search?q=$query" - pkgUrl = baseUrl & "/$name/$version/$user/$channel/search$query" - cfgUrl = baseUrl & "/$name/$version/$user/$channel/revisions/$recipe/packages/$build/revisions" - dlUrl = baseUrl & "/$name/$version/$user/$channel/revisions/$recipe/packages/$build/revisions/$revision/files/$file" + conanBaseUrl = "https://conan.bintray.com/v2/conans" + conanSearchUrl = conanBaseUrl & "/search?q=$query" + conanPkgUrl = conanBaseUrl & "/$name/$version/$user/$channel/search$query" + conanCfgUrl = conanBaseUrl & "/$name/$version/$user/$channel/revisions/$recipe/packages/$build/revisions" + conanDlUrl = conanBaseUrl & "/$name/$version/$user/$channel/revisions/$recipe/packages/$build/revisions/$revision/files/$file" # Bintray download sub-URL for explicit `user/channel` (not _/_) - dlAltUrl = "/download_file?file_path=$user%2F$name%2F$version%2F$channel%2F0%2Fpackage%2F$build%2F0%2F$file" + conanDlAltUrl = "/download_file?file_path=$user%2F$name%2F$version%2F$channel%2F0%2Fpackage%2F$build%2F0%2F$file" # Strings conanInfo = "conaninfo.json" @@ -42,18 +42,14 @@ const var # Bintray download URL for explicit `user/channel` - baseAltUrl {.compiletime.} = { + conanBaseAltUrl {.compiletime.} = { "bincrafters": "https://bintray.com/bincrafters/public-conan", "conan": "https://bintray.com/conan-community/conan" }.toTable() -template fixOutDir() {.dirty.} = - let - outdir = if outdir.isAbsolute(): outdir else: getProjectDir() / outdir - -proc addAltBaseUrl*(name, url: string) = +proc addAltConanBaseUrl*(name, url: string) = # Add an alternate base URL for a custom conan repo on bintray - baseAltUrl[name] = url + conanBaseAltUrl[name] = url proc jsonGet(url: string): JsonNode = # Make HTTP call and return content as JSON @@ -137,7 +133,7 @@ proc getUriFromConanPackage*(pkg: ConanPackage): string = proc searchConan*(name: string, version = "", user = "", channel = ""): ConanPackage = ## Search for package by `name` and optional `version`, `user` and `channel` - ## + ## ## Search is quite slow so it is preferable to specify a version and use `getConanBuilds()` var query = name @@ -149,7 +145,7 @@ proc searchConan*(name: string, version = "", user = "", channel = ""): ConanPac query &= "/" & channel let - j1 = jsonGet(searchUrl % ["query", query]) + j1 = jsonGet(conanSearchUrl % ["query", query]) res = j1.getOrDefault("results").getElems() if res.len != 0: @@ -193,7 +189,7 @@ proc getConanBuilds*(pkg: ConanPackage, filter = "") = query.replace("&", "%20and%20") else: "" - url = pkgUrl % [ + url = conanPkgUrl % [ "name", pkg.name, "version", pkg.version, "user", pkg.user, @@ -234,7 +230,7 @@ proc getConanBuilds*(pkg: ConanPackage, filter = "") = proc getConanRevisions*(pkg: ConanPackage, bld: ConanBuild) = ## Get all revisions of a build let - url = cfgUrl % [ + url = conanCfgUrl % [ "name", pkg.name, "version", pkg.version, "user", pkg.user, @@ -269,22 +265,23 @@ proc saveConanInfo*(pkg: ConanPackage, outdir: string) = writeFile(file, $$pkg) proc parseConanManifest(pkg: ConanPackage, outdir: string) = - # Get all header and library info from downloaded conan package + # Get all library info from downloaded conan package let file = outdir / conanManifest - + if fileExists(file): let data = readFile(file) for line in data.splitLines(): let line = line.split(':')[0] - if line.startsWith("include/"): - pkg.headers.add line - elif line.startsWith("lib/"): - pkg.libs.add line + if line.startsWith("lib/"): + if line.endsWith(".a") or line.endsWith(".lib"): + pkg.staticLibs.add line + elif line.endsWith(".so"): + pkg.sharedLibs.add line elif line.startsWith("bin/") and line.endsWith("dll"): - pkg.libs.add line + pkg.sharedLibs.add line proc dlConanBuild*(pkg: ConanPackage, bld: ConanBuild, outdir: string, revision = "") = ## Download specific `revision` of `bld` to `outdir` @@ -300,7 +297,7 @@ proc dlConanBuild*(pkg: ConanPackage, bld: ConanBuild, outdir: string, revision url = if pkg.user == "_": - dlUrl % [ + conanDlUrl % [ "name", pkg.name, "version", pkg.version, "user", pkg.user, @@ -311,7 +308,7 @@ proc dlConanBuild*(pkg: ConanPackage, bld: ConanBuild, outdir: string, revision "file", conanPackage ] else: - baseAltUrl[pkg.user] & dlAltUrl % [ + conanBaseAltUrl[pkg.user] & conanDlAltUrl % [ "name", pkg.name, "version", pkg.version, "user", pkg.user, @@ -331,7 +328,7 @@ proc dlConanBuild*(pkg: ConanPackage, bld: ConanBuild, outdir: string, revision proc dlConanRequires*(pkg: ConanPackage, bld: ConanBuild, outdir: string) proc downloadConan*(pkg: ConanPackage, outdir: string, clean = true) = ## Download latest recipe/build/revision of `pkg` to `outdir` - ## + ## ## High-level API that handles the end to end Conan process flow to find ## latest package binary and downloads and extracts it to `outdir`. fixOutDir() @@ -351,7 +348,7 @@ proc downloadConan*(pkg: ConanPackage, outdir: string, clean = true) = pkg.getConanBuilds() - doAssert pkg.recipes.len != 0, &"# Failed to download {pkg.name} v{pkg.version} from Conan - check https://conan.io/center" + doAssert pkg.recipes.len != 0, &"Failed to download {pkg.name} v{pkg.version} from Conan - check https://conan.io/center" echo &"# Downloading {pkg.name} v{pkg.version} from Conan" for recipe, builds in pkg.recipes: @@ -375,18 +372,25 @@ proc dlConanRequires*(pkg: ConanPackage, bld: ConanBuild, outdir: string) = if bld.options["shared"] == "False": for req in bld.requires: let - rpkg = newConanPackageFromUri(req) + rpkg = newConanPackageFromUri(req, shared = false) downloadConan(rpkg, outdir, clean = false) pkg.requires.add rpkg -proc getConanLibs*(pkg: ConanPackage, outdir: string): seq[string] = - ## Get all Conan libs (.so|.a|.lib|.dll) in pkg, including deps +proc getConanLDeps*(pkg: ConanPackage, outdir: string, main = true): seq[string] = + ## Get all Conan libs - shared (.so|.dll) or static (.a|.lib) in pkg, including deps ## in descending order - ## + ## ## `outdir` is prefixed to each entry - for lib in pkg.libs: - result.add outdir / lib + let + libs = if pkg.shared: pkg.sharedLibs else: pkg.staticLibs + str = if pkg.shared: "shared" else: "static" + + doAssert libs.len != 0, &"No {str} libs found for {pkg.name} in {outdir}" + + if not main: + for lib in libs: + result.add outdir / lib for cpkg in pkg.requires: - result.add cpkg.getConanLibs(outdir) + result.add cpkg.getConanLDeps(outdir, main = false) diff --git a/nimterop/jbb.nim b/nimterop/jbb.nim new file mode 100644 index 0000000..9f0d173 --- /dev/null +++ b/nimterop/jbb.nim @@ -0,0 +1,210 @@ +import marshal, os, strutils + +type + JBBPackage* = ref object + ## JBBPackage type that stores package information + name*: string + version*: string + + url*: string + + sharedLibs*: seq[string] + staticLibs*: seq[string] + requires*: seq[JBBPackage] + +const + # JBB URLs + jbbBaseUrl = "https://github.com/JuliaBinaryWrappers/$1_jll.jl" + + jbbInfo = "jbbinfo.json" + jbbProject = "Project.toml" + jbbArtifacts = "Artifacts.toml" + +proc `==`*(pkg1, pkg2: JBBPackage): bool = + ## Check if two JBBPackage objects are equal + (not pkg1.isNil and not pkg2.isNil and + pkg1.name == pkg2.name and + pkg1.version == pkg2.version) + +proc newJBBPackage*(name, version: string): JBBPackage = + ## Create a new JBBPackage with specified name and version + result = new(JBBPackage) + result.name = name + result.version = version + +proc parseJBBProject(pkg: JBBPackage, outdir: string) = + # Get all dependencies from Project.toml + let + file = outdir / jbbProject + + if fileExists(file): + let + data = readFile(file) + var + deps = false + + doAssert pkg.version in data, &"{pkg.name} v{pkg.version} not found" + + for line in data.splitLines(): + let + line = line.strip() + if line.len != 0: + if line.startsWith('['): + if line == "[deps]": + deps = true + else: + deps = false + elif deps: + let + name = line.split()[0] + if name.endsWith("_jll"): + pkg.requires.add newJBBPackage(name[0 .. ^5], "") + +proc parseJBBArtifacts(pkg: JBBPackage, outdir: string) = + # Get build information from Artifacts.toml + let + file = outdir / jbbArtifacts + + (arch, os, _, _) = getGccInfo() + + if fileExists(file): + let + data = readFile(file) + + doAssert pkg.version in data, &"{pkg.name} v{pkg.version} not found" + + var + found = false + for line in data.splitLines(): + let + line = line.strip() + if line.len != 0: + if line.startsWith("arch = ") and not found: + let + barch = line.split(" = ")[1].strip(chars = {'"'}) + if barch == arch: + found = true + elif line.startsWith("os = ") and found: + let + bos = line.split(" = ")[1].strip(chars = {'"'}) + if bos != os: + found = false + elif line.startsWith("url = ") and found: + pkg.url = line.split(" = ")[1].strip(chars = {'"'}) + break + +proc findJBBLibs(pkg: JBBPackage, outdir: string) = + pkg.sharedLibs = findFiles("lib[\\\\/].*\\.(so|dylib)", outdir) + pkg.sharedLibs.add findFiles("bin[\\\\/].*\\.(dll)", outdir) + for i in 0 ..< pkg.sharedLibs.len: + if pkg.sharedLibs[i].isAbsolute: + pkg.sharedLibs[i] = pkg.sharedLibs[i][outdir.len+1 .. ^1] + + for lib in findFiles("lib[\\\\/].*\\.(a|lib)$", outdir): + if not lib.endsWith(".dll.a"): + if lib.isAbsolute: + pkg.staticLibs.add lib[outdir.len+1 .. ^1] + else: + pkg.staticLibs.add lib + +proc getJBBRepo*(pkg: JBBPackage, outdir: string) = + ## Clone JBB package repo and checkout version tag if version is + ## specified in package + let + path = outdir / "repos" / pkg.name + + gitPull( + jbbBaseUrl % pkg.name, + outdir = path, + plist = "*.toml", + "master", + quiet = true + ) + + if pkg.version.len != 0: + # Checkout correct tag + let + tags = gitTags(path) + for i in tags.len - 1 .. 0: + if pkg.version in tags[i] and i != tags.len - 1: + gitCheckout(path, tags[i-1]) + + pkg.parseJBBProject(path) + pkg.parseJBBArtifacts(path) + +proc loadJBBInfo*(outdir: string): JBBPackage = + ## Load cached package info from `outdir/jbbinfo.json` + fixOutDir() + let + file = outdir / jbbInfo + + if fileExists(file): + result = to[JBBPackage](readFile(file)) + +proc saveJBBInfo*(pkg: JBBPackage, outdir: string) = + ## Save downloaded package info to `outdir/jbbinfo.json` + fixOutDir() + let + file = outdir / jbbInfo + + writeFile(file, $$pkg) + +proc dlJBBRequires*(pkg: JBBPackage, outdir: string) +proc downloadJBB*(pkg: JBBPackage, outdir: string, clean = true) = + ## Download `pkg` from BinaryBuilder.org to `outdir` + ## + ## High-level API that handles the end to end JBB process flow to find + ## latest package binary and downloads and extracts it to `outdir`. + fixOutDir() + let + cpkg = loadJBBInfo(outdir) + + if cpkg == pkg: + return + elif clean: + cleanDir(outdir) + + pkg.getJBBRepo(outdir) + + doAssert pkg.url.len != 0, &"Failed to download {pkg.name} info from BinaryBuilder.org" + + let + vstr = + if pkg.version.len != 0: + &" v{pkg.version}" + else: + "" + path = outdir / "downloads" / pkg.name + echo &"# Downloading {pkg.name}{vstr} from BinaryBuilder.org" + downloadUrl(pkg.url, path, quiet = true) + pkg.findJBBLibs(path) + mvTree(path, outdir) + + pkg.dlJBBRequires(outdir) + + if clean: + pkg.saveJBBInfo(outdir) + +proc dlJBBRequires*(pkg: JBBPackage, outdir: string) = + ## Download all required dependencies of this `pkg` + fixOutDir() + for rpkg in pkg.requires: + downloadJBB(rpkg, outdir, clean = false) + +proc getJBBLDeps*(pkg: JBBPackage, outdir: string, shared: bool, main = true): seq[string] = + ## Get all BinaryBuilder.org libs - shared (.so|.dll) or static (.a|.lib) in pkg, including deps + ## in descending order + ## + ## `outdir` is prefixed to each entry + let + libs = if shared: pkg.sharedLibs else: pkg.staticLibs + str = if shared: "shared" else: "static" + + doAssert libs.len != 0, &"No {str} libs found for {pkg.name} in {outdir}" + + if not main: + for lib in libs: + result.add outdir / lib + + for cpkg in pkg.requires: + result.add cpkg.getJBBLDeps(outdir, shared, main = false) diff --git a/tests/getheader.nims b/tests/getheader.nims index 349b9bb..1d0ba1d 100644 --- a/tests/getheader.nims +++ b/tests/getheader.nims @@ -23,6 +23,7 @@ var testCall(cmd & lrcmd, "No build files found", 1) testCall(cmd & " -d:libssh2Conan" & sshcmd, "Need version for Conan uri", 1) +testCall(cmd & " -d:libssh2JBB" & sshcmd, "Need version for BinaryBuilder.org uri", 1) when defined(posix): # stdlib @@ -43,6 +44,11 @@ else: # conan static for Windows testCall(cmd & " -d:zlibConan -d:zlibSetVer=1.2.11 -d:zlibStatic" & zrcmd, zexp, 0) +# JBB +testCall(cmd & " -d:libssh2JBB -d:libssh2SetVer=1.9.0" & sshcmd, zexp, 0) +testCall(cmd & " -d:zlibJBB -d:zlibSetVer=1.2.11" & zrcmd, zexp, 0) +testCall(cmd & " -d:zlibJBB -d:zlibSetVer=1.2.11 -d:zlibStatic" & zrcmd, zexp, 0) + # git testCall(cmd & " -d:envTest" & zrcmd, zexp, 0) testCall(cmd & " -d:envTestStatic" & zrcmd, zexp, 0, delete = false) diff --git a/tests/libssh2.nim b/tests/libssh2.nim index b7e591c..48b8ba9 100644 --- a/tests/libssh2.nim +++ b/tests/libssh2.nim @@ -6,6 +6,7 @@ const getHeader( header = "libssh2.h", conanuri = "libssh2/$1", + jbburi = "libssh2/$1", outdir = outdir ) @@ -14,16 +15,16 @@ cOverride: stat = object stat64 = object SOCKET = object - + when not libssh2Static: cImport(libssh2Path, recurse = true, dynlib = "libssh2LPath", flags = "-f:ast2 -c -E_ -F_") - when not defined(Windows): + when not defined(Windows) and not isDefined(libssh2JBB): proc zlibVersion(): cstring {.importc, dynlib: libssh2LPath.} else: cImport(libssh2Path, recurse = true, flags = "-f:ast2 -c -E_ -F_") - when not defined(Windows): + when not defined(Windows) and not isDefined(libssh2JBB): proc zlibVersion(): cstring {.importc.} {.passL: "-lpthread".} @@ -39,8 +40,11 @@ if session == nil: libssh2_session_set_blocking(session, 0.cint) echo "zlib version = " & (block: - when not defined(Windows): + when not defined(Windows) and not isDefined(libssh2JBB): $zlibVersion() else: "" -) \ No newline at end of file +) + +static: + echo libssh2LDeps \ No newline at end of file diff --git a/tests/zlib.nim b/tests/zlib.nim index 15400d4..2bd9395 100644 --- a/tests/zlib.nim +++ b/tests/zlib.nim @@ -28,6 +28,7 @@ getHeader( giturl = "https://github.com/madler/zlib", dlurl = "http://zlib.net/zlib-$1.tar.gz", conanuri = "zlib/$1", + jbburi = "zlib/$1", outdir = baseDir, altNames = "z,zlib" ) @@ -72,3 +73,6 @@ else: cImport(zlibPath, recurse = true, flags = FLAGS) echo "zlib version = " & $zlibVersion() + +when isDefined(zlibJBB) and isDefined(zlibStatic): + {.passL: "-no-pie".} From 9d8fee19c01881619b68164a51aaf51dd17e8be3 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 16 Jun 2020 17:41:18 -0500 Subject: [PATCH 515/593] libdir support --- nimterop/build.nim | 97 +++++++++++++++++++++++++++++++++++++++----- nimterop/cimport.nim | 13 ------ nimterop/conan.nim | 2 +- nimterop/jbb.nim | 16 ++------ nimterop/nimconf.nim | 61 +++++++++++++--------------- 5 files changed, 120 insertions(+), 69 deletions(-) diff --git a/nimterop/build.nim b/nimterop/build.nim index eda27e7..6cb497d 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -158,8 +158,10 @@ proc mkDir*(dir: string) = flag = when not defined(Windows): "-p" else: "" discard execAction(&"mkdir {flag} {dir.sanitizePath}", retry = 2) -proc cpFile*(source, dest: string, move = false) = +proc cpFile*(source, dest: string, psymlink = false, move = false) = ## Copy a file from `source` to `dest` at compile time + ## + ## `psymlink = true` preserves symlinks instead of dereferencing on posix let source = source.replace("/", $DirSep) dest = dest.replace("/", $DirSep) @@ -173,7 +175,10 @@ proc cpFile*(source, dest: string, move = false) = if move: "mv -f" else: - "cp -f" + if psymlink: + "cp -fd" + else: + "cp -f" discard execAction(&"{cmd} {source.sanitizePath} {dest.sanitizePath}", retry = 2) @@ -233,6 +238,20 @@ proc mvTree*(source, dest: string) = ## Move contents of source dir to the destination, not the directory itself cpTree(source, dest, move = true) +proc getFileDate*(fullpath: string): string = + ## Get file date for `fullpath` + var + ret = 0 + cmd = + when defined(Windows): + &"cmd /c for %a in ({fullpath.sanitizePath}) do echo %~ta" + elif defined(Linux): + &"stat -c %y {fullpath.sanitizePath}" + elif defined(OSX) or defined(FreeBSD): + &"stat -f %m {fullpath.sanitizePath}" + + (result, ret) = execAction(cmd) + proc getProjectCacheDir*(name: string, forceClean = true): string = ## Get a cache directory where all nimterop artifacts can be stored ## @@ -1083,7 +1102,8 @@ macro isDefined*(def: untyped): untyped = macro getHeader*( header: static[string], giturl: static[string] = "", dlurl: static[string] = "", - conanuri: static[string] = "", jbburi: static[string] = "", outdir: static[string] = "", + conanuri: static[string] = "", jbburi: static[string] = "", + outdir: static[string] = "", libdir: static[string] = "", conFlags: static[string] = "", cmakeFlags: static[string] = "", makeFlags: static[string] = "", altNames: static[string] = "", buildTypes: static[openArray[BuildType]] = [btCmake, btAutoconf]): untyped = ## Get the path to a header file for wrapping with @@ -1125,7 +1145,14 @@ macro getHeader*( ## ## The header path is stored in `const xxxPath` and can be used in a `cImport()` call ## in the calling wrapper. The dynamic library path is stored in `const xxxLPath` and can - ## be used for the `dynlib` parameter (within quotes) or with `{.passL.}`. + ## be used for the `dynlib` parameter (within quotes) or with `{.passL.}`. Any dependency + ## libraries downloaded by `Conan` or `JBB` are returned in `const xxxLDeps` as a seq[string]. + ## + ## `libdir` can be used to instruct `getHeader()` to copy shared libraries and their + ## dependencies to that directory. This prevents any runtime failures if `outdir` gets + ## removed or its contents changed. By default, `libdir` is set to the output directory + ## where the program binary will be created. The values of `xxxLPath` and `xxxLDeps` will + ## reflect this new location. ## ## `-d:xxxStatic` can be specified to statically link with the library instead. This ## will automatically add a `{.passL.}` call to the static library for convenience. Note @@ -1214,6 +1241,8 @@ macro getHeader*( "" mode = getCompilerMode(header) + libdir = if libdir.len != 0: libdir else: getOutDir() + # Use alternate library names if specified for regex search if altNames.len != 0: lre = lre % ("(" & altNames.replace(",", "|") & ")") @@ -1272,9 +1301,9 @@ macro getHeader*( static: `preBuild`(`outdir`, prePath) - const - # Library binary path - build if not standard - `lpath`* = + let + # Library binary path - build if not standard / conan / jbb + lpath {.compiletime.} = when useStd: stdLPath elif `nameConan` or `nameJBB`: @@ -1283,7 +1312,7 @@ macro getHeader*( buildLibrary(`lname`, `outdir`, `conFlags`, `cmakeFlags`, `makeFlags`, `buildTypes`) # Library dependecy paths - `ldeps`*: seq[string] = + ldeps {.compiletime.}: seq[string] = when `nameConan`: getConanLDeps(`outdir`) elif `nameJBB`: @@ -1291,6 +1320,7 @@ macro getHeader*( else: @[] + const # Header path - search again in case header is generated in build `path`* = if prePath.len != 0: @@ -1301,12 +1331,57 @@ macro getHeader*( static: doAssert `path`.len != 0, "\nHeader " & `header` & " not found - " & "missing/empty outdir or -d:$1Std -d:$1Git -d:$1DL -d:$1Conan or -d:$1JBB not specified" % `name` - doAssert `lpath`.len != 0, "\nLibrary " & `lname` & " not found" - echo "# Including library " & `lpath` + doAssert lpath.len != 0, "\nLibrary " & `lname` & " not found" + + proc extractFilenameStatic(str: string): string {.compiletime.} = + var + pos = -1 + for i in countdown(str.len - 1, 0): + if str[i] == '/' or str[i] == '\\': + pos = i + 1 + break + result = str[pos .. ^1] + + proc joinPathStatic(str1, str2: string): string {.compiletime.} = + let + sep = when defined(Windows): "\\" else: "/" + result = str1 & sep & str2 - # Automatically link with static library and dependencies when `nameStatic`: + const + `lpath`* = lpath + `ldeps`* = ldeps + + # Automatically link with static library and dependencies {.passL: `lpath`.} if `ldeps`.len != 0: {.passL: `ldeps`.join(" ").} + + static: + echo "# Including library " & lpath + if `ldeps`.len != 0: + echo "# Including dependencies " & `ldeps`.join(" ") + else: + const + `lpath`* = joinPathStatic(`libdir`, lpath.extractFilenameStatic()) + `ldeps`* = block: + var + ldeps = ldeps + for i in 0 ..< ldeps.len: + let + lname = ldeps[i].extractFilenameStatic() + ldeptgt = joinPathStatic(`libdir`, lname) + if not fileExists(ldeptgt) or getFileDate(ldeps[i]) > getFileDate(ldeptgt): + echo "# Copying " & lname & " to " & `libdir` + cpFile(ldeps[i], ldeptgt, psymlink = true) + ldeps[i] = ldeptgt + ldeps + + static: + # Copy shared libraries and dependencies to `libdir` + if not fileExists(`lpath`) or getFileDate(lpath) > getFileDate(`lpath`): + echo "# Copying " & `lpath`.extractFilenameStatic() & " to " & `libdir` + cpFile(lpath, `lpath`) + + echo "# Including library " & `lpath` ) diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index 0559db7..c81c35b 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -70,19 +70,6 @@ proc walkDirImpl(indir, inext: string, file=true): seq[string] = if ret == 0: result = output.splitLines() -proc getFileDate(fullpath: string): string = - var - ret = 0 - cmd = - when defined(Windows): - &"cmd /c for %a in ({fullpath.sanitizePath}) do echo %~ta" - elif defined(Linux): - &"stat -c %y {fullpath.sanitizePath}" - elif defined(OSX) or defined(FreeBSD): - &"stat -f %m {fullpath.sanitizePath}" - - (result, ret) = execAction(cmd) - proc getCacheValue(fullpath: string): string = if not gStateCT.nocache: result = fullpath.getFileDate() diff --git a/nimterop/conan.nim b/nimterop/conan.nim index bfe2e94..f8740d0 100644 --- a/nimterop/conan.nim +++ b/nimterop/conan.nim @@ -278,7 +278,7 @@ proc parseConanManifest(pkg: ConanPackage, outdir: string) = if line.startsWith("lib/"): if line.endsWith(".a") or line.endsWith(".lib"): pkg.staticLibs.add line - elif line.endsWith(".so"): + elif line.endsWith(".so") or line.endsWith(".dylib"): pkg.sharedLibs.add line elif line.startsWith("bin/") and line.endsWith("dll"): pkg.sharedLibs.add line diff --git a/nimterop/jbb.nim b/nimterop/jbb.nim index 9f0d173..3e7e623 100644 --- a/nimterop/jbb.nim +++ b/nimterop/jbb.nim @@ -94,18 +94,11 @@ proc parseJBBArtifacts(pkg: JBBPackage, outdir: string) = break proc findJBBLibs(pkg: JBBPackage, outdir: string) = - pkg.sharedLibs = findFiles("lib[\\\\/].*\\.(so|dylib)", outdir) - pkg.sharedLibs.add findFiles("bin[\\\\/].*\\.(dll)", outdir) - for i in 0 ..< pkg.sharedLibs.len: - if pkg.sharedLibs[i].isAbsolute: - pkg.sharedLibs[i] = pkg.sharedLibs[i][outdir.len+1 .. ^1] + pkg.sharedLibs = findFiles("(bin|lib)[\\\\/].*\\.(so|dll|dynlib)[0-9.]*", outdir) for lib in findFiles("lib[\\\\/].*\\.(a|lib)$", outdir): if not lib.endsWith(".dll.a"): - if lib.isAbsolute: - pkg.staticLibs.add lib[outdir.len+1 .. ^1] - else: - pkg.staticLibs.add lib + pkg.staticLibs.add lib proc getJBBRepo*(pkg: JBBPackage, outdir: string) = ## Clone JBB package repo and checkout version tag if version is @@ -174,11 +167,10 @@ proc downloadJBB*(pkg: JBBPackage, outdir: string, clean = true) = &" v{pkg.version}" else: "" - path = outdir / "downloads" / pkg.name + path = outdir / pkg.name echo &"# Downloading {pkg.name}{vstr} from BinaryBuilder.org" downloadUrl(pkg.url, path, quiet = true) pkg.findJBBLibs(path) - mvTree(path, outdir) pkg.dlJBBRequires(outdir) @@ -204,7 +196,7 @@ proc getJBBLDeps*(pkg: JBBPackage, outdir: string, shared: bool, main = true): s if not main: for lib in libs: - result.add outdir / lib + result.add lib for cpkg in pkg.requires: result.add cpkg.getJBBLDeps(outdir, shared, main = false) diff --git a/nimterop/nimconf.nim b/nimterop/nimconf.nim index 33215ef..98fc8fe 100644 --- a/nimterop/nimconf.nim +++ b/nimterop/nimconf.nim @@ -16,6 +16,7 @@ type paths*: OrderedSet[string] nimblePaths*: OrderedSet[string] nimcacheDir*: string + outDir*: string proc getJson(projectDir: string): JsonNode = # Get `nim dump` json value for `projectDir` @@ -67,35 +68,6 @@ proc stripName(path, projectName: string): string = else: result = path -proc getNimcacheDir*(projectDir = ""): string = - ## Get nimcache directory for current compilation or specified `projectDir` - when nimvm: - when (NimMajor, NimMinor, NimPatch) >= (1, 2, 0): - # Get value at compile time from `std/compilesettings` - result = stripName( - querySetting(SingleValueSetting.nimcacheDir), - querySetting(SingleValueSetting.projectName) - ) - else: - discard - - # Not Nim v1.2.0+ or runtime - if result.len == 0: - let - # Get project directory for < v1.2.0 at compile time - projectDir = if projectDir.len != 0: projectDir else: getProjectDir() - - # Use `nim dump` to figure out nimcache for `projectDir` - let - dumpJson = getJson(projectDir) - - if dumpJson != nil and dumpJson.hasKey("nimcache"): - result = stripName(dumpJson["nimcache"].getStr(), "dummy") - - # Set to OS defaults if not detectable - if result.len == 0: - result = getOsCacheDir() - proc jsonToSeq(node: JsonNode, key: string): seq[string] = # Convert JsonArray to seq[string] for specified `key` if node.hasKey(key): @@ -126,7 +98,11 @@ proc getNimConfig*(projectDir = ""): Config = libPath = getCurrentCompilerExe().parentDir().parentDir() / "lib" lazyPaths = querySettingSeq(MultipleValueSetting.lazyPaths) searchPaths = querySettingSeq(MultipleValueSetting.searchPaths) - result.nimcacheDir = querySetting(SingleValueSetting.nimcacheDir) + result.nimcacheDir = stripName( + querySetting(SingleValueSetting.nimcacheDir), + querySetting(SingleValueSetting.projectName) + ) + result.outDir = querySetting(SingleValueSetting.outDir) else: discard @@ -150,6 +126,11 @@ proc getNimConfig*(projectDir = ""): Config = # Usually `libPath` is last entry in `searchPaths` libPath = searchPaths[^1] + if dumpJson.hasKey("nimcache"): + result.nimcacheDir = stripName(dumpJson["nimcache"].getStr(), "dummy") + if dumpJson.hasKey("outdir"): + result.outDir = dumpJson["outdir"].getStr() + # Parse version if version.len != 0: let @@ -188,7 +169,11 @@ proc getNimConfig*(projectDir = ""): Config = if not skip: result.paths.incl path - result.nimcacheDir = getNimcacheDir(projectDir) + if result.nimcacheDir.len == 0: + result.nimcacheDir = getOsCacheDir() + + if result.outDir.len == 0: + result.outDir = projectDir proc getNimConfigFlags(cfg: Config): string = # Convert configuration into Nim flags for cfg file or command line @@ -227,4 +212,16 @@ proc writeNimConfig*(cfgFile: string, projectDir = "") = let cfg = getNimConfig(projectDir) cfgOut = getNimConfigFlags(cfg) - writeFile(cfgFile, cfgOut) \ No newline at end of file + writeFile(cfgFile, cfgOut) + +proc getNimcacheDir*(projectDir = ""): string = + ## Get nimcache directory for current compilation or specified `projectDir` + let + cfg = getNimConfig(projectDir) + result = cfg.nimcacheDir + +proc getOutDir*(projectDir = ""): string = + ## Get output directory for current compilation or specified `projectDir` + let + cfg = getNimConfig(projectDir) + result = cfg.outDir From c359cc0226effd3b3dc47af74defb6b6b7bc7bca Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 16 Jun 2020 20:41:32 -0500 Subject: [PATCH 516/593] Fix lib copy issue --- nimterop/build.nim | 20 +++++++++++++++++--- nimterop/conan.nim | 2 ++ tests/getheader.nims | 3 +++ 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/nimterop/build.nim b/nimterop/build.nim index 6cb497d..b5cdc59 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -252,6 +252,17 @@ proc getFileDate*(fullpath: string): string = (result, ret) = execAction(cmd) +proc touchFile*(fullpath: string) = + ## Touch file to update modified date + var + cmd = + when defined(Windows): + &"cmd /c copy /b {fullpath.sanitizePath}+" + else: + &"touch {fullpath.sanitizePath}" + + discard execAction(cmd) + proc getProjectCacheDir*(name: string, forceClean = true): string = ## Get a cache directory where all nimterop artifacts can be stored ## @@ -1367,19 +1378,22 @@ macro getHeader*( `ldeps`* = block: var ldeps = ldeps + copied: seq[string] for i in 0 ..< ldeps.len: let lname = ldeps[i].extractFilenameStatic() ldeptgt = joinPathStatic(`libdir`, lname) - if not fileExists(ldeptgt) or getFileDate(ldeps[i]) > getFileDate(ldeptgt): - echo "# Copying " & lname & " to " & `libdir` + if not fileExists(ldeptgt) or getFileDate(ldeps[i]) != getFileDate(ldeptgt): cpFile(ldeps[i], ldeptgt, psymlink = true) + copied.add lname ldeps[i] = ldeptgt + if copied.len != 0: + echo "# Copying dependencies: " & copied.join(" ") & "\n# to " & `libdir` ldeps static: # Copy shared libraries and dependencies to `libdir` - if not fileExists(`lpath`) or getFileDate(lpath) > getFileDate(`lpath`): + if not fileExists(`lpath`) or getFileDate(lpath) != getFileDate(`lpath`): echo "# Copying " & `lpath`.extractFilenameStatic() & " to " & `libdir` cpFile(lpath, `lpath`) diff --git a/nimterop/conan.nim b/nimterop/conan.nim index f8740d0..fcb0495 100644 --- a/nimterop/conan.nim +++ b/nimterop/conan.nim @@ -346,6 +346,8 @@ proc downloadConan*(pkg: ConanPackage, outdir: string, clean = true) = elif clean: cleanDir(outdir) + echo &"# Downloading {pkg.name} v{pkg.version} from Conan" + pkg.getConanBuilds() doAssert pkg.recipes.len != 0, &"Failed to download {pkg.name} v{pkg.version} from Conan - check https://conan.io/center" diff --git a/tests/getheader.nims b/tests/getheader.nims index 1d0ba1d..7a3c176 100644 --- a/tests/getheader.nims +++ b/tests/getheader.nims @@ -40,6 +40,7 @@ when defined(posix): # conan static testCall(cmd & " -d:libssh2Conan -d:libssh2SetVer=1.9.0 -d:libssh2Static" & sshcmd, zexp, 0) +<<<<<<< HEAD else: # conan static for Windows testCall(cmd & " -d:zlibConan -d:zlibSetVer=1.2.11 -d:zlibStatic" & zrcmd, zexp, 0) @@ -48,6 +49,8 @@ else: testCall(cmd & " -d:libssh2JBB -d:libssh2SetVer=1.9.0" & sshcmd, zexp, 0) testCall(cmd & " -d:zlibJBB -d:zlibSetVer=1.2.11" & zrcmd, zexp, 0) testCall(cmd & " -d:zlibJBB -d:zlibSetVer=1.2.11 -d:zlibStatic" & zrcmd, zexp, 0) +======= +>>>>>>> c35eb74... Add tests for conan, recurse implies preprocess # git testCall(cmd & " -d:envTest" & zrcmd, zexp, 0) From 0a014e084f3afef204b7539fa688183d9b2f62d7 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 16 Jun 2020 22:57:28 -0500 Subject: [PATCH 517/593] Fix OSX --- nimterop/build.nim | 4 ++-- nimterop/jbb.nim | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/nimterop/build.nim b/nimterop/build.nim index b5cdc59..28f2b3c 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -176,7 +176,7 @@ proc cpFile*(source, dest: string, psymlink = false, move = false) = "mv -f" else: if psymlink: - "cp -fd" + "cp -fa" else: "cp -f" @@ -1055,7 +1055,7 @@ proc getDynlibExt(): string = elif defined(linux) or defined(FreeBSD): result = "\\.so[0-9.]*" elif defined(macosx): - result = "\\.dylib[0-9.]*" + result = "[0-9.\\-]*\\.dylib" var gDefines {.compileTime.} = initTable[string, string]() diff --git a/nimterop/jbb.nim b/nimterop/jbb.nim index 3e7e623..de59a87 100644 --- a/nimterop/jbb.nim +++ b/nimterop/jbb.nim @@ -94,7 +94,7 @@ proc parseJBBArtifacts(pkg: JBBPackage, outdir: string) = break proc findJBBLibs(pkg: JBBPackage, outdir: string) = - pkg.sharedLibs = findFiles("(bin|lib)[\\\\/].*\\.(so|dll|dynlib)[0-9.]*", outdir) + pkg.sharedLibs = findFiles("(bin|lib)[\\\\/].*\\.(so|dll|dylib)[0-9.]*", outdir) for lib in findFiles("lib[\\\\/].*\\.(a|lib)$", outdir): if not lib.endsWith(".dll.a"): From 7870840d2d6992f53d1bfc319e2b52422b234f36 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 16 Jun 2020 23:37:03 -0500 Subject: [PATCH 518/593] Fix Windows file date --- nimterop/build.nim | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/nimterop/build.nim b/nimterop/build.nim index 28f2b3c..dbdcd4c 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -244,7 +244,9 @@ proc getFileDate*(fullpath: string): string = ret = 0 cmd = when defined(Windows): - &"cmd /c for %a in ({fullpath.sanitizePath}) do echo %~ta" + let + (head, tail) = fullpath.splitPath() + &"cmd /c forfiles /P {head.sanitizePath()} /M {tail.sanitizePath} /C \"cmd /c echo @fdate @ftime @fsize\"" elif defined(Linux): &"stat -c %y {fullpath.sanitizePath}" elif defined(OSX) or defined(FreeBSD): From 1820fdffcf8af4b1c5ecca8bdc548c206e24b439 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 18 Jun 2020 10:22:22 -0500 Subject: [PATCH 519/593] Optional version and uri, no Std copy, reuse deps, jbb libc check --- .travis.yml | 2 +- appveyor.yml | 1 + nimterop/build.nim | 150 +++++++++++++++++++++++++++---------------- nimterop/conan.nim | 58 +++++++++++++---- nimterop/globals.nim | 2 +- nimterop/jbb.nim | 63 +++++++++++------- tests/libssh2.nim | 5 +- tests/lzma.nim | 2 + tests/zlib.nim | 2 - 9 files changed, 185 insertions(+), 100 deletions(-) diff --git a/.travis.yml b/.travis.yml index d4e9bde..173da68 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,7 +13,7 @@ language: c env: - BRANCH=0.20.2 - BRANCH=1.0.6 - - BRANCH=1.2.0 + - BRANCH=1.2.2 - BRANCH=devel cache: diff --git a/appveyor.yml b/appveyor.yml index d67b01d..b572ea1 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -11,6 +11,7 @@ environment: matrix: - NIM_VERSION: 0.20.2 - NIM_VERSION: 1.0.6 + - NIM_VERSION: 1.2.2 for: - diff --git a/nimterop/build.nim b/nimterop/build.nim index dbdcd4c..b391f7a 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -2,6 +2,8 @@ import hashes, macros, osproc, sets, strformat, strutils, tables import os except findExe, sleep +export extractFilename, `/` + type BuildType* = enum btAutoconf, btCmake @@ -850,6 +852,31 @@ template fixOutDir() {.dirty.} = let outdir = if outdir.isAbsolute(): outdir else: getProjectDir() / outdir +proc compareVersions*(ver1, ver2: string): int = + ## Compare two version strings x.y.z and return -1, 0, 1 + ## + ## ver1 < ver2 = -1 + ## ver1 = ver2 = 0 + ## ver1 > ver2 = 1 + let + ver1seq = ver1.replace("-", "").split('.') + ver2seq = ver2.replace("-", "").split('.') + for i in 0 ..< ver1seq.len: + let + p1 = ver1seq[i] + p2 = if i < ver2seq.len: ver2seq[i] else: "0" + + try: + let + h1 = p1.parseHexInt() + h2 = p2.parseHexInt() + + if h1 < h2: return -1 + elif h1 > h2: return 1 + except ValueError: + if p1 < p2: return -1 + elif p1 > p2: return 1 + # Conan support include conan @@ -913,10 +940,10 @@ proc getConanPath(header, uri, outdir, version: string, shared: bool): string = uri = uri if "$#" in uri or "$1" in uri: - doAssert version.len != 0, "Need version for Conan uri" + doAssert version.len != 0, "Need version for Conan.io uri: " & uri uri = uri % version - else: - doAssert version.len == 0, "Conan uri does not contain version" + elif version.len != 0: + uri = uri & "/" & version let pkg = newConanPackageFromUri(uri, shared) @@ -934,6 +961,7 @@ proc getJBBPath(header, uri, outdir, version: string): string = let spl = uri.split('/', 1) name = spl[0] + hasVersion = version.len != 0 var ver = @@ -942,11 +970,15 @@ proc getJBBPath(header, uri, outdir, version: string): string = else: "" - if "$#" in ver or "$1" in ver: - doAssert version.len != 0, "Need version for BinaryBuilder.org uri" - ver = ver % version - else: - doAssert version.len == 0, "BinaryBuilder.org uri does not contain version" + if ver.len != 0: + if "$#" in ver or "$1" in ver: + doAssert hasVersion, "Need version for BinaryBuilder.org uri: " & uri + ver = ver % version + elif hasVersion: + doAssert false, "Version in both uri `" & uri & "` and `-d:xxxSetVer=\"" & + version & "\"` for BinaryBuilder.org" + elif hasVersion: + ver = version let pkg = newJBBPackage(name, ver) @@ -1129,10 +1161,10 @@ macro getHeader*( ## `-d:xxxStd` - search standard system paths. E.g. `/usr/include` and `/usr/lib` on Linux ## `-d:xxxGit` - clone source from a git repo specified in `giturl` ## `-d:xxxDL` - download source from `dlurl` and extract if required - ## `-d:xxxConan` - download headers and binary from conan.io using `conanuri` - ## typically formatted as `name/version[@user/channel][:bhash]` - ## `-d:xxxJBB` - download headers and binary from BinaryBuilder.org using `jbburi` - ## typically formatted as `name/version` + ## `-d:xxxConan` - download headers and binary from Conan.io using `conanuri` with + ## format `pkgname[/version[@user/channel][:bhash]]` + ## `-d:xxxJBB` - download headers and binary from BinaryBuilder.org using `jbburi` with + ## format `pkgname[/version]` ## ## This allows a single wrapper to be used in different ways depending on the user's needs. ## If no `-d:xxx` defines are specified, `outdir` will be searched for the header as is. @@ -1145,8 +1177,15 @@ macro getHeader*( ## one of the other methods. ## ## `-d:xxxSetVer=x.y.z` can be used to specify which version to use. It is used as a tag - ## name for Git whereas for DL, Conan and BinaryBuilder.org, it replaces `$1` in the URL - ## defined. + ## name for `Git` whereas for `DL`, `Conan` and `JBB`, it replaces `$1` in the URL + ## if specified. Specifying `-d:xxxSetVer` without a `$1` will download that version for + ## `Conan` and `JBB` if available. If no version is specified, the latest release of the + ## package is downloaded. For `Conan`, `-d:xxxSetVer` can also be used to set additional + ## URI information: + ## `-d:xxxSetVer=1.9.0@bincrafters/stable:bhash` + ## + ## If `conanuri` or `jbburi` are not defined and `Conan` or `JBB` is selected, the `header` + ## filename is used instead. ## ## All defines can also be set in code using `setDefines()` and checked for using ## `isDefined()` which checks for defines set from both `-d` and `setDefines()`. @@ -1165,7 +1204,7 @@ macro getHeader*( ## dependencies to that directory. This prevents any runtime failures if `outdir` gets ## removed or its contents changed. By default, `libdir` is set to the output directory ## where the program binary will be created. The values of `xxxLPath` and `xxxLDeps` will - ## reflect this new location. + ## reflect this new location. `libdir` is ignored for `Std` mode. ## ## `-d:xxxStatic` can be specified to statically link with the library instead. This ## will automatically add a `{.passL.}` call to the static library for convenience. Note @@ -1210,6 +1249,10 @@ macro getHeader*( origname = header.extractFilename().split(".")[0] name = origname.split(seps = AllChars-Letters-Digits).join() + # Default to origname if not specified + conanuri = if conanuri.len != 0: conanuri else: origname + jbburi = if jbburi.len != 0: jbburi else: origname + # -d:xxx for this header stdStr = name & "Std" gitStr = name & "Git" @@ -1316,7 +1359,7 @@ macro getHeader*( let # Library binary path - build if not standard / conan / jbb - lpath {.compiletime.} = + lpath {.compileTime.} = when useStd: stdLPath elif `nameConan` or `nameJBB`: @@ -1325,11 +1368,14 @@ macro getHeader*( buildLibrary(`lname`, `outdir`, `conFlags`, `cmakeFlags`, `makeFlags`, `buildTypes`) # Library dependecy paths - ldeps {.compiletime.}: seq[string] = - when `nameConan`: - getConanLDeps(`outdir`) - elif `nameJBB`: - getJBBLDeps(`outdir`, not `nameStatic`) + ldeps {.compileTime.}: seq[string] = + when not useStd: + when `nameConan`: + getConanLDeps(`outdir`) + elif `nameJBB`: + getJBBLDeps(`outdir`, not `nameStatic`) + else: + @[] else: @[] @@ -1346,20 +1392,6 @@ macro getHeader*( "missing/empty outdir or -d:$1Std -d:$1Git -d:$1DL -d:$1Conan or -d:$1JBB not specified" % `name` doAssert lpath.len != 0, "\nLibrary " & `lname` & " not found" - proc extractFilenameStatic(str: string): string {.compiletime.} = - var - pos = -1 - for i in countdown(str.len - 1, 0): - if str[i] == '/' or str[i] == '\\': - pos = i + 1 - break - result = str[pos .. ^1] - - proc joinPathStatic(str1, str2: string): string {.compiletime.} = - let - sep = when defined(Windows): "\\" else: "/" - result = str1 & sep & str2 - when `nameStatic`: const `lpath`* = lpath @@ -1376,28 +1408,34 @@ macro getHeader*( echo "# Including dependencies " & `ldeps`.join(" ") else: const - `lpath`* = joinPathStatic(`libdir`, lpath.extractFilenameStatic()) - `ldeps`* = block: - var - ldeps = ldeps - copied: seq[string] - for i in 0 ..< ldeps.len: - let - lname = ldeps[i].extractFilenameStatic() - ldeptgt = joinPathStatic(`libdir`, lname) - if not fileExists(ldeptgt) or getFileDate(ldeps[i]) != getFileDate(ldeptgt): - cpFile(ldeps[i], ldeptgt, psymlink = true) - copied.add lname - ldeps[i] = ldeptgt - if copied.len != 0: - echo "# Copying dependencies: " & copied.join(" ") & "\n# to " & `libdir` - ldeps + `lpath`* = when not useStd: `libdir` / lpath.extractFilename() else: lpath + `ldeps`* = + when not useStd: + block: + var + ldeps = ldeps + copied: seq[string] + for i in 0 ..< ldeps.len: + let + lname = ldeps[i].extractFilename() + ldeptgt = `libdir` / lname + if not fileExists(ldeptgt) or getFileDate(ldeps[i]) != getFileDate(ldeptgt): + cpFile(ldeps[i], ldeptgt, psymlink = true) + copied.add lname + ldeps[i] = ldeptgt + # Copy downloaded dependencies to `libdir` + if copied.len != 0: + echo "# Copying dependencies: " & copied.join(" ") & "\n# to " & `libdir` + ldeps + else: + ldeps static: - # Copy shared libraries and dependencies to `libdir` - if not fileExists(`lpath`) or getFileDate(lpath) != getFileDate(`lpath`): - echo "# Copying " & `lpath`.extractFilenameStatic() & " to " & `libdir` - cpFile(lpath, `lpath`) + when not useStd: + # Copy downloaded shared libraries to `libdir` + if not fileExists(`lpath`) or getFileDate(lpath) != getFileDate(`lpath`): + echo "# Copying " & `lpath`.extractFilename() & " to " & `libdir` + cpFile(lpath, `lpath`) - echo "# Including library " & `lpath` + echo "# Including library " & `lpath` ) diff --git a/nimterop/conan.nim b/nimterop/conan.nim index fcb0495..6e761df 100644 --- a/nimterop/conan.nim +++ b/nimterop/conan.nim @@ -42,11 +42,14 @@ const var # Bintray download URL for explicit `user/channel` - conanBaseAltUrl {.compiletime.} = { + conanBaseAltUrl {.compileTime.} = { "bincrafters": "https://bintray.com/bincrafters/public-conan", "conan": "https://bintray.com/conan-community/conan" }.toTable() + # Reuse dependencies already downloaded + gConanRequires {.compileTime.}: Table[string, ConanPackage] + proc addAltConanBaseUrl*(name, url: string) = # Add an alternate base URL for a custom conan repo on bintray conanBaseAltUrl[name] = url @@ -144,13 +147,28 @@ proc searchConan*(name: string, version = "", user = "", channel = ""): ConanPac if channel.len != 0: query &= "/" & channel + echo &"# Searching Conan.io for latest version of {name}" + let j1 = jsonGet(conanSearchUrl % ["query", query]) res = j1.getOrDefault("results").getElems() - if res.len != 0: - # Return last entry - latest - result = newConanPackageFromUri(res[^1].getStr()) + # Return latest comparing versions - prefer @_/_ + var + latest = "" + latestv = "" + for i in 0 ..< res.len: + let + str = res[i].getStr() + if "@_/_" in str: + let + ver = str.split('/')[1].split('@')[0] + if latestv.len == 0 or compareVersions(ver, latestv) > 0: + latestv = ver + latest = str + + if latest.len != 0: + result = newConanPackageFromUri(latest) proc searchConan*(pkg: ConanPackage): ConanPackage = ## Search for latest package based on incomplete package info @@ -288,6 +306,9 @@ proc dlConanBuild*(pkg: ConanPackage, bld: ConanBuild, outdir: string, revision ## ## If omitted, the latest revision (first) is downloaded fixOutDir() + + doAssert bld.revisions.len != 0, "No build revisions found for Conan.io package " & pkg.getUriFromConanPackage() + let revision = if revision.len != 0: @@ -326,7 +347,7 @@ proc dlConanBuild*(pkg: ConanPackage, bld: ConanBuild, outdir: string, revision rmFile(outdir / conanManifest) proc dlConanRequires*(pkg: ConanPackage, bld: ConanBuild, outdir: string) -proc downloadConan*(pkg: ConanPackage, outdir: string, clean = true) = +proc downloadConan*(pkg: ConanPackage, outdir: string, main = true) = ## Download latest recipe/build/revision of `pkg` to `outdir` ## ## High-level API that handles the end to end Conan process flow to find @@ -339,11 +360,13 @@ proc downloadConan*(pkg: ConanPackage, outdir: string, clean = true) = else: pkg - cpkg = loadConanInfo(outdir) + if main: + let + cpkg = loadConanInfo(outdir) + + if cpkg == pkg: + return - if cpkg == pkg: - return - elif clean: cleanDir(outdir) echo &"# Downloading {pkg.name} v{pkg.version} from Conan" @@ -352,7 +375,7 @@ proc downloadConan*(pkg: ConanPackage, outdir: string, clean = true) = doAssert pkg.recipes.len != 0, &"Failed to download {pkg.name} v{pkg.version} from Conan - check https://conan.io/center" - echo &"# Downloading {pkg.name} v{pkg.version} from Conan" + echo &"# Downloading {pkg.name} v{pkg.version} from Conan.io" for recipe, builds in pkg.recipes: for build in builds: if pkg.bhash.len == 0 or pkg.bhash == build.bhash: @@ -362,7 +385,7 @@ proc downloadConan*(pkg: ConanPackage, outdir: string, clean = true) = break break - if clean: + if main: pkg.saveConanInfo(outdir) proc dlConanRequires*(pkg: ConanPackage, bld: ConanBuild, outdir: string) = @@ -374,10 +397,17 @@ proc dlConanRequires*(pkg: ConanPackage, bld: ConanBuild, outdir: string) = if bld.options["shared"] == "False": for req in bld.requires: let - rpkg = newConanPackageFromUri(req, shared = false) + name = req.split('/')[0] + if gConanRequires.hasKey(name): + # Reuse dep already downloaded + pkg.requires.add gConanRequires[name] + else: + let + rpkg = newConanPackageFromUri(req, shared = false) - downloadConan(rpkg, outdir, clean = false) - pkg.requires.add rpkg + downloadConan(rpkg, outdir, main = false) + pkg.requires.add rpkg + gConanRequires[name] = rpkg proc getConanLDeps*(pkg: ConanPackage, outdir: string, main = true): seq[string] = ## Get all Conan libs - shared (.so|.dll) or static (.a|.lib) in pkg, including deps diff --git a/nimterop/globals.nim b/nimterop/globals.nim index 8062ac8..c79f4a5 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -146,7 +146,7 @@ when defined(TOAST): gecho join(args, "").getCommented() else: var - gStateCT* {.compiletime, used.} = new(State) + gStateCT* {.compileTime, used.} = new(State) template nBl*(s: typed): untyped {.used.} = (s.len != 0) diff --git a/nimterop/jbb.nim b/nimterop/jbb.nim index de59a87..5d421f0 100644 --- a/nimterop/jbb.nim +++ b/nimterop/jbb.nim @@ -20,6 +20,10 @@ const jbbProject = "Project.toml" jbbArtifacts = "Artifacts.toml" +var + # Reuse dependencies already downloaded + gJBBRequires {.compileTime.}: Table[string, JBBPackage] + proc `==`*(pkg1, pkg2: JBBPackage): bool = ## Check if two JBBPackage objects are equal (not pkg1.isNil and not pkg2.isNil and @@ -79,19 +83,26 @@ proc parseJBBArtifacts(pkg: JBBPackage, outdir: string) = let line = line.strip() if line.len != 0: - if line.startsWith("arch = ") and not found: - let - barch = line.split(" = ")[1].strip(chars = {'"'}) - if barch == arch: - found = true - elif line.startsWith("os = ") and found: - let - bos = line.split(" = ")[1].strip(chars = {'"'}) - if bos != os: - found = false - elif line.startsWith("url = ") and found: - pkg.url = line.split(" = ")[1].strip(chars = {'"'}) - break + let + spl = line.split(" = ", 1) + name = spl[0] + val = if spl.len == 2: spl[1].strip(chars = {'"', ' '}) else: "" + + # Match arch, os and glibc on Linux to find download URL + case name + of "arch": + if val == arch and not found: found = true + of "os": + if val != os and found: found = false + of "libc": + when defined(Linux): + if val != "glibc" and found: found = false + of "url": + if found: + pkg.url = val + break + else: + discard proc findJBBLibs(pkg: JBBPackage, outdir: string) = pkg.sharedLibs = findFiles("(bin|lib)[\\\\/].*\\.(so|dll|dylib)[0-9.]*", outdir) @@ -143,18 +154,19 @@ proc saveJBBInfo*(pkg: JBBPackage, outdir: string) = writeFile(file, $$pkg) proc dlJBBRequires*(pkg: JBBPackage, outdir: string) -proc downloadJBB*(pkg: JBBPackage, outdir: string, clean = true) = +proc downloadJBB*(pkg: JBBPackage, outdir: string, main = true) = ## Download `pkg` from BinaryBuilder.org to `outdir` ## ## High-level API that handles the end to end JBB process flow to find ## latest package binary and downloads and extracts it to `outdir`. fixOutDir() - let - cpkg = loadJBBInfo(outdir) + if main: + let + cpkg = loadJBBInfo(outdir) + + if cpkg == pkg: + return - if cpkg == pkg: - return - elif clean: cleanDir(outdir) pkg.getJBBRepo(outdir) @@ -174,14 +186,21 @@ proc downloadJBB*(pkg: JBBPackage, outdir: string, clean = true) = pkg.dlJBBRequires(outdir) - if clean: + if main: pkg.saveJBBInfo(outdir) proc dlJBBRequires*(pkg: JBBPackage, outdir: string) = ## Download all required dependencies of this `pkg` fixOutDir() - for rpkg in pkg.requires: - downloadJBB(rpkg, outdir, clean = false) + for i in 0 ..< pkg.requires.len: + let + rpkg = pkg.requires[i] + if gJBBRequires.hasKey(rpkg.name): + # Reuse dep already downloaded + pkg.requires[i] = gJBBRequires[rpkg.name] + else: + downloadJBB(rpkg, outdir, main = false) + gJBBRequires[rpkg.name] = rpkg proc getJBBLDeps*(pkg: JBBPackage, outdir: string, shared: bool, main = true): seq[string] = ## Get all BinaryBuilder.org libs - shared (.so|.dll) or static (.a|.lib) in pkg, including deps diff --git a/tests/libssh2.nim b/tests/libssh2.nim index 48b8ba9..172f6ae 100644 --- a/tests/libssh2.nim +++ b/tests/libssh2.nim @@ -6,7 +6,7 @@ const getHeader( header = "libssh2.h", conanuri = "libssh2/$1", - jbburi = "libssh2/$1", + jbburi = "libssh2/1.9.0", outdir = outdir ) @@ -45,6 +45,3 @@ echo "zlib version = " & (block: else: "" ) - -static: - echo libssh2LDeps \ No newline at end of file diff --git a/tests/lzma.nim b/tests/lzma.nim index cff39de..9bda18e 100644 --- a/tests/lzma.nim +++ b/tests/lzma.nim @@ -24,6 +24,8 @@ getHeader( "lzma.h", giturl = "https://github.com/xz-mirror/xz", dlurl = "https://tukaani.org/xz/xz-$1.tar.gz", + conanuri = "xz_utils", + jbburi = "xz", outdir = baseDir, conFlags = "--disable-xz --disable-xzdec --disable-lzmadec --disable-lzmainfo" ) diff --git a/tests/zlib.nim b/tests/zlib.nim index 2bd9395..53384c3 100644 --- a/tests/zlib.nim +++ b/tests/zlib.nim @@ -27,8 +27,6 @@ getHeader( "zlib.h", giturl = "https://github.com/madler/zlib", dlurl = "http://zlib.net/zlib-$1.tar.gz", - conanuri = "zlib/$1", - jbburi = "zlib/$1", outdir = baseDir, altNames = "z,zlib" ) From f207911d38537fbadf42069b679259aed2dd929d Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 18 Jun 2020 14:33:32 -0500 Subject: [PATCH 520/593] --gc:arc fixes and testing --- nimterop/conan.nim | 9 ++++++--- nimterop/jbb.nim | 9 ++++++--- tests/getheader.nims | 3 +++ 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/nimterop/conan.nim b/nimterop/conan.nim index 6e761df..ee74141 100644 --- a/nimterop/conan.nim +++ b/nimterop/conan.nim @@ -1,4 +1,4 @@ -import json, marshal, os, strformat, strutils, tables +import json, os, strformat, strutils, tables type ConanPackage* = ref object @@ -272,7 +272,10 @@ proc loadConanInfo*(outdir: string): ConanPackage = file = outdir / conanInfo if fileExists(file): - result = to[ConanPackage](readFile(file)) + try: + result = to(readFile(file).parseJson(), ConanPackage) + except: + discard proc saveConanInfo*(pkg: ConanPackage, outdir: string) = ## Save downloaded package info to `outdir/conaninfo.json` @@ -280,7 +283,7 @@ proc saveConanInfo*(pkg: ConanPackage, outdir: string) = let file = outdir / conanInfo - writeFile(file, $$pkg) + writeFile(file, $(%pkg)) proc parseConanManifest(pkg: ConanPackage, outdir: string) = # Get all library info from downloaded conan package diff --git a/nimterop/jbb.nim b/nimterop/jbb.nim index 5d421f0..b5e66fb 100644 --- a/nimterop/jbb.nim +++ b/nimterop/jbb.nim @@ -1,4 +1,4 @@ -import marshal, os, strutils +import json, os, strutils type JBBPackage* = ref object @@ -143,7 +143,10 @@ proc loadJBBInfo*(outdir: string): JBBPackage = file = outdir / jbbInfo if fileExists(file): - result = to[JBBPackage](readFile(file)) + try: + result = to(readFile(file).parseJson(), JBBPackage) + except: + discard proc saveJBBInfo*(pkg: JBBPackage, outdir: string) = ## Save downloaded package info to `outdir/jbbinfo.json` @@ -151,7 +154,7 @@ proc saveJBBInfo*(pkg: JBBPackage, outdir: string) = let file = outdir / jbbInfo - writeFile(file, $$pkg) + writeFile(file, $(%pkg)) proc dlJBBRequires*(pkg: JBBPackage, outdir: string) proc downloadJBB*(pkg: JBBPackage, outdir: string, main = true) = diff --git a/tests/getheader.nims b/tests/getheader.nims index 7a3c176..2fe4d9c 100644 --- a/tests/getheader.nims +++ b/tests/getheader.nims @@ -21,6 +21,9 @@ var lexp = "liblzma version = " zexp = "zlib version = " +when (NimMajor, NimMinor, NimPatch) >= (1, 2, 0): + cmd &= " --gc:arc" + testCall(cmd & lrcmd, "No build files found", 1) testCall(cmd & " -d:libssh2Conan" & sshcmd, "Need version for Conan uri", 1) testCall(cmd & " -d:libssh2JBB" & sshcmd, "Need version for BinaryBuilder.org uri", 1) From 9b2aa7d4b1691db69e76bad1b681eafc5bfb060a Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 18 Jun 2020 14:52:27 -0500 Subject: [PATCH 521/593] Use marshal pre 1.2.0 --- nimterop/conan.nim | 23 +++++++++++++++++------ nimterop/jbb.nim | 19 ++++++++++++++----- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/nimterop/conan.nim b/nimterop/conan.nim index ee74141..cc060f8 100644 --- a/nimterop/conan.nim +++ b/nimterop/conan.nim @@ -1,4 +1,9 @@ -import json, os, strformat, strutils, tables +import os, strformat, strutils, tables + +when (NimMajor, NimMinor, NimPatch) < (1, 2, 0): + import marshal +else: + import json type ConanPackage* = ref object @@ -272,10 +277,13 @@ proc loadConanInfo*(outdir: string): ConanPackage = file = outdir / conanInfo if fileExists(file): - try: - result = to(readFile(file).parseJson(), ConanPackage) - except: - discard + when (NimMajor, NimMinor, NimPatch) < (1, 2, 0): + result = to[ConanPackage](readFile(file)) + else: + try: + result = to(readFile(file).parseJson(), ConanPackage) + except: + discard proc saveConanInfo*(pkg: ConanPackage, outdir: string) = ## Save downloaded package info to `outdir/conaninfo.json` @@ -283,7 +291,10 @@ proc saveConanInfo*(pkg: ConanPackage, outdir: string) = let file = outdir / conanInfo - writeFile(file, $(%pkg)) + when (NimMajor, NimMinor, NimPatch) < (1, 2, 0): + writeFile(file, $$pkg) + else: + writeFile(file, $(%pkg)) proc parseConanManifest(pkg: ConanPackage, outdir: string) = # Get all library info from downloaded conan package diff --git a/nimterop/jbb.nim b/nimterop/jbb.nim index b5e66fb..c282197 100644 --- a/nimterop/jbb.nim +++ b/nimterop/jbb.nim @@ -1,5 +1,8 @@ import json, os, strutils +when (NimMajor, NimMinor, NimPatch) < (1, 2, 0): + import marshal + type JBBPackage* = ref object ## JBBPackage type that stores package information @@ -143,10 +146,13 @@ proc loadJBBInfo*(outdir: string): JBBPackage = file = outdir / jbbInfo if fileExists(file): - try: - result = to(readFile(file).parseJson(), JBBPackage) - except: - discard + when (NimMajor, NimMinor, NimPatch) < (1, 2, 0): + result = to[JBBPackage](readFile(file)) + else: + try: + result = to(readFile(file).parseJson(), JBBPackage) + except: + discard proc saveJBBInfo*(pkg: JBBPackage, outdir: string) = ## Save downloaded package info to `outdir/jbbinfo.json` @@ -154,7 +160,10 @@ proc saveJBBInfo*(pkg: JBBPackage, outdir: string) = let file = outdir / jbbInfo - writeFile(file, $(%pkg)) + when (NimMajor, NimMinor, NimPatch) < (1, 2, 0): + writeFile(file, $$pkg) + else: + writeFile(file, $(%pkg)) proc dlJBBRequires*(pkg: JBBPackage, outdir: string) proc downloadJBB*(pkg: JBBPackage, outdir: string, main = true) = From 7e0b0b1a2b69a835a680afce88f7af39b2c944b0 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Fri, 19 Jun 2020 13:32:01 -0500 Subject: [PATCH 522/593] Retries, conan VS MD/14 --- nimterop/build.nim | 8 ++++---- nimterop/conan.nim | 4 ++++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/nimterop/build.nim b/nimterop/build.nim index b391f7a..edbe439 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -129,7 +129,7 @@ proc execAction*(cmd: string, retry = 0, die = true, cache = false, # On failure, retry or die as requested if result.ret != 0: if retry > 0: - sleep(500) + sleep(1000) result = execAction(cmd, retry = retry - 1, die, cache, cacheKey) elif die: doAssert false, "Command failed: " & $result.ret & "\ncmd: " & ccmd & @@ -368,7 +368,7 @@ proc downloadUrl*(url, outdir: string, quiet = false) = cmd = "powershell [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; wget $# -OutFile $#" else: doAssert false, "No download tool available - curl, wget" - discard execAction(cmd % [url.quoteShell, (outdir/file).sanitizePath], retry = 1) + discard execAction(cmd % [url.quoteShell, (outdir/file).sanitizePath], retry = 3) if ext == ".zip": extractZip(file, outdir, quiet) @@ -436,12 +436,12 @@ proc gitPull*(url: string, outdir = "", plist = "", checkout = "", quiet = false if checkout.len != 0: if not quiet: echo "# Checking out " & checkout - discard execAction(&"cd {outdirQ} && git fetch", retry = 1) + discard execAction(&"cd {outdirQ} && git fetch", retry = 3) discard execAction(&"cd {outdirQ} && git checkout {checkout}") else: if not quiet: echo "# Pulling repository" - discard execAction(&"cd {outdirQ} && git pull --depth=1 origin master", retry = 1) + discard execAction(&"cd {outdirQ} && git pull --depth=1 origin master", retry = 3) proc gitTags*(outdir: string): seq[string] = ## Get all the git tags in the specified directory diff --git a/nimterop/conan.nim b/nimterop/conan.nim index cc060f8..7e1bd8e 100644 --- a/nimterop/conan.nim +++ b/nimterop/conan.nim @@ -208,6 +208,10 @@ proc getConanBuilds*(pkg: ConanPackage, filter = "") = query &= &"&{filter}" if "compiler=" notin filter and os != "windows": query &= &"&compiler={compiler}&compiler.version=" & vfilter + if "compiler.runtime=" notin filter and os == "windows": + query &= &"&compiler.runtime=MD" + if "compiler.version=" notin filter and os == "windows": + query &= &"&compiler.version=14" query.replace("&", "%20and%20") else: "" From 7c9d826998e7347e613d823ba00ca6160d712a2f Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Fri, 19 Jun 2020 18:03:37 -0500 Subject: [PATCH 523/593] Handle octal values correctly --- nimterop/exprparser.nim | 5 +++-- tests/include/tast2.h | 1 + tests/tast2.nim | 1 + 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/nimterop/exprparser.nim b/nimterop/exprparser.nim index 0fea184..0d2099a 100644 --- a/nimterop/exprparser.nim +++ b/nimterop/exprparser.nim @@ -140,8 +140,6 @@ proc getIntNode(number, suffix: string): PNode {.inline.} = var val: BiggestInt flags: TNodeFlags - # I realize these regex are wasteful on performance, but - # couldn't come up with a better idea. if number.startsWith("0X") or number.startsWith("0x"): val = parseHexInt(number) flags = {nfBase16} @@ -203,6 +201,9 @@ proc processNumberLiteral(gState: State, node: TSNode): PNode = if number.startsWith("-"): number = number[1 ..< number.len] prefix = "-" + if number.len > 1 and number[0] == '0' and number[1] notin ['x', 'X']: + # Octal 0123 + number = "0o" & number[1 .. ^1] if tripleEndings.any(proc (s: string): bool = number.endsWith(s)): suffix = number[^3 .. ^1] number = number[0 ..< ^3] diff --git a/tests/include/tast2.h b/tests/include/tast2.h index 019f7c4..6f569d5 100644 --- a/tests/include/tast2.h +++ b/tests/include/tast2.h @@ -7,6 +7,7 @@ extern "C" { #define C 0x10 #define D "hello" #define E 'c' +#define F 01234 #define UEXPR (1234u << 1) #define ULEXPR (1234ul << 2) diff --git a/tests/tast2.nim b/tests/tast2.nim index fd0175a..124c4e4 100644 --- a/tests/tast2.nim +++ b/tests/tast2.nim @@ -110,6 +110,7 @@ assert B == 1.0 assert C == 0x10 assert D == "hello" assert E == 'c' +assert F == 0o1234 assert not defined(NOTSUPPORTEDSTR) From 73fec6753fdcade0277c6c529e52ef01096e28e1 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Fri, 19 Jun 2020 21:31:22 -0500 Subject: [PATCH 524/593] Download retries --- nimterop/build.nim | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/nimterop/build.nim b/nimterop/build.nim index edbe439..62b5e1f 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -76,7 +76,7 @@ proc getNimteropCacheDir(): string = result = getNimcacheDir() / "nimterop" proc execAction*(cmd: string, retry = 0, die = true, cache = false, - cacheKey = ""): tuple[output: string, ret: int] = + cacheKey = "", onRetry: proc() = nil): tuple[output: string, ret: int] = ## Execute an external command - supported at compile time ## ## Checks if command exits successfully before returning. If not, an @@ -129,7 +129,9 @@ proc execAction*(cmd: string, retry = 0, die = true, cache = false, # On failure, retry or die as requested if result.ret != 0: if retry > 0: - sleep(1000) + if not onRetry.isNil: + onRetry() + sleep(500) result = execAction(cmd, retry = retry - 1, die, cache, cacheKey) elif die: doAssert false, "Command failed: " & $result.ret & "\ncmd: " & ccmd & @@ -344,16 +346,17 @@ proc extractTar*(tarfile, outdir: string, quiet = false) = if name.len != 0: rmFile(outdir / name) -proc downloadUrl*(url, outdir: string, quiet = false) = +proc downloadUrl*(url, outdir: string, quiet = false, retry = 1) = ## Download a file using `curl` or `wget` (or `powershell` on Windows) to the specified directory ## ## If an archive file, it is automatically extracted after download. let file = url.extractFilename() + filePath = outdir / file ext = file.splitFile().ext.toLowerAscii() archives = @[".zip", ".xz", ".gz", ".bz2", ".tgz", ".tar"] - if not (ext in archives and fileExists(outdir/file)): + if not (ext in archives and fileExists(filePath)): if not quiet: echo "# Downloading " & file mkDir(outdir) @@ -368,7 +371,8 @@ proc downloadUrl*(url, outdir: string, quiet = false) = cmd = "powershell [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; wget $# -OutFile $#" else: doAssert false, "No download tool available - curl, wget" - discard execAction(cmd % [url.quoteShell, (outdir/file).sanitizePath], retry = 3) + discard execAction(cmd % [url.quoteShell, (filePath).sanitizePath], retry = 3, + onRetry = proc() = rmFile(filePath)) if ext == ".zip": extractZip(file, outdir, quiet) From fbc8c2ad9edd413472849500822d929c6578c568 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Sat, 20 Jun 2020 00:09:50 -0500 Subject: [PATCH 525/593] Reorganize file structure --- CHANGES.md | 30 + nimterop/build.nim | 1420 +----------------------- nimterop/build/ccompiler.nim | 101 ++ nimterop/{ => build}/conan.nim | 0 nimterop/build/getheader.nim | 504 +++++++++ nimterop/{ => build}/jbb.nim | 2 +- nimterop/{ => build}/nimconf.nim | 0 nimterop/build/shell.nim | 465 ++++++++ nimterop/build/tools.nim | 260 +++++ nimterop/git.nim | 1 - nimterop/toast.nim | 4 +- nimterop/{ => toastlib}/ast.nim | 3 +- nimterop/{ => toastlib}/ast2.nim | 4 +- nimterop/{ => toastlib}/comphelp.nim | 3 +- nimterop/{ => toastlib}/exprparser.nim | 6 +- nimterop/{ => toastlib}/getters.nim | 2 +- nimterop/{ => toastlib}/grammar.nim | 3 +- nimterop/{ => toastlib}/lisp.nim | 3 +- nimterop/{ => toastlib}/tshelp.nim | 5 +- 19 files changed, 1435 insertions(+), 1381 deletions(-) create mode 100644 nimterop/build/ccompiler.nim rename nimterop/{ => build}/conan.nim (100%) create mode 100644 nimterop/build/getheader.nim rename nimterop/{ => build}/jbb.nim (99%) rename nimterop/{ => build}/nimconf.nim (100%) create mode 100644 nimterop/build/shell.nim create mode 100644 nimterop/build/tools.nim delete mode 100644 nimterop/git.nim rename nimterop/{ => toastlib}/ast.nim (99%) rename nimterop/{ => toastlib}/ast2.nim (99%) rename nimterop/{ => toastlib}/comphelp.nim (98%) rename nimterop/{ => toastlib}/exprparser.nim (99%) rename nimterop/{ => toastlib}/getters.nim (99%) rename nimterop/{ => toastlib}/grammar.nim (99%) rename nimterop/{ => toastlib}/lisp.nim (97%) rename nimterop/{ => toastlib}/tshelp.nim (99%) diff --git a/CHANGES.md b/CHANGES.md index e47974d..cedf5a5 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,34 @@ # Nimterop Change History +## Version 0.6.0 + +This release adds the ability to download precompiled binaries from [Conan.io](https://conan.io/center) and Julia's [BinaryBuilder.org](https://binarybuilder.org). This alleviates the headache of searching and downloading libraries manually both for wrapper writers as well as end users. There are some known limitations but it should prove to become more useful as these sites expand their capabilities. + +Conan.io shared builds tend to have all dependencies statically linked into the binary so a single so/dll/dylib has everything. For Conan.io static builds and all libraries on BinaryBuilder.org, dependencies are also downloaded and linked as needed. They are returned in the new `const xxxLDeps` in case wrapper writers need it for some reason. + +Known concerns: +- Conan.io only compiles Windows builds with Microsoft's VC++ compiler so static .lib files may not always work with MinGW on Windows. +- Conan.io compiles all Mac builds on OSX 10.14 so older versions of the OS will grumble when statically linking these libraries. +- BinaryBuilder.org does not include static libs for all their projects. + +Refer to the documentation for `getHeader()` for details on how to use this new capability. + +See the full list of changes here: + +https://github.com/nimterop/nimterop/compare/v0.5.9...v0.6.0 + +### Breaking changes + +- All shared libraries installed by `getHeader()` will now get copied into the `libdir` parameter specified. If left blank, `libdir` will default to the directory where the executable binary gets created (outdir). While this is not really a breaking change, it is a change in behavior compared to older versions of nimterop. Note that `Std` libraries are not copied over. [#154](i154) + +- `git.nim` has been removed. This module was an artifact from the early days and was renamed to `build.nim` back in v0.2.0. + +### New functionality + +- `getHeader()` now detects and links against `.lib` files as part of enabling Conan.io. Not all `.lib` files are compatible with MinGW as already stated above but for those that work, this is a required capability. + + + ## Version 0.5.0 This release introduces a new backend for wrapper generation dubbed `ast2` that leverages the Nim compiler AST and renderer. The new design simplifies feature development and already includes all the functionality of the legacy algorithm plus fixes for several open issues. @@ -73,6 +102,7 @@ https://github.com/nimterop/nimterop/compare/v0.4.4...v0.5.0 [i148]: https://github.com/nimterop/nimterop/issues/148 [i151]: https://github.com/nimterop/nimterop/issues/151 [i153]: https://github.com/nimterop/nimterop/issues/153 +[i154]: https://github.com/nimterop/nimterop/issues/154 [i155]: https://github.com/nimterop/nimterop/issues/155 [i156]: https://github.com/nimterop/nimterop/issues/156 [i159]: https://github.com/nimterop/nimterop/issues/159 diff --git a/nimterop/build.nim b/nimterop/build.nim index 62b5e1f..99adeca 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -4,21 +4,13 @@ import os except findExe, sleep export extractFilename, `/` -type - BuildType* = enum - btAutoconf, btCmake - - BuildStatus = object - built: bool - buildPath: string - error: string - # build specific debug since we cannot import globals (yet) var gDebug* = false gDebugCT* {.compileTime.} = false gNimExe* = "" +# Misc helpers proc echoDebug(str: string) = let str = "\n# " & str.strip().replace("\n", "\n# ") when nimvm: @@ -26,24 +18,6 @@ proc echoDebug(str: string) = else: if gDebug: echo str -proc fixCmd(cmd: string): string = - when defined(Windows): - # Replace 'cd d:\abc' with 'd: && cd d:\abc` - var filteredCmd = cmd - if cmd.toLower().startsWith("cd"): - var - colonIndex = cmd.find(":") - driveLetter = cmd.substr(colonIndex-1, colonIndex) - if (driveLetter[0].isAlphaAscii() and - driveLetter[1] == ':' and - colonIndex == 4): - filteredCmd = &"{driveLetter} && {cmd}" - result = "cmd /c " & filteredCmd - elif defined(posix): - result = cmd - else: - doAssert false - proc sanitizePath*(path: string, noQuote = false, sep = $DirSep): string = result = path.multiReplace([("\\\\", sep), ("\\", sep), ("/", sep)]) if not noQuote: @@ -57,801 +31,6 @@ proc getCurrentNimCompiler*(): string = else: result = gNimExe -# Nim cfg file related functionality -include "."/nimconf - -proc sleep*(milsecs: int) = - ## Sleep at compile time - let - cmd = - when defined(Windows): - "cmd /c timeout " - else: - "sleep " - - discard gorgeEx(cmd & $(milsecs / 1000)) - -proc getNimteropCacheDir(): string = - # Get location to cache all nimterop artifacts - result = getNimcacheDir() / "nimterop" - -proc execAction*(cmd: string, retry = 0, die = true, cache = false, - cacheKey = "", onRetry: proc() = nil): tuple[output: string, ret: int] = - ## Execute an external command - supported at compile time - ## - ## Checks if command exits successfully before returning. If not, an - ## error is raised. Always caches results to be used in nimsuggest or nimcheck - ## mode. - ## - ## `retry` - number of times command should be retried before error - ## `die = false` - return on errors - ## `cache = true` - cache results unless cleared with -f - ## `cacheKey` - key to create unique cache entry - let - ccmd = fixCmd(cmd) - - when nimvm: - # Cache results for speedup if cache = true - # Else cache for preserving functionality in nimsuggest and nimcheck - let - hash = (ccmd & cacheKey).hash().abs() - cachePath = getNimteropCacheDir() / "execCache" / "nimterop_" & $hash - cacheFile = cachePath & ".txt" - retFile = cachePath & "_ret.txt" - - when defined(nimsuggest) or defined(nimcheck): - # Load results from cache file if generated in previous run - if fileExists(cacheFile) and fileExists(retFile): - result.output = cacheFile.readFile() - result.ret = retFile.readFile().parseInt() - elif die: - doAssert false, "Results not cached - run nim c/cpp at least once\n" & ccmd - else: - if cache and fileExists(cacheFile) and fileExists(retFile) and not compileOption("forceBuild"): - # Return from cache when requested - result.output = cacheFile.readFile() - result.ret = retFile.readFile().parseInt() - else: - # Execute command and store results in cache - (result.output, result.ret) = gorgeEx(ccmd) - if result.ret == 0 or die == false: - # mkdir for execCache dir (circular dependency) - let dir = cacheFile.parentDir() - if not dirExists(dir): - let flag = when not defined(Windows): "-p" else: "" - discard execAction(&"mkdir {flag} {dir.sanitizePath}") - cacheFile.writeFile(result.output) - retFile.writeFile($result.ret) - else: - # Used by toast - (result.output, result.ret) = execCmdEx(ccmd) - - # On failure, retry or die as requested - if result.ret != 0: - if retry > 0: - if not onRetry.isNil: - onRetry() - sleep(500) - result = execAction(cmd, retry = retry - 1, die, cache, cacheKey) - elif die: - doAssert false, "Command failed: " & $result.ret & "\ncmd: " & ccmd & - "\nresult:\n" & result.output - -proc findExe*(exe: string): string = - ## Find the specified executable using the `which`/`where` command - supported - ## at compile time - var - cmd = - when defined(Windows): - "where " & exe - else: - "which " & exe - - (output, ret) = execAction(cmd, die = false) - - if ret == 0: - return output.splitLines()[0].strip() - -proc mkDir*(dir: string) = - ## Create a directory at compile time - ## - ## The `os` module is not available at compile time so a few - ## crucial helper functions are included with nimterop. - if not dirExists(dir): - let - flag = when not defined(Windows): "-p" else: "" - discard execAction(&"mkdir {flag} {dir.sanitizePath}", retry = 2) - -proc cpFile*(source, dest: string, psymlink = false, move = false) = - ## Copy a file from `source` to `dest` at compile time - ## - ## `psymlink = true` preserves symlinks instead of dereferencing on posix - let - source = source.replace("/", $DirSep) - dest = dest.replace("/", $DirSep) - cmd = - when defined(Windows): - if move: - "move /y" - else: - "copy /y" - else: - if move: - "mv -f" - else: - if psymlink: - "cp -fa" - else: - "cp -f" - - discard execAction(&"{cmd} {source.sanitizePath} {dest.sanitizePath}", retry = 2) - -proc mvFile*(source, dest: string) = - ## Move a file from `source` to `dest` at compile time - cpFile(source, dest, move=true) - -proc rmFile*(source: string, dir = false) = - ## Remove a file or pattern at compile time - let - source = source.replace("/", $DirSep) - cmd = - when defined(Windows): - if dir: - "rd /s/q" - else: - "del /s/q/f" - else: - "rm -rf" - exists = - if dir: - dirExists(source) - else: - fileExists(source) - - if exists: - discard execAction(&"{cmd} {source.sanitizePath}", retry = 2) - -proc rmDir*(dir: string) = - ## Remove a directory or pattern at compile time - rmFile(dir, dir = true) - -proc cleanDir*(dir: string) = - ## Remove all contents of a directory at compile time - for kind, path in walkDir(dir): - if kind == pcDir: - rmDir(path) - else: - rmFile(path) - -proc cpTree*(source, dest: string, move = false) = - ## Copy contents of source dir to the destination, not the directory itself - for kind, path in walkDir(source, relative = true): - if kind == pcDir: - cpTree(source / path, dest / path, move) - if move: - rmDir(source / path) - else: - if not dirExists(dest): - mkDir(dest) - if move: - mvFile(source / path, dest / path) - else: - cpFile(source / path, dest / path) - -proc mvTree*(source, dest: string) = - ## Move contents of source dir to the destination, not the directory itself - cpTree(source, dest, move = true) - -proc getFileDate*(fullpath: string): string = - ## Get file date for `fullpath` - var - ret = 0 - cmd = - when defined(Windows): - let - (head, tail) = fullpath.splitPath() - &"cmd /c forfiles /P {head.sanitizePath()} /M {tail.sanitizePath} /C \"cmd /c echo @fdate @ftime @fsize\"" - elif defined(Linux): - &"stat -c %y {fullpath.sanitizePath}" - elif defined(OSX) or defined(FreeBSD): - &"stat -f %m {fullpath.sanitizePath}" - - (result, ret) = execAction(cmd) - -proc touchFile*(fullpath: string) = - ## Touch file to update modified date - var - cmd = - when defined(Windows): - &"cmd /c copy /b {fullpath.sanitizePath}+" - else: - &"touch {fullpath.sanitizePath}" - - discard execAction(cmd) - -proc getProjectCacheDir*(name: string, forceClean = true): string = - ## Get a cache directory where all nimterop artifacts can be stored - ## - ## Projects can use this location to download source code and build binaries - ## that can be then accessed by multiple apps. This is created under the - ## per-user Nim cache directory. - ## - ## Use `name` to specify the subdirectory name for a project. - ## - ## `forceClean` is enabled by default and effectively deletes the folder - ## if Nim is compiled with the `-f` or `--forceBuild` flag. This allows - ## any project to start out with a clean cache dir on a forced build. - ## - ## NOTE: avoid calling `getProjectCacheDir()` multiple times on the same - ## `name` when `forceClean = true` else checked out source might get deleted - ## at the wrong time during build. - ## - ## E.g. - ## `nimgit2` downloads `libgit2` source so `name = "libgit2"` - ## - ## `nimarchive` downloads `libarchive`, `bzlib`, `liblzma` and `zlib` so - ## `name = "nimarchive" / "libarchive"` for `libarchive`, etc. - result = getNimteropCacheDir() / name - - if forceClean and compileOption("forceBuild"): - echo "# Removing " & result - rmDir(result) - -proc extractZip*(zipfile, outdir: string, quiet = false) = - ## Extract a zip file using `powershell` on Windows and `unzip` on other - ## systems to the specified output directory - var cmd = "unzip -o $#" - if defined(Windows): - cmd = "powershell -nologo -noprofile -command \"& { Add-Type -A " & - "'System.IO.Compression.FileSystem'; " & - "[IO.Compression.ZipFile]::ExtractToDirectory('$#', '.'); }\"" - - if not quiet: - echo "# Extracting " & zipfile - discard execAction(&"cd {outdir.sanitizePath} && {cmd % zipfile}") - -proc extractTar*(tarfile, outdir: string, quiet = false) = - ## Extract a tar file using `tar`, `7z` or `7za` to the specified output directory - var - cmd = "" - name = "" - - if findExe("tar").len != 0: - let - ext = tarfile.splitFile().ext.toLowerAscii() - typ = - case ext - of ".gz", ".tgz": "z" - of ".xz": "J" - of ".bz2": "j" - else: "" - - cmd = "tar xvf" & typ & " " & tarfile.sanitizePath - else: - for i in ["7z", "7za"]: - if findExe(i).len != 0: - cmd = i & " x $#" % tarfile.sanitizePath - - name = tarfile.splitFile().name - if ".tar" in name.toLowerAscii(): - cmd &= " && " & i & " x $#" % name.sanitizePath - - break - - doAssert cmd.len != 0, "No extraction tool - tar, 7z, 7za - available for " & tarfile.sanitizePath - - if not quiet: - echo "# Extracting " & tarfile - discard execAction(&"cd {outdir.sanitizePath} && {cmd}") - if name.len != 0: - rmFile(outdir / name) - -proc downloadUrl*(url, outdir: string, quiet = false, retry = 1) = - ## Download a file using `curl` or `wget` (or `powershell` on Windows) to the specified directory - ## - ## If an archive file, it is automatically extracted after download. - let - file = url.extractFilename() - filePath = outdir / file - ext = file.splitFile().ext.toLowerAscii() - archives = @[".zip", ".xz", ".gz", ".bz2", ".tgz", ".tar"] - - if not (ext in archives and fileExists(filePath)): - if not quiet: - echo "# Downloading " & file - mkDir(outdir) - var cmd = findExe("curl") - if cmd.len != 0: - cmd &= " -Lk $# -o $#" - else: - cmd = findExe("wget") - if cmd.len != 0: - cmd &= " $# -O $#" - elif defined(Windows): - cmd = "powershell [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; wget $# -OutFile $#" - else: - doAssert false, "No download tool available - curl, wget" - discard execAction(cmd % [url.quoteShell, (filePath).sanitizePath], retry = 3, - onRetry = proc() = rmFile(filePath)) - - if ext == ".zip": - extractZip(file, outdir, quiet) - elif ext in archives: - extractTar(file, outdir, quiet) - -proc gitReset*(outdir: string) = - ## Hard reset the git repository at the specified directory - echo "# Resetting " & outdir - - let cmd = &"cd {outdir.sanitizePath} && git reset --hard" - while execAction(cmd).output.contains("Permission denied"): - sleep(1000) - echo "# Retrying ..." - -proc gitCheckout*(file, outdir: string) = - ## Checkout the specified `file` in the git repository at `outdir` - ## - ## This effectively resets all changes in the file and can be - ## used to undo any changes that were made to source files to enable - ## successful wrapping with `cImport()` or `c2nImport()`. - echo "# Resetting " & file - let file2 = file.relativePath outdir - let cmd = &"cd {outdir.sanitizePath} && git checkout {file2.sanitizePath}" - while execAction(cmd).output.contains("Permission denied"): - sleep(500) - echo "# Retrying ..." - -proc gitPull*(url: string, outdir = "", plist = "", checkout = "", quiet = false) = - ## Pull the specified git repository to the output directory - ## - ## `plist` is the list of specific files and directories or wildcards - ## to sparsely checkout. Multiple values can be specified one entry per - ## line. It is optional and if omitted, the entire repository will be - ## checked out. - ## - ## `checkout` is the git tag, branch or commit hash to checkout once - ## the repository is downloaded. This allows for pinning to a specific - ## version of the code. - if dirExists(outdir/".git"): - gitReset(outdir) - return - - let - outdirQ = outdir.sanitizePath - - mkDir(outdir) - - if not quiet: - echo "# Setting up Git repo: " & url - discard execAction(&"cd {outdirQ} && git init .") - discard execAction(&"cd {outdirQ} && git remote add origin {url}") - - if plist.len != 0: - # If a specific list of files is required, create a sparse checkout - # file for git in its config directory - let sparsefile = outdir / ".git/info/sparse-checkout" - - discard execAction(&"cd {outdirQ} && git config core.sparsecheckout true") - writeFile(sparsefile, plist) - - # In case directory has old files from another run - discard execAction(&"cd {outdirQ} && git clean -fxd") - - if checkout.len != 0: - if not quiet: - echo "# Checking out " & checkout - discard execAction(&"cd {outdirQ} && git fetch", retry = 3) - discard execAction(&"cd {outdirQ} && git checkout {checkout}") - else: - if not quiet: - echo "# Pulling repository" - discard execAction(&"cd {outdirQ} && git pull --depth=1 origin master", retry = 3) - -proc gitTags*(outdir: string): seq[string] = - ## Get all the git tags in the specified directory - let - cmd = &"cd {outdir.sanitizePath} && git tag" - tags = execAction(cmd).output.splitLines() - for tag in tags: - let - tag = tag.strip() - if tag.len != 0: - result.add tag - -proc findFiles*(file: string, dir: string, recurse = true, regex = false): seq[string] = - ## Find all matching files in the specified directory - ## - ## `file` is a regular expression if `regex` is true - ## - ## Turn off recursive search with `recurse` - var - cmd = - when defined(Windows): - "nimgrep --filenames --oneline --nocolor $1 \"$2\" $3" - elif defined(linux): - "find $3 $1 -regextype egrep -regex $2" - elif defined(osx) or defined(FreeBSD): - "find -E $3 $1 -regex $2" - - recursive = "" - - if recurse: - when defined(Windows): - recursive = "--recursive" - else: - when not defined(Windows): - recursive = "-maxdepth 1" - - var - dir = dir - file = file - if not recurse: - let - pdir = file.parentDir() - if pdir.len != 0: - dir = dir / pdir - - file = file.extractFilename - - cmd = cmd % [recursive, (".*[\\\\/]" & file & "$").quoteShell, dir.sanitizePath] - - let - (files, ret) = execAction(cmd, die = false) - if ret == 0: - for line in files.splitLines(): - let f = - when defined(Windows): - if ": " in line: - line.split(": ", maxsplit = 1)[1] - else: - "" - else: - line - if f.len != 0: - result.add f - -proc findFile*(file: string, dir: string, recurse = true, first = false, regex = false): string = - ## Find the file in the specified directory - ## - ## `file` is a regular expression if `regex` is true - ## - ## Turn off recursive search with `recurse` and stop on first match with - ## `first`. Without it, the shortest match is returned. - let - matches = findFiles(file, dir, recurse, regex) - for match in matches: - if (result.len == 0 or result.len > match.len): - result = match - if first: break - -proc flagBuild*(base: string, flags: openArray[string]): string = - ## Simple helper proc to generate flags for `configure`, `cmake`, etc. - ## - ## Every entry in `flags` is replaced into the `base` string and - ## concatenated to the result. - ## - ## E.g. - ## `base = "--disable-$#"` - ## `flags = @["one", "two"]` - ## - ## `flagBuild(base, flags) => " --disable-one --disable-two"` - for i in flags: - result &= " " & base % i - -proc linkLibs*(names: openArray[string], staticLink = true): string = - ## Create linker flags for specified libraries - ## - ## Prepends `lib` to the name so you only need `ssl` for `libssl`. - var - stat = if staticLink: "--static" else: "" - resSet: OrderedSet[string] - resSet.init() - - for name in names: - let - cmd = &"pkg-config --libs --silence-errors {stat} lib{name}" - (libs, _) = execAction(cmd, die = false) - for lib in libs.split(" "): - resSet.incl lib - - if staticLink: - resSet.incl "--static" - - for res in resSet: - result &= " " & res - -proc configure*(path, check: string, flags = "") = - ## Run the GNU `configure` command to generate all Makefiles or other - ## build scripts in the specified path - ## - ## If a `configure` script is not present and an `autogen.sh` script - ## is present, it will be run before attempting `configure`. - ## - ## Next, if `configure.ac` or `configure.in` exist, `autoreconf` will - ## be executed. - ## - ## `check` is a file that will be generated by the `configure` command. - ## This is required to prevent configure from running on every build. It - ## is relative to the `path` and should not be an absolute path. - ## - ## `flags` are any flags that should be passed to the `configure` command. - if (path / check).fileExists(): - return - - echo "# Configuring " & path - - if not fileExists(path / "configure"): - for i in @["autogen.sh", "build" / "autogen.sh"]: - if fileExists(path / i): - echo "# Running autogen.sh" - - when defined(unix): - echoDebug execAction( - &"cd {(path / i).parentDir().sanitizePath} && ./autogen.sh").output - else: - echoDebug execAction( - &"cd {(path / i).parentDir().sanitizePath} && bash ./autogen.sh").output - - break - - if not fileExists(path / "configure"): - for i in @["configure.ac", "configure.in"]: - if fileExists(path / i): - echo "# Running autoreconf" - - echoDebug execAction(&"cd {path.sanitizePath} && autoreconf -fi").output - - break - - if fileExists(path / "configure"): - echo "# Running configure " & flags - - when defined(unix): - var - cmd = &"cd {path.sanitizePath} && ./configure" - else: - var - cmd = &"cd {path.sanitizePath} && bash ./configure" - if flags.len != 0: - cmd &= &" {flags}" - - echoDebug execAction(cmd).output - - doAssert (path / check).fileExists(), "Configure failed" - -proc getCmakePropertyStr(name, property, value: string): string = - &"\nset_target_properties({name} PROPERTIES {property} \"{value}\")\n" - -proc getCmakeIncludePath*(paths: openArray[string]): string = - ## Create a `cmake` flag to specify custom include paths - ## - ## Result can be included in the `flag` parameter for `cmake()` or - ## the `cmakeFlags` parameter for `getHeader()`. - for path in paths: - result &= path & ";" - result = " -DCMAKE_INCLUDE_PATH=" & result[0 .. ^2].sanitizePath(sep = "/") - -proc setCmakeProperty*(outdir, name, property, value: string) = - ## Set a `cmake` property in `outdir / CMakeLists.txt` - usable in the `xxxPreBuild` hook - ## for `getHeader()` - ## - ## `set_target_properties(name PROPERTIES property "value")` - let - cm = outdir / "CMakeLists.txt" - if cm.fileExists(): - cm.writeFile( - cm.readFile() & getCmakePropertyStr(name, property, value) - ) - -proc setCmakeLibName*(outdir, name, prefix = "", oname = "", suffix = "") = - ## Set a `cmake` property in `outdir / CMakeLists.txt` to specify a custom library output - ## name - usable in the `xxxPreBuild` hook for `getHeader()` - ## - ## `prefix` is typically `lib` - ## `oname` is the library name - ## `suffix` is typically `.a` - ## - ## Sometimes, `cmake` generates non-standard library names - e.g. zlib compiles to - ## `libzlibstatic.a` on Windows. This proc can help rename it to `libzlib.a` so that `getHeader()` - ## can find it after the library is compiled. - ## - ## ``` - ## set_target_properties(name PROPERTIES PREFIX "prefix") - ## set_target_properties(name PROPERTIES OUTPUT_NAME "oname") - ## set_target_properties(name PROPERTIES SUFFIX "suffix") - ## ``` - let - cm = outdir / "CMakeLists.txt" - if cm.fileExists(): - var - str = "" - if prefix.len != 0: - str &= getCmakePropertyStr(name, "PREFIX", prefix) - if oname.len != 0: - str &= getCmakePropertyStr(name, "OUTPUT_NAME", oname) - if suffix.len != 0: - str &= getCmakePropertyStr(name, "SUFFIX", suffix) - if str.len != 0: - cm.writeFile(cm.readFile() & str) - -proc setCmakePositionIndependentCode*(outdir: string) = - ## Set a `cmake` directive to create libraries with -fPIC enabled - let - cm = outdir / "CMakeLists.txt" - if cm.fileExists(): - let - pic = "set(CMAKE_POSITION_INDEPENDENT_CODE ON)" - cmd = cm.readFile() - if not cmd.contains(pic): - cm.writeFile( - pic & "\n" & cmd - ) - -proc cmake*(path, check, flags: string) = - ## Run the `cmake` command to generate all Makefiles or other - ## build scripts in the specified path - ## - ## `path` will be created since typically `cmake` is run in an - ## empty directory. - ## - ## `check` is a file that will be generated by the `cmake` command. - ## This is required to prevent `cmake` from running on every build. It - ## is relative to the `path` and should not be an absolute path. - ## - ## `flags` are any flags that should be passed to the `cmake` command. - ## Unlike `configure`, it is required since typically it will be the - ## path to the repository, typically `..` when `path` is a subdir. - if (path / check).fileExists(): - return - - echo "# Running cmake " & flags - echo "# Path: " & path - - mkDir(path) - - let - cmd = &"cd {path.sanitizePath} && cmake {flags}" - - echoDebug execAction(cmd).output - - doAssert (path / check).fileExists(), "cmake failed" - -proc make*(path, check: string, flags = "", regex = false) = - ## Run the `make` command to build all binaries in the specified path - ## - ## `check` is a file that will be generated by the `make` command. - ## This is required to prevent `make` from running on every build. It - ## is relative to the `path` and should not be an absolute path. - ## - ## `flags` are any flags that should be passed to the `make` command. - ## - ## `regex` can be set to true if `check` is a regular expression. - ## - ## If `make.exe` is missing and `mingw32-make.exe` is available, it will - ## be copied over to make.exe in the same location. - if findFile(check, path, regex = regex).len != 0: - return - - echo "# Running make " & flags - echo "# Path: " & path - - var - cmd = findExe("make") - - if cmd.len == 0: - cmd = findExe("mingw32-make") - if cmd.len != 0: - cpFile(cmd, cmd.replace("mingw32-make", "make")) - doAssert cmd.len != 0, "Make not found" - - cmd = &"cd {path.sanitizePath} && make" - if flags.len != 0: - cmd &= &" {flags}" - - echoDebug execAction(cmd).output - - doAssert findFile(check, path, regex = regex).len != 0, "make failed" - -proc getCompilerMode*(path: string): string = - ## Determines a target language mode from an input filename, if one is not already specified. - let file = path.splitFile() - if file.ext in [".hxx", ".hpp", ".hh", ".H", ".h++", ".cpp", ".cxx", ".cc", ".C", ".c++"]: - result = "cpp" - elif file.ext in [".h", ".c"]: - result = "c" - -proc getGccModeArg*(mode: string): string = - ## Produces a GCC argument that explicitly sets the language mode to be used by the compiler. - if mode == "cpp": - result = "-xc++" - elif mode == "c": - result = "-xc" - -proc getCompiler*(): string = - var - compiler = - when defined(gcc): - "gcc" - elif defined(clang): - "clang" - else: - doAssert false, "Nimterop only supports gcc and clang at this time" - - result = getEnv("CC", compiler) - -proc getGccPaths*(mode: string): seq[string] = - var - nul = when defined(Windows): "nul" else: "/dev/null" - inc = false - - (outp, _) = execAction(&"""{getCompiler()} -Wp,-v {getGccModeArg(mode)} {nul}""", die = false) - - for line in outp.splitLines(): - if "#include <...> search starts here" in line: - inc = true - continue - elif "End of search list" in line: - break - if inc: - var - path = line.strip().normalizedPath() - if path notin result: - result.add path - - when defined(osx): - result.add(execAction("xcrun --show-sdk-path").output.strip() & "/usr/include") - -proc getGccLibPaths*(mode: string): seq[string] = - var - nul = when defined(Windows): "nul" else: "/dev/null" - linker = when defined(OSX): "-Xlinker" else: "" - - (outp, _) = execAction(&"""{getCompiler()} {linker} -v {getGccModeArg(mode)} {nul}""", die = false) - - for line in outp.splitLines(): - if "LIBRARY_PATH=" in line: - for path in line[13 .. ^1].split(PathSep): - var - path = path.strip().normalizedPath() - if path notin result: - result.add path - break - elif '\t' in line: - var - path = line.strip().normalizedPath() - if path notin result: - result.add path - - when defined(osx): - result.add "/usr/lib" - -proc getGccInfo*(): tuple[arch, os, compiler, version: string] = - let - (outp, _) = execAction(&"{getCompiler()} -v") - for line in outp.splitLines(): - if line.startsWith("Target: "): - result.arch = line.split(' ')[1].split('-')[0] - result.os = - if "linux" in line: - "linux" - elif "android" in line: - "android" - elif "darwin" in line: - "macos" - elif "w64" in line or "mingw" in line: - "windows" - else: - "unknown" - elif " version " in line: - result.version = line.split(" version ")[1].split(' ')[0] - if "clang" in outp: - if result.os == "macos": - result.compiler = "apple-clang" - else: - result.compiler = "clang" - else: - result.compiler = "gcc" - template fixOutDir() {.dirty.} = let outdir = if outdir.isAbsolute(): outdir else: getProjectDir() / outdir @@ -881,565 +60,74 @@ proc compareVersions*(ver1, ver2: string): int = if p1 < p2: return -1 elif p1 > p2: return 1 -# Conan support -include conan - -# Julia Binary Builder support -include jbb - -proc getStdPath(header, mode: string): string = - for inc in getGccPaths(mode): - result = findFile(header, inc, recurse = false, first = true) - if result.len != 0: - break - -proc getStdLibPath(lname, mode: string): string = - for lib in getGccLibPaths(mode): - result = findFile(lname, lib, recurse = false, first = true, regex = true) - if result.len != 0: - break - -proc getGitPath(header, url, outdir, version: string): string = - doAssert url.len != 0, "No git url setup for " & header - doAssert findExe("git").len != 0, "git executable missing" - - gitPull(url, outdir, checkout = version) - - result = findFile(header, outdir) - -proc getDlPath(header, url, outdir, version: string): string = - doAssert url.len != 0, "No download url setup for " & header - - var - dlurl = url - if "$#" in url or "$1" in url: - doAssert version.len != 0, "Need version for download url" - dlurl = url % version - else: - doAssert version.len == 0, "Download url does not contain version" - - downloadUrl(dlurl, outdir) - - var - dirname = "" - for kind, path in walkDir(outdir, relative = true): - if kind == pcFile and path != dlurl.extractFilename(): - dirname = "" - break - elif kind == pcDir: - if dirname.len == 0: - dirname = path - else: - dirname = "" - break - - if dirname.len != 0: - for kind, path in walkDir(outdir / dirname, relative = true): - mvFile(outdir / dirname / path, outdir / path) - - result = findFile(header, outdir) - -proc getConanPath(header, uri, outdir, version: string, shared: bool): string = - var - uri = uri - - if "$#" in uri or "$1" in uri: - doAssert version.len != 0, "Need version for Conan.io uri: " & uri - uri = uri % version - elif version.len != 0: - uri = uri & "/" & version - - let - pkg = newConanPackageFromUri(uri, shared) - downloadConan(pkg, outdir) - - result = findFile(header, outdir) - -proc getConanLDeps(outdir: string): seq[string] = - let - pkg = loadConanInfo(outdir) - - result = pkg.getConanLDeps(outdir) - -proc getJBBPath(header, uri, outdir, version: string): string = - let - spl = uri.split('/', 1) - name = spl[0] - hasVersion = version.len != 0 - - var - ver = - if spl.len == 2: - spl[1] - else: - "" - - if ver.len != 0: - if "$#" in ver or "$1" in ver: - doAssert hasVersion, "Need version for BinaryBuilder.org uri: " & uri - ver = ver % version - elif hasVersion: - doAssert false, "Version in both uri `" & uri & "` and `-d:xxxSetVer=\"" & - version & "\"` for BinaryBuilder.org" - elif hasVersion: - ver = version - - let - pkg = newJBBPackage(name, ver) - downloadJBB(pkg, outdir) - - result = findFile(header, outdir) - -proc getJBBLDeps(outdir: string, shared: bool): seq[string] = - let - pkg = loadJBBInfo(outdir) - - result = pkg.getJBBLDeps(outdir, shared) - -proc getLocalPath(header, outdir: string): string = - if outdir.len != 0: - result = findFile(header, outdir) - -proc getNumProcs(): string = +proc fixCmd(cmd: string): string = when defined(Windows): - getEnv("NUMBER_OF_PROCESSORS").strip() - elif defined(linux): - execAction("nproc").output.strip() - elif defined(macosx) or defined(FreeBSD): - execAction("sysctl -n hw.ncpu").output.strip() + # Replace 'cd d:\abc' with 'd: && cd d:\abc` + var filteredCmd = cmd + if cmd.toLower().startsWith("cd"): + var + colonIndex = cmd.find(":") + driveLetter = cmd.substr(colonIndex-1, colonIndex) + if (driveLetter[0].isAlphaAscii() and + driveLetter[1] == ':' and + colonIndex == 4): + filteredCmd = &"{driveLetter} && {cmd}" + result = "cmd /c " & filteredCmd + elif defined(posix): + result = cmd else: - "1" + doAssert false -proc buildWithCmake(outdir, flags: string): BuildStatus = - if not fileExists(outdir / "Makefile"): - if fileExists(outdir / "CMakeLists.txt"): - if findExe("cmake").len != 0: - var - gen = "" - when defined(Windows): - if findExe("sh").len != 0: - let - uname = execAction("sh -c uname -a").output.toLowerAscii() - if uname.contains("msys"): - gen = "MSYS Makefiles".quoteShell - elif uname.contains("mingw"): - gen = "MinGW Makefiles".quoteShell & " -DCMAKE_SH=\"CMAKE_SH-NOTFOUND\"" - else: - echo "Unsupported system: " & uname - else: - gen = "MinGW Makefiles".quoteShell - else: - gen = "Unix Makefiles".quoteShell - if findExe("ccache").len != 0: - gen &= " -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache" - result.buildPath = outdir / "buildcache" - cmake(result.buildPath, "Makefile", &".. -G {gen} {flags}") - result.built = true - else: - result.error = "cmake capable but cmake executable missing" - else: - result.buildPath = outdir +# Nim cfg file related functionality +include "."/build/nimconf -proc buildWithAutoConf(outdir, flags: string): BuildStatus = - if not fileExists(outdir / "Makefile"): - if findExe("bash").len != 0: - for file in @["configure", "configure.ac", "configure.in", "autogen.sh", "build/autogen.sh"]: - if fileExists(outdir / file): - configure(outdir, "Makefile", flags) - result.buildPath = outdir - result.built = true - break - else: - result.error = "configure capable but bash executable missing" - else: - result.buildPath = outdir +proc getNimteropCacheDir(): string = + # Get location to cache all nimterop artifacts + result = getNimcacheDir() / "nimterop" -proc buildLibrary(lname, outdir, conFlags, cmakeFlags, makeFlags: string, buildTypes: openArray[BuildType]): string = - var - lpath = findFile(lname, outdir, regex = true) - makeFlagsProc = &"-j {getNumProcs()} {makeFlags}" - makePath = outdir +# Functionality shelled out to external executables +include "."/build/shell - if lpath.len != 0: - return lpath - - var buildStatus: BuildStatus - - for buildType in buildTypes: - case buildType - of btCmake: - buildStatus = buildWithCmake(makePath, cmakeFlags) - of btAutoconf: - buildStatus = buildWithAutoConf(makePath, conFlags) - - if buildStatus.built: - break - - if buildStatus.buildPath.len > 0: - let libraryExists = findFile(lname, buildStatus.buildPath, regex = true).len > 0 - - if not libraryExists and fileExists(buildStatus.buildPath / "Makefile"): - make(buildStatus.buildPath, lname, makeFlagsProc, regex = true) - buildStatus.built = true - - let error = if buildStatus.error.len > 0: buildStatus.error else: "No build files found in " & outdir - doAssert buildStatus.built, &"\nBuild configuration failed - {error}\n" - - result = findFile(lname, outdir, regex = true) - -proc getDynlibExt(): string = - when defined(Windows): - result = "[0-9.\\-]*\\.dll" - elif defined(linux) or defined(FreeBSD): - result = "\\.so[0-9.]*" - elif defined(macosx): - result = "[0-9.\\-]*\\.dylib" - -var - gDefines {.compileTime.} = initTable[string, string]() - -macro setDefines*(defs: static openArray[string]): untyped = - ## Specify `-d:xxx` values in code instead of having to rely on the command - ## line or `cfg` or `nims` files. +proc getProjectCacheDir*(name: string, forceClean = true): string = + ## Get a cache directory where all nimterop artifacts can be stored ## - ## At this time, Nim does not allow creation of `-d:xxx` defines in code. In - ## addition, Nim only loads config files for the module being compiled but not - ## for imported packages. This becomes a challenge when wanting to ship a wrapper - ## library that wants to control `getHeader()` for an underlying package. + ## Projects can use this location to download source code and build binaries + ## that can be then accessed by multiple apps. This is created under the + ## per-user Nim cache directory. ## - ## E.g. nimarchive wanting to set `-d:lzmaStatic` + ## Use `name` to specify the subdirectory name for a project. ## - ## The consumer of nimarchive would need to set such defines as part of their - ## project, making it inconvenient. + ## `forceClean` is enabled by default and effectively deletes the folder + ## if Nim is compiled with the `-f` or `--forceBuild` flag. This allows + ## any project to start out with a clean cache dir on a forced build. ## - ## By calling this proc with the defines preferred before importing such a module, - ## the caller can set the behavior in code instead. + ## NOTE: avoid calling `getProjectCacheDir()` multiple times on the same + ## `name` when `forceClean = true` else checked out source might get deleted + ## at the wrong time during build. ## - ## .. code-block:: nim + ## E.g. + ## `nimgit2` downloads `libgit2` source so `name = "libgit2"` ## - ## setDefines(@["lzmaStatic", "lzmaDL", "lzmaSetVer=5.2.4"]) - ## - ## import lzma - for def in defs: - let - nv = def.strip().split("=", maxsplit = 1) - if nv.len != 0: - let - n = nv[0] - v = - if nv.len == 2: - nv[1] - else: - "" - gDefines[n] = v + ## `nimarchive` downloads `libarchive`, `bzlib`, `liblzma` and `zlib` so + ## `name = "nimarchive" / "libarchive"` for `libarchive`, etc. + result = getNimteropCacheDir() / name -macro clearDefines*(): untyped = - ## Clear all defines set using `setDefines()`. - gDefines.clear() + if forceClean and compileOption("forceBuild"): + echo "# Removing " & result + rmDir(result) -macro isDefined*(def: untyped): untyped = - ## Check if `-d:xxx` is set globally or via `setDefines()` - let - sdef = gDefines.hasKey(def.strVal()) - result = newNimNode(nnkStmtList) - result.add(quote do: - when defined(`def`) or `sdef` != 0: - true - else: - false - ) +# C compiler support +include "."/build/ccompiler -macro getHeader*( - header: static[string], giturl: static[string] = "", dlurl: static[string] = "", - conanuri: static[string] = "", jbburi: static[string] = "", - outdir: static[string] = "", libdir: static[string] = "", - conFlags: static[string] = "", cmakeFlags: static[string] = "", makeFlags: static[string] = "", - altNames: static[string] = "", buildTypes: static[openArray[BuildType]] = [btCmake, btAutoconf]): untyped = - ## Get the path to a header file for wrapping with - ## `cImport() `_ or - ## `c2nImport() `_. - ## - ## This proc checks `-d:xxx` defines based on the header name (e.g. lzma from lzma.h), - ## and accordingly employs different ways to obtain the source. - ## - ## `-d:xxxStd` - search standard system paths. E.g. `/usr/include` and `/usr/lib` on Linux - ## `-d:xxxGit` - clone source from a git repo specified in `giturl` - ## `-d:xxxDL` - download source from `dlurl` and extract if required - ## `-d:xxxConan` - download headers and binary from Conan.io using `conanuri` with - ## format `pkgname[/version[@user/channel][:bhash]]` - ## `-d:xxxJBB` - download headers and binary from BinaryBuilder.org using `jbburi` with - ## format `pkgname[/version]` - ## - ## This allows a single wrapper to be used in different ways depending on the user's needs. - ## If no `-d:xxx` defines are specified, `outdir` will be searched for the header as is. - ## The user can opt to download the sources to `outdir` using any other method such as - ## git sub-modules, vendoring or pointing to a repository that was already cloned. - ## - ## If multiple `-d:xxx` defines are specified, precedence is `Std` and then `Git`, `DL`, - ## `Conan` or `JBB`. This allows using a system installed library if available before - ## falling back to manual building. The user would need to specify both `-d:xxxStd` and - ## one of the other methods. - ## - ## `-d:xxxSetVer=x.y.z` can be used to specify which version to use. It is used as a tag - ## name for `Git` whereas for `DL`, `Conan` and `JBB`, it replaces `$1` in the URL - ## if specified. Specifying `-d:xxxSetVer` without a `$1` will download that version for - ## `Conan` and `JBB` if available. If no version is specified, the latest release of the - ## package is downloaded. For `Conan`, `-d:xxxSetVer` can also be used to set additional - ## URI information: - ## `-d:xxxSetVer=1.9.0@bincrafters/stable:bhash` - ## - ## If `conanuri` or `jbburi` are not defined and `Conan` or `JBB` is selected, the `header` - ## filename is used instead. - ## - ## All defines can also be set in code using `setDefines()` and checked for using - ## `isDefined()` which checks for defines set from both `-d` and `setDefines()`. - ## - ## The library is then configured (with `cmake` or `autotools` if possible) and built - ## using `make`, unless using `-d:xxxStd` which presumes that the system package - ## manager was used to install prebuilt headers and binaries, or using `-d:xxxConan` - ## or `-d:xxxJBB` which download pre-built binaries. - ## - ## The header path is stored in `const xxxPath` and can be used in a `cImport()` call - ## in the calling wrapper. The dynamic library path is stored in `const xxxLPath` and can - ## be used for the `dynlib` parameter (within quotes) or with `{.passL.}`. Any dependency - ## libraries downloaded by `Conan` or `JBB` are returned in `const xxxLDeps` as a seq[string]. - ## - ## `libdir` can be used to instruct `getHeader()` to copy shared libraries and their - ## dependencies to that directory. This prevents any runtime failures if `outdir` gets - ## removed or its contents changed. By default, `libdir` is set to the output directory - ## where the program binary will be created. The values of `xxxLPath` and `xxxLDeps` will - ## reflect this new location. `libdir` is ignored for `Std` mode. - ## - ## `-d:xxxStatic` can be specified to statically link with the library instead. This - ## will automatically add a `{.passL.}` call to the static library for convenience. Note - ## that `-d:xxxConan` and `-d:xxxJBB` download all dependency libs as well and the - ## `xxxLPath` will include paths to all of them separated by space in the right order for - ## linking. - ## - ## Note also that Conan currently builds all OSX binaries on 10.14 so older versions of - ## OSX will complain if statically linking to these binaries. Further, all Conan binaries - ## for Windows are built with Visual Studio so static linking the `.lib` files with gcc - ## or clang might lead to incompatibility issues if the library uses Visual Studio - ## specific compiler features. - ## - ## `conFlags`, `cmakeFlags` and `makeFlags` allow sending custom parameters to `configure`, - ## `cmake` and `make` in case additional configuration is required as part of the build - ## process. - ## - ## `altNames` is a list of alternate names for the library - e.g. zlib uses `zlib.h` for - ## the header but the typical lib name is `libz.so` and not `libzlib.so`. However, it is - ## libzlib.dll on Windows if built with cmake. In this case, `altNames = "z,zlib"`. Comma - ## separate for multiple alternate names without spaces. - ## - ## The original header name is not included by default if `altNames` is set since it could - ## cause the wrong lib to be selected. E.g. `SDL2/SDL.h` could pick `libSDL.so` even if - ## `altNames = "SDL2"`. Explicitly include it in `altNames` like the `zlib` example when - ## required. - ## - ## `buildTypes` specifies a list of ordered build strategies to use when building the - ## downloaded source files. Default is [btCmake, btAutoconf] - ## - ## `xxxPreBuild` is a hook that is called after the source code is pulled from Git or - ## downloaded but before the library is built. This might be needed if some initial prep - ## needs to be done before compilation. A few values are provided to the hook to help - ## provide context: - ## - ## `outdir` is the same `outdir` passed in and `header` is the discovered header path - ## in the downloaded source code. - ## - ## Simply define `proc xxxPreBuild(outdir, header: string)` in the wrapper and it will get - ## called prior to the build process. - var - origname = header.extractFilename().split(".")[0] - name = origname.split(seps = AllChars-Letters-Digits).join() +when not defined(TOAST): + # configure, cmake, make support + include "."/build/tools - # Default to origname if not specified - conanuri = if conanuri.len != 0: conanuri else: origname - jbburi = if jbburi.len != 0: jbburi else: origname + # Conan.io support + include "."/build/conan - # -d:xxx for this header - stdStr = name & "Std" - gitStr = name & "Git" - dlStr = name & "DL" - conanStr = name & "Conan" - jbbStr = name & "JBB" + # Julia BinaryBuilder.org support + include "."/build/jbb - staticStr = name & "Static" - verStr = name & "SetVer" - - # Ident nodes of the -d:xxx to check in when statements - nameStd = newIdentNode(stdStr) - nameGit = newIdentNode(gitStr) - nameDL = newIdentNode(dlStr) - nameConan = newIdentNode(conanStr) - nameJBB = newIdentNode(jbbStr) - - nameStatic = newIdentNode(staticStr) - - # Consts to generate - path = newIdentNode(name & "Path") - lpath = newIdentNode(name & "LPath") - ldeps = newIdentNode(name & "LDeps") - version = newIdentNode(verStr) - lname = newIdentNode(name & "LName") - preBuild = newIdentNode(name & "PreBuild") - - # Regex for library search - lre = "(lib)?$1[_-]?(static)?" - - # If -d:xxx set with setDefines() - stdVal = gDefines.hasKey(stdStr) - gitVal = gDefines.hasKey(gitStr) - dlVal = gDefines.hasKey(dlStr) - conanVal = gDefines.hasKey(conanStr) - jbbVal = gDefines.hasKey(jbbStr) - staticVal = gDefines.hasKey(staticStr) - verVal = - if gDefines.hasKey(verStr): - gDefines[verStr] - else: - "" - mode = getCompilerMode(header) - - libdir = if libdir.len != 0: libdir else: getOutDir() - - # Use alternate library names if specified for regex search - if altNames.len != 0: - lre = lre % ("(" & altNames.replace(",", "|") & ")") - else: - lre = lre % origname - - result = newNimNode(nnkStmtList) - result.add(quote do: - # Need to check -d:xxx or setDefines() - const - `nameStd`* = when defined(`nameStd`): true else: `stdVal` == 1 - `nameGit`* = when defined(`nameGit`): true else: `gitVal` == 1 - `nameDL`* = when defined(`nameDL`): true else: `dlVal` == 1 - `nameConan`* = when defined(`nameConan`): true else: `conanVal` == 1 - `nameJBB`* = when defined(`nameJBB`): true else: `jbbVal` == 1 - `nameStatic`* = when defined(`nameStatic`): true else: `staticVal` == 1 - - # Search for header in outdir (after retrieving code) depending on -d:xxx mode - proc getPath(header, giturl, dlurl, conanuri, jbburi, outdir, version: string, shared: bool): string = - when `nameGit`: - getGitPath(header, giturl, outdir, version) - elif `nameDL`: - getDlPath(header, dlurl, outdir, version) - elif `nameConan`: - getConanPath(header, conanuri, outdir, version, shared) - elif `nameJBB`: - getJBBPath(header, jbburi, outdir, version) - else: - getLocalPath(header, outdir) - - const - `version`* {.strdefine.} = `verVal` - `lname` = - when `nameStatic`: - `lre` & "\\.(a|lib)" - else: - `lre` & getDynlibExt() - - # Look in standard path if requested by user - stdPath = - when `nameStd`: getStdPath(`header`, `mode`) else: "" - stdLPath = - when `nameStd`: getStdLibPath(`lname`, `mode`) else: "" - - useStd = stdPath.len != 0 and stdLPath.len != 0 - - # Look elsewhere if requested while prioritizing standard paths - prePath = - when useStd: - stdPath - else: - getPath(`header`, `giturl`, `dlurl`, `conanuri`, `jbburi`, `outdir`, `version`, not `nameStatic`) - - # Run preBuild hook before building library if not Std, Conan or JBB - when not (useStd or `nameConan` or `nameJBB`) and declared(`preBuild`): - static: - `preBuild`(`outdir`, prePath) - - let - # Library binary path - build if not standard / conan / jbb - lpath {.compileTime.} = - when useStd: - stdLPath - elif `nameConan` or `nameJBB`: - findFile(`lname`, `outdir`, regex = true) - else: - buildLibrary(`lname`, `outdir`, `conFlags`, `cmakeFlags`, `makeFlags`, `buildTypes`) - - # Library dependecy paths - ldeps {.compileTime.}: seq[string] = - when not useStd: - when `nameConan`: - getConanLDeps(`outdir`) - elif `nameJBB`: - getJBBLDeps(`outdir`, not `nameStatic`) - else: - @[] - else: - @[] - - const - # Header path - search again in case header is generated in build - `path`* = - if prePath.len != 0: - prePath - else: - getPath(`header`, `giturl`, `dlurl`, `conanuri`, `jbburi`, `outdir`, `version`, not `nameStatic`) - - static: - doAssert `path`.len != 0, "\nHeader " & `header` & " not found - " & - "missing/empty outdir or -d:$1Std -d:$1Git -d:$1DL -d:$1Conan or -d:$1JBB not specified" % `name` - doAssert lpath.len != 0, "\nLibrary " & `lname` & " not found" - - when `nameStatic`: - const - `lpath`* = lpath - `ldeps`* = ldeps - - # Automatically link with static library and dependencies - {.passL: `lpath`.} - if `ldeps`.len != 0: - {.passL: `ldeps`.join(" ").} - - static: - echo "# Including library " & lpath - if `ldeps`.len != 0: - echo "# Including dependencies " & `ldeps`.join(" ") - else: - const - `lpath`* = when not useStd: `libdir` / lpath.extractFilename() else: lpath - `ldeps`* = - when not useStd: - block: - var - ldeps = ldeps - copied: seq[string] - for i in 0 ..< ldeps.len: - let - lname = ldeps[i].extractFilename() - ldeptgt = `libdir` / lname - if not fileExists(ldeptgt) or getFileDate(ldeps[i]) != getFileDate(ldeptgt): - cpFile(ldeps[i], ldeptgt, psymlink = true) - copied.add lname - ldeps[i] = ldeptgt - # Copy downloaded dependencies to `libdir` - if copied.len != 0: - echo "# Copying dependencies: " & copied.join(" ") & "\n# to " & `libdir` - ldeps - else: - ldeps - - static: - when not useStd: - # Copy downloaded shared libraries to `libdir` - if not fileExists(`lpath`) or getFileDate(lpath) != getFileDate(`lpath`): - echo "# Copying " & `lpath`.extractFilename() & " to " & `libdir` - cpFile(lpath, `lpath`) - - echo "# Including library " & `lpath` - ) + # getHeader support + include "."/build/getheader diff --git a/nimterop/build/ccompiler.nim b/nimterop/build/ccompiler.nim new file mode 100644 index 0000000..c33c94a --- /dev/null +++ b/nimterop/build/ccompiler.nim @@ -0,0 +1,101 @@ +import os, strformat, strutils + +proc getCompilerMode*(path: string): string = + ## Determines a target language mode from an input filename, if one is not already specified. + let file = path.splitFile() + if file.ext in [".hxx", ".hpp", ".hh", ".H", ".h++", ".cpp", ".cxx", ".cc", ".C", ".c++"]: + result = "cpp" + elif file.ext in [".h", ".c"]: + result = "c" + +proc getGccModeArg*(mode: string): string = + ## Produces a GCC argument that explicitly sets the language mode to be used by the compiler. + if mode == "cpp": + result = "-xc++" + elif mode == "c": + result = "-xc" + +proc getCompiler*(): string = + var + compiler = + when defined(gcc): + "gcc" + elif defined(clang): + "clang" + else: + doAssert false, "Nimterop only supports gcc and clang at this time" + + result = getEnv("CC", compiler) + +proc getGccPaths*(mode: string): seq[string] = + var + nul = when defined(Windows): "nul" else: "/dev/null" + inc = false + + (outp, _) = execAction(&"""{getCompiler()} -Wp,-v {getGccModeArg(mode)} {nul}""", die = false) + + for line in outp.splitLines(): + if "#include <...> search starts here" in line: + inc = true + continue + elif "End of search list" in line: + break + if inc: + var + path = line.strip().normalizedPath() + if path notin result: + result.add path + + when defined(osx): + result.add(execAction("xcrun --show-sdk-path").output.strip() & "/usr/include") + +proc getGccLibPaths*(mode: string): seq[string] = + var + nul = when defined(Windows): "nul" else: "/dev/null" + linker = when defined(OSX): "-Xlinker" else: "" + + (outp, _) = execAction(&"""{getCompiler()} {linker} -v {getGccModeArg(mode)} {nul}""", die = false) + + for line in outp.splitLines(): + if "LIBRARY_PATH=" in line: + for path in line[13 .. ^1].split(PathSep): + var + path = path.strip().normalizedPath() + if path notin result: + result.add path + break + elif '\t' in line: + var + path = line.strip().normalizedPath() + if path notin result: + result.add path + + when defined(osx): + result.add "/usr/lib" + +proc getGccInfo*(): tuple[arch, os, compiler, version: string] = + let + (outp, _) = execAction(&"{getCompiler()} -v") + for line in outp.splitLines(): + if line.startsWith("Target: "): + result.arch = line.split(' ')[1].split('-')[0] + result.os = + if "linux" in line: + "linux" + elif "android" in line: + "android" + elif "darwin" in line: + "macos" + elif "w64" in line or "mingw" in line: + "windows" + else: + "unknown" + elif " version " in line: + result.version = line.split(" version ")[1].split(' ')[0] + if "clang" in outp: + if result.os == "macos": + result.compiler = "apple-clang" + else: + result.compiler = "clang" + else: + result.compiler = "gcc" diff --git a/nimterop/conan.nim b/nimterop/build/conan.nim similarity index 100% rename from nimterop/conan.nim rename to nimterop/build/conan.nim diff --git a/nimterop/build/getheader.nim b/nimterop/build/getheader.nim new file mode 100644 index 0000000..3852fbf --- /dev/null +++ b/nimterop/build/getheader.nim @@ -0,0 +1,504 @@ +import macros, os, strutils, tables + +var + gDefines {.compileTime.} = initTable[string, string]() + +macro setDefines*(defs: static openArray[string]): untyped = + ## Specify `-d:xxx` values in code instead of having to rely on the command + ## line or `cfg` or `nims` files. + ## + ## At this time, Nim does not allow creation of `-d:xxx` defines in code. In + ## addition, Nim only loads config files for the module being compiled but not + ## for imported packages. This becomes a challenge when wanting to ship a wrapper + ## library that wants to control `getHeader()` for an underlying package. + ## + ## E.g. nimarchive wanting to set `-d:lzmaStatic` + ## + ## The consumer of nimarchive would need to set such defines as part of their + ## project, making it inconvenient. + ## + ## By calling this proc with the defines preferred before importing such a module, + ## the caller can set the behavior in code instead. + ## + ## .. code-block:: nim + ## + ## setDefines(@["lzmaStatic", "lzmaDL", "lzmaSetVer=5.2.4"]) + ## + ## import lzma + for def in defs: + let + nv = def.strip().split("=", maxsplit = 1) + if nv.len != 0: + let + n = nv[0] + v = + if nv.len == 2: + nv[1] + else: + "" + gDefines[n] = v + +macro clearDefines*(): untyped = + ## Clear all defines set using `setDefines()`. + gDefines.clear() + +macro isDefined*(def: untyped): untyped = + ## Check if `-d:xxx` is set globally or via `setDefines()` + let + sdef = gDefines.hasKey(def.strVal()) + result = newNimNode(nnkStmtList) + result.add(quote do: + when defined(`def`) or `sdef` != 0: + true + else: + false + ) + +proc getDynlibExt(): string = + when defined(Windows): + result = "[0-9.\\-]*\\.dll" + elif defined(linux) or defined(FreeBSD): + result = "\\.so[0-9.]*" + elif defined(macosx): + result = "[0-9.\\-]*\\.dylib" + +proc getStdPath(header, mode: string): string = + for inc in getGccPaths(mode): + result = findFile(header, inc, recurse = false, first = true) + if result.len != 0: + break + +proc getStdLibPath(lname, mode: string): string = + for lib in getGccLibPaths(mode): + result = findFile(lname, lib, recurse = false, first = true, regex = true) + if result.len != 0: + break + +proc getGitPath(header, url, outdir, version: string): string = + doAssert url.len != 0, "No git url setup for " & header + doAssert findExe("git").len != 0, "git executable missing" + + gitPull(url, outdir, checkout = version) + + result = findFile(header, outdir) + +proc getDlPath(header, url, outdir, version: string): string = + doAssert url.len != 0, "No download url setup for " & header + + var + dlurl = url + if "$#" in url or "$1" in url: + doAssert version.len != 0, "Need version for download url" + dlurl = url % version + else: + doAssert version.len == 0, "Download url does not contain version" + + downloadUrl(dlurl, outdir) + + var + dirname = "" + for kind, path in walkDir(outdir, relative = true): + if kind == pcFile and path != dlurl.extractFilename(): + dirname = "" + break + elif kind == pcDir: + if dirname.len == 0: + dirname = path + else: + dirname = "" + break + + if dirname.len != 0: + for kind, path in walkDir(outdir / dirname, relative = true): + mvFile(outdir / dirname / path, outdir / path) + + result = findFile(header, outdir) + +proc getConanPath(header, uri, outdir, version: string, shared: bool): string = + var + uri = uri + + if "$#" in uri or "$1" in uri: + doAssert version.len != 0, "Need version for Conan.io uri: " & uri + uri = uri % version + elif version.len != 0: + uri = uri & "/" & version + + let + pkg = newConanPackageFromUri(uri, shared) + downloadConan(pkg, outdir) + + result = findFile(header, outdir) + +proc getConanLDeps(outdir: string): seq[string] = + let + pkg = loadConanInfo(outdir) + + result = pkg.getConanLDeps(outdir) + +proc getJBBPath(header, uri, outdir, version: string): string = + let + spl = uri.split('/', 1) + name = spl[0] + hasVersion = version.len != 0 + + var + ver = + if spl.len == 2: + spl[1] + else: + "" + + if ver.len != 0: + if "$#" in ver or "$1" in ver: + doAssert hasVersion, "Need version for BinaryBuilder.org uri: " & uri + ver = ver % version + elif hasVersion: + doAssert false, "Version in both uri `" & uri & "` and `-d:xxxSetVer=\"" & + version & "\"` for BinaryBuilder.org" + elif hasVersion: + ver = version + + let + pkg = newJBBPackage(name, ver) + downloadJBB(pkg, outdir) + + result = findFile(header, outdir) + +proc getJBBLDeps(outdir: string, shared: bool): seq[string] = + let + pkg = loadJBBInfo(outdir) + + result = pkg.getJBBLDeps(outdir, shared) + +proc getLocalPath(header, outdir: string): string = + if outdir.len != 0: + result = findFile(header, outdir) + +proc buildLibrary(lname, outdir, conFlags, cmakeFlags, makeFlags: string, buildTypes: openArray[BuildType]): string = + var + lpath = findFile(lname, outdir, regex = true) + makeFlagsProc = &"-j {getNumProcs()} {makeFlags}" + makePath = outdir + + if lpath.len != 0: + return lpath + + var buildStatus: BuildStatus + + for buildType in buildTypes: + case buildType + of btCmake: + buildStatus = buildWithCmake(makePath, cmakeFlags) + of btAutoconf: + buildStatus = buildWithAutoConf(makePath, conFlags) + + if buildStatus.built: + break + + if buildStatus.buildPath.len > 0: + let libraryExists = findFile(lname, buildStatus.buildPath, regex = true).len > 0 + + if not libraryExists and fileExists(buildStatus.buildPath / "Makefile"): + make(buildStatus.buildPath, lname, makeFlagsProc, regex = true) + buildStatus.built = true + + let error = if buildStatus.error.len > 0: buildStatus.error else: "No build files found in " & outdir + doAssert buildStatus.built, &"\nBuild configuration failed - {error}\n" + + result = findFile(lname, outdir, regex = true) + +macro getHeader*( + header: static[string], giturl: static[string] = "", dlurl: static[string] = "", + conanuri: static[string] = "", jbburi: static[string] = "", + outdir: static[string] = "", libdir: static[string] = "", + conFlags: static[string] = "", cmakeFlags: static[string] = "", makeFlags: static[string] = "", + altNames: static[string] = "", buildTypes: static[openArray[BuildType]] = [btCmake, btAutoconf]): untyped = + ## Get the path to a header file for wrapping with + ## `cImport() `_ or + ## `c2nImport() `_. + ## + ## This proc checks `-d:xxx` defines based on the header name (e.g. lzma from lzma.h), + ## and accordingly employs different ways to obtain the source. + ## + ## `-d:xxxStd` - search standard system paths. E.g. `/usr/include` and `/usr/lib` on Linux + ## `-d:xxxGit` - clone source from a git repo specified in `giturl` + ## `-d:xxxDL` - download source from `dlurl` and extract if required + ## `-d:xxxConan` - download headers and binary from Conan.io using `conanuri` with + ## format `pkgname[/version[@user/channel][:bhash]]` + ## `-d:xxxJBB` - download headers and binary from BinaryBuilder.org using `jbburi` with + ## format `pkgname[/version]` + ## + ## This allows a single wrapper to be used in different ways depending on the user's needs. + ## If no `-d:xxx` defines are specified, `outdir` will be searched for the header as is. + ## The user can opt to download the sources to `outdir` using any other method such as + ## git sub-modules, vendoring or pointing to a repository that was already cloned. + ## + ## If multiple `-d:xxx` defines are specified, precedence is `Std` and then `Git`, `DL`, + ## `Conan` or `JBB`. This allows using a system installed library if available before + ## falling back to manual building. The user would need to specify both `-d:xxxStd` and + ## one of the other methods. + ## + ## `-d:xxxSetVer=x.y.z` can be used to specify which version to use. It is used as a tag + ## name for `Git` whereas for `DL`, `Conan` and `JBB`, it replaces `$1` in the URL + ## if specified. Specifying `-d:xxxSetVer` without a `$1` will download that version for + ## `Conan` and `JBB` if available. If no version is specified, the latest release of the + ## package is downloaded. For `Conan`, `-d:xxxSetVer` can also be used to set additional + ## URI information: + ## `-d:xxxSetVer=1.9.0@bincrafters/stable:bhash` + ## + ## If `conanuri` or `jbburi` are not defined and `Conan` or `JBB` is selected, the `header` + ## filename is used instead. + ## + ## All defines can also be set in code using `setDefines()` and checked for using + ## `isDefined()` which checks for defines set from both `-d` and `setDefines()`. + ## + ## The library is then configured (with `cmake` or `autotools` if possible) and built + ## using `make`, unless using `-d:xxxStd` which presumes that the system package + ## manager was used to install prebuilt headers and binaries, or using `-d:xxxConan` + ## or `-d:xxxJBB` which download pre-built binaries. + ## + ## The header path is stored in `const xxxPath` and can be used in a `cImport()` call + ## in the calling wrapper. The dynamic library path is stored in `const xxxLPath` and can + ## be used for the `dynlib` parameter (within quotes) or with `{.passL.}`. Any dependency + ## libraries downloaded by `Conan` or `JBB` are returned in `const xxxLDeps` as a seq[string]. + ## + ## `libdir` can be used to instruct `getHeader()` to copy shared libraries and their + ## dependencies to that directory. This prevents any runtime failures if `outdir` gets + ## removed or its contents changed. By default, `libdir` is set to the output directory + ## where the program binary will be created. The values of `xxxLPath` and `xxxLDeps` will + ## reflect this new location. `libdir` is ignored for `Std` mode. + ## + ## `-d:xxxStatic` can be specified to statically link with the library instead. This + ## will automatically add a `{.passL.}` call to the static library for convenience. Note + ## that `-d:xxxConan` and `-d:xxxJBB` download all dependency libs as well and the + ## `xxxLPath` will include paths to all of them separated by space in the right order for + ## linking. + ## + ## Note also that Conan currently builds all OSX binaries on 10.14 so older versions of + ## OSX will complain if statically linking to these binaries. Further, all Conan binaries + ## for Windows are built with Visual Studio so static linking the `.lib` files with gcc + ## or clang might lead to incompatibility issues if the library uses Visual Studio + ## specific compiler features. + ## + ## `conFlags`, `cmakeFlags` and `makeFlags` allow sending custom parameters to `configure`, + ## `cmake` and `make` in case additional configuration is required as part of the build + ## process. + ## + ## `altNames` is a list of alternate names for the library - e.g. zlib uses `zlib.h` for + ## the header but the typical lib name is `libz.so` and not `libzlib.so`. However, it is + ## libzlib.dll on Windows if built with cmake. In this case, `altNames = "z,zlib"`. Comma + ## separate for multiple alternate names without spaces. + ## + ## The original header name is not included by default if `altNames` is set since it could + ## cause the wrong lib to be selected. E.g. `SDL2/SDL.h` could pick `libSDL.so` even if + ## `altNames = "SDL2"`. Explicitly include it in `altNames` like the `zlib` example when + ## required. + ## + ## `buildTypes` specifies a list of ordered build strategies to use when building the + ## downloaded source files. Default is [btCmake, btAutoconf] + ## + ## `xxxPreBuild` is a hook that is called after the source code is pulled from Git or + ## downloaded but before the library is built. This might be needed if some initial prep + ## needs to be done before compilation. A few values are provided to the hook to help + ## provide context: + ## + ## `outdir` is the same `outdir` passed in and `header` is the discovered header path + ## in the downloaded source code. + ## + ## Simply define `proc xxxPreBuild(outdir, header: string)` in the wrapper and it will get + ## called prior to the build process. + var + origname = header.extractFilename().split(".")[0] + name = origname.split(seps = AllChars-Letters-Digits).join() + + # Default to origname if not specified + conanuri = if conanuri.len != 0: conanuri else: origname + jbburi = if jbburi.len != 0: jbburi else: origname + + # -d:xxx for this header + stdStr = name & "Std" + gitStr = name & "Git" + dlStr = name & "DL" + conanStr = name & "Conan" + jbbStr = name & "JBB" + + staticStr = name & "Static" + verStr = name & "SetVer" + + # Ident nodes of the -d:xxx to check in when statements + nameStd = newIdentNode(stdStr) + nameGit = newIdentNode(gitStr) + nameDL = newIdentNode(dlStr) + nameConan = newIdentNode(conanStr) + nameJBB = newIdentNode(jbbStr) + + nameStatic = newIdentNode(staticStr) + + # Consts to generate + path = newIdentNode(name & "Path") + lpath = newIdentNode(name & "LPath") + ldeps = newIdentNode(name & "LDeps") + version = newIdentNode(verStr) + lname = newIdentNode(name & "LName") + preBuild = newIdentNode(name & "PreBuild") + + # Regex for library search + lre = "(lib)?$1[_-]?(static)?" + + # If -d:xxx set with setDefines() + stdVal = gDefines.hasKey(stdStr) + gitVal = gDefines.hasKey(gitStr) + dlVal = gDefines.hasKey(dlStr) + conanVal = gDefines.hasKey(conanStr) + jbbVal = gDefines.hasKey(jbbStr) + staticVal = gDefines.hasKey(staticStr) + verVal = + if gDefines.hasKey(verStr): + gDefines[verStr] + else: + "" + mode = getCompilerMode(header) + + libdir = if libdir.len != 0: libdir else: getOutDir() + + # Use alternate library names if specified for regex search + if altNames.len != 0: + lre = lre % ("(" & altNames.replace(",", "|") & ")") + else: + lre = lre % origname + + result = newNimNode(nnkStmtList) + result.add(quote do: + # Need to check -d:xxx or setDefines() + const + `nameStd`* = when defined(`nameStd`): true else: `stdVal` == 1 + `nameGit`* = when defined(`nameGit`): true else: `gitVal` == 1 + `nameDL`* = when defined(`nameDL`): true else: `dlVal` == 1 + `nameConan`* = when defined(`nameConan`): true else: `conanVal` == 1 + `nameJBB`* = when defined(`nameJBB`): true else: `jbbVal` == 1 + `nameStatic`* = when defined(`nameStatic`): true else: `staticVal` == 1 + + # Search for header in outdir (after retrieving code) depending on -d:xxx mode + proc getPath(header, giturl, dlurl, conanuri, jbburi, outdir, version: string, shared: bool): string = + when `nameGit`: + getGitPath(header, giturl, outdir, version) + elif `nameDL`: + getDlPath(header, dlurl, outdir, version) + elif `nameConan`: + getConanPath(header, conanuri, outdir, version, shared) + elif `nameJBB`: + getJBBPath(header, jbburi, outdir, version) + else: + getLocalPath(header, outdir) + + const + `version`* {.strdefine.} = `verVal` + `lname` = + when `nameStatic`: + `lre` & "\\.(a|lib)" + else: + `lre` & getDynlibExt() + + # Look in standard path if requested by user + stdPath = + when `nameStd`: getStdPath(`header`, `mode`) else: "" + stdLPath = + when `nameStd`: getStdLibPath(`lname`, `mode`) else: "" + + useStd = stdPath.len != 0 and stdLPath.len != 0 + + # Look elsewhere if requested while prioritizing standard paths + prePath = + when useStd: + stdPath + else: + getPath(`header`, `giturl`, `dlurl`, `conanuri`, `jbburi`, `outdir`, `version`, not `nameStatic`) + + # Run preBuild hook before building library if not Std, Conan or JBB + when not (useStd or `nameConan` or `nameJBB`) and declared(`preBuild`): + static: + `preBuild`(`outdir`, prePath) + + let + # Library binary path - build if not standard / conan / jbb + lpath {.compileTime.} = + when useStd: + stdLPath + elif `nameConan` or `nameJBB`: + findFile(`lname`, `outdir`, regex = true) + else: + buildLibrary(`lname`, `outdir`, `conFlags`, `cmakeFlags`, `makeFlags`, `buildTypes`) + + # Library dependecy paths + ldeps {.compileTime.}: seq[string] = + when not useStd: + when `nameConan`: + getConanLDeps(`outdir`) + elif `nameJBB`: + getJBBLDeps(`outdir`, not `nameStatic`) + else: + @[] + else: + @[] + + const + # Header path - search again in case header is generated in build + `path`* = + if prePath.len != 0: + prePath + else: + getPath(`header`, `giturl`, `dlurl`, `conanuri`, `jbburi`, `outdir`, `version`, not `nameStatic`) + + static: + doAssert `path`.len != 0, "\nHeader " & `header` & " not found - " & + "missing/empty outdir or -d:$1Std -d:$1Git -d:$1DL -d:$1Conan or -d:$1JBB not specified" % `name` + doAssert lpath.len != 0, "\nLibrary " & `lname` & " not found" + + when `nameStatic`: + const + `lpath`* = lpath + `ldeps`* = ldeps + + # Automatically link with static library and dependencies + {.passL: `lpath`.} + if `ldeps`.len != 0: + {.passL: `ldeps`.join(" ").} + + static: + echo "# Including library " & lpath + if `ldeps`.len != 0: + echo "# Including dependencies " & `ldeps`.join(" ") + else: + const + `lpath`* = when not useStd: `libdir` / lpath.extractFilename() else: lpath + `ldeps`* = + when not useStd: + block: + var + ldeps = ldeps + copied: seq[string] + for i in 0 ..< ldeps.len: + let + lname = ldeps[i].extractFilename() + ldeptgt = `libdir` / lname + if not fileExists(ldeptgt) or getFileDate(ldeps[i]) != getFileDate(ldeptgt): + cpFile(ldeps[i], ldeptgt, psymlink = true) + copied.add lname + ldeps[i] = ldeptgt + # Copy downloaded dependencies to `libdir` + if copied.len != 0: + echo "# Copying dependencies: " & copied.join(" ") & "\n# to " & `libdir` + ldeps + else: + ldeps + + static: + when not useStd: + # Copy downloaded shared libraries to `libdir` + if not fileExists(`lpath`) or getFileDate(lpath) != getFileDate(`lpath`): + echo "# Copying " & `lpath`.extractFilename() & " to " & `libdir` + cpFile(lpath, `lpath`) + + echo "# Including library " & `lpath` + ) diff --git a/nimterop/jbb.nim b/nimterop/build/jbb.nim similarity index 99% rename from nimterop/jbb.nim rename to nimterop/build/jbb.nim index c282197..15bc578 100644 --- a/nimterop/jbb.nim +++ b/nimterop/build/jbb.nim @@ -1,4 +1,4 @@ -import json, os, strutils +import json, os, strformat, strutils, tables when (NimMajor, NimMinor, NimPatch) < (1, 2, 0): import marshal diff --git a/nimterop/nimconf.nim b/nimterop/build/nimconf.nim similarity index 100% rename from nimterop/nimconf.nim rename to nimterop/build/nimconf.nim diff --git a/nimterop/build/shell.nim b/nimterop/build/shell.nim new file mode 100644 index 0000000..4f3c316 --- /dev/null +++ b/nimterop/build/shell.nim @@ -0,0 +1,465 @@ +import os, strformat, strutils + +proc sleep*(milsecs: int) = + ## Sleep at compile time + let + cmd = + when defined(Windows): + "cmd /c timeout " + else: + "sleep " + + discard gorgeEx(cmd & $(milsecs / 1000)) + +proc execAction*(cmd: string, retry = 0, die = true, cache = false, + cacheKey = "", onRetry: proc() = nil): tuple[output: string, ret: int] = + ## Execute an external command - supported at compile time + ## + ## Checks if command exits successfully before returning. If not, an + ## error is raised. Always caches results to be used in nimsuggest or nimcheck + ## mode. + ## + ## `retry` - number of times command should be retried before error + ## `die = false` - return on errors + ## `cache = true` - cache results unless cleared with -f + ## `cacheKey` - key to create unique cache entry + let + ccmd = fixCmd(cmd) + + when nimvm: + # Cache results for speedup if cache = true + # Else cache for preserving functionality in nimsuggest and nimcheck + let + hash = (ccmd & cacheKey).hash().abs() + cachePath = getNimteropCacheDir() / "execCache" / "nimterop_" & $hash + cacheFile = cachePath & ".txt" + retFile = cachePath & "_ret.txt" + + when defined(nimsuggest) or defined(nimcheck): + # Load results from cache file if generated in previous run + if fileExists(cacheFile) and fileExists(retFile): + result.output = cacheFile.readFile() + result.ret = retFile.readFile().parseInt() + elif die: + doAssert false, "Results not cached - run nim c/cpp at least once\n" & ccmd + else: + if cache and fileExists(cacheFile) and fileExists(retFile) and not compileOption("forceBuild"): + # Return from cache when requested + result.output = cacheFile.readFile() + result.ret = retFile.readFile().parseInt() + else: + # Execute command and store results in cache + (result.output, result.ret) = gorgeEx(ccmd) + if result.ret == 0 or die == false: + # mkdir for execCache dir (circular dependency) + let dir = cacheFile.parentDir() + if not dirExists(dir): + let flag = when not defined(Windows): "-p" else: "" + discard execAction(&"mkdir {flag} {dir.sanitizePath}") + cacheFile.writeFile(result.output) + retFile.writeFile($result.ret) + else: + # Used by toast + (result.output, result.ret) = execCmdEx(ccmd) + + # On failure, retry or die as requested + if result.ret != 0: + if retry > 0: + if not onRetry.isNil: + onRetry() + sleep(500) + result = execAction(cmd, retry = retry - 1, die, cache, cacheKey) + elif die: + doAssert false, "Command failed: " & $result.ret & "\ncmd: " & ccmd & + "\nresult:\n" & result.output + +proc findExe*(exe: string): string = + ## Find the specified executable using the `which`/`where` command - supported + ## at compile time + var + cmd = + when defined(Windows): + "where " & exe + else: + "which " & exe + + (output, ret) = execAction(cmd, die = false) + + if ret == 0: + return output.splitLines()[0].strip() + +proc mkDir*(dir: string) = + ## Create a directory at compile time + ## + ## The `os` module is not available at compile time so a few + ## crucial helper functions are included with nimterop. + if not dirExists(dir): + let + flag = when not defined(Windows): "-p" else: "" + discard execAction(&"mkdir {flag} {dir.sanitizePath}", retry = 2) + +proc cpFile*(source, dest: string, psymlink = false, move = false) = + ## Copy a file from `source` to `dest` at compile time + ## + ## `psymlink = true` preserves symlinks instead of dereferencing on posix + let + source = source.replace("/", $DirSep) + dest = dest.replace("/", $DirSep) + cmd = + when defined(Windows): + if move: + "move /y" + else: + "copy /y" + else: + if move: + "mv -f" + else: + if psymlink: + "cp -fa" + else: + "cp -f" + + discard execAction(&"{cmd} {source.sanitizePath} {dest.sanitizePath}", retry = 2) + +proc mvFile*(source, dest: string) = + ## Move a file from `source` to `dest` at compile time + cpFile(source, dest, move=true) + +proc rmFile*(source: string, dir = false) = + ## Remove a file or pattern at compile time + let + source = source.replace("/", $DirSep) + cmd = + when defined(Windows): + if dir: + "rd /s/q" + else: + "del /s/q/f" + else: + "rm -rf" + exists = + if dir: + dirExists(source) + else: + fileExists(source) + + if exists: + discard execAction(&"{cmd} {source.sanitizePath}", retry = 2) + +proc rmDir*(dir: string) = + ## Remove a directory or pattern at compile time + rmFile(dir, dir = true) + +proc cleanDir*(dir: string) = + ## Remove all contents of a directory at compile time + for kind, path in walkDir(dir): + if kind == pcDir: + rmDir(path) + else: + rmFile(path) + +proc cpTree*(source, dest: string, move = false) = + ## Copy contents of source dir to the destination, not the directory itself + for kind, path in walkDir(source, relative = true): + if kind == pcDir: + cpTree(source / path, dest / path, move) + if move: + rmDir(source / path) + else: + if not dirExists(dest): + mkDir(dest) + if move: + mvFile(source / path, dest / path) + else: + cpFile(source / path, dest / path) + +proc mvTree*(source, dest: string) = + ## Move contents of source dir to the destination, not the directory itself + cpTree(source, dest, move = true) + +proc getFileDate*(fullpath: string): string = + ## Get file date for `fullpath` + var + ret = 0 + cmd = + when defined(Windows): + let + (head, tail) = fullpath.splitPath() + &"cmd /c forfiles /P {head.sanitizePath()} /M {tail.sanitizePath} /C \"cmd /c echo @fdate @ftime @fsize\"" + elif defined(Linux): + &"stat -c %y {fullpath.sanitizePath}" + elif defined(OSX) or defined(FreeBSD): + &"stat -f %m {fullpath.sanitizePath}" + + (result, ret) = execAction(cmd) + +proc touchFile*(fullpath: string) = + ## Touch file to update modified date + var + cmd = + when defined(Windows): + &"cmd /c copy /b {fullpath.sanitizePath}+" + else: + &"touch {fullpath.sanitizePath}" + + discard execAction(cmd) + +proc extractZip*(zipfile, outdir: string, quiet = false) = + ## Extract a zip file using `powershell` on Windows and `unzip` on other + ## systems to the specified output directory + var cmd = "unzip -o $#" + if defined(Windows): + cmd = "powershell -nologo -noprofile -command \"& { Add-Type -A " & + "'System.IO.Compression.FileSystem'; " & + "[IO.Compression.ZipFile]::ExtractToDirectory('$#', '.'); }\"" + + if not quiet: + echo "# Extracting " & zipfile + discard execAction(&"cd {outdir.sanitizePath} && {cmd % zipfile}") + +proc extractTar*(tarfile, outdir: string, quiet = false) = + ## Extract a tar file using `tar`, `7z` or `7za` to the specified output directory + var + cmd = "" + name = "" + + if findExe("tar").len != 0: + let + ext = tarfile.splitFile().ext.toLowerAscii() + typ = + case ext + of ".gz", ".tgz": "z" + of ".xz": "J" + of ".bz2": "j" + else: "" + + cmd = "tar xvf" & typ & " " & tarfile.sanitizePath + else: + for i in ["7z", "7za"]: + if findExe(i).len != 0: + cmd = i & " x $#" % tarfile.sanitizePath + + name = tarfile.splitFile().name + if ".tar" in name.toLowerAscii(): + cmd &= " && " & i & " x $#" % name.sanitizePath + + break + + doAssert cmd.len != 0, "No extraction tool - tar, 7z, 7za - available for " & tarfile.sanitizePath + + if not quiet: + echo "# Extracting " & tarfile + discard execAction(&"cd {outdir.sanitizePath} && {cmd}") + if name.len != 0: + rmFile(outdir / name) + +proc downloadUrl*(url, outdir: string, quiet = false, retry = 1) = + ## Download a file using `curl` or `wget` (or `powershell` on Windows) to the specified directory + ## + ## If an archive file, it is automatically extracted after download. + let + file = url.extractFilename() + filePath = outdir / file + ext = file.splitFile().ext.toLowerAscii() + archives = @[".zip", ".xz", ".gz", ".bz2", ".tgz", ".tar"] + + if not (ext in archives and fileExists(filePath)): + if not quiet: + echo "# Downloading " & file + mkDir(outdir) + var cmd = findExe("curl") + if cmd.len != 0: + cmd &= " -Lk $# -o $#" + else: + cmd = findExe("wget") + if cmd.len != 0: + cmd &= " $# -O $#" + elif defined(Windows): + cmd = "powershell [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; wget $# -OutFile $#" + else: + doAssert false, "No download tool available - curl, wget" + discard execAction(cmd % [url.quoteShell, (filePath).sanitizePath], retry = 3, + onRetry = proc() = rmFile(filePath)) + + if ext == ".zip": + extractZip(file, outdir, quiet) + elif ext in archives: + extractTar(file, outdir, quiet) + +proc gitReset*(outdir: string) = + ## Hard reset the git repository at the specified directory + echo "# Resetting " & outdir + + let cmd = &"cd {outdir.sanitizePath} && git reset --hard" + while execAction(cmd).output.contains("Permission denied"): + sleep(1000) + echo "# Retrying ..." + +proc gitCheckout*(file, outdir: string) = + ## Checkout the specified `file` in the git repository at `outdir` + ## + ## This effectively resets all changes in the file and can be + ## used to undo any changes that were made to source files to enable + ## successful wrapping with `cImport()` or `c2nImport()`. + echo "# Resetting " & file + let file2 = file.relativePath outdir + let cmd = &"cd {outdir.sanitizePath} && git checkout {file2.sanitizePath}" + while execAction(cmd).output.contains("Permission denied"): + sleep(500) + echo "# Retrying ..." + +proc gitPull*(url: string, outdir = "", plist = "", checkout = "", quiet = false) = + ## Pull the specified git repository to the output directory + ## + ## `plist` is the list of specific files and directories or wildcards + ## to sparsely checkout. Multiple values can be specified one entry per + ## line. It is optional and if omitted, the entire repository will be + ## checked out. + ## + ## `checkout` is the git tag, branch or commit hash to checkout once + ## the repository is downloaded. This allows for pinning to a specific + ## version of the code. + if dirExists(outdir/".git"): + gitReset(outdir) + return + + let + outdirQ = outdir.sanitizePath + + mkDir(outdir) + + if not quiet: + echo "# Setting up Git repo: " & url + discard execAction(&"cd {outdirQ} && git init .") + discard execAction(&"cd {outdirQ} && git remote add origin {url}") + + if plist.len != 0: + # If a specific list of files is required, create a sparse checkout + # file for git in its config directory + let sparsefile = outdir / ".git/info/sparse-checkout" + + discard execAction(&"cd {outdirQ} && git config core.sparsecheckout true") + writeFile(sparsefile, plist) + + # In case directory has old files from another run + discard execAction(&"cd {outdirQ} && git clean -fxd") + + if checkout.len != 0: + if not quiet: + echo "# Checking out " & checkout + discard execAction(&"cd {outdirQ} && git fetch", retry = 3) + discard execAction(&"cd {outdirQ} && git checkout {checkout}") + else: + if not quiet: + echo "# Pulling repository" + discard execAction(&"cd {outdirQ} && git pull --depth=1 origin master", retry = 3) + +proc gitTags*(outdir: string): seq[string] = + ## Get all the git tags in the specified directory + let + cmd = &"cd {outdir.sanitizePath} && git tag" + tags = execAction(cmd).output.splitLines() + for tag in tags: + let + tag = tag.strip() + if tag.len != 0: + result.add tag + +proc findFiles*(file: string, dir: string, recurse = true, regex = false): seq[string] = + ## Find all matching files in the specified directory + ## + ## `file` is a regular expression if `regex` is true + ## + ## Turn off recursive search with `recurse` + var + cmd = + when defined(Windows): + "nimgrep --filenames --oneline --nocolor $1 \"$2\" $3" + elif defined(linux): + "find $3 $1 -regextype egrep -regex $2" + elif defined(osx) or defined(FreeBSD): + "find -E $3 $1 -regex $2" + + recursive = "" + + if recurse: + when defined(Windows): + recursive = "--recursive" + else: + when not defined(Windows): + recursive = "-maxdepth 1" + + var + dir = dir + file = file + if not recurse: + let + pdir = file.parentDir() + if pdir.len != 0: + dir = dir / pdir + + file = file.extractFilename + + cmd = cmd % [recursive, (".*[\\\\/]" & file & "$").quoteShell, dir.sanitizePath] + + let + (files, ret) = execAction(cmd, die = false) + if ret == 0: + for line in files.splitLines(): + let f = + when defined(Windows): + if ": " in line: + line.split(": ", maxsplit = 1)[1] + else: + "" + else: + line + if f.len != 0: + result.add f + +proc findFile*(file: string, dir: string, recurse = true, first = false, regex = false): string = + ## Find the file in the specified directory + ## + ## `file` is a regular expression if `regex` is true + ## + ## Turn off recursive search with `recurse` and stop on first match with + ## `first`. Without it, the shortest match is returned. + let + matches = findFiles(file, dir, recurse, regex) + for match in matches: + if (result.len == 0 or result.len > match.len): + result = match + if first: break + +proc linkLibs*(names: openArray[string], staticLink = true): string = + ## Create linker flags for specified libraries using pkg-config + ## + ## Prepends `lib` to the name so you only need `ssl` for `libssl`. + var + stat = if staticLink: "--static" else: "" + resSet: OrderedSet[string] + resSet.init() + + for name in names: + let + cmd = &"pkg-config --libs --silence-errors {stat} lib{name}" + (libs, _) = execAction(cmd, die = false) + for lib in libs.split(" "): + resSet.incl lib + + if staticLink: + resSet.incl "--static" + + for res in resSet: + result &= " " & res + +proc getNumProcs(): string = + when defined(Windows): + getEnv("NUMBER_OF_PROCESSORS").strip() + elif defined(linux): + execAction("nproc").output.strip() + elif defined(macosx) or defined(FreeBSD): + execAction("sysctl -n hw.ncpu").output.strip() + else: + "1" diff --git a/nimterop/build/tools.nim b/nimterop/build/tools.nim new file mode 100644 index 0000000..772c48b --- /dev/null +++ b/nimterop/build/tools.nim @@ -0,0 +1,260 @@ +import os, strformat, strutils + +type + BuildType* = enum + btAutoconf, btCmake + + BuildStatus = object + built: bool + buildPath: string + error: string + +proc configure*(path, check: string, flags = "") = + ## Run the GNU `configure` command to generate all Makefiles or other + ## build scripts in the specified path + ## + ## If a `configure` script is not present and an `autogen.sh` script + ## is present, it will be run before attempting `configure`. + ## + ## Next, if `configure.ac` or `configure.in` exist, `autoreconf` will + ## be executed. + ## + ## `check` is a file that will be generated by the `configure` command. + ## This is required to prevent configure from running on every build. It + ## is relative to the `path` and should not be an absolute path. + ## + ## `flags` are any flags that should be passed to the `configure` command. + if (path / check).fileExists(): + return + + echo "# Configuring " & path + + if not fileExists(path / "configure"): + for i in @["autogen.sh", "build" / "autogen.sh"]: + if fileExists(path / i): + echo "# Running autogen.sh" + + when defined(unix): + echoDebug execAction( + &"cd {(path / i).parentDir().sanitizePath} && ./autogen.sh").output + else: + echoDebug execAction( + &"cd {(path / i).parentDir().sanitizePath} && bash ./autogen.sh").output + + break + + if not fileExists(path / "configure"): + for i in @["configure.ac", "configure.in"]: + if fileExists(path / i): + echo "# Running autoreconf" + + echoDebug execAction(&"cd {path.sanitizePath} && autoreconf -fi").output + + break + + if fileExists(path / "configure"): + echo "# Running configure " & flags + + when defined(unix): + var + cmd = &"cd {path.sanitizePath} && ./configure" + else: + var + cmd = &"cd {path.sanitizePath} && bash ./configure" + if flags.len != 0: + cmd &= &" {flags}" + + echoDebug execAction(cmd).output + + doAssert (path / check).fileExists(), "Configure failed" + +proc getCmakePropertyStr(name, property, value: string): string = + &"\nset_target_properties({name} PROPERTIES {property} \"{value}\")\n" + +proc getCmakeIncludePath*(paths: openArray[string]): string = + ## Create a `cmake` flag to specify custom include paths + ## + ## Result can be included in the `flag` parameter for `cmake()` or + ## the `cmakeFlags` parameter for `getHeader()`. + for path in paths: + result &= path & ";" + result = " -DCMAKE_INCLUDE_PATH=" & result[0 .. ^2].sanitizePath(sep = "/") + +proc setCmakeProperty*(outdir, name, property, value: string) = + ## Set a `cmake` property in `outdir / CMakeLists.txt` - usable in the `xxxPreBuild` hook + ## for `getHeader()` + ## + ## `set_target_properties(name PROPERTIES property "value")` + let + cm = outdir / "CMakeLists.txt" + if cm.fileExists(): + cm.writeFile( + cm.readFile() & getCmakePropertyStr(name, property, value) + ) + +proc setCmakeLibName*(outdir, name, prefix = "", oname = "", suffix = "") = + ## Set a `cmake` property in `outdir / CMakeLists.txt` to specify a custom library output + ## name - usable in the `xxxPreBuild` hook for `getHeader()` + ## + ## `prefix` is typically `lib` + ## `oname` is the library name + ## `suffix` is typically `.a` + ## + ## Sometimes, `cmake` generates non-standard library names - e.g. zlib compiles to + ## `libzlibstatic.a` on Windows. This proc can help rename it to `libzlib.a` so that `getHeader()` + ## can find it after the library is compiled. + ## + ## ``` + ## set_target_properties(name PROPERTIES PREFIX "prefix") + ## set_target_properties(name PROPERTIES OUTPUT_NAME "oname") + ## set_target_properties(name PROPERTIES SUFFIX "suffix") + ## ``` + let + cm = outdir / "CMakeLists.txt" + if cm.fileExists(): + var + str = "" + if prefix.len != 0: + str &= getCmakePropertyStr(name, "PREFIX", prefix) + if oname.len != 0: + str &= getCmakePropertyStr(name, "OUTPUT_NAME", oname) + if suffix.len != 0: + str &= getCmakePropertyStr(name, "SUFFIX", suffix) + if str.len != 0: + cm.writeFile(cm.readFile() & str) + +proc setCmakePositionIndependentCode*(outdir: string) = + ## Set a `cmake` directive to create libraries with -fPIC enabled + let + cm = outdir / "CMakeLists.txt" + if cm.fileExists(): + let + pic = "set(CMAKE_POSITION_INDEPENDENT_CODE ON)" + cmd = cm.readFile() + if not cmd.contains(pic): + cm.writeFile( + pic & "\n" & cmd + ) + +proc cmake*(path, check, flags: string) = + ## Run the `cmake` command to generate all Makefiles or other + ## build scripts in the specified path + ## + ## `path` will be created since typically `cmake` is run in an + ## empty directory. + ## + ## `check` is a file that will be generated by the `cmake` command. + ## This is required to prevent `cmake` from running on every build. It + ## is relative to the `path` and should not be an absolute path. + ## + ## `flags` are any flags that should be passed to the `cmake` command. + ## Unlike `configure`, it is required since typically it will be the + ## path to the repository, typically `..` when `path` is a subdir. + if (path / check).fileExists(): + return + + echo "# Running cmake " & flags + echo "# Path: " & path + + mkDir(path) + + let + cmd = &"cd {path.sanitizePath} && cmake {flags}" + + echoDebug execAction(cmd).output + + doAssert (path / check).fileExists(), "cmake failed" + +proc make*(path, check: string, flags = "", regex = false) = + ## Run the `make` command to build all binaries in the specified path + ## + ## `check` is a file that will be generated by the `make` command. + ## This is required to prevent `make` from running on every build. It + ## is relative to the `path` and should not be an absolute path. + ## + ## `flags` are any flags that should be passed to the `make` command. + ## + ## `regex` can be set to true if `check` is a regular expression. + ## + ## If `make.exe` is missing and `mingw32-make.exe` is available, it will + ## be copied over to make.exe in the same location. + if findFile(check, path, regex = regex).len != 0: + return + + echo "# Running make " & flags + echo "# Path: " & path + + var + cmd = findExe("make") + + if cmd.len == 0: + cmd = findExe("mingw32-make") + if cmd.len != 0: + cpFile(cmd, cmd.replace("mingw32-make", "make")) + doAssert cmd.len != 0, "Make not found" + + cmd = &"cd {path.sanitizePath} && make" + if flags.len != 0: + cmd &= &" {flags}" + + echoDebug execAction(cmd).output + + doAssert findFile(check, path, regex = regex).len != 0, "make failed" + +proc buildWithCmake(outdir, flags: string): BuildStatus = + if not fileExists(outdir / "Makefile"): + if fileExists(outdir / "CMakeLists.txt"): + if findExe("cmake").len != 0: + var + gen = "" + when defined(Windows): + if findExe("sh").len != 0: + let + uname = execAction("sh -c uname -a").output.toLowerAscii() + if uname.contains("msys"): + gen = "MSYS Makefiles".quoteShell + elif uname.contains("mingw"): + gen = "MinGW Makefiles".quoteShell & " -DCMAKE_SH=\"CMAKE_SH-NOTFOUND\"" + else: + echo "Unsupported system: " & uname + else: + gen = "MinGW Makefiles".quoteShell + else: + gen = "Unix Makefiles".quoteShell + if findExe("ccache").len != 0: + gen &= " -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache" + result.buildPath = outdir / "buildcache" + cmake(result.buildPath, "Makefile", &".. -G {gen} {flags}") + result.built = true + else: + result.error = "cmake capable but cmake executable missing" + else: + result.buildPath = outdir + +proc buildWithAutoConf(outdir, flags: string): BuildStatus = + if not fileExists(outdir / "Makefile"): + if findExe("bash").len != 0: + for file in @["configure", "configure.ac", "configure.in", "autogen.sh", "build/autogen.sh"]: + if fileExists(outdir / file): + configure(outdir, "Makefile", flags) + result.buildPath = outdir + result.built = true + break + else: + result.error = "configure capable but bash executable missing" + else: + result.buildPath = outdir + +proc flagBuild*(base: string, flags: openArray[string]): string = + ## Simple helper proc to generate flags for `configure`, `cmake`, etc. + ## + ## Every entry in `flags` is replaced into the `base` string and + ## concatenated to the result. + ## + ## E.g. + ## `base = "--disable-$#"` + ## `flags = @["one", "two"]` + ## + ## `flagBuild(base, flags) => " --disable-one --disable-two"` + for i in flags: + result &= " " & base % i diff --git a/nimterop/git.nim b/nimterop/git.nim deleted file mode 100644 index 7a0cf2a..0000000 --- a/nimterop/git.nim +++ /dev/null @@ -1 +0,0 @@ -include build \ No newline at end of file diff --git a/nimterop/toast.nim b/nimterop/toast.nim index 1844a56..495e5d1 100644 --- a/nimterop/toast.nim +++ b/nimterop/toast.nim @@ -2,7 +2,9 @@ import os, osproc, sets, strformat, strutils, tables, times import "."/treesitter/[api, c, cpp] -import "."/[ast, ast2, build, globals, getters, grammar, tshelp] +import "."/[build, globals] + +import "."/toastlib/[ast, ast2, getters, grammar, tshelp] proc process(gState: State, path: string, astTable: AstTable) = doAssert existsFile(path), &"Invalid path {path}" diff --git a/nimterop/ast.nim b/nimterop/toastlib/ast.nim similarity index 99% rename from nimterop/ast.nim rename to nimterop/toastlib/ast.nim index 78501fd..0b62a34 100644 --- a/nimterop/ast.nim +++ b/nimterop/toastlib/ast.nim @@ -2,7 +2,8 @@ import hashes, macros, os, sets, strformat, strutils, tables import regex -import "."/[getters, globals, treesitter/api, tshelp] +import ".."/[globals, treesitter/api] +import "."/[getters, tshelp] proc getHeaderPragma*(gState: State): string = result = diff --git a/nimterop/ast2.nim b/nimterop/toastlib/ast2.nim similarity index 99% rename from nimterop/ast2.nim rename to nimterop/toastlib/ast2.nim index de3b452..ffe961e 100644 --- a/nimterop/ast2.nim +++ b/nimterop/toastlib/ast2.nim @@ -2,9 +2,9 @@ import macros, os, sequtils, sets, strformat, strutils, tables, times import compiler/[ast, idents, lineinfos, modulegraphs, msgs, options, renderer] -import "."/treesitter/api +import ".."/[globals, treesitter/api] -import "."/[comphelp, exprparser, globals, getters, tshelp] +import "."/[comphelp, exprparser, getters, tshelp] proc getOverrideOrSkip(gState: State, node: TSNode, origname: string, kind: NimSymKind): PNode = # Check if symbol `origname` of `kind` and `origname` has any cOverride defined diff --git a/nimterop/comphelp.nim b/nimterop/toastlib/comphelp.nim similarity index 98% rename from nimterop/comphelp.nim rename to nimterop/toastlib/comphelp.nim index e577717..d404c42 100644 --- a/nimterop/comphelp.nim +++ b/nimterop/toastlib/comphelp.nim @@ -2,7 +2,8 @@ import macros, strutils import compiler/[ast, idents, lineinfos, msgs, options, parser, pathutils, renderer] -import "."/[globals, getters, treesitter/api, tshelp] +import ".."/[globals, treesitter/api] +import "."/[getters, tshelp] proc handleError*(conf: ConfigRef, info: TLineInfo, msg: TMsgKind, arg: string) = # Raise exception in parseString() instead of exiting for errors diff --git a/nimterop/exprparser.nim b/nimterop/toastlib/exprparser.nim similarity index 99% rename from nimterop/exprparser.nim rename to nimterop/toastlib/exprparser.nim index 0d2099a..dc9f97e 100644 --- a/nimterop/exprparser.nim +++ b/nimterop/toastlib/exprparser.nim @@ -4,9 +4,9 @@ import regex import compiler/[ast, renderer] -import "."/treesitter/[api, c, cpp] - -import "."/[globals, getters, comphelp, tshelp] +import ".."/treesitter/[api, c, cpp] +import ".."/globals +import "."/[getters, comphelp, tshelp] # This version of exprparser should be able to handle: # diff --git a/nimterop/getters.nim b/nimterop/toastlib/getters.nim similarity index 99% rename from nimterop/getters.nim rename to nimterop/toastlib/getters.nim index b092663..b4070f3 100644 --- a/nimterop/getters.nim +++ b/nimterop/toastlib/getters.nim @@ -2,7 +2,7 @@ import dynlib, macros, os, sequtils, sets, strformat, strutils, tables, times import regex -import "."/[build, globals, plugin] +import ".."/[build, globals, plugin] const gReserved = """ addr and as asm diff --git a/nimterop/grammar.nim b/nimterop/toastlib/grammar.nim similarity index 99% rename from nimterop/grammar.nim rename to nimterop/toastlib/grammar.nim index e061a70..52b19e7 100644 --- a/nimterop/grammar.nim +++ b/nimterop/toastlib/grammar.nim @@ -2,7 +2,8 @@ import macros, strformat, strutils, tables import regex -import "."/[ast, getters, globals, lisp, treesitter/api, tshelp] +import ".."/[globals, treesitter/api] +import "."/[ast, getters, lisp, tshelp] type Grammar = seq[tuple[grammar: string, call: proc(ast: ref Ast, node: TSNode, gState: State) {.nimcall.}]] diff --git a/nimterop/lisp.nim b/nimterop/toastlib/lisp.nim similarity index 97% rename from nimterop/lisp.nim rename to nimterop/toastlib/lisp.nim index 8287cf5..57d71a1 100644 --- a/nimterop/lisp.nim +++ b/nimterop/toastlib/lisp.nim @@ -1,4 +1,5 @@ -import "."/[getters, globals] +import ".."/globals +import "."/getters var gTokens: seq[string] diff --git a/nimterop/tshelp.nim b/nimterop/toastlib/tshelp.nim similarity index 99% rename from nimterop/tshelp.nim rename to nimterop/toastlib/tshelp.nim index ad3e89e..91f77ec 100644 --- a/nimterop/tshelp.nim +++ b/nimterop/toastlib/tshelp.nim @@ -1,7 +1,8 @@ import sets, strformat, strutils -import "."/[getters, globals] -import "."/treesitter/[api, c, cpp] +import ".."/treesitter/[api, c, cpp] +import ".."/globals +import "."/getters template withCodeAst*(code: string, mode: string, body: untyped): untyped = ## A simple template to inject the TSNode into a body of code From 69e372beeaa4c1aa306efb13237bf274a33a1f05 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Sat, 20 Jun 2020 13:52:01 -0500 Subject: [PATCH 526/593] Improve octal fix --- nimterop/build.nim | 5 ++++- nimterop/build/nimconf.nim | 3 ++- nimterop/toastlib/exprparser.nim | 22 ++++++++++------------ 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/nimterop/build.nim b/nimterop/build.nim index 99adeca..0754615 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -1,4 +1,7 @@ -import hashes, macros, osproc, sets, strformat, strutils, tables +import hashes, osproc, sets, strformat, strutils + +when not defined(TOAST): + import macros, tables import os except findExe, sleep diff --git a/nimterop/build/nimconf.nim b/nimterop/build/nimconf.nim index 98fc8fe..3ba5ed0 100644 --- a/nimterop/build/nimconf.nim +++ b/nimterop/build/nimconf.nim @@ -1,4 +1,4 @@ -import json, macros, os, osproc, sets, strformat, strutils +import json, os, osproc, sets, strformat, strutils when nimvm: when (NimMajor, NimMinor, NimPatch) >= (1, 2, 0): @@ -55,6 +55,7 @@ proc getProjectDir*(): string = result = querySetting(projectFull).parentDir() else: # Get from `macros` + import macros result = getProjectPath() else: discard diff --git a/nimterop/toastlib/exprparser.nim b/nimterop/toastlib/exprparser.nim index dc9f97e..28b49d3 100644 --- a/nimterop/toastlib/exprparser.nim +++ b/nimterop/toastlib/exprparser.nim @@ -140,15 +140,16 @@ proc getIntNode(number, suffix: string): PNode {.inline.} = var val: BiggestInt flags: TNodeFlags - if number.startsWith("0X") or number.startsWith("0x"): - val = parseHexInt(number) - flags = {nfBase16} - elif number.startsWith("0B") or number.startsWith("0b"): - val = parseBinInt(number) - flags = {nfBase2} - elif number.startsWith("0O") or number.startsWith("0o"): - val = parseOctInt(number) - flags = {nfBase8} + if number.len > 1 and number[0] == '0': + if number[1] in ['x', 'X']: + val = parseHexInt(number) + flags = {nfBase16} + elif number[1] in ['b', 'B']: + val = parseBinInt(number) + flags = {nfBase2} + else: + val = parseOctInt(number) + flags = {nfBase8} else: val = parseInt(number) @@ -201,9 +202,6 @@ proc processNumberLiteral(gState: State, node: TSNode): PNode = if number.startsWith("-"): number = number[1 ..< number.len] prefix = "-" - if number.len > 1 and number[0] == '0' and number[1] notin ['x', 'X']: - # Octal 0123 - number = "0o" & number[1 .. ^1] if tripleEndings.any(proc (s: string): bool = number.endsWith(s)): suffix = number[^3 .. ^1] number = number[0 ..< ^3] From c3228683fa91e01c75a8676479ee13a41c7f5a02 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Sat, 20 Jun 2020 14:21:59 -0500 Subject: [PATCH 527/593] Fix macros bug --- nimterop/build/nimconf.nim | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nimterop/build/nimconf.nim b/nimterop/build/nimconf.nim index 3ba5ed0..c87a60f 100644 --- a/nimterop/build/nimconf.nim +++ b/nimterop/build/nimconf.nim @@ -3,6 +3,8 @@ import json, os, osproc, sets, strformat, strutils when nimvm: when (NimMajor, NimMinor, NimPatch) >= (1, 2, 0): import std/compilesettings + else: + import macros else: discard @@ -55,7 +57,6 @@ proc getProjectDir*(): string = result = querySetting(projectFull).parentDir() else: # Get from `macros` - import macros result = getProjectPath() else: discard From d07bd2d71e194a3ed1c0bd5eec9537db26b0bf3f Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Sat, 20 Jun 2020 22:06:02 -0500 Subject: [PATCH 528/593] findExe sanitizePath --- nimterop/build/shell.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimterop/build/shell.nim b/nimterop/build/shell.nim index 4f3c316..235f7b5 100644 --- a/nimterop/build/shell.nim +++ b/nimterop/build/shell.nim @@ -86,7 +86,7 @@ proc findExe*(exe: string): string = (output, ret) = execAction(cmd, die = false) if ret == 0: - return output.splitLines()[0].strip() + return output.splitLines()[0].strip().sanitizePath proc mkDir*(dir: string) = ## Create a directory at compile time From 6c3142a27c186ed4b02bf717ad2dafc37fe81440 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 23 Jun 2020 09:50:00 -0500 Subject: [PATCH 529/593] Fix findFile with regex --- nimterop/build/shell.nim | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nimterop/build/shell.nim b/nimterop/build/shell.nim index 235f7b5..5179798 100644 --- a/nimterop/build/shell.nim +++ b/nimterop/build/shell.nim @@ -393,7 +393,8 @@ proc findFiles*(file: string, dir: string, recurse = true, regex = false): seq[s var dir = dir file = file - if not recurse: + # If file = `path/file`, adjust dir = `dir/path` and search for new file + if not (recurse or regex): let pdir = file.parentDir() if pdir.len != 0: From 77380630383f37f08d0ead6438aa4c90966b8d25 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 23 Jun 2020 11:42:50 -0500 Subject: [PATCH 530/593] Fix #231 - const func type, comment in struct --- nimterop/toastlib/ast2.nim | 13 +++--- nimterop/toastlib/tshelp.nim | 2 +- tests/include/tast2.h | 83 ++++++++++++++++++++++++++++++++++-- tests/tast2.nim | 4 ++ 4 files changed, 92 insertions(+), 10 deletions(-) diff --git a/nimterop/toastlib/ast2.nim b/nimterop/toastlib/ast2.nim index ffe961e..701b0b4 100644 --- a/nimterop/toastlib/ast2.nim +++ b/nimterop/toastlib/ast2.nim @@ -1238,8 +1238,9 @@ proc addType(gState: State, node: TSNode, union = false) = gState.addTypeObject(node[0], union = union) else: let - fdecl = node[1].anyChildInTree("function_declarator") - adecl = node[1].anyChildInTree("array_declarator") + start = node.getStartAtom() + fdecl = node[start+1].anyChildInTree("function_declarator") + adecl = node[start+1].anyChildInTree("array_declarator") if fdlist.isNil: if adecl.isNil and fdecl.isNil: # typedef X Y; @@ -1341,9 +1342,9 @@ proc addType(gState: State, node: TSNode, union = false) = # First add struct as object decho("addType(): case 6") - gState.addTypeObject(node[0], union = union) + gState.addTypeObject(node[start], union = union) - if node.len > 1 and gState.getNodeVal(node[1]) != "": + if node.len > start+1 and gState.getNodeVal(node[start+1]) != "": # Add any additional names gState.addTypeTyped(node) else: @@ -1357,14 +1358,14 @@ proc addType(gState: State, node: TSNode, union = false) = name = block: var name = "" - for i in 1 ..< node.len: + for i in start+1 ..< node.len: if node[i].getName() == "type_identifier": name = gState.getNodeVal(node[i].getAtom()) name # Now add struct as object with specified name - gState.addTypeObject(node[0], fname = name, istype = true, union = union) + gState.addTypeObject(node[start], fname = name, istype = true, union = union) if name.nBl: # Add any additional names diff --git a/nimterop/toastlib/tshelp.nim b/nimterop/toastlib/tshelp.nim index 91f77ec..b055259 100644 --- a/nimterop/toastlib/tshelp.nim +++ b/nimterop/toastlib/tshelp.nim @@ -62,7 +62,7 @@ proc getAtom*(node: TSNode): TSNode = if node.getName() in gAtoms: return node elif node.len != 0: - if node[0].getName() == "type_qualifier": + if node[0].getName() in ["type_qualifier", "comment"]: # Skip const, volatile if node.len > 1: return node[1].getAtom() diff --git a/tests/include/tast2.h b/tests/include/tast2.h index 6f569d5..89ad486 100644 --- a/tests/include/tast2.h +++ b/tests/include/tast2.h @@ -61,6 +61,7 @@ struct some_struct_s struct parent_struct_s { + /* Random comment */ struct some_struct_s s[SOME_CONST]; }; @@ -108,6 +109,9 @@ typedef struct A20 { char a1; } A20, A21, *A21p; //Expression typedef struct A22 { const int **f1; int *f2[123+132]; } A22; +// #231 +typedef const char *(*A23)(); + //Unions union U1 {int f1; float f2; }; typedef union U2 { const int **f1; int abc[123+132]; } U2; @@ -239,6 +243,7 @@ typedef struct { struct { int f1; } f2; struct NT3 { + /* Random comment */ struct { int f1; union NU1 { @@ -277,6 +282,65 @@ struct TestMyInt { #define C 0x10 #define D "hello" #define E 'c' +#define F 01234 + +#define UEXPR (1234u << 1) +#define ULEXPR (1234ul << 2) +#define ULLEXPR (1234ull << 3) +#define LEXPR (1234l << 4) +#define LLEXPR (1234ll << 5) + +#define SHL1 (1u << 1) +#define SHL2 (1u << 2) +#define SHL3 (1u << 3) +#define COERCE 645635634896ull + 35436 +#define COERCE2 645635634896 + 35436ul +#define BINEXPR ~(-(1u << !-1)) ^ (10 >> 1) +#define POINTEREXPR (int*)0 +#define POINTERPOINTERPOINTEREXPR (int***)0 +#define BOOL true +#define MATHEXPR (1 + 2/3*20 - 100) +#define ANDEXPR (100 & 11000) +#define CASTEXPR (char) 34 +#define AVAL 100 +#define BVAL 200 +#define EQ1 AVAL <= BVAL +#define EQ2 AVAL >= BVAL +#define EQ3 AVAL > BVAL +#define EQ4 AVAL < BVAL +#define EQ5 AVAL != BVAL +#define EQ6 AVAL == BVAL + +// testing integer out of long int range +#define INT_FAST16_MIN (-9223372036854775807L-1) + +#define SIZEOF sizeof(char) +#define REG_STR "regular string" +#define NOTSUPPORTEDSTR "not a " REG_STR + +#define NULLCHAR '\0' +#define OCTCHAR '\012' +#define HEXCHAR '\xFE' +#define TRICKYSTR "\x4E\034\nfoo\0\'\"\r\v\a\b\e\f\t\\\?bar" + +#define ALLSHL (SHL1 | SHL2 | SHL3) + +#ifdef NIMTEROP +#define SOME_CONST 8 +#endif + +struct some_struct_s +{ + int x; +}; + +struct parent_struct_s +{ + /* Random comment */ + struct some_struct_s s[SOME_CONST]; +}; + +typedef struct some_struct_s SOME_ARRAY[SOME_CONST]; struct A0; struct A1 {}; @@ -303,10 +367,10 @@ typedef char *(*A11)[3]; typedef struct A0 *A111[12]; typedef int - **(*A12)(int, int b, int *c, int *, int *count[4], int (*func)(int, int)), + **(*A12)(int, int b, int *c, int *, int /*out*/ *count[4], int (*func)(int, int)), **(*A121)(float, float b, float *c, float *, float *count[4], float (*func)(float, float)), **(*A122)(char, char b, char *c, char *, char *count[4], char (*func)(char, char)); -typedef int A13(int, int, void (*func)(void)); +typedef int (*A13)(int, int, void (*func)(void)); struct A14 { volatile char a1; }; struct A15 { char *a1; const int *a2[1]; }; @@ -320,6 +384,9 @@ typedef struct A20 { char a1; } A20, A21, *A21p; //Expression typedef struct A22 { const int **f1; int *f2[123+132]; } A22; +// #231 +typedef const char *(*A23)(); + //Unions union U1 {int f1; float f2; }; typedef union U2 { const int **f1; int abc[123+132]; } U2; @@ -403,6 +470,16 @@ void int sqlite3_bind_blob(struct A1*, int, const void*, int n, void(*)(void*)); +// Issue #174 - type name[] => UncheckedArray[type] +int ucArrFunc1(int text[]); +int ucArrFunc2(int text[][5], int (*func)(int text[])); + +typedef int ucArrType1[][5]; +struct ucArrType2 { + float f1[5][5]; + int *f2[][5]; +}; + typedef struct fieldfuncfunc { int *(*func1)(int f1, int *(*sfunc1)(int f1, int *(*ssfunc1)(int f1, ...))); }; @@ -441,6 +518,7 @@ typedef struct { struct { int f1; } f2; struct NT3 { + /* Random comment */ struct { int f1; union NU1 { @@ -469,7 +547,6 @@ struct TestMyInt { }; - #endif #ifdef __cplusplus diff --git a/tests/tast2.nim b/tests/tast2.nim index 124c4e4..3f626ae 100644 --- a/tests/tast2.nim +++ b/tests/tast2.nim @@ -333,6 +333,10 @@ checkPragmas(A22, pHeaderBy, istype = false) var a22: A22 a22.f1 = addr a15.a2[0] +assert A23 is proc(): cstring {.cdecl.} +checkPragmas(A23, pHeaderImp & "cdecl") +var a23: A23 + assert U1 is object assert sizeof(U1) == sizeof(cfloat) checkPragmas(U1, pHeaderBy & @["union"], istype = false) From e44ab30af97b8aceefc2568a83fb59c3e5ac21cd Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 23 Jun 2020 12:48:18 -0500 Subject: [PATCH 531/593] Fix rebase issues --- nimterop/build/conan.nim | 2 -- tests/getheader.nims | 13 ++++++------- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/nimterop/build/conan.nim b/nimterop/build/conan.nim index 7e1bd8e..3430752 100644 --- a/nimterop/build/conan.nim +++ b/nimterop/build/conan.nim @@ -387,8 +387,6 @@ proc downloadConan*(pkg: ConanPackage, outdir: string, main = true) = cleanDir(outdir) - echo &"# Downloading {pkg.name} v{pkg.version} from Conan" - pkg.getConanBuilds() doAssert pkg.recipes.len != 0, &"Failed to download {pkg.name} v{pkg.version} from Conan - check https://conan.io/center" diff --git a/tests/getheader.nims b/tests/getheader.nims index 2fe4d9c..916abcf 100644 --- a/tests/getheader.nims +++ b/tests/getheader.nims @@ -25,8 +25,8 @@ when (NimMajor, NimMinor, NimPatch) >= (1, 2, 0): cmd &= " --gc:arc" testCall(cmd & lrcmd, "No build files found", 1) -testCall(cmd & " -d:libssh2Conan" & sshcmd, "Need version for Conan uri", 1) -testCall(cmd & " -d:libssh2JBB" & sshcmd, "Need version for BinaryBuilder.org uri", 1) +testCall(cmd & " -d:libssh2Conan" & sshcmd, "Need version for Conan.io uri", 1) +testCall(cmd & " -d:libssh2JBB -d:libssh2SetVer=1.9.0" & sshcmd, "Version in both uri", 1) when defined(posix): # stdlib @@ -43,17 +43,15 @@ when defined(posix): # conan static testCall(cmd & " -d:libssh2Conan -d:libssh2SetVer=1.9.0 -d:libssh2Static" & sshcmd, zexp, 0) -<<<<<<< HEAD else: # conan static for Windows testCall(cmd & " -d:zlibConan -d:zlibSetVer=1.2.11 -d:zlibStatic" & zrcmd, zexp, 0) # JBB -testCall(cmd & " -d:libssh2JBB -d:libssh2SetVer=1.9.0" & sshcmd, zexp, 0) +testCall(cmd & " -d:libssh2JBB" & sshcmd, zexp, 0) testCall(cmd & " -d:zlibJBB -d:zlibSetVer=1.2.11" & zrcmd, zexp, 0) -testCall(cmd & " -d:zlibJBB -d:zlibSetVer=1.2.11 -d:zlibStatic" & zrcmd, zexp, 0) -======= ->>>>>>> c35eb74... Add tests for conan, recurse implies preprocess +testCall(cmd & " -d:zlibJBB -d:zlibSetVer=1.2.11 -d:zlibStatic" & zrcmd, zexp, 0, delete = false) +testCall(cmd & " -d:lzmaJBB -d:lzmaSetVer=5.2.4" & lrcmd, lexp & "5.2.4", 0) # git testCall(cmd & " -d:envTest" & zrcmd, zexp, 0) @@ -74,3 +72,4 @@ testCall(cmd & " -d:zlibDL -d:zlibStatic -d:zlibSetVer=1.2.11" & zrcmd, zexp & " # conan testCall(cmd & " -d:libssh2Conan -d:libssh2SetVer=1.9.0" & sshcmd, zexp, 0) +testCall(cmd & " -d:lzmaConan -d:lzmaSetVer=5.2.4" & lrcmd, lexp & "5.2.4", 0) \ No newline at end of file From a8ea96055d9d1276fff401ffb1866e1f34d6bc46 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 23 Jun 2020 23:20:15 -0500 Subject: [PATCH 532/593] dynlib allow path, don't delete project, fix proc inline comment --- CHANGES.md | 1 + README.md | 2 +- nimterop/build/getheader.nim | 6 ++++++ nimterop/toast.nim | 2 +- nimterop/toastlib/ast2.nim | 5 ++++- nimterop/toastlib/tshelp.nim | 8 +++++++- 6 files changed, 20 insertions(+), 4 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index cedf5a5..bf4b50a 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -27,6 +27,7 @@ https://github.com/nimterop/nimterop/compare/v0.5.9...v0.6.0 - `getHeader()` now detects and links against `.lib` files as part of enabling Conan.io. Not all `.lib` files are compatible with MinGW as already stated above but for those that work, this is a required capability. +- The `dynlib` command line parameter to `toast` and `cImport()` can also be the path to a shared library (dll|so|dylib) in place of a Nim const string containing the path. This allows for the traditional use case of passing `"xxxLPath"` to `cImport()` as well as simply passing the path to the library on the command line as is. This allows the creation of standalone cached wrappers as well as the usage of the `--check` and the `--stub` functionality that `toast` provides via `cImport()`. ## Version 0.5.0 diff --git a/README.md b/README.md index ca17b90..af8501a 100644 --- a/README.md +++ b/README.md @@ -217,7 +217,7 @@ Options: -C=, --convention= string "cdecl" calling convention for wrapped procs -d, --debug bool false enable debug output -D=, --defines= strings {} definitions to pass to preprocessor - -l=, --dynlib= string "" import symbols from library in specified Nim string + -l=, --dynlib= string "" {.dynlib.} pragma to import symbols - Nim const string or file path -f=, --feature= Features ast1 flags to enable experimental features -I=, --includeDirs= strings {} include directory to pass to preprocessor -m=, --mode= string "" language parser: c or cpp diff --git a/nimterop/build/getheader.nim b/nimterop/build/getheader.nim index 3852fbf..69741b0 100644 --- a/nimterop/build/getheader.nim +++ b/nimterop/build/getheader.nim @@ -392,6 +392,12 @@ macro getHeader*( else: getLocalPath(header, outdir) + static: + # Don't delete project + when not `nameStd` and (`nameGit` or `nameDL` or `nameConan` or `nameJBB`): + doAssert `outdir`.len != 0, "getHeader():outdir cannot be blank" + doAssert `outdir` != getProjectPath(), "getHeader():outdir cannot be the project path" + const `version`* {.strdefine.} = `verVal` `lname` = diff --git a/nimterop/toast.nim b/nimterop/toast.nim index 495e5d1..e8e14cc 100644 --- a/nimterop/toast.nim +++ b/nimterop/toast.nim @@ -240,7 +240,7 @@ when isMainModule: "convention": "calling convention for wrapped procs", "debug": "enable debug output", "defines": "definitions to pass to preprocessor", - "dynlib": "import symbols from library in specified Nim string", + "dynlib": "{.dynlib.} pragma to import symbols - Nim const string or file path", "feature": "flags to enable experimental features", "includeDirs": "include directory to pass to preprocessor", "mode": "language parser: c or cpp", diff --git a/nimterop/toastlib/ast2.nim b/nimterop/toastlib/ast2.nim index 701b0b4..0016e29 100644 --- a/nimterop/toastlib/ast2.nim +++ b/nimterop/toastlib/ast2.nim @@ -1805,7 +1805,10 @@ proc setupPragmas(gState: State, root: TSNode, fullpath: string) = # {.pragma: impnameDyn, dynlib: libname.} let dynPragma = gState.newPragma(root, "pragma", gState.getIdent(gState.impShort & "Dyn")) - gState.addPragma(root, dynPragma, "dynlib", gState.getIdent(gState.dynlib)) + if '.' in gState.dynlib: + gState.addPragma(root, dynPragma, "dynlib", newStrNode(nkStrLit, gState.dynlib)) + else: + gState.addPragma(root, dynPragma, "dynlib", gState.getIdent(gState.dynlib)) gState.pragmaSection.add dynPragma count += 1 diff --git a/nimterop/toastlib/tshelp.nim b/nimterop/toastlib/tshelp.nim index b055259..e7e8d75 100644 --- a/nimterop/toastlib/tshelp.nim +++ b/nimterop/toastlib/tshelp.nim @@ -154,7 +154,13 @@ proc firstChildInTree*(node: TSNode, ntype: string): TSNode = while not cnode.isNil: if cnode.getName() == ntype: return cnode - cnode = cnode[0] + if cnode.len != 0: + for i in 0 ..< cnode.len: + if cnode[i].getName() != "comment": + cnode = cnode[i] + break + else: + cnode = cnode[0] proc anyChildInTree*(node: TSNode, ntype: string): TSNode = # Search for node type anywhere in tree - depth first From d126e9944fee992f46bd51d2f65f3db752249163 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 24 Jun 2020 10:37:38 -0500 Subject: [PATCH 533/593] Remove legacy backend --- CHANGES.md | 2 + README.md | 9 +- nimterop.nimble | 13 +- nimterop/build.nim | 8 +- nimterop/build/getheader.nim | 3 +- nimterop/build/shell.nim | 3 +- nimterop/build/tools.nim | 9 +- nimterop/globals.nim | 27 +- nimterop/toast.nim | 39 +- nimterop/toastlib/ast.nim | 253 ----------- nimterop/toastlib/getters.nim | 125 ------ nimterop/toastlib/grammar.nim | 768 ---------------------------------- nimterop/toastlib/lisp.nim | 60 --- nimterop/toastlib/tshelp.nim | 1 - tests/getheader.nims | 2 +- tests/libssh2.nim | 4 +- tests/rsa.nim | 2 +- 17 files changed, 33 insertions(+), 1295 deletions(-) delete mode 100644 nimterop/toastlib/ast.nim delete mode 100644 nimterop/toastlib/grammar.nim delete mode 100644 nimterop/toastlib/lisp.nim diff --git a/CHANGES.md b/CHANGES.md index bf4b50a..93bb8af 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -19,6 +19,8 @@ https://github.com/nimterop/nimterop/compare/v0.5.9...v0.6.0 ### Breaking changes +- The legacy algorithm has been removed as promised. `ast2` is now the default and wrappers no longer need to explicitly specify `-f:ast2` in order to use it. + - All shared libraries installed by `getHeader()` will now get copied into the `libdir` parameter specified. If left blank, `libdir` will default to the directory where the executable binary gets created (outdir). While this is not really a breaking change, it is a change in behavior compared to older versions of nimterop. Note that `Std` libraries are not copied over. [#154](i154) - `git.nim` has been removed. This module was an artifact from the early days and was renamed to `build.nim` back in v0.2.0. diff --git a/README.md b/README.md index af8501a..b054d97 100644 --- a/README.md +++ b/README.md @@ -177,13 +177,13 @@ Now that this is understood, a user might want any combination of the above in t - By default, generated wrappers will include the `{.header, importc.}` pragmas for types and procs. This can be disabled with the `--noHeader | -H` flag to `toast` or `flags = "-H"` param to `cImport()` which will remove `{.header}` for both and `{.importc.}` for types only. - By default, generated wrappers will assume that the user will link the library implementation themselves. The `--dynlib | -l` flag to `toast` or `dynlib = "headerLPath"` param to `cImport()` will configure the wrapper to generate `{.dynlib.}` pragmas for procs. -This results in four cases: +This results in four supported cases: 1. Default: `{.header, importc.}` for both types and procs 2. With `--noHeader`, types will be pure Nim and procs will be just `{.importc.}` 3. With `--dynlib`, types will still be `{.header, importc.}` but procs will be `{.dynlib, importc.}` 4. With `--dynlib` and `--noHeader`, types will be pure Nim, procs will be `{.dynlib, importc.}` -While `ast2` supports all these modes, the legacy backend does not support the third mixed case and will infer `--noHeader` when `--dynlib` is specified (case 4). Creation of a standalone wrapper (case 4) which does not require the header or library at compile time will require an explicit `--noHeader` and `--dynlib` for `ast2`. +Creation of a standalone wrapper (case 4) which does not require the header or library at compile time will require an explicit `--noHeader` and `--dynlib`. More documentation on on these pragmas can be found in the Nim manual: - [{.importc.}](https://nim-lang.org/docs/manual.html#foreign-function-interface-importc-pragma) @@ -218,7 +218,7 @@ Options: -d, --debug bool false enable debug output -D=, --defines= strings {} definitions to pass to preprocessor -l=, --dynlib= string "" {.dynlib.} pragma to import symbols - Nim const string or file path - -f=, --feature= Features ast1 flags to enable experimental features + -f=, --feature= Features {} flags to enable experimental features -I=, --includeDirs= strings {} include directory to pass to preprocessor -m=, --mode= string "" language parser: c or cpp --nim= string "nim" use a particular Nim executable @@ -226,12 +226,11 @@ Options: -H, --noHeader bool false skip {.header.} pragma in wrapper -o=, --output= string "" file to output content - default: stdout -a, --past bool false print AST output - -g, --pgrammar bool false print grammar --pluginSourcePath= string "" nim file to build and load as a plugin -n, --pnim bool false print Nim output -E=, --prefix= strings {} strip prefix from identifiers -p, --preprocess bool false run preprocessor on header - -r, --recurse bool false process #include files, implies --preprocess + -r, --recurse bool false process #include files - implies --preprocess -G=, --replace= strings {} replace X with Y in identifiers, X1=Y1,X2=Y2, @X for regex -s, --stub bool false stub out undefined type references as objects -F=, --suffix= strings {} strip suffix from identifiers diff --git a/nimterop.nimble b/nimterop.nimble index 1657aed..7be89c6 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -1,6 +1,6 @@ # Package -version = "0.5.9" +version = "0.6.0" author = "genotrance" description = "C/C++ interop for Nim" license = "MIT" @@ -55,15 +55,12 @@ task test, "Test": execTest "tests/tast2.nim", "-d:NOHEADER" execTest "tests/tnimterop_c.nim" - execTest "tests/tnimterop_c.nim", "-d:FLAGS=\"-f:ast2\"" - execTest "tests/tnimterop_c.nim", "-d:FLAGS=\"-f:ast2 -H\"" + execTest "tests/tnimterop_c.nim", "-d:FLAGS=\"-H\"" execCmd "nim cpp --hints:off -f -r tests/tnimterop_cpp.nim" execCmd "./nimterop/toast tests/toast.cfg tests/include/toast.h" - execCmd "./nimterop/toast tests/toast.cfg -f:ast2 tests/include/toast.h" execTest "tests/tpcre.nim" - execTest "tests/tpcre.nim", "-d:FLAGS=\"-f:ast2\"" when defined(Linux): execTest "tests/rsa.nim" @@ -72,12 +69,10 @@ task test, "Test": # Platform specific tests when defined(Windows): execTest "tests/tmath.nim" - execTest "tests/tmath.nim", "-d:FLAGS=\"-f:ast2\"" - execTest "tests/tmath.nim", "-d:FLAGS=\"-f:ast2 -H\"" + execTest "tests/tmath.nim", "-d:FLAGS=\"-H\"" if defined(OSX) or defined(Windows) or not existsEnv("TRAVIS"): execTest "tests/tsoloud.nim" - execTest "tests/tsoloud.nim", "-d:FLAGS=\"-f:ast2\"" - execTest "tests/tsoloud.nim", "-d:FLAGS=\"-f:ast2 -H\"" + execTest "tests/tsoloud.nim", "-d:FLAGS=\"-H\"" # getHeader tests withDir("tests"): diff --git a/nimterop/build.nim b/nimterop/build.nim index 0754615..672cb58 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -14,12 +14,6 @@ var gNimExe* = "" # Misc helpers -proc echoDebug(str: string) = - let str = "\n# " & str.strip().replace("\n", "\n# ") - when nimvm: - if gDebugCT: echo str - else: - if gDebug: echo str proc sanitizePath*(path: string, noQuote = false, sep = $DirSep): string = result = path.multiReplace([("\\\\", sep), ("\\", sep), ("/", sep)]) @@ -34,7 +28,7 @@ proc getCurrentNimCompiler*(): string = else: result = gNimExe -template fixOutDir() {.dirty.} = +template fixOutDir() {.dirty, used.} = let outdir = if outdir.isAbsolute(): outdir else: getProjectDir() / outdir diff --git a/nimterop/build/getheader.nim b/nimterop/build/getheader.nim index 69741b0..216b599 100644 --- a/nimterop/build/getheader.nim +++ b/nimterop/build/getheader.nim @@ -178,7 +178,6 @@ proc getLocalPath(header, outdir: string): string = proc buildLibrary(lname, outdir, conFlags, cmakeFlags, makeFlags: string, buildTypes: openArray[BuildType]): string = var lpath = findFile(lname, outdir, regex = true) - makeFlagsProc = &"-j {getNumProcs()} {makeFlags}" makePath = outdir if lpath.len != 0: @@ -200,7 +199,7 @@ proc buildLibrary(lname, outdir, conFlags, cmakeFlags, makeFlags: string, buildT let libraryExists = findFile(lname, buildStatus.buildPath, regex = true).len > 0 if not libraryExists and fileExists(buildStatus.buildPath / "Makefile"): - make(buildStatus.buildPath, lname, makeFlagsProc, regex = true) + make(buildStatus.buildPath, lname, makeFlags, regex = true) buildStatus.built = true let error = if buildStatus.error.len > 0: buildStatus.error else: "No build files found in " & outdir diff --git a/nimterop/build/shell.nim b/nimterop/build/shell.nim index 5179798..bc07285 100644 --- a/nimterop/build/shell.nim +++ b/nimterop/build/shell.nim @@ -455,7 +455,8 @@ proc linkLibs*(names: openArray[string], staticLink = true): string = for res in resSet: result &= " " & res -proc getNumProcs(): string = +proc getNumProcs*(): string = + ## Get number of processors when defined(Windows): getEnv("NUMBER_OF_PROCESSORS").strip() elif defined(linux): diff --git a/nimterop/build/tools.nim b/nimterop/build/tools.nim index 772c48b..c6a4283 100644 --- a/nimterop/build/tools.nim +++ b/nimterop/build/tools.nim @@ -9,6 +9,13 @@ type buildPath: string error: string +proc echoDebug(str: string) = + let str = "\n# " & str.strip().replace("\n", "\n# ") + when nimvm: + if gDebugCT: echo str + else: + if gDebug: echo str + proc configure*(path, check: string, flags = "") = ## Run the GNU `configure` command to generate all Makefiles or other ## build scripts in the specified path @@ -193,7 +200,7 @@ proc make*(path, check: string, flags = "", regex = false) = cpFile(cmd, cmd.replace("mingw32-make", "make")) doAssert cmd.len != 0, "Make not found" - cmd = &"cd {path.sanitizePath} && make" + cmd = &"cd {path.sanitizePath} && make -j {getNumProcs()}" if flags.len != 0: cmd &= &" {flags}" diff --git a/nimterop/globals.nim b/nimterop/globals.nim index c79f4a5..fa8f8de 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -3,8 +3,6 @@ import tables when defined(TOAST): import sets, sequtils, strutils - import regex - import "."/plugin import compiler/[ast, idents, modulegraphs, options] @@ -13,7 +11,7 @@ when defined(TOAST): type Feature* = enum - ast1, ast2 + ast2 State* = ref object # Command line arguments to toast - some forwarded from cimport.nim @@ -72,12 +70,6 @@ type # Controls whether or not the current expression # should validate idents against currently defined idents skipIdentValidation*: bool - - # Legacy AST fields, remove when ast2 becomes default - constStr*, enumStr*, procStr*, typeStr*: string - commentStr*, debugStr*, skipStr*: string - data*: seq[tuple[name, val: string]] - nodeBranch*: seq[string] else: # cimport.nim specific compile*: seq[string] # `cCompile()` list of files already processed @@ -114,23 +106,6 @@ when defined(TOAST): ].concat(toSeq(gExpressions.items)) type - Kind* = enum - exactlyOne - oneOrMore # + - zeroOrMore # * - zeroOrOne # ? - orWithNext # ! - - Ast* = object - name*: string - kind*: Kind - recursive*: bool - children*: seq[ref Ast] - tonim*: proc (ast: ref Ast, node: TSNode, gState: State) - regex*: Regex - - AstTable* {.used.} = TableRef[string, seq[ref Ast]] - Status* = enum success, unknown, error diff --git a/nimterop/toast.nim b/nimterop/toast.nim index e8e14cc..b7a993a 100644 --- a/nimterop/toast.nim +++ b/nimterop/toast.nim @@ -4,9 +4,9 @@ import "."/treesitter/[api, c, cpp] import "."/[build, globals] -import "."/toastlib/[ast, ast2, getters, grammar, tshelp] +import "."/toastlib/[ast2, getters, tshelp] -proc process(gState: State, path: string, astTable: AstTable) = +proc process(gState: State, path: string) = doAssert existsFile(path), &"Invalid path {path}" if gState.mode.Bl: @@ -21,10 +21,7 @@ proc process(gState: State, path: string, astTable: AstTable) = if gState.past: gecho gState.printLisp(root) elif gState.pnim: - if Feature.ast2 in gState.feature: - ast2.parseNim(gState, path, root) - elif Feature.ast1 in gState.feature: - ast.parseNim(gState, path, root, astTable) + parseNim(gState, path, root) elif gState.preprocess: gecho gState.code @@ -43,7 +40,6 @@ proc main( noHeader = false, output = "", past = false, - pgrammar = false, pluginSourcePath: string = "", pnim = false, prefix: seq[string] = @[], @@ -84,10 +80,6 @@ proc main( build.gDebug = gState.debug build.gNimExe = gState.nim - # Default `ast` mode - if gState.feature.Bl: - gState.feature.add Feature.ast1 - # Split some arguments with , gState.symOverride = gState.symOverride.getSplitComma() gState.prefix = gState.prefix.getSplitComma() @@ -137,31 +129,14 @@ proc main( if gState.debug: echo &"# Writing output to {outputFile}\n" - # Process grammar into AST - let - astTable = - if Feature.ast1 in gState.feature: - parseGrammar() - else: - nil - - if pgrammar: - if Feature.ast1 in gState.feature: - # Print AST of grammar - gState.printGrammar(astTable) - elif source.nBl: + if source.nBl: # Print source after preprocess or Nim output if gState.pnim: gState.initNim() for src in source: - gState.process(src.expandSymlinkAbs(), astTable) + gState.process(src.expandSymlinkAbs()) if gState.pnim: - if Feature.ast2 in gState.feature: - ast2.printNim(gState) - elif Feature.ast1 in gState.feature: - ast.printNim(gState) - gecho """{.hint: "The legacy wrapper generation algorithm is deprecated and will be removed in the next release of Nimterop.".}""" - gecho """{.hint: "Refer to CHANGES.md for details on migrating to the new backend.".}""" + printNim(gState) # Close outputFile if outputFile.len != 0: @@ -249,7 +224,6 @@ when isMainModule: "noHeader": "skip {.header.} pragma in wrapper", "output": "file to output content - default: stdout", "past": "print AST output", - "pgrammar": "print grammar", "pluginSourcePath": "nim file to build and load as a plugin", "pnim": "print Nim output", "prefix": "strip prefix from identifiers", @@ -273,7 +247,6 @@ when isMainModule: "noHeader": 'H', "output": 'o', "past": 'a', - "pgrammar": 'g', "pnim": 'n', "prefix": 'E', "preprocess": 'p', diff --git a/nimterop/toastlib/ast.nim b/nimterop/toastlib/ast.nim deleted file mode 100644 index 0b62a34..0000000 --- a/nimterop/toastlib/ast.nim +++ /dev/null @@ -1,253 +0,0 @@ -import hashes, macros, os, sets, strformat, strutils, tables - -import regex - -import ".."/[globals, treesitter/api] -import "."/[getters, tshelp] - -proc getHeaderPragma*(gState: State): string = - result = - if not gState.noHeader and gState.dynlib.Bl: - &", header: {gState.currentHeader}" - else: - "" - -proc getDynlib*(gState: State): string = - result = - if gState.dynlib.nBl: - &", dynlib: {gState.dynlib}" - else: - "" - -proc getImportC*(gState: State, origName, nimName: string): string = - if nimName != origName: - result = &"importc: \"{origName}\"{gState.getHeaderPragma()}" - else: - result = gState.impShort - -proc getPragma*(gState: State, pragmas: varargs[string]): string = - result = "" - for pragma in pragmas.items(): - if pragma.nBl: - result &= pragma & ", " - if result.nBl: - result = " {." & result[0 .. ^3] & ".}" - - result = result.replace(gState.impShort & ", cdecl", gState.impShort & "C") - - let - dy = gState.getDynlib() - - if ", cdecl" in result and dy.nBl: - result = result.replace(".}", dy & ".}") - -proc saveNodeData(node: TSNode, gState: State): bool = - let name = $node.tsNodeType() - - # Atoms are nodes whose values are to be saved - if name in gAtoms: - let - pname = node.getPxName(1) - ppname = node.getPxName(2) - pppname = node.getPxName(3) - ppppname = node.getPxName(4) - - var - val = gState.getNodeVal(node) - - # Skip since value already obtained from parent atom - if name == "primitive_type" and pname == "sized_type_specifier": - return true - - # Skip since value already obtained from parent expression - if name in ["number_literal", "identifier"] and pname in gExpressions: - return true - - # Add reference point in saved data for bitfield_clause - if name in ["number_literal"] and pname == "bitfield_clause": - gState.data.add(("bitfield_clause", val)) - return true - - # Process value as a type - if name in ["primitive_type", "sized_type_specifier"]: - val = val.getType() - - if node.tsNodePrevNamedSibling().tsNodeIsNull(): - if pname == "pointer_declarator": - if ppname notin ["function_declarator", "array_declarator"]: - gState.data.add(("pointer_declarator", "")) - elif ppname == "array_declarator": - gState.data.add(("array_pointer_declarator", "")) - - # Double pointer - if ppname == "pointer_declarator": - gState.data.add(("pointer_declarator", "")) - elif pname in ["function_declarator", "array_declarator"]: - if ppname == "pointer_declarator": - gState.data.add(("pointer_declarator", "")) - if pppname == "pointer_declarator": - gState.data.add(("pointer_declarator", "")) - - gState.data.add((name, val)) - - if pname == "pointer_declarator" and - ppname == "function_declarator": - if name == "field_identifier": - if pppname == "pointer_declarator": - gState.data.insert(("pointer_declarator", ""), gState.data.len-1) - if ppppname == "pointer_declarator": - gState.data.insert(("pointer_declarator", ""), gState.data.len-1) - gState.data.add(("function_declarator", "")) - elif name == "identifier": - gState.data.add(("pointer_declarator", "")) - - # Save node value for a top-level expression - elif name in gExpressions and name != "escape_sequence": - if $node.tsNodeParent.tsNodeType() notin gExpressions: - gState.data.add((name, gState.getNodeVal(node))) - - elif name in ["abstract_pointer_declarator", "enumerator", "field_declaration", "function_declarator"]: - gState.data.add((name.replace("abstract_", ""), "")) - - return true - -proc searchAstForNode(ast: ref Ast, node: TSNode, gState: State): bool = - let - childNames = node.getTSNodeNamedChildNames().join() - - if ast.isNil: - return - - if gState.debug: - gState.nodeBranch.add $node.tsNodeType() - gecho "#" & spaces(gState.nodeBranch.len * 2) & gState.nodeBranch[^1] - - if ast.children.nBl: - if childNames.contains(ast.regex) or - (childNames.Bl and ast.recursive): - if node.getTSNodeNamedChildCountSansComments() != 0: - var flag = true - - for i in 0 .. node.tsNodeNamedChildCount()-1: - if $node.tsNodeNamedChild(i).tsNodeType() != "comment": - let - nodeChild = node.tsNodeNamedChild(i) - astChild = - if not ast.recursive: - ast.getAstChildByName($nodeChild.tsNodeType()) - else: - ast - - if not searchAstForNode(astChild, nodeChild, gState): - flag = false - break - - if flag: - result = node.saveNodeData(gState) - else: - result = node.saveNodeData(gState) - else: - if gState.debug: - gecho "#" & spaces(gState.nodeBranch.len * 2) & &" {ast.getRegexForAstChildren()} !=~ {childNames}" - elif node.getTSNodeNamedChildCountSansComments() == 0: - result = node.saveNodeData(gState) - - if gState.debug: - discard gState.nodeBranch.pop() - if gState.nodeBranch.Bl: - gecho "" - -proc searchAst(root: TSNode, astTable: AstTable, gState: State) = - var - node = root - nextnode: TSNode - depth = 0 - - while true: - if not node.tsNodeIsNull() and depth > -1: - let - name = $node.tsNodeType() - if name in astTable: - for ast in astTable[name]: - if gState.debug: - gecho "\n# " & gState.getNodeVal(node).replace("\n", "\n# ") & "\n" - if searchAstForNode(ast, node, gState): - ast.tonim(ast, node, gState) - if gState.debug: - gState.debugStr &= "\n# " & gState.data.join("\n# ") & "\n" - break - gState.data = @[] - else: - break - - if $node.tsNodeType() notin astTable and node.tsNodeNamedChildCount() != 0: - nextnode = node.tsNodeNamedChild(0) - depth += 1 - else: - nextnode = node.tsNodeNextNamedSibling() - - if nextnode.tsNodeIsNull(): - while true: - node = node.tsNodeParent() - depth -= 1 - if depth == -1: - break - if node == root: - break - if not node.tsNodeNextNamedSibling().tsNodeIsNull(): - node = node.tsNodeNextNamedSibling() - break - else: - node = nextnode - - if node == root: - break - -proc parseNim*(gState: State, fullpath: string, root: TSNode, astTable: AstTable) = - # Generate Nim from tree-sitter AST root node - var - fp = fullpath.replace("\\", "/") - - gState.currentHeader = getCurrentHeader(fullpath) - gState.impShort = gState.currentHeader.replace("header", "imp") - gState.sourceFile = fullpath - - if not gState.noHeader and gState.dynlib.Bl: - gState.constStr &= &"\n {gState.currentHeader} {{.used.}} = \"{fp}\"" - - root.searchAst(astTable, gState) - -proc printNim*(gState: State) = - # Print Nim generated by parseNim() - if gState.enumStr.nBl: - gecho &"{gState.enumStr}\n" - - gState.constStr = gState.getOverrideFinal(nskConst) & gState.constStr - if gState.constStr.nBl: - gecho &"const{gState.constStr}\n" - - gecho &""" -{{.pragma: {gState.impShort}, importc{gState.getHeaderPragma()}.}} -{{.pragma: {gState.impShort}C, {gState.impShort}, cdecl{gState.getDynlib()}.}} -""" - - gState.typeStr = gState.getOverrideFinal(nskType) & gState.typeStr - if gState.typeStr.nBl: - gecho &"type{gState.typeStr}\n" - - gState.procStr = gState.getOverrideFinal(nskProc) & gState.procStr - if gState.procStr.nBl: - gecho &"{gState.procStr}\n" - - gecho "{.pop.}" - - if gState.debug: - if gState.debugStr.nBl: - gecho gState.debugStr - - if gState.skipStr.nBl: - let - hash = gState.skipStr.hash().abs() - sname = getTempDir() / &"nimterop_{$hash}.h" - gecho &"# Writing skipped definitions to {sname}\n" - writeFile(sname, gState.skipStr) diff --git a/nimterop/toastlib/getters.nim b/nimterop/toastlib/getters.nim index b4070f3..0c1b784 100644 --- a/nimterop/toastlib/getters.nim +++ b/nimterop/toastlib/getters.nim @@ -304,131 +304,6 @@ proc getPreprocessor*(gState: State, fullpath: string) = rdata.add line gState.code = rdata.join("\n") -converter toString*(kind: Kind): string = - return case kind: - of exactlyOne: - "" - of oneOrMore: - "+" - of zeroOrMore: - "*" - of zeroOrOne: - "?" - of orWithNext: - "!" - -converter toKind*(kind: string): Kind = - return case kind: - of "+": - oneOrMore - of "*": - zeroOrMore - of "?": - zeroOrOne - of "!": - orWithNext - else: - exactlyOne - -proc getNameKind*(name: string): tuple[name: string, kind: Kind, recursive: bool] = - if name[0] == '^': - result.recursive = true - result.name = name[1 .. ^1] - else: - result.name = name - result.kind = $name[^1] - - if result.kind != exactlyOne: - result.name = result.name[0 .. ^2] - -proc getRegexForAstChildren*(ast: ref Ast): string = - result = "^" - for i in 0 .. ast.children.len-1: - let - kind: string = ast.children[i].kind - begin = if result[^1] == '|': "" else: "(?:" - case kind: - of "!": - result &= &"{begin}{ast.children[i].name}|" - else: - result &= &"{begin}{ast.children[i].name}){kind}" - result &= "$" - -proc getAstChildByName*(ast: ref Ast, name: string): ref Ast = - for i in 0 .. ast.children.len-1: - if name in ast.children[i].name.split("|"): - return ast.children[i] - - if ast.children.len == 1 and ast.children[0].name == ".": - return ast.children[0] - -proc getNimExpression*(gState: State, expr: string, name = ""): string = - # Convert C/C++ expression into Nim - cast identifiers to `name` if specified - var - clean = expr.multiReplace([("\n", " "), ("\r", "")]) - ident = "" - gen = "" - hex = false - - for i in 0 .. clean.len: - if i != clean.len: - if clean[i] in IdentChars: - if clean[i] in Digits and ident.Bl: - # Identifiers cannot start with digits - gen = $clean[i] - elif clean[i] in HexDigits and hex == true: - # Part of a hex number - gen = $clean[i] - elif i > 0 and i < clean.len-1 and clean[i] in ['x', 'X'] and - clean[i-1] == '0' and clean[i+1] in HexDigits: - # Found a hex number - gen = $clean[i] - hex = true - else: - # Part of an identifier - ident &= clean[i] - hex = false - else: - gen = (block: - if (i == 0 or clean[i-1] != '\'') or - (i == clean.len - 1 or clean[i+1] != '\''): - # If unquoted, convert logical ops to Nim - case clean[i] - of '^': " xor " - of '&': " and " - of '|': " or " - of '~': " not " - else: $clean[i] - else: - $clean[i] - ) - hex = false - - if i == clean.len or gen.nBl: - # Process identifier - if ident.nBl: - # Issue #178 - if ident != "_": - ident = gState.getIdentifier(ident, nskConst, name) - if name.nBl and ident in gState.constIdentifiers: - ident = ident & "." & name - result &= ident - ident = "" - result &= gen - gen = "" - - # Convert shift ops to Nim - result = result.multiReplace([ - ("<<", " shl "), (">>", " shr ") - ]) - -proc getComments*(gState: State, strip = false): string = - if not gState.noComments and gState.commentStr.nBl: - result = "\n" & gState.commentStr - if strip: - result = result.replace("\n ", "\n") - gState.commentStr = "" - # Plugin related proc dll*(path: string): string = diff --git a/nimterop/toastlib/grammar.nim b/nimterop/toastlib/grammar.nim deleted file mode 100644 index 52b19e7..0000000 --- a/nimterop/toastlib/grammar.nim +++ /dev/null @@ -1,768 +0,0 @@ -import macros, strformat, strutils, tables - -import regex - -import ".."/[globals, treesitter/api] -import "."/[ast, getters, lisp, tshelp] - -type - Grammar = seq[tuple[grammar: string, call: proc(ast: ref Ast, node: TSNode, gState: State) {.nimcall.}]] - -proc getPtrType(str: string): string = - result = case str: - of "ptr cchar": - "cstring" - of "ptr ptr cchar": - "ptr cstring" - of "ptr object": - "pointer" - of "ptr ptr object": - "ptr pointer" - of "ptr FILE": - "File" - else: - str - -proc getLit(str: string): string = - # Used to convert #define literals into const - let - str = str.replace(re"/[/*].*?(?:\*/)?$", "").strip() - - if str.contains(re"^[\-]?[\d]*[.]?[\d]+$") or # decimal - str.contains(re"^0x[\da-fA-F]+$") or # hexadecimal - str.contains(re"^'[[:ascii:]]'$") or # char - str.contains(re"""^"[[:ascii:]]+"$"""): # char * - return str - -proc initGrammar(): Grammar = - # #define X Y - result.add((""" - (preproc_def - (identifier) - (preproc_arg) - ) - """, - proc (ast: ref Ast, node: TSNode, gState: State) = - if gState.debug: - gState.debugStr &= "\n# define X Y" - - let - name = gState.data[0].val - nname = gState.getIdentifier(name, nskConst) - val = gState.data[1].val.getLit() - - if not nname.nBl: - let - override = gState.getOverride(name, nskConst) - if override.nBl: - gState.constStr &= &"{gState.getComments()}\n{override}" - else: - gState.constStr &= &"{gState.getComments()}\n # Const '{name}' skipped" - if gState.debug: - gState.skipStr &= &"\n{gState.getNodeVal(node)}" - elif val.nBl and gState.addNewIdentifer(nname): - gState.constStr &= &"{gState.getComments()}\n {nname}* = {val}" - )) - - let - typeGrammar = """ - (type_qualifier?) - (primitive_type|type_identifier?) - (type_qualifier?) - (sized_type_specifier? - (primitive_type?) - ) - (struct_specifier|union_specifier|enum_specifier? - (type_identifier) - ) - """ - - arrGrammar = &""" - (array_declarator! - (pointer_declarator! - (pointer_declarator! - (type_identifier) - ) - (type_identifier) - ) - (type_identifier|identifier) - (identifier|number_literal) - ) - """ - - paramListGrammar = &""" - (parameter_list - (parameter_declaration* - {typeGrammar} - (identifier|type_identifier?) - (pointer_declarator? - (type_qualifier?) - (pointer_declarator! - (type_qualifier?) - {arrGrammar} - (identifier|type_identifier) - ) - {arrGrammar} - (identifier|type_identifier) - ) - {arrGrammar} - (abstract_pointer_declarator? - (abstract_pointer_declarator?) - ) - ) - ) - """ - - funcGrammar = &""" - (function_declarator* - (identifier|type_identifier!) - (pointer_declarator - (pointer_declarator! - (type_identifier) - ) - (type_identifier|identifier) - ) - {paramListGrammar} - (noexcept|throw_specifier?) - ) - """ - - template funcParamCommon(fname, pname, ptyp, pptr, pout, count, i, flen: untyped): untyped = - ptyp = gState.getIdentifier(gState.data[i].val, nskType, fname).getType() - - pptr = "" - while i+1 < gState.data.len and gState.data[i+1].name == "pointer_declarator": - pptr &= "ptr " - i += 1 - - if i+1 < gState.data.len and gState.data[i+1].name == "identifier": - pname = gState.getIdentifier(gState.data[i+1].val, nskParam, fname) - i += 2 - else: - pname = "a" & $count - count += 1 - i += 1 - - if i < gState.data.len and gState.data[i].name in ["identifier", "number_literal"]: - flen = gState.data[i].val - if gState.data[i].name == "identifier": - flen = gState.getIdentifier(flen, nskConst, fname) - - pout &= &"{pname}: array[{flen}, {getPtrType(pptr&ptyp)}], " - i += 1 - elif pptr.nBl or ptyp != "object": - pout &= &"{pname}: {getPtrType(pptr&ptyp)}, " - - # typedef int X - # typedef X Y - # typedef struct X Y - # typedef ?* Y - result.add((&""" - (type_definition - {typeGrammar} - (type_identifier!) - {arrGrammar} - (pointer_declarator! - (pointer_declarator! - (type_identifier!) - {arrGrammar} - {funcGrammar} - ) - (type_identifier!) - {arrGrammar} - {funcGrammar} - ) - {funcGrammar} - ) - """, - proc (ast: ref Ast, node: TSNode, gState: State) = - if gState.debug: - gState.debugStr &= "\n# typedef X Y" - - var - i = 0 - typ = gState.getIdentifier(gState.data[i].val, nskType, "IgnoreSkipSymbol").getType() - name = "" - nname = "" - tptr = "" - aptr = "" - pragmas: seq[string] = @[] - - i += 1 - while i < gState.data.len and "pointer" in gState.data[i].name: - case gState.data[i].name: - of "pointer_declarator": - tptr &= "ptr " - i += 1 - of "array_pointer_declarator": - aptr &= "ptr " - i += 1 - - if i < gState.data.len: - name = gState.data[i].val - nname = gState.getIdentifier(name, nskType) - i += 1 - - if not gState.noHeader and gState.dynlib.Bl: - pragmas.add gState.getImportC(name, nname) - - let - pragma = gState.getPragma(pragmas) - - if not nname.nBl: - let - override = gState.getOverride(name, nskType) - if override.nBl: - gState.typeStr &= &"{gState.getComments()}\n{override}" - elif nname notin gTypeMap and typ.nBl and gState.addNewIdentifer(nname): - if i < gState.data.len and gState.data[^1].name == "function_declarator": - var - fname = nname - pout, pname, ptyp, pptr = "" - count = 1 - flen = "" - - while i < gState.data.len: - if gState.data[i].name == "function_declarator": - break - - funcParamCommon(fname, pname, ptyp, pptr, pout, count, i, flen) - - if pout.nBl and pout[^2 .. ^1] == ", ": - pout = pout[0 .. ^3] - - if tptr.nBl or typ != "object": - gState.typeStr &= &"{gState.getComments()}\n {nname}*{pragma} = proc({pout}): {getPtrType(tptr&typ)} {{.cdecl.}}" - else: - gState.typeStr &= &"{gState.getComments()}\n {nname}*{pragma} = proc({pout}) {{.cdecl.}}" - else: - if i < gState.data.len and gState.data[i].name in ["identifier", "number_literal"]: - var - flen = gState.data[i].val - if gState.data[i].name == "identifier": - flen = gState.getIdentifier(flen, nskConst, nname) - - gState.typeStr &= &"{gState.getComments()}\n {nname}*{pragma} = {aptr}array[{flen}, {getPtrType(tptr&typ)}]" - else: - if nname == typ: - pragmas.add "incompleteStruct" - let - pragma = gState.getPragma(pragmas) - gState.typeStr &= &"{gState.getComments()}\n {nname}*{pragma} = object" - else: - gState.typeStr &= &"{gState.getComments()}\n {nname}*{pragma} = {getPtrType(tptr&typ)}" - )) - - proc pDupTypeCommon(nname: string, fend: int, gState: State, isEnum=false) = - if gState.debug: - gState.debugStr &= "\n# pDupTypeCommon()" - - var - dname = gState.data[^1].val - ndname = gState.getIdentifier(dname, nskType) - dptr = - if fend == 2: - "ptr " - else: - "" - - if ndname.nBl and ndname != nname: - if isEnum: - if gState.addNewIdentifer(ndname): - gState.enumStr &= &"{gState.getComments(true)}\ntype {ndname}* = {dptr}{nname}" - else: - if gState.addNewIdentifer(ndname): - let - pragma = gState.getPragma(gState.getImportc(dname, ndname), "bycopy") - gState.typeStr &= - &"{gState.getComments()}\n {ndname}*{pragma} = {dptr}{nname}" - - proc pStructCommon(ast: ref Ast, node: TSNode, name: string, fstart, fend: int, gState: State) = - if gState.debug: - gState.debugStr &= "\n# pStructCommon" - - var - nname = gState.getIdentifier(name, nskType) - prefix = "" - union = "" - - case $node.tsNodeType(): - of "struct_specifier": - prefix = "struct " - of "union_specifier": - prefix = "union " - union = ", union" - of "type_definition": - if node.getTSNodeNamedChildCountSansComments() != 0: - for i in 0 .. node.tsNodeNamedChildCount()-1: - let - nchild = $node.tsNodeNamedChild(i).tsNodeType() - if nchild != "comment": - case nchild: - of "struct_specifier": - if fstart == 1: - prefix = "struct " - of "union_specifier": - if fstart == 1: - prefix = "union " - union = ", union" - break - - if not nname.nBl: - let - override = gState.getOverride(name, nskType) - if override.nBl: - gState.typeStr &= &"{gState.getComments()}\n{override}" - elif gState.addNewIdentifer(nname): - if gState.data.len == 1: - gState.typeStr &= &"{gState.getComments()}\n {nname}* {{.bycopy{union}.}} = object" - else: - var - pragmas: seq[string] = @[] - if not gState.noHeader and gState.dynlib.Bl: - pragmas.add gState.getImportC(prefix & name, nname) - pragmas.add "bycopy" - if union.nBl: - pragmas.add "union" - - let - pragma = gState.getPragma(pragmas) - - gState.typeStr &= &"{gState.getComments()}\n {nname}*{pragma} = object" - - var - i = fstart - ftyp, fname: string - fptr = "" - aptr = "" - flen = "" - while i < gState.data.len-fend: - fptr = "" - aptr = "" - if gState.data[i].name == "field_declaration": - i += 1 - continue - - if gState.data[i].name notin ["field_identifier", "pointer_declarator", "array_pointer_declarator"]: - ftyp = gState.getIdentifier(gState.data[i].val, nskType, nname).getType() - i += 1 - - while i < gState.data.len-fend and "pointer" in gState.data[i].name: - case gState.data[i].name: - of "pointer_declarator": - fptr &= "ptr " - i += 1 - of "array_pointer_declarator": - aptr &= "ptr " - i += 1 - - fname = gState.getIdentifier(gState.data[i].val, nskField, nname) - - if i+1 < gState.data.len-fend and gState.data[i+1].name in gEnumVals: - # Struct field is an array where size is an expression - var - flen = gState.getNimExpression(gState.data[i+1].val) - if "/" in flen: - flen = &"({flen}).int" - gState.typeStr &= &"{gState.getComments()}\n {fname}*: {aptr}array[{flen}, {getPtrType(fptr&ftyp)}]" - i += 2 - elif i+1 < gState.data.len-fend and gState.data[i+1].name == "bitfield_clause": - let - size = gState.data[i+1].val - gState.typeStr &= &"{gState.getComments()}\n {fname}* {{.bitsize: {size}.}} : {getPtrType(fptr&ftyp)} " - i += 2 - elif i+1 < gState.data.len-fend and gState.data[i+1].name == "function_declarator": - var - pout, pname, ptyp, pptr = "" - count = 1 - - i += 2 - while i < gState.data.len-fend: - if gState.data[i].name == "function_declarator": - i += 1 - continue - - if gState.data[i].name == "field_declaration": - break - - funcParamCommon(fname, pname, ptyp, pptr, pout, count, i, flen) - - if pout.nBl and pout[^2 .. ^1] == ", ": - pout = pout[0 .. ^3] - if fptr.nBl or ftyp != "object": - gState.typeStr &= &"{gState.getComments()}\n {fname}*: proc({pout}): {getPtrType(fptr&ftyp)} {{.cdecl.}}" - else: - gState.typeStr &= &"{gState.getComments()}\n {fname}*: proc({pout}) {{.cdecl.}}" - i += 1 - else: - if ftyp == "object": - gState.typeStr &= &"{gState.getComments()}\n {fname}*: pointer" - else: - gState.typeStr &= &"{gState.getComments()}\n {fname}*: {getPtrType(fptr&ftyp)}" - i += 1 - - if node.tsNodeType() == "type_definition" and - gState.data[^1].name == "type_identifier" and gState.data[^1].val.nBl: - pDupTypeCommon(nname, fend, gState, false) - - let - fieldGrammar = &""" - (field_identifier!) - (bitfield_clause! - (number_literal) - ) - (array_declarator! - (field_identifier!) - (pointer_declarator - (pointer_declarator! - (field_identifier) - ) - (field_identifier) - ) - (^$1+) - ) - (function_declarator+ - (pointer_declarator - (pointer_declarator! - (field_identifier) - ) - (field_identifier) - ) - {paramListGrammar} - ) - """ % gEnumVals.join("|") - - fieldListGrammar = &""" - (field_declaration_list? - (field_declaration+ - {typeGrammar} - (pointer_declarator! - (pointer_declarator! - {fieldGrammar} - ) - {fieldGrammar} - ) - {fieldGrammar} - ) - ) - """ - - # struct X {} - result.add((&""" - (struct_specifier|union_specifier - (type_identifier) - {fieldListGrammar} - ) - """, - proc (ast: ref Ast, node: TSNode, gState: State) = - if gState.debug: - gState.debugStr &= "\n# struct X {}" - - pStructCommon(ast, node, gState.data[0].val, 1, 1, gState) - )) - - # typedef struct X {} - result.add((&""" - (type_definition - (struct_specifier|union_specifier - (type_identifier?) - {fieldListGrammar} - ) - (type_identifier!) - (pointer_declarator - (pointer_declarator! - (type_identifier) - ) - (type_identifier) - ) - ) - """, - proc (ast: ref Ast, node: TSNode, gState: State) = - if gState.debug: - gState.debugStr &= "\n# typedef struct X {}" - - var - fstart = 0 - fend = 1 - - if gState.data[^2].name == "pointer_declarator": - fend = 2 - - if gState.data.len > 1 and - gState.data[0].name == "type_identifier" and - gState.data[1].name notin ["field_identifier", "pointer_declarator"]: - - fstart = 1 - pStructCommon(ast, node, gState.data[0].val, fstart, fend, gState) - else: - pStructCommon(ast, node, gState.data[^1].val, fstart, fend, gState) - )) - - proc pEnumCommon(ast: ref Ast, node: TSNode, name: string, fstart, fend: int, gState: State) = - if gState.debug: - gState.debugStr &= "\n# pEnumCommon()" - - let nname = - if name.Bl: - getUniqueIdentifier(gState, "Enum") - else: - gState.getIdentifier(name, nskType) - - if nname.nBl and gState.addNewIdentifer(nname): - gState.enumStr &= &"{gState.getComments(true)}\ndefineEnum({nname})" - - var - i = fstart - count = 0 - while i < gState.data.len-fend: - if gState.data[i].name == "enumerator": - i += 1 - continue - - let - fname = gState.getIdentifier(gState.data[i].val, nskEnumField) - - if i+1 < gState.data.len-fend and - gState.data[i+1].name in gEnumVals: - if fname.nBl and gState.addNewIdentifer(fname): - gState.constStr &= &"{gState.getComments()}\n {fname}* = ({gState.getNimExpression(gState.data[i+1].val)}).{nname}" - try: - count = gState.data[i+1].val.parseInt() + 1 - except: - count += 1 - i += 2 - else: - if fname.nBl and gState.addNewIdentifer(fname): - gState.constStr &= &"{gState.getComments()}\n {fname}* = {count}.{nname}" - i += 1 - count += 1 - - if node.tsNodeType() == "type_definition" and - gState.data[^1].name == "type_identifier" and gState.data[^1].val.nBl: - pDupTypeCommon(nname, fend, gState, true) - - # enum X {} - result.add((""" - (enum_specifier - (type_identifier?) - (enumerator_list - (enumerator+ - (identifier?) - (^$1+) - ) - ) - ) - """ % gEnumVals.join("|"), - proc (ast: ref Ast, node: TSNode, gState: State) = - if gState.debug: - gState.debugStr &= "\n# enum X {}" - - var - name = "" - offset = 0 - - if gState.data[0].name == "type_identifier": - name = gState.data[0].val - offset = 1 - - pEnumCommon(ast, node, name, offset, 0, gState) - )) - - # typedef enum {} X - result.add((&""" - (type_definition - {result[^1].grammar} - (type_identifier!) - (pointer_declarator - (pointer_declarator! - (type_identifier) - ) - (type_identifier) - ) - ) - """, - proc (ast: ref Ast, node: TSNode, gState: State) = - if gState.debug: - gState.debugStr &= "\n# typedef enum {}" - - var - fstart = 0 - fend = 1 - - if gState.data[^2].name == "pointer_declarator": - fend = 2 - - if gState.data[0].name == "type_identifier": - fstart = 1 - - pEnumCommon(ast, node, gState.data[0].val, fstart, fend, gState) - else: - pEnumCommon(ast, node, gState.data[^1].val, fstart, fend, gState) - )) - - # typ function(typ param1, ...) - result.add((&""" - (declaration - (storage_class_specifier?) - {typeGrammar} - (pointer_declarator! - (pointer_declarator! - {funcGrammar} - ) - {funcGrammar} - ) - {funcGrammar} - ) - """, - proc (ast: ref Ast, node: TSNode, gState: State) = - if gState.debug: - gState.debugStr &= "\n# typ function" - - var - fptr = "" - i = 1 - - while i < gState.data.len: - if gState.data[i].name == "function_declarator": - i += 1 - continue - - fptr = "" - while i < gState.data.len and gState.data[i].name == "pointer_declarator": - fptr &= "ptr " - i += 1 - - var - fname = gState.data[i].val - fnname = gState.getIdentifier(fname, nskProc) - pout, pname, ptyp, pptr = "" - count = 1 - flen = "" - fVar = false - - i += 1 - if i < gState.data.len and gState.data[i].name == "pointer_declarator": - fVar = true - i += 1 - - while i < gState.data.len: - if gState.data[i].name == "function_declarator": - break - - funcParamCommon(fnname, pname, ptyp, pptr, pout, count, i, flen) - - if pout.nBl and pout[^2 .. ^1] == ", ": - pout = pout[0 .. ^3] - - if not fnname.nBl: - let - override = gState.getOverride(fname, nskProc) - if override.nBl: - gState.typeStr &= &"{gState.getComments()}\n{override}" - elif gState.addNewIdentifer(fnname): - let - ftyp = gState.getIdentifier(gState.data[0].val, nskType, fnname).getType() - pragma = gState.getPragma(gState.getImportC(fname, fnname), "cdecl") - - if fptr.nBl or ftyp != "object": - if fVar: - gState.procStr &= &"{gState.getComments(true)}\nvar {fnname}*: proc ({pout}): {getPtrType(fptr&ftyp)}{{.cdecl.}}" - else: - gState.procStr &= &"{gState.getComments(true)}\nproc {fnname}*({pout}): {getPtrType(fptr&ftyp)}{pragma}" - else: - if fVar: - gState.procStr &= &"{gState.getComments(true)}\nvar {fnname}*: proc ({pout}){{.cdecl.}}" - else: - gState.procStr &= &"{gState.getComments(true)}\nproc {fnname}*({pout}){pragma}" - )) - - # // comment - result.add((&""" - (comment - ) - """, - proc (ast: ref Ast, node: TSNode, gState: State) = - let - cmt = $gState.getNodeVal(node) - - for line in cmt.splitLines(): - let - line = line.multiReplace([("//", ""), ("/*", ""), ("*/", "")]) - - gState.commentStr &= &"\n # {line.strip(leading=false)}" - )) - - # // unknown - result.add((&""" - (type_definition|struct_specifier|union_specifier|enum_specifier|declaration - (^.*) - ) - """, - proc (ast: ref Ast, node: TSNode, gState: State) = - var - done = false - for i in gState.data: - case $node.tsNodeType() - of "declaration": - if i.name == "identifier": - let - override = gState.getOverride(i.val, nskProc) - - if override.nBl: - gState.procStr &= &"{gState.getComments(true)}\n{override}" - done = true - break - else: - gState.procStr &= &"{gState.getComments(true)}\n# Declaration '{i.val}' skipped" - - else: - if i.name == "type_identifier": - let - override = gState.getOverride(i.val, nskType) - - if override.nBl: - gState.typeStr &= &"{gState.getComments()}\n{override}" - done = true - break - else: - gState.typeStr &= &"{gState.getComments()}\n # Type '{i.val}' skipped" - - if gState.debug and not done: - gState.skipStr &= &"\n{gState.getNodeVal(node)}" - )) - -proc initRegex(ast: ref Ast) = - if ast.children.nBl: - if not ast.recursive: - for child in ast.children: - child.initRegex() - - var - reg: string - try: - reg = ast.getRegexForAstChildren() - ast.regex = reg.re() - except: - echo reg - raise newException(Exception, getCurrentExceptionMsg()) - -proc parseGrammar*(): AstTable = - const grammars = initGrammar() - - result = newTable[string, seq[ref Ast]]() - for i in 0 .. grammars.len-1: - var - ast = grammars[i].grammar.parseLisp() - - ast.tonim = grammars[i].call - ast.initRegex() - for n in ast.name.split("|"): - if n notin result: - result[n] = @[ast] - else: - result[n].add(ast) - -proc printGrammar*(gState: State, astTable: AstTable) = - for name in astTable.keys(): - for ast in astTable[name]: - gecho ast.printAst() diff --git a/nimterop/toastlib/lisp.nim b/nimterop/toastlib/lisp.nim deleted file mode 100644 index 57d71a1..0000000 --- a/nimterop/toastlib/lisp.nim +++ /dev/null @@ -1,60 +0,0 @@ -import ".."/globals -import "."/getters - -var - gTokens: seq[string] - idx = 0 - -proc tokenize(tree: string) = - var collect = "" - - gTokens = @[] - idx = 0 - for i in tree: - case i: - of ' ', '\n', '\r', '(', ')': - if collect.nBl: - gTokens.add(collect) - collect = "" - if i in ['(', ')']: - gTokens.add($i) - else: - collect &= $i - -proc readFromTokens(): ref Ast = - if idx == gTokens.len: - doAssert false, "Bad AST " & $(idx: idx) - - if gTokens[idx] == "(": - if gTokens.len - idx < 2: - doAssert false, "Corrupt AST " & $(gTokensLen: gTokens.len, idx: idx) - result = new(Ast) - (result.name, result.kind, result.recursive) = gTokens[idx+1].getNameKind() - result.children = @[] - if result.recursive: - result.children.add(result) - idx += 2 - while gTokens[idx] != ")": - var res = readFromTokens() - if not res.isNil: - result.children.add(res) - elif gTokens[idx] == ")": - doAssert false, "Poor AST " & $(idx: idx) - - idx += 1 - -proc printAst*(node: ref Ast, offset=""): string = - result = offset & "(" & (if node.recursive: "^" else: "") & node.name & node.kind.toString() - - if node.children.nBl and not node.recursive: - result &= "\n" - for child in node.children: - result &= printAst(child, offset & " ") - result &= offset & ")\n" - else: - result &= ")\n" - -proc parseLisp*(tree: string): ref Ast = - tokenize(tree) - - return readFromTokens() diff --git a/nimterop/toastlib/tshelp.nim b/nimterop/toastlib/tshelp.nim index e7e8d75..9310cf7 100644 --- a/nimterop/toastlib/tshelp.nim +++ b/nimterop/toastlib/tshelp.nim @@ -2,7 +2,6 @@ import sets, strformat, strutils import ".."/treesitter/[api, c, cpp] import ".."/globals -import "."/getters template withCodeAst*(code: string, mode: string, body: untyped): untyped = ## A simple template to inject the TSNode into a body of code diff --git a/tests/getheader.nims b/tests/getheader.nims index 916abcf..e5d964c 100644 --- a/tests/getheader.nims +++ b/tests/getheader.nims @@ -14,7 +14,7 @@ proc testCall(cmd, output: string, exitCode: int, delete = true) = doAssert outp.contains(output), outp var - cmd = "nim c -f --hints:off -d:FLAGS=\"-f:ast2\" -d:checkAbi" + cmd = "nim c -f --hints:off -d:checkAbi" lrcmd = " -r lzma.nim" zrcmd = " -r zlib.nim" sshcmd = " -r libssh2.nim" diff --git a/tests/libssh2.nim b/tests/libssh2.nim index 172f6ae..09343bc 100644 --- a/tests/libssh2.nim +++ b/tests/libssh2.nim @@ -17,12 +17,12 @@ cOverride: SOCKET = object when not libssh2Static: - cImport(libssh2Path, recurse = true, dynlib = "libssh2LPath", flags = "-f:ast2 -c -E_ -F_") + cImport(libssh2Path, recurse = true, dynlib = "libssh2LPath", flags = "-c -E_ -F_") when not defined(Windows) and not isDefined(libssh2JBB): proc zlibVersion(): cstring {.importc, dynlib: libssh2LPath.} else: - cImport(libssh2Path, recurse = true, flags = "-f:ast2 -c -E_ -F_") + cImport(libssh2Path, recurse = true, flags = "-c -E_ -F_") when not defined(Windows) and not isDefined(libssh2JBB): proc zlibVersion(): cstring {.importc.} diff --git a/tests/rsa.nim b/tests/rsa.nim index a4aa64b..f5c343c 100644 --- a/tests/rsa.nim +++ b/tests/rsa.nim @@ -39,7 +39,7 @@ cOverride: cImport(@[ basePath / "rsa.h", basePath / "err.h", -], recurse = true, flags = "-f:ast2 -s -c " & FLAGS) +], recurse = true, flags = "-s -c " & FLAGS) {.passL: cryptoLPath.} From 63a75bce4ee36ad2e09ff4957408c7f49e319c2a Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 24 Jun 2020 12:24:15 -0500 Subject: [PATCH 534/593] No more includes in build --- nimterop/build.nim | 129 +++++----------------------------- nimterop/build/ccompiler.nim | 2 + nimterop/build/conan.nim | 6 ++ nimterop/build/getheader.nim | 7 +- nimterop/build/jbb.nim | 6 ++ nimterop/build/nimconf.nim | 6 ++ nimterop/build/shell.nim | 85 ++++++++++++++++------ nimterop/build/tools.nim | 22 +++--- nimterop/cimport.nim | 1 - nimterop/globals.nim | 20 ++++-- nimterop/paths.nim | 2 +- nimterop/setup.nim | 3 +- nimterop/toast.nim | 10 ++- nimterop/toastlib/getters.nim | 3 +- nimterop/treesitter/cpp.nim | 3 +- 15 files changed, 144 insertions(+), 161 deletions(-) diff --git a/nimterop/build.nim b/nimterop/build.nim index 672cb58..3a73f56 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -1,130 +1,39 @@ -import hashes, osproc, sets, strformat, strutils - when not defined(TOAST): - import macros, tables - -import os except findExe, sleep + import os except findExe, sleep +else: + import os export extractFilename, `/` -# build specific debug since we cannot import globals (yet) -var - gDebug* = false - gDebugCT* {.compileTime.} = false - gNimExe* = "" - # Misc helpers - -proc sanitizePath*(path: string, noQuote = false, sep = $DirSep): string = - result = path.multiReplace([("\\\\", sep), ("\\", sep), ("/", sep)]) - if not noQuote: - result = result.quoteShell - -proc getCurrentNimCompiler*(): string = - when nimvm: - result = getCurrentCompilerExe() - when defined(nimsuggest): - result = result.replace("nimsuggest", "nim") - else: - result = gNimExe - -template fixOutDir() {.dirty, used.} = - let - outdir = if outdir.isAbsolute(): outdir else: getProjectDir() / outdir - -proc compareVersions*(ver1, ver2: string): int = - ## Compare two version strings x.y.z and return -1, 0, 1 - ## - ## ver1 < ver2 = -1 - ## ver1 = ver2 = 0 - ## ver1 > ver2 = 1 - let - ver1seq = ver1.replace("-", "").split('.') - ver2seq = ver2.replace("-", "").split('.') - for i in 0 ..< ver1seq.len: - let - p1 = ver1seq[i] - p2 = if i < ver2seq.len: ver2seq[i] else: "0" - - try: - let - h1 = p1.parseHexInt() - h2 = p2.parseHexInt() - - if h1 < h2: return -1 - elif h1 > h2: return 1 - except ValueError: - if p1 < p2: return -1 - elif p1 > p2: return 1 - -proc fixCmd(cmd: string): string = - when defined(Windows): - # Replace 'cd d:\abc' with 'd: && cd d:\abc` - var filteredCmd = cmd - if cmd.toLower().startsWith("cd"): - var - colonIndex = cmd.find(":") - driveLetter = cmd.substr(colonIndex-1, colonIndex) - if (driveLetter[0].isAlphaAscii() and - driveLetter[1] == ':' and - colonIndex == 4): - filteredCmd = &"{driveLetter} && {cmd}" - result = "cmd /c " & filteredCmd - elif defined(posix): - result = cmd - else: - doAssert false +import "."/build/misc +export misc # Nim cfg file related functionality -include "."/build/nimconf - -proc getNimteropCacheDir(): string = - # Get location to cache all nimterop artifacts - result = getNimcacheDir() / "nimterop" +import "."/build/nimconf +export nimconf # Functionality shelled out to external executables -include "."/build/shell - -proc getProjectCacheDir*(name: string, forceClean = true): string = - ## Get a cache directory where all nimterop artifacts can be stored - ## - ## Projects can use this location to download source code and build binaries - ## that can be then accessed by multiple apps. This is created under the - ## per-user Nim cache directory. - ## - ## Use `name` to specify the subdirectory name for a project. - ## - ## `forceClean` is enabled by default and effectively deletes the folder - ## if Nim is compiled with the `-f` or `--forceBuild` flag. This allows - ## any project to start out with a clean cache dir on a forced build. - ## - ## NOTE: avoid calling `getProjectCacheDir()` multiple times on the same - ## `name` when `forceClean = true` else checked out source might get deleted - ## at the wrong time during build. - ## - ## E.g. - ## `nimgit2` downloads `libgit2` source so `name = "libgit2"` - ## - ## `nimarchive` downloads `libarchive`, `bzlib`, `liblzma` and `zlib` so - ## `name = "nimarchive" / "libarchive"` for `libarchive`, etc. - result = getNimteropCacheDir() / name - - if forceClean and compileOption("forceBuild"): - echo "# Removing " & result - rmDir(result) +import "."/build/shell +export shell # C compiler support -include "."/build/ccompiler +import "."/build/ccompiler +export ccompiler when not defined(TOAST): # configure, cmake, make support - include "."/build/tools + import "."/build/tools + export tools # Conan.io support - include "."/build/conan + import "."/build/conan + export conan # Julia BinaryBuilder.org support - include "."/build/jbb + import "."/build/jbb + export jbb # getHeader support - include "."/build/getheader + import "."/build/getheader + export getheader diff --git a/nimterop/build/ccompiler.nim b/nimterop/build/ccompiler.nim index c33c94a..550e1b2 100644 --- a/nimterop/build/ccompiler.nim +++ b/nimterop/build/ccompiler.nim @@ -1,5 +1,7 @@ import os, strformat, strutils +import "."/shell + proc getCompilerMode*(path: string): string = ## Determines a target language mode from an input filename, if one is not already specified. let file = path.splitFile() diff --git a/nimterop/build/conan.nim b/nimterop/build/conan.nim index 3430752..31e7f26 100644 --- a/nimterop/build/conan.nim +++ b/nimterop/build/conan.nim @@ -1,5 +1,7 @@ import os, strformat, strutils, tables +import "."/[ccompiler, misc, nimconf, shell] + when (NimMajor, NimMinor, NimPatch) < (1, 2, 0): import marshal else: @@ -77,6 +79,10 @@ proc jsonGet(url: string): JsonNode = discard rmFile(file) +template fixOutDir() {.dirty.} = + let + outdir = if outdir.isAbsolute(): outdir else: getProjectDir() / outdir + proc `==`*(pkg1, pkg2: ConanPackage): bool = ## Check if two ConanPackage objects are equal (not pkg1.isNil and not pkg2.isNil and diff --git a/nimterop/build/getheader.nim b/nimterop/build/getheader.nim index 216b599..8bb13fd 100644 --- a/nimterop/build/getheader.nim +++ b/nimterop/build/getheader.nim @@ -1,4 +1,9 @@ -import macros, os, strutils, tables +import macros, strformat, strutils, tables + +import os except findExe + +import ".."/globals +import "."/[ccompiler, conan, jbb, nimconf, shell, tools] var gDefines {.compileTime.} = initTable[string, string]() diff --git a/nimterop/build/jbb.nim b/nimterop/build/jbb.nim index 15bc578..cb48a27 100644 --- a/nimterop/build/jbb.nim +++ b/nimterop/build/jbb.nim @@ -1,5 +1,7 @@ import json, os, strformat, strutils, tables +import "."/[ccompiler, nimconf, shell] + when (NimMajor, NimMinor, NimPatch) < (1, 2, 0): import marshal @@ -27,6 +29,10 @@ var # Reuse dependencies already downloaded gJBBRequires {.compileTime.}: Table[string, JBBPackage] +template fixOutDir() {.dirty.} = + let + outdir = if outdir.isAbsolute(): outdir else: getProjectDir() / outdir + proc `==`*(pkg1, pkg2: JBBPackage): bool = ## Check if two JBBPackage objects are equal (not pkg1.isNil and not pkg2.isNil and diff --git a/nimterop/build/nimconf.nim b/nimterop/build/nimconf.nim index c87a60f..70e47a3 100644 --- a/nimterop/build/nimconf.nim +++ b/nimterop/build/nimconf.nim @@ -1,5 +1,7 @@ import json, os, osproc, sets, strformat, strutils +import "."/misc + when nimvm: when (NimMajor, NimMinor, NimPatch) >= (1, 2, 0): import std/compilesettings @@ -227,3 +229,7 @@ proc getOutDir*(projectDir = ""): string = let cfg = getNimConfig(projectDir) result = cfg.outDir + +proc getNimteropCacheDir*(): string = + ## Get location to cache all nimterop artifacts + result = getNimcacheDir() / "nimterop" diff --git a/nimterop/build/shell.nim b/nimterop/build/shell.nim index bc07285..7f84db3 100644 --- a/nimterop/build/shell.nim +++ b/nimterop/build/shell.nim @@ -1,15 +1,25 @@ -import os, strformat, strutils +import hashes, osproc, sets, strformat, strutils -proc sleep*(milsecs: int) = - ## Sleep at compile time - let - cmd = - when defined(Windows): - "cmd /c timeout " - else: - "sleep " +when not defined(TOAST): + import os except findExe, sleep +else: + import os - discard gorgeEx(cmd & $(milsecs / 1000)) +import "."/[misc, nimconf] + +when not defined(TOAST): + proc sleep*(milsecs: int) = + ## Sleep at compile time + let + cmd = + when defined(Windows): + "cmd /c timeout " + else: + "sleep " + + discard gorgeEx(cmd & $(milsecs / 1000)) +else: + export sleep proc execAction*(cmd: string, retry = 0, die = true, cache = false, cacheKey = "", onRetry: proc() = nil): tuple[output: string, ret: int] = @@ -73,20 +83,23 @@ proc execAction*(cmd: string, retry = 0, die = true, cache = false, doAssert false, "Command failed: " & $result.ret & "\ncmd: " & ccmd & "\nresult:\n" & result.output -proc findExe*(exe: string): string = - ## Find the specified executable using the `which`/`where` command - supported - ## at compile time - var - cmd = - when defined(Windows): - "where " & exe - else: - "which " & exe +when not defined(TOAST): + proc findExe*(exe: string): string = + ## Find the specified executable using the `which`/`where` command - supported + ## at compile time + var + cmd = + when defined(Windows): + "where " & exe + else: + "which " & exe - (output, ret) = execAction(cmd, die = false) + (output, ret) = execAction(cmd, die = false) - if ret == 0: - return output.splitLines()[0].strip().sanitizePath + if ret == 0: + return output.splitLines()[0].strip().sanitizePath +else: + export findExe proc mkDir*(dir: string) = ## Create a directory at compile time @@ -465,3 +478,31 @@ proc getNumProcs*(): string = execAction("sysctl -n hw.ncpu").output.strip() else: "1" + +proc getProjectCacheDir*(name: string, forceClean = true): string = + ## Get a cache directory where all nimterop artifacts can be stored + ## + ## Projects can use this location to download source code and build binaries + ## that can be then accessed by multiple apps. This is created under the + ## per-user Nim cache directory. + ## + ## Use `name` to specify the subdirectory name for a project. + ## + ## `forceClean` is enabled by default and effectively deletes the folder + ## if Nim is compiled with the `-f` or `--forceBuild` flag. This allows + ## any project to start out with a clean cache dir on a forced build. + ## + ## NOTE: avoid calling `getProjectCacheDir()` multiple times on the same + ## `name` when `forceClean = true` else checked out source might get deleted + ## at the wrong time during build. + ## + ## E.g. + ## `nimgit2` downloads `libgit2` source so `name = "libgit2"` + ## + ## `nimarchive` downloads `libarchive`, `bzlib`, `liblzma` and `zlib` so + ## `name = "nimarchive" / "libarchive"` for `libarchive`, etc. + result = getNimteropCacheDir() / name + + if forceClean and compileOption("forceBuild"): + echo "# Removing " & result + rmDir(result) diff --git a/nimterop/build/tools.nim b/nimterop/build/tools.nim index c6a4283..5be1f4b 100644 --- a/nimterop/build/tools.nim +++ b/nimterop/build/tools.nim @@ -1,20 +1,16 @@ -import os, strformat, strutils +import strformat, strutils -type - BuildType* = enum - btAutoconf, btCmake +import os except findExe - BuildStatus = object - built: bool - buildPath: string - error: string +import ".."/globals +import "."/[misc, shell] proc echoDebug(str: string) = let str = "\n# " & str.strip().replace("\n", "\n# ") - when nimvm: - if gDebugCT: echo str + when defined(TOAST): + if gState.debug: echo str else: - if gDebug: echo str + if gStateCT.debug: echo str proc configure*(path, check: string, flags = "") = ## Run the GNU `configure` command to generate all Makefiles or other @@ -208,7 +204,7 @@ proc make*(path, check: string, flags = "", regex = false) = doAssert findFile(check, path, regex = regex).len != 0, "make failed" -proc buildWithCmake(outdir, flags: string): BuildStatus = +proc buildWithCmake*(outdir, flags: string): BuildStatus = if not fileExists(outdir / "Makefile"): if fileExists(outdir / "CMakeLists.txt"): if findExe("cmake").len != 0: @@ -238,7 +234,7 @@ proc buildWithCmake(outdir, flags: string): BuildStatus = else: result.buildPath = outdir -proc buildWithAutoConf(outdir, flags: string): BuildStatus = +proc buildWithAutoConf*(outdir, flags: string): BuildStatus = if not fileExists(outdir / "Makefile"): if findExe("bash").len != 0: for file in @["configure", "configure.ac", "configure.in", "autogen.sh", "build/autogen.sh"]: diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index c81c35b..38a75e7 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -376,7 +376,6 @@ proc cSearchPath*(path: string): string {.compileTime.}= proc cDebug*() {.compileTime.} = ## Enable debug messages and display the generated Nim code gStateCT.debug = true - build.gDebugCT = true proc cDisableCaching*() {.compileTime.} = ## Disable caching of generated Nim code - useful during wrapper development diff --git a/nimterop/globals.nim b/nimterop/globals.nim index fa8f8de..e8117c8 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -7,7 +7,7 @@ when defined(TOAST): import compiler/[ast, idents, modulegraphs, options] - import "."/treesitter/api + # import "."/treesitter/api type Feature* = enum @@ -78,6 +78,21 @@ type pluginSource*: string # `cPlugin()` generated code to write to plugin file from searchDirs*: seq[string] # `cSearchPath()` added directories for header search + BuildType* = enum + btAutoconf, btCmake + + BuildStatus* = object + built*: bool + buildPath*: string + error*: string + +when nimvm: + var + gStateCT* {.compileTime, used.} = new(State) +else: + var + gState*: State + when defined(TOAST): const gAtoms* {.used.} = @[ @@ -119,9 +134,6 @@ when defined(TOAST): template decho*(args: varargs[string, `$`]): untyped = if gState.debug: gecho join(args, "").getCommented() -else: - var - gStateCT* {.compileTime, used.} = new(State) template nBl*(s: typed): untyped {.used.} = (s.len != 0) diff --git a/nimterop/paths.nim b/nimterop/paths.nim index fa245b3..b336d46 100644 --- a/nimterop/paths.nim +++ b/nimterop/paths.nim @@ -1,6 +1,6 @@ import os -import "."/build +import "."/build/shell const cacheDir* = getProjectCacheDir("nimterop", forceClean = false) diff --git a/nimterop/setup.nim b/nimterop/setup.nim index 3f16dd7..998d9e9 100644 --- a/nimterop/setup.nim +++ b/nimterop/setup.nim @@ -1,6 +1,7 @@ import os, strutils -import "."/[build, paths] +import "."/[paths] +import "."/build/[shell] proc treesitterSetup*() = gitPull("https://github.com/tree-sitter/tree-sitter", cacheDir / "treesitter", """ diff --git a/nimterop/toast.nim b/nimterop/toast.nim index b7a993a..e888e30 100644 --- a/nimterop/toast.nim +++ b/nimterop/toast.nim @@ -2,10 +2,12 @@ import os, osproc, sets, strformat, strutils, tables, times import "."/treesitter/[api, c, cpp] -import "."/[build, globals] +import "."/[globals] import "."/toastlib/[ast2, getters, tshelp] +import "."/build/[ccompiler, misc] + proc process(gState: State, path: string) = doAssert existsFile(path), &"Invalid path {path}" @@ -54,7 +56,7 @@ proc main( ) = # Setup global state with arguments - var gState = State( + gState = State( convention: convention, debug: debug, defines: defines, @@ -76,10 +78,6 @@ proc main( symOverride: symOverride ) - # Set gDebug in build.nim - build.gDebug = gState.debug - build.gNimExe = gState.nim - # Split some arguments with , gState.symOverride = gState.symOverride.getSplitComma() gState.prefix = gState.prefix.getSplitComma() diff --git a/nimterop/toastlib/getters.nim b/nimterop/toastlib/getters.nim index 0c1b784..c3f48ae 100644 --- a/nimterop/toastlib/getters.nim +++ b/nimterop/toastlib/getters.nim @@ -2,7 +2,8 @@ import dynlib, macros, os, sequtils, sets, strformat, strutils, tables, times import regex -import ".."/[build, globals, plugin] +import ".."/[globals, plugin] +import ".."/build/[ccompiler, misc, nimconf, shell] const gReserved = """ addr and as asm diff --git a/nimterop/treesitter/cpp.nim b/nimterop/treesitter/cpp.nim index 2fe3128..4f5be17 100644 --- a/nimterop/treesitter/cpp.nim +++ b/nimterop/treesitter/cpp.nim @@ -1,6 +1,7 @@ import strutils, os -import ".."/[build, setup, paths] +import ".."/[setup, paths] +import ".."/build/shell static: treesitterCppSetup() From a0413f1595be040c57bc3d75cea1679e5d671d71 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 24 Jun 2020 13:17:25 -0500 Subject: [PATCH 535/593] Use g/decho in build --- nimterop/build/conan.nim | 10 +++--- nimterop/build/getheader.nim | 10 +++--- nimterop/build/jbb.nim | 3 +- nimterop/build/misc.nim | 62 ++++++++++++++++++++++++++++++++++++ nimterop/build/nimconf.nim | 3 +- nimterop/build/shell.nim | 23 ++++++------- nimterop/build/tools.nim | 37 +++++++++------------ nimterop/cimport.nim | 18 +++++------ nimterop/globals.nim | 29 +++++++++++++---- nimterop/toast.nim | 3 +- nimterop/toastlib/tshelp.nim | 3 -- 11 files changed, 135 insertions(+), 66 deletions(-) create mode 100644 nimterop/build/misc.nim diff --git a/nimterop/build/conan.nim b/nimterop/build/conan.nim index 31e7f26..792de01 100644 --- a/nimterop/build/conan.nim +++ b/nimterop/build/conan.nim @@ -1,11 +1,11 @@ -import os, strformat, strutils, tables +import json, os, strformat, strutils, tables + +import ".."/globals import "."/[ccompiler, misc, nimconf, shell] when (NimMajor, NimMinor, NimPatch) < (1, 2, 0): import marshal -else: - import json type ConanPackage* = ref object @@ -158,7 +158,7 @@ proc searchConan*(name: string, version = "", user = "", channel = ""): ConanPac if channel.len != 0: query &= "/" & channel - echo &"# Searching Conan.io for latest version of {name}" + gecho &"# Searching Conan.io for latest version of {name}" let j1 = jsonGet(conanSearchUrl % ["query", query]) @@ -397,7 +397,7 @@ proc downloadConan*(pkg: ConanPackage, outdir: string, main = true) = doAssert pkg.recipes.len != 0, &"Failed to download {pkg.name} v{pkg.version} from Conan - check https://conan.io/center" - echo &"# Downloading {pkg.name} v{pkg.version} from Conan.io" + gecho &"# Downloading {pkg.name} v{pkg.version} from Conan.io" for recipe, builds in pkg.recipes: for build in builds: if pkg.bhash.len == 0 or pkg.bhash == build.bhash: diff --git a/nimterop/build/getheader.nim b/nimterop/build/getheader.nim index 8bb13fd..6972ccc 100644 --- a/nimterop/build/getheader.nim +++ b/nimterop/build/getheader.nim @@ -476,9 +476,9 @@ macro getHeader*( {.passL: `ldeps`.join(" ").} static: - echo "# Including library " & lpath + gecho "# Including library " & lpath if `ldeps`.len != 0: - echo "# Including dependencies " & `ldeps`.join(" ") + gecho "# Including dependencies " & `ldeps`.join(" ") else: const `lpath`* = when not useStd: `libdir` / lpath.extractFilename() else: lpath @@ -498,7 +498,7 @@ macro getHeader*( ldeps[i] = ldeptgt # Copy downloaded dependencies to `libdir` if copied.len != 0: - echo "# Copying dependencies: " & copied.join(" ") & "\n# to " & `libdir` + gecho "# Copying dependencies: " & copied.join(" ") & "\n# to " & `libdir` ldeps else: ldeps @@ -507,8 +507,8 @@ macro getHeader*( when not useStd: # Copy downloaded shared libraries to `libdir` if not fileExists(`lpath`) or getFileDate(lpath) != getFileDate(`lpath`): - echo "# Copying " & `lpath`.extractFilename() & " to " & `libdir` + gecho "# Copying " & `lpath`.extractFilename() & " to " & `libdir` cpFile(lpath, `lpath`) - echo "# Including library " & `lpath` + gecho "# Including library " & `lpath` ) diff --git a/nimterop/build/jbb.nim b/nimterop/build/jbb.nim index cb48a27..0fb163f 100644 --- a/nimterop/build/jbb.nim +++ b/nimterop/build/jbb.nim @@ -1,5 +1,6 @@ import json, os, strformat, strutils, tables +import ".."/globals import "."/[ccompiler, nimconf, shell] when (NimMajor, NimMinor, NimPatch) < (1, 2, 0): @@ -198,7 +199,7 @@ proc downloadJBB*(pkg: JBBPackage, outdir: string, main = true) = else: "" path = outdir / pkg.name - echo &"# Downloading {pkg.name}{vstr} from BinaryBuilder.org" + gecho &"# Downloading {pkg.name}{vstr} from BinaryBuilder.org" downloadUrl(pkg.url, path, quiet = true) pkg.findJBBLibs(path) diff --git a/nimterop/build/misc.nim b/nimterop/build/misc.nim new file mode 100644 index 0000000..c6c0e48 --- /dev/null +++ b/nimterop/build/misc.nim @@ -0,0 +1,62 @@ +import os, strutils + +when defined(Windows): + import strformat + +import ".."/globals + +proc sanitizePath*(path: string, noQuote = false, sep = $DirSep): string = + result = path.multiReplace([("\\\\", sep), ("\\", sep), ("/", sep)]) + if not noQuote: + result = result.quoteShell + +proc getCurrentNimCompiler*(): string = + when nimvm: + result = getCurrentCompilerExe() + when defined(nimsuggest): + result = result.replace("nimsuggest", "nim") + else: + result = gState.nim + +proc compareVersions*(ver1, ver2: string): int = + ## Compare two version strings x.y.z and return -1, 0, 1 + ## + ## ver1 < ver2 = -1 + ## ver1 = ver2 = 0 + ## ver1 > ver2 = 1 + let + ver1seq = ver1.replace("-", "").split('.') + ver2seq = ver2.replace("-", "").split('.') + for i in 0 ..< ver1seq.len: + let + p1 = ver1seq[i] + p2 = if i < ver2seq.len: ver2seq[i] else: "0" + + try: + let + h1 = p1.parseHexInt() + h2 = p2.parseHexInt() + + if h1 < h2: return -1 + elif h1 > h2: return 1 + except ValueError: + if p1 < p2: return -1 + elif p1 > p2: return 1 + +proc fixCmd*(cmd: string): string = + when defined(Windows): + # Replace 'cd d:\abc' with 'd: && cd d:\abc` + var filteredCmd = cmd + if cmd.toLower().startsWith("cd"): + var + colonIndex = cmd.find(":") + driveLetter = cmd.substr(colonIndex-1, colonIndex) + if (driveLetter[0].isAlphaAscii() and + driveLetter[1] == ':' and + colonIndex == 4): + filteredCmd = &"{driveLetter} && {cmd}" + result = "cmd /c " & filteredCmd + elif defined(posix): + result = cmd + else: + doAssert false diff --git a/nimterop/build/nimconf.nim b/nimterop/build/nimconf.nim index 70e47a3..3bbe521 100644 --- a/nimterop/build/nimconf.nim +++ b/nimterop/build/nimconf.nim @@ -1,5 +1,6 @@ import json, os, osproc, sets, strformat, strutils +import ".."/globals import "."/misc when nimvm: @@ -42,7 +43,7 @@ proc getJson(projectDir: string): JsonNode = try: result = parseJson(dump) except JsonParsingError as e: - echo "# Failed to parse `nim dump` output: " & e.msg + gecho "# Failed to parse `nim dump` output: " & e.msg proc getOsCacheDir(): string = # OS default cache directory diff --git a/nimterop/build/shell.nim b/nimterop/build/shell.nim index 7f84db3..a5d49de 100644 --- a/nimterop/build/shell.nim +++ b/nimterop/build/shell.nim @@ -5,6 +5,7 @@ when not defined(TOAST): else: import os +import ".."/globals import "."/[misc, nimconf] when not defined(TOAST): @@ -228,7 +229,7 @@ proc extractZip*(zipfile, outdir: string, quiet = false) = "[IO.Compression.ZipFile]::ExtractToDirectory('$#', '.'); }\"" if not quiet: - echo "# Extracting " & zipfile + gecho "# Extracting " & zipfile discard execAction(&"cd {outdir.sanitizePath} && {cmd % zipfile}") proc extractTar*(tarfile, outdir: string, quiet = false) = @@ -262,7 +263,7 @@ proc extractTar*(tarfile, outdir: string, quiet = false) = doAssert cmd.len != 0, "No extraction tool - tar, 7z, 7za - available for " & tarfile.sanitizePath if not quiet: - echo "# Extracting " & tarfile + gecho "# Extracting " & tarfile discard execAction(&"cd {outdir.sanitizePath} && {cmd}") if name.len != 0: rmFile(outdir / name) @@ -279,7 +280,7 @@ proc downloadUrl*(url, outdir: string, quiet = false, retry = 1) = if not (ext in archives and fileExists(filePath)): if not quiet: - echo "# Downloading " & file + gecho "# Downloading " & file mkDir(outdir) var cmd = findExe("curl") if cmd.len != 0: @@ -302,12 +303,12 @@ proc downloadUrl*(url, outdir: string, quiet = false, retry = 1) = proc gitReset*(outdir: string) = ## Hard reset the git repository at the specified directory - echo "# Resetting " & outdir + gecho "# Resetting " & outdir let cmd = &"cd {outdir.sanitizePath} && git reset --hard" while execAction(cmd).output.contains("Permission denied"): sleep(1000) - echo "# Retrying ..." + gecho "# Retrying ..." proc gitCheckout*(file, outdir: string) = ## Checkout the specified `file` in the git repository at `outdir` @@ -315,12 +316,12 @@ proc gitCheckout*(file, outdir: string) = ## This effectively resets all changes in the file and can be ## used to undo any changes that were made to source files to enable ## successful wrapping with `cImport()` or `c2nImport()`. - echo "# Resetting " & file + gecho "# Resetting " & file let file2 = file.relativePath outdir let cmd = &"cd {outdir.sanitizePath} && git checkout {file2.sanitizePath}" while execAction(cmd).output.contains("Permission denied"): sleep(500) - echo "# Retrying ..." + gecho "# Retrying ..." proc gitPull*(url: string, outdir = "", plist = "", checkout = "", quiet = false) = ## Pull the specified git repository to the output directory @@ -343,7 +344,7 @@ proc gitPull*(url: string, outdir = "", plist = "", checkout = "", quiet = false mkDir(outdir) if not quiet: - echo "# Setting up Git repo: " & url + gecho "# Setting up Git repo: " & url discard execAction(&"cd {outdirQ} && git init .") discard execAction(&"cd {outdirQ} && git remote add origin {url}") @@ -360,12 +361,12 @@ proc gitPull*(url: string, outdir = "", plist = "", checkout = "", quiet = false if checkout.len != 0: if not quiet: - echo "# Checking out " & checkout + gecho "# Checking out " & checkout discard execAction(&"cd {outdirQ} && git fetch", retry = 3) discard execAction(&"cd {outdirQ} && git checkout {checkout}") else: if not quiet: - echo "# Pulling repository" + gecho "# Pulling repository" discard execAction(&"cd {outdirQ} && git pull --depth=1 origin master", retry = 3) proc gitTags*(outdir: string): seq[string] = @@ -504,5 +505,5 @@ proc getProjectCacheDir*(name: string, forceClean = true): string = result = getNimteropCacheDir() / name if forceClean and compileOption("forceBuild"): - echo "# Removing " & result + gecho "# Removing " & result rmDir(result) diff --git a/nimterop/build/tools.nim b/nimterop/build/tools.nim index 5be1f4b..c164ffd 100644 --- a/nimterop/build/tools.nim +++ b/nimterop/build/tools.nim @@ -5,13 +5,6 @@ import os except findExe import ".."/globals import "."/[misc, shell] -proc echoDebug(str: string) = - let str = "\n# " & str.strip().replace("\n", "\n# ") - when defined(TOAST): - if gState.debug: echo str - else: - if gStateCT.debug: echo str - proc configure*(path, check: string, flags = "") = ## Run the GNU `configure` command to generate all Makefiles or other ## build scripts in the specified path @@ -30,18 +23,18 @@ proc configure*(path, check: string, flags = "") = if (path / check).fileExists(): return - echo "# Configuring " & path + gecho "# Configuring " & path if not fileExists(path / "configure"): for i in @["autogen.sh", "build" / "autogen.sh"]: if fileExists(path / i): - echo "# Running autogen.sh" + gecho "# Running autogen.sh" when defined(unix): - echoDebug execAction( + decho execAction( &"cd {(path / i).parentDir().sanitizePath} && ./autogen.sh").output else: - echoDebug execAction( + decho execAction( &"cd {(path / i).parentDir().sanitizePath} && bash ./autogen.sh").output break @@ -49,14 +42,14 @@ proc configure*(path, check: string, flags = "") = if not fileExists(path / "configure"): for i in @["configure.ac", "configure.in"]: if fileExists(path / i): - echo "# Running autoreconf" + gecho "# Running autoreconf" - echoDebug execAction(&"cd {path.sanitizePath} && autoreconf -fi").output + decho execAction(&"cd {path.sanitizePath} && autoreconf -fi").output break if fileExists(path / "configure"): - echo "# Running configure " & flags + gecho "# Running configure " & flags when defined(unix): var @@ -67,7 +60,7 @@ proc configure*(path, check: string, flags = "") = if flags.len != 0: cmd &= &" {flags}" - echoDebug execAction(cmd).output + decho execAction(cmd).output doAssert (path / check).fileExists(), "Configure failed" @@ -156,15 +149,15 @@ proc cmake*(path, check, flags: string) = if (path / check).fileExists(): return - echo "# Running cmake " & flags - echo "# Path: " & path + gecho "# Running cmake " & flags + gecho "# Path: " & path mkDir(path) let cmd = &"cd {path.sanitizePath} && cmake {flags}" - echoDebug execAction(cmd).output + decho execAction(cmd).output doAssert (path / check).fileExists(), "cmake failed" @@ -184,8 +177,8 @@ proc make*(path, check: string, flags = "", regex = false) = if findFile(check, path, regex = regex).len != 0: return - echo "# Running make " & flags - echo "# Path: " & path + gecho "# Running make " & flags + gecho "# Path: " & path var cmd = findExe("make") @@ -200,7 +193,7 @@ proc make*(path, check: string, flags = "", regex = false) = if flags.len != 0: cmd &= &" {flags}" - echoDebug execAction(cmd).output + decho execAction(cmd).output doAssert findFile(check, path, regex = regex).len != 0, "make failed" @@ -219,7 +212,7 @@ proc buildWithCmake*(outdir, flags: string): BuildStatus = elif uname.contains("mingw"): gen = "MinGW Makefiles".quoteShell & " -DCMAKE_SH=\"CMAKE_SH-NOTFOUND\"" else: - echo "Unsupported system: " & uname + gecho "Unsupported system: " & uname else: gen = "MinGW Makefiles".quoteShell else: diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index 38a75e7..edfdeb9 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -246,8 +246,8 @@ proc onSymbolOverride*(sym: var Symbol) {.exportc, dynlib.} = gStateCT.symOverride.add name - if gStateCT.debug and names.nBl: - echo "# Overriding " & names.join(" ") + if names.nBl: + decho "Overriding " & names.join(" ") proc cSkipSymbol*(skips: seq[string]) {.compileTime.} = ## Similar to `cOverride() `_, this macro allows @@ -412,7 +412,7 @@ macro cDefine*(name: static string, val: static string = ""): untyped = {.passC: `str`.} if gStateCT.debug: - echo result.repr & "\n" + gecho result.repr & "\n" proc cAddSearchDir*(dir: string) {.compileTime.} = ## Add directory `dir` to the search path used in calls to @@ -442,7 +442,7 @@ macro cIncludeDir*(dir: static string): untyped = result.add quote do: {.passC: `str`.} if gStateCT.debug: - echo result.repr + gecho result.repr proc cAddStdDir*(mode = "c") {.compileTime.} = ## Add the standard `c` [default] or `cpp` include paths to search @@ -545,7 +545,7 @@ macro cCompile*(path: static string, mode = "c", exclude = ""): untyped = result.add stmt.parseStmt() if gStateCT.debug: - echo result.repr + gecho result.repr macro cImport*(filenames: static seq[string], recurse: static bool = false, dynlib: static string = "", mode: static string = "c", flags: static string = ""): untyped = @@ -565,7 +565,7 @@ macro cImport*(filenames: static seq[string], recurse: static bool = false, dynl if gStateCT.pluginSourcePath.Bl: cPluginHelper(gStateCT.pluginSource) - echo "# Importing " & fullpaths.join(", ").sanitizePath + gecho "# Importing " & fullpaths.join(", ").sanitizePath let output = getToast(fullpaths, recurse, dynlib, mode, flags) @@ -576,7 +576,7 @@ macro cImport*(filenames: static seq[string], recurse: static bool = false, dynl gStateCT.overrides = "" if gStateCT.debug: - echo output + gecho output try: let body = parseStmt(output) @@ -661,7 +661,7 @@ macro c2nImport*(filename: static string, recurse: static bool = false, dynlib: let fullpath = findPath(filename) - echo "# Importing " & fullpath & " with c2nim" + gecho "# Importing " & fullpath & " with c2nim" let output = getToast(@[fullpath], recurse, dynlib, mode, noNimout = true) @@ -700,7 +700,7 @@ macro c2nImport*(filename: static string, recurse: static bool = false, dynlib: nimout = &"const {header} = \"{fullpath}\"\n\n" & readFile(npath) if gStateCT.debug: - echo nimout + gecho nimout try: let body = parseStmt(nimout) diff --git a/nimterop/globals.nim b/nimterop/globals.nim index e8117c8..a89bac4 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -1,4 +1,4 @@ -import tables +import strutils, tables when defined(TOAST): import sets, sequtils, strutils @@ -124,16 +124,31 @@ when defined(TOAST): Status* = enum success, unknown, error - # Redirect output to file when required - template gecho*(args: string) = - if gState.outputHandle.isNil: +proc getCommented*(str: string): string = + "\n# " & str.strip().replace("\n", "\n# ") + +# Redirect output to file when required +template gecho*(args: string) = + when defined(TOAST): + when nimvm: echo args else: - gState.outputHandle.writeLine(args) + if gState.outputHandle.isNil: + echo args + else: + gState.outputHandle.writeLine(args) + else: + echo args - template decho*(args: varargs[string, `$`]): untyped = +template decho*(args: varargs[string, `$`]): untyped = + let + str = join(args, "").getCommented() + when defined(TOAST): if gState.debug: - gecho join(args, "").getCommented() + gecho str + else: + if gStateCT.debug: + echo str template nBl*(s: typed): untyped {.used.} = (s.len != 0) diff --git a/nimterop/toast.nim b/nimterop/toast.nim index e888e30..6fe5180 100644 --- a/nimterop/toast.nim +++ b/nimterop/toast.nim @@ -124,8 +124,7 @@ proc main( doAssert gState.outputHandle.open(outputFile, fmWrite), &"Failed to write to {outputFile}" - if gState.debug: - echo &"# Writing output to {outputFile}\n" + decho &"# Writing output to {outputFile}\n" if source.nBl: # Print source after preprocess or Nim output diff --git a/nimterop/toastlib/tshelp.nim b/nimterop/toastlib/tshelp.nim index 9310cf7..3b7c2cc 100644 --- a/nimterop/toastlib/tshelp.nim +++ b/nimterop/toastlib/tshelp.nim @@ -30,9 +30,6 @@ template withCodeAst*(code: string, mode: string, body: untyped): untyped = defer: tree.tsTreeDelete() -proc getCommented*(str: string): string = - "\n# " & str.strip().replace("\n", "\n# ") - proc isNil*(node: TSNode): bool = node.tsNodeIsNull() From 85a4365e3cef38e6490d3ff591e33fee9d2167a9 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 25 Jun 2020 00:10:13 -0500 Subject: [PATCH 536/593] Adjust git checkout if changed, tree-sitter version bump --- nimterop/build/shell.nim | 18 ++++++++++++++---- nimterop/globals.nim | 4 +++- nimterop/setup.nim | 6 +++--- nimterop/toastlib/ast2.nim | 5 ++++- nimterop/toastlib/exprparser.nim | 2 +- 5 files changed, 25 insertions(+), 10 deletions(-) diff --git a/nimterop/build/shell.nim b/nimterop/build/shell.nim index a5d49de..53c0b5f 100644 --- a/nimterop/build/shell.nim +++ b/nimterop/build/shell.nim @@ -323,6 +323,12 @@ proc gitCheckout*(file, outdir: string) = sleep(500) gecho "# Retrying ..." +proc gitAtCheckout*(outdir, checkout: string): bool = + ## Check if specified git repository is checked out to the specified + ## commit hash, tag or branch + result = checkout in execAction( + &"cd {outdir.sanitizePath} && git log --decorate --no-color -n 1 --format=oneline").output + proc gitPull*(url: string, outdir = "", plist = "", checkout = "", quiet = false) = ## Pull the specified git repository to the output directory ## @@ -334,13 +340,17 @@ proc gitPull*(url: string, outdir = "", plist = "", checkout = "", quiet = false ## `checkout` is the git tag, branch or commit hash to checkout once ## the repository is downloaded. This allows for pinning to a specific ## version of the code. - if dirExists(outdir/".git"): - gitReset(outdir) - return - let outdirQ = outdir.sanitizePath + if dirExists(outdir/".git"): + gitReset(outdir) + if checkout.nBl and not gitAtCheckout(outdir, checkout): + gecho &"# Updating repository to checkout {checkout}" + discard execAction( + &"cd {outdirQ} && git clean -fxd && git fetch && git checkout {checkout}", retry = 3) + return + mkDir(outdir) if not quiet: diff --git a/nimterop/globals.nim b/nimterop/globals.nim index a89bac4..c831589 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -111,7 +111,9 @@ when defined(TOAST): "bitwise_expression", "shift_expression", "math_expression", - "escape_sequence" + "escape_sequence", + "binary_expression", + "unary_expression" ].toHashSet() gEnumVals* {.used.} = @[ diff --git a/nimterop/setup.nim b/nimterop/setup.nim index 998d9e9..a0940d2 100644 --- a/nimterop/setup.nim +++ b/nimterop/setup.nim @@ -7,7 +7,7 @@ proc treesitterSetup*() = gitPull("https://github.com/tree-sitter/tree-sitter", cacheDir / "treesitter", """ lib/include/* lib/src/* -""", "0.15.5") +""", "0.15.14") gitPull("https://github.com/JuliaStrings/utf8proc", cacheDir / "utf8proc", """ *.c @@ -37,7 +37,7 @@ src/*.h src/*.c src/*.cc src/tree_sitter/parser.h -""", "v0.15.0") +""", "v0.15.3") writeFile(cacheDir / "treesitter_c" / "src" / "api.h", """ const TSLanguage *tree_sitter_c(); @@ -49,7 +49,7 @@ src/*.h src/*.c src/*.cc src/tree_sitter/parser.h -""", "v0.15.0") +""", "v0.15.1") writeFile(cacheDir / "treesitter_cpp" / "src" / "api.h", """ const TSLanguage *tree_sitter_cpp(); diff --git a/nimterop/toastlib/ast2.nim b/nimterop/toastlib/ast2.nim index 0016e29..783b6e4 100644 --- a/nimterop/toastlib/ast2.nim +++ b/nimterop/toastlib/ast2.nim @@ -1099,7 +1099,10 @@ proc getTypeProc(gState: State, name: string, node, rnode: TSNode): PNode = ncount = if not afdecl.isNil: # Pointer to function pointer - afdecl[0].getXCount("abstract_pointer_declarator") + if afdecl[0].getName() == "abstract_parenthesized_declarator": + afdecl[0][0].getXCount("abstract_pointer_declarator") + else: + afdecl[0].getXCount("abstract_pointer_declarator") else: node.getAtom().tsNodeParent().getPtrCount(reverse = true) diff --git a/nimterop/toastlib/exprparser.nim b/nimterop/toastlib/exprparser.nim index 28b49d3..13b1a98 100644 --- a/nimterop/toastlib/exprparser.nim +++ b/nimterop/toastlib/exprparser.nim @@ -535,7 +535,7 @@ proc processTSNode(gState: State, node: TSNode, typeofNode: var PNode): PNode = # once we upgrade of "math_expression", "logical_expression", "relational_expression", "bitwise_expression", "equality_expression", "binary_expression", - "shift_expression": + "shift_expression", "unary_expression": # Input -> a == b, a != b, !a, ~a, a < b, a > b, a <= b, a >= b, a >> b, a << b # Output -> # typeof(a)(a == typeof(a)(b)) From f42ba492e3b4649e9fb0e18c095464669aed463e Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 25 Jun 2020 00:59:42 -0500 Subject: [PATCH 537/593] Bump to latest tree-sitter --- nimterop/setup.nim | 11 +- nimterop/treesitter/api.nim | 306 ++++++++++++++++++++++------------ nimterop/treesitter/tsgen.nim | 9 +- 3 files changed, 199 insertions(+), 127 deletions(-) diff --git a/nimterop/setup.nim b/nimterop/setup.nim index a0940d2..6da0bbe 100644 --- a/nimterop/setup.nim +++ b/nimterop/setup.nim @@ -7,12 +7,7 @@ proc treesitterSetup*() = gitPull("https://github.com/tree-sitter/tree-sitter", cacheDir / "treesitter", """ lib/include/* lib/src/* -""", "0.15.14") - - gitPull("https://github.com/JuliaStrings/utf8proc", cacheDir / "utf8proc", """ -*.c -*.h -""") +""", "0.16.8") let tbase = cacheDir / "treesitter" / "lib" @@ -37,7 +32,7 @@ src/*.h src/*.c src/*.cc src/tree_sitter/parser.h -""", "v0.15.3") +""", "0.16.1") writeFile(cacheDir / "treesitter_c" / "src" / "api.h", """ const TSLanguage *tree_sitter_c(); @@ -49,7 +44,7 @@ src/*.h src/*.c src/*.cc src/tree_sitter/parser.h -""", "v0.15.1") +""", "v0.16.0") writeFile(cacheDir / "treesitter_cpp" / "src" / "api.h", """ const TSLanguage *tree_sitter_cpp(); diff --git a/nimterop/treesitter/api.nim b/nimterop/treesitter/api.nim index 09e328d..116bc10 100644 --- a/nimterop/treesitter/api.nim +++ b/nimterop/treesitter/api.nim @@ -12,56 +12,70 @@ const sourcePath = cacheDir / "treesitter" / "lib" when defined(Linux): {.passC: "-std=c11".} -{.passC: "-DUTF8PROC_STATIC".} {.passC: "-I$1" % (sourcePath / "include").} {.passC: "-I$1" % (sourcePath / "src").} -{.passC: "-I$1" % (sourcePath / ".." / ".." / "utf8proc").} {.compile: sourcePath / "src" / "lib.c".} ### Generated below -{.hint[ConvFromXtoItselfNotNeeded]: off.} +{.push hint[ConvFromXtoItselfNotNeeded]: off.} +{.pragma: impapiHdr, header: sourcePath / "include" / "tree_sitter" / "api.h".} defineEnum(TSInputEncoding) defineEnum(TSSymbolType) defineEnum(TSLogType) +defineEnum(TSQueryPredicateStepType) +defineEnum(TSQueryError) + const - headerapi {.used.} = sourcePath / "include" / "tree_sitter" / "api.h" - TREE_SITTER_LANGUAGE_VERSION* = 9 - TSInputEncodingUTF8* = 0.TSInputEncoding - TSInputEncodingUTF16* = 1.TSInputEncoding - TSSymbolTypeRegular* = 0.TSSymbolType - TSSymbolTypeAnonymous* = 1.TSSymbolType - TSSymbolTypeAuxiliary* = 2.TSSymbolType - TSLogTypeParse* = 0.TSLogType - TSLogTypeLex* = 1.TSLogType + TREE_SITTER_LANGUAGE_VERSION* = 11 + TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION* = 9 + TSInputEncodingUTF8* = (0).TSInputEncoding + TSInputEncodingUTF16* = (TSInputEncodingUTF8 + 1).TSInputEncoding + TSSymbolTypeRegular* = (0).TSSymbolType + TSSymbolTypeAnonymous* = (TSSymbolTypeRegular + 1).TSSymbolType + TSSymbolTypeAuxiliary* = (TSSymbolTypeAnonymous + 1).TSSymbolType + TSLogTypeParse* = (0).TSLogType + TSLogTypeLex* = (TSLogTypeParse + 1).TSLogType + TSQueryPredicateStepTypeDone* = (0).TSQueryPredicateStepType + TSQueryPredicateStepTypeCapture* = (TSQueryPredicateStepTypeDone + 1).TSQueryPredicateStepType + TSQueryPredicateStepTypeString* = (TSQueryPredicateStepTypeCapture + 1).TSQueryPredicateStepType + TSQueryErrorNone* = (0).TSQueryError + TSQueryErrorSyntax* = (TSQueryErrorNone + 1).TSQueryError + TSQueryErrorNodeType* = (TSQueryErrorSyntax + 1).TSQueryError + TSQueryErrorField* = (TSQueryErrorNodeType + 1).TSQueryError + TSQueryErrorCapture* = (TSQueryErrorField + 1).TSQueryError + type - TSSymbol* = uint16 - TSLanguage* = object - TSParser* = object - TSTree* = object - TSPoint* {.importc, header: headerapi, bycopy.} = object + TSSymbol* {.importc, impapiHdr.} = uint16 + TSFieldId* {.importc, impapiHdr.} = uint16 + TSLanguage* {.importc, impapiHdr, incompleteStruct.} = object + TSParser* {.importc, impapiHdr, incompleteStruct.} = object + TSTree* {.importc, impapiHdr, incompleteStruct.} = object + TSQuery* {.importc, impapiHdr, incompleteStruct.} = object + TSQueryCursor* {.importc, impapiHdr, incompleteStruct.} = object + TSPoint* {.bycopy, importc, impapiHdr.} = object row*: uint32 column*: uint32 - TSRange* {.importc, header: headerapi, bycopy.} = object + TSRange* {.bycopy, importc, impapiHdr.} = object start_point*: TSPoint end_point*: TSPoint start_byte*: uint32 end_byte*: uint32 - TSInput* {.importc, header: headerapi, bycopy.} = object + TSInput* {.bycopy, importc, impapiHdr.} = object payload*: pointer read*: proc (payload: pointer; byte_index: uint32; position: TSPoint; - bytes_read: ptr uint32): cstring {.nimcall.} + bytes_read: ptr uint32): cstring {.cdecl.} encoding*: TSInputEncoding - TSLogger* {.importc, header: headerapi, bycopy.} = object + TSLogger* {.bycopy, importc, impapiHdr.} = object payload*: pointer - log*: proc (payload: pointer; a1: TSLogType; a2: cstring) {.nimcall.} + log*: proc (payload: pointer; a2: TSLogType; a3: cstring) {.cdecl.} - TSInputEdit* {.importc, header: headerapi, bycopy.} = object + TSInputEdit* {.bycopy, importc, impapiHdr.} = object start_byte*: uint32 old_end_byte*: uint32 new_end_byte*: uint32 @@ -69,106 +83,176 @@ type old_end_point*: TSPoint new_end_point*: TSPoint - TSNode* {.importc, header: headerapi, bycopy.} = object + TSNode* {.bycopy, importc, impapiHdr.} = object context*: array[4, uint32] id*: pointer tree*: ptr TSTree - TSTreeCursor* {.importc, header: headerapi, bycopy.} = object + TSTreeCursor* {.bycopy, importc, impapiHdr.} = object tree*: pointer id*: pointer context*: array[2, uint32] -proc ts_parser_new*(): ptr TSParser {.importc, header: headerapi.} -proc ts_parser_delete*(a1: ptr TSParser) {.importc, header: headerapi.} -proc ts_parser_language*(a1: ptr TSParser): ptr TSLanguage {.importc, header: headerapi.} -proc ts_parser_set_language*(a1: ptr TSParser; a2: ptr TSLanguage): bool {.importc, - header: headerapi.} -proc ts_parser_logger*(a1: ptr TSParser): TSLogger {.importc, header: headerapi.} -proc ts_parser_set_logger*(a1: ptr TSParser; a2: TSLogger) {.importc, header: headerapi.} -proc ts_parser_print_dot_graphs*(a1: ptr TSParser; a2: cint) {.importc, - header: headerapi.} -proc ts_parser_halt_on_error*(a1: ptr TSParser; a2: bool) {.importc, header: headerapi.} -proc ts_parser_parse*(a1: ptr TSParser; a2: ptr TSTree; a3: TSInput): ptr TSTree {.importc, - header: headerapi.} -proc ts_parser_parse_string*(a1: ptr TSParser; a2: ptr TSTree; a3: cstring; a4: uint32): ptr TSTree {. - importc, header: headerapi.} -proc ts_parser_parse_string_encoding*(a1: ptr TSParser; a2: ptr TSTree; a3: cstring; - a4: uint32; a5: TSInputEncoding): ptr TSTree {. - importc, header: headerapi.} -proc ts_parser_enabled*(a1: ptr TSParser): bool {.importc, header: headerapi.} -proc ts_parser_set_enabled*(a1: ptr TSParser; a2: bool) {.importc, header: headerapi.} -proc ts_parser_operation_limit*(a1: ptr TSParser): cuint {.importc, header: headerapi.} -proc ts_parser_set_operation_limit*(a1: ptr TSParser; a2: cuint) {.importc, - header: headerapi.} -proc ts_parser_reset*(a1: ptr TSParser) {.importc, header: headerapi.} -proc ts_parser_set_included_ranges*(a1: ptr TSParser; a2: ptr TSRange; a3: uint32) {. - importc, header: headerapi.} -proc ts_parser_included_ranges*(a1: ptr TSParser; a2: ptr uint32): ptr TSRange {.importc, - header: headerapi.} -proc ts_tree_copy*(a1: ptr TSTree): ptr TSTree {.importc, header: headerapi.} -proc ts_tree_delete*(a1: ptr TSTree) {.importc, header: headerapi.} -proc ts_tree_root_node*(a1: ptr TSTree): TSNode {.importc, header: headerapi.} -proc ts_tree_edit*(a1: ptr TSTree; a2: ptr TSInputEdit) {.importc, header: headerapi.} -proc ts_tree_get_changed_ranges*(a1: ptr TSTree; a2: ptr TSTree; a3: ptr uint32): ptr TSRange {. - importc, header: headerapi.} -proc ts_tree_print_dot_graph*(a1: ptr TSTree; a2: ptr FILE) {.importc, header: headerapi.} -proc ts_tree_language*(a1: ptr TSTree): ptr TSLanguage {.importc, header: headerapi.} -proc ts_node_start_byte*(a1: TSNode): uint32 {.importc, header: headerapi.} -proc ts_node_start_point*(a1: TSNode): TSPoint {.importc, header: headerapi.} -proc ts_node_end_byte*(a1: TSNode): uint32 {.importc, header: headerapi.} -proc ts_node_end_point*(a1: TSNode): TSPoint {.importc, header: headerapi.} -proc ts_node_symbol*(a1: TSNode): TSSymbol {.importc, header: headerapi.} -proc ts_node_type*(a1: TSNode): cstring {.importc, header: headerapi.} -proc ts_node_string*(a1: TSNode): cstring {.importc, header: headerapi.} -proc ts_node_eq*(a1: TSNode; a2: TSNode): bool {.importc, header: headerapi.} -proc ts_node_is_null*(a1: TSNode): bool {.importc, header: headerapi.} -proc ts_node_is_named*(a1: TSNode): bool {.importc, header: headerapi.} -proc ts_node_is_missing*(a1: TSNode): bool {.importc, header: headerapi.} -proc ts_node_has_changes*(a1: TSNode): bool {.importc, header: headerapi.} -proc ts_node_has_error*(a1: TSNode): bool {.importc, header: headerapi.} -proc ts_node_parent*(a1: TSNode): TSNode {.importc, header: headerapi.} -proc ts_node_child*(a1: TSNode; a2: uint32): TSNode {.importc, header: headerapi.} -proc ts_node_named_child*(a1: TSNode; a2: uint32): TSNode {.importc, header: headerapi.} -proc ts_node_child_count*(a1: TSNode): uint32 {.importc, header: headerapi.} -proc ts_node_named_child_count*(a1: TSNode): uint32 {.importc, header: headerapi.} -proc ts_node_next_sibling*(a1: TSNode): TSNode {.importc, header: headerapi.} -proc ts_node_next_named_sibling*(a1: TSNode): TSNode {.importc, header: headerapi.} -proc ts_node_prev_sibling*(a1: TSNode): TSNode {.importc, header: headerapi.} -proc ts_node_prev_named_sibling*(a1: TSNode): TSNode {.importc, header: headerapi.} -proc ts_node_first_child_for_byte*(a1: TSNode; a2: uint32): TSNode {.importc, - header: headerapi.} + TSQueryCapture* {.bycopy, importc, impapiHdr.} = object + node*: TSNode + index*: uint32 + + TSQueryMatch* {.bycopy, importc, impapiHdr.} = object + id*: uint32 + pattern_index*: uint16 + capture_count*: uint16 + captures*: ptr TSQueryCapture + + TSQueryPredicateStep* {.bycopy, importc, impapiHdr.} = object + `type`*: TSQueryPredicateStepType + value_id*: uint32 + +proc ts_parser_new*(): ptr TSParser {.importc, cdecl, impapiHdr.} +proc ts_parser_delete*(parser: ptr TSParser) {.importc, cdecl, impapiHdr.} +proc ts_parser_set_language*(self: ptr TSParser; language: ptr TSLanguage): bool {. + importc, cdecl, impapiHdr.} +proc ts_parser_language*(self: ptr TSParser): ptr TSLanguage {.importc, cdecl, impapiHdr.} +proc ts_parser_set_included_ranges*(self: ptr TSParser; ranges: ptr TSRange; + length: uint32) {.importc, cdecl, impapiHdr.} +proc ts_parser_included_ranges*(self: ptr TSParser; length: ptr uint32): ptr TSRange {. + importc, cdecl, impapiHdr.} +proc ts_parser_parse*(self: ptr TSParser; old_tree: ptr TSTree; input: TSInput): ptr TSTree {. + importc, cdecl, impapiHdr.} +proc ts_parser_parse_string*(self: ptr TSParser; old_tree: ptr TSTree; string: cstring; + length: uint32): ptr TSTree {.importc, cdecl, impapiHdr.} +proc ts_parser_parse_string_encoding*(self: ptr TSParser; old_tree: ptr TSTree; + string: cstring; length: uint32; + encoding: TSInputEncoding): ptr TSTree {. + importc, cdecl, impapiHdr.} +proc ts_parser_reset*(self: ptr TSParser) {.importc, cdecl, impapiHdr.} +proc ts_parser_set_timeout_micros*(self: ptr TSParser; timeout: uint64) {.importc, + cdecl, impapiHdr.} +proc ts_parser_timeout_micros*(self: ptr TSParser): uint64 {.importc, cdecl, impapiHdr.} +proc ts_parser_set_cancellation_flag*(self: ptr TSParser; flag: ptr uint) {.importc, + cdecl, impapiHdr.} +proc ts_parser_cancellation_flag*(self: ptr TSParser): ptr uint {.importc, cdecl, + impapiHdr.} +proc ts_parser_set_logger*(self: ptr TSParser; logger: TSLogger) {.importc, cdecl, + impapiHdr.} +proc ts_parser_logger*(self: ptr TSParser): TSLogger {.importc, cdecl, impapiHdr.} +proc ts_parser_print_dot_graphs*(self: ptr TSParser; file: cint) {.importc, cdecl, + impapiHdr.} +proc ts_parser_halt_on_error*(self: ptr TSParser; halt: bool) {.importc, cdecl, + impapiHdr.} +proc ts_tree_copy*(self: ptr TSTree): ptr TSTree {.importc, cdecl, impapiHdr.} +proc ts_tree_delete*(self: ptr TSTree) {.importc, cdecl, impapiHdr.} +proc ts_tree_root_node*(self: ptr TSTree): TSNode {.importc, cdecl, impapiHdr.} +proc ts_tree_language*(a1: ptr TSTree): ptr TSLanguage {.importc, cdecl, impapiHdr.} +proc ts_tree_edit*(self: ptr TSTree; edit: ptr TSInputEdit) {.importc, cdecl, impapiHdr.} +proc ts_tree_get_changed_ranges*(old_tree: ptr TSTree; new_tree: ptr TSTree; + length: ptr uint32): ptr TSRange {.importc, cdecl, + impapiHdr.} +proc ts_tree_print_dot_graph*(a1: ptr TSTree; a2: File) {.importc, cdecl, impapiHdr.} +proc ts_node_type*(a1: TSNode): cstring {.importc, cdecl, impapiHdr.} +proc ts_node_symbol*(a1: TSNode): TSSymbol {.importc, cdecl, impapiHdr.} +proc ts_node_start_byte*(a1: TSNode): uint32 {.importc, cdecl, impapiHdr.} +proc ts_node_start_point*(a1: TSNode): TSPoint {.importc, cdecl, impapiHdr.} +proc ts_node_end_byte*(a1: TSNode): uint32 {.importc, cdecl, impapiHdr.} +proc ts_node_end_point*(a1: TSNode): TSPoint {.importc, cdecl, impapiHdr.} +proc ts_node_string*(a1: TSNode): cstring {.importc, cdecl, impapiHdr.} +proc ts_node_is_null*(a1: TSNode): bool {.importc, cdecl, impapiHdr.} +proc ts_node_is_named*(a1: TSNode): bool {.importc, cdecl, impapiHdr.} +proc ts_node_is_missing*(a1: TSNode): bool {.importc, cdecl, impapiHdr.} +proc ts_node_is_extra*(a1: TSNode): bool {.importc, cdecl, impapiHdr.} +proc ts_node_has_changes*(a1: TSNode): bool {.importc, cdecl, impapiHdr.} +proc ts_node_has_error*(a1: TSNode): bool {.importc, cdecl, impapiHdr.} +proc ts_node_parent*(a1: TSNode): TSNode {.importc, cdecl, impapiHdr.} +proc ts_node_child*(a1: TSNode; a2: uint32): TSNode {.importc, cdecl, impapiHdr.} +proc ts_node_child_count*(a1: TSNode): uint32 {.importc, cdecl, impapiHdr.} +proc ts_node_named_child*(a1: TSNode; a2: uint32): TSNode {.importc, cdecl, impapiHdr.} +proc ts_node_named_child_count*(a1: TSNode): uint32 {.importc, cdecl, impapiHdr.} +proc ts_node_child_by_field_name*(self: TSNode; field_name: cstring; + field_name_length: uint32): TSNode {.importc, + cdecl, impapiHdr.} +proc ts_node_child_by_field_id*(a1: TSNode; a2: TSFieldId): TSNode {.importc, cdecl, + impapiHdr.} +proc ts_node_next_sibling*(a1: TSNode): TSNode {.importc, cdecl, impapiHdr.} +proc ts_node_prev_sibling*(a1: TSNode): TSNode {.importc, cdecl, impapiHdr.} +proc ts_node_next_named_sibling*(a1: TSNode): TSNode {.importc, cdecl, impapiHdr.} +proc ts_node_prev_named_sibling*(a1: TSNode): TSNode {.importc, cdecl, impapiHdr.} +proc ts_node_first_child_for_byte*(a1: TSNode; a2: uint32): TSNode {.importc, cdecl, + impapiHdr.} proc ts_node_first_named_child_for_byte*(a1: TSNode; a2: uint32): TSNode {.importc, - header: headerapi.} + cdecl, impapiHdr.} proc ts_node_descendant_for_byte_range*(a1: TSNode; a2: uint32; a3: uint32): TSNode {. - importc, header: headerapi.} -proc ts_node_named_descendant_for_byte_range*(a1: TSNode; a2: uint32; a3: uint32): TSNode {. - importc, header: headerapi.} + importc, cdecl, impapiHdr.} proc ts_node_descendant_for_point_range*(a1: TSNode; a2: TSPoint; a3: TSPoint): TSNode {. - importc, header: headerapi.} + importc, cdecl, impapiHdr.} +proc ts_node_named_descendant_for_byte_range*(a1: TSNode; a2: uint32; a3: uint32): TSNode {. + importc, cdecl, impapiHdr.} proc ts_node_named_descendant_for_point_range*(a1: TSNode; a2: TSPoint; a3: TSPoint): TSNode {. - importc, header: headerapi.} -proc ts_node_edit*(a1: ptr TSNode; a2: ptr TSInputEdit) {.importc, header: headerapi.} -proc ts_tree_cursor_new*(a1: TSNode): TSTreeCursor {.importc, header: headerapi.} -proc ts_tree_cursor_delete*(a1: ptr TSTreeCursor) {.importc, header: headerapi.} -proc ts_tree_cursor_reset*(a1: ptr TSTreeCursor; a2: TSNode) {.importc, - header: headerapi.} -proc ts_tree_cursor_current_node*(a1: ptr TSTreeCursor): TSNode {.importc, - header: headerapi.} -proc ts_tree_cursor_goto_parent*(a1: ptr TSTreeCursor): bool {.importc, - header: headerapi.} -proc ts_tree_cursor_goto_next_sibling*(a1: ptr TSTreeCursor): bool {.importc, - header: headerapi.} -proc ts_tree_cursor_goto_first_child*(a1: ptr TSTreeCursor): bool {.importc, - header: headerapi.} + importc, cdecl, impapiHdr.} +proc ts_node_edit*(a1: ptr TSNode; a2: ptr TSInputEdit) {.importc, cdecl, impapiHdr.} +proc ts_node_eq*(a1: TSNode; a2: TSNode): bool {.importc, cdecl, impapiHdr.} +proc ts_tree_cursor_new*(a1: TSNode): TSTreeCursor {.importc, cdecl, impapiHdr.} +proc ts_tree_cursor_delete*(a1: ptr TSTreeCursor) {.importc, cdecl, impapiHdr.} +proc ts_tree_cursor_reset*(a1: ptr TSTreeCursor; a2: TSNode) {.importc, cdecl, impapiHdr.} +proc ts_tree_cursor_current_node*(a1: ptr TSTreeCursor): TSNode {.importc, cdecl, + impapiHdr.} +proc ts_tree_cursor_current_field_name*(a1: ptr TSTreeCursor): cstring {.importc, + cdecl, impapiHdr.} +proc ts_tree_cursor_current_field_id*(a1: ptr TSTreeCursor): TSFieldId {.importc, + cdecl, impapiHdr.} +proc ts_tree_cursor_goto_parent*(a1: ptr TSTreeCursor): bool {.importc, cdecl, + impapiHdr.} +proc ts_tree_cursor_goto_next_sibling*(a1: ptr TSTreeCursor): bool {.importc, cdecl, + impapiHdr.} +proc ts_tree_cursor_goto_first_child*(a1: ptr TSTreeCursor): bool {.importc, cdecl, + impapiHdr.} proc ts_tree_cursor_goto_first_child_for_byte*(a1: ptr TSTreeCursor; a2: uint32): int64 {. - importc, header: headerapi.} -proc ts_language_symbol_count*(a1: ptr TSLanguage): uint32 {.importc, - header: headerapi.} + importc, cdecl, impapiHdr.} +proc ts_tree_cursor_copy*(a1: ptr TSTreeCursor): TSTreeCursor {.importc, cdecl, + impapiHdr.} +proc ts_query_new*(language: ptr TSLanguage; source: cstring; source_len: uint32; + error_offset: ptr uint32; error_type: ptr TSQueryError): ptr TSQuery {. + importc, cdecl, impapiHdr.} +proc ts_query_delete*(a1: ptr TSQuery) {.importc, cdecl, impapiHdr.} +proc ts_query_pattern_count*(a1: ptr TSQuery): uint32 {.importc, cdecl, impapiHdr.} +proc ts_query_capture_count*(a1: ptr TSQuery): uint32 {.importc, cdecl, impapiHdr.} +proc ts_query_string_count*(a1: ptr TSQuery): uint32 {.importc, cdecl, impapiHdr.} +proc ts_query_start_byte_for_pattern*(a1: ptr TSQuery; a2: uint32): uint32 {.importc, + cdecl, impapiHdr.} +proc ts_query_predicates_for_pattern*(self: ptr TSQuery; pattern_index: uint32; + length: ptr uint32): ptr TSQueryPredicateStep {. + importc, cdecl, impapiHdr.} +proc ts_query_capture_name_for_id*(a1: ptr TSQuery; id: uint32; length: ptr uint32): cstring {. + importc, cdecl, impapiHdr.} +proc ts_query_string_value_for_id*(a1: ptr TSQuery; id: uint32; length: ptr uint32): cstring {. + importc, cdecl, impapiHdr.} +proc ts_query_disable_capture*(a1: ptr TSQuery; a2: cstring; a3: uint32) {.importc, + cdecl, impapiHdr.} +proc ts_query_cursor_new*(): ptr TSQueryCursor {.importc, cdecl, impapiHdr.} +proc ts_query_cursor_delete*(a1: ptr TSQueryCursor) {.importc, cdecl, impapiHdr.} +proc ts_query_cursor_exec*(a1: ptr TSQueryCursor; a2: ptr TSQuery; a3: TSNode) {.importc, + cdecl, impapiHdr.} +proc ts_query_cursor_set_byte_range*(a1: ptr TSQueryCursor; a2: uint32; a3: uint32) {. + importc, cdecl, impapiHdr.} +proc ts_query_cursor_set_point_range*(a1: ptr TSQueryCursor; a2: TSPoint; a3: TSPoint) {. + importc, cdecl, impapiHdr.} +proc ts_query_cursor_next_match*(a1: ptr TSQueryCursor; match: ptr TSQueryMatch): bool {. + importc, cdecl, impapiHdr.} +proc ts_query_cursor_remove_match*(a1: ptr TSQueryCursor; id: uint32) {.importc, cdecl, + impapiHdr.} +proc ts_query_cursor_next_capture*(a1: ptr TSQueryCursor; match: ptr TSQueryMatch; + capture_index: ptr uint32): bool {.importc, cdecl, + impapiHdr.} +proc ts_language_symbol_count*(a1: ptr TSLanguage): uint32 {.importc, cdecl, impapiHdr.} proc ts_language_symbol_name*(a1: ptr TSLanguage; a2: TSSymbol): cstring {.importc, - header: headerapi.} -proc ts_language_symbol_for_name*(a1: ptr TSLanguage; a2: cstring): TSSymbol {.importc, - header: headerapi.} + cdecl, impapiHdr.} +proc ts_language_symbol_for_name*(self: ptr TSLanguage; string: cstring; + length: uint32; is_named: bool): TSSymbol {.importc, + cdecl, impapiHdr.} +proc ts_language_field_count*(a1: ptr TSLanguage): uint32 {.importc, cdecl, impapiHdr.} +proc ts_language_field_name_for_id*(a1: ptr TSLanguage; a2: TSFieldId): cstring {. + importc, cdecl, impapiHdr.} +proc ts_language_field_id_for_name*(a1: ptr TSLanguage; a2: cstring; a3: uint32): TSFieldId {. + importc, cdecl, impapiHdr.} proc ts_language_symbol_type*(a1: ptr TSLanguage; a2: TSSymbol): TSSymbolType {. - importc, header: headerapi.} -proc ts_language_version*(a1: ptr TSLanguage): uint32 {.importc, header: headerapi.} + importc, cdecl, impapiHdr.} +proc ts_language_version*(a1: ptr TSLanguage): uint32 {.importc, cdecl, impapiHdr.} +{.pop.} diff --git a/nimterop/treesitter/tsgen.nim b/nimterop/treesitter/tsgen.nim index 484483c..ee2c8e0 100644 --- a/nimterop/treesitter/tsgen.nim +++ b/nimterop/treesitter/tsgen.nim @@ -5,14 +5,7 @@ import os import nimterop/[cimport, paths] -cPlugin: - import strutils - - proc onSymbol*(sym: var Symbol) {.exportc, dynlib.} = - if "_CRT" in sym.name: - sym.name = sym.name.strip(chars={'_'}) - static: cDebug() -cImport(cacheDir / "treesitter" /"lib" / "include" / "tree_sitter" / "api.h") +cImport(cacheDir / "treesitter" / "lib" / "include" / "tree_sitter" / "api.h", flags = "-E_ -c") From e3e1d80a55777b695db393fc440226093044472b Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 25 Jun 2020 10:00:12 -0500 Subject: [PATCH 538/593] Add minitest for nim CI --- CHANGES.md | 2 ++ nimterop.nimble | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 93bb8af..6748521 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -31,6 +31,8 @@ https://github.com/nimterop/nimterop/compare/v0.5.9...v0.6.0 - The `dynlib` command line parameter to `toast` and `cImport()` can also be the path to a shared library (dll|so|dylib) in place of a Nim const string containing the path. This allows for the traditional use case of passing `"xxxLPath"` to `cImport()` as well as simply passing the path to the library on the command line as is. This allows the creation of standalone cached wrappers as well as the usage of the `--check` and the `--stub` functionality that `toast` provides via `cImport()`. +- `gitPull()` now checks if an existing repository is at the `checkout` value specified. If not, it will pull the latest changes and checkout the specified commit, tag or branch. + ## Version 0.5.0 diff --git a/nimterop.nimble b/nimterop.nimble index 7be89c6..101805e 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -45,6 +45,11 @@ task btd, "build toast": task docs, "Generate docs": buildDocs(@["nimterop/all.nim"], "build/htmldocs") +task minitest, "Test for Nim CI": + exec "nim c -f -d:danger nimterop/toast" + exec "nim c -f -d:checkAbi -r tests/tast2.nim" + exec "nim c -f -d:checkAbi -d:zlibStd -d:zlibDL -d:zlibSetVer=1.2.11 -r tests/zlib.nim" + task test, "Test": rmFile("tests/timeit.txt") From 4ece07969d9aea6e9d8966b64fa445477115483a Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Sat, 27 Jun 2020 12:28:22 -0500 Subject: [PATCH 539/593] Bump dep versions --- nimterop.nimble | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimterop.nimble b/nimterop.nimble index 101805e..bf9f520 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -9,7 +9,7 @@ bin = @["nimterop/toast"] installDirs = @["nimterop"] # Dependencies -requires "nim >= 0.20.2", "regex >= 0.14.1", "cligen >= 0.9.45" +requires "nim >= 0.20.2", "regex >= 0.15.0", "cligen >= 1.0.0" import nimterop/docs import os From f543124d7e2bec7f7ca8a47b70d88438a96443ed Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 29 Jun 2020 21:47:00 -0500 Subject: [PATCH 540/593] Fix #125 - no more types import --- nimterop/all.nim | 2 +- nimterop/cimport.nim | 5 +-- nimterop/enumtype.nim | 42 ++++++++++++++++++ nimterop/globals.nim | 5 ++- nimterop/toastlib/ast2.nim | 11 +++-- nimterop/toastlib/comphelp.nim | 2 +- nimterop/toastlib/exprparser.nim | 2 +- nimterop/toastlib/getters.nim | 41 +++++++++++++++++- nimterop/treesitter/api.nim | 3 +- nimterop/types.nim | 74 -------------------------------- 10 files changed, 99 insertions(+), 88 deletions(-) create mode 100644 nimterop/enumtype.nim delete mode 100644 nimterop/types.nim diff --git a/nimterop/all.nim b/nimterop/all.nim index 6be6d11..20ab4e8 100644 --- a/nimterop/all.nim +++ b/nimterop/all.nim @@ -2,4 +2,4 @@ The following modules are available to users of Nimterop. ]## -import "."/[docs, cimport, build, types, plugin] +import "."/[build, cimport, docs, plugin] diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index edfdeb9..b5c62a2 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -17,8 +17,7 @@ All `{.compileTime.}` procs must be used in a compile time context, e.g. using: import hashes, macros, os, strformat, strutils -import "."/[build, globals, paths, types] -export types +import "."/[build, globals, paths] proc interpPath(dir: string): string= # TODO: more robust: needs a DirSep after "$projpath" @@ -153,7 +152,7 @@ proc getToast(fullpaths: seq[string], recurse: bool = false, dynlib: string = "" # see https://github.com/nimterop/nimterop/issues/69 (result, ret) = execAction(cmd, die = false, cache = (not gStateCT.nocache), - cacheKey = getCacheValue(fullpaths)) + cacheKey = getCacheValue(toastExe) & getCacheValue(fullpaths)) doAssert ret == 0, getToastError(result) macro cOverride*(body): untyped = diff --git a/nimterop/enumtype.nim b/nimterop/enumtype.nim new file mode 100644 index 0000000..3c20b79 --- /dev/null +++ b/nimterop/enumtype.nim @@ -0,0 +1,42 @@ +import macros + +macro defineEnum(typ: untyped): untyped = + result = newNimNode(nnkStmtList) + + # Enum mapped to distinct cint + result.add quote do: + type `typ`* = distinct cint + + for i in ["+", "-", "*", "div", "mod", "shl", "shr", "or", "and", "xor", "<", "<=", "==", ">", ">="]: + let + ni = newIdentNode(i) + typout = if i[0] in "<=>": newIdentNode("bool") else: typ # comparisons return bool + if i[0] == '>': # cannot borrow `>` and `>=` from templates + let + nopp = if i.len == 2: newIdentNode("<=") else: newIdentNode("<") + result.add quote do: + proc `ni`*(x: `typ`, y: cint): `typout` = `nopp`(y, x) + proc `ni`*(x: cint, y: `typ`): `typout` = `nopp`(y, x) + proc `ni`*(x, y: `typ`): `typout` = `nopp`(y, x) + else: + result.add quote do: + proc `ni`*(x: `typ`, y: cint): `typout` {.borrow.} + proc `ni`*(x: cint, y: `typ`): `typout` {.borrow.} + proc `ni`*(x, y: `typ`): `typout` {.borrow.} + result.add quote do: + proc `ni`*(x: `typ`, y: int): `typout` = `ni`(x, y.cint) + proc `ni`*(x: int, y: `typ`): `typout` = `ni`(x.cint, y) + + let + divop = newIdentNode("/") # `/`() + dlrop = newIdentNode("$") # `$`() + notop = newIdentNode("not") # `not`() + result.add quote do: + proc `divop`*(x, y: `typ`): `typ` = `typ`((x.float / y.float).cint) + proc `divop`*(x: `typ`, y: cint): `typ` = `divop`(x, `typ`(y)) + proc `divop`*(x: cint, y: `typ`): `typ` = `divop`(`typ`(x), y) + proc `divop`*(x: `typ`, y: int): `typ` = `divop`(x, y.cint) + proc `divop`*(x: int, y: `typ`): `typ` = `divop`(x.cint, y) + + proc `dlrop`*(x: `typ`): string {.borrow.} + proc `notop`*(x: `typ`): `typ` {.borrow.} diff --git a/nimterop/globals.nim b/nimterop/globals.nim index c831589..d1e22a6 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -54,7 +54,7 @@ type constIdentifiers*: HashSet[string] # Const names for enum casting identifiers*: TableRef[string, string] # Symbols that have been declared so far indexed by nimName skippedSyms*: HashSet[string] # Symbols that have been skipped due to being unwrappable or - # the user provided override is blank + # the user provided override is blank # Nim compiler objects constSection*, enumSection*, pragmaSection*, procSection*, typeSection*, varSection*: PNode @@ -70,6 +70,9 @@ type # Controls whether or not the current expression # should validate idents against currently defined idents skipIdentValidation*: bool + + # Top level header for wrapper output - include imported types, pragmas and other info + wrapperHeader*: string else: # cimport.nim specific compile*: seq[string] # `cCompile()` list of files already processed diff --git a/nimterop/toastlib/ast2.nim b/nimterop/toastlib/ast2.nim index 783b6e4..0147463 100644 --- a/nimterop/toastlib/ast2.nim +++ b/nimterop/toastlib/ast2.nim @@ -1481,6 +1481,11 @@ proc addEnum(gState: State, node: TSNode) = if node.getName() == "type_definition" and node.len > 1: gState.addTypeTyped(node, ftname = name, offset = offset) + if gEnumMacro.nBl: + # Add enum generation macro once + gState.wrapperHeader &= gEnumMacro + gEnumMacro = "" + proc addProc(gState: State, node, rnode: TSNode, commentNodes: seq[TSNode]) = # Add a proc # @@ -1822,10 +1827,7 @@ proc setupPragmas(gState: State, root: TSNode, fullpath: string) = proc initNim*(gState: State) = # Initialize for parseNim() one time - gecho """import nimterop/types - -{.push hint[ConvFromXtoItselfNotNeeded]: off.} -""" + gState.wrapperHeader = "{.push hint[ConvFromXtoItselfNotNeeded]: off.}\n" # Track identifiers already rendered and corresponding PNodes gState.identifiers = newTable[string, string]() @@ -1876,6 +1878,7 @@ proc printNim*(gState: State) = tree.add gState.varSection tree.add gState.procSection + gecho gState.wrapperHeader gecho tree.renderTree() gecho "{.pop.}" \ No newline at end of file diff --git a/nimterop/toastlib/comphelp.nim b/nimterop/toastlib/comphelp.nim index d404c42..642fbbd 100644 --- a/nimterop/toastlib/comphelp.nim +++ b/nimterop/toastlib/comphelp.nim @@ -95,7 +95,7 @@ proc getNameInfo*(gState: State, node: TSNode, kind: NimSymKind, parent = ""): result.name = gState.getIdentifier(result.origname, kind, parent) if result.name.nBl: if kind == nskType: - result.name = result.name.getType() + result.name = gState.getType(result.name, parent) result.info = gState.getLineInfo(node) proc getPtrType*(str: string): string = diff --git a/nimterop/toastlib/exprparser.nim b/nimterop/toastlib/exprparser.nim index 13b1a98..a77dbf9 100644 --- a/nimterop/toastlib/exprparser.nim +++ b/nimterop/toastlib/exprparser.nim @@ -580,7 +580,7 @@ proc processTSNode(gState: State, node: TSNode, typeofNode: var PNode): PNode = of "sized_type_specifier", "primitive_type", "type_identifier": # Input -> int, unsigned int, long int, etc # Output -> cint, cuint, clong, etc - let ty = getType(node.val) + let ty = gState.getType(node.val, parent = node.getName()) if ty.len > 0: # If ty is not empty, one of C's builtin types has been found result = gState.getExprIdent(ty, nskType, parent=node.getName()) diff --git a/nimterop/toastlib/getters.nim b/nimterop/toastlib/getters.nim index c3f48ae..43a4f6f 100644 --- a/nimterop/toastlib/getters.nim +++ b/nimterop/toastlib/getters.nim @@ -29,7 +29,13 @@ yield""".split(Whitespace).toHashSet() # Types related +const + # Enum macro read from file - written into wrapper when required + gEnumMacroConst = staticRead(currentSourcePath.parentDir().parentDir() / "enumtype.nim") + var + gEnumMacro* = gEnumMacroConst + gTypeMap* = { # char "char": "cchar", @@ -107,13 +113,40 @@ var "long double": "clongdouble", # Misc Nim types - "Bool": "bool" + "Bool": "bool", + "ptrdiff_t": "ByteAddress" }.toTable() # Nim type names that shouldn't need to be wrapped again gTypeMapValues* = toSeq(gTypeMap.values).toHashSet() -proc getType*(str: string): string = + # Types to import from C/Nim if used in wrapper + gTypeImport* = { + "time_t": """ +import std/time_t as std_time_t +type time_t* = Time +""", + + "time64_t": """ +import std/time_t as std_time64_t +type time64_t* = Time +""", + + "wchar_t": """ +when defined(cpp): + # http://www.cplusplus.com/reference/cwchar/wchar_t/ + # In C++, wchar_t is a distinct fundamental type (and thus it is + # not defined in nor any other header). + type wchar_t* {.importc.} = object +else: + type wchar_t* {.importc, header:"".} = object +""", + + "va_list": """ +type va_list* {.importc, header:"".} = object +"""}.toTable() + +proc getType*(gState: State, str, parent: string): string = if str == "void": return "object" @@ -121,6 +154,10 @@ proc getType*(str: string): string = if gTypeMap.hasKey(result): result = gTypeMap[result] + elif parent.nBl and gTypeImport.hasKey(result) and not gState.identifierNodes.hasKey(result): + # Include C/Nim type imports once if a field/param and not already declared + gState.wrapperHeader &= "\n" & gTypeImport[result] + gTypeImport.del result # Identifier related diff --git a/nimterop/treesitter/api.nim b/nimterop/treesitter/api.nim index 116bc10..753178c 100644 --- a/nimterop/treesitter/api.nim +++ b/nimterop/treesitter/api.nim @@ -2,7 +2,8 @@ import strutils, os -import ".."/[setup, paths, types] +include ".."/enumtype +import ".."/[paths, setup] static: treesitterSetup() diff --git a/nimterop/types.nim b/nimterop/types.nim deleted file mode 100644 index 38f95d1..0000000 --- a/nimterop/types.nim +++ /dev/null @@ -1,74 +0,0 @@ -# see https://github.com/nimterop/nimterop/issues/79 - -import std/time_t as time_t_temp -type - time_t* = time_t_temp.Time - time64_t* = time_t_temp.Time - -when defined(cpp): - # http://www.cplusplus.com/reference/cwchar/wchar_t/ - # In C++, wchar_t is a distinct fundamental type (and thus it is - # not defined in nor any other header). - type - wchar_t* {.importc.} = object -else: - type - wchar_t* {.importc, header:"".} = object - -type - ptrdiff_t* = ByteAddress - -type - va_list* {.importc, header:"".} = object - -template enumOp*(op, typ, typout) = - proc op*(x: typ, y: cint): typout {.borrow.} - proc op*(x: cint, y: typ): typout {.borrow.} - proc op*(x, y: typ): typout {.borrow.} - - proc op*(x: typ, y: int): typout = op(x, y.cint) - proc op*(x: int, y: typ): typout = op(x.cint, y) - -template defineEnum*(typ) = - # Create a `distinct cint` type for C enums since Nim enums - # need to be in order and cannot have duplicates. - type - typ* = distinct cint - - # Enum operations allowed - enumOp(`+`, typ, typ) - enumOp(`-`, typ, typ) - enumOp(`*`, typ, typ) - enumOp(`<`, typ, bool) - enumOp(`<=`, typ, bool) - enumOp(`==`, typ, bool) - enumOp(`div`, typ, typ) - enumOp(`mod`, typ, typ) - - # These don't work with `enumOp()` for some reason - proc `shl`*(x: typ, y: cint): typ {.borrow.} - proc `shl`*(x: cint, y: typ): typ {.borrow.} - proc `shl`*(x, y: typ): typ {.borrow.} - - proc `shr`*(x: typ, y: cint): typ {.borrow.} - proc `shr`*(x: cint, y: typ): typ {.borrow.} - proc `shr`*(x, y: typ): typ {.borrow.} - - proc `or`*(x: typ, y: cint): typ {.borrow.} - proc `or`*(x: cint, y: typ): typ {.borrow.} - proc `or`*(x, y: typ): typ {.borrow.} - - proc `and`*(x: typ, y: cint): typ {.borrow.} - proc `and`*(x: cint, y: typ): typ {.borrow.} - proc `and`*(x, y: typ): typ {.borrow.} - - proc `xor`*(x: typ, y: cint): typ {.borrow.} - proc `xor`*(x: cint, y: typ): typ {.borrow.} - proc `xor`*(x, y: typ): typ {.borrow.} - - proc `/`*(x, y: typ): typ = - return (x.float / y.float).cint.typ - proc `/`*(x: typ, y: cint): typ = `/`(x, y.typ) - proc `/`*(x: cint, y: typ): typ = `/`(x.typ, y) - - proc `$`*(x: typ): string {.borrow.} From a28c3e7cb4f6da157667b921ab725b92f6774512 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 30 Jun 2020 14:08:09 -0500 Subject: [PATCH 541/593] Improve errors - don't point to macros.nim --- CHANGES.md | 6 ++ nimterop.nimble | 2 +- nimterop/build/shell.nim | 14 +++-- nimterop/cimport.nim | 124 +++++++++++++++++++-------------------- nimterop/toast.nim | 9 ++- 5 files changed, 84 insertions(+), 71 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 6748521..3488252 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -33,6 +33,12 @@ https://github.com/nimterop/nimterop/compare/v0.5.9...v0.6.0 - `gitPull()` now checks if an existing repository is at the `checkout` value specified. If not, it will pull the latest changes and checkout the specified commit, tag or branch. +### Other improvements + +- Generated wrappers no longer depend on nimterop being present - no more `import nimterop/types`. Supporting code is directly included in the wrapper output and only when required. E.g. enum macro is only included if wrapper contains enums. [#125](i125) (since v0.6.1) + +- `cImport()` now includes wrapper output from a file rather than inline. Errors in generated wrappers will no longer point to a line in `macros.nim` making debugging easier. + ## Version 0.5.0 diff --git a/nimterop.nimble b/nimterop.nimble index bf9f520..ebc5f0a 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -1,6 +1,6 @@ # Package -version = "0.6.0" +version = "0.6.1" author = "genotrance" description = "C/C++ interop for Nim" license = "MIT" diff --git a/nimterop/build/shell.nim b/nimterop/build/shell.nim index 53c0b5f..2b29734 100644 --- a/nimterop/build/shell.nim +++ b/nimterop/build/shell.nim @@ -23,7 +23,8 @@ else: export sleep proc execAction*(cmd: string, retry = 0, die = true, cache = false, - cacheKey = "", onRetry: proc() = nil): tuple[output: string, ret: int] = + cacheKey = "", onRetry: proc() = nil, + onError: proc(output: string, err: int) = nil): tuple[output: string, ret: int] = ## Execute an external command - supported at compile time ## ## Checks if command exits successfully before returning. If not, an @@ -34,6 +35,8 @@ proc execAction*(cmd: string, retry = 0, die = true, cache = false, ## `die = false` - return on errors ## `cache = true` - cache results unless cleared with -f ## `cacheKey` - key to create unique cache entry + ## `onRetry()` - proc to call before retrying + ## `onError(output, err)` - proc to call on error let ccmd = fixCmd(cmd) @@ -80,9 +83,12 @@ proc execAction*(cmd: string, retry = 0, die = true, cache = false, onRetry() sleep(500) result = execAction(cmd, retry = retry - 1, die, cache, cacheKey) - elif die: - doAssert false, "Command failed: " & $result.ret & "\ncmd: " & ccmd & - "\nresult:\n" & result.output + else: + if not onError.isNil: + onError(result.output, result.ret) + + doAssert not die, "Command failed: " & $result.ret & "\ncmd: " & ccmd & + "\nresult:\n" & result.output when not defined(TOAST): proc findExe*(exe: string): string = diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index b5c62a2..6e0a80f 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -17,7 +17,8 @@ All `{.compileTime.}` procs must be used in a compile time context, e.g. using: import hashes, macros, os, strformat, strutils -import "."/[build, globals, paths] +import "."/[globals, paths] +import "."/build/[ccompiler, misc, nimconf, shell] proc interpPath(dir: string): string= # TODO: more robust: needs a DirSep after "$projpath" @@ -90,35 +91,30 @@ proc getToastError(output: string): string = if result.Bl: result = "\n\n" & output -proc getNimCheckError(output: string): tuple[tmpFile, errors: string] = - let - hash = output.hash().abs() - - result.tmpFile = getProjectCacheDir("failed", forceClean = false) / "nimterop_" & $hash & ".nim" - - if not fileExists(result.tmpFile) or gStateCT.nocache or compileOption("forceBuild"): - mkDir(result.tmpFile.parentDir()) - writeFile(result.tmpFile, output) - - doAssert fileExists(result.tmpFile), "Failed to write to cache dir: " & result.tmpFile - +proc getNimCheckError(nimFile: string) = let (check, _) = execAction( - &"{getCurrentNimCompiler()} check {result.tmpFile.sanitizePath}", + &"{getCurrentNimCompiler()} check {nimFile.sanitizePath}", die = false ) - result.errors = "\n\n" & check + doAssert false, &"\n\n{check}\n\n" & + "Codegen limitation or error - review 'nim check' output above generated for " & nimFile proc getToast(fullpaths: seq[string], recurse: bool = false, dynlib: string = "", mode = "c", flags = "", noNimout = false): string = var - ret = 0 cmd = when defined(Windows): "cmd /c " else: "" + ext = "h" + + let + toastExe = toastExePath() + # see https://github.com/nimterop/nimterop/issues/69 + cacheKey = getCacheValue(toastExe) & getCacheValue(fullpaths) - let toastExe = toastExePath() doAssert fileExists(toastExe), "toast not compiled: " & toastExe.sanitizePath & " make sure 'nimble build' or 'nimble install' built it" + cmd &= &"{toastExe} --preprocess -m:{mode}" if recurse: @@ -147,13 +143,29 @@ proc getToast(fullpaths: seq[string], recurse: bool = false, dynlib: string = "" if gStateCT.pluginSourcePath.nBl: cmd.add &" --pluginSourcePath={gStateCT.pluginSourcePath.sanitizePath}" + ext = "nim" + for fullpath in fullpaths: cmd.add &" {fullpath.sanitizePath}" - # see https://github.com/nimterop/nimterop/issues/69 - (result, ret) = execAction(cmd, die = false, cache = (not gStateCT.nocache), - cacheKey = getCacheValue(toastExe) & getCacheValue(fullpaths)) - doAssert ret == 0, getToastError(result) + # Generate filename for toast output + let + hash = (cmd & cacheKey).hash().abs() + cachePath = getNimteropCacheDir() / "toastCache" / "nimterop_" & $hash + + result = cachePath.addFileExt(ext) + + if not fileExists(result) or compileOption("forceBuild"): + let + dir = cachePath.parentDir() + if not dirExists(dir): + mkDir(dir) + + cmd.add &" -o {result.sanitizePath}" + + var + (_, ret) = execAction(cmd, die = false) + doAssert ret == 0, getToastError(result.readFile()) macro cOverride*(body): untyped = ## When the wrapper code generated by nimterop is missing certain symbols or not @@ -567,7 +579,7 @@ macro cImport*(filenames: static seq[string], recurse: static bool = false, dynl gecho "# Importing " & fullpaths.join(", ").sanitizePath let - output = getToast(fullpaths, recurse, dynlib, mode, flags) + nimFile = getToast(fullpaths, recurse, dynlib, mode, flags) # Reset plugin and overrides for next cImport if gStateCT.overrides.nBl: @@ -575,16 +587,12 @@ macro cImport*(filenames: static seq[string], recurse: static bool = false, dynl gStateCT.overrides = "" if gStateCT.debug: - gecho output + gecho nimFile.readFile() try: - let body = parseStmt(output) - - result.add body + result.add parseStmt("include " & nimFile.changeFileExt("")) except: - let - (tmpFile, errors) = getNimCheckError(output) - doAssert false, errors & "\n\nNimterop codegen limitation or error - review 'nim check' output above generated for " & tmpFile + getNimCheckError(nimFile) macro cImport*(filename: static string, recurse: static bool = false, dynlib: static string = "", mode: static string = "c", flags: static string = ""): untyped = @@ -663,49 +671,37 @@ macro c2nImport*(filename: static string, recurse: static bool = false, dynlib: gecho "# Importing " & fullpath & " with c2nim" let - output = getToast(@[fullpath], recurse, dynlib, mode, noNimout = true) - hash = output.hash().abs() - hpath = getProjectCacheDir("c2nimCache", forceClean = false) / "nimterop_" & $hash & ".h" - npath = hpath[0 .. hpath.rfind('.')] & "nim" + hFile = getToast(@[fullpath], recurse, dynlib, mode, noNimout = true) + nimFile = hFile.changeFileExt("nim") header = "header" & fullpath.splitFile().name.split(seps = {'-', '.'}).join() - if not fileExists(hpath) or gStateCT.nocache or compileOption("forceBuild"): - mkDir(hpath.parentDir()) - writeFile(hpath, output) + if not fileExists(nimFile) or compileOption("forceBuild"): + var + cmd = when defined(Windows): "cmd /c " else: "" + cmd &= &"c2nim {hFile} --header:{header}" - doAssert fileExists(hpath), "Unable to write temporary header file: " & hpath + if dynlib.nBl: + cmd.add &" --dynlib:{dynlib}" + if mode.contains("cpp"): + cmd.add " --cpp" + if flags.nBl: + cmd.add &" {flags}" - var - cmd = when defined(Windows): "cmd /c " else: "" - cmd &= &"c2nim {hpath} --header:{header}" + for i in gStateCT.defines: + cmd.add &" --assumedef:{i.quoteShell}" - if dynlib.nBl: - cmd.add &" --dynlib:{dynlib}" - if mode.contains("cpp"): - cmd.add " --cpp" - if flags.nBl: - cmd.add &" {flags}" + let + (c2nimout, ret) = execAction(cmd) + if ret != 0: + rmFile(nimFile) + doAssert false, "\n\nc2nim codegen limitation or error - " & c2nimout - for i in gStateCT.defines: - cmd.add &" --assumedef:{i.quoteShell}" - - let - (c2nimout, ret) = execAction(cmd, cache = not gStateCT.nocache, - cacheKey = getCacheValue(hpath)) - - doAssert ret == 0, "\n\nc2nim codegen limitation or error - " & c2nimout - - var - nimout = &"const {header} = \"{fullpath}\"\n\n" & readFile(npath) + nimFile.writeFile(&"const {header} = \"{fullpath}\"\n\n" & readFile(nimFile)) if gStateCT.debug: - gecho nimout + gecho nimFile.readFile() try: - let body = parseStmt(nimout) - - result.add body + result.add parseStmt("include " & nimFile.changeFileExt("")) except: - let - (tmpFile, errors) = getNimCheckError(nimout) - doAssert false, errors & "\n\nc2nim codegen limitation or error - review 'nim check' output above generated for " & tmpFile + getNimCheckError(nimFile) diff --git a/nimterop/toast.nim b/nimterop/toast.nim index 6fe5180..fbaa960 100644 --- a/nimterop/toast.nim +++ b/nimterop/toast.nim @@ -8,6 +8,10 @@ import "."/toastlib/[ast2, getters, tshelp] import "."/build/[ccompiler, misc] +var + # Output generated before main() is called + preMainOut = "" + proc process(gState: State, path: string) = doAssert existsFile(path), &"Invalid path {path}" @@ -129,6 +133,7 @@ proc main( if source.nBl: # Print source after preprocess or Nim output if gState.pnim: + gecho preMainOut gState.initNim() for src in source: gState.process(src.expandSymlinkAbs()) @@ -187,7 +192,7 @@ proc mergeParams(cmdNames: seq[string], cmdLine = commandLineParams()): seq[stri # https://github.com/c-blake/cligen/issues/149 for param in cmdLine: if param.fileExists() and param.splitFile().ext == ".cfg": - echo &"# Loading flags from '{param}'" + preMainOut &= &"# Loading flags from '{param}'\n" for line in param.readFile().splitLines(): let line = line.strip() @@ -197,7 +202,7 @@ proc mergeParams(cmdNames: seq[string], cmdLine = commandLineParams()): seq[stri result.add param if result.len != 0 and "-h" notin result and "--help" notin result: - echo &"""# Generated @ {$now()} + preMainOut &= &"""# Generated @ {$now()} # Command line: # {getAppFilename()} {result.join(" ")} """ From b22b23620da088f8728802199bb1a8c0f5999ec6 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 30 Jun 2020 15:43:09 -0500 Subject: [PATCH 542/593] Fix Windows include issue --- nimterop/cimport.nim | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index 6e0a80f..109b172 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -154,6 +154,8 @@ proc getToast(fullpaths: seq[string], recurse: bool = false, dynlib: string = "" cachePath = getNimteropCacheDir() / "toastCache" / "nimterop_" & $hash result = cachePath.addFileExt(ext) + when defined(Windows): + result = result.replace(DirSep, '/') if not fileExists(result) or compileOption("forceBuild"): let @@ -590,7 +592,10 @@ macro cImport*(filenames: static seq[string], recurse: static bool = false, dynl gecho nimFile.readFile() try: - result.add parseStmt("include " & nimFile.changeFileExt("")) + let + nimFileNode = newStrLitNode(nimFile.changeFileExt("")) + result.add quote do: + include `nimFileNode` except: getNimCheckError(nimFile) @@ -702,6 +707,9 @@ macro c2nImport*(filename: static string, recurse: static bool = false, dynlib: gecho nimFile.readFile() try: - result.add parseStmt("include " & nimFile.changeFileExt("")) + let + nimFileNode = newStrLitNode(nimFile.changeFileExt("")) + result.add quote do: + include `nimFileNode` except: getNimCheckError(nimFile) From 2aef7c99b36bbc9db9bcbcd62c06c6a5e2d4d0c0 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 30 Jun 2020 22:33:10 -0500 Subject: [PATCH 543/593] Fix #127 - write wrapper to file --- CHANGES.md | 14 +++-- nimterop.nimble | 30 +++++++--- nimterop/cimport.nim | 135 ++++++++++++++++++++----------------------- tests/tast2.nim | 6 +- 4 files changed, 100 insertions(+), 85 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 3488252..43f1d34 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -15,13 +15,13 @@ Refer to the documentation for `getHeader()` for details on how to use this new See the full list of changes here: -https://github.com/nimterop/nimterop/compare/v0.5.9...v0.6.0 +https://github.com/nimterop/nimterop/compare/v0.5.9...v0.6.1 ### Breaking changes - The legacy algorithm has been removed as promised. `ast2` is now the default and wrappers no longer need to explicitly specify `-f:ast2` in order to use it. -- All shared libraries installed by `getHeader()` will now get copied into the `libdir` parameter specified. If left blank, `libdir` will default to the directory where the executable binary gets created (outdir). While this is not really a breaking change, it is a change in behavior compared to older versions of nimterop. Note that `Std` libraries are not copied over. [#154](i154) +- All shared libraries installed by `getHeader()` will now get copied into the `libdir` parameter specified. If left blank, `libdir` will default to the directory where the executable binary gets created (outdir). While this is not really a breaking change, it is a change in behavior compared to older versions of nimterop. Note that `Std` libraries are not copied over. [#154][i154] - `git.nim` has been removed. This module was an artifact from the early days and was renamed to `build.nim` back in v0.2.0. @@ -33,11 +33,13 @@ https://github.com/nimterop/nimterop/compare/v0.5.9...v0.6.0 - `gitPull()` now checks if an existing repository is at the `checkout` value specified. If not, it will pull the latest changes and checkout the specified commit, tag or branch. +- `cImport()` can now write the generated wrapper output to a user-defined file with the `nimFile` param. [#127][i127] (since v0.6.1) + ### Other improvements -- Generated wrappers no longer depend on nimterop being present - no more `import nimterop/types`. Supporting code is directly included in the wrapper output and only when required. E.g. enum macro is only included if wrapper contains enums. [#125](i125) (since v0.6.1) +- Generated wrappers no longer depend on nimterop being present - no more `import nimterop/types`. Supporting code is directly included in the wrapper output and only when required. E.g. enum macro is only included if wrapper contains enums. [#125][i125] (since v0.6.1) -- `cImport()` now includes wrapper output from a file rather than inline. Errors in generated wrappers will no longer point to a line in `macros.nim` making debugging easier. +- `cImport()` now includes wrapper output from a file rather than inline. Errors in generated wrappers will no longer point to a line in `macros.nim` making debugging easier. (since v0.6.1) ## Version 0.5.0 @@ -50,7 +52,7 @@ Version 0.6.0 of Nimterop will make `ast2` the default backend and the legacy al See the full list of changes here: -https://github.com/nimterop/nimterop/compare/v0.4.4...v0.5.0 +https://github.com/nimterop/nimterop/compare/v0.4.4...v0.5.4 ### Breaking changes @@ -108,6 +110,8 @@ https://github.com/nimterop/nimterop/compare/v0.4.4...v0.5.0 [i54]: https://github.com/nimterop/nimterop/issues/54 [i74]: https://github.com/nimterop/nimterop/issues/74 [i76]: https://github.com/nimterop/nimterop/issues/76 +[i125]: https://github.com/nimterop/nimterop/issues/125 +[i127]: https://github.com/nimterop/nimterop/issues/127 [i137]: https://github.com/nimterop/nimterop/issues/137 [i147]: https://github.com/nimterop/nimterop/issues/147 [i148]: https://github.com/nimterop/nimterop/issues/148 diff --git a/nimterop.nimble b/nimterop.nimble index ebc5f0a..628ef40 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -50,14 +50,10 @@ task minitest, "Test for Nim CI": exec "nim c -f -d:checkAbi -r tests/tast2.nim" exec "nim c -f -d:checkAbi -d:zlibStd -d:zlibDL -d:zlibSetVer=1.2.11 -r tests/zlib.nim" -task test, "Test": - rmFile("tests/timeit.txt") - - buildTimeitTask() - buildToastTask() - +task basic, "Basic tests": execTest "tests/tast2.nim" execTest "tests/tast2.nim", "-d:NOHEADER" + execTest "tests/tast2.nim", "-d:NOHEADER -d:WRAPPED" execTest "tests/tnimterop_c.nim" execTest "tests/tnimterop_c.nim", "-d:FLAGS=\"-H\"" @@ -65,6 +61,7 @@ task test, "Test": execCmd "nim cpp --hints:off -f -r tests/tnimterop_cpp.nim" execCmd "./nimterop/toast tests/toast.cfg tests/include/toast.h" +task wrapper, "Wrapper tests": execTest "tests/tpcre.nim" when defined(Linux): @@ -79,12 +76,29 @@ task test, "Test": execTest "tests/tsoloud.nim" execTest "tests/tsoloud.nim", "-d:FLAGS=\"-H\"" - # getHeader tests +task getheader, "getHeader tests": withDir("tests"): exec "nim e getheader.nims" - if not existsEnv("APPVEYOR"): + +task package, "Wrapper package tests": + if not existsEnv("APPVEYOR"): + withDir("tests"): exec "nim e wrappers.nims" +task test, "Test": + rmFile("tests/timeit.txt") + + buildTimeitTask() + buildToastTask() + + basicTask() + + wrapperTask() + + getheaderTask() + + packageTask() + docsTask() echo readFile("tests/timeit.txt") diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index 109b172..d992c04 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -70,6 +70,9 @@ proc walkDirImpl(indir, inext: string, file=true): seq[string] = if ret == 0: result = output.splitLines() +proc fixRelFile(file: string): string = + if file.isAbsolute(): file else: getProjectDir() / file + proc getCacheValue(fullpath: string): string = if not gStateCT.nocache: result = fullpath.getFileDate() @@ -102,7 +105,7 @@ proc getNimCheckError(nimFile: string) = "Codegen limitation or error - review 'nim check' output above generated for " & nimFile proc getToast(fullpaths: seq[string], recurse: bool = false, dynlib: string = "", - mode = "c", flags = "", noNimout = false): string = + mode = "c", flags = "", outFile = "", noNimout = false): string = var cmd = when defined(Windows): "cmd /c " else: "" ext = "h" @@ -148,18 +151,17 @@ proc getToast(fullpaths: seq[string], recurse: bool = false, dynlib: string = "" for fullpath in fullpaths: cmd.add &" {fullpath.sanitizePath}" - # Generate filename for toast output - let - hash = (cmd & cacheKey).hash().abs() - cachePath = getNimteropCacheDir() / "toastCache" / "nimterop_" & $hash + result = if outFile.nBl: fixRelFile(outFile) else: + # Generate filename for toast output if not specified + getNimteropCacheDir() / "toastCache" / "nimterop_" & + ($(cmd & cacheKey).hash().abs()).addFileExt(ext) - result = cachePath.addFileExt(ext) when defined(Windows): result = result.replace(DirSep, '/') if not fileExists(result) or compileOption("forceBuild"): let - dir = cachePath.parentDir() + dir = result.parentDir() if not dirExists(dir): mkDir(dir) @@ -171,9 +173,8 @@ proc getToast(fullpaths: seq[string], recurse: bool = false, dynlib: string = "" macro cOverride*(body): untyped = ## When the wrapper code generated by nimterop is missing certain symbols or not - ## accurate, it may be required to hand wrap them. Define them in a - ## `cOverride() `_ macro block so that Nimterop uses - ## these definitions instead. + ## accurate, it may be required to hand wrap them. Define them in a `cOverride()` + ## macro block so that Nimterop uses these definitions instead. ## ## For example: ## @@ -194,9 +195,9 @@ macro cOverride*(body): untyped = ## cOverride: ## proc svGetCallerInfo(fileName: var cstring; lineNumber: var cint) ## - ## Using the `cOverride() `_ block, nimterop - ## can be instructed to use this definition of `svGetCallerInfo()` instead. - ## This works for procs, consts and types. + ## Using the `cOverride()` block, nimterop can be instructed to use this + ## definition of `svGetCallerInfo()` instead. This works for procs, consts + ## and types. ## ## `cOverride()` only affects the next `cImport()` call. This is because any ## recognized symbols get overridden in place and any remaining symbols get @@ -263,11 +264,10 @@ proc onSymbolOverride*(sym: var Symbol) {.exportc, dynlib.} = decho "Overriding " & names.join(" ") proc cSkipSymbol*(skips: seq[string]) {.compileTime.} = - ## Similar to `cOverride() `_, this macro allows - ## filtering out symbols not of interest from the generated output. + ## Similar to `cOverride()`, this macro allows filtering out symbols not of + ## interest from the generated output. ## - ## `cSkipSymbol() `_ only affects calls to - ## `cImport() `_ that follow it. + ## `cSkipSymbol()` only affects calls to `cImport()` that follow it. runnableExamples: static: cSkipSymbol @["proc1", "Type2"] gStateCT.symOverride.add skips @@ -291,11 +291,9 @@ proc cPluginHelper(body: string, imports = "import macros, nimterop/plugin\n\n") gStateCT.pluginSourcePath = path macro cPlugin*(body): untyped = - ## When `cOverride() `_ and - ## `cSkipSymbol() `_ - ## are not adequate, the `cPlugin() `_ macro can be used - ## to customize the generated Nim output. The following callbacks are available at - ## this time. + ## When `cOverride()` and `cSkipSymbol()` are not adequate, the `cPlugin()` + ## macro can be used to customize the generated Nim output. The following + ## callbacks are available at this time. ## ## .. code-block:: nim ## @@ -325,9 +323,7 @@ macro cPlugin*(body): untyped = ## `macros` and `nimterop/plugins` are implicitly imported to provide access to standard ## plugin facilities. ## - ## `cPlugin() `_ only affects calls to - ## `cImport() `_ that - ## follow it. + ## `cPlugin()` only affects calls to `cImport()` that follow it. runnableExamples: cPlugin: import strutils @@ -367,14 +363,10 @@ macro cPluginPath*(path: static[string]): untyped = proc cSearchPath*(path: string): string {.compileTime.}= ## Get full path to file or directory `path` in search path configured - ## using `cAddSearchDir() `_ and - ## `cAddStdDir() `_. + ## using `cAddSearchDir()` and `cAddStdDir()`. ## ## This can be used to locate files or directories that can be passed onto - ## `cCompile() `_, - ## `cIncludeDir() `_ and - ## `cImport() `_. - + ## `cCompile()`, `cIncludeDir()` and `cImport()`. result = findPath(path, fail = false) if result.Bl: var found = false @@ -394,21 +386,17 @@ proc cDisableCaching*() {.compileTime.} = ## Disable caching of generated Nim code - useful during wrapper development ## ## If files included by header being processed by - ## `cImport() `_ - ## change and affect the generated content, they will be ignored and the cached - ## value will continue to be used . Use `cDisableCaching() `_ - ## to avoid this scenario during development. + ## `cImport()` change and affect the generated content, they will be ignored + ## and the cached value will continue to be used . Use `cDisableCaching()` to + ## avoid this scenario during development. ## - ## `nim -f` was broken prior to 0.19.4 but can also be used to flush the cached content. - + ## `nim -f` can also be used to flush the cached content. gStateCT.nocache = true macro cDefine*(name: static string, val: static string = ""): untyped = ## `#define` an identifer that is forwarded to the C/C++ preprocessor if - ## called within `cImport() `_ - ## or `c2nImport() `_ - ## as well as to the C/C++ compiler during Nim compilation using `{.passC: "-DXXX".}` - + ## called within `cImport()` or `c2nImport()` as well as to the C/C++ + ## compiler during Nim compilation using `{.passC: "-DXXX".}` result = newNimNode(nnkStmtList) var str = name @@ -429,7 +417,7 @@ macro cDefine*(name: static string, val: static string = ""): untyped = proc cAddSearchDir*(dir: string) {.compileTime.} = ## Add directory `dir` to the search path used in calls to - ## `cSearchPath() `_. + ## `cSearchPath()`. runnableExamples: import nimterop/paths, os static: @@ -441,10 +429,8 @@ proc cAddSearchDir*(dir: string) {.compileTime.} = macro cIncludeDir*(dir: static string): untyped = ## Add an include directory that is forwarded to the C/C++ preprocessor if - ## called within `cImport() `_ - ## or `c2nImport() `_ - ## as well as to the C/C++ compiler during Nim compilation using `{.passC: "-IXXX".}`. - + ## called within `cImport()` or `c2nImport()` as well as to the C/C++ + ## compiler during Nim compilation using `{.passC: "-IXXX".}`. var dir = interpPath(dir) result = newNimNode(nnkStmtList) @@ -459,7 +445,7 @@ macro cIncludeDir*(dir: static string): untyped = proc cAddStdDir*(mode = "c") {.compileTime.} = ## Add the standard `c` [default] or `cpp` include paths to search - ## path used in calls to `cSearchPath() `_ + ## path used in calls to `cSearchPath()`. runnableExamples: static: cAddStdDir() import os @@ -561,7 +547,7 @@ macro cCompile*(path: static string, mode = "c", exclude = ""): untyped = gecho result.repr macro cImport*(filenames: static seq[string], recurse: static bool = false, dynlib: static string = "", - mode: static string = "c", flags: static string = ""): untyped = + mode: static string = "c", flags: static string = "", nimFile: static string = ""): untyped = ## Import multiple headers in one shot ## ## This macro is preferable over multiple individual `cImport()` calls, especially @@ -581,7 +567,7 @@ macro cImport*(filenames: static seq[string], recurse: static bool = false, dynl gecho "# Importing " & fullpaths.join(", ").sanitizePath let - nimFile = getToast(fullpaths, recurse, dynlib, mode, flags) + nimFile = getToast(fullpaths, recurse, dynlib, mode, flags, nimFile) # Reset plugin and overrides for next cImport if gStateCT.overrides.nBl: @@ -600,16 +586,15 @@ macro cImport*(filenames: static seq[string], recurse: static bool = false, dynl getNimCheckError(nimFile) macro cImport*(filename: static string, recurse: static bool = false, dynlib: static string = "", - mode: static string = "c", flags: static string = ""): untyped = + mode: static string = "c", flags: static string = "", nimFile: static string = ""): untyped = ## Import all supported definitions from specified header file. Generated ## content is cached in `nimcache` until `filename` changes unless - ## `cDisableCaching() `_ is set. `nim -f` - ## can also be used after Nim v0.19.4 to flush the cache. + ## `cDisableCaching()` is set. `nim -f` can also be used to flush the cache. ## ## `recurse` can be used to generate Nim wrappers from `#include` files ## referenced in `filename`. This is only done for files in the same ## directory as `filename` or in a directory added using - ## `cIncludeDir() `_ + ## `cIncludeDir()`. ## ## `dynlib` can be used to specify the Nim string to use to specify the dynamic ## library to load the imported symbols from. For example: @@ -630,9 +615,9 @@ macro cImport*(filename: static string, recurse: static bool = false, dynlib: st ## ## cImport("pcre.h", dynlib="dynpcre") ## - ## If `dynlib` is not specified, the C/C++ implementation files can be compiled in - ## with `cCompile() `_, or the - ## `{.passL.}` pragma can be used to specify the static lib to link. + ## If `dynlib` is not specified, the C/C++ implementation files can be compiled + ## in with `cCompile()`, or the `{.passL.}` pragma can be used to specify the + ## static lib to link. ## ## `mode` selects the preprocessor and tree-sitter parser to be used to process ## the header. @@ -641,33 +626,41 @@ macro cImport*(filename: static string, recurse: static bool = false, dynlib: st ## good example would be `--prefix` and `--suffix` which strip leading and ## trailing strings from identifiers, `_` being quite common. ## + ## `nimFile` is the location where the generated wrapper should get written. + ## By default, the generated wrapper is written to `nimcache` and included from + ## there. `nimFile` makes it possible to write the wrapper to a predetermined + ## location which can then be directly imported into the main application and + ## checked into source control if preferred. Importing the nimterop wrapper with + ## `nimFile` specified still works per usual. If `nimFile` is not an absolute + ## path, it is relative to the project path. + ## ## `cImport()` consumes and resets preceding `cOverride()` calls. `cPlugin()` ## is retained for the next `cImport()` call unless a new `cPlugin()` call is ## defined. return quote do: - cImport(@[`filename`], bool(`recurse`), `dynlib`, `mode`, `flags`) + cImport(@[`filename`], bool(`recurse`), `dynlib`, `mode`, `flags`, `nimFile`) macro c2nImport*(filename: static string, recurse: static bool = false, dynlib: static string = "", - mode: static string = "c", flags: static string = ""): untyped = + mode: static string = "c", flags: static string = "", nimFile: static string = ""): untyped = ## Import all supported definitions from specified header file using `c2nim` ## - ## Similar to `cImport() `_ - ## but uses `c2nim` to generate the Nim wrapper instead of `toast`. Note that neither - ## `cOverride() `_, `cSkipSymbol() `_ - ## nor `cPlugin() `_ have any impact on `c2nim`. + ## Similar to `cImport()` but uses `c2nim` to generate the Nim wrapper instead + ## of `toast`. Note that neither `cOverride()`, `cSkipSymbol()` nor `cPlugin()` + ## have any impact on `c2nim`. ## - ## `toast` is only used to preprocess the header file and recurse - ## if specified. + ## `toast` is only used to preprocess the header file and `recurse` if specified. ## ## `mode` should be set to `cpp` for c2nim to wrap C++ headers. ## ## `flags` can be used to pass other command line arguments to `c2nim`. ## - ## `nimterop` does not depend on `c2nim` as a `nimble` dependency so it - ## does not get installed automatically. Any wrapper or library that requires this proc - ## needs to install `c2nim` with `nimble install c2nim` or add it as a dependency in - ## its own `.nimble` file. - + ## `nimFile` is the location where the generated wrapper should get written, + ## similar to `cImport()`. + ## + ## `nimterop` does not depend on `c2nim` as a `nimble` dependency so it does not + ## get installed automatically. Any wrapper or library that requires this proc + ## needs to install `c2nim` with `nimble install c2nim` or add it as a dependency + ## in its own `.nimble` file. result = newNimNode(nnkStmtList) let @@ -677,13 +670,13 @@ macro c2nImport*(filename: static string, recurse: static bool = false, dynlib: let hFile = getToast(@[fullpath], recurse, dynlib, mode, noNimout = true) - nimFile = hFile.changeFileExt("nim") + nimFile = if nimFile.nBl: fixRelFile(nimFile) else: hFile.changeFileExt("nim") header = "header" & fullpath.splitFile().name.split(seps = {'-', '.'}).join() if not fileExists(nimFile) or compileOption("forceBuild"): var cmd = when defined(Windows): "cmd /c " else: "" - cmd &= &"c2nim {hFile} --header:{header}" + cmd &= &"c2nim {hFile} --header:{header} --out:{nimFile.sanitizePath}" if dynlib.nBl: cmd.add &" --dynlib:{dynlib}" diff --git a/tests/tast2.nim b/tests/tast2.nim index 3f626ae..669ec98 100644 --- a/tests/tast2.nim +++ b/tests/tast2.nim @@ -38,7 +38,11 @@ cOverride: A1* = A0 cDefine("SOME_CONST=100") -cImport(path, flags="-f:ast2 -ENK_,SDL_ -GVICE=SLICE -TMyInt=cint" & flags) + +when not defined(WRAPPED): + cImport(path, flags="-f:ast2 -ENK_,SDL_ -GVICE=SLICE -TMyInt=cint" & flags, nimFile = "tast2wrapped.nim") +else: + import tast2wrapped proc getPragmas(n: NimNode): HashSet[string] = # Find all pragmas in AST, return as "name" or "name:value" in set From a63f67f6850dab10ec0c8784d370f8178edc7bf9 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 2 Jul 2020 00:10:16 -0500 Subject: [PATCH 544/593] Minor fixes, improvements --- nimterop/globals.nim | 8 ++-- nimterop/setup.nim | 8 ---- nimterop/toastlib/getters.nim | 83 ++++++++++++++++++----------------- nimterop/treesitter/c.nim | 2 +- nimterop/treesitter/cpp.nim | 2 +- 5 files changed, 48 insertions(+), 55 deletions(-) diff --git a/nimterop/globals.nim b/nimterop/globals.nim index d1e22a6..e0b9b8f 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -129,7 +129,7 @@ when defined(TOAST): Status* = enum success, unknown, error -proc getCommented*(str: string): string = +template getCommented*(str: string): string = "\n# " & str.strip().replace("\n", "\n# ") # Redirect output to file when required @@ -147,13 +147,13 @@ template gecho*(args: string) = template decho*(args: varargs[string, `$`]): untyped = let - str = join(args, "").getCommented() + str = join(args, "") when defined(TOAST): if gState.debug: - gecho str + gecho str.getCommented() else: if gStateCT.debug: - echo str + echo str.getCommented() template nBl*(s: typed): untyped {.used.} = (s.len != 0) diff --git a/nimterop/setup.nim b/nimterop/setup.nim index 6da0bbe..6da1358 100644 --- a/nimterop/setup.nim +++ b/nimterop/setup.nim @@ -34,10 +34,6 @@ src/*.cc src/tree_sitter/parser.h """, "0.16.1") - writeFile(cacheDir / "treesitter_c" / "src" / "api.h", """ -const TSLanguage *tree_sitter_c(); -""") - proc treesitterCppSetup*() = gitPull("https://github.com/tree-sitter/tree-sitter-cpp", cacheDir / "treesitter_cpp", """ src/*.h @@ -45,7 +41,3 @@ src/*.c src/*.cc src/tree_sitter/parser.h """, "v0.16.0") - - writeFile(cacheDir / "treesitter_cpp" / "src" / "api.h", """ -const TSLanguage *tree_sitter_cpp(); -""") diff --git a/nimterop/toastlib/getters.nim b/nimterop/toastlib/getters.nim index 43a4f6f..534b6fa 100644 --- a/nimterop/toastlib/getters.nim +++ b/nimterop/toastlib/getters.nim @@ -1,4 +1,4 @@ -import dynlib, macros, os, sequtils, sets, strformat, strutils, tables, times +import dynlib, macros, os, osproc, sequtils, sets, streams, strformat, strutils, tables, times import regex @@ -124,12 +124,12 @@ var gTypeImport* = { "time_t": """ import std/time_t as std_time_t -type time_t* = Time +type time_t* = std_time_t.Time """, "time64_t": """ import std/time_t as std_time64_t -type time64_t* = Time +type time64_t* = std_time_t.Time """, "wchar_t": """ @@ -286,10 +286,7 @@ proc getCurrentHeader*(fullpath: string): string = proc getPreprocessor*(gState: State, fullpath: string) = var - cmts = if gState.noComments: "" else: "-CC" - cmd = &"""{getCompiler()} -E {cmts} -dD {getGccModeArg(gState.mode)} -w """ - - rdata: seq[string] + args: seq[string] start = false sfile = fullpath.sanitizePath(noQuote = true) @@ -297,50 +294,54 @@ proc getPreprocessor*(gState: State, fullpath: string) = pDir = sfile.expandFilename().parentDir() includeDirs: seq[string] + args.add @["-E", "-dD", getGccModeArg(gState.mode), "-w"] + if not gState.noComments: + args.add "-CC" + for inc in gState.includeDirs: - cmd &= &"-I{inc.sanitizePath} " + args.add &"-I{inc.sanitizePath}" includeDirs.add inc.absolutePath().sanitizePath(noQuote = true) for def in gState.defines: - cmd &= &"-D{def} " + args.add &"-D{def}" # Remove gcc special calls - if defined(posix): - cmd &= "-D__attribute__\\(x\\)= " - else: - cmd &= "-D__attribute__(x)= " - - cmd &= "-D__restrict= -D__extension__= -D__inline__=inline -D__inline=inline " - # https://github.com/tree-sitter/tree-sitter-c/issues/43 - cmd &= "-D_Noreturn= " - - cmd &= &"{fullpath.sanitizePath}" + args.add @["-D__attribute__(x)=", "-D__restrict=", "-D__extension__=", "-D__inline__=inline", + "-D__inline=inline", "-D_Noreturn=", &"{fullpath.sanitizePath}"] # Include content only from file - for line in execAction(cmd).output.splitLines(): - # We want to keep blank lines here for comment processing - if line.len > 1 and line[0 .. 1] == "# ": - start = false - let - saniLine = line.sanitizePath(noQuote = true) - if sfile in saniLine or - (DirSep notin saniLine and sfileName in saniLine): - start = true - elif gState.recurse: - if pDir.Bl or pDir in saniLine: + var + p = startProcess(getCompiler(), args = args, options = {poStdErrToStdOut, poUsePath}) + outp = p.outputStream() + line = "" + + # Include content only from file + gState.code = "" + while true: + if outp.readLine(line): + # We want to keep blank lines here for comment processing + if line.len > 1 and line[0] == '#' and line[1] == ' ': + start = false + line = line.sanitizePath(noQuote = true) + if sfile in line or + (DirSep notin line and sfileName in line): start = true - else: - for inc in includeDirs: - if inc in saniLine: - start = true - break - else: - if start: - if "#undef" in line: - continue - rdata.add line - gState.code = rdata.join("\n") + elif gState.recurse: + if pDir.Bl or pDir in line: + start = true + else: + for inc in includeDirs: + if inc in line: + start = true + break + else: + if start: + if "#undef" in line: + continue + gState.code.add line & "\n" + elif not p.running(): break + p.close() # Plugin related diff --git a/nimterop/treesitter/c.nim b/nimterop/treesitter/c.nim index d779bfd..4280b91 100644 --- a/nimterop/treesitter/c.nim +++ b/nimterop/treesitter/c.nim @@ -13,4 +13,4 @@ import "."/api {.compile: srcDir / "parser.c".} -proc treeSitterC*(): ptr TSLanguage {.importc: "tree_sitter_c", header: srcDir / "api.h".} +proc treeSitterC*(): ptr TSLanguage {.importc: "tree_sitter_c".} diff --git a/nimterop/treesitter/cpp.nim b/nimterop/treesitter/cpp.nim index 4f5be17..fd0437e 100644 --- a/nimterop/treesitter/cpp.nim +++ b/nimterop/treesitter/cpp.nim @@ -18,4 +18,4 @@ static: {.compile: srcDir / "parser_cpp.c".} {.compile: srcDir / "scanner.cc".} -proc treeSitterCpp*(): ptr TSLanguage {.importc: "tree_sitter_cpp", header: srcDir / "api.h".} +proc treeSitterCpp*(): ptr TSLanguage {.importc: "tree_sitter_cpp".} From 94acdeb5f1e0576decdb116570d5b2f05af82bf7 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 2 Jul 2020 02:29:28 -0500 Subject: [PATCH 545/593] Fix #238 crash --- nimterop/toastlib/ast2.nim | 2 +- nimterop/toastlib/getters.nim | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/nimterop/toastlib/ast2.nim b/nimterop/toastlib/ast2.nim index 0147463..5769893 100644 --- a/nimterop/toastlib/ast2.nim +++ b/nimterop/toastlib/ast2.nim @@ -1668,7 +1668,7 @@ proc addDecl(gState: State, node: TSNode) = commentNodes: seq[TSNode] for i in start+1 ..< node.len: - if node[i].getName() == "comment": + if node[i].getName() in ["comment", "type_qualifier"]: continue if firstDecl: diff --git a/nimterop/toastlib/getters.nim b/nimterop/toastlib/getters.nim index 534b6fa..3a71c78 100644 --- a/nimterop/toastlib/getters.nim +++ b/nimterop/toastlib/getters.nim @@ -129,7 +129,7 @@ type time_t* = std_time_t.Time "time64_t": """ import std/time_t as std_time64_t -type time64_t* = std_time_t.Time +type time64_t* = std_time64_t.Time """, "wchar_t": """ From 1e88a3b42ec6d27c1d924ee9f6840852b1a68797 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 2 Jul 2020 12:41:56 -0500 Subject: [PATCH 546/593] Fix static inline and restrict --- nimterop/toastlib/ast2.nim | 3 ++- nimterop/toastlib/getters.nim | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/nimterop/toastlib/ast2.nim b/nimterop/toastlib/ast2.nim index 5769893..dc4d220 100644 --- a/nimterop/toastlib/ast2.nim +++ b/nimterop/toastlib/ast2.nim @@ -1703,8 +1703,9 @@ proc addDef(gState: State, node: TSNode) = let start = getStartAtom(node) commentNodes = gState.getCommentNodes(node) + fdecl = node[start+1].firstChildInTree("function_declarator") - if node[start+1].getName() == "function_declarator": + if not fdecl.isNil: if not gState.noHeader: gState.addProc(node[start+1], node[start], commentNodes) else: diff --git a/nimterop/toastlib/getters.nim b/nimterop/toastlib/getters.nim index 3a71c78..08ba604 100644 --- a/nimterop/toastlib/getters.nim +++ b/nimterop/toastlib/getters.nim @@ -307,7 +307,7 @@ proc getPreprocessor*(gState: State, fullpath: string) = # Remove gcc special calls # https://github.com/tree-sitter/tree-sitter-c/issues/43 - args.add @["-D__attribute__(x)=", "-D__restrict=", "-D__extension__=", "-D__inline__=inline", + args.add @["-D__attribute__(x)=", "-D__restrict=", "-D__restrict__=", "-D__extension__=", "-D__inline__=inline", "-D__inline=inline", "-D_Noreturn=", &"{fullpath.sanitizePath}"] # Include content only from file From c3f4f3e487ce8bf8bd9e6e9a370a808e00638091 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 2 Jul 2020 20:11:11 -0500 Subject: [PATCH 547/593] Handle tserror in static inline, wrap headers only once --- nimterop/globals.nim | 1 + nimterop/toast.nim | 6 +++++- nimterop/toastlib/ast2.nim | 23 ++++++++++++----------- nimterop/toastlib/getters.nim | 15 ++++++++++----- nimterop/toastlib/tshelp.nim | 9 +++++++++ 5 files changed, 37 insertions(+), 17 deletions(-) diff --git a/nimterop/globals.nim b/nimterop/globals.nim index e0b9b8f..17b9518 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -55,6 +55,7 @@ type identifiers*: TableRef[string, string] # Symbols that have been declared so far indexed by nimName skippedSyms*: HashSet[string] # Symbols that have been skipped due to being unwrappable or # the user provided override is blank + headersProcessed*: HashSet[string] # Headers already processed directly or recursively # Nim compiler objects constSection*, enumSection*, pragmaSection*, procSection*, typeSection*, varSection*: PNode diff --git a/nimterop/toast.nim b/nimterop/toast.nim index fbaa960..1cda239 100644 --- a/nimterop/toast.nim +++ b/nimterop/toast.nim @@ -136,7 +136,11 @@ proc main( gecho preMainOut gState.initNim() for src in source: - gState.process(src.expandSymlinkAbs()) + let + src = src.expandSymlinkAbs() + if src notin gState.headersProcessed: + gState.process(src) + gState.headersProcessed.incl src if gState.pnim: printNim(gState) diff --git a/nimterop/toastlib/ast2.nim b/nimterop/toastlib/ast2.nim index dc4d220..43ec8d3 100644 --- a/nimterop/toastlib/ast2.nim +++ b/nimterop/toastlib/ast2.nim @@ -137,7 +137,7 @@ proc newConstDef(gState: State, node: TSNode, fname = "", fval = ""): PNode = # In case symbol was skipped earlier gState.skippedSyms.excl origname else: - gecho &"# const '{origname}' is duplicate, skipped" + decho &"const '{origname}' is duplicate, skipped" else: gecho &"# const '{origname}' has unsupported value '{val.strip()}'" gState.skippedSyms.incl origname @@ -391,7 +391,7 @@ proc newXIdent(gState: State, node: TSNode, kind = nskType, fname = "", pragmas: gState.identifierNodes[name] = result else: - gecho &"# {getKeyword(kind)} '{origname}' is duplicate, skipped" + decho &"{getKeyword(kind)} '{origname}' is duplicate, skipped" proc newArrayTree(gState: State, node: TSNode, typ, size: PNode = nil): PNode = # Create nkBracketExpr tree depending on input @@ -1706,6 +1706,9 @@ proc addDef(gState: State, node: TSNode) = fdecl = node[start+1].firstChildInTree("function_declarator") if not fdecl.isNil: + if gState.getNodeError(fdecl): + return + if not gState.noHeader: gState.addProc(node[start+1], node[start], commentNodes) else: @@ -1716,19 +1719,14 @@ proc processNode(gState: State, node: TSNode): Status = const known = ["preproc_def", "type_definition", "struct_specifier", "union_specifier", "enum_specifier", - "declaration", "function_definition"].toHashSet() + "declaration"].toHashSet() result = success let name = node.getName() if name in known: # Recognized top-level nodes - let - err = node.anyChildInTree("ERROR") - if not err.isNil: - # Bail on errors - gState.printDebug(node) - gecho &"# tree-sitter parse error: '{gState.getNodeVal(node).splitLines()[0]}', skipped" + if gState.getNodeError(node): result = Status.error else: # Process nodes @@ -1750,8 +1748,11 @@ proc processNode(gState: State, node: TSNode): Status = gState.addEnum(node) of "declaration": gState.addDecl(node) - of "function_definition": - gState.addDef(node) + elif name == "function_definition": + # Separate since we only need to check function_declarator for errors and + # not the compound_statement which could have errors but does not impact + # wrapper generation + gState.addDef(node) else: # Unknown, will check child nodes result = unknown diff --git a/nimterop/toastlib/getters.nim b/nimterop/toastlib/getters.nim index 08ba604..bfbd4be 100644 --- a/nimterop/toastlib/getters.nim +++ b/nimterop/toastlib/getters.nim @@ -315,6 +315,7 @@ proc getPreprocessor*(gState: State, fullpath: string) = p = startProcess(getCompiler(), args = args, options = {poStdErrToStdOut, poUsePath}) outp = p.outputStream() line = "" + newHeaders: HashSet[string] # Include content only from file gState.code = "" @@ -323,17 +324,19 @@ proc getPreprocessor*(gState: State, fullpath: string) = # We want to keep blank lines here for comment processing if line.len > 1 and line[0] == '#' and line[1] == ' ': start = false - line = line.sanitizePath(noQuote = true) - if sfile in line or - (DirSep notin line and sfileName in line): + line = line.split('"')[1].sanitizePath(noQuote = true) + if sfile == line or + (DirSep notin line and sfileName == line): start = true elif gState.recurse: - if pDir.Bl or pDir in line: + if (pDir.Bl or pDir in line) and line notin gState.headersProcessed: start = true + newHeaders.incl line else: for inc in includeDirs: - if inc in line: + if line.startsWith(inc) and line notin gState.headersProcessed: start = true + newHeaders.incl line break else: if start: @@ -342,6 +345,7 @@ proc getPreprocessor*(gState: State, fullpath: string) = gState.code.add line & "\n" elif not p.running(): break p.close() + gState.headersProcessed.incl newHeaders # Plugin related @@ -393,3 +397,4 @@ proc expandSymlinkAbs*(path: string): string = result = path.expandFilename().normalizedPath() except: result = path + result = result.sanitizePath(noQuote = true) \ No newline at end of file diff --git a/nimterop/toastlib/tshelp.nim b/nimterop/toastlib/tshelp.nim index 3b7c2cc..bbe029f 100644 --- a/nimterop/toastlib/tshelp.nim +++ b/nimterop/toastlib/tshelp.nim @@ -399,3 +399,12 @@ proc getTSNodeNamedChildNames*(node: TSNode): seq[string] = if name != "comment": result.add(name) + +proc getNodeError*(gState: State, node: TSNode): bool = + let + err = node.anyChildInTree("ERROR") + if not err.isNil: + # Bail on errors + gState.printDebug(node) + gecho &"# tree-sitter parse error: '{gState.getNodeVal(node).splitLines()[0]}', skipped" + result = true \ No newline at end of file From f191ea7244df545c3dc7b4dc2451a600694fe298 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 2 Jul 2020 23:55:26 -0500 Subject: [PATCH 548/593] Fix #237 - anonymous nested struct/unions, fix #236 - unnamed enums --- CHANGES.md | 8 +++- README.md | 5 ++- nimterop/toastlib/ast2.nim | 78 +++++++++++++++++++++++++++++++++----- tests/include/tast2.h | 41 ++++++++++++++++++++ tests/tast2.nim | 20 +++++++++- tests/tnimterop_c.nim | 2 +- 6 files changed, 139 insertions(+), 15 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 43f1d34..e85d261 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -25,6 +25,8 @@ https://github.com/nimterop/nimterop/compare/v0.5.9...v0.6.1 - `git.nim` has been removed. This module was an artifact from the early days and was renamed to `build.nim` back in v0.2.0. +- Nameless enum values are no longer typed to the made-up enum type name, they are instead typed as `cint` to match the underlying type. This allows using such enums without having to depend on the made-up name which could change if enum ordering changes upstream. [#236][i236] (since v0.6.1) + ### New functionality - `getHeader()` now detects and links against `.lib` files as part of enabling Conan.io. Not all `.lib` files are compatible with MinGW as already stated above but for those that work, this is a required capability. @@ -35,6 +37,8 @@ https://github.com/nimterop/nimterop/compare/v0.5.9...v0.6.1 - `cImport()` can now write the generated wrapper output to a user-defined file with the `nimFile` param. [#127][i127] (since v0.6.1) +- Nimterop now supports anonymous nested structs/unions but it only works correctly for unions when `noHeader` is turned off (the default). This is because Nim does not support nested structs/unions and is unaware of the underlying memory structure. [#237][i237] (since v0.6.1) + ### Other improvements - Generated wrappers no longer depend on nimterop being present - no more `import nimterop/types`. Supporting code is directly included in the wrapper output and only when required. E.g. enum macro is only included if wrapper contains enums. [#125][i125] (since v0.6.1) @@ -128,4 +132,6 @@ https://github.com/nimterop/nimterop/compare/v0.4.4...v0.5.4 [i181]: https://github.com/nimterop/nimterop/issues/181 [i196]: https://github.com/nimterop/nimterop/issues/196 [i197]: https://github.com/nimterop/nimterop/issues/197 -[i200]: https://github.com/nimterop/nimterop/issues/200 \ No newline at end of file +[i200]: https://github.com/nimterop/nimterop/issues/200 +[i236]: https://github.com/nimterop/nimterop/issues/236 +[i237]: https://github.com/nimterop/nimterop/issues/237 \ No newline at end of file diff --git a/README.md b/README.md index b054d97..f9e9307 100644 --- a/README.md +++ b/README.md @@ -28,8 +28,9 @@ This will download and install nimterop in the standard Nimble package location, ## Usage -Nimterop can be used in two ways: +Nimterop can be used in three ways: - Creating a wrapper file - a `.nim` file that contains calls to the high-level API that can download and build the C library as well as generate the required Nim code to interface with the library. This wrapper file can then be imported into Nim code like any other module and it will be processed at compile time. +- Same as the first option except using the `nimFile` param to `cImport()` to write the generated wrapper to a file during build time just once and then importing that generated wrapper into the application like any other Nim module. - Using the command line `toast` tool to generate the Nim code which can then be stored into a file and imported separately. Any combination of the above is possible - only download, build or wrapping and nimterop avoids imposing any particular workflow. @@ -169,7 +170,7 @@ For types, `{.header: "header.h".}` informs Nim that `header.h` has the symbol a For functions, `{.header.}` works the same as types and can be omitted if preferred. The `{.importc.}` pragma is still required, unlike types since functions need to be linked to the implementation in the library. The user will need to provide this information at link time with `{.passL.}` and linking to a library with `-lheader` or `path/to/libheader.a`. It is also possible to just use `cCompile()` or `{.compile.}` to compile some C source files which contain the implementation. -While `{.header.}` can be omitted for convenience, it does prevent wrapping of `static inline` functions as well as type checking of the wrapper ABI with `-d:checkAbi` at compile time. The user will need to choose based on the library in question. +While `{.header.}` can be omitted for convenience, it does prevent wrapping of `static inline` functions as well as type checking of the wrapper ABI with `-d:checkAbi` at compile time. Further, anonymous nested structs/unions within unions will be rendered incorrectly by Nim since it is unaware of the true memory structure of the type. The user will need to choose based on the library in question. Going further, the `{.dynlib: "path/to/libheader.so".}` pragma can be used to inform Nim to load the library at runtime and link the function instead of linking at compile time. This enables creation of a wrapper that does not need the library present at compile time. diff --git a/nimterop/toastlib/ast2.nim b/nimterop/toastlib/ast2.nim index 43ec8d3..fb2b55f 100644 --- a/nimterop/toastlib/ast2.nim +++ b/nimterop/toastlib/ast2.nim @@ -704,6 +704,17 @@ proc newRecListTree(gState: State, name: string, node: TSNode): PNode = edecl = node[i].anyChildInTree("enumerator_list") commentNodes = gState.getCommentNodes(node[i]) + # Check if struct/union field is anonymous + isNamedField = block: + var found = false + if not fdecl.isNil: + var sibling = fdecl.tsNodeParent().tsNodeNextNamedSibling() + while not sibling.isNil and sibling.getName() != "field_identifier": + sibling = sibling.tsNodeNextNamedSibling() + if not sibling.isNil: + found = true + found + # `tname` is name of nested struct / union / enum just # added, passed on as type name for field in `newIdentDefs()` (processed, tname) = @@ -725,11 +736,48 @@ proc newRecListTree(gState: State, name: string, node: TSNode): PNode = if processed != success: return nil - # Add nkIdentDefs for each field - for field in gState.newIdentDefs(name, node[i], i, ftname = tname, exported = true): - if not field.isNil: - field.comment = gState.getCommentsStr(commentNodes) - result.add field + if not fdecl.isNil and not isNamedField: + # Since anonymous, add fields directly to this struct/union + + # nkTypeDef( <= last + # nkPragmaExpr( + # .. + # ), + # nkEmpty(), + # nkObjectTy( <= last[2] + # nkEmpty(), + # nkEmpty(), + # nkRecList( <= last[2][2] + # nkIdentDefs( <= field1 + # .. + # ), + # nkIdentDefs( <= field2 + # .. + # ) + # ) + # ) + # ) + let + last = gState.typeSection[^1] + obj = + if last.len > 2 and last[2].kind == nkObjectTy: + last[2] + else: nil + recList = + if not obj.isNil and obj.len > 2 and obj[2].kind == nkRecList: + obj[2] + else: nil + + if not recList.isNil: + for identdef in recList: + result.add identdef + gState.typeSection.sons.del(gState.typeSection.len-1) + else: + # Add nkIdentDefs for each field + for field in gState.newIdentDefs(name, node[i], i, ftname = tname, exported = true): + if not field.isNil: + field.comment = gState.getCommentsStr(commentNodes) + result.add field proc addTypeObject(gState: State, node: TSNode, typeDef: PNode = nil, fname = "", istype = false, union = false) = # Add a type of object @@ -1444,14 +1492,16 @@ proc addEnum(gState: State, node: TSNode) = fval = "" if prev.Bl: # Starting default value - fval = &"(0).{name}" + fval = &"(0)" else: # One greater than previous - fval = &"({prev} + 1).{name}" + fval = &"({prev} + 1)" if en.len > 1 and en[1].getName() in gEnumVals: + # Enum value specified, evaluate later, don't use calculated value fieldDeclarations.add((fname, forigname, "", gState.getNodeVal(en[1]), commentNodes)) else: + # Set calculated value fieldDeclarations.add((fname, forigname, fval, "", commentNodes)) fnames.incl fname @@ -1464,10 +1514,18 @@ proc addEnum(gState: State, node: TSNode) = # parseCExpression requires all const identifiers to be present for the enum for (fname, forigname, fval, cexpr, commentNodes) in fieldDeclarations: let - fval = + fval = block: + var fval = fval if fval.Bl: - "(" & $gState.parseCExpression(cexpr, name) & ")." & name - else: fval + # Evaluate enum value from expression + fval = &"({$gState.parseCExpression(cexpr, name)})" + if origname.nBl: + # Named enum so cast to type - #236 + fval &= &".{name}" + else: + # Cast to cint to match underlying type + fval &= ".cint" + fval # Cannot use newConstDef() since parseString(fval) adds backticks to and/or constNode = gState.parseString(&"const {fname}* = {fval}")[0][0] diff --git a/tests/include/tast2.h b/tests/include/tast2.h index 89ad486..06a0078 100644 --- a/tests/include/tast2.h +++ b/tests/include/tast2.h @@ -271,6 +271,27 @@ struct TestMyInt { MyInt f1; }; +// Issue #237 +typedef union sx_ivec3 { + struct { + int x; + int y; + struct z { + int z; + }; + }; + + int n[3]; +} sx_ivec3; + +// Issue #236 +enum { + SG_INVALID_ID = 0, + SG_NUM_SHADER_STAGES = 2, + SG_MAX_MIPMAPS = 16, + SG_MAX_TEXTUREARRAY_LAYERS = 128 +}; + // DUPLICATES @@ -546,6 +567,26 @@ struct TestMyInt { MyInt f1; }; +// Issue #237 +typedef union sx_ivec3 { + struct { + int x; + int y; + struct z { + int z; + }; + }; + + int n[3]; +} sx_ivec3; + +// Issue #236 +enum { + SG_INVALID_ID = 0, + SG_NUM_SHADER_STAGES = 2, + SG_MAX_MIPMAPS = 16, + SG_MAX_TEXTUREARRAY_LAYERS = 128 +}; #endif diff --git a/tests/tast2.nim b/tests/tast2.nim index 669ec98..ade5dff 100644 --- a/tests/tast2.nim +++ b/tests/tast2.nim @@ -353,6 +353,7 @@ checkPragmas(U2, pHeaderBy & @["union"], istype = false) var u2: U2 u2.f1 = addr a15.a2[0] +assert PANEL_WINDOW is nk_panel_type assert PANEL_WINDOW == 1 assert PANEL_GROUP == 2 assert PANEL_POPUP == 4 @@ -497,4 +498,21 @@ when not defined(NOHEADER): when declared(MyInt): assert false, "MyInt is defined!" testFields(TestMyInt, "f1!cint") -checkPragmas(TestMyInt, pHeaderBy, isType = false) \ No newline at end of file +checkPragmas(TestMyInt, pHeaderBy, isType = false) + +# #237 +assert sx_ivec3 is object +testFields(sx_ivec3, "x|y|z|n!cint|cint|cint|array[3, cint]") +checkPragmas(sx_ivec3, pHeaderBy & @["union"], istype = false) +var sx: sx_ivec3 +sx.x = 5 +assert sx.n[0] == 5 +when not defined(NOHEADER): + # Nim doesn't know of the anonymous nested struct so when the header + # isn't present, the test below breaks + sx.n[1] = 4 + assert sx.y == 4 + +# #236 +assert SG_MAX_MIPMAPS is cint +assert SG_MAX_MIPMAPS == 16 \ No newline at end of file diff --git a/tests/tnimterop_c.nim b/tests/tnimterop_c.nim index ef814ea..ac7193c 100644 --- a/tests/tnimterop_c.nim +++ b/tests/tnimterop_c.nim @@ -70,7 +70,7 @@ var e: ENUM e2: ENUM2 = enum5 - e3: Enum_testh1 = enum7 + e3 = enum7 e4: ENUM4 = enum11 vptr: VOIDPTR From 1ad32e4574a70d48cc0f50e71f354207bcdd2bd0 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Fri, 3 Jul 2020 01:46:27 -0500 Subject: [PATCH 549/593] Fix missing preprocessor errors, toast errors, cDisableCache not working, print generated wrapper location --- nimterop/cimport.nim | 24 ++++++++---------------- nimterop/toastlib/getters.nim | 7 +++++++ tests/include/tast2.h | 2 +- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index d992c04..114ab80 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -82,18 +82,6 @@ proc getCacheValue(fullpaths: seq[string]): string = for fullpath in fullpaths: result &= getCacheValue(fullpath) -proc getToastError(output: string): string = - # Filter out preprocessor errors - for line in output.splitLines(): - if "fatal error:" in line.toLowerAscii: - if result.len == 0: - result = "\n\nFailed in preprocessing, check if `cIncludeDir()` is needed or compiler `mode` is correct (c/cpp)" - result &= "\n\nERROR:$1\n" % line.split("fatal error:")[1] - - # Toast error - if result.Bl: - result = "\n\n" & output - proc getNimCheckError(nimFile: string) = let (check, _) = execAction( @@ -159,7 +147,7 @@ proc getToast(fullpaths: seq[string], recurse: bool = false, dynlib: string = "" when defined(Windows): result = result.replace(DirSep, '/') - if not fileExists(result) or compileOption("forceBuild"): + if not fileExists(result) or gStateCT.nocache or compileOption("forceBuild"): let dir = result.parentDir() if not dirExists(dir): @@ -168,8 +156,8 @@ proc getToast(fullpaths: seq[string], recurse: bool = false, dynlib: string = "" cmd.add &" -o {result.sanitizePath}" var - (_, ret) = execAction(cmd, die = false) - doAssert ret == 0, getToastError(result.readFile()) + (output, ret) = execAction(cmd, die = false) + doAssert ret == 0, result.readFile() & output macro cOverride*(body): untyped = ## When the wrapper code generated by nimterop is missing certain symbols or not @@ -577,6 +565,8 @@ macro cImport*(filenames: static seq[string], recurse: static bool = false, dynl if gStateCT.debug: gecho nimFile.readFile() + gecho "# Saved to " & nimFile + try: let nimFileNode = newStrLitNode(nimFile.changeFileExt("")) @@ -673,7 +663,7 @@ macro c2nImport*(filename: static string, recurse: static bool = false, dynlib: nimFile = if nimFile.nBl: fixRelFile(nimFile) else: hFile.changeFileExt("nim") header = "header" & fullpath.splitFile().name.split(seps = {'-', '.'}).join() - if not fileExists(nimFile) or compileOption("forceBuild"): + if not fileExists(nimFile) or gStateCT.nocache or compileOption("forceBuild"): var cmd = when defined(Windows): "cmd /c " else: "" cmd &= &"c2nim {hFile} --header:{header} --out:{nimFile.sanitizePath}" @@ -699,6 +689,8 @@ macro c2nImport*(filename: static string, recurse: static bool = false, dynlib: if gStateCT.debug: gecho nimFile.readFile() + gecho "# Saved to " & nimFile + try: let nimFileNode = newStrLitNode(nimFile.changeFileExt("")) diff --git a/nimterop/toastlib/getters.nim b/nimterop/toastlib/getters.nim index bfbd4be..df930bb 100644 --- a/nimterop/toastlib/getters.nim +++ b/nimterop/toastlib/getters.nim @@ -338,6 +338,10 @@ proc getPreprocessor*(gState: State, fullpath: string) = start = true newHeaders.incl line break + elif ": fatal error:" in line: + doAssert false, + "\n\nFailed in preprocessing, check if `cIncludeDir()` is needed or compiler `mode` is correct (c/cpp)" & + "\n\nERROR:$1\n" % line.split(": fatal error:")[1] else: if start: if "#undef" in line: @@ -345,6 +349,9 @@ proc getPreprocessor*(gState: State, fullpath: string) = gState.code.add line & "\n" elif not p.running(): break p.close() + assert p.peekExitCode() == 0, + gState.code & "\n\nFailed in preprocessing:\n " & + getCompiler() & " " & args.join(" ") gState.headersProcessed.incl newHeaders # Plugin related diff --git a/tests/include/tast2.h b/tests/include/tast2.h index 06a0078..f9e0017 100644 --- a/tests/include/tast2.h +++ b/tests/include/tast2.h @@ -276,7 +276,7 @@ typedef union sx_ivec3 { struct { int x; int y; - struct z { + struct { int z; }; }; From 4d344e5807c17d8644cf23753d8445443cdb72bb Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Fri, 3 Jul 2020 16:17:34 -0500 Subject: [PATCH 550/593] Handle (*field), ident starting w/ digit error, fix detection of plugin and toast errors --- nimterop/cimport.nim | 2 +- nimterop/toastlib/ast2.nim | 3 ++- nimterop/toastlib/getters.nim | 13 ++++++++----- nimterop/toastlib/tshelp.nim | 2 +- tests/include/tast2.h | 7 +++++++ tests/tast2.nim | 6 +++++- 6 files changed, 24 insertions(+), 9 deletions(-) diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index 114ab80..cedd903 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -157,7 +157,7 @@ proc getToast(fullpaths: seq[string], recurse: bool = false, dynlib: string = "" var (output, ret) = execAction(cmd, die = false) - doAssert ret == 0, result.readFile() & output + doAssert ret == 0, "\n\n" & (if result.fileExists(): result.readFile() else: "") & output macro cOverride*(body): untyped = ## When the wrapper code generated by nimterop is missing certain symbols or not diff --git a/nimterop/toastlib/ast2.nim b/nimterop/toastlib/ast2.nim index fb2b55f..083d4b2 100644 --- a/nimterop/toastlib/ast2.nim +++ b/nimterop/toastlib/ast2.nim @@ -523,7 +523,8 @@ proc newIdentDef(gState: State, name: string, node: TSNode, tname: string, tinfo result.add pident let - count = node[offset].getPtrCount() + # Could be parenthesized + count = node[offset].getAtom().tsNodeParent().getPtrCount(reverse = true) if count > 0: result.add gState.newPtrTree(count, tident) else: diff --git a/nimterop/toastlib/getters.nim b/nimterop/toastlib/getters.nim index df930bb..1e70d59 100644 --- a/nimterop/toastlib/getters.nim +++ b/nimterop/toastlib/getters.nim @@ -167,13 +167,15 @@ proc checkIdentifier(name, kind, parent, origName: string) = if name.nBl: let - origStr = if name != origName: &", originally '{origName}' before 'cPlugin:onSymbol()', still" else: "" - errmsg = &"Identifier '{parentStr}{name}' ({kind}){origStr} contains $1 " & + origStr = if name != origName: &", originally '{origName}' before 'cPlugin:onSymbol()'," else: "" + errmsg = &"Identifier '{parentStr}{name}' ({kind}){origStr} $1 " & "which Nim does not allow. Use toast flag '$2' or 'cPlugin()' to modify." - doAssert name[0] != '_' and name[^1] != '_', errmsg % ["leading/trailing underscores '_'", "--prefix or --suffix"] + doAssert name[0] != '_' and name[^1] != '_', errmsg % ["has leading/trailing underscores '_'", "--prefix or --suffix"] - doAssert (not name.contains("__")): errmsg % ["consecutive underscores '_'", "--replace"] + doAssert (not name.contains("__")): errmsg % ["has consecutive underscores '_'", "--replace"] + + doAssert not name[0].isDigit(), errmsg % [&"starts with a digit '{name[0]}'", "--prefix"] # Cannot blank out symbols which are fields or params # @@ -381,7 +383,8 @@ proc loadPlugin*(gState: State, sourcePath: string) = # Compile plugin as library with `markAndSweep` GC cmd = &"{gState.nim} c --app:lib --gc:markAndSweep {flags} {outflags} {sourcePath.sanitizePath}" - discard execAction(cmd) + (output, ret) = execAction(cmd, die = false) + doAssert ret == 0, output & "\nFailed to compile cPlugin()\n\ncmd: " & cmd doAssert fileExists(pdll), "No plugin binary generated for " & sourcePath let lib = loadLib(pdll) diff --git a/nimterop/toastlib/tshelp.nim b/nimterop/toastlib/tshelp.nim index bbe029f..81c8d0d 100644 --- a/nimterop/toastlib/tshelp.nim +++ b/nimterop/toastlib/tshelp.nim @@ -116,7 +116,7 @@ proc getXCount*(node: TSNode, ntype: string, reverse = false): int = break proc getPtrCount*(node: TSNode, reverse = false): int = - node.getXCount("pointer_declarator") + node.getXCount("pointer_declarator", reverse) proc getArrayCount*(node: TSNode, reverse = false): int = node.getXCount("array_declarator") diff --git a/tests/include/tast2.h b/tests/include/tast2.h index f9e0017..38c5f18 100644 --- a/tests/include/tast2.h +++ b/tests/include/tast2.h @@ -292,6 +292,9 @@ enum { SG_MAX_TEXTUREARRAY_LAYERS = 128 }; +struct parenpoin { + void (*gtk_reserved1); +}; // DUPLICATES @@ -588,6 +591,10 @@ enum { SG_MAX_TEXTUREARRAY_LAYERS = 128 }; +struct parenpoin { + void (*__gtk_reserved1); +}; + #endif #ifdef __cplusplus diff --git a/tests/tast2.nim b/tests/tast2.nim index ade5dff..17edfb0 100644 --- a/tests/tast2.nim +++ b/tests/tast2.nim @@ -515,4 +515,8 @@ when not defined(NOHEADER): # #236 assert SG_MAX_MIPMAPS is cint -assert SG_MAX_MIPMAPS == 16 \ No newline at end of file +assert SG_MAX_MIPMAPS == 16 + +assert parenpoin is object +var pp: parenpoin +assert pp.gtk_reserved1 is pointer \ No newline at end of file From 03d1b54d6c10317a7bd005f35ecb7a9b426051fb Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Fri, 3 Jul 2020 23:51:52 -0500 Subject: [PATCH 551/593] gitPull non-master default branch, rmFile fix --- nimterop/build/shell.nim | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/nimterop/build/shell.nim b/nimterop/build/shell.nim index 2b29734..f07f70c 100644 --- a/nimterop/build/shell.nim +++ b/nimterop/build/shell.nim @@ -155,7 +155,7 @@ proc rmFile*(source: string, dir = false) = if dir: "rd /s/q" else: - "del /s/q/f" + "del /q/f" else: "rm -rf" exists = @@ -335,6 +335,18 @@ proc gitAtCheckout*(outdir, checkout: string): bool = result = checkout in execAction( &"cd {outdir.sanitizePath} && git log --decorate --no-color -n 1 --format=oneline").output +proc gitDefaultBranch*(outdir: string): string = + ## Get the default branch for a git repository before it is pulled + result = "master" + let + output = execAction( + &"cd {outdir.sanitizePath} && git remote show origin" + ).output + + for line in output.splitLines(): + if "HEAD branch: " in line: + result = line.split("branch: ")[1].strip() + proc gitPull*(url: string, outdir = "", plist = "", checkout = "", quiet = false) = ## Pull the specified git repository to the output directory ## @@ -375,15 +387,14 @@ proc gitPull*(url: string, outdir = "", plist = "", checkout = "", quiet = false # In case directory has old files from another run discard execAction(&"cd {outdirQ} && git clean -fxd") - if checkout.len != 0: - if not quiet: - gecho "# Checking out " & checkout - discard execAction(&"cd {outdirQ} && git fetch", retry = 3) - discard execAction(&"cd {outdirQ} && git checkout {checkout}") - else: - if not quiet: - gecho "# Pulling repository" - discard execAction(&"cd {outdirQ} && git pull --depth=1 origin master", retry = 3) + # Checkout specified branch/tag/commit or default branch - typically master + let + checkout = if checkout.Bl: gitDefaultBranch(outdir) else: checkout + + if not quiet: + gecho "# Checking out " & checkout + discard execAction(&"cd {outdirQ} && git fetch", retry = 3) + discard execAction(&"cd {outdirQ} && git checkout {checkout}") proc gitTags*(outdir: string): seq[string] = ## Get all the git tags in the specified directory From 90c5f54dc3b21c32e6666065c7a192c89a37fb4f Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Sat, 4 Jul 2020 00:49:46 -0500 Subject: [PATCH 552/593] v0.6.2 --- nimterop.nimble | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimterop.nimble b/nimterop.nimble index 628ef40..adbd171 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -1,6 +1,6 @@ # Package -version = "0.6.1" +version = "0.6.2" author = "genotrance" description = "C/C++ interop for Nim" license = "MIT" From 37cdc5b94ec42c268fc2f7dc63cea967b3d521cd Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Sat, 11 Jul 2020 17:29:21 -0500 Subject: [PATCH 553/593] Add jbbFlags to customize xxxJBB --- CHANGES.md | 4 ++- nimterop/build/getheader.nim | 42 ++++++++++++++++++++++--------- nimterop/build/jbb.nim | 48 ++++++++++++++++++++++++------------ 3 files changed, 66 insertions(+), 28 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index e85d261..70e1f76 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -15,7 +15,7 @@ Refer to the documentation for `getHeader()` for details on how to use this new See the full list of changes here: -https://github.com/nimterop/nimterop/compare/v0.5.9...v0.6.1 +https://github.com/nimterop/nimterop/compare/v0.5.9...v0.6.3 ### Breaking changes @@ -39,6 +39,8 @@ https://github.com/nimterop/nimterop/compare/v0.5.9...v0.6.1 - Nimterop now supports anonymous nested structs/unions but it only works correctly for unions when `noHeader` is turned off (the default). This is because Nim does not support nested structs/unions and is unaware of the underlying memory structure. [#237][i237] (since v0.6.1) +- `xxxJBB` now allows for customizing the base location to search packages with the `jbbFlags` param to `getHeader()`. Specifying `giturl=xxx` where `xxx` could be a full Git URL or just the username for Github.com allows changing the default Git repo. In addition, `url=xxx` is also supported to download project info and binaries compiled with BinaryBuilder.org but hosted at another non-Git location. (since v0.6.3) + ### Other improvements - Generated wrappers no longer depend on nimterop being present - no more `import nimterop/types`. Supporting code is directly included in the wrapper output and only when required. E.g. enum macro is only included if wrapper contains enums. [#125][i125] (since v0.6.1) diff --git a/nimterop/build/getheader.nim b/nimterop/build/getheader.nim index 6972ccc..d5b398a 100644 --- a/nimterop/build/getheader.nim +++ b/nimterop/build/getheader.nim @@ -141,18 +141,14 @@ proc getConanLDeps(outdir: string): seq[string] = result = pkg.getConanLDeps(outdir) -proc getJBBPath(header, uri, outdir, version: string): string = +proc getJBBPath(header, uri, flags, outdir, version: string): string = let spl = uri.split('/', 1) name = spl[0] hasVersion = version.len != 0 var - ver = - if spl.len == 2: - spl[1] - else: - "" + ver = if spl.len == 2: spl[1] else: "" if ver.len != 0: if "$#" in ver or "$1" in ver: @@ -166,6 +162,20 @@ proc getJBBPath(header, uri, outdir, version: string): string = let pkg = newJBBPackage(name, ver) + + # Handle `jbbFlags` + if flags.nBl: + if flags.startsWith("giturl="): + let + val = flags["giturl=".len .. ^1] + if val.contains("://"): + pkg.baseUrl = val + else: + pkg.baseUrl = "https://github.com/" & val + elif flags.startsWith("url="): + pkg.baseUrl = flags["url=".len .. ^1] + pkg.isGit = false + downloadJBB(pkg, outdir) result = findFile(header, outdir) @@ -217,7 +227,8 @@ macro getHeader*( conanuri: static[string] = "", jbburi: static[string] = "", outdir: static[string] = "", libdir: static[string] = "", conFlags: static[string] = "", cmakeFlags: static[string] = "", makeFlags: static[string] = "", - altNames: static[string] = "", buildTypes: static[openArray[BuildType]] = [btCmake, btAutoconf]): untyped = + jbbFlags: static[string] = "", altNames: static[string] = "", + buildTypes: static[openArray[BuildType]] = [btCmake, btAutoconf]): untyped = ## Get the path to a header file for wrapping with ## `cImport() `_ or ## `c2nImport() `_. @@ -289,6 +300,13 @@ macro getHeader*( ## `cmake` and `make` in case additional configuration is required as part of the build ## process. ## + ## `jbbFlags` allows changing the BinaryBuilder.org defaults: + ## - `giturl=customUrl` changes the default `https://github.com/JuliaBinaryWrappers` to + ## another Git URL. If no hostname is specified, `https://github.com` is assumed. + ## - `url=customUrl` uses regular HTTP instead of Git and looks for `Artifacts.toml` and + ## `Project.toml` files at that location. `$1` or `$#` are replaced with the version + ## if specified. + ## ## `altNames` is a list of alternate names for the library - e.g. zlib uses `zlib.h` for ## the header but the typical lib name is `libz.so` and not `libzlib.so`. However, it is ## libzlib.dll on Windows if built with cmake. In this case, `altNames = "z,zlib"`. Comma @@ -384,7 +402,7 @@ macro getHeader*( `nameStatic`* = when defined(`nameStatic`): true else: `staticVal` == 1 # Search for header in outdir (after retrieving code) depending on -d:xxx mode - proc getPath(header, giturl, dlurl, conanuri, jbburi, outdir, version: string, shared: bool): string = + proc getPath(header, giturl, dlurl, conanuri, jbburi, jbbFlags, outdir, version: string, shared: bool): string = when `nameGit`: getGitPath(header, giturl, outdir, version) elif `nameDL`: @@ -392,7 +410,7 @@ macro getHeader*( elif `nameConan`: getConanPath(header, conanuri, outdir, version, shared) elif `nameJBB`: - getJBBPath(header, jbburi, outdir, version) + getJBBPath(header, jbburi, jbbFlags, outdir, version) else: getLocalPath(header, outdir) @@ -423,7 +441,8 @@ macro getHeader*( when useStd: stdPath else: - getPath(`header`, `giturl`, `dlurl`, `conanuri`, `jbburi`, `outdir`, `version`, not `nameStatic`) + getPath(`header`, `giturl`, `dlurl`, `conanuri`, `jbburi`, `jbbFlags`, + `outdir`, `version`, not `nameStatic`) # Run preBuild hook before building library if not Std, Conan or JBB when not (useStd or `nameConan` or `nameJBB`) and declared(`preBuild`): @@ -458,7 +477,8 @@ macro getHeader*( if prePath.len != 0: prePath else: - getPath(`header`, `giturl`, `dlurl`, `conanuri`, `jbburi`, `outdir`, `version`, not `nameStatic`) + getPath(`header`, `giturl`, `dlurl`, `conanuri`, `jbburi`, `jbbFlags`, + `outdir`, `version`, not `nameStatic`) static: doAssert `path`.len != 0, "\nHeader " & `header` & " not found - " & diff --git a/nimterop/build/jbb.nim b/nimterop/build/jbb.nim index 0fb163f..b9272c7 100644 --- a/nimterop/build/jbb.nim +++ b/nimterop/build/jbb.nim @@ -12,7 +12,10 @@ type name*: string version*: string - url*: string + baseUrl*: string # Location to find package + isGit*: bool # Git or HTTP + + url*: string # Download URL sharedLibs*: seq[string] staticLibs*: seq[string] @@ -20,7 +23,7 @@ type const # JBB URLs - jbbBaseUrl = "https://github.com/JuliaBinaryWrappers/$1_jll.jl" + jbbBaseUrl = "https://github.com/JuliaBinaryWrappers" jbbInfo = "jbbinfo.json" jbbProject = "Project.toml" @@ -45,6 +48,8 @@ proc newJBBPackage*(name, version: string): JBBPackage = result = new(JBBPackage) result.name = name result.version = version + result.baseUrl = jbbBaseUrl + result.isGit = true proc parseJBBProject(pkg: JBBPackage, outdir: string) = # Get all dependencies from Project.toml @@ -127,21 +132,32 @@ proc getJBBRepo*(pkg: JBBPackage, outdir: string) = let path = outdir / "repos" / pkg.name - gitPull( - jbbBaseUrl % pkg.name, - outdir = path, - plist = "*.toml", - "master", - quiet = true - ) + if pkg.isGit: + # Get package info using Git + gitPull( + pkg.baseUrl & ("/$1_jll.jl" % pkg.name), + outdir = path, + plist = "*.toml", + "master", + quiet = true + ) - if pkg.version.len != 0: - # Checkout correct tag - let - tags = gitTags(path) - for i in tags.len - 1 .. 0: - if pkg.version in tags[i] and i != tags.len - 1: - gitCheckout(path, tags[i-1]) + if pkg.version.len != 0: + # Checkout correct tag + let + tags = gitTags(path) + for i in tags.len - 1 .. 0: + if pkg.version in tags[i] and i != tags.len - 1: + gitCheckout(path, tags[i-1]) + else: + # Download package info from HTTP + var + url = pkg.baseUrl + if "$#" in url or "$1" in url: + doAssert pkg.version.len != 0, "Need version for custom BinaryBuilder.org url: " & url + url = url % pkg.version + downloadUrl(url & "Artifacts.toml", path, quiet = true) + downloadUrl(url & "Project.toml", path, quiet = true) pkg.parseJBBProject(path) pkg.parseJBBArtifacts(path) From fb2acc752a283223b5c4647bfe85d75cd23a5b4f Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Sun, 12 Jul 2020 00:12:41 -0500 Subject: [PATCH 554/593] v0.6.3 --- nimterop.nimble | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimterop.nimble b/nimterop.nimble index adbd171..16a6c6a 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -1,6 +1,6 @@ # Package -version = "0.6.2" +version = "0.6.3" author = "genotrance" description = "C/C++ interop for Nim" license = "MIT" From a9887cc6b2569bddd1daf56ae66960fb500be3e9 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Sun, 12 Jul 2020 17:35:29 -0500 Subject: [PATCH 555/593] Add ability to exclude files or directories from wrapped output --- CHANGES.md | 4 +++ README.md | 2 ++ nimterop/cimport.nim | 56 ++++++++++++++++++++++++++++------- nimterop/globals.nim | 1 + nimterop/toast.nim | 6 +++- nimterop/toastlib/getters.nim | 16 ++++++++-- 6 files changed, 70 insertions(+), 15 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 70e1f76..23aa2bb 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -41,12 +41,16 @@ https://github.com/nimterop/nimterop/compare/v0.5.9...v0.6.3 - `xxxJBB` now allows for customizing the base location to search packages with the `jbbFlags` param to `getHeader()`. Specifying `giturl=xxx` where `xxx` could be a full Git URL or just the username for Github.com allows changing the default Git repo. In addition, `url=xxx` is also supported to download project info and binaries compiled with BinaryBuilder.org but hosted at another non-Git location. (since v0.6.3) +- It is now possible to exclude the contents of specific files or entire directories from the wrapped output using `--exclude | -X` with `toast` or `cExclude()` from a wrapper. This might be required when a header uses `#include` to pull in external dependencies. E.g. `sciter` has a `#include ` which pulls in the entire GTK ecosystem which is needed for successful preprocessing but we do not want to include those headers in the wrapped output when using `--recurse | -r`. + ### Other improvements - Generated wrappers no longer depend on nimterop being present - no more `import nimterop/types`. Supporting code is directly included in the wrapper output and only when required. E.g. enum macro is only included if wrapper contains enums. [#125][i125] (since v0.6.1) - `cImport()` now includes wrapper output from a file rather than inline. Errors in generated wrappers will no longer point to a line in `macros.nim` making debugging easier. (since v0.6.1) +- `cIncludeDir()` can now accept a `seq[string]` of directories and an optional `exclude` param which sets those include directories to not be included in the wrapped output. + ## Version 0.5.0 diff --git a/README.md b/README.md index f9e9307..0e79a6f 100644 --- a/README.md +++ b/README.md @@ -132,6 +132,7 @@ cDefine("HAS_ABC") # Set #defines for preprocessor and compiler cDefine("HAS_ABC", "DEF") cIncludeDir("clib/include") # Setup any include directories +cExclude("clib/file.h") # Exclude file from wrapped output cImport("clib.h") # Generate wrappers for header specified @@ -219,6 +220,7 @@ Options: -d, --debug bool false enable debug output -D=, --defines= strings {} definitions to pass to preprocessor -l=, --dynlib= string "" {.dynlib.} pragma to import symbols - Nim const string or file path + -X=, --exclude= strings {} files or directories to exclude from the wrapped output -f=, --feature= Features {} flags to enable experimental features -I=, --includeDirs= strings {} include directory to pass to preprocessor -m=, --mode= string "" language parser: c or cpp diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index cedd903..95004ad 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -120,6 +120,9 @@ proc getToast(fullpaths: seq[string], recurse: bool = false, dynlib: string = "" for i in gStateCT.includeDirs: cmd.add &" --includeDirs+={i.sanitizePath}" + for i in gStateCT.exclude: + cmd.add &" --exclude+={i.sanitizePath}" + if not noNimout: cmd.add &" --pnim" @@ -415,21 +418,52 @@ proc cAddSearchDir*(dir: string) {.compileTime.} = if dir notin gStateCT.searchDirs: gStateCT.searchDirs.add(dir) -macro cIncludeDir*(dir: static string): untyped = +macro cIncludeDir*(dirs: static seq[string], exclude: static[bool] = false): untyped = + ## Add include directories that are forwarded to the C/C++ preprocessor if + ## called within `cImport()` or `c2nImport()` as well as to the C/C++ + ## compiler during Nim compilation using `{.passC: "-IXXX".}`. + ## + ## Set `exclude = true` if the contents of these include directories should + ## not be included in the wrapped output. + for dir in dirs: + var dir = interpPath(dir) + result = newNimNode(nnkStmtList) + + let fullpath = findPath(dir) + if fullpath notin gStateCT.includeDirs: + gStateCT.includeDirs.add(fullpath) + if exclude: + gStateCT.exclude.add(fullpath) + let str = &"-I{fullpath.quoteShell}" + result.add quote do: + {.passC: `str`.} + if gStateCT.debug: + gecho result.repr + +macro cIncludeDir*(dir: static[string], exclude: static[bool] = false): untyped = ## Add an include directory that is forwarded to the C/C++ preprocessor if ## called within `cImport()` or `c2nImport()` as well as to the C/C++ ## compiler during Nim compilation using `{.passC: "-IXXX".}`. - var dir = interpPath(dir) - result = newNimNode(nnkStmtList) + ## + ## Set `exclude = true` if the contents of this include directory should + ## not be included in the wrapped output. + return quote do: + cIncludeDir(@[`dir`], `exclude` == 1) - let fullpath = findPath(dir) - if fullpath notin gStateCT.includeDirs: - gStateCT.includeDirs.add(fullpath) - let str = &"-I{fullpath.quoteShell}" - result.add quote do: - {.passC: `str`.} - if gStateCT.debug: - gecho result.repr +macro cExclude*(paths: static seq[string]): untyped = + ## Exclude specified paths - files or directories from the wrapped output + ## + ## Full path to file or directory is required. + result = newNimNode(nnkStmtList) + for path in paths: + gStateCT.exclude.add path + +macro cExclude*(path: static string): untyped = + ## Exclude specified path - file or directory from the wrapped output. + ## + ## Full path to file or directory is required. + return quote do: + cExclude(@[`path`]) proc cAddStdDir*(mode = "c") {.compileTime.} = ## Add the standard `c` [default] or `cpp` include paths to search diff --git a/nimterop/globals.nim b/nimterop/globals.nim index 17b9518..89e403f 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -19,6 +19,7 @@ type debug*: bool # `cDebug()` or `--debug | -d` to enable debug mode defines*: seq[string] # Symbols added by `cDefine()` and `--define | -D` for C/C++ preprocessor/compiler dynlib*: string # `cImport(dynlib)` or `--dynlib | -l` to specify variable containing library name + exclude*: seq[string] # files or directories to exclude from the wrapped output feature*: seq[Feature] # `--feature | -f` feature flags enabled includeDirs*: seq[string] # Paths added by `cIncludeDir()` and `--includeDirs | -I` for C/C++ preprocessor/compiler mode*: string # `cImport(mode)` or `--mode | -m` to override detected compiler mode - c or cpp diff --git a/nimterop/toast.nim b/nimterop/toast.nim index 1cda239..20dc79e 100644 --- a/nimterop/toast.nim +++ b/nimterop/toast.nim @@ -13,7 +13,7 @@ var preMainOut = "" proc process(gState: State, path: string) = - doAssert existsFile(path), &"Invalid path {path}" + doAssert fileExists(path), &"Invalid path {path}" if gState.mode.Bl: gState.mode = getCompilerMode(path) @@ -38,6 +38,7 @@ proc main( debug = false, defines: seq[string] = @[], dynlib: string = "", + exclude: seq[string] = @[], feature: seq[Feature] = @[], includeDirs: seq[string] = @[], mode = "", @@ -65,6 +66,7 @@ proc main( debug: debug, defines: defines, dynlib: dynlib, + exclude: exclude, feature: feature, includeDirs: includeDirs, mode: mode, @@ -222,6 +224,7 @@ when isMainModule: "debug": "enable debug output", "defines": "definitions to pass to preprocessor", "dynlib": "{.dynlib.} pragma to import symbols - Nim const string or file path", + "exclude": "files or directories to exclude from the wrapped output", "feature": "flags to enable experimental features", "includeDirs": "include directory to pass to preprocessor", "mode": "language parser: c or cpp", @@ -247,6 +250,7 @@ when isMainModule: "debug": 'd', "defines": 'D', "dynlib": 'l', + "exclude": 'X', "feature": 'f', "includeDirs": 'I', "noComments": 'c', diff --git a/nimterop/toastlib/getters.nim b/nimterop/toastlib/getters.nim index 1e70d59..8c6abe1 100644 --- a/nimterop/toastlib/getters.nim +++ b/nimterop/toastlib/getters.nim @@ -286,7 +286,16 @@ proc getKeyword*(kind: NimSymKind): string = proc getCurrentHeader*(fullpath: string): string = ("header" & fullpath.splitFile().name.multiReplace([(".", ""), ("-", "")])) +proc isIncluded(gState: State, file: string): bool {.inline.} = + # Check if the specified file should be excluded from wrapped output + if gState.exclude.nBl: + for excl in gState.exclude: + if file.startsWith(excl): + return + result = true + proc getPreprocessor*(gState: State, fullpath: string) = + # Get preprocessed output from the C/C++ compiler var args: seq[string] start = false @@ -332,14 +341,15 @@ proc getPreprocessor*(gState: State, fullpath: string) = start = true elif gState.recurse: if (pDir.Bl or pDir in line) and line notin gState.headersProcessed: - start = true newHeaders.incl line + start = gState.isIncluded(line) else: for inc in includeDirs: if line.startsWith(inc) and line notin gState.headersProcessed: - start = true newHeaders.incl line - break + start = gState.isIncluded(line) + if start: + break elif ": fatal error:" in line: doAssert false, "\n\nFailed in preprocessing, check if `cIncludeDir()` is needed or compiler `mode` is correct (c/cpp)" & From d7c94bb70bb754ffbe85669e550589089d6597d1 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Sun, 12 Jul 2020 22:21:35 -0500 Subject: [PATCH 556/593] Bump to v0.6.4 --- .travis.yml | 3 ++- CHANGES.md | 4 ++-- nimterop.nimble | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 173da68..b58b29d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,7 +13,7 @@ language: c env: - BRANCH=0.20.2 - BRANCH=1.0.6 - - BRANCH=1.2.2 + - BRANCH=1.2.4 - BRANCH=devel cache: @@ -26,6 +26,7 @@ install: - source travis.sh script: + - set -e - nimble develop -y - nimble test - nimble --verbose --nimbleDir:`pwd`/build/fakenimble install nimterop@#head -y diff --git a/CHANGES.md b/CHANGES.md index 23aa2bb..91cecac 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -41,7 +41,7 @@ https://github.com/nimterop/nimterop/compare/v0.5.9...v0.6.3 - `xxxJBB` now allows for customizing the base location to search packages with the `jbbFlags` param to `getHeader()`. Specifying `giturl=xxx` where `xxx` could be a full Git URL or just the username for Github.com allows changing the default Git repo. In addition, `url=xxx` is also supported to download project info and binaries compiled with BinaryBuilder.org but hosted at another non-Git location. (since v0.6.3) -- It is now possible to exclude the contents of specific files or entire directories from the wrapped output using `--exclude | -X` with `toast` or `cExclude()` from a wrapper. This might be required when a header uses `#include` to pull in external dependencies. E.g. `sciter` has a `#include ` which pulls in the entire GTK ecosystem which is needed for successful preprocessing but we do not want to include those headers in the wrapped output when using `--recurse | -r`. +- It is now possible to exclude the contents of specific files or entire directories from the wrapped output using `--exclude | -X` with `toast` or `cExclude()` from a wrapper. This might be required when a header uses `#include` to pull in external dependencies. E.g. `sciter` has a `#include ` which pulls in the entire GTK ecosystem which is needed for successful preprocessing but we do not want to include those headers in the wrapped output when using `--recurse | -r`. (since v0.6.4) ### Other improvements @@ -49,7 +49,7 @@ https://github.com/nimterop/nimterop/compare/v0.5.9...v0.6.3 - `cImport()` now includes wrapper output from a file rather than inline. Errors in generated wrappers will no longer point to a line in `macros.nim` making debugging easier. (since v0.6.1) -- `cIncludeDir()` can now accept a `seq[string]` of directories and an optional `exclude` param which sets those include directories to not be included in the wrapped output. +- `cIncludeDir()` can now accept a `seq[string]` of directories and an optional `exclude` param which sets those include directories to not be included in the wrapped output. (since v0.6.4) ## Version 0.5.0 diff --git a/nimterop.nimble b/nimterop.nimble index 16a6c6a..1eb35ef 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -1,6 +1,6 @@ # Package -version = "0.6.3" +version = "0.6.4" author = "genotrance" description = "C/C++ interop for Nim" license = "MIT" From 27fcecaa26a186dbc1e45c475baefe7182abb425 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 13 Jul 2020 17:47:17 -0500 Subject: [PATCH 557/593] Caching fixes, wchar_t --- nimterop/cimport.nim | 42 ++++++++++++++++++++++++++++++----- nimterop/toastlib/getters.nim | 4 ++-- 2 files changed, 39 insertions(+), 7 deletions(-) diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index 95004ad..aa7895a 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -142,15 +142,35 @@ proc getToast(fullpaths: seq[string], recurse: bool = false, dynlib: string = "" for fullpath in fullpaths: cmd.add &" {fullpath.sanitizePath}" - result = if outFile.nBl: fixRelFile(outFile) else: - # Generate filename for toast output if not specified - getNimteropCacheDir() / "toastCache" / "nimterop_" & + let + cacheFile = getNimteropCacheDir() / "toastCache" / "nimterop_" & ($(cmd & cacheKey).hash().abs()).addFileExt(ext) + if outFile.nBl: + result = fixRelFile(outFile) + else: + result = cacheFile + when defined(Windows): result = result.replace(DirSep, '/') - if not fileExists(result) or gStateCT.nocache or compileOption("forceBuild"): + let + # When to regenerate the wrapper + regen = + if gStateCT.nocache or compileOption("forceBuild"): + # No caching or forced + true + elif not fileExists(result): + # Cache or outfile doesn't exist + true + elif outFile.nBl and (not fileExists(cacheFile) or + result.getFileDate() > cacheFile.getFileDate()): + # Outfile exists but cache doesn't or outdated + true + else: + false + + if regen: let dir = result.parentDir() if not dirExists(dir): @@ -160,7 +180,19 @@ proc getToast(fullpaths: seq[string], recurse: bool = false, dynlib: string = "" var (output, ret) = execAction(cmd, die = false) - doAssert ret == 0, "\n\n" & (if result.fileExists(): result.readFile() else: "") & output + if ret != 0: + # If toast fails, print failure to output and delete any generated files + let errout = if result.fileExists(): result.readFile() & output else: output + rmFile(result) + doAssert false, "\n\n" & errout & "\n" + + # Write empty cache file to track changes when outFile specified + if outFile.nBl: + let dir = cacheFile.parentDir() + if not dirExists(dir): + mkdir(dir) + + writeFile(cacheFile, "") macro cOverride*(body): untyped = ## When the wrapper code generated by nimterop is missing certain symbols or not diff --git a/nimterop/toastlib/getters.nim b/nimterop/toastlib/getters.nim index 8c6abe1..8a4586d 100644 --- a/nimterop/toastlib/getters.nim +++ b/nimterop/toastlib/getters.nim @@ -139,7 +139,7 @@ when defined(cpp): # not defined in nor any other header). type wchar_t* {.importc.} = object else: - type wchar_t* {.importc, header:"".} = object + type wchar_t* {.importc, header:"stddef.h".} = object """, "va_list": """ @@ -417,4 +417,4 @@ proc expandSymlinkAbs*(path: string): string = result = path.expandFilename().normalizedPath() except: result = path - result = result.sanitizePath(noQuote = true) \ No newline at end of file + result = result.sanitizePath(noQuote = true) From 6ffacf92fc19d2cd0754e2409868a2dca4501e93 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 14 Jul 2020 18:08:59 -0500 Subject: [PATCH 558/593] Forward pragmas to toast --- README.md | 2 + nimterop/build/conan.nim | 20 ++-- nimterop/build/jbb.nim | 17 ++- nimterop/build/nimconf.nim | 4 + nimterop/cimport.nim | 212 ++++++++++++++++--------------------- nimterop/globals.nim | 5 +- nimterop/template.nim | 111 ------------------- nimterop/templite.nim | 36 ------- nimterop/toast.nim | 9 ++ nimterop/toastlib/ast2.nim | 24 ++++- tests/libssh2.nim | 4 +- tests/rsa.nim | 4 +- tests/tast2.nim | 2 +- tests/tsoloud.nim | 8 +- tests/zlib.nim | 10 +- 15 files changed, 162 insertions(+), 306 deletions(-) delete mode 100644 nimterop/template.nim delete mode 100644 nimterop/templite.nim diff --git a/README.md b/README.md index 0e79a6f..cda3b5e 100644 --- a/README.md +++ b/README.md @@ -139,6 +139,8 @@ cImport("clib.h") # Generate wrappers for header specified cCompile("clib/src/*.c") # Compile in any implementation source files ``` +All `{.compileTime.}` procs must be used in a compile time context, like `cDebug()` and `cDisableCaching()` above. + Module documentation for the wrapper API can be found [here](https://nimterop.github.io/nimterop/cimport.html). #### Preprocessing diff --git a/nimterop/build/conan.nim b/nimterop/build/conan.nim index 792de01..dd43dc9 100644 --- a/nimterop/build/conan.nim +++ b/nimterop/build/conan.nim @@ -79,10 +79,6 @@ proc jsonGet(url: string): JsonNode = discard rmFile(file) -template fixOutDir() {.dirty.} = - let - outdir = if outdir.isAbsolute(): outdir else: getProjectDir() / outdir - proc `==`*(pkg1, pkg2: ConanPackage): bool = ## Check if two ConanPackage objects are equal (not pkg1.isNil and not pkg2.isNil and @@ -282,9 +278,8 @@ proc getConanRevisions*(pkg: ConanPackage, bld: ConanBuild) = proc loadConanInfo*(outdir: string): ConanPackage = ## Load cached package info from `outdir/conaninfo.json` - fixOutDir() let - file = outdir / conanInfo + file = fixRelPath(outdir) / conanInfo if fileExists(file): when (NimMajor, NimMinor, NimPatch) < (1, 2, 0): @@ -297,9 +292,8 @@ proc loadConanInfo*(outdir: string): ConanPackage = proc saveConanInfo*(pkg: ConanPackage, outdir: string) = ## Save downloaded package info to `outdir/conaninfo.json` - fixOutDir() let - file = outdir / conanInfo + file = fixRelPath(outdir) / conanInfo when (NimMajor, NimMinor, NimPatch) < (1, 2, 0): writeFile(file, $$pkg) @@ -329,11 +323,11 @@ proc dlConanBuild*(pkg: ConanPackage, bld: ConanBuild, outdir: string, revision ## Download specific `revision` of `bld` to `outdir` ## ## If omitted, the latest revision (first) is downloaded - fixOutDir() - doAssert bld.revisions.len != 0, "No build revisions found for Conan.io package " & pkg.getUriFromConanPackage() let + outdir = fixRelPath(outdir) + revision = if revision.len != 0: revision @@ -376,8 +370,9 @@ proc downloadConan*(pkg: ConanPackage, outdir: string, main = true) = ## ## High-level API that handles the end to end Conan process flow to find ## latest package binary and downloads and extracts it to `outdir`. - fixOutDir() let + outdir = fixRelPath(outdir) + pkg = if pkg.version.len == 0: searchConan(pkg) @@ -415,7 +410,8 @@ proc dlConanRequires*(pkg: ConanPackage, bld: ConanBuild, outdir: string) = ## ## This is not required for shared libs since conan builds them ## with all dependencies statically linked in - fixOutDir() + let + outdir = fixRelPath(outdir) if bld.options["shared"] == "False": for req in bld.requires: let diff --git a/nimterop/build/jbb.nim b/nimterop/build/jbb.nim index b9272c7..a430a55 100644 --- a/nimterop/build/jbb.nim +++ b/nimterop/build/jbb.nim @@ -33,10 +33,6 @@ var # Reuse dependencies already downloaded gJBBRequires {.compileTime.}: Table[string, JBBPackage] -template fixOutDir() {.dirty.} = - let - outdir = if outdir.isAbsolute(): outdir else: getProjectDir() / outdir - proc `==`*(pkg1, pkg2: JBBPackage): bool = ## Check if two JBBPackage objects are equal (not pkg1.isNil and not pkg2.isNil and @@ -164,9 +160,8 @@ proc getJBBRepo*(pkg: JBBPackage, outdir: string) = proc loadJBBInfo*(outdir: string): JBBPackage = ## Load cached package info from `outdir/jbbinfo.json` - fixOutDir() let - file = outdir / jbbInfo + file = fixRelPath(outdir) / jbbInfo if fileExists(file): when (NimMajor, NimMinor, NimPatch) < (1, 2, 0): @@ -179,9 +174,8 @@ proc loadJBBInfo*(outdir: string): JBBPackage = proc saveJBBInfo*(pkg: JBBPackage, outdir: string) = ## Save downloaded package info to `outdir/jbbinfo.json` - fixOutDir() let - file = outdir / jbbInfo + file = fixRelPath(outdir) / jbbInfo when (NimMajor, NimMinor, NimPatch) < (1, 2, 0): writeFile(file, $$pkg) @@ -194,7 +188,9 @@ proc downloadJBB*(pkg: JBBPackage, outdir: string, main = true) = ## ## High-level API that handles the end to end JBB process flow to find ## latest package binary and downloads and extracts it to `outdir`. - fixOutDir() + let + outdir = fixRelPath(outdir) + if main: let cpkg = loadJBBInfo(outdir) @@ -226,7 +222,8 @@ proc downloadJBB*(pkg: JBBPackage, outdir: string, main = true) = proc dlJBBRequires*(pkg: JBBPackage, outdir: string) = ## Download all required dependencies of this `pkg` - fixOutDir() + let + outdir = fixRelPath(outdir) for i in 0 ..< pkg.requires.len: let rpkg = pkg.requires[i] diff --git a/nimterop/build/nimconf.nim b/nimterop/build/nimconf.nim index 3bbe521..7624bf2 100644 --- a/nimterop/build/nimconf.nim +++ b/nimterop/build/nimconf.nim @@ -234,3 +234,7 @@ proc getOutDir*(projectDir = ""): string = proc getNimteropCacheDir*(): string = ## Get location to cache all nimterop artifacts result = getNimcacheDir() / "nimterop" + +proc fixRelPath*(path: string): string = + ## If `path` is relative, consider relative to `projectPath` + if path.isAbsolute: path else: getProjectDir() / path \ No newline at end of file diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index aa7895a..6120cb5 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -1,78 +1,17 @@ -##[ -This is the main nimterop import file to help with wrapping C/C++ source code. - -Check out `template.nim `_ -as a starting point for wrapping a new library. The template can be copied and -trimmed down and modified as required. `templite.nim `_ is a shorter -version for more experienced users. - -All `{.compileTime.}` procs must be used in a compile time context, e.g. using: - -.. code-block:: c - - static: - cAddStdDir() - -]## - import hashes, macros, os, strformat, strutils import "."/[globals, paths] import "."/build/[ccompiler, misc, nimconf, shell] -proc interpPath(dir: string): string= - # TODO: more robust: needs a DirSep after "$projpath" - # disabling this interpolation as this is error prone, but other less - # interpolations can be added, eg see https://github.com/nim-lang/Nim/pull/10530 - # result = dir.replace("$projpath", getProjectPath()) - result = dir - -proc joinPathIfRel(path1: string, path2: string): string = - if path2.isAbsolute: - result = path2 - else: - result = joinPath(path1, path2) - proc findPath(path: string, fail = true): string = # Relative to project path - result = joinPathIfRel(getProjectPath(), path).replace("\\", "/") + let + path = fixRelPath(path) + result = path.replace("\\", "/") if not fileExists(result) and not dirExists(result): doAssert (not fail), "File or directory not found: " & path result = "" -proc walkDirImpl(indir, inext: string, file=true): seq[string] = - let - dir = joinPathIfRel(getProjectPath(), indir) - ext = - if inext.nBl: - when not defined(Windows): - "-name " & inext - else: - "\\" & inext - else: - "" - - let - cmd = - when defined(Windows): - if file: - "cmd /c dir /s/b/a-d " & dir.replace("/", "\\") & ext - else: - "cmd /c dir /s/b/ad " & dir.replace("/", "\\") - else: - if file: - "find $1 -type f $2" % [dir, ext] - else: - "find $1 -type d" % dir - - (output, ret) = execAction(cmd, die = false) - - if ret == 0: - result = output.splitLines() - -proc fixRelFile(file: string): string = - if file.isAbsolute(): file else: getProjectDir() / file - proc getCacheValue(fullpath: string): string = if not gStateCT.nocache: result = fullpath.getFileDate() @@ -123,6 +62,15 @@ proc getToast(fullpaths: seq[string], recurse: bool = false, dynlib: string = "" for i in gStateCT.exclude: cmd.add &" --exclude+={i.sanitizePath}" + for i in gStateCT.passC: + cmd.add &" --passC+={i.quoteShell}" + + for i in gStateCT.passL: + cmd.add &" --passL+={i.quoteShell}" + + for i in gStateCT.compile: + cmd.add &" --compile+={i.sanitizePath}" + if not noNimout: cmd.add &" --pnim" @@ -147,7 +95,7 @@ proc getToast(fullpaths: seq[string], recurse: bool = false, dynlib: string = "" ($(cmd & cacheKey).hash().abs()).addFileExt(ext) if outFile.nBl: - result = fixRelFile(outFile) + result = fixRelPath(outFile) else: result = cacheFile @@ -384,7 +332,7 @@ macro cPluginPath*(path: static[string]): untyped = doAssert fileExists(path), "Plugin file not found: " & path cPluginHelper(readFile(path), imports = "") -proc cSearchPath*(path: string): string {.compileTime.}= +proc cSearchPath*(path: string): string {.compileTime.} = ## Get full path to file or directory `path` in search path configured ## using `cAddSearchDir()` and `cAddStdDir()`. ## @@ -416,27 +364,38 @@ proc cDisableCaching*() {.compileTime.} = ## `nim -f` can also be used to flush the cached content. gStateCT.nocache = true -macro cDefine*(name: static string, val: static string = ""): untyped = +macro cDefine*(name: static[string], val: static[string] = ""): untyped = ## `#define` an identifer that is forwarded to the C/C++ preprocessor if ## called within `cImport()` or `c2nImport()` as well as to the C/C++ ## compiler during Nim compilation using `{.passC: "-DXXX".}` - result = newNimNode(nnkStmtList) - var str = name - # todo: see https://github.com/nimterop/nimterop/issues/100 for - # edge case of empty strings if val.nBl: str &= &"={val.quoteShell}" if str notin gStateCT.defines: gStateCT.defines.add(str) - str = "-D" & str - result.add quote do: - {.passC: `str`.} +macro cDefine*(values: static seq[string]): untyped = + ## `#define` multiple identifers that are forwarded to the C/C++ preprocessor + ## if called within `cImport()` or `c2nImport()` as well as to the C/C++ + ## compiler during Nim compilation using `{.passC: "-DXXX".}` + for value in values: + let + spl = value.split("=", maxsplit = 1) + name = spl[0] + val = if spl.len == 2: spl[1] else: "" + discard quote do: + cDefine(`name`, `val`) - if gStateCT.debug: - gecho result.repr & "\n" +macro cPassC*(value: static string): untyped = + ## Create a `{.passC.}` entry that gets forwarded to the C/C++ compiler + ## during Nim compilation. + gStateCT.passC.add value + +macro cPassL*(value: static string): untyped = + ## Create a `{.passL.}` entry that gets forwarded to the C/C++ compiler + ## during Nim compilation. + gStateCT.passL.add value proc cAddSearchDir*(dir: string) {.compileTime.} = ## Add directory `dir` to the search path used in calls to @@ -445,8 +404,8 @@ proc cAddSearchDir*(dir: string) {.compileTime.} = import nimterop/paths, os static: cAddSearchDir testsIncludeDir() - doAssert cSearchPath("test.h").existsFile - var dir = interpPath(dir) + doAssert cSearchPath("test.h").fileExists + if dir notin gStateCT.searchDirs: gStateCT.searchDirs.add(dir) @@ -458,19 +417,11 @@ macro cIncludeDir*(dirs: static seq[string], exclude: static[bool] = false): unt ## Set `exclude = true` if the contents of these include directories should ## not be included in the wrapped output. for dir in dirs: - var dir = interpPath(dir) - result = newNimNode(nnkStmtList) - let fullpath = findPath(dir) if fullpath notin gStateCT.includeDirs: gStateCT.includeDirs.add(fullpath) if exclude: gStateCT.exclude.add(fullpath) - let str = &"-I{fullpath.quoteShell}" - result.add quote do: - {.passC: `str`.} - if gStateCT.debug: - gecho result.repr macro cIncludeDir*(dir: static[string], exclude: static[bool] = false): untyped = ## Add an include directory that is forwarded to the C/C++ preprocessor if @@ -501,16 +452,17 @@ proc cAddStdDir*(mode = "c") {.compileTime.} = ## Add the standard `c` [default] or `cpp` include paths to search ## path used in calls to `cSearchPath()`. runnableExamples: - static: cAddStdDir() import os - doAssert cSearchPath("math.h").existsFile + static: + cAddStdDir() + doAssert cSearchPath("math.h").fileExists for inc in getGccPaths(mode): cAddSearchDir inc -macro cCompile*(path: static string, mode = "c", exclude = ""): untyped = +macro cCompile*(path: static string, mode: static[string] = "c", exclude: static[string] = ""): untyped = ## Compile and link C/C++ implementation into resulting binary using `{.compile.}` ## - ## `path` can be a specific file or contain wildcards: + ## `path` can be a specific file or contain `*` wildcard for filename: ## ## .. code-block:: nim ## @@ -532,26 +484,21 @@ macro cCompile*(path: static string, mode = "c", exclude = ""): untyped = ## ## cCompile("path/to/dir", exclude="test2.c") - result = newNimNode(nnkStmtList) - - var - stmt = "" - - proc fcompile(file: string): string = + proc fcompile(file: string) = let (_, fn, ext) = file.splitFile() var ufn = fn uniq = 1 - while ufn in gStateCT.compile: + while ufn in gStateCT.compcache: ufn = fn & $uniq uniq += 1 # - https://github.com/nim-lang/Nim/issues/10299 # - https://github.com/nim-lang/Nim/issues/10486 - gStateCT.compile.add(ufn) + gStateCT.compcache.add(ufn) if fn == ufn: - return "{.compile: \"$#\".}\n" % file.replace("\\", "/") + gStateCT.compile.add file.replace("\\", "/") else: # - https://github.com/nim-lang/Nim/issues/9370 let @@ -559,7 +506,7 @@ macro cCompile*(path: static string, mode = "c", exclude = ""): untyped = tmpFile = file.parentDir() / &"_nimterop_{$hash}_{ufn}{ext}" if not tmpFile.fileExists() or file.getFileDate() > tmpFile.getFileDate(): cpFile(file, tmpFile) - return "{.compile: \"$#\".}\n" % tmpFile.replace("\\", "/") + gStateCT.compile.add tmpFile.replace("\\", "/") # Due to https://github.com/nim-lang/Nim/issues/9863 # cannot use seq[string] for excludes @@ -572,33 +519,37 @@ macro cCompile*(path: static string, mode = "c", exclude = ""): untyped = if excl in file: result = false - proc dcompile(dir, exclude: string, ext=""): string = + proc dcompile(dir, exclude: string, ext="") = let - files = walkDirImpl(dir, ext) + (dir, pat) = + if "*" in dir: + dir.splitPath() + else: + (dir, "") - for f in files: - if f.nBl and f.notExcluded(exclude): - result &= fcompile(f) + for file in walkDirRec(dir): + if ext.nBl or pat.nBl: + let + fext = file.splitFile().ext + if (ext.nBl and fext != ext) or (pat.nBl and fext != pat[1 .. ^1]): + continue + if file.notExcluded(exclude): + fcompile(file) - if path.contains("*") or path.contains("?"): - stmt &= dcompile(path, exclude.strVal()) + if "*" in path: + dcompile(path, exclude) else: let fpath = findPath(path) - if fileExists(fpath) and fpath.notExcluded(exclude.strVal()): - stmt &= fcompile(fpath) + if fileExists(fpath) and fpath.notExcluded(exclude): + fcompile(fpath) elif dirExists(fpath): - if mode.strVal().contains("cpp"): - for i in @["*.cpp", "*.c++", "*.cc", "*.cxx"]: - stmt &= dcompile(fpath, exclude.strVal(), i) + if mode.contains("cpp"): + for i in @[".cpp", ".c++", ".cc", ".cxx"]: + dcompile(fpath, exclude, i) when not defined(Windows): - stmt &= dcompile(fpath, exclude.strVal(), "*.C") + dcompile(fpath, exclude, ".C") else: - stmt &= dcompile(fpath, exclude.strVal(), "*.c") - - result.add stmt.parseStmt() - - if gStateCT.debug: - gecho result.repr + dcompile(fpath, exclude, ".c") macro cImport*(filenames: static seq[string], recurse: static bool = false, dynlib: static string = "", mode: static string = "c", flags: static string = "", nimFile: static string = ""): untyped = @@ -726,7 +677,7 @@ macro c2nImport*(filename: static string, recurse: static bool = false, dynlib: let hFile = getToast(@[fullpath], recurse, dynlib, mode, noNimout = true) - nimFile = if nimFile.nBl: fixRelFile(nimFile) else: hFile.changeFileExt("nim") + nimFile = if nimFile.nBl: fixRelPath(nimFile) else: hFile.changeFileExt("nim") header = "header" & fullpath.splitFile().name.split(seps = {'-', '.'}).join() if not fileExists(nimFile) or gStateCT.nocache or compileOption("forceBuild"): @@ -741,8 +692,29 @@ macro c2nImport*(filename: static string, recurse: static bool = false, dynlib: if flags.nBl: cmd.add &" {flags}" + # Have to create pragmas for c2nim since toast handles this at runtime for i in gStateCT.defines: cmd.add &" --assumedef:{i.quoteShell}" + let str = "-D" & i + result.add quote do: + {.passC: `str`.} + + for i in gStateCT.includeDirs: + let str = &"-I{i.quoteShell}" + result.add quote do: + {.passC: `str`.} + + for i in gStateCT.passC: + result.add quote do: + {.passC: `i`.} + + for i in gStateCT.passL: + result.add quote do: + {.passL: `i`.} + + for i in gStateCT.compile: + result.add quote do: + {.compile: `i`.} let (c2nimout, ret) = execAction(cmd) diff --git a/nimterop/globals.nim b/nimterop/globals.nim index 89e403f..2900272 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -15,6 +15,7 @@ type State* = ref object # Command line arguments to toast - some forwarded from cimport.nim + compile*: seq[string] # `--compile` to create `{.compile.}` entries in generated wrapper convention*: string # `--convention | -C` to change calling convention from cdecl default debug*: bool # `cDebug()` or `--debug | -d` to enable debug mode defines*: seq[string] # Symbols added by `cDefine()` and `--define | -D` for C/C++ preprocessor/compiler @@ -26,6 +27,8 @@ type nim*: string # `--nim` to specify full path to Nim compiler noComments*: bool # `--noComments | -c` to disable rendering comments in wrappers noHeader*: bool # `--noHeader | -H` to skip {.header.} pragma in wrapper + passC*: seq[string] # `--passC` to create `{.passC.}` entries in the generated wrapper + passL*: seq[string] # `--passL` to create `{.passL.}` entries in the generated wrapper past*: bool # `--past | -a` to print tree-sitter AST of code pluginSourcePath*: string # `--pluginSourcePath` specified path to plugin file to compile and load pnim*: bool # `--pnim | -n` to render Nim wrapper for header @@ -77,7 +80,7 @@ type wrapperHeader*: string else: # cimport.nim specific - compile*: seq[string] # `cCompile()` list of files already processed + compcache*: seq[string] # `cCompile()` list of files already processed nocache*: bool # `cDisableCaching()` to disable caching of artifacts overrides*: string # `cOverride()` code which gets added to `cPlugin()` output pluginSource*: string # `cPlugin()` generated code to write to plugin file from diff --git a/nimterop/template.nim b/nimterop/template.nim deleted file mode 100644 index c6e846f..0000000 --- a/nimterop/template.nim +++ /dev/null @@ -1,111 +0,0 @@ -import os, strutils - -import nimterop/[cimport, build, paths] - -# Documentation: -# https://github.com/nimterop/nimterop -# https://nimterop.github.io/nimterop/cimport.html - -const - # Location where any sources should get downloaded. Adjust depending on - # actual location of wrapper file relative to project. - baseDir = currentSourcePath.parentDir()/"build" - - # All files and dirs should be inside to baseDir - srcDir = baseDir/"project" - -static: - # Print generated Nim to output - cDebug() - - # Disable caching so that wrapper is generated every time. Useful during - # development. Remove once wrapper is working as expected. - cDisableCaching() - - # Download C/C++ source code from a git repository - gitPull("https://github.com/user/project", outdir = srcDir, plist = """ -include/*.h -src/*.c -""", checkout = "tag/branch/hash") - - # Download source from the web - zip files are auto extracted - downloadUrl("https://hostname.com/file.h", outdir = srcDir) - - # Run GNU configure on the source - when defined(posix): - configure(srcDir, fileThatShouldGetGenerated, flagsToConfigure) - - # Run cmake on the source - cmake(srcDir/"build", fileThatShouldGetGenerated, flagsToCmake) - - # Run standard file/directory operations with mkDir(), cpFile(), mvFile() - - # Edit file contents if required with readFile(), writeFile() and standard - # string operations - - # Run any other external commands with execAction() - - # Skip any symbols from being wrapped - cSkipSymbol(@["type1", "proc2"]) - -# Manually wrap any symbols since nimterop cannot or incorrectly wraps them -cOverride: - # Standard Nim code to wrap types, consts, procs, etc. - type - symbol = object - -# Specify include directories for gcc and Nim -cIncludeDir(srcDir/"include") - -# Define global symbols -cDefine("SYMBOL", "value") - -# Any global compiler options -{.passC: "flags".} - -# Any global linker options -{.passL: "flags".} - -# Compile in any common source code -cCompile(srcDir/"file.c") - -# Perform OS specific tasks -when defined(Windows): - # Windows specific symbols, options and files - - # Dynamic library to link against - const dynlibFile = - when defined(cpu64): - "xyz64.dll" - else: - "xyz32.dll" -elif defined(posix): - # Common posix symbols, options and files - - when defined(linux): - # Linux specific - const dynlibFile = "libxyz.so(.2|.1|)" - elif defined(osx): - # MacOSX specific - const dynlibFile = "libxyz(.2|.1|).dylib" - else: - static: doAssert false -else: - static: doAssert false - -# Use cPlugin() to make any symbol changes -cPlugin: - import strutils - - # Symbol renaming examples - proc onSymbol*(sym: var Symbol) {.exportc, dynlib.} = - # Get rid of leading and trailing underscores - sym.name = sym.name.strip(chars = {'_'}) - - # Remove prefixes or suffixes from procs - if sym.kind == nskProc and sym.name.contains("SDL_"): - sym.name = sym.name.replace("SDL_", "") - -# Finally import wrapped header file. Recurse if #include files should also -# be wrapped. Set dynlib if binding to dynamic library. -cImport(srcDir/"include/file.h", recurse = true, dynlib="dynlibFile") diff --git a/nimterop/templite.nim b/nimterop/templite.nim deleted file mode 100644 index 7d8eb5b..0000000 --- a/nimterop/templite.nim +++ /dev/null @@ -1,36 +0,0 @@ -import os, strutils - -import nimterop/[cimport, build, paths] - -const - baseDir = currentSourcePath.parentDir()/"build" - - srcDir = baseDir/"project" - -static: - cDebug() - cDisableCaching() - - gitPull("https://github.com/user/project", outdir = srcDir, plist = """ -include/*.h -src/*.c -""", checkout = "tag/branch/hash") - - downloadUrl("https://hostname.com/file.h", outdir = srcDir) - -cIncludeDir(srcDir/"include") - -cDefine("SYMBOL", "value") - -{.passC: "flags".} -{.passL: "flags".} - -cCompile(srcDir/"file.c") - -cPlugin: - import strutils - - proc onSymbol*(sym: var Symbol) {.exportc, dynlib.} = - sym.name = sym.name.strip(chars = {'_'}) - -cImport(srcDir/"include/file.h", recurse = true) diff --git a/nimterop/toast.nim b/nimterop/toast.nim index 20dc79e..8695216 100644 --- a/nimterop/toast.nim +++ b/nimterop/toast.nim @@ -34,6 +34,7 @@ proc process(gState: State, path: string) = # CLI processing with default values proc main( check = false, + compile: seq[string] = @[], convention = "cdecl", debug = false, defines: seq[string] = @[], @@ -46,6 +47,8 @@ proc main( noComments = false, noHeader = false, output = "", + passC: seq[string] = @[], + passL: seq[string] = @[], past = false, pluginSourcePath: string = "", pnim = false, @@ -62,6 +65,7 @@ proc main( # Setup global state with arguments gState = State( + compile: compile, convention: convention, debug: debug, defines: defines, @@ -73,6 +77,8 @@ proc main( nim: nim.sanitizePath, noComments: noComments, noHeader: noHeader, + passC: passC, + passL: passL, past: past, pluginSourcePath: pluginSourcePath, pnim: pnim, @@ -220,6 +226,7 @@ when isMainModule: import cligen dispatch(main, help = { "check": "check generated wrapper with compiler", + "compile": "create {.compile.} entries in generated wrapper", "convention": "calling convention for wrapped procs", "debug": "enable debug output", "defines": "definitions to pass to preprocessor", @@ -232,6 +239,8 @@ when isMainModule: "noComments": "exclude top-level comments from output", "noHeader": "skip {.header.} pragma in wrapper", "output": "file to output content - default: stdout", + "passC": "create {.passC.} entries in generated wrapper", + "passL": "create {.passL.} entries in generated wrapper", "past": "print AST output", "pluginSourcePath": "nim file to build and load as a plugin", "pnim": "print Nim output", diff --git a/nimterop/toastlib/ast2.nim b/nimterop/toastlib/ast2.nim index 083d4b2..7f2b4ad 100644 --- a/nimterop/toastlib/ast2.nim +++ b/nimterop/toastlib/ast2.nim @@ -1881,11 +1881,31 @@ proc setupPragmas(gState: State, root: TSNode, fullpath: string) = gState.pragmaSection.add dynPragma count += 1 - # Add `{.experimental: "codeReordering".} for #206 + # Only if not already done if gState.pragmaSection.len == count: - # Only if not already done + # Add `{.experimental: "codeReordering".} for #206 gState.pragmaSection.add gState.newPragma(root, "experimental", newStrNode(nkStrLit, "codeReordering")) + # Create `{.passC.}` from defines + for define in gState.defines: + gState.pragmaSection.add gState.newPragma(root, "passC", newStrNode(nkStrLit, "-D" & define)) + + # Create `{.passC.}` from include directories + for inc in gState.includeDirs: + gState.pragmaSection.add gState.newPragma(root, "passC", newStrNode(nkStrLit, "-I" & inc.quoteShell)) + + # Create `{.passC.}` from passC + for passC in gState.passC: + gState.pragmaSection.add gState.newPragma(root, "passC", newStrNode(nkStrLit, passC)) + + # Create `{.passL.}` from passL + for passL in gState.passL: + gState.pragmaSection.add gState.newPragma(root, "passL", newStrNode(nkStrLit, passL)) + + # Create `{.compile.}` for specified files + for file in gState.compile: + gState.pragmaSection.add gState.newPragma(root, "compile", newStrNode(nkStrLit, file)) + proc initNim*(gState: State) = # Initialize for parseNim() one time gState.wrapperHeader = "{.push hint[ConvFromXtoItselfNotNeeded]: off.}\n" diff --git a/tests/libssh2.nim b/tests/libssh2.nim index 09343bc..940b2df 100644 --- a/tests/libssh2.nim +++ b/tests/libssh2.nim @@ -22,13 +22,13 @@ when not libssh2Static: when not defined(Windows) and not isDefined(libssh2JBB): proc zlibVersion(): cstring {.importc, dynlib: libssh2LPath.} else: + cPassL("-lpthread") + cImport(libssh2Path, recurse = true, flags = "-c -E_ -F_") when not defined(Windows) and not isDefined(libssh2JBB): proc zlibVersion(): cstring {.importc.} - {.passL: "-lpthread".} - assert libssh2_init(0) == 0 let diff --git a/tests/rsa.nim b/tests/rsa.nim index f5c343c..ee36286 100644 --- a/tests/rsa.nim +++ b/tests/rsa.nim @@ -35,13 +35,13 @@ cPlugin: cOverride: proc OPENSSL_die*(assertion: cstring; file: cstring; line: cint) {.importc.} +cPassL(cryptoLPath) + # Skip comments for https://github.com/tree-sitter/tree-sitter-c/issues/44 cImport(@[ basePath / "rsa.h", basePath / "err.h", ], recurse = true, flags = "-s -c " & FLAGS) -{.passL: cryptoLPath.} - OpensslInit() echo $OPENSSL_VERSION_TEXT diff --git a/tests/tast2.nim b/tests/tast2.nim index 17edfb0..a410de4 100644 --- a/tests/tast2.nim +++ b/tests/tast2.nim @@ -2,7 +2,7 @@ import macros, os, sets, strutils import nimterop/[cimport] -{.passC: "-DNIMTEROP".} +cPassC("-DNIMTEROP") static: # Skip casting on lower nim compilers because diff --git a/tests/tsoloud.nim b/tests/tsoloud.nim index 4d9a28b..d594516 100644 --- a/tests/tsoloud.nim +++ b/tests/tsoloud.nim @@ -24,15 +24,15 @@ cIncludeDir(incl) when defined(osx): cDefine("WITH_COREAUDIO") - {.passL: "-framework CoreAudio -framework AudioToolbox".} + cPassL("-framework CoreAudio -framework AudioToolbox") cCompile(src/"backend/coreaudio/*.cpp") elif defined(Linux): - {.passL: "-lpthread".} + cPassL("-lpthread") cDefine("WITH_OSS") cCompile(src/"backend/oss/*.cpp") elif defined(Windows): - {.passC: "-msse".} - {.passL: "-lwinmm".} + cPassC("-msse") + cPassL("-lwinmm") cDefine("WITH_WINMM") cCompile(src/"backend/winmm/*.cpp") else: diff --git a/tests/zlib.nim b/tests/zlib.nim index 53384c3..d4744eb 100644 --- a/tests/zlib.nim +++ b/tests/zlib.nim @@ -65,12 +65,12 @@ when zlibGit or zlibDL: when dirExists(baseDir / "buildcache"): cIncludeDir(baseDir / "buildcache") -when not zlibStatic: +when not isDefined(zlibStatic): cImport(zlibPath, recurse = true, dynlib = "zlibLPath", flags = FLAGS) else: + when isDefined(zlibJBB): + cPassL("-no-pie") + cImport(zlibPath, recurse = true, flags = FLAGS) -echo "zlib version = " & $zlibVersion() - -when isDefined(zlibJBB) and isDefined(zlibStatic): - {.passL: "-no-pie".} +echo "zlib version = " & $zlibVersion() \ No newline at end of file From aa813bdf3212f22642ec81d79f712911d9df4226 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 14 Jul 2020 20:20:42 -0500 Subject: [PATCH 559/593] Forward getHeader passL --- nimterop/build/getheader.nim | 54 +++++++++++++++++------------------- 1 file changed, 26 insertions(+), 28 deletions(-) diff --git a/nimterop/build/getheader.nim b/nimterop/build/getheader.nim index d5b398a..dbd965e 100644 --- a/nimterop/build/getheader.nim +++ b/nimterop/build/getheader.nim @@ -33,7 +33,7 @@ macro setDefines*(defs: static openArray[string]): untyped = for def in defs: let nv = def.strip().split("=", maxsplit = 1) - if nv.len != 0: + if nv.nBl: let n = nv[0] v = @@ -70,33 +70,33 @@ proc getDynlibExt(): string = proc getStdPath(header, mode: string): string = for inc in getGccPaths(mode): result = findFile(header, inc, recurse = false, first = true) - if result.len != 0: + if result.nBl: break proc getStdLibPath(lname, mode: string): string = for lib in getGccLibPaths(mode): result = findFile(lname, lib, recurse = false, first = true, regex = true) - if result.len != 0: + if result.nBl: break proc getGitPath(header, url, outdir, version: string): string = - doAssert url.len != 0, "No git url setup for " & header - doAssert findExe("git").len != 0, "git executable missing" + doAssert url.nBl, "No git url setup for " & header + doAssert findExe("git").nBl, "git executable missing" gitPull(url, outdir, checkout = version) result = findFile(header, outdir) proc getDlPath(header, url, outdir, version: string): string = - doAssert url.len != 0, "No download url setup for " & header + doAssert url.nBl, "No download url setup for " & header var dlurl = url if "$#" in url or "$1" in url: - doAssert version.len != 0, "Need version for download url" + doAssert version.nBl, "Need version for download url" dlurl = url % version else: - doAssert version.len == 0, "Download url does not contain version" + doAssert version.Bl, "Download url does not contain version" downloadUrl(dlurl, outdir) @@ -107,13 +107,13 @@ proc getDlPath(header, url, outdir, version: string): string = dirname = "" break elif kind == pcDir: - if dirname.len == 0: + if dirname.Bl: dirname = path else: dirname = "" break - if dirname.len != 0: + if dirname.nBl: for kind, path in walkDir(outdir / dirname, relative = true): mvFile(outdir / dirname / path, outdir / path) @@ -124,9 +124,9 @@ proc getConanPath(header, uri, outdir, version: string, shared: bool): string = uri = uri if "$#" in uri or "$1" in uri: - doAssert version.len != 0, "Need version for Conan.io uri: " & uri + doAssert version.nBl, "Need version for Conan.io uri: " & uri uri = uri % version - elif version.len != 0: + elif version.nBl: uri = uri & "/" & version let @@ -145,12 +145,12 @@ proc getJBBPath(header, uri, flags, outdir, version: string): string = let spl = uri.split('/', 1) name = spl[0] - hasVersion = version.len != 0 + hasVersion = version.nBl var ver = if spl.len == 2: spl[1] else: "" - if ver.len != 0: + if ver.nBl: if "$#" in ver or "$1" in ver: doAssert hasVersion, "Need version for BinaryBuilder.org uri: " & uri ver = ver % version @@ -187,7 +187,7 @@ proc getJBBLDeps(outdir: string, shared: bool): seq[string] = result = pkg.getJBBLDeps(outdir, shared) proc getLocalPath(header, outdir: string): string = - if outdir.len != 0: + if outdir.nBl: result = findFile(header, outdir) proc buildLibrary(lname, outdir, conFlags, cmakeFlags, makeFlags: string, buildTypes: openArray[BuildType]): string = @@ -195,7 +195,7 @@ proc buildLibrary(lname, outdir, conFlags, cmakeFlags, makeFlags: string, buildT lpath = findFile(lname, outdir, regex = true) makePath = outdir - if lpath.len != 0: + if lpath.nBl: return lpath var buildStatus: BuildStatus @@ -275,7 +275,7 @@ macro getHeader*( ## ## The header path is stored in `const xxxPath` and can be used in a `cImport()` call ## in the calling wrapper. The dynamic library path is stored in `const xxxLPath` and can - ## be used for the `dynlib` parameter (within quotes) or with `{.passL.}`. Any dependency + ## be used for the `dynlib` parameter (within quotes) or with `cPassL()`. Any dependency ## libraries downloaded by `Conan` or `JBB` are returned in `const xxxLDeps` as a seq[string]. ## ## `libdir` can be used to instruct `getHeader()` to copy shared libraries and their @@ -285,7 +285,7 @@ macro getHeader*( ## reflect this new location. `libdir` is ignored for `Std` mode. ## ## `-d:xxxStatic` can be specified to statically link with the library instead. This - ## will automatically add a `{.passL.}` call to the static library for convenience. Note + ## will automatically add a `cPassL()` call to the static library for convenience. Note ## that `-d:xxxConan` and `-d:xxxJBB` download all dependency libs as well and the ## `xxxLPath` will include paths to all of them separated by space in the right order for ## linking. @@ -335,8 +335,8 @@ macro getHeader*( name = origname.split(seps = AllChars-Letters-Digits).join() # Default to origname if not specified - conanuri = if conanuri.len != 0: conanuri else: origname - jbburi = if jbburi.len != 0: jbburi else: origname + conanuri = if conanuri.nBl: conanuri else: origname + jbburi = if jbburi.nBl: jbburi else: origname # -d:xxx for this header stdStr = name & "Std" @@ -382,10 +382,10 @@ macro getHeader*( "" mode = getCompilerMode(header) - libdir = if libdir.len != 0: libdir else: getOutDir() + libdir = if libdir.nBl: libdir else: getOutDir() # Use alternate library names if specified for regex search - if altNames.len != 0: + if altNames.nBl: lre = lre % ("(" & altNames.replace(",", "|") & ")") else: lre = lre % origname @@ -491,14 +491,12 @@ macro getHeader*( `ldeps`* = ldeps # Automatically link with static library and dependencies - {.passL: `lpath`.} - if `ldeps`.len != 0: - {.passL: `ldeps`.join(" ").} - static: gecho "# Including library " & lpath - if `ldeps`.len != 0: - gecho "# Including dependencies " & `ldeps`.join(" ") + gStateCT.passL.add lpath + if ldeps.len != 0: + gecho "# Including dependencies " & ldeps.join(" ") + gStateCT.passL.add ldeps.join(" ") else: const `lpath`* = when not useStd: `libdir` / lpath.extractFilename() else: lpath From 44f335c87ffdf153e8e1cad4d7f59f638f19c76b Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 15 Jul 2020 09:08:10 -0500 Subject: [PATCH 560/593] Doc updates --- CHANGES.md | 14 ++++++++++++-- README.md | 6 +++++- nimterop/cimport.nim | 12 ++++++++++++ 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 91cecac..8609474 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -15,7 +15,7 @@ Refer to the documentation for `getHeader()` for details on how to use this new See the full list of changes here: -https://github.com/nimterop/nimterop/compare/v0.5.9...v0.6.3 +https://github.com/nimterop/nimterop/compare/v0.5.9...v0.6.5 ### Breaking changes @@ -27,6 +27,8 @@ https://github.com/nimterop/nimterop/compare/v0.5.9...v0.6.3 - Nameless enum values are no longer typed to the made-up enum type name, they are instead typed as `cint` to match the underlying type. This allows using such enums without having to depend on the made-up name which could change if enum ordering changes upstream. [#236][i236] (since v0.6.1) +- Static libraries installed and linked with `getHeader()` now have their `{.passL.}` pragmas forwarded to the generated wrapper. This might lead to link errors in existing wrappers if other dependencies are specified with `{.passL.}` calls and the order of linking is wrong. This can be fixed by changing such explicit `{.passL.}` calls with `cPassL()` which will forward the link call to the generated wrapper as well. (since v0.6.5) + ### New functionality - `getHeader()` now detects and links against `.lib` files as part of enabling Conan.io. Not all `.lib` files are compatible with MinGW as already stated above but for those that work, this is a required capability. @@ -43,6 +45,12 @@ https://github.com/nimterop/nimterop/compare/v0.5.9...v0.6.3 - It is now possible to exclude the contents of specific files or entire directories from the wrapped output using `--exclude | -X` with `toast` or `cExclude()` from a wrapper. This might be required when a header uses `#include` to pull in external dependencies. E.g. `sciter` has a `#include ` which pulls in the entire GTK ecosystem which is needed for successful preprocessing but we do not want to include those headers in the wrapped output when using `--recurse | -r`. (since v0.6.4) +- All `cDefine()`, `cIncludeDir()` and `cCompile()` calls now forward relevant pragmas into the generated wrapper further enabling standalone wrappers. [#239][i239] + +- Added `cPassC()` and `cPassL()` to forward C/C++ compilation pragmas into the generated wrapper. (since v0.6.5) + +- Added `--compile`, `--passC` and `--passL` flags to `toast` to enable the previous two improvements. (since v0.6.5) + ### Other improvements - Generated wrappers no longer depend on nimterop being present - no more `import nimterop/types`. Supporting code is directly included in the wrapper output and only when required. E.g. enum macro is only included if wrapper contains enums. [#125][i125] (since v0.6.1) @@ -51,6 +59,7 @@ https://github.com/nimterop/nimterop/compare/v0.5.9...v0.6.3 - `cIncludeDir()` can now accept a `seq[string]` of directories and an optional `exclude` param which sets those include directories to not be included in the wrapped output. (since v0.6.4) +- `cDefine()` can now accept a `seq[string]` of values. (since v0.6.5) ## Version 0.5.0 @@ -140,4 +149,5 @@ https://github.com/nimterop/nimterop/compare/v0.4.4...v0.5.4 [i197]: https://github.com/nimterop/nimterop/issues/197 [i200]: https://github.com/nimterop/nimterop/issues/200 [i236]: https://github.com/nimterop/nimterop/issues/236 -[i237]: https://github.com/nimterop/nimterop/issues/237 \ No newline at end of file +[i237]: https://github.com/nimterop/nimterop/issues/237 +[i239]: https://github.com/nimterop/nimterop/issues/239 \ No newline at end of file diff --git a/README.md b/README.md index cda3b5e..4770563 100644 --- a/README.md +++ b/README.md @@ -218,10 +218,12 @@ Options: -h, --help print this cligen-erated help --help-syntax advanced: prepend,plurals,.. -k, --check bool false check generated wrapper with compiler + --compile= strings {} create {.compile.} entries in generated wrapper -C=, --convention= string "cdecl" calling convention for wrapped procs -d, --debug bool false enable debug output -D=, --defines= strings {} definitions to pass to preprocessor - -l=, --dynlib= string "" {.dynlib.} pragma to import symbols - Nim const string or file path + -l=, --dynlib= string "" {.dynlib.} pragma to import symbols - Nim const string or + file path -X=, --exclude= strings {} files or directories to exclude from the wrapped output -f=, --feature= Features {} flags to enable experimental features -I=, --includeDirs= strings {} include directory to pass to preprocessor @@ -230,6 +232,8 @@ Options: -c, --noComments bool false exclude top-level comments from output -H, --noHeader bool false skip {.header.} pragma in wrapper -o=, --output= string "" file to output content - default: stdout + --passC= strings {} create {.passC.} entries in generated wrapper + --passL= strings {} create {.passL.} entries in generated wrapper -a, --past bool false print AST output --pluginSourcePath= string "" nim file to build and load as a plugin -n, --pnim bool false print Nim output diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index 6120cb5..c82f884 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -368,6 +368,8 @@ macro cDefine*(name: static[string], val: static[string] = ""): untyped = ## `#define` an identifer that is forwarded to the C/C++ preprocessor if ## called within `cImport()` or `c2nImport()` as well as to the C/C++ ## compiler during Nim compilation using `{.passC: "-DXXX".}` + ## + ## This needs to be called before `cImport()` to take effect. var str = name if val.nBl: str &= &"={val.quoteShell}" @@ -379,6 +381,8 @@ macro cDefine*(values: static seq[string]): untyped = ## `#define` multiple identifers that are forwarded to the C/C++ preprocessor ## if called within `cImport()` or `c2nImport()` as well as to the C/C++ ## compiler during Nim compilation using `{.passC: "-DXXX".}` + ## + ## This needs to be called before `cImport()` to take effect. for value in values: let spl = value.split("=", maxsplit = 1) @@ -390,11 +394,15 @@ macro cDefine*(values: static seq[string]): untyped = macro cPassC*(value: static string): untyped = ## Create a `{.passC.}` entry that gets forwarded to the C/C++ compiler ## during Nim compilation. + ## + ## This needs to be called before `cImport()` to take effect. gStateCT.passC.add value macro cPassL*(value: static string): untyped = ## Create a `{.passL.}` entry that gets forwarded to the C/C++ compiler ## during Nim compilation. + ## + ## This needs to be called before `cImport()` to take effect. gStateCT.passL.add value proc cAddSearchDir*(dir: string) {.compileTime.} = @@ -416,6 +424,8 @@ macro cIncludeDir*(dirs: static seq[string], exclude: static[bool] = false): unt ## ## Set `exclude = true` if the contents of these include directories should ## not be included in the wrapped output. + ## + ## This needs to be called before `cImport()` to take effect. for dir in dirs: let fullpath = findPath(dir) if fullpath notin gStateCT.includeDirs: @@ -430,6 +440,8 @@ macro cIncludeDir*(dir: static[string], exclude: static[bool] = false): untyped ## ## Set `exclude = true` if the contents of this include directory should ## not be included in the wrapped output. + ## + ## This needs to be called before `cImport()` to take effect. return quote do: cIncludeDir(@[`dir`], `exclude` == 1) From e61dc54a898a395902205b5794e09ece0e9b35ba Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 15 Jul 2020 11:33:26 -0500 Subject: [PATCH 561/593] renderPragma, cleanup --- CHANGES.md | 5 +- README.md | 4 +- nimterop/cimport.nim | 548 +++++++++++++++++++++++-------------------- 3 files changed, 294 insertions(+), 263 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 8609474..e7e9213 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -47,10 +47,12 @@ https://github.com/nimterop/nimterop/compare/v0.5.9...v0.6.5 - All `cDefine()`, `cIncludeDir()` and `cCompile()` calls now forward relevant pragmas into the generated wrapper further enabling standalone wrappers. [#239][i239] -- Added `cPassC()` and `cPassL()` to forward C/C++ compilation pragmas into the generated wrapper. (since v0.6.5) +- Added `cPassC()` and `cPassL()` to forward C/C++ compilation pragmas into the generated wrapper. These should be used in place of `{.passC.}` and `{.passL.}` and need to be called before `cImport()` to take effect. (since v0.6.5) - Added `--compile`, `--passC` and `--passL` flags to `toast` to enable the previous two improvements. (since v0.6.5) +- Added `renderPragma()` to create pragmas inline in case `cImport()` is not being used. (since v0.6.5) + ### Other improvements - Generated wrappers no longer depend on nimterop being present - no more `import nimterop/types`. Supporting code is directly included in the wrapper output and only when required. E.g. enum macro is only included if wrapper contains enums. [#125][i125] (since v0.6.1) @@ -61,6 +63,7 @@ https://github.com/nimterop/nimterop/compare/v0.5.9...v0.6.5 - `cDefine()` can now accept a `seq[string]` of values. (since v0.6.5) + ## Version 0.5.0 This release introduces a new backend for wrapper generation dubbed `ast2` that leverages the Nim compiler AST and renderer. The new design simplifies feature development and already includes all the functionality of the legacy algorithm plus fixes for several open issues. diff --git a/README.md b/README.md index 4770563..d652d0d 100644 --- a/README.md +++ b/README.md @@ -97,7 +97,7 @@ Flags can be specified to these tools via `getHeader()` or directly via the unde If `-d:headerStatic` is specified, `getHeader()` will return the static library path in `headerLPath`. The wrapper writer can check for this and call `cImport()` accordingly as in the example above. If `-d:headerStatic` is omitted, the dynamic library is returned in `headerLPath`. -All dependency libraries (supported by Conan and JBB) will be returned in `headerLDeps`. Static libraries and dependencies are automatically linked using `{.passL.}`. Conan shared libs include all dependencies whereas JBB shared libs expect the required dependencies to be in the same location or in `LD_LIBRARY_PATH`. +All dependency libraries (supported by Conan and JBB) will be returned in `headerLDeps`. Static libraries and dependencies are automatically linked using `cPassL()`. Conan shared libs include all dependencies whereas JBB shared libs expect the required dependencies to be in the same location or in `LD_LIBRARY_PATH`. `getHeader()` searches for libraries based on the header name by default: - `libheader.so` or `libheader.a` on Linux @@ -171,7 +171,7 @@ Nim provides some flexibility when it comes to using C/C++ libraries. In order t For types, `{.header: "header.h".}` informs Nim that `header.h` has the symbol and to `#include "header.h"` in the generated code. However, types can be mostly recreated in pure Nim so it is also possible to omit both `{.importc.}` and `{.header}` and it will work just fine except with a different name in the generated C code. This allows the user to compile the wrapper without requiring `header.h` to be present. -For functions, `{.header.}` works the same as types and can be omitted if preferred. The `{.importc.}` pragma is still required, unlike types since functions need to be linked to the implementation in the library. The user will need to provide this information at link time with `{.passL.}` and linking to a library with `-lheader` or `path/to/libheader.a`. It is also possible to just use `cCompile()` or `{.compile.}` to compile some C source files which contain the implementation. +For functions, `{.header.}` works the same as types and can be omitted if preferred. The `{.importc.}` pragma is still required, unlike types since functions need to be linked to the implementation in the library. The user will need to provide this information at link time with `cPassL()` and linking to a library with `-lheader` or `path/to/libheader.a`. It is also possible to just use `cCompile()` or `{.compile.}` to compile some C source files which contain the implementation. While `{.header.}` can be omitted for convenience, it does prevent wrapping of `static inline` functions as well as type checking of the wrapper ABI with `-d:checkAbi` at compile time. Further, anonymous nested structs/unions within unions will be rendered incorrectly by Nim since it is unaware of the true memory structure of the type. The user will need to choose based on the library in question. diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index c82f884..88aed1a 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -64,12 +64,15 @@ proc getToast(fullpaths: seq[string], recurse: bool = false, dynlib: string = "" for i in gStateCT.passC: cmd.add &" --passC+={i.quoteShell}" + gStateCT.passC = @[] for i in gStateCT.passL: cmd.add &" --passL+={i.quoteShell}" + gStateCT.passL = @[] for i in gStateCT.compile: cmd.add &" --compile+={i.sanitizePath}" + gStateCT.compile = @[] if not noNimout: cmd.add &" --pnim" @@ -142,6 +145,288 @@ proc getToast(fullpaths: seq[string], recurse: bool = false, dynlib: string = "" writeFile(cacheFile, "") +proc cDebug*() {.compileTime.} = + ## Enable debug messages and display the generated Nim code + gStateCT.debug = true + +proc cDisableCaching*() {.compileTime.} = + ## Disable caching of generated Nim code - useful during wrapper development + ## + ## If files included by header being processed by + ## `cImport()` change and affect the generated content, they will be ignored + ## and the cached value will continue to be used . Use `cDisableCaching()` to + ## avoid this scenario during development. + ## + ## `nim -f` can also be used to flush the cached content. + gStateCT.nocache = true + +proc cSearchPath*(path: string): string {.compileTime.} = + ## Get full path to file or directory `path` in search path configured + ## using `cAddSearchDir()` and `cAddStdDir()`. + ## + ## This can be used to locate files or directories that can be passed onto + ## `cCompile()`, `cIncludeDir()` and `cImport()`. + result = findPath(path, fail = false) + if result.Bl: + var found = false + for inc in gStateCT.searchDirs: + result = findPath(inc / path, fail = false) + if result.nBl: + found = true + break + doAssert found, "File or directory not found: " & path & + " gStateCT.searchDirs: " & $gStateCT.searchDirs + +proc cAddSearchDir*(dir: string) {.compileTime.} = + ## Add directory `dir` to the search path used in calls to + ## `cSearchPath()`. + runnableExamples: + import nimterop/paths, os + static: + cAddSearchDir testsIncludeDir() + doAssert cSearchPath("test.h").fileExists + + if dir notin gStateCT.searchDirs: + gStateCT.searchDirs.add(dir) + +proc cAddStdDir*(mode = "c") {.compileTime.} = + ## Add the standard `c` [default] or `cpp` include paths to search + ## path used in calls to `cSearchPath()`. + runnableExamples: + import os + static: + cAddStdDir() + doAssert cSearchPath("math.h").fileExists + for inc in getGccPaths(mode): + cAddSearchDir inc + +macro cDefine*(name: static[string], val: static[string] = ""): untyped = + ## `#define` an identifer that is forwarded to the C/C++ preprocessor if + ## called within `cImport()` or `c2nImport()` as well as to the C/C++ + ## compiler during Nim compilation using `{.passC: "-DXXX".}` + ## + ## This needs to be called before `cImport()` to take effect. + var str = name + if val.nBl: + str &= &"={val.quoteShell}" + + if str notin gStateCT.defines: + gStateCT.defines.add(str) + +macro cDefine*(values: static seq[string]): untyped = + ## `#define` multiple identifers that are forwarded to the C/C++ preprocessor + ## if called within `cImport()` or `c2nImport()` as well as to the C/C++ + ## compiler during Nim compilation using `{.passC: "-DXXX".}` + ## + ## This needs to be called before `cImport()` to take effect. + for value in values: + let + spl = value.split("=", maxsplit = 1) + name = spl[0] + val = if spl.len == 2: spl[1] else: "" + discard quote do: + cDefine(`name`, `val`) + +macro cIncludeDir*(dirs: static seq[string], exclude: static[bool] = false): untyped = + ## Add include directories that are forwarded to the C/C++ preprocessor if + ## called within `cImport()` or `c2nImport()` as well as to the C/C++ + ## compiler during Nim compilation using `{.passC: "-IXXX".}`. + ## + ## Set `exclude = true` if the contents of these include directories should + ## not be included in the wrapped output. + ## + ## This needs to be called before `cImport()` to take effect. + for dir in dirs: + let fullpath = findPath(dir) + if fullpath notin gStateCT.includeDirs: + gStateCT.includeDirs.add(fullpath) + if exclude: + gStateCT.exclude.add(fullpath) + +macro cIncludeDir*(dir: static[string], exclude: static[bool] = false): untyped = + ## Add an include directory that is forwarded to the C/C++ preprocessor if + ## called within `cImport()` or `c2nImport()` as well as to the C/C++ + ## compiler during Nim compilation using `{.passC: "-IXXX".}`. + ## + ## Set `exclude = true` if the contents of this include directory should + ## not be included in the wrapped output. + ## + ## This needs to be called before `cImport()` to take effect. + return quote do: + cIncludeDir(@[`dir`], `exclude` == 1) + +macro cExclude*(paths: static seq[string]): untyped = + ## Exclude specified paths - files or directories from the wrapped output + ## + ## Full path to file or directory is required. + result = newNimNode(nnkStmtList) + for path in paths: + gStateCT.exclude.add path + +macro cExclude*(path: static string): untyped = + ## Exclude specified path - file or directory from the wrapped output. + ## + ## Full path to file or directory is required. + return quote do: + cExclude(@[`path`]) + +macro cPassC*(value: static string): untyped = + ## Create a `{.passC.}` entry that gets forwarded to the C/C++ compiler + ## during Nim compilation. + ## + ## `cPassC()` needs to be called before `cImport()` to take effect and gets + ## consumed and reset so as not to impact subsequent `cImport()` calls. + gStateCT.passC.add value + +macro cPassL*(value: static string): untyped = + ## Create a `{.passL.}` entry that gets forwarded to the C/C++ compiler + ## during Nim compilation. + ## + ## `cPassL()` needs to be called before `cImport()` to take effect and gets + ## consumed and reset so as not to impact subsequent `cImport()` calls. + gStateCT.passL.add value + +macro cCompile*(path: static string, mode: static[string] = "c", exclude: static[string] = ""): untyped = + ## Compile and link C/C++ implementation into resulting binary using `{.compile.}` + ## + ## `path` can be a specific file or contain `*` wildcard for filename: + ## + ## .. code-block:: nim + ## + ## cCompile("file.c") + ## cCompile("path/to/*.c") + ## + ## `mode` recursively searches for code files in `path`. + ## + ## `c` searches for `*.c` whereas `cpp` searches for `*.C *.cpp *.c++ *.cc *.cxx` + ## + ## .. code-block:: nim + ## + ## cCompile("path/to/dir", "cpp") + ## + ## `exclude` can be used to exclude files by partial string match. Comma separated to + ## specify multiple exclude strings + ## + ## .. code-block:: nim + ## + ## cCompile("path/to/dir", exclude="test2.c") + ## + ## `cCompile()` needs to be called before `cImport()` to take effect and gets + ## consumed and reset so as not to impact subsequent `cImport()` calls. + + proc fcompile(file: string) = + let + (_, fn, ext) = file.splitFile() + var + ufn = fn + uniq = 1 + while ufn in gStateCT.compcache: + ufn = fn & $uniq + uniq += 1 + + # - https://github.com/nim-lang/Nim/issues/10299 + # - https://github.com/nim-lang/Nim/issues/10486 + gStateCT.compcache.add(ufn) + if fn == ufn: + gStateCT.compile.add file.replace("\\", "/") + else: + # - https://github.com/nim-lang/Nim/issues/9370 + let + hash = file.hash().abs() + tmpFile = file.parentDir() / &"_nimterop_{$hash}_{ufn}{ext}" + if not tmpFile.fileExists() or file.getFileDate() > tmpFile.getFileDate(): + cpFile(file, tmpFile) + gStateCT.compile.add tmpFile.replace("\\", "/") + + # Due to https://github.com/nim-lang/Nim/issues/9863 + # cannot use seq[string] for excludes + proc notExcluded(file, exclude: string): bool = + result = true + if "_nimterop_" in file: + result = false + elif exclude.nBl: + for excl in exclude.split(","): + if excl in file: + result = false + + proc dcompile(dir, exclude: string, ext="") = + let + (dir, pat) = + if "*" in dir: + dir.splitPath() + else: + (dir, "") + + for file in walkDirRec(dir): + if ext.nBl or pat.nBl: + let + fext = file.splitFile().ext + if (ext.nBl and fext != ext) or (pat.nBl and fext != pat[1 .. ^1]): + continue + if file.notExcluded(exclude): + fcompile(file) + + if "*" in path: + dcompile(path, exclude) + else: + let fpath = findPath(path) + if fileExists(fpath) and fpath.notExcluded(exclude): + fcompile(fpath) + elif dirExists(fpath): + if mode.contains("cpp"): + for i in @[".cpp", ".c++", ".cc", ".cxx"]: + dcompile(fpath, exclude, i) + when not defined(Windows): + dcompile(fpath, exclude, ".C") + else: + dcompile(fpath, exclude, ".c") + +macro renderPragma*(): untyped = + ## All `cDefine()`, `cIncludeDir()`, `cCompile()`, `cPassC()` and `cPassL()` + ## content typically gets forwarded via `cImport()` to the generated wrapper to be + ## rendered as part of the output so as to enable standalone wrappers. If `cImport()` + ## is not being used for some reason, `renderPragma()` can create these pragmas + ## in the nimterop wrapper itself. A good example is using `getHeader()` without + ## calling `cImport()`. + ## + ## `c2nImport()` already uses this macro so there's no need to use it when typically + ## wrapping headers. + result = newNimNode(nnkStmtList) + + for i in gStateCT.defines: + let str = "-D" & i + result.add quote do: + {.passC: `str`.} + + for i in gStateCT.includeDirs: + let str = &"-I{i.quoteShell}" + result.add quote do: + {.passC: `str`.} + + for i in gStateCT.passC: + result.add quote do: + {.passC: `i`.} + gStateCT.passC = @[] + + for i in gStateCT.passL: + result.add quote do: + {.passL: `i`.} + gStateCT.passL = @[] + + for i in gStateCT.compile: + result.add quote do: + {.compile: `i`.} + gStateCT.compile = @[] + +proc cSkipSymbol*(skips: seq[string]) {.compileTime.} = + ## Similar to `cOverride()`, this macro allows filtering out symbols not of + ## interest from the generated output. + ## + ## `cSkipSymbol()` only affects calls to `cImport()` that follow it. + runnableExamples: + static: cSkipSymbol @["proc1", "Type2"] + gStateCT.symOverride.add skips + macro cOverride*(body): untyped = ## When the wrapper code generated by nimterop is missing certain symbols or not ## accurate, it may be required to hand wrap them. Define them in a `cOverride()` @@ -234,15 +519,6 @@ proc onSymbolOverride*(sym: var Symbol) {.exportc, dynlib.} = if names.nBl: decho "Overriding " & names.join(" ") -proc cSkipSymbol*(skips: seq[string]) {.compileTime.} = - ## Similar to `cOverride()`, this macro allows filtering out symbols not of - ## interest from the generated output. - ## - ## `cSkipSymbol()` only affects calls to `cImport()` that follow it. - runnableExamples: - static: cSkipSymbol @["proc1", "Type2"] - gStateCT.symOverride.add skips - proc cPluginHelper(body: string, imports = "import macros, nimterop/plugin\n\n") = gStateCT.pluginSource = body @@ -332,237 +608,6 @@ macro cPluginPath*(path: static[string]): untyped = doAssert fileExists(path), "Plugin file not found: " & path cPluginHelper(readFile(path), imports = "") -proc cSearchPath*(path: string): string {.compileTime.} = - ## Get full path to file or directory `path` in search path configured - ## using `cAddSearchDir()` and `cAddStdDir()`. - ## - ## This can be used to locate files or directories that can be passed onto - ## `cCompile()`, `cIncludeDir()` and `cImport()`. - result = findPath(path, fail = false) - if result.Bl: - var found = false - for inc in gStateCT.searchDirs: - result = findPath(inc / path, fail = false) - if result.nBl: - found = true - break - doAssert found, "File or directory not found: " & path & - " gStateCT.searchDirs: " & $gStateCT.searchDirs - -proc cDebug*() {.compileTime.} = - ## Enable debug messages and display the generated Nim code - gStateCT.debug = true - -proc cDisableCaching*() {.compileTime.} = - ## Disable caching of generated Nim code - useful during wrapper development - ## - ## If files included by header being processed by - ## `cImport()` change and affect the generated content, they will be ignored - ## and the cached value will continue to be used . Use `cDisableCaching()` to - ## avoid this scenario during development. - ## - ## `nim -f` can also be used to flush the cached content. - gStateCT.nocache = true - -macro cDefine*(name: static[string], val: static[string] = ""): untyped = - ## `#define` an identifer that is forwarded to the C/C++ preprocessor if - ## called within `cImport()` or `c2nImport()` as well as to the C/C++ - ## compiler during Nim compilation using `{.passC: "-DXXX".}` - ## - ## This needs to be called before `cImport()` to take effect. - var str = name - if val.nBl: - str &= &"={val.quoteShell}" - - if str notin gStateCT.defines: - gStateCT.defines.add(str) - -macro cDefine*(values: static seq[string]): untyped = - ## `#define` multiple identifers that are forwarded to the C/C++ preprocessor - ## if called within `cImport()` or `c2nImport()` as well as to the C/C++ - ## compiler during Nim compilation using `{.passC: "-DXXX".}` - ## - ## This needs to be called before `cImport()` to take effect. - for value in values: - let - spl = value.split("=", maxsplit = 1) - name = spl[0] - val = if spl.len == 2: spl[1] else: "" - discard quote do: - cDefine(`name`, `val`) - -macro cPassC*(value: static string): untyped = - ## Create a `{.passC.}` entry that gets forwarded to the C/C++ compiler - ## during Nim compilation. - ## - ## This needs to be called before `cImport()` to take effect. - gStateCT.passC.add value - -macro cPassL*(value: static string): untyped = - ## Create a `{.passL.}` entry that gets forwarded to the C/C++ compiler - ## during Nim compilation. - ## - ## This needs to be called before `cImport()` to take effect. - gStateCT.passL.add value - -proc cAddSearchDir*(dir: string) {.compileTime.} = - ## Add directory `dir` to the search path used in calls to - ## `cSearchPath()`. - runnableExamples: - import nimterop/paths, os - static: - cAddSearchDir testsIncludeDir() - doAssert cSearchPath("test.h").fileExists - - if dir notin gStateCT.searchDirs: - gStateCT.searchDirs.add(dir) - -macro cIncludeDir*(dirs: static seq[string], exclude: static[bool] = false): untyped = - ## Add include directories that are forwarded to the C/C++ preprocessor if - ## called within `cImport()` or `c2nImport()` as well as to the C/C++ - ## compiler during Nim compilation using `{.passC: "-IXXX".}`. - ## - ## Set `exclude = true` if the contents of these include directories should - ## not be included in the wrapped output. - ## - ## This needs to be called before `cImport()` to take effect. - for dir in dirs: - let fullpath = findPath(dir) - if fullpath notin gStateCT.includeDirs: - gStateCT.includeDirs.add(fullpath) - if exclude: - gStateCT.exclude.add(fullpath) - -macro cIncludeDir*(dir: static[string], exclude: static[bool] = false): untyped = - ## Add an include directory that is forwarded to the C/C++ preprocessor if - ## called within `cImport()` or `c2nImport()` as well as to the C/C++ - ## compiler during Nim compilation using `{.passC: "-IXXX".}`. - ## - ## Set `exclude = true` if the contents of this include directory should - ## not be included in the wrapped output. - ## - ## This needs to be called before `cImport()` to take effect. - return quote do: - cIncludeDir(@[`dir`], `exclude` == 1) - -macro cExclude*(paths: static seq[string]): untyped = - ## Exclude specified paths - files or directories from the wrapped output - ## - ## Full path to file or directory is required. - result = newNimNode(nnkStmtList) - for path in paths: - gStateCT.exclude.add path - -macro cExclude*(path: static string): untyped = - ## Exclude specified path - file or directory from the wrapped output. - ## - ## Full path to file or directory is required. - return quote do: - cExclude(@[`path`]) - -proc cAddStdDir*(mode = "c") {.compileTime.} = - ## Add the standard `c` [default] or `cpp` include paths to search - ## path used in calls to `cSearchPath()`. - runnableExamples: - import os - static: - cAddStdDir() - doAssert cSearchPath("math.h").fileExists - for inc in getGccPaths(mode): - cAddSearchDir inc - -macro cCompile*(path: static string, mode: static[string] = "c", exclude: static[string] = ""): untyped = - ## Compile and link C/C++ implementation into resulting binary using `{.compile.}` - ## - ## `path` can be a specific file or contain `*` wildcard for filename: - ## - ## .. code-block:: nim - ## - ## cCompile("file.c") - ## cCompile("path/to/*.c") - ## - ## `mode` recursively searches for code files in `path`. - ## - ## `c` searches for `*.c` whereas `cpp` searches for `*.C *.cpp *.c++ *.cc *.cxx` - ## - ## .. code-block:: nim - ## - ## cCompile("path/to/dir", "cpp") - ## - ## `exclude` can be used to exclude files by partial string match. Comma separated to - ## specify multiple exclude strings - ## - ## .. code-block:: nim - ## - ## cCompile("path/to/dir", exclude="test2.c") - - proc fcompile(file: string) = - let - (_, fn, ext) = file.splitFile() - var - ufn = fn - uniq = 1 - while ufn in gStateCT.compcache: - ufn = fn & $uniq - uniq += 1 - - # - https://github.com/nim-lang/Nim/issues/10299 - # - https://github.com/nim-lang/Nim/issues/10486 - gStateCT.compcache.add(ufn) - if fn == ufn: - gStateCT.compile.add file.replace("\\", "/") - else: - # - https://github.com/nim-lang/Nim/issues/9370 - let - hash = file.hash().abs() - tmpFile = file.parentDir() / &"_nimterop_{$hash}_{ufn}{ext}" - if not tmpFile.fileExists() or file.getFileDate() > tmpFile.getFileDate(): - cpFile(file, tmpFile) - gStateCT.compile.add tmpFile.replace("\\", "/") - - # Due to https://github.com/nim-lang/Nim/issues/9863 - # cannot use seq[string] for excludes - proc notExcluded(file, exclude: string): bool = - result = true - if "_nimterop_" in file: - result = false - elif exclude.nBl: - for excl in exclude.split(","): - if excl in file: - result = false - - proc dcompile(dir, exclude: string, ext="") = - let - (dir, pat) = - if "*" in dir: - dir.splitPath() - else: - (dir, "") - - for file in walkDirRec(dir): - if ext.nBl or pat.nBl: - let - fext = file.splitFile().ext - if (ext.nBl and fext != ext) or (pat.nBl and fext != pat[1 .. ^1]): - continue - if file.notExcluded(exclude): - fcompile(file) - - if "*" in path: - dcompile(path, exclude) - else: - let fpath = findPath(path) - if fileExists(fpath) and fpath.notExcluded(exclude): - fcompile(fpath) - elif dirExists(fpath): - if mode.contains("cpp"): - for i in @[".cpp", ".c++", ".cc", ".cxx"]: - dcompile(fpath, exclude, i) - when not defined(Windows): - dcompile(fpath, exclude, ".C") - else: - dcompile(fpath, exclude, ".c") - macro cImport*(filenames: static seq[string], recurse: static bool = false, dynlib: static string = "", mode: static string = "c", flags: static string = "", nimFile: static string = ""): untyped = ## Import multiple headers in one shot @@ -704,29 +749,12 @@ macro c2nImport*(filename: static string, recurse: static bool = false, dynlib: if flags.nBl: cmd.add &" {flags}" - # Have to create pragmas for c2nim since toast handles this at runtime for i in gStateCT.defines: cmd.add &" --assumedef:{i.quoteShell}" - let str = "-D" & i - result.add quote do: - {.passC: `str`.} - for i in gStateCT.includeDirs: - let str = &"-I{i.quoteShell}" - result.add quote do: - {.passC: `str`.} - - for i in gStateCT.passC: - result.add quote do: - {.passC: `i`.} - - for i in gStateCT.passL: - result.add quote do: - {.passL: `i`.} - - for i in gStateCT.compile: - result.add quote do: - {.compile: `i`.} + # Have to create pragmas for c2nim since toast handles this at runtime + result.add quote do: + renderPragma() let (c2nimout, ret) = execAction(cmd) From d95deffb6aa9993eda989a20116cf7fd72eb767a Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Wed, 15 Jul 2020 21:06:59 -0500 Subject: [PATCH 562/593] v0.6.5 --- nimterop.nimble | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimterop.nimble b/nimterop.nimble index 1eb35ef..a246483 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -1,6 +1,6 @@ # Package -version = "0.6.4" +version = "0.6.5" author = "genotrance" description = "C/C++ interop for Nim" license = "MIT" From 74c9506529b422333a67e363d0554d91d542f289 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 16 Jul 2020 15:33:41 -0500 Subject: [PATCH 563/593] Skip Conan and JBB deps --- CHANGES.md | 2 ++ README.md | 2 +- nimterop/build/conan.nim | 8 +++++- nimterop/build/getheader.nim | 54 ++++++++++++++++++++++++------------ nimterop/build/jbb.nim | 9 +++++- 5 files changed, 55 insertions(+), 20 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index e7e9213..edd6c97 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -53,6 +53,8 @@ https://github.com/nimterop/nimterop/compare/v0.5.9...v0.6.5 - Added `renderPragma()` to create pragmas inline in case `cImport()` is not being used. (since v0.6.5) +- `xxxConan` and `xxxJBB` now allow skipping required dependencies by specifying `skip=pkg1,pkg2` to the `conanFlags` and `jbbFlags` params to `getHeader()`. (since v0.6.6) + ### Other improvements - Generated wrappers no longer depend on nimterop being present - no more `import nimterop/types`. Supporting code is directly included in the wrapper output and only when required. E.g. enum macro is only included if wrapper contains enums. [#125][i125] (since v0.6.1) diff --git a/README.md b/README.md index d652d0d..96f3a46 100644 --- a/README.md +++ b/README.md @@ -97,7 +97,7 @@ Flags can be specified to these tools via `getHeader()` or directly via the unde If `-d:headerStatic` is specified, `getHeader()` will return the static library path in `headerLPath`. The wrapper writer can check for this and call `cImport()` accordingly as in the example above. If `-d:headerStatic` is omitted, the dynamic library is returned in `headerLPath`. -All dependency libraries (supported by Conan and JBB) will be returned in `headerLDeps`. Static libraries and dependencies are automatically linked using `cPassL()`. Conan shared libs include all dependencies whereas JBB shared libs expect the required dependencies to be in the same location or in `LD_LIBRARY_PATH`. +All dependency libraries (supported by Conan and JBB) will be returned in `headerLDeps`. Static libraries and dependencies are automatically linked using `cPassL()`. Conan shared libs typically include dependencies compiled in whereas JBB shared libs expect the required dependencies to be in the same location or in `LD_LIBRARY_PATH`. `conanFlags` and `jbbFlags` can be used to skip required dependencies from being downloaded in case another source is preferred. This can be done with `skip=pkg1,pkg2` to these flags. `getHeader()` searches for libraries based on the header name by default: - `libheader.so` or `libheader.a` on Linux diff --git a/nimterop/build/conan.nim b/nimterop/build/conan.nim index dd43dc9..eb27557 100644 --- a/nimterop/build/conan.nim +++ b/nimterop/build/conan.nim @@ -22,6 +22,8 @@ type staticLibs*: seq[string] requires*: seq[ConanPackage] + skipRequires*: seq[string] + ConanBuild* = ref object ## Build type that stores build specific info and revisions bhash*: string @@ -245,7 +247,10 @@ proc getConanBuilds*(pkg: ConanPackage, filter = "") = bld.options = newTable[string, string](8) for key, value in options.getFields(): bld.options[key] = value.getStr() - bld.requires = requires.to(seq[string]) + for req in requires.to(seq[string]): + # Filter skipped dependencies + if req.toLowerAscii() notin pkg.skipRequires: + bld.requires.add req bld.recipe_hash = bdata.getOrDefault("recipe_hash").getStr() if pkg.recipes.hasKey(bld.recipe_hash): @@ -422,6 +427,7 @@ proc dlConanRequires*(pkg: ConanPackage, bld: ConanBuild, outdir: string) = else: let rpkg = newConanPackageFromUri(req, shared = false) + rpkg.skipRequires = pkg.skipRequires downloadConan(rpkg, outdir, main = false) pkg.requires.add rpkg diff --git a/nimterop/build/getheader.nim b/nimterop/build/getheader.nim index dbd965e..85a0331 100644 --- a/nimterop/build/getheader.nim +++ b/nimterop/build/getheader.nim @@ -119,7 +119,7 @@ proc getDlPath(header, url, outdir, version: string): string = result = findFile(header, outdir) -proc getConanPath(header, uri, outdir, version: string, shared: bool): string = +proc getConanPath(header, uri, flags, outdir, version: string, shared: bool): string = var uri = uri @@ -131,6 +131,15 @@ proc getConanPath(header, uri, outdir, version: string, shared: bool): string = let pkg = newConanPackageFromUri(uri, shared) + + # Handle `conanFlags` + if flags.nBl: + for flag in flags.split(" "): + if flag.startsWith("skip="): + for req in flag["skip=".len .. ^1].split(","): + if req.nBl: + pkg.skipRequires.add req.toLowerAscii() + downloadConan(pkg, outdir) result = findFile(header, outdir) @@ -165,16 +174,21 @@ proc getJBBPath(header, uri, flags, outdir, version: string): string = # Handle `jbbFlags` if flags.nBl: - if flags.startsWith("giturl="): - let - val = flags["giturl=".len .. ^1] - if val.contains("://"): - pkg.baseUrl = val - else: - pkg.baseUrl = "https://github.com/" & val - elif flags.startsWith("url="): - pkg.baseUrl = flags["url=".len .. ^1] - pkg.isGit = false + for flag in flags.split(" "): + if flag.startsWith("giturl="): + let + val = flag["giturl=".len .. ^1] + if val.contains("://"): + pkg.baseUrl = val + else: + pkg.baseUrl = "https://github.com/" & val + elif flag.startsWith("url="): + pkg.baseUrl = flag["url=".len .. ^1] + pkg.isGit = false + elif flag.startsWith("skip="): + for req in flag["skip=".len .. ^1].split(","): + if req.nBl: + pkg.skipRequires.add req.toLowerAscii() downloadJBB(pkg, outdir) @@ -227,7 +241,7 @@ macro getHeader*( conanuri: static[string] = "", jbburi: static[string] = "", outdir: static[string] = "", libdir: static[string] = "", conFlags: static[string] = "", cmakeFlags: static[string] = "", makeFlags: static[string] = "", - jbbFlags: static[string] = "", altNames: static[string] = "", + conanFlags: static[string] = "", jbbFlags: static[string] = "", altNames: static[string] = "", buildTypes: static[openArray[BuildType]] = [btCmake, btAutoconf]): untyped = ## Get the path to a header file for wrapping with ## `cImport() `_ or @@ -300,7 +314,12 @@ macro getHeader*( ## `cmake` and `make` in case additional configuration is required as part of the build ## process. ## - ## `jbbFlags` allows changing the BinaryBuilder.org defaults: + ## `conanFlags` and `jbbFlags` allow changing the Conan.io and BinaryBuilder.org defaults: + ## - `skip=pkg1,pkg2` skips the specified packages which are required dependencies of the + ## package in question. This enables downloading those dependencies from other sources + ## if required. + ## + ## `jbbFlags` allows two additional customizations: ## - `giturl=customUrl` changes the default `https://github.com/JuliaBinaryWrappers` to ## another Git URL. If no hostname is specified, `https://github.com` is assumed. ## - `url=customUrl` uses regular HTTP instead of Git and looks for `Artifacts.toml` and @@ -402,13 +421,14 @@ macro getHeader*( `nameStatic`* = when defined(`nameStatic`): true else: `staticVal` == 1 # Search for header in outdir (after retrieving code) depending on -d:xxx mode - proc getPath(header, giturl, dlurl, conanuri, jbburi, jbbFlags, outdir, version: string, shared: bool): string = + proc getPath(header, giturl, dlurl, conanuri, conanFlags, jbburi, jbbFlags, + outdir, version: string, shared: bool): string = when `nameGit`: getGitPath(header, giturl, outdir, version) elif `nameDL`: getDlPath(header, dlurl, outdir, version) elif `nameConan`: - getConanPath(header, conanuri, outdir, version, shared) + getConanPath(header, conanuri, conanFlags, outdir, version, shared) elif `nameJBB`: getJBBPath(header, jbburi, jbbFlags, outdir, version) else: @@ -441,7 +461,7 @@ macro getHeader*( when useStd: stdPath else: - getPath(`header`, `giturl`, `dlurl`, `conanuri`, `jbburi`, `jbbFlags`, + getPath(`header`, `giturl`, `dlurl`, `conanuri`, `conanFlags`, `jbburi`, `jbbFlags`, `outdir`, `version`, not `nameStatic`) # Run preBuild hook before building library if not Std, Conan or JBB @@ -477,7 +497,7 @@ macro getHeader*( if prePath.len != 0: prePath else: - getPath(`header`, `giturl`, `dlurl`, `conanuri`, `jbburi`, `jbbFlags`, + getPath(`header`, `giturl`, `dlurl`, `conanuri`, `conanFlags`, `jbburi`, `jbbFlags`, `outdir`, `version`, not `nameStatic`) static: diff --git a/nimterop/build/jbb.nim b/nimterop/build/jbb.nim index a430a55..a4ff98f 100644 --- a/nimterop/build/jbb.nim +++ b/nimterop/build/jbb.nim @@ -21,6 +21,8 @@ type staticLibs*: seq[string] requires*: seq[JBBPackage] + skipRequires*: seq[string] + const # JBB URLs jbbBaseUrl = "https://github.com/JuliaBinaryWrappers" @@ -73,7 +75,12 @@ proc parseJBBProject(pkg: JBBPackage, outdir: string) = let name = line.split()[0] if name.endsWith("_jll"): - pkg.requires.add newJBBPackage(name[0 .. ^5], "") + # Filter skipped dependencies + let + pname = name[0 .. ^5] + if pname.toLowerAscii() notin pkg.skipRequires: + pkg.requires.add newJBBPackage(pname, "") + pkg.requires[^1].skipRequires = pkg.skipRequires proc parseJBBArtifacts(pkg: JBBPackage, outdir: string) = # Get build information from Artifacts.toml From 5acfd0e8197160e8f71274473a4f9f2f75bc8fbc Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 16 Jul 2020 16:05:22 -0500 Subject: [PATCH 564/593] Handle JBB case where no dep for os/arch combo --- nimterop/build/conan.nim | 36 ++++++++++++++++++------------------ nimterop/build/jbb.nim | 17 ++++++++++------- 2 files changed, 28 insertions(+), 25 deletions(-) diff --git a/nimterop/build/conan.nim b/nimterop/build/conan.nim index eb27557..6df25d8 100644 --- a/nimterop/build/conan.nim +++ b/nimterop/build/conan.nim @@ -134,13 +134,13 @@ proc newConanPackageFromUri*(uri: string, shared = true): ConanPackage = proc getUriFromConanPackage*(pkg: ConanPackage): string = ## Convert a ConanPackage to a conan uri result = pkg.name - if pkg.version.len != 0: + if pkg.version.nBl: result &= "/" & pkg.version - if pkg.user.len != 0: + if pkg.user.nBl: result &= "@" & pkg.user - if pkg.channel.len != 0: + if pkg.channel.nBl: result &= "/" & pkg.channel - if pkg.bhash.len != 0: + if pkg.bhash.nBl: result &= ":" & pkg.bhash proc searchConan*(name: string, version = "", user = "", channel = ""): ConanPackage = @@ -149,11 +149,11 @@ proc searchConan*(name: string, version = "", user = "", channel = ""): ConanPac ## Search is quite slow so it is preferable to specify a version and use `getConanBuilds()` var query = name - if version.len != 0: + if version.nBl: query &= "/" & version - if user.len != 0: + if user.nBl: query &= "@" & user - if channel.len != 0: + if channel.nBl: query &= "/" & channel gecho &"# Searching Conan.io for latest version of {name}" @@ -172,11 +172,11 @@ proc searchConan*(name: string, version = "", user = "", channel = ""): ConanPac if "@_/_" in str: let ver = str.split('/')[1].split('@')[0] - if latestv.len == 0 or compareVersions(ver, latestv) > 0: + if latestv.Bl or compareVersions(ver, latestv) > 0: latestv = ver latest = str - if latest.len != 0: + if latest.nBl: result = newConanPackageFromUri(latest) proc searchConan*(pkg: ConanPackage): ConanPackage = @@ -200,7 +200,7 @@ proc getConanBuilds*(pkg: ConanPackage, filter = "") = vsplit[0] query = - if pkg.bhash.len == 0: + if pkg.bhash.Bl: block: var query = &"?q=arch={arch}&os={os.capitalizeAscii()}" @@ -208,7 +208,7 @@ proc getConanBuilds*(pkg: ConanPackage, filter = "") = query &= "&build_type=Release" if "shared=" notin filter: query &= &"&options.shared={($pkg.shared).capitalizeAscii()}" - if filter.len != 0: + if filter.nBl: query &= &"&{filter}" if "compiler=" notin filter and os != "windows": query &= &"&compiler={compiler}&compiler.version=" & vfilter @@ -232,7 +232,7 @@ proc getConanBuilds*(pkg: ConanPackage, filter = "") = if not j1.isNil: for bhash, bdata in j1.getFields(): - if pkg.bhash.len == 0 or pkg.bhash == bhash: + if pkg.bhash.Bl or pkg.bhash == bhash: let bld = new(ConanBuild) settings = bdata.getOrDefault("settings") @@ -328,13 +328,13 @@ proc dlConanBuild*(pkg: ConanPackage, bld: ConanBuild, outdir: string, revision ## Download specific `revision` of `bld` to `outdir` ## ## If omitted, the latest revision (first) is downloaded - doAssert bld.revisions.len != 0, "No build revisions found for Conan.io package " & pkg.getUriFromConanPackage() + doAssert bld.revisions.nBl, "No build revisions found for Conan.io package " & pkg.getUriFromConanPackage() let outdir = fixRelPath(outdir) revision = - if revision.len != 0: + if revision.nBl: revision else: bld.revisions[0] @@ -379,7 +379,7 @@ proc downloadConan*(pkg: ConanPackage, outdir: string, main = true) = outdir = fixRelPath(outdir) pkg = - if pkg.version.len == 0: + if pkg.version.Bl: searchConan(pkg) else: pkg @@ -395,12 +395,12 @@ proc downloadConan*(pkg: ConanPackage, outdir: string, main = true) = pkg.getConanBuilds() - doAssert pkg.recipes.len != 0, &"Failed to download {pkg.name} v{pkg.version} from Conan - check https://conan.io/center" + doAssert pkg.recipes.nBl, &"Failed to download {pkg.name} v{pkg.version} from Conan - check https://conan.io/center" gecho &"# Downloading {pkg.name} v{pkg.version} from Conan.io" for recipe, builds in pkg.recipes: for build in builds: - if pkg.bhash.len == 0 or pkg.bhash == build.bhash: + if pkg.bhash.Bl or pkg.bhash == build.bhash: pkg.getConanRevisions(build) pkg.dlConanBuild(build, outdir) pkg.dlConanRequires(build, outdir) @@ -442,7 +442,7 @@ proc getConanLDeps*(pkg: ConanPackage, outdir: string, main = true): seq[string] libs = if pkg.shared: pkg.sharedLibs else: pkg.staticLibs str = if pkg.shared: "shared" else: "static" - doAssert libs.len != 0, &"No {str} libs found for {pkg.name} in {outdir}" + doAssert libs.nBl, &"No {str} libs found for {pkg.name} in {outdir}" if not main: for lib in libs: diff --git a/nimterop/build/jbb.nim b/nimterop/build/jbb.nim index a4ff98f..9dacfe2 100644 --- a/nimterop/build/jbb.nim +++ b/nimterop/build/jbb.nim @@ -65,7 +65,7 @@ proc parseJBBProject(pkg: JBBPackage, outdir: string) = for line in data.splitLines(): let line = line.strip() - if line.len != 0: + if line.nBl: if line.startsWith('['): if line == "[deps]": deps = true @@ -100,7 +100,7 @@ proc parseJBBArtifacts(pkg: JBBPackage, outdir: string) = for line in data.splitLines(): let line = line.strip() - if line.len != 0: + if line.nBl: let spl = line.split(" = ", 1) name = spl[0] @@ -145,7 +145,7 @@ proc getJBBRepo*(pkg: JBBPackage, outdir: string) = quiet = true ) - if pkg.version.len != 0: + if pkg.version.nBl: # Checkout correct tag let tags = gitTags(path) @@ -157,7 +157,7 @@ proc getJBBRepo*(pkg: JBBPackage, outdir: string) = var url = pkg.baseUrl if "$#" in url or "$1" in url: - doAssert pkg.version.len != 0, "Need version for custom BinaryBuilder.org url: " & url + doAssert pkg.version.nBl, "Need version for custom BinaryBuilder.org url: " & url url = url % pkg.version downloadUrl(url & "Artifacts.toml", path, quiet = true) downloadUrl(url & "Project.toml", path, quiet = true) @@ -209,11 +209,14 @@ proc downloadJBB*(pkg: JBBPackage, outdir: string, main = true) = pkg.getJBBRepo(outdir) - doAssert pkg.url.len != 0, &"Failed to download {pkg.name} info from BinaryBuilder.org" + if pkg.url.Bl: + # No url for deps means no package for that os/arch combo - e.g. Attr + doAssert not main, &"Failed to download {pkg.name} info from BinaryBuilder.org" + return let vstr = - if pkg.version.len != 0: + if pkg.version.nBl: &" v{pkg.version}" else: "" @@ -250,7 +253,7 @@ proc getJBBLDeps*(pkg: JBBPackage, outdir: string, shared: bool, main = true): s libs = if shared: pkg.sharedLibs else: pkg.staticLibs str = if shared: "shared" else: "static" - doAssert libs.len != 0, &"No {str} libs found for {pkg.name} in {outdir}" + doAssert libs.nBl, &"No {str} libs found for {pkg.name} in {outdir}" if not main: for lib in libs: From b1ca1c6ffdbf8c2704f62c672ccfb498810970be Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 16 Jul 2020 17:19:41 -0500 Subject: [PATCH 565/593] Skip fix for JBB --- nimterop/build/jbb.nim | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/nimterop/build/jbb.nim b/nimterop/build/jbb.nim index 9dacfe2..c8d86c3 100644 --- a/nimterop/build/jbb.nim +++ b/nimterop/build/jbb.nim @@ -260,4 +260,6 @@ proc getJBBLDeps*(pkg: JBBPackage, outdir: string, shared: bool, main = true): s result.add lib for cpkg in pkg.requires: - result.add cpkg.getJBBLDeps(outdir, shared, main = false) + # No url for deps means no package for that os/arch combo - e.g. Attr + if cpkg.url.nBl: + result.add cpkg.getJBBLDeps(outdir, shared, main = false) From 5ac66286d5d44a50d0a84d1810694f818b4dda62 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Fri, 17 Jul 2020 20:56:22 -0500 Subject: [PATCH 566/593] v0.6.6 --- nimterop.nimble | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nimterop.nimble b/nimterop.nimble index a246483..3cb733f 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -1,6 +1,6 @@ # Package -version = "0.6.5" +version = "0.6.6" author = "genotrance" description = "C/C++ interop for Nim" license = "MIT" @@ -48,7 +48,7 @@ task docs, "Generate docs": task minitest, "Test for Nim CI": exec "nim c -f -d:danger nimterop/toast" exec "nim c -f -d:checkAbi -r tests/tast2.nim" - exec "nim c -f -d:checkAbi -d:zlibStd -d:zlibDL -d:zlibSetVer=1.2.11 -r tests/zlib.nim" + exec "nim c -f -d:checkAbi -d:zlibJBB -d:zlibSetVer=1.2.11 -r tests/zlib.nim" task basic, "Basic tests": execTest "tests/tast2.nim" From dfc4e09454b5e517185b0f83c9baa642a86c6b61 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 28 Jul 2020 14:09:48 -0500 Subject: [PATCH 567/593] Fix docs for nimble change --- nimterop/docs.nim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nimterop/docs.nim b/nimterop/docs.nim index 5fe87a1..6a5ef0c 100644 --- a/nimterop/docs.nim +++ b/nimterop/docs.nim @@ -1,4 +1,4 @@ -import macros, strformat +import strformat from os import parentDir, getCurrentCompilerExe, DirSep @@ -32,7 +32,7 @@ proc execAction(cmd: string): string = (result, ret) = gorgeEx(ccmd) doAssert ret == 0, "Command failed: " & $ret & "\ncmd: " & ccmd & "\nresult:\n" & result -proc buildDocs*(files: openArray[string], path: string, baseDir = getProjectPath() & $DirSep, +proc buildDocs*(files: openArray[string], path: string, baseDir = getCurrentDir() & $DirSep, defines: openArray[string] = @[], nimArgs = "") = ## Generate docs for all specified nim `files` to the specified `path` ## From 96d4d6a8957eed5d696e164b81353ec6b47c3a87 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 30 Jul 2020 20:33:56 -0500 Subject: [PATCH 568/593] v0.6.7 --- nimterop.nimble | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimterop.nimble b/nimterop.nimble index 3cb733f..8b07a47 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -1,6 +1,6 @@ # Package -version = "0.6.6" +version = "0.6.7" author = "genotrance" description = "C/C++ interop for Nim" license = "MIT" From 11814811e32ca5394bdc99c83ccaf2866b6d5c00 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Sun, 2 Aug 2020 22:20:04 -0500 Subject: [PATCH 569/593] Multiple getHeader, linkLibs name fix --- nimterop/build/getheader.nim | 8 +++++--- nimterop/build/shell.nim | 15 ++++++++++----- nimterop/toastlib/ast2.nim | 2 +- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/nimterop/build/getheader.nim b/nimterop/build/getheader.nim index 85a0331..4549894 100644 --- a/nimterop/build/getheader.nim +++ b/nimterop/build/getheader.nim @@ -366,6 +366,7 @@ macro getHeader*( staticStr = name & "Static" verStr = name & "SetVer" + getPath = name & "GetPath" # Ident nodes of the -d:xxx to check in when statements nameStd = newIdentNode(stdStr) @@ -375,6 +376,7 @@ macro getHeader*( nameJBB = newIdentNode(jbbStr) nameStatic = newIdentNode(staticStr) + nameGetPath = newIdentNode(getPath) # Consts to generate path = newIdentNode(name & "Path") @@ -421,7 +423,7 @@ macro getHeader*( `nameStatic`* = when defined(`nameStatic`): true else: `staticVal` == 1 # Search for header in outdir (after retrieving code) depending on -d:xxx mode - proc getPath(header, giturl, dlurl, conanuri, conanFlags, jbburi, jbbFlags, + proc `nameGetPath`(header, giturl, dlurl, conanuri, conanFlags, jbburi, jbbFlags, outdir, version: string, shared: bool): string = when `nameGit`: getGitPath(header, giturl, outdir, version) @@ -461,7 +463,7 @@ macro getHeader*( when useStd: stdPath else: - getPath(`header`, `giturl`, `dlurl`, `conanuri`, `conanFlags`, `jbburi`, `jbbFlags`, + `nameGetPath`(`header`, `giturl`, `dlurl`, `conanuri`, `conanFlags`, `jbburi`, `jbbFlags`, `outdir`, `version`, not `nameStatic`) # Run preBuild hook before building library if not Std, Conan or JBB @@ -497,7 +499,7 @@ macro getHeader*( if prePath.len != 0: prePath else: - getPath(`header`, `giturl`, `dlurl`, `conanuri`, `conanFlags`, `jbburi`, `jbbFlags`, + `nameGetPath`(`header`, `giturl`, `dlurl`, `conanuri`, `conanFlags`, `jbburi`, `jbbFlags`, `outdir`, `version`, not `nameStatic`) static: diff --git a/nimterop/build/shell.nim b/nimterop/build/shell.nim index f07f70c..f0af561 100644 --- a/nimterop/build/shell.nim +++ b/nimterop/build/shell.nim @@ -481,14 +481,19 @@ proc linkLibs*(names: openArray[string], staticLink = true): string = var stat = if staticLink: "--static" else: "" resSet: OrderedSet[string] + cmd = &"pkg-config --libs --silence-errors {stat}" resSet.init() for name in names: - let - cmd = &"pkg-config --libs --silence-errors {stat} lib{name}" - (libs, _) = execAction(cmd, die = false) - for lib in libs.split(" "): - resSet.incl lib + for n in ["lib" & name, name]: + # Try libname and name - e.g. MagickWand doesn't have lib + let + cmd = &"{cmd} {n}" + (libs, _) = execAction(cmd, die = false) + if libs.len != 0: + for lib in libs.split(" "): + resSet.incl lib + break if staticLink: resSet.incl "--static" diff --git a/nimterop/toastlib/ast2.nim b/nimterop/toastlib/ast2.nim index 7f2b4ad..bea6ff6 100644 --- a/nimterop/toastlib/ast2.nim +++ b/nimterop/toastlib/ast2.nim @@ -633,7 +633,7 @@ iterator newIdentDefs(gState: State, name: string, node: TSNode, offset: SomeInt yield result else: for i in start+1 ..< node.len: - if node[i].getName() == "bitfield_clause": + if node[i].getName() in ["bitfield_clause", "comment"]: continue yield gState.newIdentDef(name, node, tname, tinfo, tident, start, i, offset, exported) From 672e634d89f4db7158c9986fa96b0d5f02174259 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Sun, 2 Aug 2020 23:25:54 -0500 Subject: [PATCH 570/593] v0.6.8 --- nimterop.nimble | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimterop.nimble b/nimterop.nimble index 8b07a47..804f1a5 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -1,6 +1,6 @@ # Package -version = "0.6.7" +version = "0.6.8" author = "genotrance" description = "C/C++ interop for Nim" license = "MIT" From dc90a1debb8c5e914173d69f9a8d3fce2670d330 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 27 Aug 2020 20:01:04 -0500 Subject: [PATCH 571/593] Fix -std issue with clang --- nimterop/treesitter/api.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimterop/treesitter/api.nim b/nimterop/treesitter/api.nim index 753178c..b763722 100644 --- a/nimterop/treesitter/api.nim +++ b/nimterop/treesitter/api.nim @@ -10,7 +10,7 @@ static: const sourcePath = cacheDir / "treesitter" / "lib" -when defined(Linux): +when defined(Linux) and defined(gcc): {.passC: "-std=c11".} {.passC: "-I$1" % (sourcePath / "include").} From f07dd4dd56c587021f6477bae3731ff4abb1f1b1 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 27 Aug 2020 21:12:51 -0500 Subject: [PATCH 572/593] v0.6.9 --- nimterop.nimble | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimterop.nimble b/nimterop.nimble index 804f1a5..1ef3fb6 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -1,6 +1,6 @@ # Package -version = "0.6.8" +version = "0.6.9" author = "genotrance" description = "C/C++ interop for Nim" license = "MIT" From c0079db1548882949ded9fb3453a1a433a809aa8 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 27 Aug 2020 22:30:53 -0500 Subject: [PATCH 573/593] Test arm64 and ppc --- .travis.yml | 47 +++++++++++++++++++++++++++++++++++++---------- appveyor.yml | 4 ++-- 2 files changed, 39 insertions(+), 12 deletions(-) diff --git a/.travis.yml b/.travis.yml index b58b29d..25d8449 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,20 +1,47 @@ -os: - - windows - - linux - - osx +os: linux +dist: bionic +language: c addons: apt: packages: - autopoint -language: c +matrix: + include: + # Linux - amd64 + - env: BRANCH=0.20.2 + - env: BRANCH=1.0.8 + - env: BRANCH=1.2.6 + - env: BRANCH=devel -env: - - BRANCH=0.20.2 - - BRANCH=1.0.6 - - BRANCH=1.2.4 - - BRANCH=devel + # Linux - arm64 + - arch: arm64 + env: BRANCH=1.2.6 + + # Linux - ppc64 + - arch: ppc64le + env: BRANCH=1.2.6 + + # macOS - amd64 + - os: osx + env: BRANCH=0.20.2 + - os: osx + env: BRANCH=1.0.8 + - os: osx + env: BRANCH=1.2.6 + - os: osx + env: BRANCH=devel + + # windows - amd64 + - os: windows + env: BRANCH=0.20.2 + - os: windows + env: BRANCH=1.0.8 + - os: windows + env: BRANCH=1.2.6 + - os: windows + env: BRANCH=devel cache: directories: diff --git a/appveyor.yml b/appveyor.yml index b572ea1..273eee2 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -10,8 +10,8 @@ matrix: environment: matrix: - NIM_VERSION: 0.20.2 - - NIM_VERSION: 1.0.6 - - NIM_VERSION: 1.2.2 + - NIM_VERSION: 1.0.8 + - NIM_VERSION: 1.2.6 for: - From 650281039c7cb11cf089a86dc82830a347ae8784 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Fri, 28 Aug 2020 16:08:11 -0500 Subject: [PATCH 574/593] Fix preprocessing bug --- nimterop/toastlib/getters.nim | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nimterop/toastlib/getters.nim b/nimterop/toastlib/getters.nim index 8a4586d..f0a4735 100644 --- a/nimterop/toastlib/getters.nim +++ b/nimterop/toastlib/getters.nim @@ -333,7 +333,8 @@ proc getPreprocessor*(gState: State, fullpath: string) = while true: if outp.readLine(line): # We want to keep blank lines here for comment processing - if line.len > 1 and line[0] == '#' and line[1] == ' ': + if line.len > 10 and line[0] == '#' and line[1] == ' ' and line.contains('"'): + # # 1 "path/to/file.h" 1 start = false line = line.split('"')[1].sanitizePath(noQuote = true) if sfile == line or From 9b848bc726ee37fb1abbce2fb51b30c189aa5a69 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Fri, 28 Aug 2020 16:14:36 -0500 Subject: [PATCH 575/593] Adjust CI for failures --- .travis.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index 25d8449..5a88169 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,16 +12,16 @@ matrix: # Linux - amd64 - env: BRANCH=0.20.2 - env: BRANCH=1.0.8 - - env: BRANCH=1.2.6 + - env: BRANCH=1.2.4 - env: BRANCH=devel # Linux - arm64 - - arch: arm64 - env: BRANCH=1.2.6 + # - arch: arm64 + # env: BRANCH=1.2.4 # Linux - ppc64 - - arch: ppc64le - env: BRANCH=1.2.6 + # - arch: ppc64le + # env: BRANCH=1.2.4 # macOS - amd64 - os: osx @@ -29,7 +29,7 @@ matrix: - os: osx env: BRANCH=1.0.8 - os: osx - env: BRANCH=1.2.6 + env: BRANCH=1.2.4 - os: osx env: BRANCH=devel @@ -39,7 +39,7 @@ matrix: - os: windows env: BRANCH=1.0.8 - os: windows - env: BRANCH=1.2.6 + env: BRANCH=1.2.4 - os: windows env: BRANCH=devel From 6e86ebc194d5f56e519802e78f9b5e39d6ea7f51 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Fri, 28 Aug 2020 17:19:27 -0500 Subject: [PATCH 576/593] Fix appveyor --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 273eee2..d807b19 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -11,7 +11,7 @@ environment: matrix: - NIM_VERSION: 0.20.2 - NIM_VERSION: 1.0.8 - - NIM_VERSION: 1.2.6 + - NIM_VERSION: 1.2.4 for: - From f2139d53750c673208a3895e6c2b318e83ab7bf6 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Fri, 28 Aug 2020 17:19:31 -0500 Subject: [PATCH 577/593] v0.6.10 --- nimterop.nimble | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimterop.nimble b/nimterop.nimble index 1ef3fb6..1fbd440 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -1,6 +1,6 @@ # Package -version = "0.6.9" +version = "0.6.10" author = "genotrance" description = "C/C++ interop for Nim" license = "MIT" From b82d7ce87b2aa3b9ee194230565bfe6d73262b38 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 1 Sep 2020 12:38:21 -0500 Subject: [PATCH 578/593] Fix #248 - static build on Windows --- nimterop/toast.nims | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/nimterop/toast.nims b/nimterop/toast.nims index e9a3c99..e67a881 100644 --- a/nimterop/toast.nims +++ b/nimterop/toast.nims @@ -24,3 +24,7 @@ switch("out", currentSourcePath.parentDir() / "toast".addFileExt(ExeExt)) # Define TOAST for globals.nim switch("define", "TOAST") + +# Static for Windows - #248 +when defined(Windows): + switch("passL", "-static") From 674d842415ef68979f6407cb31b08f179238b189 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Tue, 1 Sep 2020 14:09:54 -0500 Subject: [PATCH 579/593] v0.6.11 --- nimterop.nimble | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimterop.nimble b/nimterop.nimble index 1fbd440..49c40d0 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -1,6 +1,6 @@ # Package -version = "0.6.10" +version = "0.6.11" author = "genotrance" description = "C/C++ interop for Nim" license = "MIT" From 93c83728c71132a63c69ecfaab84c4c91bb05615 Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Sun, 23 Aug 2020 17:11:18 -0600 Subject: [PATCH 580/593] Fix nimterop imports --- nimterop/enumtypepub.nim | 42 +++++++++++++++++++++++++++++++++++ nimterop/toastlib/getters.nim | 2 +- 2 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 nimterop/enumtypepub.nim diff --git a/nimterop/enumtypepub.nim b/nimterop/enumtypepub.nim new file mode 100644 index 0000000..7700e30 --- /dev/null +++ b/nimterop/enumtypepub.nim @@ -0,0 +1,42 @@ +import macros + +macro defineEnum*(typ: untyped): untyped = + result = newNimNode(nnkStmtList) + + # Enum mapped to distinct cint + result.add quote do: + type `typ`* = distinct cint + + for i in ["+", "-", "*", "div", "mod", "shl", "shr", "or", "and", "xor", "<", "<=", "==", ">", ">="]: + let + ni = newIdentNode(i) + typout = if i[0] in "<=>": newIdentNode("bool") else: typ # comparisons return bool + if i[0] == '>': # cannot borrow `>` and `>=` from templates + let + nopp = if i.len == 2: newIdentNode("<=") else: newIdentNode("<") + result.add quote do: + proc `ni`*(x: `typ`, y: cint): `typout` = `nopp`(y, x) + proc `ni`*(x: cint, y: `typ`): `typout` = `nopp`(y, x) + proc `ni`*(x, y: `typ`): `typout` = `nopp`(y, x) + else: + result.add quote do: + proc `ni`*(x: `typ`, y: cint): `typout` {.borrow.} + proc `ni`*(x: cint, y: `typ`): `typout` {.borrow.} + proc `ni`*(x, y: `typ`): `typout` {.borrow.} + result.add quote do: + proc `ni`*(x: `typ`, y: int): `typout` = `ni`(x, y.cint) + proc `ni`*(x: int, y: `typ`): `typout` = `ni`(x.cint, y) + + let + divop = newIdentNode("/") # `/`() + dlrop = newIdentNode("$") # `$`() + notop = newIdentNode("not") # `not`() + result.add quote do: + proc `divop`*(x, y: `typ`): `typ` = `typ`((x.float / y.float).cint) + proc `divop`*(x: `typ`, y: cint): `typ` = `divop`(x, `typ`(y)) + proc `divop`*(x: cint, y: `typ`): `typ` = `divop`(`typ`(x), y) + proc `divop`*(x: `typ`, y: int): `typ` = `divop`(x, y.cint) + proc `divop`*(x: int, y: `typ`): `typ` = `divop`(x.cint, y) + + proc `dlrop`*(x: `typ`): string {.borrow.} + proc `notop`*(x: `typ`): `typ` {.borrow.} diff --git a/nimterop/toastlib/getters.nim b/nimterop/toastlib/getters.nim index f0a4735..2e1ac4c 100644 --- a/nimterop/toastlib/getters.nim +++ b/nimterop/toastlib/getters.nim @@ -31,7 +31,7 @@ yield""".split(Whitespace).toHashSet() const # Enum macro read from file - written into wrapper when required - gEnumMacroConst = staticRead(currentSourcePath.parentDir().parentDir() / "enumtype.nim") + gEnumMacroConst = "import nimterop / enumtypepub" var gEnumMacro* = gEnumMacroConst From 00941e892588503d18b3d271a65b0596bc6d857b Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Sat, 12 Sep 2020 10:59:14 -0600 Subject: [PATCH 581/593] Fix regen issues windows/linux --- nimterop/build/shell.nim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nimterop/build/shell.nim b/nimterop/build/shell.nim index f0af561..e5a70a8 100644 --- a/nimterop/build/shell.nim +++ b/nimterop/build/shell.nim @@ -206,9 +206,9 @@ proc getFileDate*(fullpath: string): string = when defined(Windows): let (head, tail) = fullpath.splitPath() - &"cmd /c forfiles /P {head.sanitizePath()} /M {tail.sanitizePath} /C \"cmd /c echo @fdate @ftime @fsize\"" + &"forfiles /P {head.sanitizePath()} /M {tail.sanitizePath} /C \"cmd /c echo @fdate @ftime\"" elif defined(Linux): - &"stat -c %y {fullpath.sanitizePath}" + &"stat -c %Y {fullpath.sanitizePath}" elif defined(OSX) or defined(FreeBSD): &"stat -f %m {fullpath.sanitizePath}" From 316a56107a4ccfcc0773d5a5b7f59abf0e05f922 Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Sat, 12 Sep 2020 12:48:45 -0600 Subject: [PATCH 582/593] Add ability to get a define value --- nimterop/build/getheader.nim | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/nimterop/build/getheader.nim b/nimterop/build/getheader.nim index 4549894..bbc810a 100644 --- a/nimterop/build/getheader.nim +++ b/nimterop/build/getheader.nim @@ -59,6 +59,11 @@ macro isDefined*(def: untyped): untyped = false ) +macro getDefine*(def: untyped): untyped = + if gDefines.hasKey(def.strVal()): + return newStrLitNode(gDefines[def.strVal()]) + return newStrLitNode("") + proc getDynlibExt(): string = when defined(Windows): result = "[0-9.\\-]*\\.dll" From 1b8aa46b8a5b8254cee5aa0c5d73e29881ca7ed9 Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Sat, 12 Sep 2020 15:24:29 -0600 Subject: [PATCH 583/593] Improve on getdefine --- nimterop/build/getheader.nim | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/nimterop/build/getheader.nim b/nimterop/build/getheader.nim index bbc810a..36dd50c 100644 --- a/nimterop/build/getheader.nim +++ b/nimterop/build/getheader.nim @@ -60,9 +60,15 @@ macro isDefined*(def: untyped): untyped = ) macro getDefine*(def: untyped): untyped = - if gDefines.hasKey(def.strVal()): - return newStrLitNode(gDefines[def.strVal()]) - return newStrLitNode("") + let version = newIdentNode(def.strVal()) + let verVal = + if gDefines.hasKey(def.strVal()): + gDefines[def.strVal()] + else: + "" + result = quote do: + const `version` {.strdefine.} = `verVal` + `version` proc getDynlibExt(): string = when defined(Windows): From 217bce386a2ef7119e4914b19461d18e0fae821a Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Thu, 17 Sep 2020 19:59:41 -0600 Subject: [PATCH 584/593] Don't die on nimcheck for cached files --- nimterop/build/shell.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimterop/build/shell.nim b/nimterop/build/shell.nim index e5a70a8..a8511c2 100644 --- a/nimterop/build/shell.nim +++ b/nimterop/build/shell.nim @@ -212,7 +212,7 @@ proc getFileDate*(fullpath: string): string = elif defined(OSX) or defined(FreeBSD): &"stat -f %m {fullpath.sanitizePath}" - (result, ret) = execAction(cmd) + (result, ret) = execAction(cmd, die=false) proc touchFile*(fullpath: string) = ## Touch file to update modified date From 60cc0d26efb79e4becb064e2db3bf5973bd25b89 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Fri, 2 Oct 2020 17:46:27 -0500 Subject: [PATCH 585/593] Add musl support --- nimterop/build/ccompiler.nim | 4 +++- nimterop/build/conan.nim | 30 ++++++++++++++++++++++-------- nimterop/build/jbb.nim | 26 +++++++++++++++++++------- nimterop/build/shell.nim | 29 ++++++----------------------- 4 files changed, 50 insertions(+), 39 deletions(-) diff --git a/nimterop/build/ccompiler.nim b/nimterop/build/ccompiler.nim index 550e1b2..f21f45a 100644 --- a/nimterop/build/ccompiler.nim +++ b/nimterop/build/ccompiler.nim @@ -75,7 +75,7 @@ proc getGccLibPaths*(mode: string): seq[string] = when defined(osx): result.add "/usr/lib" -proc getGccInfo*(): tuple[arch, os, compiler, version: string] = +proc getGccInfo*(): tuple[arch, os, compiler, version, libc: string] = let (outp, _) = execAction(&"{getCompiler()} -v") for line in outp.splitLines(): @@ -101,3 +101,5 @@ proc getGccInfo*(): tuple[arch, os, compiler, version: string] = result.compiler = "clang" else: result.compiler = "gcc" + if "musl" in outp: + result.libc = "musl" diff --git a/nimterop/build/conan.nim b/nimterop/build/conan.nim index 6df25d8..ac74089 100644 --- a/nimterop/build/conan.nim +++ b/nimterop/build/conan.nim @@ -16,6 +16,8 @@ type channel*: string recipes*: OrderedTableRef[string, seq[ConanBuild]] + arch*, os*, compiler*, compversion*: string + bhash*: string shared*: bool sharedLibs*: seq[string] @@ -89,6 +91,11 @@ proc `==`*(pkg1, pkg2: ConanPackage): bool = pkg1.user == pkg2.user and pkg1.channel == pkg2.channel and + pkg1.arch == pkg2.arch and + pkg1.os == pkg2.os and + pkg1.compiler == pkg2.compiler and + pkg1.compversion == pkg2.compversion and + pkg1.bhash == pkg2.bhash and pkg1.shared == pkg2.shared) @@ -101,6 +108,15 @@ proc newConanPackage*(name, version, user = "_", channel = "_", bhash = "", shar result.channel = channel result.recipes = newOrderedTable[string, seq[ConanBuild]](2) + let + (arch, os, compiler, compversion, libc) = getGccInfo() + doAssert libc != "musl", "Conan does not provide precompiled binaries using musl" + + result.arch = arch + result.os = os + result.compiler = compiler + result.compversion = compversion + result.bhash = bhash result.shared = shared @@ -189,9 +205,7 @@ proc getConanBuilds*(pkg: ConanPackage, filter = "") = ## `filter` can be used to tweak search terms ## e.g. build_type=Debug&compiler=clang let - (arch, os, compiler, version) = getGccInfo() - - vsplit = version.split('.') + vsplit = pkg.compversion.split('.') vfilter = when defined(OSX): @@ -203,18 +217,18 @@ proc getConanBuilds*(pkg: ConanPackage, filter = "") = if pkg.bhash.Bl: block: var - query = &"?q=arch={arch}&os={os.capitalizeAscii()}" + query = &"?q=arch={pkg.arch}&os={pkg.os.capitalizeAscii()}" if "build_type" notin filter: query &= "&build_type=Release" if "shared=" notin filter: query &= &"&options.shared={($pkg.shared).capitalizeAscii()}" if filter.nBl: query &= &"&{filter}" - if "compiler=" notin filter and os != "windows": - query &= &"&compiler={compiler}&compiler.version=" & vfilter - if "compiler.runtime=" notin filter and os == "windows": + if "compiler=" notin filter and pkg.os != "windows": + query &= &"&compiler={pkg.compiler}&compiler.version=" & vfilter + if "compiler.runtime=" notin filter and pkg.os == "windows": query &= &"&compiler.runtime=MD" - if "compiler.version=" notin filter and os == "windows": + if "compiler.version=" notin filter and pkg.os == "windows": query &= &"&compiler.version=14" query.replace("&", "%20and%20") diff --git a/nimterop/build/jbb.nim b/nimterop/build/jbb.nim index c8d86c3..392f848 100644 --- a/nimterop/build/jbb.nim +++ b/nimterop/build/jbb.nim @@ -17,6 +17,8 @@ type url*: string # Download URL + arch*, os*, libc*: string # Target + sharedLibs*: seq[string] staticLibs*: seq[string] requires*: seq[JBBPackage] @@ -39,7 +41,11 @@ proc `==`*(pkg1, pkg2: JBBPackage): bool = ## Check if two JBBPackage objects are equal (not pkg1.isNil and not pkg2.isNil and pkg1.name == pkg2.name and - pkg1.version == pkg2.version) + pkg1.version == pkg2.version and + + pkg1.arch == pkg2.arch and + pkg1.os == pkg2.os and + pkg1.libc == pkg2.libc) proc newJBBPackage*(name, version: string): JBBPackage = ## Create a new JBBPackage with specified name and version @@ -49,6 +55,12 @@ proc newJBBPackage*(name, version: string): JBBPackage = result.baseUrl = jbbBaseUrl result.isGit = true + let + (arch, os, _, _, libc) = getGccInfo() + result.arch = arch + result.os = os + result.libc = libc + proc parseJBBProject(pkg: JBBPackage, outdir: string) = # Get all dependencies from Project.toml let @@ -87,8 +99,6 @@ proc parseJBBArtifacts(pkg: JBBPackage, outdir: string) = let file = outdir / jbbArtifacts - (arch, os, _, _) = getGccInfo() - if fileExists(file): let data = readFile(file) @@ -109,12 +119,14 @@ proc parseJBBArtifacts(pkg: JBBPackage, outdir: string) = # Match arch, os and glibc on Linux to find download URL case name of "arch": - if val == arch and not found: found = true + if val == pkg.arch and not found: found = true of "os": - if val != os and found: found = false + if val != pkg.os and found: found = false of "libc": when defined(Linux): - if val != "glibc" and found: found = false + if found: + let libc = if pkg.libc.nBl: pkg.libc else: "glibc" + if val != libc: found = false of "url": if found: pkg.url = val @@ -125,7 +137,7 @@ proc parseJBBArtifacts(pkg: JBBPackage, outdir: string) = proc findJBBLibs(pkg: JBBPackage, outdir: string) = pkg.sharedLibs = findFiles("(bin|lib)[\\\\/].*\\.(so|dll|dylib)[0-9.]*", outdir) - for lib in findFiles("lib[\\\\/].*\\.(a|lib)$", outdir): + for lib in findFiles("lib[\\\\/].*\\.(a|lib)", outdir): if not lib.endsWith(".dll.a"): pkg.staticLibs.add lib diff --git a/nimterop/build/shell.nim b/nimterop/build/shell.nim index f0af561..d0a10fb 100644 --- a/nimterop/build/shell.nim +++ b/nimterop/build/shell.nim @@ -414,22 +414,8 @@ proc findFiles*(file: string, dir: string, recurse = true, regex = false): seq[s ## ## Turn off recursive search with `recurse` var - cmd = - when defined(Windows): - "nimgrep --filenames --oneline --nocolor $1 \"$2\" $3" - elif defined(linux): - "find $3 $1 -regextype egrep -regex $2" - elif defined(osx) or defined(FreeBSD): - "find -E $3 $1 -regex $2" - - recursive = "" - - if recurse: - when defined(Windows): - recursive = "--recursive" - else: - when not defined(Windows): - recursive = "-maxdepth 1" + cmd = "nimgrep --follow --filenames --oneline --nocolor $1 \"$2\" $3" + recursive = if recurse: "--recursive" else: "" var dir = dir @@ -443,20 +429,17 @@ proc findFiles*(file: string, dir: string, recurse = true, regex = false): seq[s file = file.extractFilename - cmd = cmd % [recursive, (".*[\\\\/]" & file & "$").quoteShell, dir.sanitizePath] + cmd = cmd % [recursive, (".*[\\\\/]" & file & "$"), dir.sanitizePath] let (files, ret) = execAction(cmd, die = false) if ret == 0: for line in files.splitLines(): let f = - when defined(Windows): - if ": " in line: - line.split(": ", maxsplit = 1)[1] - else: - "" + if ": " in line: + line.split(": ", maxsplit = 1)[1] else: - line + "" if f.len != 0: result.add f From 13e5ce7e221f9e675d6747857cd3f9dbef961d40 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 5 Oct 2020 12:17:36 -0500 Subject: [PATCH 586/593] Add loaf, replace find --- nimterop.nimble | 6 +++++- nimterop/build/shell.nim | 16 +++++++--------- nimterop/loaf.nim | 39 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 10 deletions(-) create mode 100644 nimterop/loaf.nim diff --git a/nimterop.nimble b/nimterop.nimble index 49c40d0..8e12ee8 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -5,7 +5,7 @@ author = "genotrance" description = "C/C++ interop for Nim" license = "MIT" -bin = @["nimterop/toast"] +bin = @["nimterop/toast", "nimterop/loaf"] installDirs = @["nimterop"] # Dependencies @@ -33,6 +33,9 @@ proc execTest(test: string, flags = "", runDocs = true) = task buildTimeit, "build timer": exec "nim c --hints:off -d:danger tests/timeit" +task buildLoaf, "build loaf": + execCmd("nim c --hints:off -d:danger nimterop/loaf.nim") + task buildToast, "build toast": execCmd("nim c --hints:off -d:danger nimterop/toast.nim") @@ -89,6 +92,7 @@ task test, "Test": rmFile("tests/timeit.txt") buildTimeitTask() + buildLoafTask() buildToastTask() basicTask() diff --git a/nimterop/build/shell.nim b/nimterop/build/shell.nim index d0a10fb..7c65b71 100644 --- a/nimterop/build/shell.nim +++ b/nimterop/build/shell.nim @@ -407,6 +407,9 @@ proc gitTags*(outdir: string): seq[string] = if tag.len != 0: result.add tag +proc loafExePath(): string = + currentSourcePath.parentDir.parentDir / ("loaf".addFileExt ExeExt) + proc findFiles*(file: string, dir: string, recurse = true, regex = false): seq[string] = ## Find all matching files in the specified directory ## @@ -414,8 +417,8 @@ proc findFiles*(file: string, dir: string, recurse = true, regex = false): seq[s ## ## Turn off recursive search with `recurse` var - cmd = "nimgrep --follow --filenames --oneline --nocolor $1 \"$2\" $3" - recursive = if recurse: "--recursive" else: "" + cmd = loafExePath().quoteShell & " find --rexp $1 \"$2\" $3" + recursive = if recurse: "--recurse" else: "" var dir = dir @@ -435,13 +438,8 @@ proc findFiles*(file: string, dir: string, recurse = true, regex = false): seq[s (files, ret) = execAction(cmd, die = false) if ret == 0: for line in files.splitLines(): - let f = - if ": " in line: - line.split(": ", maxsplit = 1)[1] - else: - "" - if f.len != 0: - result.add f + if line.len != 0: + result.add line proc findFile*(file: string, dir: string, recurse = true, first = false, regex = false): string = ## Find the file in the specified directory diff --git a/nimterop/loaf.nim b/nimterop/loaf.nim new file mode 100644 index 0000000..04b377e --- /dev/null +++ b/nimterop/loaf.nim @@ -0,0 +1,39 @@ +import system except find + +import os + +import cligen + +import strutils except find +import regex except find + +proc findRec(dir: string, pattern: string | Regex, recurse: bool) = + for kind, path in walkDir(dir): + if kind in [pcDir, pcLinkToDir]: + if recurse: findRec(path, pattern, recurse) + elif pattern in path: + echo path.absolutePath() + +proc find(recurse = false, rexp = false, args: seq[string]) = + var + pat = "" + rpat: Regex + for arg in args: + if not arg.startsWith("-"): + if dirExists(arg): + if rexp: + findRec(arg, rpat, recurse) + else: + findRec(arg, pat, recurse) + else: + pat = arg + if rexp: rpat = re(arg) + +when isMainModule: + dispatchMulti([ + find, help = { + "recurse": "recursive search", + "rexp": "patterns are regular expressions", + "args": "pattern1 dir1 dir2 pattern2 dir3 ..." + } + ]) From 94b3b04e6d72d1e8f02bc116abb6e8d05a90c54e Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 5 Oct 2020 13:33:54 -0500 Subject: [PATCH 587/593] Fix build error messaging --- nimterop/build/getheader.nim | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/nimterop/build/getheader.nim b/nimterop/build/getheader.nim index 4549894..918e923 100644 --- a/nimterop/build/getheader.nim +++ b/nimterop/build/getheader.nim @@ -208,11 +208,12 @@ proc buildLibrary(lname, outdir, conFlags, cmakeFlags, makeFlags: string, buildT var lpath = findFile(lname, outdir, regex = true) makePath = outdir + buildStatus: BuildStatus + errors: seq[string] if lpath.nBl: return lpath - var buildStatus: BuildStatus for buildType in buildTypes: case buildType @@ -223,6 +224,8 @@ proc buildLibrary(lname, outdir, conFlags, cmakeFlags, makeFlags: string, buildT if buildStatus.built: break + elif buildStatus.error.nBl: + errors.add buildStatus.error if buildStatus.buildPath.len > 0: let libraryExists = findFile(lname, buildStatus.buildPath, regex = true).len > 0 @@ -231,7 +234,7 @@ proc buildLibrary(lname, outdir, conFlags, cmakeFlags, makeFlags: string, buildT make(buildStatus.buildPath, lname, makeFlags, regex = true) buildStatus.built = true - let error = if buildStatus.error.len > 0: buildStatus.error else: "No build files found in " & outdir + let error = if errors.len > 0: errors.join("\n") else: "No build files found in " & outdir doAssert buildStatus.built, &"\nBuild configuration failed - {error}\n" result = findFile(lname, outdir, regex = true) From 0c2ca16f7ad9b1798f1c28ca0a3268d98e845a8d Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Mon, 5 Oct 2020 21:25:35 -0500 Subject: [PATCH 588/593] v0.6.12 --- nimterop.nimble | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimterop.nimble b/nimterop.nimble index 8e12ee8..6d4306c 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -1,6 +1,6 @@ # Package -version = "0.6.11" +version = "0.6.12" author = "genotrance" description = "C/C++ interop for Nim" license = "MIT" From 0e003b5dba306143beb586231f17e013a946e4b2 Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 8 Oct 2020 23:17:43 -0500 Subject: [PATCH 589/593] Build loaf for minitest --- nimterop.nimble | 1 + 1 file changed, 1 insertion(+) diff --git a/nimterop.nimble b/nimterop.nimble index 6d4306c..9a9083f 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -49,6 +49,7 @@ task docs, "Generate docs": buildDocs(@["nimterop/all.nim"], "build/htmldocs") task minitest, "Test for Nim CI": + exec "nim c -f -d:danger nimterop/loaf.nim" exec "nim c -f -d:danger nimterop/toast" exec "nim c -f -d:checkAbi -r tests/tast2.nim" exec "nim c -f -d:checkAbi -d:zlibJBB -d:zlibSetVer=1.2.11 -r tests/zlib.nim" From e987b50610c4756a1f5acaaba8fb865c6e0c8693 Mon Sep 17 00:00:00 2001 From: n5m <72841454+n5m@users.noreply.github.com> Date: Thu, 15 Oct 2020 13:48:39 +0000 Subject: [PATCH 590/593] ensure loaf exists before finding (#256) --- nimterop/build/shell.nim | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/nimterop/build/shell.nim b/nimterop/build/shell.nim index 7c65b71..24075cf 100644 --- a/nimterop/build/shell.nim +++ b/nimterop/build/shell.nim @@ -416,8 +416,14 @@ proc findFiles*(file: string, dir: string, recurse = true, regex = false): seq[s ## `file` is a regular expression if `regex` is true ## ## Turn off recursive search with `recurse` + let + loafExe = loafExePath() + + doAssert fileExists(loafExe), "loaf not compiled: " & loafExe.sanitizePath & + " make sure 'nimble build' or 'nimble install' built it" + var - cmd = loafExePath().quoteShell & " find --rexp $1 \"$2\" $3" + cmd = loafExe.quoteShell & " find --rexp $1 \"$2\" $3" recursive = if recurse: "--recurse" else: "" var From f7cee5c983650336f93fde5d4fea087863ac0e5e Mon Sep 17 00:00:00 2001 From: Ganesh Viswanathan Date: Thu, 15 Oct 2020 08:48:57 -0500 Subject: [PATCH 591/593] v0.6.13 --- nimterop.nimble | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimterop.nimble b/nimterop.nimble index 9a9083f..15a8ed1 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -1,6 +1,6 @@ # Package -version = "0.6.12" +version = "0.6.13" author = "genotrance" description = "C/C++ interop for Nim" license = "MIT" From b568863527d8b700922774e64a41db50f9b701cb Mon Sep 17 00:00:00 2001 From: Joey Date: Tue, 20 Oct 2020 11:08:52 -0600 Subject: [PATCH 592/593] Fix #233: make shl/shr use the direct left operand for type casting (#235) --- nimterop/toastlib/exprparser.nim | 16 +++++++++++++--- tests/include/tast2.h | 1 + tests/tast2.nim | 2 ++ 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/nimterop/toastlib/exprparser.nim b/nimterop/toastlib/exprparser.nim index a77dbf9..a67ed59 100644 --- a/nimterop/toastlib/exprparser.nim +++ b/nimterop/toastlib/exprparser.nim @@ -379,18 +379,28 @@ proc processBinaryExpression(gState: State, node: TSNode, typeofNode: var PNode) result.add gState.getIdent(nimSym) let leftNode = gState.processTSNode(left, typeofNode) + var tyNode = typeofNode if typeofNode.isNil: typeofNode = nkCall.newTree( gState.getIdent("typeof"), leftNode ) + tyNode = typeofNode - let rightNode = gState.processTSNode(right, typeofNode) + # Special case of setting the shift left/right type + # to be the type of the direct left operand + if binarySym in [">>", "<<"]: + tyNode = nkCall.newTree( + gState.getIdent("typeof"), + leftNode + ) + + let rightNode = gState.processTSNode(right, tyNode) result.add leftNode result.add nkCall.newTree( - typeofNode, + tyNode, rightNode ) if binarySym == "/": @@ -399,7 +409,7 @@ proc processBinaryExpression(gState: State, node: TSNode, typeofNode: var PNode) # So we need to emulate C here and cast the whole # expression to the type of the first arg result = nkCall.newTree( - typeofNode, + tyNode, result ) diff --git a/tests/include/tast2.h b/tests/include/tast2.h index 38c5f18..ede71d5 100644 --- a/tests/include/tast2.h +++ b/tests/include/tast2.h @@ -35,6 +35,7 @@ extern "C" { #define EQ4 AVAL < BVAL #define EQ5 AVAL != BVAL #define EQ6 AVAL == BVAL +#define SX_NEAR_ZERO (1.0f / (1 << 28)) // testing integer out of long int range #define INT_FAST16_MIN (-9223372036854775807L-1) diff --git a/tests/tast2.nim b/tests/tast2.nim index a410de4..e301fb5 100644 --- a/tests/tast2.nim +++ b/tests/tast2.nim @@ -134,6 +134,8 @@ assert EQ4 == (AVAL < BVAL) assert EQ5 == (AVAL != BVAL) assert EQ6 == (AVAL == BVAL) +assert SX_NEAR_ZERO == 3.725290298461914e-09 + assert SIZEOF == 1 assert COERCE == 645635670332'u64 From fa9e66b4a371b78d97d074cf531fad8f55135334 Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Sat, 15 May 2021 18:39:47 -0600 Subject: [PATCH 593/593] Update cligen --- nimterop.nimble | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nimterop.nimble b/nimterop.nimble index 15a8ed1..87e1bc4 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -9,7 +9,7 @@ bin = @["nimterop/toast", "nimterop/loaf"] installDirs = @["nimterop"] # Dependencies -requires "nim >= 0.20.2", "regex >= 0.15.0", "cligen >= 1.0.0" +requires "nim >= 0.20.2", "regex >= 0.15.0", "cligen >= 1.5.3" import nimterop/docs import os