Add preprocessor step in toast
This commit is contained in:
parent
14b75cea31
commit
9ee67da1c2
5 changed files with 83 additions and 22 deletions
|
|
@ -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]
|
||||
|
||||
for inc in gIncludeDirs:
|
||||
rdata: seq[string] = @[]
|
||||
start = false
|
||||
sfile = fullpath.sanitizePath
|
||||
|
||||
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)
|
||||
|
||||
# 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")
|
||||
|
|
|
|||
|
|
@ -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`)
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
import strutils
|
||||
|
||||
import regex
|
||||
|
||||
import globals
|
||||
|
||||
var
|
||||
|
|
|
|||
51
toast.nim
51
toast.nim
|
|
@ -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()
|
||||
Loading…
Add table
Add a link
Reference in a new issue