71 lines
1.2 KiB
Go
71 lines
1.2 KiB
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"os"
|
||
|
"io"
|
||
|
"bufio"
|
||
|
"fmt"
|
||
|
|
||
|
"github.com/google/shlex"
|
||
|
)
|
||
|
|
||
|
type Directive struct {
|
||
|
Params []string
|
||
|
Children []*Directive
|
||
|
}
|
||
|
|
||
|
func Load(path string) ([]*Directive, error) {
|
||
|
f, err := os.Open(path)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
defer f.Close()
|
||
|
|
||
|
return Parse(f)
|
||
|
}
|
||
|
|
||
|
func Parse(r io.Reader) ([]*Directive, error) {
|
||
|
scanner := bufio.NewScanner(r)
|
||
|
|
||
|
var directives []*Directive
|
||
|
var cur *Directive
|
||
|
for scanner.Scan() {
|
||
|
l := scanner.Text()
|
||
|
words, err := shlex.Split(l)
|
||
|
if err != nil {
|
||
|
return directives, fmt.Errorf("failed to parse config file: %v", err)
|
||
|
} else if len(words) == 0 {
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
if len(words) == 1 && l[len(l) - 1] == '}' {
|
||
|
if cur == nil {
|
||
|
return nil, fmt.Errorf("unexpected '}'")
|
||
|
}
|
||
|
cur = nil
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
var d *Directive
|
||
|
if words[len(words) - 1] == "{" && l[len(l) - 1] == '{' {
|
||
|
d = &Directive{
|
||
|
Params: words[:len(words) - 1],
|
||
|
}
|
||
|
cur = d
|
||
|
directives = append(directives, d)
|
||
|
} else {
|
||
|
d = &Directive{Params: words}
|
||
|
if cur != nil {
|
||
|
cur.Children = append(cur.Children, d)
|
||
|
} else {
|
||
|
directives = append(directives, d)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if err := scanner.Err(); err != nil {
|
||
|
return nil, fmt.Errorf("failed to read config file: %v", err)
|
||
|
}
|
||
|
|
||
|
return directives, nil
|
||
|
}
|