diff --git a/nimterop/build.nim b/nimterop/build.nim index a3dd95f..bcbd96a 100644 --- a/nimterop/build.nim +++ b/nimterop/build.nim @@ -1,4 +1,4 @@ -import macros, osproc, regex, strformat, strutils, tables +import macros, osproc, strformat, strutils, tables import os except findExe, sleep @@ -253,31 +253,52 @@ proc gitPull*(url: string, outdir = "", plist = "", checkout = "") = echo "# Pulling repository" discard execAction(&"cd {outdirQ} && git pull --depth=1 origin master") -proc findFile*(file: string|Regex, dir: string, recurse = true, first = false): string = +proc findFile*(file: string, dir: string, recurse = true, first = false, regex = false): string = ## Find the file in the specified directory ## - ## `file` can be a string or a regex object + ## `file` is a regular expression if `regex` is true ## ## Turn off recursive search with `recurse` and stop on first match with ## `first`. Without it, the shortest match is returned. - when file is Regex: - var - rm: RegexMatch + var + cmd = + when defined(windows): + "nimgrep --filenames --oneline --nocolor $1 $2 $3" + elif defined(linux): + "find $3 $1 -regextype egrep -regex $2" + elif defined(osx): + "find -E $3 $1 -regex $2" + + recursive = "" + + if recurse: + when defined(windows): + recursive = "--recursive" else: + when not defined(windows): + recursive = "-maxdepth 1" + + if not regex: let dir = dir / file.parentDir() file = file.extractFilename - for f in walkDirRec(dir, yieldFilter = {pcFile, pcLinkToFile}, - followFilter = if recurse: {pcDir} else: {}): - let - fn = f.extractFilename() - when file is string: - if (result.len == 0 or result.len > f.len) and fn == file: - result = f - if first: break - else: - if (result.len == 0 or result.len > f.len) and fn.match(file, rm): + cmd = cmd % [recursive, (".*[\\\\/]" & file & "$").quoteShell, dir.sanitizePath] + + let + (files, ret) = gorgeEx(cmd) + if ret == 0: + for line in files.splitLines(): + let f = + when defined(windows): + if ": " in line: + line.split(": ", maxsplit = 1)[1] + else: + "" + else: + line + + if (f.len != 0 and (result.len == 0 or result.len > f.len)): result = f if first: break @@ -442,7 +463,7 @@ proc cmake*(path, check, flags: string) = doAssert (path / check).fileExists(), "# cmake failed" -proc make*(path, check: string|Regex, flags = "") = +proc make*(path, check: string, flags = "", regex = false) = ## Run the `make` command to build all binaries in the specified path ## ## `check` is a file that will be generated by the `make` command. @@ -451,9 +472,11 @@ proc make*(path, check: string|Regex, flags = "") = ## ## `flags` are any flags that should be passed to the `make` command. ## + ## `regex` can be set to true if `check` is a regular expression. + ## ## If `make.exe` is missing and `mingw32-make.exe` is available, it will ## be copied over to make.exe in the same location. - if findFile(check, path).len != 0: + if findFile(check, path, regex = regex).len != 0: return echo "# Running make " & flags @@ -474,7 +497,7 @@ proc make*(path, check: string|Regex, flags = "") = echo execAction(cmd) - doAssert findFile(check, path).len != 0, "# make failed" + doAssert findFile(check, path, regex = regex).len != 0, "# make failed" proc getGccPaths*(mode = "c"): seq[string] = var @@ -532,7 +555,7 @@ proc getStdPath(header: string): string = proc getStdLibPath(lname: string): string = for lib in getGccLibPaths(): - result = findFile(re(lname), lib, recurse = false, first = true) + result = findFile(lname, lib, recurse = false, first = true, regex = true) if result.len != 0: break @@ -596,7 +619,7 @@ proc buildLibrary(lname, outdir, conFlags, cmakeFlags, makeFlags: string): strin conDepStr = "" cmakeDeps = false cmakeDepStr = "" - lpath = findFile(re(lname), outdir) + lpath = findFile(lname, outdir, regex = true) makeFlagsProc = &"-j {getNumProcs()} {makeFlags}" made = false makePath = outdir @@ -643,7 +666,7 @@ proc buildLibrary(lname, outdir, conFlags, cmakeFlags, makeFlags: string): strin conDepStr &= "bash executable missing" if fileExists(makePath / "Makefile"): - make(makePath, re(lname), makeFlagsProc) + make(makePath, lname, makeFlagsProc, regex = true) made = true var @@ -656,7 +679,7 @@ proc buildLibrary(lname, outdir, conFlags, cmakeFlags, makeFlags: string): strin error = "No build files found in " & outdir doAssert cmakeDeps or conDeps or made, &"\n# Build configuration failed - {error}\n" - result = findFile(re(lname), outdir) + result = findFile(lname, outdir, regex = true) proc getDynlibExt(): string = when defined(windows): diff --git a/nimterop/docs.nim b/nimterop/docs.nim index 0b46967..8fd396b 100644 --- a/nimterop/docs.nim +++ b/nimterop/docs.nim @@ -1,7 +1,7 @@ import macros, strformat when (NimMajor, NimMinor, NimPatch) >= (0, 19, 9): - from os import parentDir + from os import parentDir, getCurrentCompilerExe proc getNimRootDir(): string = #[ hack, but works @@ -11,8 +11,12 @@ when (NimMajor, NimMinor, NimPatch) >= (0, 19, 9): nimRootDir ]# fmt"{currentSourcePath}".parentDir.parentDir.parentDir +else: + proc getCurrentCompilerExe*(): string = + "nim" -proc buildDocs*(files: seq[string], path: string, baseDir = getProjectPath() & "/") = +proc buildDocs*(files: openArray[string], path: string, baseDir = getProjectPath() & "/", + defines: openArray[string] = @[]) = ## Generate docs for all specified nim `files` to the specified `path` ## ## `baseDir` is the project path by default and `files` and `path` are relative @@ -30,16 +34,22 @@ proc buildDocs*(files: seq[string], path: string, baseDir = getProjectPath() & " else: baseDir path = baseDir & path + defStr = block: + var defStr = "" + for def in defines: + defStr &= " -d:" & def + defStr + nim = getCurrentCompilerExe() for file in files: - echo gorge(&"nim doc -o:{path} --project --index:on {baseDir & file}") + echo gorge(&"{nim} doc {defStr} -o:{path} --project --index:on {baseDir & file}") - echo gorge(&"nim buildIndex -o:{path}/theindex.html {path}") + echo gorge(&"{nim} buildIndex -o:{path}/theindex.html {path}") when declared(getNimRootDir): #[ this enables doc search, works at least locally with: cd {path} && python -m SimpleHTTPServer 9009 ]# - echo gorge(&"nim js -o:{path}/dochack.js {getNimRootDir()}/tools/dochack/dochack.nim") + echo gorge(&"{nim} js -o:{path}/dochack.js {getNimRootDir()}/tools/dochack/dochack.nim") for i in 0 .. paramCount(): if paramStr(i) == "--publish": diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 20fd8b3..d08b318 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -380,9 +380,11 @@ proc getPragma*(nimState: NimState, pragmas: varargs[string]): string = if ", cdecl" in result and dy.len != 0: result = result.replace(".}", dy & ".}") -proc getComments*(nimState: NimState): string = +proc getComments*(nimState: NimState, strip = false): string = if not nimState.gState.nocomments and nimState.commentStr.len != 0: result = "\n" & nimState.commentStr + if strip: + result = result.replace("\n ", "\n") nimState.commentStr = "" proc dll*(path: string): string = diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index bfc5def..b14a208 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -212,7 +212,7 @@ proc initGrammar(): Grammar = if ndname.nBl and ndname != nname: if isEnum: if nimState.addNewIdentifer(ndname): - nimState.enumStr &= &"{nimState.getComments()}\ntype {ndname}* = {dptr}{nname}" + nimState.enumStr &= &"{nimState.getComments(true)}\ntype {ndname}* = {dptr}{nname}" else: if nimState.addNewIdentifer(ndname): let @@ -434,7 +434,7 @@ proc initGrammar(): Grammar = nimState.getIdentifier(name, nskType) if nname.nBl and nimState.addNewIdentifer(nname): - nimState.enumStr &= &"{nimState.getComments()}\ndefineEnum({nname})" + nimState.enumStr &= &"{nimState.getComments(true)}\ndefineEnum({nname})" var i = fstart @@ -579,9 +579,9 @@ proc initGrammar(): Grammar = pragma = nimState.getPragma(nimState.getImportC(fname, fnname), "cdecl") if fptr.len != 0 or ftyp != "object": - nimState.procStr &= &"{nimState.getComments()}\nproc {fnname}*({pout}): {getPtrType(fptr&ftyp)}{pragma}" + nimState.procStr &= &"{nimState.getComments(true)}\nproc {fnname}*({pout}): {getPtrType(fptr&ftyp)}{pragma}" else: - nimState.procStr &= &"{nimState.getComments()}\nproc {fnname}*({pout}){pragma}" + nimState.procStr &= &"{nimState.getComments(true)}\nproc {fnname}*({pout}){pragma}" )) # // comment @@ -597,7 +597,7 @@ proc initGrammar(): Grammar = let line = line.multiReplace([("//", ""), ("/*", ""), ("*/", "")]) - nimState.commentStr &= &"\n# {line.strip(leading=false)}" + nimState.commentStr &= &"\n # {line.strip(leading=false)}" )) proc initRegex(ast: ref Ast) =