aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/BurntSushi
diff options
context:
space:
mode:
authorTaras Madan <tarasmadan@google.com>2025-01-22 16:07:17 +0100
committerTaras Madan <tarasmadan@google.com>2025-01-23 10:42:36 +0000
commit7b4377ad9d8a7205416df8d6217ef2b010f89481 (patch)
treee6fec4fd12ff807a16d847923f501075bf71d16c /vendor/github.com/BurntSushi
parent475a4c203afb8b7d3af51c4fd32bb170ff32a45e (diff)
vendor: delete
Diffstat (limited to 'vendor/github.com/BurntSushi')
-rw-r--r--vendor/github.com/BurntSushi/toml/.gitignore2
-rw-r--r--vendor/github.com/BurntSushi/toml/COPYING21
-rw-r--r--vendor/github.com/BurntSushi/toml/README.md120
-rw-r--r--vendor/github.com/BurntSushi/toml/decode.go615
-rw-r--r--vendor/github.com/BurntSushi/toml/deprecated.go29
-rw-r--r--vendor/github.com/BurntSushi/toml/doc.go8
-rw-r--r--vendor/github.com/BurntSushi/toml/encode.go778
-rw-r--r--vendor/github.com/BurntSushi/toml/error.go347
-rw-r--r--vendor/github.com/BurntSushi/toml/internal/tz.go36
-rw-r--r--vendor/github.com/BurntSushi/toml/lex.go1287
-rw-r--r--vendor/github.com/BurntSushi/toml/meta.go148
-rw-r--r--vendor/github.com/BurntSushi/toml/parse.go846
-rw-r--r--vendor/github.com/BurntSushi/toml/type_fields.go238
-rw-r--r--vendor/github.com/BurntSushi/toml/type_toml.go65
14 files changed, 0 insertions, 4540 deletions
diff --git a/vendor/github.com/BurntSushi/toml/.gitignore b/vendor/github.com/BurntSushi/toml/.gitignore
deleted file mode 100644
index fe79e3add..000000000
--- a/vendor/github.com/BurntSushi/toml/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-/toml.test
-/toml-test
diff --git a/vendor/github.com/BurntSushi/toml/COPYING b/vendor/github.com/BurntSushi/toml/COPYING
deleted file mode 100644
index 01b574320..000000000
--- a/vendor/github.com/BurntSushi/toml/COPYING
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2013 TOML authors
-
-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.
diff --git a/vendor/github.com/BurntSushi/toml/README.md b/vendor/github.com/BurntSushi/toml/README.md
deleted file mode 100644
index 639e6c399..000000000
--- a/vendor/github.com/BurntSushi/toml/README.md
+++ /dev/null
@@ -1,120 +0,0 @@
-TOML stands for Tom's Obvious, Minimal Language. This Go package provides a
-reflection interface similar to Go's standard library `json` and `xml` packages.
-
-Compatible with TOML version [v1.0.0](https://toml.io/en/v1.0.0).
-
-Documentation: https://godocs.io/github.com/BurntSushi/toml
-
-See the [releases page](https://github.com/BurntSushi/toml/releases) for a
-changelog; this information is also in the git tag annotations (e.g. `git show
-v0.4.0`).
-
-This library requires Go 1.18 or newer; add it to your go.mod with:
-
- % go get github.com/BurntSushi/toml@latest
-
-It also comes with a TOML validator CLI tool:
-
- % go install github.com/BurntSushi/toml/cmd/tomlv@latest
- % tomlv some-toml-file.toml
-
-### Examples
-For the simplest example, consider some TOML file as just a list of keys and
-values:
-
-```toml
-Age = 25
-Cats = [ "Cauchy", "Plato" ]
-Pi = 3.14
-Perfection = [ 6, 28, 496, 8128 ]
-DOB = 1987-07-05T05:45:00Z
-```
-
-Which can be decoded with:
-
-```go
-type Config struct {
- Age int
- Cats []string
- Pi float64
- Perfection []int
- DOB time.Time
-}
-
-var conf Config
-_, err := toml.Decode(tomlData, &conf)
-```
-
-You can also use struct tags if your struct field name doesn't map to a TOML key
-value directly:
-
-```toml
-some_key_NAME = "wat"
-```
-
-```go
-type TOML struct {
- ObscureKey string `toml:"some_key_NAME"`
-}
-```
-
-Beware that like other decoders **only exported fields** are considered when
-encoding and decoding; private fields are silently ignored.
-
-### Using the `Marshaler` and `encoding.TextUnmarshaler` interfaces
-Here's an example that automatically parses values in a `mail.Address`:
-
-```toml
-contacts = [
- "Donald Duck <donald@duckburg.com>",
- "Scrooge McDuck <scrooge@duckburg.com>",
-]
-```
-
-Can be decoded with:
-
-```go
-// Create address type which satisfies the encoding.TextUnmarshaler interface.
-type address struct {
- *mail.Address
-}
-
-func (a *address) UnmarshalText(text []byte) error {
- var err error
- a.Address, err = mail.ParseAddress(string(text))
- return err
-}
-
-// Decode it.
-func decode() {
- blob := `
- contacts = [
- "Donald Duck <donald@duckburg.com>",
- "Scrooge McDuck <scrooge@duckburg.com>",
- ]
- `
-
- var contacts struct {
- Contacts []address
- }
-
- _, err := toml.Decode(blob, &contacts)
- if err != nil {
- log.Fatal(err)
- }
-
- for _, c := range contacts.Contacts {
- fmt.Printf("%#v\n", c.Address)
- }
-
- // Output:
- // &mail.Address{Name:"Donald Duck", Address:"donald@duckburg.com"}
- // &mail.Address{Name:"Scrooge McDuck", Address:"scrooge@duckburg.com"}
-}
-```
-
-To target TOML specifically you can implement `UnmarshalTOML` TOML interface in
-a similar way.
-
-### More complex usage
-See the [`_example/`](/_example) directory for a more complex example.
diff --git a/vendor/github.com/BurntSushi/toml/decode.go b/vendor/github.com/BurntSushi/toml/decode.go
deleted file mode 100644
index c05a0b7e5..000000000
--- a/vendor/github.com/BurntSushi/toml/decode.go
+++ /dev/null
@@ -1,615 +0,0 @@
-package toml
-
-import (
- "bytes"
- "encoding"
- "encoding/json"
- "fmt"
- "io"
- "io/fs"
- "math"
- "os"
- "reflect"
- "strconv"
- "strings"
- "time"
-)
-
-// Unmarshaler is the interface implemented by objects that can unmarshal a
-// TOML description of themselves.
-type Unmarshaler interface {
- UnmarshalTOML(any) error
-}
-
-// Unmarshal decodes the contents of data in TOML format into a pointer v.
-//
-// See [Decoder] for a description of the decoding process.
-func Unmarshal(data []byte, v any) error {
- _, err := NewDecoder(bytes.NewReader(data)).Decode(v)
- return err
-}
-
-// Decode the TOML data in to the pointer v.
-//
-// See [Decoder] for a description of the decoding process.
-func Decode(data string, v any) (MetaData, error) {
- return NewDecoder(strings.NewReader(data)).Decode(v)
-}
-
-// DecodeFile reads the contents of a file and decodes it with [Decode].
-func DecodeFile(path string, v any) (MetaData, error) {
- fp, err := os.Open(path)
- if err != nil {
- return MetaData{}, err
- }
- defer fp.Close()
- return NewDecoder(fp).Decode(v)
-}
-
-// DecodeFS reads the contents of a file from [fs.FS] and decodes it with
-// [Decode].
-func DecodeFS(fsys fs.FS, path string, v any) (MetaData, error) {
- fp, err := fsys.Open(path)
- if err != nil {
- return MetaData{}, err
- }
- defer fp.Close()
- return NewDecoder(fp).Decode(v)
-}
-
-// Primitive is a TOML value that hasn't been decoded into a Go value.
-//
-// This type can be used for any value, which will cause decoding to be delayed.
-// You can use [PrimitiveDecode] to "manually" decode these values.
-//
-// NOTE: The underlying representation of a `Primitive` value is subject to
-// change. Do not rely on it.
-//
-// NOTE: Primitive values are still parsed, so using them will only avoid the
-// overhead of reflection. They can be useful when you don't know the exact type
-// of TOML data until runtime.
-type Primitive struct {
- undecoded any
- context Key
-}
-
-// The significand precision for float32 and float64 is 24 and 53 bits; this is
-// the range a natural number can be stored in a float without loss of data.
-const (
- maxSafeFloat32Int = 16777215 // 2^24-1
- maxSafeFloat64Int = int64(9007199254740991) // 2^53-1
-)
-
-// Decoder decodes TOML data.
-//
-// TOML tables correspond to Go structs or maps; they can be used
-// interchangeably, but structs offer better type safety.
-//
-// TOML table arrays correspond to either a slice of structs or a slice of maps.
-//
-// TOML datetimes correspond to [time.Time]. Local datetimes are parsed in the
-// local timezone.
-//
-// [time.Duration] types are treated as nanoseconds if the TOML value is an
-// integer, or they're parsed with time.ParseDuration() if they're strings.
-//
-// All other TOML types (float, string, int, bool and array) correspond to the
-// obvious Go types.
-//
-// An exception to the above rules is if a type implements the TextUnmarshaler
-// interface, in which case any primitive TOML value (floats, strings, integers,
-// booleans, datetimes) will be converted to a []byte and given to the value's
-// UnmarshalText method. See the Unmarshaler example for a demonstration with
-// email addresses.
-//
-// # Key mapping
-//
-// TOML keys can map to either keys in a Go map or field names in a Go struct.
-// The special `toml` struct tag can be used to map TOML keys to struct fields
-// that don't match the key name exactly (see the example). A case insensitive
-// match to struct names will be tried if an exact match can't be found.
-//
-// The mapping between TOML values and Go values is loose. That is, there may
-// exist TOML values that cannot be placed into your representation, and there
-// may be parts of your representation that do not correspond to TOML values.
-// This loose mapping can be made stricter by using the IsDefined and/or
-// Undecoded methods on the MetaData returned.
-//
-// This decoder does not handle cyclic types. Decode will not terminate if a
-// cyclic type is passed.
-type Decoder struct {
- r io.Reader
-}
-
-// NewDecoder creates a new Decoder.
-func NewDecoder(r io.Reader) *Decoder {
- return &Decoder{r: r}
-}
-
-var (
- unmarshalToml = reflect.TypeOf((*Unmarshaler)(nil)).Elem()
- unmarshalText = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem()
- primitiveType = reflect.TypeOf((*Primitive)(nil)).Elem()
-)
-
-// Decode TOML data in to the pointer `v`.
-func (dec *Decoder) Decode(v any) (MetaData, error) {
- rv := reflect.ValueOf(v)
- if rv.Kind() != reflect.Ptr {
- s := "%q"
- if reflect.TypeOf(v) == nil {
- s = "%v"
- }
-
- return MetaData{}, fmt.Errorf("toml: cannot decode to non-pointer "+s, reflect.TypeOf(v))
- }
- if rv.IsNil() {
- return MetaData{}, fmt.Errorf("toml: cannot decode to nil value of %q", reflect.TypeOf(v))
- }
-
- // Check if this is a supported type: struct, map, any, or something that
- // implements UnmarshalTOML or UnmarshalText.
- rv = indirect(rv)
- rt := rv.Type()
- if rv.Kind() != reflect.Struct && rv.Kind() != reflect.Map &&
- !(rv.Kind() == reflect.Interface && rv.NumMethod() == 0) &&
- !rt.Implements(unmarshalToml) && !rt.Implements(unmarshalText) {
- return MetaData{}, fmt.Errorf("toml: cannot decode to type %s", rt)
- }
-
- // TODO: parser should read from io.Reader? Or at the very least, make it
- // read from []byte rather than string
- data, err := io.ReadAll(dec.r)
- if err != nil {
- return MetaData{}, err
- }
-
- p, err := parse(string(data))
- if err != nil {
- return MetaData{}, err
- }
-
- md := MetaData{
- mapping: p.mapping,
- keyInfo: p.keyInfo,
- keys: p.ordered,
- decoded: make(map[string]struct{}, len(p.ordered)),
- context: nil,
- data: data,
- }
- return md, md.unify(p.mapping, rv)
-}
-
-// PrimitiveDecode is just like the other Decode* functions, except it decodes a
-// TOML value that has already been parsed. Valid primitive values can *only* be
-// obtained from values filled by the decoder functions, including this method.
-// (i.e., v may contain more [Primitive] values.)
-//
-// Meta data for primitive values is included in the meta data returned by the
-// Decode* functions with one exception: keys returned by the Undecoded method
-// will only reflect keys that were decoded. Namely, any keys hidden behind a
-// Primitive will be considered undecoded. Executing this method will update the
-// undecoded keys in the meta data. (See the example.)
-func (md *MetaData) PrimitiveDecode(primValue Primitive, v any) error {
- md.context = primValue.context
- defer func() { md.context = nil }()
- return md.unify(primValue.undecoded, rvalue(v))
-}
-
-// unify performs a sort of type unification based on the structure of `rv`,
-// which is the client representation.
-//
-// Any type mismatch produces an error. Finding a type that we don't know
-// how to handle produces an unsupported type error.
-func (md *MetaData) unify(data any, rv reflect.Value) error {
- // Special case. Look for a `Primitive` value.
- // TODO: #76 would make this superfluous after implemented.
- if rv.Type() == primitiveType {
- // Save the undecoded data and the key context into the primitive
- // value.
- context := make(Key, len(md.context))
- copy(context, md.context)
- rv.Set(reflect.ValueOf(Primitive{
- undecoded: data,
- context: context,
- }))
- return nil
- }
-
- rvi := rv.Interface()
- if v, ok := rvi.(Unmarshaler); ok {
- err := v.UnmarshalTOML(data)
- if err != nil {
- return md.parseErr(err)
- }
- return nil
- }
- if v, ok := rvi.(encoding.TextUnmarshaler); ok {
- return md.unifyText(data, v)
- }
-
- // TODO:
- // The behavior here is incorrect whenever a Go type satisfies the
- // encoding.TextUnmarshaler interface but also corresponds to a TOML hash or
- // array. In particular, the unmarshaler should only be applied to primitive
- // TOML values. But at this point, it will be applied to all kinds of values
- // and produce an incorrect error whenever those values are hashes or arrays
- // (including arrays of tables).
-
- k := rv.Kind()
-
- if k >= reflect.Int && k <= reflect.Uint64 {
- return md.unifyInt(data, rv)
- }
- switch k {
- case reflect.Struct:
- return md.unifyStruct(data, rv)
- case reflect.Map:
- return md.unifyMap(data, rv)
- case reflect.Array:
- return md.unifyArray(data, rv)
- case reflect.Slice:
- return md.unifySlice(data, rv)
- case reflect.String:
- return md.unifyString(data, rv)
- case reflect.Bool:
- return md.unifyBool(data, rv)
- case reflect.Interface:
- if rv.NumMethod() > 0 { /// Only empty interfaces are supported.
- return md.e("unsupported type %s", rv.Type())
- }
- return md.unifyAnything(data, rv)
- case reflect.Float32, reflect.Float64:
- return md.unifyFloat64(data, rv)
- }
- return md.e("unsupported type %s", rv.Kind())
-}
-
-func (md *MetaData) unifyStruct(mapping any, rv reflect.Value) error {
- tmap, ok := mapping.(map[string]any)
- if !ok {
- if mapping == nil {
- return nil
- }
- return md.e("type mismatch for %s: expected table but found %s", rv.Type().String(), fmtType(mapping))
- }
-
- for key, datum := range tmap {
- var f *field
- fields := cachedTypeFields(rv.Type())
- for i := range fields {
- ff := &fields[i]
- if ff.name == key {
- f = ff
- break
- }
- if f == nil && strings.EqualFold(ff.name, key) {
- f = ff
- }
- }
- if f != nil {
- subv := rv
- for _, i := range f.index {
- subv = indirect(subv.Field(i))
- }
-
- if isUnifiable(subv) {
- md.decoded[md.context.add(key).String()] = struct{}{}
- md.context = append(md.context, key)
-
- err := md.unify(datum, subv)
- if err != nil {
- return err
- }
- md.context = md.context[0 : len(md.context)-1]
- } else if f.name != "" {
- return md.e("cannot write unexported field %s.%s", rv.Type().String(), f.name)
- }
- }
- }
- return nil
-}
-
-func (md *MetaData) unifyMap(mapping any, rv reflect.Value) error {
- keyType := rv.Type().Key().Kind()
- if keyType != reflect.String && keyType != reflect.Interface {
- return fmt.Errorf("toml: cannot decode to a map with non-string key type (%s in %q)",
- keyType, rv.Type())
- }
-
- tmap, ok := mapping.(map[string]any)
- if !ok {
- if tmap == nil {
- return nil
- }
- return md.badtype("map", mapping)
- }
- if rv.IsNil() {
- rv.Set(reflect.MakeMap(rv.Type()))
- }
- for k, v := range tmap {
- md.decoded[md.context.add(k).String()] = struct{}{}
- md.context = append(md.context, k)
-
- rvval := reflect.Indirect(reflect.New(rv.Type().Elem()))
-
- err := md.unify(v, indirect(rvval))
- if err != nil {
- return err
- }
- md.context = md.context[0 : len(md.context)-1]
-
- rvkey := indirect(reflect.New(rv.Type().Key()))
-
- switch keyType {
- case reflect.Interface:
- rvkey.Set(reflect.ValueOf(k))
- case reflect.String:
- rvkey.SetString(k)
- }
-
- rv.SetMapIndex(rvkey, rvval)
- }
- return nil
-}
-
-func (md *MetaData) unifyArray(data any, rv reflect.Value) error {
- datav := reflect.ValueOf(data)
- if datav.Kind() != reflect.Slice {
- if !datav.IsValid() {
- return nil
- }
- return md.badtype("slice", data)
- }
- if l := datav.Len(); l != rv.Len() {
- return md.e("expected array length %d; got TOML array of length %d", rv.Len(), l)
- }
- return md.unifySliceArray(datav, rv)
-}
-
-func (md *MetaData) unifySlice(data any, rv reflect.Value) error {
- datav := reflect.ValueOf(data)
- if datav.Kind() != reflect.Slice {
- if !datav.IsValid() {
- return nil
- }
- return md.badtype("slice", data)
- }
- n := datav.Len()
- if rv.IsNil() || rv.Cap() < n {
- rv.Set(reflect.MakeSlice(rv.Type(), n, n))
- }
- rv.SetLen(n)
- return md.unifySliceArray(datav, rv)
-}
-
-func (md *MetaData) unifySliceArray(data, rv reflect.Value) error {
- l := data.Len()
- for i := 0; i < l; i++ {
- err := md.unify(data.Index(i).Interface(), indirect(rv.Index(i)))
- if err != nil {
- return err
- }
- }
- return nil
-}
-
-func (md *MetaData) unifyString(data any, rv reflect.Value) error {
- _, ok := rv.Interface().(json.Number)
- if ok {
- if i, ok := data.(int64); ok {
- rv.SetString(strconv.FormatInt(i, 10))
- } else if f, ok := data.(float64); ok {
- rv.SetString(strconv.FormatFloat(f, 'f', -1, 64))
- } else {
- return md.badtype("string", data)
- }
- return nil
- }
-
- if s, ok := data.(string); ok {
- rv.SetString(s)
- return nil
- }
- return md.badtype("string", data)
-}
-
-func (md *MetaData) unifyFloat64(data any, rv reflect.Value) error {
- rvk := rv.Kind()
-
- if num, ok := data.(float64); ok {
- switch rvk {
- case reflect.Float32:
- if num < -math.MaxFloat32 || num > math.MaxFloat32 {
- return md.parseErr(errParseRange{i: num, size: rvk.String()})
- }
- fallthrough
- case reflect.Float64:
- rv.SetFloat(num)
- default:
- panic("bug")
- }
- return nil
- }
-
- if num, ok := data.(int64); ok {
- if (rvk == reflect.Float32 && (num < -maxSafeFloat32Int || num > maxSafeFloat32Int)) ||
- (rvk == reflect.Float64 && (num < -maxSafeFloat64Int || num > maxSafeFloat64Int)) {
- return md.parseErr(errUnsafeFloat{i: num, size: rvk.String()})
- }
- rv.SetFloat(float64(num))
- return nil
- }
-
- return md.badtype("float", data)
-}
-
-func (md *MetaData) unifyInt(data any, rv reflect.Value) error {
- _, ok := rv.Interface().(time.Duration)
- if ok {
- // Parse as string duration, and fall back to regular integer parsing
- // (as nanosecond) if this is not a string.
- if s, ok := data.(string); ok {
- dur, err := time.ParseDuration(s)
- if err != nil {
- return md.parseErr(errParseDuration{s})
- }
- rv.SetInt(int64(dur))
- return nil
- }
- }
-
- num, ok := data.(int64)
- if !ok {
- return md.badtype("integer", data)
- }
-
- rvk := rv.Kind()
- switch {
- case rvk >= reflect.Int && rvk <= reflect.Int64:
- if (rvk == reflect.Int8 && (num < math.MinInt8 || num > math.MaxInt8)) ||
- (rvk == reflect.Int16 && (num < math.MinInt16 || num > math.MaxInt16)) ||
- (rvk == reflect.Int32 && (num < math.MinInt32 || num > math.MaxInt32)) {
- return md.parseErr(errParseRange{i: num, size: rvk.String()})
- }
- rv.SetInt(num)
- case rvk >= reflect.Uint && rvk <= reflect.Uint64:
- unum := uint64(num)
- if rvk == reflect.Uint8 && (num < 0 || unum > math.MaxUint8) ||
- rvk == reflect.Uint16 && (num < 0 || unum > math.MaxUint16) ||
- rvk == reflect.Uint32 && (num < 0 || unum > math.MaxUint32) {
- return md.parseErr(errParseRange{i: num, size: rvk.String()})
- }
- rv.SetUint(unum)
- default:
- panic("unreachable")
- }
- return nil
-}
-
-func (md *MetaData) unifyBool(data any, rv reflect.Value) error {
- if b, ok := data.(bool); ok {
- rv.SetBool(b)
- return nil
- }
- return md.badtype("boolean", data)
-}
-
-func (md *MetaData) unifyAnything(data any, rv reflect.Value) error {
- rv.Set(reflect.ValueOf(data))
- return nil
-}
-
-func (md *MetaData) unifyText(data any, v encoding.TextUnmarshaler) error {
- var s string
- switch sdata := data.(type) {
- case Marshaler:
- text, err := sdata.MarshalTOML()
- if err != nil {
- return err
- }
- s = string(text)
- case encoding.TextMarshaler:
- text, err := sdata.MarshalText()
- if err != nil {
- return err
- }
- s = string(text)
- case fmt.Stringer:
- s = sdata.String()
- case string:
- s = sdata
- case bool:
- s = fmt.Sprintf("%v", sdata)
- case int64:
- s = fmt.Sprintf("%d", sdata)
- case float64:
- s = fmt.Sprintf("%f", sdata)
- default:
- return md.badtype("primitive (string-like)", data)
- }
- if err := v.UnmarshalText([]byte(s)); err != nil {
- return md.parseErr(err)
- }
- return nil
-}
-
-func (md *MetaData) badtype(dst string, data any) error {
- return md.e("incompatible types: TOML value has type %s; destination has type %s", fmtType(data), dst)
-}
-
-func (md *MetaData) parseErr(err error) error {
- k := md.context.String()
- d := string(md.data)
- return ParseError{
- Message: err.Error(),
- err: err,
- LastKey: k,
- Position: md.keyInfo[k].pos.withCol(d),
- Line: md.keyInfo[k].pos.Line,
- input: d,
- }
-}
-
-func (md *MetaData) e(format string, args ...any) error {
- f := "toml: "
- if len(md.context) > 0 {
- f = fmt.Sprintf("toml: (last key %q): ", md.context)
- p := md.keyInfo[md.context.String()].pos
- if p.Line > 0 {
- f = fmt.Sprintf("toml: line %d (last key %q): ", p.Line, md.context)
- }
- }
- return fmt.Errorf(f+format, args...)
-}
-
-// rvalue returns a reflect.Value of `v`. All pointers are resolved.
-func rvalue(v any) reflect.Value {
- return indirect(reflect.ValueOf(v))
-}
-
-// indirect returns the value pointed to by a pointer.
-//
-// Pointers are followed until the value is not a pointer. New values are
-// allocated for each nil pointer.
-//
-// An exception to this rule is if the value satisfies an interface of interest
-// to us (like encoding.TextUnmarshaler).
-func indirect(v reflect.Value) reflect.Value {
- if v.Kind() != reflect.Ptr {
- if v.CanSet() {
- pv := v.Addr()
- pvi := pv.Interface()
- if _, ok := pvi.(encoding.TextUnmarshaler); ok {
- return pv
- }
- if _, ok := pvi.(Unmarshaler); ok {
- return pv
- }
- }
- return v
- }
- if v.IsNil() {
- v.Set(reflect.New(v.Type().Elem()))
- }
- return indirect(reflect.Indirect(v))
-}
-
-func isUnifiable(rv reflect.Value) bool {
- if rv.CanSet() {
- return true
- }
- rvi := rv.Interface()
- if _, ok := rvi.(encoding.TextUnmarshaler); ok {
- return true
- }
- if _, ok := rvi.(Unmarshaler); ok {
- return true
- }
- return false
-}
-
-// fmt %T with "interface {}" replaced with "any", which is far more readable.
-func fmtType(t any) string {
- return strings.ReplaceAll(fmt.Sprintf("%T", t), "interface {}", "any")
-}
diff --git a/vendor/github.com/BurntSushi/toml/deprecated.go b/vendor/github.com/BurntSushi/toml/deprecated.go
deleted file mode 100644
index 155709a80..000000000
--- a/vendor/github.com/BurntSushi/toml/deprecated.go
+++ /dev/null
@@ -1,29 +0,0 @@
-package toml
-
-import (
- "encoding"
- "io"
-)
-
-// TextMarshaler is an alias for encoding.TextMarshaler.
-//
-// Deprecated: use encoding.TextMarshaler
-type TextMarshaler encoding.TextMarshaler
-
-// TextUnmarshaler is an alias for encoding.TextUnmarshaler.
-//
-// Deprecated: use encoding.TextUnmarshaler
-type TextUnmarshaler encoding.TextUnmarshaler
-
-// DecodeReader is an alias for NewDecoder(r).Decode(v).
-//
-// Deprecated: use NewDecoder(reader).Decode(&value).
-func DecodeReader(r io.Reader, v any) (MetaData, error) { return NewDecoder(r).Decode(v) }
-
-// PrimitiveDecode is an alias for MetaData.PrimitiveDecode().
-//
-// Deprecated: use MetaData.PrimitiveDecode.
-func PrimitiveDecode(primValue Primitive, v any) error {
- md := MetaData{decoded: make(map[string]struct{})}
- return md.unify(primValue.undecoded, rvalue(v))
-}
diff --git a/vendor/github.com/BurntSushi/toml/doc.go b/vendor/github.com/BurntSushi/toml/doc.go
deleted file mode 100644
index 82c90a905..000000000
--- a/vendor/github.com/BurntSushi/toml/doc.go
+++ /dev/null
@@ -1,8 +0,0 @@
-// Package toml implements decoding and encoding of TOML files.
-//
-// This package supports TOML v1.0.0, as specified at https://toml.io
-//
-// The github.com/BurntSushi/toml/cmd/tomlv package implements a TOML validator,
-// and can be used to verify if TOML document is valid. It can also be used to
-// print the type of each key.
-package toml
diff --git a/vendor/github.com/BurntSushi/toml/encode.go b/vendor/github.com/BurntSushi/toml/encode.go
deleted file mode 100644
index 73366c0d9..000000000
--- a/vendor/github.com/BurntSushi/toml/encode.go
+++ /dev/null
@@ -1,778 +0,0 @@
-package toml
-
-import (
- "bufio"
- "bytes"
- "encoding"
- "encoding/json"
- "errors"
- "fmt"
- "io"
- "math"
- "reflect"
- "sort"
- "strconv"
- "strings"
- "time"
-
- "github.com/BurntSushi/toml/internal"
-)
-
-type tomlEncodeError struct{ error }
-
-var (
- errArrayNilElement = errors.New("toml: cannot encode array with nil element")
- errNonString = errors.New("toml: cannot encode a map with non-string key type")
- errNoKey = errors.New("toml: top-level values must be Go maps or structs")
- errAnything = errors.New("") // used in testing
-)
-
-var dblQuotedReplacer = strings.NewReplacer(
- "\"", "\\\"",
- "\\", "\\\\",
- "\x00", `\u0000`,
- "\x01", `\u0001`,
- "\x02", `\u0002`,
- "\x03", `\u0003`,
- "\x04", `\u0004`,
- "\x05", `\u0005`,
- "\x06", `\u0006`,
- "\x07", `\u0007`,
- "\b", `\b`,
- "\t", `\t`,
- "\n", `\n`,
- "\x0b", `\u000b`,
- "\f", `\f`,
- "\r", `\r`,
- "\x0e", `\u000e`,
- "\x0f", `\u000f`,
- "\x10", `\u0010`,
- "\x11", `\u0011`,
- "\x12", `\u0012`,
- "\x13", `\u0013`,
- "\x14", `\u0014`,
- "\x15", `\u0015`,
- "\x16", `\u0016`,
- "\x17", `\u0017`,
- "\x18", `\u0018`,
- "\x19", `\u0019`,
- "\x1a", `\u001a`,
- "\x1b", `\u001b`,
- "\x1c", `\u001c`,
- "\x1d", `\u001d`,
- "\x1e", `\u001e`,
- "\x1f", `\u001f`,
- "\x7f", `\u007f`,
-)
-
-var (
- marshalToml = reflect.TypeOf((*Marshaler)(nil)).Elem()
- marshalText = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem()
- timeType = reflect.TypeOf((*time.Time)(nil)).Elem()
-)
-
-// Marshaler is the interface implemented by types that can marshal themselves
-// into valid TOML.
-type Marshaler interface {
- MarshalTOML() ([]byte, error)
-}
-
-// Marshal returns a TOML representation of the Go value.
-//
-// See [Encoder] for a description of the encoding process.
-func Marshal(v any) ([]byte, error) {
- buff := new(bytes.Buffer)
- if err := NewEncoder(buff).Encode(v); err != nil {
- return nil, err
- }
- return buff.Bytes(), nil
-}
-
-// Encoder encodes a Go to a TOML document.
-//
-// The mapping between Go values and TOML values should be precisely the same as
-// for [Decode].
-//
-// time.Time is encoded as a RFC 3339 string, and time.Duration as its string
-// representation.
-//
-// The [Marshaler] and [encoding.TextMarshaler] interfaces are supported to
-// encoding the value as custom TOML.
-//
-// If you want to write arbitrary binary data then you will need to use
-// something like base64 since TOML does not have any binary types.
-//
-// When encoding TOML hashes (Go maps or structs), keys without any sub-hashes
-// are encoded first.
-//
-// Go maps will be sorted alphabetically by key for deterministic output.
-//
-// The toml struct tag can be used to provide the key name; if omitted the
-// struct field name will be used. If the "omitempty" option is present the
-// following value will be skipped:
-//
-// - arrays, slices, maps, and string with len of 0
-// - struct with all zero values
-// - bool false
-//
-// If omitzero is given all int and float types with a value of 0 will be
-// skipped.
-//
-// Encoding Go values without a corresponding TOML representation will return an
-// error. Examples of this includes maps with non-string keys, slices with nil
-// elements, embedded non-struct types, and nested slices containing maps or
-// structs. (e.g. [][]map[string]string is not allowed but []map[string]string
-// is okay, as is []map[string][]string).
-//
-// NOTE: only exported keys are encoded due to the use of reflection. Unexported
-// keys are silently discarded.
-type Encoder struct {
- Indent string // string for a single indentation level; default is two spaces.
- hasWritten bool // written any output to w yet?
- w *bufio.Writer
-}
-
-// NewEncoder create a new Encoder.
-func NewEncoder(w io.Writer) *Encoder {
- return &Encoder{w: bufio.NewWriter(w), Indent: " "}
-}
-
-// Encode writes a TOML representation of the Go value to the [Encoder]'s writer.
-//
-// An error is returned if the value given cannot be encoded to a valid TOML
-// document.
-func (enc *Encoder) Encode(v any) error {
- rv := eindirect(reflect.ValueOf(v))
- err := enc.safeEncode(Key([]string{}), rv)
- if err != nil {
- return err
- }
- return enc.w.Flush()
-}
-
-func (enc *Encoder) safeEncode(key Key, rv reflect.Value) (err error) {
- defer func() {
- if r := recover(); r != nil {
- if terr, ok := r.(tomlEncodeError); ok {
- err = terr.error
- return
- }
- panic(r)
- }
- }()
- enc.encode(key, rv)
- return nil
-}
-
-func (enc *Encoder) encode(key Key, rv reflect.Value) {
- // If we can marshal the type to text, then we use that. This prevents the
- // encoder for handling these types as generic structs (or whatever the
- // underlying type of a TextMarshaler is).
- switch {
- case isMarshaler(rv):
- enc.writeKeyValue(key, rv, false)
- return
- case rv.Type() == primitiveType: // TODO: #76 would make this superfluous after implemented.
- enc.encode(key, reflect.ValueOf(rv.Interface().(Primitive).undecoded))
- return
- }
-
- k := rv.Kind()
- switch k {
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32,
- reflect.Int64,
- reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32,
- reflect.Uint64,
- reflect.Float32, reflect.Float64, reflect.String, reflect.Bool:
- enc.writeKeyValue(key, rv, false)
- case reflect.Array, reflect.Slice:
- if typeEqual(tomlArrayHash, tomlTypeOfGo(rv)) {
- enc.eArrayOfTables(key, rv)
- } else {
- enc.writeKeyValue(key, rv, false)
- }
- case reflect.Interface:
- if rv.IsNil() {
- return
- }
- enc.encode(key, rv.Elem())
- case reflect.Map:
- if rv.IsNil() {
- return
- }
- enc.eTable(key, rv)
- case reflect.Ptr:
- if rv.IsNil() {
- return
- }
- enc.encode(key, rv.Elem())
- case reflect.Struct:
- enc.eTable(key, rv)
- default:
- encPanic(fmt.Errorf("unsupported type for key '%s': %s", key, k))
- }
-}
-
-// eElement encodes any value that can be an array element.
-func (enc *Encoder) eElement(rv reflect.Value) {
- switch v := rv.Interface().(type) {
- case time.Time: // Using TextMarshaler adds extra quotes, which we don't want.
- format := time.RFC3339Nano
- switch v.Location() {
- case internal.LocalDatetime:
- format = "2006-01-02T15:04:05.999999999"
- case internal.LocalDate:
- format = "2006-01-02"
- case internal.LocalTime:
- format = "15:04:05.999999999"
- }
- switch v.Location() {
- default:
- enc.wf(v.Format(format))
- case internal.LocalDatetime, internal.LocalDate, internal.LocalTime:
- enc.wf(v.In(time.UTC).Format(format))
- }
- return
- case Marshaler:
- s, err := v.MarshalTOML()
- if err != nil {
- encPanic(err)
- }
- if s == nil {
- encPanic(errors.New("MarshalTOML returned nil and no error"))
- }
- enc.w.Write(s)
- return
- case encoding.TextMarshaler:
- s, err := v.MarshalText()
- if err != nil {
- encPanic(err)
- }
- if s == nil {
- encPanic(errors.New("MarshalText returned nil and no error"))
- }
- enc.writeQuoted(string(s))
- return
- case time.Duration:
- enc.writeQuoted(v.String())
- return
- case json.Number:
- n, _ := rv.Interface().(json.Number)
-
- if n == "" { /// Useful zero value.
- enc.w.WriteByte('0')
- return
- } else if v, err := n.Int64(); err == nil {
- enc.eElement(reflect.ValueOf(v))
- return
- } else if v, err := n.Float64(); err == nil {
- enc.eElement(reflect.ValueOf(v))
- return
- }
- encPanic(fmt.Errorf("unable to convert %q to int64 or float64", n))
- }
-
- switch rv.Kind() {
- case reflect.Ptr:
- enc.eElement(rv.Elem())
- return
- case reflect.String:
- enc.writeQuoted(rv.String())
- case reflect.Bool:
- enc.wf(strconv.FormatBool(rv.Bool()))
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- enc.wf(strconv.FormatInt(rv.Int(), 10))
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
- enc.wf(strconv.FormatUint(rv.Uint(), 10))
- case reflect.Float32:
- f := rv.Float()
- if math.IsNaN(f) {
- if math.Signbit(f) {
- enc.wf("-")
- }
- enc.wf("nan")
- } else if math.IsInf(f, 0) {
- if math.Signbit(f) {
- enc.wf("-")
- }
- enc.wf("inf")
- } else {
- enc.wf(floatAddDecimal(strconv.FormatFloat(f, 'f', -1, 32)))
- }
- case reflect.Float64:
- f := rv.Float()
- if math.IsNaN(f) {
- if math.Signbit(f) {
- enc.wf("-")
- }
- enc.wf("nan")
- } else if math.IsInf(f, 0) {
- if math.Signbit(f) {
- enc.wf("-")
- }
- enc.wf("inf")
- } else {
- enc.wf(floatAddDecimal(strconv.FormatFloat(f, 'f', -1, 64)))
- }
- case reflect.Array, reflect.Slice:
- enc.eArrayOrSliceElement(rv)
- case reflect.Struct:
- enc.eStruct(nil, rv, true)
- case reflect.Map:
- enc.eMap(nil, rv, true)
- case reflect.Interface:
- enc.eElement(rv.Elem())
- default:
- encPanic(fmt.Errorf("unexpected type: %s", fmtType(rv.Interface())))
- }
-}
-
-// By the TOML spec, all floats must have a decimal with at least one number on
-// either side.
-func floatAddDecimal(fstr string) string {
- if !strings.Contains(fstr, ".") {
- return fstr + ".0"
- }
- return fstr
-}
-
-func (enc *Encoder) writeQuoted(s string) {
- enc.wf("\"%s\"", dblQuotedReplacer.Replace(s))
-}
-
-func (enc *Encoder) eArrayOrSliceElement(rv reflect.Value) {
- length := rv.Len()
- enc.wf("[")
- for i := 0; i < length; i++ {
- elem := eindirect(rv.Index(i))
- enc.eElement(elem)
- if i != length-1 {
- enc.wf(", ")
- }
- }
- enc.wf("]")
-}
-
-func (enc *Encoder) eArrayOfTables(key Key, rv reflect.Value) {
- if len(key) == 0 {
- encPanic(errNoKey)
- }
- for i := 0; i < rv.Len(); i++ {
- trv := eindirect(rv.Index(i))
- if isNil(trv) {
- continue
- }
- enc.newline()
- enc.wf("%s[[%s]]", enc.indentStr(key), key)
- enc.newline()
- enc.eMapOrStruct(key, trv, false)
- }
-}
-
-func (enc *Encoder) eTable(key Key, rv reflect.Value) {
- if len(key) == 1 {
- // Output an extra newline between top-level tables.
- // (The newline isn't written if nothing else has been written though.)
- enc.newline()
- }
- if len(key) > 0 {
- enc.wf("%s[%s]", enc.indentStr(key), key)
- enc.newline()
- }
- enc.eMapOrStruct(key, rv, false)
-}
-
-func (enc *Encoder) eMapOrStruct(key Key, rv reflect.Value, inline bool) {
- switch rv.Kind() {
- case reflect.Map:
- enc.eMap(key, rv, inline)
- case reflect.Struct:
- enc.eStruct(key, rv, inline)
- default:
- // Should never happen?
- panic("eTable: unhandled reflect.Value Kind: " + rv.Kind().String())
- }
-}
-
-func (enc *Encoder) eMap(key Key, rv reflect.Value, inline bool) {
- rt := rv.Type()
- if rt.Key().Kind() != reflect.String {
- encPanic(errNonString)
- }
-
- // Sort keys so that we have deterministic output. And write keys directly
- // underneath this key first, before writing sub-structs or sub-maps.
- var mapKeysDirect, mapKeysSub []string
- for _, mapKey := range rv.MapKeys() {
- k := mapKey.String()
- if typeIsTable(tomlTypeOfGo(eindirect(rv.MapIndex(mapKey)))) {
- mapKeysSub = append(mapKeysSub, k)
- } else {
- mapKeysDirect = append(mapKeysDirect, k)
- }
- }
-
- var writeMapKeys = func(mapKeys []string, trailC bool) {
- sort.Strings(mapKeys)
- for i, mapKey := range mapKeys {
- val := eindirect(rv.MapIndex(reflect.ValueOf(mapKey)))
- if isNil(val) {
- continue
- }
-
- if inline {
- enc.writeKeyValue(Key{mapKey}, val, true)
- if trailC || i != len(mapKeys)-1 {
- enc.wf(", ")
- }
- } else {
- enc.encode(key.add(mapKey), val)
- }
- }
- }
-
- if inline {
- enc.wf("{")
- }
- writeMapKeys(mapKeysDirect, len(mapKeysSub) > 0)
- writeMapKeys(mapKeysSub, false)
- if inline {
- enc.wf("}")
- }
-}
-
-const is32Bit = (32 << (^uint(0) >> 63)) == 32
-
-func pointerTo(t reflect.Type) reflect.Type {
- if t.Kind() == reflect.Ptr {
- return pointerTo(t.Elem())
- }
- return t
-}
-
-func (enc *Encoder) eStruct(key Key, rv reflect.Value, inline bool) {
- // Write keys for fields directly under this key first, because if we write
- // a field that creates a new table then all keys under it will be in that
- // table (not the one we're writing here).
- //
- // Fields is a [][]int: for fieldsDirect this always has one entry (the
- // struct index). For fieldsSub it contains two entries: the parent field
- // index from tv, and the field indexes for the fields of the sub.
- var (
- rt = rv.Type()
- fieldsDirect, fieldsSub [][]int
- addFields func(rt reflect.Type, rv reflect.Value, start []int)
- )
- addFields = func(rt reflect.Type, rv reflect.Value, start []int) {
- for i := 0; i < rt.NumField(); i++ {
- f := rt.Field(i)
- isEmbed := f.Anonymous && pointerTo(f.Type).Kind() == reflect.Struct
- if f.PkgPath != "" && !isEmbed { /// Skip unexported fields.
- continue
- }
- opts := getOptions(f.Tag)
- if opts.skip {
- continue
- }
-
- frv := eindirect(rv.Field(i))
-
- if is32Bit {
- // Copy so it works correct on 32bit archs; not clear why this
- // is needed. See #314, and https://www.reddit.com/r/golang/comments/pnx8v4
- // This also works fine on 64bit, but 32bit archs are somewhat
- // rare and this is a wee bit faster.
- copyStart := make([]int, len(start))
- copy(copyStart, start)
- start = copyStart
- }
-
- // Treat anonymous struct fields with tag names as though they are
- // not anonymous, like encoding/json does.
- //
- // Non-struct anonymous fields use the normal encoding logic.
- if isEmbed {
- if getOptions(f.Tag).name == "" && frv.Kind() == reflect.Struct {
- addFields(frv.Type(), frv, append(start, f.Index...))
- continue
- }
- }
-
- if typeIsTable(tomlTypeOfGo(frv)) {
- fieldsSub = append(fieldsSub, append(start, f.Index...))
- } else {
- fieldsDirect = append(fieldsDirect, append(start, f.Index...))
- }
- }
- }
- addFields(rt, rv, nil)
-
- writeFields := func(fields [][]int) {
- for _, fieldIndex := range fields {
- fieldType := rt.FieldByIndex(fieldIndex)
- fieldVal := rv.FieldByIndex(fieldIndex)
-
- opts := getOptions(fieldType.Tag)
- if opts.skip {
- continue
- }
- if opts.omitempty && isEmpty(fieldVal) {
- continue
- }
-
- fieldVal = eindirect(fieldVal)
-
- if isNil(fieldVal) { /// Don't write anything for nil fields.
- continue
- }
-
- keyName := fieldType.Name
- if opts.name != "" {
- keyName = opts.name
- }
-
- if opts.omitzero && isZero(fieldVal) {
- continue
- }
-
- if inline {
- enc.writeKeyValue(Key{keyName}, fieldVal, true)
- if fieldIndex[0] != len(fields)-1 {
- enc.wf(", ")
- }
- } else {
- enc.encode(key.add(keyName), fieldVal)
- }
- }
- }
-
- if inline {
- enc.wf("{")
- }
- writeFields(fieldsDirect)
- writeFields(fieldsSub)
- if inline {
- enc.wf("}")
- }
-}
-
-// tomlTypeOfGo returns the TOML type name of the Go value's type.
-//
-// It is used to determine whether the types of array elements are mixed (which
-// is forbidden). If the Go value is nil, then it is illegal for it to be an
-// array element, and valueIsNil is returned as true.
-//
-// The type may be `nil`, which means no concrete TOML type could be found.
-func tomlTypeOfGo(rv reflect.Value) tomlType {
- if isNil(rv) || !rv.IsValid() {
- return nil
- }
-
- if rv.Kind() == reflect.Struct {
- if rv.Type() == timeType {
- return tomlDatetime
- }
- if isMarshaler(rv) {
- return tomlString
- }
- return tomlHash
- }
-
- if isMarshaler(rv) {
- return tomlString
- }
-
- switch rv.Kind() {
- case reflect.Bool:
- return tomlBool
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32,
- reflect.Int64,
- reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32,
- reflect.Uint64:
- return tomlInteger
- case reflect.Float32, reflect.Float64:
- return tomlFloat
- case reflect.Array, reflect.Slice:
- if isTableArray(rv) {
- return tomlArrayHash
- }
- return tomlArray
- case reflect.Ptr, reflect.Interface:
- return tomlTypeOfGo(rv.Elem())
- case reflect.String:
- return tomlString
- case reflect.Map:
- return tomlHash
- default:
- encPanic(errors.New("unsupported type: " + rv.Kind().String()))
- panic("unreachable")
- }
-}
-
-func isMarshaler(rv reflect.Value) bool {
- return rv.Type().Implements(marshalText) || rv.Type().Implements(marshalToml)
-}
-
-// isTableArray reports if all entries in the array or slice are a table.
-func isTableArray(arr reflect.Value) bool {
- if isNil(arr) || !arr.IsValid() || arr.Len() == 0 {
- return false
- }
-
- ret := true
- for i := 0; i < arr.Len(); i++ {
- tt := tomlTypeOfGo(eindirect(arr.Index(i)))
- // Don't allow nil.
- if tt == nil {
- encPanic(errArrayNilElement)
- }
-
- if ret && !typeEqual(tomlHash, tt) {
- ret = false
- }
- }
- return ret
-}
-
-type tagOptions struct {
- skip bool // "-"
- name string
- omitempty bool
- omitzero bool
-}
-
-func getOptions(tag reflect.StructTag) tagOptions {
- t := tag.Get("toml")
- if t == "-" {
- return tagOptions{skip: true}
- }
- var opts tagOptions
- parts := strings.Split(t, ",")
- opts.name = parts[0]
- for _, s := range parts[1:] {
- switch s {
- case "omitempty":
- opts.omitempty = true
- case "omitzero":
- opts.omitzero = true
- }
- }
- return opts
-}
-
-func isZero(rv reflect.Value) bool {
- switch rv.Kind() {
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- return rv.Int() == 0
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
- return rv.Uint() == 0
- case reflect.Float32, reflect.Float64:
- return rv.Float() == 0.0
- }
- return false
-}
-
-func isEmpty(rv reflect.Value) bool {
- switch rv.Kind() {
- case reflect.Array, reflect.Slice, reflect.Map, reflect.String:
- return rv.Len() == 0
- case reflect.Struct:
- if rv.Type().Comparable() {
- return reflect.Zero(rv.Type()).Interface() == rv.Interface()
- }
- // Need to also check if all the fields are empty, otherwise something
- // like this with uncomparable types will always return true:
- //
- // type a struct{ field b }
- // type b struct{ s []string }
- // s := a{field: b{s: []string{"AAA"}}}
- for i := 0; i < rv.NumField(); i++ {
- if !isEmpty(rv.Field(i)) {
- return false
- }
- }
- return true
- case reflect.Bool:
- return !rv.Bool()
- case reflect.Ptr:
- return rv.IsNil()
- }
- return false
-}
-
-func (enc *Encoder) newline() {
- if enc.hasWritten {
- enc.wf("\n")
- }
-}
-
-// Write a key/value pair:
-//
-// key = <any value>
-//
-// This is also used for "k = v" in inline tables; so something like this will
-// be written in three calls:
-//
-// ┌───────────────────┐
-// │ ┌───┐ ┌────┐│
-// v v v v vv
-// key = {k = 1, k2 = 2}
-func (enc *Encoder) writeKeyValue(key Key, val reflect.Value, inline bool) {
- /// Marshaler used on top-level document; call eElement() to just call
- /// Marshal{TOML,Text}.
- if len(key) == 0 {
- enc.eElement(val)
- return
- }
- enc.wf("%s%s = ", enc.indentStr(key), key.maybeQuoted(len(key)-1))
- enc.eElement(val)
- if !inline {
- enc.newline()
- }
-}
-
-func (enc *Encoder) wf(format string, v ...any) {
- _, err := fmt.Fprintf(enc.w, format, v...)
- if err != nil {
- encPanic(err)
- }
- enc.hasWritten = true
-}
-
-func (enc *Encoder) indentStr(key Key) string {
- return strings.Repeat(enc.Indent, len(key)-1)
-}
-
-func encPanic(err error) {
- panic(tomlEncodeError{err})
-}
-
-// Resolve any level of pointers to the actual value (e.g. **string → string).
-func eindirect(v reflect.Value) reflect.Value {
- if v.Kind() != reflect.Ptr && v.Kind() != reflect.Interface {
- if isMarshaler(v) {
- return v
- }
- if v.CanAddr() { /// Special case for marshalers; see #358.
- if pv := v.Addr(); isMarshaler(pv) {
- return pv
- }
- }
- return v
- }
-
- if v.IsNil() {
- return v
- }
-
- return eindirect(v.Elem())
-}
-
-func isNil(rv reflect.Value) bool {
- switch rv.Kind() {
- case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
- return rv.IsNil()
- default:
- return false
- }
-}
diff --git a/vendor/github.com/BurntSushi/toml/error.go b/vendor/github.com/BurntSushi/toml/error.go
deleted file mode 100644
index 1dd523211..000000000
--- a/vendor/github.com/BurntSushi/toml/error.go
+++ /dev/null
@@ -1,347 +0,0 @@
-package toml
-
-import (
- "fmt"
- "strings"
-)
-
-// ParseError is returned when there is an error parsing the TOML syntax such as
-// invalid syntax, duplicate keys, etc.
-//
-// In addition to the error message itself, you can also print detailed location
-// information with context by using [ErrorWithPosition]:
-//
-// toml: error: Key 'fruit' was already created and cannot be used as an array.
-//
-// At line 4, column 2-7:
-//
-// 2 | fruit = []
-// 3 |
-// 4 | [[fruit]] # Not allowed
-// ^^^^^
-//
-// [ErrorWithUsage] can be used to print the above with some more detailed usage
-// guidance:
-//
-// toml: error: newlines not allowed within inline tables
-//
-// At line 1, column 18:
-//
-// 1 | x = [{ key = 42 #
-// ^
-//
-// Error help:
-//
-// Inline tables must always be on a single line:
-//
-// table = {key = 42, second = 43}
-//
-// It is invalid to split them over multiple lines like so:
-//
-// # INVALID
-// table = {
-// key = 42,
-// second = 43
-// }
-//
-// Use regular for this:
-//
-// [table]
-// key = 42
-// second = 43
-type ParseError struct {
- Message string // Short technical message.
- Usage string // Longer message with usage guidance; may be blank.
- Position Position // Position of the error
- LastKey string // Last parsed key, may be blank.
-
- // Line the error occurred.
- //
- // Deprecated: use [Position].
- Line int
-
- err error
- input string
-}
-
-// Position of an error.
-type Position struct {
- Line int // Line number, starting at 1.
- Col int // Error column, starting at 1.
- Start int // Start of error, as byte offset starting at 0.
- Len int // Lenght of the error in bytes.
-}
-
-func (p Position) withCol(tomlFile string) Position {
- var (
- pos int
- lines = strings.Split(tomlFile, "\n")
- )
- for i := range lines {
- ll := len(lines[i]) + 1 // +1 for the removed newline
- if pos+ll >= p.Start {
- p.Col = p.Start - pos + 1
- if p.Col < 1 { // Should never happen, but just in case.
- p.Col = 1
- }
- break
- }
- pos += ll
- }
- return p
-}
-
-func (pe ParseError) Error() string {
- if pe.LastKey == "" {
- return fmt.Sprintf("toml: line %d: %s", pe.Position.Line, pe.Message)
- }
- return fmt.Sprintf("toml: line %d (last key %q): %s",
- pe.Position.Line, pe.LastKey, pe.Message)
-}
-
-// ErrorWithPosition returns the error with detailed location context.
-//
-// See the documentation on [ParseError].
-func (pe ParseError) ErrorWithPosition() string {
- if pe.input == "" { // Should never happen, but just in case.
- return pe.Error()
- }
-
- // TODO: don't show control characters as literals? This may not show up
- // well everywhere.
-
- var (
- lines = strings.Split(pe.input, "\n")
- b = new(strings.Builder)
- )
- if pe.Position.Len == 1 {
- fmt.Fprintf(b, "toml: error: %s\n\nAt line %d, column %d:\n\n",
- pe.Message, pe.Position.Line, pe.Position.Col)
- } else {
- fmt.Fprintf(b, "toml: error: %s\n\nAt line %d, column %d-%d:\n\n",
- pe.Message, pe.Position.Line, pe.Position.Col, pe.Position.Col+pe.Position.Len-1)
- }
- if pe.Position.Line > 2 {
- fmt.Fprintf(b, "% 7d | %s\n", pe.Position.Line-2, expandTab(lines[pe.Position.Line-3]))
- }
- if pe.Position.Line > 1 {
- fmt.Fprintf(b, "% 7d | %s\n", pe.Position.Line-1, expandTab(lines[pe.Position.Line-2]))
- }
-
- /// Expand tabs, so that the ^^^s are at the correct position, but leave
- /// "column 10-13" intact. Adjusting this to the visual column would be
- /// better, but we don't know the tabsize of the user in their editor, which
- /// can be 8, 4, 2, or something else. We can't know. So leaving it as the
- /// character index is probably the "most correct".
- expanded := expandTab(lines[pe.Position.Line-1])
- diff := len(expanded) - len(lines[pe.Position.Line-1])
-
- fmt.Fprintf(b, "% 7d | %s\n", pe.Position.Line, expanded)
- fmt.Fprintf(b, "% 10s%s%s\n", "", strings.Repeat(" ", pe.Position.Col-1+diff), strings.Repeat("^", pe.Position.Len))
- return b.String()
-}
-
-// ErrorWithUsage returns the error with detailed location context and usage
-// guidance.
-//
-// See the documentation on [ParseError].
-func (pe ParseError) ErrorWithUsage() string {
- m := pe.ErrorWithPosition()
- if u, ok := pe.err.(interface{ Usage() string }); ok && u.Usage() != "" {
- lines := strings.Split(strings.TrimSpace(u.Usage()), "\n")
- for i := range lines {
- if lines[i] != "" {
- lines[i] = " " + lines[i]
- }
- }
- return m + "Error help:\n\n" + strings.Join(lines, "\n") + "\n"
- }
- return m
-}
-
-func expandTab(s string) string {
- var (
- b strings.Builder
- l int
- fill = func(n int) string {
- b := make([]byte, n)
- for i := range b {
- b[i] = ' '
- }
- return string(b)
- }
- )
- b.Grow(len(s))
- for _, r := range s {
- switch r {
- case '\t':
- tw := 8 - l%8
- b.WriteString(fill(tw))
- l += tw
- default:
- b.WriteRune(r)
- l += 1
- }
- }
- return b.String()
-}
-
-type (
- errLexControl struct{ r rune }
- errLexEscape struct{ r rune }
- errLexUTF8 struct{ b byte }
- errParseDate struct{ v string }
- errLexInlineTableNL struct{}
- errLexStringNL struct{}
- errParseRange struct {
- i any // int or float
- size string // "int64", "uint16", etc.
- }
- errUnsafeFloat struct {
- i interface{} // float32 or float64
- size string // "float32" or "float64"
- }
- errParseDuration struct{ d string }
-)
-
-func (e errLexControl) Error() string {
- return fmt.Sprintf("TOML files cannot contain control characters: '0x%02x'", e.r)
-}
-func (e errLexControl) Usage() string { return "" }
-
-func (e errLexEscape) Error() string { return fmt.Sprintf(`invalid escape in string '\%c'`, e.r) }
-func (e errLexEscape) Usage() string { return usageEscape }
-func (e errLexUTF8) Error() string { return fmt.Sprintf("invalid UTF-8 byte: 0x%02x", e.b) }
-func (e errLexUTF8) Usage() string { return "" }
-func (e errParseDate) Error() string { return fmt.Sprintf("invalid datetime: %q", e.v) }
-func (e errParseDate) Usage() string { return usageDate }
-func (e errLexInlineTableNL) Error() string { return "newlines not allowed within inline tables" }
-func (e errLexInlineTableNL) Usage() string { return usageInlineNewline }
-func (e errLexStringNL) Error() string { return "strings cannot contain newlines" }
-func (e errLexStringNL) Usage() string { return usageStringNewline }
-func (e errParseRange) Error() string { return fmt.Sprintf("%v is out of range for %s", e.i, e.size) }
-func (e errParseRange) Usage() string { return usageIntOverflow }
-func (e errUnsafeFloat) Error() string {
- return fmt.Sprintf("%v is out of the safe %s range", e.i, e.size)
-}
-func (e errUnsafeFloat) Usage() string { return usageUnsafeFloat }
-func (e errParseDuration) Error() string { return fmt.Sprintf("invalid duration: %q", e.d) }
-func (e errParseDuration) Usage() string { return usageDuration }
-
-const usageEscape = `
-A '\' inside a "-delimited string is interpreted as an escape character.
-
-The following escape sequences are supported:
-\b, \t, \n, \f, \r, \", \\, \uXXXX, and \UXXXXXXXX
-
-To prevent a '\' from being recognized as an escape character, use either:
-
-- a ' or '''-delimited string; escape characters aren't processed in them; or
-- write two backslashes to get a single backslash: '\\'.
-
-If you're trying to add a Windows path (e.g. "C:\Users\martin") then using '/'
-instead of '\' will usually also work: "C:/Users/martin".
-`
-
-const usageInlineNewline = `
-Inline tables must always be on a single line:
-
- table = {key = 42, second = 43}
-
-It is invalid to split them over multiple lines like so:
-
- # INVALID
- table = {
- key = 42,
- second = 43
- }
-
-Use regular for this:
-
- [table]
- key = 42
- second = 43
-`
-
-const usageStringNewline = `
-Strings must always be on a single line, and cannot span more than one line:
-
- # INVALID
- string = "Hello,
- world!"
-
-Instead use """ or ''' to split strings over multiple lines:
-
- string = """Hello,
- world!"""
-`
-
-const usageIntOverflow = `
-This number is too large; this may be an error in the TOML, but it can also be a
-bug in the program that uses too small of an integer.
-
-The maximum and minimum values are:
-
- size │ lowest │ highest
- ───────┼────────────────┼──────────────
- int8 │ -128 │ 127
- int16 │ -32,768 │ 32,767
- int32 │ -2,147,483,648 │ 2,147,483,647
- int64 │ -9.2 × 10¹⁷ │ 9.2 × 10¹⁷
- uint8 │ 0 │ 255
- uint16 │ 0 │ 65,535
- uint32 │ 0 │ 4,294,967,295
- uint64 │ 0 │ 1.8 × 10¹⁸
-
-int refers to int32 on 32-bit systems and int64 on 64-bit systems.
-`
-
-const usageUnsafeFloat = `
-This number is outside of the "safe" range for floating point numbers; whole
-(non-fractional) numbers outside the below range can not always be represented
-accurately in a float, leading to some loss of accuracy.
-
-Explicitly mark a number as a fractional unit by adding ".0", which will incur
-some loss of accuracy; for example:
-
- f = 2_000_000_000.0
-
-Accuracy ranges:
-
- float32 = 16,777,215
- float64 = 9,007,199,254,740,991
-`
-
-const usageDuration = `
-A duration must be as "number<unit>", without any spaces. Valid units are:
-
- ns nanoseconds (billionth of a second)
- us, µs microseconds (millionth of a second)
- ms milliseconds (thousands of a second)
- s seconds
- m minutes
- h hours
-
-You can combine multiple units; for example "5m10s" for 5 minutes and 10
-seconds.
-`
-
-const usageDate = `
-A TOML datetime must be in one of the following formats:
-
- 2006-01-02T15:04:05Z07:00 Date and time, with timezone.
- 2006-01-02T15:04:05 Date and time, but without timezone.
- 2006-01-02 Date without a time or timezone.
- 15:04:05 Just a time, without any timezone.
-
-Seconds may optionally have a fraction, up to nanosecond precision:
-
- 15:04:05.123
- 15:04:05.856018510
-`
-
-// TOML 1.1:
-// The seconds part in times is optional, and may be omitted:
-// 2006-01-02T15:04Z07:00
-// 2006-01-02T15:04
-// 15:04
diff --git a/vendor/github.com/BurntSushi/toml/internal/tz.go b/vendor/github.com/BurntSushi/toml/internal/tz.go
deleted file mode 100644
index 022f15bc2..000000000
--- a/vendor/github.com/BurntSushi/toml/internal/tz.go
+++ /dev/null
@@ -1,36 +0,0 @@
-package internal
-
-import "time"
-
-// Timezones used for local datetime, date, and time TOML types.
-//
-// The exact way times and dates without a timezone should be interpreted is not
-// well-defined in the TOML specification and left to the implementation. These
-// defaults to current local timezone offset of the computer, but this can be
-// changed by changing these variables before decoding.
-//
-// TODO:
-// Ideally we'd like to offer people the ability to configure the used timezone
-// by setting Decoder.Timezone and Encoder.Timezone; however, this is a bit
-// tricky: the reason we use three different variables for this is to support
-// round-tripping – without these specific TZ names we wouldn't know which
-// format to use.
-//
-// There isn't a good way to encode this right now though, and passing this sort
-// of information also ties in to various related issues such as string format
-// encoding, encoding of comments, etc.
-//
-// So, for the time being, just put this in internal until we can write a good
-// comprehensive API for doing all of this.
-//
-// The reason they're exported is because they're referred from in e.g.
-// internal/tag.
-//
-// Note that this behaviour is valid according to the TOML spec as the exact
-// behaviour is left up to implementations.
-var (
- localOffset = func() int { _, o := time.Now().Zone(); return o }()
- LocalDatetime = time.FixedZone("datetime-local", localOffset)
- LocalDate = time.FixedZone("date-local", localOffset)
- LocalTime = time.FixedZone("time-local", localOffset)
-)
diff --git a/vendor/github.com/BurntSushi/toml/lex.go b/vendor/github.com/BurntSushi/toml/lex.go
deleted file mode 100644
index 6878d9d69..000000000
--- a/vendor/github.com/BurntSushi/toml/lex.go
+++ /dev/null
@@ -1,1287 +0,0 @@
-package toml
-
-import (
- "fmt"
- "reflect"
- "runtime"
- "strings"
- "unicode"
- "unicode/utf8"
-)
-
-type itemType int
-
-const (
- itemError itemType = iota
- itemNIL // used in the parser to indicate no type
- itemEOF
- itemText
- itemString
- itemStringEsc
- itemRawString
- itemMultilineString
- itemRawMultilineString
- itemBool
- itemInteger
- itemFloat
- itemDatetime
- itemArray // the start of an array
- itemArrayEnd
- itemTableStart
- itemTableEnd
- itemArrayTableStart
- itemArrayTableEnd
- itemKeyStart
- itemKeyEnd
- itemCommentStart
- itemInlineTableStart
- itemInlineTableEnd
-)
-
-const eof = 0
-
-type stateFn func(lx *lexer) stateFn
-
-func (p Position) String() string {
- return fmt.Sprintf("at line %d; start %d; length %d", p.Line, p.Start, p.Len)
-}
-
-type lexer struct {
- input string
- start int
- pos int
- line int
- state stateFn
- items chan item
- tomlNext bool
- esc bool
-
- // Allow for backing up up to 4 runes. This is necessary because TOML
- // contains 3-rune tokens (""" and ''').
- prevWidths [4]int
- nprev int // how many of prevWidths are in use
- atEOF bool // If we emit an eof, we can still back up, but it is not OK to call next again.
-
- // A stack of state functions used to maintain context.
- //
- // The idea is to reuse parts of the state machine in various places. For
- // example, values can appear at the top level or within arbitrarily nested
- // arrays. The last state on the stack is used after a value has been lexed.
- // Similarly for comments.
- stack []stateFn
-}
-
-type item struct {
- typ itemType
- val string
- err error
- pos Position
-}
-
-func (lx *lexer) nextItem() item {
- for {
- select {
- case item := <-lx.items:
- return item
- default:
- lx.state = lx.state(lx)
- //fmt.Printf(" STATE %-24s current: %-10s stack: %s\n", lx.state, lx.current(), lx.stack)
- }
- }
-}
-
-func lex(input string, tomlNext bool) *lexer {
- lx := &lexer{
- input: input,
- state: lexTop,
- items: make(chan item, 10),
- stack: make([]stateFn, 0, 10),
- line: 1,
- tomlNext: tomlNext,
- }
- return lx
-}
-
-func (lx *lexer) push(state stateFn) {
- lx.stack = append(lx.stack, state)
-}
-
-func (lx *lexer) pop() stateFn {
- if len(lx.stack) == 0 {
- return lx.errorf("BUG in lexer: no states to pop")
- }
- last := lx.stack[len(lx.stack)-1]
- lx.stack = lx.stack[0 : len(lx.stack)-1]
- return last
-}
-
-func (lx *lexer) current() string {
- return lx.input[lx.start:lx.pos]
-}
-
-func (lx lexer) getPos() Position {
- p := Position{
- Line: lx.line,
- Start: lx.start,
- Len: lx.pos - lx.start,
- }
- if p.Len <= 0 {
- p.Len = 1
- }
- return p
-}
-
-func (lx *lexer) emit(typ itemType) {
- // Needed for multiline strings ending with an incomplete UTF-8 sequence.
- if lx.start > lx.pos {
- lx.error(errLexUTF8{lx.input[lx.pos]})
- return
- }
- lx.items <- item{typ: typ, pos: lx.getPos(), val: lx.current()}
- lx.start = lx.pos
-}
-
-func (lx *lexer) emitTrim(typ itemType) {
- lx.items <- item{typ: typ, pos: lx.getPos(), val: strings.TrimSpace(lx.current())}
- lx.start = lx.pos
-}
-
-func (lx *lexer) next() (r rune) {
- if lx.atEOF {
- panic("BUG in lexer: next called after EOF")
- }
- if lx.pos >= len(lx.input) {
- lx.atEOF = true
- return eof
- }
-
- if lx.input[lx.pos] == '\n' {
- lx.line++
- }
- lx.prevWidths[3] = lx.prevWidths[2]
- lx.prevWidths[2] = lx.prevWidths[1]
- lx.prevWidths[1] = lx.prevWidths[0]
- if lx.nprev < 4 {
- lx.nprev++
- }
-
- r, w := utf8.DecodeRuneInString(lx.input[lx.pos:])
- if r == utf8.RuneError && w == 1 {
- lx.error(errLexUTF8{lx.input[lx.pos]})
- return utf8.RuneError
- }
-
- // Note: don't use peek() here, as this calls next().
- if isControl(r) || (r == '\r' && (len(lx.input)-1 == lx.pos || lx.input[lx.pos+1] != '\n')) {
- lx.errorControlChar(r)
- return utf8.RuneError
- }
-
- lx.prevWidths[0] = w
- lx.pos += w
- return r
-}
-
-// ignore skips over the pending input before this point.
-func (lx *lexer) ignore() {
- lx.start = lx.pos
-}
-
-// backup steps back one rune. Can be called 4 times between calls to next.
-func (lx *lexer) backup() {
- if lx.atEOF {
- lx.atEOF = false
- return
- }
- if lx.nprev < 1 {
- panic("BUG in lexer: backed up too far")
- }
- w := lx.prevWidths[0]
- lx.prevWidths[0] = lx.prevWidths[1]
- lx.prevWidths[1] = lx.prevWidths[2]
- lx.prevWidths[2] = lx.prevWidths[3]
- lx.nprev--
-
- lx.pos -= w
- if lx.pos < len(lx.input) && lx.input[lx.pos] == '\n' {
- lx.line--
- }
-}
-
-// accept consumes the next rune if it's equal to `valid`.
-func (lx *lexer) accept(valid rune) bool {
- if lx.next() == valid {
- return true
- }
- lx.backup()
- return false
-}
-
-// peek returns but does not consume the next rune in the input.
-func (lx *lexer) peek() rune {
- r := lx.next()
- lx.backup()
- return r
-}
-
-// skip ignores all input that matches the given predicate.
-func (lx *lexer) skip(pred func(rune) bool) {
- for {
- r := lx.next()
- if pred(r) {
- continue
- }
- lx.backup()
- lx.ignore()
- return
- }
-}
-
-// error stops all lexing by emitting an error and returning `nil`.
-//
-// Note that any value that is a character is escaped if it's a special
-// character (newlines, tabs, etc.).
-func (lx *lexer) error(err error) stateFn {
- if lx.atEOF {
- return lx.errorPrevLine(err)
- }
- lx.items <- item{typ: itemError, pos: lx.getPos(), err: err}
- return nil
-}
-
-// errorfPrevline is like error(), but sets the position to the last column of
-// the previous line.
-//
-// This is so that unexpected EOF or NL errors don't show on a new blank line.
-func (lx *lexer) errorPrevLine(err error) stateFn {
- pos := lx.getPos()
- pos.Line--
- pos.Len = 1
- pos.Start = lx.pos - 1
- lx.items <- item{typ: itemError, pos: pos, err: err}
- return nil
-}
-
-// errorPos is like error(), but allows explicitly setting the position.
-func (lx *lexer) errorPos(start, length int, err error) stateFn {
- pos := lx.getPos()
- pos.Start = start
- pos.Len = length
- lx.items <- item{typ: itemError, pos: pos, err: err}
- return nil
-}
-
-// errorf is like error, and creates a new error.
-func (lx *lexer) errorf(format string, values ...any) stateFn {
- if lx.atEOF {
- pos := lx.getPos()
- pos.Line--
- pos.Len = 1
- pos.Start = lx.pos - 1
- lx.items <- item{typ: itemError, pos: pos, err: fmt.Errorf(format, values...)}
- return nil
- }
- lx.items <- item{typ: itemError, pos: lx.getPos(), err: fmt.Errorf(format, values...)}
- return nil
-}
-
-func (lx *lexer) errorControlChar(cc rune) stateFn {
- return lx.errorPos(lx.pos-1, 1, errLexControl{cc})
-}
-
-// lexTop consumes elements at the top level of TOML data.
-func lexTop(lx *lexer) stateFn {
- r := lx.next()
- if isWhitespace(r) || isNL(r) {
- return lexSkip(lx, lexTop)
- }
- switch r {
- case '#':
- lx.push(lexTop)
- return lexCommentStart
- case '[':
- return lexTableStart
- case eof:
- if lx.pos > lx.start {
- return lx.errorf("unexpected EOF")
- }
- lx.emit(itemEOF)
- return nil
- }
-
- // At this point, the only valid item can be a key, so we back up
- // and let the key lexer do the rest.
- lx.backup()
- lx.push(lexTopEnd)
- return lexKeyStart
-}
-
-// lexTopEnd is entered whenever a top-level item has been consumed. (A value
-// or a table.) It must see only whitespace, and will turn back to lexTop
-// upon a newline. If it sees EOF, it will quit the lexer successfully.
-func lexTopEnd(lx *lexer) stateFn {
- r := lx.next()
- switch {
- case r == '#':
- // a comment will read to a newline for us.
- lx.push(lexTop)
- return lexCommentStart
- case isWhitespace(r):
- return lexTopEnd
- case isNL(r):
- lx.ignore()
- return lexTop
- case r == eof:
- lx.emit(itemEOF)
- return nil
- }
- return lx.errorf("expected a top-level item to end with a newline, comment, or EOF, but got %q instead", r)
-}
-
-// lexTable lexes the beginning of a table. Namely, it makes sure that
-// it starts with a character other than '.' and ']'.
-// It assumes that '[' has already been consumed.
-// It also handles the case that this is an item in an array of tables.
-// e.g., '[[name]]'.
-func lexTableStart(lx *lexer) stateFn {
- if lx.peek() == '[' {
- lx.next()
- lx.emit(itemArrayTableStart)
- lx.push(lexArrayTableEnd)
- } else {
- lx.emit(itemTableStart)
- lx.push(lexTableEnd)
- }
- return lexTableNameStart
-}
-
-func lexTableEnd(lx *lexer) stateFn {
- lx.emit(itemTableEnd)
- return lexTopEnd
-}
-
-func lexArrayTableEnd(lx *lexer) stateFn {
- if r := lx.next(); r != ']' {
- return lx.errorf("expected end of table array name delimiter ']', but got %q instead", r)
- }
- lx.emit(itemArrayTableEnd)
- return lexTopEnd
-}
-
-func lexTableNameStart(lx *lexer) stateFn {
- lx.skip(isWhitespace)
- switch r := lx.peek(); {
- case r == ']' || r == eof:
- return lx.errorf("unexpected end of table name (table names cannot be empty)")
- case r == '.':
- return lx.errorf("unexpected table separator (table names cannot be empty)")
- case r == '"' || r == '\'':
- lx.ignore()
- lx.push(lexTableNameEnd)
- return lexQuotedName
- default:
- lx.push(lexTableNameEnd)
- return lexBareName
- }
-}
-
-// lexTableNameEnd reads the end of a piece of a table name, optionally
-// consuming whitespace.
-func lexTableNameEnd(lx *lexer) stateFn {
- lx.skip(isWhitespace)
- switch r := lx.next(); {
- case isWhitespace(r):
- return lexTableNameEnd
- case r == '.':
- lx.ignore()
- return lexTableNameStart
- case r == ']':
- return lx.pop()
- default:
- return lx.errorf("expected '.' or ']' to end table name, but got %q instead", r)
- }
-}
-
-// lexBareName lexes one part of a key or table.
-//
-// It assumes that at least one valid character for the table has already been
-// read.
-//
-// Lexes only one part, e.g. only 'a' inside 'a.b'.
-func lexBareName(lx *lexer) stateFn {
- r := lx.next()
- if isBareKeyChar(r, lx.tomlNext) {
- return lexBareName
- }
- lx.backup()
- lx.emit(itemText)
- return lx.pop()
-}
-
-// lexBareName lexes one part of a key or table.
-//
-// It assumes that at least one valid character for the table has already been
-// read.
-//
-// Lexes only one part, e.g. only '"a"' inside '"a".b'.
-func lexQuotedName(lx *lexer) stateFn {
- r := lx.next()
- switch {
- case isWhitespace(r):
- return lexSkip(lx, lexValue)
- case r == '"':
- lx.ignore() // ignore the '"'
- return lexString
- case r == '\'':
- lx.ignore() // ignore the "'"
- return lexRawString
- case r == eof:
- return lx.errorf("unexpected EOF; expected value")
- default:
- return lx.errorf("expected value but found %q instead", r)
- }
-}
-
-// lexKeyStart consumes all key parts until a '='.
-func lexKeyStart(lx *lexer) stateFn {
- lx.skip(isWhitespace)
- switch r := lx.peek(); {
- case r == '=' || r == eof:
- return lx.errorf("unexpected '=': key name appears blank")
- case r == '.':
- return lx.errorf("unexpected '.': keys cannot start with a '.'")
- case r == '"' || r == '\'':
- lx.ignore()
- fallthrough
- default: // Bare key
- lx.emit(itemKeyStart)
- return lexKeyNameStart
- }
-}
-
-func lexKeyNameStart(lx *lexer) stateFn {
- lx.skip(isWhitespace)
- switch r := lx.peek(); {
- case r == '=' || r == eof:
- return lx.errorf("unexpected '='")
- case r == '.':
- return lx.errorf("unexpected '.'")
- case r == '"' || r == '\'':
- lx.ignore()
- lx.push(lexKeyEnd)
- return lexQuotedName
- default:
- lx.push(lexKeyEnd)
- return lexBareName
- }
-}
-
-// lexKeyEnd consumes the end of a key and trims whitespace (up to the key
-// separator).
-func lexKeyEnd(lx *lexer) stateFn {
- lx.skip(isWhitespace)
- switch r := lx.next(); {
- case isWhitespace(r):
- return lexSkip(lx, lexKeyEnd)
- case r == eof:
- return lx.errorf("unexpected EOF; expected key separator '='")
- case r == '.':
- lx.ignore()
- return lexKeyNameStart
- case r == '=':
- lx.emit(itemKeyEnd)
- return lexSkip(lx, lexValue)
- default:
- if r == '\n' {
- return lx.errorPrevLine(fmt.Errorf("expected '.' or '=', but got %q instead", r))
- }
- return lx.errorf("expected '.' or '=', but got %q instead", r)
- }
-}
-
-// lexValue starts the consumption of a value anywhere a value is expected.
-// lexValue will ignore whitespace.
-// After a value is lexed, the last state on the next is popped and returned.
-func lexValue(lx *lexer) stateFn {
- // We allow whitespace to precede a value, but NOT newlines.
- // In array syntax, the array states are responsible for ignoring newlines.
- r := lx.next()
- switch {
- case isWhitespace(r):
- return lexSkip(lx, lexValue)
- case isDigit(r):
- lx.backup() // avoid an extra state and use the same as above
- return lexNumberOrDateStart
- }
- switch r {
- case '[':
- lx.ignore()
- lx.emit(itemArray)
- return lexArrayValue
- case '{':
- lx.ignore()
- lx.emit(itemInlineTableStart)
- return lexInlineTableValue
- case '"':
- if lx.accept('"') {
- if lx.accept('"') {
- lx.ignore() // Ignore """
- return lexMultilineString
- }
- lx.backup()
- }
- lx.ignore() // ignore the '"'
- return lexString
- case '\'':
- if lx.accept('\'') {
- if lx.accept('\'') {
- lx.ignore() // Ignore """
- return lexMultilineRawString
- }
- lx.backup()
- }
- lx.ignore() // ignore the "'"
- return lexRawString
- case '.': // special error case, be kind to users
- return lx.errorf("floats must start with a digit, not '.'")
- case 'i', 'n':
- if (lx.accept('n') && lx.accept('f')) || (lx.accept('a') && lx.accept('n')) {
- lx.emit(itemFloat)
- return lx.pop()
- }
- case '-', '+':
- return lexDecimalNumberStart
- }
- if unicode.IsLetter(r) {
- // Be permissive here; lexBool will give a nice error if the
- // user wrote something like
- // x = foo
- // (i.e. not 'true' or 'false' but is something else word-like.)
- lx.backup()
- return lexBool
- }
- if r == eof {
- return lx.errorf("unexpected EOF; expected value")
- }
- if r == '\n' {
- return lx.errorPrevLine(fmt.Errorf("expected value but found %q instead", r))
- }
- return lx.errorf("expected value but found %q instead", r)
-}
-
-// lexArrayValue consumes one value in an array. It assumes that '[' or ','
-// have already been consumed. All whitespace and newlines are ignored.
-func lexArrayValue(lx *lexer) stateFn {
- r := lx.next()
- switch {
- case isWhitespace(r) || isNL(r):
- return lexSkip(lx, lexArrayValue)
- case r == '#':
- lx.push(lexArrayValue)
- return lexCommentStart
- case r == ',':
- return lx.errorf("unexpected comma")
- case r == ']':
- return lexArrayEnd
- }
-
- lx.backup()
- lx.push(lexArrayValueEnd)
- return lexValue
-}
-
-// lexArrayValueEnd consumes everything between the end of an array value and
-// the next value (or the end of the array): it ignores whitespace and newlines
-// and expects either a ',' or a ']'.
-func lexArrayValueEnd(lx *lexer) stateFn {
- switch r := lx.next(); {
- case isWhitespace(r) || isNL(r):
- return lexSkip(lx, lexArrayValueEnd)
- case r == '#':
- lx.push(lexArrayValueEnd)
- return lexCommentStart
- case r == ',':
- lx.ignore()
- return lexArrayValue // move on to the next value
- case r == ']':
- return lexArrayEnd
- default:
- return lx.errorf("expected a comma (',') or array terminator (']'), but got %s", runeOrEOF(r))
- }
-}
-
-// lexArrayEnd finishes the lexing of an array.
-// It assumes that a ']' has just been consumed.
-func lexArrayEnd(lx *lexer) stateFn {
- lx.ignore()
- lx.emit(itemArrayEnd)
- return lx.pop()
-}
-
-// lexInlineTableValue consumes one key/value pair in an inline table.
-// It assumes that '{' or ',' have already been consumed. Whitespace is ignored.
-func lexInlineTableValue(lx *lexer) stateFn {
- r := lx.next()
- switch {
- case isWhitespace(r):
- return lexSkip(lx, lexInlineTableValue)
- case isNL(r):
- if lx.tomlNext {
- return lexSkip(lx, lexInlineTableValue)
- }
- return lx.errorPrevLine(errLexInlineTableNL{})
- case r == '#':
- lx.push(lexInlineTableValue)
- return lexCommentStart
- case r == ',':
- return lx.errorf("unexpected comma")
- case r == '}':
- return lexInlineTableEnd
- }
- lx.backup()
- lx.push(lexInlineTableValueEnd)
- return lexKeyStart
-}
-
-// lexInlineTableValueEnd consumes everything between the end of an inline table
-// key/value pair and the next pair (or the end of the table):
-// it ignores whitespace and expects either a ',' or a '}'.
-func lexInlineTableValueEnd(lx *lexer) stateFn {
- switch r := lx.next(); {
- case isWhitespace(r):
- return lexSkip(lx, lexInlineTableValueEnd)
- case isNL(r):
- if lx.tomlNext {
- return lexSkip(lx, lexInlineTableValueEnd)
- }
- return lx.errorPrevLine(errLexInlineTableNL{})
- case r == '#':
- lx.push(lexInlineTableValueEnd)
- return lexCommentStart
- case r == ',':
- lx.ignore()
- lx.skip(isWhitespace)
- if lx.peek() == '}' {
- if lx.tomlNext {
- return lexInlineTableValueEnd
- }
- return lx.errorf("trailing comma not allowed in inline tables")
- }
- return lexInlineTableValue
- case r == '}':
- return lexInlineTableEnd
- default:
- return lx.errorf("expected a comma or an inline table terminator '}', but got %s instead", runeOrEOF(r))
- }
-}
-
-func runeOrEOF(r rune) string {
- if r == eof {
- return "end of file"
- }
- return "'" + string(r) + "'"
-}
-
-// lexInlineTableEnd finishes the lexing of an inline table.
-// It assumes that a '}' has just been consumed.
-func lexInlineTableEnd(lx *lexer) stateFn {
- lx.ignore()
- lx.emit(itemInlineTableEnd)
- return lx.pop()
-}
-
-// lexString consumes the inner contents of a string. It assumes that the
-// beginning '"' has already been consumed and ignored.
-func lexString(lx *lexer) stateFn {
- r := lx.next()
- switch {
- case r == eof:
- return lx.errorf(`unexpected EOF; expected '"'`)
- case isNL(r):
- return lx.errorPrevLine(errLexStringNL{})
- case r == '\\':
- lx.push(lexString)
- return lexStringEscape
- case r == '"':
- lx.backup()
- if lx.esc {
- lx.esc = false
- lx.emit(itemStringEsc)
- } else {
- lx.emit(itemString)
- }
- lx.next()
- lx.ignore()
- return lx.pop()
- }
- return lexString
-}
-
-// lexMultilineString consumes the inner contents of a string. It assumes that
-// the beginning '"""' has already been consumed and ignored.
-func lexMultilineString(lx *lexer) stateFn {
- r := lx.next()
- switch r {
- default:
- return lexMultilineString
- case eof:
- return lx.errorf(`unexpected EOF; expected '"""'`)
- case '\\':
- return lexMultilineStringEscape
- case '"':
- /// Found " → try to read two more "".
- if lx.accept('"') {
- if lx.accept('"') {
- /// Peek ahead: the string can contain " and "", including at the
- /// end: """str"""""
- /// 6 or more at the end, however, is an error.
- if lx.peek() == '"' {
- /// Check if we already lexed 5 's; if so we have 6 now, and
- /// that's just too many man!
- ///
- /// Second check is for the edge case:
- ///
- /// two quotes allowed.
- /// vv
- /// """lol \""""""
- /// ^^ ^^^---- closing three
- /// escaped
- ///
- /// But ugly, but it works
- if strings.HasSuffix(lx.current(), `"""""`) && !strings.HasSuffix(lx.current(), `\"""""`) {
- return lx.errorf(`unexpected '""""""'`)
- }
- lx.backup()
- lx.backup()
- return lexMultilineString
- }
-
- lx.backup() /// backup: don't include the """ in the item.
- lx.backup()
- lx.backup()
- lx.esc = false
- lx.emit(itemMultilineString)
- lx.next() /// Read over ''' again and discard it.
- lx.next()
- lx.next()
- lx.ignore()
- return lx.pop()
- }
- lx.backup()
- }
- return lexMultilineString
- }
-}
-
-// lexRawString consumes a raw string. Nothing can be escaped in such a string.
-// It assumes that the beginning "'" has already been consumed and ignored.
-func lexRawString(lx *lexer) stateFn {
- r := lx.next()
- switch {
- default:
- return lexRawString
- case r == eof:
- return lx.errorf(`unexpected EOF; expected "'"`)
- case isNL(r):
- return lx.errorPrevLine(errLexStringNL{})
- case r == '\'':
- lx.backup()
- lx.emit(itemRawString)
- lx.next()
- lx.ignore()
- return lx.pop()
- }
-}
-
-// lexMultilineRawString consumes a raw string. Nothing can be escaped in such a
-// string. It assumes that the beginning triple-' has already been consumed and
-// ignored.
-func lexMultilineRawString(lx *lexer) stateFn {
- r := lx.next()
- switch r {
- default:
- return lexMultilineRawString
- case eof:
- return lx.errorf(`unexpected EOF; expected "'''"`)
- case '\'':
- /// Found ' → try to read two more ''.
- if lx.accept('\'') {
- if lx.accept('\'') {
- /// Peek ahead: the string can contain ' and '', including at the
- /// end: '''str'''''
- /// 6 or more at the end, however, is an error.
- if lx.peek() == '\'' {
- /// Check if we already lexed 5 's; if so we have 6 now, and
- /// that's just too many man!
- if strings.HasSuffix(lx.current(), "'''''") {
- return lx.errorf(`unexpected "''''''"`)
- }
- lx.backup()
- lx.backup()
- return lexMultilineRawString
- }
-
- lx.backup() /// backup: don't include the ''' in the item.
- lx.backup()
- lx.backup()
- lx.emit(itemRawMultilineString)
- lx.next() /// Read over ''' again and discard it.
- lx.next()
- lx.next()
- lx.ignore()
- return lx.pop()
- }
- lx.backup()
- }
- return lexMultilineRawString
- }
-}
-
-// lexMultilineStringEscape consumes an escaped character. It assumes that the
-// preceding '\\' has already been consumed.
-func lexMultilineStringEscape(lx *lexer) stateFn {
- if isNL(lx.next()) { /// \ escaping newline.
- return lexMultilineString
- }
- lx.backup()
- lx.push(lexMultilineString)
- return lexStringEscape(lx)
-}
-
-func lexStringEscape(lx *lexer) stateFn {
- lx.esc = true
- r := lx.next()
- switch r {
- case 'e':
- if !lx.tomlNext {
- return lx.error(errLexEscape{r})
- }
- fallthrough
- case 'b':
- fallthrough
- case 't':
- fallthrough
- case 'n':
- fallthrough
- case 'f':
- fallthrough
- case 'r':
- fallthrough
- case '"':
- fallthrough
- case ' ', '\t':
- // Inside """ .. """ strings you can use \ to escape newlines, and any
- // amount of whitespace can be between the \ and \n.
- fallthrough
- case '\\':
- return lx.pop()
- case 'x':
- if !lx.tomlNext {
- return lx.error(errLexEscape{r})
- }
- return lexHexEscape
- case 'u':
- return lexShortUnicodeEscape
- case 'U':
- return lexLongUnicodeEscape
- }
- return lx.error(errLexEscape{r})
-}
-
-func lexHexEscape(lx *lexer) stateFn {
- var r rune
- for i := 0; i < 2; i++ {
- r = lx.next()
- if !isHex(r) {
- return lx.errorf(`expected two hexadecimal digits after '\x', but got %q instead`, lx.current())
- }
- }
- return lx.pop()
-}
-
-func lexShortUnicodeEscape(lx *lexer) stateFn {
- var r rune
- for i := 0; i < 4; i++ {
- r = lx.next()
- if !isHex(r) {
- return lx.errorf(`expected four hexadecimal digits after '\u', but got %q instead`, lx.current())
- }
- }
- return lx.pop()
-}
-
-func lexLongUnicodeEscape(lx *lexer) stateFn {
- var r rune
- for i := 0; i < 8; i++ {
- r = lx.next()
- if !isHex(r) {
- return lx.errorf(`expected eight hexadecimal digits after '\U', but got %q instead`, lx.current())
- }
- }
- return lx.pop()
-}
-
-// lexNumberOrDateStart processes the first character of a value which begins
-// with a digit. It exists to catch values starting with '0', so that
-// lexBaseNumberOrDate can differentiate base prefixed integers from other
-// types.
-func lexNumberOrDateStart(lx *lexer) stateFn {
- r := lx.next()
- switch r {
- case '0':
- return lexBaseNumberOrDate
- }
-
- if !isDigit(r) {
- // The only way to reach this state is if the value starts
- // with a digit, so specifically treat anything else as an
- // error.
- return lx.errorf("expected a digit but got %q", r)
- }
-
- return lexNumberOrDate
-}
-
-// lexNumberOrDate consumes either an integer, float or datetime.
-func lexNumberOrDate(lx *lexer) stateFn {
- r := lx.next()
- if isDigit(r) {
- return lexNumberOrDate
- }
- switch r {
- case '-', ':':
- return lexDatetime
- case '_':
- return lexDecimalNumber
- case '.', 'e', 'E':
- return lexFloat
- }
-
- lx.backup()
- lx.emit(itemInteger)
- return lx.pop()
-}
-
-// lexDatetime consumes a Datetime, to a first approximation.
-// The parser validates that it matches one of the accepted formats.
-func lexDatetime(lx *lexer) stateFn {
- r := lx.next()
- if isDigit(r) {
- return lexDatetime
- }
- switch r {
- case '-', ':', 'T', 't', ' ', '.', 'Z', 'z', '+':
- return lexDatetime
- }
-
- lx.backup()
- lx.emitTrim(itemDatetime)
- return lx.pop()
-}
-
-// lexHexInteger consumes a hexadecimal integer after seeing the '0x' prefix.
-func lexHexInteger(lx *lexer) stateFn {
- r := lx.next()
- if isHex(r) {
- return lexHexInteger
- }
- switch r {
- case '_':
- return lexHexInteger
- }
-
- lx.backup()
- lx.emit(itemInteger)
- return lx.pop()
-}
-
-// lexOctalInteger consumes an octal integer after seeing the '0o' prefix.
-func lexOctalInteger(lx *lexer) stateFn {
- r := lx.next()
- if isOctal(r) {
- return lexOctalInteger
- }
- switch r {
- case '_':
- return lexOctalInteger
- }
-
- lx.backup()
- lx.emit(itemInteger)
- return lx.pop()
-}
-
-// lexBinaryInteger consumes a binary integer after seeing the '0b' prefix.
-func lexBinaryInteger(lx *lexer) stateFn {
- r := lx.next()
- if isBinary(r) {
- return lexBinaryInteger
- }
- switch r {
- case '_':
- return lexBinaryInteger
- }
-
- lx.backup()
- lx.emit(itemInteger)
- return lx.pop()
-}
-
-// lexDecimalNumber consumes a decimal float or integer.
-func lexDecimalNumber(lx *lexer) stateFn {
- r := lx.next()
- if isDigit(r) {
- return lexDecimalNumber
- }
- switch r {
- case '.', 'e', 'E':
- return lexFloat
- case '_':
- return lexDecimalNumber
- }
-
- lx.backup()
- lx.emit(itemInteger)
- return lx.pop()
-}
-
-// lexDecimalNumber consumes the first digit of a number beginning with a sign.
-// It assumes the sign has already been consumed. Values which start with a sign
-// are only allowed to be decimal integers or floats.
-//
-// The special "nan" and "inf" values are also recognized.
-func lexDecimalNumberStart(lx *lexer) stateFn {
- r := lx.next()
-
- // Special error cases to give users better error messages
- switch r {
- case 'i':
- if !lx.accept('n') || !lx.accept('f') {
- return lx.errorf("invalid float: '%s'", lx.current())
- }
- lx.emit(itemFloat)
- return lx.pop()
- case 'n':
- if !lx.accept('a') || !lx.accept('n') {
- return lx.errorf("invalid float: '%s'", lx.current())
- }
- lx.emit(itemFloat)
- return lx.pop()
- case '0':
- p := lx.peek()
- switch p {
- case 'b', 'o', 'x':
- return lx.errorf("cannot use sign with non-decimal numbers: '%s%c'", lx.current(), p)
- }
- case '.':
- return lx.errorf("floats must start with a digit, not '.'")
- }
-
- if isDigit(r) {
- return lexDecimalNumber
- }
-
- return lx.errorf("expected a digit but got %q", r)
-}
-
-// lexBaseNumberOrDate differentiates between the possible values which
-// start with '0'. It assumes that before reaching this state, the initial '0'
-// has been consumed.
-func lexBaseNumberOrDate(lx *lexer) stateFn {
- r := lx.next()
- // Note: All datetimes start with at least two digits, so we don't
- // handle date characters (':', '-', etc.) here.
- if isDigit(r) {
- return lexNumberOrDate
- }
- switch r {
- case '_':
- // Can only be decimal, because there can't be an underscore
- // between the '0' and the base designator, and dates can't
- // contain underscores.
- return lexDecimalNumber
- case '.', 'e', 'E':
- return lexFloat
- case 'b':
- r = lx.peek()
- if !isBinary(r) {
- lx.errorf("not a binary number: '%s%c'", lx.current(), r)
- }
- return lexBinaryInteger
- case 'o':
- r = lx.peek()
- if !isOctal(r) {
- lx.errorf("not an octal number: '%s%c'", lx.current(), r)
- }
- return lexOctalInteger
- case 'x':
- r = lx.peek()
- if !isHex(r) {
- lx.errorf("not a hexidecimal number: '%s%c'", lx.current(), r)
- }
- return lexHexInteger
- }
-
- lx.backup()
- lx.emit(itemInteger)
- return lx.pop()
-}
-
-// lexFloat consumes the elements of a float. It allows any sequence of
-// float-like characters, so floats emitted by the lexer are only a first
-// approximation and must be validated by the parser.
-func lexFloat(lx *lexer) stateFn {
- r := lx.next()
- if isDigit(r) {
- return lexFloat
- }
- switch r {
- case '_', '.', '-', '+', 'e', 'E':
- return lexFloat
- }
-
- lx.backup()
- lx.emit(itemFloat)
- return lx.pop()
-}
-
-// lexBool consumes a bool string: 'true' or 'false.
-func lexBool(lx *lexer) stateFn {
- var rs []rune
- for {
- r := lx.next()
- if !unicode.IsLetter(r) {
- lx.backup()
- break
- }
- rs = append(rs, r)
- }
- s := string(rs)
- switch s {
- case "true", "false":
- lx.emit(itemBool)
- return lx.pop()
- }
- return lx.errorf("expected value but found %q instead", s)
-}
-
-// lexCommentStart begins the lexing of a comment. It will emit
-// itemCommentStart and consume no characters, passing control to lexComment.
-func lexCommentStart(lx *lexer) stateFn {
- lx.ignore()
- lx.emit(itemCommentStart)
- return lexComment
-}
-
-// lexComment lexes an entire comment. It assumes that '#' has been consumed.
-// It will consume *up to* the first newline character, and pass control
-// back to the last state on the stack.
-func lexComment(lx *lexer) stateFn {
- switch r := lx.next(); {
- case isNL(r) || r == eof:
- lx.backup()
- lx.emit(itemText)
- return lx.pop()
- default:
- return lexComment
- }
-}
-
-// lexSkip ignores all slurped input and moves on to the next state.
-func lexSkip(lx *lexer, nextState stateFn) stateFn {
- lx.ignore()
- return nextState
-}
-
-func (s stateFn) String() string {
- name := runtime.FuncForPC(reflect.ValueOf(s).Pointer()).Name()
- if i := strings.LastIndexByte(name, '.'); i > -1 {
- name = name[i+1:]
- }
- if s == nil {
- name = "<nil>"
- }
- return name + "()"
-}
-
-func (itype itemType) String() string {
- switch itype {
- case itemError:
- return "Error"
- case itemNIL:
- return "NIL"
- case itemEOF:
- return "EOF"
- case itemText:
- return "Text"
- case itemString, itemStringEsc, itemRawString, itemMultilineString, itemRawMultilineString:
- return "String"
- case itemBool:
- return "Bool"
- case itemInteger:
- return "Integer"
- case itemFloat:
- return "Float"
- case itemDatetime:
- return "DateTime"
- case itemTableStart:
- return "TableStart"
- case itemTableEnd:
- return "TableEnd"
- case itemKeyStart:
- return "KeyStart"
- case itemKeyEnd:
- return "KeyEnd"
- case itemArray:
- return "Array"
- case itemArrayEnd:
- return "ArrayEnd"
- case itemCommentStart:
- return "CommentStart"
- case itemInlineTableStart:
- return "InlineTableStart"
- case itemInlineTableEnd:
- return "InlineTableEnd"
- }
- panic(fmt.Sprintf("BUG: Unknown type '%d'.", int(itype)))
-}
-
-func (item item) String() string {
- return fmt.Sprintf("(%s, %s)", item.typ, item.val)
-}
-
-func isWhitespace(r rune) bool { return r == '\t' || r == ' ' }
-func isNL(r rune) bool { return r == '\n' || r == '\r' }
-func isControl(r rune) bool { // Control characters except \t, \r, \n
- switch r {
- case '\t', '\r', '\n':
- return false
- default:
- return (r >= 0x00 && r <= 0x1f) || r == 0x7f
- }
-}
-func isDigit(r rune) bool { return r >= '0' && r <= '9' }
-func isBinary(r rune) bool { return r == '0' || r == '1' }
-func isOctal(r rune) bool { return r >= '0' && r <= '7' }
-func isHex(r rune) bool { return (r >= '0' && r <= '9') || (r|0x20 >= 'a' && r|0x20 <= 'f') }
-func isBareKeyChar(r rune, tomlNext bool) bool {
- if tomlNext {
- return (r >= 'A' && r <= 'Z') ||
- (r >= 'a' && r <= 'z') ||
- (r >= '0' && r <= '9') ||
- r == '_' || r == '-' ||
- r == 0xb2 || r == 0xb3 || r == 0xb9 || (r >= 0xbc && r <= 0xbe) ||
- (r >= 0xc0 && r <= 0xd6) || (r >= 0xd8 && r <= 0xf6) || (r >= 0xf8 && r <= 0x037d) ||
- (r >= 0x037f && r <= 0x1fff) ||
- (r >= 0x200c && r <= 0x200d) || (r >= 0x203f && r <= 0x2040) ||
- (r >= 0x2070 && r <= 0x218f) || (r >= 0x2460 && r <= 0x24ff) ||
- (r >= 0x2c00 && r <= 0x2fef) || (r >= 0x3001 && r <= 0xd7ff) ||
- (r >= 0xf900 && r <= 0xfdcf) || (r >= 0xfdf0 && r <= 0xfffd) ||
- (r >= 0x10000 && r <= 0xeffff)
- }
-
- return (r >= 'A' && r <= 'Z') ||
- (r >= 'a' && r <= 'z') ||
- (r >= '0' && r <= '9') ||
- r == '_' || r == '-'
-}
diff --git a/vendor/github.com/BurntSushi/toml/meta.go b/vendor/github.com/BurntSushi/toml/meta.go
deleted file mode 100644
index e61453730..000000000
--- a/vendor/github.com/BurntSushi/toml/meta.go
+++ /dev/null
@@ -1,148 +0,0 @@
-package toml
-
-import (
- "strings"
-)
-
-// MetaData allows access to meta information about TOML data that's not
-// accessible otherwise.
-//
-// It allows checking if a key is defined in the TOML data, whether any keys
-// were undecoded, and the TOML type of a key.
-type MetaData struct {
- context Key // Used only during decoding.
-
- keyInfo map[string]keyInfo
- mapping map[string]any
- keys []Key
- decoded map[string]struct{}
- data []byte // Input file; for errors.
-}
-
-// IsDefined reports if the key exists in the TOML data.
-//
-// The key should be specified hierarchically, for example to access the TOML
-// key "a.b.c" you would use IsDefined("a", "b", "c"). Keys are case sensitive.
-//
-// Returns false for an empty key.
-func (md *MetaData) IsDefined(key ...string) bool {
- if len(key) == 0 {
- return false
- }
-
- var (
- hash map[string]any
- ok bool
- hashOrVal any = md.mapping
- )
- for _, k := range key {
- if hash, ok = hashOrVal.(map[string]any); !ok {
- return false
- }
- if hashOrVal, ok = hash[k]; !ok {
- return false
- }
- }
- return true
-}
-
-// Type returns a string representation of the type of the key specified.
-//
-// Type will return the empty string if given an empty key or a key that does
-// not exist. Keys are case sensitive.
-func (md *MetaData) Type(key ...string) string {
- if ki, ok := md.keyInfo[Key(key).String()]; ok {
- return ki.tomlType.typeString()
- }
- return ""
-}
-
-// Keys returns a slice of every key in the TOML data, including key groups.
-//
-// Each key is itself a slice, where the first element is the top of the
-// hierarchy and the last is the most specific. The list will have the same
-// order as the keys appeared in the TOML data.
-//
-// All keys returned are non-empty.
-func (md *MetaData) Keys() []Key {
- return md.keys
-}
-
-// Undecoded returns all keys that have not been decoded in the order in which
-// they appear in the original TOML document.
-//
-// This includes keys that haven't been decoded because of a [Primitive] value.
-// Once the Primitive value is decoded, the keys will be considered decoded.
-//
-// Also note that decoding into an empty interface will result in no decoding,
-// and so no keys will be considered decoded.
-//
-// In this sense, the Undecoded keys correspond to keys in the TOML document
-// that do not have a concrete type in your representation.
-func (md *MetaData) Undecoded() []Key {
- undecoded := make([]Key, 0, len(md.keys))
- for _, key := range md.keys {
- if _, ok := md.decoded[key.String()]; !ok {
- undecoded = append(undecoded, key)
- }
- }
- return undecoded
-}
-
-// Key represents any TOML key, including key groups. Use [MetaData.Keys] to get
-// values of this type.
-type Key []string
-
-func (k Key) String() string {
- // This is called quite often, so it's a bit funky to make it faster.
- var b strings.Builder
- b.Grow(len(k) * 25)
-outer:
- for i, kk := range k {
- if i > 0 {
- b.WriteByte('.')
- }
- if kk == "" {
- b.WriteString(`""`)
- } else {
- for _, r := range kk {
- // "Inline" isBareKeyChar
- if !((r >= 'A' && r <= 'Z') || (r >= 'a' && r <= 'z') || (r >= '0' && r <= '9') || r == '_' || r == '-') {
- b.WriteByte('"')
- b.WriteString(dblQuotedReplacer.Replace(kk))
- b.WriteByte('"')
- continue outer
- }
- }
- b.WriteString(kk)
- }
- }
- return b.String()
-}
-
-func (k Key) maybeQuoted(i int) string {
- if k[i] == "" {
- return `""`
- }
- for _, r := range k[i] {
- if (r >= 'A' && r <= 'Z') || (r >= 'a' && r <= 'z') || (r >= '0' && r <= '9') || r == '_' || r == '-' {
- continue
- }
- return `"` + dblQuotedReplacer.Replace(k[i]) + `"`
- }
- return k[i]
-}
-
-// Like append(), but only increase the cap by 1.
-func (k Key) add(piece string) Key {
- if cap(k) > len(k) {
- return append(k, piece)
- }
- newKey := make(Key, len(k)+1)
- copy(newKey, k)
- newKey[len(k)] = piece
- return newKey
-}
-
-func (k Key) parent() Key { return k[:len(k)-1] } // all except the last piece.
-func (k Key) last() string { return k[len(k)-1] } // last piece of this key.
diff --git a/vendor/github.com/BurntSushi/toml/parse.go b/vendor/github.com/BurntSushi/toml/parse.go
deleted file mode 100644
index 3f2c090c8..000000000
--- a/vendor/github.com/BurntSushi/toml/parse.go
+++ /dev/null
@@ -1,846 +0,0 @@
-package toml
-
-import (
- "fmt"
- "math"
- "os"
- "strconv"
- "strings"
- "time"
- "unicode/utf8"
-
- "github.com/BurntSushi/toml/internal"
-)
-
-type parser struct {
- lx *lexer
- context Key // Full key for the current hash in scope.
- currentKey string // Base key name for everything except hashes.
- pos Position // Current position in the TOML file.
- tomlNext bool
-
- ordered []Key // List of keys in the order that they appear in the TOML data.
-
- keyInfo map[string]keyInfo // Map keyname → info about the TOML key.
- mapping map[string]any // Map keyname → key value.
- implicits map[string]struct{} // Record implicit keys (e.g. "key.group.names").
-}
-
-type keyInfo struct {
- pos Position
- tomlType tomlType
-}
-
-func parse(data string) (p *parser, err error) {
- _, tomlNext := os.LookupEnv("BURNTSUSHI_TOML_110")
-
- defer func() {
- if r := recover(); r != nil {
- if pErr, ok := r.(ParseError); ok {
- pErr.input = data
- err = pErr
- return
- }
- panic(r)
- }
- }()
-
- // Read over BOM; do this here as the lexer calls utf8.DecodeRuneInString()
- // which mangles stuff. UTF-16 BOM isn't strictly valid, but some tools add
- // it anyway.
- if strings.HasPrefix(data, "\xff\xfe") || strings.HasPrefix(data, "\xfe\xff") { // UTF-16
- data = data[2:]
- //lint:ignore S1017 https://github.com/dominikh/go-tools/issues/1447
- } else if strings.HasPrefix(data, "\xef\xbb\xbf") { // UTF-8
- data = data[3:]
- }
-
- // Examine first few bytes for NULL bytes; this probably means it's a UTF-16
- // file (second byte in surrogate pair being NULL). Again, do this here to
- // avoid having to deal with UTF-8/16 stuff in the lexer.
- ex := 6
- if len(data) < 6 {
- ex = len(data)
- }
- if i := strings.IndexRune(data[:ex], 0); i > -1 {
- return nil, ParseError{
- Message: "files cannot contain NULL bytes; probably using UTF-16; TOML files must be UTF-8",
- Position: Position{Line: 1, Col: 1, Start: i, Len: 1},
- Line: 1,
- input: data,
- }
- }
-
- p = &parser{
- keyInfo: make(map[string]keyInfo),
- mapping: make(map[string]any),
- lx: lex(data, tomlNext),
- ordered: make([]Key, 0),
- implicits: make(map[string]struct{}),
- tomlNext: tomlNext,
- }
- for {
- item := p.next()
- if item.typ == itemEOF {
- break
- }
- p.topLevel(item)
- }
-
- return p, nil
-}
-
-func (p *parser) panicErr(it item, err error) {
- panic(ParseError{
- Message: err.Error(),
- err: err,
- Position: it.pos.withCol(p.lx.input),
- Line: it.pos.Len,
- LastKey: p.current(),
- })
-}
-
-func (p *parser) panicItemf(it item, format string, v ...any) {
- panic(ParseError{
- Message: fmt.Sprintf(format, v...),
- Position: it.pos.withCol(p.lx.input),
- Line: it.pos.Len,
- LastKey: p.current(),
- })
-}
-
-func (p *parser) panicf(format string, v ...any) {
- panic(ParseError{
- Message: fmt.Sprintf(format, v...),
- Position: p.pos.withCol(p.lx.input),
- Line: p.pos.Line,
- LastKey: p.current(),
- })
-}
-
-func (p *parser) next() item {
- it := p.lx.nextItem()
- //fmt.Printf("ITEM %-18s line %-3d │ %q\n", it.typ, it.pos.Line, it.val)
- if it.typ == itemError {
- if it.err != nil {
- panic(ParseError{
- Message: it.err.Error(),
- err: it.err,
- Position: it.pos.withCol(p.lx.input),
- Line: it.pos.Line,
- LastKey: p.current(),
- })
- }
-
- p.panicItemf(it, "%s", it.val)
- }
- return it
-}
-
-func (p *parser) nextPos() item {
- it := p.next()
- p.pos = it.pos
- return it
-}
-
-func (p *parser) bug(format string, v ...any) {
- panic(fmt.Sprintf("BUG: "+format+"\n\n", v...))
-}
-
-func (p *parser) expect(typ itemType) item {
- it := p.next()
- p.assertEqual(typ, it.typ)
- return it
-}
-
-func (p *parser) assertEqual(expected, got itemType) {
- if expected != got {
- p.bug("Expected '%s' but got '%s'.", expected, got)
- }
-}
-
-func (p *parser) topLevel(item item) {
- switch item.typ {
- case itemCommentStart: // # ..
- p.expect(itemText)
- case itemTableStart: // [ .. ]
- name := p.nextPos()
-
- var key Key
- for ; name.typ != itemTableEnd && name.typ != itemEOF; name = p.next() {
- key = append(key, p.keyString(name))
- }
- p.assertEqual(itemTableEnd, name.typ)
-
- p.addContext(key, false)
- p.setType("", tomlHash, item.pos)
- p.ordered = append(p.ordered, key)
- case itemArrayTableStart: // [[ .. ]]
- name := p.nextPos()
-
- var key Key
- for ; name.typ != itemArrayTableEnd && name.typ != itemEOF; name = p.next() {
- key = append(key, p.keyString(name))
- }
- p.assertEqual(itemArrayTableEnd, name.typ)
-
- p.addContext(key, true)
- p.setType("", tomlArrayHash, item.pos)
- p.ordered = append(p.ordered, key)
- case itemKeyStart: // key = ..
- outerContext := p.context
- /// Read all the key parts (e.g. 'a' and 'b' in 'a.b')
- k := p.nextPos()
- var key Key
- for ; k.typ != itemKeyEnd && k.typ != itemEOF; k = p.next() {
- key = append(key, p.keyString(k))
- }
- p.assertEqual(itemKeyEnd, k.typ)
-
- /// The current key is the last part.
- p.currentKey = key.last()
-
- /// All the other parts (if any) are the context; need to set each part
- /// as implicit.
- context := key.parent()
- for i := range context {
- p.addImplicitContext(append(p.context, context[i:i+1]...))
- }
- p.ordered = append(p.ordered, p.context.add(p.currentKey))
-
- /// Set value.
- vItem := p.next()
- val, typ := p.value(vItem, false)
- p.setValue(p.currentKey, val)
- p.setType(p.currentKey, typ, vItem.pos)
-
- /// Remove the context we added (preserving any context from [tbl] lines).
- p.context = outerContext
- p.currentKey = ""
- default:
- p.bug("Unexpected type at top level: %s", item.typ)
- }
-}
-
-// Gets a string for a key (or part of a key in a table name).
-func (p *parser) keyString(it item) string {
- switch it.typ {
- case itemText:
- return it.val
- case itemString, itemStringEsc, itemMultilineString,
- itemRawString, itemRawMultilineString:
- s, _ := p.value(it, false)
- return s.(string)
- default:
- p.bug("Unexpected key type: %s", it.typ)
- }
- panic("unreachable")
-}
-
-var datetimeRepl = strings.NewReplacer(
- "z", "Z",
- "t", "T",
- " ", "T")
-
-// value translates an expected value from the lexer into a Go value wrapped
-// as an empty interface.
-func (p *parser) value(it item, parentIsArray bool) (any, tomlType) {
- switch it.typ {
- case itemString:
- return it.val, p.typeOfPrimitive(it)
- case itemStringEsc:
- return p.replaceEscapes(it, it.val), p.typeOfPrimitive(it)
- case itemMultilineString:
- return p.replaceEscapes(it, p.stripEscapedNewlines(stripFirstNewline(it.val))), p.typeOfPrimitive(it)
- case itemRawString:
- return it.val, p.typeOfPrimitive(it)
- case itemRawMultilineString:
- return stripFirstNewline(it.val), p.typeOfPrimitive(it)
- case itemInteger:
- return p.valueInteger(it)
- case itemFloat:
- return p.valueFloat(it)
- case itemBool:
- switch it.val {
- case "true":
- return true, p.typeOfPrimitive(it)
- case "false":
- return false, p.typeOfPrimitive(it)
- default:
- p.bug("Expected boolean value, but got '%s'.", it.val)
- }
- case itemDatetime:
- return p.valueDatetime(it)
- case itemArray:
- return p.valueArray(it)
- case itemInlineTableStart:
- return p.valueInlineTable(it, parentIsArray)
- default:
- p.bug("Unexpected value type: %s", it.typ)
- }
- panic("unreachable")
-}
-
-func (p *parser) valueInteger(it item) (any, tomlType) {
- if !numUnderscoresOK(it.val) {
- p.panicItemf(it, "Invalid integer %q: underscores must be surrounded by digits", it.val)
- }
- if numHasLeadingZero(it.val) {
- p.panicItemf(it, "Invalid integer %q: cannot have leading zeroes", it.val)
- }
-
- num, err := strconv.ParseInt(it.val, 0, 64)
- if err != nil {
- // Distinguish integer values. Normally, it'd be a bug if the lexer
- // provides an invalid integer, but it's possible that the number is
- // out of range of valid values (which the lexer cannot determine).
- // So mark the former as a bug but the latter as a legitimate user
- // error.
- if e, ok := err.(*strconv.NumError); ok && e.Err == strconv.ErrRange {
- p.panicErr(it, errParseRange{i: it.val, size: "int64"})
- } else {
- p.bug("Expected integer value, but got '%s'.", it.val)
- }
- }
- return num, p.typeOfPrimitive(it)
-}
-
-func (p *parser) valueFloat(it item) (any, tomlType) {
- parts := strings.FieldsFunc(it.val, func(r rune) bool {
- switch r {
- case '.', 'e', 'E':
- return true
- }
- return false
- })
- for _, part := range parts {
- if !numUnderscoresOK(part) {
- p.panicItemf(it, "Invalid float %q: underscores must be surrounded by digits", it.val)
- }
- }
- if len(parts) > 0 && numHasLeadingZero(parts[0]) {
- p.panicItemf(it, "Invalid float %q: cannot have leading zeroes", it.val)
- }
- if !numPeriodsOK(it.val) {
- // As a special case, numbers like '123.' or '1.e2',
- // which are valid as far as Go/strconv are concerned,
- // must be rejected because TOML says that a fractional
- // part consists of '.' followed by 1+ digits.
- p.panicItemf(it, "Invalid float %q: '.' must be followed by one or more digits", it.val)
- }
- val := strings.Replace(it.val, "_", "", -1)
- signbit := false
- if val == "+nan" || val == "-nan" {
- signbit = val == "-nan"
- val = "nan"
- }
- num, err := strconv.ParseFloat(val, 64)
- if err != nil {
- if e, ok := err.(*strconv.NumError); ok && e.Err == strconv.ErrRange {
- p.panicErr(it, errParseRange{i: it.val, size: "float64"})
- } else {
- p.panicItemf(it, "Invalid float value: %q", it.val)
- }
- }
- if signbit {
- num = math.Copysign(num, -1)
- }
- return num, p.typeOfPrimitive(it)
-}
-
-var dtTypes = []struct {
- fmt string
- zone *time.Location
- next bool
-}{
- {time.RFC3339Nano, time.Local, false},
- {"2006-01-02T15:04:05.999999999", internal.LocalDatetime, false},
- {"2006-01-02", internal.LocalDate, false},
- {"15:04:05.999999999", internal.LocalTime, false},
-
- // tomlNext
- {"2006-01-02T15:04Z07:00", time.Local, true},
- {"2006-01-02T15:04", internal.LocalDatetime, true},
- {"15:04", internal.LocalTime, true},
-}
-
-func (p *parser) valueDatetime(it item) (any, tomlType) {
- it.val = datetimeRepl.Replace(it.val)
- var (
- t time.Time
- ok bool
- err error
- )
- for _, dt := range dtTypes {
- if dt.next && !p.tomlNext {
- continue
- }
- t, err = time.ParseInLocation(dt.fmt, it.val, dt.zone)
- if err == nil {
- if missingLeadingZero(it.val, dt.fmt) {
- p.panicErr(it, errParseDate{it.val})
- }
- ok = true
- break
- }
- }
- if !ok {
- p.panicErr(it, errParseDate{it.val})
- }
- return t, p.typeOfPrimitive(it)
-}
-
-// Go's time.Parse() will accept numbers without a leading zero; there isn't any
-// way to require it. https://github.com/golang/go/issues/29911
-//
-// Depend on the fact that the separators (- and :) should always be at the same
-// location.
-func missingLeadingZero(d, l string) bool {
- for i, c := range []byte(l) {
- if c == '.' || c == 'Z' {
- return false
- }
- if (c < '0' || c > '9') && d[i] != c {
- return true
- }
- }
- return false
-}
-
-func (p *parser) valueArray(it item) (any, tomlType) {
- p.setType(p.currentKey, tomlArray, it.pos)
-
- var (
- // Initialize to a non-nil slice to make it consistent with how S = []
- // decodes into a non-nil slice inside something like struct { S
- // []string }. See #338
- array = make([]any, 0, 2)
- )
- for it = p.next(); it.typ != itemArrayEnd; it = p.next() {
- if it.typ == itemCommentStart {
- p.expect(itemText)
- continue
- }
-
- val, typ := p.value(it, true)
- array = append(array, val)
-
- // XXX: type isn't used here, we need it to record the accurate type
- // information.
- //
- // Not entirely sure how to best store this; could use "key[0]",
- // "key[1]" notation, or maybe store it on the Array type?
- _ = typ
- }
- return array, tomlArray
-}
-
-func (p *parser) valueInlineTable(it item, parentIsArray bool) (any, tomlType) {
- var (
- topHash = make(map[string]any)
- outerContext = p.context
- outerKey = p.currentKey
- )
-
- p.context = append(p.context, p.currentKey)
- prevContext := p.context
- p.currentKey = ""
-
- p.addImplicit(p.context)
- p.addContext(p.context, parentIsArray)
-
- /// Loop over all table key/value pairs.
- for it := p.next(); it.typ != itemInlineTableEnd; it = p.next() {
- if it.typ == itemCommentStart {
- p.expect(itemText)
- continue
- }
-
- /// Read all key parts.
- k := p.nextPos()
- var key Key
- for ; k.typ != itemKeyEnd && k.typ != itemEOF; k = p.next() {
- key = append(key, p.keyString(k))
- }
- p.assertEqual(itemKeyEnd, k.typ)
-
- /// The current key is the last part.
- p.currentKey = key.last()
-
- /// All the other parts (if any) are the context; need to set each part
- /// as implicit.
- context := key.parent()
- for i := range context {
- p.addImplicitContext(append(p.context, context[i:i+1]...))
- }
- p.ordered = append(p.ordered, p.context.add(p.currentKey))
-
- /// Set the value.
- val, typ := p.value(p.next(), false)
- p.setValue(p.currentKey, val)
- p.setType(p.currentKey, typ, it.pos)
-
- hash := topHash
- for _, c := range context {
- h, ok := hash[c]
- if !ok {
- h = make(map[string]any)
- hash[c] = h
- }
- hash, ok = h.(map[string]any)
- if !ok {
- p.panicf("%q is not a table", p.context)
- }
- }
- hash[p.currentKey] = val
-
- /// Restore context.
- p.context = prevContext
- }
- p.context = outerContext
- p.currentKey = outerKey
- return topHash, tomlHash
-}
-
-// numHasLeadingZero checks if this number has leading zeroes, allowing for '0',
-// +/- signs, and base prefixes.
-func numHasLeadingZero(s string) bool {
- if len(s) > 1 && s[0] == '0' && !(s[1] == 'b' || s[1] == 'o' || s[1] == 'x') { // Allow 0b, 0o, 0x
- return true
- }
- if len(s) > 2 && (s[0] == '-' || s[0] == '+') && s[1] == '0' {
- return true
- }
- return false
-}
-
-// numUnderscoresOK checks whether each underscore in s is surrounded by
-// characters that are not underscores.
-func numUnderscoresOK(s string) bool {
- switch s {
- case "nan", "+nan", "-nan", "inf", "-inf", "+inf":
- return true
- }
- accept := false
- for _, r := range s {
- if r == '_' {
- if !accept {
- return false
- }
- }
-
- // isHexis a superset of all the permissable characters surrounding an
- // underscore.
- accept = isHex(r)
- }
- return accept
-}
-
-// numPeriodsOK checks whether every period in s is followed by a digit.
-func numPeriodsOK(s string) bool {
- period := false
- for _, r := range s {
- if period && !isDigit(r) {
- return false
- }
- period = r == '.'
- }
- return !period
-}
-
-// Set the current context of the parser, where the context is either a hash or
-// an array of hashes, depending on the value of the `array` parameter.
-//
-// Establishing the context also makes sure that the key isn't a duplicate, and
-// will create implicit hashes automatically.
-func (p *parser) addContext(key Key, array bool) {
- /// Always start at the top level and drill down for our context.
- hashContext := p.mapping
- keyContext := make(Key, 0, len(key)-1)
-
- /// We only need implicit hashes for the parents.
- for _, k := range key.parent() {
- _, ok := hashContext[k]
- keyContext = append(keyContext, k)
-
- // No key? Make an implicit hash and move on.
- if !ok {
- p.addImplicit(keyContext)
- hashContext[k] = make(map[string]any)
- }
-
- // If the hash context is actually an array of tables, then set
- // the hash context to the last element in that array.
- //
- // Otherwise, it better be a table, since this MUST be a key group (by
- // virtue of it not being the last element in a key).
- switch t := hashContext[k].(type) {
- case []map[string]any:
- hashContext = t[len(t)-1]
- case map[string]any:
- hashContext = t
- default:
- p.panicf("Key '%s' was already created as a hash.", keyContext)
- }
- }
-
- p.context = keyContext
- if array {
- // If this is the first element for this array, then allocate a new
- // list of tables for it.
- k := key.last()
- if _, ok := hashContext[k]; !ok {
- hashContext[k] = make([]map[string]any, 0, 4)
- }
-
- // Add a new table. But make sure the key hasn't already been used
- // for something else.
- if hash, ok := hashContext[k].([]map[string]any); ok {
- hashContext[k] = append(hash, make(map[string]any))
- } else {
- p.panicf("Key '%s' was already created and cannot be used as an array.", key)
- }
- } else {
- p.setValue(key.last(), make(map[string]any))
- }
- p.context = append(p.context, key.last())
-}
-
-// setValue sets the given key to the given value in the current context.
-// It will make sure that the key hasn't already been defined, account for
-// implicit key groups.
-func (p *parser) setValue(key string, value any) {
- var (
- tmpHash any
- ok bool
- hash = p.mapping
- keyContext = make(Key, 0, len(p.context)+1)
- )
- for _, k := range p.context {
- keyContext = append(keyContext, k)
- if tmpHash, ok = hash[k]; !ok {
- p.bug("Context for key '%s' has not been established.", keyContext)
- }
- switch t := tmpHash.(type) {
- case []map[string]any:
- // The context is a table of hashes. Pick the most recent table
- // defined as the current hash.
- hash = t[len(t)-1]
- case map[string]any:
- hash = t
- default:
- p.panicf("Key '%s' has already been defined.", keyContext)
- }
- }
- keyContext = append(keyContext, key)
-
- if _, ok := hash[key]; ok {
- // Normally redefining keys isn't allowed, but the key could have been
- // defined implicitly and it's allowed to be redefined concretely. (See
- // the `valid/implicit-and-explicit-after.toml` in toml-test)
- //
- // But we have to make sure to stop marking it as an implicit. (So that
- // another redefinition provokes an error.)
- //
- // Note that since it has already been defined (as a hash), we don't
- // want to overwrite it. So our business is done.
- if p.isArray(keyContext) {
- p.removeImplicit(keyContext)
- hash[key] = value
- return
- }
- if p.isImplicit(keyContext) {
- p.removeImplicit(keyContext)
- return
- }
- // Otherwise, we have a concrete key trying to override a previous key,
- // which is *always* wrong.
- p.panicf("Key '%s' has already been defined.", keyContext)
- }
-
- hash[key] = value
-}
-
-// setType sets the type of a particular value at a given key. It should be
-// called immediately AFTER setValue.
-//
-// Note that if `key` is empty, then the type given will be applied to the
-// current context (which is either a table or an array of tables).
-func (p *parser) setType(key string, typ tomlType, pos Position) {
- keyContext := make(Key, 0, len(p.context)+1)
- keyContext = append(keyContext, p.context...)
- if len(key) > 0 { // allow type setting for hashes
- keyContext = append(keyContext, key)
- }
- // Special case to make empty keys ("" = 1) work.
- // Without it it will set "" rather than `""`.
- // TODO: why is this needed? And why is this only needed here?
- if len(keyContext) == 0 {
- keyContext = Key{""}
- }
- p.keyInfo[keyContext.String()] = keyInfo{tomlType: typ, pos: pos}
-}
-
-// Implicit keys need to be created when tables are implied in "a.b.c.d = 1" and
-// "[a.b.c]" (the "a", "b", and "c" hashes are never created explicitly).
-func (p *parser) addImplicit(key Key) { p.implicits[key.String()] = struct{}{} }
-func (p *parser) removeImplicit(key Key) { delete(p.implicits, key.String()) }
-func (p *parser) isImplicit(key Key) bool { _, ok := p.implicits[key.String()]; return ok }
-func (p *parser) isArray(key Key) bool { return p.keyInfo[key.String()].tomlType == tomlArray }
-func (p *parser) addImplicitContext(key Key) { p.addImplicit(key); p.addContext(key, false) }
-
-// current returns the full key name of the current context.
-func (p *parser) current() string {
- if len(p.currentKey) == 0 {
- return p.context.String()
- }
- if len(p.context) == 0 {
- return p.currentKey
- }
- return fmt.Sprintf("%s.%s", p.context, p.currentKey)
-}
-
-func stripFirstNewline(s string) string {
- if len(s) > 0 && s[0] == '\n' {
- return s[1:]
- }
- if len(s) > 1 && s[0] == '\r' && s[1] == '\n' {
- return s[2:]
- }
- return s
-}
-
-// stripEscapedNewlines removes whitespace after line-ending backslashes in
-// multiline strings.
-//
-// A line-ending backslash is an unescaped \ followed only by whitespace until
-// the next newline. After a line-ending backslash, all whitespace is removed
-// until the next non-whitespace character.
-func (p *parser) stripEscapedNewlines(s string) string {
- var (
- b strings.Builder
- i int
- )
- b.Grow(len(s))
- for {
- ix := strings.Index(s[i:], `\`)
- if ix < 0 {
- b.WriteString(s)
- return b.String()
- }
- i += ix
-
- if len(s) > i+1 && s[i+1] == '\\' {
- // Escaped backslash.
- i += 2
- continue
- }
- // Scan until the next non-whitespace.
- j := i + 1
- whitespaceLoop:
- for ; j < len(s); j++ {
- switch s[j] {
- case ' ', '\t', '\r', '\n':
- default:
- break whitespaceLoop
- }
- }
- if j == i+1 {
- // Not a whitespace escape.
- i++
- continue
- }
- if !strings.Contains(s[i:j], "\n") {
- // This is not a line-ending backslash. (It's a bad escape sequence,
- // but we can let replaceEscapes catch it.)
- i++
- continue
- }
- b.WriteString(s[:i])
- s = s[j:]
- i = 0
- }
-}
-
-func (p *parser) replaceEscapes(it item, str string) string {
- var (
- b strings.Builder
- skip = 0
- )
- b.Grow(len(str))
- for i, c := range str {
- if skip > 0 {
- skip--
- continue
- }
- if c != '\\' {
- b.WriteRune(c)
- continue
- }
-
- if i >= len(str) {
- p.bug("Escape sequence at end of string.")
- return ""
- }
- switch str[i+1] {
- default:
- p.bug("Expected valid escape code after \\, but got %q.", str[i+1])
- case ' ', '\t':
- p.panicItemf(it, "invalid escape: '\\%c'", str[i+1])
- case 'b':
- b.WriteByte(0x08)
- skip = 1
- case 't':
- b.WriteByte(0x09)
- skip = 1
- case 'n':
- b.WriteByte(0x0a)
- skip = 1
- case 'f':
- b.WriteByte(0x0c)
- skip = 1
- case 'r':
- b.WriteByte(0x0d)
- skip = 1
- case 'e':
- if p.tomlNext {
- b.WriteByte(0x1b)
- skip = 1
- }
- case '"':
- b.WriteByte(0x22)
- skip = 1
- case '\\':
- b.WriteByte(0x5c)
- skip = 1
- // The lexer guarantees the correct number of characters are present;
- // don't need to check here.
- case 'x':
- if p.tomlNext {
- escaped := p.asciiEscapeToUnicode(it, str[i+2:i+4])
- b.WriteRune(escaped)
- skip = 3
- }
- case 'u':
- escaped := p.asciiEscapeToUnicode(it, str[i+2:i+6])
- b.WriteRune(escaped)
- skip = 5
- case 'U':
- escaped := p.asciiEscapeToUnicode(it, str[i+2:i+10])
- b.WriteRune(escaped)
- skip = 9
- }
- }
- return b.String()
-}
-
-func (p *parser) asciiEscapeToUnicode(it item, s string) rune {
- hex, err := strconv.ParseUint(strings.ToLower(s), 16, 32)
- if err != nil {
- p.bug("Could not parse '%s' as a hexadecimal number, but the lexer claims it's OK: %s", s, err)
- }
- if !utf8.ValidRune(rune(hex)) {
- p.panicItemf(it, "Escaped character '\\u%s' is not valid UTF-8.", s)
- }
- return rune(hex)
-}
diff --git a/vendor/github.com/BurntSushi/toml/type_fields.go b/vendor/github.com/BurntSushi/toml/type_fields.go
deleted file mode 100644
index 10c51f7ee..000000000
--- a/vendor/github.com/BurntSushi/toml/type_fields.go
+++ /dev/null
@@ -1,238 +0,0 @@
-package toml
-
-// Struct field handling is adapted from code in encoding/json:
-//
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the Go distribution.
-
-import (
- "reflect"
- "sort"
- "sync"
-)
-
-// A field represents a single field found in a struct.
-type field struct {
- name string // the name of the field (`toml` tag included)
- tag bool // whether field has a `toml` tag
- index []int // represents the depth of an anonymous field
- typ reflect.Type // the type of the field
-}
-
-// byName sorts field by name, breaking ties with depth,
-// then breaking ties with "name came from toml tag", then
-// breaking ties with index sequence.
-type byName []field
-
-func (x byName) Len() int { return len(x) }
-func (x byName) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
-func (x byName) Less(i, j int) bool {
- if x[i].name != x[j].name {
- return x[i].name < x[j].name
- }
- if len(x[i].index) != len(x[j].index) {
- return len(x[i].index) < len(x[j].index)
- }
- if x[i].tag != x[j].tag {
- return x[i].tag
- }
- return byIndex(x).Less(i, j)
-}
-
-// byIndex sorts field by index sequence.
-type byIndex []field
-
-func (x byIndex) Len() int { return len(x) }
-func (x byIndex) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
-func (x byIndex) Less(i, j int) bool {
- for k, xik := range x[i].index {
- if k >= len(x[j].index) {
- return false
- }
- if xik != x[j].index[k] {
- return xik < x[j].index[k]
- }
- }
- return len(x[i].index) < len(x[j].index)
-}
-
-// typeFields returns a list of fields that TOML should recognize for the given
-// type. The algorithm is breadth-first search over the set of structs to
-// include - the top struct and then any reachable anonymous structs.
-func typeFields(t reflect.Type) []field {
- // Anonymous fields to explore at the current level and the next.
- current := []field{}
- next := []field{{typ: t}}
-
- // Count of queued names for current level and the next.
- var count map[reflect.Type]int
- var nextCount map[reflect.Type]int
-
- // Types already visited at an earlier level.
- visited := map[reflect.Type]bool{}
-
- // Fields found.
- var fields []field
-
- for len(next) > 0 {
- current, next = next, current[:0]
- count, nextCount = nextCount, map[reflect.Type]int{}
-
- for _, f := range current {
- if visited[f.typ] {
- continue
- }
- visited[f.typ] = true
-
- // Scan f.typ for fields to include.
- for i := 0; i < f.typ.NumField(); i++ {
- sf := f.typ.Field(i)
- if sf.PkgPath != "" && !sf.Anonymous { // unexported
- continue
- }
- opts := getOptions(sf.Tag)
- if opts.skip {
- continue
- }
- index := make([]int, len(f.index)+1)
- copy(index, f.index)
- index[len(f.index)] = i
-
- ft := sf.Type
- if ft.Name() == "" && ft.Kind() == reflect.Ptr {
- // Follow pointer.
- ft = ft.Elem()
- }
-
- // Record found field and index sequence.
- if opts.name != "" || !sf.Anonymous || ft.Kind() != reflect.Struct {
- tagged := opts.name != ""
- name := opts.name
- if name == "" {
- name = sf.Name
- }
- fields = append(fields, field{name, tagged, index, ft})
- if count[f.typ] > 1 {
- // If there were multiple instances, add a second,
- // so that the annihilation code will see a duplicate.
- // It only cares about the distinction between 1 or 2,
- // so don't bother generating any more copies.
- fields = append(fields, fields[len(fields)-1])
- }
- continue
- }
-
- // Record new anonymous struct to explore in next round.
- nextCount[ft]++
- if nextCount[ft] == 1 {
- f := field{name: ft.Name(), index: index, typ: ft}
- next = append(next, f)
- }
- }
- }
- }
-
- sort.Sort(byName(fields))
-
- // Delete all fields that are hidden by the Go rules for embedded fields,
- // except that fields with TOML tags are promoted.
-
- // The fields are sorted in primary order of name, secondary order
- // of field index length. Loop over names; for each name, delete
- // hidden fields by choosing the one dominant field that survives.
- out := fields[:0]
- for advance, i := 0, 0; i < len(fields); i += advance {
- // One iteration per name.
- // Find the sequence of fields with the name of this first field.
- fi := fields[i]
- name := fi.name
- for advance = 1; i+advance < len(fields); advance++ {
- fj := fields[i+advance]
- if fj.name != name {
- break
- }
- }
- if advance == 1 { // Only one field with this name
- out = append(out, fi)
- continue
- }
- dominant, ok := dominantField(fields[i : i+advance])
- if ok {
- out = append(out, dominant)
- }
- }
-
- fields = out
- sort.Sort(byIndex(fields))
-
- return fields
-}
-
-// dominantField looks through the fields, all of which are known to
-// have the same name, to find the single field that dominates the
-// others using Go's embedding rules, modified by the presence of
-// TOML tags. If there are multiple top-level fields, the boolean
-// will be false: This condition is an error in Go and we skip all
-// the fields.
-func dominantField(fields []field) (field, bool) {
- // The fields are sorted in increasing index-length order. The winner
- // must therefore be one with the shortest index length. Drop all
- // longer entries, which is easy: just truncate the slice.
- length := len(fields[0].index)
- tagged := -1 // Index of first tagged field.
- for i, f := range fields {
- if len(f.index) > length {
- fields = fields[:i]
- break
- }
- if f.tag {
- if tagged >= 0 {
- // Multiple tagged fields at the same level: conflict.
- // Return no field.
- return field{}, false
- }
- tagged = i
- }
- }
- if tagged >= 0 {
- return fields[tagged], true
- }
- // All remaining fields have the same length. If there's more than one,
- // we have a conflict (two fields named "X" at the same level) and we
- // return no field.
- if len(fields) > 1 {
- return field{}, false
- }
- return fields[0], true
-}
-
-var fieldCache struct {
- sync.RWMutex
- m map[reflect.Type][]field
-}
-
-// cachedTypeFields is like typeFields but uses a cache to avoid repeated work.
-func cachedTypeFields(t reflect.Type) []field {
- fieldCache.RLock()
- f := fieldCache.m[t]
- fieldCache.RUnlock()
- if f != nil {
- return f
- }
-
- // Compute fields without lock.
- // Might duplicate effort but won't hold other computations back.
- f = typeFields(t)
- if f == nil {
- f = []field{}
- }
-
- fieldCache.Lock()
- if fieldCache.m == nil {
- fieldCache.m = map[reflect.Type][]field{}
- }
- fieldCache.m[t] = f
- fieldCache.Unlock()
- return f
-}
diff --git a/vendor/github.com/BurntSushi/toml/type_toml.go b/vendor/github.com/BurntSushi/toml/type_toml.go
deleted file mode 100644
index 1c090d331..000000000
--- a/vendor/github.com/BurntSushi/toml/type_toml.go
+++ /dev/null
@@ -1,65 +0,0 @@
-package toml
-
-// tomlType represents any Go type that corresponds to a TOML type.
-// While the first draft of the TOML spec has a simplistic type system that
-// probably doesn't need this level of sophistication, we seem to be militating
-// toward adding real composite types.
-type tomlType interface {
- typeString() string
-}
-
-// typeEqual accepts any two types and returns true if they are equal.
-func typeEqual(t1, t2 tomlType) bool {
- if t1 == nil || t2 == nil {
- return false
- }
- return t1.typeString() == t2.typeString()
-}
-
-func typeIsTable(t tomlType) bool {
- return typeEqual(t, tomlHash) || typeEqual(t, tomlArrayHash)
-}
-
-type tomlBaseType string
-
-func (btype tomlBaseType) typeString() string { return string(btype) }
-func (btype tomlBaseType) String() string { return btype.typeString() }
-
-var (
- tomlInteger tomlBaseType = "Integer"
- tomlFloat tomlBaseType = "Float"
- tomlDatetime tomlBaseType = "Datetime"
- tomlString tomlBaseType = "String"
- tomlBool tomlBaseType = "Bool"
- tomlArray tomlBaseType = "Array"
- tomlHash tomlBaseType = "Hash"
- tomlArrayHash tomlBaseType = "ArrayHash"
-)
-
-// typeOfPrimitive returns a tomlType of any primitive value in TOML.
-// Primitive values are: Integer, Float, Datetime, String and Bool.
-//
-// Passing a lexer item other than the following will cause a BUG message
-// to occur: itemString, itemBool, itemInteger, itemFloat, itemDatetime.
-func (p *parser) typeOfPrimitive(lexItem item) tomlType {
- switch lexItem.typ {
- case itemInteger:
- return tomlInteger
- case itemFloat:
- return tomlFloat
- case itemDatetime:
- return tomlDatetime
- case itemString, itemStringEsc:
- return tomlString
- case itemMultilineString:
- return tomlString
- case itemRawString:
- return tomlString
- case itemRawMultilineString:
- return tomlString
- case itemBool:
- return tomlBool
- }
- p.bug("Cannot infer primitive type of lex item '%s'.", lexItem)
- panic("unreachable")
-}