This commit is contained in:
Thomas Pelletier
2017-12-22 12:45:48 +01:00
committed by GitHub
parent 861c4734ac
commit 0131db6d73
4 changed files with 39 additions and 42 deletions
+31 -31
View File
@@ -23,19 +23,19 @@ var escapeSequenceMap = map[rune]rune{
type parseKeyState int type parseKeyState int
const ( const (
BARE parseKeyState = iota bare parseKeyState = iota
BASIC basic
LITERAL literal
ESC esc
UNICODE_4 unicode4
UNICODE_8 unicode8
) )
func parseKey(key string) ([]string, error) { func parseKey(key string) ([]string, error) {
groups := []string{} groups := []string{}
var buffer bytes.Buffer var buffer bytes.Buffer
var hex bytes.Buffer var hex bytes.Buffer
state := BARE state := bare
wasInQuotes := false wasInQuotes := false
ignoreSpace := true ignoreSpace := true
expectDot := false expectDot := false
@@ -48,66 +48,66 @@ func parseKey(key string) ([]string, error) {
ignoreSpace = false ignoreSpace = false
} }
if state == ESC { if state == esc {
if char == 'u' { if char == 'u' {
state = UNICODE_4 state = unicode4
hex.Reset() hex.Reset()
} else if char == 'U' { } else if char == 'U' {
state = UNICODE_8 state = unicode8
hex.Reset() hex.Reset()
} else if newChar, ok := escapeSequenceMap[char]; ok { } else if newChar, ok := escapeSequenceMap[char]; ok {
buffer.WriteRune(newChar) buffer.WriteRune(newChar)
state = BASIC state = basic
} else { } else {
return nil, fmt.Errorf(`invalid escape sequence \%c`, char) return nil, fmt.Errorf(`invalid escape sequence \%c`, char)
} }
continue continue
} }
if state == UNICODE_4 || state == UNICODE_8 { if state == unicode4 || state == unicode8 {
if isHexDigit(char) { if isHexDigit(char) {
hex.WriteRune(char) hex.WriteRune(char)
} }
if (state == UNICODE_4 && hex.Len() == 4) || (state == UNICODE_8 && hex.Len() == 8) { if (state == unicode4 && hex.Len() == 4) || (state == unicode8 && hex.Len() == 8) {
if value, err := strconv.ParseInt(hex.String(), 16, 32); err == nil { if value, err := strconv.ParseInt(hex.String(), 16, 32); err == nil {
buffer.WriteRune(rune(value)) buffer.WriteRune(rune(value))
} else { } else {
return nil, err return nil, err
} }
state = BASIC state = basic
} }
continue continue
} }
switch char { switch char {
case '\\': case '\\':
if state == BASIC { if state == basic {
state = ESC state = esc
} else if state == LITERAL { } else if state == literal {
buffer.WriteRune(char) buffer.WriteRune(char)
} }
case '\'': case '\'':
if state == BARE { if state == bare {
state = LITERAL state = literal
} else if state == LITERAL { } else if state == literal {
groups = append(groups, buffer.String()) groups = append(groups, buffer.String())
buffer.Reset() buffer.Reset()
wasInQuotes = true wasInQuotes = true
state = BARE state = bare
} }
expectDot = false expectDot = false
case '"': case '"':
if state == BARE { if state == bare {
state = BASIC state = basic
} else if state == BASIC { } else if state == basic {
groups = append(groups, buffer.String()) groups = append(groups, buffer.String())
buffer.Reset() buffer.Reset()
state = BARE state = bare
wasInQuotes = true wasInQuotes = true
} }
expectDot = false expectDot = false
case '.': case '.':
if state != BARE { if state != bare {
buffer.WriteRune(char) buffer.WriteRune(char)
} else { } else {
if !wasInQuotes { if !wasInQuotes {
@@ -122,13 +122,13 @@ func parseKey(key string) ([]string, error) {
wasInQuotes = false wasInQuotes = false
} }
case ' ': case ' ':
if state == BASIC { if state == basic {
buffer.WriteRune(char) buffer.WriteRune(char)
} else { } else {
expectDot = true expectDot = true
} }
default: default:
if state == BARE { if state == bare {
if !isValidBareChar(char) { if !isValidBareChar(char) {
return nil, fmt.Errorf("invalid bare character: %c", char) return nil, fmt.Errorf("invalid bare character: %c", char)
} else if expectDot { } else if expectDot {
@@ -140,10 +140,10 @@ func parseKey(key string) ([]string, error) {
} }
} }
// state must be BARE at the end // state must be bare at the end
if state == ESC { if state == esc {
return nil, errors.New("unfinished escape sequence") return nil, errors.New("unfinished escape sequence")
} else if state != BARE { } else if state != bare {
return nil, errors.New("mismatched quotes") return nil, errors.New("mismatched quotes")
} }
+3 -6
View File
@@ -472,21 +472,18 @@ func (d *Decoder) valueFromToml(mtype reflect.Type, tval interface{}) (reflect.V
case *Tree: case *Tree:
if isTree(mtype) { if isTree(mtype) {
return d.valueFromTree(mtype, tval.(*Tree)) return d.valueFromTree(mtype, tval.(*Tree))
} else {
return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to a tree", tval, tval)
} }
return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to a tree", tval, tval)
case []*Tree: case []*Tree:
if isTreeSlice(mtype) { if isTreeSlice(mtype) {
return d.valueFromTreeSlice(mtype, tval.([]*Tree)) return d.valueFromTreeSlice(mtype, tval.([]*Tree))
} else {
return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to trees", tval, tval)
} }
return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to trees", tval, tval)
case []interface{}: case []interface{}:
if isOtherSlice(mtype) { if isOtherSlice(mtype) {
return d.valueFromOtherSlice(mtype, tval.([]interface{})) return d.valueFromOtherSlice(mtype, tval.([]interface{}))
} else {
return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to a slice", tval, tval)
} }
return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to a slice", tval, tval)
default: default:
switch mtype.Kind() { switch mtype.Kind() {
case reflect.Bool: case reflect.Bool:
+3 -3
View File
@@ -146,8 +146,8 @@ var docData = testDoc{
Second: &subdoc, Second: &subdoc,
}, },
SubDocList: []testSubDoc{ SubDocList: []testSubDoc{
testSubDoc{"List.First", 0}, {"List.First", 0},
testSubDoc{"List.Second", 0}, {"List.Second", 0},
}, },
SubDocPtrs: []*testSubDoc{&subdoc}, SubDocPtrs: []*testSubDoc{&subdoc},
} }
@@ -530,7 +530,7 @@ var strPtr = []*string{&str1, &str2}
var strPtr2 = []*[]*string{&strPtr} var strPtr2 = []*[]*string{&strPtr}
var nestedTestData = nestedMarshalTestStruct{ var nestedTestData = nestedMarshalTestStruct{
String: [][]string{[]string{"Five", "Six"}, []string{"One", "Two"}}, String: [][]string{{"Five", "Six"}, {"One", "Two"}},
StringPtr: &strPtr2, StringPtr: &strPtr2,
} }
+2 -2
View File
@@ -60,7 +60,7 @@ func TestTreeCreateToTree(t *testing.T) {
}, },
"array": []string{"a", "b", "c"}, "array": []string{"a", "b", "c"},
"array_uint": []uint{uint(1), uint(2)}, "array_uint": []uint{uint(1), uint(2)},
"array_table": []map[string]interface{}{map[string]interface{}{"sub_map": 52}}, "array_table": []map[string]interface{}{{"sub_map": 52}},
"array_times": []time.Time{time.Now(), time.Now()}, "array_times": []time.Time{time.Now(), time.Now()},
"map_times": map[string]time.Time{"now": time.Now()}, "map_times": map[string]time.Time{"now": time.Now()},
"custom_string_map_key": map[customString]interface{}{customString("custom"): "custom"}, "custom_string_map_key": map[customString]interface{}{customString("custom"): "custom"},
@@ -97,7 +97,7 @@ func TestTreeCreateToTreeInvalidArrayMemberType(t *testing.T) {
} }
func TestTreeCreateToTreeInvalidTableGroupType(t *testing.T) { func TestTreeCreateToTreeInvalidTableGroupType(t *testing.T) {
_, err := TreeFromMap(map[string]interface{}{"foo": []map[string]interface{}{map[string]interface{}{"hello": t}}}) _, err := TreeFromMap(map[string]interface{}{"foo": []map[string]interface{}{{"hello": t}}})
expected := "cannot convert type *testing.T to Tree" expected := "cannot convert type *testing.T to Tree"
if err.Error() != expected { if err.Error() != expected {
t.Fatalf("expected error %s, got %s", expected, err.Error()) t.Fatalf("expected error %s, got %s", expected, err.Error())