diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2013-12-07 13:59:50 -0800 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2013-12-07 13:59:50 -0800 |
commit | 5cdfa4b1afb37c294fa3ccb06e9ed6d9f0e8830b (patch) | |
tree | 9a9b2b25fb5a4bf1f2c9b72525d9b45f1a94d697 | |
parent | ed760c0397d733f21f6b14783db4743188ec3452 (diff) | |
parent | e7e8c7706240c4bef17533da63df988d228ba127 (diff) | |
download | Nim-5cdfa4b1afb37c294fa3ccb06e9ed6d9f0e8830b.tar.gz |
Merge pull request #702 from zielmicha/master
Make quoteIfContainsWhite quote argument, so it can be safely passed to shell.
-rw-r--r-- | lib/pure/strutils.nim | 51 | ||||
-rw-r--r-- | web/news.txt | 2 |
2 files changed, 45 insertions, 8 deletions
diff --git a/lib/pure/strutils.nim b/lib/pure/strutils.nim index a4aa81578..0299f5cd2 100644 --- a/lib/pure/strutils.nim +++ b/lib/pure/strutils.nim @@ -709,14 +709,6 @@ proc rfind*(s, sub: string, start: int = -1): int {.noSideEffect.} = if result != -1: return return -1 -proc quoteIfContainsWhite*(s: string): string = - ## returns ``'"' & s & '"'`` if `s` contains a space and does not - ## start with a quote, else returns `s` - if find(s, {' ', '\t'}) >= 0 and s[0] != '"': - result = '"' & s & '"' - else: - result = s - proc contains*(s: string, c: char): bool {.noSideEffect.} = ## Same as ``find(s, c) >= 0``. return find(s, c) >= 0 @@ -780,6 +772,49 @@ proc replaceWord*(s, sub: string, by = ""): string {.noSideEffect, # copy the rest: add result, substr(s, i) +proc quoteIfContainsWhite*(s: string): string {.noSideEffect.} = + ## Quote s, so it can be safely passed to shell. + when defined(Windows): + # 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("\"") + + else: + # 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 delete*(s: var string, first, last: int) {.noSideEffect, rtl, extern: "nsuDelete".} = ## Deletes in `s` the characters at position `first` .. `last`. This modifies diff --git a/web/news.txt b/web/news.txt index 1b492fa97..f919089a5 100644 --- a/web/news.txt +++ b/web/news.txt @@ -28,6 +28,8 @@ Changes affecting backwards compatibility require an error code to be passed to them. This error code can be retrieved using the new ``OSLastError`` proc. - ``os.parentDir`` now returns "" if there is no parent dir. +- ``quoteIfContainsWhite`` now escapes argument in such way that it can be safely + passed to shell, instead of just adding double quotes. Compiler Additions |