diff options
| author | 2026-03-06 10:52:02 +0800 | |
|---|---|---|
| committer | 2026-03-06 10:53:37 +0800 | |
| commit | f36918966727be99bfe9d461059269f36f92058a (patch) | |
| tree | ff2c6545d369a74c210574f821298181307c701a /config/key_value.go | |
| parent | objecttype: Split files (diff) | |
| signature | No signature | |
config: Split files
Diffstat (limited to 'config/key_value.go')
| -rw-r--r-- | config/key_value.go | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/config/key_value.go b/config/key_value.go new file mode 100644 index 00000000..482bfcc7 --- /dev/null +++ b/config/key_value.go @@ -0,0 +1,119 @@ +package config + +import ( + "bytes" + "errors" + "fmt" + "io" +) + +func (p *configParser) parseKeyValue(cfg *Config) error { + if p.currentSection == "" { + return errors.New("key-value pair before any section header") + } + + var key bytes.Buffer + + for { + ch, err := p.nextChar() + if errors.Is(err, io.EOF) { + break + } + + if err != nil { + return err + } + + if ch == '=' || ch == '\n' || isSpace(ch) { + p.unreadChar(ch) + + break + } + + if !isKeyChar(ch) { + return fmt.Errorf("invalid character in key: %q", ch) + } + + key.WriteByte(toLower(ch)) + } + + keyStr := key.String() + if len(keyStr) == 0 { + return errors.New("empty key name") + } + + if !isLetter(keyStr[0]) { + return errors.New("key must start with a letter") + } + + for { + ch, err := p.nextChar() + if errors.Is(err, io.EOF) { + cfg.entries = append(cfg.entries, ConfigEntry{ + Section: p.currentSection, + Subsection: p.currentSubsec, + Key: keyStr, + Kind: ValueValueless, + Value: "", + }) + + return nil + } + + if err != nil { + return err + } + + if ch == '\n' { + cfg.entries = append(cfg.entries, ConfigEntry{ + Section: p.currentSection, + Subsection: p.currentSubsec, + Key: keyStr, + Kind: ValueValueless, + Value: "", + }) + + return nil + } + + if ch == '#' || ch == ';' { + err := p.skipToEOL() + if err != nil && !errors.Is(err, io.EOF) { + return err + } + + cfg.entries = append(cfg.entries, ConfigEntry{ + Section: p.currentSection, + Subsection: p.currentSubsec, + Key: keyStr, + Kind: ValueValueless, + Value: "", + }) + + return nil + } + + if ch == '=' { + break + } + + if !isSpace(ch) { + return fmt.Errorf("unexpected character after key: %q", ch) + } + } + + value, err := p.parseValue() + if err != nil { + return err + } + + cfg.entries = append(cfg.entries, ConfigEntry{ + Section: p.currentSection, + Subsection: p.currentSubsec, + Key: keyStr, + Kind: ValueString, + Value: value, + }) + + return nil +} |
