diff options
| author | Ganesh Viswanathan <dev@genotrance.com> | 2018-07-12 14:39:24 -0500 |
|---|---|---|
| committer | Ganesh Viswanathan <dev@genotrance.com> | 2018-07-12 14:39:24 -0500 |
| commit | 4b761bebd4528d771cfb4b56d5b2e73f34e9a6d5 (patch) | |
| tree | ab4af5ad4f87faa9537d41d8cd913d9178eb3339 /src | |
| parent | 562f3fd7ebbbef9302d62a3ef578a614fa345a2a (diff) | |
| download | nimgen-4b761bebd4528d771cfb4b56d5b2e73f34e9a6d5.tar.gz nimgen-4b761bebd4528d771cfb4b56d5b2e73f34e9a6d5.zip | |
Fix rename bug, additional cleanup
Diffstat (limited to 'src')
| -rw-r--r-- | src/nimgen.nim | 2 | ||||
| -rw-r--r-- | src/nimgen/c2nim.nim | 130 | ||||
| -rw-r--r-- | src/nimgen/external.nim (renamed from src/nimgen/prepare.nim) | 69 | ||||
| -rw-r--r-- | src/nimgen/file.nim | 60 | ||||
| -rw-r--r-- | src/nimgen/fileops.nim | 2 | ||||
| -rw-r--r-- | src/nimgen/gencore.nim | 205 | ||||
| -rw-r--r-- | src/nimgen/runcfg.nim (renamed from src/nimgen/config.nim) | 14 |
7 files changed, 239 insertions, 243 deletions
diff --git a/src/nimgen.nim b/src/nimgen.nim index 44ee88b..5777398 100644 --- a/src/nimgen.nim +++ b/src/nimgen.nim @@ -1,6 +1,6 @@ import os -import nimgen/config +import nimgen/runcfg for i in commandLineParams(): if i != "-f": diff --git a/src/nimgen/c2nim.nim b/src/nimgen/c2nim.nim new file mode 100644 index 0000000..07b15e0 --- /dev/null +++ b/src/nimgen/c2nim.nim @@ -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) diff --git a/src/nimgen/prepare.nim b/src/nimgen/external.nim index a1857a5..f642cfb 100644 --- a/src/nimgen/prepare.nim +++ b/src/nimgen/external.nim @@ -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] + + for inc in gIncludes: + cmd &= " -I " & inc - let - lfile = spl[0].strip() - rfile = spl[1].strip() + # Run preprocessor + var data = execProc(cmd) - copyFile(lfile, rfile) - echo "Copied $# to $#" % [lfile, rfile] + # 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 diff --git a/src/nimgen/file.nim b/src/nimgen/file.nim index 27296d2..1a316bf 100644 --- a/src/nimgen/file.nim +++ b/src/nimgen/file.nim @@ -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 - - 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() +proc doCopy*(flist: string) = + for pair in flist.split(","): + let spl = pair.split("=") + if spl.len() != 2: + echo "Bad copy syntax: " & flist + quit(1) - final = final.replace(srch, repl) - newname = newname.replace(matches[0], final) + let + lfile = spl[0].strip() + rfile = spl[1].strip() - gRenames[file] = gOutput/newname + copyFile(lfile, rfile) + echo "Copied $# to $#" % [lfile, rfile] diff --git a/src/nimgen/fileops.nim b/src/nimgen/fileops.nim index d7ecd62..2e51d09 100644 --- a/src/nimgen/fileops.nim +++ b/src/nimgen/fileops.nim @@ -1,6 +1,6 @@ import os, regex, strutils -import file, prepare +import external, file # ### # Manipulating content diff --git a/src/nimgen/gencore.nim b/src/nimgen/gencore.nim index 59e86fe..f794991 100644 --- a/src/nimgen/gencore.nim +++ b/src/nimgen/gencore.nim @@ -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 diff --git a/src/nimgen/config.nim b/src/nimgen/runcfg.nim index 3a0f3b0..96e067e 100644 --- a/src/nimgen/config.nim +++ b/src/nimgen/runcfg.nim @@ -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): |
