add quoteShell to osproc.nim
This commit is contained in:
parent
9848f82c03
commit
b8072bd22e
1 changed files with 63 additions and 2 deletions
|
|
@ -41,6 +41,58 @@ type
|
||||||
poStdErrToStdOut, ## merge stdout and stderr to the stdout stream
|
poStdErrToStdOut, ## merge stdout and stderr to the stdout stream
|
||||||
poParentStreams ## use the parent's streams
|
poParentStreams ## use the parent's streams
|
||||||
|
|
||||||
|
proc quoteShellWindows*(s: string): string {.noSideEffect, rtl, extern: "nosp$1".} =
|
||||||
|
## Quote s, so it can be safely passed to Windows API.
|
||||||
|
## Based on Python's subprocess.list2cmdline
|
||||||
|
## See http://msdn.microsoft.com/en-us/library/17w5ykft.aspx
|
||||||
|
let needQuote = {' ', '\t'} in s or s.len == 0
|
||||||
|
|
||||||
|
result = ""
|
||||||
|
var backslashBuff = ""
|
||||||
|
if needQuote:
|
||||||
|
result.add("\"")
|
||||||
|
|
||||||
|
for c in s:
|
||||||
|
if c == '\\':
|
||||||
|
backslashBuff.add(c)
|
||||||
|
elif c == '\"':
|
||||||
|
result.add(backslashBuff)
|
||||||
|
result.add(backslashBuff)
|
||||||
|
backslashBuff.setLen(0)
|
||||||
|
result.add("\\\"")
|
||||||
|
else:
|
||||||
|
if backslashBuff.len != 0:
|
||||||
|
result.add(backslashBuff)
|
||||||
|
backslashBuff.setLen(0)
|
||||||
|
result.add(c)
|
||||||
|
|
||||||
|
if needQuote:
|
||||||
|
result.add("\"")
|
||||||
|
|
||||||
|
proc quoteShellPosix*(s: string): string {.noSideEffect, rtl, extern: "nosp$1".} =
|
||||||
|
## Quote s, so it can be safely passed to POSIX shell.
|
||||||
|
## Based on Python's pipes.quote
|
||||||
|
const safeUnixChars = {'%', '+', '-', '.', '/', '_', ':', '=', '@',
|
||||||
|
'0'..'9', 'A'..'Z', 'a'..'z'}
|
||||||
|
if s.len == 0:
|
||||||
|
return "''"
|
||||||
|
|
||||||
|
let safe = s.allCharsInSet(safeUnixChars)
|
||||||
|
|
||||||
|
if safe:
|
||||||
|
return s
|
||||||
|
else:
|
||||||
|
return "'" & s.replace("'", "'\"'\"'") & "'"
|
||||||
|
|
||||||
|
proc quoteShell*(s: string): string {.noSideEffect, rtl, extern: "nosp$1".} =
|
||||||
|
## Quote s, so it can be safely passed to shell.
|
||||||
|
when defined(Windows):
|
||||||
|
return quoteShellWindows(s)
|
||||||
|
elif defined(posix):
|
||||||
|
return quoteShellPosix(s)
|
||||||
|
else:
|
||||||
|
{.error:"quoteShell is not supported on your system".}
|
||||||
|
|
||||||
proc execProcess*(command: string,
|
proc execProcess*(command: string,
|
||||||
options: set[TProcessOption] = {poStdErrToStdOut,
|
options: set[TProcessOption] = {poStdErrToStdOut,
|
||||||
poUseShell}): TaintedString {.
|
poUseShell}): TaintedString {.
|
||||||
|
|
@ -792,5 +844,14 @@ proc execCmdEx*(command: string, options: set[TProcessOption] = {
|
||||||
close(p)
|
close(p)
|
||||||
|
|
||||||
when isMainModule:
|
when isMainModule:
|
||||||
var x = execProcess("gcc -v")
|
assert quoteShellWindows("aaa") == "aaa"
|
||||||
echo "ECHO ", x
|
assert quoteShellWindows("aaa\"") == "aaa\\\""
|
||||||
|
assert quoteShellWindows("") == "\"\""
|
||||||
|
|
||||||
|
assert quoteShellPosix("aaa") == "aaa"
|
||||||
|
assert quoteShellPosix("aaa a") == "'aaa a'"
|
||||||
|
assert quoteShellPosix("") == "''"
|
||||||
|
assert quoteShellPosix("a'a") == "'a'\"'\"'a'"
|
||||||
|
|
||||||
|
when defined(posix):
|
||||||
|
assert quoteShell("") == "''"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue