podman
86 строк · 1.7 Кб
1// Copyright 2013-2022 Frank Schroeder. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package properties
6
7import (
8"fmt"
9"runtime"
10)
11
12type parser struct {
13lex *lexer
14}
15
16func parse(input string) (properties *Properties, err error) {
17p := &parser{lex: lex(input)}
18defer p.recover(&err)
19
20properties = NewProperties()
21key := ""
22comments := []string{}
23
24for {
25token := p.expectOneOf(itemComment, itemKey, itemEOF)
26switch token.typ {
27case itemEOF:
28goto done
29case itemComment:
30comments = append(comments, token.val)
31continue
32case itemKey:
33key = token.val
34if _, ok := properties.m[key]; !ok {
35properties.k = append(properties.k, key)
36}
37}
38
39token = p.expectOneOf(itemValue, itemEOF)
40if len(comments) > 0 {
41properties.c[key] = comments
42comments = []string{}
43}
44switch token.typ {
45case itemEOF:
46properties.m[key] = ""
47goto done
48case itemValue:
49properties.m[key] = token.val
50}
51}
52
53done:
54return properties, nil
55}
56
57func (p *parser) errorf(format string, args ...interface{}) {
58format = fmt.Sprintf("properties: Line %d: %s", p.lex.lineNumber(), format)
59panic(fmt.Errorf(format, args...))
60}
61
62func (p *parser) expectOneOf(expected ...itemType) (token item) {
63token = p.lex.nextItem()
64for _, v := range expected {
65if token.typ == v {
66return token
67}
68}
69p.unexpected(token)
70panic("unexpected token")
71}
72
73func (p *parser) unexpected(token item) {
74p.errorf(token.String())
75}
76
77// recover is the handler that turns panics into returns from the top level of Parse.
78func (p *parser) recover(errp *error) {
79e := recover()
80if e != nil {
81if _, ok := e.(runtime.Error); ok {
82panic(e)
83}
84*errp = e.(error)
85}
86}
87