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.
__Documentation__
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
Detailed documentation is available for [cimport](https://genotrance.github.io/nimterop/cimport.html) and [git](https://genotrance.github.io/nimterop/git.html).
__Implementation Details__

View file

@ -99,8 +99,8 @@ proc getToast(fullpath: string, recurse: bool = false): string =
for i in gStateCT.includeDirs:
cmd.add &"--includeDirs+={i.quoteShell} "
for i in gStateCT.symOverride:
cmd.add &"--symOverride+={i} "
if gStateCT.symOverride.len != 0:
cmd.add &"--symOverride={gStateCT.symOverride.join(\",\")} "
cmd.add &"{fullpath.quoteShell}"
echo cmd
@ -117,8 +117,9 @@ 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 longer defines these symbols.
## accurate, it may be required to hand wrap them. Define them in a
## `cOverride() <cimport.html#cOverride.m,>`_ macro block so that Nimterop no
## longer defines these symbols.
##
## For example:
##
@ -139,16 +140,17 @@ macro cOverride*(body): untyped =
## 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.
## Using the `cOverride() <cimport.html#cOverride.m,>`_ block, nimterop
## can be instructed to skip over ``svGetCallerInfo()``. This works for procs,
## consts and types.
for sym in body:
case sym.kind:
of nnkProcDef:
gStateCT.symOverride.add $sym[0]
gStateCT.symOverride.add ($sym[0]).strip(chars={'*'})
of nnkConstSection, nnkTypeSection:
for ssym in sym:
gStateCT.symOverride.add $ssym[0]
gStateCT.symOverride.add ($ssym[0]).strip(chars={'*'})
else:
discard
@ -157,12 +159,26 @@ macro cOverride*(body): untyped =
if gStateCT.debug:
echo "Overriding " & gStateCT.symOverride.join(" ")
proc cSearchPath*(path: string): string {.compileTime.}=
## Return a file or directory found in search path configured using
## ``cSearchPath()``
macro cSkipSymbol*(skips: varargs[string]): untyped =
## Similar to `cOverride() <cimport.html#cOverride.m,>`_, this macro allows
## filtering out symbols not of interest from the generated output.
##
## This proc can be used to locate files or directories in calls to
## ``cCompile()``, ``cIncludeDir()`` and ``cImport()``.
## .. code-block:: nim
##
## 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)
if result.len == 0:
@ -183,11 +199,12 @@ macro cDebug*(): untyped =
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.
## If files included by header being processed by `cImport() <cimport.html#cImport.m,>`_
## change and affect the generated content, they will be ignored and the cached
## 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
@ -214,7 +231,7 @@ macro cDefine*(name: static string, val: static string = ""): untyped =
macro cAddSearchDir*(dir: static string): untyped =
## Add directory ``dir`` to the search path used in calls to
## ``cSearchPath()``
## `cSearchPath() <cimport.html#cSearchPath,string>`_.
##
## This allows something like this:
##
@ -229,7 +246,8 @@ macro cAddSearchDir*(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".}``
## using ``{.passC: "-IXXX".}``. This is also provided to the
## preprocessor during Nim code generation.
var dir = interpPath(dir)
result = newNimNode(nnkStmtList)
@ -250,7 +268,7 @@ macro cIncludeDir*(dir: static string): untyped =
macro cAddStdDir*(mode = "c"): untyped =
## 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:
##
@ -343,11 +361,13 @@ 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.
## `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
## 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)

View file

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

View file

@ -5,6 +5,15 @@ gitPull("https://github.com/jarikomppa/soloud", "soloud", "include/*\nsrc/*\n")
cDebug()
cDisableCaching()
cOverride:
type
Soloud* = pointer
AlignedFloatBuffer* = pointer
proc Soloud_destroy*(aSoloud: ptr Soloud) {.importc: "Soloud_destroy".}
cSkipSymbol("WavStream_stop", "WavStream_setFilter")
const
inc = "soloud/include"
src = "soloud/src"
@ -35,4 +44,10 @@ var
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,
defines: seq[string] = @[],
includeDirs: seq[string] = @[],
symOverride: seq[string] = @[],
source: seq[string],
) =
@ -125,6 +126,7 @@ proc main(
debug: debug,
defines: defines,
includeDirs: includeDirs,
symOverride: symOverride
)
if pgrammar:
@ -141,6 +143,7 @@ when isMainModule:
"pnim": "print Nim output",
"defines": "definitions to pass to preprocessor",
"includeDirs": "include directory to pass to preprocessor",
"symOverride": "skip generating specified symbols",
"preprocess": "run preprocessor on header",
"pgrammar": "print grammar",
"recurse": "process #include files",
@ -151,6 +154,7 @@ when isMainModule:
"pnim": 'n',
"defines": 'D',
"includeDirs": 'I',
"symOverride": 'O',
"preprocess": 'p',
"recurse": 'r',
"debug": 'd',