Fix #56 - override and skip, html links

This commit is contained in:
Ganesh Viswanathan 2019-01-23 19:40:01 -06:00
commit 2cec3015ed
5 changed files with 71 additions and 59 deletions

View file

@ -49,35 +49,7 @@ 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. The `toast` binary can also be used directly on the CLI. The `--help` flag provides more details.
__Documentation__ Detailed documentation is available for [cimport](https://genotrance.github.io/nimterop/cimport.html) and [git](https://genotrance.github.io/nimterop/git.html).
Documentation can be found [here](https://genotrance.github.io/nimterop/cimport.html).
`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
`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 the search path used in calls to `cSearchPath()`
`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
`gitPull()` - pull a git repository prior to C/C++ interop
__Implementation Details__ __Implementation Details__

View file

@ -99,8 +99,8 @@ proc getToast(fullpath: string, recurse: bool = false): string =
for i in gStateCT.includeDirs: for i in gStateCT.includeDirs:
cmd.add &"--includeDirs+={i.quoteShell} " cmd.add &"--includeDirs+={i.quoteShell} "
for i in gStateCT.symOverride: if gStateCT.symOverride.len != 0:
cmd.add &"--symOverride+={i} " cmd.add &"--symOverride={gStateCT.symOverride.join(\",\")} "
cmd.add &"{fullpath.quoteShell}" cmd.add &"{fullpath.quoteShell}"
echo cmd echo cmd
@ -117,8 +117,9 @@ proc getGccPaths(mode = "c"): string =
macro cOverride*(body): untyped = macro cOverride*(body): untyped =
## When the wrapper code generated by nimterop is missing certain symbols or not ## 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()`` ## accurate, it may be required to hand wrap them. Define them in a
## macro block so that Nimterop no longer defines these symbols. ## `cOverride() <cimport.html#cOverride.m,>`_ macro block so that Nimterop no
## longer defines these symbols.
## ##
## For example: ## For example:
## ##
@ -139,16 +140,17 @@ macro cOverride*(body): untyped =
## cOverride: ## cOverride:
## proc svGetCallerInfo(fileName: var cstring; lineNumber: var cint) ## proc svGetCallerInfo(fileName: var cstring; lineNumber: var cint)
## ##
## Using the ``cOverride()`` block, nimterop can be instructed to skip over ## Using the `cOverride() <cimport.html#cOverride.m,>`_ block, nimterop
## ``svGetCallerInfo()``. This works for procs, consts and types. ## can be instructed to skip over ``svGetCallerInfo()``. This works for procs,
## consts and types.
for sym in body: for sym in body:
case sym.kind: case sym.kind:
of nnkProcDef: of nnkProcDef:
gStateCT.symOverride.add $sym[0] gStateCT.symOverride.add ($sym[0]).strip(chars={'*'})
of nnkConstSection, nnkTypeSection: of nnkConstSection, nnkTypeSection:
for ssym in sym: for ssym in sym:
gStateCT.symOverride.add $ssym[0] gStateCT.symOverride.add ($ssym[0]).strip(chars={'*'})
else: else:
discard discard
@ -157,12 +159,26 @@ macro cOverride*(body): untyped =
if gStateCT.debug: if gStateCT.debug:
echo "Overriding " & gStateCT.symOverride.join(" ") echo "Overriding " & gStateCT.symOverride.join(" ")
proc cSearchPath*(path: string): string {.compileTime.}= macro cSkipSymbol*(skips: varargs[string]): untyped =
## Return a file or directory found in search path configured using ## Similar to `cOverride() <cimport.html#cOverride.m,>`_, this macro allows
## ``cSearchPath()`` ## filtering out symbols not of interest from the generated output.
## ##
## This proc can be used to locate files or directories in calls to ## .. code-block:: nim
## ``cCompile()``, ``cIncludeDir()`` and ``cImport()``. ##
## cSkipSymbol "proc1", "Type2"
for skip in skips:
gStateCT.symOverride.add skip.strVal
proc cSearchPath*(path: string): string {.compileTime.}=
## Get full path to file or directory ``path`` in search path configured
## using `cAddSearchDir() <cimport.html#cAddSearchDir.m,>`_ and
## `cAddStdDir() <cimport.html#cAddStdDir.m,string>`_.
##
## This can be used to locate files or directories that can be passed onto
## `cCompile() <cimport.html#cCompile.m,,string>`_,
## `cIncludeDir() <cimport.html#cIncludeDir.m,>`_ and
## `cImport() <cimport.html#cImport.m,>`_.
result = findPath(path, fail = false) result = findPath(path, fail = false)
if result.len == 0: if result.len == 0:
@ -183,11 +199,12 @@ macro cDebug*(): untyped =
macro cDisableCaching*(): untyped = macro cDisableCaching*(): untyped =
## Disable caching of generated Nim code - useful during wrapper development ## Disable caching of generated Nim code - useful during wrapper development
## ##
## If files included by header bring processed by ``cImport()`` change and affect ## If files included by header being processed by `cImport() <cimport.html#cImport.m,>`_
## the generated content, ``cImport()`` won't detect the change and use the cached ## change and affect the generated content, they will be ignored and the cached
## value. Use ``cDisableCaching()`` to avoid this scenario. ## value will continue to be used . Use `cDisableCaching() <cimport.html#cDisableCaching.m,>`_
## to avoid this scenario during development.
## ##
## ``nim -f`` is currently broken but will eventually allow forcing regeneration. ## ``nim -f`` was broken prior to 0.19.4 but can also be used to flush the cached content.
gStateCT.nocache = true gStateCT.nocache = true
@ -214,7 +231,7 @@ macro cDefine*(name: static string, val: static string = ""): untyped =
macro cAddSearchDir*(dir: static string): untyped = macro cAddSearchDir*(dir: static string): untyped =
## Add directory ``dir`` to the search path used in calls to ## Add directory ``dir`` to the search path used in calls to
## ``cSearchPath()`` ## `cSearchPath() <cimport.html#cSearchPath,string>`_.
## ##
## This allows something like this: ## This allows something like this:
## ##
@ -229,7 +246,8 @@ macro cAddSearchDir*(dir: static string): untyped =
macro cIncludeDir*(dir: static string): untyped = macro cIncludeDir*(dir: static string): untyped =
## Add an include directory that is forwarded to the C/C++ compiler ## Add an include directory that is forwarded to the C/C++ compiler
## using ``{.passC: "-IXXX".}`` ## using ``{.passC: "-IXXX".}``. This is also provided to the
## preprocessor during Nim code generation.
var dir = interpPath(dir) var dir = interpPath(dir)
result = newNimNode(nnkStmtList) result = newNimNode(nnkStmtList)
@ -250,7 +268,7 @@ macro cIncludeDir*(dir: static string): untyped =
macro cAddStdDir*(mode = "c"): untyped = macro cAddStdDir*(mode = "c"): untyped =
## 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()`` ## path used in calls to `cSearchPath() <cimport.html#cSearchPath,string>`_
## ##
## This allows something like this: ## This allows something like this:
## ##
@ -343,11 +361,13 @@ macro cCompile*(path: static string, mode = "c"): untyped =
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 ## Import all supported definitions from specified header file. Generated
## content is cached in ``nimcache`` until ``filename`` changes unless ## content is cached in ``nimcache`` until ``filename`` changes unless
## ``cDisableCaching()`` is set. ## `cDisableCaching() <cimport.html#cDisableCaching.m,>`_ 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 ## ``recurse`` can be used to generate Nim wrappers from ``#include`` files
## referenced in ``filename``. This is only done for files in the same ## referenced in ``filename``. This is only done for files in the same
## directory as ``filename`` or in a directory added using ``cIncludeDir()``. ## directory as ``filename`` or in a directory added using
## `cIncludeDir() <cimport.html#cIncludeDir.m,>`_
result = newNimNode(nnkStmtList) result = newNimNode(nnkStmtList)

View file

@ -105,14 +105,15 @@ proc getUniqueIdentifier*(existing: HashSet[string], prefix = ""): string =
return name & $count return name & $count
proc addNewIdentifer*(existing: var HashSet[string], name: string): bool = proc addNewIdentifer*(existing: var HashSet[string], name: string): bool =
let if name notin gStateRT.symOverride:
nimName = let
if existing == gStateRT.types: nimName =
name[0] & name[1 .. ^1].replace("_", "").toLowerAscii if existing == gStateRT.types:
else: name[0] & name[1 .. ^1].replace("_", "").toLowerAscii
name.replace("_", "").toLowerAscii else:
name.replace("_", "").toLowerAscii
return not existing.containsOrIncl(nimName) return not existing.containsOrIncl(nimName)
proc getPtrType*(str: string): string = proc getPtrType*(str: string): string =
result = case str: result = case str:

View file

@ -5,6 +5,15 @@ gitPull("https://github.com/jarikomppa/soloud", "soloud", "include/*\nsrc/*\n")
cDebug() cDebug()
cDisableCaching() cDisableCaching()
cOverride:
type
Soloud* = pointer
AlignedFloatBuffer* = pointer
proc Soloud_destroy*(aSoloud: ptr Soloud) {.importc: "Soloud_destroy".}
cSkipSymbol("WavStream_stop", "WavStream_setFilter")
const const
inc = "soloud/include" inc = "soloud/include"
src = "soloud/src" src = "soloud/src"
@ -35,4 +44,10 @@ var
echo s.Soloud_init() echo s.Soloud_init()
s.Soloud_destroy() s.Soloud_destroy()
when declared(WavStream_stop):
assert "WavStream_stop() not skipped"
when declared(WavStream_setFilter):
assert "WavStream_setFilter not skipped"

View file

@ -112,6 +112,7 @@ proc main(
debug = false, debug = false,
defines: seq[string] = @[], defines: seq[string] = @[],
includeDirs: seq[string] = @[], includeDirs: seq[string] = @[],
symOverride: seq[string] = @[],
source: seq[string], source: seq[string],
) = ) =
@ -125,6 +126,7 @@ proc main(
debug: debug, debug: debug,
defines: defines, defines: defines,
includeDirs: includeDirs, includeDirs: includeDirs,
symOverride: symOverride
) )
if pgrammar: if pgrammar:
@ -141,6 +143,7 @@ when isMainModule:
"pnim": "print Nim output", "pnim": "print Nim output",
"defines": "definitions to pass to preprocessor", "defines": "definitions to pass to preprocessor",
"includeDirs": "include directory to pass to preprocessor", "includeDirs": "include directory to pass to preprocessor",
"symOverride": "skip generating specified symbols",
"preprocess": "run preprocessor on header", "preprocess": "run preprocessor on header",
"pgrammar": "print grammar", "pgrammar": "print grammar",
"recurse": "process #include files", "recurse": "process #include files",
@ -151,6 +154,7 @@ when isMainModule:
"pnim": 'n', "pnim": 'n',
"defines": 'D', "defines": 'D',
"includeDirs": 'I', "includeDirs": 'I',
"symOverride": 'O',
"preprocess": 'p', "preprocess": 'p',
"recurse": 'r', "recurse": 'r',
"debug": 'd', "debug": 'd',