Add cImport for multiple headers
This commit is contained in:
parent
f17b958f47
commit
c1f46680f7
3 changed files with 99 additions and 37 deletions
|
|
@ -51,6 +51,9 @@ task test, "Test":
|
||||||
execTest "tests/tpcre.nim"
|
execTest "tests/tpcre.nim"
|
||||||
execTest "tests/tpcre.nim", "-d:FLAGS=\"-f:ast2\""
|
execTest "tests/tpcre.nim", "-d:FLAGS=\"-f:ast2\""
|
||||||
|
|
||||||
|
execTest "tests/rsa.nim"
|
||||||
|
execTest "tests/rsa.nim", "-d:FLAGS=\"-H\""
|
||||||
|
|
||||||
# Platform specific tests
|
# Platform specific tests
|
||||||
when defined(Windows):
|
when defined(Windows):
|
||||||
execTest "tests/tmath.nim"
|
execTest "tests/tmath.nim"
|
||||||
|
|
|
||||||
|
|
@ -91,6 +91,11 @@ proc getCacheValue(fullpath: string): string =
|
||||||
if not gStateCT.nocache:
|
if not gStateCT.nocache:
|
||||||
result = fullpath.getFileDate()
|
result = fullpath.getFileDate()
|
||||||
|
|
||||||
|
proc getCacheValue(fullpaths: seq[string]): string =
|
||||||
|
if not gStateCT.nocache:
|
||||||
|
for fullpath in fullpaths:
|
||||||
|
result &= getCacheValue(fullpath)
|
||||||
|
|
||||||
proc getToastError(output: string): string =
|
proc getToastError(output: string): string =
|
||||||
# Filter out preprocessor errors
|
# Filter out preprocessor errors
|
||||||
for line in output.splitLines():
|
for line in output.splitLines():
|
||||||
|
|
@ -121,7 +126,7 @@ proc getNimCheckError(output: string): tuple[tmpFile, errors: string] =
|
||||||
|
|
||||||
result.errors = "\n\n" & check
|
result.errors = "\n\n" & check
|
||||||
|
|
||||||
proc getToast(fullpath: string, recurse: bool = false, dynlib: string = "",
|
proc getToast(fullpaths: seq[string], recurse: bool = false, dynlib: string = "",
|
||||||
mode = "c", flags = "", noNimout = false): string =
|
mode = "c", flags = "", noNimout = false): string =
|
||||||
var
|
var
|
||||||
ret = 0
|
ret = 0
|
||||||
|
|
@ -158,11 +163,12 @@ proc getToast(fullpath: string, recurse: bool = false, dynlib: string = "",
|
||||||
if gStateCT.pluginSourcePath.nBl:
|
if gStateCT.pluginSourcePath.nBl:
|
||||||
cmd.add &" --pluginSourcePath={gStateCT.pluginSourcePath.sanitizePath}"
|
cmd.add &" --pluginSourcePath={gStateCT.pluginSourcePath.sanitizePath}"
|
||||||
|
|
||||||
cmd.add &" {fullpath.sanitizePath}"
|
for fullpath in fullpaths:
|
||||||
|
cmd.add &" {fullpath.sanitizePath}"
|
||||||
|
|
||||||
# see https://github.com/nimterop/nimterop/issues/69
|
# see https://github.com/nimterop/nimterop/issues/69
|
||||||
(result, ret) = execAction(cmd, die = false, cache = (not gStateCT.nocache),
|
(result, ret) = execAction(cmd, die = false, cache = (not gStateCT.nocache),
|
||||||
cacheKey = getCacheValue(fullpath))
|
cacheKey = getCacheValue(fullpaths))
|
||||||
doAssert ret == 0, getToastError(result)
|
doAssert ret == 0, getToastError(result)
|
||||||
|
|
||||||
macro cOverride*(body): untyped =
|
macro cOverride*(body): untyped =
|
||||||
|
|
@ -555,6 +561,46 @@ macro cCompile*(path: static string, mode = "c", exclude = ""): untyped =
|
||||||
if gStateCT.debug:
|
if gStateCT.debug:
|
||||||
echo result.repr
|
echo result.repr
|
||||||
|
|
||||||
|
macro cImport*(filenames: static seq[string], recurse: static bool = false, dynlib: static string = "",
|
||||||
|
mode: static string = "c", flags: static string = ""): untyped =
|
||||||
|
## Import multiple headers in one shot
|
||||||
|
##
|
||||||
|
## This macro is preferable over multiple individual `cImport()` calls, especially
|
||||||
|
## when the headers might `#include` the same headers and result in duplicate symbols.
|
||||||
|
result = newNimNode(nnkStmtList)
|
||||||
|
|
||||||
|
var
|
||||||
|
fullpaths: seq[string]
|
||||||
|
|
||||||
|
for filename in filenames:
|
||||||
|
fullpaths.add findPath(filename)
|
||||||
|
|
||||||
|
# In case cOverride called after cPlugin
|
||||||
|
if gStateCT.pluginSourcePath.Bl:
|
||||||
|
cPluginHelper(gStateCT.pluginSource)
|
||||||
|
|
||||||
|
echo "# Importing " & fullpaths.join(", ").sanitizePath
|
||||||
|
|
||||||
|
let
|
||||||
|
output = getToast(fullpaths, recurse, dynlib, mode, flags)
|
||||||
|
|
||||||
|
# Reset plugin and overrides for next cImport
|
||||||
|
if gStateCT.overrides.nBl:
|
||||||
|
gStateCT.pluginSourcePath = ""
|
||||||
|
gStateCT.overrides = ""
|
||||||
|
|
||||||
|
if gStateCT.debug:
|
||||||
|
echo output
|
||||||
|
|
||||||
|
try:
|
||||||
|
let body = parseStmt(output)
|
||||||
|
|
||||||
|
result.add body
|
||||||
|
except:
|
||||||
|
let
|
||||||
|
(tmpFile, errors) = getNimCheckError(output)
|
||||||
|
doAssert false, errors & "\n\nNimterop codegen limitation or error - review 'nim check' output above generated for " & tmpFile
|
||||||
|
|
||||||
macro cImport*(filename: static string, recurse: static bool = false, dynlib: static string = "",
|
macro cImport*(filename: static string, recurse: static bool = false, dynlib: static string = "",
|
||||||
mode: static string = "c", flags: static string = ""): untyped =
|
mode: static string = "c", flags: static string = ""): untyped =
|
||||||
## Import all supported definitions from specified header file. Generated
|
## Import all supported definitions from specified header file. Generated
|
||||||
|
|
@ -590,8 +636,8 @@ macro cImport*(filename: static string, recurse: static bool = false, dynlib: st
|
||||||
## with `cCompile() <cimport.html#cCompile.m%2C%2Cstring%2Cstring>`_, or the
|
## with `cCompile() <cimport.html#cCompile.m%2C%2Cstring%2Cstring>`_, or the
|
||||||
## `{.passL.}` pragma can be used to specify the static lib to link.
|
## `{.passL.}` pragma can be used to specify the static lib to link.
|
||||||
##
|
##
|
||||||
## `mode` is purely for forward compatibility when toast adds C++ support. It can
|
## `mode` selects the preprocessor and tree-sitter parser to be used to process
|
||||||
## be ignored for the foreseeable future.
|
## the header.
|
||||||
##
|
##
|
||||||
## `flags` can be used to pass any other command line arguments to `toast`. A
|
## `flags` can be used to pass any other command line arguments to `toast`. A
|
||||||
## good example would be `--prefix` and `--suffix` which strip leading and
|
## good example would be `--prefix` and `--suffix` which strip leading and
|
||||||
|
|
@ -600,37 +646,8 @@ macro cImport*(filename: static string, recurse: static bool = false, dynlib: st
|
||||||
## `cImport()` consumes and resets preceding `cOverride()` calls. `cPlugin()`
|
## `cImport()` consumes and resets preceding `cOverride()` calls. `cPlugin()`
|
||||||
## is retained for the next `cImport()` call unless a new `cPlugin()` call is
|
## is retained for the next `cImport()` call unless a new `cPlugin()` call is
|
||||||
## defined.
|
## defined.
|
||||||
|
return quote do:
|
||||||
result = newNimNode(nnkStmtList)
|
cImport(@[`filename`], bool(`recurse`), `dynlib`, `mode`, `flags`)
|
||||||
|
|
||||||
let
|
|
||||||
fullpath = findPath(filename)
|
|
||||||
|
|
||||||
# In case cOverride called after cPlugin
|
|
||||||
if gStateCT.pluginSourcePath.Bl:
|
|
||||||
cPluginHelper(gStateCT.pluginSource)
|
|
||||||
|
|
||||||
echo "# Importing " & fullpath.sanitizePath
|
|
||||||
|
|
||||||
let
|
|
||||||
output = getToast(fullpath, recurse, dynlib, mode, flags)
|
|
||||||
|
|
||||||
# Reset plugin and overrides for next cImport
|
|
||||||
if gStateCT.overrides.nBl:
|
|
||||||
gStateCT.pluginSourcePath = ""
|
|
||||||
gStateCT.overrides = ""
|
|
||||||
|
|
||||||
if gStateCT.debug:
|
|
||||||
echo output
|
|
||||||
|
|
||||||
try:
|
|
||||||
let body = parseStmt(output)
|
|
||||||
|
|
||||||
result.add body
|
|
||||||
except:
|
|
||||||
let
|
|
||||||
(tmpFile, errors) = getNimCheckError(output)
|
|
||||||
doAssert false, errors & "\n\nNimterop codegen limitation or error - review 'nim check' output above generated for " & tmpFile
|
|
||||||
|
|
||||||
macro c2nImport*(filename: static string, recurse: static bool = false, dynlib: static string = "",
|
macro c2nImport*(filename: static string, recurse: static bool = false, dynlib: static string = "",
|
||||||
mode: static string = "c", flags: static string = ""): untyped =
|
mode: static string = "c", flags: static string = ""): untyped =
|
||||||
|
|
@ -661,7 +678,7 @@ macro c2nImport*(filename: static string, recurse: static bool = false, dynlib:
|
||||||
echo "# Importing " & fullpath & " with c2nim"
|
echo "# Importing " & fullpath & " with c2nim"
|
||||||
|
|
||||||
let
|
let
|
||||||
output = getToast(fullpath, recurse, dynlib, noNimout = true)
|
output = getToast(@[fullpath], recurse, dynlib, noNimout = true)
|
||||||
hash = output.hash().abs()
|
hash = output.hash().abs()
|
||||||
hpath = getProjectCacheDir("c2nimCache", forceClean = false) / "nimterop_" & $hash & ".h"
|
hpath = getProjectCacheDir("c2nimCache", forceClean = false) / "nimterop_" & $hash & ".h"
|
||||||
npath = hpath[0 .. hpath.rfind('.')] & "nim"
|
npath = hpath[0 .. hpath.rfind('.')] & "nim"
|
||||||
|
|
|
||||||
42
tests/rsa.nim
Normal file
42
tests/rsa.nim
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
import os
|
||||||
|
import strutils
|
||||||
|
|
||||||
|
import nimterop/[build, cimport]
|
||||||
|
|
||||||
|
setDefines(@["cryptoStd"])
|
||||||
|
getHeader("openssl/crypto.h")
|
||||||
|
|
||||||
|
const
|
||||||
|
basePath = cryptoPath.parentDir
|
||||||
|
FLAGS {.strdefine.} = ""
|
||||||
|
|
||||||
|
cPlugin:
|
||||||
|
import strutils
|
||||||
|
|
||||||
|
proc onSymbol*(sym: var Symbol) {.exportc, dynlib.} =
|
||||||
|
sym.name = sym.name.strip(chars = {'_'}).replace("__", "_")
|
||||||
|
|
||||||
|
if sym.name in [
|
||||||
|
"AES_ENCRYPT", "AES_DECRYPT",
|
||||||
|
"BIO_CTRL_PENDING", "BIO_CTRL_WPENDING",
|
||||||
|
"BN_F_BNRAND", "BN_F_BNRAND_RANGE",
|
||||||
|
"CRYPTO_THREADID",
|
||||||
|
"EVP_CIPHER",
|
||||||
|
"OPENSSL_VERSION",
|
||||||
|
"PKCS7_ENCRYPT", "PKCS7_STREAM",
|
||||||
|
"SSL_TXT_ADH", "SSL_TXT_AECDH", "SSL_TXT_kECDHE"
|
||||||
|
]:
|
||||||
|
sym.name = "C_" & sym.name
|
||||||
|
|
||||||
|
cOverride:
|
||||||
|
proc OPENSSL_die*(assertion: cstring; file: cstring; line: cint) {.importc.}
|
||||||
|
|
||||||
|
cImport(@[
|
||||||
|
basePath / "rsa.h",
|
||||||
|
basePath / "err.h",
|
||||||
|
], recurse = true, flags = "-f:ast2 -s " & FLAGS)
|
||||||
|
|
||||||
|
{.passL: cryptoLPath.}
|
||||||
|
|
||||||
|
OpensslInit()
|
||||||
|
echo $OPENSSL_VERSION_TEXT
|
||||||
Loading…
Add table
Add a link
Reference in a new issue