68 lines
1.9 KiB
Go
68 lines
1.9 KiB
Go
package conf
|
|
|
|
import (
|
|
"bufio"
|
|
"io"
|
|
"os"
|
|
"regexp"
|
|
"strings"
|
|
)
|
|
|
|
var (
|
|
configKeyValueRe = regexp.MustCompile(`(\w+) *= *(.+)\b[\t| |\n]*`)
|
|
configOptionRe = regexp.MustCompile(`(\w+)`)
|
|
configCommentedOut = "#"
|
|
)
|
|
|
|
// ParseFile reads values from file. It returns nil and error if os.Open(filename) fails.
|
|
// It would be wise to always check returned error.
|
|
// ParseFile captures two types of values: "key = value" and "option". Either key value pair or
|
|
// option must be put in its own line in the file.
|
|
// Key or option must be a single word. In example line:
|
|
// "option1 option2"
|
|
// only option1 will be captured. option2 needs to be in a separate line in the file to take effect.
|
|
// In line "key = value1,value2,value3" all of value1, value2, and value3 will be
|
|
// captured. They can be later accesed separately with Setting's Split() method.
|
|
func ParseFile(filename string) (*Config, error) {
|
|
file, err := os.Open(filename)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer file.Close()
|
|
return parseReader(file), nil
|
|
}
|
|
|
|
// ParseReader reads from r and returns Config. See also ParseFile.
|
|
func ParseReader(r io.Reader) *Config {
|
|
return parseReader(r)
|
|
}
|
|
|
|
// ParseReadCloser reads from r, returns Config and calls r.Close().
|
|
// See also ParseFile.
|
|
func ParseReadCloser(r io.ReadCloser) *Config {
|
|
defer r.Close()
|
|
return parseReader(r)
|
|
}
|
|
|
|
func parseReader(r io.Reader) *Config {
|
|
var c Config
|
|
c.Settings = make(map[string]string)
|
|
c.Options = make(map[string]struct{})
|
|
scanner := bufio.NewScanner(r)
|
|
for scanner.Scan() {
|
|
line := scanner.Text()
|
|
if strings.HasPrefix(line, configCommentedOut) {
|
|
continue
|
|
}
|
|
switch {
|
|
case configKeyValueRe.MatchString(line):
|
|
kvpair := configKeyValueRe.FindStringSubmatch(line)
|
|
c.Settings[kvpair[1]] = kvpair[2]
|
|
case configOptionRe.MatchString(line):
|
|
opt := configOptionRe.FindString(line)
|
|
c.Options[opt] = struct{}{}
|
|
}
|
|
}
|
|
return &c
|
|
}
|