open-vault/vendor/github.com/go-ini/ini/ini.go

212 lines
7.1 KiB
Go
Raw Normal View History

2018-07-11 20:04:02 +00:00
// +build go1.6
2015-11-18 15:36:57 +00:00
// Copyright 2014 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 ini provides INI file read and write functionality in Go.
package ini
import (
"bytes"
"fmt"
"io"
2017-01-04 21:47:38 +00:00
"io/ioutil"
2015-11-18 15:36:57 +00:00
"os"
"regexp"
"runtime"
)
const (
2016-03-11 03:50:44 +00:00
// Name for default section. You can use this constant or the string literal.
// In most of cases, an empty string is all you need to access the section.
2015-11-18 15:36:57 +00:00
DEFAULT_SECTION = "DEFAULT"
2016-03-11 03:50:44 +00:00
2015-11-18 15:36:57 +00:00
// Maximum allowed depth when recursively substituing variable names.
_DEPTH_VALUES = 99
2018-07-11 20:04:02 +00:00
_VERSION = "1.38.0"
2015-11-18 15:36:57 +00:00
)
2016-03-11 03:50:44 +00:00
// Version returns current package version literal.
2015-11-18 15:36:57 +00:00
func Version() string {
return _VERSION
}
var (
2016-03-11 03:50:44 +00:00
// Delimiter to determine or compose a new line.
// This variable will be changed to "\r\n" automatically on Windows
// at package init time.
2015-11-18 15:36:57 +00:00
LineBreak = "\n"
// Variable regexp pattern: %(variable)s
varPattern = regexp.MustCompile(`%\(([^\)]+)\)s`)
2016-03-11 03:50:44 +00:00
// Indicate whether to align "=" sign with spaces to produce pretty output
// or reduce all possible spaces for compact format.
2015-11-18 15:36:57 +00:00
PrettyFormat = true
2016-04-26 00:18:04 +00:00
// Place spaces around "=" sign even when PrettyFormat is false
PrettyEqual = false
2016-04-26 00:18:04 +00:00
// Explicitly write DEFAULT section header
DefaultHeader = false
2017-06-05 14:50:46 +00:00
2017-05-24 13:40:58 +00:00
// Indicate whether to put a line between sections
PrettySection = true
2015-11-18 15:36:57 +00:00
)
func init() {
if runtime.GOOS == "windows" {
LineBreak = "\r\n"
}
}
func inSlice(str string, s []string) bool {
for _, v := range s {
if str == v {
return true
}
}
return false
}
2016-03-11 03:50:44 +00:00
// dataSource is an interface that returns object which can be read and closed.
2015-11-18 15:36:57 +00:00
type dataSource interface {
ReadCloser() (io.ReadCloser, error)
}
2016-03-11 03:50:44 +00:00
// sourceFile represents an object that contains content on the local file system.
2015-11-18 15:36:57 +00:00
type sourceFile struct {
name string
}
func (s sourceFile) ReadCloser() (_ io.ReadCloser, err error) {
return os.Open(s.name)
}
2016-03-11 03:50:44 +00:00
// sourceData represents an object that contains content in memory.
2015-11-18 15:36:57 +00:00
type sourceData struct {
data []byte
}
func (s *sourceData) ReadCloser() (io.ReadCloser, error) {
2017-01-04 21:47:38 +00:00
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
2015-11-18 15:36:57 +00:00
}
func parseDataSource(source interface{}) (dataSource, error) {
switch s := source.(type) {
case string:
return sourceFile{s}, nil
case []byte:
return &sourceData{s}, nil
2017-01-04 21:47:38 +00:00
case io.ReadCloser:
return &sourceReadCloser{s}, nil
2015-11-18 15:36:57 +00:00
default:
return nil, fmt.Errorf("error parsing data source: unknown type '%s'", s)
}
}
2016-06-30 18:19:03 +00:00
type LoadOptions struct {
2016-07-23 00:11:47 +00:00
// Loose indicates whether the parser should ignore nonexistent files or return error.
2016-06-30 18:19:03 +00:00
Loose bool
// Insensitive indicates whether the parser forces all section and key names to lowercase.
Insensitive bool
2016-07-23 00:11:47 +00:00
// IgnoreContinuation indicates whether to ignore continuation lines while parsing.
IgnoreContinuation bool
2017-03-31 00:03:13 +00:00
// IgnoreInlineComment indicates whether to ignore comments at the end of value and treat it as part of value.
IgnoreInlineComment bool
2018-07-11 20:04:02 +00:00
// SkipUnrecognizableLines indicates whether to skip unrecognizable lines that do not conform to key/value pairs.
SkipUnrecognizableLines bool
2016-09-02 22:05:09 +00:00
// 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
2017-02-24 19:36:54 +00:00
// AllowShadows indicates whether to keep track of keys with same name under same section.
AllowShadows bool
2018-01-26 23:51:00 +00:00
// AllowNestedValues indicates whether to allow AWS-like nested values.
// Docs: http://docs.aws.amazon.com/cli/latest/topic/config-vars.html#nested-values
AllowNestedValues bool
// AllowPythonMultilineValues indicates whether to allow Python-like multi-line values.
// Docs: https://docs.python.org/3/library/configparser.html#supported-ini-file-structure
// Relevant quote: Values can also span multiple lines, as long as they are indented deeper
// than the first line of the value.
AllowPythonMultilineValues bool
// SpaceBeforeInlineComment indicates whether to allow comment symbols (\# and \;) inside value.
// Docs: https://docs.python.org/2/library/configparser.html
// Quote: Comments may appear on their own in an otherwise empty line, or may be entered in lines holding values or section names.
// In the latter case, they need to be preceded by a whitespace character to be recognized as a comment.
SpaceBeforeInlineComment bool
2018-01-26 23:51:00 +00:00
// UnescapeValueDoubleQuotes indicates whether to unescape double quotes inside value to regular format
// when value is surrounded by double quotes, e.g. key="a \"value\"" => key=a "value"
2017-10-27 19:06:04 +00:00
UnescapeValueDoubleQuotes bool
2018-01-26 23:51:00 +00:00
// UnescapeValueCommentSymbols indicates to unescape comment symbols (\# and \;) inside value to regular format
// when value is NOT surrounded by any quotes.
// Note: UNSTABLE, behavior might change to only unescape inside double quotes but may noy necessary at all.
UnescapeValueCommentSymbols bool
2018-07-11 20:04:02 +00:00
// UnparseableSections stores a list of blocks that are allowed with raw content which do not otherwise
2017-01-04 21:47:38 +00:00
// conform to key/value pairs. Specify the names of those blocks here.
UnparseableSections []string
2016-06-30 18:19:03 +00:00
}
func LoadSources(opts LoadOptions, source interface{}, others ...interface{}) (_ *File, err error) {
2015-11-18 15:36:57 +00:00
sources := make([]dataSource, len(others)+1)
sources[0], err = parseDataSource(source)
if err != nil {
return nil, err
}
for i := range others {
sources[i+1], err = parseDataSource(others[i])
if err != nil {
return nil, err
}
}
2016-06-30 18:19:03 +00:00
f := newFile(sources, opts)
if err = f.Reload(); err != nil {
return nil, err
}
return f, nil
2015-11-18 15:36:57 +00:00
}
2016-03-11 03:50:44 +00:00
// Load loads and parses from INI data sources.
// Arguments can be mixed of file name with string type, or raw data in []byte.
// It will return error if list contains nonexistent files.
func Load(source interface{}, others ...interface{}) (*File, error) {
2016-06-30 18:19:03 +00:00
return LoadSources(LoadOptions{}, source, others...)
2016-03-11 03:50:44 +00:00
}
// LooseLoad has exactly same functionality as Load function
// except it ignores nonexistent files instead of returning error.
func LooseLoad(source interface{}, others ...interface{}) (*File, error) {
2016-06-30 18:19:03 +00:00
return LoadSources(LoadOptions{Loose: true}, source, others...)
}
// InsensitiveLoad has exactly same functionality as Load function
// except it forces all section and key names to be lowercased.
func InsensitiveLoad(source interface{}, others ...interface{}) (*File, error) {
return LoadSources(LoadOptions{Insensitive: true}, source, others...)
2016-03-11 03:50:44 +00:00
}
2017-02-24 19:36:54 +00:00
// 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...)
}