aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShulhan <ms@kilabit.info>2019-05-26 03:37:44 +0700
committerShulhan <ms@kilabit.info>2019-05-26 03:37:44 +0700
commit491e71ede506a29f01f40d8396c1e6b1b39de636 (patch)
tree9761e13bf8bcea63a9ad3c77de42fd421788fa92
parent671de3811ee64e7224fe8056290f5d3da2a1556d (diff)
downloadpakakeh.go-491e71ede506a29f01f40d8396c1e6b1b39de636.tar.xz
ini: add method to add, set, and unset variable
The Add() method will add new key and value to the last item in section and/or subsection. The Set() method set the last variable's value in section-subsection that match with the key. The Unset() method will remove the last variable's in section and/or subsection that match with the key.
-rw-r--r--lib/ini/ini.go113
-rw-r--r--lib/ini/ini_example_test.go136
2 files changed, 244 insertions, 5 deletions
diff --git a/lib/ini/ini.go b/lib/ini/ini.go
index 95808392..1670718c 100644
--- a/lib/ini/ini.go
+++ b/lib/ini/ini.go
@@ -48,6 +48,89 @@ func Parse(text []byte) (in *Ini, err error) {
}
//
+// Add the new key and value to the last item in section and/or subsection.
+//
+// If section or subsection is not exist it will create a new one.
+// If section or key is empty, or value already exist it will not modify the
+// INI object.
+//
+// It will return true if new variable is added, otherwise it will return
+// false.
+//
+func (in *Ini) Add(secName, subName, key, value string) bool {
+ if len(secName) == 0 || len(key) == 0 {
+ return false
+ }
+
+ secName = strings.ToLower(secName)
+
+ sec := in.getSection(secName, subName)
+ if sec != nil {
+ return sec.add(key, value)
+ }
+
+ if len(value) == 0 {
+ value = varValueTrue
+ }
+
+ sec = newSection(secName, subName)
+ v := &variable{
+ mode: lineModeValue,
+ key: key,
+ keyLower: strings.ToLower(key),
+ value: value,
+ }
+ sec.vars = append(sec.vars, v)
+ in.secs = append(in.secs, sec)
+
+ return true
+}
+
+//
+// Set the last variable's value in section-subsection that match with the
+// key.
+// If key found it will return true; otherwise it will return false.
+//
+func (in *Ini) Set(secName, subName, key, value string) bool {
+ if len(secName) == 0 || len(key) == 0 {
+ return false
+ }
+
+ secName = strings.ToLower(secName)
+
+ sec := in.getSection(secName, subName)
+ if sec == nil {
+ return false
+ }
+
+ key = strings.ToLower(key)
+
+ return sec.set(key, value)
+}
+
+//
+// Unset remove the last variable's in section and/or subsection that match
+// with the key.
+// If key found it will return true, otherwise it will return false.
+//
+func (in *Ini) Unset(secName, subName, key string) bool {
+ if len(secName) == 0 || len(key) == 0 {
+ return false
+ }
+
+ secName = strings.ToLower(secName)
+
+ sec := in.getSection(secName, subName)
+ if sec == nil {
+ return false
+ }
+
+ sec.unset(key)
+
+ return true
+}
+
+//
// addSection append the new section to the list.
//
func (in *Ini) addSection(sec *section) {
@@ -264,13 +347,11 @@ func (in *Ini) Save(filename string) (err error) {
}
err = in.Write(f)
-
- errClose := f.Close()
- if errClose != nil {
- println("ini.Save:", errClose)
+ if err != nil {
+ return
}
- return
+ return f.Close()
}
//
@@ -287,3 +368,25 @@ func (in *Ini) Write(w io.Writer) (err error) {
return
}
+
+//
+// getSection return the last section that have the same name and/or with
+// subsection's name.
+// Section's name MUST have in lowercase.
+//
+func (in *Ini) getSection(secName, subName string) *section {
+ x := len(in.secs) - 1
+ for ; x >= 0; x-- {
+ if in.secs[x].mode == lineModeEmpty || in.secs[x].mode == lineModeComment {
+ continue
+ }
+ if in.secs[x].nameLower != secName {
+ continue
+ }
+ if in.secs[x].sub != subName {
+ continue
+ }
+ return in.secs[x]
+ }
+ return nil
+}
diff --git a/lib/ini/ini_example_test.go b/lib/ini/ini_example_test.go
index cbdb62bd..06985788 100644
--- a/lib/ini/ini_example_test.go
+++ b/lib/ini/ini_example_test.go
@@ -3,8 +3,41 @@ package ini
import (
"fmt"
"log"
+ "os"
)
+func ExampleIni_Add() {
+ ini := new(Ini)
+
+ ini.Add("", "", "k1", "v1")
+ ini.Add("s1", "", "", "v2")
+
+ ini.Add("s1", "", "k1", "")
+ ini.Add("s1", "", "k1", "v1")
+ ini.Add("s1", "", "k1", "v2")
+ ini.Add("s1", "", "k1", "v1")
+
+ ini.Add("s1", "sub", "k1", "v1")
+ ini.Add("s1", "sub", "k1", "v1")
+
+ ini.Add("s2", "sub", "k1", "v1")
+
+ err := ini.Write(os.Stdout)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ // Output:
+ // [s1]
+ // k1 = true
+ // k1 = v1
+ // k1 = v2
+ // [s1 "sub"]
+ // k1 = v1
+ // [s2 "sub"]
+ // k1 = v1
+}
+
func ExampleIni_Gets() {
input := []byte(`
[section]
@@ -158,3 +191,106 @@ func ExampleIni_Rebase() {
// key = value2
// key = value1
}
+
+func ExampleIni_Set() {
+ input := []byte(`
+[section]
+key=value1 # comment
+key2= ; another comment
+
+[section "sub"]
+key=value1
+
+[section] ; here is comment on section
+key=value2
+key2=false
+
+[section "sub"]
+key=value2
+key=value1
+`)
+
+ ini, err := Parse(input)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ ini.Set("", "sub", "key", "value3")
+ ini.Set("sectionnotexist", "sub", "key", "value3")
+ ini.Set("section", "sub", "key", "value3")
+ ini.Set("section", "", "key", "value4")
+ ini.Set("section", "", "keynotexist", "value4")
+
+ err = ini.Write(os.Stdout)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ //Output:
+ //[section]
+ //key=value1 # comment
+ //key2= ; another comment
+ //
+ //[section "sub"]
+ //key=value1
+ //
+ //[section] ; here is comment on section
+ //key=value4
+ //key2=false
+ //
+ //[section "sub"]
+ //key=value2
+ //key=value3
+}
+
+func ExampleIni_Unset() {
+ input := []byte(`
+[section]
+key=value1 # comment
+key2= ; another comment
+
+[section "sub"]
+key=value1
+
+; here is comment on section
+[section]
+key=value2
+key2=false
+
+[section "sub"]
+key=value2
+key=value1
+`)
+
+ ini, err := Parse(input)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ ini.Unset("", "sub", "keynotexist")
+ ini.Unset("sectionnotexist", "sub", "keynotexist")
+ ini.Unset("section", "sub", "keynotexist")
+ ini.Unset("section", "sub", "key")
+ ini.Unset("section", "", "keynotexist")
+ ini.Unset("section", "", "key")
+
+ err = ini.Write(os.Stdout)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ //Output:
+ //[section]
+ //key=value1 # comment
+ //key2= ; another comment
+ //
+ //[section "sub"]
+ //key=value1
+ //
+ //; here is comment on section
+ //[section]
+ //key2=false
+ //
+ //[section "sub"]
+ //key=value2
+}