Updated with feedback
This commit is contained in:
parent
699d56d72e
commit
6c1f458a84
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
|
||||
|
||||
|
|
@ -88,24 +88,24 @@ proc getToast(fullpath: string, recurse: bool = false): string =
|
|||
ret = 0
|
||||
cmd = when defined(Windows): "cmd /c " else: ""
|
||||
|
||||
cmd &= "toast --pnim --preprocess "
|
||||
cmd &= "toast --pnim --preprocess"
|
||||
|
||||
if recurse:
|
||||
cmd.add "--recurse "
|
||||
cmd.add " --recurse"
|
||||
|
||||
for i in gStateCT.defines:
|
||||
cmd.add &"--defines+={i.quoteShell} "
|
||||
cmd.add &" --defines+={i.quoteShell}"
|
||||
|
||||
for i in gStateCT.includeDirs:
|
||||
cmd.add &"--includeDirs+={i.quoteShell} "
|
||||
cmd.add &" --includeDirs+={i.quoteShell}"
|
||||
|
||||
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():
|
||||
cmd.add &"--pluginFile={gStateCT.pluginFile.quoteShell} "
|
||||
if gStateCT.pluginFile.nBl:
|
||||
cmd.add &" --pluginFile={gStateCT.pluginFile.quoteShell}"
|
||||
|
||||
cmd.add &"{fullpath.quoteShell}"
|
||||
cmd.add &" {fullpath.quoteShell}"
|
||||
echo cmd
|
||||
(result, ret) = gorgeEx(cmd, cache=getCacheValue(fullpath))
|
||||
doAssert ret == 0, getToastError(result)
|
||||
|
|
@ -130,7 +130,7 @@ macro cOverride*(body): untyped =
|
|||
##
|
||||
## int svGetCallerInfo(const char** fileName, int *lineNumber);
|
||||
##
|
||||
## This could get mapped to:
|
||||
## This might mapped to:
|
||||
##
|
||||
## .. code-block:: nim
|
||||
##
|
||||
|
|
@ -166,9 +166,8 @@ 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.
|
||||
##
|
||||
## .. code-block:: nim
|
||||
##
|
||||
## cSkipSymbol "proc1", "Type2"
|
||||
runnableExamples:
|
||||
cSkipSymbol "proc1", "Type2"
|
||||
|
||||
for skip in skips:
|
||||
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.
|
||||
## The following callbacks are available at this time.
|
||||
##
|
||||
## .. code-block:: nim
|
||||
##
|
||||
## cPlugin:
|
||||
## import strutils
|
||||
##
|
||||
## proc onSymbol*(sym: string): string {.exportc, dynlib.} =
|
||||
## return sym.strip(chars={'_'})
|
||||
runnableExamples:
|
||||
cPlugin:
|
||||
import strutils
|
||||
|
||||
proc onSymbol*(sym: string): string {.exportc, dynlib.} =
|
||||
return sym.strip(chars={'_'})
|
||||
|
||||
let
|
||||
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)
|
||||
|
||||
doAssert fileExists(path), "Unable to write plugin file: " & path
|
||||
|
||||
gStateCT.pluginFile = path
|
||||
|
||||
proc cSearchPath*(path: string): string {.compileTime.}=
|
||||
|
|
@ -209,8 +211,8 @@ proc cSearchPath*(path: string): string {.compileTime.}=
|
|||
if result.len == 0:
|
||||
var found = false
|
||||
for inc in gStateCT.searchDirs:
|
||||
result = (inc & "/" & path).replace("\\", "/")
|
||||
if fileExists(result) or dirExists(result):
|
||||
result = findPath(inc & "/" & path, fail = false)
|
||||
if result.len != 0:
|
||||
found = true
|
||||
break
|
||||
doAssert found, "File or directory not found: " & path &
|
||||
|
|
@ -297,10 +299,9 @@ macro cAddStdDir*(mode = "c"): untyped =
|
|||
##
|
||||
## This allows something like this:
|
||||
##
|
||||
## .. code-block:: nim
|
||||
##
|
||||
## cAddStdDir()
|
||||
## cImport cSearchPath("math.h")
|
||||
runnableExamples:
|
||||
cAddStdDir()
|
||||
echo cSearchPath("math.h")
|
||||
|
||||
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
|
||||
|
||||
|
|
@ -87,15 +87,18 @@ proc getType*(str: string): string =
|
|||
if gTypeMap.hasKey(result):
|
||||
result = gTypeMap[result]
|
||||
|
||||
template checkUnderscores(str, errmsg: string): untyped =
|
||||
doAssert str[0] != '_' and str[^1] != '_', errmsg
|
||||
|
||||
proc getIdentifier*(str: string): string =
|
||||
doAssert str.len != 0, "Blank identifier error"
|
||||
|
||||
if gStateRT.onSymbol != nil:
|
||||
result = gStateRT.onSymbol(str)
|
||||
checkUnderscores(result, &"Identifier '{str}' still contains leading/trailing underscores '_' after 'cPlugin:onSymbol()': result '{result}'")
|
||||
else:
|
||||
result = str
|
||||
|
||||
doAssert result[0] != '_' and result[^1] != '_', &"Identifier '{result}' with leading/trailing underscore '_' not supported: use cPlugin() to handle"
|
||||
checkUnderscores(result, &"Identifier '{result}' contains unsupported leading/trailing underscores '_': use 'cPlugin:onSymbol()' to handle")
|
||||
|
||||
if result in gReserved:
|
||||
result = &"`{result}`"
|
||||
|
|
@ -317,23 +320,22 @@ proc getSplitComma*(joined: seq[string]): seq[string] =
|
|||
|
||||
proc dll*(path: string): string =
|
||||
let
|
||||
(dir, name, ext) = path.splitFile()
|
||||
(dir, name, _) = path.splitFile()
|
||||
|
||||
when defined(Windows):
|
||||
result = dir/name.addFileExt("dll")
|
||||
when defined(Linux):
|
||||
result = dir/"lib" & name.addFileExt("so")
|
||||
when defined(OSX):
|
||||
result = dir/"lib" & name.addFileExt("dylib")
|
||||
result = dir / (DynlibFormat % name)
|
||||
|
||||
proc loadPlugin*(fullpath: string) =
|
||||
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)
|
||||
doAssert fileExists(fullpath.dll), "No plugin binary generated for " & fullpath
|
||||
doAssert fileExists(pdll), "No plugin binary generated for " & fullpath
|
||||
|
||||
let lib = loadLib(fullpath.dll)
|
||||
doAssert lib != nil, "Plugin load failed"
|
||||
let lib = loadLib(pdll)
|
||||
doAssert lib != nil, "Plugin $1 compiled to $2 failed to load" % [fullpath, pdll]
|
||||
|
||||
gStateRT.onSymbol = cast[proc(sym: string): string {.cdecl.}](lib.symAddr("onSymbol"))
|
||||
doAssert gStateRT.onSymbol != nil, "onSymbol() load failed"
|
||||
gStateRT.onSymbol = cast[typeof(gStateRT.onSymbol)](lib.symAddr("onSymbol"))
|
||||
doAssert gStateRT.onSymbol != nil, "onSymbol() load failed from " & pdll
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import sequtils, sets, tables
|
||||
import macros, sequtils, sets, tables
|
||||
|
||||
import regex
|
||||
|
||||
|
|
@ -45,6 +45,10 @@ type
|
|||
tonim*: proc (ast: ref Ast, node: TSNode)
|
||||
regex*: Regex
|
||||
|
||||
Symbol = object
|
||||
name: string
|
||||
kind: NimSymKind
|
||||
|
||||
State = object
|
||||
compile*, defines*, headers*, includeDirs*, searchDirs*, symOverride*: seq[string]
|
||||
|
||||
|
|
@ -75,4 +79,4 @@ type CompileMode = enum
|
|||
const modeDefault {.used.} = $cpp # TODO: USE this everywhere relevant
|
||||
|
||||
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