diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/ci_testresults.nim | 24 | ||||
-rw-r--r-- | tools/dochack/dochack.nim | 45 | ||||
-rw-r--r-- | tools/dochack/karax.nim | 344 | ||||
-rw-r--r-- | tools/finish.nim | 25 | ||||
-rw-r--r-- | tools/kochdocs.nim | 39 | ||||
-rw-r--r-- | tools/nim-gdb.py | 25 | ||||
-rw-r--r-- | tools/nimgrep.nim | 4 | ||||
-rw-r--r-- | tools/vccexe/vccenv.nim | 6 | ||||
-rw-r--r-- | tools/vccexe/vccexe.nim | 25 | ||||
-rw-r--r-- | tools/vccexe/vcvarsall.nim | 6 |
10 files changed, 150 insertions, 393 deletions
diff --git a/tools/ci_testresults.nim b/tools/ci_testresults.nim new file mode 100644 index 000000000..3201606d7 --- /dev/null +++ b/tools/ci_testresults.nim @@ -0,0 +1,24 @@ +## Print summary of failed tests for CI + +import os, json, sets, strformat + +const skip = toSet(["reDisabled", "reIgnored", "reSuccess", "reJoined"]) + +when isMainModule: + for fn in walkFiles("testresults/*.json"): + let entries = fn.readFile().parseJson() + for j in entries: + let res = j["result"].getStr() + if skip.contains(res): + continue + echo fmt """ +Category: {j["category"].getStr()} +Name: {j["name"].getStr()} +Action: {j["action"].getStr()} +Result: {res} +-------- Expected ------- +{j["expected"].getStr()} +--------- Given -------- +{j["given"].getStr()} +------------------------- +""" diff --git a/tools/dochack/dochack.nim b/tools/dochack/dochack.nim index 61c61225d..2f8465a63 100644 --- a/tools/dochack/dochack.nim +++ b/tools/dochack/dochack.nim @@ -1,6 +1,38 @@ -import karax +import dom import fuzzysearch +proc textContent(e: Element): cstring {. + importcpp: "#.textContent", nodecl.} + +proc textContent(e: Node): cstring {. + importcpp: "#.textContent", nodecl.} + +proc tree(tag: string; kids: varargs[Element]): Element = + result = document.createElement tag + for k in kids: + result.appendChild k + +proc add(parent, kid: Element) = + if parent.nodeName == cstring"TR" and ( + kid.nodeName == cstring"TD" or kid.nodeName == cstring"TH"): + let k = document.createElement("TD") + appendChild(k, kid) + appendChild(parent, k) + else: + appendChild(parent, kid) + +proc setClass(e: Element; value: string) = + e.setAttribute("class", value) +proc text(s: string): Element = cast[Element](document.createTextNode(s)) +proc text(s: cstring): Element = cast[Element](document.createTextNode(s)) + +proc getElementById(id: cstring): Element {.importc: "document.getElementById", nodecl.} + +proc replaceById(id: cstring; newTree: Node) = + let x = getElementById(id) + x.parentNode.replaceChild(newTree, x) + newTree.id = id + proc findNodeWith(x: Element; tag, content: cstring): Element = if x.nodeName == tag and x.textContent == content: return x @@ -182,7 +214,7 @@ proc buildToc(orig: TocEntry; types, procs: seq[Element]): TocEntry = t.markElement() for p in procs: if not isMarked(p): - let xx = karax.getElementsByClass(p.parent, cstring"attachedType") + let xx = getElementsByClass(p.parent, cstring"attachedType") if xx.len == 1 and xx[0].textContent == t.textContent: #kout(cstring"found ", p.nodeName) let q = tree("A", text(p.title)) @@ -230,7 +262,7 @@ proc groupBy*(value: cstring) {.exportc.} = togglevis(getElementById"toc-list") var - db: seq[Element] + db: seq[Node] contents: seq[cstring] template normalize(x: cstring): cstring = x.toLower.replace("_", "") @@ -258,7 +290,7 @@ proc dosearch(value: cstring): Element = let ul = tree("UL") result = tree("DIV") result.setClass"search_results" - var matches: seq[(Element, int)] = @[] + var matches: seq[(Node, int)] = @[] for i in 0..<db.len: let c = contents[i] if c == cstring"Examples" or c == cstring"PEG construction": @@ -270,11 +302,10 @@ proc dosearch(value: cstring): Element = if matched: matches.add((db[i], score)) - matches.sort do (a, b: auto) -> int: - b[1] - a[1] + matches.sort(proc(a, b: auto): int = b[1] - a[1]) for i in 0 ..< min(matches.len, 19): matches[i][0].innerHTML = matches[i][0].getAttribute("data-doc-search-tag") - ul.add(tree("LI", matches[i][0])) + ul.add(tree("LI", cast[Element](matches[i][0]))) if ul.len == 0: result.add tree("B", text"no search results") else: diff --git a/tools/dochack/karax.nim b/tools/dochack/karax.nim deleted file mode 100644 index 020fd37d1..000000000 --- a/tools/dochack/karax.nim +++ /dev/null @@ -1,344 +0,0 @@ -# Simple lib to write JS UIs - -import dom - -export dom.Element, dom.Event, dom.cloneNode, dom - -proc kout*[T](x: T) {.importc: "console.log", varargs.} - ## the preferred way of debugging karax applications. - -proc id*(e: Node): cstring {.importcpp: "#.id", nodecl.} -proc `id=`*(e: Node; x: cstring) {.importcpp: "#.id = #", nodecl.} -proc className*(e: Node): cstring {.importcpp: "#.className", nodecl.} -proc `className=`*(e: Node; v: cstring) {.importcpp: "#.className = #", nodecl.} - -proc value*(e: Element): cstring {.importcpp: "#.value", nodecl.} -proc `value=`*(e: Element; v: cstring) {.importcpp: "#.value = #", nodecl.} - -proc getElementsByClass*(e: Element; name: cstring): seq[Element] {.importcpp: "#.getElementsByClassName(#)", nodecl.} - -proc toLower*(x: cstring): cstring {. - importcpp: "#.toLowerCase()", nodecl.} -proc replace*(x: cstring; search, by: cstring): cstring {. - importcpp: "#.replace(#, #)", nodecl.} - -type - EventHandler* = proc(ev: Event) - EventHandlerId* = proc(ev: Event; id: int) - - Timeout* = ref object - -var document* {.importc.}: Document - -var - dorender: proc (): Element {.closure.} - drawTimeout: Timeout - currentTree: Element - -proc setRenderer*(renderer: proc (): Element) = - dorender = renderer - -proc setTimeout*(action: proc(); ms: int): Timeout {.importc, nodecl.} -proc clearTimeout*(t: Timeout) {.importc, nodecl.} -proc targetElem*(e: Event): Element = cast[Element](e.target) - -proc getElementById*(id: cstring): Element {.importc: "document.getElementById", nodecl.} - -proc getElementsByClassName*(cls: cstring): seq[Element] {.importc: - "document.getElementsByClassName", nodecl.} - -proc textContent*(e: Element): cstring {. - importcpp: "#.textContent", nodecl.} - -proc replaceById*(id: cstring; newTree: Node) = - let x = getElementById(id) - x.parentNode.replaceChild(newTree, x) - newTree.id = id - -proc equals(a, b: Node): bool = - if a.nodeType != b.nodeType: return false - if a.id != b.id: return false - if a.nodeName != b.nodeName: return false - if a.nodeType == TextNode: - if a.data != b.data: return false - elif a.childNodes.len != b.childNodes.len: - return false - if a.className != b.className: - # style differences are updated in place and we pretend - # it's still the same node - a.className = b.className - #return false - return true - -proc diffTree(parent, a, b: Node) = - if equals(a, b): - if a.nodeType != TextNode: - # we need to do this correctly in the presence of asyncronous - # DOM updates: - var i = 0 - while i < a.childNodes.len and a.childNodes.len == b.childNodes.len: - diffTree(a, a.childNodes[i], b.childNodes[i]) - inc i - elif parent == nil: - replaceById("ROOT", b) - else: - parent.replaceChild(b, a) - -proc dodraw() = - let newtree = dorender() - newtree.id = "ROOT" - if currentTree == nil: - currentTree = newtree - replaceById("ROOT", currentTree) - else: - diffTree(nil, currentTree, newtree) - -proc redraw*() = - # we buffer redraw requests: - if drawTimeout != nil: - clearTimeout(drawTimeout) - drawTimeout = setTimeout(dodraw, 30) - -proc tree*(tag: string; kids: varargs[Element]): Element = - result = document.createElement tag - for k in kids: - result.appendChild k - -proc tree*(tag: string; attrs: openarray[(string, string)]; - kids: varargs[Element]): Element = - result = tree(tag, kids) - for a in attrs: result.setAttribute(a[0], a[1]) - -proc text*(s: string): Element = cast[Element](document.createTextNode(s)) -proc text*(s: cstring): Element = cast[Element](document.createTextNode(s)) -proc add*(parent, kid: Element) = - if parent.nodeName == cstring"TR" and ( - kid.nodeName == cstring"TD" or kid.nodeName == cstring"TH"): - let k = document.createElement("TD") - appendChild(k, kid) - appendChild(parent, k) - else: - appendChild(parent, kid) - -proc len*(x: Element): int {.importcpp: "#.childNodes.length".} -proc `[]`*(x: Element; idx: int): Element {.importcpp: "#.childNodes[#]".} - -proc isInt*(s: cstring): bool {.asmNoStackFrame.} = - asm """ - return s.match(/^[0-9]+$/); - """ - -var - linkCounter: int - -proc link*(id: int): Element = - result = document.createElement("a") - result.setAttribute("href", "#") - inc linkCounter - result.setAttribute("id", $linkCounter & ":" & $id) - -proc link*(action: EventHandler): Element = - result = document.createElement("a") - result.setAttribute("href", "#") - addEventListener(result, "click", action) - -proc parseInt*(s: cstring): int {.importc, nodecl.} -proc parseFloat*(s: cstring): float {.importc, nodecl.} -proc split*(s, sep: cstring): seq[cstring] {.importcpp, nodecl.} - -proc startsWith*(a, b: cstring): bool {.importcpp: "startsWith", nodecl.} -proc contains*(a, b: cstring): bool {.importcpp: "(#.indexOf(#)>=0)", nodecl.} -proc substr*(s: cstring; start: int): cstring {.importcpp: "substr", nodecl.} -proc substr*(s: cstring; start, length: int): cstring {.importcpp: "substr", nodecl.} - -#proc len*(s: cstring): int {.importcpp: "#.length", nodecl.} -proc `&`*(a, b: cstring): cstring {.importcpp: "(# + #)", nodecl.} -proc toCstr*(s: int): cstring {.importcpp: "((#)+'')", nodecl.} - -proc suffix*(s, prefix: cstring): cstring = - if s.startsWith(prefix): - result = s.substr(prefix.len) - else: - kout(cstring"bug! " & s & cstring" does not start with " & prefix) - -proc valueAsInt*(e: Element): int = parseInt(e.value) -proc suffixAsInt*(s, prefix: cstring): int = parseInt(suffix(s, prefix)) - -proc scrollTop*(e: Element): int {.importcpp: "#.scrollTop", nodecl.} -proc offsetHeight*(e: Element): int {.importcpp: "#.offsetHeight", nodecl.} -proc offsetTop*(e: Element): int {.importcpp: "#.offsetTop", nodecl.} - -template onImpl(s) {.dirty} = - proc wrapper(ev: Event) = - action(ev) - redraw() - addEventListener(e, s, wrapper) - -proc setOnclick*(e: Element; action: proc(ev: Event)) = - onImpl "click" - -proc setOnclick*(e: Element; action: proc(ev: Event; id: int)) = - proc wrapper(ev: Event) = - let id = ev.target.id - let a = id.split(":") - if a.len == 2: - action(ev, parseInt(a[1])) - redraw() - else: - kout(cstring("cannot deal with id "), id) - addEventListener(e, "click", wrapper) - -proc setOnfocuslost*(e: Element; action: EventHandler) = - onImpl "blur" - -proc setOnchanged*(e: Element; action: EventHandler) = - onImpl "change" - -proc setOnscroll*(e: Element; action: EventHandler) = - onImpl "scroll" - -proc select*(choices: openarray[string]): Element = - result = document.createElement("select") - var i = 0 - for c in choices: - result.add tree("option", [("value", $i)], text(c)) - inc i - -proc select*(choices: openarray[(int, string)]): Element = - result = document.createElement("select") - for c in choices: - result.add tree("option", [("value", $c[0])], text(c[1])) - -var radioCounter: int - -proc radio*(choices: openarray[(int, string)]): Element = - result = document.createElement("fieldset") - var i = 0 - inc radioCounter - for c in choices: - let id = "radio_" & c[1] & $i - var kid = tree("input", [("type", "radio"), - ("id", id), ("name", "radio" & $radioCounter), - ("value", $c[0])]) - if i == 0: - kid.setAttribute("checked", "checked") - var lab = tree("label", [("for", id)], text(c[1])) - kid.add lab - result.add kid - inc i - -proc tag*(name: string; id="", class=""): Element = - result = document.createElement(name) - if id.len > 0: - result.setAttribute("id", id) - if class.len > 0: - result.setAttribute("class", class) - -proc tdiv*(id="", class=""): Element = tag("div", id, class) -proc span*(id="", class=""): Element = tag("span", id, class) - -proc th*(s: string): Element = - result = tag("th") - result.add text(s) - -proc td*(s: string): Element = - result = tag("td") - result.add text(s) - -proc td*(s: Element): Element = - result = tag("td") - result.add s - -proc td*(class: string; s: Element): Element = - result = tag("td") - result.add s - result.setAttribute("class", class) - -proc table*(class="", kids: varargs[Element]): Element = - result = tag("table", "", class) - for k in kids: result.add k - -proc tr*(kids: varargs[Element]): Element = - result = tag("tr") - for k in kids: - if k.nodeName == cstring"TD" or k.nodeName == cstring"TH": - result.add k - else: - result.add td(k) - -proc setClass*(e: Element; value: string) = - e.setAttribute("class", value) - -proc setAttr*(e: Element; key, value: cstring) = - e.setAttribute(key, value) - -proc getAttr*(e: Element; key: cstring): cstring {. - importcpp: "#.getAttribute(#)", nodecl.} - -proc realtimeInput*(id, val: string; changed: proc(value: cstring)): Element = - let oldElem = getElementById(id) - #if oldElem != nil: return oldElem - let newVal = if oldElem.isNil: val else: $oldElem.value - var timer: Timeout - proc wrapper() = - changed(getElementById(id).value) - redraw() - proc onkeyup(ev: Event) = - if timer != nil: clearTimeout(timer) - timer = setTimeout(wrapper, 400) - result = tree("input", [("type", "text"), - ("value", newVal), - ("id", id)]) - result.addEventListener("keyup", onkeyup) - -proc ajax(meth, url: cstring; headers: openarray[(string, string)]; - data: cstring; - cont: proc (httpStatus: int; response: cstring)) = - proc setRequestHeader(a, b: cstring) {.importc: "ajax.setRequestHeader".} - {.emit: """ - var ajax = new XMLHttpRequest(); - ajax.open(`meth`,`url`,true);""".} - for a, b in items(headers): - setRequestHeader(a, b) - {.emit: """ - ajax.onreadystatechange = function(){ - if(this.readyState == 4){ - if(this.status == 200){ - `cont`(this.status, this.responseText); - } else { - `cont`(this.status, this.statusText); - } - } - } - ajax.send(`data`); - """.} - -proc ajaxPut*(url: string; headers: openarray[(string, string)]; - data: cstring; - cont: proc (httpStatus: int, response: cstring)) = - ajax("PUT", url, headers, data, cont) - -proc ajaxGet*(url: string; headers: openarray[(string, string)]; - cont: proc (httpStatus: int, response: cstring)) = - ajax("GET", url, headers, nil, cont) - -{.push stackTrace:off.} - -proc setupErrorHandler*(useAlert=false) = - ## Installs an error handler that transforms native JS unhandled - ## exceptions into Nim based stack traces. If `useAlert` is false, - ## the error message it put into the console, otherwise `alert` - ## is called. - proc stackTraceAsCstring(): cstring = cstring(getStackTrace()) - {.emit: """ - window.onerror = function(msg, url, line, col, error) { - var x = "Error: " + msg + "\n" + `stackTraceAsCstring`() - if (`useAlert`) - alert(x); - else - console.log(x); - var suppressErrorAlert = true; - return suppressErrorAlert; - };""".} - -{.pop.} diff --git a/tools/finish.nim b/tools/finish.nim index 4f2c72595..815b99a12 100644 --- a/tools/finish.nim +++ b/tools/finish.nim @@ -8,6 +8,9 @@ const mingw = "mingw$1-6.3.0.7z" % arch url = r"https://nim-lang.org/download/" & mingw +var + interactive = true + type DownloadResult = enum Failure, @@ -38,19 +41,28 @@ proc downloadMingw(): DownloadResult = if cmd.len > 0: if execShellCmd(cmd) != 0: echo "download failed! ", cmd - openDefaultBrowser(url) - result = Manual + if interactive: + openDefaultBrowser(url) + result = Manual + else: + result = Failure else: if unzip(): result = Success else: - openDefaultBrowser(url) - result = Manual + if interactive: + openDefaultBrowser(url) + result = Manual + else: + result = Failure when defined(windows): import registry proc askBool(m: string): bool = stdout.write m + if not interactive: + stdout.writeLine "y (non-interactive mode)" + return true while true: try: let answer = stdin.readLine().normalize @@ -67,6 +79,9 @@ when defined(windows): proc askNumber(m: string; a, b: int): int = stdout.write m stdout.write " [" & $a & ".." & $b & "] " + if not interactive: + stdout.writeLine $a & " (non-interactive mode)" + return a while true: let answer = stdin.readLine() try: @@ -291,4 +306,6 @@ when isMainModule: when defined(testdownload): discard downloadMingw() else: + if "-y" in commandLineParams(): + interactive = false main() diff --git a/tools/kochdocs.nim b/tools/kochdocs.nim index 658b9ead7..f109cbbab 100644 --- a/tools/kochdocs.nim +++ b/tools/kochdocs.nim @@ -25,7 +25,6 @@ proc findNim*(): string = # assume there is a symlink to the exe or something: return nim - proc exec*(cmd: string, errorcode: int = QuitFailure, additionalPath = "") = let prevPath = getEnv("PATH") if additionalPath.len > 0: @@ -38,6 +37,21 @@ proc exec*(cmd: string, errorcode: int = QuitFailure, additionalPath = "") = if execShellCmd(cmd) != 0: quit("FAILURE", errorcode) putEnv("PATH", prevPath) +template inFold*(desc, body) = + if existsEnv("TRAVIS"): + echo "travis_fold:start:" & desc.replace(" ", "_") + + body + + if existsEnv("TRAVIS"): + echo "travis_fold:end:" & desc.replace(" ", "_") + +proc execFold*(desc, cmd: string, errorcode: int = QuitFailure, additionalPath = "") = + ## Execute shell command. Add log folding on Travis CI. + # https://github.com/travis-ci/travis-ci/issues/2285#issuecomment-42724719 + inFold(desc): + exec(cmd, errorcode, additionalPath) + proc execCleanPath*(cmd: string, additionalPath = ""; errorcode: int = QuitFailure) = # simulate a poor man's virtual environment @@ -56,14 +70,15 @@ proc nimexec*(cmd: string) = exec findNim() & " " & cmd proc nimCompile*(input: string, outputDir = "bin", mode = "c", options = "") = - # TODO: simplify pending https://github.com/nim-lang/Nim/issues/9513 - var cmd = findNim() & " " & mode let output = outputDir / input.splitFile.name.exe - cmd.add " -o:" & output - cmd.add " " & options - cmd.add " " & input + let cmd = findNim() & " " & mode & " -o:" & output & " " & options & " " & input exec cmd +proc nimCompileFold*(desc, input: string, outputDir = "bin", mode = "c", options = "") = + let output = outputDir / input.splitFile.name.exe + let cmd = findNim() & " " & mode & " -o:" & output & " " & options & " " & input + execFold(desc, cmd) + const pdf = """ doc/manual.rst @@ -101,11 +116,13 @@ doc/nep1.rst doc/nims.rst doc/contributing.rst doc/codeowners.rst +doc/packaging.rst doc/manual/var_t_return.rst """.splitWhitespace() doc = """ lib/system.nim +lib/system/io.nim lib/system/nimscript.nim lib/deprecated/pure/ospaths.nim lib/pure/parsejson.nim @@ -126,7 +143,6 @@ lib/js/asyncjs.nim lib/pure/os.nim lib/pure/strutils.nim lib/pure/math.nim -lib/pure/matchers.nim lib/std/editdistance.nim lib/std/wordwrap.nim lib/experimental/diff.nim @@ -161,10 +177,8 @@ lib/impure/db_mysql.nim lib/impure/db_sqlite.nim lib/impure/db_odbc.nim lib/pure/db_common.nim -lib/pure/httpserver.nim lib/pure/httpclient.nim lib/pure/smtp.nim -lib/impure/ssl.nim lib/pure/ropes.nim lib/pure/unidecode/unidecode.nim lib/pure/xmlparser.nim @@ -174,25 +188,20 @@ lib/pure/colors.nim lib/pure/mimetypes.nim lib/pure/json.nim lib/pure/base64.nim -lib/pure/scgi.nim lib/impure/nre.nim lib/impure/nre/private/util.nim -lib/deprecated/pure/sockets.nim -lib/deprecated/pure/asyncio.nim lib/pure/collections/tables.nim lib/pure/collections/sets.nim lib/pure/collections/lists.nim lib/pure/collections/sharedlist.nim lib/pure/collections/sharedtables.nim lib/pure/collections/intsets.nim -lib/pure/collections/queues.nim lib/pure/collections/deques.nim lib/pure/encodings.nim lib/pure/collections/sequtils.nim lib/pure/collections/rtarrays.nim lib/pure/cookies.nim lib/pure/memfiles.nim -lib/pure/subexes.nim lib/pure/collections/critbits.nim lib/core/locks.nim lib/core/rlocks.nim @@ -218,7 +227,6 @@ lib/pure/selectors.nim lib/pure/sugar.nim lib/pure/collections/chains.nim lib/pure/asyncfile.nim -lib/deprecated/pure/ftpclient.nim lib/pure/asyncftpclient.nim lib/pure/lenientops.nim lib/pure/md5.nim @@ -229,6 +237,7 @@ lib/pure/collections/heapqueue.nim lib/pure/fenv.nim lib/std/sha1.nim lib/std/varints.nim +lib/std/time_t.nim lib/impure/rdstdin.nim lib/wrappers/linenoise/linenoise.nim lib/pure/strformat.nim diff --git a/tools/nim-gdb.py b/tools/nim-gdb.py index 1a0d89fcb..2abaf6926 100644 --- a/tools/nim-gdb.py +++ b/tools/nim-gdb.py @@ -1,4 +1,3 @@ - import gdb import re import sys @@ -16,8 +15,6 @@ def printErrorOnce(id, message): errorSet.add(id) gdb.write(message, gdb.STDERR) -nimobjfile = gdb.current_objfile() or gdb.objfiles()[0] -nimobjfile.type_printers = [] ################################################################################ ##### Type pretty printers @@ -121,9 +118,6 @@ class NimTypePrinter: def instantiate(self): return NimTypeRecognizer() - -nimobjfile.type_printers = [NimTypePrinter()] - ################################################################################ ##### GDB Function, equivalent of Nim's $ operator ################################################################################ @@ -528,5 +522,20 @@ def makematcher(klass): printErrorOnce(typeName, "No matcher for type '" + typeName + "': " + str(e) + "\n") return matcher -nimobjfile.pretty_printers = [] -nimobjfile.pretty_printers.extend([makematcher(var) for var in list(vars().values()) if hasattr(var, 'pattern')]) +def register_nim_pretty_printers_for_object(objfile): + nimMainSym = gdb.lookup_global_symbol("NimMain", gdb.SYMBOL_FUNCTIONS_DOMAIN) + if nimMainSym and nimMainSym.symtab.objfile == objfile: + print("set Nim pretty printers for ", objfile.filename) + + objfile.type_printers = [NimTypePrinter()] + objfile.pretty_printers = [makematcher(var) for var in list(globals().values()) if hasattr(var, 'pattern')] + +# Register pretty printers for all objfiles that are already loaded. +for old_objfile in gdb.objfiles(): + register_nim_pretty_printers_for_object(old_objfile) + +# Register an event handler to register nim pretty printers for all future objfiles. +def new_object_handler(event): + register_nim_pretty_printers_for_object(event.new_objfile) + +gdb.events.new_objfile.connect(new_object_handler) diff --git a/tools/nimgrep.nim b/tools/nimgrep.nim index 8c6353e31..0a835b038 100644 --- a/tools/nimgrep.nim +++ b/tools/nimgrep.nim @@ -160,7 +160,7 @@ proc processFile(pattern; filename: string; counter: var int) = var reallyReplace = true while i < buffer.len: let t = findBounds(buffer, pattern, matches, i) - if t.first < 0: break + if t.first < 0 or t.last < t.first: break inc(line, countLines(buffer, i, t.first-1)) var wholeMatch = buffer.substr(t.first, t.last) @@ -336,7 +336,7 @@ else: for f in items(filenames): walker(pegp, f, counter) else: - var reflags = {reStudy, reExtended} + var reflags = {reStudy} if optIgnoreStyle in options: pattern = styleInsensitive(pattern) if optWord in options: diff --git a/tools/vccexe/vccenv.nim b/tools/vccexe/vccenv.nim index 6ddf2e29a..12a6e6b3d 100644 --- a/tools/vccexe/vccenv.nim +++ b/tools/vccexe/vccenv.nim @@ -16,7 +16,7 @@ type vs140 = (140, "VS140COMNTOOLS") ## Visual Studio 2015 const - vcvarsallRelativePath = joinPath("..", "..", "VC", "vcvarsall") ## Relative path from the COMNTOOLS path to the vcvarsall file. + vcvarsallRelativePath = joinPath("..", "..", "VC", "vcvarsall.bat") ## Relative path from the COMNTOOLS path to the vcvarsall file. proc vccEnvVcVarsAllPath*(version: VccEnvVersion = vsUndefined): string = ## Returns the path to the VCC Developer Command Prompt executable for the specified VCC version. @@ -39,9 +39,9 @@ proc vccEnvVcVarsAllPath*(version: VccEnvVersion = vsUndefined): string = for tryVersion in [vs140, vs120, vs110, vs100, vs90]: let tryPath = vccEnvVcVarsAllPath(tryVersion) if tryPath.len > 0: - result = tryPath + return tryPath else: # Specific version requested let key = $version let val = getEnv key if val.len > 0: - result = expandFilename(val & vcvarsallRelativePath) + result = try: expandFilename(joinPath(val, vcvarsallRelativePath)) except OSError: "" diff --git a/tools/vccexe/vccexe.nim b/tools/vccexe/vccexe.nim index f794885f2..28d9e4173 100644 --- a/tools/vccexe/vccexe.nim +++ b/tools/vccexe/vccexe.nim @@ -46,6 +46,8 @@ const sdktypeSepIdx = sdktypePrefix.len sdkversionSepIdx = sdkversionPrefix.len + vcvarsallDefaultPath = "vcvarsall.bat" + helpText = """ +-----------------------------------------------------------------+ | Microsoft C/C++ compiler wrapper for Nim | @@ -158,6 +160,10 @@ when isMainModule: vccversionValue = vccUndefined vcvarsallArg = discoverVccVcVarsAllPath() + if vcvarsallArg == "": + # Assume that default executable is in current directory or in PATH + vcvarsallArg = findExe(vcvarsallDefaultPath) + if printPathArg: var head = $vccversionValue if head.len < 1: @@ -180,9 +186,16 @@ when isMainModule: if not noCommandArg: # Run VCC command with the VCC process environment - let vccProcess = startProcess( - commandArg, - args = clArgs, - options = vccOptions - ) - quit vccProcess.waitForExit() + try: + let vccProcess = startProcess( + commandArg, + args = clArgs, + options = vccOptions + ) + quit vccProcess.waitForExit() + except: + if vcvarsallArg.len != 0: + echo "Hint: using " & vcvarsallArg + else: + echo "Hint: vcvarsall.bat was not found" + raise diff --git a/tools/vccexe/vcvarsall.nim b/tools/vccexe/vcvarsall.nim index defcf687f..81b0fb42b 100644 --- a/tools/vccexe/vcvarsall.nim +++ b/tools/vccexe/vcvarsall.nim @@ -10,7 +10,6 @@ import strtabs, strutils, os, osproc const comSpecEnvKey = "ComSpec" ## Environment Variable that specifies the command-line application path in Windows ## Usually set to cmd.exe - vcvarsallDefaultPath = "vcvarsall.bat" type VccArch* = enum ## The VCC compile target architectures @@ -48,11 +47,10 @@ proc vccVarsAll*(path: string, arch: VccArch = vccarchUnspecified, platform_type ## verbose ## Echo the command-line passed on to the system to load the VCC environment. Defaults to `false`. - var vccvarsallpath = path - # Assume that default executable is in current directory or in PATH if path == "": - vccvarsallpath = vcvarsallDefaultPath + return nil + let vccvarsallpath = path var args: seq[string] = @[] let archStr: string = $arch |