key: escape delimiters in string slice values (#116)

* Escape delimiters in string slice values

Fixes #32

* [enh] add test
This commit is contained in:
Adam Tauber
2017-10-14 17:03:21 -04:00
committed by 无闻
parent dd08f93220
commit 696b7e6429
4 changed files with 63 additions and 8 deletions
+16
View File
@@ -87,6 +87,14 @@ key = "value"
key2 = "value2" ; This is a comment for key2
key3 = "one", "two", "three"
[string escapes]
key1 = value1, value2, value3
key2 = value1\, value2
key3 = val\ue1, value2
key4 = value1\\, value\\\\2
key5 = value1\,, value2
key6 = aaa bbb\ and\ space ccc
[advance]
value with quotes = "some value"
value quote2 again = 'some value'
@@ -408,6 +416,14 @@ Good man.
key2 = value2
key3 = "one", "two", "three"
[string escapes]
key1 = value1, value2, value3
key2 = value1\, value2
key3 = val\ue1, value2
key4 = value1\\, value\\\\2
key5 = value1\,, value2
key6 = aaa bbb\ and\ space ccc
[advance]
value with quotes = some value
value quote2 again = some value
+33 -4
View File
@@ -15,6 +15,7 @@
package ini
import (
"bytes"
"errors"
"fmt"
"strconv"
@@ -444,11 +445,39 @@ func (k *Key) Strings(delim string) []string {
return []string{}
}
vals := strings.Split(str, delim)
for i := range vals {
// vals[i] = k.transformValue(strings.TrimSpace(vals[i]))
vals[i] = strings.TrimSpace(vals[i])
runes := []rune(str)
vals := make([]string, 0)
idx := 0
var buf bytes.Buffer
escape := false
for {
if escape {
escape = false
if runes[idx] != '\\' && !strings.HasPrefix(string(runes[idx:]), delim) {
buf.WriteRune('\\')
}
buf.WriteRune(runes[idx])
} else {
if runes[idx] == '\\' {
escape = true
} else if strings.HasPrefix(string(runes[idx:]), delim) {
idx += len(delim) - 1
vals = append(vals, strings.TrimSpace(buf.String()))
buf.Reset()
} else {
buf.WriteRune(runes[idx])
}
}
idx += 1
if idx == len(runes) {
break
}
}
if buf.Len() > 0 {
vals = append(vals, strings.TrimSpace(buf.String()))
}
return vals
}
+11 -1
View File
@@ -73,7 +73,7 @@ func Test_Key(t *testing.T) {
Convey("Get sections", func() {
sections := cfg.Sections()
for i, name := range []string{DEFAULT_SECTION, "author", "package", "package.sub", "features", "types", "array", "note", "comments", "advance"} {
for i, name := range []string{DEFAULT_SECTION, "author", "package", "package.sub", "features", "types", "array", "note", "comments", "string escapes", "advance"} {
So(sections[i].Name(), ShouldEqual, name)
}
})
@@ -243,6 +243,16 @@ func Test_Key(t *testing.T) {
timesEqual(vals6, t, t, t)
})
Convey("Test string slice escapes", func() {
sec := cfg.Section("string escapes")
So(sec.Key("key1").Strings(","), ShouldResemble, []string{"value1", "value2", "value3"})
So(sec.Key("key2").Strings(","), ShouldResemble, []string{"value1, value2"})
So(sec.Key("key3").Strings(","), ShouldResemble, []string{`val\ue1`, "value2"})
So(sec.Key("key4").Strings(","), ShouldResemble, []string{`value1\`, `value\\2`})
So(sec.Key("key5").Strings(",,"), ShouldResemble, []string{"value1,, value2"})
So(sec.Key("key6").Strings(" "), ShouldResemble, []string{"aaa", "bbb and space", "ccc"})
})
Convey("Get valid values into slice", func() {
sec := cfg.Section("array")
vals1 := sec.Key("FLOAT64S").ValidFloat64s(",")
+1 -1
View File
@@ -28,7 +28,7 @@ func Test_Section(t *testing.T) {
So(cfg, ShouldNotBeNil)
Convey("Get section strings", func() {
So(strings.Join(cfg.SectionStrings(), ","), ShouldEqual, "DEFAULT,author,package,package.sub,features,types,array,note,comments,advance")
So(strings.Join(cfg.SectionStrings(), ","), ShouldEqual, "DEFAULT,author,package,package.sub,features,types,array,note,comments,string escapes,advance")
})
Convey("Delete a section", func() {