Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Radical change. Move towards goinstall compatibility.

- Remove goconfig module, instead use json-based config files.
- Don't build goremote and don't generate rpc.go each time.
- Fix small issue when `gocode set lib-path ""` was unacceptable.
  • Loading branch information...
commit a889242167e791026dbadbe92342cbffbbcdc567 1 parent 82c9044
@nsf authored
View
1  .gitignore
@@ -4,7 +4,6 @@
gocode
goremote
gocodetest
-rpc.go
*.swp
listidents
showcursor
View
17 Makefile
@@ -1,6 +1,5 @@
include $(GOROOT)/src/Make.inc
-PREREQ+=configfile.a
TARG=gocode
GOFILES=gocode.go\
autocompletefile.go\
@@ -22,19 +21,3 @@ GOFILES+=os_posix.go
endif
include $(GOROOT)/src/Make.cmd
-
-rpc.go: server.go goremote/goremote
- ./goremote/goremote server.go | gofmt > rpc.go
-
-goremote/goremote: goremote/goremote.go
- gomake -C goremote
-
-configfile.a: goconfig/configfile.go
- gomake -C goconfig
- cp goconfig/_obj/configfile.a .
-
-clean: cleandeps
-
-cleandeps:
- gomake -C goremote clean
- gomake -C goconfig clean
View
112 config.go
@@ -1,15 +1,15 @@
package main
import (
- cfg "./configfile"
"bytes"
- "errors"
"fmt"
"io"
+ "io/ioutil"
"os"
"path/filepath"
"reflect"
"strconv"
+ "encoding/json"
)
//-------------------------------------------------------------------------
@@ -20,17 +20,32 @@ import (
//-------------------------------------------------------------------------
var Config = struct {
- ProposeBuiltins bool "propose-builtins"
- LibPath string "lib-path"
+ ProposeBuiltins bool `json:"propose-builtins"`
+ LibPath string `json:"lib-path"`
}{
false,
"",
}
+var boolStrings = map[string]bool{
+ "t": true,
+ "true": true,
+ "y": true,
+ "yes": true,
+ "on": true,
+ "1": true,
+ "f": false,
+ "false": false,
+ "n": false,
+ "no": false,
+ "off": false,
+ "0": false,
+}
+
func setValue(v reflect.Value, name, value string) {
switch t := v; t.Kind() {
case reflect.Bool:
- v, ok := cfg.BoolStrings[value]
+ v, ok := boolStrings[value]
if ok {
t.SetBool(v)
}
@@ -71,8 +86,8 @@ func listConfig(v interface{}) string {
buf := bytes.NewBuffer(make([]byte, 0, 256))
for i := 0; i < str.NumField(); i++ {
v := str.Field(i)
- name := typ.Field(i).Tag
- listValue(v, string(name), buf)
+ name := typ.Field(i).Tag.Get("json")
+ listValue(v, name, buf)
}
return buf.String()
}
@@ -86,8 +101,8 @@ func listOption(v interface{}, name string) string {
buf := bytes.NewBuffer(make([]byte, 0, 256))
for i := 0; i < str.NumField(); i++ {
v := str.Field(i)
- nm := typ.Field(i).Tag
- if string(nm) == name {
+ nm := typ.Field(i).Tag.Get("json")
+ if nm == name {
listValue(v, name, buf)
}
}
@@ -103,8 +118,8 @@ func setOption(v interface{}, name, value string) string {
buf := bytes.NewBuffer(make([]byte, 0, 256))
for i := 0; i < str.NumField(); i++ {
v := str.Field(i)
- nm := typ.Field(i).Tag
- if string(nm) == name {
+ nm := typ.Field(i).Tag.Get("json")
+ if nm == name {
setValue(v, name, value)
listValue(v, name, buf)
}
@@ -128,59 +143,20 @@ func interfaceIsPtrStruct(v interface{}) (reflect.Value, reflect.Type, bool) {
return str, typ, true
}
-func writeValue(v reflect.Value, name string, c *cfg.ConfigFile) {
- switch v.Kind() {
- case reflect.Bool, reflect.String,
- reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Float32, reflect.Float64:
- c.AddOption(cfg.DefaultSection, name, fmt.Sprint(v.Interface()))
- }
-}
-
-func readValue(v reflect.Value, name string, c *cfg.ConfigFile) {
- if !c.HasOption(cfg.DefaultSection, name) {
- return
- }
- switch t := v; t.Kind() {
- case reflect.Bool:
- v, err := c.GetBool(cfg.DefaultSection, name)
- if err == nil {
- t.SetBool(v)
- }
- case reflect.String:
- v, err := c.GetString(cfg.DefaultSection, name)
- if err == nil {
- t.SetString(v)
- }
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- v, err := c.GetInt(cfg.DefaultSection, name)
- if err == nil {
- t.SetInt(int64(v))
- }
- case reflect.Float32, reflect.Float64:
- v, err := c.GetFloat(cfg.DefaultSection, name)
- if err == nil {
- t.SetFloat(float64(v))
- }
- }
-}
-
func writeConfig(v interface{}) error {
- const errstr = "WriteConfig expects a pointer to a struct value as an argument"
-
- str, typ, ok := interfaceIsPtrStruct(v)
- if !ok {
- return errors.New(errstr)
+ data, err := json.Marshal(v)
+ if err != nil {
+ return err
}
- c := cfg.NewConfigFile()
- for i := 0; i < str.NumField(); i++ {
- v := str.Field(i)
- name := typ.Field(i).Tag
- writeValue(v, string(name), c)
+ makeSureConfigDirExists()
+ f, err := os.Create(configFile())
+ if err != nil {
+ return err
}
+ defer f.Close()
- makeSureConfigDirExists()
- err := c.WriteConfigFile(configFile(), 0644, "gocode config file")
+ _, err = f.Write(data)
if err != nil {
return err
}
@@ -189,22 +165,14 @@ func writeConfig(v interface{}) error {
}
func readConfig(v interface{}) error {
- c, err := cfg.ReadConfigFile(configFile())
+ data, err := ioutil.ReadFile(configFile())
if err != nil {
return err
}
- const errstr = "ReadConfig expects a pointer to a struct value as an argument"
-
- str, typ, ok := interfaceIsPtrStruct(v)
- if !ok {
- return errors.New(errstr)
- }
-
- for i := 0; i < str.NumField(); i++ {
- v := str.Field(i)
- name := typ.Field(i).Tag
- readValue(v, string(name), c)
+ err = json.Unmarshal(data, v)
+ if err != nil {
+ return err
}
return nil
@@ -226,5 +194,5 @@ func makeSureConfigDirExists() {
}
func configFile() string {
- return filepath.Join(xdgHomeDir(), "gocode", "config.ini")
+ return filepath.Join(xdgHomeDir(), "gocode", "config.json")
}
View
4 gocode.go
@@ -279,9 +279,9 @@ func cmdDropCache(c *rpc.Client) {
func cmdSet(c *rpc.Client) {
switch flag.NArg() {
case 1:
- fmt.Print(Client_Set(c, "", ""))
+ fmt.Print(Client_Set(c, "\x00", "\x00"))
case 2:
- fmt.Print(Client_Set(c, flag.Arg(1), ""))
+ fmt.Print(Client_Set(c, flag.Arg(1), "\x00"))
case 3:
fmt.Print(Client_Set(c, flag.Arg(1), flag.Arg(2)))
}
View
7 goconfig/Makefile
@@ -1,7 +0,0 @@
-include $(GOROOT)/src/Make.inc
-
-TARG=configfile
-GOFILES=\
- configfile.go\
-
-include $(GOROOT)/src/Make.pkg
View
16 goconfig/README
@@ -1,16 +0,0 @@
-The Makefile and configfile_test.py are to be used only
-if you want to place this package in the standard library.
-
-To place this package in the standard library and run
-the test cases do:
-mkdir $GOROOT/src/pkg/configfile/
-cp configfile.go configfile_test.go Makefile $GOROOT/src/pkg/configfile/
-cd $GOROOT/src/pkg/configfile/
-make
-gotest configfile_test.go
-(and you should see PASS).
-
-Otherwise, to use it separately from the standard library
-just do as usual:
-6g configfile.go
-... and then link to your own source file.
View
462 goconfig/configfile.go
@@ -1,462 +0,0 @@
-// This package implements a parser for configuration files.
-// This allows easy reading and writing of structured configuration files.
-//
-// Given a sample configuration file:
-//
-// [default]
-// host=www.example.com
-// protocol=http://
-// base-url=%(protocol)s%(host)s
-//
-// [service-1]
-// url=%(base-url)s/some/path
-// delegation : on
-// maxclients=200 # do not set this higher
-// comments=This is a multi-line
-// entry ; And this is a comment
-//
-// To read this configuration file, do:
-//
-// c, err := configfile.ReadConfigFile("config.cfg");
-// c.GetString("service-1", "url"); // result is string :http://www.example.com/some/path"
-// c.GetInt("service-1", "maxclients"); // result is int 200
-// c.GetBool("service-1", "delegation"); // result is bool true
-// c.GetString("service-1", "comments"); // result is string "This is a multi-line\nentry"
-//
-// Note the support for unfolding variables (such as %(base-url)s), which are read from the special
-// (reserved) section name [default].
-//
-// A new configuration file can also be created with:
-//
-// c := configfile.NewConfigFile();
-// c.AddSection("section");
-// c.AddOption("section", "option", "value");
-// c.WriteConfigFile("config.cfg", 0644, "A header for this file"); // use 0644 as file permission
-//
-// This results in the file:
-//
-// # A header for this file
-// [section]
-// option=value
-//
-// Note that sections and options are case-insensitive (values are case-sensitive)
-// and are converted to lowercase when saved to a file.
-//
-// The functionality and workflow is loosely based on the configparser.py package
-// of the Python Standard Library.
-package configfile
-
-import (
- "bufio"
- "errors"
- "io"
- "os"
- "regexp"
- "strconv"
- "strings"
-)
-
-// ConfigFile is the representation of configuration settings.
-// The public interface is entirely through methods.
-type ConfigFile struct {
- data map[string]map[string]string // Maps sections to options to values.
-}
-
-var (
- DefaultSection = "default" // Default section name (must be lower-case).
- DepthValues = 200 // Maximum allowed depth when recursively substituing variable names.
-
- // Strings accepted as bool.
- BoolStrings = map[string]bool{
- "t": true,
- "true": true,
- "y": true,
- "yes": true,
- "on": true,
- "1": true,
- "f": false,
- "false": false,
- "n": false,
- "no": false,
- "off": false,
- "0": false,
- }
-
- varRegExp = regexp.MustCompile(`%\(([a-zA-Z0-9_.\-]+)\)s`)
-)
-
-// AddSection adds a new section to the configuration.
-// It returns true if the new section was inserted, and false if the section already existed.
-func (c *ConfigFile) AddSection(section string) bool {
- section = strings.ToLower(section)
-
- if _, ok := c.data[section]; ok {
- return false
- }
- c.data[section] = make(map[string]string)
-
- return true
-}
-
-// RemoveSection removes a section from the configuration.
-// It returns true if the section was removed, and false if section did not exist.
-func (c *ConfigFile) RemoveSection(section string) bool {
- section = strings.ToLower(section)
-
- switch _, ok := c.data[section]; {
- case !ok:
- return false
- case section == DefaultSection:
- return false // default section cannot be removed
- default:
- for o := range c.data[section] {
- delete(c.data[section], o)
- }
- delete(c.data, section)
- }
-
- return true
-}
-
-// AddOption adds a new option and value to the configuration.
-// 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.
-func (c *ConfigFile) AddOption(section string, option string, value string) bool {
- c.AddSection(section) // make sure section exists
-
- section = strings.ToLower(section)
- option = strings.ToLower(option)
-
- _, ok := c.data[section][option]
- c.data[section][option] = value
-
- return !ok
-}
-
-// RemoveOption removes a option and value from the configuration.
-// It returns true if the option and value were removed, and false otherwise,
-// including if the section did not exist.
-func (c *ConfigFile) RemoveOption(section string, option string) bool {
- section = strings.ToLower(section)
- option = strings.ToLower(option)
-
- if _, ok := c.data[section]; !ok {
- return false
- }
-
- _, ok := c.data[section][option]
- delete(c.data[section], option)
-
- return ok
-}
-
-// NewConfigFile creates an empty configuration representation.
-// This representation can be filled with AddSection and AddOption and then
-// saved to a file using WriteConfigFile.
-func NewConfigFile() *ConfigFile {
- c := new(ConfigFile)
- c.data = make(map[string]map[string]string)
-
- c.AddSection(DefaultSection) // default section always exists
-
- return c
-}
-
-func stripComments(l string) string {
- // comments are preceded by space or TAB
- for _, c := range []string{" ;", "\t;", " #", "\t#"} {
- if i := strings.Index(l, c); i != -1 {
- l = l[0:i]
- }
- }
- return l
-}
-
-func firstIndex(s string, delim []byte) int {
- for i := 0; i < len(s); i++ {
- for j := 0; j < len(delim); j++ {
- if s[i] == delim[j] {
- return i
- }
- }
- }
- return -1
-}
-
-func (c *ConfigFile) read(buf *bufio.Reader) (err error) {
- var section, option string
- for {
- l, err := buf.ReadString('\n') // parse line-by-line
- if err == io.EOF {
- break
- } else if err != nil {
- return err
- }
-
- l = strings.TrimSpace(l)
- // switch written for readability (not performance)
- switch {
- case len(l) == 0: // empty line
- continue
-
- case l[0] == '#': // comment
- continue
-
- case l[0] == ';': // comment
- continue
-
- case len(l) >= 3 && strings.ToLower(l[0:3]) == "rem": // comment (for windows users)
- continue
-
- case l[0] == '[' && l[len(l)-1] == ']': // new section
- option = "" // reset multi-line value
- section = strings.TrimSpace(l[1 : len(l)-1])
- c.AddSection(section)
-
- case section == "": // not new section and no section defined so far
- return errors.New("section not found: must start with section")
-
- default: // other alternatives
- i := firstIndex(l, []byte{'=', ':'})
- switch {
- case i > 0: // option and value
- i := firstIndex(l, []byte{'=', ':'})
- option = strings.TrimSpace(l[0:i])
- value := strings.TrimSpace(stripComments(l[i+1:]))
- c.AddOption(section, option, value)
-
- case section != "" && option != "": // continuation of multi-line value
- prev, _ := c.GetRawString(section, option)
- value := strings.TrimSpace(stripComments(l))
- c.AddOption(section, option, prev+"\n"+value)
-
- default:
- return errors.New("could not parse line: " + l)
- }
- }
- }
- return nil
-}
-
-// ReadConfigFile reads a file and returns a new configuration representation.
-// This representation can be queried with GetString, etc.
-func ReadConfigFile(fname string) (c *ConfigFile, err error) {
- var file *os.File
-
- if file, err = os.Open(fname); err != nil {
- return nil, err
- }
-
- c = NewConfigFile()
- if err = c.read(bufio.NewReader(file)); err != nil {
- return nil, err
- }
-
- if err = file.Close(); err != nil {
- return nil, err
- }
-
- return c, nil
-}
-
-func (c *ConfigFile) write(buf *bufio.Writer, header string) (err error) {
- if header != "" {
- if _, err = buf.WriteString("# " + header + "\n"); err != nil {
- return err
- }
- }
-
- for section, sectionmap := range c.data {
- if section == DefaultSection && len(sectionmap) == 0 {
- continue // skip default section if empty
- }
- if _, err = buf.WriteString("[" + section + "]\n"); err != nil {
- return err
- }
- for option, value := range sectionmap {
- if _, err = buf.WriteString(option + "=" + value + "\n"); err != nil {
- return err
- }
- }
- if _, err = buf.WriteString("\n"); err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// WriteConfigFile saves the configuration representation to a file.
-// 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.
-func (c *ConfigFile) WriteConfigFile(fname string, perm uint32, header string) (err error) {
- var file *os.File
-
- if file, err = os.Create(fname); err != nil {
- return err
- }
-
- buf := bufio.NewWriter(file)
- if err = c.write(buf, header); err != nil {
- return err
- }
- buf.Flush()
-
- return file.Close()
-}
-
-// GetSections returns the list of sections in the configuration.
-// (The default section always exists.)
-func (c *ConfigFile) GetSections() (sections []string) {
- sections = make([]string, len(c.data))
-
- i := 0
- for s := range c.data {
- sections[i] = s
- i++
- }
-
- return sections
-}
-
-// HasSection checks if the configuration has the given section.
-// (The default section always exists.)
-func (c *ConfigFile) HasSection(section string) bool {
- _, ok := c.data[strings.ToLower(section)]
-
- return ok
-}
-
-// GetOptions returns the list of options available in the given section.
-// 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.
-func (c *ConfigFile) GetOptions(section string) (options []string, err error) {
- section = strings.ToLower(section)
-
- if _, ok := c.data[section]; !ok {
- return nil, errors.New("section not found")
- }
-
- options = make([]string, len(c.data[DefaultSection])+len(c.data[section]))
- i := 0
- for s := range c.data[DefaultSection] {
- options[i] = s
- i++
- }
- for s := range c.data[section] {
- options[i] = s
- i++
- }
-
- return options, nil
-}
-
-// HasOption checks if the configuration has the given option in the section.
-// It returns false if either the option or section do not exist.
-func (c *ConfigFile) HasOption(section string, option string) bool {
- section = strings.ToLower(section)
- option = strings.ToLower(option)
-
- if _, ok := c.data[section]; !ok {
- return false
- }
-
- _, okd := c.data[DefaultSection][option]
- _, oknd := c.data[section][option]
-
- return okd || oknd
-}
-
-// GetRawString gets the (raw) string value for the given option in the section.
-// 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.
-func (c *ConfigFile) GetRawString(section string, option string) (value string, err error) {
- section = strings.ToLower(section)
- option = strings.ToLower(option)
-
- if _, ok := c.data[section]; ok {
- if value, ok = c.data[section][option]; ok {
- return value, nil
- }
- return "", errors.New("option not found")
- }
- return "", errors.New("section not found")
-}
-
-// GetString gets the string value for the given option in the section.
-// If the value needs to be unfolded (see e.g. %(host)s example in the beginning of this documentation),
-// 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.
-func (c *ConfigFile) GetString(section string, option string) (value string, err error) {
- value, err = c.GetRawString(section, option)
- if err != nil {
- return "", err
- }
-
- section = strings.ToLower(section)
-
- var i int
-
- for i = 0; i < DepthValues; i++ { // keep a sane depth
- vr := varRegExp.FindStringSubmatchIndex(value)
- if len(vr) == 0 {
- break
- }
-
- noption := value[vr[2]:vr[3]]
- noption = strings.ToLower(noption)
-
- nvalue, _ := c.data[DefaultSection][noption] // search variable in default section
- if _, ok := c.data[section][noption]; ok {
- nvalue = c.data[section][noption]
- }
- if nvalue == "" {
- return "", errors.New("option not found: " + noption)
- }
-
- // substitute by new value and take off leading '%(' and trailing ')s'
- value = value[0:vr[2]-2] + nvalue + value[vr[3]+2:]
- }
-
- if i == DepthValues {
- return "", errors.New("possible cycle while unfolding variables: max depth of " + strconv.Itoa(DepthValues) + " reached")
- }
-
- return value, nil
-}
-
-// GetInt has the same behaviour as GetString but converts the response to int.
-func (c *ConfigFile) GetInt(section string, option string) (value int, err error) {
- sv, err := c.GetString(section, option)
- if err == nil {
- value, err = strconv.Atoi(sv)
- }
-
- return value, err
-}
-
-// GetFloat has the same behaviour as GetString but converts the response to float.
-func (c *ConfigFile) GetFloat(section string, option string) (value float64, err error) {
- sv, err := c.GetString(section, option)
- if err == nil {
- value, err = strconv.ParseFloat(sv, 64)
- }
-
- return value, err
-}
-
-// GetBool has the same behaviour as GetString but converts the response to bool.
-// See constant BoolStrings for string values converted to bool.
-func (c *ConfigFile) GetBool(section string, option string) (value bool, err error) {
- sv, err := c.GetString(section, option)
- if err != nil {
- return false, err
- }
-
- value, ok := BoolStrings[strings.ToLower(sv)]
- if !ok {
- return false, errors.New("could not parse bool value: " + sv)
- }
-
- return value, nil
-}
View
216 goconfig/configfile_test.go
@@ -1,216 +0,0 @@
-package configfile_test
-
-import (
- "bufio"
- . "configfile"
- "os"
- "strings"
- "testing"
-)
-
-func testGet(t *testing.T, c *ConfigFile, section string, option string, expected interface{}) {
- ok := false
- switch _ := expected.(type) {
- case string:
- v, _ := c.GetString(section, option)
- if v == expected.(string) {
- ok = true
- }
- case int:
- v, _ := c.GetInt(section, option)
- if v == expected.(int) {
- ok = true
- }
- case bool:
- v, _ := c.GetBool(section, option)
- if v == expected.(bool) {
- ok = true
- }
- default:
- t.Fatalf("Bad test case")
- }
- if !ok {
- t.Errorf("Get failure: expected different value for %s %s", section, option)
- }
-}
-
-// Create configuration representation and run multiple tests in-memory.
-func TestInMemory(t *testing.T) {
- c := NewConfigFile()
-
- // test empty structure
- if len(c.GetSections()) != 1 { // should be empty
- t.Errorf("GetSections failure: invalid length")
- }
- if c.HasSection("no-section") { // test presence of missing section
- t.Errorf("HasSection failure: invalid section")
- }
- _, err := c.GetOptions("no-section") // get options for missing section
- if err == nil {
- t.Errorf("GetOptions failure: invalid section")
- }
- if c.HasOption("no-section", "no-option") { // test presence of option for missing section
- t.Errorf("HasSection failure: invalid/section/option")
- }
- _, err = c.GetString("no-section", "no-option") // get value from missing section/option
- if err == nil {
- t.Errorf("GetString failure: got value for missing section/option")
- }
- _, err = c.GetInt("no-section", "no-option") // get value from missing section/option
- if err == nil {
- t.Errorf("GetInt failure: got value for missing section/option")
- }
- if c.RemoveSection("no-section") { // remove missing section
- t.Errorf("RemoveSection failure: removed missing section")
- }
- if c.RemoveOption("no-section", "no-option") { // remove missing section/option
- t.Errorf("RemoveOption failure: removed missing section/option")
- }
-
- // fill up structure
- if !c.AddSection("section1") { // add section
- t.Errorf("AddSection failure: false on first insert")
- }
- if c.AddSection("section1") { // re-add same section
- t.Errorf("AddSection failure: true on second insert")
- }
- if c.AddSection(DefaultSection) { // default section always exists
- t.Errorf("AddSection failure: true on default section insert")
- }
-
- if !c.AddOption("section1", "option1", "value1") { // add option/value
- t.Errorf("AddOption failure: false on first insert")
- }
- testGet(t, c, "section1", "option1", "value1") // read it back
-
- if c.AddOption("section1", "option1", "value2") { // overwrite value
- t.Errorf("AddOption failure: true on second insert")
- }
- testGet(t, c, "section1", "option1", "value2") // read it back again
-
- if !c.RemoveOption("section1", "option1") { // remove option/value
- t.Errorf("RemoveOption failure: false on first remove")
- }
- if c.RemoveOption("section1", "option1") { // remove again
- t.Errorf("RemoveOption failure: true on second remove")
- }
- _, err = c.GetString("section1", "option1") // read it back again
- if err == nil {
- t.Errorf("GetString failure: got value for removed section/option")
- }
- if !c.RemoveSection("section1") { // remove existing section
- t.Errorf("RemoveSection failure: false on first remove")
- }
- if c.RemoveSection("section1") { // remove again
- t.Errorf("RemoveSection failure: true on second remove")
- }
-
- // test types
- if !c.AddSection("section2") { // add section
- t.Errorf("AddSection failure: false on first insert")
- }
-
- if !c.AddOption("section2", "test-number", "666") { // add number
- t.Errorf("AddOption failure: false on first insert")
- }
- testGet(t, c, "section2", "test-number", 666) // read it back
-
- if !c.AddOption("section2", "test-yes", "yes") { // add 'yes' (bool)
- t.Errorf("AddOption failure: false on first insert")
- }
- testGet(t, c, "section2", "test-yes", true) // read it back
-
- if !c.AddOption("section2", "test-false", "false") { // add 'false' (bool)
- t.Errorf("AddOption failure: false on first insert")
- }
- testGet(t, c, "section2", "test-false", false) // read it back
-
- // test cycle
- c.AddOption(DefaultSection, "opt1", "%(opt2)s")
- c.AddOption(DefaultSection, "opt2", "%(opt1)s")
- _, err = c.GetString(DefaultSection, "opt1")
- if err == nil {
- t.Errorf("GetString failure: no error for cycle")
- } else if strings.Index(err.String(), "cycle") < 0 {
- t.Errorf("GetString failure: incorrect error for cycle")
- }
-}
-
-// Create a 'tough' configuration file and test (read) parsing.
-func TestReadFile(t *testing.T) {
- const tmp = "/tmp/__config_test.go__garbage"
- defer os.Remove(tmp)
-
- file, err := os.Create(tmp)
- if err != nil {
- t.Fatalf("Test cannot run because cannot write temporary file: " + tmp)
- }
-
- buf := bufio.NewWriter(file)
- buf.WriteString("[section-1]\n")
- buf.WriteString(" option1=value1 ; This is a comment\n")
- buf.WriteString(" option2 : 2#Not a comment\t#Now this is a comment after a TAB\n")
- buf.WriteString(" # Let me put another comment\n")
- buf.WriteString(" option3= line1\nline2 \n\tline3 # Comment\n")
- buf.WriteString("; Another comment\n")
- buf.WriteString("[" + DefaultSection + "]\n")
- buf.WriteString("variable1=small\n")
- buf.WriteString("variable2=a_part_of_a_%(variable1)s_test\n")
- buf.WriteString("[secTION-2]\n")
- buf.WriteString("IS-flag-TRUE=Yes\n")
- buf.WriteString("[section-1]\n") // continue again [section-1]
- buf.WriteString("option4=this_is_%(variable2)s.\n")
- buf.Flush()
- file.Close()
-
- c, err := ReadConfigFile(tmp)
- if err != nil {
- t.Fatalf("ReadConfigFile failure: " + err.String())
- }
- if len(c.GetSections()) != 3 { // check number of sections
- t.Errorf("GetSections failure: wrong number of sections")
- }
- opts, err := c.GetOptions("section-1") // check number of options
- if len(opts) != 6 { // 4 of [section-1] plus 2 of [default]
- t.Errorf("GetOptions failure: wrong number of options")
- }
-
- testGet(t, c, "section-1", "option1", "value1")
- testGet(t, c, "section-1", "option2", "2#Not a comment")
- testGet(t, c, "section-1", "option3", "line1\nline2\nline3")
- testGet(t, c, "section-1", "option4", "this_is_a_part_of_a_small_test.")
- testGet(t, c, "SECtion-2", "is-FLAG-true", true) // case-insensitive
-}
-
-// Test writing and reading back a configuration file.
-func TestWriteReadFile(t *testing.T) {
- const tmp = "/tmp/__config_test.go__garbage"
- defer os.Remove(tmp)
-
- cw := NewConfigFile()
-
- // write file; will test only read later on
- cw.AddSection("First-Section")
- cw.AddOption("First-Section", "option1", "value option1")
- cw.AddOption("First-Section", "option2", "2")
-
- cw.AddOption(DefaultSection, "host", "www.example.com")
- cw.AddOption(DefaultSection, "protocol", "https://")
- cw.AddOption(DefaultSection, "base-url", "%(protocol)s%(host)s")
-
- cw.AddOption("Another-Section", "useHTTPS", "y")
- cw.AddOption("Another-Section", "url", "%(base-url)s/some/path")
-
- cw.WriteConfigFile(tmp, 0644, "Test file for test-case")
-
- // read back file and test
- cr, err := ReadConfigFile(tmp)
- if err != nil {
- t.Fatalf("ReadConfigFile failure: " + err.String())
- }
-
- testGet(t, cr, "first-section", "option1", "value option1")
- testGet(t, cr, "first-section", "option2", 2)
- testGet(t, cr, "Another-SECTION", "usehttps", true)
- testGet(t, cr, "another-section", "url", "https://www.example.com/some/path")
-}
View
136 rpc.go
@@ -0,0 +1,136 @@
+// WARNING! Autogenerated by goremote, don't touch.
+
+package main
+
+import (
+ "net/rpc"
+)
+
+type RPCRemote struct {
+}
+
+// wrapper for: Server_AutoComplete
+
+type Args_AutoComplete struct {
+ Arg0 []byte
+ Arg1 string
+ Arg2 int
+}
+type Reply_AutoComplete struct {
+ Arg0, Arg1, Arg2 []string
+ Arg3 int
+}
+
+func (r *RPCRemote) RPCServer_AutoComplete(args *Args_AutoComplete, reply *Reply_AutoComplete) error {
+ reply.Arg0, reply.Arg1, reply.Arg2, reply.Arg3 = Server_AutoComplete(args.Arg0, args.Arg1, args.Arg2)
+ return nil
+}
+func Client_AutoComplete(cli *rpc.Client, Arg0 []byte, Arg1 string, Arg2 int) (a, b, c []string, d int) {
+ var args Args_AutoComplete
+ var reply Reply_AutoComplete
+ args.Arg0 = Arg0
+ args.Arg1 = Arg1
+ args.Arg2 = Arg2
+ err := cli.Call("RPCRemote.RPCServer_AutoComplete", &args, &reply)
+ if err != nil {
+ panic(err)
+ }
+ return reply.Arg0, reply.Arg1, reply.Arg2, reply.Arg3
+}
+
+// wrapper for: Server_Close
+
+type Args_Close struct {
+ Arg0 int
+}
+type Reply_Close struct {
+ Arg0 int
+}
+
+func (r *RPCRemote) RPCServer_Close(args *Args_Close, reply *Reply_Close) error {
+ reply.Arg0 = Server_Close(args.Arg0)
+ return nil
+}
+func Client_Close(cli *rpc.Client, Arg0 int) int {
+ var args Args_Close
+ var reply Reply_Close
+ args.Arg0 = Arg0
+ err := cli.Call("RPCRemote.RPCServer_Close", &args, &reply)
+ if err != nil {
+ panic(err)
+ }
+ return reply.Arg0
+}
+
+// wrapper for: Server_Status
+
+type Args_Status struct {
+ Arg0 int
+}
+type Reply_Status struct {
+ Arg0 string
+}
+
+func (r *RPCRemote) RPCServer_Status(args *Args_Status, reply *Reply_Status) error {
+ reply.Arg0 = Server_Status(args.Arg0)
+ return nil
+}
+func Client_Status(cli *rpc.Client, Arg0 int) string {
+ var args Args_Status
+ var reply Reply_Status
+ args.Arg0 = Arg0
+ err := cli.Call("RPCRemote.RPCServer_Status", &args, &reply)
+ if err != nil {
+ panic(err)
+ }
+ return reply.Arg0
+}
+
+// wrapper for: Server_DropCache
+
+type Args_DropCache struct {
+ Arg0 int
+}
+type Reply_DropCache struct {
+ Arg0 int
+}
+
+func (r *RPCRemote) RPCServer_DropCache(args *Args_DropCache, reply *Reply_DropCache) error {
+ reply.Arg0 = Server_DropCache(args.Arg0)
+ return nil
+}
+func Client_DropCache(cli *rpc.Client, Arg0 int) int {
+ var args Args_DropCache
+ var reply Reply_DropCache
+ args.Arg0 = Arg0
+ err := cli.Call("RPCRemote.RPCServer_DropCache", &args, &reply)
+ if err != nil {
+ panic(err)
+ }
+ return reply.Arg0
+}
+
+// wrapper for: Server_Set
+
+type Args_Set struct {
+ Arg0, Arg1 string
+}
+type Reply_Set struct {
+ Arg0 string
+}
+
+func (r *RPCRemote) RPCServer_Set(args *Args_Set, reply *Reply_Set) error {
+ reply.Arg0 = Server_Set(args.Arg0, args.Arg1)
+ return nil
+}
+func Client_Set(cli *rpc.Client, Arg0, Arg1 string) string {
+ var args Args_Set
+ var reply Reply_Set
+ args.Arg0 = Arg0
+ args.Arg1 = Arg1
+ err := cli.Call("RPCRemote.RPCServer_Set", &args, &reply)
+ if err != nil {
+ panic(err)
+ }
+ return reply.Arg0
+}
View
4 server.go
@@ -98,9 +98,9 @@ func Server_DropCache(notused int) int {
}
func Server_Set(key, value string) string {
- if key == "" {
+ if key == "\x00" {
return listConfig(&Config)
- } else if value == "" {
+ } else if value == "\x00" {
return listOption(&Config, key)
}
return setOption(&Config, key, value)
Please sign in to comment.
Something went wrong with that request. Please try again.