parent
14468e2336
commit
f6a8cba7b5
2 changed files with 68 additions and 65 deletions
|
|
@ -558,3 +558,68 @@ proc expandTilde*(path: string): string {.
|
||||||
result = getHomeDir() / path.substr(2)
|
result = getHomeDir() / path.substr(2)
|
||||||
else:
|
else:
|
||||||
result = path
|
result = path
|
||||||
|
|
||||||
|
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".}
|
||||||
|
|
||||||
|
when isMainModule:
|
||||||
|
assert quoteShellWindows("aaa") == "aaa"
|
||||||
|
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("") == "''"
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,9 @@ include "system/inclrtl"
|
||||||
import
|
import
|
||||||
strutils, os, strtabs, streams, cpuinfo
|
strutils, os, strtabs, streams, cpuinfo
|
||||||
|
|
||||||
|
from ospaths import quoteShell, quoteShellWindows, quoteShellPosix
|
||||||
|
export quoteShell, quoteShellWindows, quoteShellPosix
|
||||||
|
|
||||||
when defined(windows):
|
when defined(windows):
|
||||||
import winlean
|
import winlean
|
||||||
else:
|
else:
|
||||||
|
|
@ -60,58 +63,6 @@ type
|
||||||
const poUseShell* {.deprecated.} = poUsePath
|
const poUseShell* {.deprecated.} = poUsePath
|
||||||
## Deprecated alias for poUsePath.
|
## Deprecated alias for poUsePath.
|
||||||
|
|
||||||
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,
|
||||||
args: openArray[string] = [],
|
args: openArray[string] = [],
|
||||||
env: StringTableRef = nil,
|
env: StringTableRef = nil,
|
||||||
|
|
@ -1291,16 +1242,3 @@ proc execCmdEx*(command: string, options: set[ProcessOption] = {
|
||||||
result[1] = peekExitCode(p)
|
result[1] = peekExitCode(p)
|
||||||
if result[1] != -1: break
|
if result[1] != -1: break
|
||||||
close(p)
|
close(p)
|
||||||
|
|
||||||
when isMainModule:
|
|
||||||
assert quoteShellWindows("aaa") == "aaa"
|
|
||||||
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