Fix #161 - enable stubbing in toast

This commit is contained in:
Ganesh Viswanathan 2019-12-20 00:10:31 -06:00
commit 54dfd61b1b
2 changed files with 58 additions and 14 deletions

View file

@ -112,6 +112,7 @@ Options(opt-arg sep :|=|spc):
-E=, --prefix= strings {} Strip prefix from identifiers
-p, --preprocess bool false run preprocessor on header
-r, --recurse bool false process #include files
-s, --stub bool false stub out undefined type references as objects
-F=, --suffix= strings {} Strip suffix from identifiers
-O=, --symOverride= strings {} skip generating specified symbols
```

View file

@ -54,7 +54,7 @@ proc printLisp(gState: State, root: TSNode) =
break
proc process(gState: State, path: string, astTable: AstTable) =
doAssert existsFile(path), "Invalid path " & path
doAssert existsFile(path), &"Invalid path {path}"
var
parser = tsParserNew()
@ -81,7 +81,7 @@ proc process(gState: State, path: string, astTable: AstTable) =
elif gState.mode == "cpp":
doAssert parser.tsParserSetLanguage(treeSitterCpp()), "Failed to load C++ parser"
else:
doAssert false, "Invalid parser " & gState.mode
doAssert false, &"Invalid parser {gState.mode}"
var
tree = parser.tsParserParseString(nil, gState.code.cstring, gState.code.len.uint32)
@ -115,6 +115,7 @@ proc main(
prefix: seq[string] = @[],
preprocess = false,
recurse = false,
stub = false,
suffix: seq[string] = @[],
symOverride: seq[string] = @[],
source: seq[string]
@ -153,20 +154,26 @@ proc main(
outputFile = output
outputHandle: File
stdoutBackup = stdout
check = check or stub
# Fix output file extention
if outputFile.len != 0:
if outputFile.splitFile().ext != ".nim":
outputFile = outputFile & ".nim"
# Check needs a file
if check and outputFile.len == 0:
outputFile = getTempDir() / "toast_" & ($getTime().toUnix()).addFileExt("nim")
when defined(windows):
# https://github.com/nim-lang/Nim/issues/12939
echo "Cannot print wrapper with check on Windows, review " & outputFile & "\n"
echo &"Cannot print wrapper with check on Windows, review {outputFile}\n"
# Redirect output to file
if outputFile.len != 0:
when defined(windows):
doAssert stdout.reopen(outputFile, fmWrite), "Failed to write to " & outputFile
doAssert stdout.reopen(outputFile, fmWrite), &"Failed to write to {outputFile}"
else:
doAssert outputHandle.open(outputFile, fmWrite), "Failed to write to " & outputFile
doAssert outputHandle.open(outputFile, fmWrite), &"Failed to write to {outputFile}"
stdout = outputHandle
# Process grammar into AST
@ -187,19 +194,53 @@ proc main(
# Restore stdout
stdout = stdoutBackup
# Check Nim output
if gState.pnim and check:
# Run nim check on generated wrapper
var
(check, err) = execCmdEx(&"{getCurrentCompilerExe()} check {outputFile}")
if err != 0:
# Failed check so try stubbing
if stub:
# Close output file to prepend stubs
when not defined(windows):
outputHandle.close()
else:
stdout.close()
# Find undeclared identifiers in error
var
data = ""
stubData = ""
for line in check.splitLines:
if "undeclared identifier" in line:
try:
# Add stub of object type
stubData &= " " & line.split("'")[1] & " = object\n"
except:
discard
# Include in wrapper file
data = outputFile.readFile()
if "type\n" in data:
# In existing type block
data = data.replace("type\n", "type\n" & stubData)
else:
# At the top if none already
data = "type\n" & stubData & data
outputFile.writeFile(data)
# Rerun nim check on stubbed wrapper
(check, err) = execCmdEx(&"{getCurrentCompilerExe()} check {outputFile}")
doAssert err == 0, "# Nim check with stub failed:\n\n" & check
else:
doAssert err == 0, "# Nim check failed:\n\n" & check
when not defined(windows):
# Print wrapper if temporarily redirected to file
if check and output.len == 0:
stdout.write outputFile.readFile()
# Check Nim output
if gState.pnim and check:
var
(check, err) = execCmdEx(&"{getCurrentCompilerExe()} check {outputFile}")
if err == 0:
echo "# Checked wrapper successfully"
else:
doAssert err == 0, "# Nim check failed:\n\n" & check
when isMainModule:
# Setup cligen command line help and short flags
import cligen
@ -221,6 +262,7 @@ when isMainModule:
"recurse": "process #include files",
"source" : "C/C++ source/header",
"prefix": "Strip prefix from identifiers",
"stub": "stub out undefined type references as objects",
"suffix": "Strip suffix from identifiers",
"symOverride": "skip generating specified symbols"
}, short = {
@ -237,6 +279,7 @@ when isMainModule:
"prefix": 'E',
"preprocess": 'p',
"recurse": 'r',
"stub": 's',
"suffix": 'F',
"symOverride": 'O'
})