1 // Parsing keys handling both bare and quoted keys.
13 var escapeSequenceMap = map[rune]rune{
23 type parseKeyState int
26 BARE parseKeyState = iota
34 func parseKey(key string) ([]string, error) {
36 var buffer bytes.Buffer
43 for _, char := range key {
55 } else if char == 'U' {
58 } else if newChar, ok := escapeSequenceMap[char]; ok {
59 buffer.WriteRune(newChar)
62 return nil, fmt.Errorf(`invalid escape sequence \%c`, char)
67 if state == UNICODE_4 || state == UNICODE_8 {
71 if (state == UNICODE_4 && hex.Len() == 4) || (state == UNICODE_8 && hex.Len() == 8) {
72 if value, err := strconv.ParseInt(hex.String(), 16, 32); err == nil {
73 buffer.WriteRune(rune(value))
86 } else if state == LITERAL {
87 buffer.WriteRune(char)
92 } else if state == LITERAL {
93 groups = append(groups, buffer.String())
102 } else if state == BASIC {
103 groups = append(groups, buffer.String())
111 buffer.WriteRune(char)
114 if buffer.Len() == 0 {
115 return nil, errors.New("empty table key")
117 groups = append(groups, buffer.String())
126 buffer.WriteRune(char)
132 if !isValidBareChar(char) {
133 return nil, fmt.Errorf("invalid bare character: %c", char)
134 } else if expectDot {
135 return nil, errors.New("what?")
138 buffer.WriteRune(char)
143 // state must be BARE at the end
145 return nil, errors.New("unfinished escape sequence")
146 } else if state != BARE {
147 return nil, errors.New("mismatched quotes")
150 if buffer.Len() > 0 {
151 groups = append(groups, buffer.String())
153 if len(groups) == 0 {
154 return nil, errors.New("empty key")
159 func isValidBareChar(r rune) bool {
160 return isAlphanumeric(r) || r == '-' || unicode.IsNumber(r)