Add preprocessor step in toast

This commit is contained in:
Ganesh Viswanathan 2018-11-27 14:56:47 -06:00
commit 9ee67da1c2
5 changed files with 83 additions and 22 deletions

View file

@ -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")

View file

@ -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`)

View file

@ -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]

View file

@ -1,7 +1,5 @@
import strutils
import regex
import globals
var

View file

@ -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()