Fix #149 - cOverride injecting multiple times

This commit is contained in:
Ganesh Viswanathan 2019-11-01 16:26:57 -05:00
commit 36726e2442
8 changed files with 79 additions and 69 deletions

View file

@ -78,9 +78,9 @@ proc searchAstForNode(ast: ref Ast, node: TSNode, nimState: NimState): bool =
nimState.nodeBranch.add $node.tsNodeType()
echo "#" & spaces(nimState.nodeBranch.len * 2) & nimState.nodeBranch[^1]
if ast.children.len != 0:
if ast.children.nBl:
if childNames.contains(ast.regex) or
(childNames.len == 0 and ast.recursive):
(childNames.Bl and ast.recursive):
if node.getTSNodeNamedChildCountSansComments() != 0:
var flag = true
@ -110,7 +110,7 @@ proc searchAstForNode(ast: ref Ast, node: TSNode, nimState: NimState): bool =
if nimState.gState.debug:
discard nimState.nodeBranch.pop()
if nimstate.nodeBranch.len == 0:
if nimstate.nodeBranch.Bl:
echo ""
proc searchAst(root: TSNode, astTable: AstTable, nimState: NimState) =
@ -179,7 +179,7 @@ proc printNim*(gState: State, fullpath: string, root: TSNode, astTable: AstTable
nimState.impShort = nimState.currentHeader.replace("header", "imp")
nimState.sourceFile = fullpath
if nimState.gState.dynlib.len == 0:
if nimState.gState.dynlib.Bl:
nimState.constStr &= &"\n {nimState.currentHeader} {{.used.}} = \"{fp}\""
root.searchAst(astTable, nimState)

View file

@ -34,7 +34,7 @@ proc execAction*(cmd: string, retry = 0, nostderr = false): string =
var
colonIndex = cmd.find(":")
driveLetter = cmd.substr(colonIndex-1, colonIndex)
if (driveLetter[0].isAlphaAscii() and
if (driveLetter[0].isAlphaAscii() and
driveLetter[1] == ':' and
colonIndex == 4):
filteredCmd = &"{driveLetter} && {cmd}"

View file

@ -48,7 +48,7 @@ proc walkDirImpl(indir, inext: string, file=true): seq[string] =
let
dir = joinPathIfRel(getProjectPath(), indir)
ext =
if inext.len != 0:
if inext.nBl:
when not defined(Windows):
"-name " & inext
else:
@ -100,7 +100,7 @@ proc getToastError(output: string): string =
result &= "\n\nERROR:$1\n" % line.split("fatal error:")[1]
# Toast error
if result.len == 0:
if result.Bl:
result = "\n\n" & output
proc getNimCheckError(output: string): tuple[tmpFile, errors: string] =
@ -139,7 +139,7 @@ proc getToast(fullpath: string, recurse: bool = false, dynlib: string = "",
if recurse:
cmd.add " --recurse"
if flags.len != 0:
if flags.nBl:
cmd.add flags
for i in gStateCT.defines:
@ -151,10 +151,10 @@ proc getToast(fullpath: string, recurse: bool = false, dynlib: string = "",
if not noNimout:
cmd.add &" --pnim"
if dynlib.len != 0:
if dynlib.nBl:
cmd.add &" --dynlib={dynlib}"
if gStateCT.symOverride.len != 0:
if gStateCT.symOverride.nBl:
cmd.add &" --symOverride={gStateCT.symOverride.join(\",\")}"
when (NimMajor, NimMinor, NimPatch) >= (0, 19, 9):
@ -222,7 +222,7 @@ macro cOverride*(body): untyped =
else:
discard
if gStateCT.overrides.len == 0:
if gStateCT.overrides.Bl:
gStateCT.overrides = """
import sets, tables
@ -230,7 +230,7 @@ proc onSymbolOverride*(sym: var Symbol) {.exportc, dynlib.} =
"""
# If cPlugin called before cOverride
if gStateCT.pluginSourcePath.len != 0:
if gStateCT.pluginSourcePath.nBl:
gStateCT.pluginSourcePath = ""
var
@ -257,7 +257,7 @@ proc onSymbolOverride*(sym: var Symbol) {.exportc, dynlib.} =
gStateCT.symOverride.add name
if gStateCT.debug and names.len != 0:
if gStateCT.debug and names.nBl:
echo "# Overriding " & names.join(" ")
proc cSkipSymbol*(skips: seq[string]) {.compileTime.} =
@ -273,18 +273,19 @@ proc cSkipSymbol*(skips: seq[string]) {.compileTime.} =
proc cPluginHelper(body: string) =
gStateCT.pluginSource = body
let
data = "import macros, nimterop/plugin\n\n" & body & gStateCT.overrides
hash = data.hash().abs()
path = getProjectCacheDir("cPlugins", forceClean = false) / "nimterop_" & $hash & ".nim"
if gStateCT.pluginSource.nBl or gStateCT.overrides.nBl:
let
data = "import macros, nimterop/plugin\n\n" & body & gStateCT.overrides
hash = data.hash().abs()
path = getProjectCacheDir("cPlugins", forceClean = false) / "nimterop_" & $hash & ".nim"
if not fileExists(path) or gStateCT.nocache or compileOption("forceBuild"):
mkDir(path.parentDir())
writeFile(path, data)
if not fileExists(path) or gStateCT.nocache or compileOption("forceBuild"):
mkDir(path.parentDir())
writeFile(path, data)
doAssert fileExists(path), "Unable to write plugin file: " & path
doAssert fileExists(path), "Unable to write plugin file: " & path
gStateCT.pluginSourcePath = path
gStateCT.pluginSourcePath = path
macro cPlugin*(body): untyped =
## When `cOverride() <cimport.html#cOverride.m>`_ and
@ -347,11 +348,11 @@ proc cSearchPath*(path: string): string {.compileTime.}=
## `cImport() <cimport.html#cImport.m%2C%2Cstring%2Cstring%2Cstring>`_.
result = findPath(path, fail = false)
if result.len == 0:
if result.Bl:
var found = false
for inc in gStateCT.searchDirs:
result = findPath(inc / path, fail = false)
if result.len != 0:
if result.nBl:
found = true
break
doAssert found, "File or directory not found: " & path &
@ -498,7 +499,7 @@ macro cCompile*(path: static string, mode = "c", exclude = ""): untyped =
result = true
if "_nimterop_" in file:
result = false
elif exclude.len != 0:
elif exclude.nBl:
for excl in exclude.split(","):
if excl in file:
result = false
@ -508,7 +509,7 @@ macro cCompile*(path: static string, mode = "c", exclude = ""): untyped =
files = walkDirImpl(dir, ext)
for f in files:
if f.len != 0 and f.notExcluded(exclude):
if f.nBl and f.notExcluded(exclude):
result &= fcompile(f)
if path.contains("*") or path.contains("?"):
@ -576,7 +577,8 @@ macro cImport*(filename: static string, recurse: static bool = false, dynlib: st
let
fullpath = findPath(filename)
if gStateCT.overrides.len != 0 and gStateCT.pluginSourcePath.len == 0:
# In case cOverride called after cPlugin
if gStateCT.pluginSourcePath.Bl:
cPluginHelper(gStateCT.pluginSource)
echo "# Importing " & fullpath.sanitizePath
@ -584,6 +586,10 @@ macro cImport*(filename: static string, recurse: static bool = false, dynlib: st
let
output = getToast(fullpath, recurse, dynlib, mode, flags)
# Reset plugin and overrides for next cImport
gStateCT.pluginSourcePath = ""
gStateCT.overrides = ""
if gStateCT.debug:
echo output
@ -641,11 +647,11 @@ macro c2nImport*(filename: static string, recurse: static bool = false, dynlib:
cmd = when defined(Windows): "cmd /c " else: ""
cmd &= &"c2nim {hpath} --header:{header}"
if dynlib.len != 0:
if dynlib.nBl:
cmd.add &" --dynlib:{dynlib}"
if mode.contains("cpp"):
cmd.add " --cpp"
if flags.len != 0:
if flags.nBl:
cmd.add &" {flags}"
for i in gStateCT.defines:

View file

@ -95,7 +95,7 @@ proc checkIdentifier(name, kind, parent, origName: string) =
let
parentStr = if parent.nBl: parent & ":" else: ""
if name.len != 0:
if name.nBl:
let
origStr = if name != origName: &", originally '{origName}' before 'cPlugin:onSymbol()', still" else: ""
errmsg = &"Identifier '{parentStr}{name}' ({kind}){origStr} contains"
@ -108,7 +108,7 @@ proc checkIdentifier(name, kind, parent, origName: string) =
doAssert name.nBl, &"Blank identifier, originally '{parentStr}{name}' ({kind}), cannot be empty"
proc getIdentifier*(nimState: NimState, name: string, kind: NimSymKind, parent=""): string =
doAssert name.len != 0, "Blank identifier error"
doAssert name.nBl, "Blank identifier error"
if name notin nimState.gState.symOverride or parent.nBl:
if nimState.gState.onSymbol != nil:
@ -153,7 +153,7 @@ proc addNewIdentifer*(nimState: NimState, name: string, override = false): bool
result = true
proc getOverride*(nimState: NimState, name: string, kind: NimSymKind): string =
doAssert name.len != 0, "Blank identifier error"
doAssert name.nBl, "Blank identifier error"
if nimState.gState.onSymbolOverride != nil:
var
@ -162,7 +162,7 @@ proc getOverride*(nimState: NimState, name: string, kind: NimSymKind): string =
if nname.nBl:
nimState.gState.onSymbolOverride(sym)
if sym.override.len != 0 and nimState.addNewIdentifer(nname, override = true):
if sym.override.nBl and nimState.addNewIdentifer(nname, override = true):
result = sym.override
if kind != nskProc:
@ -257,7 +257,7 @@ proc getPreprocessor*(gState: State, fullpath: string, mode = "cpp"): string =
elif gState.recurse:
let
pDir = sfile.expandFilename().parentDir().sanitizePath(noQuote = true)
if pDir.len == 0 or pDir in saniLine:
if pDir.Bl or pDir in saniLine:
start = true
else:
for inc in gState.includeDirs:
@ -368,10 +368,10 @@ proc getNimExpression*(nimState: NimState, expr: string): string =
for i in 0 .. clean.len:
if i != clean.len:
if clean[i] == '_' and ident.len == 0:
if clean[i] == '_' and ident.Bl:
gen = $clean[i]
elif clean[i] in IdentChars:
if clean[i] in Digits and ident.len == 0:
if clean[i] in Digits and ident.Bl:
gen = $clean[i]
elif clean[i] in HexDigits and hex == true:
gen = $clean[i]
@ -397,8 +397,8 @@ proc getNimExpression*(nimState: NimState, expr: string): string =
)
hex = false
if i == clean.len or gen.len != 0:
if ident.len != 0:
if i == clean.len or gen.nBl:
if ident.nBl:
ident = nimState.getIdentifier(ident, nskConst)
result &= ident
ident = ""
@ -415,14 +415,14 @@ proc getSplitComma*(joined: seq[string]): seq[string] =
proc getHeader*(nimState: NimState): string =
result =
if nimState.gState.dynlib.len == 0:
if nimState.gState.dynlib.Bl:
&", header: {nimState.currentHeader}"
else:
""
proc getDynlib*(nimState: NimState): string =
result =
if nimState.gState.dynlib.len != 0:
if nimState.gState.dynlib.nBl:
&", dynlib: {nimState.gState.dynlib}"
else:
""
@ -436,9 +436,9 @@ proc getImportC*(nimState: NimState, origName, nimName: string): string =
proc getPragma*(nimState: NimState, pragmas: varargs[string]): string =
result = ""
for pragma in pragmas.items():
if pragma.len != 0:
if pragma.nBl:
result &= pragma & ", "
if result.len != 0:
if result.nBl:
result = " {." & result[0 .. ^3] & ".}"
result = result.replace(nimState.impShort & ", cdecl", nimState.impShort & "C")
@ -446,11 +446,11 @@ proc getPragma*(nimState: NimState, pragmas: varargs[string]): string =
let
dy = nimState.getDynlib()
if ", cdecl" in result and dy.len != 0:
if ", cdecl" in result and dy.nBl:
result = result.replace(".}", dy & ".}")
proc getComments*(nimState: NimState, strip = false): string =
if not nimState.gState.nocomments and nimState.commentStr.len != 0:
if not nimState.gState.nocomments and nimState.commentStr.nBl:
result = "\n" & nimState.commentStr
if strip:
result = result.replace("\n ", "\n")

View file

@ -81,6 +81,9 @@ var
template nBl(s: typed): untyped {.used.} =
(s.len != 0)
template Bl(s: typed): untyped {.used.} =
(s.len == 0)
type CompileMode = enum
c,
cpp,
@ -89,4 +92,5 @@ type CompileMode = enum
const modeDefault {.used.} = $cpp # TODO: USE this everywhere relevant
when not declared(CIMPORT):
export gAtoms, gExpressions, gEnumVals, Kind, Ast, AstTable, State, NimState, nBl, CompileMode, modeDefault
export gAtoms, gExpressions, gEnumVals, Kind, Ast, AstTable, State, NimState,
nBl, Bl, CompileMode, modeDefault

View file

@ -27,7 +27,7 @@ proc initGrammar(): Grammar =
if not nname.nBl:
let
override = nimState.getOverride(name, nskConst)
if override.len != 0:
if override.nBl:
nimState.constStr &= &"{nimState.getComments()}\n{override}"
else:
nimState.constStr &= &"{nimState.getComments()}\n # Const '{name}' skipped"
@ -123,7 +123,7 @@ proc initGrammar(): Grammar =
pout &= &"{pname}: array[{flen}, {getPtrType(pptr&ptyp)}], "
i += 1
elif pptr.len != 0 or ptyp != "object":
elif pptr.nBl or ptyp != "object":
pout &= &"{pname}: {getPtrType(pptr&ptyp)}, "
# typedef int X
@ -176,7 +176,7 @@ proc initGrammar(): Grammar =
nname = nimState.getIdentifier(name, nskType)
i += 1
if nimState.gState.dynlib.len == 0:
if nimState.gState.dynlib.Bl:
pragmas.add nimState.getImportC(name, nname)
let
@ -185,7 +185,7 @@ proc initGrammar(): Grammar =
if not nname.nBl:
let
override = nimState.getOverride(name, nskType)
if override.len != 0:
if override.nBl:
nimState.typeStr &= &"{nimState.getComments()}\n{override}"
elif nname notin gTypeMap and typ.nBl and nimState.addNewIdentifer(nname):
if i < nimState.data.len and nimState.data[^1].name == "function_declarator":
@ -201,10 +201,10 @@ proc initGrammar(): Grammar =
funcParamCommon(fname, pname, ptyp, pptr, pout, count, i, flen)
if pout.len != 0 and pout[^2 .. ^1] == ", ":
if pout.nBl and pout[^2 .. ^1] == ", ":
pout = pout[0 .. ^3]
if tptr.len != 0 or typ != "object":
if tptr.nBl or typ != "object":
nimState.typeStr &= &"{nimState.getComments()}\n {nname}*{pragma} = proc({pout}): {getPtrType(tptr&typ)} {{.cdecl.}}"
else:
nimState.typeStr &= &"{nimState.getComments()}\n {nname}*{pragma} = proc({pout}) {{.cdecl.}}"
@ -284,7 +284,7 @@ proc initGrammar(): Grammar =
if not nname.nBl:
let
override = nimState.getOverride(name, nskType)
if override.len != 0:
if override.nBl:
nimState.typeStr &= &"{nimState.getComments()}\n{override}"
elif nimState.addNewIdentifer(nname):
if nimState.data.len == 1:
@ -292,10 +292,10 @@ proc initGrammar(): Grammar =
else:
var
pragmas: seq[string] = @[]
if nimState.gState.dynlib.len == 0:
if nimState.gState.dynlib.Bl:
pragmas.add nimState.getImportC(prefix & name, nname)
pragmas.add "bycopy"
if union.len != 0:
if union.nBl:
pragmas.add "union"
let
@ -357,9 +357,9 @@ proc initGrammar(): Grammar =
funcParamCommon(fname, pname, ptyp, pptr, pout, count, i, flen)
if pout.len != 0 and pout[^2 .. ^1] == ", ":
if pout.nBl and pout[^2 .. ^1] == ", ":
pout = pout[0 .. ^3]
if fptr.len != 0 or ftyp != "object":
if fptr.nBl or ftyp != "object":
nimState.typeStr &= &"{nimState.getComments()}\n {fname}*: proc({pout}): {getPtrType(fptr&ftyp)} {{.cdecl.}}"
else:
nimState.typeStr &= &"{nimState.getComments()}\n {fname}*: proc({pout}) {{.cdecl.}}"
@ -372,7 +372,7 @@ proc initGrammar(): Grammar =
i += 1
if node.tsNodeType() == "type_definition" and
nimState.data[^1].name == "type_identifier" and nimState.data[^1].val.len != 0:
nimState.data[^1].name == "type_identifier" and nimState.data[^1].val.nBl:
pDupTypeCommon(nname, fend, nimState, false)
let
@ -473,7 +473,7 @@ proc initGrammar(): Grammar =
nimState.debugStr &= "\n# pEnumCommon()"
let nname =
if name.len == 0:
if name.Bl:
getUniqueIdentifier(nimState, "Enum")
else:
nimState.getIdentifier(name, nskType)
@ -508,7 +508,7 @@ proc initGrammar(): Grammar =
count += 1
if node.tsNodeType() == "type_definition" and
nimState.data[^1].name == "type_identifier" and nimState.data[^1].val.len != 0:
nimState.data[^1].name == "type_identifier" and nimState.data[^1].val.nBl:
pDupTypeCommon(nname, fend, nimState, true)
# enum X {}
@ -621,20 +621,20 @@ proc initGrammar(): Grammar =
funcParamCommon(fnname, pname, ptyp, pptr, pout, count, i, flen)
if pout.len != 0 and pout[^2 .. ^1] == ", ":
if pout.nBl and pout[^2 .. ^1] == ", ":
pout = pout[0 .. ^3]
if not fnname.nBl:
let
override = nimState.getOverride(fname, nskProc)
if override.len != 0:
if override.nBl:
nimState.typeStr &= &"{nimState.getComments()}\n{override}"
elif nimState.addNewIdentifer(fnname):
let
ftyp = nimState.getIdentifier(nimState.data[0].val, nskType, fnname).getType()
pragma = nimState.getPragma(nimState.getImportC(fname, fnname), "cdecl")
if fptr.len != 0 or ftyp != "object":
if fptr.nBl or ftyp != "object":
if fVar:
nimState.procStr &= &"{nimState.getComments(true)}\nvar {fnname}*: proc ({pout}): {getPtrType(fptr&ftyp)}{{.cdecl.}}"
else:
@ -678,7 +678,7 @@ proc initGrammar(): Grammar =
let
override = nimState.getOverride(i.val, nskProc)
if override.len != 0:
if override.nBl:
nimState.procStr &= &"{nimState.getComments(true)}\n{override}"
done = true
break
@ -690,7 +690,7 @@ proc initGrammar(): Grammar =
let
override = nimState.getOverride(i.val, nskType)
if override.len != 0:
if override.nBl:
nimState.typeStr &= &"{nimState.getComments()}\n{override}"
done = true
break
@ -702,7 +702,7 @@ proc initGrammar(): Grammar =
))
proc initRegex(ast: ref Ast) =
if ast.children.len != 0:
if ast.children.nBl:
if not ast.recursive:
for child in ast.children:
child.initRegex()

View file

@ -45,7 +45,7 @@ proc readFromTokens(): ref Ast =
proc printAst*(node: ref Ast, offset=""): string =
result = offset & "(" & (if node.recursive: "^" else: "") & node.name & node.kind.toString()
if node.children.len != 0 and not node.recursive:
if node.children.nBl and not node.recursive:
result &= "\n"
for child in node.children:
result &= printAst(child, offset & " ")

View file

@ -63,7 +63,7 @@ proc process(gState: State, path: string, astTable: AstTable) =
defer:
parser.tsParserDelete()
if gState.mode.len == 0:
if gState.mode.Bl:
if ext in [".h", ".c"]:
gState.mode = "c"
elif ext in [".hxx", ".hpp", ".hh", ".H", ".h++", ".cpp", ".cxx", ".cc", ".C", ".c++"]:
@ -74,7 +74,7 @@ proc process(gState: State, path: string, astTable: AstTable) =
else:
gState.code = readFile(path)
doAssert gState.code.len != 0, "Empty file or preprocessor error"
doAssert gState.code.nBl, "Empty file or preprocessor error"
if gState.mode == "c":
doAssert parser.tsParserSetLanguage(treeSitterC()), "Failed to load C parser"
@ -141,7 +141,7 @@ proc main(
astTable = parseGrammar()
if pgrammar:
astTable.printGrammar()
elif source.len != 0:
elif source.nBl:
if gState.pnim:
printNimHeader()
for src in source: