Fix rename bug, additional cleanup

This commit is contained in:
Ganesh Viswanathan 2018-07-12 14:39:24 -05:00
commit 4b761bebd4
7 changed files with 239 additions and 243 deletions

View file

@ -1,6 +1,6 @@
import os
import nimgen/config
import nimgen/runcfg
for i in commandLineParams():
if i != "-f":

130
src/nimgen/c2nim.nim Normal file
View file

@ -0,0 +1,130 @@
import os, ospaths, regex, strutils
import external, file, fileops, gencore, globals
template relativePath(path: untyped): untyped =
path.multiReplace([(gOutput, ""), ("\\", "/"), ("//", "/")])
proc c2nim*(fl, outfile: string, c2nimConfig: c2nimConfigObj) =
var file = search(fl)
if file == "":
return
if file in gDoneRecursive:
return
echo "Processing $# => $#" % [file, outfile]
gDoneRecursive.add(file)
# Remove static inline function bodies
removeStatic(file)
fixFuncProtos(file)
var cfile = file
if c2nimConfig.preprocess:
cfile = "temp-$#.c" % [outfile.extractFilename()]
writeFile(cfile, runPreprocess(file, c2nimConfig.ppflags, c2nimConfig.flags, c2nimConfig.inline))
elif c2nimConfig.ctags:
cfile = "temp-$#.c" % [outfile.extractFilename()]
writeFile(cfile, runCtags(file))
if c2nimConfig.defines and (c2nimConfig.preprocess or c2nimConfig.ctags):
prepend(cfile, getDefines(file, c2nimConfig.inline))
var
extflags = ""
passC = ""
outlib = ""
outpragma = ""
passC = "import ospaths, strutils\n"
for inc in gIncludes:
if inc.isAbsolute():
passC &= ("""{.passC: "-I\"$#\"".}""" % [inc]) & "\n"
else:
passC &= (
"""{.passC: "-I\"" & currentSourcePath().splitPath().head & "$#\"".}""" %
inc.relativePath()
) & "\n"
for prag in c2nimConfig.pragma:
outpragma &= "{." & prag & ".}\n"
let fname = file.splitFile().name.replace(re"[\.\-]", "_")
if c2nimConfig.dynlib.len() != 0:
let
win = "when defined(Windows):\n"
lin = "when defined(Linux):\n"
osx = "when defined(MacOSX):\n"
var winlib, linlib, osxlib: string = ""
for dl in c2nimConfig.dynlib:
let
lib = " const dynlib$# = \"$#\"\n" % [fname, dl]
ext = dl.splitFile().ext
if ext == ".dll":
winlib &= lib
elif ext == ".so":
linlib &= lib
elif ext == ".dylib":
osxlib &= lib
if winlib != "":
outlib &= win & winlib & "\n"
if linlib != "":
outlib &= lin & linlib & "\n"
if osxlib != "":
outlib &= osx & osxlib & "\n"
if outlib != "":
extflags &= " --dynlib:dynlib$#" % fname
else:
if file.isAbsolute():
passC &= "const header$# = \"$#\"\n" % [fname, file]
else:
passC &= "const header$# = currentSourcePath().splitPath().head & \"$#\"\n" %
[fname, file.relativePath()]
extflags = "--header:header$#" % fname
# Run c2nim on generated file
var cmd = "c2nim $# $# --out:$# $#" % [c2nimConfig.flags, extflags, outfile, cfile]
when defined(windows):
cmd = "cmd /c " & cmd
discard execProc(cmd)
if c2nimConfig.preprocess or c2nimConfig.ctags:
try:
removeFile(cfile)
except:
discard
# Nim doesn't like {.cdecl.} for type proc()
freplace(outfile, re"(?m)(.*? = proc.*?)\{.cdecl.\}", "$#")
freplace(outfile, " {.cdecl.})", ")")
# Include {.compile.} directives
for cpl in c2nimConfig.compile:
let fcpl = search(cpl)
if getFileInfo(fcpl).kind == pcFile:
prepend(outfile, compile(file=fcpl))
else:
prepend(outfile, compile(dir=fcpl))
# Add any pragmas
if outpragma != "":
prepend(outfile, outpragma)
# Add header file and include paths
if passC != "":
prepend(outfile, passC)
# Add dynamic library
if outlib != "":
prepend(outfile, outlib)
# Add back static functions for compilation
reAddStatic(file)

View file

@ -1,4 +1,4 @@
import os, osproc, streams, strutils
import os, osproc, regex, ropes, streams, strutils
import globals
@ -102,16 +102,61 @@ proc gitSparseCheckout*(plist: string) =
echo "Checking out artifacts"
discard execProc("git pull --depth=1 origin master")
proc doCopy*(flist: string) =
for pair in flist.split(","):
let spl = pair.split("=")
if spl.len() != 2:
echo "Bad copy syntax: " & flist
quit(1)
proc runPreprocess*(file, ppflags, flags: string, inline: bool): string =
var
pproc = if flags.contains("cpp"): gCppCompiler else: gCCompiler
cmd = "$# -E $# $#" % [pproc, ppflags, file]
let
lfile = spl[0].strip()
rfile = spl[1].strip()
for inc in gIncludes:
cmd &= " -I " & inc
copyFile(lfile, rfile)
echo "Copied $# to $#" % [lfile, rfile]
# Run preprocessor
var data = execProc(cmd)
# Include content only from file
var
rdata: Rope
start = false
sfile = file.replace("\\", "/")
if inline:
sfile = sfile.parentDir()
for line in data.splitLines():
if line.strip() != "":
if line[0] == '#' and not line.contains("#pragma"):
start = false
if sfile in line.replace("\\", "/").replace("//", "/"):
start = true
if not ("\\" in line) and not ("/" in line) and extractFilename(sfile) in line:
start = true
else:
if start:
rdata.add(
line.replace("_Noreturn", "")
.replace("(())", "")
.replace("WINAPI", "")
.replace("__attribute__", "")
.replace("extern \"C\"", "")
.replace(re"\(\([_a-z]+?\)\)", "")
.replace(re"\(\(__format__[\s]*\(__[gnu_]*printf__, [\d]+, [\d]+\)\)\);", ";") & "\n"
)
return $rdata
proc runCtags*(file: string): string =
var
cmd = "ctags -o - --fields=+S+K --c-kinds=+p --file-scope=no " & file
fps = execProc(cmd)
fdata = ""
for line in fps.splitLines():
var spl = line.split(re"\t")
if spl.len() > 4:
if spl[0] != "main" and spl[3] != "member":
var fn = ""
var match: RegexMatch
if spl[2].find(re"/\^(.*?)\(", match):
fn = spl[2][match.group(0)[0]]
fn &= spl[4].replace("signature:", "") & ";"
fdata &= fn & "\n"
return fdata

View file

@ -46,8 +46,33 @@ proc search*(file: string): string =
# Only keep relative directory
return result.multiReplace([("\\", $DirSep), ("//", $DirSep), (gProjectDir & $DirSep, "")])
proc rename*(file: string, renfile: string) =
if file.splitFile().ext == ".nim":
return
var
nimout = getNimout(file, false)
newname = renfile.replace("$nimout", extractFilename(nimout))
if newname =~ peg"(!\$.)*{'$replace'\s*'('\s*{(!\)\S)+}')'}":
var final = nimout.extractFilename()
for entry in matches[1].split(","):
let spl = entry.split("=")
if spl.len() != 2:
echo "Bad replace syntax: " & renfile
quit(1)
let
srch = spl[0].strip()
repl = spl[1].strip()
final = final.replace(srch, repl)
newname = newname.replace(matches[0], final)
gRenames[file] = gOutput/newname
# ###
# Loading / unloading
# Actions
proc openRetry*(file: string, mode: FileMode = fmRead): File =
while true:
@ -74,27 +99,16 @@ template withFile*(file: string, body: untyped): untyped =
else:
echo "Missing file " & file
proc rename*(file: string, renfile: string) =
if file.splitFile().ext == ".nim":
return
proc doCopy*(flist: string) =
for pair in flist.split(","):
let spl = pair.split("=")
if spl.len() != 2:
echo "Bad copy syntax: " & flist
quit(1)
var
nimout = getNimout(file, false)
newname = renfile.replace("$nimout", extractFilename(nimout))
let
lfile = spl[0].strip()
rfile = spl[1].strip()
if newname =~ peg"(!\$.)*{'$replace'\s*'('\s*{(!\)\S)+}')'}":
var final = nimout.extractFilename()
for entry in matches[1].split(","):
let spl = entry.split("=")
if spl.len() != 2:
echo "Bad replace syntax: " & renfile
quit(1)
let
srch = spl[0].strip()
repl = spl[1].strip()
final = final.replace(srch, repl)
newname = newname.replace(matches[0], final)
gRenames[file] = gOutput/newname
copyFile(lfile, rfile)
echo "Copied $# to $#" % [lfile, rfile]

View file

@ -1,6 +1,6 @@
import os, regex, strutils
import file, prepare
import external, file
# ###
# Manipulating content

View file

@ -1,6 +1,6 @@
import os, regex, ropes, sequtils, strutils, tables
import os, regex, sequtils, strutils
import file, fileops, globals, prepare
import file, globals
proc addEnv*(str: string): string =
var newStr = str
@ -92,204 +92,3 @@ proc getDefines*(file: string, inline=false): string =
withFile(file):
for def in content.findAll(re"(?m)^(\s*#\s*define\s+[\w\d_]+\s+[\d\-.xf]+)(?:\r|//|/*).*?$"):
result &= content[def.group(0)[0]] & "\n"
proc runPreprocess*(file, ppflags, flags: string, inline: bool): string =
var
pproc = if flags.contains("cpp"): gCppCompiler else: gCCompiler
cmd = "$# -E $# $#" % [pproc, ppflags, file]
for inc in gIncludes:
cmd &= " -I " & inc
# Run preprocessor
var data = execProc(cmd)
# Include content only from file
var
rdata: Rope
start = false
sfile = file.replace("\\", "/")
if inline:
sfile = sfile.parentDir()
for line in data.splitLines():
if line.strip() != "":
if line[0] == '#' and not line.contains("#pragma"):
start = false
if sfile in line.replace("\\", "/").replace("//", "/"):
start = true
if not ("\\" in line) and not ("/" in line) and extractFilename(sfile) in line:
start = true
else:
if start:
rdata.add(
line.replace("_Noreturn", "")
.replace("(())", "")
.replace("WINAPI", "")
.replace("__attribute__", "")
.replace("extern \"C\"", "")
.replace(re"\(\([_a-z]+?\)\)", "")
.replace(re"\(\(__format__[\s]*\(__[gnu_]*printf__, [\d]+, [\d]+\)\)\);", ";") & "\n"
)
return $rdata
proc runCtags*(file: string): string =
var
cmd = "ctags -o - --fields=+S+K --c-kinds=+p --file-scope=no " & file
fps = execProc(cmd)
fdata = ""
for line in fps.splitLines():
var spl = line.split(re"\t")
if spl.len() > 4:
if spl[0] != "main" and spl[3] != "member":
var fn = ""
var match: RegexMatch
if spl[2].find(re"/\^(.*?)\(", match):
fn = spl[2][match.group(0)[0]]
fn &= spl[4].replace("signature:", "") & ";"
fdata &= fn & "\n"
return fdata
template relativePath(path: untyped): untyped =
path.multiReplace([(gOutput, ""), ("\\", "/"), ("//", "/")])
proc c2nim*(fl, outfile: string, c2nimConfig: c2nimConfigObj): seq[string] =
var
incls: seq[string] = @[]
incout = ""
file = search(fl)
if file == "":
return
if file in gDoneRecursive:
return
echo "Processing $# => $#" % [file, outfile]
gDoneRecursive.add(file)
# Remove static inline function bodies
removeStatic(file)
fixFuncProtos(file)
if c2nimConfig.recurse:
incls = getIncls(file)
for inc in incls:
incout &= "import $#\n" % inc.search().getNimout()[0 .. ^5]
var cfile = file
if c2nimConfig.preprocess:
cfile = "temp-$#.c" % [outfile.extractFilename()]
writeFile(cfile, runPreprocess(file, c2nimConfig.ppflags, c2nimConfig.flags, c2nimConfig.inline))
elif c2nimConfig.ctags:
cfile = "temp-$#.c" % [outfile.extractFilename()]
writeFile(cfile, runCtags(file))
if c2nimConfig.defines and (c2nimConfig.preprocess or c2nimConfig.ctags):
prepend(cfile, getDefines(file, c2nimConfig.inline))
var
extflags = ""
passC = ""
outlib = ""
outpragma = ""
passC = "import ospaths, strutils\n"
for inc in gIncludes:
if inc.isAbsolute():
passC &= ("""{.passC: "-I\"$#\"".}""" % [inc]) & "\n"
else:
passC &= (
"""{.passC: "-I\"" & currentSourcePath().splitPath().head & "$#\"".}""" %
inc.relativePath()
) & "\n"
for prag in c2nimConfig.pragma:
outpragma &= "{." & prag & ".}\n"
let fname = file.splitFile().name.replace(re"[\.\-]", "_")
if c2nimConfig.dynlib.len() != 0:
let
win = "when defined(Windows):\n"
lin = "when defined(Linux):\n"
osx = "when defined(MacOSX):\n"
var winlib, linlib, osxlib: string = ""
for dl in c2nimConfig.dynlib:
let
lib = " const dynlib$# = \"$#\"\n" % [fname, dl]
ext = dl.splitFile().ext
if ext == ".dll":
winlib &= lib
elif ext == ".so":
linlib &= lib
elif ext == ".dylib":
osxlib &= lib
if winlib != "":
outlib &= win & winlib & "\n"
if linlib != "":
outlib &= lin & linlib & "\n"
if osxlib != "":
outlib &= osx & osxlib & "\n"
if outlib != "":
extflags &= " --dynlib:dynlib$#" % fname
else:
if file.isAbsolute():
passC &= "const header$# = \"$#\"\n" % [fname, file]
else:
passC &= "const header$# = currentSourcePath().splitPath().head & \"$#\"\n" %
[fname, file.relativePath()]
extflags = "--header:header$#" % fname
# Run c2nim on generated file
var cmd = "c2nim $# $# --out:$# $#" % [c2nimConfig.flags, extflags, outfile, cfile]
when defined(windows):
cmd = "cmd /c " & cmd
discard execProc(cmd)
if c2nimConfig.preprocess or c2nimConfig.ctags:
try:
removeFile(cfile)
except:
discard
# Import nim modules
if c2nimConfig.recurse:
prepend(outfile, incout)
# Nim doesn't like {.cdecl.} for type proc()
freplace(outfile, re"(?m)(.*? = proc.*?)\{.cdecl.\}", "$#")
freplace(outfile, " {.cdecl.})", ")")
# Include {.compile.} directives
for cpl in c2nimConfig.compile:
let fcpl = search(cpl)
if getFileInfo(fcpl).kind == pcFile:
prepend(outfile, compile(file=fcpl))
else:
prepend(outfile, compile(dir=fcpl))
# Add any pragmas
if outpragma != "":
prepend(outfile, outpragma)
# Add header file and include paths
if passC != "":
prepend(outfile, passC)
# Add dynamic library
if outlib != "":
prepend(outfile, outlib)
# Add back static functions for compilation
reAddStatic(file)
return incls

View file

@ -1,6 +1,6 @@
import os, parsecfg, regex, strutils, tables
import file, fileops, gencore, globals, prepare
import c2nim, external, file, fileops, gencore, globals
proc `[]`*(table: OrderedTableRef[string, string], key: string): string =
## Gets table values with env vars inserted
@ -109,10 +109,14 @@ proc runFile*(file: string, cfgin: OrderedTableRef) =
quit(1)
if not noprocess:
var incls = c2nim(file, getNimout(sfile), c2nimConfig)
if c2nimConfig.recurse and incls.len() != 0:
let outfile = getNimout(sfile)
c2nim(file, outfile, c2nimConfig)
if c2nimConfig.recurse:
var
cfg = newOrderedTable[string, string]()
incls = getIncls(sfile)
incout = ""
for name, value in c2nimConfig.fieldPairs:
when value is string:
@ -125,6 +129,10 @@ proc runFile*(file: string, cfgin: OrderedTableRef) =
for inc in incls:
runFile(inc, cfg)
incout &= "import $#\n" % inc.search().getNimout()[0 .. ^5]
if incout.len() != 0:
prepend(outfile, incout)
proc runCfg*(cfg: string) =
if not fileExists(cfg):