Add stdin read support to nimscrit #3983 (#10292)

This commit is contained in:
genotrance
2019-01-14 02:26:10 -06:00
committed by Andreas Rumpf
parent 29e0a792ff
commit c707267212
2 changed files with 38 additions and 6 deletions

View File

@@ -42,15 +42,18 @@ proc setupVM*(module: PSym; cache: IdentCache; scriptName: string;
proc (a: VmArgs) =
body
template cbos(name, body) {.dirty.} =
template cbexc(name, exc, body) {.dirty.} =
result.registerCallback "stdlib.system." & astToStr(name),
proc (a: VmArgs) =
errorMsg = ""
try:
body
except OSError:
except exc:
errorMsg = getCurrentExceptionMsg()
template cbos(name, body) {.dirty.} =
cbexc(name, OSError, body)
# Idea: Treat link to file as a file, but ignore link to directory to prevent
# endless recursions out of the box.
cbos listFiles:
@@ -64,7 +67,7 @@ proc setupVM*(module: PSym; cache: IdentCache; scriptName: string;
cbos createDir:
os.createDir getString(a, 0)
result.registerCallback "stdlib.system.getOsError",
result.registerCallback "stdlib.system.getError",
proc (a: VmArgs) = setResult(a, errorMsg)
cbos setCurrentDir:
@@ -157,6 +160,12 @@ proc setupVM*(module: PSym; cache: IdentCache; scriptName: string;
setResult(a, os.getAppFilename())
cbconf cppDefine:
options.cppDefine(conf, a.getString(0))
cbexc stdinReadLine, EOFError:
setResult(a, "")
setResult(a, stdin.readLine())
cbexc stdinReadAll, EOFError:
setResult(a, "")
setResult(a, stdin.readAll())
proc runNimScript*(cache: IdentCache; scriptName: AbsoluteFile;
freshDefines=true; conf: ConfigRef) =

View File

@@ -46,7 +46,7 @@ proc copyDir(src, dest: string) {.
tags: [ReadIOEffect, WriteIOEffect], raises: [OSError].} = builtin
proc createDir(dir: string) {.tags: [WriteIOEffect], raises: [OSError].} =
builtin
proc getOsError: string = builtin
proc getError: string = builtin
proc setCurrentDir(dir: string) = builtin
proc getCurrentDir*(): string =
## Retrieves the current working directory.
@@ -178,9 +178,12 @@ var
mode*: ScriptMode ## Set this to influence how mkDir, rmDir, rmFile etc.
## behave
template checkError(exc: untyped): untyped =
let err = getError()
if err.len > 0: raise newException(exc, err)
template checkOsError =
let err = getOsError()
if err.len > 0: raise newException(OSError, err)
checkError(OSError)
template log(msg: string, body: untyped) =
if mode in {ScriptMode.Verbose, ScriptMode.Whatif}:
@@ -332,6 +335,26 @@ proc cppDefine*(define: string) =
## needs to be mangled.
builtin
proc stdinReadLine(): TaintedString {.
tags: [ReadIOEffect], raises: [IOError].} =
builtin
proc stdinReadAll(): TaintedString {.
tags: [ReadIOEffect], raises: [IOError].} =
builtin
proc readLineFromStdin*(): TaintedString {.raises: [IOError].} =
## Reads a line of data from stdin - blocks until \n or EOF which happens when stdin is closed
log "readLineFromStdin":
result = stdinReadLine()
checkError(EOFError)
proc readAllFromStdin*(): TaintedString {.raises: [IOError].} =
## Reads all data from stdin - blocks until EOF which happens when stdin is closed
log "readAllFromStdin":
result = stdinReadAll()
checkError(EOFError)
when not defined(nimble):
template `==?`(a, b: string): bool = cmpIgnoreStyle(a, b) == 0
template task*(name: untyped; description: string; body: untyped): untyped =