Fix #146 - prefix/suffix for stripping
This commit is contained in:
parent
0db54af54f
commit
bce8e09073
6 changed files with 110 additions and 77 deletions
28
README.md
28
README.md
|
|
@ -93,23 +93,25 @@ The `toast` binary can also be used directly on the CLI:
|
|||
toast -h
|
||||
Usage:
|
||||
main [optional-params] C/C++ source/header
|
||||
Options(opt-arg sep :|=|spc):
|
||||
Options(opt-arg sep :|=|spc):
|
||||
-h, --help print this cligen-erated help
|
||||
--help-syntax advanced: prepend, multi-val,..
|
||||
-p, --preprocess bool false run preprocessor on header
|
||||
-a, --past bool false print AST output
|
||||
-n, --pnim bool false print Nim output
|
||||
-r, --recurse bool false process #include files
|
||||
-c, --nocomments bool false exclude top-level comments from output
|
||||
-D=, --defines= strings {} definitions to pass to preprocessor
|
||||
-I=, --includeDirs= strings {} include directory to pass to preprocessor
|
||||
-l=, --dynlib= string "" Import symbols from library in specified Nim string
|
||||
-O=, --symOverride= strings {} skip generating specified symbols
|
||||
--nim= string "nim" use a particular Nim executable (default: $PATH/nim)
|
||||
--pluginSourcePath= string "" Nim file to build and load as a plugin
|
||||
--help-syntax advanced: prepend,plurals,..
|
||||
-d, --debug bool false enable debug output
|
||||
-D=, --defines= strings {} definitions to pass to preprocessor
|
||||
-l=, --dynlib= string "" Import symbols from library in specified Nim string
|
||||
-I=, --includeDirs= strings {} include directory to pass to preprocessor
|
||||
-m=, --mode= string "cpp" language parser: c or cpp
|
||||
--nim= string "nim" use a particular Nim executable (default: $PATH/nim)
|
||||
-c, --nocomments bool false exclude top-level comments from output
|
||||
-a, --past bool false print AST output
|
||||
-g, --pgrammar bool false print grammar
|
||||
--pluginSourcePath= string "" Nim file to build and load as a plugin
|
||||
-n, --pnim bool false print Nim output
|
||||
-E=, --prefix= strings {} Strip prefix from identifiers
|
||||
-p, --preprocess bool false run preprocessor on header
|
||||
-r, --recurse bool false process #include files
|
||||
-F=, --suffix= strings {} Strip suffix from identifiers
|
||||
-O=, --symOverride= strings {} skip generating specified symbols
|
||||
```
|
||||
|
||||
__Implementation Details__
|
||||
|
|
|
|||
|
|
@ -140,7 +140,7 @@ proc getToast(fullpath: string, recurse: bool = false, dynlib: string = "",
|
|||
cmd.add " --recurse"
|
||||
|
||||
if flags.nBl:
|
||||
cmd.add flags
|
||||
cmd.add " " & flags
|
||||
|
||||
for i in gStateCT.defines:
|
||||
cmd.add &" --defines+={i.quoteShell}"
|
||||
|
|
@ -300,13 +300,18 @@ macro cPlugin*(body): untyped =
|
|||
##
|
||||
## proc onSymbol(sym: var Symbol) {.exportc, dynlib.}
|
||||
##
|
||||
## `onSymbol()` can be used to handle symbol name modifications required due to invalid
|
||||
## characters like leading/trailing `_` or rename symbols that would clash due to Nim's style
|
||||
## insensitivity. It can also be used to remove prefixes and suffixes like `SDL_`. The symbol
|
||||
## name and type is provided to the callback and the name can be modified.
|
||||
## `onSymbol()` can be used to handle symbol name modifications required due
|
||||
## to invalid characters in identifiers or to rename symbols that would clash
|
||||
## due to Nim's style insensitivity. The symbol name and type is provided to
|
||||
## the callback and the name can be modified.
|
||||
##
|
||||
## Returning a blank name will result in the symbol being skipped. This will fail for `nskParam`
|
||||
## and `nskField` since the generated Nim code will be wrong.
|
||||
## While `cPlugin` can easily remove leading/trailing `_` or prefixes and
|
||||
## suffixes like `SDL_`, passing `--prefix` or `--suffix` flags to `cImport`
|
||||
## in the `flags` parameter is much easier. However, these flags will only be
|
||||
## considered when no `cPlugin` is specified.
|
||||
##
|
||||
## Returning a blank name will result in the symbol being skipped. This will
|
||||
## fail for `nskParam` and `nskField` since the generated Nim code will be wrong.
|
||||
##
|
||||
## Symbol types can be any of the following:
|
||||
## - `nskConst` for constants
|
||||
|
|
@ -316,10 +321,12 @@ macro cPlugin*(body): untyped =
|
|||
## - `nskEnumField` for enum (field) names, though they are in the global namespace as `nskConst`
|
||||
## - `nskProc` - for proc names
|
||||
##
|
||||
## `nimterop/plugins` is implicitly imported to provide access to standard plugin facilities.
|
||||
## `nimterop/plugins` is implicitly imported to provide access to standard
|
||||
## plugin facilities.
|
||||
##
|
||||
## `cPlugin() <cimport.html#cPlugin.m>`_ only affects calls to
|
||||
## `cImport() <cimport.html#cImport.m%2C%2Cstring%2Cstring%2Cstring>`_ that follow it.
|
||||
## `cImport() <cimport.html#cImport.m%2C%2Cstring%2Cstring%2Cstring>`_ that
|
||||
## follow it.
|
||||
runnableExamples:
|
||||
cPlugin:
|
||||
import strutils
|
||||
|
|
@ -572,7 +579,9 @@ macro cImport*(filename: static string, recurse: static bool = false, dynlib: st
|
|||
## `mode` is purely for forward compatibility when toast adds C++ support. It can
|
||||
## be ignored for the foreseeable future.
|
||||
##
|
||||
## `flags` can be used to pass any other command line arguments to `toast`.
|
||||
## `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
|
||||
## trailing strings from identifiers, `_` being quite common.
|
||||
##
|
||||
## `cImport()` consumes and resets preceding `cOverride()` calls. `cPlugin()`
|
||||
## is retained for the next `cImport()` call unless a new `cPlugin()` call is
|
||||
|
|
|
|||
|
|
@ -112,6 +112,7 @@ proc getIdentifier*(nimState: NimState, name: string, kind: NimSymKind, parent="
|
|||
|
||||
if name notin nimState.gState.symOverride or parent.nBl:
|
||||
if nimState.gState.onSymbol != nil:
|
||||
# Use onSymbol from plugin provided by user
|
||||
var
|
||||
sym = Symbol(name: name, parent: parent, kind: kind)
|
||||
nimState.gState.onSymbol(sym)
|
||||
|
|
@ -120,11 +121,23 @@ proc getIdentifier*(nimState: NimState, name: string, kind: NimSymKind, parent="
|
|||
else:
|
||||
result = name
|
||||
|
||||
# Strip out --prefix from CLI if specified
|
||||
for str in nimState.gState.prefix:
|
||||
if result.startsWith(str):
|
||||
result = result[str.len .. ^1]
|
||||
|
||||
# Strip out --suffix from CLI if specified
|
||||
for str in nimState.gState.suffix:
|
||||
if result.endsWith(str):
|
||||
result = result[0 .. ^(str.len+1)]
|
||||
|
||||
checkIdentifier(result, $kind, parent, name)
|
||||
|
||||
if result in gReserved or (result == "object" and kind != nskType):
|
||||
# Enclose in backticks since Nim reserved word
|
||||
result = &"`{result}`"
|
||||
else:
|
||||
# Skip identifier since in symOverride
|
||||
result = ""
|
||||
|
||||
proc getUniqueIdentifier*(nimState: NimState, prefix = ""): string =
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ type
|
|||
AstTable {.used.} = TableRef[string, seq[ref Ast]]
|
||||
|
||||
State = ref object
|
||||
compile*, defines*, headers*, includeDirs*, searchDirs*, symOverride*: seq[string]
|
||||
compile*, defines*, headers*, includeDirs*, searchDirs*, prefix*, suffix*, symOverride*: seq[string]
|
||||
|
||||
nocache*, nocomments*, debug*, past*, preprocess*, pnim*, pretty*, recurse*: bool
|
||||
|
||||
|
|
|
|||
|
|
@ -97,42 +97,51 @@ proc process(gState: State, path: string, astTable: AstTable) =
|
|||
elif gState.preprocess:
|
||||
echo gState.code
|
||||
|
||||
# CLI processing with default values
|
||||
proc main(
|
||||
preprocess = false,
|
||||
past = false,
|
||||
pnim = false,
|
||||
recurse = false,
|
||||
nocomments = false,
|
||||
defines: seq[string] = @[],
|
||||
includeDirs: seq[string] = @[],
|
||||
dynlib: string = "",
|
||||
symOverride: seq[string] = @[],
|
||||
nim: string = "nim",
|
||||
pluginSourcePath: string = "",
|
||||
debug = false,
|
||||
defines: seq[string] = @[],
|
||||
dynlib: string = "",
|
||||
includeDirs: seq[string] = @[],
|
||||
mode = modeDefault,
|
||||
nim: string = "nim",
|
||||
nocomments = false,
|
||||
past = false,
|
||||
pgrammar = false,
|
||||
pluginSourcePath: string = "",
|
||||
pnim = false,
|
||||
prefix: seq[string] = @[],
|
||||
preprocess = false,
|
||||
recurse = false,
|
||||
suffix: seq[string] = @[],
|
||||
symOverride: seq[string] = @[],
|
||||
source: seq[string]
|
||||
) =
|
||||
|
||||
# Setup global state with arguments
|
||||
var gState = State(
|
||||
preprocess: preprocess,
|
||||
past: past,
|
||||
pnim: pnim,
|
||||
recurse: recurse,
|
||||
nocomments: nocomments,
|
||||
defines: defines,
|
||||
includeDirs: includeDirs,
|
||||
dynlib: dynlib,
|
||||
symOverride: symOverride,
|
||||
nim: nim,
|
||||
pluginSourcePath: pluginSourcePath,
|
||||
debug: debug,
|
||||
defines: defines,
|
||||
dynlib: dynlib,
|
||||
includeDirs: includeDirs,
|
||||
mode: mode,
|
||||
pretty: true
|
||||
nim: nim,
|
||||
nocomments: nocomments,
|
||||
past: past,
|
||||
pluginSourcePath: pluginSourcePath,
|
||||
pnim: pnim,
|
||||
prefix: prefix,
|
||||
preprocess: preprocess,
|
||||
pretty: true,
|
||||
recurse: recurse,
|
||||
suffix: suffix,
|
||||
symOverride: symOverride
|
||||
)
|
||||
|
||||
# Split some arguments with ,
|
||||
gState.symOverride = gState.symOverride.getSplitComma()
|
||||
gState.prefix = gState.prefix.getSplitComma()
|
||||
gState.suffix = gState.suffix.getSplitComma()
|
||||
|
||||
if pluginSourcePath.nBl:
|
||||
gState.loadPlugin(pluginSourcePath)
|
||||
|
|
@ -148,33 +157,38 @@ proc main(
|
|||
gState.process(src.expandSymlinkAbs(), astTable)
|
||||
|
||||
when isMainModule:
|
||||
# Setup cligen command line help and short flags
|
||||
import cligen
|
||||
dispatch(main, help = {
|
||||
"preprocess": "run preprocessor on header",
|
||||
"past": "print AST output",
|
||||
"pnim": "print Nim output",
|
||||
"recurse": "process #include files",
|
||||
"nocomments": "exclude top-level comments from output",
|
||||
"defines": "definitions to pass to preprocessor",
|
||||
"includeDirs": "include directory to pass to preprocessor",
|
||||
"dynlib": "Import symbols from library in specified Nim string",
|
||||
"symOverride": "skip generating specified symbols",
|
||||
"nim": "use a particular Nim executable (default: $PATH/nim)",
|
||||
"pluginSourcePath": "Nim file to build and load as a plugin",
|
||||
"debug": "enable debug output",
|
||||
"defines": "definitions to pass to preprocessor",
|
||||
"dynlib": "Import symbols from library in specified Nim string",
|
||||
"includeDirs": "include directory to pass to preprocessor",
|
||||
"mode": "language parser: c or cpp",
|
||||
"nim": "use a particular Nim executable (default: $PATH/nim)",
|
||||
"nocomments": "exclude top-level comments from output",
|
||||
"past": "print AST output",
|
||||
"pgrammar": "print grammar",
|
||||
"source" : "C/C++ source/header"
|
||||
"pluginSourcePath": "Nim file to build and load as a plugin",
|
||||
"pnim": "print Nim output",
|
||||
"preprocess": "run preprocessor on header",
|
||||
"recurse": "process #include files",
|
||||
"source" : "C/C++ source/header",
|
||||
"prefix": "Strip prefix from identifiers",
|
||||
"suffix": "Strip suffix from identifiers",
|
||||
"symOverride": "skip generating specified symbols"
|
||||
}, short = {
|
||||
"preprocess": 'p',
|
||||
"past": 'a',
|
||||
"pnim": 'n',
|
||||
"recurse": 'r',
|
||||
"nocomments": 'c',
|
||||
"defines": 'D',
|
||||
"includeDirs": 'I',
|
||||
"dynlib": 'l',
|
||||
"symOverride": 'O',
|
||||
"debug": 'd',
|
||||
"pgrammar": 'g'
|
||||
"defines": 'D',
|
||||
"dynlib": 'l',
|
||||
"includeDirs": 'I',
|
||||
"nocomments": 'c',
|
||||
"past": 'a',
|
||||
"pgrammar": 'g',
|
||||
"pnim": 'n',
|
||||
"prefix": 'E',
|
||||
"preprocess": 'p',
|
||||
"recurse": 'r',
|
||||
"suffix": 'F',
|
||||
"symOverride": 'O'
|
||||
})
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import nimterop/[build, cimport]
|
|||
|
||||
const
|
||||
baseDir = getProjectCacheDir("nimterop" / "tests" / "liblzma")
|
||||
flags = "--prefix=__,_"
|
||||
|
||||
static:
|
||||
cDebug()
|
||||
|
|
@ -21,12 +22,6 @@ getHeader(
|
|||
conFlags = "--disable-xz --disable-xzdec --disable-lzmadec --disable-lzmainfo"
|
||||
)
|
||||
|
||||
cPlugin:
|
||||
import strutils
|
||||
|
||||
proc onSymbol*(sym: var Symbol) {.exportc, dynlib.} =
|
||||
sym.name = sym.name.strip(chars = {'_'})
|
||||
|
||||
cOverride:
|
||||
type
|
||||
lzma_internal = object
|
||||
|
|
@ -39,8 +34,8 @@ cOverride:
|
|||
lzma_index_iter = object
|
||||
|
||||
when not lzmaStatic:
|
||||
cImport(lzmaPath, recurse = true, dynlib = "lzmaLPath")
|
||||
cImport(lzmaPath, recurse = true, dynlib = "lzmaLPath", flags = flags)
|
||||
else:
|
||||
cImport(lzmaPath, recurse = true)
|
||||
cImport(lzmaPath, recurse = true, flags = flags)
|
||||
|
||||
echo "liblzma version = " & $lzma_version_string()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue