vendor/gopkg.in/ini.v1/file.go
author Mikael Berthe <mikael@lilotux.net>
Sun, 16 Feb 2020 18:54:01 +0100
changeset 251 1c52a0eeb952
child 256 6d9efbef00a9
permissions -rw-r--r--
Update dependencies This should fix #22.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
251
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     1
// Copyright 2017 Unknwon
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     2
//
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     3
// Licensed under the Apache License, Version 2.0 (the "License"): you may
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     4
// not use this file except in compliance with the License. You may obtain
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     5
// a copy of the License at
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     6
//
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     7
//     http://www.apache.org/licenses/LICENSE-2.0
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     8
//
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     9
// Unless required by applicable law or agreed to in writing, software
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    10
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    11
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    12
// License for the specific language governing permissions and limitations
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    13
// under the License.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    14
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    15
package ini
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    16
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    17
import (
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    18
	"bytes"
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    19
	"errors"
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    20
	"fmt"
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    21
	"io"
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    22
	"io/ioutil"
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    23
	"os"
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    24
	"strings"
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    25
	"sync"
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    26
)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    27
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    28
// File represents a combination of a or more INI file(s) in memory.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    29
type File struct {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    30
	options     LoadOptions
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    31
	dataSources []dataSource
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    32
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    33
	// Should make things safe, but sometimes doesn't matter.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    34
	BlockMode bool
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    35
	lock      sync.RWMutex
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    36
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    37
	// To keep data in order.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    38
	sectionList []string
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    39
	// Actual data is stored here.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    40
	sections map[string]*Section
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    41
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    42
	NameMapper
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    43
	ValueMapper
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    44
}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    45
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    46
// newFile initializes File object with given data sources.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    47
func newFile(dataSources []dataSource, opts LoadOptions) *File {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    48
	if len(opts.KeyValueDelimiters) == 0 {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    49
		opts.KeyValueDelimiters = "=:"
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    50
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    51
	return &File{
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    52
		BlockMode:   true,
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    53
		dataSources: dataSources,
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    54
		sections:    make(map[string]*Section),
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    55
		sectionList: make([]string, 0, 10),
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    56
		options:     opts,
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    57
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    58
}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    59
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    60
// Empty returns an empty file object.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    61
func Empty() *File {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    62
	// Ignore error here, we sure our data is good.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    63
	f, _ := Load([]byte(""))
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    64
	return f
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    65
}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    66
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    67
// NewSection creates a new section.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    68
func (f *File) NewSection(name string) (*Section, error) {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    69
	if len(name) == 0 {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    70
		return nil, errors.New("error creating new section: empty section name")
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    71
	} else if f.options.Insensitive && name != DefaultSection {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    72
		name = strings.ToLower(name)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    73
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    74
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    75
	if f.BlockMode {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    76
		f.lock.Lock()
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    77
		defer f.lock.Unlock()
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    78
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    79
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    80
	if inSlice(name, f.sectionList) {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    81
		return f.sections[name], nil
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    82
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    83
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    84
	f.sectionList = append(f.sectionList, name)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    85
	f.sections[name] = newSection(f, name)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    86
	return f.sections[name], nil
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    87
}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    88
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    89
// NewRawSection creates a new section with an unparseable body.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    90
func (f *File) NewRawSection(name, body string) (*Section, error) {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    91
	section, err := f.NewSection(name)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    92
	if err != nil {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    93
		return nil, err
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    94
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    95
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    96
	section.isRawSection = true
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    97
	section.rawBody = body
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    98
	return section, nil
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    99
}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   100
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   101
// NewSections creates a list of sections.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   102
func (f *File) NewSections(names ...string) (err error) {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   103
	for _, name := range names {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   104
		if _, err = f.NewSection(name); err != nil {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   105
			return err
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   106
		}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   107
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   108
	return nil
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   109
}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   110
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   111
// GetSection returns section by given name.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   112
func (f *File) GetSection(name string) (*Section, error) {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   113
	if len(name) == 0 {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   114
		name = DefaultSection
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   115
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   116
	if f.options.Insensitive {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   117
		name = strings.ToLower(name)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   118
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   119
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   120
	if f.BlockMode {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   121
		f.lock.RLock()
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   122
		defer f.lock.RUnlock()
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   123
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   124
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   125
	sec := f.sections[name]
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   126
	if sec == nil {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   127
		return nil, fmt.Errorf("section '%s' does not exist", name)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   128
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   129
	return sec, nil
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   130
}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   131
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   132
// Section assumes named section exists and returns a zero-value when not.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   133
func (f *File) Section(name string) *Section {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   134
	sec, err := f.GetSection(name)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   135
	if err != nil {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   136
		// Note: It's OK here because the only possible error is empty section name,
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   137
		// but if it's empty, this piece of code won't be executed.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   138
		sec, _ = f.NewSection(name)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   139
		return sec
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   140
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   141
	return sec
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   142
}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   143
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   144
// Sections returns a list of Section stored in the current instance.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   145
func (f *File) Sections() []*Section {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   146
	if f.BlockMode {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   147
		f.lock.RLock()
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   148
		defer f.lock.RUnlock()
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   149
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   150
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   151
	sections := make([]*Section, len(f.sectionList))
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   152
	for i, name := range f.sectionList {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   153
		sections[i] = f.sections[name]
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   154
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   155
	return sections
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   156
}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   157
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   158
// ChildSections returns a list of child sections of given section name.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   159
func (f *File) ChildSections(name string) []*Section {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   160
	return f.Section(name).ChildSections()
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   161
}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   162
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   163
// SectionStrings returns list of section names.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   164
func (f *File) SectionStrings() []string {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   165
	list := make([]string, len(f.sectionList))
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   166
	copy(list, f.sectionList)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   167
	return list
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   168
}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   169
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   170
// DeleteSection deletes a section.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   171
func (f *File) DeleteSection(name string) {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   172
	if f.BlockMode {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   173
		f.lock.Lock()
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   174
		defer f.lock.Unlock()
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   175
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   176
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   177
	if len(name) == 0 {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   178
		name = DefaultSection
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   179
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   180
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   181
	for i, s := range f.sectionList {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   182
		if s == name {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   183
			f.sectionList = append(f.sectionList[:i], f.sectionList[i+1:]...)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   184
			delete(f.sections, name)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   185
			return
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   186
		}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   187
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   188
}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   189
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   190
func (f *File) reload(s dataSource) error {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   191
	r, err := s.ReadCloser()
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   192
	if err != nil {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   193
		return err
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   194
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   195
	defer r.Close()
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   196
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   197
	return f.parse(r)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   198
}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   199
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   200
// Reload reloads and parses all data sources.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   201
func (f *File) Reload() (err error) {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   202
	for _, s := range f.dataSources {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   203
		if err = f.reload(s); err != nil {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   204
			// In loose mode, we create an empty default section for nonexistent files.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   205
			if os.IsNotExist(err) && f.options.Loose {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   206
				f.parse(bytes.NewBuffer(nil))
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   207
				continue
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   208
			}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   209
			return err
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   210
		}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   211
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   212
	return nil
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   213
}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   214
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   215
// Append appends one or more data sources and reloads automatically.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   216
func (f *File) Append(source interface{}, others ...interface{}) error {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   217
	ds, err := parseDataSource(source)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   218
	if err != nil {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   219
		return err
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   220
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   221
	f.dataSources = append(f.dataSources, ds)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   222
	for _, s := range others {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   223
		ds, err = parseDataSource(s)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   224
		if err != nil {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   225
			return err
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   226
		}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   227
		f.dataSources = append(f.dataSources, ds)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   228
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   229
	return f.Reload()
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   230
}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   231
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   232
func (f *File) writeToBuffer(indent string) (*bytes.Buffer, error) {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   233
	equalSign := DefaultFormatLeft + "=" + DefaultFormatRight
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   234
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   235
	if PrettyFormat || PrettyEqual {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   236
		equalSign = " = "
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   237
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   238
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   239
	// Use buffer to make sure target is safe until finish encoding.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   240
	buf := bytes.NewBuffer(nil)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   241
	for i, sname := range f.sectionList {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   242
		sec := f.Section(sname)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   243
		if len(sec.Comment) > 0 {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   244
			// Support multiline comments
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   245
			lines := strings.Split(sec.Comment, LineBreak)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   246
			for i := range lines {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   247
				if lines[i][0] != '#' && lines[i][0] != ';' {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   248
					lines[i] = "; " + lines[i]
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   249
				} else {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   250
					lines[i] = lines[i][:1] + " " + strings.TrimSpace(lines[i][1:])
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   251
				}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   252
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   253
				if _, err := buf.WriteString(lines[i] + LineBreak); err != nil {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   254
					return nil, err
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   255
				}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   256
			}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   257
		}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   258
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   259
		if i > 0 || DefaultHeader {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   260
			if _, err := buf.WriteString("[" + sname + "]" + LineBreak); err != nil {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   261
				return nil, err
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   262
			}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   263
		} else {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   264
			// Write nothing if default section is empty
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   265
			if len(sec.keyList) == 0 {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   266
				continue
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   267
			}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   268
		}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   269
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   270
		if sec.isRawSection {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   271
			if _, err := buf.WriteString(sec.rawBody); err != nil {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   272
				return nil, err
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   273
			}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   274
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   275
			if PrettySection {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   276
				// Put a line between sections
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   277
				if _, err := buf.WriteString(LineBreak); err != nil {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   278
					return nil, err
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   279
				}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   280
			}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   281
			continue
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   282
		}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   283
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   284
		// Count and generate alignment length and buffer spaces using the
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   285
		// longest key. Keys may be modifed if they contain certain characters so
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   286
		// we need to take that into account in our calculation.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   287
		alignLength := 0
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   288
		if PrettyFormat {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   289
			for _, kname := range sec.keyList {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   290
				keyLength := len(kname)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   291
				// First case will surround key by ` and second by """
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   292
				if strings.Contains(kname, "\"") || strings.ContainsAny(kname, f.options.KeyValueDelimiters) {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   293
					keyLength += 2
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   294
				} else if strings.Contains(kname, "`") {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   295
					keyLength += 6
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   296
				}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   297
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   298
				if keyLength > alignLength {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   299
					alignLength = keyLength
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   300
				}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   301
			}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   302
		}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   303
		alignSpaces := bytes.Repeat([]byte(" "), alignLength)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   304
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   305
	KeyList:
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   306
		for _, kname := range sec.keyList {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   307
			key := sec.Key(kname)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   308
			if len(key.Comment) > 0 {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   309
				if len(indent) > 0 && sname != DefaultSection {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   310
					buf.WriteString(indent)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   311
				}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   312
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   313
				// Support multiline comments
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   314
				lines := strings.Split(key.Comment, LineBreak)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   315
				for i := range lines {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   316
					if lines[i][0] != '#' && lines[i][0] != ';' {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   317
						lines[i] = "; " + strings.TrimSpace(lines[i])
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   318
					} else {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   319
						lines[i] = lines[i][:1] + " " + strings.TrimSpace(lines[i][1:])
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   320
					}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   321
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   322
					if _, err := buf.WriteString(lines[i] + LineBreak); err != nil {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   323
						return nil, err
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   324
					}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   325
				}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   326
			}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   327
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   328
			if len(indent) > 0 && sname != DefaultSection {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   329
				buf.WriteString(indent)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   330
			}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   331
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   332
			switch {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   333
			case key.isAutoIncrement:
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   334
				kname = "-"
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   335
			case strings.Contains(kname, "\"") || strings.ContainsAny(kname, f.options.KeyValueDelimiters):
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   336
				kname = "`" + kname + "`"
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   337
			case strings.Contains(kname, "`"):
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   338
				kname = `"""` + kname + `"""`
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   339
			}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   340
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   341
			for _, val := range key.ValueWithShadows() {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   342
				if _, err := buf.WriteString(kname); err != nil {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   343
					return nil, err
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   344
				}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   345
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   346
				if key.isBooleanType {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   347
					if kname != sec.keyList[len(sec.keyList)-1] {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   348
						buf.WriteString(LineBreak)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   349
					}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   350
					continue KeyList
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   351
				}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   352
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   353
				// Write out alignment spaces before "=" sign
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   354
				if PrettyFormat {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   355
					buf.Write(alignSpaces[:alignLength-len(kname)])
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   356
				}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   357
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   358
				// In case key value contains "\n", "`", "\"", "#" or ";"
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   359
				if strings.ContainsAny(val, "\n`") {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   360
					val = `"""` + val + `"""`
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   361
				} else if !f.options.IgnoreInlineComment && strings.ContainsAny(val, "#;") {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   362
					val = "`" + val + "`"
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   363
				}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   364
				if _, err := buf.WriteString(equalSign + val + LineBreak); err != nil {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   365
					return nil, err
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   366
				}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   367
			}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   368
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   369
			for _, val := range key.nestedValues {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   370
				if _, err := buf.WriteString(indent + "  " + val + LineBreak); err != nil {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   371
					return nil, err
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   372
				}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   373
			}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   374
		}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   375
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   376
		if PrettySection {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   377
			// Put a line between sections
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   378
			if _, err := buf.WriteString(LineBreak); err != nil {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   379
				return nil, err
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   380
			}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   381
		}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   382
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   383
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   384
	return buf, nil
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   385
}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   386
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   387
// WriteToIndent writes content into io.Writer with given indention.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   388
// If PrettyFormat has been set to be true,
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   389
// it will align "=" sign with spaces under each section.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   390
func (f *File) WriteToIndent(w io.Writer, indent string) (int64, error) {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   391
	buf, err := f.writeToBuffer(indent)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   392
	if err != nil {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   393
		return 0, err
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   394
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   395
	return buf.WriteTo(w)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   396
}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   397
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   398
// WriteTo writes file content into io.Writer.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   399
func (f *File) WriteTo(w io.Writer) (int64, error) {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   400
	return f.WriteToIndent(w, "")
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   401
}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   402
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   403
// SaveToIndent writes content to file system with given value indention.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   404
func (f *File) SaveToIndent(filename, indent string) error {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   405
	// Note: Because we are truncating with os.Create,
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   406
	// 	so it's safer to save to a temporary file location and rename afte done.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   407
	buf, err := f.writeToBuffer(indent)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   408
	if err != nil {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   409
		return err
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   410
	}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   411
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   412
	return ioutil.WriteFile(filename, buf.Bytes(), 0666)
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   413
}
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   414
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   415
// SaveTo writes content to file system.
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   416
func (f *File) SaveTo(filename string) error {
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   417
	return f.SaveToIndent(filename, "")
1c52a0eeb952 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   418
}