summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/vm.nim5
-rw-r--r--compiler/vmdef.nim1
-rw-r--r--compiler/vmdeps.nim24
-rw-r--r--compiler/vmops.nim6
-rw-r--r--lib/system.nim5
-rw-r--r--tests/vm/tgorge.nim20
-rw-r--r--tests/vm/tgorgeex.bat2
-rw-r--r--tests/vm/tgorgeex.sh3
8 files changed, 46 insertions, 20 deletions
diff --git a/compiler/vm.nim b/compiler/vm.nim
index 1bb440c6c..91fe3d209 100644
--- a/compiler/vm.nim
+++ b/compiler/vm.nim
@@ -879,7 +879,8 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
         # it's a callback:
         c.callbacks[-prc.offset-2].value(
           VmArgs(ra: ra, rb: rb, rc: rc, slots: cast[pointer](regs),
-                 currentException: c.currentExceptionB))
+                 currentException: c.currentExceptionB,
+                 currentLineInfo: c.debug[pc]))
       elif sfImportc in prc.flags:
         if allowFFI notin c.features:
           globalError(c.debug[pc], errGenerated, "VM not allowed to do FFI")
@@ -1246,7 +1247,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
       createStr regs[ra]
       regs[ra].node.strVal = opGorge(regs[rb].node.strVal,
                                      regs[rc].node.strVal, regs[rd].node.strVal,
-                                     c.debug[pc])
+                                     c.debug[pc])[0]
     of opcNError:
       decodeB(rkNode)
       let a = regs[ra].node
diff --git a/compiler/vmdef.nim b/compiler/vmdef.nim
index 7fb35e890..263ec8378 100644
--- a/compiler/vmdef.nim
+++ b/compiler/vmdef.nim
@@ -181,6 +181,7 @@ type
     ra*, rb*, rc*: Natural
     slots*: pointer
     currentException*: PNode
+    currentLineInfo*: TLineInfo
   VmCallback* = proc (args: VmArgs) {.closure.}
 
   PCtx* = ref TCtx
diff --git a/compiler/vmdeps.nim b/compiler/vmdeps.nim
index bda2710dc..ebd2f557f 100644
--- a/compiler/vmdeps.nim
+++ b/compiler/vmdeps.nim
@@ -9,24 +9,24 @@
 
 import ast, types, msgs, os, osproc, streams, options, idents, securehash
 
-proc readOutput(p: Process): string =
-  result = ""
+proc readOutput(p: Process): (string, int) =
+  result[0] = ""
   var output = p.outputStream
   while not output.atEnd:
-    result.add(output.readLine)
-    result.add("\n")
-  if result.len > 0:
-    result.setLen(result.len - "\n".len)
-  discard p.waitForExit
+    result[0].add(output.readLine)
+    result[0].add("\n")
+  if result[0].len > 0:
+    result[0].setLen(result[0].len - "\n".len)
+  result[1] = p.waitForExit
 
-proc opGorge*(cmd, input, cache: string, info: TLineInfo): string =
+proc opGorge*(cmd, input, cache: string, info: TLineInfo): (string, int) =
   let workingDir = parentDir(info.toFullPath)
   if cache.len > 0:# and optForceFullMake notin gGlobalOptions:
     let h = secureHash(cmd & "\t" & input & "\t" & cache)
     let filename = options.toGeneratedFile("gorge_" & $h, "txt")
     var f: File
     if open(f, filename):
-      result = f.readAll
+      result = (f.readAll, 0)
       f.close
       return
     var readSuccessful = false
@@ -38,9 +38,9 @@ proc opGorge*(cmd, input, cache: string, info: TLineInfo): string =
         p.inputStream.close()
       result = p.readOutput
       readSuccessful = true
-      writeFile(filename, result)
+      writeFile(filename, result[0])
     except IOError, OSError:
-      if not readSuccessful: result = ""
+      if not readSuccessful: result = ("", -1)
   else:
     try:
       var p = startProcess(cmd, workingDir,
@@ -50,7 +50,7 @@ proc opGorge*(cmd, input, cache: string, info: TLineInfo): string =
         p.inputStream.close()
       result = p.readOutput
     except IOError, OSError:
-      result = ""
+      result = ("", -1)
 
 proc opSlurp*(file: string, info: TLineInfo, module: PSym): string =
   try:
diff --git a/compiler/vmops.nim b/compiler/vmops.nim
index 1c2725a98..b0911579e 100644
--- a/compiler/vmops.nim
+++ b/compiler/vmops.nim
@@ -59,6 +59,11 @@ proc staticWalkDirImpl(path: string, relative: bool): PNode =
     result.add newTree(nkPar, newIntNode(nkIntLit, k.ord),
                               newStrNode(nkStrLit, f))
 
+proc gorgeExWrapper(a: VmArgs) {.nimcall.} =
+  let (s, e) = opGorge(getString(a, 0), getString(a, 1), getString(a, 2),
+                       a.currentLineInfo)
+  setResult a, newTree(nkPar, newStrNode(nkStrLit, s), newIntNode(nkIntLit, e))
+
 proc registerAdditionalOps*(c: PCtx) =
   wrap1f_math(sqrt)
   wrap1f_math(ln)
@@ -92,3 +97,4 @@ proc registerAdditionalOps*(c: PCtx) =
   systemop getCurrentExceptionMsg
   registerCallback c, "stdlib.*.staticWalkDir", proc (a: VmArgs) {.nimcall.} =
     setResult(a, staticWalkDirImpl(getString(a, 0), getBool(a, 1)))
+  systemop gorgeEx
diff --git a/lib/system.nim b/lib/system.nim
index 309df7f84..83dc20869 100644
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -3368,6 +3368,11 @@ proc staticExec*(command: string, input = "", cache = ""): string {.
   ## .. code-block:: nim
   ##     const stateMachine = staticExec("dfaoptimizer", "input", "0.8.0")
 
+proc gorgeEx*(command: string, input = "", cache = ""): tuple[output: string,
+                                                              exitCode: int] =
+  ## Same as `gorge` but also returns the precious exit code.
+  discard
+
 proc `+=`*[T: SomeOrdinal|uint|uint64](x: var T, y: T) {.
   magic: "Inc", noSideEffect.}
   ## Increments an ordinal
diff --git a/tests/vm/tgorge.nim b/tests/vm/tgorge.nim
index 596f5d667..694754f41 100644
--- a/tests/vm/tgorge.nim
+++ b/tests/vm/tgorge.nim
@@ -3,10 +3,18 @@ import os
 template getScriptDir(): string =
   parentDir(instantiationInfo(-1, true).filename)
 
-const
-  execName = when defined(windows): "tgorge.bat" else: "sh tgorge.sh"
-  relOutput = gorge(execName)
-  absOutput = gorge(getScriptDir() / execName)
+block gorge:
+  const
+    execName = when defined(windows): "tgorge.bat" else: "./tgorge.sh"
+    relOutput = gorge(execName)
+    absOutput = gorge(getScriptDir() / execName)
 
-doAssert relOutput == "gorge test"
-doAssert absOutput == "gorge test"
+  doAssert relOutput == "gorge test"
+  doAssert absOutput == "gorge test"
+
+block gorgeEx:
+  const
+    execName = when defined(windows): "tgorgeex.bat" else: "./tgorgeex.sh"
+    res = gorgeEx(execName)
+  doAssert res.output == "gorgeex test"
+  doAssert res.exitCode == 1
diff --git a/tests/vm/tgorgeex.bat b/tests/vm/tgorgeex.bat
new file mode 100644
index 000000000..57f11fdd1
--- /dev/null
+++ b/tests/vm/tgorgeex.bat
@@ -0,0 +1,2 @@
+@echo gorgeex test
+@exit /b 1
diff --git a/tests/vm/tgorgeex.sh b/tests/vm/tgorgeex.sh
new file mode 100644
index 000000000..36ba0a02f
--- /dev/null
+++ b/tests/vm/tgorgeex.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+echo "gorgeex test"
+exit 1