ran gofmt

This commit is contained in:
Stephen Weinberg 2010-04-08 13:39:05 -04:00
parent 5817e58bf8
commit 4cea74d15d
5 changed files with 189 additions and 181 deletions

56
conf.go
View File

@ -39,7 +39,7 @@ import (
// ConfigFile is the representation of configuration settings. // ConfigFile is the representation of configuration settings.
// The public interface is entirely through methods. // The public interface is entirely through methods.
type ConfigFile struct { type ConfigFile struct {
data map[string]map[string]string; // Maps sections to options to values. data map[string]map[string]string // Maps sections to options to values.
} }
const ( const (
@ -56,8 +56,8 @@ const (
) )
var ( var (
DefaultSection = "default"; // Default section name (must be lower-case). DefaultSection = "default" // Default section name (must be lower-case).
DepthValues = 200; // Maximum allowed depth when recursively substituing variable names. DepthValues = 200 // Maximum allowed depth when recursively substituing variable names.
// Strings accepted as bool. // Strings accepted as bool.
BoolStrings = map[string]bool{ BoolStrings = map[string]bool{
@ -73,30 +73,30 @@ var (
"no": false, "no": false,
"off": false, "off": false,
"0": false, "0": false,
}; }
varRegExp = regexp.MustCompile(`%\(([a-zA-Z0-9_.\-]+)\)s`); varRegExp = regexp.MustCompile(`%\(([a-zA-Z0-9_.\-]+)\)s`)
) )
// AddSection adds a new section to the configuration. // AddSection adds a new section to the configuration.
// It returns true if the new section was inserted, and false if the section already existed. // It returns true if the new section was inserted, and false if the section already existed.
func (c *ConfigFile) AddSection(section string) bool { func (c *ConfigFile) AddSection(section string) bool {
section = strings.ToLower(section); section = strings.ToLower(section)
if _, ok := c.data[section]; ok { if _, ok := c.data[section]; ok {
return false return false
} }
c.data[section] = make(map[string]string); c.data[section] = make(map[string]string)
return true; return true
} }
// RemoveSection removes a section from the configuration. // RemoveSection removes a section from the configuration.
// It returns true if the section was removed, and false if section did not exist. // It returns true if the section was removed, and false if section did not exist.
func (c *ConfigFile) RemoveSection(section string) bool { func (c *ConfigFile) RemoveSection(section string) bool {
section = strings.ToLower(section); section = strings.ToLower(section)
switch _, ok := c.data[section]; { switch _, ok := c.data[section]; {
case !ok: case !ok:
@ -107,10 +107,10 @@ func (c *ConfigFile) RemoveSection(section string) bool {
for o, _ := range c.data[section] { for o, _ := range c.data[section] {
c.data[section][o] = "", false c.data[section][o] = "", false
} }
c.data[section] = nil, false; c.data[section] = nil, false
} }
return true; return true
} }
@ -118,15 +118,15 @@ func (c *ConfigFile) RemoveSection(section string) bool {
// It returns true if the option and value were inserted, and false if the value was overwritten. // It returns true if the option and value were inserted, and false if the value was overwritten.
// If the section does not exist in advance, it is created. // If the section does not exist in advance, it is created.
func (c *ConfigFile) AddOption(section string, option string, value string) bool { func (c *ConfigFile) AddOption(section string, option string, value string) bool {
c.AddSection(section); // make sure section exists c.AddSection(section) // make sure section exists
section = strings.ToLower(section); section = strings.ToLower(section)
option = strings.ToLower(option); option = strings.ToLower(option)
_, ok := c.data[section][option]; _, ok := c.data[section][option]
c.data[section][option] = value; c.data[section][option] = value
return !ok; return !ok
} }
@ -134,17 +134,17 @@ func (c *ConfigFile) AddOption(section string, option string, value string) bool
// It returns true if the option and value were removed, and false otherwise, // It returns true if the option and value were removed, and false otherwise,
// including if the section did not exist. // including if the section did not exist.
func (c *ConfigFile) RemoveOption(section string, option string) bool { func (c *ConfigFile) RemoveOption(section string, option string) bool {
section = strings.ToLower(section); section = strings.ToLower(section)
option = strings.ToLower(option); option = strings.ToLower(option)
if _, ok := c.data[section]; !ok { if _, ok := c.data[section]; !ok {
return false return false
} }
_, ok := c.data[section][option]; _, ok := c.data[section][option]
c.data[section][option] = "", false; c.data[section][option] = "", false
return ok; return ok
} }
@ -152,12 +152,12 @@ func (c *ConfigFile) RemoveOption(section string, option string) bool {
// This representation can be filled with AddSection and AddOption and then // This representation can be filled with AddSection and AddOption and then
// saved to a file using WriteConfigFile. // saved to a file using WriteConfigFile.
func NewConfigFile() *ConfigFile { func NewConfigFile() *ConfigFile {
c := new(ConfigFile); c := new(ConfigFile)
c.data = make(map[string]map[string]string); c.data = make(map[string]map[string]string)
c.AddSection(DefaultSection); // default section always exists c.AddSection(DefaultSection) // default section always exists
return c; return c
} }
@ -168,7 +168,7 @@ func stripComments(l string) string {
l = l[0:i] l = l[0:i]
} }
} }
return l; return l
} }
@ -180,7 +180,7 @@ func firstIndex(s string, delim []byte) int {
} }
} }
} }
return -1; return -1
} }
type GetError struct { type GetError struct {

View File

@ -1,6 +1,6 @@
package conf_test package conf_test
import( import (
. "conf" . "conf"
"testing" "testing"
"strconv" "strconv"
@ -35,7 +35,7 @@ type booltest struct {
answer bool answer bool
} }
var testSet = []interface{} { var testSet = []interface{}{
stringtest{"", "host", "example.com"}, stringtest{"", "host", "example.com"},
inttest{"default", "port", 43}, inttest{"default", "port", 43},
booltest{"default", "compression", true}, booltest{"default", "compression", true},

96
get.go
View File

@ -9,24 +9,26 @@ import (
// GetSections returns the list of sections in the configuration. // GetSections returns the list of sections in the configuration.
// (The default section always exists.) // (The default section always exists.)
func (c *ConfigFile) GetSections() (sections []string) { func (c *ConfigFile) GetSections() (sections []string) {
sections = make([]string, len(c.data)); sections = make([]string, len(c.data))
i := 0; i := 0
for s, _ := range c.data { for s, _ := range c.data {
sections[i] = s; sections[i] = s
i++; i++
} }
return sections; return sections
} }
// HasSection checks if the configuration has the given section. // HasSection checks if the configuration has the given section.
// (The default section always exists.) // (The default section always exists.)
func (c *ConfigFile) HasSection(section string) bool { func (c *ConfigFile) HasSection(section string) bool {
if section == "" {section = "default"} if section == "" {
_, ok := c.data[strings.ToLower(section)]; section = "default"
}
_, ok := c.data[strings.ToLower(section)]
return ok; return ok
} }
@ -34,43 +36,47 @@ func (c *ConfigFile) HasSection(section string) bool {
// It returns an error if the section does not exist and an empty list if the section is empty. // It returns an error if the section does not exist and an empty list if the section is empty.
// Options within the default section are also included. // Options within the default section are also included.
func (c *ConfigFile) GetOptions(section string) (options []string, err os.Error) { func (c *ConfigFile) GetOptions(section string) (options []string, err os.Error) {
if section == "" {section = "default"} if section == "" {
section = strings.ToLower(section); section = "default"
}
section = strings.ToLower(section)
if _, ok := c.data[section]; !ok { if _, ok := c.data[section]; !ok {
return nil, GetError{SectionNotFound, "", "", section, ""} return nil, GetError{SectionNotFound, "", "", section, ""}
} }
options = make([]string, len(c.data[DefaultSection])+len(c.data[section])); options = make([]string, len(c.data[DefaultSection])+len(c.data[section]))
i := 0; i := 0
for s, _ := range c.data[DefaultSection] { for s, _ := range c.data[DefaultSection] {
options[i] = s; options[i] = s
i++; i++
} }
for s, _ := range c.data[section] { for s, _ := range c.data[section] {
options[i] = s; options[i] = s
i++; i++
} }
return options, nil; return options, nil
} }
// HasOption checks if the configuration has the given option in the section. // HasOption checks if the configuration has the given option in the section.
// It returns false if either the option or section do not exist. // It returns false if either the option or section do not exist.
func (c *ConfigFile) HasOption(section string, option string) bool { func (c *ConfigFile) HasOption(section string, option string) bool {
if section == "" {section = "default"} if section == "" {
section = strings.ToLower(section); section = "default"
option = strings.ToLower(option); }
section = strings.ToLower(section)
option = strings.ToLower(option)
if _, ok := c.data[section]; !ok { if _, ok := c.data[section]; !ok {
return false return false
} }
_, okd := c.data[DefaultSection][option]; _, okd := c.data[DefaultSection][option]
_, oknd := c.data[section][option]; _, oknd := c.data[section][option]
return okd || oknd; return okd || oknd
} }
@ -78,18 +84,20 @@ func (c *ConfigFile) HasOption(section string, option string) bool {
// The raw string value is not subjected to unfolding, which was illustrated in the beginning of this documentation. // The raw string value is not subjected to unfolding, which was illustrated in the beginning of this documentation.
// It returns an error if either the section or the option do not exist. // It returns an error if either the section or the option do not exist.
func (c *ConfigFile) GetRawString(section string, option string) (value string, err os.Error) { func (c *ConfigFile) GetRawString(section string, option string) (value string, err os.Error) {
if section == "" {section = "default"} if section == "" {
section = "default"
}
section = strings.ToLower(section); section = strings.ToLower(section)
option = strings.ToLower(option); option = strings.ToLower(option)
if _, ok := c.data[section]; ok { if _, ok := c.data[section]; ok {
if value, ok = c.data[section][option]; ok { if value, ok = c.data[section][option]; ok {
return value, nil return value, nil
} }
return "", GetError{OptionNotFound, "", "", section, option}; return "", GetError{OptionNotFound, "", "", section, option}
} }
return "", GetError{SectionNotFound, "", "", section, option}; return "", GetError{SectionNotFound, "", "", section, option}
} }
@ -98,25 +106,25 @@ func (c *ConfigFile) GetRawString(section string, option string) (value string,
// then GetString does this unfolding automatically, up to DepthValues number of iterations. // then GetString does this unfolding automatically, up to DepthValues number of iterations.
// It returns an error if either the section or the option do not exist, or the unfolding cycled. // It returns an error if either the section or the option do not exist, or the unfolding cycled.
func (c *ConfigFile) GetString(section string, option string) (value string, err os.Error) { func (c *ConfigFile) GetString(section string, option string) (value string, err os.Error) {
value, err = c.GetRawString(section, option); value, err = c.GetRawString(section, option)
if err != nil { if err != nil {
return "", err return "", err
} }
section = strings.ToLower(section); section = strings.ToLower(section)
var i int; var i int
for i = 0; i < DepthValues; i++ { // keep a sane depth for i = 0; i < DepthValues; i++ { // keep a sane depth
vr := varRegExp.ExecuteString(value); vr := varRegExp.ExecuteString(value)
if len(vr) == 0 { if len(vr) == 0 {
break break
} }
noption := value[vr[2]:vr[3]]; noption := value[vr[2]:vr[3]]
noption = strings.ToLower(noption); noption = strings.ToLower(noption)
nvalue, _ := c.data[DefaultSection][noption]; // search variable in default section nvalue, _ := c.data[DefaultSection][noption] // search variable in default section
if _, ok := c.data[section][noption]; ok { if _, ok := c.data[section][noption]; ok {
nvalue = c.data[section][noption] nvalue = c.data[section][noption]
} }
@ -125,20 +133,20 @@ func (c *ConfigFile) GetString(section string, option string) (value string, err
} }
// substitute by new value and take off leading '%(' and trailing ')s' // substitute by new value and take off leading '%(' and trailing ')s'
value = value[0:vr[2]-2] + nvalue + value[vr[3]+2:]; value = value[0:vr[2]-2] + nvalue + value[vr[3]+2:]
} }
if i == DepthValues { if i == DepthValues {
return "", GetError{MaxDepthReached, "", "", section, option} return "", GetError{MaxDepthReached, "", "", section, option}
} }
return value, nil; return value, nil
} }
// GetInt has the same behaviour as GetString but converts the response to int. // GetInt has the same behaviour as GetString but converts the response to int.
func (c *ConfigFile) GetInt(section string, option string) (value int, err os.Error) { func (c *ConfigFile) GetInt(section string, option string) (value int, err os.Error) {
sv, err := c.GetString(section, option); sv, err := c.GetString(section, option)
if err == nil { if err == nil {
value, err = strconv.Atoi(sv) value, err = strconv.Atoi(sv)
if err != nil { if err != nil {
@ -146,13 +154,13 @@ func (c *ConfigFile) GetInt(section string, option string) (value int, err os.Er
} }
} }
return value, err; return value, err
} }
// GetFloat has the same behaviour as GetString but converts the response to float. // GetFloat has the same behaviour as GetString but converts the response to float.
func (c *ConfigFile) GetFloat(section string, option string) (value float, err os.Error) { func (c *ConfigFile) GetFloat(section string, option string) (value float, err os.Error) {
sv, err := c.GetString(section, option); sv, err := c.GetString(section, option)
if err == nil { if err == nil {
value, err = strconv.Atof(sv) value, err = strconv.Atof(sv)
if err != nil { if err != nil {
@ -160,22 +168,22 @@ func (c *ConfigFile) GetFloat(section string, option string) (value float, err o
} }
} }
return value, err; return value, err
} }
// GetBool has the same behaviour as GetString but converts the response to bool. // GetBool has the same behaviour as GetString but converts the response to bool.
// See constant BoolStrings for string values converted to bool. // See constant BoolStrings for string values converted to bool.
func (c *ConfigFile) GetBool(section string, option string) (value bool, err os.Error) { func (c *ConfigFile) GetBool(section string, option string) (value bool, err os.Error) {
sv, err := c.GetString(section, option); sv, err := c.GetString(section, option)
if err != nil { if err != nil {
return false, err return false, err
} }
value, ok := BoolStrings[strings.ToLower(sv)]; value, ok := BoolStrings[strings.ToLower(sv)]
if !ok { if !ok {
return false, GetError{CouldNotParse, "bool", sv, section, option} return false, GetError{CouldNotParse, "bool", sv, section, option}
} }
return value, nil; return value, nil
} }

36
read.go
View File

@ -11,13 +11,13 @@ import (
// ReadConfigFile reads a file and returns a new configuration representation. // ReadConfigFile reads a file and returns a new configuration representation.
// This representation can be queried with GetString, etc. // This representation can be queried with GetString, etc.
func ReadConfigFile(fname string) (c *ConfigFile, err os.Error) { func ReadConfigFile(fname string) (c *ConfigFile, err os.Error) {
var file *os.File; var file *os.File
if file, err = os.Open(fname, os.O_RDONLY, 0); err != nil { if file, err = os.Open(fname, os.O_RDONLY, 0); err != nil {
return nil, err return nil, err
} }
c = NewConfigFile(); c = NewConfigFile()
if err = c.Read(file); err != nil { if err = c.Read(file); err != nil {
return nil, err return nil, err
} }
@ -32,7 +32,7 @@ func ReadConfigFile(fname string) (c *ConfigFile, err os.Error) {
func ReadConfigBytes(conf []byte) (c *ConfigFile, err os.Error) { func ReadConfigBytes(conf []byte) (c *ConfigFile, err os.Error) {
buf := bytes.NewBuffer(conf) buf := bytes.NewBuffer(conf)
c = NewConfigFile(); c = NewConfigFile()
if err = c.Read(buf); err != nil { if err = c.Read(buf); err != nil {
return nil, err return nil, err
} }
@ -45,15 +45,15 @@ func ReadConfigBytes(conf []byte) (c *ConfigFile, err os.Error) {
func (c *ConfigFile) Read(reader io.Reader) (err os.Error) { func (c *ConfigFile) Read(reader io.Reader) (err os.Error) {
buf := bufio.NewReader(reader) buf := bufio.NewReader(reader)
var section, option string; var section, option string
section = "default" section = "default"
for { for {
l, buferr := buf.ReadString('\n'); // parse line-by-line l, buferr := buf.ReadString('\n') // parse line-by-line
if buferr != nil && buferr != os.EOF { if buferr != nil && buferr != os.EOF {
return err return err
} }
l = strings.TrimSpace(l); l = strings.TrimSpace(l)
// switch written for readability (not performance) // switch written for readability (not performance)
switch { switch {
case len(l) == 0: // empty line case len(l) == 0: // empty line
@ -69,26 +69,26 @@ func (c *ConfigFile) Read(reader io.Reader) (err os.Error) {
continue continue
case l[0] == '[' && l[len(l)-1] == ']': // new section case l[0] == '[' && l[len(l)-1] == ']': // new section
option = ""; // reset multi-line value option = "" // reset multi-line value
section = strings.TrimSpace(l[1 : len(l)-1]); section = strings.TrimSpace(l[1 : len(l)-1])
c.AddSection(section); c.AddSection(section)
case section == "": // not new section and no section defined so far case section == "": // not new section and no section defined so far
return ReadError{BlankSection, l} return ReadError{BlankSection, l}
default: // other alternatives default: // other alternatives
i := firstIndex(l, []byte{'=', ':'}); i := firstIndex(l, []byte{'=', ':'})
switch { switch {
case i > 0: // option and value case i > 0: // option and value
i := firstIndex(l, []byte{'=', ':'}); i := firstIndex(l, []byte{'=', ':'})
option = strings.TrimSpace(l[0:i]); option = strings.TrimSpace(l[0:i])
value := strings.TrimSpace(stripComments(l[i+1:])); value := strings.TrimSpace(stripComments(l[i+1:]))
c.AddOption(section, option, value); c.AddOption(section, option, value)
case section != "" && option != "": // continuation of multi-line value case section != "" && option != "": // continuation of multi-line value
prev, _ := c.GetRawString(section, option); prev, _ := c.GetRawString(section, option)
value := strings.TrimSpace(stripComments(l)); value := strings.TrimSpace(stripComments(l))
c.AddOption(section, option, prev+"\n"+value); c.AddOption(section, option, prev+"\n"+value)
default: default:
return ReadError{CouldNotParse, l} return ReadError{CouldNotParse, l}
@ -100,5 +100,5 @@ func (c *ConfigFile) Read(reader io.Reader) (err os.Error) {
break break
} }
} }
return nil; return nil
} }

View File

@ -10,7 +10,7 @@ import (
// The desired file permissions must be passed as in os.Open. // The desired file permissions must be passed as in os.Open.
// The header is a string that is saved as a comment in the first line of the file. // The header is a string that is saved as a comment in the first line of the file.
func (c *ConfigFile) WriteConfigFile(fname string, perm int, header string) (err os.Error) { func (c *ConfigFile) WriteConfigFile(fname string, perm int, header string) (err os.Error) {
var file *os.File; var file *os.File
if file, err = os.Open(fname, os.O_WRONLY|os.O_CREAT|os.O_TRUNC, perm); err != nil { if file, err = os.Open(fname, os.O_WRONLY|os.O_CREAT|os.O_TRUNC, perm); err != nil {
return err return err
@ -19,7 +19,7 @@ func (c *ConfigFile) WriteConfigFile(fname string, perm int, header string) (err
return err return err
} }
return file.Close(); return file.Close()
} }
// WriteConfigBytes returns the configuration file. // WriteConfigBytes returns the configuration file.
@ -60,5 +60,5 @@ func (c *ConfigFile) Write(writer io.Writer, header string) (err os.Error) {
buf.WriteTo(writer) buf.WriteTo(writer)
return nil; return nil
} }