diff options
| author | Ganesh Viswanathan <dev@genotrance.com> | 2019-02-06 14:47:09 -0600 |
|---|---|---|
| committer | Ganesh Viswanathan <dev@genotrance.com> | 2019-02-06 14:47:09 -0600 |
| commit | 10aef55dadfbb9a4a1b4cab5ce64242cc1a63d66 (patch) | |
| tree | 1da683f201c3d002096ef979dde03161ad986ed9 | |
| parent | 61eb0457441a8cc7d45a6cad53ebac8a7cc0d4f9 (diff) | |
| download | nimterop-10aef55dadfbb9a4a1b4cab5ce64242cc1a63d66.tar.gz nimterop-10aef55dadfbb9a4a1b4cab5ce64242cc1a63d66.zip | |
Add exclude to cCompile, fix duplicate filename compilation, mkDir fix, cp/mvFile, full relativePath
| -rw-r--r-- | nimterop/ast.nim | 2 | ||||
| -rw-r--r-- | nimterop/cimport.nim | 61 | ||||
| -rw-r--r-- | nimterop/git.nim | 76 |
3 files changed, 110 insertions, 29 deletions
diff --git a/nimterop/ast.nim b/nimterop/ast.nim index 1cc2c6c..94465a7 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -146,7 +146,7 @@ proc printNim*(fullpath: string, root: TSNode, astTable: AstTable) = nimState.identifiers = newTable[string, string]() nimState.currentHeader = getCurrentHeader(fullpath) - nimState.constStr &= &"\n {nimState.currentHeader} = \"{fp}\"" + nimState.constStr &= &"\n {nimState.currentHeader} {{.used.}} = \"{fp}\"" root.searchAst(astTable, nimState) diff --git a/nimterop/cimport.nim b/nimterop/cimport.nim index 714cc93..443eca3 100644 --- a/nimterop/cimport.nim +++ b/nimterop/cimport.nim @@ -12,9 +12,9 @@ import hashes, macros, os, strformat, strutils const CIMPORT {.used.} = 1 -include "." / globals +include "."/globals -import "." / [types, paths] +import "."/[git, paths, types] export types proc interpPath(dir: string): string= @@ -359,7 +359,7 @@ proc cAddStdDir*(mode = "c") {.compileTime.} = if inc: cAddSearchDir line.strip() -macro cCompile*(path: static string, mode = "c"): untyped = +macro cCompile*(path: static string, mode = "c", exclude = ""): untyped = ## Compile and link C/C++ implementation into resulting binary using ``{.compile.}`` ## ## ``path`` can be a specific file or contain wildcards: @@ -376,6 +376,13 @@ macro cCompile*(path: static string, mode = "c"): untyped = ## .. code-block:: nim ## ## cCompile("path/to/dir", "cpp") + ## + ## ``exclude`` can be used to exclude files by partial string match. Comma separated to + ## specify multiple exclude strings + ## + ## .. code-block:: nim + ## + ## cCompile("path/to/dir", exclude="test2.c") result = newNimNode(nnkStmtList) @@ -383,7 +390,8 @@ macro cCompile*(path: static string, mode = "c"): untyped = stmt = "" proc fcompile(file: string): string = - let fn = file.splitFile().name + let + (_, fn, ext) = file.splitFile() var ufn = fn uniq = 1 @@ -391,32 +399,53 @@ macro cCompile*(path: static string, mode = "c"): untyped = ufn = fn & $uniq uniq += 1 + # - https://github.com/nim-lang/Nim/issues/10299 + # - https://github.com/nim-lang/Nim/issues/10486 gStateCT.compile.add(ufn) if fn == ufn: - return "{.compile: \"$#\".}" % file.replace("\\", "/") + return "{.compile: \"$#\".}\n" % file.replace("\\", "/") else: - return "{.compile: (\"../$#\", \"$#.o\").}" % [file.replace("\\", "/"), ufn] - - proc dcompile(dir: string, ext=""): string = + # - https://github.com/nim-lang/Nim/issues/9370 + let + hash = file.hash().abs() + tmpFile = file.parentDir() / &"_nimterop_{$hash}_{ufn}{ext}" + if not tmpFile.fileExists() or file.getFileDate() > tmpFile.getFileDate(): + cpFile(file, tmpFile) + return "{.compile: \"$#\".}\n" % tmpFile.replace("\\", "/") + + # Due to https://github.com/nim-lang/Nim/issues/9863 + # cannot use seq[string] for excludes + proc notExcluded(file, exclude: string): bool = + result = true + if "_nimterop_" in file: + result = false + elif exclude.len != 0: + for excl in exclude.split(","): + if excl in file: + result = false + + proc dcompile(dir, exclude: string, ext=""): string = let files = walkDirImpl(dir, ext) for f in files: - if f.len != 0: - result &= fcompile(f) & "\n" + if f.len != 0 and f.notExcluded(exclude): + result &= fcompile(f) if path.contains("*") or path.contains("?"): - stmt &= dcompile(path) + stmt &= dcompile(path, exclude.strVal()) else: let fpath = findPath(path) - if fileExists(fpath): - stmt &= fcompile(fpath) & "\n" + if fileExists(fpath) and fpath.notExcluded(exclude.strVal()): + stmt &= fcompile(fpath) elif dirExists(fpath): if mode.strVal().contains("cpp"): - for i in @["*.C", "*.cpp", "*.c++", "*.cc", "*.cxx"]: - stmt &= dcompile(fpath, i) + for i in @["*.cpp", "*.c++", "*.cc", "*.cxx"]: + stmt &= dcompile(fpath, exclude.strVal(), i) + when not defined(Windows): + stmt &= dcompile(fpath, exclude.strVal(), "*.C") else: - stmt &= dcompile(fpath, "*.c") + stmt &= dcompile(fpath, exclude.strVal(), "*.c") result.add stmt.parseStmt() diff --git a/nimterop/git.nim b/nimterop/git.nim index f7de472..5b657b9 100644 --- a/nimterop/git.nim +++ b/nimterop/git.nim @@ -23,9 +23,70 @@ proc execAction*(cmd: string, nostderr=false): string = doAssert false, msg proc mkDir*(dir: string) = + if not dirExists(dir): + let + flag = when not defined(Windows): "-p" else: "" + discard execAction(&"mkdir {flag} {dir.quoteShell}") + +proc cpFile*(source, dest: string, move=false) = let - flag = when not defined(Windows): "-p" else: "" - discard execAction(&"mkdir {flag} {dir.quoteShell}") + source = source.replace("/", $DirSep) + dest = dest.replace("/", $DirSep) + cmd = + when defined(Windows): + if move: + "move /y" + else: + "copy /y" + else: + if move: + "mv -f" + else: + "cp -f" + + discard execAction(&"{cmd} {source.quoteShell} {dest.quoteShell}") + +proc mvFile*(source, dest: string) = + cpFile(source, dest, move=true) + +when (NimMajor, NimMinor, NimPatch) < (0, 19, 9): + proc relativePath*(path, base: string; sep = DirSep): string = + ## Copied from `os.relativePath` ; remove after nim >= 0.19.9 + if path.len == 0: return "" + var f, b: PathIter + var ff = (0, -1) + var bb = (0, -1) # (int, int) + result = newStringOfCap(path.len) + while f.hasNext(path) and b.hasNext(base): + ff = next(f, path) + bb = next(b, base) + let diff = ff[1] - ff[0] + if diff != bb[1] - bb[0]: break + var same = true + for i in 0..diff: + if path[i + ff[0]] !=? base[i + bb[0]]: + same = false + break + if not same: break + ff = (0, -1) + bb = (0, -1) + + while true: + if bb[1] >= bb[0]: + if result.len > 0 and result[^1] != sep: + result.add sep + result.add ".." + if not b.hasNext(base): break + bb = b.next(base) + + while true: + if ff[1] >= ff[0]: + if result.len > 0 and result[^1] != sep: + result.add sep + for i in 0..ff[1] - ff[0]: + result.add path[i + ff[0]] + if not f.hasNext(path): break + ff = f.next(path) proc extractZip*(zipfile, outdir: string) = var cmd = "unzip -o $#" @@ -62,18 +123,9 @@ proc gitReset*(outdir: string) = sleep(1000) echo " Retrying ..." -proc relativePathNaive*(file, base: string): string = - ## naive version of `os.relativePath` ; remove after nim >= 0.19.9 - runnableExamples: - doAssert "/foo/bar/baz/log.txt".relativePathNaive("/foo/bar") == "baz/log.txt" - var base = base - if not base.endsWith "/": base.add "/" - doAssert file.startsWith base - result = file[base.len .. ^1] - proc gitCheckout*(file, outdir: string) = echo "Resetting " & file - let file2 = file.relativePathNaive outdir + let file2 = file.relativePath outdir let cmd = &"cd {outdir.quoteShell} && git checkout {file2.quoteShell}" while execAction(cmd).contains("Permission denied"): sleep(500) |
