From 68e7691275a0db712404d2f8f1fb1a29ab61d295 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Sun, 30 Jun 2019 13:48:13 +0200 Subject: [PATCH] Add quoteWord proc --- confutils.nim | 2 +- confutils/shell_completion.nim | 24 +++++++++++++++++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/confutils.nim b/confutils.nim index 4c6d1f5..dfaa848 100644 --- a/confutils.nim +++ b/confutils.nim @@ -441,7 +441,7 @@ proc load*(Configuration: type, for opt in matchingOptions: # The trailing '=' means the switch accepts an argument - let trailing = if opt.typename != "bool": '=' else: ' ' + let trailing = if opt.typename != "bool": "=" else: "" if longForm in filterKind: stdout.writeLine("--", opt.name, trailing) diff --git a/confutils/shell_completion.nim b/confutils/shell_completion.nim index b048cdd..1365e7a 100644 --- a/confutils/shell_completion.nim +++ b/confutils/shell_completion.nim @@ -13,6 +13,7 @@ type const WORDBREAKS = "\"'@><=;|&(:" + SAFE_CHARS = {'a'..'z', 'A'..'Z', '0'..'9', '@', '%', '+', '=', ':', ',', '.', '/', '-'} proc open(l: var ShellLexer, input: Stream, wordBreakChars: string = WORDBREAKS, preserveTrailingWs = true) = lexbase.open(l, input) @@ -139,6 +140,20 @@ proc splitCompletionLine*(): seq[string] = break result.add(token.get()) +proc quoteWord*(word: string): string = + if len(word) == 0: + return "''" + + if allCharsInSet(word, SAFE_CHARS): + return word + + result.add('\'') + for ch in word: + if ch == '\'': result.add('\\') + result.add(ch) + + result.add('\'') + # Test data lifted from python's shlex unit-tests const data = """ foo bar|foo|bar| @@ -224,4 +239,11 @@ when isMainModule: if got != expected: echo "got ", got echo "expected ", expected - assert(false) + doAssert(false) + + doAssert(quoteWord("") == "''") + doAssert(quoteWord("\\\"") == "'\\\"'") + doAssert(quoteWord("foobar") == "foobar") + doAssert(quoteWord("foo$bar") == "'foo$bar'") + doAssert(quoteWord("foo bar") == "'foo bar'") + doAssert(quoteWord("foo'bar") == "'foo\\'bar'")