diff options
| author | Ganesh Viswanathan <dev@genotrance.com> | 2018-11-27 14:56:47 -0600 |
|---|---|---|
| committer | Ganesh Viswanathan <dev@genotrance.com> | 2018-11-27 14:56:47 -0600 |
| commit | 9ee67da1c254db70b84712a96c33389f5f3feb9b (patch) | |
| tree | 400da5fe5dbe8535f89d83a75dbd8fe1833a4de7 | |
| parent | 14b75cea31bb923801dd7857699abb3d2a30c9d6 (diff) | |
| download | nimterop-9ee67da1c254db70b84712a96c33389f5f3feb9b.tar.gz nimterop-9ee67da1c254db70b84712a96c33389f5f3feb9b.zip | |
Add preprocessor step in toast
| -rw-r--r-- | nimterop/getters.nim | 41 | ||||
| -rw-r--r-- | nimterop/git.nim | 9 | ||||
| -rw-r--r-- | nimterop/globals.nim | 2 | ||||
| -rw-r--r-- | nimterop/lisp.nim | 2 | ||||
| -rw-r--r-- | toast.nim | 51 |
5 files changed, 83 insertions, 22 deletions
diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 6ba83e8..c9ac3b9 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -1,9 +1,12 @@ -import macros, strformat, strutils +import macros, ospaths, strformat, strutils import regex import git, globals +proc sanitizePath*(path: string): string = + path.multiReplace([("\\\\", $DirSep), ("\\", $DirSep), ("//", $DirSep)]) + proc getIdentifier*(str: string): string = result = str.strip(chars={'_'}) @@ -42,12 +45,42 @@ proc getPreprocessor*(fullpath: string, mode = "cpp"): string = var mmode = if mode == "cpp": "c++" else: mode cmd = &"gcc -E -dD -x{mmode} " + gdef, gdir: seq[string] + + rdata: seq[string] = @[] + start = false + sfile = fullpath.sanitizePath - for inc in gIncludeDirs: + when nimvm: + gdef = gDefines + gdir = gIncludeDirs + else: + gdef = gDefinesRT + gdir = gIncludeDirsRT + + for inc in gdir: cmd &= &"-I\"{inc}\" " - for def in gDefines: + for def in gdef: cmd &= &"-D{def} " cmd &= &"\"{fullpath}\"" - return staticExec(cmd)
\ No newline at end of file + + # Include content only from file + for line in execAction(cmd).splitLines(): + if line.strip() != "": + if line[0] == '#' and not line.contains("#pragma") and not line.contains("define"): + start = false + if sfile in line.sanitizePath: + start = true + if not ("\\" in line) and not ("/" in line) and extractFilename(sfile) in line: + start = true + else: + if start: + rdata.add( + line.multiReplace([("_Noreturn", ""), ("(())", ""), ("WINAPI", ""), + ("__attribute__", ""), ("extern \"C\"", "")]) + .replace(re"\(\([_a-z]+?\)\)", "") + .replace(re"\(\(__format__[\s]*\(__[gnu_]*printf__, [\d]+, [\d]+\)\)\);", ";") + ) + return rdata.join("\n") diff --git a/nimterop/git.nim b/nimterop/git.nim index b55b365..51ea756 100644 --- a/nimterop/git.nim +++ b/nimterop/git.nim @@ -1,4 +1,4 @@ -import macros, os, regex, strformat, strutils +import macros, os, osproc, regex, strformat, strutils import globals @@ -11,7 +11,10 @@ proc execAction*(cmd: string): string = when defined(Linux) or defined(MacOSX): ccmd = "bash -c '" & cmd & "'" - (result, ret) = gorgeEx(ccmd) + when nimvm: + (result, ret) = gorgeEx(ccmd) + else: + (result, ret) = execCmdEx(ccmd) if ret != 0: echo "Command failed: " & $ret echo ccmd @@ -66,7 +69,7 @@ macro gitPull*(url: static string, outdirN = "", plistN = "", checkoutN = ""): u outdir = getProjectPath()/outdirN.strVal() plist = plistN.strVal() checkout = checkoutN.strVal() - + if dirExists(outdir/".git"): discard quote do: gitReset(`outdirN`) diff --git a/nimterop/globals.nim b/nimterop/globals.nim index ccc4ec2..ae3d03b 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -20,10 +20,12 @@ type var gDefines* {.compiletime.}: seq[string] + gDefinesRT*: seq[string] gCompile* {.compiletime.}: seq[string] gConsts* {.compiletime.}: seq[string] gHeaders* {.compiletime.}: seq[string] gIncludeDirs* {.compiletime.}: seq[string] + gIncludeDirsRT*: seq[string] gProcs* {.compiletime.}: seq[string] gSearchDirs* {.compiletime.}: seq[string] gTypes* {.compiletime.}: seq[string] diff --git a/nimterop/lisp.nim b/nimterop/lisp.nim index 2727c18..c4a3b54 100644 --- a/nimterop/lisp.nim +++ b/nimterop/lisp.nim @@ -1,7 +1,5 @@ import strutils -import regex - import globals var @@ -1,13 +1,17 @@ import os, strutils -import regex - import treesitter/[runtime, c, cpp] +import nimterop/[globals, getters] + const HELP = """ > toast header.h --m minimized output - non-pretty --c C mode - CPP is default""" +-a print AST output +-c C mode - CPP is default +-m print minimized AST output - non-pretty (implies -a) +-p run preprocessor on header +-D definitions to pass to preprocessor +-I include directory to pass to preprocessor""" proc printLisp(root: TSNode, data: var string, pretty = true) = var @@ -20,6 +24,8 @@ proc printLisp(root: TSNode, data: var string, pretty = true) = if pretty: stdout.write spaces(depth) stdout.write "(" & $node.tsNodeType() & " " & $node.tsNodeStartByte() & " " & $node.tsNodeEndByte() + else: + return if node.tsNodeNamedChildCount() != 0: if pretty: @@ -37,6 +43,8 @@ proc printLisp(root: TSNode, data: var string, pretty = true) = while true: node = node.tsNodeParent() depth -= 1 + if depth == -1: + break if pretty: echo spaces(depth) & ")" else: @@ -52,7 +60,7 @@ proc printLisp(root: TSNode, data: var string, pretty = true) = if node == root: break -proc process(path: string, mode="cpp", pretty = true) = +proc process(path: string, mode="cpp", past, pretty, preprocess: bool) = if not existsFile(path): echo "Invalid path " & path return @@ -61,7 +69,7 @@ proc process(path: string, mode="cpp", pretty = true) = parser = tsParserNew() ext = path.splitFile().ext pmode = "" - data = readFile(path) + data = "" defer: parser.tsParserDelete() @@ -73,8 +81,10 @@ proc process(path: string, mode="cpp", pretty = true) = elif ext in [".hxx", ".hpp", ".hh", ".H", ".h++", ".cpp", ".cxx", ".cc", ".C", ".c++"]: pmode = "cpp" - if "cplusplus" in data or "extern \"C\"" in data: - pmode = "cpp" + if preprocess: + data = getPreprocessor(path) + else: + data = readFile(path) if pmode == "c": if not parser.tsParserSetLanguage(treeSitterC()): @@ -95,23 +105,38 @@ proc process(path: string, mode="cpp", pretty = true) = defer: tree.tsTreeDelete() - printLisp(root, data, pretty) + if past: + printLisp(root, data, pretty) proc parseCli() = var mode = "cpp" params = commandLineParams() + + past = false pretty = true + preprocess = false for param in params: - if param in ["-h", "--help", "-?", "/?", "/h"]: + let flag = if param.len() <= 2: param else: param[0..<2] + + if flag in ["-h", "--help", "-?", "/?", "/h"]: echo HELP quit() - elif param == "-c": + elif flag == "-a": + past = true + elif flag == "-c": mode = "c" - elif param == "-m": + elif flag == "-m": + past = true pretty = false + elif flag == "-p": + preprocess = true + elif flag == "-D": + gDefinesRT.add(param[2..^1]) + elif flag == "-I": + gIncludeDirsRT.add(param[2..^1]) else: - process(param, mode, pretty) + process(param, mode, past, pretty, preprocess) parseCli()
\ No newline at end of file |
