pax_global_header00006660000000000000000000000064125473542030014517gustar00rootroot0000000000000052 comment=5811abcabb29d6af0fdf060f96d328962bd3cd5e golang-github-naoina-toml-0.0~git20170709.5811abc/000077500000000000000000000000001254735420300211205ustar00rootroot00000000000000golang-github-naoina-toml-0.0~git20170709.5811abc/.travis.yml000066400000000000000000000001331254735420300232260ustar00rootroot00000000000000language: go go: - 1.3 - tip install: - go get -v ./... script: - go test ./... golang-github-naoina-toml-0.0~git20170709.5811abc/LICENSE000066400000000000000000000020621254735420300221250ustar00rootroot00000000000000Copyright (c) 2014 Naoya Inada 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. golang-github-naoina-toml-0.0~git20170709.5811abc/Makefile000066400000000000000000000002631254735420300225610ustar00rootroot00000000000000GO = go PEG = peg .SUFFIXES: .peg .peg.go .PHONY: all test clean all: parse.peg.go .peg.peg.go: $(PEG) -switch -inline $< test: all $(GO) test ./... clean: $(RM) *.peg.go golang-github-naoina-toml-0.0~git20170709.5811abc/README.md000066400000000000000000000121531254735420300224010ustar00rootroot00000000000000# TOML parser and encoder library for Golang [![Build Status](https://travis-ci.org/naoina/toml.png?branch=master)](https://travis-ci.org/naoina/toml) [TOML](https://github.com/toml-lang/toml) parser and encoder library for [Golang](http://golang.org/). This library is compatible with TOML version [v0.4.0](https://github.com/toml-lang/toml/blob/master/versions/en/toml-v0.4.0.md). ## Installation go get -u github.com/naoina/toml ## Usage The following TOML save as `example.toml`. ```toml # This is a TOML document. Boom. title = "TOML Example" [owner] name = "Lance Uppercut" dob = 1979-05-27T07:32:00-08:00 # First class dates? Why not? [database] server = "192.168.1.1" ports = [ 8001, 8001, 8002 ] connection_max = 5000 enabled = true [servers] # You can indent as you please. Tabs or spaces. TOML don't care. [servers.alpha] ip = "10.0.0.1" dc = "eqdc10" [servers.beta] ip = "10.0.0.2" dc = "eqdc10" [clients] data = [ ["gamma", "delta"], [1, 2] ] # Line breaks are OK when inside arrays hosts = [ "alpha", "omega" ] ``` Then above TOML will mapping to `tomlConfig` struct using `toml.Unmarshal`. ```go package main import ( "io/ioutil" "os" "time" "github.com/naoina/toml" ) type tomlConfig struct { Title string Owner struct { Name string Dob time.Time } Database struct { Server string Ports []int ConnectionMax uint Enabled bool } Servers map[string]Server Clients struct { Data [][]interface{} Hosts []string } } type Server struct { IP string DC string } func main() { f, err := os.Open("example.toml") if err != nil { panic(err) } defer f.Close() buf, err := ioutil.ReadAll(f) if err != nil { panic(err) } var config tomlConfig if err := toml.Unmarshal(buf, &config); err != nil { panic(err) } // then to use the unmarshaled config... } ``` ## Mappings A key and value of TOML will map to the corresponding field. The fields of struct for mapping must be exported. The rules of the mapping of key are following: #### Exact matching ```toml timeout_seconds = 256 ``` ```go type Config struct { Timeout_seconds int } ``` #### Camelcase matching ```toml server_name = "srv1" ``` ```go type Config struct { ServerName string } ``` #### Uppercase matching ```toml ip = "10.0.0.1" ``` ```go type Config struct { IP string } ``` See the following examples for the value mappings. ### String ```toml val = "string" ``` ```go type Config struct { Val string } ``` ### Integer ```toml val = 100 ``` ```go type Config struct { Val int } ``` All types that can be used are following: * int8 (from `-128` to `127`) * int16 (from `-32768` to `32767`) * int32 (from `-2147483648` to `2147483647`) * int64 (from `-9223372036854775808` to `9223372036854775807`) * int (same as `int32` on 32bit environment, or `int64` on 64bit environment) * uint8 (from `0` to `255`) * uint16 (from `0` to `65535`) * uint32 (from `0` to `4294967295`) * uint64 (from `0` to `18446744073709551615`) * uint (same as `uint` on 32bit environment, or `uint64` on 64bit environment) ### Float ```toml val = 3.1415 ``` ```go type Config struct { Val float32 } ``` All types that can be used are following: * float32 * float64 ### Boolean ```toml val = true ``` ```go type Config struct { Val bool } ``` ### Datetime ```toml val = 2014-09-28T21:27:39Z ``` ```go type Config struct { Val time.Time } ``` ### Array ```toml val = ["a", "b", "c"] ``` ```go type Config struct { Val []string } ``` Also following examples all can be mapped: ```toml val1 = [1, 2, 3] val2 = [["a", "b"], ["c", "d"]] val3 = [[1, 2, 3], ["a", "b", "c"]] val4 = [[1, 2, 3], [["a", "b"], [true, false]]] ``` ```go type Config struct { Val1 []int Val2 [][]string Val3 [][]interface{} Val4 [][]interface{} } ``` ### Table ```toml [server] type = "app" [server.development] ip = "10.0.0.1" [server.production] ip = "10.0.0.2" ``` ```go type Config struct { Server map[string]Server } type Server struct { IP string } ``` You can also use the following struct instead of map of struct. ```go type Config struct { Server struct { Development Server Production Server } } type Server struct { IP string } ``` ### Array of Tables ```toml [[fruit]] name = "apple" [fruit.physical] color = "red" shape = "round" [[fruit.variety]] name = "red delicious" [[fruit.variety]] name = "granny smith" [[fruit]] name = "banana" [[fruit.variety]] name = "plantain" ``` ```go type Config struct { Fruit []struct { Name string Physical struct { Color string Shape string } Variety []struct { Name string } } } ``` ### Using `toml.UnmarshalTOML` interface ```toml duration = "10s" ``` ```go import time type Config struct { Duration Duration } type Duration struct { time.Duration } func (d *Duration) UnmarshalTOML(data []byte) error { d.Duration, err := time.ParseDuration(string(data)) return err } ``` ## API documentation See [Godoc](http://godoc.org/github.com/naoina/toml). ## License MIT golang-github-naoina-toml-0.0~git20170709.5811abc/_example/000077500000000000000000000000001254735420300227125ustar00rootroot00000000000000golang-github-naoina-toml-0.0~git20170709.5811abc/_example/example.toml000066400000000000000000000011371254735420300252440ustar00rootroot00000000000000title = "TOML Example" [owner] name = "Tom Preston-Werner" organization = "GitHub" bio = "GitHub Cofounder & CEO\nLikes tater tots and beer." dob = 1979-05-27T07:32:00Z # First class dates? Why not? [database] server = "192.168.1.1" ports = [ 8001, 8001, 8002 ] connection_max = 5000 enabled = true [servers] # You can indent as you please. Tabs or spaces. TOML don't care. [servers.alpha] ip = "10.0.0.1" dc = "eqdc10" [servers.beta] ip = "10.0.0.2" dc = "eqdc10" [clients] data = [ ["gamma", "delta"], [1, 2] ] # Line breaks are OK when inside arrays hosts = [ "alpha", "omega" ] golang-github-naoina-toml-0.0~git20170709.5811abc/_example/main.go000066400000000000000000000014261254735420300241700ustar00rootroot00000000000000package main import ( "io/ioutil" "os" "time" "github.com/naoina/toml" ) type tomlConfig struct { Title string Owner struct { Name string Org string `toml:"organization"` Bio string Dob time.Time } Database struct { Server string Ports []int ConnectionMax uint Enabled bool } Servers struct { Alpha Server Beta Server } Clients struct { Data [][]interface{} Hosts []string } } type Server struct { IP string DC string } func main() { f, err := os.Open("example.toml") if err != nil { panic(err) } defer f.Close() buf, err := ioutil.ReadAll(f) if err != nil { panic(err) } var config tomlConfig if err := toml.Unmarshal(buf, &config); err != nil { panic(err) } // then to use the unmarshaled config... } golang-github-naoina-toml-0.0~git20170709.5811abc/ast/000077500000000000000000000000001254735420300217075ustar00rootroot00000000000000golang-github-naoina-toml-0.0~git20170709.5811abc/ast/ast.go000066400000000000000000000050371254735420300230320ustar00rootroot00000000000000package ast import ( "strconv" "time" ) type Position struct { Begin int End int } type Value interface { Pos() int End() int Source() string } type String struct { Position Position Value string Data []rune } func (s *String) Pos() int { return s.Position.Begin } func (s *String) End() int { return s.Position.End } func (s *String) Source() string { return string(s.Data) } type Integer struct { Position Position Value string Data []rune } func (i *Integer) Pos() int { return i.Position.Begin } func (i *Integer) End() int { return i.Position.End } func (i *Integer) Source() string { return string(i.Data) } func (i *Integer) Int() (int64, error) { return strconv.ParseInt(i.Value, 10, 64) } type Float struct { Position Position Value string Data []rune } func (f *Float) Pos() int { return f.Position.Begin } func (f *Float) End() int { return f.Position.End } func (f *Float) Source() string { return string(f.Data) } func (f *Float) Float() (float64, error) { return strconv.ParseFloat(f.Value, 64) } type Boolean struct { Position Position Value string Data []rune } func (b *Boolean) Pos() int { return b.Position.Begin } func (b *Boolean) End() int { return b.Position.End } func (b *Boolean) Source() string { return string(b.Data) } func (b *Boolean) Boolean() (bool, error) { return strconv.ParseBool(b.Value) } type Datetime struct { Position Position Value string Data []rune } func (d *Datetime) Pos() int { return d.Position.Begin } func (d *Datetime) End() int { return d.Position.End } func (d *Datetime) Source() string { return string(d.Data) } func (d *Datetime) Time() (time.Time, error) { return time.Parse(time.RFC3339Nano, d.Value) } type Array struct { Position Position Value []Value Data []rune } func (a *Array) Pos() int { return a.Position.Begin } func (a *Array) End() int { return a.Position.End } func (a *Array) Source() string { return string(a.Data) } type TableType uint8 const ( TableTypeNormal TableType = iota TableTypeArray ) var tableTypes = [...]string{ "normal", "array", } func (t TableType) String() string { return tableTypes[t] } type Table struct { Position Position Line int Name string Fields map[string]interface{} Type TableType Data []rune } func (t *Table) Pos() int { return t.Position.Begin } func (t *Table) End() int { return t.Position.End } func (t *Table) Source() string { return string(t.Data) } type KeyValue struct { Key string Value Value Line int } golang-github-naoina-toml-0.0~git20170709.5811abc/decode.go000066400000000000000000000404241254735420300226760ustar00rootroot00000000000000package toml import ( "fmt" "io" "io/ioutil" "reflect" "strconv" "strings" "github.com/naoina/toml/ast" ) const ( tableSeparator = '.' ) var ( escapeReplacer = strings.NewReplacer( "\b", "\\n", "\f", "\\f", "\n", "\\n", "\r", "\\r", "\t", "\\t", ) underscoreReplacer = strings.NewReplacer( "_", "", ) ) // Unmarshal parses the TOML data and stores the result in the value pointed to by v. // // Unmarshal will mapped to v that according to following rules: // // TOML strings to string // TOML integers to any int type // TOML floats to float32 or float64 // TOML booleans to bool // TOML datetimes to time.Time // TOML arrays to any type of slice or []interface{} // TOML tables to struct // TOML array of tables to slice of struct func Unmarshal(data []byte, v interface{}) error { table, err := Parse(data) if err != nil { return err } if err := UnmarshalTable(table, v); err != nil { return fmt.Errorf("toml: unmarshal: %v", err) } return nil } // A Decoder reads and decodes TOML from an input stream. type Decoder struct { r io.Reader } // NewDecoder returns a new Decoder that reads from r. // Note that it reads all from r before parsing it. func NewDecoder(r io.Reader) *Decoder { return &Decoder{ r: r, } } // Decode parses the TOML data from its input and stores it in the value pointed to by v. // See the documentation for Unmarshal for details about the conversion of TOML into a Go value. func (d *Decoder) Decode(v interface{}) error { b, err := ioutil.ReadAll(d.r) if err != nil { return err } return Unmarshal(b, v) } // Unmarshaler is the interface implemented by objects that can unmarshal a // TOML description of themselves. // The input can be assumed to be a valid encoding of a TOML value. // UnmarshalJSON must copy the TOML data if it wishes to retain the data after // returning. type Unmarshaler interface { UnmarshalTOML([]byte) error } // UnmarshalTable applies the contents of an ast.Table to the value pointed at by v. // // UnmarshalTable will mapped to v that according to following rules: // // TOML strings to string // TOML integers to any int type // TOML floats to float32 or float64 // TOML booleans to bool // TOML datetimes to time.Time // TOML arrays to any type of slice or []interface{} // TOML tables to struct // TOML array of tables to slice of struct func UnmarshalTable(t *ast.Table, v interface{}) (err error) { if v == nil { return fmt.Errorf("v must not be nil") } rv := reflect.ValueOf(v) if kind := rv.Kind(); kind != reflect.Ptr && kind != reflect.Map { return fmt.Errorf("v must be a pointer or map") } for rv.Kind() == reflect.Ptr { rv = rv.Elem() } if err, ok := setUnmarshaler(rv, string(t.Data)); ok { return err } for key, val := range t.Fields { switch av := val.(type) { case *ast.KeyValue: fv, fieldName, found := findField(rv, key) if !found { return fmt.Errorf("line %d: field corresponding to `%s' is not defined in `%T'", av.Line, key, v) } switch fv.Kind() { case reflect.Map: mv := reflect.New(fv.Type().Elem()).Elem() if err := UnmarshalTable(t, mv.Addr().Interface()); err != nil { return err } fv.SetMapIndex(reflect.ValueOf(fieldName), mv) default: if err := setValue(fv, av.Value); err != nil { return fmt.Errorf("line %d: %v.%s: %v", av.Line, rv.Type(), fieldName, err) } if rv.Kind() == reflect.Map { rv.SetMapIndex(reflect.ValueOf(fieldName), fv) } } case *ast.Table: fv, fieldName, found := findField(rv, key) if !found { return fmt.Errorf("line %d: field corresponding to `%s' is not defined in `%T'", av.Line, key, v) } if err, ok := setUnmarshaler(fv, string(av.Data)); ok { if err != nil { return err } continue } for fv.Kind() == reflect.Ptr { fv.Set(reflect.New(fv.Type().Elem())) fv = fv.Elem() } switch fv.Kind() { case reflect.Struct: vv := reflect.New(fv.Type()).Elem() if err := UnmarshalTable(av, vv.Addr().Interface()); err != nil { return err } fv.Set(vv) if rv.Kind() == reflect.Map { rv.SetMapIndex(reflect.ValueOf(fieldName), fv) } case reflect.Map: mv := reflect.MakeMap(fv.Type()) if err := UnmarshalTable(av, mv.Interface()); err != nil { return err } fv.Set(mv) default: return fmt.Errorf("line %d: `%v.%s' must be struct or map, but %v given", av.Line, rv.Type(), fieldName, fv.Kind()) } case []*ast.Table: fv, fieldName, found := findField(rv, key) if !found { return fmt.Errorf("line %d: field corresponding to `%s' is not defined in `%T'", av[0].Line, key, v) } data := make([]string, 0, len(av)) for _, tbl := range av { data = append(data, string(tbl.Data)) } if err, ok := setUnmarshaler(fv, strings.Join(data, "\n")); ok { if err != nil { return err } continue } t := fv.Type().Elem() pc := 0 for ; t.Kind() == reflect.Ptr; pc++ { t = t.Elem() } if fv.Kind() != reflect.Slice { return fmt.Errorf("line %d: `%v.%s' must be slice type, but %v given", av[0].Line, rv.Type(), fieldName, fv.Kind()) } for _, tbl := range av { var vv reflect.Value switch t.Kind() { case reflect.Map: vv = reflect.MakeMap(t) if err := UnmarshalTable(tbl, vv.Interface()); err != nil { return err } default: vv = reflect.New(t).Elem() if err := UnmarshalTable(tbl, vv.Addr().Interface()); err != nil { return err } } for i := 0; i < pc; i++ { vv = vv.Addr() pv := reflect.New(vv.Type()).Elem() pv.Set(vv) vv = pv } fv.Set(reflect.Append(fv, vv)) } if rv.Kind() == reflect.Map { rv.SetMapIndex(reflect.ValueOf(fieldName), fv) } default: return fmt.Errorf("BUG: unknown type `%T'", t) } } return nil } func setUnmarshaler(lhs reflect.Value, data string) (error, bool) { for lhs.Kind() == reflect.Ptr { lhs.Set(reflect.New(lhs.Type().Elem())) lhs = lhs.Elem() } if lhs.CanAddr() { if u, ok := lhs.Addr().Interface().(Unmarshaler); ok { return u.UnmarshalTOML([]byte(data)), true } } return nil, false } func setValue(lhs reflect.Value, val ast.Value) error { for lhs.Kind() == reflect.Ptr { lhs.Set(reflect.New(lhs.Type().Elem())) lhs = lhs.Elem() } if err, ok := setUnmarshaler(lhs, val.Source()); ok { return err } switch v := val.(type) { case *ast.Integer: if err := setInt(lhs, v); err != nil { return err } case *ast.Float: if err := setFloat(lhs, v); err != nil { return err } case *ast.String: if err := setString(lhs, v); err != nil { return err } case *ast.Boolean: if err := setBoolean(lhs, v); err != nil { return err } case *ast.Datetime: if err := setDatetime(lhs, v); err != nil { return err } case *ast.Array: if err := setArray(lhs, v); err != nil { return err } } return nil } func setInt(fv reflect.Value, v *ast.Integer) error { i, err := v.Int() if err != nil { return err } switch fv.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: if fv.OverflowInt(i) { return &errorOutOfRange{fv.Kind(), i} } fv.SetInt(i) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: fv.SetUint(uint64(i)) case reflect.Interface: fv.Set(reflect.ValueOf(i)) default: return fmt.Errorf("`%v' is not any types of int", fv.Type()) } return nil } func setFloat(fv reflect.Value, v *ast.Float) error { f, err := v.Float() if err != nil { return err } switch fv.Kind() { case reflect.Float32, reflect.Float64: if fv.OverflowFloat(f) { return &errorOutOfRange{fv.Kind(), f} } fv.SetFloat(f) case reflect.Interface: fv.Set(reflect.ValueOf(f)) default: return fmt.Errorf("`%v' is not float32 or float64", fv.Type()) } return nil } func setString(fv reflect.Value, v *ast.String) error { return set(fv, v.Value) } func setBoolean(fv reflect.Value, v *ast.Boolean) error { b, err := v.Boolean() if err != nil { return err } return set(fv, b) } func setDatetime(fv reflect.Value, v *ast.Datetime) error { tm, err := v.Time() if err != nil { return err } return set(fv, tm) } func setArray(fv reflect.Value, v *ast.Array) error { if len(v.Value) == 0 { return nil } typ := reflect.TypeOf(v.Value[0]) for _, vv := range v.Value[1:] { if typ != reflect.TypeOf(vv) { return fmt.Errorf("array cannot contain multiple types") } } sliceType := fv.Type() if fv.Kind() == reflect.Interface { sliceType = reflect.SliceOf(sliceType) } slice := reflect.MakeSlice(sliceType, 0, len(v.Value)) t := sliceType.Elem() for _, vv := range v.Value { tmp := reflect.New(t).Elem() if err := setValue(tmp, vv); err != nil { return err } slice = reflect.Append(slice, tmp) } fv.Set(slice) return nil } func set(fv reflect.Value, v interface{}) error { rhs := reflect.ValueOf(v) if !rhs.Type().AssignableTo(fv.Type()) { return fmt.Errorf("`%v' type is not assignable to `%v' type", rhs.Type(), fv.Type()) } fv.Set(rhs) return nil } type stack struct { key string table *ast.Table } type toml struct { table *ast.Table line int currentTable *ast.Table s string key string val ast.Value arr *array tableMap map[string]*ast.Table stack []*stack skip bool } func (p *toml) init(data []rune) { p.line = 1 p.table = &ast.Table{ Line: p.line, Type: ast.TableTypeNormal, Data: data[:len(data)-1], // truncate the end_symbol added by PEG parse generator. } p.tableMap = map[string]*ast.Table{ "": p.table, } p.currentTable = p.table } func (p *toml) Error(err error) { panic(convertError{fmt.Errorf("toml: line %d: %v", p.line, err)}) } func (p *tomlParser) SetTime(begin, end int) { p.val = &ast.Datetime{ Position: ast.Position{Begin: begin, End: end}, Data: p.buffer[begin:end], Value: string(p.buffer[begin:end]), } } func (p *tomlParser) SetFloat64(begin, end int) { p.val = &ast.Float{ Position: ast.Position{Begin: begin, End: end}, Data: p.buffer[begin:end], Value: underscoreReplacer.Replace(string(p.buffer[begin:end])), } } func (p *tomlParser) SetInt64(begin, end int) { p.val = &ast.Integer{ Position: ast.Position{Begin: begin, End: end}, Data: p.buffer[begin:end], Value: underscoreReplacer.Replace(string(p.buffer[begin:end])), } } func (p *tomlParser) SetString(begin, end int) { p.val = &ast.String{ Position: ast.Position{Begin: begin, End: end}, Data: p.buffer[begin:end], Value: p.s, } p.s = "" } func (p *tomlParser) SetBool(begin, end int) { p.val = &ast.Boolean{ Position: ast.Position{Begin: begin, End: end}, Data: p.buffer[begin:end], Value: string(p.buffer[begin:end]), } } func (p *tomlParser) StartArray() { if p.arr == nil { p.arr = &array{line: p.line, current: &ast.Array{}} return } p.arr.child = &array{parent: p.arr, line: p.line, current: &ast.Array{}} p.arr = p.arr.child } func (p *tomlParser) AddArrayVal() { if p.arr.current == nil { p.arr.current = &ast.Array{} } p.arr.current.Value = append(p.arr.current.Value, p.val) } func (p *tomlParser) SetArray(begin, end int) { p.arr.current.Position = ast.Position{Begin: begin, End: end} p.arr.current.Data = p.buffer[begin:end] p.val = p.arr.current p.arr = p.arr.parent } func (p *toml) SetTable(buf []rune, begin, end int) { p.setTable(p.table, buf, begin, end) } func (p *toml) setTable(t *ast.Table, buf []rune, begin, end int) { name := string(buf[begin:end]) names := splitTableKey(name) if t, exists := p.tableMap[name]; exists { if lt := p.tableMap[names[len(names)-1]]; t.Type == ast.TableTypeArray || lt != nil && lt.Type == ast.TableTypeNormal { p.Error(fmt.Errorf("table `%s' is in conflict with %v table in line %d", name, t.Type, t.Line)) } } t, err := p.lookupTable(t, names) if err != nil { p.Error(err) } p.currentTable = t p.tableMap[name] = p.currentTable } func (p *tomlParser) SetTableString(begin, end int) { p.currentTable.Data = p.buffer[begin:end] p.currentTable.Position.Begin = begin p.currentTable.Position.End = end } func (p *toml) SetArrayTable(buf []rune, begin, end int) { p.setArrayTable(p.table, buf, begin, end) } func (p *toml) setArrayTable(t *ast.Table, buf []rune, begin, end int) { name := string(buf[begin:end]) if t, exists := p.tableMap[name]; exists && t.Type == ast.TableTypeNormal { p.Error(fmt.Errorf("table `%s' is in conflict with %v table in line %d", name, t.Type, t.Line)) } names := splitTableKey(name) t, err := p.lookupTable(t, names[:len(names)-1]) if err != nil { p.Error(err) } last := names[len(names)-1] tbl := &ast.Table{ Position: ast.Position{begin, end}, Line: p.line, Name: last, Type: ast.TableTypeArray, } switch v := t.Fields[last].(type) { case nil: if t.Fields == nil { t.Fields = make(map[string]interface{}) } t.Fields[last] = []*ast.Table{tbl} case []*ast.Table: t.Fields[last] = append(v, tbl) case *ast.KeyValue: p.Error(fmt.Errorf("key `%s' is in conflict with line %d", last, v.Line)) default: p.Error(fmt.Errorf("BUG: key `%s' is in conflict but it's unknown type `%T'", last, v)) } p.currentTable = tbl p.tableMap[name] = p.currentTable } func (p *toml) StartInlineTable() { p.skip = false p.stack = append(p.stack, &stack{p.key, p.currentTable}) buf := []rune(p.key) if p.arr == nil { p.setTable(p.currentTable, buf, 0, len(buf)) } else { p.setArrayTable(p.currentTable, buf, 0, len(buf)) } } func (p *toml) EndInlineTable() { st := p.stack[len(p.stack)-1] p.key, p.currentTable = st.key, st.table p.stack[len(p.stack)-1] = nil p.stack = p.stack[:len(p.stack)-1] p.skip = true } func (p *toml) AddLineCount(i int) { p.line += i } func (p *toml) SetKey(buf []rune, begin, end int) { p.key = string(buf[begin:end]) } func (p *toml) AddKeyValue() { if p.skip { p.skip = false return } if val, exists := p.currentTable.Fields[p.key]; exists { switch v := val.(type) { case *ast.Table: p.Error(fmt.Errorf("key `%s' is in conflict with %v table in line %d", p.key, v.Type, v.Line)) case *ast.KeyValue: p.Error(fmt.Errorf("key `%s' is in conflict with line %d", p.key, v.Line)) default: p.Error(fmt.Errorf("BUG: key `%s' is in conflict but it's unknown type `%T'", p.key, v)) } } if p.currentTable.Fields == nil { p.currentTable.Fields = make(map[string]interface{}) } p.currentTable.Fields[p.key] = &ast.KeyValue{ Key: p.key, Value: p.val, Line: p.line, } } func (p *toml) SetBasicString(buf []rune, begin, end int) { p.s = p.unquote(string(buf[begin:end])) } func (p *toml) SetMultilineString() { p.s = p.unquote(`"` + escapeReplacer.Replace(strings.TrimLeft(p.s, "\r\n")) + `"`) } func (p *toml) AddMultilineBasicBody(buf []rune, begin, end int) { p.s += string(buf[begin:end]) } func (p *toml) SetLiteralString(buf []rune, begin, end int) { p.s = string(buf[begin:end]) } func (p *toml) SetMultilineLiteralString(buf []rune, begin, end int) { p.s = strings.TrimLeft(string(buf[begin:end]), "\r\n") } func (p *toml) unquote(s string) string { s, err := strconv.Unquote(s) if err != nil { p.Error(err) } return s } func (p *toml) lookupTable(t *ast.Table, keys []string) (*ast.Table, error) { for _, s := range keys { val, exists := t.Fields[s] if !exists { tbl := &ast.Table{ Line: p.line, Name: s, Type: ast.TableTypeNormal, } if t.Fields == nil { t.Fields = make(map[string]interface{}) } t.Fields[s] = tbl t = tbl continue } switch v := val.(type) { case *ast.Table: t = v case []*ast.Table: t = v[len(v)-1] case *ast.KeyValue: return nil, fmt.Errorf("key `%s' is in conflict with line %d", s, v.Line) default: return nil, fmt.Errorf("BUG: key `%s' is in conflict but it's unknown type `%T'", s, v) } } return t, nil } func splitTableKey(tk string) []string { key := make([]byte, 0, 1) keys := make([]string, 0, 1) inQuote := false for i := 0; i < len(tk); i++ { k := tk[i] switch { case k == tableSeparator && !inQuote: keys = append(keys, string(key)) key = key[:0] // reuse buffer. case k == '"': inQuote = !inQuote case (k == ' ' || k == '\t') && !inQuote: // skip. default: key = append(key, k) } } keys = append(keys, string(key)) return keys } type convertError struct { err error } func (e convertError) Error() string { return e.err.Error() } type array struct { parent *array child *array current *ast.Array line int } golang-github-naoina-toml-0.0~git20170709.5811abc/decode_bench_test.go000066400000000000000000000013411254735420300250670ustar00rootroot00000000000000package toml_test import ( "testing" "time" "github.com/naoina/toml" ) func BenchmarkUnmarshal(b *testing.B) { var v struct { Title string Owner struct { Name string Organization string Bio string Dob time.Time } Database struct { Server string Ports []int ConnectionMax int Enabled bool } Servers struct { Alpha struct { IP string DC string } Beta struct { IP string DC string } } Clients struct { Data []interface{} Hosts []string } } data, err := loadTestData() if err != nil { b.Fatal(err) } for i := 0; i < b.N; i++ { if err := toml.Unmarshal(data, &v); err != nil { b.Fatal(err) } } } golang-github-naoina-toml-0.0~git20170709.5811abc/decode_test.go000066400000000000000000000646771254735420300237550ustar00rootroot00000000000000package toml_test import ( "fmt" "io/ioutil" "path/filepath" "reflect" "testing" "time" "github.com/naoina/toml" ) const ( dataDir = "testdata" ) func loadTestData() ([]byte, error) { f := filepath.Join(dataDir, "test.toml") data, err := ioutil.ReadFile(f) if err != nil { return nil, err } return data, nil } func mustTime(tm time.Time, err error) time.Time { if err != nil { panic(err) } return tm } type Name struct { First string Last string } type Point struct { X int Y int } type Inline struct { Name Name Point Point } type Subtable struct { Key string } type Table struct { Key string Subtable Subtable Inline Inline } type W struct { } type Z struct { W W } type Y struct { Z Z } type X struct { Y Y } type Basic struct { Basic string } type Continued struct { Key1 string Key2 string Key3 string } type Multiline struct { Key1 string Key2 string Key3 string Continued Continued } type LiteralMultiline struct { Regex2 string Lines string } type Literal struct { Winpath string Winpath2 string Quoted string Regex string Multiline LiteralMultiline } type String struct { Basic Basic Multiline Multiline Literal Literal } type IntegerUnderscores struct { Key1 int Key2 int Key3 int } type Integer struct { Key1 int Key2 int Key3 int Key4 int Underscores IntegerUnderscores } type Fractional struct { Key1 float64 Key2 float64 Key3 float64 } type Exponent struct { Key1 float64 Key2 float64 Key3 float64 } type Both struct { Key float64 } type FloatUnderscores struct { Key1 float64 Key2 float64 } type Float struct { Fractional Fractional Exponent Exponent Both Both Underscores FloatUnderscores } type Boolean struct { True bool False bool } type Datetime struct { Key1 time.Time Key2 time.Time Key3 time.Time } type Array struct { Key1 []int Key2 []string Key3 [][]int Key4 [][]interface{} Key5 []int Key6 []int } type Product struct { Name string Sku int64 Color string } type Physical struct { Color string Shape string } type Variety struct { Name string } type Fruit struct { Name string Physical Physical Variety []Variety } type testStruct struct { Table Table X X String String Integer Integer Float Float Boolean Boolean Datetime Datetime Array Array Products []Product Fruit []Fruit } func TestUnmarshal(t *testing.T) { data, err := loadTestData() if err != nil { t.Fatal(err) } var v testStruct var actual interface{} = toml.Unmarshal(data, &v) var expect interface{} = nil if !reflect.DeepEqual(actual, expect) { t.Errorf(`toml.Unmarshal(data, &testStruct{}) => %#v; want %#v`, actual, expect) } actual = v expect = testStruct{ Table: Table{ Key: "value", Subtable: Subtable{ Key: "another value", }, Inline: Inline{ Name: Name{ First: "Tom", Last: "Preston-Werner", }, Point: Point{ X: 1, Y: 2, }, }, }, X: X{}, String: String{ Basic: Basic{ Basic: "I'm a string. \"You can quote me\". Name\tJos\u00E9\nLocation\tSF.", }, Multiline: Multiline{ Key1: "One\nTwo", Key2: "One\nTwo", Key3: "One\nTwo", Continued: Continued{ Key1: "The quick brown fox jumps over the lazy dog.", Key2: "The quick brown fox jumps over the lazy dog.", Key3: "The quick brown fox jumps over the lazy dog.", }, }, Literal: Literal{ Winpath: `C:\Users\nodejs\templates`, Winpath2: `\\ServerX\admin$\system32\`, Quoted: `Tom "Dubs" Preston-Werner`, Regex: `<\i\c*\s*>`, Multiline: LiteralMultiline{ Regex2: `I [dw]on't need \d{2} apples`, Lines: "The first newline is\ntrimmed in raw strings.\n All other whitespace\n is preserved.\n", }, }, }, Integer: Integer{ Key1: 99, Key2: 42, Key3: 0, Key4: -17, Underscores: IntegerUnderscores{ Key1: 1000, Key2: 5349221, Key3: 12345, }, }, Float: Float{ Fractional: Fractional{ Key1: 1.0, Key2: 3.1415, Key3: -0.01, }, Exponent: Exponent{ Key1: 5e22, Key2: 1e6, Key3: -2e-2, }, Both: Both{ Key: 6.626e-34, }, Underscores: FloatUnderscores{ Key1: 9224617.445991228313, Key2: 1e100, }, }, Boolean: Boolean{ True: true, False: false, }, Datetime: Datetime{ Key1: mustTime(time.Parse(time.RFC3339Nano, "1979-05-27T07:32:00Z")), Key2: mustTime(time.Parse(time.RFC3339Nano, "1979-05-27T00:32:00-07:00")), Key3: mustTime(time.Parse(time.RFC3339Nano, "1979-05-27T00:32:00.999999-07:00")), }, Array: Array{ Key1: []int{1, 2, 3}, Key2: []string{"red", "yellow", "green"}, Key3: [][]int{{1, 2}, {3, 4, 5}}, Key4: [][]interface{}{{int64(1), int64(2)}, {"a", "b", "c"}}, Key5: []int{1, 2, 3}, Key6: []int{1, 2}, }, Products: []Product{ {Name: "Hammer", Sku: 738594937}, {}, {Name: "Nail", Sku: 284758393, Color: "gray"}, }, Fruit: []Fruit{ { Name: "apple", Physical: Physical{ Color: "red", Shape: "round", }, Variety: []Variety{ {Name: "red delicious"}, {Name: "granny smith"}, }, }, { Name: "banana", Variety: []Variety{ {Name: "plantain"}, }, }, }, } if !reflect.DeepEqual(actual, expect) { t.Errorf(`toml.Unmarshal(data, v); v => %#v; want %#v`, actual, expect) } } type testcase struct { data string err error actual interface{} expect interface{} } func testUnmarshal(t *testing.T, testcases []testcase) { for _, v := range testcases { var actual error = toml.Unmarshal([]byte(v.data), v.actual) var expect error = v.err if !reflect.DeepEqual(actual, expect) { t.Errorf(`toml.Unmarshal([]byte(%#v), %#v) => %#v; want %#v`, v.data, nil, actual, expect) } if !reflect.DeepEqual(v.actual, v.expect) { t.Errorf(`toml.Unmarshal([]byte(%#v), v); v => %#v; want %#v`, v.data, v.actual, v.expect) } } } func TestUnmarshal_WithString(t *testing.T) { type testStruct struct { Str string Key1 string Key2 string Key3 string Winpath string Winpath2 string Quoted string Regex string Regex2 string Lines string } testUnmarshal(t, []testcase{ {`str = "I'm a string. \"You can quote me\". Name\tJos\u00E9\nLocation\tSF."`, nil, &testStruct{}, &testStruct{ Str: "I'm a string. \"You can quote me\". Name\tJos\u00E9\nLocation\tSF.", }}, {`key1 = "One\nTwo" key2 = """One\nTwo""" key3 = """ One Two""" `, nil, &testStruct{}, &testStruct{ Key1: "One\nTwo", Key2: "One\nTwo", Key3: "One\nTwo", }}, {`# The following strings are byte-for-byte equivalent: key1 = "The quick brown fox jumps over the lazy dog." key2 = """ The quick brown \ fox jumps over \ the lazy dog.""" key3 = """\ The quick brown \ fox jumps over \ the lazy dog.\ """`, nil, &testStruct{}, &testStruct{ Key1: "The quick brown fox jumps over the lazy dog.", Key2: "The quick brown fox jumps over the lazy dog.", Key3: "The quick brown fox jumps over the lazy dog.", }}, {`# What you see is what you get. winpath = 'C:\Users\nodejs\templates' winpath2 = '\\ServerX\admin$\system32\' quoted = 'Tom "Dubs" Preston-Werner' regex = '<\i\c*\s*>'`, nil, &testStruct{}, &testStruct{ Winpath: `C:\Users\nodejs\templates`, Winpath2: `\\ServerX\admin$\system32\`, Quoted: `Tom "Dubs" Preston-Werner`, Regex: `<\i\c*\s*>`, }}, {`regex2 = '''I [dw]on't need \d{2} apples''' lines = ''' The first newline is trimmed in raw strings. All other whitespace is preserved. '''`, nil, &testStruct{}, &testStruct{ Regex2: `I [dw]on't need \d{2} apples`, Lines: "The first newline is\ntrimmed in raw strings.\n All other whitespace\n is preserved.\n", }}, }) } func TestUnmarshal_WithInteger(t *testing.T) { type testStruct struct { Intval int64 } testUnmarshal(t, []testcase{ {`intval = 0`, nil, &testStruct{}, &testStruct{0}}, {`intval = +0`, nil, &testStruct{}, &testStruct{0}}, {`intval = -0`, nil, &testStruct{}, &testStruct{-0}}, {`intval = 1`, nil, &testStruct{}, &testStruct{1}}, {`intval = +1`, nil, &testStruct{}, &testStruct{1}}, {`intval = -1`, nil, &testStruct{}, &testStruct{-1}}, {`intval = 10`, nil, &testStruct{}, &testStruct{10}}, {`intval = 777`, nil, &testStruct{}, &testStruct{777}}, {`intval = 2147483647`, nil, &testStruct{}, &testStruct{2147483647}}, {`intval = 2147483648`, nil, &testStruct{}, &testStruct{2147483648}}, {`intval = +2147483648`, nil, &testStruct{}, &testStruct{2147483648}}, {`intval = -2147483648`, nil, &testStruct{}, &testStruct{-2147483648}}, {`intval = -2147483649`, nil, &testStruct{}, &testStruct{-2147483649}}, {`intval = 9223372036854775807`, nil, &testStruct{}, &testStruct{9223372036854775807}}, {`intval = +9223372036854775807`, nil, &testStruct{}, &testStruct{9223372036854775807}}, {`intval = 9223372036854775808`, fmt.Errorf(`toml: unmarshal: line 1: toml_test.testStruct.Intval: strconv.ParseInt: parsing "9223372036854775808": value out of range`), &testStruct{}, &testStruct{}}, {`intval = +9223372036854775808`, fmt.Errorf(`toml: unmarshal: line 1: toml_test.testStruct.Intval: strconv.ParseInt: parsing "+9223372036854775808": value out of range`), &testStruct{}, &testStruct{}}, {`intval = -9223372036854775808`, nil, &testStruct{}, &testStruct{-9223372036854775808}}, {`intval = -9223372036854775809`, fmt.Errorf(`toml: unmarshal: line 1: toml_test.testStruct.Intval: strconv.ParseInt: parsing "-9223372036854775809": value out of range`), &testStruct{}, &testStruct{}}, {`intval = 1_000`, nil, &testStruct{}, &testStruct{1000}}, {`intval = 5_349_221`, nil, &testStruct{}, &testStruct{5349221}}, {`intval = 1_2_3_4_5`, nil, &testStruct{}, &testStruct{12345}}, {`intval = _1_000`, fmt.Errorf("toml: line 1: parse error"), &testStruct{}, &testStruct{}}, {`intval = 1_000_`, fmt.Errorf("toml: line 1: parse error"), &testStruct{}, &testStruct{}}, }) } func TestUnmarshal_WithFloat(t *testing.T) { type testStruct struct { Floatval float64 } testUnmarshal(t, []testcase{ {`floatval = 0.0`, nil, &testStruct{}, &testStruct{0.0}}, {`floatval = +0.0`, nil, &testStruct{}, &testStruct{0.0}}, {`floatval = -0.0`, nil, &testStruct{}, &testStruct{-0.0}}, {`floatval = 0.1`, nil, &testStruct{}, &testStruct{0.1}}, {`floatval = +0.1`, nil, &testStruct{}, &testStruct{0.1}}, {`floatval = -0.1`, nil, &testStruct{}, &testStruct{-0.1}}, {`floatval = 0.2`, nil, &testStruct{}, &testStruct{0.2}}, {`floatval = +0.2`, nil, &testStruct{}, &testStruct{0.2}}, {`floatval = -0.2`, nil, &testStruct{}, &testStruct{-0.2}}, {`floatval = 1.0`, nil, &testStruct{}, &testStruct{1.0}}, {`floatval = +1.0`, nil, &testStruct{}, &testStruct{1.0}}, {`floatval = -1.0`, nil, &testStruct{}, &testStruct{-1.0}}, {`floatval = 1.1`, nil, &testStruct{}, &testStruct{1.1}}, {`floatval = +1.1`, nil, &testStruct{}, &testStruct{1.1}}, {`floatval = -1.1`, nil, &testStruct{}, &testStruct{-1.1}}, {`floatval = 3.1415`, nil, &testStruct{}, &testStruct{3.1415}}, {`floatval = +3.1415`, nil, &testStruct{}, &testStruct{3.1415}}, {`floatval = -3.1415`, nil, &testStruct{}, &testStruct{-3.1415}}, {`floatval = 10.2e5`, nil, &testStruct{}, &testStruct{10.2e5}}, {`floatval = +10.2e5`, nil, &testStruct{}, &testStruct{10.2e5}}, {`floatval = -10.2e5`, nil, &testStruct{}, &testStruct{-10.2e5}}, {`floatval = 10.2E5`, nil, &testStruct{}, &testStruct{10.2e5}}, {`floatval = +10.2E5`, nil, &testStruct{}, &testStruct{10.2e5}}, {`floatval = -10.2E5`, nil, &testStruct{}, &testStruct{-10.2e5}}, {`floatval = 5e+22`, nil, &testStruct{}, &testStruct{5e+22}}, {`floatval = 1e6`, nil, &testStruct{}, &testStruct{1e6}}, {`floatval = -2E-2`, nil, &testStruct{}, &testStruct{-2E-2}}, {`floatval = 6.626e-34`, nil, &testStruct{}, &testStruct{6.626e-34}}, {`floatval = 9_224_617.445_991_228_313`, nil, &testStruct{}, &testStruct{9224617.445991228313}}, {`floatval = 1e1_00`, nil, &testStruct{}, &testStruct{1e100}}, {`floatval = 1e02`, nil, &testStruct{}, &testStruct{1e2}}, {`floatval = _1e1_00`, fmt.Errorf("toml: line 1: parse error"), &testStruct{}, &testStruct{}}, {`floatval = 1e1_00_`, fmt.Errorf("toml: line 1: parse error"), &testStruct{}, &testStruct{}}, }) } func TestUnmarshal_WithBoolean(t *testing.T) { type testStruct struct { Boolval bool } testUnmarshal(t, []testcase{ {`boolval = true`, nil, &testStruct{}, &testStruct{true}}, {`boolval = false`, nil, &testStruct{}, &testStruct{false}}, }) } func TestUnmarshal_WithDatetime(t *testing.T) { type testStruct struct { Datetimeval time.Time } testUnmarshal(t, []testcase{ {`datetimeval = 1979-05-27T07:32:00Z`, nil, &testStruct{}, &testStruct{ mustTime(time.Parse(time.RFC3339Nano, "1979-05-27T07:32:00Z")), }}, {`datetimeval = 2014-09-13T12:37:39Z`, nil, &testStruct{}, &testStruct{ mustTime(time.Parse(time.RFC3339Nano, "2014-09-13T12:37:39Z")), }}, {`datetimeval = 1979-05-27T00:32:00-07:00`, nil, &testStruct{}, &testStruct{ mustTime(time.Parse(time.RFC3339Nano, "1979-05-27T00:32:00-07:00")), }}, {`datetimeval = 1979-05-27T00:32:00.999999-07:00`, nil, &testStruct{}, &testStruct{ mustTime(time.Parse(time.RFC3339Nano, "1979-05-27T00:32:00.999999-07:00")), }}, }) } func TestUnmarshal_WithArray(t *testing.T) { testUnmarshal(t, []testcase{ {`arrayval = []`, nil, &struct{ Arrayval []interface{} }{}, &struct{ Arrayval []interface{} }{}}, {`arrayval = [ 1 ]`, nil, &struct{ Arrayval []int }{}, &struct { Arrayval []int }{ []int{1}, }}, {`arrayval = [ 1, 2, 3 ]`, nil, &struct{ Arrayval []int }{}, &struct { Arrayval []int }{ []int{1, 2, 3}, }}, {`arrayval = [ 1, 2, 3, ]`, nil, &struct{ Arrayval []int }{}, &struct { Arrayval []int }{ []int{1, 2, 3}, }}, {`arrayval = ["red", "yellow", "green"]`, nil, &struct{ Arrayval []string }{}, &struct{ Arrayval []string }{ []string{"red", "yellow", "green"}, }}, {`arrayval = [ "all", 'strings', """are the same""", '''type''']`, nil, &struct{ Arrayval []string }{}, &struct{ Arrayval []string }{ []string{"all", "strings", "are the same", "type"}, }}, {`arrayval = [[1,2],[3,4,5]]`, nil, &struct{ Arrayval [][]int }{}, &struct{ Arrayval [][]int }{ [][]int{ []int{1, 2}, []int{3, 4, 5}, }, }}, {`arrayval = [ [ 1, 2 ], ["a", "b", "c"] ] # this is ok`, nil, &struct{ Arrayval [][]interface{} }{}, &struct{ Arrayval [][]interface{} }{ [][]interface{}{ []interface{}{int64(1), int64(2)}, []interface{}{"a", "b", "c"}, }, }}, {`arrayval = [ [ 1, 2 ], [ [3, 4], [5, 6] ] ] # this is ok`, nil, &struct{ Arrayval [][]interface{} }{}, &struct{ Arrayval [][]interface{} }{ [][]interface{}{ []interface{}{int64(1), int64(2)}, []interface{}{ []interface{}{int64(3), int64(4)}, []interface{}{int64(5), int64(6)}, }, }, }}, {`arrayval = [ [ 1, 2 ], [ [3, 4], [5, 6], [7, 8] ] ] # this is ok`, nil, &struct{ Arrayval [][]interface{} }{}, &struct{ Arrayval [][]interface{} }{ [][]interface{}{ []interface{}{int64(1), int64(2)}, []interface{}{ []interface{}{int64(3), int64(4)}, []interface{}{int64(5), int64(6)}, []interface{}{int64(7), int64(8)}, }, }, }}, {`arrayval = [ [[ 1, 2 ]], [3, 4], [5, 6] ] # this is ok`, nil, &struct{ Arrayval [][]interface{} }{}, &struct{ Arrayval [][]interface{} }{ [][]interface{}{ []interface{}{ []interface{}{int64(1), int64(2)}, }, []interface{}{int64(3), int64(4)}, []interface{}{int64(5), int64(6)}, }, }}, {`arrayval = [ 1, 2.0 ] # note: this is NOT ok`, fmt.Errorf("toml: unmarshal: line 1: struct { Arrayval []interface {} }.Arrayval: array cannot contain multiple types"), &struct{ Arrayval []interface{} }{}, &struct{ Arrayval []interface{} }{}}, {`key = [ 1, 2, 3 ]`, nil, &struct{ Key []int }{}, &struct{ Key []int }{ []int{1, 2, 3}, }}, {`key = [ 1, 2, # this is ok ]`, nil, &struct{ Key []int }{}, &struct{ Key []int }{ []int{1, 2}, }}, }) } func TestUnmarshal_WithTable(t *testing.T) { type W struct{} type Z struct { W W } type Y struct { Z Z } type X struct { Y Y } type testStruct struct { Table struct { Key string } Dog struct { Tater struct{} } X X A struct { D int B struct { C int } } } type testQuotedKeyStruct struct { Dog struct { TaterMan struct { Type string } `toml:"tater.man"` } } type testQuotedKeyWithWhitespaceStruct struct { Dog struct { TaterMan struct { Type string } `toml:"tater . man"` } } type testStructWithMap struct { Servers map[string]struct { IP string DC string } } testUnmarshal(t, []testcase{ {`[table]`, nil, &testStruct{}, &testStruct{}}, {`[table] key = "value"`, nil, &testStruct{}, &testStruct{ Table: struct { Key string }{ Key: "value", }, }}, {`[dog.tater]`, nil, &testStruct{}, &testStruct{ Dog: struct { Tater struct{} }{ Tater: struct{}{}, }, }}, {`[dog."tater.man"] type = "pug"`, nil, &testQuotedKeyStruct{}, &testQuotedKeyStruct{ Dog: struct { TaterMan struct { Type string } `toml:"tater.man"` }{ TaterMan: struct { Type string }{ Type: "pug", }, }, }}, {`[dog."tater . man"] type = "pug"`, nil, &testQuotedKeyWithWhitespaceStruct{}, &testQuotedKeyWithWhitespaceStruct{ Dog: struct { TaterMan struct { Type string } `toml:"tater . man"` }{ TaterMan: struct { Type string }{ Type: "pug", }, }, }}, {`[x.y.z.w] # for this to work`, nil, &testStruct{}, &testStruct{ X: X{}, }}, {`[ x . y . z . w ]`, nil, &testStruct{}, &testStruct{ X: X{}, }}, {`[ x . "y" . z . "w" ]`, nil, &testStruct{}, &testStruct{ X: X{}, }}, {`table = {}`, nil, &testStruct{}, &testStruct{}}, {`table = { key = "value" }`, nil, &testStruct{}, &testStruct{ Table: struct { Key string }{ Key: "value", }, }}, {`x = { y = { "z" = { w = {} } } }`, nil, &testStruct{}, &testStruct{X: X{}}}, {`[a.b] c = 1 [a] d = 2`, nil, &testStruct{}, &testStruct{ A: struct { D int B struct { C int } }{ D: 2, B: struct { C int }{ C: 1, }, }, }}, {`# DO NOT DO THIS [a] b = 1 [a] c = 2`, fmt.Errorf("toml: line 6: table `a' is in conflict with normal table in line 3"), &testStruct{}, &testStruct{}}, {`# DO NOT DO THIS EITHER [a] b = 1 [a.b] c = 2`, fmt.Errorf("toml: line 6: key `b' is in conflict with line 4"), &testStruct{}, &testStruct{}}, {`# DO NOT DO THIS EITHER [a.b] c = 2 [a] b = 1`, fmt.Errorf("toml: line 7: key `b' is in conflict with normal table in line 3"), &testStruct{}, &testStruct{}}, {`[]`, fmt.Errorf("toml: line 1: parse error"), &testStruct{}, &testStruct{}}, {`[a.]`, fmt.Errorf("toml: line 1: parse error"), &testStruct{}, &testStruct{}}, {`[a..b]`, fmt.Errorf("toml: line 1: parse error"), &testStruct{}, &testStruct{}}, {`[.b]`, fmt.Errorf("toml: line 1: parse error"), &testStruct{}, &testStruct{}}, {`[.]`, fmt.Errorf("toml: line 1: parse error"), &testStruct{}, &testStruct{}}, {` = "no key name" # not allowed`, fmt.Errorf("toml: line 1: parse error"), &testStruct{}, &testStruct{}}, {`[servers] [servers.alpha] ip = "10.0.0.1" dc = "eqdc10" [servers.beta] ip = "10.0.0.2" dc = "eqdc10" `, nil, &testStructWithMap{}, &testStructWithMap{ Servers: map[string]struct { IP string DC string }{ "alpha": { IP: "10.0.0.1", DC: "eqdc10", }, "beta": { IP: "10.0.0.2", DC: "eqdc10", }, }, }}, }) } func TestUnmarshal_WithArrayTable(t *testing.T) { type Product struct { Name string SKU int64 Color string } type Physical struct { Color string Shape string } type Variety struct { Name string } type Fruit struct { Name string Physical Physical Variety []Variety } type testStruct struct { Products []Product Fruit []Fruit } type testStructWithMap struct { Fruit []map[string][]struct { Name string } } testUnmarshal(t, []testcase{ {`[[products]] name = "Hammer" sku = 738594937 [[products]] [[products]] name = "Nail" sku = 284758393 color = "gray"`, nil, &testStruct{}, &testStruct{ Products: []Product{ {Name: "Hammer", SKU: 738594937}, {}, {Name: "Nail", SKU: 284758393, Color: "gray"}, }, }}, {`products = [{name = "Hammer", sku = 738594937}, {}, {name = "Nail", sku = 284758393, color = "gray"}]`, nil, &testStruct{}, &testStruct{ Products: []Product{ {Name: "Hammer", SKU: 738594937}, {}, {Name: "Nail", SKU: 284758393, Color: "gray"}, }, }}, {`[[fruit]] name = "apple" [fruit.physical] color = "red" shape = "round" [[fruit.variety]] name = "red delicious" [[fruit.variety]] name = "granny smith" [[fruit]] name = "banana" [fruit.physical] color = "yellow" shape = "lune" [[fruit.variety]] name = "plantain"`, nil, &testStruct{}, &testStruct{ Fruit: []Fruit{ { Name: "apple", Physical: Physical{ Color: "red", Shape: "round", }, Variety: []Variety{ {Name: "red delicious"}, {Name: "granny smith"}, }, }, { Name: "banana", Physical: Physical{ Color: "yellow", Shape: "lune", }, Variety: []Variety{ {Name: "plantain"}, }, }, }, }}, {`[[fruit]] [[fruit.variety]] name = "red delicious" [[fruit.variety]] name = "granny smith" [[fruit]] [[fruit.variety]] name = "plantain" [[fruit.area]] name = "phillippines"`, nil, &testStructWithMap{}, &testStructWithMap{ Fruit: []map[string][]struct { Name string }{ { "variety": { {Name: "red delicious"}, {Name: "granny smith"}, }, }, { "variety": { {Name: "plantain"}, }, "area": { {Name: "phillippines"}, }, }, }, }}, {`# INVALID TOML DOC [[fruit]] name = "apple" [[fruit.variety]] name = "red delicious" # This table conflicts with the previous table [fruit.variety] name = "granny smith"`, fmt.Errorf("toml: line 9: table `fruit.variety' is in conflict with array table in line 5"), &testStruct{}, &testStruct{}}, {`# INVALID TOML DOC [[fruit]] name = "apple" [fruit.variety] name = "granny smith" # This table conflicts with the previous table [[fruit.variety]] name = "red delicious"`, fmt.Errorf("toml: line 9: table `fruit.variety' is in conflict with normal table in line 5"), &testStruct{}, &testStruct{}}, }) } type UnmarshalString string func (u *UnmarshalString) UnmarshalTOML(data []byte) error { *u = UnmarshalString("UnmarshalString: " + string(data)) return nil } type testUnmarshalStruct struct { Title string Author UnmarshalString } func (u *testUnmarshalStruct) UnmarshalTOML(data []byte) error { u.Title = "Unmarshaled: " + string(data) return nil } func TestUnmarshal_WithUnmarshaler(t *testing.T) { type testStruct struct { Title UnmarshalString MaxConn UnmarshalString Ports UnmarshalString Servers UnmarshalString Table UnmarshalString Arraytable UnmarshalString ArrayOfStruct []testUnmarshalStruct } data := `title = "testtitle" max_conn = 777 ports = [8080, 8081, 8082] servers = [1, 2, 3] [table] name = "alice" [[arraytable]] name = "alice" [[arraytable]] name = "bob" [[array_of_struct]] title = "Alice's Adventures in Wonderland" author = "Lewis Carroll" ` var v testStruct if err := toml.Unmarshal([]byte(data), &v); err != nil { t.Fatal(err) } actual := v expect := testStruct{ Title: `UnmarshalString: "testtitle"`, MaxConn: `UnmarshalString: 777`, Ports: `UnmarshalString: [8080, 8081, 8082]`, Servers: `UnmarshalString: [1, 2, 3]`, Table: "UnmarshalString: [table]\nname = \"alice\"", Arraytable: "UnmarshalString: [[arraytable]]\nname = \"alice\"\n[[arraytable]]\nname = \"bob\"", ArrayOfStruct: []testUnmarshalStruct{ { Title: "Unmarshaled: [[array_of_struct]]\ntitle = \"Alice's Adventures in Wonderland\"\nauthor = \"Lewis Carroll\"", Author: "", }, }, } if !reflect.DeepEqual(actual, expect) { t.Errorf(`toml.Unmarshal(data, &v); v => %#v; want %#v`, actual, expect) } } func TestUnmarshal_WithUnmarshalerForTopLevelStruct(t *testing.T) { data := `title = "Alice's Adventures in Wonderland" author = "Lewis Carroll" ` var v testUnmarshalStruct if err := toml.Unmarshal([]byte(data), &v); err != nil { t.Fatal(err) } actual := v expect := testUnmarshalStruct{ Title: `Unmarshaled: title = "Alice's Adventures in Wonderland" author = "Lewis Carroll" `, Author: "", } if !reflect.DeepEqual(actual, expect) { t.Errorf(`toml.Unmarshal(data, &v); v => %#v; want %#v`, actual, expect) } } func TestUnmarshal_WithMultibyteString(t *testing.T) { type testStruct struct { Name string Numbers []string } v := testStruct{} data := `name = "七一〇七" numbers = ["壱", "弐", "参"] ` if err := toml.Unmarshal([]byte(data), &v); err != nil { t.Fatal(err) } actual := v expect := testStruct{ Name: "七一〇七", Numbers: []string{"壱", "弐", "参"}, } if !reflect.DeepEqual(actual, expect) { t.Errorf(`toml.Unmarshal([]byte(data), &v); v => %#v; want %#v`, actual, expect) } } func TestUnmarshal_WithPointers(t *testing.T) { type Inline struct { Key1 string Key2 *string Key3 **string } type Table struct { Key1 *string Key2 **string Key3 ***string } type testStruct struct { Inline *Inline Tables []*Table } type testStruct2 struct { Inline **Inline Tables []**Table } type testStruct3 struct { Inline ***Inline Tables []***Table } data := ` inline = { key1 = "test", key2 = "a", key3 = "b" } [[tables]] key1 = "a" key2 = "a" key3 = "a" [[tables]] key1 = "b" key2 = "b" key3 = "b" ` s1 := "a" s2 := &s1 s3 := &s2 s4 := &s3 s5 := "b" s6 := &s5 s7 := &s6 s8 := &s7 i1 := &Inline{"test", s2, s7} i2 := &i1 i3 := &i2 t1 := &Table{s2, s3, s4} t2 := &Table{s6, s7, s8} t3 := &t1 t4 := &t2 sc := &testStruct{ Inline: i1, Tables: []*Table{t1, t2}, } ac := &testStruct{} testUnmarshal(t, []testcase{ {data, nil, ac, sc}, {data, nil, &testStruct2{}, &testStruct2{ Inline: i2, Tables: []**Table{&t1, &t2}, }}, {data, nil, &testStruct3{}, &testStruct3{ Inline: i3, Tables: []***Table{&t3, &t4}, }}, }) } func TestUnmarshalMap(t *testing.T) { testUnmarshal(t, []testcase{ {` name = "evan" foo = 1 `, nil, map[string]interface{}{}, map[string]interface{}{ "name": "evan", "foo": int64(1), }}, }) } golang-github-naoina-toml-0.0~git20170709.5811abc/encode.go000066400000000000000000000151421254735420300227070ustar00rootroot00000000000000package toml import ( "fmt" "io" "reflect" "strconv" "time" "go/ast" "github.com/naoina/go-stringutil" ) const ( tagOmitempty = "omitempty" tagSkip = "-" ) // Marshal returns the TOML encoding of v. // // Struct values encode as TOML. Each exported struct field becomes a field of // the TOML structure unless // - the field's tag is "-", or // - the field is empty and its tag specifies the "omitempty" option. // The "toml" key in the struct field's tag value is the key name, followed by // an optional comma and options. Examples: // // // Field is ignored by this package. // Field int `toml:"-"` // // // Field appears in TOML as key "myName". // Field int `toml:"myName"` // // // Field appears in TOML as key "myName" and the field is omitted from the // // result of encoding if its value is empty. // Field int `toml:"myName,omitempty"` // // // Field appears in TOML as key "field", but the field is skipped if // // empty. // // Note the leading comma. // Field int `toml:",omitempty"` func Marshal(v interface{}) ([]byte, error) { return marshal(nil, "", reflect.ValueOf(v), false, false) } // A Encoder writes TOML to an output stream. type Encoder struct { w io.Writer } // NewEncoder returns a new Encoder that writes to w. func NewEncoder(w io.Writer) *Encoder { return &Encoder{ w: w, } } // Encode writes the TOML of v to the stream. // See the documentation for Marshal for details about the conversion of Go values to TOML. func (e *Encoder) Encode(v interface{}) error { b, err := Marshal(v) if err != nil { return err } _, err = e.w.Write(b) return err } // Marshaler is the interface implemented by objects that can marshal themshelves into valid TOML. type Marshaler interface { MarshalTOML() ([]byte, error) } func marshal(buf []byte, prefix string, rv reflect.Value, inArray, arrayTable bool) ([]byte, error) { rt := rv.Type() for i := 0; i < rv.NumField(); i++ { ft := rt.Field(i) if !ast.IsExported(ft.Name) { continue } colName, rest := extractTag(rt.Field(i).Tag.Get(fieldTagName)) if colName == tagSkip { continue } if colName == "" { colName = stringutil.ToSnakeCase(ft.Name) } fv := rv.Field(i) switch rest { case tagOmitempty: if fv.Interface() == reflect.Zero(ft.Type).Interface() { continue } } var err error if buf, err = encodeValue(buf, prefix, colName, fv, inArray, arrayTable); err != nil { return nil, err } } return buf, nil } func encodeValue(buf []byte, prefix, name string, fv reflect.Value, inArray, arrayTable bool) ([]byte, error) { switch t := fv.Interface().(type) { case Marshaler: b, err := t.MarshalTOML() if err != nil { return nil, err } return appendNewline(append(appendKey(buf, name, inArray, arrayTable), b...), inArray, arrayTable), nil case time.Time: return appendNewline(encodeTime(appendKey(buf, name, inArray, arrayTable), t), inArray, arrayTable), nil } switch fv.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return appendNewline(encodeInt(appendKey(buf, name, inArray, arrayTable), fv.Int()), inArray, arrayTable), nil case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: return appendNewline(encodeUint(appendKey(buf, name, inArray, arrayTable), fv.Uint()), inArray, arrayTable), nil case reflect.Float32, reflect.Float64: return appendNewline(encodeFloat(appendKey(buf, name, inArray, arrayTable), fv.Float()), inArray, arrayTable), nil case reflect.Bool: return appendNewline(encodeBool(appendKey(buf, name, inArray, arrayTable), fv.Bool()), inArray, arrayTable), nil case reflect.String: return appendNewline(encodeString(appendKey(buf, name, inArray, arrayTable), fv.String()), inArray, arrayTable), nil case reflect.Slice, reflect.Array: ft := fv.Type().Elem() for ft.Kind() == reflect.Ptr { ft = ft.Elem() } if ft.Kind() == reflect.Struct { name := tableName(prefix, name) var err error for i := 0; i < fv.Len(); i++ { if buf, err = marshal(append(append(append(buf, '[', '['), name...), ']', ']', '\n'), name, fv.Index(i), false, true); err != nil { return nil, err } } return buf, nil } buf = append(appendKey(buf, name, inArray, arrayTable), '[') var err error for i := 0; i < fv.Len(); i++ { if i != 0 { buf = append(buf, ',') } if buf, err = encodeValue(buf, prefix, name, fv.Index(i), true, false); err != nil { return nil, err } } return appendNewline(append(buf, ']'), inArray, arrayTable), nil case reflect.Struct: name := tableName(prefix, name) return marshal(append(append(append(buf, '['), name...), ']', '\n'), name, fv, inArray, arrayTable) case reflect.Interface: var err error if buf, err = encodeInterface(appendKey(buf, name, inArray, arrayTable), fv.Interface()); err != nil { return nil, err } return appendNewline(buf, inArray, arrayTable), nil } return nil, fmt.Errorf("toml: marshal: unsupported type %v", fv.Kind()) } func appendKey(buf []byte, key string, inArray, arrayTable bool) []byte { if !inArray { return append(append(buf, key...), '=') } return buf } func appendNewline(buf []byte, inArray, arrayTable bool) []byte { if !inArray { return append(buf, '\n') } return buf } func encodeInterface(buf []byte, v interface{}) ([]byte, error) { switch v := v.(type) { case int: return encodeInt(buf, int64(v)), nil case int8: return encodeInt(buf, int64(v)), nil case int16: return encodeInt(buf, int64(v)), nil case int32: return encodeInt(buf, int64(v)), nil case int64: return encodeInt(buf, v), nil case uint: return encodeUint(buf, uint64(v)), nil case uint8: return encodeUint(buf, uint64(v)), nil case uint16: return encodeUint(buf, uint64(v)), nil case uint32: return encodeUint(buf, uint64(v)), nil case uint64: return encodeUint(buf, v), nil case float32: return encodeFloat(buf, float64(v)), nil case float64: return encodeFloat(buf, v), nil case bool: return encodeBool(buf, v), nil case string: return encodeString(buf, v), nil } return nil, fmt.Errorf("toml: marshal: unable to detect a type of value `%v'", v) } func encodeInt(buf []byte, i int64) []byte { return strconv.AppendInt(buf, i, 10) } func encodeUint(buf []byte, u uint64) []byte { return strconv.AppendUint(buf, u, 10) } func encodeFloat(buf []byte, f float64) []byte { return strconv.AppendFloat(buf, f, 'e', -1, 64) } func encodeBool(buf []byte, b bool) []byte { return strconv.AppendBool(buf, b) } func encodeString(buf []byte, s string) []byte { return strconv.AppendQuote(buf, s) } func encodeTime(buf []byte, t time.Time) []byte { return append(buf, t.Format(time.RFC3339Nano)...) } golang-github-naoina-toml-0.0~git20170709.5811abc/encode_test.go000066400000000000000000000142031254735420300237430ustar00rootroot00000000000000package toml_test import ( "reflect" "testing" "time" "github.com/naoina/toml" ) func TestMarshal(t *testing.T) { for _, v := range []struct { v interface{} expect string }{ {struct{ Name string }{"alice"}, "name=\"alice\"\n"}, {struct{ Age int }{7}, "age=7\n"}, {struct { Name string Age int }{"alice", 7}, "name=\"alice\"\nage=7\n"}, {struct { Name string `toml:"-"` Age int }{"alice", 7}, "age=7\n"}, {struct { Name string `toml:"my_name"` }{"bob"}, "my_name=\"bob\"\n"}, {struct { Name string `toml:"my_name,omitempty"` }{"bob"}, "my_name=\"bob\"\n"}, {struct { Name string `toml:",omitempty"` }{"bob"}, "name=\"bob\"\n"}, {struct { Name string `toml:",omitempty"` }{""}, ""}, } { b, err := toml.Marshal(v.v) var actual interface{} = err var expect interface{} = nil if !reflect.DeepEqual(actual, expect) { t.Errorf(`Marshal(%#v) => %#v; want %#v`, v.v, actual, expect) } actual = string(b) expect = v.expect if !reflect.DeepEqual(actual, expect) { t.Errorf(`Marshal(%#v); v => %#v; want %#v`, v, actual, expect) } } } func TestMarshalWhole(t *testing.T) { for _, v := range []struct { v interface{} expect string }{ { testStruct{ Table: Table{ Key: "value", Subtable: Subtable{ Key: "another value", }, Inline: Inline{ Name: Name{ First: "Tom", Last: "Preston-Werner", }, Point: Point{ X: 1, Y: 2, }, }, }, X: X{}, String: String{ Basic: Basic{ Basic: "I'm a string. \"You can quote me\". Name\tJos\u00E9\nLocation\tSF.", }, Multiline: Multiline{ Key1: "One\nTwo", Continued: Continued{ Key1: "The quick brown fox jumps over the lazy dog.", }, }, Literal: Literal{ Winpath: `C:\Users\nodejs\templates`, Winpath2: `\\ServerX\admin$\system32\`, Quoted: `Tom "Dubs" Preston-Werner`, Regex: `<\i\c*\s*>`, Multiline: LiteralMultiline{ Regex2: `I [dw]on't need \d{2} apples`, Lines: "The first newline is\ntrimmed in raw strings.\n All other whitespace\n is preserved.\n", }, }, }, Integer: Integer{ Key1: 99, Key2: 42, Key3: 0, Key4: -17, Underscores: IntegerUnderscores{ Key1: 1000, Key2: 5349221, Key3: 12345, }, }, Float: Float{ Fractional: Fractional{ Key1: 1.0, Key2: 3.1415, Key3: -0.01, }, Exponent: Exponent{ Key1: 5e22, Key2: 1e6, Key3: -2e-2, }, Both: Both{ Key: 6.626e-34, }, Underscores: FloatUnderscores{ Key1: 9224617.445991228313, Key2: 1e100, }, }, Boolean: Boolean{ True: true, False: false, }, Datetime: Datetime{ Key1: mustTime(time.Parse(time.RFC3339Nano, "1979-05-27T07:32:00Z")), Key2: mustTime(time.Parse(time.RFC3339Nano, "1979-05-27T00:32:00-07:00")), Key3: mustTime(time.Parse(time.RFC3339Nano, "1979-05-27T00:32:00.999999-07:00")), }, Array: Array{ Key1: []int{1, 2, 3}, Key2: []string{"red", "yellow", "green"}, Key3: [][]int{{1, 2}, {3, 4, 5}}, Key4: [][]interface{}{{int64(1), int64(2)}, {"a", "b", "c"}}, Key5: []int{1, 2, 3}, Key6: []int{1, 2}, }, Products: []Product{ {Name: "Hammer", Sku: 738594937}, {}, {Name: "Nail", Sku: 284758393, Color: "gray"}, }, Fruit: []Fruit{ { Name: "apple", Physical: Physical{ Color: "red", Shape: "round", }, Variety: []Variety{ {Name: "red delicious"}, {Name: "granny smith"}, }, }, { Name: "banana", Variety: []Variety{ {Name: "plantain"}, }, }, }, }, `[table] key="value" [table.subtable] key="another value" [table.inline] [table.inline.name] first="Tom" last="Preston-Werner" [table.inline.point] x=1 y=2 [x] [x.y] [x.y.z] [x.y.z.w] [string] [string.basic] basic="I'm a string. \"You can quote me\". Name\tJosé\nLocation\tSF." [string.multiline] key1="One\nTwo" key2="" key3="" [string.multiline.continued] key1="The quick brown fox jumps over the lazy dog." key2="" key3="" [string.literal] winpath="C:\\Users\\nodejs\\templates" winpath2="\\\\ServerX\\admin$\\system32\\" quoted="Tom \"Dubs\" Preston-Werner" regex="<\\i\\c*\\s*>" [string.literal.multiline] regex2="I [dw]on't need \\d{2} apples" lines="The first newline is\ntrimmed in raw strings.\n All other whitespace\n is preserved.\n" [integer] key1=99 key2=42 key3=0 key4=-17 [integer.underscores] key1=1000 key2=5349221 key3=12345 [float] [float.fractional] key1=1e+00 key2=3.1415e+00 key3=-1e-02 [float.exponent] key1=5e+22 key2=1e+06 key3=-2e-02 [float.both] key=6.626e-34 [float.underscores] key1=9.224617445991227e+06 key2=1e+100 [boolean] true=true false=false [datetime] key1=1979-05-27T07:32:00Z key2=1979-05-27T00:32:00-07:00 key3=1979-05-27T00:32:00.999999-07:00 [array] key1=[1,2,3] key2=["red","yellow","green"] key3=[[1,2],[3,4,5]] key4=[[1,2],["a","b","c"]] key5=[1,2,3] key6=[1,2] [[products]] name="Hammer" sku=738594937 color="" [[products]] name="" sku=0 color="" [[products]] name="Nail" sku=284758393 color="gray" [[fruit]] name="apple" [fruit.physical] color="red" shape="round" [[fruit.variety]] name="red delicious" [[fruit.variety]] name="granny smith" [[fruit]] name="banana" [fruit.physical] color="" shape="" [[fruit.variety]] name="plantain" `, }, } { b, err := toml.Marshal(v.v) var actual interface{} = err var expect interface{} = nil if !reflect.DeepEqual(actual, expect) { t.Errorf(`Marshal(%#v) => %#v; want %#v`, v.v, actual, expect) } actual = string(b) expect = v.expect if !reflect.DeepEqual(actual, expect) { t.Errorf(`Marshal(%#v); v => %#v; want %#v`, v.v, actual, expect) } // test for reversible. dest := testStruct{} actual = toml.Unmarshal(b, &dest) expect = nil if !reflect.DeepEqual(actual, expect) { t.Errorf(`Unmarshal after Marshal => %#v; want %#v`, actual, expect) } actual = dest expect = v.v if !reflect.DeepEqual(actual, expect) { t.Errorf(`Unmarshal after Marshal => %#v; want %#v`, v, actual, expect) } } } golang-github-naoina-toml-0.0~git20170709.5811abc/error.go000066400000000000000000000011411254735420300225750ustar00rootroot00000000000000package toml import ( "fmt" "reflect" ) func (e *parseError) Line() int { tokens := e.p.tokenTree.Error() positions := make([]int, len(tokens)*2) p := 0 for _, token := range tokens { positions[p], p = int(token.begin), p+1 positions[p], p = int(token.end), p+1 } for _, t := range translatePositions(e.p.Buffer, positions) { if e.p.line < t.line { e.p.line = t.line } } return e.p.line } type errorOutOfRange struct { kind reflect.Kind v interface{} } func (err *errorOutOfRange) Error() string { return fmt.Sprintf("value %d is out of range for `%v` type", err.v, err.kind) } golang-github-naoina-toml-0.0~git20170709.5811abc/parse.go000066400000000000000000000016071254735420300225650ustar00rootroot00000000000000package toml import ( "fmt" "github.com/naoina/toml/ast" ) // Parse returns an AST representation of TOML. // The toplevel is represented by a table. func Parse(data []byte) (*ast.Table, error) { d := &parseState{p: &tomlParser{Buffer: string(data)}} d.init() if err := d.parse(); err != nil { return nil, err } return d.p.toml.table, nil } type parseState struct { p *tomlParser } func (d *parseState) init() { d.p.Init() d.p.toml.init(d.p.buffer) } func (d *parseState) parse() error { if err := d.p.Parse(); err != nil { if err, ok := err.(*parseError); ok { return fmt.Errorf("toml: line %d: parse error", err.Line()) } return err } return d.execute() } func (d *parseState) execute() (err error) { defer func() { e := recover() if e != nil { cerr, ok := e.(convertError) if !ok { panic(e) } err = cerr.err } }() d.p.Execute() return nil } golang-github-naoina-toml-0.0~git20170709.5811abc/parse.peg000066400000000000000000000062321254735420300227320ustar00rootroot00000000000000package toml type tomlParser Peg { toml } TOML <- Expression (newline Expression)* newline? !. { _ = buffer } Expression <- ( { p.SetTableString(begin, end) } / ws keyval ws comment? / ws comment? / ws ) newline <- <[\r\n]+> { p.AddLineCount(end - begin) } ws <- [ \t]* wsnl <- ( [ \t] / <[\r\n]> { p.AddLineCount(end - begin) } )* comment <- '#' <[\t -\0x10FFFF]*> keyval <- key ws '=' ws val { p.AddKeyValue() } key <- bareKey / quotedKey bareKey <- <[0-9A-Za-z\-_]+> { p.SetKey(p.buffer, begin, end) } quotedKey <- '"' '"' { p.SetKey(p.buffer, begin, end) } val <- ( { p.SetTime(begin, end) } / { p.SetFloat64(begin, end) } / { p.SetInt64(begin, end) } / { p.SetString(begin, end) } / { p.SetBool(begin, end) } / { p.SetArray(begin, end) } / inlineTable ) table <- stdTable / arrayTable stdTable <- '[' ws ws ']' { p.SetTable(p.buffer, begin, end) } arrayTable <- '[[' ws ws ']]' { p.SetArrayTable(p.buffer, begin, end) } inlineTable <- ( '{' { p.StartInlineTable() } ws inlineTableKeyValues ws '}' { p.EndInlineTable() } ) inlineTableKeyValues <- (keyval inlineTableValSep?)* tableKey <- key (tableKeySep key)* tableKeySep <- ws '.' ws inlineTableValSep <- ws ',' ws integer <- [\-+]? int int <- [1-9] (digit / '_' digit)+ / digit float <- integer (frac exp? / frac? exp) frac <- '.' digit (digit / '_' digit)* exp <- [eE] [\-+]? digit (digit / '_' digit)* string <- ( mlLiteralString / literalString / mlBasicString / basicString ) basicString <- <'"' basicChar* '"'> { p.SetBasicString(p.buffer, begin, end) } basicChar <- basicUnescaped / escaped escaped <- escape ([btnfr"/\\] / 'u' hexQuad / 'U' hexQuad hexQuad) basicUnescaped <- [ -!#-\[\]-\0x10FFFF] escape <- '\\' mlBasicString <- '"""' mlBasicBody '"""' { p.SetMultilineString() } mlBasicBody <- ( { p.AddMultilineBasicBody(p.buffer, begin, end) } / escape newline wsnl )* literalString <- "'" "'" { p.SetLiteralString(p.buffer, begin, end) } literalChar <- [\t -&(-\0x10FFFF] mlLiteralString <- "'''" "'''" { p.SetMultilineLiteralString(p.buffer, begin, end) } mlLiteralBody <- (!"'''" (mlLiteralChar / newline))* mlLiteralChar <- [\t -\0x10FFFF] hexdigit <- [0-9A-Fa-f] hexQuad <- hexdigit hexdigit hexdigit hexdigit boolean <- 'true' / 'false' dateFullYear <- digitQuad dateMonth <- digitDual dateMDay <- digitDual timeHour <- digitDual timeMinute <- digitDual timeSecond <- digitDual timeSecfrac <- '.' digit+ timeNumoffset <- [\-+] timeHour ':' timeMinute timeOffset <- 'Z' / timeNumoffset partialTime <- timeHour ':' timeMinute ':' timeSecond timeSecfrac? fullDate <- dateFullYear '-' dateMonth '-' dateMDay fullTime <- partialTime timeOffset datetime <- fullDate 'T' fullTime digit <- [0-9] digitDual <- digit digit digitQuad <- digitDual digitDual array <- ( '[' { p.StartArray() } wsnl arrayValues wsnl ']' ) arrayValues <- ( val { p.AddArrayVal() } arraySep? (comment? newline)? )* arraySep <- ws ',' wsnl golang-github-naoina-toml-0.0~git20170709.5811abc/parse.peg.go000066400000000000000000002264161254735420300233460ustar00rootroot00000000000000package toml import ( "fmt" "math" "sort" "strconv" ) const end_symbol rune = 4 /* The rule types inferred from the grammar are below. */ type pegRule uint8 const ( ruleUnknown pegRule = iota ruleTOML ruleExpression rulenewline rulews rulewsnl rulecomment rulekeyval rulekey rulebareKey rulequotedKey ruleval ruletable rulestdTable rulearrayTable ruleinlineTable ruleinlineTableKeyValues ruletableKey ruletableKeySep ruleinlineTableValSep ruleinteger ruleint rulefloat rulefrac ruleexp rulestring rulebasicString rulebasicChar ruleescaped rulebasicUnescaped ruleescape rulemlBasicString rulemlBasicBody ruleliteralString ruleliteralChar rulemlLiteralString rulemlLiteralBody rulemlLiteralChar rulehexdigit rulehexQuad ruleboolean ruledateFullYear ruledateMonth ruledateMDay ruletimeHour ruletimeMinute ruletimeSecond ruletimeSecfrac ruletimeNumoffset ruletimeOffset rulepartialTime rulefullDate rulefullTime ruledatetime ruledigit ruledigitDual ruledigitQuad rulearray rulearrayValues rulearraySep ruleAction0 rulePegText ruleAction1 ruleAction2 ruleAction3 ruleAction4 ruleAction5 ruleAction6 ruleAction7 ruleAction8 ruleAction9 ruleAction10 ruleAction11 ruleAction12 ruleAction13 ruleAction14 ruleAction15 ruleAction16 ruleAction17 ruleAction18 ruleAction19 ruleAction20 ruleAction21 ruleAction22 ruleAction23 rulePre_ rule_In_ rule_Suf ) var rul3s = [...]string{ "Unknown", "TOML", "Expression", "newline", "ws", "wsnl", "comment", "keyval", "key", "bareKey", "quotedKey", "val", "table", "stdTable", "arrayTable", "inlineTable", "inlineTableKeyValues", "tableKey", "tableKeySep", "inlineTableValSep", "integer", "int", "float", "frac", "exp", "string", "basicString", "basicChar", "escaped", "basicUnescaped", "escape", "mlBasicString", "mlBasicBody", "literalString", "literalChar", "mlLiteralString", "mlLiteralBody", "mlLiteralChar", "hexdigit", "hexQuad", "boolean", "dateFullYear", "dateMonth", "dateMDay", "timeHour", "timeMinute", "timeSecond", "timeSecfrac", "timeNumoffset", "timeOffset", "partialTime", "fullDate", "fullTime", "datetime", "digit", "digitDual", "digitQuad", "array", "arrayValues", "arraySep", "Action0", "PegText", "Action1", "Action2", "Action3", "Action4", "Action5", "Action6", "Action7", "Action8", "Action9", "Action10", "Action11", "Action12", "Action13", "Action14", "Action15", "Action16", "Action17", "Action18", "Action19", "Action20", "Action21", "Action22", "Action23", "Pre_", "_In_", "_Suf", } type tokenTree interface { Print() PrintSyntax() PrintSyntaxTree(buffer string) Add(rule pegRule, begin, end, next, depth int) Expand(index int) tokenTree Tokens() <-chan token32 AST() *node32 Error() []token32 trim(length int) } type node32 struct { token32 up, next *node32 } func (node *node32) print(depth int, buffer string) { for node != nil { for c := 0; c < depth; c++ { fmt.Printf(" ") } fmt.Printf("\x1B[34m%v\x1B[m %v\n", rul3s[node.pegRule], strconv.Quote(string(([]rune(buffer)[node.begin:node.end])))) if node.up != nil { node.up.print(depth+1, buffer) } node = node.next } } func (ast *node32) Print(buffer string) { ast.print(0, buffer) } type element struct { node *node32 down *element } /* ${@} bit structure for abstract syntax tree */ type token16 struct { pegRule begin, end, next int16 } func (t *token16) isZero() bool { return t.pegRule == ruleUnknown && t.begin == 0 && t.end == 0 && t.next == 0 } func (t *token16) isParentOf(u token16) bool { return t.begin <= u.begin && t.end >= u.end && t.next > u.next } func (t *token16) getToken32() token32 { return token32{pegRule: t.pegRule, begin: int32(t.begin), end: int32(t.end), next: int32(t.next)} } func (t *token16) String() string { return fmt.Sprintf("\x1B[34m%v\x1B[m %v %v %v", rul3s[t.pegRule], t.begin, t.end, t.next) } type tokens16 struct { tree []token16 ordered [][]token16 } func (t *tokens16) trim(length int) { t.tree = t.tree[0:length] } func (t *tokens16) Print() { for _, token := range t.tree { fmt.Println(token.String()) } } func (t *tokens16) Order() [][]token16 { if t.ordered != nil { return t.ordered } depths := make([]int16, 1, math.MaxInt16) for i, token := range t.tree { if token.pegRule == ruleUnknown { t.tree = t.tree[:i] break } depth := int(token.next) if length := len(depths); depth >= length { depths = depths[:depth+1] } depths[depth]++ } depths = append(depths, 0) ordered, pool := make([][]token16, len(depths)), make([]token16, len(t.tree)+len(depths)) for i, depth := range depths { depth++ ordered[i], pool, depths[i] = pool[:depth], pool[depth:], 0 } for i, token := range t.tree { depth := token.next token.next = int16(i) ordered[depth][depths[depth]] = token depths[depth]++ } t.ordered = ordered return ordered } type state16 struct { token16 depths []int16 leaf bool } func (t *tokens16) AST() *node32 { tokens := t.Tokens() stack := &element{node: &node32{token32: <-tokens}} for token := range tokens { if token.begin == token.end { continue } node := &node32{token32: token} for stack != nil && stack.node.begin >= token.begin && stack.node.end <= token.end { stack.node.next = node.up node.up = stack.node stack = stack.down } stack = &element{node: node, down: stack} } return stack.node } func (t *tokens16) PreOrder() (<-chan state16, [][]token16) { s, ordered := make(chan state16, 6), t.Order() go func() { var states [8]state16 for i, _ := range states { states[i].depths = make([]int16, len(ordered)) } depths, state, depth := make([]int16, len(ordered)), 0, 1 write := func(t token16, leaf bool) { S := states[state] state, S.pegRule, S.begin, S.end, S.next, S.leaf = (state+1)%8, t.pegRule, t.begin, t.end, int16(depth), leaf copy(S.depths, depths) s <- S } states[state].token16 = ordered[0][0] depths[0]++ state++ a, b := ordered[depth-1][depths[depth-1]-1], ordered[depth][depths[depth]] depthFirstSearch: for { for { if i := depths[depth]; i > 0 { if c, j := ordered[depth][i-1], depths[depth-1]; a.isParentOf(c) && (j < 2 || !ordered[depth-1][j-2].isParentOf(c)) { if c.end != b.begin { write(token16{pegRule: rule_In_, begin: c.end, end: b.begin}, true) } break } } if a.begin < b.begin { write(token16{pegRule: rulePre_, begin: a.begin, end: b.begin}, true) } break } next := depth + 1 if c := ordered[next][depths[next]]; c.pegRule != ruleUnknown && b.isParentOf(c) { write(b, false) depths[depth]++ depth, a, b = next, b, c continue } write(b, true) depths[depth]++ c, parent := ordered[depth][depths[depth]], true for { if c.pegRule != ruleUnknown && a.isParentOf(c) { b = c continue depthFirstSearch } else if parent && b.end != a.end { write(token16{pegRule: rule_Suf, begin: b.end, end: a.end}, true) } depth-- if depth > 0 { a, b, c = ordered[depth-1][depths[depth-1]-1], a, ordered[depth][depths[depth]] parent = a.isParentOf(b) continue } break depthFirstSearch } } close(s) }() return s, ordered } func (t *tokens16) PrintSyntax() { tokens, ordered := t.PreOrder() max := -1 for token := range tokens { if !token.leaf { fmt.Printf("%v", token.begin) for i, leaf, depths := 0, int(token.next), token.depths; i < leaf; i++ { fmt.Printf(" \x1B[36m%v\x1B[m", rul3s[ordered[i][depths[i]-1].pegRule]) } fmt.Printf(" \x1B[36m%v\x1B[m\n", rul3s[token.pegRule]) } else if token.begin == token.end { fmt.Printf("%v", token.begin) for i, leaf, depths := 0, int(token.next), token.depths; i < leaf; i++ { fmt.Printf(" \x1B[31m%v\x1B[m", rul3s[ordered[i][depths[i]-1].pegRule]) } fmt.Printf(" \x1B[31m%v\x1B[m\n", rul3s[token.pegRule]) } else { for c, end := token.begin, token.end; c < end; c++ { if i := int(c); max+1 < i { for j := max; j < i; j++ { fmt.Printf("skip %v %v\n", j, token.String()) } max = i } else if i := int(c); i <= max { for j := i; j <= max; j++ { fmt.Printf("dupe %v %v\n", j, token.String()) } } else { max = int(c) } fmt.Printf("%v", c) for i, leaf, depths := 0, int(token.next), token.depths; i < leaf; i++ { fmt.Printf(" \x1B[34m%v\x1B[m", rul3s[ordered[i][depths[i]-1].pegRule]) } fmt.Printf(" \x1B[34m%v\x1B[m\n", rul3s[token.pegRule]) } fmt.Printf("\n") } } } func (t *tokens16) PrintSyntaxTree(buffer string) { tokens, _ := t.PreOrder() for token := range tokens { for c := 0; c < int(token.next); c++ { fmt.Printf(" ") } fmt.Printf("\x1B[34m%v\x1B[m %v\n", rul3s[token.pegRule], strconv.Quote(string(([]rune(buffer)[token.begin:token.end])))) } } func (t *tokens16) Add(rule pegRule, begin, end, depth, index int) { t.tree[index] = token16{pegRule: rule, begin: int16(begin), end: int16(end), next: int16(depth)} } func (t *tokens16) Tokens() <-chan token32 { s := make(chan token32, 16) go func() { for _, v := range t.tree { s <- v.getToken32() } close(s) }() return s } func (t *tokens16) Error() []token32 { ordered := t.Order() length := len(ordered) tokens, length := make([]token32, length), length-1 for i, _ := range tokens { o := ordered[length-i] if len(o) > 1 { tokens[i] = o[len(o)-2].getToken32() } } return tokens } /* ${@} bit structure for abstract syntax tree */ type token32 struct { pegRule begin, end, next int32 } func (t *token32) isZero() bool { return t.pegRule == ruleUnknown && t.begin == 0 && t.end == 0 && t.next == 0 } func (t *token32) isParentOf(u token32) bool { return t.begin <= u.begin && t.end >= u.end && t.next > u.next } func (t *token32) getToken32() token32 { return token32{pegRule: t.pegRule, begin: int32(t.begin), end: int32(t.end), next: int32(t.next)} } func (t *token32) String() string { return fmt.Sprintf("\x1B[34m%v\x1B[m %v %v %v", rul3s[t.pegRule], t.begin, t.end, t.next) } type tokens32 struct { tree []token32 ordered [][]token32 } func (t *tokens32) trim(length int) { t.tree = t.tree[0:length] } func (t *tokens32) Print() { for _, token := range t.tree { fmt.Println(token.String()) } } func (t *tokens32) Order() [][]token32 { if t.ordered != nil { return t.ordered } depths := make([]int32, 1, math.MaxInt16) for i, token := range t.tree { if token.pegRule == ruleUnknown { t.tree = t.tree[:i] break } depth := int(token.next) if length := len(depths); depth >= length { depths = depths[:depth+1] } depths[depth]++ } depths = append(depths, 0) ordered, pool := make([][]token32, len(depths)), make([]token32, len(t.tree)+len(depths)) for i, depth := range depths { depth++ ordered[i], pool, depths[i] = pool[:depth], pool[depth:], 0 } for i, token := range t.tree { depth := token.next token.next = int32(i) ordered[depth][depths[depth]] = token depths[depth]++ } t.ordered = ordered return ordered } type state32 struct { token32 depths []int32 leaf bool } func (t *tokens32) AST() *node32 { tokens := t.Tokens() stack := &element{node: &node32{token32: <-tokens}} for token := range tokens { if token.begin == token.end { continue } node := &node32{token32: token} for stack != nil && stack.node.begin >= token.begin && stack.node.end <= token.end { stack.node.next = node.up node.up = stack.node stack = stack.down } stack = &element{node: node, down: stack} } return stack.node } func (t *tokens32) PreOrder() (<-chan state32, [][]token32) { s, ordered := make(chan state32, 6), t.Order() go func() { var states [8]state32 for i, _ := range states { states[i].depths = make([]int32, len(ordered)) } depths, state, depth := make([]int32, len(ordered)), 0, 1 write := func(t token32, leaf bool) { S := states[state] state, S.pegRule, S.begin, S.end, S.next, S.leaf = (state+1)%8, t.pegRule, t.begin, t.end, int32(depth), leaf copy(S.depths, depths) s <- S } states[state].token32 = ordered[0][0] depths[0]++ state++ a, b := ordered[depth-1][depths[depth-1]-1], ordered[depth][depths[depth]] depthFirstSearch: for { for { if i := depths[depth]; i > 0 { if c, j := ordered[depth][i-1], depths[depth-1]; a.isParentOf(c) && (j < 2 || !ordered[depth-1][j-2].isParentOf(c)) { if c.end != b.begin { write(token32{pegRule: rule_In_, begin: c.end, end: b.begin}, true) } break } } if a.begin < b.begin { write(token32{pegRule: rulePre_, begin: a.begin, end: b.begin}, true) } break } next := depth + 1 if c := ordered[next][depths[next]]; c.pegRule != ruleUnknown && b.isParentOf(c) { write(b, false) depths[depth]++ depth, a, b = next, b, c continue } write(b, true) depths[depth]++ c, parent := ordered[depth][depths[depth]], true for { if c.pegRule != ruleUnknown && a.isParentOf(c) { b = c continue depthFirstSearch } else if parent && b.end != a.end { write(token32{pegRule: rule_Suf, begin: b.end, end: a.end}, true) } depth-- if depth > 0 { a, b, c = ordered[depth-1][depths[depth-1]-1], a, ordered[depth][depths[depth]] parent = a.isParentOf(b) continue } break depthFirstSearch } } close(s) }() return s, ordered } func (t *tokens32) PrintSyntax() { tokens, ordered := t.PreOrder() max := -1 for token := range tokens { if !token.leaf { fmt.Printf("%v", token.begin) for i, leaf, depths := 0, int(token.next), token.depths; i < leaf; i++ { fmt.Printf(" \x1B[36m%v\x1B[m", rul3s[ordered[i][depths[i]-1].pegRule]) } fmt.Printf(" \x1B[36m%v\x1B[m\n", rul3s[token.pegRule]) } else if token.begin == token.end { fmt.Printf("%v", token.begin) for i, leaf, depths := 0, int(token.next), token.depths; i < leaf; i++ { fmt.Printf(" \x1B[31m%v\x1B[m", rul3s[ordered[i][depths[i]-1].pegRule]) } fmt.Printf(" \x1B[31m%v\x1B[m\n", rul3s[token.pegRule]) } else { for c, end := token.begin, token.end; c < end; c++ { if i := int(c); max+1 < i { for j := max; j < i; j++ { fmt.Printf("skip %v %v\n", j, token.String()) } max = i } else if i := int(c); i <= max { for j := i; j <= max; j++ { fmt.Printf("dupe %v %v\n", j, token.String()) } } else { max = int(c) } fmt.Printf("%v", c) for i, leaf, depths := 0, int(token.next), token.depths; i < leaf; i++ { fmt.Printf(" \x1B[34m%v\x1B[m", rul3s[ordered[i][depths[i]-1].pegRule]) } fmt.Printf(" \x1B[34m%v\x1B[m\n", rul3s[token.pegRule]) } fmt.Printf("\n") } } } func (t *tokens32) PrintSyntaxTree(buffer string) { tokens, _ := t.PreOrder() for token := range tokens { for c := 0; c < int(token.next); c++ { fmt.Printf(" ") } fmt.Printf("\x1B[34m%v\x1B[m %v\n", rul3s[token.pegRule], strconv.Quote(string(([]rune(buffer)[token.begin:token.end])))) } } func (t *tokens32) Add(rule pegRule, begin, end, depth, index int) { t.tree[index] = token32{pegRule: rule, begin: int32(begin), end: int32(end), next: int32(depth)} } func (t *tokens32) Tokens() <-chan token32 { s := make(chan token32, 16) go func() { for _, v := range t.tree { s <- v.getToken32() } close(s) }() return s } func (t *tokens32) Error() []token32 { ordered := t.Order() length := len(ordered) tokens, length := make([]token32, length), length-1 for i, _ := range tokens { o := ordered[length-i] if len(o) > 1 { tokens[i] = o[len(o)-2].getToken32() } } return tokens } func (t *tokens16) Expand(index int) tokenTree { tree := t.tree if index >= len(tree) { expanded := make([]token32, 2*len(tree)) for i, v := range tree { expanded[i] = v.getToken32() } return &tokens32{tree: expanded} } return nil } func (t *tokens32) Expand(index int) tokenTree { tree := t.tree if index >= len(tree) { expanded := make([]token32, 2*len(tree)) copy(expanded, tree) t.tree = expanded } return nil } type tomlParser struct { toml Buffer string buffer []rune rules [85]func() bool Parse func(rule ...int) error Reset func() tokenTree } type textPosition struct { line, symbol int } type textPositionMap map[int]textPosition func translatePositions(buffer string, positions []int) textPositionMap { length, translations, j, line, symbol := len(positions), make(textPositionMap, len(positions)), 0, 1, 0 sort.Ints(positions) search: for i, c := range buffer[0:] { if c == '\n' { line, symbol = line+1, 0 } else { symbol++ } if i == positions[j] { translations[positions[j]] = textPosition{line, symbol} for j++; j < length; j++ { if i != positions[j] { continue search } } break search } } return translations } type parseError struct { p *tomlParser } func (e *parseError) Error() string { tokens, error := e.p.tokenTree.Error(), "\n" positions, p := make([]int, 2*len(tokens)), 0 for _, token := range tokens { positions[p], p = int(token.begin), p+1 positions[p], p = int(token.end), p+1 } translations := translatePositions(e.p.Buffer, positions) for _, token := range tokens { begin, end := int(token.begin), int(token.end) error += fmt.Sprintf("parse error near \x1B[34m%v\x1B[m (line %v symbol %v - line %v symbol %v):\n%v\n", rul3s[token.pegRule], translations[begin].line, translations[begin].symbol, translations[end].line, translations[end].symbol, /*strconv.Quote(*/ e.p.Buffer[begin:end] /*)*/) } return error } func (p *tomlParser) PrintSyntaxTree() { p.tokenTree.PrintSyntaxTree(p.Buffer) } func (p *tomlParser) Highlighter() { p.tokenTree.PrintSyntax() } func (p *tomlParser) Execute() { buffer, begin, end := p.Buffer, 0, 0 for token := range p.tokenTree.Tokens() { switch token.pegRule { case rulePegText: begin, end = int(token.begin), int(token.end) case ruleAction0: _ = buffer case ruleAction1: p.SetTableString(begin, end) case ruleAction2: p.AddLineCount(end - begin) case ruleAction3: p.AddLineCount(end - begin) case ruleAction4: p.AddKeyValue() case ruleAction5: p.SetKey(p.buffer, begin, end) case ruleAction6: p.SetKey(p.buffer, begin, end) case ruleAction7: p.SetTime(begin, end) case ruleAction8: p.SetFloat64(begin, end) case ruleAction9: p.SetInt64(begin, end) case ruleAction10: p.SetString(begin, end) case ruleAction11: p.SetBool(begin, end) case ruleAction12: p.SetArray(begin, end) case ruleAction13: p.SetTable(p.buffer, begin, end) case ruleAction14: p.SetArrayTable(p.buffer, begin, end) case ruleAction15: p.StartInlineTable() case ruleAction16: p.EndInlineTable() case ruleAction17: p.SetBasicString(p.buffer, begin, end) case ruleAction18: p.SetMultilineString() case ruleAction19: p.AddMultilineBasicBody(p.buffer, begin, end) case ruleAction20: p.SetLiteralString(p.buffer, begin, end) case ruleAction21: p.SetMultilineLiteralString(p.buffer, begin, end) case ruleAction22: p.StartArray() case ruleAction23: p.AddArrayVal() } } _, _, _ = buffer, begin, end } func (p *tomlParser) Init() { p.buffer = []rune(p.Buffer) if len(p.buffer) == 0 || p.buffer[len(p.buffer)-1] != end_symbol { p.buffer = append(p.buffer, end_symbol) } var tree tokenTree = &tokens16{tree: make([]token16, math.MaxInt16)} position, depth, tokenIndex, buffer, _rules := 0, 0, 0, p.buffer, p.rules p.Parse = func(rule ...int) error { r := 1 if len(rule) > 0 { r = rule[0] } matches := p.rules[r]() p.tokenTree = tree if matches { p.tokenTree.trim(tokenIndex) return nil } return &parseError{p} } p.Reset = func() { position, tokenIndex, depth = 0, 0, 0 } add := func(rule pegRule, begin int) { if t := tree.Expand(tokenIndex); t != nil { tree = t } tree.Add(rule, begin, position, depth, tokenIndex) tokenIndex++ } matchDot := func() bool { if buffer[position] != end_symbol { position++ return true } return false } /*matchChar := func(c byte) bool { if buffer[position] == c { position++ return true } return false }*/ /*matchRange := func(lower byte, upper byte) bool { if c := buffer[position]; c >= lower && c <= upper { position++ return true } return false }*/ _rules = [...]func() bool{ nil, /* 0 TOML <- <(Expression (newline Expression)* newline? !. Action0)> */ func() bool { position0, tokenIndex0, depth0 := position, tokenIndex, depth { position1 := position depth++ if !_rules[ruleExpression]() { goto l0 } l2: { position3, tokenIndex3, depth3 := position, tokenIndex, depth if !_rules[rulenewline]() { goto l3 } if !_rules[ruleExpression]() { goto l3 } goto l2 l3: position, tokenIndex, depth = position3, tokenIndex3, depth3 } { position4, tokenIndex4, depth4 := position, tokenIndex, depth if !_rules[rulenewline]() { goto l4 } goto l5 l4: position, tokenIndex, depth = position4, tokenIndex4, depth4 } l5: { position6, tokenIndex6, depth6 := position, tokenIndex, depth if !matchDot() { goto l6 } goto l0 l6: position, tokenIndex, depth = position6, tokenIndex6, depth6 } { add(ruleAction0, position) } depth-- add(ruleTOML, position1) } return true l0: position, tokenIndex, depth = position0, tokenIndex0, depth0 return false }, /* 1 Expression <- <((<(ws table ws comment? (wsnl keyval ws comment?)*)> Action1) / (ws keyval ws comment?) / (ws comment?) / ws)> */ func() bool { position8, tokenIndex8, depth8 := position, tokenIndex, depth { position9 := position depth++ { position10, tokenIndex10, depth10 := position, tokenIndex, depth { position12 := position depth++ if !_rules[rulews]() { goto l11 } { position13 := position depth++ { position14, tokenIndex14, depth14 := position, tokenIndex, depth { position16 := position depth++ if buffer[position] != rune('[') { goto l15 } position++ if !_rules[rulews]() { goto l15 } { position17 := position depth++ if !_rules[ruletableKey]() { goto l15 } depth-- add(rulePegText, position17) } if !_rules[rulews]() { goto l15 } if buffer[position] != rune(']') { goto l15 } position++ { add(ruleAction13, position) } depth-- add(rulestdTable, position16) } goto l14 l15: position, tokenIndex, depth = position14, tokenIndex14, depth14 { position19 := position depth++ if buffer[position] != rune('[') { goto l11 } position++ if buffer[position] != rune('[') { goto l11 } position++ if !_rules[rulews]() { goto l11 } { position20 := position depth++ if !_rules[ruletableKey]() { goto l11 } depth-- add(rulePegText, position20) } if !_rules[rulews]() { goto l11 } if buffer[position] != rune(']') { goto l11 } position++ if buffer[position] != rune(']') { goto l11 } position++ { add(ruleAction14, position) } depth-- add(rulearrayTable, position19) } } l14: depth-- add(ruletable, position13) } if !_rules[rulews]() { goto l11 } { position22, tokenIndex22, depth22 := position, tokenIndex, depth if !_rules[rulecomment]() { goto l22 } goto l23 l22: position, tokenIndex, depth = position22, tokenIndex22, depth22 } l23: l24: { position25, tokenIndex25, depth25 := position, tokenIndex, depth if !_rules[rulewsnl]() { goto l25 } if !_rules[rulekeyval]() { goto l25 } if !_rules[rulews]() { goto l25 } { position26, tokenIndex26, depth26 := position, tokenIndex, depth if !_rules[rulecomment]() { goto l26 } goto l27 l26: position, tokenIndex, depth = position26, tokenIndex26, depth26 } l27: goto l24 l25: position, tokenIndex, depth = position25, tokenIndex25, depth25 } depth-- add(rulePegText, position12) } { add(ruleAction1, position) } goto l10 l11: position, tokenIndex, depth = position10, tokenIndex10, depth10 if !_rules[rulews]() { goto l29 } if !_rules[rulekeyval]() { goto l29 } if !_rules[rulews]() { goto l29 } { position30, tokenIndex30, depth30 := position, tokenIndex, depth if !_rules[rulecomment]() { goto l30 } goto l31 l30: position, tokenIndex, depth = position30, tokenIndex30, depth30 } l31: goto l10 l29: position, tokenIndex, depth = position10, tokenIndex10, depth10 if !_rules[rulews]() { goto l32 } { position33, tokenIndex33, depth33 := position, tokenIndex, depth if !_rules[rulecomment]() { goto l33 } goto l34 l33: position, tokenIndex, depth = position33, tokenIndex33, depth33 } l34: goto l10 l32: position, tokenIndex, depth = position10, tokenIndex10, depth10 if !_rules[rulews]() { goto l8 } } l10: depth-- add(ruleExpression, position9) } return true l8: position, tokenIndex, depth = position8, tokenIndex8, depth8 return false }, /* 2 newline <- <(<('\r' / '\n')+> Action2)> */ func() bool { position35, tokenIndex35, depth35 := position, tokenIndex, depth { position36 := position depth++ { position37 := position depth++ { position40, tokenIndex40, depth40 := position, tokenIndex, depth if buffer[position] != rune('\r') { goto l41 } position++ goto l40 l41: position, tokenIndex, depth = position40, tokenIndex40, depth40 if buffer[position] != rune('\n') { goto l35 } position++ } l40: l38: { position39, tokenIndex39, depth39 := position, tokenIndex, depth { position42, tokenIndex42, depth42 := position, tokenIndex, depth if buffer[position] != rune('\r') { goto l43 } position++ goto l42 l43: position, tokenIndex, depth = position42, tokenIndex42, depth42 if buffer[position] != rune('\n') { goto l39 } position++ } l42: goto l38 l39: position, tokenIndex, depth = position39, tokenIndex39, depth39 } depth-- add(rulePegText, position37) } { add(ruleAction2, position) } depth-- add(rulenewline, position36) } return true l35: position, tokenIndex, depth = position35, tokenIndex35, depth35 return false }, /* 3 ws <- <(' ' / '\t')*> */ func() bool { { position46 := position depth++ l47: { position48, tokenIndex48, depth48 := position, tokenIndex, depth { position49, tokenIndex49, depth49 := position, tokenIndex, depth if buffer[position] != rune(' ') { goto l50 } position++ goto l49 l50: position, tokenIndex, depth = position49, tokenIndex49, depth49 if buffer[position] != rune('\t') { goto l48 } position++ } l49: goto l47 l48: position, tokenIndex, depth = position48, tokenIndex48, depth48 } depth-- add(rulews, position46) } return true }, /* 4 wsnl <- <((&('\t') '\t') | (&(' ') ' ') | (&('\n' | '\r') (<('\r' / '\n')> Action3)))*> */ func() bool { { position52 := position depth++ l53: { position54, tokenIndex54, depth54 := position, tokenIndex, depth { switch buffer[position] { case '\t': if buffer[position] != rune('\t') { goto l54 } position++ break case ' ': if buffer[position] != rune(' ') { goto l54 } position++ break default: { position56 := position depth++ { position57, tokenIndex57, depth57 := position, tokenIndex, depth if buffer[position] != rune('\r') { goto l58 } position++ goto l57 l58: position, tokenIndex, depth = position57, tokenIndex57, depth57 if buffer[position] != rune('\n') { goto l54 } position++ } l57: depth-- add(rulePegText, position56) } { add(ruleAction3, position) } break } } goto l53 l54: position, tokenIndex, depth = position54, tokenIndex54, depth54 } depth-- add(rulewsnl, position52) } return true }, /* 5 comment <- <('#' <('\t' / [ -􏿿])*>)> */ func() bool { position60, tokenIndex60, depth60 := position, tokenIndex, depth { position61 := position depth++ if buffer[position] != rune('#') { goto l60 } position++ { position62 := position depth++ l63: { position64, tokenIndex64, depth64 := position, tokenIndex, depth { position65, tokenIndex65, depth65 := position, tokenIndex, depth if buffer[position] != rune('\t') { goto l66 } position++ goto l65 l66: position, tokenIndex, depth = position65, tokenIndex65, depth65 if c := buffer[position]; c < rune(' ') || c > rune('\U0010ffff') { goto l64 } position++ } l65: goto l63 l64: position, tokenIndex, depth = position64, tokenIndex64, depth64 } depth-- add(rulePegText, position62) } depth-- add(rulecomment, position61) } return true l60: position, tokenIndex, depth = position60, tokenIndex60, depth60 return false }, /* 6 keyval <- <(key ws '=' ws val Action4)> */ func() bool { position67, tokenIndex67, depth67 := position, tokenIndex, depth { position68 := position depth++ if !_rules[rulekey]() { goto l67 } if !_rules[rulews]() { goto l67 } if buffer[position] != rune('=') { goto l67 } position++ if !_rules[rulews]() { goto l67 } if !_rules[ruleval]() { goto l67 } { add(ruleAction4, position) } depth-- add(rulekeyval, position68) } return true l67: position, tokenIndex, depth = position67, tokenIndex67, depth67 return false }, /* 7 key <- <(bareKey / quotedKey)> */ func() bool { position70, tokenIndex70, depth70 := position, tokenIndex, depth { position71 := position depth++ { position72, tokenIndex72, depth72 := position, tokenIndex, depth { position74 := position depth++ { position75 := position depth++ { switch buffer[position] { case '_': if buffer[position] != rune('_') { goto l73 } position++ break case '-': if buffer[position] != rune('-') { goto l73 } position++ break case 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z': if c := buffer[position]; c < rune('a') || c > rune('z') { goto l73 } position++ break case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': if c := buffer[position]; c < rune('0') || c > rune('9') { goto l73 } position++ break default: if c := buffer[position]; c < rune('A') || c > rune('Z') { goto l73 } position++ break } } l76: { position77, tokenIndex77, depth77 := position, tokenIndex, depth { switch buffer[position] { case '_': if buffer[position] != rune('_') { goto l77 } position++ break case '-': if buffer[position] != rune('-') { goto l77 } position++ break case 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z': if c := buffer[position]; c < rune('a') || c > rune('z') { goto l77 } position++ break case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': if c := buffer[position]; c < rune('0') || c > rune('9') { goto l77 } position++ break default: if c := buffer[position]; c < rune('A') || c > rune('Z') { goto l77 } position++ break } } goto l76 l77: position, tokenIndex, depth = position77, tokenIndex77, depth77 } depth-- add(rulePegText, position75) } { add(ruleAction5, position) } depth-- add(rulebareKey, position74) } goto l72 l73: position, tokenIndex, depth = position72, tokenIndex72, depth72 { position81 := position depth++ if buffer[position] != rune('"') { goto l70 } position++ { position82 := position depth++ if !_rules[rulebasicChar]() { goto l70 } l83: { position84, tokenIndex84, depth84 := position, tokenIndex, depth if !_rules[rulebasicChar]() { goto l84 } goto l83 l84: position, tokenIndex, depth = position84, tokenIndex84, depth84 } depth-- add(rulePegText, position82) } if buffer[position] != rune('"') { goto l70 } position++ { add(ruleAction6, position) } depth-- add(rulequotedKey, position81) } } l72: depth-- add(rulekey, position71) } return true l70: position, tokenIndex, depth = position70, tokenIndex70, depth70 return false }, /* 8 bareKey <- <(<((&('_') '_') | (&('-') '-') | (&('a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z') [a-z]) | (&('0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9') [0-9]) | (&('A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z') [A-Z]))+> Action5)> */ nil, /* 9 quotedKey <- <('"' '"' Action6)> */ nil, /* 10 val <- <(( Action7) / ( Action8) / ((&('{') inlineTable) | (&('[') ( Action12)) | (&('f' | 't') ( Action11)) | (&('"' | '\'') ( Action10)) | (&('+' | '-' | '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9') ( Action9))))> */ func() bool { position88, tokenIndex88, depth88 := position, tokenIndex, depth { position89 := position depth++ { position90, tokenIndex90, depth90 := position, tokenIndex, depth { position92 := position depth++ { position93 := position depth++ { position94 := position depth++ { position95 := position depth++ { position96 := position depth++ if !_rules[ruledigitDual]() { goto l91 } if !_rules[ruledigitDual]() { goto l91 } depth-- add(ruledigitQuad, position96) } depth-- add(ruledateFullYear, position95) } if buffer[position] != rune('-') { goto l91 } position++ { position97 := position depth++ if !_rules[ruledigitDual]() { goto l91 } depth-- add(ruledateMonth, position97) } if buffer[position] != rune('-') { goto l91 } position++ { position98 := position depth++ if !_rules[ruledigitDual]() { goto l91 } depth-- add(ruledateMDay, position98) } depth-- add(rulefullDate, position94) } if buffer[position] != rune('T') { goto l91 } position++ { position99 := position depth++ { position100 := position depth++ if !_rules[ruletimeHour]() { goto l91 } if buffer[position] != rune(':') { goto l91 } position++ if !_rules[ruletimeMinute]() { goto l91 } if buffer[position] != rune(':') { goto l91 } position++ { position101 := position depth++ if !_rules[ruledigitDual]() { goto l91 } depth-- add(ruletimeSecond, position101) } { position102, tokenIndex102, depth102 := position, tokenIndex, depth { position104 := position depth++ if buffer[position] != rune('.') { goto l102 } position++ if !_rules[ruledigit]() { goto l102 } l105: { position106, tokenIndex106, depth106 := position, tokenIndex, depth if !_rules[ruledigit]() { goto l106 } goto l105 l106: position, tokenIndex, depth = position106, tokenIndex106, depth106 } depth-- add(ruletimeSecfrac, position104) } goto l103 l102: position, tokenIndex, depth = position102, tokenIndex102, depth102 } l103: depth-- add(rulepartialTime, position100) } { position107 := position depth++ { position108, tokenIndex108, depth108 := position, tokenIndex, depth if buffer[position] != rune('Z') { goto l109 } position++ goto l108 l109: position, tokenIndex, depth = position108, tokenIndex108, depth108 { position110 := position depth++ { position111, tokenIndex111, depth111 := position, tokenIndex, depth if buffer[position] != rune('-') { goto l112 } position++ goto l111 l112: position, tokenIndex, depth = position111, tokenIndex111, depth111 if buffer[position] != rune('+') { goto l91 } position++ } l111: if !_rules[ruletimeHour]() { goto l91 } if buffer[position] != rune(':') { goto l91 } position++ if !_rules[ruletimeMinute]() { goto l91 } depth-- add(ruletimeNumoffset, position110) } } l108: depth-- add(ruletimeOffset, position107) } depth-- add(rulefullTime, position99) } depth-- add(ruledatetime, position93) } depth-- add(rulePegText, position92) } { add(ruleAction7, position) } goto l90 l91: position, tokenIndex, depth = position90, tokenIndex90, depth90 { position115 := position depth++ { position116 := position depth++ if !_rules[ruleinteger]() { goto l114 } { position117, tokenIndex117, depth117 := position, tokenIndex, depth if !_rules[rulefrac]() { goto l118 } { position119, tokenIndex119, depth119 := position, tokenIndex, depth if !_rules[ruleexp]() { goto l119 } goto l120 l119: position, tokenIndex, depth = position119, tokenIndex119, depth119 } l120: goto l117 l118: position, tokenIndex, depth = position117, tokenIndex117, depth117 { position121, tokenIndex121, depth121 := position, tokenIndex, depth if !_rules[rulefrac]() { goto l121 } goto l122 l121: position, tokenIndex, depth = position121, tokenIndex121, depth121 } l122: if !_rules[ruleexp]() { goto l114 } } l117: depth-- add(rulefloat, position116) } depth-- add(rulePegText, position115) } { add(ruleAction8, position) } goto l90 l114: position, tokenIndex, depth = position90, tokenIndex90, depth90 { switch buffer[position] { case '{': { position125 := position depth++ if buffer[position] != rune('{') { goto l88 } position++ { add(ruleAction15, position) } if !_rules[rulews]() { goto l88 } { position127 := position depth++ l128: { position129, tokenIndex129, depth129 := position, tokenIndex, depth if !_rules[rulekeyval]() { goto l129 } { position130, tokenIndex130, depth130 := position, tokenIndex, depth { position132 := position depth++ if !_rules[rulews]() { goto l130 } if buffer[position] != rune(',') { goto l130 } position++ if !_rules[rulews]() { goto l130 } depth-- add(ruleinlineTableValSep, position132) } goto l131 l130: position, tokenIndex, depth = position130, tokenIndex130, depth130 } l131: goto l128 l129: position, tokenIndex, depth = position129, tokenIndex129, depth129 } depth-- add(ruleinlineTableKeyValues, position127) } if !_rules[rulews]() { goto l88 } if buffer[position] != rune('}') { goto l88 } position++ { add(ruleAction16, position) } depth-- add(ruleinlineTable, position125) } break case '[': { position134 := position depth++ { position135 := position depth++ if buffer[position] != rune('[') { goto l88 } position++ { add(ruleAction22, position) } if !_rules[rulewsnl]() { goto l88 } { position137 := position depth++ l138: { position139, tokenIndex139, depth139 := position, tokenIndex, depth if !_rules[ruleval]() { goto l139 } { add(ruleAction23, position) } { position141, tokenIndex141, depth141 := position, tokenIndex, depth { position143 := position depth++ if !_rules[rulews]() { goto l141 } if buffer[position] != rune(',') { goto l141 } position++ if !_rules[rulewsnl]() { goto l141 } depth-- add(rulearraySep, position143) } goto l142 l141: position, tokenIndex, depth = position141, tokenIndex141, depth141 } l142: { position144, tokenIndex144, depth144 := position, tokenIndex, depth { position146, tokenIndex146, depth146 := position, tokenIndex, depth if !_rules[rulecomment]() { goto l146 } goto l147 l146: position, tokenIndex, depth = position146, tokenIndex146, depth146 } l147: if !_rules[rulenewline]() { goto l144 } goto l145 l144: position, tokenIndex, depth = position144, tokenIndex144, depth144 } l145: goto l138 l139: position, tokenIndex, depth = position139, tokenIndex139, depth139 } depth-- add(rulearrayValues, position137) } if !_rules[rulewsnl]() { goto l88 } if buffer[position] != rune(']') { goto l88 } position++ depth-- add(rulearray, position135) } depth-- add(rulePegText, position134) } { add(ruleAction12, position) } break case 'f', 't': { position149 := position depth++ { position150 := position depth++ { position151, tokenIndex151, depth151 := position, tokenIndex, depth if buffer[position] != rune('t') { goto l152 } position++ if buffer[position] != rune('r') { goto l152 } position++ if buffer[position] != rune('u') { goto l152 } position++ if buffer[position] != rune('e') { goto l152 } position++ goto l151 l152: position, tokenIndex, depth = position151, tokenIndex151, depth151 if buffer[position] != rune('f') { goto l88 } position++ if buffer[position] != rune('a') { goto l88 } position++ if buffer[position] != rune('l') { goto l88 } position++ if buffer[position] != rune('s') { goto l88 } position++ if buffer[position] != rune('e') { goto l88 } position++ } l151: depth-- add(ruleboolean, position150) } depth-- add(rulePegText, position149) } { add(ruleAction11, position) } break case '"', '\'': { position154 := position depth++ { position155 := position depth++ { position156, tokenIndex156, depth156 := position, tokenIndex, depth { position158 := position depth++ if buffer[position] != rune('\'') { goto l157 } position++ if buffer[position] != rune('\'') { goto l157 } position++ if buffer[position] != rune('\'') { goto l157 } position++ { position159 := position depth++ { position160 := position depth++ l161: { position162, tokenIndex162, depth162 := position, tokenIndex, depth { position163, tokenIndex163, depth163 := position, tokenIndex, depth if buffer[position] != rune('\'') { goto l163 } position++ if buffer[position] != rune('\'') { goto l163 } position++ if buffer[position] != rune('\'') { goto l163 } position++ goto l162 l163: position, tokenIndex, depth = position163, tokenIndex163, depth163 } { position164, tokenIndex164, depth164 := position, tokenIndex, depth { position166 := position depth++ { position167, tokenIndex167, depth167 := position, tokenIndex, depth if buffer[position] != rune('\t') { goto l168 } position++ goto l167 l168: position, tokenIndex, depth = position167, tokenIndex167, depth167 if c := buffer[position]; c < rune(' ') || c > rune('\U0010ffff') { goto l165 } position++ } l167: depth-- add(rulemlLiteralChar, position166) } goto l164 l165: position, tokenIndex, depth = position164, tokenIndex164, depth164 if !_rules[rulenewline]() { goto l162 } } l164: goto l161 l162: position, tokenIndex, depth = position162, tokenIndex162, depth162 } depth-- add(rulemlLiteralBody, position160) } depth-- add(rulePegText, position159) } if buffer[position] != rune('\'') { goto l157 } position++ if buffer[position] != rune('\'') { goto l157 } position++ if buffer[position] != rune('\'') { goto l157 } position++ { add(ruleAction21, position) } depth-- add(rulemlLiteralString, position158) } goto l156 l157: position, tokenIndex, depth = position156, tokenIndex156, depth156 { position171 := position depth++ if buffer[position] != rune('\'') { goto l170 } position++ { position172 := position depth++ l173: { position174, tokenIndex174, depth174 := position, tokenIndex, depth { position175 := position depth++ { switch buffer[position] { case '\t': if buffer[position] != rune('\t') { goto l174 } position++ break case ' ', '!', '"', '#', '$', '%', '&': if c := buffer[position]; c < rune(' ') || c > rune('&') { goto l174 } position++ break default: if c := buffer[position]; c < rune('(') || c > rune('\U0010ffff') { goto l174 } position++ break } } depth-- add(ruleliteralChar, position175) } goto l173 l174: position, tokenIndex, depth = position174, tokenIndex174, depth174 } depth-- add(rulePegText, position172) } if buffer[position] != rune('\'') { goto l170 } position++ { add(ruleAction20, position) } depth-- add(ruleliteralString, position171) } goto l156 l170: position, tokenIndex, depth = position156, tokenIndex156, depth156 { position179 := position depth++ if buffer[position] != rune('"') { goto l178 } position++ if buffer[position] != rune('"') { goto l178 } position++ if buffer[position] != rune('"') { goto l178 } position++ { position180 := position depth++ l181: { position182, tokenIndex182, depth182 := position, tokenIndex, depth { position183, tokenIndex183, depth183 := position, tokenIndex, depth { position185 := position depth++ { position186, tokenIndex186, depth186 := position, tokenIndex, depth if !_rules[rulebasicChar]() { goto l187 } goto l186 l187: position, tokenIndex, depth = position186, tokenIndex186, depth186 if !_rules[rulenewline]() { goto l184 } } l186: depth-- add(rulePegText, position185) } { add(ruleAction19, position) } goto l183 l184: position, tokenIndex, depth = position183, tokenIndex183, depth183 if !_rules[ruleescape]() { goto l182 } if !_rules[rulenewline]() { goto l182 } if !_rules[rulewsnl]() { goto l182 } } l183: goto l181 l182: position, tokenIndex, depth = position182, tokenIndex182, depth182 } depth-- add(rulemlBasicBody, position180) } if buffer[position] != rune('"') { goto l178 } position++ if buffer[position] != rune('"') { goto l178 } position++ if buffer[position] != rune('"') { goto l178 } position++ { add(ruleAction18, position) } depth-- add(rulemlBasicString, position179) } goto l156 l178: position, tokenIndex, depth = position156, tokenIndex156, depth156 { position190 := position depth++ { position191 := position depth++ if buffer[position] != rune('"') { goto l88 } position++ l192: { position193, tokenIndex193, depth193 := position, tokenIndex, depth if !_rules[rulebasicChar]() { goto l193 } goto l192 l193: position, tokenIndex, depth = position193, tokenIndex193, depth193 } if buffer[position] != rune('"') { goto l88 } position++ depth-- add(rulePegText, position191) } { add(ruleAction17, position) } depth-- add(rulebasicString, position190) } } l156: depth-- add(rulestring, position155) } depth-- add(rulePegText, position154) } { add(ruleAction10, position) } break default: { position196 := position depth++ if !_rules[ruleinteger]() { goto l88 } depth-- add(rulePegText, position196) } { add(ruleAction9, position) } break } } } l90: depth-- add(ruleval, position89) } return true l88: position, tokenIndex, depth = position88, tokenIndex88, depth88 return false }, /* 11 table <- <(stdTable / arrayTable)> */ nil, /* 12 stdTable <- <('[' ws ws ']' Action13)> */ nil, /* 13 arrayTable <- <('[' '[' ws ws (']' ']') Action14)> */ nil, /* 14 inlineTable <- <('{' Action15 ws inlineTableKeyValues ws '}' Action16)> */ nil, /* 15 inlineTableKeyValues <- <(keyval inlineTableValSep?)*> */ nil, /* 16 tableKey <- <(key (tableKeySep key)*)> */ func() bool { position203, tokenIndex203, depth203 := position, tokenIndex, depth { position204 := position depth++ if !_rules[rulekey]() { goto l203 } l205: { position206, tokenIndex206, depth206 := position, tokenIndex, depth { position207 := position depth++ if !_rules[rulews]() { goto l206 } if buffer[position] != rune('.') { goto l206 } position++ if !_rules[rulews]() { goto l206 } depth-- add(ruletableKeySep, position207) } if !_rules[rulekey]() { goto l206 } goto l205 l206: position, tokenIndex, depth = position206, tokenIndex206, depth206 } depth-- add(ruletableKey, position204) } return true l203: position, tokenIndex, depth = position203, tokenIndex203, depth203 return false }, /* 17 tableKeySep <- <(ws '.' ws)> */ nil, /* 18 inlineTableValSep <- <(ws ',' ws)> */ nil, /* 19 integer <- <(('-' / '+')? int)> */ func() bool { position210, tokenIndex210, depth210 := position, tokenIndex, depth { position211 := position depth++ { position212, tokenIndex212, depth212 := position, tokenIndex, depth { position214, tokenIndex214, depth214 := position, tokenIndex, depth if buffer[position] != rune('-') { goto l215 } position++ goto l214 l215: position, tokenIndex, depth = position214, tokenIndex214, depth214 if buffer[position] != rune('+') { goto l212 } position++ } l214: goto l213 l212: position, tokenIndex, depth = position212, tokenIndex212, depth212 } l213: { position216 := position depth++ { position217, tokenIndex217, depth217 := position, tokenIndex, depth if c := buffer[position]; c < rune('1') || c > rune('9') { goto l218 } position++ { position221, tokenIndex221, depth221 := position, tokenIndex, depth if !_rules[ruledigit]() { goto l222 } goto l221 l222: position, tokenIndex, depth = position221, tokenIndex221, depth221 if buffer[position] != rune('_') { goto l218 } position++ if !_rules[ruledigit]() { goto l218 } } l221: l219: { position220, tokenIndex220, depth220 := position, tokenIndex, depth { position223, tokenIndex223, depth223 := position, tokenIndex, depth if !_rules[ruledigit]() { goto l224 } goto l223 l224: position, tokenIndex, depth = position223, tokenIndex223, depth223 if buffer[position] != rune('_') { goto l220 } position++ if !_rules[ruledigit]() { goto l220 } } l223: goto l219 l220: position, tokenIndex, depth = position220, tokenIndex220, depth220 } goto l217 l218: position, tokenIndex, depth = position217, tokenIndex217, depth217 if !_rules[ruledigit]() { goto l210 } } l217: depth-- add(ruleint, position216) } depth-- add(ruleinteger, position211) } return true l210: position, tokenIndex, depth = position210, tokenIndex210, depth210 return false }, /* 20 int <- <(([1-9] (digit / ('_' digit))+) / digit)> */ nil, /* 21 float <- <(integer ((frac exp?) / (frac? exp)))> */ nil, /* 22 frac <- <('.' digit (digit / ('_' digit))*)> */ func() bool { position227, tokenIndex227, depth227 := position, tokenIndex, depth { position228 := position depth++ if buffer[position] != rune('.') { goto l227 } position++ if !_rules[ruledigit]() { goto l227 } l229: { position230, tokenIndex230, depth230 := position, tokenIndex, depth { position231, tokenIndex231, depth231 := position, tokenIndex, depth if !_rules[ruledigit]() { goto l232 } goto l231 l232: position, tokenIndex, depth = position231, tokenIndex231, depth231 if buffer[position] != rune('_') { goto l230 } position++ if !_rules[ruledigit]() { goto l230 } } l231: goto l229 l230: position, tokenIndex, depth = position230, tokenIndex230, depth230 } depth-- add(rulefrac, position228) } return true l227: position, tokenIndex, depth = position227, tokenIndex227, depth227 return false }, /* 23 exp <- <(('e' / 'E') ('-' / '+')? digit (digit / ('_' digit))*)> */ func() bool { position233, tokenIndex233, depth233 := position, tokenIndex, depth { position234 := position depth++ { position235, tokenIndex235, depth235 := position, tokenIndex, depth if buffer[position] != rune('e') { goto l236 } position++ goto l235 l236: position, tokenIndex, depth = position235, tokenIndex235, depth235 if buffer[position] != rune('E') { goto l233 } position++ } l235: { position237, tokenIndex237, depth237 := position, tokenIndex, depth { position239, tokenIndex239, depth239 := position, tokenIndex, depth if buffer[position] != rune('-') { goto l240 } position++ goto l239 l240: position, tokenIndex, depth = position239, tokenIndex239, depth239 if buffer[position] != rune('+') { goto l237 } position++ } l239: goto l238 l237: position, tokenIndex, depth = position237, tokenIndex237, depth237 } l238: if !_rules[ruledigit]() { goto l233 } l241: { position242, tokenIndex242, depth242 := position, tokenIndex, depth { position243, tokenIndex243, depth243 := position, tokenIndex, depth if !_rules[ruledigit]() { goto l244 } goto l243 l244: position, tokenIndex, depth = position243, tokenIndex243, depth243 if buffer[position] != rune('_') { goto l242 } position++ if !_rules[ruledigit]() { goto l242 } } l243: goto l241 l242: position, tokenIndex, depth = position242, tokenIndex242, depth242 } depth-- add(ruleexp, position234) } return true l233: position, tokenIndex, depth = position233, tokenIndex233, depth233 return false }, /* 24 string <- <(mlLiteralString / literalString / mlBasicString / basicString)> */ nil, /* 25 basicString <- <(<('"' basicChar* '"')> Action17)> */ nil, /* 26 basicChar <- <(basicUnescaped / escaped)> */ func() bool { position247, tokenIndex247, depth247 := position, tokenIndex, depth { position248 := position depth++ { position249, tokenIndex249, depth249 := position, tokenIndex, depth { position251 := position depth++ { switch buffer[position] { case ' ', '!': if c := buffer[position]; c < rune(' ') || c > rune('!') { goto l250 } position++ break case '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[': if c := buffer[position]; c < rune('#') || c > rune('[') { goto l250 } position++ break default: if c := buffer[position]; c < rune(']') || c > rune('\U0010ffff') { goto l250 } position++ break } } depth-- add(rulebasicUnescaped, position251) } goto l249 l250: position, tokenIndex, depth = position249, tokenIndex249, depth249 { position253 := position depth++ if !_rules[ruleescape]() { goto l247 } { switch buffer[position] { case 'U': if buffer[position] != rune('U') { goto l247 } position++ if !_rules[rulehexQuad]() { goto l247 } if !_rules[rulehexQuad]() { goto l247 } break case 'u': if buffer[position] != rune('u') { goto l247 } position++ if !_rules[rulehexQuad]() { goto l247 } break case '\\': if buffer[position] != rune('\\') { goto l247 } position++ break case '/': if buffer[position] != rune('/') { goto l247 } position++ break case '"': if buffer[position] != rune('"') { goto l247 } position++ break case 'r': if buffer[position] != rune('r') { goto l247 } position++ break case 'f': if buffer[position] != rune('f') { goto l247 } position++ break case 'n': if buffer[position] != rune('n') { goto l247 } position++ break case 't': if buffer[position] != rune('t') { goto l247 } position++ break default: if buffer[position] != rune('b') { goto l247 } position++ break } } depth-- add(ruleescaped, position253) } } l249: depth-- add(rulebasicChar, position248) } return true l247: position, tokenIndex, depth = position247, tokenIndex247, depth247 return false }, /* 27 escaped <- <(escape ((&('U') ('U' hexQuad hexQuad)) | (&('u') ('u' hexQuad)) | (&('\\') '\\') | (&('/') '/') | (&('"') '"') | (&('r') 'r') | (&('f') 'f') | (&('n') 'n') | (&('t') 't') | (&('b') 'b')))> */ nil, /* 28 basicUnescaped <- <((&(' ' | '!') [ -!]) | (&('#' | '$' | '%' | '&' | '\'' | '(' | ')' | '*' | '+' | ',' | '-' | '.' | '/' | '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | ':' | ';' | '<' | '=' | '>' | '?' | '@' | 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z' | '[') [#-[]) | (&(']' | '^' | '_' | '`' | 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z' | '{' | '|' | '}' | '~' | '\u007f' | '\u0080' | '\u0081' | '\u0082' | '\u0083' | '\u0084' | '\u0085' | '\u0086' | '\u0087' | '\u0088' | '\u0089' | '\u008a' | '\u008b' | '\u008c' | '\u008d' | '\u008e' | '\u008f' | '\u0090' | '\u0091' | '\u0092' | '\u0093' | '\u0094' | '\u0095' | '\u0096' | '\u0097' | '\u0098' | '\u0099' | '\u009a' | '\u009b' | '\u009c' | '\u009d' | '\u009e' | '\u009f' | '\u00a0' | '¡' | '¢' | '£' | '¤' | '¥' | '¦' | '§' | '¨' | '©' | 'ª' | '«' | '¬' | '\u00ad' | '®' | '¯' | '°' | '±' | '²' | '³' | '´' | 'µ' | '¶' | '·' | '¸' | '¹' | 'º' | '»' | '¼' | '½' | '¾' | '¿' | 'À' | 'Á' | 'Â' | 'Ã' | 'Ä' | 'Å' | 'Æ' | 'Ç' | 'È' | 'É' | 'Ê' | 'Ë' | 'Ì' | 'Í' | 'Î' | 'Ï' | 'Ð' | 'Ñ' | 'Ò' | 'Ó' | 'Ô' | 'Õ' | 'Ö' | '×' | 'Ø' | 'Ù' | 'Ú' | 'Û' | 'Ü' | 'Ý' | 'Þ' | 'ß' | 'à' | 'á' | 'â' | 'ã' | 'ä' | 'å' | 'æ' | 'ç' | 'è' | 'é' | 'ê' | 'ë' | 'ì' | 'í' | 'î' | 'ï' | 'ð' | 'ñ' | 'ò' | 'ó' | 'ô') []-􏿿]))> */ nil, /* 29 escape <- <'\\'> */ func() bool { position257, tokenIndex257, depth257 := position, tokenIndex, depth { position258 := position depth++ if buffer[position] != rune('\\') { goto l257 } position++ depth-- add(ruleescape, position258) } return true l257: position, tokenIndex, depth = position257, tokenIndex257, depth257 return false }, /* 30 mlBasicString <- <('"' '"' '"' mlBasicBody ('"' '"' '"') Action18)> */ nil, /* 31 mlBasicBody <- <((<(basicChar / newline)> Action19) / (escape newline wsnl))*> */ nil, /* 32 literalString <- <('\'' '\'' Action20)> */ nil, /* 33 literalChar <- <((&('\t') '\t') | (&(' ' | '!' | '"' | '#' | '$' | '%' | '&') [ -&]) | (&('(' | ')' | '*' | '+' | ',' | '-' | '.' | '/' | '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | ':' | ';' | '<' | '=' | '>' | '?' | '@' | 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z' | '[' | '\\' | ']' | '^' | '_' | '`' | 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z' | '{' | '|' | '}' | '~' | '\u007f' | '\u0080' | '\u0081' | '\u0082' | '\u0083' | '\u0084' | '\u0085' | '\u0086' | '\u0087' | '\u0088' | '\u0089' | '\u008a' | '\u008b' | '\u008c' | '\u008d' | '\u008e' | '\u008f' | '\u0090' | '\u0091' | '\u0092' | '\u0093' | '\u0094' | '\u0095' | '\u0096' | '\u0097' | '\u0098' | '\u0099' | '\u009a' | '\u009b' | '\u009c' | '\u009d' | '\u009e' | '\u009f' | '\u00a0' | '¡' | '¢' | '£' | '¤' | '¥' | '¦' | '§' | '¨' | '©' | 'ª' | '«' | '¬' | '\u00ad' | '®' | '¯' | '°' | '±' | '²' | '³' | '´' | 'µ' | '¶' | '·' | '¸' | '¹' | 'º' | '»' | '¼' | '½' | '¾' | '¿' | 'À' | 'Á' | 'Â' | 'Ã' | 'Ä' | 'Å' | 'Æ' | 'Ç' | 'È' | 'É' | 'Ê' | 'Ë' | 'Ì' | 'Í' | 'Î' | 'Ï' | 'Ð' | 'Ñ' | 'Ò' | 'Ó' | 'Ô' | 'Õ' | 'Ö' | '×' | 'Ø' | 'Ù' | 'Ú' | 'Û' | 'Ü' | 'Ý' | 'Þ' | 'ß' | 'à' | 'á' | 'â' | 'ã' | 'ä' | 'å' | 'æ' | 'ç' | 'è' | 'é' | 'ê' | 'ë' | 'ì' | 'í' | 'î' | 'ï' | 'ð' | 'ñ' | 'ò' | 'ó' | 'ô') [(-􏿿]))> */ nil, /* 34 mlLiteralString <- <('\'' '\'' '\'' ('\'' '\'' '\'') Action21)> */ nil, /* 35 mlLiteralBody <- <(!('\'' '\'' '\'') (mlLiteralChar / newline))*> */ nil, /* 36 mlLiteralChar <- <('\t' / [ -􏿿])> */ nil, /* 37 hexdigit <- <((&('a' | 'b' | 'c' | 'd' | 'e' | 'f') [a-f]) | (&('A' | 'B' | 'C' | 'D' | 'E' | 'F') [A-F]) | (&('0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9') [0-9]))> */ func() bool { position266, tokenIndex266, depth266 := position, tokenIndex, depth { position267 := position depth++ { switch buffer[position] { case 'a', 'b', 'c', 'd', 'e', 'f': if c := buffer[position]; c < rune('a') || c > rune('f') { goto l266 } position++ break case 'A', 'B', 'C', 'D', 'E', 'F': if c := buffer[position]; c < rune('A') || c > rune('F') { goto l266 } position++ break default: if c := buffer[position]; c < rune('0') || c > rune('9') { goto l266 } position++ break } } depth-- add(rulehexdigit, position267) } return true l266: position, tokenIndex, depth = position266, tokenIndex266, depth266 return false }, /* 38 hexQuad <- <(hexdigit hexdigit hexdigit hexdigit)> */ func() bool { position269, tokenIndex269, depth269 := position, tokenIndex, depth { position270 := position depth++ if !_rules[rulehexdigit]() { goto l269 } if !_rules[rulehexdigit]() { goto l269 } if !_rules[rulehexdigit]() { goto l269 } if !_rules[rulehexdigit]() { goto l269 } depth-- add(rulehexQuad, position270) } return true l269: position, tokenIndex, depth = position269, tokenIndex269, depth269 return false }, /* 39 boolean <- <(('t' 'r' 'u' 'e') / ('f' 'a' 'l' 's' 'e'))> */ nil, /* 40 dateFullYear <- */ nil, /* 41 dateMonth <- */ nil, /* 42 dateMDay <- */ nil, /* 43 timeHour <- */ func() bool { position275, tokenIndex275, depth275 := position, tokenIndex, depth { position276 := position depth++ if !_rules[ruledigitDual]() { goto l275 } depth-- add(ruletimeHour, position276) } return true l275: position, tokenIndex, depth = position275, tokenIndex275, depth275 return false }, /* 44 timeMinute <- */ func() bool { position277, tokenIndex277, depth277 := position, tokenIndex, depth { position278 := position depth++ if !_rules[ruledigitDual]() { goto l277 } depth-- add(ruletimeMinute, position278) } return true l277: position, tokenIndex, depth = position277, tokenIndex277, depth277 return false }, /* 45 timeSecond <- */ nil, /* 46 timeSecfrac <- <('.' digit+)> */ nil, /* 47 timeNumoffset <- <(('-' / '+') timeHour ':' timeMinute)> */ nil, /* 48 timeOffset <- <('Z' / timeNumoffset)> */ nil, /* 49 partialTime <- <(timeHour ':' timeMinute ':' timeSecond timeSecfrac?)> */ nil, /* 50 fullDate <- <(dateFullYear '-' dateMonth '-' dateMDay)> */ nil, /* 51 fullTime <- <(partialTime timeOffset)> */ nil, /* 52 datetime <- <(fullDate 'T' fullTime)> */ nil, /* 53 digit <- <[0-9]> */ func() bool { position287, tokenIndex287, depth287 := position, tokenIndex, depth { position288 := position depth++ if c := buffer[position]; c < rune('0') || c > rune('9') { goto l287 } position++ depth-- add(ruledigit, position288) } return true l287: position, tokenIndex, depth = position287, tokenIndex287, depth287 return false }, /* 54 digitDual <- <(digit digit)> */ func() bool { position289, tokenIndex289, depth289 := position, tokenIndex, depth { position290 := position depth++ if !_rules[ruledigit]() { goto l289 } if !_rules[ruledigit]() { goto l289 } depth-- add(ruledigitDual, position290) } return true l289: position, tokenIndex, depth = position289, tokenIndex289, depth289 return false }, /* 55 digitQuad <- <(digitDual digitDual)> */ nil, /* 56 array <- <('[' Action22 wsnl arrayValues wsnl ']')> */ nil, /* 57 arrayValues <- <(val Action23 arraySep? (comment? newline)?)*> */ nil, /* 58 arraySep <- <(ws ',' wsnl)> */ nil, /* 60 Action0 <- <{ _ = buffer }> */ nil, nil, /* 62 Action1 <- <{ p.SetTableString(begin, end) }> */ nil, /* 63 Action2 <- <{ p.AddLineCount(end - begin) }> */ nil, /* 64 Action3 <- <{ p.AddLineCount(end - begin) }> */ nil, /* 65 Action4 <- <{ p.AddKeyValue() }> */ nil, /* 66 Action5 <- <{ p.SetKey(p.buffer, begin, end) }> */ nil, /* 67 Action6 <- <{ p.SetKey(p.buffer, begin, end) }> */ nil, /* 68 Action7 <- <{ p.SetTime(begin, end) }> */ nil, /* 69 Action8 <- <{ p.SetFloat64(begin, end) }> */ nil, /* 70 Action9 <- <{ p.SetInt64(begin, end) }> */ nil, /* 71 Action10 <- <{ p.SetString(begin, end) }> */ nil, /* 72 Action11 <- <{ p.SetBool(begin, end) }> */ nil, /* 73 Action12 <- <{ p.SetArray(begin, end) }> */ nil, /* 74 Action13 <- <{ p.SetTable(p.buffer, begin, end) }> */ nil, /* 75 Action14 <- <{ p.SetArrayTable(p.buffer, begin, end) }> */ nil, /* 76 Action15 <- <{ p.StartInlineTable() }> */ nil, /* 77 Action16 <- <{ p.EndInlineTable() }> */ nil, /* 78 Action17 <- <{ p.SetBasicString(p.buffer, begin, end) }> */ nil, /* 79 Action18 <- <{ p.SetMultilineString() }> */ nil, /* 80 Action19 <- <{ p.AddMultilineBasicBody(p.buffer, begin, end) }> */ nil, /* 81 Action20 <- <{ p.SetLiteralString(p.buffer, begin, end) }> */ nil, /* 82 Action21 <- <{ p.SetMultilineLiteralString(p.buffer, begin, end) }> */ nil, /* 83 Action22 <- <{ p.StartArray() }> */ nil, /* 84 Action23 <- <{ p.AddArrayVal() }> */ nil, } p.rules = _rules } golang-github-naoina-toml-0.0~git20170709.5811abc/testdata/000077500000000000000000000000001254735420300227315ustar00rootroot00000000000000golang-github-naoina-toml-0.0~git20170709.5811abc/testdata/test.toml000066400000000000000000000121711254735420300246070ustar00rootroot00000000000000################################################################################ ## Comment # Speak your mind with the hash symbol. They go from the symbol to the end of # the line. ################################################################################ ## Table # Tables (also known as hash tables or dictionaries) are collections of # key/value pairs. They appear in square brackets on a line by themselves. [table] key = "value" # Yeah, you can do this. # Nested tables are denoted by table names with dots in them. Name your tables # whatever crap you please, just don't use #, ., [ or ]. [table.subtable] key = "another value" # You don't need to specify all the super-tables if you don't want to. TOML # knows how to do it for you. # [x] you # [x.y] don't # [x.y.z] need these [x.y.z.w] # for this to work ################################################################################ ## Inline Table # Inline tables provide a more compact syntax for expressing tables. They are # especially useful for grouped data that can otherwise quickly become verbose. # Inline tables are enclosed in curly braces `{` and `}`. No newlines are # allowed between the curly braces unless they are valid within a value. [table.inline] name = { first = "Tom", last = "Preston-Werner" } point = { x = 1, y = 2 } ################################################################################ ## String # There are four ways to express strings: basic, multi-line basic, literal, and # multi-line literal. All strings must contain only valid UTF-8 characters. [string.basic] basic = "I'm a string. \"You can quote me\". Name\tJos\u00E9\nLocation\tSF." [string.multiline] # The following strings are byte-for-byte equivalent: key1 = "One\nTwo" key2 = """One\nTwo""" key3 = """ One Two""" [string.multiline.continued] # The following strings are byte-for-byte equivalent: key1 = "The quick brown fox jumps over the lazy dog." key2 = """ The quick brown \ fox jumps over \ the lazy dog.""" key3 = """\ The quick brown \ fox jumps over \ the lazy dog.\ """ [string.literal] # What you see is what you get. winpath = 'C:\Users\nodejs\templates' winpath2 = '\\ServerX\admin$\system32\' quoted = 'Tom "Dubs" Preston-Werner' regex = '<\i\c*\s*>' [string.literal.multiline] regex2 = '''I [dw]on't need \d{2} apples''' lines = ''' The first newline is trimmed in raw strings. All other whitespace is preserved. ''' ################################################################################ ## Integer # Integers are whole numbers. Positive numbers may be prefixed with a plus sign. # Negative numbers are prefixed with a minus sign. [integer] key1 = +99 key2 = 42 key3 = 0 key4 = -17 [integer.underscores] # For large numbers, you may use underscores to enhance readability. Each # underscore must be surrounded by at least one digit. key1 = 1_000 key2 = 5_349_221 key3 = 1_2_3_4_5 # valid but inadvisable ################################################################################ ## Float # A float consists of an integer part (which may be prefixed with a plus or # minus sign) followed by a fractional part and/or an exponent part. [float.fractional] key1 = +1.0 key2 = 3.1415 key3 = -0.01 [float.exponent] key1 = 5e+22 key2 = 1e6 key3 = -2E-2 [float.both] key = 6.626e-34 [float.underscores] key1 = 9_224_617.445_991_228_313 key2 = 1e1_00 ################################################################################ ## Boolean # Booleans are just the tokens you're used to. Always lowercase. [boolean] True = true False = false ################################################################################ ## Datetime # Datetimes are RFC 3339 dates. [datetime] key1 = 1979-05-27T07:32:00Z key2 = 1979-05-27T00:32:00-07:00 key3 = 1979-05-27T00:32:00.999999-07:00 ################################################################################ ## Array # Arrays are square brackets with other primitives inside. Whitespace is # ignored. Elements are separated by commas. Data types may not be mixed. [array] key1 = [ 1, 2, 3 ] key2 = [ "red", "yellow", "green" ] key3 = [ [ 1, 2 ], [3, 4, 5] ] key4 = [ [ 1, 2 ], ["a", "b", "c"] ] # this is ok # Arrays can also be multiline. So in addition to ignoring whitespace, arrays # also ignore newlines between the brackets. Terminating commas are ok before # the closing bracket. key5 = [ 1, 2, 3 ] key6 = [ 1, 2, # this is ok ] ################################################################################ ## Array of Tables # These can be expressed by using a table name in double brackets. Each table # with the same double bracketed name will be an element in the array. The # tables are inserted in the order encountered. [[products]] name = "Hammer" sku = 738594937 [[products]] [[products]] name = "Nail" sku = 284758393 color = "gray" # You can create nested arrays of tables as well. [[fruit]] name = "apple" [fruit.physical] color = "red" shape = "round" [[fruit.variety]] name = "red delicious" [[fruit.variety]] name = "granny smith" [[fruit]] name = "banana" [[fruit.variety]] name = "plantain" golang-github-naoina-toml-0.0~git20170709.5811abc/util.go000066400000000000000000000032741254735420300224320ustar00rootroot00000000000000package toml import ( "go/ast" "reflect" "strings" "unicode" ) // toCamelCase returns a copy of the string s with all Unicode letters mapped to their camel case. // It will convert to upper case previous letter of '_' and first letter, and remove letter of '_'. func toCamelCase(s string) string { if s == "" { return "" } result := make([]rune, 0, len(s)) upper := false for _, r := range s { if r == '_' { upper = true continue } if upper { result = append(result, unicode.ToUpper(r)) upper = false continue } result = append(result, r) } result[0] = unicode.ToUpper(result[0]) return string(result) } const ( fieldTagName = "toml" ) func findField(rv reflect.Value, name string) (field reflect.Value, fieldName string, found bool) { switch rv.Kind() { case reflect.Struct: rt := rv.Type() for i := 0; i < rt.NumField(); i++ { ft := rt.Field(i) if !ast.IsExported(ft.Name) { continue } if col, _ := extractTag(ft.Tag.Get(fieldTagName)); col == name { return rv.Field(i), ft.Name, true } } for _, name := range []string{ strings.Title(name), toCamelCase(name), strings.ToUpper(name), } { if field := rv.FieldByName(name); field.IsValid() { return field, name, true } } case reflect.Map: return reflect.New(rv.Type().Elem()).Elem(), name, true } return field, "", false } func extractTag(tag string) (col, rest string) { tags := strings.SplitN(tag, ",", 2) if len(tags) == 2 { return strings.TrimSpace(tags[0]), strings.TrimSpace(tags[1]) } return strings.TrimSpace(tags[0]), "" } func tableName(prefix, name string) string { if prefix != "" { return prefix + string(tableSeparator) + name } return name }