migrate to go modules from vndr
Signed-off-by: Tariq Ibrahim <tariq181290@gmail.com>
This commit is contained in:
parent
dcfe05ce6c
commit
5223c27422
503 changed files with 273730 additions and 9491 deletions
5
vendor/github.com/go-ini/ini/.gitignore
generated
vendored
Normal file
5
vendor/github.com/go-ini/ini/.gitignore
generated
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
testdata/conf_out.ini
|
||||
ini.sublime-project
|
||||
ini.sublime-workspace
|
||||
testdata/conf_reflect.ini
|
||||
.idea
|
17
vendor/github.com/go-ini/ini/.travis.yml
generated
vendored
Normal file
17
vendor/github.com/go-ini/ini/.travis.yml
generated
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
sudo: false
|
||||
language: go
|
||||
go:
|
||||
- 1.4.x
|
||||
- 1.5.x
|
||||
- 1.6.x
|
||||
- 1.7.x
|
||||
- master
|
||||
|
||||
script:
|
||||
- go get golang.org/x/tools/cmd/cover
|
||||
- go get github.com/smartystreets/goconvey
|
||||
- go test -v -cover -race
|
||||
|
||||
notifications:
|
||||
email:
|
||||
- u@gogs.io
|
12
vendor/github.com/go-ini/ini/Makefile
generated
vendored
Normal file
12
vendor/github.com/go-ini/ini/Makefile
generated
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
.PHONY: build test bench vet
|
||||
|
||||
build: vet bench
|
||||
|
||||
test:
|
||||
go test -v -cover -race
|
||||
|
||||
bench:
|
||||
go test -v -cover -race -test.bench=. -test.benchmem
|
||||
|
||||
vet:
|
||||
go vet
|
41
vendor/github.com/go-ini/ini/README.md
generated
vendored
41
vendor/github.com/go-ini/ini/README.md
generated
vendored
|
@ -1,4 +1,4 @@
|
|||
INI [](https://travis-ci.org/go-ini/ini)
|
||||
INI [](https://travis-ci.org/go-ini/ini) [](https://sourcegraph.com/github.com/go-ini/ini?badge)
|
||||
===
|
||||
|
||||

|
||||
|
@ -9,7 +9,7 @@ Package ini provides INI file read and write functionality in Go.
|
|||
|
||||
## Feature
|
||||
|
||||
- Load multiple data sources(`[]byte` or file) with overwrites.
|
||||
- Load multiple data sources(`[]byte`, file and `io.ReadCloser`) with overwrites.
|
||||
- Read with recursion values.
|
||||
- Read with parent-child sections.
|
||||
- Read with auto-increment key names.
|
||||
|
@ -44,10 +44,10 @@ Please add `-u` flag to update in the future.
|
|||
|
||||
### Loading from data sources
|
||||
|
||||
A **Data Source** is either raw data in type `[]byte` or a file name with type `string` and you can load **as many data sources as you want**. Passing other types will simply return an error.
|
||||
A **Data Source** is either raw data in type `[]byte`, a file name with type `string` or `io.ReadCloser`. You can load **as many data sources as you want**. Passing other types will simply return an error.
|
||||
|
||||
```go
|
||||
cfg, err := ini.Load([]byte("raw data"), "filename")
|
||||
cfg, err := ini.Load([]byte("raw data"), "filename", ioutil.NopCloser(bytes.NewReader([]byte("some other data"))))
|
||||
```
|
||||
|
||||
Or start with an empty object:
|
||||
|
@ -106,6 +106,22 @@ cfg, err := LoadSources(LoadOptions{AllowBooleanKeys: true}, "my.cnf"))
|
|||
|
||||
The value of those keys are always `true`, and when you save to a file, it will keep in the same foramt as you read.
|
||||
|
||||
To generate such keys in your program, you could use `NewBooleanKey`:
|
||||
|
||||
```go
|
||||
key, err := sec.NewBooleanKey("skip-host-cache")
|
||||
```
|
||||
|
||||
#### Comment
|
||||
|
||||
Take care that following format will be treated as comment:
|
||||
|
||||
1. Line begins with `#` or `;`
|
||||
2. Words after `#` or `;`
|
||||
3. Words after section name (i.e words after `[some section name]`)
|
||||
|
||||
If you want to save a value with `#` or `;`, please quote them with ``` ` ``` or ``` """ ```.
|
||||
|
||||
### Working with sections
|
||||
|
||||
To get a section, you would need to:
|
||||
|
@ -123,7 +139,7 @@ section, err := cfg.GetSection("")
|
|||
When you're pretty sure the section exists, following code could make your life easier:
|
||||
|
||||
```go
|
||||
section := cfg.Section("")
|
||||
section := cfg.Section("section name")
|
||||
```
|
||||
|
||||
What happens when the section somehow does not exist? Don't panic, it automatically creates and returns a new section to you.
|
||||
|
@ -453,6 +469,21 @@ cfg.Section("package.sub").Key("CLONE_URL").String() // https://gopkg.in/ini.v1
|
|||
cfg.Section("package.sub").ParentKeys() // ["CLONE_URL"]
|
||||
```
|
||||
|
||||
### Unparseable Sections
|
||||
|
||||
Sometimes, you have sections that do not contain key-value pairs but raw content, to handle such case, you can use `LoadOptions.UnparsableSections`:
|
||||
|
||||
```go
|
||||
cfg, err := LoadSources(LoadOptions{UnparseableSections: []string{"COMMENTS"}}, `[COMMENTS]
|
||||
<1><L.Slide#2> This slide has the fuel listed in the wrong units <e.1>`))
|
||||
|
||||
body := cfg.Section("COMMENTS").Body()
|
||||
|
||||
/* --- start ---
|
||||
<1><L.Slide#2> This slide has the fuel listed in the wrong units <e.1>
|
||||
------ end --- */
|
||||
```
|
||||
|
||||
### Auto-increment Key Names
|
||||
|
||||
If key name is `-` in data source, then it would be seen as special syntax for auto-increment key name start from 1, and every section is independent on counter.
|
||||
|
|
47
vendor/github.com/go-ini/ini/README_ZH.md
generated
vendored
47
vendor/github.com/go-ini/ini/README_ZH.md
generated
vendored
|
@ -2,7 +2,7 @@
|
|||
|
||||
## 功能特性
|
||||
|
||||
- 支持覆盖加载多个数据源(`[]byte` 或文件)
|
||||
- 支持覆盖加载多个数据源(`[]byte`、文件和 `io.ReadCloser`)
|
||||
- 支持递归读取键值
|
||||
- 支持读取父子分区
|
||||
- 支持读取自增键名
|
||||
|
@ -37,10 +37,10 @@
|
|||
|
||||
### 从数据源加载
|
||||
|
||||
一个 **数据源** 可以是 `[]byte` 类型的原始数据,或 `string` 类型的文件路径。您可以加载 **任意多个** 数据源。如果您传递其它类型的数据源,则会直接返回错误。
|
||||
一个 **数据源** 可以是 `[]byte` 类型的原始数据,`string` 类型的文件路径或 `io.ReadCloser`。您可以加载 **任意多个** 数据源。如果您传递其它类型的数据源,则会直接返回错误。
|
||||
|
||||
```go
|
||||
cfg, err := ini.Load([]byte("raw data"), "filename")
|
||||
cfg, err := ini.Load([]byte("raw data"), "filename", ioutil.NopCloser(bytes.NewReader([]byte("some other data"))))
|
||||
```
|
||||
|
||||
或者从一个空白的文件开始:
|
||||
|
@ -99,6 +99,22 @@ cfg, err := LoadSources(LoadOptions{AllowBooleanKeys: true}, "my.cnf"))
|
|||
|
||||
这些键的值永远为 `true`,且在保存到文件时也只会输出键名。
|
||||
|
||||
如果您想要通过程序来生成此类键,则可以使用 `NewBooleanKey`:
|
||||
|
||||
```go
|
||||
key, err := sec.NewBooleanKey("skip-host-cache")
|
||||
```
|
||||
|
||||
#### 关于注释
|
||||
|
||||
下述几种情况的内容将被视为注释:
|
||||
|
||||
1. 所有以 `#` 或 `;` 开头的行
|
||||
2. 所有在 `#` 或 `;` 之后的内容
|
||||
3. 分区标签后的文字 (即 `[分区名]` 之后的内容)
|
||||
|
||||
如果你希望使用包含 `#` 或 `;` 的值,请使用 ``` ` ``` 或 ``` """ ``` 进行包覆。
|
||||
|
||||
### 操作分区(Section)
|
||||
|
||||
获取指定分区:
|
||||
|
@ -116,7 +132,7 @@ section, err := cfg.GetSection("")
|
|||
当您非常确定某个分区是存在的,可以使用以下简便方法:
|
||||
|
||||
```go
|
||||
section := cfg.Section("")
|
||||
section := cfg.Section("section name")
|
||||
```
|
||||
|
||||
如果不小心判断错了,要获取的分区其实是不存在的,那会发生什么呢?没事的,它会自动创建并返回一个对应的分区对象给您。
|
||||
|
@ -399,9 +415,9 @@ cfg.WriteToIndent(writer, "\t")
|
|||
ini.PrettyFormat = false
|
||||
```
|
||||
|
||||
### 高级用法
|
||||
## 高级用法
|
||||
|
||||
#### 递归读取键值
|
||||
### 递归读取键值
|
||||
|
||||
在获取所有键值的过程中,特殊语法 `%(<name>)s` 会被应用,其中 `<name>` 可以是相同分区或者默认分区下的键名。字符串 `%(<name>)s` 会被相应的键值所替代,如果指定的键不存在,则会用空字符串替代。您可以最多使用 99 层的递归嵌套。
|
||||
|
||||
|
@ -421,7 +437,7 @@ cfg.Section("author").Key("GITHUB").String() // https://github.com/Unknwon
|
|||
cfg.Section("package").Key("FULL_NAME").String() // github.com/go-ini/ini
|
||||
```
|
||||
|
||||
#### 读取父子分区
|
||||
### 读取父子分区
|
||||
|
||||
您可以在分区名称中使用 `.` 来表示两个或多个分区之间的父子关系。如果某个键在子分区中不存在,则会去它的父分区中再次寻找,直到没有父分区为止。
|
||||
|
||||
|
@ -446,7 +462,22 @@ cfg.Section("package.sub").Key("CLONE_URL").String() // https://gopkg.in/ini.v1
|
|||
cfg.Section("package.sub").ParentKeys() // ["CLONE_URL"]
|
||||
```
|
||||
|
||||
#### 读取自增键名
|
||||
### 无法解析的分区
|
||||
|
||||
如果遇到一些比较特殊的分区,它们不包含常见的键值对,而是没有固定格式的纯文本,则可以使用 `LoadOptions.UnparsableSections` 进行处理:
|
||||
|
||||
```go
|
||||
cfg, err := LoadSources(LoadOptions{UnparseableSections: []string{"COMMENTS"}}, `[COMMENTS]
|
||||
<1><L.Slide#2> This slide has the fuel listed in the wrong units <e.1>`))
|
||||
|
||||
body := cfg.Section("COMMENTS").Body()
|
||||
|
||||
/* --- start ---
|
||||
<1><L.Slide#2> This slide has the fuel listed in the wrong units <e.1>
|
||||
------ end --- */
|
||||
```
|
||||
|
||||
### 读取自增键名
|
||||
|
||||
如果数据源中的键名为 `-`,则认为该键使用了自增键名的特殊语法。计数器从 1 开始,并且分区之间是相互独立的。
|
||||
|
||||
|
|
90
vendor/github.com/go-ini/ini/ini.go
generated
vendored
90
vendor/github.com/go-ini/ini/ini.go
generated
vendored
|
@ -20,6 +20,7 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"regexp"
|
||||
"runtime"
|
||||
|
@ -36,7 +37,7 @@ const (
|
|||
|
||||
// Maximum allowed depth when recursively substituing variable names.
|
||||
_DEPTH_VALUES = 99
|
||||
_VERSION = "1.21.1"
|
||||
_VERSION = "1.25.4"
|
||||
)
|
||||
|
||||
// Version returns current package version literal.
|
||||
|
@ -108,7 +109,16 @@ type sourceData struct {
|
|||
}
|
||||
|
||||
func (s *sourceData) ReadCloser() (io.ReadCloser, error) {
|
||||
return &bytesReadCloser{bytes.NewReader(s.data)}, nil
|
||||
return ioutil.NopCloser(bytes.NewReader(s.data)), nil
|
||||
}
|
||||
|
||||
// sourceReadCloser represents an input stream with Close method.
|
||||
type sourceReadCloser struct {
|
||||
reader io.ReadCloser
|
||||
}
|
||||
|
||||
func (s *sourceReadCloser) ReadCloser() (io.ReadCloser, error) {
|
||||
return s.reader, nil
|
||||
}
|
||||
|
||||
// File represents a combination of a or more INI file(s) in memory.
|
||||
|
@ -149,6 +159,8 @@ func parseDataSource(source interface{}) (dataSource, error) {
|
|||
return sourceFile{s}, nil
|
||||
case []byte:
|
||||
return &sourceData{s}, nil
|
||||
case io.ReadCloser:
|
||||
return &sourceReadCloser{s}, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("error parsing data source: unknown type '%s'", s)
|
||||
}
|
||||
|
@ -164,6 +176,11 @@ type LoadOptions struct {
|
|||
// AllowBooleanKeys indicates whether to allow boolean type keys or treat as value is missing.
|
||||
// This type of keys are mostly used in my.cnf.
|
||||
AllowBooleanKeys bool
|
||||
// AllowShadows indicates whether to keep track of keys with same name under same section.
|
||||
AllowShadows bool
|
||||
// Some INI formats allow group blocks that store a block of raw content that doesn't otherwise
|
||||
// conform to key/value pairs. Specify the names of those blocks here.
|
||||
UnparseableSections []string
|
||||
}
|
||||
|
||||
func LoadSources(opts LoadOptions, source interface{}, others ...interface{}) (_ *File, err error) {
|
||||
|
@ -204,6 +221,12 @@ func InsensitiveLoad(source interface{}, others ...interface{}) (*File, error) {
|
|||
return LoadSources(LoadOptions{Insensitive: true}, source, others...)
|
||||
}
|
||||
|
||||
// InsensitiveLoad has exactly same functionality as Load function
|
||||
// except it allows have shadow keys.
|
||||
func ShadowLoad(source interface{}, others ...interface{}) (*File, error) {
|
||||
return LoadSources(LoadOptions{AllowShadows: true}, source, others...)
|
||||
}
|
||||
|
||||
// Empty returns an empty file object.
|
||||
func Empty() *File {
|
||||
// Ignore error here, we sure our data is good.
|
||||
|
@ -233,6 +256,18 @@ func (f *File) NewSection(name string) (*Section, error) {
|
|||
return f.sections[name], nil
|
||||
}
|
||||
|
||||
// NewRawSection creates a new section with an unparseable body.
|
||||
func (f *File) NewRawSection(name, body string) (*Section, error) {
|
||||
section, err := f.NewSection(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
section.isRawSection = true
|
||||
section.rawBody = body
|
||||
return section, nil
|
||||
}
|
||||
|
||||
// NewSections creates a list of sections.
|
||||
func (f *File) NewSections(names ...string) (err error) {
|
||||
for _, name := range names {
|
||||
|
@ -386,6 +421,13 @@ func (f *File) WriteToIndent(w io.Writer, indent string) (n int64, err error) {
|
|||
}
|
||||
}
|
||||
|
||||
if sec.isRawSection {
|
||||
if _, err = buf.WriteString(sec.rawBody); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
// Count and generate alignment length and buffer spaces using the
|
||||
// longest key. Keys may be modifed if they contain certain characters so
|
||||
// we need to take that into account in our calculation.
|
||||
|
@ -407,6 +449,7 @@ func (f *File) WriteToIndent(w io.Writer, indent string) (n int64, err error) {
|
|||
}
|
||||
alignSpaces := bytes.Repeat([]byte(" "), alignLength)
|
||||
|
||||
KEY_LIST:
|
||||
for _, kname := range sec.keyList {
|
||||
key := sec.Key(kname)
|
||||
if len(key.Comment) > 0 {
|
||||
|
@ -433,28 +476,33 @@ func (f *File) WriteToIndent(w io.Writer, indent string) (n int64, err error) {
|
|||
case strings.Contains(kname, "`"):
|
||||
kname = `"""` + kname + `"""`
|
||||
}
|
||||
if _, err = buf.WriteString(kname); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if key.isBooleanType {
|
||||
continue
|
||||
}
|
||||
for _, val := range key.ValueWithShadows() {
|
||||
if _, err = buf.WriteString(kname); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// Write out alignment spaces before "=" sign
|
||||
if PrettyFormat {
|
||||
buf.Write(alignSpaces[:alignLength-len(kname)])
|
||||
}
|
||||
if key.isBooleanType {
|
||||
if kname != sec.keyList[len(sec.keyList)-1] {
|
||||
buf.WriteString(LineBreak)
|
||||
}
|
||||
continue KEY_LIST
|
||||
}
|
||||
|
||||
val := key.value
|
||||
// In case key value contains "\n", "`", "\"", "#" or ";"
|
||||
if strings.ContainsAny(val, "\n`") {
|
||||
val = `"""` + val + `"""`
|
||||
} else if strings.ContainsAny(val, "#;") {
|
||||
val = "`" + val + "`"
|
||||
}
|
||||
if _, err = buf.WriteString(equalSign + val + LineBreak); err != nil {
|
||||
return 0, err
|
||||
// Write out alignment spaces before "=" sign
|
||||
if PrettyFormat {
|
||||
buf.Write(alignSpaces[:alignLength-len(kname)])
|
||||
}
|
||||
|
||||
// In case key value contains "\n", "`", "\"", "#" or ";"
|
||||
if strings.ContainsAny(val, "\n`") {
|
||||
val = `"""` + val + `"""`
|
||||
} else if strings.ContainsAny(val, "#;") {
|
||||
val = "`" + val + "`"
|
||||
}
|
||||
if _, err = buf.WriteString(equalSign + val + LineBreak); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
104
vendor/github.com/go-ini/ini/key.go
generated
vendored
104
vendor/github.com/go-ini/ini/key.go
generated
vendored
|
@ -15,6 +15,7 @@
|
|||
package ini
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
@ -29,9 +30,42 @@ type Key struct {
|
|||
isAutoIncrement bool
|
||||
isBooleanType bool
|
||||
|
||||
isShadow bool
|
||||
shadows []*Key
|
||||
|
||||
Comment string
|
||||
}
|
||||
|
||||
// newKey simply return a key object with given values.
|
||||
func newKey(s *Section, name, val string) *Key {
|
||||
return &Key{
|
||||
s: s,
|
||||
name: name,
|
||||
value: val,
|
||||
}
|
||||
}
|
||||
|
||||
func (k *Key) addShadow(val string) error {
|
||||
if k.isShadow {
|
||||
return errors.New("cannot add shadow to another shadow key")
|
||||
} else if k.isAutoIncrement || k.isBooleanType {
|
||||
return errors.New("cannot add shadow to auto-increment or boolean key")
|
||||
}
|
||||
|
||||
shadow := newKey(k.s, k.name, val)
|
||||
shadow.isShadow = true
|
||||
k.shadows = append(k.shadows, shadow)
|
||||
return nil
|
||||
}
|
||||
|
||||
// AddShadow adds a new shadow key to itself.
|
||||
func (k *Key) AddShadow(val string) error {
|
||||
if !k.s.f.options.AllowShadows {
|
||||
return errors.New("shadow key is not allowed")
|
||||
}
|
||||
return k.addShadow(val)
|
||||
}
|
||||
|
||||
// ValueMapper represents a mapping function for values, e.g. os.ExpandEnv
|
||||
type ValueMapper func(string) string
|
||||
|
||||
|
@ -45,16 +79,29 @@ func (k *Key) Value() string {
|
|||
return k.value
|
||||
}
|
||||
|
||||
// String returns string representation of value.
|
||||
func (k *Key) String() string {
|
||||
val := k.value
|
||||
// ValueWithShadows returns raw values of key and its shadows if any.
|
||||
func (k *Key) ValueWithShadows() []string {
|
||||
if len(k.shadows) == 0 {
|
||||
return []string{k.value}
|
||||
}
|
||||
vals := make([]string, len(k.shadows)+1)
|
||||
vals[0] = k.value
|
||||
for i := range k.shadows {
|
||||
vals[i+1] = k.shadows[i].value
|
||||
}
|
||||
return vals
|
||||
}
|
||||
|
||||
// transformValue takes a raw value and transforms to its final string.
|
||||
func (k *Key) transformValue(val string) string {
|
||||
if k.s.f.ValueMapper != nil {
|
||||
val = k.s.f.ValueMapper(val)
|
||||
}
|
||||
if strings.Index(val, "%") == -1 {
|
||||
|
||||
// Fail-fast if no indicate char found for recursive value
|
||||
if !strings.Contains(val, "%") {
|
||||
return val
|
||||
}
|
||||
|
||||
for i := 0; i < _DEPTH_VALUES; i++ {
|
||||
vr := varPattern.FindString(val)
|
||||
if len(vr) == 0 {
|
||||
|
@ -78,6 +125,11 @@ func (k *Key) String() string {
|
|||
return val
|
||||
}
|
||||
|
||||
// String returns string representation of value.
|
||||
func (k *Key) String() string {
|
||||
return k.transformValue(k.value)
|
||||
}
|
||||
|
||||
// Validate accepts a validate function which can
|
||||
// return modifed result as key value.
|
||||
func (k *Key) Validate(fn func(string) string) string {
|
||||
|
@ -394,11 +446,31 @@ func (k *Key) Strings(delim string) []string {
|
|||
|
||||
vals := strings.Split(str, delim)
|
||||
for i := range vals {
|
||||
// vals[i] = k.transformValue(strings.TrimSpace(vals[i]))
|
||||
vals[i] = strings.TrimSpace(vals[i])
|
||||
}
|
||||
return vals
|
||||
}
|
||||
|
||||
// StringsWithShadows returns list of string divided by given delimiter.
|
||||
// Shadows will also be appended if any.
|
||||
func (k *Key) StringsWithShadows(delim string) []string {
|
||||
vals := k.ValueWithShadows()
|
||||
results := make([]string, 0, len(vals)*2)
|
||||
for i := range vals {
|
||||
if len(vals) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
results = append(results, strings.Split(vals[i], delim)...)
|
||||
}
|
||||
|
||||
for i := range results {
|
||||
results[i] = k.transformValue(strings.TrimSpace(results[i]))
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
||||
// Float64s returns list of float64 divided by given delimiter. Any invalid input will be treated as zero value.
|
||||
func (k *Key) Float64s(delim string) []float64 {
|
||||
vals, _ := k.getFloat64s(delim, true, false)
|
||||
|
@ -407,13 +479,13 @@ func (k *Key) Float64s(delim string) []float64 {
|
|||
|
||||
// Ints returns list of int divided by given delimiter. Any invalid input will be treated as zero value.
|
||||
func (k *Key) Ints(delim string) []int {
|
||||
vals, _ := k.getInts(delim, true, false)
|
||||
vals, _ := k.parseInts(k.Strings(delim), true, false)
|
||||
return vals
|
||||
}
|
||||
|
||||
// Int64s returns list of int64 divided by given delimiter. Any invalid input will be treated as zero value.
|
||||
func (k *Key) Int64s(delim string) []int64 {
|
||||
vals, _ := k.getInt64s(delim, true, false)
|
||||
vals, _ := k.parseInt64s(k.Strings(delim), true, false)
|
||||
return vals
|
||||
}
|
||||
|
||||
|
@ -452,14 +524,14 @@ func (k *Key) ValidFloat64s(delim string) []float64 {
|
|||
// ValidInts returns list of int divided by given delimiter. If some value is not integer, then it will
|
||||
// not be included to result list.
|
||||
func (k *Key) ValidInts(delim string) []int {
|
||||
vals, _ := k.getInts(delim, false, false)
|
||||
vals, _ := k.parseInts(k.Strings(delim), false, false)
|
||||
return vals
|
||||
}
|
||||
|
||||
// ValidInt64s returns list of int64 divided by given delimiter. If some value is not 64-bit integer,
|
||||
// then it will not be included to result list.
|
||||
func (k *Key) ValidInt64s(delim string) []int64 {
|
||||
vals, _ := k.getInt64s(delim, false, false)
|
||||
vals, _ := k.parseInt64s(k.Strings(delim), false, false)
|
||||
return vals
|
||||
}
|
||||
|
||||
|
@ -495,12 +567,12 @@ func (k *Key) StrictFloat64s(delim string) ([]float64, error) {
|
|||
|
||||
// StrictInts returns list of int divided by given delimiter or error on first invalid input.
|
||||
func (k *Key) StrictInts(delim string) ([]int, error) {
|
||||
return k.getInts(delim, false, true)
|
||||
return k.parseInts(k.Strings(delim), false, true)
|
||||
}
|
||||
|
||||
// StrictInt64s returns list of int64 divided by given delimiter or error on first invalid input.
|
||||
func (k *Key) StrictInt64s(delim string) ([]int64, error) {
|
||||
return k.getInt64s(delim, false, true)
|
||||
return k.parseInt64s(k.Strings(delim), false, true)
|
||||
}
|
||||
|
||||
// StrictUints returns list of uint divided by given delimiter or error on first invalid input.
|
||||
|
@ -541,9 +613,8 @@ func (k *Key) getFloat64s(delim string, addInvalid, returnOnInvalid bool) ([]flo
|
|||
return vals, nil
|
||||
}
|
||||
|
||||
// getInts returns list of int divided by given delimiter.
|
||||
func (k *Key) getInts(delim string, addInvalid, returnOnInvalid bool) ([]int, error) {
|
||||
strs := k.Strings(delim)
|
||||
// parseInts transforms strings to ints.
|
||||
func (k *Key) parseInts(strs []string, addInvalid, returnOnInvalid bool) ([]int, error) {
|
||||
vals := make([]int, 0, len(strs))
|
||||
for _, str := range strs {
|
||||
val, err := strconv.Atoi(str)
|
||||
|
@ -557,9 +628,8 @@ func (k *Key) getInts(delim string, addInvalid, returnOnInvalid bool) ([]int, er
|
|||
return vals, nil
|
||||
}
|
||||
|
||||
// getInt64s returns list of int64 divided by given delimiter.
|
||||
func (k *Key) getInt64s(delim string, addInvalid, returnOnInvalid bool) ([]int64, error) {
|
||||
strs := k.Strings(delim)
|
||||
// parseInt64s transforms strings to int64s.
|
||||
func (k *Key) parseInt64s(strs []string, addInvalid, returnOnInvalid bool) ([]int64, error) {
|
||||
vals := make([]int64, 0, len(strs))
|
||||
for _, str := range strs {
|
||||
val, err := strconv.ParseInt(str, 10, 64)
|
||||
|
|
59
vendor/github.com/go-ini/ini/parser.go
generated
vendored
59
vendor/github.com/go-ini/ini/parser.go
generated
vendored
|
@ -48,16 +48,31 @@ func newParser(r io.Reader) *parser {
|
|||
}
|
||||
}
|
||||
|
||||
// BOM handles header of BOM-UTF8 format.
|
||||
// BOM handles header of UTF-8, UTF-16 LE and UTF-16 BE's BOM format.
|
||||
// http://en.wikipedia.org/wiki/Byte_order_mark#Representations_of_byte_order_marks_by_encoding
|
||||
func (p *parser) BOM() error {
|
||||
mask, err := p.buf.Peek(3)
|
||||
mask, err := p.buf.Peek(2)
|
||||
if err != nil && err != io.EOF {
|
||||
return err
|
||||
} else if len(mask) < 3 {
|
||||
} else if len(mask) < 2 {
|
||||
return nil
|
||||
} else if mask[0] == 239 && mask[1] == 187 && mask[2] == 191 {
|
||||
}
|
||||
|
||||
switch {
|
||||
case mask[0] == 254 && mask[1] == 255:
|
||||
fallthrough
|
||||
case mask[0] == 255 && mask[1] == 254:
|
||||
p.buf.Read(mask)
|
||||
case mask[0] == 239 && mask[1] == 187:
|
||||
mask, err := p.buf.Peek(3)
|
||||
if err != nil && err != io.EOF {
|
||||
return err
|
||||
} else if len(mask) < 3 {
|
||||
return nil
|
||||
}
|
||||
if mask[2] == 191 {
|
||||
p.buf.Read(mask)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -235,6 +250,7 @@ func (f *File) parse(reader io.Reader) (err error) {
|
|||
section, _ := f.NewSection(DEFAULT_SECTION)
|
||||
|
||||
var line []byte
|
||||
var inUnparseableSection bool
|
||||
for !p.isEOF {
|
||||
line, err = p.readUntil('\n')
|
||||
if err != nil {
|
||||
|
@ -280,6 +296,21 @@ func (f *File) parse(reader io.Reader) (err error) {
|
|||
// Reset aotu-counter and comments
|
||||
p.comment.Reset()
|
||||
p.count = 1
|
||||
|
||||
inUnparseableSection = false
|
||||
for i := range f.options.UnparseableSections {
|
||||
if f.options.UnparseableSections[i] == name ||
|
||||
(f.options.Insensitive && strings.ToLower(f.options.UnparseableSections[i]) == strings.ToLower(name)) {
|
||||
inUnparseableSection = true
|
||||
continue
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if inUnparseableSection {
|
||||
section.isRawSection = true
|
||||
section.rawBody += string(line)
|
||||
continue
|
||||
}
|
||||
|
||||
|
@ -287,11 +318,14 @@ func (f *File) parse(reader io.Reader) (err error) {
|
|||
if err != nil {
|
||||
// Treat as boolean key when desired, and whole line is key name.
|
||||
if IsErrDelimiterNotFound(err) && f.options.AllowBooleanKeys {
|
||||
key, err := section.NewKey(string(line), "true")
|
||||
kname, err := p.readValue(line, f.options.IgnoreContinuation)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
key, err := section.NewBooleanKey(kname)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
key.isBooleanType = true
|
||||
key.Comment = strings.TrimSpace(p.comment.String())
|
||||
p.comment.Reset()
|
||||
continue
|
||||
|
@ -307,17 +341,16 @@ func (f *File) parse(reader io.Reader) (err error) {
|
|||
p.count++
|
||||
}
|
||||
|
||||
key, err := section.NewKey(kname, "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
key.isAutoIncrement = isAutoIncr
|
||||
|
||||
value, err := p.readValue(line[offset:], f.options.IgnoreContinuation)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
key.SetValue(value)
|
||||
|
||||
key, err := section.NewKey(kname, value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
key.isAutoIncrement = isAutoIncr
|
||||
key.Comment = strings.TrimSpace(p.comment.String())
|
||||
p.comment.Reset()
|
||||
}
|
||||
|
|
42
vendor/github.com/go-ini/ini/section.go
generated
vendored
42
vendor/github.com/go-ini/ini/section.go
generated
vendored
|
@ -28,10 +28,19 @@ type Section struct {
|
|||
keys map[string]*Key
|
||||
keyList []string
|
||||
keysHash map[string]string
|
||||
|
||||
isRawSection bool
|
||||
rawBody string
|
||||
}
|
||||
|
||||
func newSection(f *File, name string) *Section {
|
||||
return &Section{f, "", name, make(map[string]*Key), make([]string, 0, 10), make(map[string]string)}
|
||||
return &Section{
|
||||
f: f,
|
||||
name: name,
|
||||
keys: make(map[string]*Key),
|
||||
keyList: make([]string, 0, 10),
|
||||
keysHash: make(map[string]string),
|
||||
}
|
||||
}
|
||||
|
||||
// Name returns name of Section.
|
||||
|
@ -39,6 +48,12 @@ func (s *Section) Name() string {
|
|||
return s.name
|
||||
}
|
||||
|
||||
// Body returns rawBody of Section if the section was marked as unparseable.
|
||||
// It still follows the other rules of the INI format surrounding leading/trailing whitespace.
|
||||
func (s *Section) Body() string {
|
||||
return strings.TrimSpace(s.rawBody)
|
||||
}
|
||||
|
||||
// NewKey creates a new key to given section.
|
||||
func (s *Section) NewKey(name, val string) (*Key, error) {
|
||||
if len(name) == 0 {
|
||||
|
@ -53,20 +68,33 @@ func (s *Section) NewKey(name, val string) (*Key, error) {
|
|||
}
|
||||
|
||||
if inSlice(name, s.keyList) {
|
||||
s.keys[name].value = val
|
||||
if s.f.options.AllowShadows {
|
||||
if err := s.keys[name].addShadow(val); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
s.keys[name].value = val
|
||||
}
|
||||
return s.keys[name], nil
|
||||
}
|
||||
|
||||
s.keyList = append(s.keyList, name)
|
||||
s.keys[name] = &Key{
|
||||
s: s,
|
||||
name: name,
|
||||
value: val,
|
||||
}
|
||||
s.keys[name] = newKey(s, name, val)
|
||||
s.keysHash[name] = val
|
||||
return s.keys[name], nil
|
||||
}
|
||||
|
||||
// NewBooleanKey creates a new boolean type key to given section.
|
||||
func (s *Section) NewBooleanKey(name string) (*Key, error) {
|
||||
key, err := s.NewKey(name, "true")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
key.isBooleanType = true
|
||||
return key, nil
|
||||
}
|
||||
|
||||
// GetKey returns key in section by given name.
|
||||
func (s *Section) GetKey(name string) (*Key, error) {
|
||||
// FIXME: change to section level lock?
|
||||
|
|
39
vendor/github.com/go-ini/ini/struct.go
generated
vendored
39
vendor/github.com/go-ini/ini/struct.go
generated
vendored
|
@ -78,8 +78,14 @@ func parseDelim(actual string) string {
|
|||
var reflectTime = reflect.TypeOf(time.Now()).Kind()
|
||||
|
||||
// setSliceWithProperType sets proper values to slice based on its type.
|
||||
func setSliceWithProperType(key *Key, field reflect.Value, delim string) error {
|
||||
strs := key.Strings(delim)
|
||||
func setSliceWithProperType(key *Key, field reflect.Value, delim string, allowShadow bool) error {
|
||||
var strs []string
|
||||
if allowShadow {
|
||||
strs = key.StringsWithShadows(delim)
|
||||
} else {
|
||||
strs = key.Strings(delim)
|
||||
}
|
||||
|
||||
numVals := len(strs)
|
||||
if numVals == 0 {
|
||||
return nil
|
||||
|
@ -92,9 +98,9 @@ func setSliceWithProperType(key *Key, field reflect.Value, delim string) error {
|
|||
case reflect.String:
|
||||
vals = strs
|
||||
case reflect.Int:
|
||||
vals = key.Ints(delim)
|
||||
vals, _ = key.parseInts(strs, true, false)
|
||||
case reflect.Int64:
|
||||
vals = key.Int64s(delim)
|
||||
vals, _ = key.parseInt64s(strs, true, false)
|
||||
case reflect.Uint:
|
||||
vals = key.Uints(delim)
|
||||
case reflect.Uint64:
|
||||
|
@ -133,7 +139,7 @@ func setSliceWithProperType(key *Key, field reflect.Value, delim string) error {
|
|||
// setWithProperType sets proper value to field based on its type,
|
||||
// but it does not return error for failing parsing,
|
||||
// because we want to use default value that is already assigned to strcut.
|
||||
func setWithProperType(t reflect.Type, key *Key, field reflect.Value, delim string) error {
|
||||
func setWithProperType(t reflect.Type, key *Key, field reflect.Value, delim string, allowShadow bool) error {
|
||||
switch t.Kind() {
|
||||
case reflect.String:
|
||||
if len(key.String()) == 0 {
|
||||
|
@ -174,7 +180,7 @@ func setWithProperType(t reflect.Type, key *Key, field reflect.Value, delim stri
|
|||
}
|
||||
field.SetUint(uintVal)
|
||||
|
||||
case reflect.Float64:
|
||||
case reflect.Float32, reflect.Float64:
|
||||
floatVal, err := key.Float64()
|
||||
if err != nil {
|
||||
return nil
|
||||
|
@ -187,13 +193,25 @@ func setWithProperType(t reflect.Type, key *Key, field reflect.Value, delim stri
|
|||
}
|
||||
field.Set(reflect.ValueOf(timeVal))
|
||||
case reflect.Slice:
|
||||
return setSliceWithProperType(key, field, delim)
|
||||
return setSliceWithProperType(key, field, delim, allowShadow)
|
||||
default:
|
||||
return fmt.Errorf("unsupported type '%s'", t)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseTagOptions(tag string) (rawName string, omitEmpty bool, allowShadow bool) {
|
||||
opts := strings.SplitN(tag, ",", 3)
|
||||
rawName = opts[0]
|
||||
if len(opts) > 1 {
|
||||
omitEmpty = opts[1] == "omitempty"
|
||||
}
|
||||
if len(opts) > 2 {
|
||||
allowShadow = opts[2] == "allowshadow"
|
||||
}
|
||||
return rawName, omitEmpty, allowShadow
|
||||
}
|
||||
|
||||
func (s *Section) mapTo(val reflect.Value) error {
|
||||
if val.Kind() == reflect.Ptr {
|
||||
val = val.Elem()
|
||||
|
@ -209,8 +227,8 @@ func (s *Section) mapTo(val reflect.Value) error {
|
|||
continue
|
||||
}
|
||||
|
||||
opts := strings.SplitN(tag, ",", 2) // strip off possible omitempty
|
||||
fieldName := s.parseFieldName(tpField.Name, opts[0])
|
||||
rawName, _, allowShadow := parseTagOptions(tag)
|
||||
fieldName := s.parseFieldName(tpField.Name, rawName)
|
||||
if len(fieldName) == 0 || !field.CanSet() {
|
||||
continue
|
||||
}
|
||||
|
@ -231,7 +249,8 @@ func (s *Section) mapTo(val reflect.Value) error {
|
|||
}
|
||||
|
||||
if key, err := s.GetKey(fieldName); err == nil {
|
||||
if err = setWithProperType(tpField.Type, key, field, parseDelim(tpField.Tag.Get("delim"))); err != nil {
|
||||
delim := parseDelim(tpField.Tag.Get("delim"))
|
||||
if err = setWithProperType(tpField.Type, key, field, delim, allowShadow); err != nil {
|
||||
return fmt.Errorf("error mapping field(%s): %v", fieldName, err)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue