vendor/github.com/pelletier/go-toml/keysparsing.go
author Mikael Berthe <mikael@lilotux.net>
Sun, 11 Jul 2021 10:35:56 +0200
changeset 256 6d9efbef00a9
parent 251 1c52a0eeb952
permissions -rw-r--r--
Update dependencies
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
242
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     1
// Parsing keys handling both bare and quoted keys.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     2
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     3
package toml
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     4
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     5
import (
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     6
	"errors"
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     7
	"fmt"
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     8
)
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     9
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    10
// Convert the bare key group string to an array.
251
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    11
// The input supports double quotation and single quotation,
242
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    12
// but escape sequences are not supported. Lexers must unescape them beforehand.
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    13
func parseKey(key string) ([]string, error) {
251
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    14
	runes := []rune(key)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    15
	var groups []string
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    16
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    17
	if len(key) == 0 {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    18
		return nil, errors.New("empty key")
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    19
	}
242
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    20
251
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    21
	idx := 0
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    22
	for idx < len(runes) {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    23
		for ; idx < len(runes) && isSpace(runes[idx]); idx++ {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    24
			// skip leading whitespace
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    25
		}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    26
		if idx >= len(runes) {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    27
			break
242
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    28
		}
251
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    29
		r := runes[idx]
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    30
		if isValidBareChar(r) {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    31
			// parse bare key
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    32
			startIdx := idx
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    33
			endIdx := -1
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    34
			idx++
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    35
			for idx < len(runes) {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    36
				r = runes[idx]
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    37
				if isValidBareChar(r) {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    38
					idx++
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    39
				} else if r == '.' {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    40
					endIdx = idx
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    41
					break
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    42
				} else if isSpace(r) {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    43
					endIdx = idx
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    44
					for ; idx < len(runes) && isSpace(runes[idx]); idx++ {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    45
						// skip trailing whitespace
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    46
					}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    47
					if idx < len(runes) && runes[idx] != '.' {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    48
						return nil, fmt.Errorf("invalid key character after whitespace: %c", runes[idx])
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    49
					}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    50
					break
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    51
				} else {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    52
					return nil, fmt.Errorf("invalid bare key character: %c", r)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    53
				}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    54
			}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    55
			if endIdx == -1 {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    56
				endIdx = idx
242
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    57
			}
251
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    58
			groups = append(groups, string(runes[startIdx:endIdx]))
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    59
		} else if r == '\'' {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    60
			// parse single quoted key
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    61
			idx++
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    62
			startIdx := idx
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    63
			for {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    64
				if idx >= len(runes) {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    65
					return nil, fmt.Errorf("unclosed single-quoted key")
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    66
				}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    67
				r = runes[idx]
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    68
				if r == '\'' {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    69
					groups = append(groups, string(runes[startIdx:idx]))
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    70
					idx++
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    71
					break
242
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    72
				}
251
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    73
				idx++
242
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    74
			}
251
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    75
		} else if r == '"' {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    76
			// parse double quoted key
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    77
			idx++
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    78
			startIdx := idx
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    79
			for {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    80
				if idx >= len(runes) {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    81
					return nil, fmt.Errorf("unclosed double-quoted key")
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    82
				}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    83
				r = runes[idx]
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    84
				if r == '"' {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    85
					groups = append(groups, string(runes[startIdx:idx]))
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    86
					idx++
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    87
					break
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    88
				}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    89
				idx++
242
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    90
			}
251
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    91
		} else if r == '.' {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    92
			idx++
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    93
			if idx >= len(runes) {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    94
				return nil, fmt.Errorf("unexpected end of key")
242
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    95
			}
251
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    96
			r = runes[idx]
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    97
			if !isValidBareChar(r) && r != '\'' && r != '"' && r != ' ' {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    98
				return nil, fmt.Errorf("expecting key part after dot")
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
    99
			}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
   100
		} else {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
   101
			return nil, fmt.Errorf("invalid key character: %c", r)
242
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   102
		}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   103
	}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   104
	if len(groups) == 0 {
251
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 242
diff changeset
   105
		return nil, fmt.Errorf("empty key")
242
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   106
	}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   107
	return groups, nil
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   108
}
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   109
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   110
func isValidBareChar(r rune) bool {
256
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents: 251
diff changeset
   111
	return isAlphanumeric(r) || r == '-' || isDigit(r)
242
2a9ec03fe5a1 Use vendoring for backward compatibility
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   112
}