-
Notifications
You must be signed in to change notification settings - Fork 0
/
parseini.go
150 lines (124 loc) · 3.18 KB
/
parseini.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
// Go :: parse INI configuration files
// modified by unixman
// (c) 2022 unix-world.org
// r.20220410.0712
package parseini
import (
"bufio"
"fmt"
"io"
"regexp"
"strings"
"strconv"
)
var (
sectionRegex = regexp.MustCompile(`^\[(.*)\]$`)
assignRegex = regexp.MustCompile(`^([^=]+)=(.*)$`)
)
// A Data represents a parsed INI file.
type Data map[string]Section
// A Section represents a single section of an INI file.
type Section map[string]string
// ErrSyntax is returned when there is a syntax error in an INI file.
type ErrSyntax struct {
Line int64
Source string // The contents of the erroneous line, without leading or trailing whitespace
}
func (e ErrSyntax) Error() string {
return fmt.Sprintf("invalid INI syntax on line %d: %s", e.Line, e.Source)
} //END FUNCTION
// Returns a named Section. A Section will be created if one does not already exist for the given name.
func (f Data) Section(name string) Section {
section := f[name]
if(section == nil) {
section = make(Section)
f[name] = section
} //end if
return section
} //END FUNCTION
// Looks up a value for a key in a section and returns that value, along with a boolean result similar to a map lookup.
func (f Data) Get(section, key string) (value string, ok bool) {
if s := f[section]; s != nil {
value, ok = s[key]
} //end if
return
} //END FUNCTION
// Loads INI data from a reader and stores the data in the Data.
func (f Data) Load(in io.Reader) (err error) {
bufin, ok := in.(*bufio.Reader)
if(!ok) {
bufin = bufio.NewReader(in)
} //end if
return parseData(bufin, f)
} //END FUNCTION
// Parse the INI Data
func parseData(in *bufio.Reader, dat Data) (err error) {
section := ""
lineNum := 0
for done := false; !done; {
var line string
if line, err = in.ReadString('\n'); err != nil {
if(err == io.EOF) {
done = true
} else {
return
} //end if else
} //end if
lineNum++
line = strings.TrimSpace(line)
if(len(line) == 0) {
// Skip blank lines
continue
} //end if
if line[0] == ';' || line[0] == '#' {
// Skip comments
continue
} //end if
if groups := assignRegex.FindStringSubmatch(line); groups != nil {
key, val := groups[1], groups[2]
key, val = strings.TrimSpace(key), strings.TrimSpace(val)
dat.Section(section)[key] = val
} else if groups := sectionRegex.FindStringSubmatch(line); groups != nil {
name := strings.TrimSpace(groups[1])
section = name
// Create the section if it does not exist
dat.Section(section)
} else {
return ErrSyntax{int64(lineNum), line}
} //end if else
} //end for
return nil
} //END FUNCTION
// Loads and returns a Data from a string.
func Load(src string) (Data, error) {
dat := make(Data)
in := strings.NewReader(src)
err := dat.Load(in)
return dat, err
} //END FUNCTION
func GetIniStrVal(dat Data, section string, key string) string {
//--
str, ok := dat.Get(section, key)
if(!ok) {
str = ""
} //end if
//--
return str
//--
} //END FUNCTION
func GetIniIntVal(dat Data, section string, key string) int {
//--
str, ok := dat.Get(section, key)
if(!ok) {
str = ""
} //end if
//--
i, err := strconv.Atoi(str)
if(err != nil) {
i = 0
} //end if
//--
return i
//--
} //END FUNCTION
// #END