Compare commits
5 Commits
Author | SHA1 | Date | |
---|---|---|---|
c258e6096f | |||
a5976526ae | |||
3d467bd979 | |||
28fe0bda17 | |||
25f6b1537d |
23
.gitignore
vendored
23
.gitignore
vendored
@ -1,20 +1,3 @@
|
|||||||
# Binaries for programs and plugins
|
/bin/
|
||||||
bin/*
|
/test/data/out_ini/
|
||||||
multini
|
/cmd/multini/multini
|
||||||
*.exe
|
|
||||||
*.exe~
|
|
||||||
*.dll
|
|
||||||
*.so
|
|
||||||
*.dylib
|
|
||||||
|
|
||||||
# Test binary, built with `go test -c`
|
|
||||||
*.test
|
|
||||||
|
|
||||||
# Custom binary test
|
|
||||||
tests/out_ini/*
|
|
||||||
|
|
||||||
# Output of the go coverage tool, specifically when used with LiteIDE
|
|
||||||
*.out
|
|
||||||
|
|
||||||
# Dependency directories (remove the comment below to include it)
|
|
||||||
# vendor/
|
|
||||||
|
2
README.md
Normal file
2
README.md
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# multini
|
||||||
|
it's like crudini but for ini files with duplicate parameter names
|
@ -13,43 +13,97 @@ import (
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
// Ng - Named Group
|
// Ng - Named Group
|
||||||
NgPrefix string = `prefix`
|
NgPrefix string = `prefix`
|
||||||
NgPostifx string = `postfix`
|
NgPostifx string = `postfix`
|
||||||
NgSection string = `section`
|
NgSection string = `section`
|
||||||
NgKey string = `key`
|
NgKey string = `key`
|
||||||
NgKeyPostfix string = `key_postfix`
|
NgKeyPostfix string = `key_postfix`
|
||||||
NgValue string = `value`
|
NgValue string = `value`
|
||||||
NgValuePrefix string = `value_prefix`
|
NgValuePrefix string = `value_prefix`
|
||||||
NgValuePostfix string = `value_postfix`
|
NgValuePostfix string = `value_postfix`
|
||||||
NgComment string = `comment`
|
NgComment string = `comment`
|
||||||
NgCommentPrefix string = `comment_prefix`
|
NgData string = `data`
|
||||||
|
|
||||||
RxBodyPrefix string = `(?P<` + NgPrefix + `>\s+)?`
|
RxEmpty string = `^(?P<` + NgPrefix + `>\s+)?$`
|
||||||
RxSectionName string = `\[(?P<` + NgSection + `>.+)\]`
|
RxSection string = `^(?P<` + NgPrefix + `>\s+)?\[(?P<` + NgSection + `>[^\]]+)\](?P<` + NgPostifx + `>\s+)?$`
|
||||||
RxKey string = `(?P<` + NgKey + `>(?:[^;#/=]+[^\s=;#/]|[^;#/=]))?`
|
RxKey string = `^(?P<` + NgPrefix + `>\s+)?(?P<` + NgKey + `>.*[^\s]+)(?P<` + NgKeyPostfix + `>\s+)?$`
|
||||||
RxKeyPostfix string = `(?P<` + NgKeyPostfix + `>\s+)?`
|
RxValue string = `^(?P<` + NgValuePrefix + `>\s+)?(?P<` + NgValue + `>.*[^\s])(?P<` + NgValuePostfix + `>\s+)?$`
|
||||||
RxValuePrefix string = `(?P<` + NgValuePrefix + `>\s+)?`
|
|
||||||
RxValue string = `(?P<` + NgValue + `>(?:[^;#/]+[^\s;#/]|[^;#/]))?`
|
RxEmptyCompile *regexp.Regexp = regexp.MustCompile(RxEmpty)
|
||||||
RxValuePostfix string = `(?P<` + NgValuePostfix + `>\s+)?`
|
RxSectionCompile *regexp.Regexp = regexp.MustCompile(RxSection)
|
||||||
RxKeyVal string = RxKey + RxKeyPostfix + `=` + RxValuePrefix + RxValue + RxValuePostfix
|
RxKeyCompile *regexp.Regexp = regexp.MustCompile(RxKey)
|
||||||
RxBody string = `(?:` + RxSectionName + `|` + RxKeyVal + `)?`
|
RxValueCompile *regexp.Regexp = regexp.MustCompile(RxValue)
|
||||||
RxBodyPostfix string = `(?P<` + NgPostifx + `>\s+)?`
|
|
||||||
RxCommentPrefix string = `(?P<` + NgCommentPrefix + `>([#;]|//)\s*)`
|
|
||||||
RxCommentText string = `(?P<` + NgComment + `>.+)?`
|
|
||||||
RxComment string = `(?:` + RxCommentPrefix + RxCommentText + `)?`
|
|
||||||
Rx string = RxBodyPrefix + RxBody + RxBodyPostfix + RxComment
|
|
||||||
RxCompiled *regexp.Regexp = regexp.MustCompile(Rx)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func rxParse(rx *regexp.Regexp, str string) map[string]string {
|
func parse(str string) map[string]string {
|
||||||
match := rx.FindStringSubmatch(str)
|
var result map[string]string = make(map[string]string)
|
||||||
result := make(map[string]string)
|
var data string
|
||||||
for i, name := range rx.SubexpNames() {
|
|
||||||
|
data, result[NgComment] = getDataComment(str)
|
||||||
|
|
||||||
|
if data != "" {
|
||||||
|
findNamedGroups(data, RxEmptyCompile, &result)
|
||||||
|
}
|
||||||
|
|
||||||
|
if result[NgPrefix] != "" {
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
findNamedGroups(data, RxSectionCompile, &result)
|
||||||
|
|
||||||
|
if result[NgSection] == "" && data != "" {
|
||||||
|
keyPart, valPart := getKeyValue(data)
|
||||||
|
findNamedGroups(keyPart, RxKeyCompile, &result)
|
||||||
|
findNamedGroups(valPart, RxValueCompile, &result)
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func findNamedGroups(str string, Rx *regexp.Regexp, result *map[string]string) {
|
||||||
|
match := Rx.FindStringSubmatch(str)
|
||||||
|
for i, name := range Rx.SubexpNames() {
|
||||||
if i != 0 && name != "" && i <= len(match) {
|
if i != 0 && name != "" && i <= len(match) {
|
||||||
result[name] = match[i]
|
(*result)[name] = match[i]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result
|
}
|
||||||
|
|
||||||
|
func getDataComment(str string) (string, string) {
|
||||||
|
var indexes []int
|
||||||
|
var commentIndex int = -1
|
||||||
|
|
||||||
|
indexes = append(indexes, strings.Index(str, "//"))
|
||||||
|
indexes = append(indexes, strings.Index(str, "#"))
|
||||||
|
indexes = append(indexes, strings.Index(str, ";"))
|
||||||
|
|
||||||
|
for _, index := range indexes {
|
||||||
|
if commentIndex == -1 {
|
||||||
|
if index != -1 {
|
||||||
|
commentIndex = index
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if index != -1 {
|
||||||
|
if commentIndex > index {
|
||||||
|
commentIndex = index
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if commentIndex == -1 {
|
||||||
|
return str, ""
|
||||||
|
} else {
|
||||||
|
return str[:commentIndex], str[commentIndex:]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getKeyValue(data string) (string, string) {
|
||||||
|
index := strings.Index(data, "=")
|
||||||
|
if index != -1 {
|
||||||
|
return data[:index], data[index+1:]
|
||||||
|
}
|
||||||
|
return "", ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func debugMap(el map[string]string) string {
|
func debugMap(el map[string]string) string {
|
||||||
@ -61,14 +115,14 @@ func debugMap(el map[string]string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func appendLine(ini *types.Ini, line string) error {
|
func appendLine(ini *types.Ini, line string) error {
|
||||||
elements := rxParse(RxCompiled, line)
|
// elements := rxParse(line)
|
||||||
|
elements := parse(line)
|
||||||
switch {
|
switch {
|
||||||
case elements[NgSection] != "":
|
case elements[NgSection] != "":
|
||||||
var newSection types.Section
|
var newSection types.Section
|
||||||
newSection.Name = elements[NgSection]
|
newSection.Name = elements[NgSection]
|
||||||
newSection.Prefix = elements[NgPrefix]
|
newSection.Prefix = elements[NgPrefix]
|
||||||
newSection.Postfix = elements[NgPostifx]
|
newSection.Postfix = elements[NgPostifx]
|
||||||
newSection.Comment.Prefix = elements[NgCommentPrefix]
|
|
||||||
newSection.Comment.Value = elements[NgComment]
|
newSection.Comment.Value = elements[NgComment]
|
||||||
if newSection.Line() == line {
|
if newSection.Line() == line {
|
||||||
ini.Sections = append(ini.Sections, &newSection)
|
ini.Sections = append(ini.Sections, &newSection)
|
||||||
@ -87,7 +141,6 @@ func appendLine(ini *types.Ini, line string) error {
|
|||||||
newKeyValue.PrefixValue = elements[NgValuePrefix]
|
newKeyValue.PrefixValue = elements[NgValuePrefix]
|
||||||
newKeyValue.PostfixValue = elements[NgValuePostfix]
|
newKeyValue.PostfixValue = elements[NgValuePostfix]
|
||||||
newKeyValue.Comment.Value = elements[NgComment]
|
newKeyValue.Comment.Value = elements[NgComment]
|
||||||
newKeyValue.Comment.Prefix = elements[NgCommentPrefix]
|
|
||||||
if newKeyValue.Line() == line {
|
if newKeyValue.Line() == line {
|
||||||
ini.Sections[len(ini.Sections)-1].(*types.Section).Lines = append(ini.Sections[len(ini.Sections)-1].(*types.Section).Lines, &newKeyValue)
|
ini.Sections[len(ini.Sections)-1].(*types.Section).Lines = append(ini.Sections[len(ini.Sections)-1].(*types.Section).Lines, &newKeyValue)
|
||||||
return nil
|
return nil
|
||||||
@ -98,8 +151,8 @@ func appendLine(ini *types.Ini, line string) error {
|
|||||||
}
|
}
|
||||||
case elements[NgComment] != "":
|
case elements[NgComment] != "":
|
||||||
var newComment types.Comment
|
var newComment types.Comment
|
||||||
newComment.Prefix = elements[NgPrefix] + elements[NgCommentPrefix]
|
|
||||||
newComment.Value = elements[NgComment]
|
newComment.Value = elements[NgComment]
|
||||||
|
newComment.Prefix = elements[NgPrefix]
|
||||||
if newComment.Line() == line {
|
if newComment.Line() == line {
|
||||||
ini.Sections[len(ini.Sections)-1].(*types.Section).Lines = append(ini.Sections[len(ini.Sections)-1].(*types.Section).Lines, &newComment)
|
ini.Sections[len(ini.Sections)-1].(*types.Section).Lines = append(ini.Sections[len(ini.Sections)-1].(*types.Section).Lines, &newComment)
|
||||||
return nil
|
return nil
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# comment
|
# comment
|
||||||
; comment again
|
; comment again
|
||||||
|
// comment with indent
|
||||||
DefKey1 = Some Value1
|
DefKey1 = Some Value1
|
||||||
DefKey2 = Some Value2 And Tabs! # With Comment
|
DefKey2 = Some Value2 And Tabs! # With Comment
|
||||||
DefKey3=NoSpaces!
|
DefKey3=NoSpaces!
|
||||||
|
1
test/data/expected_ini/test_get_key_slashes.sh.ini
Normal file
1
test/data/expected_ini/test_get_key_slashes.sh.ini
Normal file
@ -0,0 +1 @@
|
|||||||
|
skip/skip
|
@ -1,6 +1,6 @@
|
|||||||
# comment
|
# comment
|
||||||
; comment again
|
; comment again
|
||||||
|
// comment with indent
|
||||||
DefKey1 = Some Value1
|
DefKey1 = Some Value1
|
||||||
DefKey2 = Some Value2 And Tabs! # With Comment
|
DefKey2 = Some Value2 And Tabs! # With Comment
|
||||||
DefKey3=NoSpaces!
|
DefKey3=NoSpaces!
|
||||||
|
19
test/data/in_ini/test_get_key_slashes.sh.ini
Normal file
19
test/data/in_ini/test_get_key_slashes.sh.ini
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
# comment
|
||||||
|
; comment again
|
||||||
|
|
||||||
|
DefKey1 = Some Value1
|
||||||
|
DefKey2 = Some Value2 And Tabs! # With Comment
|
||||||
|
DefKey3=NoSpaces!
|
||||||
|
|
||||||
|
[Slashes/Test] // Comment For Section
|
||||||
|
./Dir1/File = skip/skip // comment
|
||||||
|
Key2 = 2
|
||||||
|
|
||||||
|
[MultipleKeySection] // C style comment
|
||||||
|
Key = 1
|
||||||
|
Key = 2
|
||||||
|
Key = 3
|
||||||
|
|
||||||
|
[SectionWithIndent]
|
||||||
|
Key=Value
|
||||||
|
[SectionWithoutNewLineBefore]
|
7
test/data/test_get_key_slashes.sh
Executable file
7
test/data/test_get_key_slashes.sh
Executable file
@ -0,0 +1,7 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
source "common.sh"
|
||||||
|
|
||||||
|
$Multini --get "$InIni" 'Slashes/Test' './Dir1/File' > "$OutIni"
|
||||||
|
|
||||||
|
compare
|
Reference in New Issue
Block a user