aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rw-r--r--nimgen.nim164
-rw-r--r--nimgen.nimble2
3 files changed, 94 insertions, 74 deletions
diff --git a/README.md b/README.md
index aadfd90..d47239e 100644
--- a/README.md
+++ b/README.md
@@ -101,6 +101,8 @@ The following keys can be used to prepare dependencies such as downloading ZIP f
```execute``` = command to run during preparation
+```copy``` = copy a file to another location. Preferred over moving to preserve original. Comma separate for multiple entries. E.g. copy = "output/config.h.in=output/config.h"
+
_[n.wildcard]_
File wildcards such as *.nim, ssl*.h, etc. can be used to perform tasks across a group of files. This is useful to define common operations such as global text replacements without having to specify an explicit section for every single file. These operations will be performed on every matching file that is defined as a _sourcefile_ or recursed files. Only applies on source files following the wildcard declarations.
diff --git a/nimgen.nim b/nimgen.nim
index 4766bb7..fc3e8ce 100644
--- a/nimgen.nim
+++ b/nimgen.nim
@@ -1,17 +1,17 @@
import nre, os, ospaths, osproc, parsecfg, pegs, ropes, sequtils, streams, strutils, tables
var
- DONE: seq[string] = @[]
- DONE_INLINE: seq[string] = @[]
-
- CONFIG: Config
- FILTER = ""
- QUOTES = true
- OUTPUT = ""
- INCLUDES: seq[string] = @[]
- EXCLUDES: seq[string] = @[]
- RENAMES = initTable[string, string]()
- WILDCARDS = newConfig()
+ gDoneRecursive: seq[string] = @[]
+ gDoneInline: seq[string] = @[]
+
+ gConfig: Config
+ gFilter = ""
+ gQuotes = true
+ gOutput = ""
+ gIncludes: seq[string] = @[]
+ gExcludes: seq[string] = @[]
+ gRenames = initTable[string, string]()
+ gWildcards = newConfig()
const DOC = """
Nimgen is a helper for c2nim to simpilfy and automate the wrapping of C libraries
@@ -52,7 +52,7 @@ proc extractZip(zipfile: string) =
if defined(Windows):
cmd = "powershell -nologo -noprofile -command \"& { Add-Type -A 'System.IO.Compression.FileSystem'; [IO.Compression.ZipFile]::ExtractToDirectory('$#', '.'); }\""
- setCurrentDir(OUTPUT)
+ setCurrentDir(gOutput)
defer: setCurrentDir("..")
echo "Extracting " & zipfile
@@ -67,9 +67,9 @@ proc downloadUrl(url: string) =
if defined(Windows):
cmd = "powershell wget $# -OutFile $#"
- if not (ext == ".zip" and fileExists(OUTPUT/file)):
+ if not (ext == ".zip" and fileExists(gOutput/file)):
echo "Downloading " & file
- discard execProc(cmd % [url, OUTPUT/file])
+ discard execProc(cmd % [url, gOutput/file])
if ext == ".zip":
extractZip(file)
@@ -77,18 +77,18 @@ proc downloadUrl(url: string) =
proc gitReset() =
echo "Resetting Git repo"
- setCurrentDir(OUTPUT)
+ setCurrentDir(gOutput)
defer: setCurrentDir("..")
discard execProc("git reset --hard HEAD")
proc gitRemotePull(url: string, pull=true) =
- if dirExists(OUTPUT/".git"):
+ if dirExists(gOutput/".git"):
if pull:
gitReset()
return
- setCurrentDir(OUTPUT)
+ setCurrentDir(gOutput)
defer: setCurrentDir("..")
echo "Setting up Git repo"
@@ -101,11 +101,11 @@ proc gitRemotePull(url: string, pull=true) =
proc gitSparseCheckout(plist: string) =
let sparsefile = ".git/info/sparse-checkout"
- if fileExists(OUTPUT/sparsefile):
+ if fileExists(gOutput/sparsefile):
gitReset()
return
- setCurrentDir(OUTPUT)
+ setCurrentDir(gOutput)
defer: setCurrentDir("..")
discard execProc("git config core.sparsecheckout true")
@@ -114,6 +114,20 @@ 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)
+
+ let
+ lfile = spl[0].strip()
+ rfile = spl[1].strip()
+
+ copyFile(lfile, rfile)
+ echo "Copied $# to $#" % [lfile, rfile]
+
proc getKey(ukey: string): tuple[key: string, val: bool] =
var kv = ukey.replace(re"\..*", "").split("-", 1)
if kv.len() == 1:
@@ -132,20 +146,20 @@ proc getKey(ukey: string): tuple[key: string, val: bool] =
proc getNimout(file: string, rename=true): string =
result = file.splitFile().name.replace(re"[\-\.]", "_") & ".nim"
- if OUTPUT != "":
- result = OUTPUT/result
+ if gOutput != "":
+ result = gOutput/result
if not rename:
return
- if RENAMES.hasKey(file):
- result = RENAMES[file]
+ if gRenames.hasKey(file):
+ result = gRenames[file]
if not dirExists(parentDir(result)):
createDir(parentDir(result))
proc exclude(file: string): bool =
- for excl in EXCLUDES:
+ for excl in gExcludes:
if excl in file:
return true
return false
@@ -159,7 +173,7 @@ proc search(file: string): string =
result = getNimout(file)
elif not fileExists(result) and not dirExists(result):
var found = false
- for inc in INCLUDES:
+ for inc in gIncludes:
result = inc/file
if fileExists(result) or dirExists(result):
found = true
@@ -265,7 +279,6 @@ proc rename(file: string, renfile: string) =
nimout = getNimout(file, false)
newname = renfile.replace("$nimout", extractFilename(nimout))
- #if newname =~ peg"(!\$.)*{'$replace'\s*'('\s*{(!\,\S)+}\s*','\s*{(!\)\S)+}\s*')'}":
if newname =~ peg"(!\$.)*{'$replace'\s*'('\s*{(!\)\S)+}')'}":
var final = nimout.extractFilename()
for entry in matches[1].split(","):
@@ -274,14 +287,14 @@ proc rename(file: string, renfile: string) =
echo "Bad replace syntax: " & renfile
quit(1)
- var
+ let
srch = spl[0].strip()
repl = spl[1].strip()
final = final.replace(srch, repl)
newname = newname.replace(matches[0], final)
- RENAMES[file] = OUTPUT/newname
+ gRenames[file] = gOutput/newname
proc compile(dir="", file=""): string =
proc fcompile(file: string): string =
@@ -309,19 +322,19 @@ proc fixFuncProtos(file: string) =
proc getIncls(file: string, inline=false): seq[string] =
result = @[]
- if inline and file in DONE_INLINE:
+ if inline and file in gDoneInline:
return
withFile(file):
for f in content.findIter(re"(?m)^\s*#\s*include\s+(.*?)$"):
var inc = f.captures[0].strip()
- if ((QUOTES and inc.contains("\"")) or (FILTER != "" and FILTER in inc)) and (not exclude(inc)):
+ if ((gQuotes and inc.contains("\"")) or (gFilter != "" and gFilter in inc)) and (not exclude(inc)):
result.add(
inc.replace(re"""[<>"]""", "").replace(re"\/[\*\/].*$", "").strip())
result = result.deduplicate()
- DONE_INLINE.add(file)
+ gDoneInline.add(file)
if inline:
var sres = newSeq[string]()
@@ -353,7 +366,7 @@ proc runPreprocess(file, ppflags, flags: string, inline: bool): string =
pproc = if flags.contains("cpp"): "g++" else: "gcc"
cmd = "$# -E $# $#" % [pproc, ppflags, file]
- for inc in INCLUDES:
+ for inc in gIncludes:
cmd &= " -I " & inc
# Run preprocessor
@@ -414,11 +427,11 @@ proc c2nim(fl, outfile, flags, ppflags: string, recurse, inline, preprocess, cta
if file == "":
return
- if file in DONE:
+ if file in gDoneRecursive:
return
echo "Processing $# => $#" % [file, outfile]
- DONE.add(file)
+ gDoneRecursive.add(file)
fixFuncProtos(file)
@@ -455,10 +468,11 @@ proc c2nim(fl, outfile, flags, ppflags: string, recurse, inline, preprocess, cta
passC = ""
outlib = ""
outpragma = ""
+ outcompile = ""
passC = "import strutils\n"
- for inc in INCLUDES:
- passC &= ("""{.passC: "-I\"" & gorge("nimble path $#").strip() & "/$#\"".}""" % [OUTPUT, inc]) & "\n"
+ for inc in gIncludes:
+ passC &= ("""{.passC: "-I\"" & gorge("nimble path $#").strip() & "/$#\"".}""" % [gOutput, inc]) & "\n"
for prag in pragma:
outpragma &= "{." & prag & ".}\n"
@@ -517,6 +531,8 @@ proc c2nim(fl, outfile, flags, ppflags: string, recurse, inline, preprocess, cta
freplace(outfile, " {.cdecl.})", ")")
# Include {.compile.} directives
+ outcompile = compile(compile)
+
for cpl in compile:
let fcpl = search(cpl)
if getFileInfo(fcpl).kind == pcFile:
@@ -544,12 +560,12 @@ proc runFile(file: string, cfgin: OrderedTableRef) =
cfg = cfgin
sfile = search(file)
- for pattern in WILDCARDS.keys():
+ for pattern in gWildcards.keys():
let pat = pattern.replace(".", "\\.").replace("*", ".*").replace("?", ".?")
if file.find(re(pat)).isSome():
echo "Appending " & file & " " & pattern
- for key in WILDCARDS[pattern].keys():
- cfg[key & "." & pattern] = WILDCARDS[pattern][key]
+ for key in gWildcards[pattern].keys():
+ cfg[key & "." & pattern] = gWildcards[pattern][key]
var
srch = ""
@@ -634,73 +650,75 @@ proc runCfg(cfg: string) =
echo "Config doesn't exist: " & cfg
quit(1)
- CONFIG = loadConfig(cfg)
+ gConfig = loadConfig(cfg)
- if CONFIG.hasKey("n.global"):
- if CONFIG["n.global"].hasKey("output"):
- OUTPUT = CONFIG["n.global"]["output"]
- if dirExists(OUTPUT):
+ if gConfig.hasKey("n.global"):
+ if gConfig["n.global"].hasKey("output"):
+ gOutput = gConfig["n.global"]["output"]
+ if dirExists(gOutput):
if "-f" in commandLineParams():
try:
- removeDir(OUTPUT)
+ removeDir(gOutput)
except OSError:
- echo "Directory in use: " & OUTPUT
+ echo "Directory in use: " & gOutput
quit(1)
else:
- for f in walkFiles(OUTPUT/"*.nim"):
+ for f in walkFiles(gOutput/"*.nim"):
try:
removeFile(f)
except OSError:
echo "Unable to delete: " & f
quit(1)
- createDir(OUTPUT)
+ createDir(gOutput)
- if CONFIG["n.global"].hasKey("filter"):
- FILTER = CONFIG["n.global"]["filter"]
- if CONFIG["n.global"].hasKey("quotes"):
- if CONFIG["n.global"]["quotes"] == "false":
- QUOTES = false
+ if gConfig["n.global"].hasKey("filter"):
+ gFilter = gConfig["n.global"]["filter"]
+ if gConfig["n.global"].hasKey("quotes"):
+ if gConfig["n.global"]["quotes"] == "false":
+ gQuotes = false
- if CONFIG.hasKey("n.include"):
- for inc in CONFIG["n.include"].keys():
- INCLUDES.add(inc)
+ if gConfig.hasKey("n.include"):
+ for inc in gConfig["n.include"].keys():
+ gIncludes.add(inc)
- if CONFIG.hasKey("n.exclude"):
- for excl in CONFIG["n.exclude"].keys():
- EXCLUDES.add(excl)
+ if gConfig.hasKey("n.exclude"):
+ for excl in gConfig["n.exclude"].keys():
+ gExcludes.add(excl)
- if CONFIG.hasKey("n.prepare"):
- for prep in CONFIG["n.prepare"].keys():
+ if gConfig.hasKey("n.prepare"):
+ for prep in gConfig["n.prepare"].keys():
let (key, val) = getKey(prep)
if val == true:
if key == "download":
- downloadUrl(CONFIG["n.prepare"][prep])
+ downloadUrl(gConfig["n.prepare"][prep])
elif key == "extract":
- extractZip(CONFIG["n.prepare"][prep])
+ extractZip(gConfig["n.prepare"][prep])
elif key == "git":
- gitRemotePull(CONFIG["n.prepare"][prep])
+ gitRemotePull(gConfig["n.prepare"][prep])
elif key == "gitremote":
- gitRemotePull(CONFIG["n.prepare"][prep], false)
+ gitRemotePull(gConfig["n.prepare"][prep], false)
elif key == "gitsparse":
- gitSparseCheckout(CONFIG["n.prepare"][prep])
+ gitSparseCheckout(gConfig["n.prepare"][prep])
elif key == "execute":
- discard execProc(CONFIG["n.prepare"][prep])
+ discard execProc(gConfig["n.prepare"][prep])
+ elif key == "copy":
+ doCopy(gConfig["n.prepare"][prep])
- if CONFIG.hasKey("n.wildcard"):
+ if gConfig.hasKey("n.wildcard"):
var wildcard = ""
- for wild in CONFIG["n.wildcard"].keys():
+ for wild in gConfig["n.wildcard"].keys():
let (key, val) = getKey(wild)
if val == true:
if key == "wildcard":
- wildcard = CONFIG["n.wildcard"][wild]
+ wildcard = gConfig["n.wildcard"][wild]
else:
- WILDCARDS.setSectionKey(wildcard, wild, CONFIG["n.wildcard"][wild])
+ gWildcards.setSectionKey(wildcard, wild, gConfig["n.wildcard"][wild])
- for file in CONFIG.keys():
+ for file in gConfig.keys():
if file in @["n.global", "n.include", "n.exclude", "n.prepare", "n.wildcard"]:
continue
- runFile(file, CONFIG[file])
+ runFile(file, gConfig[file])
# ###
# Main loop
diff --git a/nimgen.nimble b/nimgen.nimble
index 3e458ba..4d7106a 100644
--- a/nimgen.nimble
+++ b/nimgen.nimble
@@ -1,6 +1,6 @@
# Package
-version = "0.2.0"
+version = "0.2.1"
author = "genotrance"
description = "c2nim helper to simplify and automate the wrapping of C libraries"
license = "MIT"