From 6e5ef561eb8b4f26430c3e20f4e91f17af3db3ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Tue, 27 Jan 2015 10:11:18 +0100 Subject: [PATCH] Updated Godeps --- Godeps/Godeps.json | 4 - .../github.com/Unknwon/goconfig/.gitignore | 3 - .../src/github.com/Unknwon/goconfig/LICENSE | 191 ------- .../src/github.com/Unknwon/goconfig/README.md | 64 --- .../github.com/Unknwon/goconfig/README_ZH.md | 64 --- .../src/github.com/Unknwon/goconfig/conf.go | 536 ------------------ .../Unknwon/goconfig/goconfig_test.go | 348 ------------ .../src/github.com/Unknwon/goconfig/read.go | 259 --------- .../Unknwon/goconfig/testdata/conf.ini | 46 -- .../Unknwon/goconfig/testdata/conf2.ini | 37 -- .../Unknwon/goconfig/testdata/conf_test.ini | 50 -- .../src/github.com/Unknwon/goconfig/write.go | 108 ---- 12 files changed, 1710 deletions(-) delete mode 100644 Godeps/_workspace/src/github.com/Unknwon/goconfig/.gitignore delete mode 100644 Godeps/_workspace/src/github.com/Unknwon/goconfig/LICENSE delete mode 100644 Godeps/_workspace/src/github.com/Unknwon/goconfig/README.md delete mode 100644 Godeps/_workspace/src/github.com/Unknwon/goconfig/README_ZH.md delete mode 100644 Godeps/_workspace/src/github.com/Unknwon/goconfig/conf.go delete mode 100644 Godeps/_workspace/src/github.com/Unknwon/goconfig/goconfig_test.go delete mode 100644 Godeps/_workspace/src/github.com/Unknwon/goconfig/read.go delete mode 100644 Godeps/_workspace/src/github.com/Unknwon/goconfig/testdata/conf.ini delete mode 100644 Godeps/_workspace/src/github.com/Unknwon/goconfig/testdata/conf2.ini delete mode 100644 Godeps/_workspace/src/github.com/Unknwon/goconfig/testdata/conf_test.ini delete mode 100644 Godeps/_workspace/src/github.com/Unknwon/goconfig/write.go diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index 7bdedf76cba..6c36fb7d9b4 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -9,10 +9,6 @@ "ImportPath": "github.com/Unknwon/com", "Rev": "d9bcf409c8a368d06c9b347705c381e7c12d54df" }, - { - "ImportPath": "github.com/Unknwon/goconfig", - "Rev": "897bf5765c8d23edc846fdab2499a63ae64b6277" - }, { "ImportPath": "github.com/Unknwon/macaron", "Rev": "da7cbddc50b9d33e076fb1eabff13b55c3b85fc5" diff --git a/Godeps/_workspace/src/github.com/Unknwon/goconfig/.gitignore b/Godeps/_workspace/src/github.com/Unknwon/goconfig/.gitignore deleted file mode 100644 index c81d5b37479..00000000000 --- a/Godeps/_workspace/src/github.com/Unknwon/goconfig/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -.DS_Store -*.iml -.idea \ No newline at end of file diff --git a/Godeps/_workspace/src/github.com/Unknwon/goconfig/LICENSE b/Godeps/_workspace/src/github.com/Unknwon/goconfig/LICENSE deleted file mode 100644 index 8405e89a0b1..00000000000 --- a/Godeps/_workspace/src/github.com/Unknwon/goconfig/LICENSE +++ /dev/null @@ -1,191 +0,0 @@ -Apache License -Version 2.0, January 2004 -http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - -"License" shall mean the terms and conditions for use, reproduction, and -distribution as defined by Sections 1 through 9 of this document. - -"Licensor" shall mean the copyright owner or entity authorized by the copyright -owner that is granting the License. - -"Legal Entity" shall mean the union of the acting entity and all other entities -that control, are controlled by, or are under common control with that entity. -For the purposes of this definition, "control" means (i) the power, direct or -indirect, to cause the direction or management of such entity, whether by -contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the -outstanding shares, or (iii) beneficial ownership of such entity. - -"You" (or "Your") shall mean an individual or Legal Entity exercising -permissions granted by this License. - -"Source" form shall mean the preferred form for making modifications, including -but not limited to software source code, documentation source, and configuration -files. - -"Object" form shall mean any form resulting from mechanical transformation or -translation of a Source form, including but not limited to compiled object code, -generated documentation, and conversions to other media types. - -"Work" shall mean the work of authorship, whether in Source or Object form, made -available under the License, as indicated by a copyright notice that is included -in or attached to the work (an example is provided in the Appendix below). - -"Derivative Works" shall mean any work, whether in Source or Object form, that -is based on (or derived from) the Work and for which the editorial revisions, -annotations, elaborations, or other modifications represent, as a whole, an -original work of authorship. For the purposes of this License, Derivative Works -shall not include works that remain separable from, or merely link (or bind by -name) to the interfaces of, the Work and Derivative Works thereof. - -"Contribution" shall mean any work of authorship, including the original version -of the Work and any modifications or additions to that Work or Derivative Works -thereof, that is intentionally submitted to Licensor for inclusion in the Work -by the copyright owner or by an individual or Legal Entity authorized to submit -on behalf of the copyright owner. For the purposes of this definition, -"submitted" means any form of electronic, verbal, or written communication sent -to the Licensor or its representatives, including but not limited to -communication on electronic mailing lists, source code control systems, and -issue tracking systems that are managed by, or on behalf of, the Licensor for -the purpose of discussing and improving the Work, but excluding communication -that is conspicuously marked or otherwise designated in writing by the copyright -owner as "Not a Contribution." - -"Contributor" shall mean Licensor and any individual or Legal Entity on behalf -of whom a Contribution has been received by Licensor and subsequently -incorporated within the Work. - -2. Grant of Copyright License. - -Subject to the terms and conditions of this License, each Contributor hereby -grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, -irrevocable copyright license to reproduce, prepare Derivative Works of, -publicly display, publicly perform, sublicense, and distribute the Work and such -Derivative Works in Source or Object form. - -3. Grant of Patent License. - -Subject to the terms and conditions of this License, each Contributor hereby -grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, -irrevocable (except as stated in this section) patent license to make, have -made, use, offer to sell, sell, import, and otherwise transfer the Work, where -such license applies only to those patent claims licensable by such Contributor -that are necessarily infringed by their Contribution(s) alone or by combination -of their Contribution(s) with the Work to which such Contribution(s) was -submitted. If You institute patent litigation against any entity (including a -cross-claim or counterclaim in a lawsuit) alleging that the Work or a -Contribution incorporated within the Work constitutes direct or contributory -patent infringement, then any patent licenses granted to You under this License -for that Work shall terminate as of the date such litigation is filed. - -4. Redistribution. - -You may reproduce and distribute copies of the Work or Derivative Works thereof -in any medium, with or without modifications, and in Source or Object form, -provided that You meet the following conditions: - -You must give any other recipients of the Work or Derivative Works a copy of -this License; and -You must cause any modified files to carry prominent notices stating that You -changed the files; and -You must retain, in the Source form of any Derivative Works that You distribute, -all copyright, patent, trademark, and attribution notices from the Source form -of the Work, excluding those notices that do not pertain to any part of the -Derivative Works; and -If the Work includes a "NOTICE" text file as part of its distribution, then any -Derivative Works that You distribute must include a readable copy of the -attribution notices contained within such NOTICE file, excluding those notices -that do not pertain to any part of the Derivative Works, in at least one of the -following places: within a NOTICE text file distributed as part of the -Derivative Works; within the Source form or documentation, if provided along -with the Derivative Works; or, within a display generated by the Derivative -Works, if and wherever such third-party notices normally appear. The contents of -the NOTICE file are for informational purposes only and do not modify the -License. You may add Your own attribution notices within Derivative Works that -You distribute, alongside or as an addendum to the NOTICE text from the Work, -provided that such additional attribution notices cannot be construed as -modifying the License. -You may add Your own copyright statement to Your modifications and may provide -additional or different license terms and conditions for use, reproduction, or -distribution of Your modifications, or for any such Derivative Works as a whole, -provided Your use, reproduction, and distribution of the Work otherwise complies -with the conditions stated in this License. - -5. Submission of Contributions. - -Unless You explicitly state otherwise, any Contribution intentionally submitted -for inclusion in the Work by You to the Licensor shall be under the terms and -conditions of this License, without any additional terms or conditions. -Notwithstanding the above, nothing herein shall supersede or modify the terms of -any separate license agreement you may have executed with Licensor regarding -such Contributions. - -6. Trademarks. - -This License does not grant permission to use the trade names, trademarks, -service marks, or product names of the Licensor, except as required for -reasonable and customary use in describing the origin of the Work and -reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. - -Unless required by applicable law or agreed to in writing, Licensor provides the -Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, -including, without limitation, any warranties or conditions of TITLE, -NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are -solely responsible for determining the appropriateness of using or -redistributing the Work and assume any risks associated with Your exercise of -permissions under this License. - -8. Limitation of Liability. - -In no event and under no legal theory, whether in tort (including negligence), -contract, or otherwise, unless required by applicable law (such as deliberate -and grossly negligent acts) or agreed to in writing, shall any Contributor be -liable to You for damages, including any direct, indirect, special, incidental, -or consequential damages of any character arising as a result of this License or -out of the use or inability to use the Work (including but not limited to -damages for loss of goodwill, work stoppage, computer failure or malfunction, or -any and all other commercial damages or losses), even if such Contributor has -been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. - -While redistributing the Work or Derivative Works thereof, You may choose to -offer, and charge a fee for, acceptance of support, warranty, indemnity, or -other liability obligations and/or rights consistent with this License. However, -in accepting such obligations, You may act only on Your own behalf and on Your -sole responsibility, not on behalf of any other Contributor, and only if You -agree to indemnify, defend, and hold each Contributor harmless for any liability -incurred by, or claims asserted against, such Contributor by reason of your -accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work - -To apply the Apache License to your work, attach the following boilerplate -notice, with the fields enclosed by brackets "[]" replaced with your own -identifying information. (Don't include the brackets!) The text should be -enclosed in the appropriate comment syntax for the file format. We also -recommend that a file or class name and description of purpose be included on -the same "printed page" as the copyright notice for easier identification within -third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/Godeps/_workspace/src/github.com/Unknwon/goconfig/README.md b/Godeps/_workspace/src/github.com/Unknwon/goconfig/README.md deleted file mode 100644 index 3081768a096..00000000000 --- a/Godeps/_workspace/src/github.com/Unknwon/goconfig/README.md +++ /dev/null @@ -1,64 +0,0 @@ -goconfig [![Build Status](https://drone.io/github.com/Unknwon/goconfig/status.png)](https://drone.io/github.com/Unknwon/goconfig/latest) [![Go Walker](http://gowalker.org/api/v1/badge)](http://gowalker.org/github.com/Unknwon/goconfig) [![](http://gocover.io/_badge/github.com/Unknwon/goconfig)](http://gocover.io/github.com/Unknwon/goconfig) -======== - -[中文文档](README_ZH.md) - -Code Convention: based on [Go Code Convention](https://github.com/Unknwon/go-code-convention). - -## About - -Package goconfig is a easy-use, comments-support configuration file parser for the Go Programming Language, which provides a structure similar to what you would find on Microsoft Windows INI files. - -The configuration file consists of sections, led by a `[section]` header and followed by `name:value` or `name=value` entries. Note that leading whitespace is removed from values. The optional values can contain format strings which refer to other values in the same section, or values in a special DEFAULT section. Comments are indicated by ";" or "#"; comments may begin anywhere on a single line. - -## Features - -- It simplified operation processes, easy to use and undersatnd; therefore, there are less chances to have errors. -- It uses exactly the same way to access a configuration file as you use Windows APIs, so you don't need to change your code style. -- It supports read recursion sections. -- It supports auto increment of key. -- It supports **READ** and **WRITE** configuration file with comments each section or key which all the other parsers don't support!!!!!!! -- It supports get value through type bool, float64, int, int64 and string, methods that start with "Must" means ignore errors and get zero-value if error occurs, or you can specify a default value. -- It's able to load multiple files to overwrite key values. - -## Installation - - go get github.com/Unknwon/goconfig - -Or - - gopm get github.com/Unknwon/goconfig - -## API Documentation - -[Go Walker](http://gowalker.org/github.com/Unknwon/goconfig). - -## Example - -Please see [conf.ini](testdata/conf.ini) as an example. - -### Usage - -- Function `LoadConfigFile` load file(s) depends on your situation, and return a variable with type `ConfigFile`. -- `GetValue` gives basic functionality of getting a value of given section and key. -- Methods like `Bool`, `Int`, `Int64` return corresponding type of values. -- Methods start with `Must` return corresponding type of values and returns zero-value of given type if something goes wrong. -- `SetValue` sets value to given section and key, and inserts somewhere if it does not exist. -- `DeleteKey` deletes by given section and key. -- Finally, `SaveConfigFile` saves your configuration to local file system. -- Use method `Reload` in case someone else modified your file(s). -- Methods contains `Comment` help you manipulate comments. - -## More Information - -- All characters are CASE SENSITIVE, BE CAREFULL! - -## Credits - -- [goconf](http://code.google.com/p/goconf/) -- [robfig/config](https://github.com/robfig/config) -- [Delete an item from a slice](https://groups.google.com/forum/?fromgroups=#!topic/golang-nuts/lYz8ftASMQ0) - -## License - -This project is under Apache v2 License. See the [LICENSE](LICENSE) file for the full license text. \ No newline at end of file diff --git a/Godeps/_workspace/src/github.com/Unknwon/goconfig/README_ZH.md b/Godeps/_workspace/src/github.com/Unknwon/goconfig/README_ZH.md deleted file mode 100644 index d5fcbb95b68..00000000000 --- a/Godeps/_workspace/src/github.com/Unknwon/goconfig/README_ZH.md +++ /dev/null @@ -1,64 +0,0 @@ -goconfig [![Build Status](https://drone.io/github.com/Unknwon/goconfig/status.png)](https://drone.io/github.com/Unknwon/goconfig/latest) [![Go Walker](http://gowalker.org/api/v1/badge)](http://gowalker.org/github.com/Unknwon/goconfig) -======== - -本库已被 [《Go名库讲解》](https://github.com/Unknwon/go-rock-libraries-showcases/tree/master/lectures/01-goconfig) 收录讲解,欢迎前往学习如何使用! - -编码规范:基于 [Go 编码规范](https://github.com/Unknwon/go-code-convention) - -## 关于 - -包 goconfig 是一个易于使用,支持注释的 Go 语言配置文件解析器,该文件的书写格式和 Windows 下的 INI 文件一样。 - -配置文件由形为 `[section]` 的节构成,内部使用 `name:value` 或 `name=value` 这样的键值对;每行开头和尾部的空白符号都将被忽略;如果未指定任何节,则会默认放入名为 `DEFAULT` 的节当中;可以使用 “;” 或 “#” 来作为注释的开头,并可以放置于任意的单独一行中。 - -## 特性 - -- 简化流程,易于理解,更少出错。 -- 提供与 Windows API 一模一样的操作方式。 -- 支持读取递归节。 -- 支持自增键名。 -- 支持对注释的 **读** 和 **写** 操作,其它所有解析器都不支持!!!! -- 可以直接返回 bool, float64, int, int64 和 string 类型的值,如果使用 “Must” 开头的方法,则一定会返回这个类型的一个值而不返回错误,如果错误发生则会返回零值。 -- 支持加载多个文件来重写值。 - -## 安装 - - go get github.com/Unknwon/goconfig - -或 - - gopm get github.com/Unknwon/goconfig - - -## API 文档 - -[Go Walker](http://gowalker.org/github.com/Unknwon/goconfig). - -## 示例 - -请查看 [conf.ini](testdata/conf.ini) 文件作为使用示例。 - -### 用例 - -- 函数 `LoadConfigFile` 加载一个或多个文件,然后返回一个类型为 `ConfigFile` 的变量。 -- `GetValue` 可以简单的获取某个值。 -- 像 `Bool`、`Int`、`Int64` 这样的方法会直接返回指定类型的值。 -- 以 `Must` 开头的方法不会返回错误,但当错误发生时会返回零值。 -- `SetValue` 可以设置某个值。 -- `DeleteKey` 可以删除某个键。 -- 最后,`SaveConfigFile` 可以保持您的配置到本地文件系统。 -- 使用方法 `Reload` 可以重载您的配置文件。 - -## 更多信息 - -- 所有字符都是大小写敏感的! - -## 参考信息 - -- [goconf](http://code.google.com/p/goconf/) -- [robfig/config](https://github.com/robfig/config) -- [Delete an item from a slice](https://groups.google.com/forum/?fromgroups=#!topic/golang-nuts/lYz8ftASMQ0) - -## 授权许可 - -本项目采用 Apache v2 开源授权许可证,完整的授权说明已放置在 [LICENSE](LICENSE) 文件中。 diff --git a/Godeps/_workspace/src/github.com/Unknwon/goconfig/conf.go b/Godeps/_workspace/src/github.com/Unknwon/goconfig/conf.go deleted file mode 100644 index b48779a2fb4..00000000000 --- a/Godeps/_workspace/src/github.com/Unknwon/goconfig/conf.go +++ /dev/null @@ -1,536 +0,0 @@ -// Copyright 2013 Unknwon -// -// Licensed under the Apache License, Version 2.0 (the "License"): you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -// Package goconfig is a fully functional and comments-support configuration file(.ini) parser. -package goconfig - -import ( - "fmt" - "regexp" - "runtime" - "strconv" - "strings" - "sync" -) - -const ( - // Default section name. - DEFAULT_SECTION = "DEFAULT" - // Maximum allowed depth when recursively substituing variable names. - _DEPTH_VALUES = 200 -) - -type ParseError int - -const ( - ERR_SECTION_NOT_FOUND ParseError = iota + 1 - ERR_KEY_NOT_FOUND - ERR_BLANK_SECTION_NAME - ERR_COULD_NOT_PARSE -) - -var LineBreak = "\n" - -// Variable regexp pattern: %(variable)s -var varPattern = regexp.MustCompile(`%\(([^\)]+)\)s`) - -func init() { - if runtime.GOOS == "windows" { - LineBreak = "\r\n" - } -} - -// A ConfigFile represents a INI formar configuration file. -type ConfigFile struct { - lock sync.RWMutex // Go map is not safe. - fileNames []string // Support mutil-files. - data map[string]map[string]string // Section -> key : value - - // Lists can keep sections and keys in order. - sectionList []string // Section name list. - keyList map[string][]string // Section -> Key name list - - sectionComments map[string]string // Sections comments. - keyComments map[string]map[string]string // Keys comments. - BlockMode bool // Indicates whether use lock or not. -} - -// newConfigFile creates an empty configuration representation. -func newConfigFile(fileNames []string) *ConfigFile { - c := new(ConfigFile) - c.fileNames = fileNames - c.data = make(map[string]map[string]string) - c.keyList = make(map[string][]string) - c.sectionComments = make(map[string]string) - c.keyComments = make(map[string]map[string]string) - c.BlockMode = true - return c -} - -// SetValue adds a new section-key-value to the configuration. -// It returns true if the key and value were inserted, -// or returns false if the value was overwritten. -// If the section does not exist in advance, it will be created. -func (c *ConfigFile) SetValue(section, key, value string) bool { - // Blank section name represents DEFAULT section. - if len(section) == 0 { - section = DEFAULT_SECTION - } - if len(key) == 0 { - return false - } - - if c.BlockMode { - c.lock.Lock() - defer c.lock.Unlock() - } - - // Check if section exists. - if _, ok := c.data[section]; !ok { - // Execute add operation. - c.data[section] = make(map[string]string) - // Append section to list. - c.sectionList = append(c.sectionList, section) - } - - // Check if key exists. - _, ok := c.data[section][key] - c.data[section][key] = value - if !ok { - // If not exists, append to key list. - c.keyList[section] = append(c.keyList[section], key) - } - return !ok -} - -// DeleteKey deletes the key in given section. -// It returns true if the key was deleted, -// or returns false if the section or key didn't exist. -func (c *ConfigFile) DeleteKey(section, key string) bool { - // Blank section name represents DEFAULT section. - if len(section) == 0 { - section = DEFAULT_SECTION - } - - // Check if section exists. - if _, ok := c.data[section]; !ok { - return false - } - - // Check if key exists. - if _, ok := c.data[section][key]; ok { - delete(c.data[section], key) - // Remove comments of key. - c.SetKeyComments(section, key, "") - // Get index of key. - i := 0 - for _, keyName := range c.keyList[section] { - if keyName == key { - break - } - i++ - } - // Remove from key list. - c.keyList[section] = append(c.keyList[section][:i], c.keyList[section][i+1:]...) - return true - } - return false -} - -// GetValue returns the value of key available in the given section. -// If the value needs to be unfolded -// (see e.g. %(google)s example in the GoConfig_test.go), -// then String does this unfolding automatically, up to -// _DEPTH_VALUES number of iterations. -// It returns an error and empty string value if the section does not exist, -// or key does not exist in DEFAULT and current sections. -func (c *ConfigFile) GetValue(section, key string) (string, error) { - if c.BlockMode { - c.lock.RLock() - defer c.lock.RUnlock() - } - - // Blank section name represents DEFAULT section. - if len(section) == 0 { - section = DEFAULT_SECTION - } - - // Check if section exists - if _, ok := c.data[section]; !ok { - // Section does not exist. - return "", getError{ERR_SECTION_NOT_FOUND, section} - } - - // Section exists. - // Check if key exists or empty value. - value, ok := c.data[section][key] - if !ok { - // Check if it is a sub-section. - if i := strings.LastIndex(section, "."); i > -1 { - return c.GetValue(section[:i], key) - } - - // Return empty value. - return "", getError{ERR_KEY_NOT_FOUND, key} - } - - // Key exists. - var i int - for i = 0; i < _DEPTH_VALUES; i++ { - vr := varPattern.FindString(value) - if len(vr) == 0 { - break - } - - // Take off leading '%(' and trailing ')s'. - noption := strings.TrimLeft(vr, "%(") - noption = strings.TrimRight(noption, ")s") - - // Search variable in default section. - nvalue, err := c.GetValue(DEFAULT_SECTION, noption) - if err != nil && section != DEFAULT_SECTION { - // Search in the same section. - if _, ok := c.data[section][noption]; ok { - nvalue = c.data[section][noption] - } - } - - // Substitute by new value and take off leading '%(' and trailing ')s'. - value = strings.Replace(value, vr, nvalue, -1) - } - return value, nil -} - -// Bool returns bool type value. -func (c *ConfigFile) Bool(section, key string) (bool, error) { - value, err := c.GetValue(section, key) - if err != nil { - return false, err - } - return strconv.ParseBool(value) -} - -// Float64 returns float64 type value. -func (c *ConfigFile) Float64(section, key string) (float64, error) { - value, err := c.GetValue(section, key) - if err != nil { - return 0.0, err - } - return strconv.ParseFloat(value, 64) -} - -// Int returns int type value. -func (c *ConfigFile) Int(section, key string) (int, error) { - value, err := c.GetValue(section, key) - if err != nil { - return 0, err - } - return strconv.Atoi(value) -} - -// Int64 returns int64 type value. -func (c *ConfigFile) Int64(section, key string) (int64, error) { - value, err := c.GetValue(section, key) - if err != nil { - return 0, err - } - return strconv.ParseInt(value, 10, 64) -} - -// MustValue always returns value without error. -// It returns empty string if error occurs, or the default value if given. -func (c *ConfigFile) MustValue(section, key string, defaultVal ...string) string { - val, err := c.GetValue(section, key) - if len(defaultVal) > 0 && (err != nil || len(val) == 0) { - return defaultVal[0] - } - return val -} - -// MustValue always returns value without error, -// It returns empty string if error occurs, or the default value if given, -// and a bool value indicates whether default value is returned. -func (c *ConfigFile) MustValueSet(section, key string, defaultVal ...string) (string, bool) { - val, err := c.GetValue(section, key) - if len(defaultVal) > 0 && (err != nil || len(val) == 0) { - c.SetValue(section, key, defaultVal[0]) - return defaultVal[0], true - } - return val, false -} - -// MustValueRange always returns value without error, -// it returns default value if error occurs or doesn't fit into range. -func (c *ConfigFile) MustValueRange(section, key, defaultVal string, candidates []string) string { - val, err := c.GetValue(section, key) - if err != nil || len(val) == 0 { - return defaultVal - } - - for _, cand := range candidates { - if val == cand { - return val - } - } - return defaultVal -} - -// MustValueArray always returns value array without error, -// it returns empty array if error occurs, split by delimiter otherwise. -func (c *ConfigFile) MustValueArray(section, key, delim string) []string { - val, err := c.GetValue(section, key) - if err != nil || len(val) == 0 { - return []string{} - } - - vals := strings.Split(val, delim) - for i := range vals { - vals[i] = strings.TrimSpace(vals[i]) - } - return vals -} - -// MustBool always returns value without error, -// it returns false if error occurs. -func (c *ConfigFile) MustBool(section, key string, defaultVal ...bool) bool { - val, err := c.Bool(section, key) - if len(defaultVal) > 0 && err != nil { - return defaultVal[0] - } - return val -} - -// MustFloat64 always returns value without error, -// it returns 0.0 if error occurs. -func (c *ConfigFile) MustFloat64(section, key string, defaultVal ...float64) float64 { - value, err := c.Float64(section, key) - if len(defaultVal) > 0 && err != nil { - return defaultVal[0] - } - return value -} - -// MustInt always returns value without error, -// it returns 0 if error occurs. -func (c *ConfigFile) MustInt(section, key string, defaultVal ...int) int { - value, err := c.Int(section, key) - if len(defaultVal) > 0 && err != nil { - return defaultVal[0] - } - return value -} - -// MustInt64 always returns value without error, -// it returns 0 if error occurs. -func (c *ConfigFile) MustInt64(section, key string, defaultVal ...int64) int64 { - value, err := c.Int64(section, key) - if len(defaultVal) > 0 && err != nil { - return defaultVal[0] - } - return value -} - -// GetSectionList returns the list of all sections -// in the same order in the file. -func (c *ConfigFile) GetSectionList() []string { - list := make([]string, len(c.sectionList)) - copy(list, c.sectionList) - return list -} - -// GetKeyList returns the list of all keys in give section -// in the same order in the file. -// It returns nil if given section does not exist. -func (c *ConfigFile) GetKeyList(section string) []string { - // Blank section name represents DEFAULT section. - if len(section) == 0 { - section = DEFAULT_SECTION - } - - // Check if section exists. - if _, ok := c.data[section]; !ok { - return nil - } - - // Non-default section has a blank key as section keeper. - offset := 1 - if section == DEFAULT_SECTION { - offset = 0 - } - - list := make([]string, len(c.keyList[section])-offset) - copy(list, c.keyList[section][offset:]) - return list -} - -// DeleteSection deletes the entire section by given name. -// It returns true if the section was deleted, and false if the section didn't exist. -func (c *ConfigFile) DeleteSection(section string) bool { - // Blank section name represents DEFAULT section. - if len(section) == 0 { - section = DEFAULT_SECTION - } - - // Check if section exists. - if _, ok := c.data[section]; !ok { - return false - } - - delete(c.data, section) - // Remove comments of section. - c.SetSectionComments(section, "") - // Get index of section. - i := 0 - for _, secName := range c.sectionList { - if secName == section { - break - } - i++ - } - // Remove from section and key list. - c.sectionList = append(c.sectionList[:i], c.sectionList[i+1:]...) - delete(c.keyList, section) - return true -} - -// GetSection returns key-value pairs in given section. -// It section does not exist, returns nil and error. -func (c *ConfigFile) GetSection(section string) (map[string]string, error) { - // Blank section name represents DEFAULT section. - if len(section) == 0 { - section = DEFAULT_SECTION - } - - // Check if section exists. - if _, ok := c.data[section]; !ok { - // Section does not exist. - return nil, getError{ERR_SECTION_NOT_FOUND, section} - } - - // Remove pre-defined key. - secMap := c.data[section] - delete(c.data[section], " ") - - // Section exists. - return secMap, nil -} - -// SetSectionComments adds new section comments to the configuration. -// If comments are empty(0 length), it will remove its section comments! -// It returns true if the comments were inserted or removed, -// or returns false if the comments were overwritten. -func (c *ConfigFile) SetSectionComments(section, comments string) bool { - // Blank section name represents DEFAULT section. - if len(section) == 0 { - section = DEFAULT_SECTION - } - - if len(comments) == 0 { - if _, ok := c.sectionComments[section]; ok { - delete(c.sectionComments, section) - } - - // Not exists can be seen as remove. - return true - } - - // Check if comments exists. - _, ok := c.sectionComments[section] - if comments[0] != '#' && comments[0] != ';' { - comments = "; " + comments - } - c.sectionComments[section] = comments - return !ok -} - -// SetKeyComments adds new section-key comments to the configuration. -// If comments are empty(0 length), it will remove its section-key comments! -// It returns true if the comments were inserted or removed, -// or returns false if the comments were overwritten. -// If the section does not exist in advance, it is created. -func (c *ConfigFile) SetKeyComments(section, key, comments string) bool { - // Blank section name represents DEFAULT section. - if len(section) == 0 { - section = DEFAULT_SECTION - } - - // Check if section exists. - if _, ok := c.keyComments[section]; ok { - if len(comments) == 0 { - if _, ok := c.keyComments[section][key]; ok { - delete(c.keyComments[section], key) - } - - // Not exists can be seen as remove. - return true - } - } else { - if len(comments) == 0 { - // Not exists can be seen as remove. - return true - } else { - // Execute add operation. - c.keyComments[section] = make(map[string]string) - } - } - - // Check if key exists. - _, ok := c.keyComments[section][key] - if comments[0] != '#' && comments[0] != ';' { - comments = "; " + comments - } - c.keyComments[section][key] = comments - return !ok -} - -// GetSectionComments returns the comments in the given section. -// It returns an empty string(0 length) if the comments do not exist. -func (c *ConfigFile) GetSectionComments(section string) (comments string) { - // Blank section name represents DEFAULT section. - if len(section) == 0 { - section = DEFAULT_SECTION - } - return c.sectionComments[section] -} - -// GetKeyComments returns the comments of key in the given section. -// It returns an empty string(0 length) if the comments do not exist. -func (c *ConfigFile) GetKeyComments(section, key string) (comments string) { - // Blank section name represents DEFAULT section. - if len(section) == 0 { - section = DEFAULT_SECTION - } - - if _, ok := c.keyComments[section]; ok { - return c.keyComments[section][key] - } - return "" -} - -// getError occurs when get value in configuration file with invalid parameter. -type getError struct { - Reason ParseError - Name string -} - -// Error implements Error interface. -func (err getError) Error() string { - switch err.Reason { - case ERR_SECTION_NOT_FOUND: - return fmt.Sprintf("section '%s' not found", err.Name) - case ERR_KEY_NOT_FOUND: - return fmt.Sprintf("key '%s' not found", err.Name) - } - return "invalid get error" -} diff --git a/Godeps/_workspace/src/github.com/Unknwon/goconfig/goconfig_test.go b/Godeps/_workspace/src/github.com/Unknwon/goconfig/goconfig_test.go deleted file mode 100644 index 6128979692c..00000000000 --- a/Godeps/_workspace/src/github.com/Unknwon/goconfig/goconfig_test.go +++ /dev/null @@ -1,348 +0,0 @@ -// Copyright 2013 Unknwon -// -// Licensed under the Apache License, Version 2.0 (the "License"): you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -package goconfig - -import ( - "fmt" - "testing" - - . "github.com/smartystreets/goconvey/convey" -) - -func TestLoadConfigFile(t *testing.T) { - Convey("Load a single configuration file that does exist", t, func() { - c, err := LoadConfigFile("testdata/conf.ini") - So(err, ShouldBeNil) - So(c, ShouldNotBeNil) - - Convey("Test GetSectionList", func() { - So(c.GetSectionList(), ShouldResemble, - []string{"DEFAULT", "Demo", "What's this?", "url", "parent", - "parent.child", "parent.child.child", "auto increment"}) - }) - - Convey("Get value that does exist", func() { - v, err := c.GetValue("Demo", "key2") - So(err, ShouldBeNil) - So(v, ShouldEqual, "test data") - }) - - Convey("Get value that does not exist", func() { - _, err := c.GetValue("Demo", "key4") - So(err, ShouldNotBeNil) - }) - - Convey("Get value that has empty value", func() { - _, err := c.GetValue("What's this?", "empty_value") - So(err, ShouldBeNil) - }) - - Convey("Get value that section does not exist", func() { - _, err := c.GetValue("Demo404", "key4") - So(err, ShouldNotBeNil) - }) - - Convey("Get value use parent-child feature", func() { - v, err := c.GetValue("parent.child", "sex") - So(err, ShouldBeNil) - So(v, ShouldEqual, "male") - }) - - Convey("Get value use recursive feature", func() { - v, err := c.GetValue("", "search") - So(err, ShouldBeNil) - So(v, ShouldEqual, "http://www.google.com") - - v, err = c.GetValue("url", "google_url") - So(err, ShouldBeNil) - So(v, ShouldEqual, "http://www.google.fake") - }) - - Convey("Set value that does exist", func() { - So(c.SetValue("Demo", "key2", "hello man!"), ShouldBeFalse) - v, err := c.GetValue("Demo", "key2") - So(err, ShouldBeNil) - So(v, ShouldEqual, "hello man!") - }) - - Convey("Set value that does not exist", func() { - So(c.SetValue("Demo", "key4", "hello girl!"), ShouldBeTrue) - v, err := c.GetValue("Demo", "key4") - So(err, ShouldBeNil) - So(v, ShouldEqual, "hello girl!") - So(c.SetValue("", "gowalker", "https://gowalker.org"), ShouldBeTrue) - }) - - Convey("Test GetKeyList", func() { - So(c.GetKeyList("Demo"), ShouldResemble, - []string{"key1", "key2", "key3", "quote", "key:1", - "key:2=key:1", "中国", "chinese-var", "array_key"}) - }) - - Convey("Delete a key", func() { - So(c.DeleteKey("", "key404"), ShouldBeFalse) - So(c.DeleteKey("Demo", "key404"), ShouldBeFalse) - So(c.DeleteKey("Demo", "中国"), ShouldBeTrue) - _, err := c.GetValue("Demo", "中国") - So(err, ShouldNotBeNil) - So(c.DeleteKey("404", "key"), ShouldBeFalse) - }) - - Convey("Delete all the keys", func() { - for _, key := range c.GetKeyList("Demo") { - So(c.DeleteKey("Demo", key), ShouldBeTrue) - } - So(c.GetKeyList("Demo"), ShouldResemble, []string{}) - So(len(c.GetKeyList("Demo")), ShouldEqual, 0) - }) - - Convey("Delete section that does not exist", func() { - So(c.DeleteSection(""), ShouldBeTrue) - So(c.DeleteSection("404"), ShouldBeFalse) - }) - - Convey("Get section that exists", func() { - _, err = c.GetSection("") - So(err, ShouldBeNil) - }) - - Convey("Get section that does not exist", func() { - _, err = c.GetSection("404") - So(err, ShouldNotBeNil) - }) - - Convey("Set section comments", func() { - So(c.SetSectionComments("", "default section comments"), ShouldBeTrue) - }) - - Convey("Get section comments", func() { - So(c.GetSectionComments(""), ShouldEqual, "") - }) - - Convey("Set key comments", func() { - So(c.SetKeyComments("", "search", "search comments"), ShouldBeTrue) - So(c.SetKeyComments("404", "search", ""), ShouldBeTrue) - }) - - Convey("Get key comments", func() { - So(c.GetKeyComments("", "google"), ShouldEqual, "; Google") - }) - - Convey("Delete all the sections", func() { - for _, sec := range c.GetSectionList() { - So(c.DeleteSection(sec), ShouldBeTrue) - } - So(c.GetSectionList(), ShouldResemble, []string{}) - So(len(c.GetSectionList()), ShouldEqual, 0) - }) - }) - - Convey("Load a single configuration file that does not exist", t, func() { - _, err := LoadConfigFile("testdata/conf404.ini") - So(err, ShouldNotBeNil) - }) - - Convey("Load multiple configuration files", t, func() { - c, err := LoadConfigFile("testdata/conf.ini", "testdata/conf2.ini") - So(err, ShouldBeNil) - So(c, ShouldNotBeNil) - - Convey("Get value that does not exist in 1st file", func() { - v, err := c.GetValue("new section", "key1") - So(err, ShouldBeNil) - So(v, ShouldEqual, "conf.ini does not have this key") - }) - - Convey("Get value that overwrited in 2nd file", func() { - v, err := c.GetValue("Demo", "key2") - So(err, ShouldBeNil) - So(v, ShouldEqual, "rewrite this key of conf.ini") - }) - }) -} - -func TestGetKeyList(t *testing.T) { - Convey("Get key list", t, func() { - c, err := LoadConfigFile("testdata/conf.ini") - So(err, ShouldBeNil) - So(c, ShouldNotBeNil) - - Convey("Get ket list that does exist", func() { - So(c.GetKeyList("Demo"), ShouldResemble, - []string{"key1", "key2", "key3", "quote", "key:1", - "key:2=key:1", "中国", "chinese-var", "array_key"}) - So(c.GetKeyList(""), ShouldResemble, []string{"google", "search"}) - }) - - Convey("Get key list that not exist", func() { - So(c.GetKeyList("404"), ShouldBeNil) - }) - }) -} - -func TestSaveConfigFile(t *testing.T) { - Convey("Save a ConfigFile to file system", t, func() { - c, err := LoadConfigFile("testdata/conf.ini", "testdata/conf2.ini") - So(err, ShouldBeNil) - So(c, ShouldNotBeNil) - - c.SetValue("", "", "empty") - - So(SaveConfigFile(c, "testdata/conf_test.ini"), ShouldBeNil) - }) -} - -func TestReload(t *testing.T) { - Convey("Reload a configuration file", t, func() { - c, err := LoadConfigFile("testdata/conf.ini", "testdata/conf2.ini") - So(err, ShouldBeNil) - So(c, ShouldNotBeNil) - - So(c.Reload(), ShouldBeNil) - }) -} - -func TestAppendFiles(t *testing.T) { - Convey("Reload a configuration file", t, func() { - c, err := LoadConfigFile("testdata/conf.ini") - So(err, ShouldBeNil) - So(c, ShouldNotBeNil) - - So(c.AppendFiles("testdata/conf2.ini"), ShouldBeNil) - }) -} - -func TestTypes(t *testing.T) { - Convey("Return with types", t, func() { - c, err := LoadConfigFile("testdata/conf.ini") - So(err, ShouldBeNil) - So(c, ShouldNotBeNil) - - Convey("Return bool", func() { - v, err := c.Bool("parent.child", "married") - So(err, ShouldBeNil) - So(v, ShouldBeTrue) - - _, err = c.Bool("parent.child", "died") - So(err, ShouldNotBeNil) - }) - - Convey("Return float64", func() { - v, err := c.Float64("parent", "money") - So(err, ShouldBeNil) - So(v, ShouldEqual, 1.25) - - _, err = c.Float64("parent", "balance") - So(err, ShouldNotBeNil) - }) - - Convey("Return int", func() { - v, err := c.Int("parent", "age") - So(err, ShouldBeNil) - So(v, ShouldEqual, 32) - - _, err = c.Int("parent", "children") - So(err, ShouldNotBeNil) - }) - - Convey("Return int64", func() { - v, err := c.Int64("parent", "age") - So(err, ShouldBeNil) - So(v, ShouldEqual, 32) - - _, err = c.Int64("parent", "children") - So(err, ShouldNotBeNil) - }) - }) -} - -func TestMust(t *testing.T) { - Convey("Must return with type", t, func() { - c, err := LoadConfigFile("testdata/conf.ini") - So(err, ShouldBeNil) - So(c, ShouldNotBeNil) - - Convey("Return string", func() { - So(c.MustValue("parent.child", "name"), ShouldEqual, "john") - So(c.MustValue("parent.child", "died"), ShouldEqual, "") - So(c.MustValue("parent.child", "died", "no"), ShouldEqual, "no") - }) - - Convey("Return string and bool", func() { - val, ok := c.MustValueSet("parent.child", "died") - So(val, ShouldEqual, "") - So(ok, ShouldBeFalse) - val, ok = c.MustValueSet("parent.child", "died", "no") - So(val, ShouldEqual, "no") - So(ok, ShouldBeTrue) - }) - - Convey("Return bool", func() { - So(c.MustBool("parent.child", "married"), ShouldBeTrue) - So(c.MustBool("parent.child", "died"), ShouldBeFalse) - So(c.MustBool("parent.child", "died", true), ShouldBeTrue) - }) - - Convey("Return float64", func() { - So(c.MustFloat64("parent", "money"), ShouldEqual, 1.25) - So(c.MustFloat64("parent", "balance"), ShouldEqual, 0.0) - So(c.MustFloat64("parent", "balance", 1.25), ShouldEqual, 1.25) - }) - - Convey("Return int", func() { - So(c.MustInt("parent", "age"), ShouldEqual, 32) - So(c.MustInt("parent", "children"), ShouldEqual, 0) - So(c.MustInt("parent", "children", 3), ShouldEqual, 3) - }) - - Convey("Return int64", func() { - So(c.MustInt64("parent", "age"), ShouldEqual, 32) - So(c.MustInt64("parent", "children"), ShouldEqual, 0) - So(c.MustInt64("parent", "children", 3), ShouldEqual, 3) - }) - }) -} - -func TestRange(t *testing.T) { - Convey("Must return with range", t, func() { - c, err := LoadConfigFile("testdata/conf.ini") - So(err, ShouldBeNil) - So(c, ShouldNotBeNil) - - So(c.MustValueRange("What's this?", "name", "joe", []string{"hello"}), ShouldEqual, "joe") - So(c.MustValueRange("What's this?", "name404", "joe", []string{"hello"}), ShouldEqual, "joe") - So(c.MustValueRange("What's this?", "name", "joe", []string{"hello", "try one more value ^-^"}), - ShouldEqual, "try one more value ^-^") - }) -} - -func TestArray(t *testing.T) { - Convey("Must return with string array", t, func() { - c, err := LoadConfigFile("testdata/conf.ini") - So(err, ShouldBeNil) - So(c, ShouldNotBeNil) - - So(fmt.Sprintf("%s", c.MustValueArray("Demo", "array_key", ",")), ShouldEqual, "[1 2 3 4 5]") - So(fmt.Sprintf("%s", c.MustValueArray("Demo", "array_key404", ",")), ShouldEqual, "[]") - }) -} - -func TestLoadFromData(t *testing.T) { - Convey("Load config file from data", t, func() { - c, err := LoadFromData([]byte("")) - So(err, ShouldBeNil) - So(c, ShouldNotBeNil) - }) -} diff --git a/Godeps/_workspace/src/github.com/Unknwon/goconfig/read.go b/Godeps/_workspace/src/github.com/Unknwon/goconfig/read.go deleted file mode 100644 index ac78929094a..00000000000 --- a/Godeps/_workspace/src/github.com/Unknwon/goconfig/read.go +++ /dev/null @@ -1,259 +0,0 @@ -// Copyright 2013 Unknwon -// -// Licensed under the Apache License, Version 2.0 (the "License"): you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -package goconfig - -import ( - "bufio" - "bytes" - "fmt" - "io" - "io/ioutil" - "os" - "path" - "strings" - "time" -) - -// Read reads an io.Reader and returns a configuration representation. -// This representation can be queried with GetValue. -func (c *ConfigFile) read(reader io.Reader) (err error) { - buf := bufio.NewReader(reader) - - // Handle BOM-UTF8. - // http://en.wikipedia.org/wiki/Byte_order_mark#Representations_of_byte_order_marks_by_encoding - mask, err := buf.Peek(3) - if err == nil && len(mask) >= 3 && - mask[0] == 239 && mask[1] == 187 && mask[2] == 191 { - buf.Read(mask) - } - - count := 1 // Counter for auto increment. - // Current section name. - section := DEFAULT_SECTION - var comments string - // Parse line-by-line - for { - line, err := buf.ReadString('\n') - line = strings.TrimSpace(line) - lineLengh := len(line) //[SWH|+] - if err != nil { - if err != io.EOF { - return err - } - - // Reached end of file, if nothing to read then break, - // otherwise handle the last line. - if lineLengh == 0 { - break - } - } - - // switch written for readability (not performance) - switch { - case lineLengh == 0: // Empty line - continue - case line[0] == '#' || line[0] == ';': // Comment - // Append comments - if len(comments) == 0 { - comments = line - } else { - comments += LineBreak + line - } - continue - case line[0] == '[' && line[lineLengh-1] == ']': // New sction. - // Get section name. - section = strings.TrimSpace(line[1 : lineLengh-1]) - // Set section comments and empty if it has comments. - if len(comments) > 0 { - c.SetSectionComments(section, comments) - comments = "" - } - // Make section exist even though it does not have any key. - c.SetValue(section, " ", " ") - // Reset counter. - count = 1 - continue - case section == "": // No section defined so far - return readError{ERR_BLANK_SECTION_NAME, line} - default: // Other alternatives - var ( - i int - keyQuote string - key string - valQuote string - value string - ) - //[SWH|+]:支持引号包围起来的字串 - if line[0] == '"' { - if lineLengh >= 6 && line[0:3] == `"""` { - keyQuote = `"""` - } else { - keyQuote = `"` - } - } else if line[0] == '`' { - keyQuote = "`" - } - if keyQuote != "" { - qLen := len(keyQuote) - pos := strings.Index(line[qLen:], keyQuote) - if pos == -1 { - return readError{ERR_COULD_NOT_PARSE, line} - } - pos = pos + qLen - i = strings.IndexAny(line[pos:], "=:") - if i <= 0 { - return readError{ERR_COULD_NOT_PARSE, line} - } - i = i + pos - key = line[qLen:pos] //保留引号内的两端的空格 - } else { - i = strings.IndexAny(line, "=:") - if i <= 0 { - return readError{ERR_COULD_NOT_PARSE, line} - } - key = strings.TrimSpace(line[0:i]) - } - //[SWH|+]; - - // Check if it needs auto increment. - if key == "-" { - key = "#" + fmt.Sprint(count) - count++ - } - - //[SWH|+]:支持引号包围起来的字串 - lineRight := strings.TrimSpace(line[i+1:]) - lineRightLength := len(lineRight) - firstChar := "" - if lineRightLength >= 2 { - firstChar = lineRight[0:1] - } - if firstChar == "`" { - valQuote = "`" - } else if lineRightLength >= 6 && lineRight[0:3] == `"""` { - valQuote = `"""` - } - if valQuote != "" { - qLen := len(valQuote) - pos := strings.LastIndex(lineRight[qLen:], valQuote) - if pos == -1 { - return readError{ERR_COULD_NOT_PARSE, line} - } - pos = pos + qLen - value = lineRight[qLen:pos] - } else { - value = strings.TrimSpace(lineRight[0:]) - } - //[SWH|+]; - - c.SetValue(section, key, value) - // Set key comments and empty if it has comments. - if len(comments) > 0 { - c.SetKeyComments(section, key, comments) - comments = "" - } - } - - // Reached end of file. - if err == io.EOF { - break - } - } - return nil -} - -// LoadFromData accepts raw data directly from memory -// and returns a new configuration representation. -func LoadFromData(data []byte) (c *ConfigFile, err error) { - // Save memory data to temporary file to support further operations. - tmpName := path.Join(os.TempDir(), "goconfig", fmt.Sprintf("%d", time.Now().Nanosecond())) - os.MkdirAll(path.Dir(tmpName), os.ModePerm) - if err = ioutil.WriteFile(tmpName, data, 0655); err != nil { - return nil, err - } - - c = newConfigFile([]string{tmpName}) - err = c.read(bytes.NewBuffer(data)) - return c, err -} - -func (c *ConfigFile) loadFile(fileName string) (err error) { - f, err := os.Open(fileName) - if err != nil { - return err - } - defer f.Close() - - return c.read(f) -} - -// LoadConfigFile reads a file and returns a new configuration representation. -// This representation can be queried with GetValue. -func LoadConfigFile(fileName string, moreFiles ...string) (c *ConfigFile, err error) { - // Append files' name together. - fileNames := make([]string, 1, len(moreFiles)+1) - fileNames[0] = fileName - if len(moreFiles) > 0 { - fileNames = append(fileNames, moreFiles...) - } - - c = newConfigFile(fileNames) - - for _, name := range fileNames { - if err = c.loadFile(name); err != nil { - return nil, err - } - } - - return c, nil -} - -// Reload reloads configuration file in case it has changes. -func (c *ConfigFile) Reload() (err error) { - var cfg *ConfigFile - if len(c.fileNames) == 1 { - cfg, err = LoadConfigFile(c.fileNames[0]) - } else { - cfg, err = LoadConfigFile(c.fileNames[0], c.fileNames[1:]...) - } - - if err == nil { - *c = *cfg - } - return err -} - -// AppendFiles appends more files to ConfigFile and reload automatically. -func (c *ConfigFile) AppendFiles(files ...string) error { - c.fileNames = append(c.fileNames, files...) - return c.Reload() -} - -// readError occurs when read configuration file with wrong format. -type readError struct { - Reason ParseError - Content string // Line content -} - -// Error implement Error interface. -func (err readError) Error() string { - switch err.Reason { - case ERR_BLANK_SECTION_NAME: - return "empty section name not allowed" - case ERR_COULD_NOT_PARSE: - return fmt.Sprintf("could not parse line: %s", string(err.Content)) - } - return "invalid read error" -} diff --git a/Godeps/_workspace/src/github.com/Unknwon/goconfig/testdata/conf.ini b/Godeps/_workspace/src/github.com/Unknwon/goconfig/testdata/conf.ini deleted file mode 100644 index 65ab1da7c36..00000000000 --- a/Godeps/_workspace/src/github.com/Unknwon/goconfig/testdata/conf.ini +++ /dev/null @@ -1,46 +0,0 @@ -; Google -google = www.google.com -search = http://%(google)s - -; Here are Comments -; Second line -[Demo] -# This symbol can also make this line to be comments -key1 = Let's us goconfig!!! -key2 = test data -key3 = this is based on key2:%(key2)s -quote = "special case for quote -"key:1" = This is the value of "key:1" -"key:2=key:1" = this is based on "key:2=key:1" => %(key:1)s -中国 = China -chinese-var = hello %(中国)s! -array_key = 1,2,3,4,5 - -[What's this?] -; Not Enough Comments!! -name = try one more value ^-^ -empty_value = - -[url] -google_fake = www.google.fake -google_url = http://%(google_fake)s - -[parent] -name = john -relation = father -sex = male -age = 32 -money = 1.25 - -[parent.child] -age = 3 -married = true - -[parent.child.child] - -; Auto increment by setting key to "-" -[auto increment] -- = hello -- = go -- = config - diff --git a/Godeps/_workspace/src/github.com/Unknwon/goconfig/testdata/conf2.ini b/Godeps/_workspace/src/github.com/Unknwon/goconfig/testdata/conf2.ini deleted file mode 100644 index d5635bb6b8e..00000000000 --- a/Godeps/_workspace/src/github.com/Unknwon/goconfig/testdata/conf2.ini +++ /dev/null @@ -1,37 +0,0 @@ -; Google -google = www.google.com -search = http://%(google)s - -; Here are Comments -; Second line -[Demo] -# This symbol can also make this line to be comments -key1 = Let's us goconfig!!! -key2 = rewrite this key of conf.ini -key3 = this is based on key2:%(key2)s -"key:1" = This is the value of "key:1" -"""key:2"""="""this is based on "key:1" => `%(key:1)s`""" - -[What's this?] -; Not Enough Comments!! -name = try one more value ^-^ - -[parent] -name = john -relation = father -sex = male -age = 32 - -[parent.child] -age = 3 - -[parent.child.child] - -; Auto increment by setting key to "-" -[auto increment] -- = hello -- = go -- = config - -[new section] -key1 = conf.ini does not have this key \ No newline at end of file diff --git a/Godeps/_workspace/src/github.com/Unknwon/goconfig/testdata/conf_test.ini b/Godeps/_workspace/src/github.com/Unknwon/goconfig/testdata/conf_test.ini deleted file mode 100644 index 769d6561969..00000000000 --- a/Godeps/_workspace/src/github.com/Unknwon/goconfig/testdata/conf_test.ini +++ /dev/null @@ -1,50 +0,0 @@ -; Google -google = www.google.com -search = http://%(google)s - -; Here are Comments -; Second line -[Demo] -# This symbol can also make this line to be comments -key1 = Let's us goconfig!!! -key2 = rewrite this key of conf.ini -key3 = this is based on key2:%(key2)s -quote = "special case for quote -`key:1` = This is the value of "key:1" -`key:2=key:1` = this is based on "key:2=key:1" => %(key:1)s -中国 = China -chinese-var = hello %(中国)s! -array_key = 1,2,3,4,5 -`key:2` = """this is based on "key:1" => `%(key:1)s`""" - -[What's this?] -; Not Enough Comments!! -name = try one more value ^-^ -empty_value = - -[url] -google_fake = www.google.fake -google_url = http://%(google_fake)s - -[parent] -name = john -relation = father -sex = male -age = 32 -money = 1.25 - -[parent.child] -age = 3 -married = true - -[parent.child.child] - -; Auto increment by setting key to "-" -[auto increment] -- = hello -- = go -- = config - -[new section] -key1 = conf.ini does not have this key - diff --git a/Godeps/_workspace/src/github.com/Unknwon/goconfig/write.go b/Godeps/_workspace/src/github.com/Unknwon/goconfig/write.go deleted file mode 100644 index 385d51647b0..00000000000 --- a/Godeps/_workspace/src/github.com/Unknwon/goconfig/write.go +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright 2013 Unknwon -// -// Licensed under the Apache License, Version 2.0 (the "License"): you may -// not use this file except in compliance with the License. You may obtain -// a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations -// under the License. - -package goconfig - -import ( - "bytes" - "os" - "strings" -) - -// Write spaces around "=" to look better. -var PrettyFormat = true - -// SaveConfigFile writes configuration file to local file system -func SaveConfigFile(c *ConfigFile, filename string) (err error) { - // Write configuration file by filename. - var f *os.File - if f, err = os.Create(filename); err != nil { - return err - } - - equalSign := "=" - if PrettyFormat { - equalSign = " = " - } - - buf := bytes.NewBuffer(nil) - for _, section := range c.sectionList { - // Write section comments. - if len(c.GetSectionComments(section)) > 0 { - if _, err = buf.WriteString(c.GetSectionComments(section) + LineBreak); err != nil { - return err - } - } - - if section != DEFAULT_SECTION { - // Write section name. - if _, err = buf.WriteString("[" + section + "]" + LineBreak); err != nil { - return err - } - } - - for _, key := range c.keyList[section] { - if key != " " { - // Write key comments. - if len(c.GetKeyComments(section, key)) > 0 { - if _, err = buf.WriteString(c.GetKeyComments(section, key) + LineBreak); err != nil { - return err - } - } - - keyName := key - // Check if it's auto increment. - if keyName[0] == '#' { - keyName = "-" - } - //[SWH|+]:支持键名包含等号和冒号 - if strings.Contains(keyName, `=`) || strings.Contains(keyName, `:`) { - if strings.Contains(keyName, "`") { - if strings.Contains(keyName, `"`) { - keyName = `"""` + keyName + `"""` - } else { - keyName = `"` + keyName + `"` - } - } else { - keyName = "`" + keyName + "`" - } - } - value := c.data[section][key] - // In case key value contains "`" or "\"". - if strings.Contains(value, "`") { - if strings.Contains(value, `"`) { - value = `"""` + value + `"""` - } else { - value = `"` + value + `"` - } - } - - // Write key and value. - if _, err = buf.WriteString(keyName + equalSign + value + LineBreak); err != nil { - return err - } - } - } - - // Put a line between sections. - if _, err = buf.WriteString(LineBreak); err != nil { - return err - } - } - - if _, err = buf.WriteTo(f); err != nil { - return err - } - return f.Close() -}