Updated with feedback
This commit is contained in:
parent
de775468c3
commit
2d447a317b
3 changed files with 53 additions and 46 deletions
|
|
@ -1,4 +1,4 @@
|
||||||
import hashes, macros, os, ospaths, strformat, strutils
|
import hashes, macros, os, strformat, strutils
|
||||||
|
|
||||||
const CIMPORT {.used.} = 1
|
const CIMPORT {.used.} = 1
|
||||||
|
|
||||||
|
|
@ -102,7 +102,7 @@ proc getToast(fullpath: string, recurse: bool = false): string =
|
||||||
if gStateCT.symOverride.len != 0:
|
if gStateCT.symOverride.len != 0:
|
||||||
cmd.add &" --symOverride={gStateCT.symOverride.join(\",\")}"
|
cmd.add &" --symOverride={gStateCT.symOverride.join(\",\")}"
|
||||||
|
|
||||||
if gStateCT.pluginFile.nBl and gStateCT.pluginFile.fileExists():
|
if gStateCT.pluginFile.nBl:
|
||||||
cmd.add &" --pluginFile={gStateCT.pluginFile.quoteShell}"
|
cmd.add &" --pluginFile={gStateCT.pluginFile.quoteShell}"
|
||||||
|
|
||||||
cmd.add &" {fullpath.quoteShell}"
|
cmd.add &" {fullpath.quoteShell}"
|
||||||
|
|
@ -130,7 +130,7 @@ macro cOverride*(body): untyped =
|
||||||
##
|
##
|
||||||
## int svGetCallerInfo(const char** fileName, int *lineNumber);
|
## int svGetCallerInfo(const char** fileName, int *lineNumber);
|
||||||
##
|
##
|
||||||
## This could get mapped to:
|
## This might mapped to:
|
||||||
##
|
##
|
||||||
## .. code-block:: nim
|
## .. code-block:: nim
|
||||||
##
|
##
|
||||||
|
|
@ -166,9 +166,8 @@ macro cSkipSymbol*(skips: varargs[string]): untyped =
|
||||||
## Similar to `cOverride() <cimport.html#cOverride.m,>`_, this macro allows
|
## Similar to `cOverride() <cimport.html#cOverride.m,>`_, this macro allows
|
||||||
## filtering out symbols not of interest from the generated output.
|
## filtering out symbols not of interest from the generated output.
|
||||||
##
|
##
|
||||||
## .. code-block:: nim
|
runnableExamples:
|
||||||
##
|
cSkipSymbol "proc1", "Type2"
|
||||||
## cSkipSymbol "proc1", "Type2"
|
|
||||||
|
|
||||||
for skip in skips:
|
for skip in skips:
|
||||||
gStateCT.symOverride.add skip.strVal
|
gStateCT.symOverride.add skip.strVal
|
||||||
|
|
@ -178,21 +177,24 @@ macro cPlugin*(body): untyped =
|
||||||
## are not adequate, the `cPlugin() <cimport.html#cPlugin.m,>`_ macro can be used to customize the generated Nim output.
|
## are not adequate, the `cPlugin() <cimport.html#cPlugin.m,>`_ macro can be used to customize the generated Nim output.
|
||||||
## The following callbacks are available at this time.
|
## The following callbacks are available at this time.
|
||||||
##
|
##
|
||||||
## .. code-block:: nim
|
runnableExamples:
|
||||||
##
|
cPlugin:
|
||||||
## cPlugin:
|
import strutils
|
||||||
## import strutils
|
|
||||||
##
|
proc onSymbol*(sym: string): string {.exportc, dynlib.} =
|
||||||
## proc onSymbol*(sym: string): string {.exportc, dynlib.} =
|
return sym.strip(chars={'_'})
|
||||||
## return sym.strip(chars={'_'})
|
|
||||||
|
|
||||||
let
|
let
|
||||||
data = body.repr
|
data = body.repr
|
||||||
path = getTempDir() / "nimterop" & ($data.hash() & ".nim")
|
hash = data.hash()
|
||||||
|
phash = if hash<0: -hash else: hash
|
||||||
|
path = getTempDir() / "nimterop_" & $phash & ".nim"
|
||||||
|
|
||||||
if not fileExists(path):
|
if not fileExists(path) or gStateCT.nocache:
|
||||||
writeFile(path, data)
|
writeFile(path, data)
|
||||||
|
|
||||||
|
doAssert fileExists(path), "Unable to write plugin file: " & path
|
||||||
|
|
||||||
gStateCT.pluginFile = path
|
gStateCT.pluginFile = path
|
||||||
|
|
||||||
proc cSearchPath*(path: string): string {.compileTime.}=
|
proc cSearchPath*(path: string): string {.compileTime.}=
|
||||||
|
|
@ -209,8 +211,8 @@ proc cSearchPath*(path: string): string {.compileTime.}=
|
||||||
if result.len == 0:
|
if result.len == 0:
|
||||||
var found = false
|
var found = false
|
||||||
for inc in gStateCT.searchDirs:
|
for inc in gStateCT.searchDirs:
|
||||||
result = (inc & "/" & path).replace("\\", "/")
|
result = findPath(inc & "/" & path, fail = false)
|
||||||
if fileExists(result) or dirExists(result):
|
if result.len != 0:
|
||||||
found = true
|
found = true
|
||||||
break
|
break
|
||||||
doAssert found, "File or directory not found: " & path &
|
doAssert found, "File or directory not found: " & path &
|
||||||
|
|
@ -297,10 +299,9 @@ macro cAddStdDir*(mode = "c"): untyped =
|
||||||
##
|
##
|
||||||
## This allows something like this:
|
## This allows something like this:
|
||||||
##
|
##
|
||||||
## .. code-block:: nim
|
runnableExamples:
|
||||||
##
|
cAddStdDir()
|
||||||
## cAddStdDir()
|
echo cSearchPath("math.h")
|
||||||
## cImport cSearchPath("math.h")
|
|
||||||
|
|
||||||
result = newNimNode(nnkStmtList)
|
result = newNimNode(nnkStmtList)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import dynlib, macros, os, sequtils, sets, strformat, strutils, tables
|
import dynlib, macros, os, sequtils, sets, strformat, strutils, tables, times
|
||||||
|
|
||||||
import regex
|
import regex
|
||||||
|
|
||||||
|
|
@ -87,15 +87,18 @@ proc getType*(str: string): string =
|
||||||
if gTypeMap.hasKey(result):
|
if gTypeMap.hasKey(result):
|
||||||
result = gTypeMap[result]
|
result = gTypeMap[result]
|
||||||
|
|
||||||
|
template checkUnderscores(str, errmsg: string): untyped =
|
||||||
|
doAssert str[0] != '_' and str[^1] != '_', errmsg
|
||||||
|
|
||||||
proc getIdentifier*(str: string): string =
|
proc getIdentifier*(str: string): string =
|
||||||
doAssert str.len != 0, "Blank identifier error"
|
doAssert str.len != 0, "Blank identifier error"
|
||||||
|
|
||||||
if gStateRT.onSymbol != nil:
|
if gStateRT.onSymbol != nil:
|
||||||
result = gStateRT.onSymbol(str)
|
result = gStateRT.onSymbol(str)
|
||||||
|
checkUnderscores(result, &"Identifier '{str}' still contains leading/trailing underscores '_' after 'cPlugin:onSymbol()': result '{result}'")
|
||||||
else:
|
else:
|
||||||
result = str
|
result = str
|
||||||
|
checkUnderscores(result, &"Identifier '{result}' contains unsupported leading/trailing underscores '_': use 'cPlugin:onSymbol()' to handle")
|
||||||
doAssert result[0] != '_' and result[^1] != '_', &"Identifier '{result}' with leading/trailing underscore '_' not supported: use cPlugin() to handle"
|
|
||||||
|
|
||||||
if result in gReserved:
|
if result in gReserved:
|
||||||
result = &"`{result}`"
|
result = &"`{result}`"
|
||||||
|
|
@ -317,23 +320,22 @@ proc getSplitComma*(joined: seq[string]): seq[string] =
|
||||||
|
|
||||||
proc dll*(path: string): string =
|
proc dll*(path: string): string =
|
||||||
let
|
let
|
||||||
(dir, name, ext) = path.splitFile()
|
(dir, name, _) = path.splitFile()
|
||||||
|
|
||||||
when defined(Windows):
|
result = dir / (DynlibFormat % name)
|
||||||
result = dir/name.addFileExt("dll")
|
|
||||||
when defined(Linux):
|
|
||||||
result = dir/"lib" & name.addFileExt("so")
|
|
||||||
when defined(OSX):
|
|
||||||
result = dir/"lib" & name.addFileExt("dylib")
|
|
||||||
|
|
||||||
proc loadPlugin*(fullpath: string) =
|
proc loadPlugin*(fullpath: string) =
|
||||||
doAssert fileExists(fullpath), "Plugin file does not exist: " & fullpath
|
doAssert fileExists(fullpath), "Plugin file does not exist: " & fullpath
|
||||||
if not fileExists(fullpath.dll):
|
|
||||||
|
let
|
||||||
|
pdll = fullpath.dll
|
||||||
|
if not fileExists(pdll) or
|
||||||
|
fullpath.getLastModificationTime() > pdll.getLastModificationTime():
|
||||||
discard execAction("nim c --app:lib " & fullpath)
|
discard execAction("nim c --app:lib " & fullpath)
|
||||||
doAssert fileExists(fullpath.dll), "No plugin binary generated for " & fullpath
|
doAssert fileExists(pdll), "No plugin binary generated for " & fullpath
|
||||||
|
|
||||||
let lib = loadLib(fullpath.dll)
|
let lib = loadLib(pdll)
|
||||||
doAssert lib != nil, "Plugin load failed"
|
doAssert lib != nil, "Plugin $1 compiled to $2 failed to load" % [fullpath, pdll]
|
||||||
|
|
||||||
gStateRT.onSymbol = cast[proc(sym: string): string {.cdecl.}](lib.symAddr("onSymbol"))
|
gStateRT.onSymbol = cast[typeof(gStateRT.onSymbol)](lib.symAddr("onSymbol"))
|
||||||
doAssert gStateRT.onSymbol != nil, "onSymbol() load failed"
|
doAssert gStateRT.onSymbol != nil, "onSymbol() load failed from " & pdll
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import sequtils, sets, tables
|
import macros, sequtils, sets, tables
|
||||||
|
|
||||||
import regex
|
import regex
|
||||||
|
|
||||||
|
|
@ -45,6 +45,10 @@ type
|
||||||
tonim*: proc (ast: ref Ast, node: TSNode)
|
tonim*: proc (ast: ref Ast, node: TSNode)
|
||||||
regex*: Regex
|
regex*: Regex
|
||||||
|
|
||||||
|
Symbol = object
|
||||||
|
name: string
|
||||||
|
kind: NimSymKind
|
||||||
|
|
||||||
State = object
|
State = object
|
||||||
compile*, defines*, headers*, includeDirs*, searchDirs*, symOverride*: seq[string]
|
compile*, defines*, headers*, includeDirs*, searchDirs*, symOverride*: seq[string]
|
||||||
|
|
||||||
|
|
@ -75,4 +79,4 @@ type CompileMode = enum
|
||||||
const modeDefault {.used.} = $cpp # TODO: USE this everywhere relevant
|
const modeDefault {.used.} = $cpp # TODO: USE this everywhere relevant
|
||||||
|
|
||||||
when not declared(CIMPORT):
|
when not declared(CIMPORT):
|
||||||
export gAtoms, gExpressions, gEnumVals, Kind, Ast, State, gStateRT, nBl, CompileMode, modeDefault
|
export gAtoms, gExpressions, gEnumVals, Kind, Ast, Symbol, State, gStateRT, nBl, CompileMode, modeDefault
|
||||||
Loading…
Add table
Add a link
Reference in a new issue