aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGanesh Viswanathan <dev@genotrance.com>2019-01-25 16:41:54 -0600
committerGanesh Viswanathan <dev@genotrance.com>2019-01-25 16:41:54 -0600
commit2d447a317bb148ffc6169f6117600f44774d366c (patch)
tree75eecd27d6985da119c55175de04d0ad19c433a8
parentde775468c3dc8b30882d69fef0893585db85876f (diff)
downloadnimterop-2d447a317bb148ffc6169f6117600f44774d366c.tar.gz
nimterop-2d447a317bb148ffc6169f6117600f44774d366c.zip
Updated with feedback
-rw-r--r--nimterop/cimport.nim57
-rw-r--r--nimterop/getters.nim34
-rw-r--r--nimterop/globals.nim8
3 files changed, 53 insertions, 46 deletions
diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim
index 330654f..bd330b4 100644
--- a/nimterop/cimport.nim
+++ b/nimterop/cimport.nim
@@ -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)
diff --git a/nimterop/getters.nim b/nimterop/getters.nim
index f287729..1327d22 100644
--- a/nimterop/getters.nim
+++ b/nimterop/getters.nim
@@ -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
diff --git a/nimterop/globals.nim b/nimterop/globals.nim
index e24e51d..22b2794 100644
--- a/nimterop/globals.nim
+++ b/nimterop/globals.nim
@@ -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 \ No newline at end of file
+ export gAtoms, gExpressions, gEnumVals, Kind, Ast, Symbol, State, gStateRT, nBl, CompileMode, modeDefault \ No newline at end of file