diff options
| author | Ganesh Viswanathan <dev@genotrance.com> | 2019-12-18 23:49:25 -0600 |
|---|---|---|
| committer | Ganesh Viswanathan <dev@genotrance.com> | 2019-12-18 23:49:25 -0600 |
| commit | bce8e0907368df20e04252635ab5994cfd579b7b (patch) | |
| tree | 4626b23c8515566541aff752140aa41b6b9d68ee | |
| parent | 0db54af54f17c1e62dff4baa44ea40e6d14c676e (diff) | |
| download | nimterop-bce8e0907368df20e04252635ab5994cfd579b7b.tar.gz nimterop-bce8e0907368df20e04252635ab5994cfd579b7b.zip | |
Fix #146 - prefix/suffix for stripping
| -rw-r--r-- | README.md | 26 | ||||
| -rw-r--r-- | nimterop/cimport.nim | 29 | ||||
| -rw-r--r-- | nimterop/getters.nim | 13 | ||||
| -rw-r--r-- | nimterop/globals.nim | 2 | ||||
| -rw-r--r-- | nimterop/toast.nim | 92 | ||||
| -rw-r--r-- | tests/lzma.nim | 11 |
6 files changed, 103 insertions, 70 deletions
@@ -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 + --help-syntax advanced: prepend,plurals,.. + -d, --debug bool false enable debug 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 - -d, --debug bool false enable debug output + -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__ diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index 65a5401..bebcf3d 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -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 diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 53e04f8..1c5f8aa 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -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 = diff --git a/nimterop/globals.nim b/nimterop/globals.nim index de29385..7c512b1 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -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 diff --git a/nimterop/toast.nim b/nimterop/toast.nim index 9da8283..a27d415 100644 --- a/nimterop/toast.nim +++ b/nimterop/toast.nim @@ -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, + debug = false, defines: seq[string] = @[], - includeDirs: seq[string] = @[], dynlib: string = "", - symOverride: seq[string] = @[], - nim: string = "nim", - pluginSourcePath: string = "", - debug = false, + 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, + debug: debug, defines: defines, - includeDirs: includeDirs, dynlib: dynlib, - symOverride: symOverride, + includeDirs: includeDirs, + mode: mode, nim: nim, + nocomments: nocomments, + past: past, pluginSourcePath: pluginSourcePath, - debug: debug, - mode: mode, - pretty: true + 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", + "debug": "enable debug 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", + "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', + "debug": 'd', + "defines": 'D', + "dynlib": 'l', + "includeDirs": 'I', + "nocomments": 'c', "past": 'a', + "pgrammar": 'g', "pnim": 'n', + "prefix": 'E', + "preprocess": 'p', "recurse": 'r', - "nocomments": 'c', - "defines": 'D', - "includeDirs": 'I', - "dynlib": 'l', - "symOverride": 'O', - "debug": 'd', - "pgrammar": 'g' + "suffix": 'F', + "symOverride": 'O' }) diff --git a/tests/lzma.nim b/tests/lzma.nim index 785e0bb..b207a46 100644 --- a/tests/lzma.nim +++ b/tests/lzma.nim @@ -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() |
