0

Change layout to more go-style-ish, replace some modules

* Deejay files, split them to achieve go-style project layout
* Replace logrus with log/slog module to reduce dependencies
* Replace gopkg.in/ini.v1 with github.com/wlevene/ini to make sure all modules BSD licensed
* Update linter config && fix tons of linter warnings
* Update .gitignore
* Update README.md
This commit is contained in:
eleksir
2025-11-09 22:16:04 +03:00
parent c5f4682cb9
commit 79d9a2f604
211 changed files with 12879 additions and 7732 deletions

21
vendor/github.com/wlevene/ini/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2021 levene
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

420
vendor/github.com/wlevene/ini/README.md generated vendored Normal file
View File

@@ -0,0 +1,420 @@
![logo](./logo.png)
# INI Parser & Write Library
ini parser and write library for Golang,easy-use,fast
[![Build Status](https://travis-ci.org/meolu/walden.svg?branch=master)](https://github.com/wlevene/ini)
![version](https://img.shields.io/badge/version-0.1.1-blue)
# Features
* Can be read by []byte
* Can be read by file
* Supports file monitoring and takes effect in real time without reloading
* Unmarshal to Struct
* Marshal to Json
* Write ini to File
# Installation
```shell
go get github.com/wlevene/ini
```
# Example
```go
import (
"fmt"
"github.com/wlevene/ini"
)
```
### GetValue
```go
doc := `
[section]
k=v
[section1]
k1=v1
k2=1
k3=3.5
k4=0.0.0.0
`
v1 := ini.New().Load([]byte(doc)).Section("section1").Get("k1")
fmt.Println(v1)
```
Output
```
v1
```
```go
i := ini.New().Load([]byte(doc))
v1 := i.Section("section1").Get("k1")
v2 := i.GetInt("k2")
v3 := i.GetFloat64("k3")
v4 := i.Get("k4")
v5 := i.GetIntDef("keyint", 10)
v6 := i.GetDef("keys", "defualt")
fmt.Printf("v1:%v v2:%v v3:%v v4:%v v5:%v v6:%v\n", v1, v2, v3, v4, v5, v6)
```
Output
```
v1:v1 v2:1 v3:3.5 v4:0.0.0.0 v5:10 v6:defualt
```
### Marshal2Json
```go
fmt.Println(string(i.Marshal2Json()))
```
Output
```json
{"section":{"k":"v"},"section1":{"k1":"v1","k2":"1","k3":"3.5","k4":"0.0.0.0"}}
```
### Unmarshal Struct
```go
type TestConfig struct {
K string `ini:"k" json:"k,omitempty"`
K1 int `ini:"k1" json:"k1,omitempty"`
K2 float64 `ini:"k2"`
K3 int64 `ini:"k3"`
User User `ini:"user"`
}
type User struct {
Name string `ini:"name"`
Age int `ini:"age"`
}
```
```go
doc := `
k=v
k1=2
k2=2.2
k3=3
[user]
name=tom
age=-23
`
cfg := TestConfig{}
ini.Unmarshal([]byte(doc), &cfg)
fmt.Println("cfg:", cfg)
```
Output
```
cfg: {v 2 2.2 3 {tom -23}}
```
### Parse File
ini file
```ini
; this is comment
; author levene
; date 2021-8-1
a='23'34?::'<>,.'
c=d
[s1]
k=67676
k1 =fdasf
k2= sdafj3490&@)34 34w2
# comment
# 12.0.0.1
[s2]
k=3
k2=945
k3=-435
k4=0.0.0.0
k5=127.0.0.1
k6=levene@github.com
k7=~/.path.txt
k8=./34/34/uh.txt
k9=234@!@#$%^&*()324
k10='23'34?::'<>,.'
```
```go
file := "./test.ini"
ini.New().LoadFile(file).Section("s2").Get("k2")
fmt.Println(string(ini.Marshal2Json()))
```
Output
```
945
```
### Watch File
```go
file := "./test.ini"
idoc := ini.New().WatchFile(file)
v := idoc.Section("s2").Get("k1")
fmt.Println("v:", v1)
// modify k1=v1 ==> k1=v2
time.Sleep(10 * time.Second)
v = idoc.Section("s2").Get("k1")
fmt.Println("v:", v1)
```
Output
```
v: v1
v: v2
```
Print file with json
```go
file := "./test.ini"
fmt.Println(string(ini.New().LoadFile(file).Marshal2Json()))
```
Output
```json
{
"a": "'23'34?::'<>,.'",
"c": "d",
"s1": {
"k": "67676",
"k2": "34w2"
},
"s2": {
"k": "3",
"k10": "'23'34?::'<>,.'",
"k2": "945",
"k3": "-435",
"k4": "0.0.0.0",
"k5": "127.0.0.1",
"k6": "levene@github.com",
"k7": "~/.path.txt",
"k8": "./34/34/uh.txt",
"k9": "234@!@#$%^&*()324"
}
}
```
### Set Ini
```go
doc := `
k =v
[section]
a=b
c=d
`
ini := New().Load([]byte(doc)).Section("section")
fmt.Println("--------------------------------")
ini.Dump()
fmt.Println("--------------------------------")
ini.Set("a", 11).Set("c", 12.3).Section("").Set("k", "SET")
ini.Dump()
v := ini.Section("section").GetInt("a")
if v != 11 {
t.Errorf("Error: %d", v)
}
v1 := ini.GetFloat64("c")
if v1 != 12.3 {
t.Errorf("Error: %f", v1)
}
v2 := ini.Section("").Get("k")
if v2 != "SET" {
t.Errorf("Error: %s", v2)
}
```
### Wirte Ini
```go
filename := "./save.ini"
ini := New().Set("a1", 1)
ini.Save(filename)
fmt.Println(ini.Err())
ini2 := New().Set("a1", 1).Section("s1").Set("a2", "v2")
ini2.Save(filename)
fmt.Println(ini2.Err())
```
### Dump AST struct
```
INIDocNode {
CommentNode {
Comment: ; this is comment
Line: 0
}
CommentNode {
Comment: ; author levene
Line: 1
}
CommentNode {
Comment: ; date 2021-8-1
Line: 2
}
KVNode {
Key: a
Value: '23'34?::'<>,.'
Line: 5
}
KVNode {
Key: c
Value: d
Line: 6
}
Section {
Section: [s1]
Line: 8
KVNode {
Value: 67676
Line: 9
Key: k
}
KVNode {
Key: k1
Value: fdasf
Line: 10
}
KVNode {
Value: 4w2
Line: 11
Key: k2
}
}
CommentNode {
Comment: # comment
Line: 13
}
CommentNode {
Line: 14
Comment: # 12.0.0.1
}
Section {
Section: [s2]
Line: 15
KVNode {
Value: 3
Line: 17
Key: k
}
KVNode {
Value: 945
Line: 20
Key: k2
}
KVNode {
Key: k3
Value: -435
Line: 21
}
KVNode {
Line: 22
Key: k4
Value: 0.0.0.0
}
KVNode {
Line: 24
Key: k5
Value: 127.0.0.1
}
KVNode {
Key: k6
Value: levene@github.com
Line: 25
}
KVNode {
Key: k7
Value: ~/.path.txt
Line: 27
}
KVNode {
Line: 28
Key: k8
Value: ./34/34/uh.txt
}
KVNode {
Key: k9
Value: 234@!@#$%^&*()324
Line: 30
}
KVNode {
Key: k10
Value: '23'34?::'<>,.'
Line: 31
}
}
}
```
## Contributors
## License
[MIT](https://github.com/RichardLitt/standard-readme/blob/master/LICENSE)

551
vendor/github.com/wlevene/ini/ast/ast.go generated vendored Normal file
View File

@@ -0,0 +1,551 @@
package ast
import (
"bytes"
"fmt"
"strings"
)
type NodeType int
type NodeKind int
const (
// TypeBlock indicates that a node is kind of block nodes.
TypeBlock NodeType = iota + 1
// TypeDocument indicates that a node is kind of document nodes.
TypeDocNode
)
var kindMax NodeKind
var kindNames = []string{""}
// NewNodeKind returns a new Kind value.
func NewNodeKind(name string) NodeKind {
kindMax++
kindNames = append(kindNames, name)
return kindMax
}
func (k NodeKind) String() string {
return kindNames[k]
// return ""
}
// A Node interface defines basic AST node functionalities.
type Node interface {
// Type returns a type of this node.
Type() NodeType
// Kind returns a kind of this node.
Kind() NodeKind
// NextSibling returns a next sibling node of this node.
NextSibling() Node
// PreviousSibling returns a previous sibling node of this node.
PreviousSibling() Node
// Parent returns a parent node of this node.
Parent() Node
// SetParent sets a parent node to this node.
SetParent(Node)
// SetPreviousSibling sets a previous sibling node to this node.
SetPreviousSibling(Node)
// SetNextSibling sets a next sibling node to this node.
SetNextSibling(Node)
// HasChildren returns true if this node has any children, otherwise false.
HasChildren() bool
// ChildCount returns a total number of children.
ChildCount() int
// FirstChild returns a first child of this node.
FirstChild() Node
// LastChild returns a last child of this node.
LastChild() Node
// AppendChild append a node child to the tail of the children.
AppendChild(self, child Node)
// RemoveChild removes a node child from this node.
// If a node child is not children of this node, RemoveChild nothing to do.
RemoveChild(self, child Node)
// RemoveChildren removes all children from this node.
RemoveChildren(self Node)
// SortChildren sorts childrens by comparator.
SortChildren(comparator func(n1, n2 Node) int)
// ReplaceChild replace a node v1 with a node insertee.
// If v1 is not children of this node, ReplaceChild append a insetee to the
// tail of the children.
ReplaceChild(self, v1, insertee Node)
// InsertBefore inserts a node insertee before a node v1.
// If v1 is not children of this node, InsertBefore append a insetee to the
// tail of the children.
InsertBefore(self, v1, insertee Node)
// InsertAfterinserts a node insertee after a node v1.
// If v1 is not children of this node, InsertBefore append a insetee to the
// tail of the children.
InsertAfter(self, v1, insertee Node)
IsRoot() bool
Depth() int
IsLeaf() bool
// OwnerDocument returns this node's owner document.
// If this node is not a child of the Document node, OwnerDocument
// returns nil.
// OwnerDocument() *Document
// Dump dumps an AST tree structure to stdout.
// This function completely aimed for debugging.
// level is a indent level. Implementer should indent informations with
// 2 * level spaces.
Dump(source []byte, level int)
// Text returns text values of this node.
Text(source []byte) []byte
// HasBlankPreviousLines returns true if the row before this node is blank,
// otherwise false.
// This method is valid only for block nodes.
// HasBlankPreviousLines() bool
// SetBlankPreviousLines sets whether the row before this node is blank.
// This method is valid only for block nodes.
// SetBlankPreviousLines(v bool)
// Lines returns text segments that hold positions in a source.
// This method is valid only for block nodes.
// Lines() *textm.Segments
// SetLines sets text segments that hold positions in a source.
// This method is valid only for block nodes.
// SetLines(*textm.Segments)
// IsRaw returns true if contents should be rendered as 'raw' contents.
IsRaw() bool
// SetAttribute sets the given value to the attributes.
SetAttribute(name []byte, value interface{})
// SetAttributeString sets the given value to the attributes.
SetAttributeString(name string, value interface{})
// Attribute returns a (attribute value, true) if an attribute
// associated with the given name is found, otherwise
// (nil, false)
Attribute(name []byte) (interface{}, bool)
// AttributeString returns a (attribute value, true) if an attribute
// associated with the given name is found, otherwise
// (nil, false)
AttributeString(name string) (interface{}, bool)
// Attributes returns a list of attributes.
// This may be a nil if there are no attributes.
Attributes() []Attribute
// RemoveAttributes removes all attributes from this node.
RemoveAttributes()
}
type Attribute struct {
Name []byte
Value interface{}
}
// A BaseNode struct implements the Node interface partialliy.
type BaseNode struct {
firstChild Node
lastChild Node
parent Node
next Node
prev Node
childCount int
attributes []Attribute
}
func ensureIsolated(v Node) {
if p := v.Parent(); p != nil {
p.RemoveChild(p, v)
}
}
func (n *BaseNode) Kind() NodeKind {
return 0
}
func (n *BaseNode) Type() NodeType {
return 0
}
func (n *BaseNode) Depth() int {
depth := 0
var i_node Node
i_node = n.Parent()
if i_node == nil {
return depth
}
for {
i_node = i_node.Parent()
if i_node == nil {
break
}
depth = depth + 1
}
return depth
}
// IsRoot checks if node is a root node
func (n *BaseNode) IsRoot() bool {
return n.Parent() != nil
}
func (n *BaseNode) IsLeaf() bool {
return n.childCount > 0
}
// HasChildren implements Node.HasChildren .
func (n *BaseNode) HasChildren() bool {
return n.firstChild != nil
}
// SetPreviousSibling implements Node.SetPreviousSibling .
func (n *BaseNode) SetPreviousSibling(v Node) {
n.prev = v
}
// SetNextSibling implements Node.SetNextSibling .
func (n *BaseNode) SetNextSibling(v Node) {
n.next = v
}
// PreviousSibling implements Node.PreviousSibling .
func (n *BaseNode) PreviousSibling() Node {
return n.prev
}
// NextSibling implements Node.NextSibling .
func (n *BaseNode) NextSibling() Node {
return n.next
}
// RemoveChild implements Node.RemoveChild .
func (n *BaseNode) RemoveChild(self, v Node) {
if v.Parent() != self {
return
}
n.childCount--
prev := v.PreviousSibling()
next := v.NextSibling()
if prev != nil {
prev.SetNextSibling(next)
} else {
n.firstChild = next
}
if next != nil {
next.SetPreviousSibling(prev)
} else {
n.lastChild = prev
}
v.SetParent(nil)
v.SetPreviousSibling(nil)
v.SetNextSibling(nil)
}
// RemoveChildren implements Node.RemoveChildren .
func (n *BaseNode) RemoveChildren(self Node) {
for c := n.firstChild; c != nil; {
c.SetParent(nil)
c.SetPreviousSibling(nil)
next := c.NextSibling()
c.SetNextSibling(nil)
c = next
}
n.firstChild = nil
n.lastChild = nil
n.childCount = 0
}
// SortChildren implements Node.SortChildren
func (n *BaseNode) SortChildren(comparator func(n1, n2 Node) int) {
var sorted Node
current := n.firstChild
for current != nil {
next := current.NextSibling()
if sorted == nil || comparator(sorted, current) >= 0 {
current.SetNextSibling(sorted)
if sorted != nil {
sorted.SetPreviousSibling(current)
}
sorted = current
sorted.SetPreviousSibling(nil)
} else {
c := sorted
for c.NextSibling() != nil && comparator(c.NextSibling(), current) < 0 {
c = c.NextSibling()
}
current.SetNextSibling(c.NextSibling())
current.SetPreviousSibling(c)
if c.NextSibling() != nil {
c.NextSibling().SetPreviousSibling(current)
}
c.SetNextSibling(current)
}
current = next
}
n.firstChild = sorted
for c := n.firstChild; c != nil; c = c.NextSibling() {
n.lastChild = c
}
}
// FirstChild implements Node.FirstChild .
func (n *BaseNode) FirstChild() Node {
return n.firstChild
}
// LastChild implements Node.LastChild .
func (n *BaseNode) LastChild() Node {
return n.lastChild
}
// ChildCount implements Node.ChildCount .
func (n *BaseNode) ChildCount() int {
return n.childCount
}
// Parent implements Node.Parent .
func (n *BaseNode) Parent() Node {
return n.parent
}
// SetParent implements Node.SetParent .
func (n *BaseNode) SetParent(v Node) {
n.parent = v
}
// AppendChild implements Node.AppendChild .
func (n *BaseNode) AppendChild(self, v Node) {
ensureIsolated(v)
if n.firstChild == nil {
n.firstChild = v
v.SetNextSibling(nil)
v.SetPreviousSibling(nil)
} else {
last := n.lastChild
last.SetNextSibling(v)
v.SetPreviousSibling(last)
}
v.SetParent(self)
n.lastChild = v
n.childCount++
}
// ReplaceChild implements Node.ReplaceChild .
func (n *BaseNode) ReplaceChild(self, v1, insertee Node) {
n.InsertBefore(self, v1, insertee)
n.RemoveChild(self, v1)
}
// InsertAfter implements Node.InsertAfter .
func (n *BaseNode) InsertAfter(self, v1, insertee Node) {
n.InsertBefore(self, v1.NextSibling(), insertee)
}
// InsertBefore implements Node.InsertBefore .
func (n *BaseNode) InsertBefore(self, v1, insertee Node) {
n.childCount++
if v1 == nil {
n.AppendChild(self, insertee)
return
}
ensureIsolated(insertee)
if v1.Parent() == self {
c := v1
prev := c.PreviousSibling()
if prev != nil {
prev.SetNextSibling(insertee)
insertee.SetPreviousSibling(prev)
} else {
n.firstChild = insertee
insertee.SetPreviousSibling(nil)
}
insertee.SetNextSibling(c)
c.SetPreviousSibling(insertee)
insertee.SetParent(self)
}
}
// // OwnerDocument implements Node.OwnerDocument
// func (n *BaseNode) OwnerDocument() *Document {
// d := n.Parent()
// for {
// p := d.Parent()
// if p == nil {
// if v, ok := d.(*Document); ok {
// return v
// }
// break
// }
// d = p
// }
// return nil
// }
func (n *BaseNode) IsRaw() bool {
return true
}
// Text implements Node.Text .
func (n *BaseNode) Text(source []byte) []byte {
var buf bytes.Buffer
for c := n.firstChild; c != nil; c = c.NextSibling() {
buf.Write(c.Text(source))
}
return buf.Bytes()
}
// SetAttribute implements Node.SetAttribute.
func (n *BaseNode) SetAttribute(name []byte, value interface{}) {
if n.attributes == nil {
n.attributes = make([]Attribute, 0, 10)
} else {
for i, a := range n.attributes {
if bytes.Equal(a.Name, name) {
n.attributes[i].Name = name
n.attributes[i].Value = value
return
}
}
}
n.attributes = append(n.attributes, Attribute{name, value})
}
// SetAttributeString implements Node.SetAttributeString
func (n *BaseNode) SetAttributeString(name string, value interface{}) {
// n.SetAttribute(util.StringToReadOnlyBytes(name), value)
}
// Attribute implements Node.Attribute.
func (n *BaseNode) Attribute(name []byte) (interface{}, bool) {
if n.attributes == nil {
return nil, false
}
for i, a := range n.attributes {
if bytes.Equal(a.Name, name) {
return n.attributes[i].Value, true
}
}
return nil, false
}
// AttributeString implements Node.AttributeString.
func (n *BaseNode) AttributeString(s string) (interface{}, bool) {
// return n.Attribute(util.StringToReadOnlyBytes(s))
return nil, true
}
// Attributes implements Node.Attributes
func (n *BaseNode) Attributes() []Attribute {
return n.attributes
}
// RemoveAttributes implements Node.RemoveAttributes
func (n *BaseNode) RemoveAttributes() {
n.attributes = nil
}
func (n *BaseNode) Dump(source []byte, level int) {
}
// DumpHelper is a helper function to implement Node.Dump.
// kv is pairs of an attribute name and an attribute value.
// cb is a function called after wrote a name and attributes.
func DumpHelper(v Node, source []byte, level int, kv map[string]string, cb func(int)) {
name := v.Kind().String()
indent := strings.Repeat(" ", level)
fmt.Printf("%s%s {\n", indent, name)
indent2 := strings.Repeat(" ", level+1)
// if v.Type() == TypeBlock {
// fmt.Printf("%sRawText: \"", indent2)
// for i := 0; i < v.Lines().Len(); i++ {
// line := v.Lines().At(i)
// fmt.Printf("%s", line.Value(source))
// }
// fmt.Printf("\"\n")
// fmt.Printf("%sHasBlankPreviousLines: %v\n", indent2, v.HasBlankPreviousLines())
// }
for name, value := range kv {
fmt.Printf("%s%s: %s\n", indent2, name, value)
}
if cb != nil {
cb(level + 1)
}
for c := v.FirstChild(); c != nil; c = c.NextSibling() {
c.Dump(source, level+1)
}
fmt.Printf("%s}\n", indent)
}
// WalkStatus represents a current status of the Walk function.
type WalkStatus int
const (
// WalkStop indicates no more walking needed.
WalkStop WalkStatus = iota + 1
// WalkSkipChildren indicates that Walk wont walk on children of current
// node.
WalkSkipChildren
// WalkContinue indicates that Walk can continue to walk.
WalkContinue
)
// Walker is a function that will be called when Walk find a
// new node.
// entering is set true before walks children, false after walked children.
// If Walker returns error, Walk function immediately stop walking.
type Walker func(n Node, entering bool) (WalkStatus, error)
// Walk walks a AST tree by the depth first search algorithm.
func Walk(n Node, walker Walker) error {
_, err := walkHelper(n, walker)
return err
}
func walkHelper(n Node, walker Walker) (WalkStatus, error) {
status, err := walker(n, true)
if err != nil || status == WalkStop {
return status, err
}
if status != WalkSkipChildren {
for c := n.FirstChild(); c != nil; c = c.NextSibling() {
if st, err := walkHelper(c, walker); err != nil || st == WalkStop {
return WalkStop, err
}
}
}
status, err = walker(n, false)
if err != nil || status == WalkStop {
return WalkStop, err
}
return WalkContinue, nil
}

121
vendor/github.com/wlevene/ini/ast/ast_node.go generated vendored Normal file
View File

@@ -0,0 +1,121 @@
package ast
import (
"fmt"
"github.com/wlevene/ini/token"
)
type SetcionNode struct {
BaseNode
Name token.Token
}
var KindSetcion = NewNodeKind("Section")
// Kind implements Node.Kind.
func (n *SetcionNode) Kind() NodeKind {
return KindSetcion
}
func (n *SetcionNode) Type() NodeType {
return TypeDocNode
}
func (n *SetcionNode) IsRaw() bool {
return false
}
// Text implements Node.Text.
func (n *SetcionNode) Text(source []byte) []byte {
return []byte(n.Name.Literal)
}
// Dump implements Node.Dump.
func (n *SetcionNode) Dump(source []byte, level int) {
if n == nil {
return
}
name := n.Name.Literal
m := map[string]string{
"Section": fmt.Sprintf("[%v]", name),
"Line": fmt.Sprintf("%v", n.Name.Line),
}
DumpHelper(n, source, level, m, nil)
}
type KVNode struct {
BaseNode
Key token.Token
Value token.Token
Index int
Line int
}
var KindKVNode = NewNodeKind("KVNode")
// Kind implements Node.Kind.
func (n *KVNode) Kind() NodeKind {
return KindKVNode
}
func (n *KVNode) Type() NodeType {
return TypeDocNode
}
func (n *KVNode) IsRaw() bool {
return false
}
func (n *KVNode) Text(source []byte) []byte {
return source
}
// Dump implements Node.Dump.
func (n *KVNode) Dump(source []byte, level int) {
m := map[string]string{
"Key": fmt.Sprintf("%v", n.Key.Literal),
"Value": fmt.Sprintf("%v", n.Value.Literal),
"Line": fmt.Sprintf("%v", n.Key.Line),
}
DumpHelper(n, source, level, m, nil)
}
type CommentNode struct {
BaseNode
Comment token.Token
}
var KindCommentNode = NewNodeKind("CommentNode")
// Kind implements Node.Kind.
func (n *CommentNode) Kind() NodeKind {
return KindCommentNode
}
func (n *CommentNode) Type() NodeType {
return TypeDocNode
}
func (n *CommentNode) IsRaw() bool {
return false
}
func (n *CommentNode) Text(source []byte) []byte {
return source
}
// Dump implements Node.Dump.
func (n *CommentNode) Dump(source []byte, level int) {
m := map[string]string{
"Comment": fmt.Sprintf("%v", n.Comment.Literal),
"Line": fmt.Sprintf("%v", n.Comment.Line),
}
DumpHelper(n, source, level, m, nil)
}

60
vendor/github.com/wlevene/ini/ast/doc.go generated vendored Normal file
View File

@@ -0,0 +1,60 @@
package ast
import "fmt"
type Doc struct {
BaseNode
// KVs []*KVNode
// SectS []*SetcionNode
}
func NewDoc() *Doc {
doc := &Doc{
// KVs: make([]*KVNode, 0),
// SectS: make([]*SetcionNode, 0),
}
return doc
}
func (doc *Doc) DumpV2() {
// for _, item := range doc.KVs {
// item.Dump(nil, 0)
// }
// for _, item := range doc.SectS {
// item.Dump(nil, 0)
// }
DumpHelper(doc, nil, 0, nil, nil)
}
var KindDocNode = NewNodeKind("INIDocNode")
// Kind implements Node.Kind.
func (n *Doc) Kind() NodeKind {
return KindDocNode
}
func (n *Doc) Type() NodeType {
return TypeDocNode
}
func (n *Doc) IsRaw() bool {
return false
}
func (n *Doc) Text(source []byte) []byte {
return source
}
// Dump implements Node.Dump.
func (n *Doc) Dump(source []byte, level int) {
m := map[string]string{
"doc": fmt.Sprintf("%v", string(source)),
}
DumpHelper(n, source, level, m, nil)
}

597
vendor/github.com/wlevene/ini/ini.go generated vendored Normal file
View File

@@ -0,0 +1,597 @@
package ini
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
"strconv"
"strings"
"github.com/wlevene/ini/ast"
"github.com/wlevene/ini/lexer"
"github.com/wlevene/ini/parser"
"github.com/wlevene/ini/token"
"github.com/fsnotify/fsnotify"
)
// TODO: new section
type (
Ini struct {
currectSection *ast.SetcionNode
src []byte // source
l *lexer.Lexer
p *parser.Parser
doc *ast.Doc
err error
watcher *fsnotify.Watcher
exitWatchChan chan bool
}
)
func New() *Ini {
in := &Ini{
doc: &ast.Doc{},
}
return in
}
func (in *Ini) Err() error {
return in.err
}
func (in *Ini) LoadFile(file string) *Ini {
// read file content
bts, err := ioutil.ReadFile(file)
if err != nil {
in.err = err
return in
}
in.Load(bts)
return in
}
func (in *Ini) WatchFile(file string) *Ini {
in.LoadFile(file)
in.watch(file)
return in
}
func (in *Ini) watch(file string) {
if file == "" {
return
}
in.watcher, in.err = fsnotify.NewWatcher()
in.exitWatchChan = make(chan bool)
go func() {
for {
select {
case event, ok := <-in.watcher.Events:
if !ok {
return
}
if event.Op&fsnotify.Write == fsnotify.Write {
in.LoadFile(file)
}
case _, ok := <-in.watcher.Errors:
if !ok {
return
}
case <-in.exitWatchChan:
return
}
}
}()
in.err = in.watcher.Add(file)
}
func (in *Ini) StopWatch() *Ini {
in.watcher.Close()
in.exitWatchChan <- true
return in
}
func (in *Ini) Load(doc []byte) *Ini {
if len(doc) <= 0 {
return in
}
in.src = doc
in.l = lexer.New(string(in.src))
in.p = parser.New(in.l)
in.doc, in.err = in.p.ParseDocument()
return in
}
func (in *Ini) Dump() {
if in.doc == nil {
return
}
in.doc.DumpV2()
}
func (this *Ini) Marshal2Map() map[string]interface{} {
if this.doc == nil {
return nil
}
if this.err != nil {
return nil
}
kvMaps := make(map[string]interface{})
for c := this.doc.FirstChild(); c != nil; c = c.NextSibling() {
if kv_node, ok := c.(*ast.KVNode); ok {
kvMaps[kv_node.Key.Literal] = kv_node.Value.Literal
}
if sect_node, ok := c.(*ast.SetcionNode); ok {
secMap := make(map[string]interface{})
for kv := sect_node.FirstChild(); kv != nil; kv = kv.NextSibling() {
if kvnode, ok := kv.(*ast.KVNode); ok {
secMap[kvnode.Key.Literal] = kvnode.Value.Literal
}
}
kvMaps[sect_node.Name.Literal] = secMap
continue
}
}
return kvMaps
}
func (this *Ini) Marshal2Json() []byte {
kvMaps := this.Marshal2Map()
if kvMaps == nil {
return nil
}
result, err := json.Marshal(kvMaps)
this.err = err
return result
}
func (this *Ini) Section(section string) *Ini {
if this.doc == nil {
return this
}
if this.err != nil {
return this
}
this.sectionForAstDoc(section)
return this
}
func (this *Ini) Get(key string) string {
return this.GetDef(key, "")
}
func (this *Ini) GetDef(key string, def string) string {
if this.doc == nil ||
this.err != nil {
return def
}
if key == "" {
return def
}
tok := this.getToken(key)
if tok.Type != token.TokenType_VALUE {
return def
}
return tok.Literal
}
func (this *Ini) GetInt(key string) int {
return this.GetIntDef(key, 0)
}
func (this *Ini) GetIntDef(key string, def int) int {
val := this.Get(key)
if val == "" {
return def
}
ival, err := strconv.Atoi(val)
if err != nil {
return def
}
return ival
}
func (this *Ini) GetInt64(key string) int64 {
return this.GetInt64Def(key, 0)
}
func (this *Ini) GetInt64Def(key string, def int64) int64 {
val := this.Get(key)
if val == "" {
return def
}
ival, err := strconv.ParseInt(val, 10, 64)
if err != nil {
return def
}
return ival
}
func (this *Ini) GetFloat64(key string) float64 {
return this.GetFloat64Def(key, 0)
}
func (this *Ini) GetFloat64Def(key string, def float64) float64 {
val := this.Get(key)
if val == "" {
return def
}
fval, err := strconv.ParseFloat(val, 64)
if err != nil {
return def
}
return fval
}
func (this *Ini) Set(key string, val interface{}) *Ini {
if this.doc == nil ||
this.err != nil {
return this
}
if key == "" || val == nil {
return this
}
var val_str string
switch val.(type) {
case int:
val_str = fmt.Sprintf("%d", val.(int))
case int32:
val_str = fmt.Sprintf("%d", val.(int32))
case int64:
val_str = fmt.Sprintf("%d", val.(int64))
case float32:
val_str = strconv.FormatFloat(float64(val.(float32)), 'f', -1, 32)
case float64:
val_str = strconv.FormatFloat(float64(val.(float64)), 'f', -1, 64)
case string:
val_str = val.(string)
default:
return this
}
val_str = strings.Replace(val_str, "\n", "", -1)
val_str = strings.Replace(val_str, "\t", "", -1)
val_str = strings.Trim(val_str, " ")
this.setKVNode(key, val_str)
return this
}
func (this *Ini) Del(key string) *Ini {
if this.doc == nil ||
this.err != nil {
return this
}
if key == "" {
return this
}
if this.currectSection == nil {
for c := this.doc.FirstChild(); c != nil; c = c.NextSibling() {
if kv_node, ok := c.(*ast.KVNode); ok {
if kv_node.Key.Literal == key {
this.doc.RemoveChild(this.doc, kv_node)
break
}
continue
}
// if sect_node, ok := c.(*ast.SetcionNode); ok {
// continue
// }
}
} else {
for c := this.currectSection.FirstChild(); c != nil; c = c.NextSibling() {
kvnodev2 := c.(*ast.KVNode)
if kvnodev2.Key.Literal == key {
this.currectSection.RemoveChild(this.currectSection, c)
break
}
}
}
return this
}
func (this *Ini) DelSection(section string) *Ini {
if this.doc == nil ||
this.err != nil {
return this
}
if section == "" {
return this
}
if this.currectSection == nil {
for c := this.doc.FirstChild(); c != nil; c = c.NextSibling() {
if sect_node, ok := c.(*ast.SetcionNode); ok {
if sect_node.Name.Literal == section {
this.doc.RemoveChild(this.doc, sect_node)
break
}
}
}
}
return this
}
// TODO: implement Save
func (this *Ini) Save(filename string) *Ini {
if filename == "" {
return this
}
if this.doc == nil {
return this
}
var result string
is_last_type_comment := false
for c := this.doc.FirstChild(); c != nil; c = c.NextSibling() {
if kv_node, ok := c.(*ast.KVNode); ok {
is_last_type_comment = false
result = fmt.Sprintf("%s%s = %v\n", result, kv_node.Key.Literal, kv_node.Value.Literal)
continue
}
if sect_node, ok := c.(*ast.SetcionNode); ok {
if !is_last_type_comment {
result = fmt.Sprintf("%s\n", result)
}
is_last_type_comment = false
result = fmt.Sprintf("%s[%s]\n", result, sect_node.Name.Literal)
for c := sect_node.FirstChild(); c != nil; c = c.NextSibling() {
if kv_node, ok := c.(*ast.KVNode); ok {
result = fmt.Sprintf("%s%s = %v\n", result, kv_node.Key.Literal, kv_node.Value.Literal)
continue
}
}
continue
}
if comm_node, ok := c.(*ast.CommentNode); ok {
if !is_last_type_comment {
result = fmt.Sprintf("%s\n", result)
}
is_last_type_comment = true
result = fmt.Sprintf("%s%s\n", result, comm_node.Comment.Literal)
}
}
this.err = os.Remove(filename)
if this.err != nil {
return this
}
var data = []byte(result)
this.err = ioutil.WriteFile(filename, data, 0666)
return this
}
// ----------------------------------------------------------------
func (this *Ini) sectionForAstDoc(section string) {
if this.doc == nil ||
this.err != nil {
return
}
this.currectSection = nil
if section == "" {
return
}
for c := this.doc.FirstChild(); c != nil; c = c.NextSibling() {
if sect_node, ok := c.(*ast.SetcionNode); ok {
if sect_node.Name.Literal == section {
this.currectSection = sect_node
return
}
}
}
this.currectSection = &ast.SetcionNode{
Name: token.Token{
Type: token.TokenType_SECTION,
Literal: section,
},
}
this.doc.AppendChild(this.doc, this.currectSection)
}
func (this *Ini) getToken(key string) token.Token {
var tok token.Token
if key == "" {
return tok
}
if this.currectSection == nil {
for c := this.doc.FirstChild(); c != nil; c = c.NextSibling() {
if kv_node, ok := c.(*ast.KVNode); ok {
if kv_node.Key.Literal == key {
tok = kv_node.Value
return tok
}
continue
}
}
} else {
for c := this.currectSection.FirstChild(); c != nil; c = c.NextSibling() {
kvnodev2 := c.(*ast.KVNode)
if kvnodev2.Key.Literal == key {
tok = kvnodev2.Value
return tok
}
}
}
return tok
}
func (this *Ini) setKVNode(key string, val string) *Ini {
if key == "" || val == "" {
return this
}
line := 1
found := false
if this.currectSection == nil {
var last_kv_node *ast.KVNode
for c := this.doc.FirstChild(); c != nil; c = c.NextSibling() {
if kv_node, ok := c.(*ast.KVNode); ok {
last_kv_node = kv_node
if kv_node.Key.Literal == key {
kv_node.Value.Literal = val
return this
}
continue
}
// if sect_node, ok := c.(*ast.SetcionNode); ok {
// continue
// }
}
kvnode := &ast.KVNode{
Key: token.Token{
Type: token.TokenType_KEY,
Literal: key,
Line: line,
},
Value: token.Token{
Type: token.TokenType_VALUE,
Literal: val,
Line: line,
},
}
if last_kv_node == nil {
this.doc.AppendChild(this.doc, kvnode)
} else {
this.doc.InsertAfter(this.doc, last_kv_node, kvnode)
}
this.re_adjust_node_line()
} else {
for c := this.currectSection.FirstChild(); c != nil; c = c.NextSibling() {
kvnodev2 := c.(*ast.KVNode)
line = kvnodev2.Key.Line + 1
if kvnodev2.Key.Literal == key {
kvnodev2.Value.Literal = val
return this
}
}
if found == false {
kvnode := &ast.KVNode{
Key: token.Token{
Type: token.TokenType_KEY,
Literal: key,
Line: line,
},
Value: token.Token{
Type: token.TokenType_VALUE,
Literal: val,
Line: line,
},
}
this.currectSection.AppendChild(this.currectSection, kvnode)
this.re_adjust_node_line()
}
}
return this
}
// TODO: support
func (this *Ini) re_adjust_node_line() {
}

195
vendor/github.com/wlevene/ini/ini_tag.go generated vendored Normal file
View File

@@ -0,0 +1,195 @@
package ini
import (
"errors"
"fmt"
"reflect"
"strconv"
"strings"
)
func Unmarshal(data []byte, v interface{}) error {
if data == nil {
return nil
}
mp := New().Load(data).Marshal2Map()
fmt.Println("map:", mp)
bindTag("ini", v, mp)
return nil
}
// Bind binds the content of data into the struct s
func bindTag(tagName string, s interface{}, data map[string]interface{}) interface{} {
if s == nil {
return nil
}
t := reflect.TypeOf(s)
tk := t.Kind()
if tk != reflect.Ptr {
return nil
}
t = t.Elem()
tk = t.Kind()
if tk != reflect.Struct {
return nil
}
v := reflect.ValueOf(s).Elem()
for i := 0; i < t.NumField(); i++ {
f := t.Field(i)
fi := parseField(tagName, f)
fv := v.FieldByName(fi.Name)
fk := fv.Kind()
ft := fv.Type()
if v, ok := data[fi.Alias]; ok {
vt := reflect.TypeOf(v)
vk := vt.Kind()
if !vt.AssignableTo(ft) {
change_fun := func(k reflect.Kind, v interface{}) (val reflect.Value, err error) {
err = errors.New("unsupper kind")
var str_v string
var ok bool
if str_v, ok = v.(string); !ok {
return
}
// str_v = v.(string)
if k == reflect.Int {
rv, er := strconv.Atoi(str_v)
if er == nil {
val = reflect.ValueOf(rv)
err = nil
}
} else if k == reflect.Int8 {
rv, er := strconv.ParseInt(str_v, 10, 8)
if er == nil {
val = reflect.ValueOf(rv)
err = nil
}
} else if k == reflect.Int16 {
rv, er := strconv.ParseInt(str_v, 10, 16)
if er == nil {
val = reflect.ValueOf(rv)
err = nil
}
} else if k == reflect.Int32 {
rv, er := strconv.ParseInt(str_v, 10, 32)
if er == nil {
val = reflect.ValueOf(rv)
err = nil
}
} else if k == reflect.Int64 {
rv, er := strconv.ParseInt(str_v, 10, 64)
if er == nil {
val = reflect.ValueOf(rv)
err = nil
}
} else if k == reflect.Float32 {
rv, er := strconv.ParseFloat(str_v, 32)
if er == nil {
val = reflect.ValueOf(float32(rv))
err = nil
}
} else if k == reflect.Float64 {
rv, er := strconv.ParseFloat(str_v, 64)
if er == nil {
val = reflect.ValueOf(rv)
err = nil
}
}
return val, err
}
val, err := change_fun(fk, v)
if err == nil {
fv.Set(val)
continue
}
} else {
fv.Set(reflect.ValueOf(v))
continue
}
if fk == reflect.Struct && vk == reflect.Map {
if fv.CanInterface() {
bindTag(tagName, fv.Addr().Interface(), v.(map[string]interface{}))
continue
}
}
}
}
return s
}
func bindSlice(tagName string, s reflect.Value, data []interface{}) {
// sk := s.Kind()
et := s.Type().Elem()
ek := et.Kind()
ret := reflect.MakeSlice(et, s.Len(), s.Cap())
vet := reflect.TypeOf(data).Elem()
if vet.AssignableTo(et) {
for i := 0; i < s.Len(); i++ {
ret.Index(i).Set(reflect.ValueOf(data[i]))
}
} else if ek == reflect.Struct {
for i := 0; i < s.Len(); i++ {
// v := Bind(tagName, ret.Index(i).Addr().Interface(), data[i].(map[string]interface{}))
v := bindTag(tagName, ret.Index(i).Addr().Interface(), data[i].(map[string]interface{}))
ret.Index(i).Set(reflect.ValueOf(v))
}
}
}
type fieldInfo struct {
Alias string
Name string
}
// ParseField parses [FieldInfo] for the given struct field [f] from struct tag with name [tagName]
func parseField(tagName string, f reflect.StructField) *fieldInfo {
var parts []string
alias := f.Name
tag, tagOk := f.Tag.Lookup(tagName)
if tagOk {
partsTemp := strings.Split(tag, ",")
parts = make([]string, 0, len(partsTemp))
for i := 0; i < len(partsTemp); i++ {
part := strings.TrimSpace(partsTemp[i])
if len(part) != 0 {
parts = append(parts, part)
}
}
}
if len(parts) != 0 {
alias = parts[0]
// TODO parse other tags
}
return &fieldInfo{
Alias: alias,
Name: f.Name,
}
}

234
vendor/github.com/wlevene/ini/lexer/lexer.go generated vendored Normal file
View File

@@ -0,0 +1,234 @@
package lexer
import (
"github.com/wlevene/ini/token"
)
const (
LineBreak = '\n'
)
type Lexer struct {
Input []byte
char byte
position int
read_position int
line int
}
func New(input string) *Lexer {
l := &Lexer{Input: []byte(input)}
l.readChar()
return l
}
func (l *Lexer) peekChar() byte {
if l.read_position >= len(l.Input) {
return 0
} else {
return l.Input[l.read_position]
}
}
func (l *Lexer) readChar() {
if l.read_position >= len(l.Input) {
l.char = 0
} else {
l.char = l.Input[l.read_position]
}
if l.char == LineBreak {
l.line++
}
l.position = l.read_position
l.read_position++
}
func (l *Lexer) readLine() []byte {
position := l.position
for {
if l.char == LineBreak {
break
}
l.readChar()
}
return l.Input[position:l.position]
}
func (l *Lexer) skipWhitespace() {
for l.char == ' ' ||
l.char == '\t' ||
l.char == LineBreak ||
l.char == '\r' {
l.readChar()
}
}
func (l *Lexer) skipspace() {
for l.char == ' ' {
l.readChar()
}
// for l.char == ' ' ||
// l.char == '\t' {
// l.readChar()
// }
}
func (l *Lexer) skipline() {
for {
if l.char == LineBreak {
// l.line++
break
}
l.readChar()
}
}
func (l *Lexer) NextToken() token.Token {
var tok token.Token
var ch byte
l.skipWhitespace()
switch l.char {
case '[':
tok = newToken(token.TokenType_LBRACKET, l.char, l.line)
case '=':
tok = newToken(token.TokenType_ASSIGN, l.char, l.line)
case ']':
tok = newToken(token.TokenType_RBRACKET, l.char, l.line)
case 0:
tok.Literal = ""
tok.Type = token.TokenType_EOF
return tok
case '#':
fallthrough
case ';':
tok.Line = l.line
tok.Literal = string(l.readLine())
tok.Type = token.TokenType_COMMENT
default:
tok.Line = l.line
tok.Literal = string(l.readStatement())
l.skipspace()
ch = l.char
if ch == '=' {
tok.Type = token.TokenType_KEY
} else if ch == ']' {
tok.Type = token.TokenType_SECTION
} else if ch == LineBreak {
tok.Type = token.TokenType_VALUE
}
}
l.readChar()
return tok
}
/*
func (s *lexer) getNextToken() token.Token {
reToken:
ch := s.peek()
switch {
case isSpace(ch):
s.skipWhitespace()
goto reToken
case isEOF(ch):
return s.NewToken(token.EOF).Lit(string(s.read()))
case ch == ';':
return s.NewToken(token.Semicolon).Lit(string(s.read()))
case ch == '{':
return s.NewToken(token.BlockStart).Lit(string(s.read()))
case ch == '}':
return s.NewToken(token.BlockEnd).Lit(string(s.read()))
case ch == '#':
return s.scanComment()
case ch == '$':
return s.scanVariable()
case isQuote(ch):
return s.scanQuotedString(ch)
default:
return s.scanKeyword()
}
}
*/
func isLetter(ch byte) bool {
return 'a' <= ch && ch <= 'z' || 'A' <= ch && ch <= 'Z' || ch == '_'
}
func isDigit(ch byte) bool {
return ('0' <= ch && ch <= '9') || ch == '.'
}
func newToken(tokenType token.TokenType, ch byte, line int) token.Token {
return token.Token{Type: tokenType,
Literal: string(ch),
Line: line,
}
}
func (l *Lexer) readStatement() []byte {
position := l.position
for l.char != LineBreak &&
l.char != '=' &&
l.char != ']' &&
l.char != ' ' {
l.readChar()
}
return l.Input[position:l.position]
}
func (l *Lexer) readSection() token.Token {
var tok token.Token
if l.char != '[' {
return tok
}
position := l.position
for {
if l.char != ']' {
l.readChar()
}
if l.char == LineBreak {
break
}
}
return token.Token{
Type: token.TokenType_SECTION,
Literal: string(l.Input[position:l.position]),
Line: l.line,
}
}
/*
func (s *lexer) read() rune {
ch, _, err := s.reader.ReadRune()
if err != nil {
return rune(token.EOF)
}
if ch == '\n' {
s.column = 1
s.line++
} else {
s.column++
}
return ch
}
*/

BIN
vendor/github.com/wlevene/ini/logo.png generated vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

113
vendor/github.com/wlevene/ini/parser/parser.go generated vendored Normal file
View File

@@ -0,0 +1,113 @@
package parser
import (
"github.com/wlevene/ini/ast"
"github.com/wlevene/ini/lexer"
"github.com/wlevene/ini/token"
)
// type (
// prefixParseFn func() ast.Expression
// infixParseFn func(ast.Expression) ast.Expression
// )
type Parser struct {
lexer *lexer.Lexer
errors []string
currentToken token.Token
peekToken token.Token
// prefixParseFns map[token.TokenType]prefixParseFn
// infixParseFns map[token.TokenType]infixParseFn
}
func New(l *lexer.Lexer) *Parser {
p := &Parser{
lexer: l,
errors: []string{},
}
// p.prefixParseFns = make(map[token.Type]prefixParseFn)
// p.registerPrefix(token.INTEGER, p.parseIntegerLiteral)
// p.infixParseFns = make(map[token.Type]infixParseFn)
// p.registerInfix(token.PLUS, p.parseInfixExpression)
return p
}
func (p *Parser) ParseDocument() (doc *ast.Doc, err error) {
doc = ast.NewDoc()
// Read two tokens, so currentToken and peekToken are both set.
p.nextToken()
p.nextToken()
var curSection *ast.SetcionNode
var KV *ast.KVNode
for !p.curTokenIs(token.TokenType_EOF) {
if p.currentToken.Type == token.TokenType_SECTION {
curSection = nil
curSection = &ast.SetcionNode{
Name: p.currentToken,
}
if curSection != nil {
doc.AppendChild(doc, curSection)
}
} else if p.currentToken.Type == token.TokenType_KEY {
KV = nil
KV = &ast.KVNode{}
KV.Key = p.currentToken
} else if p.currentToken.Type == token.TokenType_VALUE {
if KV != nil {
KV.Value = p.currentToken
if curSection != nil {
curSection.AppendChild(curSection, KV)
} else {
doc.AppendChild(doc, KV)
}
}
} else if p.currentToken.Type == token.TokenType_COMMENT {
comment := &ast.CommentNode{
Comment: p.currentToken,
}
doc.AppendChild(doc, comment)
}
p.nextToken()
}
return doc, nil
}
func (p *Parser) nextToken() {
p.currentToken = p.peekToken
p.peekToken = p.lexer.NextToken()
}
func (p *Parser) curTokenIs(t token.TokenType) bool {
return p.currentToken.Type == t
}
func (p *Parser) peekTokenIs(t token.TokenType) bool {
return p.peekToken.Type == t
}
// func (p *Parser) registerPrefix(tokenType token.TokenType, fn prefixParseFn) {
// p.prefixParseFns[tokenType] = fn
// }
// func (p *Parser) registerInfix(tokenType token.TokenType, fn infixParseFn) {
// p.infixParseFns[tokenType] = fn
// }
func (p *Parser) peekTokenAtSameLine() bool {
return p.currentToken.Line == p.peekToken.Line && p.peekToken.Type != token.TokenType_EOF
}

4
vendor/github.com/wlevene/ini/save.ini generated vendored Normal file
View File

@@ -0,0 +1,4 @@
a1 = 1
[s1]
a2 = v2

32
vendor/github.com/wlevene/ini/test.ini generated vendored Normal file
View File

@@ -0,0 +1,32 @@
; this is comment
; author levene
; date 2021-8-1
a='23'34?::'<>,.'
c=d
[s1]
k=67676
k1 =fdasf
k2= sdafj3490&@)34 34w2
# comment
# 12.0.0.1
[s2]
k=3
k2=945
k3=-435
k4=0.0.0.0
k5=127.0.0.1
k6=levene@github.com
k7=~/.path.txt
k8=./34/34/uh.txt
k9=234@!@#$%^&*()324
k10='23'34?::'<>,.'

18
vendor/github.com/wlevene/ini/test2.ini generated vendored Normal file
View File

@@ -0,0 +1,18 @@
[s2]
k=3
k2=945
k3=-435
k4=0.0.0.0
k5=127.0.0.1
k6=levene@github.com
k7=~/.path.txt
k8=./34/34/uh.txt
k9=234@!@#$%^&*()324
k10='23'34?::'<>,.'

52
vendor/github.com/wlevene/ini/token/token.go generated vendored Normal file
View File

@@ -0,0 +1,52 @@
package token
import "fmt"
type TokenType string
const (
TokenType_ILLEGAL = "ILLEGAL"
TokenType_EOF = "EOF"
Ident = "Ident"
TokenType_SECTION = "SECTION"
TokenType_KEY = "KEY"
TokenType_VALUE = "VALUE"
TokenType_COMMENT = "#"
TokenType_COMMENT2 = "#"
TokenType_ASSIGN = "="
TokenType_LBRACKET = "["
TokenType_RBRACKET = "]"
RETURN = "RETURN"
)
type Token struct {
Type TokenType
Literal string
Line int
}
var keywords = map[string]TokenType{
"return": RETURN,
}
func LookupIdent(ident string) TokenType {
if tok, ok := keywords[ident]; ok {
return tok
}
return Ident
}
func (t Token) String() string {
return fmt.Sprintf("{Type:%s,Literal:\"%s\" Linie:%d}",
t.Type,
t.Literal,
t.Line)
}
//Is check type of a token
func (t Token) Is(typ TokenType) bool {
return t.Type == typ
}