From 460cf60260a22c99ba5b6fbe6b5eb218ba3f998d Mon Sep 17 00:00:00 2001 From: cyphar Date: Mon, 2 Jun 2014 12:13:34 +1000 Subject: [PATCH 1/2] pkg: mflag: flag: make mflag strip quotes in -flag="var" forms This patch improves the mflag package to ensure that things arguments to mflag such as `-flag="var"` or `-flag='var'` have the quotes stripped from the value (to mirror the getopt functionality for similar flags). Docker-DCO-1.1-Signed-off-by: Aleksa Sarai (github: cyphar) Upstream-commit: 0e9c40eb8243fa437bc6c3e93aaff64a10cb856e Component: engine --- components/engine/pkg/mflag/flag.go | 35 ++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/components/engine/pkg/mflag/flag.go b/components/engine/pkg/mflag/flag.go index ed85a4a4c5..2cfef331f6 100644 --- a/components/engine/pkg/mflag/flag.go +++ b/components/engine/pkg/mflag/flag.go @@ -51,6 +51,8 @@ Command line flag syntax: -flag -flag=x + -flag="x" + -flag='x' -flag x // non-boolean flags only One or two minus signs may be used; they are equivalent. The last form is not permitted for boolean flags because the @@ -775,6 +777,37 @@ func (f *FlagSet) usage() { } } +func trimQuotes(str string) string { + type quote struct { + start, end byte + } + + // All valid quote types. + quotes := []quote{ + // Double quotes + { + start: '"', + end: '"', + }, + + // Single quotes + { + start: '\'', + end: '\'', + }, + } + + for _, quote := range quotes { + // Only strip if outermost match. + if str[0] == quote.start && str[len(str)-1] == quote.end { + str = str[1 : len(str)-1] + break + } + } + + return str +} + // parseOne parses one flag. It reports whether a flag was seen. func (f *FlagSet) parseOne() (bool, string, error) { if len(f.args) == 0 { @@ -799,7 +832,7 @@ func (f *FlagSet) parseOne() (bool, string, error) { value := "" for i := 1; i < len(name); i++ { // equals cannot be first if name[i] == '=' { - value = name[i+1:] + value = trimQuotes(name[i+1:]) has_value = true name = name[0:i] break From af5c1612d8137e3d8a0a36ac813995110afd91b1 Mon Sep 17 00:00:00 2001 From: cyphar Date: Mon, 2 Jun 2014 15:02:16 +1000 Subject: [PATCH 2/2] pkg: mflag: flag: added tests for quote-stripped flags This patch adds some tests to ensure that quoted flags are properly handled by the mflag package. Docker-DCO-1.1-Signed-off-by: Aleksa Sarai (github: cyphar) Upstream-commit: e4497feaba31dd33bad790f77f783afc0c695020 Component: engine --- components/engine/pkg/mflag/flag_test.go | 30 ++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/components/engine/pkg/mflag/flag_test.go b/components/engine/pkg/mflag/flag_test.go index b9e8a0ef3e..4c2222e54b 100644 --- a/components/engine/pkg/mflag/flag_test.go +++ b/components/engine/pkg/mflag/flag_test.go @@ -173,6 +173,12 @@ func testParse(f *FlagSet, t *testing.T) { uintFlag := f.Uint([]string{"uint"}, 0, "uint value") uint64Flag := f.Uint64([]string{"-uint64"}, 0, "uint64 value") stringFlag := f.String([]string{"string"}, "0", "string value") + singleQuoteFlag := f.String([]string{"squote"}, "", "single quoted value") + doubleQuoteFlag := f.String([]string{"dquote"}, "", "double quoted value") + mixedQuoteFlag := f.String([]string{"mquote"}, "", "mixed quoted value") + mixed2QuoteFlag := f.String([]string{"mquote2"}, "", "mixed2 quoted value") + nestedQuoteFlag := f.String([]string{"nquote"}, "", "nested quoted value") + nested2QuoteFlag := f.String([]string{"nquote2"}, "", "nested2 quoted value") float64Flag := f.Float64([]string{"float64"}, 0, "float64 value") durationFlag := f.Duration([]string{"duration"}, 5*time.Second, "time.Duration value") extra := "one-extra-argument" @@ -184,6 +190,12 @@ func testParse(f *FlagSet, t *testing.T) { "-uint", "24", "--uint64", "25", "-string", "hello", + "-squote='single'", + `-dquote="double"`, + `-mquote='mixed"`, + `-mquote2="mixed2'`, + `-nquote="'single nested'"`, + `-nquote2='"double nested"'`, "-float64", "2718e28", "-duration", "2m", extra, @@ -215,6 +227,24 @@ func testParse(f *FlagSet, t *testing.T) { if *stringFlag != "hello" { t.Error("string flag should be `hello`, is ", *stringFlag) } + if *singleQuoteFlag != "single" { + t.Error("single quote string flag should be `single`, is ", *singleQuoteFlag) + } + if *doubleQuoteFlag != "double" { + t.Error("double quote string flag should be `double`, is ", *doubleQuoteFlag) + } + if *mixedQuoteFlag != `'mixed"` { + t.Error("mixed quote string flag should be `'mixed\"`, is ", *mixedQuoteFlag) + } + if *mixed2QuoteFlag != `"mixed2'` { + t.Error("mixed2 quote string flag should be `\"mixed2'`, is ", *mixed2QuoteFlag) + } + if *nestedQuoteFlag != "'single nested'" { + t.Error("nested quote string flag should be `'single nested'`, is ", *nestedQuoteFlag) + } + if *nested2QuoteFlag != `"double nested"` { + t.Error("double quote string flag should be `\"double nested\"`, is ", *nested2QuoteFlag) + } if *float64Flag != 2718e28 { t.Error("float64 flag should be 2718e28, is ", *float64Flag) }