mirror of
				https://gitea.com/Lydanne/buildx.git
				synced 2025-11-04 01:53:42 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			113 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			113 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
// Parsing keys handling both bare and quoted keys.
 | 
						|
 | 
						|
package toml
 | 
						|
 | 
						|
import (
 | 
						|
	"errors"
 | 
						|
	"fmt"
 | 
						|
)
 | 
						|
 | 
						|
// Convert the bare key group string to an array.
 | 
						|
// The input supports double quotation and single quotation,
 | 
						|
// but escape sequences are not supported. Lexers must unescape them beforehand.
 | 
						|
func parseKey(key string) ([]string, error) {
 | 
						|
	runes := []rune(key)
 | 
						|
	var groups []string
 | 
						|
 | 
						|
	if len(key) == 0 {
 | 
						|
		return nil, errors.New("empty key")
 | 
						|
	}
 | 
						|
 | 
						|
	idx := 0
 | 
						|
	for idx < len(runes) {
 | 
						|
		for ; idx < len(runes) && isSpace(runes[idx]); idx++ {
 | 
						|
			// skip leading whitespace
 | 
						|
		}
 | 
						|
		if idx >= len(runes) {
 | 
						|
			break
 | 
						|
		}
 | 
						|
		r := runes[idx]
 | 
						|
		if isValidBareChar(r) {
 | 
						|
			// parse bare key
 | 
						|
			startIdx := idx
 | 
						|
			endIdx := -1
 | 
						|
			idx++
 | 
						|
			for idx < len(runes) {
 | 
						|
				r = runes[idx]
 | 
						|
				if isValidBareChar(r) {
 | 
						|
					idx++
 | 
						|
				} else if r == '.' {
 | 
						|
					endIdx = idx
 | 
						|
					break
 | 
						|
				} else if isSpace(r) {
 | 
						|
					endIdx = idx
 | 
						|
					for ; idx < len(runes) && isSpace(runes[idx]); idx++ {
 | 
						|
						// skip trailing whitespace
 | 
						|
					}
 | 
						|
					if idx < len(runes) && runes[idx] != '.' {
 | 
						|
						return nil, fmt.Errorf("invalid key character after whitespace: %c", runes[idx])
 | 
						|
					}
 | 
						|
					break
 | 
						|
				} else {
 | 
						|
					return nil, fmt.Errorf("invalid bare key character: %c", r)
 | 
						|
				}
 | 
						|
			}
 | 
						|
			if endIdx == -1 {
 | 
						|
				endIdx = idx
 | 
						|
			}
 | 
						|
			groups = append(groups, string(runes[startIdx:endIdx]))
 | 
						|
		} else if r == '\'' {
 | 
						|
			// parse single quoted key
 | 
						|
			idx++
 | 
						|
			startIdx := idx
 | 
						|
			for {
 | 
						|
				if idx >= len(runes) {
 | 
						|
					return nil, fmt.Errorf("unclosed single-quoted key")
 | 
						|
				}
 | 
						|
				r = runes[idx]
 | 
						|
				if r == '\'' {
 | 
						|
					groups = append(groups, string(runes[startIdx:idx]))
 | 
						|
					idx++
 | 
						|
					break
 | 
						|
				}
 | 
						|
				idx++
 | 
						|
			}
 | 
						|
		} else if r == '"' {
 | 
						|
			// parse double quoted key
 | 
						|
			idx++
 | 
						|
			startIdx := idx
 | 
						|
			for {
 | 
						|
				if idx >= len(runes) {
 | 
						|
					return nil, fmt.Errorf("unclosed double-quoted key")
 | 
						|
				}
 | 
						|
				r = runes[idx]
 | 
						|
				if r == '"' {
 | 
						|
					groups = append(groups, string(runes[startIdx:idx]))
 | 
						|
					idx++
 | 
						|
					break
 | 
						|
				}
 | 
						|
				idx++
 | 
						|
			}
 | 
						|
		} else if r == '.' {
 | 
						|
			idx++
 | 
						|
			if idx >= len(runes) {
 | 
						|
				return nil, fmt.Errorf("unexpected end of key")
 | 
						|
			}
 | 
						|
			r = runes[idx]
 | 
						|
			if !isValidBareChar(r) && r != '\'' && r != '"' && r != ' ' {
 | 
						|
				return nil, fmt.Errorf("expecting key part after dot")
 | 
						|
			}
 | 
						|
		} else {
 | 
						|
			return nil, fmt.Errorf("invalid key character: %c", r)
 | 
						|
		}
 | 
						|
	}
 | 
						|
	if len(groups) == 0 {
 | 
						|
		return nil, fmt.Errorf("empty key")
 | 
						|
	}
 | 
						|
	return groups, nil
 | 
						|
}
 | 
						|
 | 
						|
func isValidBareChar(r rune) bool {
 | 
						|
	return isAlphanumeric(r) || r == '-' || isDigit(r)
 | 
						|
}
 |