ast2 static inline with -H, fix #188, --replace support

This commit is contained in:
Ganesh Viswanathan 2020-04-20 12:28:14 -05:00
commit ab0439e60e
8 changed files with 61 additions and 16 deletions

View file

@ -184,6 +184,7 @@ Options:
-E=, --prefix= strings {} strip prefix from identifiers
-p, --preprocess bool false run preprocessor on header
-r, --recurse bool false process #include files
-G=, --replace= strings {} replace X with Y in identifiers, X1=Y1,X2=Y2, @X for regex
-s, --stub bool false stub out undefined type references as objects
-F=, --suffix= strings {} strip suffix from identifiers
-O=, --symOverride= strings {} skip generating specified symbols

View file

@ -1,7 +1,5 @@
##[
Module that should import everything so that `nim doc --project nimtero/all` runs docs on everything.
The following modules are available to users of Nimterop.
]##
# TODO: make sure it does import everything.
import "."/[docs, cimport, build, types, plugin]

View file

@ -1636,6 +1636,22 @@ proc addDecl(nimState: NimState, node: TSNode) =
# Regular var
discard
proc addDef(nimState: NimState, node: TSNode) =
# Wrap static inline definition if {.header.} mode is specified
#
# Without {.header.} the definition will not be available to the C compiler
# and will fail at link time
decho("addDef()")
nimState.printDebug(node)
let
start = getStartAtom(node)
if node[start+1].getName() == "function_declarator":
if nimState.includeHeader():
nimState.addProc(node[start+1], node[start])
else:
necho &"\n# proc '$1' skipped - static inline procs require 'includeHeader'" %
nimState.getNodeVal(node[start+1].getAtom())
proc processNode(nimState: NimState, node: TSNode): bool =
result = true
@ -1658,11 +1674,7 @@ proc processNode(nimState: NimState, node: TSNode): bool =
of "declaration":
nimState.addDecl(node)
of "function_definition":
# Handle static inline
let
start = getStartAtom(node)
if node[start+1].getName() == "function_declarator":
nimState.addProc(node[start+1], node[start])
nimState.addDef(node)
else:
# Unknown
result = false

View file

@ -137,6 +137,13 @@ proc getIdentifier*(nimState: NimState, name: string, kind: NimSymKind, parent="
if result.endsWith(str):
result = result[0 .. ^(str.len+1)]
# --replace from CLI if specified
for name, value in nimState.gState.replace.pairs:
if name.len > 1 and name[0] == '@':
result = result.replace(re(name[1 .. ^1]), value)
else:
result = result.replace(name, value)
checkIdentifier(result, $kind, parent, name)
if result in gReserved or (result == "object" and kind != nskType):
@ -738,6 +745,6 @@ proc loadPlugin*(gState: State, sourcePath: string) =
proc expandSymlinkAbs*(path: string): string =
try:
result = path.expandSymlink().absolutePath(path.parentDir()).normalizedPath()
result = path.expandFilename().expandSymlink().normalizedPath()
except:
result = path

View file

@ -61,6 +61,8 @@ type
code*, convention*, dynlib*, mode*, nim*, overrides*, pluginSource*, pluginSourcePath*: string
replace*: OrderedTableRef[string, string]
feature*: seq[Feature]
onSymbol*, onSymbolOverride*: OnSymbol

View file

@ -1,4 +1,4 @@
import os, osproc, strformat, strutils, times
import os, osproc, strformat, strutils, tables, times
import "."/treesitter/[api, c, cpp]
@ -67,6 +67,7 @@ proc main(
prefix: seq[string] = @[],
preprocess = false,
recurse = false,
replace: seq[string] = @[],
stub = false,
suffix: seq[string] = @[],
symOverride: seq[string] = @[],
@ -91,6 +92,7 @@ proc main(
prefix: prefix,
preprocess: preprocess,
recurse: recurse,
replace: newOrderedTable[string, string](),
suffix: suffix,
symOverride: symOverride
)
@ -104,6 +106,14 @@ proc main(
gState.prefix = gState.prefix.getSplitComma()
gState.suffix = gState.suffix.getSplitComma()
# Replace => Table
for i in replace.getSplitComma():
let
nv = i.split("=", maxsplit = 1)
name = nv[0]
value = if nv.len == 2: nv[1] else: ""
gState.replace[name] = value
if pluginSourcePath.nBl:
gState.loadPlugin(pluginSourcePath)
@ -205,10 +215,11 @@ when isMainModule:
"pgrammar": "print grammar",
"pluginSourcePath": "nim file to build and load as a plugin",
"pnim": "print Nim output",
"prefix": "strip prefix from identifiers",
"preprocess": "run preprocessor on header",
"recurse": "process #include files",
"replace": "replace X with Y in identifiers, X1=Y1,X2=Y2, @X for regex",
"source" : "C/C++ source/header",
"prefix": "strip prefix from identifiers",
"stub": "stub out undefined type references as objects",
"suffix": "strip suffix from identifiers",
"symOverride": "skip generating specified symbols"
@ -229,6 +240,7 @@ when isMainModule:
"prefix": 'E',
"preprocess": 'p',
"recurse": 'r',
"replace": 'G',
"stub": 's',
"suffix": 'F',
"symOverride": 'O'

View file

@ -198,6 +198,10 @@ typedef struct {
enum { NEV6 = 8 * 8, NEV7 } f8;
} nested;
static inline int sitest1(int f1) {
return f1 * 2;
}
// DUPLICATES
@ -390,6 +394,10 @@ typedef struct {
enum { NEV6 = 8 * 8, NEV7 } f8;
} nested;
static inline int sitest1(int f1) {
return f1 * 2;
}
#endif

View file

@ -32,7 +32,7 @@ cOverride:
type
A1* = A0
cImport(path, flags="-f:ast2 -ENK_,SDL_" & flags)
cImport(path, flags="-f:ast2 -ENK_,SDL_ -GVICE=SLICE" & flags)
proc getPragmas(n: NimNode): HashSet[string] =
# Find all pragmas in AST, return as "name" or "name:value" in set
@ -355,9 +355,10 @@ testFields(fieldfuncfunc,
assert func2 is proc (f1: cint; sfunc2: proc (f1: cint; ssfunc2: proc (f1: cint): ptr cint {.cdecl.}): ptr cint {.cdecl.}): ptr cint {.cdecl.}
assert BASS_DEVICEINFO is object
testFields(BASS_DEVICEINFO, "name|driver|flags!cstring|cstring|cint")
checkPragmas(BASS_DEVICEINFO, pHeaderImpBy)
# Test --replace VICE=SLICE
assert BASS_DESLICEINFO is object
testFields(BASS_DESLICEINFO, "name|driver|flags!cstring|cstring|cint")
checkPragmas(BASS_DESLICEINFO, pHeaderImpBy)
# Issue #183
assert GPU_Target is object
@ -419,4 +420,8 @@ assert NEV7 == 65
assert nested is object
testFields(nested, "f1|f2|f3|f4|f5|f6|f7|f8!NT1|Type_tast2h1|NT3|Type_tast2h3|NU2|Union_tast2h1|NE1|Enum_tast2h2")
checkPragmas(nested, pHeaderImpBy)
checkPragmas(nested, pHeaderImpBy)
when defined(HEADER):
assert sitest1(5) == 10
assert sitest1(10) == 20