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)
|
||||
else:
|
||||
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
|
||||
strutils, os, strtabs, streams, cpuinfo
|
||||
|
||||
from ospaths import quoteShell, quoteShellWindows, quoteShellPosix
|
||||
export quoteShell, quoteShellWindows, quoteShellPosix
|
||||
|
||||
when defined(windows):
|
||||
import winlean
|
||||
else:
|
||||
|
|
@ -60,58 +63,6 @@ type
|
|||
const poUseShell* {.deprecated.} = 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,
|
||||
args: openArray[string] = [],
|
||||
env: StringTableRef = nil,
|
||||
|
|
@ -1291,16 +1242,3 @@ proc execCmdEx*(command: string, options: set[ProcessOption] = {
|
|||
result[1] = peekExitCode(p)
|
||||
if result[1] != -1: break
|
||||
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